]> git.openstreetmap.org Git - rails.git/blob - vendor/assets/iD/iD.js
Merge branch 'p' of https://github.com/jfirebaugh/openstreetmap-website into jfirebaugh-p
[rails.git] / vendor / assets / iD / iD.js
1 (function () {
2 var version = "4.11.0";
3
4 var d3_ascending = function(a, b) {
5   return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
6 };
7
8 var d3_bisector = function(compare) {
9   if (compare.length === 1) compare = ascendingComparator(compare);
10   return {
11     left: function(a, x, lo, hi) {
12       if (lo == null) lo = 0;
13       if (hi == null) hi = a.length;
14       while (lo < hi) {
15         var mid = lo + hi >>> 1;
16         if (compare(a[mid], x) < 0) lo = mid + 1;
17         else hi = mid;
18       }
19       return lo;
20     },
21     right: function(a, x, lo, hi) {
22       if (lo == null) lo = 0;
23       if (hi == null) hi = a.length;
24       while (lo < hi) {
25         var mid = lo + hi >>> 1;
26         if (compare(a[mid], x) > 0) hi = mid;
27         else lo = mid + 1;
28       }
29       return lo;
30     }
31   };
32 };
33
34 function ascendingComparator(f) {
35   return function(d, x) {
36     return d3_ascending(f(d), x);
37   };
38 }
39
40 var ascendingBisect = d3_bisector(d3_ascending);
41 var bisectRight = ascendingBisect.right;
42 var bisectLeft = ascendingBisect.left;
43
44 var pairs = function(array, f) {
45   if (f == null) f = pair;
46   var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n);
47   while (i < n) pairs[i] = f(p, p = array[++i]);
48   return pairs;
49 };
50
51 function pair(a, b) {
52   return [a, b];
53 }
54
55 var cross = function(values0, values1, reduce) {
56   var n0 = values0.length,
57       n1 = values1.length,
58       values = new Array(n0 * n1),
59       i0,
60       i1,
61       i,
62       value0;
63
64   if (reduce == null) reduce = pair;
65
66   for (i0 = i = 0; i0 < n0; ++i0) {
67     for (value0 = values0[i0], i1 = 0; i1 < n1; ++i1, ++i) {
68       values[i] = reduce(value0, values1[i1]);
69     }
70   }
71
72   return values;
73 };
74
75 var d3_descending = function(a, b) {
76   return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
77 };
78
79 var number = function(x) {
80   return x === null ? NaN : +x;
81 };
82
83 var variance = function(values, valueof) {
84   var n = values.length,
85       m = 0,
86       i = -1,
87       mean = 0,
88       value,
89       delta,
90       sum = 0;
91
92   if (valueof == null) {
93     while (++i < n) {
94       if (!isNaN(value = number(values[i]))) {
95         delta = value - mean;
96         mean += delta / ++m;
97         sum += delta * (value - mean);
98       }
99     }
100   }
101
102   else {
103     while (++i < n) {
104       if (!isNaN(value = number(valueof(values[i], i, values)))) {
105         delta = value - mean;
106         mean += delta / ++m;
107         sum += delta * (value - mean);
108       }
109     }
110   }
111
112   if (m > 1) return sum / (m - 1);
113 };
114
115 var deviation = function(array, f) {
116   var v = variance(array, f);
117   return v ? Math.sqrt(v) : v;
118 };
119
120 var extent = function(values, valueof) {
121   var n = values.length,
122       i = -1,
123       value,
124       min,
125       max;
126
127   if (valueof == null) {
128     while (++i < n) { // Find the first comparable value.
129       if ((value = values[i]) != null && value >= value) {
130         min = max = value;
131         while (++i < n) { // Compare the remaining values.
132           if ((value = values[i]) != null) {
133             if (min > value) min = value;
134             if (max < value) max = value;
135           }
136         }
137       }
138     }
139   }
140
141   else {
142     while (++i < n) { // Find the first comparable value.
143       if ((value = valueof(values[i], i, values)) != null && value >= value) {
144         min = max = value;
145         while (++i < n) { // Compare the remaining values.
146           if ((value = valueof(values[i], i, values)) != null) {
147             if (min > value) min = value;
148             if (max < value) max = value;
149           }
150         }
151       }
152     }
153   }
154
155   return [min, max];
156 };
157
158 var array = Array.prototype;
159
160 var slice = array.slice;
161 var map = array.map;
162
163 var constant = function(x) {
164   return function() {
165     return x;
166   };
167 };
168
169 var identity = function(x) {
170   return x;
171 };
172
173 var d3_range = function(start, stop, step) {
174   start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;
175
176   var i = -1,
177       n = Math.max(0, Math.ceil((stop - start) / step)) | 0,
178       range = new Array(n);
179
180   while (++i < n) {
181     range[i] = start + i * step;
182   }
183
184   return range;
185 };
186
187 var e10 = Math.sqrt(50);
188 var e5 = Math.sqrt(10);
189 var e2 = Math.sqrt(2);
190
191 var ticks = function(start, stop, count) {
192   var reverse,
193       i = -1,
194       n,
195       ticks,
196       step;
197
198   stop = +stop, start = +start, count = +count;
199   if (start === stop && count > 0) return [start];
200   if (reverse = stop < start) n = start, start = stop, stop = n;
201   if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return [];
202
203   if (step > 0) {
204     start = Math.ceil(start / step);
205     stop = Math.floor(stop / step);
206     ticks = new Array(n = Math.ceil(stop - start + 1));
207     while (++i < n) ticks[i] = (start + i) * step;
208   } else {
209     start = Math.floor(start * step);
210     stop = Math.ceil(stop * step);
211     ticks = new Array(n = Math.ceil(start - stop + 1));
212     while (++i < n) ticks[i] = (start - i) / step;
213   }
214
215   if (reverse) ticks.reverse();
216
217   return ticks;
218 };
219
220 function tickIncrement(start, stop, count) {
221   var step = (stop - start) / Math.max(0, count),
222       power = Math.floor(Math.log(step) / Math.LN10),
223       error = step / Math.pow(10, power);
224   return power >= 0
225       ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power)
226       : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);
227 }
228
229 function tickStep(start, stop, count) {
230   var step0 = Math.abs(stop - start) / Math.max(0, count),
231       step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),
232       error = step0 / step1;
233   if (error >= e10) step1 *= 10;
234   else if (error >= e5) step1 *= 5;
235   else if (error >= e2) step1 *= 2;
236   return stop < start ? -step1 : step1;
237 }
238
239 var sturges = function(values) {
240   return Math.ceil(Math.log(values.length) / Math.LN2) + 1;
241 };
242
243 var histogram = function() {
244   var value = identity,
245       domain = extent,
246       threshold = sturges;
247
248   function histogram(data) {
249     var i,
250         n = data.length,
251         x,
252         values = new Array(n);
253
254     for (i = 0; i < n; ++i) {
255       values[i] = value(data[i], i, data);
256     }
257
258     var xz = domain(values),
259         x0 = xz[0],
260         x1 = xz[1],
261         tz = threshold(values, x0, x1);
262
263     // Convert number of thresholds into uniform thresholds.
264     if (!Array.isArray(tz)) {
265       tz = tickStep(x0, x1, tz);
266       tz = d3_range(Math.ceil(x0 / tz) * tz, Math.floor(x1 / tz) * tz, tz); // exclusive
267     }
268
269     // Remove any thresholds outside the domain.
270     var m = tz.length;
271     while (tz[0] <= x0) tz.shift(), --m;
272     while (tz[m - 1] > x1) tz.pop(), --m;
273
274     var bins = new Array(m + 1),
275         bin;
276
277     // Initialize bins.
278     for (i = 0; i <= m; ++i) {
279       bin = bins[i] = [];
280       bin.x0 = i > 0 ? tz[i - 1] : x0;
281       bin.x1 = i < m ? tz[i] : x1;
282     }
283
284     // Assign data to bins by value, ignoring any outside the domain.
285     for (i = 0; i < n; ++i) {
286       x = values[i];
287       if (x0 <= x && x <= x1) {
288         bins[bisectRight(tz, x, 0, m)].push(data[i]);
289       }
290     }
291
292     return bins;
293   }
294
295   histogram.value = function(_) {
296     return arguments.length ? (value = typeof _ === "function" ? _ : constant(_), histogram) : value;
297   };
298
299   histogram.domain = function(_) {
300     return arguments.length ? (domain = typeof _ === "function" ? _ : constant([_[0], _[1]]), histogram) : domain;
301   };
302
303   histogram.thresholds = function(_) {
304     return arguments.length ? (threshold = typeof _ === "function" ? _ : Array.isArray(_) ? constant(slice.call(_)) : constant(_), histogram) : threshold;
305   };
306
307   return histogram;
308 };
309
310 var threshold = function(values, p, valueof) {
311   if (valueof == null) valueof = number;
312   if (!(n = values.length)) return;
313   if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values);
314   if (p >= 1) return +valueof(values[n - 1], n - 1, values);
315   var n,
316       i = (n - 1) * p,
317       i0 = Math.floor(i),
318       value0 = +valueof(values[i0], i0, values),
319       value1 = +valueof(values[i0 + 1], i0 + 1, values);
320   return value0 + (value1 - value0) * (i - i0);
321 };
322
323 var freedmanDiaconis = function(values, min, max) {
324   values = map.call(values, number).sort(d3_ascending);
325   return Math.ceil((max - min) / (2 * (threshold(values, 0.75) - threshold(values, 0.25)) * Math.pow(values.length, -1 / 3)));
326 };
327
328 var scott = function(values, min, max) {
329   return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3)));
330 };
331
332 var max = function(values, valueof) {
333   var n = values.length,
334       i = -1,
335       value,
336       max;
337
338   if (valueof == null) {
339     while (++i < n) { // Find the first comparable value.
340       if ((value = values[i]) != null && value >= value) {
341         max = value;
342         while (++i < n) { // Compare the remaining values.
343           if ((value = values[i]) != null && value > max) {
344             max = value;
345           }
346         }
347       }
348     }
349   }
350
351   else {
352     while (++i < n) { // Find the first comparable value.
353       if ((value = valueof(values[i], i, values)) != null && value >= value) {
354         max = value;
355         while (++i < n) { // Compare the remaining values.
356           if ((value = valueof(values[i], i, values)) != null && value > max) {
357             max = value;
358           }
359         }
360       }
361     }
362   }
363
364   return max;
365 };
366
367 var mean = function(values, valueof) {
368   var n = values.length,
369       m = n,
370       i = -1,
371       value,
372       sum = 0;
373
374   if (valueof == null) {
375     while (++i < n) {
376       if (!isNaN(value = number(values[i]))) sum += value;
377       else --m;
378     }
379   }
380
381   else {
382     while (++i < n) {
383       if (!isNaN(value = number(valueof(values[i], i, values)))) sum += value;
384       else --m;
385     }
386   }
387
388   if (m) return sum / m;
389 };
390
391 var d3_median = function(values, valueof) {
392   var n = values.length,
393       i = -1,
394       value,
395       numbers = [];
396
397   if (valueof == null) {
398     while (++i < n) {
399       if (!isNaN(value = number(values[i]))) {
400         numbers.push(value);
401       }
402     }
403   }
404
405   else {
406     while (++i < n) {
407       if (!isNaN(value = number(valueof(values[i], i, values)))) {
408         numbers.push(value);
409       }
410     }
411   }
412
413   return threshold(numbers.sort(d3_ascending), 0.5);
414 };
415
416 var merge = function(arrays) {
417   var n = arrays.length,
418       m,
419       i = -1,
420       j = 0,
421       merged,
422       array;
423
424   while (++i < n) j += arrays[i].length;
425   merged = new Array(j);
426
427   while (--n >= 0) {
428     array = arrays[n];
429     m = array.length;
430     while (--m >= 0) {
431       merged[--j] = array[m];
432     }
433   }
434
435   return merged;
436 };
437
438 var min = function(values, valueof) {
439   var n = values.length,
440       i = -1,
441       value,
442       min;
443
444   if (valueof == null) {
445     while (++i < n) { // Find the first comparable value.
446       if ((value = values[i]) != null && value >= value) {
447         min = value;
448         while (++i < n) { // Compare the remaining values.
449           if ((value = values[i]) != null && min > value) {
450             min = value;
451           }
452         }
453       }
454     }
455   }
456
457   else {
458     while (++i < n) { // Find the first comparable value.
459       if ((value = valueof(values[i], i, values)) != null && value >= value) {
460         min = value;
461         while (++i < n) { // Compare the remaining values.
462           if ((value = valueof(values[i], i, values)) != null && min > value) {
463             min = value;
464           }
465         }
466       }
467     }
468   }
469
470   return min;
471 };
472
473 var permute = function(array, indexes) {
474   var i = indexes.length, permutes = new Array(i);
475   while (i--) permutes[i] = array[indexes[i]];
476   return permutes;
477 };
478
479 var scan = function(values, compare) {
480   if (!(n = values.length)) return;
481   var n,
482       i = 0,
483       j = 0,
484       xi,
485       xj = values[j];
486
487   if (compare == null) compare = d3_ascending;
488
489   while (++i < n) {
490     if (compare(xi = values[i], xj) < 0 || compare(xj, xj) !== 0) {
491       xj = xi, j = i;
492     }
493   }
494
495   if (compare(xj, xj) === 0) return j;
496 };
497
498 var shuffle = function(array, i0, i1) {
499   var m = (i1 == null ? array.length : i1) - (i0 = i0 == null ? 0 : +i0),
500       t,
501       i;
502
503   while (m) {
504     i = Math.random() * m-- | 0;
505     t = array[m + i0];
506     array[m + i0] = array[i + i0];
507     array[i + i0] = t;
508   }
509
510   return array;
511 };
512
513 var sum = function(values, valueof) {
514   var n = values.length,
515       i = -1,
516       value,
517       sum = 0;
518
519   if (valueof == null) {
520     while (++i < n) {
521       if (value = +values[i]) sum += value; // Note: zero and null are equivalent.
522     }
523   }
524
525   else {
526     while (++i < n) {
527       if (value = +valueof(values[i], i, values)) sum += value;
528     }
529   }
530
531   return sum;
532 };
533
534 var transpose = function(matrix) {
535   if (!(n = matrix.length)) return [];
536   for (var i = -1, m = min(matrix, length), transpose = new Array(m); ++i < m;) {
537     for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) {
538       row[j] = matrix[j][i];
539     }
540   }
541   return transpose;
542 };
543
544 function length(d) {
545   return d.length;
546 }
547
548 var zip = function() {
549   return transpose(arguments);
550 };
551
552 var slice$1 = Array.prototype.slice;
553
554 var identity$1 = function(x) {
555   return x;
556 };
557
558 var top = 1;
559 var right = 2;
560 var bottom = 3;
561 var left = 4;
562 var epsilon = 1e-6;
563
564 function translateX(x) {
565   return "translate(" + (x + 0.5) + ",0)";
566 }
567
568 function translateY(y) {
569   return "translate(0," + (y + 0.5) + ")";
570 }
571
572 function number$1(scale) {
573   return function(d) {
574     return +scale(d);
575   };
576 }
577
578 function center(scale) {
579   var offset = Math.max(0, scale.bandwidth() - 1) / 2; // Adjust for 0.5px offset.
580   if (scale.round()) offset = Math.round(offset);
581   return function(d) {
582     return +scale(d) + offset;
583   };
584 }
585
586 function entering() {
587   return !this.__axis;
588 }
589
590 function axis(orient, scale) {
591   var tickArguments = [],
592       tickValues = null,
593       tickFormat = null,
594       tickSizeInner = 6,
595       tickSizeOuter = 6,
596       tickPadding = 3,
597       k = orient === top || orient === left ? -1 : 1,
598       x = orient === left || orient === right ? "x" : "y",
599       transform = orient === top || orient === bottom ? translateX : translateY;
600
601   function axis(context) {
602     var values = tickValues == null ? (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : tickValues,
603         format = tickFormat == null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : identity$1) : tickFormat,
604         spacing = Math.max(tickSizeInner, 0) + tickPadding,
605         range = scale.range(),
606         range0 = +range[0] + 0.5,
607         range1 = +range[range.length - 1] + 0.5,
608         position = (scale.bandwidth ? center : number$1)(scale.copy()),
609         selection = context.selection ? context.selection() : context,
610         path = selection.selectAll(".domain").data([null]),
611         tick = selection.selectAll(".tick").data(values, scale).order(),
612         tickExit = tick.exit(),
613         tickEnter = tick.enter().append("g").attr("class", "tick"),
614         line = tick.select("line"),
615         text = tick.select("text");
616
617     path = path.merge(path.enter().insert("path", ".tick")
618         .attr("class", "domain")
619         .attr("stroke", "#000"));
620
621     tick = tick.merge(tickEnter);
622
623     line = line.merge(tickEnter.append("line")
624         .attr("stroke", "#000")
625         .attr(x + "2", k * tickSizeInner));
626
627     text = text.merge(tickEnter.append("text")
628         .attr("fill", "#000")
629         .attr(x, k * spacing)
630         .attr("dy", orient === top ? "0em" : orient === bottom ? "0.71em" : "0.32em"));
631
632     if (context !== selection) {
633       path = path.transition(context);
634       tick = tick.transition(context);
635       line = line.transition(context);
636       text = text.transition(context);
637
638       tickExit = tickExit.transition(context)
639           .attr("opacity", epsilon)
640           .attr("transform", function(d) { return isFinite(d = position(d)) ? transform(d) : this.getAttribute("transform"); });
641
642       tickEnter
643           .attr("opacity", epsilon)
644           .attr("transform", function(d) { var p = this.parentNode.__axis; return transform(p && isFinite(p = p(d)) ? p : position(d)); });
645     }
646
647     tickExit.remove();
648
649     path
650         .attr("d", orient === left || orient == right
651             ? "M" + k * tickSizeOuter + "," + range0 + "H0.5V" + range1 + "H" + k * tickSizeOuter
652             : "M" + range0 + "," + k * tickSizeOuter + "V0.5H" + range1 + "V" + k * tickSizeOuter);
653
654     tick
655         .attr("opacity", 1)
656         .attr("transform", function(d) { return transform(position(d)); });
657
658     line
659         .attr(x + "2", k * tickSizeInner);
660
661     text
662         .attr(x, k * spacing)
663         .text(format);
664
665     selection.filter(entering)
666         .attr("fill", "none")
667         .attr("font-size", 10)
668         .attr("font-family", "sans-serif")
669         .attr("text-anchor", orient === right ? "start" : orient === left ? "end" : "middle");
670
671     selection
672         .each(function() { this.__axis = position; });
673   }
674
675   axis.scale = function(_) {
676     return arguments.length ? (scale = _, axis) : scale;
677   };
678
679   axis.ticks = function() {
680     return tickArguments = slice$1.call(arguments), axis;
681   };
682
683   axis.tickArguments = function(_) {
684     return arguments.length ? (tickArguments = _ == null ? [] : slice$1.call(_), axis) : tickArguments.slice();
685   };
686
687   axis.tickValues = function(_) {
688     return arguments.length ? (tickValues = _ == null ? null : slice$1.call(_), axis) : tickValues && tickValues.slice();
689   };
690
691   axis.tickFormat = function(_) {
692     return arguments.length ? (tickFormat = _, axis) : tickFormat;
693   };
694
695   axis.tickSize = function(_) {
696     return arguments.length ? (tickSizeInner = tickSizeOuter = +_, axis) : tickSizeInner;
697   };
698
699   axis.tickSizeInner = function(_) {
700     return arguments.length ? (tickSizeInner = +_, axis) : tickSizeInner;
701   };
702
703   axis.tickSizeOuter = function(_) {
704     return arguments.length ? (tickSizeOuter = +_, axis) : tickSizeOuter;
705   };
706
707   axis.tickPadding = function(_) {
708     return arguments.length ? (tickPadding = +_, axis) : tickPadding;
709   };
710
711   return axis;
712 }
713
714 function axisTop(scale) {
715   return axis(top, scale);
716 }
717
718 function axisRight(scale) {
719   return axis(right, scale);
720 }
721
722 function axisBottom(scale) {
723   return axis(bottom, scale);
724 }
725
726 function axisLeft(scale) {
727   return axis(left, scale);
728 }
729
730 var noop = {value: function() {}};
731
732 function dispatch() {
733   for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) {
734     if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t);
735     _[t] = [];
736   }
737   return new Dispatch(_);
738 }
739
740 function Dispatch(_) {
741   this._ = _;
742 }
743
744 function parseTypenames(typenames, types) {
745   return typenames.trim().split(/^|\s+/).map(function(t) {
746     var name = "", i = t.indexOf(".");
747     if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
748     if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t);
749     return {type: t, name: name};
750   });
751 }
752
753 Dispatch.prototype = dispatch.prototype = {
754   constructor: Dispatch,
755   on: function(typename, callback) {
756     var _ = this._,
757         T = parseTypenames(typename + "", _),
758         t,
759         i = -1,
760         n = T.length;
761
762     // If no callback was specified, return the callback of the given type and name.
763     if (arguments.length < 2) {
764       while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t;
765       return;
766     }
767
768     // If a type was specified, set the callback for the given type and name.
769     // Otherwise, if a null callback was specified, remove callbacks of the given name.
770     if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback);
771     while (++i < n) {
772       if (t = (typename = T[i]).type) _[t] = set(_[t], typename.name, callback);
773       else if (callback == null) for (t in _) _[t] = set(_[t], typename.name, null);
774     }
775
776     return this;
777   },
778   copy: function() {
779     var copy = {}, _ = this._;
780     for (var t in _) copy[t] = _[t].slice();
781     return new Dispatch(copy);
782   },
783   call: function(type, that) {
784     if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2];
785     if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
786     for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
787   },
788   apply: function(type, that, args) {
789     if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type);
790     for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args);
791   }
792 };
793
794 function get(type, name) {
795   for (var i = 0, n = type.length, c; i < n; ++i) {
796     if ((c = type[i]).name === name) {
797       return c.value;
798     }
799   }
800 }
801
802 function set(type, name, callback) {
803   for (var i = 0, n = type.length; i < n; ++i) {
804     if (type[i].name === name) {
805       type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1));
806       break;
807     }
808   }
809   if (callback != null) type.push({name: name, value: callback});
810   return type;
811 }
812
813 var xhtml = "http://www.w3.org/1999/xhtml";
814
815 var namespaces = {
816   svg: "http://www.w3.org/2000/svg",
817   xhtml: xhtml,
818   xlink: "http://www.w3.org/1999/xlink",
819   xml: "http://www.w3.org/XML/1998/namespace",
820   xmlns: "http://www.w3.org/2000/xmlns/"
821 };
822
823 var namespace = function(name) {
824   var prefix = name += "", i = prefix.indexOf(":");
825   if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);
826   return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name;
827 };
828
829 function creatorInherit(name) {
830   return function() {
831     var document = this.ownerDocument,
832         uri = this.namespaceURI;
833     return uri === xhtml && document.documentElement.namespaceURI === xhtml
834         ? document.createElement(name)
835         : document.createElementNS(uri, name);
836   };
837 }
838
839 function creatorFixed(fullname) {
840   return function() {
841     return this.ownerDocument.createElementNS(fullname.space, fullname.local);
842   };
843 }
844
845 var creator = function(name) {
846   var fullname = namespace(name);
847   return (fullname.local
848       ? creatorFixed
849       : creatorInherit)(fullname);
850 };
851
852 var nextId = 0;
853
854 function local$1() {
855   return new Local;
856 }
857
858 function Local() {
859   this._ = "@" + (++nextId).toString(36);
860 }
861
862 Local.prototype = local$1.prototype = {
863   constructor: Local,
864   get: function(node) {
865     var id = this._;
866     while (!(id in node)) if (!(node = node.parentNode)) return;
867     return node[id];
868   },
869   set: function(node, value) {
870     return node[this._] = value;
871   },
872   remove: function(node) {
873     return this._ in node && delete node[this._];
874   },
875   toString: function() {
876     return this._;
877   }
878 };
879
880 var matcher = function(selector) {
881   return function() {
882     return this.matches(selector);
883   };
884 };
885
886 if (typeof document !== "undefined") {
887   var element = document.documentElement;
888   if (!element.matches) {
889     var vendorMatches = element.webkitMatchesSelector
890         || element.msMatchesSelector
891         || element.mozMatchesSelector
892         || element.oMatchesSelector;
893     matcher = function(selector) {
894       return function() {
895         return vendorMatches.call(this, selector);
896       };
897     };
898   }
899 }
900
901 var matcher$1 = matcher;
902
903 var filterEvents = {};
904
905 var event = null;
906
907 if (typeof document !== "undefined") {
908   var element$1 = document.documentElement;
909   if (!("onmouseenter" in element$1)) {
910     filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"};
911   }
912 }
913
914 function filterContextListener(listener, index, group) {
915   listener = contextListener(listener, index, group);
916   return function(event) {
917     var related = event.relatedTarget;
918     if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) {
919       listener.call(this, event);
920     }
921   };
922 }
923
924 function contextListener(listener, index, group) {
925   return function(event1) {
926     var event0 = event; // Events can be reentrant (e.g., focus).
927     event = event1;
928     try {
929       listener.call(this, this.__data__, index, group);
930     } finally {
931       event = event0;
932     }
933   };
934 }
935
936 function parseTypenames$1(typenames) {
937   return typenames.trim().split(/^|\s+/).map(function(t) {
938     var name = "", i = t.indexOf(".");
939     if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
940     return {type: t, name: name};
941   });
942 }
943
944 function onRemove(typename) {
945   return function() {
946     var on = this.__on;
947     if (!on) return;
948     for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {
949       if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {
950         this.removeEventListener(o.type, o.listener, o.capture);
951       } else {
952         on[++i] = o;
953       }
954     }
955     if (++i) on.length = i;
956     else delete this.__on;
957   };
958 }
959
960 function onAdd(typename, value, capture) {
961   var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener;
962   return function(d, i, group) {
963     var on = this.__on, o, listener = wrap(value, i, group);
964     if (on) for (var j = 0, m = on.length; j < m; ++j) {
965       if ((o = on[j]).type === typename.type && o.name === typename.name) {
966         this.removeEventListener(o.type, o.listener, o.capture);
967         this.addEventListener(o.type, o.listener = listener, o.capture = capture);
968         o.value = value;
969         return;
970       }
971     }
972     this.addEventListener(typename.type, listener, capture);
973     o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture};
974     if (!on) this.__on = [o];
975     else on.push(o);
976   };
977 }
978
979 var selection_on = function(typename, value, capture) {
980   var typenames = parseTypenames$1(typename + ""), i, n = typenames.length, t;
981
982   if (arguments.length < 2) {
983     var on = this.node().__on;
984     if (on) for (var j = 0, m = on.length, o; j < m; ++j) {
985       for (i = 0, o = on[j]; i < n; ++i) {
986         if ((t = typenames[i]).type === o.type && t.name === o.name) {
987           return o.value;
988         }
989       }
990     }
991     return;
992   }
993
994   on = value ? onAdd : onRemove;
995   if (capture == null) capture = false;
996   for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture));
997   return this;
998 };
999
1000 function customEvent(event1, listener, that, args) {
1001   var event0 = event;
1002   event1.sourceEvent = event;
1003   event = event1;
1004   try {
1005     return listener.apply(that, args);
1006   } finally {
1007     event = event0;
1008   }
1009 }
1010
1011 var sourceEvent = function() {
1012   var current = event, source;
1013   while (source = current.sourceEvent) current = source;
1014   return current;
1015 };
1016
1017 var point = function(node, event) {
1018   var svg = node.ownerSVGElement || node;
1019
1020   if (svg.createSVGPoint) {
1021     var point = svg.createSVGPoint();
1022     point.x = event.clientX, point.y = event.clientY;
1023     point = point.matrixTransform(node.getScreenCTM().inverse());
1024     return [point.x, point.y];
1025   }
1026
1027   var rect = node.getBoundingClientRect();
1028   return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
1029 };
1030
1031 var d3_mouse = function(node) {
1032   var event = sourceEvent();
1033   if (event.changedTouches) event = event.changedTouches[0];
1034   return point(node, event);
1035 };
1036
1037 function none() {}
1038
1039 var selector = function(selector) {
1040   return selector == null ? none : function() {
1041     return this.querySelector(selector);
1042   };
1043 };
1044
1045 var selection_select = function(select) {
1046   if (typeof select !== "function") select = selector(select);
1047
1048   for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
1049     for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
1050       if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
1051         if ("__data__" in node) subnode.__data__ = node.__data__;
1052         subgroup[i] = subnode;
1053       }
1054     }
1055   }
1056
1057   return new Selection(subgroups, this._parents);
1058 };
1059
1060 function empty$1() {
1061   return [];
1062 }
1063
1064 var selectorAll = function(selector) {
1065   return selector == null ? empty$1 : function() {
1066     return this.querySelectorAll(selector);
1067   };
1068 };
1069
1070 var selection_selectAll = function(select) {
1071   if (typeof select !== "function") select = selectorAll(select);
1072
1073   for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
1074     for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
1075       if (node = group[i]) {
1076         subgroups.push(select.call(node, node.__data__, i, group));
1077         parents.push(node);
1078       }
1079     }
1080   }
1081
1082   return new Selection(subgroups, parents);
1083 };
1084
1085 var selection_filter = function(match) {
1086   if (typeof match !== "function") match = matcher$1(match);
1087
1088   for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
1089     for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
1090       if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
1091         subgroup.push(node);
1092       }
1093     }
1094   }
1095
1096   return new Selection(subgroups, this._parents);
1097 };
1098
1099 var sparse = function(update) {
1100   return new Array(update.length);
1101 };
1102
1103 var selection_enter = function() {
1104   return new Selection(this._enter || this._groups.map(sparse), this._parents);
1105 };
1106
1107 function EnterNode(parent, datum) {
1108   this.ownerDocument = parent.ownerDocument;
1109   this.namespaceURI = parent.namespaceURI;
1110   this._next = null;
1111   this._parent = parent;
1112   this.__data__ = datum;
1113 }
1114
1115 EnterNode.prototype = {
1116   constructor: EnterNode,
1117   appendChild: function(child) { return this._parent.insertBefore(child, this._next); },
1118   insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },
1119   querySelector: function(selector) { return this._parent.querySelector(selector); },
1120   querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }
1121 };
1122
1123 var constant$1 = function(x) {
1124   return function() {
1125     return x;
1126   };
1127 };
1128
1129 var keyPrefix = "$"; // Protect against keys like “__proto__”.
1130
1131 function bindIndex(parent, group, enter, update, exit, data) {
1132   var i = 0,
1133       node,
1134       groupLength = group.length,
1135       dataLength = data.length;
1136
1137   // Put any non-null nodes that fit into update.
1138   // Put any null nodes into enter.
1139   // Put any remaining data into enter.
1140   for (; i < dataLength; ++i) {
1141     if (node = group[i]) {
1142       node.__data__ = data[i];
1143       update[i] = node;
1144     } else {
1145       enter[i] = new EnterNode(parent, data[i]);
1146     }
1147   }
1148
1149   // Put any non-null nodes that don’t fit into exit.
1150   for (; i < groupLength; ++i) {
1151     if (node = group[i]) {
1152       exit[i] = node;
1153     }
1154   }
1155 }
1156
1157 function bindKey(parent, group, enter, update, exit, data, key) {
1158   var i,
1159       node,
1160       nodeByKeyValue = {},
1161       groupLength = group.length,
1162       dataLength = data.length,
1163       keyValues = new Array(groupLength),
1164       keyValue;
1165
1166   // Compute the key for each node.
1167   // If multiple nodes have the same key, the duplicates are added to exit.
1168   for (i = 0; i < groupLength; ++i) {
1169     if (node = group[i]) {
1170       keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group);
1171       if (keyValue in nodeByKeyValue) {
1172         exit[i] = node;
1173       } else {
1174         nodeByKeyValue[keyValue] = node;
1175       }
1176     }
1177   }
1178
1179   // Compute the key for each datum.
1180   // If there a node associated with this key, join and add it to update.
1181   // If there is not (or the key is a duplicate), add it to enter.
1182   for (i = 0; i < dataLength; ++i) {
1183     keyValue = keyPrefix + key.call(parent, data[i], i, data);
1184     if (node = nodeByKeyValue[keyValue]) {
1185       update[i] = node;
1186       node.__data__ = data[i];
1187       nodeByKeyValue[keyValue] = null;
1188     } else {
1189       enter[i] = new EnterNode(parent, data[i]);
1190     }
1191   }
1192
1193   // Add any remaining nodes that were not bound to data to exit.
1194   for (i = 0; i < groupLength; ++i) {
1195     if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) {
1196       exit[i] = node;
1197     }
1198   }
1199 }
1200
1201 var selection_data = function(value, key) {
1202   if (!value) {
1203     data = new Array(this.size()), j = -1;
1204     this.each(function(d) { data[++j] = d; });
1205     return data;
1206   }
1207
1208   var bind = key ? bindKey : bindIndex,
1209       parents = this._parents,
1210       groups = this._groups;
1211
1212   if (typeof value !== "function") value = constant$1(value);
1213
1214   for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {
1215     var parent = parents[j],
1216         group = groups[j],
1217         groupLength = group.length,
1218         data = value.call(parent, parent && parent.__data__, j, parents),
1219         dataLength = data.length,
1220         enterGroup = enter[j] = new Array(dataLength),
1221         updateGroup = update[j] = new Array(dataLength),
1222         exitGroup = exit[j] = new Array(groupLength);
1223
1224     bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);
1225
1226     // Now connect the enter nodes to their following update node, such that
1227     // appendChild can insert the materialized enter node before this node,
1228     // rather than at the end of the parent node.
1229     for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {
1230       if (previous = enterGroup[i0]) {
1231         if (i0 >= i1) i1 = i0 + 1;
1232         while (!(next = updateGroup[i1]) && ++i1 < dataLength);
1233         previous._next = next || null;
1234       }
1235     }
1236   }
1237
1238   update = new Selection(update, parents);
1239   update._enter = enter;
1240   update._exit = exit;
1241   return update;
1242 };
1243
1244 var selection_exit = function() {
1245   return new Selection(this._exit || this._groups.map(sparse), this._parents);
1246 };
1247
1248 var selection_merge = function(selection$$1) {
1249
1250   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) {
1251     for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
1252       if (node = group0[i] || group1[i]) {
1253         merge[i] = node;
1254       }
1255     }
1256   }
1257
1258   for (; j < m0; ++j) {
1259     merges[j] = groups0[j];
1260   }
1261
1262   return new Selection(merges, this._parents);
1263 };
1264
1265 var selection_order = function() {
1266
1267   for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {
1268     for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {
1269       if (node = group[i]) {
1270         if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);
1271         next = node;
1272       }
1273     }
1274   }
1275
1276   return this;
1277 };
1278
1279 var selection_sort = function(compare) {
1280   if (!compare) compare = ascending;
1281
1282   function compareNode(a, b) {
1283     return a && b ? compare(a.__data__, b.__data__) : !a - !b;
1284   }
1285
1286   for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {
1287     for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {
1288       if (node = group[i]) {
1289         sortgroup[i] = node;
1290       }
1291     }
1292     sortgroup.sort(compareNode);
1293   }
1294
1295   return new Selection(sortgroups, this._parents).order();
1296 };
1297
1298 function ascending(a, b) {
1299   return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
1300 }
1301
1302 var selection_call = function() {
1303   var callback = arguments[0];
1304   arguments[0] = this;
1305   callback.apply(null, arguments);
1306   return this;
1307 };
1308
1309 var selection_nodes = function() {
1310   var nodes = new Array(this.size()), i = -1;
1311   this.each(function() { nodes[++i] = this; });
1312   return nodes;
1313 };
1314
1315 var selection_node = function() {
1316
1317   for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
1318     for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {
1319       var node = group[i];
1320       if (node) return node;
1321     }
1322   }
1323
1324   return null;
1325 };
1326
1327 var selection_size = function() {
1328   var size = 0;
1329   this.each(function() { ++size; });
1330   return size;
1331 };
1332
1333 var selection_empty = function() {
1334   return !this.node();
1335 };
1336
1337 var selection_each = function(callback) {
1338
1339   for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
1340     for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
1341       if (node = group[i]) callback.call(node, node.__data__, i, group);
1342     }
1343   }
1344
1345   return this;
1346 };
1347
1348 function attrRemove(name) {
1349   return function() {
1350     this.removeAttribute(name);
1351   };
1352 }
1353
1354 function attrRemoveNS(fullname) {
1355   return function() {
1356     this.removeAttributeNS(fullname.space, fullname.local);
1357   };
1358 }
1359
1360 function attrConstant(name, value) {
1361   return function() {
1362     this.setAttribute(name, value);
1363   };
1364 }
1365
1366 function attrConstantNS(fullname, value) {
1367   return function() {
1368     this.setAttributeNS(fullname.space, fullname.local, value);
1369   };
1370 }
1371
1372 function attrFunction(name, value) {
1373   return function() {
1374     var v = value.apply(this, arguments);
1375     if (v == null) this.removeAttribute(name);
1376     else this.setAttribute(name, v);
1377   };
1378 }
1379
1380 function attrFunctionNS(fullname, value) {
1381   return function() {
1382     var v = value.apply(this, arguments);
1383     if (v == null) this.removeAttributeNS(fullname.space, fullname.local);
1384     else this.setAttributeNS(fullname.space, fullname.local, v);
1385   };
1386 }
1387
1388 var selection_attr = function(name, value) {
1389   var fullname = namespace(name);
1390
1391   if (arguments.length < 2) {
1392     var node = this.node();
1393     return fullname.local
1394         ? node.getAttributeNS(fullname.space, fullname.local)
1395         : node.getAttribute(fullname);
1396   }
1397
1398   return this.each((value == null
1399       ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function"
1400       ? (fullname.local ? attrFunctionNS : attrFunction)
1401       : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));
1402 };
1403
1404 var defaultView = function(node) {
1405   return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node
1406       || (node.document && node) // node is a Window
1407       || node.defaultView; // node is a Document
1408 };
1409
1410 function styleRemove(name) {
1411   return function() {
1412     this.style.removeProperty(name);
1413   };
1414 }
1415
1416 function styleConstant(name, value, priority) {
1417   return function() {
1418     this.style.setProperty(name, value, priority);
1419   };
1420 }
1421
1422 function styleFunction(name, value, priority) {
1423   return function() {
1424     var v = value.apply(this, arguments);
1425     if (v == null) this.style.removeProperty(name);
1426     else this.style.setProperty(name, v, priority);
1427   };
1428 }
1429
1430 var selection_style = function(name, value, priority) {
1431   return arguments.length > 1
1432       ? this.each((value == null
1433             ? styleRemove : typeof value === "function"
1434             ? styleFunction
1435             : styleConstant)(name, value, priority == null ? "" : priority))
1436       : styleValue(this.node(), name);
1437 };
1438
1439 function styleValue(node, name) {
1440   return node.style.getPropertyValue(name)
1441       || defaultView(node).getComputedStyle(node, null).getPropertyValue(name);
1442 }
1443
1444 function propertyRemove(name) {
1445   return function() {
1446     delete this[name];
1447   };
1448 }
1449
1450 function propertyConstant(name, value) {
1451   return function() {
1452     this[name] = value;
1453   };
1454 }
1455
1456 function propertyFunction(name, value) {
1457   return function() {
1458     var v = value.apply(this, arguments);
1459     if (v == null) delete this[name];
1460     else this[name] = v;
1461   };
1462 }
1463
1464 var selection_property = function(name, value) {
1465   return arguments.length > 1
1466       ? this.each((value == null
1467           ? propertyRemove : typeof value === "function"
1468           ? propertyFunction
1469           : propertyConstant)(name, value))
1470       : this.node()[name];
1471 };
1472
1473 function classArray(string) {
1474   return string.trim().split(/^|\s+/);
1475 }
1476
1477 function classList(node) {
1478   return node.classList || new ClassList(node);
1479 }
1480
1481 function ClassList(node) {
1482   this._node = node;
1483   this._names = classArray(node.getAttribute("class") || "");
1484 }
1485
1486 ClassList.prototype = {
1487   add: function(name) {
1488     var i = this._names.indexOf(name);
1489     if (i < 0) {
1490       this._names.push(name);
1491       this._node.setAttribute("class", this._names.join(" "));
1492     }
1493   },
1494   remove: function(name) {
1495     var i = this._names.indexOf(name);
1496     if (i >= 0) {
1497       this._names.splice(i, 1);
1498       this._node.setAttribute("class", this._names.join(" "));
1499     }
1500   },
1501   contains: function(name) {
1502     return this._names.indexOf(name) >= 0;
1503   }
1504 };
1505
1506 function classedAdd(node, names) {
1507   var list = classList(node), i = -1, n = names.length;
1508   while (++i < n) list.add(names[i]);
1509 }
1510
1511 function classedRemove(node, names) {
1512   var list = classList(node), i = -1, n = names.length;
1513   while (++i < n) list.remove(names[i]);
1514 }
1515
1516 function classedTrue(names) {
1517   return function() {
1518     classedAdd(this, names);
1519   };
1520 }
1521
1522 function classedFalse(names) {
1523   return function() {
1524     classedRemove(this, names);
1525   };
1526 }
1527
1528 function classedFunction(names, value) {
1529   return function() {
1530     (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);
1531   };
1532 }
1533
1534 var selection_classed = function(name, value) {
1535   var names = classArray(name + "");
1536
1537   if (arguments.length < 2) {
1538     var list = classList(this.node()), i = -1, n = names.length;
1539     while (++i < n) if (!list.contains(names[i])) return false;
1540     return true;
1541   }
1542
1543   return this.each((typeof value === "function"
1544       ? classedFunction : value
1545       ? classedTrue
1546       : classedFalse)(names, value));
1547 };
1548
1549 function textRemove() {
1550   this.textContent = "";
1551 }
1552
1553 function textConstant(value) {
1554   return function() {
1555     this.textContent = value;
1556   };
1557 }
1558
1559 function textFunction(value) {
1560   return function() {
1561     var v = value.apply(this, arguments);
1562     this.textContent = v == null ? "" : v;
1563   };
1564 }
1565
1566 var selection_text = function(value) {
1567   return arguments.length
1568       ? this.each(value == null
1569           ? textRemove : (typeof value === "function"
1570           ? textFunction
1571           : textConstant)(value))
1572       : this.node().textContent;
1573 };
1574
1575 function htmlRemove() {
1576   this.innerHTML = "";
1577 }
1578
1579 function htmlConstant(value) {
1580   return function() {
1581     this.innerHTML = value;
1582   };
1583 }
1584
1585 function htmlFunction(value) {
1586   return function() {
1587     var v = value.apply(this, arguments);
1588     this.innerHTML = v == null ? "" : v;
1589   };
1590 }
1591
1592 var selection_html = function(value) {
1593   return arguments.length
1594       ? this.each(value == null
1595           ? htmlRemove : (typeof value === "function"
1596           ? htmlFunction
1597           : htmlConstant)(value))
1598       : this.node().innerHTML;
1599 };
1600
1601 function raise() {
1602   if (this.nextSibling) this.parentNode.appendChild(this);
1603 }
1604
1605 var selection_raise = function() {
1606   return this.each(raise);
1607 };
1608
1609 function lower() {
1610   if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);
1611 }
1612
1613 var selection_lower = function() {
1614   return this.each(lower);
1615 };
1616
1617 var selection_append = function(name) {
1618   var create = typeof name === "function" ? name : creator(name);
1619   return this.select(function() {
1620     return this.appendChild(create.apply(this, arguments));
1621   });
1622 };
1623
1624 function constantNull() {
1625   return null;
1626 }
1627
1628 var selection_insert = function(name, before) {
1629   var create = typeof name === "function" ? name : creator(name),
1630       select = before == null ? constantNull : typeof before === "function" ? before : selector(before);
1631   return this.select(function() {
1632     return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);
1633   });
1634 };
1635
1636 function remove() {
1637   var parent = this.parentNode;
1638   if (parent) parent.removeChild(this);
1639 }
1640
1641 var selection_remove = function() {
1642   return this.each(remove);
1643 };
1644
1645 var selection_datum = function(value) {
1646   return arguments.length
1647       ? this.property("__data__", value)
1648       : this.node().__data__;
1649 };
1650
1651 function dispatchEvent(node, type, params) {
1652   var window = defaultView(node),
1653       event = window.CustomEvent;
1654
1655   if (typeof event === "function") {
1656     event = new event(type, params);
1657   } else {
1658     event = window.document.createEvent("Event");
1659     if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;
1660     else event.initEvent(type, false, false);
1661   }
1662
1663   node.dispatchEvent(event);
1664 }
1665
1666 function dispatchConstant(type, params) {
1667   return function() {
1668     return dispatchEvent(this, type, params);
1669   };
1670 }
1671
1672 function dispatchFunction(type, params) {
1673   return function() {
1674     return dispatchEvent(this, type, params.apply(this, arguments));
1675   };
1676 }
1677
1678 var selection_dispatch = function(type, params) {
1679   return this.each((typeof params === "function"
1680       ? dispatchFunction
1681       : dispatchConstant)(type, params));
1682 };
1683
1684 var root = [null];
1685
1686 function Selection(groups, parents) {
1687   this._groups = groups;
1688   this._parents = parents;
1689 }
1690
1691 function selection() {
1692   return new Selection([[document.documentElement]], root);
1693 }
1694
1695 Selection.prototype = selection.prototype = {
1696   constructor: Selection,
1697   select: selection_select,
1698   selectAll: selection_selectAll,
1699   filter: selection_filter,
1700   data: selection_data,
1701   enter: selection_enter,
1702   exit: selection_exit,
1703   merge: selection_merge,
1704   order: selection_order,
1705   sort: selection_sort,
1706   call: selection_call,
1707   nodes: selection_nodes,
1708   node: selection_node,
1709   size: selection_size,
1710   empty: selection_empty,
1711   each: selection_each,
1712   attr: selection_attr,
1713   style: selection_style,
1714   property: selection_property,
1715   classed: selection_classed,
1716   text: selection_text,
1717   html: selection_html,
1718   raise: selection_raise,
1719   lower: selection_lower,
1720   append: selection_append,
1721   insert: selection_insert,
1722   remove: selection_remove,
1723   datum: selection_datum,
1724   on: selection_on,
1725   dispatch: selection_dispatch
1726 };
1727
1728 var d3_select = function(selector) {
1729   return typeof selector === "string"
1730       ? new Selection([[document.querySelector(selector)]], [document.documentElement])
1731       : new Selection([[selector]], root);
1732 };
1733
1734 var d3_selectAll = function(selector) {
1735   return typeof selector === "string"
1736       ? new Selection([document.querySelectorAll(selector)], [document.documentElement])
1737       : new Selection([selector == null ? [] : selector], root);
1738 };
1739
1740 var touch = function(node, touches, identifier) {
1741   if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches;
1742
1743   for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) {
1744     if ((touch = touches[i]).identifier === identifier) {
1745       return point(node, touch);
1746     }
1747   }
1748
1749   return null;
1750 };
1751
1752 var d3_touches = function(node, touches) {
1753   if (touches == null) touches = sourceEvent().touches;
1754
1755   for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) {
1756     points[i] = point(node, touches[i]);
1757   }
1758
1759   return points;
1760 };
1761
1762 function nopropagation() {
1763   event.stopImmediatePropagation();
1764 }
1765
1766 var noevent = function() {
1767   event.preventDefault();
1768   event.stopImmediatePropagation();
1769 };
1770
1771 var dragDisable = function(view) {
1772   var root = view.document.documentElement,
1773       selection = d3_select(view).on("dragstart.drag", noevent, true);
1774   if ("onselectstart" in root) {
1775     selection.on("selectstart.drag", noevent, true);
1776   } else {
1777     root.__noselect = root.style.MozUserSelect;
1778     root.style.MozUserSelect = "none";
1779   }
1780 };
1781
1782 function yesdrag(view, noclick) {
1783   var root = view.document.documentElement,
1784       selection = d3_select(view).on("dragstart.drag", null);
1785   if (noclick) {
1786     selection.on("click.drag", noevent, true);
1787     setTimeout(function() { selection.on("click.drag", null); }, 0);
1788   }
1789   if ("onselectstart" in root) {
1790     selection.on("selectstart.drag", null);
1791   } else {
1792     root.style.MozUserSelect = root.__noselect;
1793     delete root.__noselect;
1794   }
1795 }
1796
1797 var constant$2 = function(x) {
1798   return function() {
1799     return x;
1800   };
1801 };
1802
1803 function DragEvent(target, type, subject, id, active, x, y, dx, dy, dispatch) {
1804   this.target = target;
1805   this.type = type;
1806   this.subject = subject;
1807   this.identifier = id;
1808   this.active = active;
1809   this.x = x;
1810   this.y = y;
1811   this.dx = dx;
1812   this.dy = dy;
1813   this._ = dispatch;
1814 }
1815
1816 DragEvent.prototype.on = function() {
1817   var value = this._.on.apply(this._, arguments);
1818   return value === this._ ? this : value;
1819 };
1820
1821 // Ignore right-click, since that should open the context menu.
1822 function defaultFilter$1() {
1823   return !event.button;
1824 }
1825
1826 function defaultContainer() {
1827   return this.parentNode;
1828 }
1829
1830 function defaultSubject(d) {
1831   return d == null ? {x: event.x, y: event.y} : d;
1832 }
1833
1834 function defaultTouchable() {
1835   return "ontouchstart" in this;
1836 }
1837
1838 var drag = function() {
1839   var filter = defaultFilter$1,
1840       container = defaultContainer,
1841       subject = defaultSubject,
1842       touchable = defaultTouchable,
1843       gestures = {},
1844       listeners = dispatch("start", "drag", "end"),
1845       active = 0,
1846       mousedownx,
1847       mousedowny,
1848       mousemoving,
1849       touchending,
1850       clickDistance2 = 0;
1851
1852   function drag(selection) {
1853     selection
1854         .on("mousedown.drag", mousedowned)
1855       .filter(touchable)
1856         .on("touchstart.drag", touchstarted)
1857         .on("touchmove.drag", touchmoved)
1858         .on("touchend.drag touchcancel.drag", touchended)
1859         .style("touch-action", "none")
1860         .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
1861   }
1862
1863   function mousedowned() {
1864     if (touchending || !filter.apply(this, arguments)) return;
1865     var gesture = beforestart("mouse", container.apply(this, arguments), d3_mouse, this, arguments);
1866     if (!gesture) return;
1867     d3_select(event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true);
1868     dragDisable(event.view);
1869     nopropagation();
1870     mousemoving = false;
1871     mousedownx = event.clientX;
1872     mousedowny = event.clientY;
1873     gesture("start");
1874   }
1875
1876   function mousemoved() {
1877     noevent();
1878     if (!mousemoving) {
1879       var dx = event.clientX - mousedownx, dy = event.clientY - mousedowny;
1880       mousemoving = dx * dx + dy * dy > clickDistance2;
1881     }
1882     gestures.mouse("drag");
1883   }
1884
1885   function mouseupped() {
1886     d3_select(event.view).on("mousemove.drag mouseup.drag", null);
1887     yesdrag(event.view, mousemoving);
1888     noevent();
1889     gestures.mouse("end");
1890   }
1891
1892   function touchstarted() {
1893     if (!filter.apply(this, arguments)) return;
1894     var touches = event.changedTouches,
1895         c = container.apply(this, arguments),
1896         n = touches.length, i, gesture;
1897
1898     for (i = 0; i < n; ++i) {
1899       if (gesture = beforestart(touches[i].identifier, c, touch, this, arguments)) {
1900         nopropagation();
1901         gesture("start");
1902       }
1903     }
1904   }
1905
1906   function touchmoved() {
1907     var touches = event.changedTouches,
1908         n = touches.length, i, gesture;
1909
1910     for (i = 0; i < n; ++i) {
1911       if (gesture = gestures[touches[i].identifier]) {
1912         noevent();
1913         gesture("drag");
1914       }
1915     }
1916   }
1917
1918   function touchended() {
1919     var touches = event.changedTouches,
1920         n = touches.length, i, gesture;
1921
1922     if (touchending) clearTimeout(touchending);
1923     touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
1924     for (i = 0; i < n; ++i) {
1925       if (gesture = gestures[touches[i].identifier]) {
1926         nopropagation();
1927         gesture("end");
1928       }
1929     }
1930   }
1931
1932   function beforestart(id, container, point, that, args) {
1933     var p = point(container, id), s, dx, dy,
1934         sublisteners = listeners.copy();
1935
1936     if (!customEvent(new DragEvent(drag, "beforestart", s, id, active, p[0], p[1], 0, 0, sublisteners), function() {
1937       if ((event.subject = s = subject.apply(that, args)) == null) return false;
1938       dx = s.x - p[0] || 0;
1939       dy = s.y - p[1] || 0;
1940       return true;
1941     })) return;
1942
1943     return function gesture(type) {
1944       var p0 = p, n;
1945       switch (type) {
1946         case "start": gestures[id] = gesture, n = active++; break;
1947         case "end": delete gestures[id], --active; // nobreak
1948         case "drag": p = point(container, id), n = active; break;
1949       }
1950       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]);
1951     };
1952   }
1953
1954   drag.filter = function(_) {
1955     return arguments.length ? (filter = typeof _ === "function" ? _ : constant$2(!!_), drag) : filter;
1956   };
1957
1958   drag.container = function(_) {
1959     return arguments.length ? (container = typeof _ === "function" ? _ : constant$2(_), drag) : container;
1960   };
1961
1962   drag.subject = function(_) {
1963     return arguments.length ? (subject = typeof _ === "function" ? _ : constant$2(_), drag) : subject;
1964   };
1965
1966   drag.touchable = function(_) {
1967     return arguments.length ? (touchable = typeof _ === "function" ? _ : constant$2(!!_), drag) : touchable;
1968   };
1969
1970   drag.on = function() {
1971     var value = listeners.on.apply(listeners, arguments);
1972     return value === listeners ? drag : value;
1973   };
1974
1975   drag.clickDistance = function(_) {
1976     return arguments.length ? (clickDistance2 = (_ = +_) * _, drag) : Math.sqrt(clickDistance2);
1977   };
1978
1979   return drag;
1980 };
1981
1982 var define = function(constructor, factory, prototype) {
1983   constructor.prototype = factory.prototype = prototype;
1984   prototype.constructor = constructor;
1985 };
1986
1987 function extend(parent, definition) {
1988   var prototype = Object.create(parent.prototype);
1989   for (var key in definition) prototype[key] = definition[key];
1990   return prototype;
1991 }
1992
1993 function Color() {}
1994
1995 var darker = 0.7;
1996 var brighter = 1 / darker;
1997
1998 var reI = "\\s*([+-]?\\d+)\\s*";
1999 var reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*";
2000 var reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*";
2001 var reHex3 = /^#([0-9a-f]{3})$/;
2002 var reHex6 = /^#([0-9a-f]{6})$/;
2003 var reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$");
2004 var reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$");
2005 var reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$");
2006 var reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$");
2007 var reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$");
2008 var reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$");
2009
2010 var named = {
2011   aliceblue: 0xf0f8ff,
2012   antiquewhite: 0xfaebd7,
2013   aqua: 0x00ffff,
2014   aquamarine: 0x7fffd4,
2015   azure: 0xf0ffff,
2016   beige: 0xf5f5dc,
2017   bisque: 0xffe4c4,
2018   black: 0x000000,
2019   blanchedalmond: 0xffebcd,
2020   blue: 0x0000ff,
2021   blueviolet: 0x8a2be2,
2022   brown: 0xa52a2a,
2023   burlywood: 0xdeb887,
2024   cadetblue: 0x5f9ea0,
2025   chartreuse: 0x7fff00,
2026   chocolate: 0xd2691e,
2027   coral: 0xff7f50,
2028   cornflowerblue: 0x6495ed,
2029   cornsilk: 0xfff8dc,
2030   crimson: 0xdc143c,
2031   cyan: 0x00ffff,
2032   darkblue: 0x00008b,
2033   darkcyan: 0x008b8b,
2034   darkgoldenrod: 0xb8860b,
2035   darkgray: 0xa9a9a9,
2036   darkgreen: 0x006400,
2037   darkgrey: 0xa9a9a9,
2038   darkkhaki: 0xbdb76b,
2039   darkmagenta: 0x8b008b,
2040   darkolivegreen: 0x556b2f,
2041   darkorange: 0xff8c00,
2042   darkorchid: 0x9932cc,
2043   darkred: 0x8b0000,
2044   darksalmon: 0xe9967a,
2045   darkseagreen: 0x8fbc8f,
2046   darkslateblue: 0x483d8b,
2047   darkslategray: 0x2f4f4f,
2048   darkslategrey: 0x2f4f4f,
2049   darkturquoise: 0x00ced1,
2050   darkviolet: 0x9400d3,
2051   deeppink: 0xff1493,
2052   deepskyblue: 0x00bfff,
2053   dimgray: 0x696969,
2054   dimgrey: 0x696969,
2055   dodgerblue: 0x1e90ff,
2056   firebrick: 0xb22222,
2057   floralwhite: 0xfffaf0,
2058   forestgreen: 0x228b22,
2059   fuchsia: 0xff00ff,
2060   gainsboro: 0xdcdcdc,
2061   ghostwhite: 0xf8f8ff,
2062   gold: 0xffd700,
2063   goldenrod: 0xdaa520,
2064   gray: 0x808080,
2065   green: 0x008000,
2066   greenyellow: 0xadff2f,
2067   grey: 0x808080,
2068   honeydew: 0xf0fff0,
2069   hotpink: 0xff69b4,
2070   indianred: 0xcd5c5c,
2071   indigo: 0x4b0082,
2072   ivory: 0xfffff0,
2073   khaki: 0xf0e68c,
2074   lavender: 0xe6e6fa,
2075   lavenderblush: 0xfff0f5,
2076   lawngreen: 0x7cfc00,
2077   lemonchiffon: 0xfffacd,
2078   lightblue: 0xadd8e6,
2079   lightcoral: 0xf08080,
2080   lightcyan: 0xe0ffff,
2081   lightgoldenrodyellow: 0xfafad2,
2082   lightgray: 0xd3d3d3,
2083   lightgreen: 0x90ee90,
2084   lightgrey: 0xd3d3d3,
2085   lightpink: 0xffb6c1,
2086   lightsalmon: 0xffa07a,
2087   lightseagreen: 0x20b2aa,
2088   lightskyblue: 0x87cefa,
2089   lightslategray: 0x778899,
2090   lightslategrey: 0x778899,
2091   lightsteelblue: 0xb0c4de,
2092   lightyellow: 0xffffe0,
2093   lime: 0x00ff00,
2094   limegreen: 0x32cd32,
2095   linen: 0xfaf0e6,
2096   magenta: 0xff00ff,
2097   maroon: 0x800000,
2098   mediumaquamarine: 0x66cdaa,
2099   mediumblue: 0x0000cd,
2100   mediumorchid: 0xba55d3,
2101   mediumpurple: 0x9370db,
2102   mediumseagreen: 0x3cb371,
2103   mediumslateblue: 0x7b68ee,
2104   mediumspringgreen: 0x00fa9a,
2105   mediumturquoise: 0x48d1cc,
2106   mediumvioletred: 0xc71585,
2107   midnightblue: 0x191970,
2108   mintcream: 0xf5fffa,
2109   mistyrose: 0xffe4e1,
2110   moccasin: 0xffe4b5,
2111   navajowhite: 0xffdead,
2112   navy: 0x000080,
2113   oldlace: 0xfdf5e6,
2114   olive: 0x808000,
2115   olivedrab: 0x6b8e23,
2116   orange: 0xffa500,
2117   orangered: 0xff4500,
2118   orchid: 0xda70d6,
2119   palegoldenrod: 0xeee8aa,
2120   palegreen: 0x98fb98,
2121   paleturquoise: 0xafeeee,
2122   palevioletred: 0xdb7093,
2123   papayawhip: 0xffefd5,
2124   peachpuff: 0xffdab9,
2125   peru: 0xcd853f,
2126   pink: 0xffc0cb,
2127   plum: 0xdda0dd,
2128   powderblue: 0xb0e0e6,
2129   purple: 0x800080,
2130   rebeccapurple: 0x663399,
2131   red: 0xff0000,
2132   rosybrown: 0xbc8f8f,
2133   royalblue: 0x4169e1,
2134   saddlebrown: 0x8b4513,
2135   salmon: 0xfa8072,
2136   sandybrown: 0xf4a460,
2137   seagreen: 0x2e8b57,
2138   seashell: 0xfff5ee,
2139   sienna: 0xa0522d,
2140   silver: 0xc0c0c0,
2141   skyblue: 0x87ceeb,
2142   slateblue: 0x6a5acd,
2143   slategray: 0x708090,
2144   slategrey: 0x708090,
2145   snow: 0xfffafa,
2146   springgreen: 0x00ff7f,
2147   steelblue: 0x4682b4,
2148   tan: 0xd2b48c,
2149   teal: 0x008080,
2150   thistle: 0xd8bfd8,
2151   tomato: 0xff6347,
2152   turquoise: 0x40e0d0,
2153   violet: 0xee82ee,
2154   wheat: 0xf5deb3,
2155   white: 0xffffff,
2156   whitesmoke: 0xf5f5f5,
2157   yellow: 0xffff00,
2158   yellowgreen: 0x9acd32
2159 };
2160
2161 define(Color, color, {
2162   displayable: function() {
2163     return this.rgb().displayable();
2164   },
2165   toString: function() {
2166     return this.rgb() + "";
2167   }
2168 });
2169
2170 function color(format) {
2171   var m;
2172   format = (format + "").trim().toLowerCase();
2173   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
2174       : (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000
2175       : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0)
2176       : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%)
2177       : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1)
2178       : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1)
2179       : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%)
2180       : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1)
2181       : named.hasOwnProperty(format) ? rgbn(named[format])
2182       : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0)
2183       : null;
2184 }
2185
2186 function rgbn(n) {
2187   return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1);
2188 }
2189
2190 function rgba(r, g, b, a) {
2191   if (a <= 0) r = g = b = NaN;
2192   return new Rgb(r, g, b, a);
2193 }
2194
2195 function rgbConvert(o) {
2196   if (!(o instanceof Color)) o = color(o);
2197   if (!o) return new Rgb;
2198   o = o.rgb();
2199   return new Rgb(o.r, o.g, o.b, o.opacity);
2200 }
2201
2202 function rgb(r, g, b, opacity) {
2203   return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
2204 }
2205
2206 function Rgb(r, g, b, opacity) {
2207   this.r = +r;
2208   this.g = +g;
2209   this.b = +b;
2210   this.opacity = +opacity;
2211 }
2212
2213 define(Rgb, rgb, extend(Color, {
2214   brighter: function(k) {
2215     k = k == null ? brighter : Math.pow(brighter, k);
2216     return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
2217   },
2218   darker: function(k) {
2219     k = k == null ? darker : Math.pow(darker, k);
2220     return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
2221   },
2222   rgb: function() {
2223     return this;
2224   },
2225   displayable: function() {
2226     return (0 <= this.r && this.r <= 255)
2227         && (0 <= this.g && this.g <= 255)
2228         && (0 <= this.b && this.b <= 255)
2229         && (0 <= this.opacity && this.opacity <= 1);
2230   },
2231   toString: function() {
2232     var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a));
2233     return (a === 1 ? "rgb(" : "rgba(")
2234         + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", "
2235         + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", "
2236         + Math.max(0, Math.min(255, Math.round(this.b) || 0))
2237         + (a === 1 ? ")" : ", " + a + ")");
2238   }
2239 }));
2240
2241 function hsla(h, s, l, a) {
2242   if (a <= 0) h = s = l = NaN;
2243   else if (l <= 0 || l >= 1) h = s = NaN;
2244   else if (s <= 0) h = NaN;
2245   return new Hsl(h, s, l, a);
2246 }
2247
2248 function hslConvert(o) {
2249   if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity);
2250   if (!(o instanceof Color)) o = color(o);
2251   if (!o) return new Hsl;
2252   if (o instanceof Hsl) return o;
2253   o = o.rgb();
2254   var r = o.r / 255,
2255       g = o.g / 255,
2256       b = o.b / 255,
2257       min = Math.min(r, g, b),
2258       max = Math.max(r, g, b),
2259       h = NaN,
2260       s = max - min,
2261       l = (max + min) / 2;
2262   if (s) {
2263     if (r === max) h = (g - b) / s + (g < b) * 6;
2264     else if (g === max) h = (b - r) / s + 2;
2265     else h = (r - g) / s + 4;
2266     s /= l < 0.5 ? max + min : 2 - max - min;
2267     h *= 60;
2268   } else {
2269     s = l > 0 && l < 1 ? 0 : h;
2270   }
2271   return new Hsl(h, s, l, o.opacity);
2272 }
2273
2274 function hsl(h, s, l, opacity) {
2275   return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity);
2276 }
2277
2278 function Hsl(h, s, l, opacity) {
2279   this.h = +h;
2280   this.s = +s;
2281   this.l = +l;
2282   this.opacity = +opacity;
2283 }
2284
2285 define(Hsl, hsl, extend(Color, {
2286   brighter: function(k) {
2287     k = k == null ? brighter : Math.pow(brighter, k);
2288     return new Hsl(this.h, this.s, this.l * k, this.opacity);
2289   },
2290   darker: function(k) {
2291     k = k == null ? darker : Math.pow(darker, k);
2292     return new Hsl(this.h, this.s, this.l * k, this.opacity);
2293   },
2294   rgb: function() {
2295     var h = this.h % 360 + (this.h < 0) * 360,
2296         s = isNaN(h) || isNaN(this.s) ? 0 : this.s,
2297         l = this.l,
2298         m2 = l + (l < 0.5 ? l : 1 - l) * s,
2299         m1 = 2 * l - m2;
2300     return new Rgb(
2301       hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2),
2302       hsl2rgb(h, m1, m2),
2303       hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2),
2304       this.opacity
2305     );
2306   },
2307   displayable: function() {
2308     return (0 <= this.s && this.s <= 1 || isNaN(this.s))
2309         && (0 <= this.l && this.l <= 1)
2310         && (0 <= this.opacity && this.opacity <= 1);
2311   }
2312 }));
2313
2314 /* From FvD 13.37, CSS Color Module Level 3 */
2315 function hsl2rgb(h, m1, m2) {
2316   return (h < 60 ? m1 + (m2 - m1) * h / 60
2317       : h < 180 ? m2
2318       : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60
2319       : m1) * 255;
2320 }
2321
2322 var deg2rad = Math.PI / 180;
2323 var rad2deg = 180 / Math.PI;
2324
2325 var Kn = 18;
2326 var Xn = 0.950470;
2327 var Yn = 1;
2328 var Zn = 1.088830;
2329 var t0 = 4 / 29;
2330 var t1 = 6 / 29;
2331 var t2 = 3 * t1 * t1;
2332 var t3 = t1 * t1 * t1;
2333
2334 function labConvert(o) {
2335   if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity);
2336   if (o instanceof Hcl) {
2337     var h = o.h * deg2rad;
2338     return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity);
2339   }
2340   if (!(o instanceof Rgb)) o = rgbConvert(o);
2341   var b = rgb2xyz(o.r),
2342       a = rgb2xyz(o.g),
2343       l = rgb2xyz(o.b),
2344       x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn),
2345       y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn),
2346       z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn);
2347   return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity);
2348 }
2349
2350 function lab(l, a, b, opacity) {
2351   return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity);
2352 }
2353
2354 function Lab(l, a, b, opacity) {
2355   this.l = +l;
2356   this.a = +a;
2357   this.b = +b;
2358   this.opacity = +opacity;
2359 }
2360
2361 define(Lab, lab, extend(Color, {
2362   brighter: function(k) {
2363     return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);
2364   },
2365   darker: function(k) {
2366     return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity);
2367   },
2368   rgb: function() {
2369     var y = (this.l + 16) / 116,
2370         x = isNaN(this.a) ? y : y + this.a / 500,
2371         z = isNaN(this.b) ? y : y - this.b / 200;
2372     y = Yn * lab2xyz(y);
2373     x = Xn * lab2xyz(x);
2374     z = Zn * lab2xyz(z);
2375     return new Rgb(
2376       xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB
2377       xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z),
2378       xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z),
2379       this.opacity
2380     );
2381   }
2382 }));
2383
2384 function xyz2lab(t) {
2385   return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0;
2386 }
2387
2388 function lab2xyz(t) {
2389   return t > t1 ? t * t * t : t2 * (t - t0);
2390 }
2391
2392 function xyz2rgb(x) {
2393   return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055);
2394 }
2395
2396 function rgb2xyz(x) {
2397   return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
2398 }
2399
2400 function hclConvert(o) {
2401   if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity);
2402   if (!(o instanceof Lab)) o = labConvert(o);
2403   var h = Math.atan2(o.b, o.a) * rad2deg;
2404   return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity);
2405 }
2406
2407 function hcl(h, c, l, opacity) {
2408   return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity);
2409 }
2410
2411 function Hcl(h, c, l, opacity) {
2412   this.h = +h;
2413   this.c = +c;
2414   this.l = +l;
2415   this.opacity = +opacity;
2416 }
2417
2418 define(Hcl, hcl, extend(Color, {
2419   brighter: function(k) {
2420     return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity);
2421   },
2422   darker: function(k) {
2423     return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity);
2424   },
2425   rgb: function() {
2426     return labConvert(this).rgb();
2427   }
2428 }));
2429
2430 var A = -0.14861;
2431 var B = +1.78277;
2432 var C = -0.29227;
2433 var D = -0.90649;
2434 var E = +1.97294;
2435 var ED = E * D;
2436 var EB = E * B;
2437 var BC_DA = B * C - D * A;
2438
2439 function cubehelixConvert(o) {
2440   if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity);
2441   if (!(o instanceof Rgb)) o = rgbConvert(o);
2442   var r = o.r / 255,
2443       g = o.g / 255,
2444       b = o.b / 255,
2445       l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB),
2446       bl = b - l,
2447       k = (E * (g - l) - C * bl) / D,
2448       s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1
2449       h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN;
2450   return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity);
2451 }
2452
2453 function cubehelix(h, s, l, opacity) {
2454   return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity);
2455 }
2456
2457 function Cubehelix(h, s, l, opacity) {
2458   this.h = +h;
2459   this.s = +s;
2460   this.l = +l;
2461   this.opacity = +opacity;
2462 }
2463
2464 define(Cubehelix, cubehelix, extend(Color, {
2465   brighter: function(k) {
2466     k = k == null ? brighter : Math.pow(brighter, k);
2467     return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
2468   },
2469   darker: function(k) {
2470     k = k == null ? darker : Math.pow(darker, k);
2471     return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
2472   },
2473   rgb: function() {
2474     var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad,
2475         l = +this.l,
2476         a = isNaN(this.s) ? 0 : this.s * l * (1 - l),
2477         cosh = Math.cos(h),
2478         sinh = Math.sin(h);
2479     return new Rgb(
2480       255 * (l + a * (A * cosh + B * sinh)),
2481       255 * (l + a * (C * cosh + D * sinh)),
2482       255 * (l + a * (E * cosh)),
2483       this.opacity
2484     );
2485   }
2486 }));
2487
2488 function basis(t1, v0, v1, v2, v3) {
2489   var t2 = t1 * t1, t3 = t2 * t1;
2490   return ((1 - 3 * t1 + 3 * t2 - t3) * v0
2491       + (4 - 6 * t2 + 3 * t3) * v1
2492       + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2
2493       + t3 * v3) / 6;
2494 }
2495
2496 var basis$1 = function(values) {
2497   var n = values.length - 1;
2498   return function(t) {
2499     var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),
2500         v1 = values[i],
2501         v2 = values[i + 1],
2502         v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,
2503         v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;
2504     return basis((t - i / n) * n, v0, v1, v2, v3);
2505   };
2506 };
2507
2508 var basisClosed = function(values) {
2509   var n = values.length;
2510   return function(t) {
2511     var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),
2512         v0 = values[(i + n - 1) % n],
2513         v1 = values[i % n],
2514         v2 = values[(i + 1) % n],
2515         v3 = values[(i + 2) % n];
2516     return basis((t - i / n) * n, v0, v1, v2, v3);
2517   };
2518 };
2519
2520 var constant$3 = function(x) {
2521   return function() {
2522     return x;
2523   };
2524 };
2525
2526 function linear(a, d) {
2527   return function(t) {
2528     return a + t * d;
2529   };
2530 }
2531
2532 function exponential(a, b, y) {
2533   return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
2534     return Math.pow(a + t * b, y);
2535   };
2536 }
2537
2538 function hue(a, b) {
2539   var d = b - a;
2540   return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$3(isNaN(a) ? b : a);
2541 }
2542
2543 function gamma(y) {
2544   return (y = +y) === 1 ? nogamma : function(a, b) {
2545     return b - a ? exponential(a, b, y) : constant$3(isNaN(a) ? b : a);
2546   };
2547 }
2548
2549 function nogamma(a, b) {
2550   var d = b - a;
2551   return d ? linear(a, d) : constant$3(isNaN(a) ? b : a);
2552 }
2553
2554 var d3_interpolateRgb = (function rgbGamma(y) {
2555   var color$$1 = gamma(y);
2556
2557   function rgb$$1(start, end) {
2558     var r = color$$1((start = rgb(start)).r, (end = rgb(end)).r),
2559         g = color$$1(start.g, end.g),
2560         b = color$$1(start.b, end.b),
2561         opacity = nogamma(start.opacity, end.opacity);
2562     return function(t) {
2563       start.r = r(t);
2564       start.g = g(t);
2565       start.b = b(t);
2566       start.opacity = opacity(t);
2567       return start + "";
2568     };
2569   }
2570
2571   rgb$$1.gamma = rgbGamma;
2572
2573   return rgb$$1;
2574 })(1);
2575
2576 function rgbSpline(spline) {
2577   return function(colors) {
2578     var n = colors.length,
2579         r = new Array(n),
2580         g = new Array(n),
2581         b = new Array(n),
2582         i, color$$1;
2583     for (i = 0; i < n; ++i) {
2584       color$$1 = rgb(colors[i]);
2585       r[i] = color$$1.r || 0;
2586       g[i] = color$$1.g || 0;
2587       b[i] = color$$1.b || 0;
2588     }
2589     r = spline(r);
2590     g = spline(g);
2591     b = spline(b);
2592     color$$1.opacity = 1;
2593     return function(t) {
2594       color$$1.r = r(t);
2595       color$$1.g = g(t);
2596       color$$1.b = b(t);
2597       return color$$1 + "";
2598     };
2599   };
2600 }
2601
2602 var rgbBasis = rgbSpline(basis$1);
2603 var rgbBasisClosed = rgbSpline(basisClosed);
2604
2605 var array$1 = function(a, b) {
2606   var nb = b ? b.length : 0,
2607       na = a ? Math.min(nb, a.length) : 0,
2608       x = new Array(nb),
2609       c = new Array(nb),
2610       i;
2611
2612   for (i = 0; i < na; ++i) x[i] = d3_interpolate(a[i], b[i]);
2613   for (; i < nb; ++i) c[i] = b[i];
2614
2615   return function(t) {
2616     for (i = 0; i < na; ++i) c[i] = x[i](t);
2617     return c;
2618   };
2619 };
2620
2621 var date = function(a, b) {
2622   var d = new Date;
2623   return a = +a, b -= a, function(t) {
2624     return d.setTime(a + b * t), d;
2625   };
2626 };
2627
2628 var d3_interpolateNumber = function(a, b) {
2629   return a = +a, b -= a, function(t) {
2630     return a + b * t;
2631   };
2632 };
2633
2634 var object = function(a, b) {
2635   var i = {},
2636       c = {},
2637       k;
2638
2639   if (a === null || typeof a !== "object") a = {};
2640   if (b === null || typeof b !== "object") b = {};
2641
2642   for (k in b) {
2643     if (k in a) {
2644       i[k] = d3_interpolate(a[k], b[k]);
2645     } else {
2646       c[k] = b[k];
2647     }
2648   }
2649
2650   return function(t) {
2651     for (k in i) c[k] = i[k](t);
2652     return c;
2653   };
2654 };
2655
2656 var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;
2657 var reB = new RegExp(reA.source, "g");
2658
2659 function zero(b) {
2660   return function() {
2661     return b;
2662   };
2663 }
2664
2665 function one(b) {
2666   return function(t) {
2667     return b(t) + "";
2668   };
2669 }
2670
2671 var interpolateString = function(a, b) {
2672   var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b
2673       am, // current match in a
2674       bm, // current match in b
2675       bs, // string preceding current number in b, if any
2676       i = -1, // index in s
2677       s = [], // string constants and placeholders
2678       q = []; // number interpolators
2679
2680   // Coerce inputs to strings.
2681   a = a + "", b = b + "";
2682
2683   // Interpolate pairs of numbers in a & b.
2684   while ((am = reA.exec(a))
2685       && (bm = reB.exec(b))) {
2686     if ((bs = bm.index) > bi) { // a string precedes the next number in b
2687       bs = b.slice(bi, bs);
2688       if (s[i]) s[i] += bs; // coalesce with previous string
2689       else s[++i] = bs;
2690     }
2691     if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match
2692       if (s[i]) s[i] += bm; // coalesce with previous string
2693       else s[++i] = bm;
2694     } else { // interpolate non-matching numbers
2695       s[++i] = null;
2696       q.push({i: i, x: d3_interpolateNumber(am, bm)});
2697     }
2698     bi = reB.lastIndex;
2699   }
2700
2701   // Add remains of b.
2702   if (bi < b.length) {
2703     bs = b.slice(bi);
2704     if (s[i]) s[i] += bs; // coalesce with previous string
2705     else s[++i] = bs;
2706   }
2707
2708   // Special optimization for only a single match.
2709   // Otherwise, interpolate each of the numbers and rejoin the string.
2710   return s.length < 2 ? (q[0]
2711       ? one(q[0].x)
2712       : zero(b))
2713       : (b = q.length, function(t) {
2714           for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);
2715           return s.join("");
2716         });
2717 };
2718
2719 var d3_interpolate = function(a, b) {
2720   var t = typeof b, c;
2721   return b == null || t === "boolean" ? constant$3(b)
2722       : (t === "number" ? d3_interpolateNumber
2723       : t === "string" ? ((c = color(b)) ? (b = c, d3_interpolateRgb) : interpolateString)
2724       : b instanceof color ? d3_interpolateRgb
2725       : b instanceof Date ? date
2726       : Array.isArray(b) ? array$1
2727       : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object
2728       : d3_interpolateNumber)(a, b);
2729 };
2730
2731 var interpolateRound = function(a, b) {
2732   return a = +a, b -= a, function(t) {
2733     return Math.round(a + b * t);
2734   };
2735 };
2736
2737 var degrees = 180 / Math.PI;
2738
2739 var identity$2 = {
2740   translateX: 0,
2741   translateY: 0,
2742   rotate: 0,
2743   skewX: 0,
2744   scaleX: 1,
2745   scaleY: 1
2746 };
2747
2748 var decompose = function(a, b, c, d, e, f) {
2749   var scaleX, scaleY, skewX;
2750   if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;
2751   if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;
2752   if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;
2753   if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;
2754   return {
2755     translateX: e,
2756     translateY: f,
2757     rotate: Math.atan2(b, a) * degrees,
2758     skewX: Math.atan(skewX) * degrees,
2759     scaleX: scaleX,
2760     scaleY: scaleY
2761   };
2762 };
2763
2764 var cssNode;
2765 var cssRoot;
2766 var cssView;
2767 var svgNode;
2768
2769 function parseCss(value) {
2770   if (value === "none") return identity$2;
2771   if (!cssNode) cssNode = document.createElement("DIV"), cssRoot = document.documentElement, cssView = document.defaultView;
2772   cssNode.style.transform = value;
2773   value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue("transform");
2774   cssRoot.removeChild(cssNode);
2775   value = value.slice(7, -1).split(",");
2776   return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]);
2777 }
2778
2779 function parseSvg(value) {
2780   if (value == null) return identity$2;
2781   if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
2782   svgNode.setAttribute("transform", value);
2783   if (!(value = svgNode.transform.baseVal.consolidate())) return identity$2;
2784   value = value.matrix;
2785   return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
2786 }
2787
2788 function interpolateTransform(parse, pxComma, pxParen, degParen) {
2789
2790   function pop(s) {
2791     return s.length ? s.pop() + " " : "";
2792   }
2793
2794   function translate(xa, ya, xb, yb, s, q) {
2795     if (xa !== xb || ya !== yb) {
2796       var i = s.push("translate(", null, pxComma, null, pxParen);
2797       q.push({i: i - 4, x: d3_interpolateNumber(xa, xb)}, {i: i - 2, x: d3_interpolateNumber(ya, yb)});
2798     } else if (xb || yb) {
2799       s.push("translate(" + xb + pxComma + yb + pxParen);
2800     }
2801   }
2802
2803   function rotate(a, b, s, q) {
2804     if (a !== b) {
2805       if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path
2806       q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: d3_interpolateNumber(a, b)});
2807     } else if (b) {
2808       s.push(pop(s) + "rotate(" + b + degParen);
2809     }
2810   }
2811
2812   function skewX(a, b, s, q) {
2813     if (a !== b) {
2814       q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: d3_interpolateNumber(a, b)});
2815     } else if (b) {
2816       s.push(pop(s) + "skewX(" + b + degParen);
2817     }
2818   }
2819
2820   function scale(xa, ya, xb, yb, s, q) {
2821     if (xa !== xb || ya !== yb) {
2822       var i = s.push(pop(s) + "scale(", null, ",", null, ")");
2823       q.push({i: i - 4, x: d3_interpolateNumber(xa, xb)}, {i: i - 2, x: d3_interpolateNumber(ya, yb)});
2824     } else if (xb !== 1 || yb !== 1) {
2825       s.push(pop(s) + "scale(" + xb + "," + yb + ")");
2826     }
2827   }
2828
2829   return function(a, b) {
2830     var s = [], // string constants and placeholders
2831         q = []; // number interpolators
2832     a = parse(a), b = parse(b);
2833     translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);
2834     rotate(a.rotate, b.rotate, s, q);
2835     skewX(a.skewX, b.skewX, s, q);
2836     scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);
2837     a = b = null; // gc
2838     return function(t) {
2839       var i = -1, n = q.length, o;
2840       while (++i < n) s[(o = q[i]).i] = o.x(t);
2841       return s.join("");
2842     };
2843   };
2844 }
2845
2846 var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)");
2847 var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")");
2848
2849 var rho = Math.SQRT2;
2850 var rho2 = 2;
2851 var rho4 = 4;
2852 var epsilon2 = 1e-12;
2853
2854 function cosh(x) {
2855   return ((x = Math.exp(x)) + 1 / x) / 2;
2856 }
2857
2858 function sinh(x) {
2859   return ((x = Math.exp(x)) - 1 / x) / 2;
2860 }
2861
2862 function tanh(x) {
2863   return ((x = Math.exp(2 * x)) - 1) / (x + 1);
2864 }
2865
2866 // p0 = [ux0, uy0, w0]
2867 // p1 = [ux1, uy1, w1]
2868 var interpolateZoom = function(p0, p1) {
2869   var ux0 = p0[0], uy0 = p0[1], w0 = p0[2],
2870       ux1 = p1[0], uy1 = p1[1], w1 = p1[2],
2871       dx = ux1 - ux0,
2872       dy = uy1 - uy0,
2873       d2 = dx * dx + dy * dy,
2874       i,
2875       S;
2876
2877   // Special case for u0 ≅ u1.
2878   if (d2 < epsilon2) {
2879     S = Math.log(w1 / w0) / rho;
2880     i = function(t) {
2881       return [
2882         ux0 + t * dx,
2883         uy0 + t * dy,
2884         w0 * Math.exp(rho * t * S)
2885       ];
2886     };
2887   }
2888
2889   // General case.
2890   else {
2891     var d1 = Math.sqrt(d2),
2892         b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1),
2893         b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1),
2894         r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0),
2895         r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);
2896     S = (r1 - r0) / rho;
2897     i = function(t) {
2898       var s = t * S,
2899           coshr0 = cosh(r0),
2900           u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));
2901       return [
2902         ux0 + u * dx,
2903         uy0 + u * dy,
2904         w0 * coshr0 / cosh(rho * s + r0)
2905       ];
2906     };
2907   }
2908
2909   i.duration = S * 1000;
2910
2911   return i;
2912 };
2913
2914 function hsl$1(hue$$1) {
2915   return function(start, end) {
2916     var h = hue$$1((start = hsl(start)).h, (end = hsl(end)).h),
2917         s = nogamma(start.s, end.s),
2918         l = nogamma(start.l, end.l),
2919         opacity = nogamma(start.opacity, end.opacity);
2920     return function(t) {
2921       start.h = h(t);
2922       start.s = s(t);
2923       start.l = l(t);
2924       start.opacity = opacity(t);
2925       return start + "";
2926     };
2927   }
2928 }
2929
2930 var hsl$2 = hsl$1(hue);
2931 var hslLong = hsl$1(nogamma);
2932
2933 function lab$1(start, end) {
2934   var l = nogamma((start = lab(start)).l, (end = lab(end)).l),
2935       a = nogamma(start.a, end.a),
2936       b = nogamma(start.b, end.b),
2937       opacity = nogamma(start.opacity, end.opacity);
2938   return function(t) {
2939     start.l = l(t);
2940     start.a = a(t);
2941     start.b = b(t);
2942     start.opacity = opacity(t);
2943     return start + "";
2944   };
2945 }
2946
2947 function hcl$1(hue$$1) {
2948   return function(start, end) {
2949     var h = hue$$1((start = hcl(start)).h, (end = hcl(end)).h),
2950         c = nogamma(start.c, end.c),
2951         l = nogamma(start.l, end.l),
2952         opacity = nogamma(start.opacity, end.opacity);
2953     return function(t) {
2954       start.h = h(t);
2955       start.c = c(t);
2956       start.l = l(t);
2957       start.opacity = opacity(t);
2958       return start + "";
2959     };
2960   }
2961 }
2962
2963 var hcl$2 = hcl$1(hue);
2964 var hclLong = hcl$1(nogamma);
2965
2966 function cubehelix$1(hue$$1) {
2967   return (function cubehelixGamma(y) {
2968     y = +y;
2969
2970     function cubehelix$$1(start, end) {
2971       var h = hue$$1((start = cubehelix(start)).h, (end = cubehelix(end)).h),
2972           s = nogamma(start.s, end.s),
2973           l = nogamma(start.l, end.l),
2974           opacity = nogamma(start.opacity, end.opacity);
2975       return function(t) {
2976         start.h = h(t);
2977         start.s = s(t);
2978         start.l = l(Math.pow(t, y));
2979         start.opacity = opacity(t);
2980         return start + "";
2981       };
2982     }
2983
2984     cubehelix$$1.gamma = cubehelixGamma;
2985
2986     return cubehelix$$1;
2987   })(1);
2988 }
2989
2990 var cubehelix$2 = cubehelix$1(hue);
2991 var cubehelixLong = cubehelix$1(nogamma);
2992
2993 var d3_quantize = function(interpolator, n) {
2994   var samples = new Array(n);
2995   for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1));
2996   return samples;
2997 };
2998
2999 var frame = 0;
3000 var timeout = 0;
3001 var interval = 0;
3002 var pokeDelay = 1000;
3003 var taskHead;
3004 var taskTail;
3005 var clockLast = 0;
3006 var clockNow = 0;
3007 var clockSkew = 0;
3008 var clock = typeof performance === "object" && performance.now ? performance : Date;
3009 var setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); };
3010
3011 function now() {
3012   return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);
3013 }
3014
3015 function clearNow() {
3016   clockNow = 0;
3017 }
3018
3019 function Timer() {
3020   this._call =
3021   this._time =
3022   this._next = null;
3023 }
3024
3025 Timer.prototype = timer.prototype = {
3026   constructor: Timer,
3027   restart: function(callback, delay, time) {
3028     if (typeof callback !== "function") throw new TypeError("callback is not a function");
3029     time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);
3030     if (!this._next && taskTail !== this) {
3031       if (taskTail) taskTail._next = this;
3032       else taskHead = this;
3033       taskTail = this;
3034     }
3035     this._call = callback;
3036     this._time = time;
3037     sleep();
3038   },
3039   stop: function() {
3040     if (this._call) {
3041       this._call = null;
3042       this._time = Infinity;
3043       sleep();
3044     }
3045   }
3046 };
3047
3048 function timer(callback, delay, time) {
3049   var t = new Timer;
3050   t.restart(callback, delay, time);
3051   return t;
3052 }
3053
3054 function timerFlush() {
3055   now(); // Get the current time, if not already set.
3056   ++frame; // Pretend we’ve set an alarm, if we haven’t already.
3057   var t = taskHead, e;
3058   while (t) {
3059     if ((e = clockNow - t._time) >= 0) t._call.call(null, e);
3060     t = t._next;
3061   }
3062   --frame;
3063 }
3064
3065 function wake() {
3066   clockNow = (clockLast = clock.now()) + clockSkew;
3067   frame = timeout = 0;
3068   try {
3069     timerFlush();
3070   } finally {
3071     frame = 0;
3072     nap();
3073     clockNow = 0;
3074   }
3075 }
3076
3077 function poke() {
3078   var now = clock.now(), delay = now - clockLast;
3079   if (delay > pokeDelay) clockSkew -= delay, clockLast = now;
3080 }
3081
3082 function nap() {
3083   var t0, t1 = taskHead, t2, time = Infinity;
3084   while (t1) {
3085     if (t1._call) {
3086       if (time > t1._time) time = t1._time;
3087       t0 = t1, t1 = t1._next;
3088     } else {
3089       t2 = t1._next, t1._next = null;
3090       t1 = t0 ? t0._next = t2 : taskHead = t2;
3091     }
3092   }
3093   taskTail = t0;
3094   sleep(time);
3095 }
3096
3097 function sleep(time) {
3098   if (frame) return; // Soonest alarm already set, or will be.
3099   if (timeout) timeout = clearTimeout(timeout);
3100   var delay = time - clockNow; // Strictly less than if we recomputed clockNow.
3101   if (delay > 24) {
3102     if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew);
3103     if (interval) interval = clearInterval(interval);
3104   } else {
3105     if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay);
3106     frame = 1, setFrame(wake);
3107   }
3108 }
3109
3110 var d3_timeout = function(callback, delay, time) {
3111   var t = new Timer;
3112   delay = delay == null ? 0 : +delay;
3113   t.restart(function(elapsed) {
3114     t.stop();
3115     callback(elapsed + delay);
3116   }, delay, time);
3117   return t;
3118 };
3119
3120 var interval$1 = function(callback, delay, time) {
3121   var t = new Timer, total = delay;
3122   if (delay == null) return t.restart(callback, delay, time), t;
3123   delay = +delay, time = time == null ? now() : +time;
3124   t.restart(function tick(elapsed) {
3125     elapsed += total;
3126     t.restart(tick, total += delay, time);
3127     callback(elapsed);
3128   }, delay, time);
3129   return t;
3130 };
3131
3132 var emptyOn = dispatch("start", "end", "interrupt");
3133 var emptyTween = [];
3134
3135 var CREATED = 0;
3136 var SCHEDULED = 1;
3137 var STARTING = 2;
3138 var STARTED = 3;
3139 var RUNNING = 4;
3140 var ENDING = 5;
3141 var ENDED = 6;
3142
3143 var schedule = function(node, name, id, index, group, timing) {
3144   var schedules = node.__transition;
3145   if (!schedules) node.__transition = {};
3146   else if (id in schedules) return;
3147   create(node, id, {
3148     name: name,
3149     index: index, // For context during callback.
3150     group: group, // For context during callback.
3151     on: emptyOn,
3152     tween: emptyTween,
3153     time: timing.time,
3154     delay: timing.delay,
3155     duration: timing.duration,
3156     ease: timing.ease,
3157     timer: null,
3158     state: CREATED
3159   });
3160 };
3161
3162 function init(node, id) {
3163   var schedule = node.__transition;
3164   if (!schedule || !(schedule = schedule[id]) || schedule.state > CREATED) throw new Error("too late");
3165   return schedule;
3166 }
3167
3168 function set$1(node, id) {
3169   var schedule = node.__transition;
3170   if (!schedule || !(schedule = schedule[id]) || schedule.state > STARTING) throw new Error("too late");
3171   return schedule;
3172 }
3173
3174 function get$1(node, id) {
3175   var schedule = node.__transition;
3176   if (!schedule || !(schedule = schedule[id])) throw new Error("too late");
3177   return schedule;
3178 }
3179
3180 function create(node, id, self) {
3181   var schedules = node.__transition,
3182       tween;
3183
3184   // Initialize the self timer when the transition is created.
3185   // Note the actual delay is not known until the first callback!
3186   schedules[id] = self;
3187   self.timer = timer(schedule, 0, self.time);
3188
3189   function schedule(elapsed) {
3190     self.state = SCHEDULED;
3191     self.timer.restart(start, self.delay, self.time);
3192
3193     // If the elapsed delay is less than our first sleep, start immediately.
3194     if (self.delay <= elapsed) start(elapsed - self.delay);
3195   }
3196
3197   function start(elapsed) {
3198     var i, j, n, o;
3199
3200     // If the state is not SCHEDULED, then we previously errored on start.
3201     if (self.state !== SCHEDULED) return stop();
3202
3203     for (i in schedules) {
3204       o = schedules[i];
3205       if (o.name !== self.name) continue;
3206
3207       // While this element already has a starting transition during this frame,
3208       // defer starting an interrupting transition until that transition has a
3209       // chance to tick (and possibly end); see d3/d3-transition#54!
3210       if (o.state === STARTED) return d3_timeout(start);
3211
3212       // Interrupt the active transition, if any.
3213       // Dispatch the interrupt event.
3214       if (o.state === RUNNING) {
3215         o.state = ENDED;
3216         o.timer.stop();
3217         o.on.call("interrupt", node, node.__data__, o.index, o.group);
3218         delete schedules[i];
3219       }
3220
3221       // Cancel any pre-empted transitions. No interrupt event is dispatched
3222       // because the cancelled transitions never started. Note that this also
3223       // removes this transition from the pending list!
3224       else if (+i < id) {
3225         o.state = ENDED;
3226         o.timer.stop();
3227         delete schedules[i];
3228       }
3229     }
3230
3231     // Defer the first tick to end of the current frame; see d3/d3#1576.
3232     // Note the transition may be canceled after start and before the first tick!
3233     // Note this must be scheduled before the start event; see d3/d3-transition#16!
3234     // Assuming this is successful, subsequent callbacks go straight to tick.
3235     d3_timeout(function() {
3236       if (self.state === STARTED) {
3237         self.state = RUNNING;
3238         self.timer.restart(tick, self.delay, self.time);
3239         tick(elapsed);
3240       }
3241     });
3242
3243     // Dispatch the start event.
3244     // Note this must be done before the tween are initialized.
3245     self.state = STARTING;
3246     self.on.call("start", node, node.__data__, self.index, self.group);
3247     if (self.state !== STARTING) return; // interrupted
3248     self.state = STARTED;
3249
3250     // Initialize the tween, deleting null tween.
3251     tween = new Array(n = self.tween.length);
3252     for (i = 0, j = -1; i < n; ++i) {
3253       if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) {
3254         tween[++j] = o;
3255       }
3256     }
3257     tween.length = j + 1;
3258   }
3259
3260   function tick(elapsed) {
3261     var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1),
3262         i = -1,
3263         n = tween.length;
3264
3265     while (++i < n) {
3266       tween[i].call(null, t);
3267     }
3268
3269     // Dispatch the end event.
3270     if (self.state === ENDING) {
3271       self.on.call("end", node, node.__data__, self.index, self.group);
3272       stop();
3273     }
3274   }
3275
3276   function stop() {
3277     self.state = ENDED;
3278     self.timer.stop();
3279     delete schedules[id];
3280     for (var i in schedules) return; // eslint-disable-line no-unused-vars
3281     delete node.__transition;
3282   }
3283 }
3284
3285 var interrupt = function(node, name) {
3286   var schedules = node.__transition,
3287       schedule$$1,
3288       active,
3289       empty = true,
3290       i;
3291
3292   if (!schedules) return;
3293
3294   name = name == null ? null : name + "";
3295
3296   for (i in schedules) {
3297     if ((schedule$$1 = schedules[i]).name !== name) { empty = false; continue; }
3298     active = schedule$$1.state > STARTING && schedule$$1.state < ENDING;
3299     schedule$$1.state = ENDED;
3300     schedule$$1.timer.stop();
3301     if (active) schedule$$1.on.call("interrupt", node, node.__data__, schedule$$1.index, schedule$$1.group);
3302     delete schedules[i];
3303   }
3304
3305   if (empty) delete node.__transition;
3306 };
3307
3308 var selection_interrupt = function(name) {
3309   return this.each(function() {
3310     interrupt(this, name);
3311   });
3312 };
3313
3314 function tweenRemove(id, name) {
3315   var tween0, tween1;
3316   return function() {
3317     var schedule$$1 = set$1(this, id),
3318         tween = schedule$$1.tween;
3319
3320     // If this node shared tween with the previous node,
3321     // just assign the updated shared tween and we’re done!
3322     // Otherwise, copy-on-write.
3323     if (tween !== tween0) {
3324       tween1 = tween0 = tween;
3325       for (var i = 0, n = tween1.length; i < n; ++i) {
3326         if (tween1[i].name === name) {
3327           tween1 = tween1.slice();
3328           tween1.splice(i, 1);
3329           break;
3330         }
3331       }
3332     }
3333
3334     schedule$$1.tween = tween1;
3335   };
3336 }
3337
3338 function tweenFunction(id, name, value) {
3339   var tween0, tween1;
3340   if (typeof value !== "function") throw new Error;
3341   return function() {
3342     var schedule$$1 = set$1(this, id),
3343         tween = schedule$$1.tween;
3344
3345     // If this node shared tween with the previous node,
3346     // just assign the updated shared tween and we’re done!
3347     // Otherwise, copy-on-write.
3348     if (tween !== tween0) {
3349       tween1 = (tween0 = tween).slice();
3350       for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) {
3351         if (tween1[i].name === name) {
3352           tween1[i] = t;
3353           break;
3354         }
3355       }
3356       if (i === n) tween1.push(t);
3357     }
3358
3359     schedule$$1.tween = tween1;
3360   };
3361 }
3362
3363 var transition_tween = function(name, value) {
3364   var id = this._id;
3365
3366   name += "";
3367
3368   if (arguments.length < 2) {
3369     var tween = get$1(this.node(), id).tween;
3370     for (var i = 0, n = tween.length, t; i < n; ++i) {
3371       if ((t = tween[i]).name === name) {
3372         return t.value;
3373       }
3374     }
3375     return null;
3376   }
3377
3378   return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value));
3379 };
3380
3381 function tweenValue(transition, name, value) {
3382   var id = transition._id;
3383
3384   transition.each(function() {
3385     var schedule$$1 = set$1(this, id);
3386     (schedule$$1.value || (schedule$$1.value = {}))[name] = value.apply(this, arguments);
3387   });
3388
3389   return function(node) {
3390     return get$1(node, id).value[name];
3391   };
3392 }
3393
3394 var interpolate = function(a, b) {
3395   var c;
3396   return (typeof b === "number" ? d3_interpolateNumber
3397       : b instanceof color ? d3_interpolateRgb
3398       : (c = color(b)) ? (b = c, d3_interpolateRgb)
3399       : interpolateString)(a, b);
3400 };
3401
3402 function attrRemove$1(name) {
3403   return function() {
3404     this.removeAttribute(name);
3405   };
3406 }
3407
3408 function attrRemoveNS$1(fullname) {
3409   return function() {
3410     this.removeAttributeNS(fullname.space, fullname.local);
3411   };
3412 }
3413
3414 function attrConstant$1(name, interpolate$$1, value1) {
3415   var value00,
3416       interpolate0;
3417   return function() {
3418     var value0 = this.getAttribute(name);
3419     return value0 === value1 ? null
3420         : value0 === value00 ? interpolate0
3421         : interpolate0 = interpolate$$1(value00 = value0, value1);
3422   };
3423 }
3424
3425 function attrConstantNS$1(fullname, interpolate$$1, value1) {
3426   var value00,
3427       interpolate0;
3428   return function() {
3429     var value0 = this.getAttributeNS(fullname.space, fullname.local);
3430     return value0 === value1 ? null
3431         : value0 === value00 ? interpolate0
3432         : interpolate0 = interpolate$$1(value00 = value0, value1);
3433   };
3434 }
3435
3436 function attrFunction$1(name, interpolate$$1, value) {
3437   var value00,
3438       value10,
3439       interpolate0;
3440   return function() {
3441     var value0, value1 = value(this);
3442     if (value1 == null) return void this.removeAttribute(name);
3443     value0 = this.getAttribute(name);
3444     return value0 === value1 ? null
3445         : value0 === value00 && value1 === value10 ? interpolate0
3446         : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
3447   };
3448 }
3449
3450 function attrFunctionNS$1(fullname, interpolate$$1, value) {
3451   var value00,
3452       value10,
3453       interpolate0;
3454   return function() {
3455     var value0, value1 = value(this);
3456     if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local);
3457     value0 = this.getAttributeNS(fullname.space, fullname.local);
3458     return value0 === value1 ? null
3459         : value0 === value00 && value1 === value10 ? interpolate0
3460         : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
3461   };
3462 }
3463
3464 var transition_attr = function(name, value) {
3465   var fullname = namespace(name), i = fullname === "transform" ? interpolateTransformSvg : interpolate;
3466   return this.attrTween(name, typeof value === "function"
3467       ? (fullname.local ? attrFunctionNS$1 : attrFunction$1)(fullname, i, tweenValue(this, "attr." + name, value))
3468       : value == null ? (fullname.local ? attrRemoveNS$1 : attrRemove$1)(fullname)
3469       : (fullname.local ? attrConstantNS$1 : attrConstant$1)(fullname, i, value + ""));
3470 };
3471
3472 function attrTweenNS(fullname, value) {
3473   function tween() {
3474     var node = this, i = value.apply(node, arguments);
3475     return i && function(t) {
3476       node.setAttributeNS(fullname.space, fullname.local, i(t));
3477     };
3478   }
3479   tween._value = value;
3480   return tween;
3481 }
3482
3483 function attrTween(name, value) {
3484   function tween() {
3485     var node = this, i = value.apply(node, arguments);
3486     return i && function(t) {
3487       node.setAttribute(name, i(t));
3488     };
3489   }
3490   tween._value = value;
3491   return tween;
3492 }
3493
3494 var transition_attrTween = function(name, value) {
3495   var key = "attr." + name;
3496   if (arguments.length < 2) return (key = this.tween(key)) && key._value;
3497   if (value == null) return this.tween(key, null);
3498   if (typeof value !== "function") throw new Error;
3499   var fullname = namespace(name);
3500   return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));
3501 };
3502
3503 function delayFunction(id, value) {
3504   return function() {
3505     init(this, id).delay = +value.apply(this, arguments);
3506   };
3507 }
3508
3509 function delayConstant(id, value) {
3510   return value = +value, function() {
3511     init(this, id).delay = value;
3512   };
3513 }
3514
3515 var transition_delay = function(value) {
3516   var id = this._id;
3517
3518   return arguments.length
3519       ? this.each((typeof value === "function"
3520           ? delayFunction
3521           : delayConstant)(id, value))
3522       : get$1(this.node(), id).delay;
3523 };
3524
3525 function durationFunction(id, value) {
3526   return function() {
3527     set$1(this, id).duration = +value.apply(this, arguments);
3528   };
3529 }
3530
3531 function durationConstant(id, value) {
3532   return value = +value, function() {
3533     set$1(this, id).duration = value;
3534   };
3535 }
3536
3537 var transition_duration = function(value) {
3538   var id = this._id;
3539
3540   return arguments.length
3541       ? this.each((typeof value === "function"
3542           ? durationFunction
3543           : durationConstant)(id, value))
3544       : get$1(this.node(), id).duration;
3545 };
3546
3547 function easeConstant(id, value) {
3548   if (typeof value !== "function") throw new Error;
3549   return function() {
3550     set$1(this, id).ease = value;
3551   };
3552 }
3553
3554 var transition_ease = function(value) {
3555   var id = this._id;
3556
3557   return arguments.length
3558       ? this.each(easeConstant(id, value))
3559       : get$1(this.node(), id).ease;
3560 };
3561
3562 var transition_filter = function(match) {
3563   if (typeof match !== "function") match = matcher$1(match);
3564
3565   for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
3566     for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
3567       if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
3568         subgroup.push(node);
3569       }
3570     }
3571   }
3572
3573   return new Transition(subgroups, this._parents, this._name, this._id);
3574 };
3575
3576 var transition_merge = function(transition$$1) {
3577   if (transition$$1._id !== this._id) throw new Error;
3578
3579   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) {
3580     for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
3581       if (node = group0[i] || group1[i]) {
3582         merge[i] = node;
3583       }
3584     }
3585   }
3586
3587   for (; j < m0; ++j) {
3588     merges[j] = groups0[j];
3589   }
3590
3591   return new Transition(merges, this._parents, this._name, this._id);
3592 };
3593
3594 function start(name) {
3595   return (name + "").trim().split(/^|\s+/).every(function(t) {
3596     var i = t.indexOf(".");
3597     if (i >= 0) t = t.slice(0, i);
3598     return !t || t === "start";
3599   });
3600 }
3601
3602 function onFunction(id, name, listener) {
3603   var on0, on1, sit = start(name) ? init : set$1;
3604   return function() {
3605     var schedule$$1 = sit(this, id),
3606         on = schedule$$1.on;
3607
3608     // If this node shared a dispatch with the previous node,
3609     // just assign the updated shared dispatch and we’re done!
3610     // Otherwise, copy-on-write.
3611     if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener);
3612
3613     schedule$$1.on = on1;
3614   };
3615 }
3616
3617 var transition_on = function(name, listener) {
3618   var id = this._id;
3619
3620   return arguments.length < 2
3621       ? get$1(this.node(), id).on.on(name)
3622       : this.each(onFunction(id, name, listener));
3623 };
3624
3625 function removeFunction(id) {
3626   return function() {
3627     var parent = this.parentNode;
3628     for (var i in this.__transition) if (+i !== id) return;
3629     if (parent) parent.removeChild(this);
3630   };
3631 }
3632
3633 var transition_remove = function() {
3634   return this.on("end.remove", removeFunction(this._id));
3635 };
3636
3637 var transition_select = function(select) {
3638   var name = this._name,
3639       id = this._id;
3640
3641   if (typeof select !== "function") select = selector(select);
3642
3643   for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
3644     for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
3645       if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
3646         if ("__data__" in node) subnode.__data__ = node.__data__;
3647         subgroup[i] = subnode;
3648         schedule(subgroup[i], name, id, i, subgroup, get$1(node, id));
3649       }
3650     }
3651   }
3652
3653   return new Transition(subgroups, this._parents, name, id);
3654 };
3655
3656 var transition_selectAll = function(select) {
3657   var name = this._name,
3658       id = this._id;
3659
3660   if (typeof select !== "function") select = selectorAll(select);
3661
3662   for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
3663     for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
3664       if (node = group[i]) {
3665         for (var children = select.call(node, node.__data__, i, group), child, inherit = get$1(node, id), k = 0, l = children.length; k < l; ++k) {
3666           if (child = children[k]) {
3667             schedule(child, name, id, k, children, inherit);
3668           }
3669         }
3670         subgroups.push(children);
3671         parents.push(node);
3672       }
3673     }
3674   }
3675
3676   return new Transition(subgroups, parents, name, id);
3677 };
3678
3679 var Selection$1 = selection.prototype.constructor;
3680
3681 var transition_selection = function() {
3682   return new Selection$1(this._groups, this._parents);
3683 };
3684
3685 function styleRemove$1(name, interpolate$$1) {
3686   var value00,
3687       value10,
3688       interpolate0;
3689   return function() {
3690     var value0 = styleValue(this, name),
3691         value1 = (this.style.removeProperty(name), styleValue(this, name));
3692     return value0 === value1 ? null
3693         : value0 === value00 && value1 === value10 ? interpolate0
3694         : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
3695   };
3696 }
3697
3698 function styleRemoveEnd(name) {
3699   return function() {
3700     this.style.removeProperty(name);
3701   };
3702 }
3703
3704 function styleConstant$1(name, interpolate$$1, value1) {
3705   var value00,
3706       interpolate0;
3707   return function() {
3708     var value0 = styleValue(this, name);
3709     return value0 === value1 ? null
3710         : value0 === value00 ? interpolate0
3711         : interpolate0 = interpolate$$1(value00 = value0, value1);
3712   };
3713 }
3714
3715 function styleFunction$1(name, interpolate$$1, value) {
3716   var value00,
3717       value10,
3718       interpolate0;
3719   return function() {
3720     var value0 = styleValue(this, name),
3721         value1 = value(this);
3722     if (value1 == null) value1 = (this.style.removeProperty(name), styleValue(this, name));
3723     return value0 === value1 ? null
3724         : value0 === value00 && value1 === value10 ? interpolate0
3725         : interpolate0 = interpolate$$1(value00 = value0, value10 = value1);
3726   };
3727 }
3728
3729 var transition_style = function(name, value, priority) {
3730   var i = (name += "") === "transform" ? interpolateTransformCss : interpolate;
3731   return value == null ? this
3732           .styleTween(name, styleRemove$1(name, i))
3733           .on("end.style." + name, styleRemoveEnd(name))
3734       : this.styleTween(name, typeof value === "function"
3735           ? styleFunction$1(name, i, tweenValue(this, "style." + name, value))
3736           : styleConstant$1(name, i, value + ""), priority);
3737 };
3738
3739 function styleTween(name, value, priority) {
3740   function tween() {
3741     var node = this, i = value.apply(node, arguments);
3742     return i && function(t) {
3743       node.style.setProperty(name, i(t), priority);
3744     };
3745   }
3746   tween._value = value;
3747   return tween;
3748 }
3749
3750 var transition_styleTween = function(name, value, priority) {
3751   var key = "style." + (name += "");
3752   if (arguments.length < 2) return (key = this.tween(key)) && key._value;
3753   if (value == null) return this.tween(key, null);
3754   if (typeof value !== "function") throw new Error;
3755   return this.tween(key, styleTween(name, value, priority == null ? "" : priority));
3756 };
3757
3758 function textConstant$1(value) {
3759   return function() {
3760     this.textContent = value;
3761   };
3762 }
3763
3764 function textFunction$1(value) {
3765   return function() {
3766     var value1 = value(this);
3767     this.textContent = value1 == null ? "" : value1;
3768   };
3769 }
3770
3771 var transition_text = function(value) {
3772   return this.tween("text", typeof value === "function"
3773       ? textFunction$1(tweenValue(this, "text", value))
3774       : textConstant$1(value == null ? "" : value + ""));
3775 };
3776
3777 var transition_transition = function() {
3778   var name = this._name,
3779       id0 = this._id,
3780       id1 = newId();
3781
3782   for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
3783     for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
3784       if (node = group[i]) {
3785         var inherit = get$1(node, id0);
3786         schedule(node, name, id1, i, group, {
3787           time: inherit.time + inherit.delay + inherit.duration,
3788           delay: 0,
3789           duration: inherit.duration,
3790           ease: inherit.ease
3791         });
3792       }
3793     }
3794   }
3795
3796   return new Transition(groups, this._parents, name, id1);
3797 };
3798
3799 var id = 0;
3800
3801 function Transition(groups, parents, name, id) {
3802   this._groups = groups;
3803   this._parents = parents;
3804   this._name = name;
3805   this._id = id;
3806 }
3807
3808 function transition(name) {
3809   return selection().transition(name);
3810 }
3811
3812 function newId() {
3813   return ++id;
3814 }
3815
3816 var selection_prototype = selection.prototype;
3817
3818 Transition.prototype = transition.prototype = {
3819   constructor: Transition,
3820   select: transition_select,
3821   selectAll: transition_selectAll,
3822   filter: transition_filter,
3823   merge: transition_merge,
3824   selection: transition_selection,
3825   transition: transition_transition,
3826   call: selection_prototype.call,
3827   nodes: selection_prototype.nodes,
3828   node: selection_prototype.node,
3829   size: selection_prototype.size,
3830   empty: selection_prototype.empty,
3831   each: selection_prototype.each,
3832   on: transition_on,
3833   attr: transition_attr,
3834   attrTween: transition_attrTween,
3835   style: transition_style,
3836   styleTween: transition_styleTween,
3837   text: transition_text,
3838   remove: transition_remove,
3839   tween: transition_tween,
3840   delay: transition_delay,
3841   duration: transition_duration,
3842   ease: transition_ease
3843 };
3844
3845 function linear$1(t) {
3846   return +t;
3847 }
3848
3849 function quadIn(t) {
3850   return t * t;
3851 }
3852
3853 function quadOut(t) {
3854   return t * (2 - t);
3855 }
3856
3857 function quadInOut(t) {
3858   return ((t *= 2) <= 1 ? t * t : --t * (2 - t) + 1) / 2;
3859 }
3860
3861 function cubicIn(t) {
3862   return t * t * t;
3863 }
3864
3865 function cubicOut(t) {
3866   return --t * t * t + 1;
3867 }
3868
3869 function cubicInOut(t) {
3870   return ((t *= 2) <= 1 ? t * t * t : (t -= 2) * t * t + 2) / 2;
3871 }
3872
3873 var exponent = 3;
3874
3875 var polyIn = (function custom(e) {
3876   e = +e;
3877
3878   function polyIn(t) {
3879     return Math.pow(t, e);
3880   }
3881
3882   polyIn.exponent = custom;
3883
3884   return polyIn;
3885 })(exponent);
3886
3887 var polyOut = (function custom(e) {
3888   e = +e;
3889
3890   function polyOut(t) {
3891     return 1 - Math.pow(1 - t, e);
3892   }
3893
3894   polyOut.exponent = custom;
3895
3896   return polyOut;
3897 })(exponent);
3898
3899 var polyInOut = (function custom(e) {
3900   e = +e;
3901
3902   function polyInOut(t) {
3903     return ((t *= 2) <= 1 ? Math.pow(t, e) : 2 - Math.pow(2 - t, e)) / 2;
3904   }
3905
3906   polyInOut.exponent = custom;
3907
3908   return polyInOut;
3909 })(exponent);
3910
3911 var pi = Math.PI;
3912 var halfPi = pi / 2;
3913
3914 function sinIn(t) {
3915   return 1 - Math.cos(t * halfPi);
3916 }
3917
3918 function sinOut(t) {
3919   return Math.sin(t * halfPi);
3920 }
3921
3922 function sinInOut(t) {
3923   return (1 - Math.cos(pi * t)) / 2;
3924 }
3925
3926 function expIn(t) {
3927   return Math.pow(2, 10 * t - 10);
3928 }
3929
3930 function expOut(t) {
3931   return 1 - Math.pow(2, -10 * t);
3932 }
3933
3934 function expInOut(t) {
3935   return ((t *= 2) <= 1 ? Math.pow(2, 10 * t - 10) : 2 - Math.pow(2, 10 - 10 * t)) / 2;
3936 }
3937
3938 function circleIn(t) {
3939   return 1 - Math.sqrt(1 - t * t);
3940 }
3941
3942 function circleOut(t) {
3943   return Math.sqrt(1 - --t * t);
3944 }
3945
3946 function circleInOut(t) {
3947   return ((t *= 2) <= 1 ? 1 - Math.sqrt(1 - t * t) : Math.sqrt(1 - (t -= 2) * t) + 1) / 2;
3948 }
3949
3950 var b1 = 4 / 11;
3951 var b2 = 6 / 11;
3952 var b3 = 8 / 11;
3953 var b4 = 3 / 4;
3954 var b5 = 9 / 11;
3955 var b6 = 10 / 11;
3956 var b7 = 15 / 16;
3957 var b8 = 21 / 22;
3958 var b9 = 63 / 64;
3959 var b0 = 1 / b1 / b1;
3960
3961 function bounceIn(t) {
3962   return 1 - bounceOut(1 - t);
3963 }
3964
3965 function bounceOut(t) {
3966   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;
3967 }
3968
3969 function bounceInOut(t) {
3970   return ((t *= 2) <= 1 ? 1 - bounceOut(1 - t) : bounceOut(t - 1) + 1) / 2;
3971 }
3972
3973 var overshoot = 1.70158;
3974
3975 var backIn = (function custom(s) {
3976   s = +s;
3977
3978   function backIn(t) {
3979     return t * t * ((s + 1) * t - s);
3980   }
3981
3982   backIn.overshoot = custom;
3983
3984   return backIn;
3985 })(overshoot);
3986
3987 var backOut = (function custom(s) {
3988   s = +s;
3989
3990   function backOut(t) {
3991     return --t * t * ((s + 1) * t + s) + 1;
3992   }
3993
3994   backOut.overshoot = custom;
3995
3996   return backOut;
3997 })(overshoot);
3998
3999 var backInOut = (function custom(s) {
4000   s = +s;
4001
4002   function backInOut(t) {
4003     return ((t *= 2) < 1 ? t * t * ((s + 1) * t - s) : (t -= 2) * t * ((s + 1) * t + s) + 2) / 2;
4004   }
4005
4006   backInOut.overshoot = custom;
4007
4008   return backInOut;
4009 })(overshoot);
4010
4011 var tau = 2 * Math.PI;
4012 var amplitude = 1;
4013 var period = 0.3;
4014
4015 var elasticIn = (function custom(a, p) {
4016   var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
4017
4018   function elasticIn(t) {
4019     return a * Math.pow(2, 10 * --t) * Math.sin((s - t) / p);
4020   }
4021
4022   elasticIn.amplitude = function(a) { return custom(a, p * tau); };
4023   elasticIn.period = function(p) { return custom(a, p); };
4024
4025   return elasticIn;
4026 })(amplitude, period);
4027
4028 var elasticOut = (function custom(a, p) {
4029   var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
4030
4031   function elasticOut(t) {
4032     return 1 - a * Math.pow(2, -10 * (t = +t)) * Math.sin((t + s) / p);
4033   }
4034
4035   elasticOut.amplitude = function(a) { return custom(a, p * tau); };
4036   elasticOut.period = function(p) { return custom(a, p); };
4037
4038   return elasticOut;
4039 })(amplitude, period);
4040
4041 var elasticInOut = (function custom(a, p) {
4042   var s = Math.asin(1 / (a = Math.max(1, a))) * (p /= tau);
4043
4044   function elasticInOut(t) {
4045     return ((t = t * 2 - 1) < 0
4046         ? a * Math.pow(2, 10 * t) * Math.sin((s - t) / p)
4047         : 2 - a * Math.pow(2, -10 * t) * Math.sin((s + t) / p)) / 2;
4048   }
4049
4050   elasticInOut.amplitude = function(a) { return custom(a, p * tau); };
4051   elasticInOut.period = function(p) { return custom(a, p); };
4052
4053   return elasticInOut;
4054 })(amplitude, period);
4055
4056 var defaultTiming = {
4057   time: null, // Set on use.
4058   delay: 0,
4059   duration: 250,
4060   ease: cubicInOut
4061 };
4062
4063 function inherit(node, id) {
4064   var timing;
4065   while (!(timing = node.__transition) || !(timing = timing[id])) {
4066     if (!(node = node.parentNode)) {
4067       return defaultTiming.time = now(), defaultTiming;
4068     }
4069   }
4070   return timing;
4071 }
4072
4073 var selection_transition = function(name) {
4074   var id,
4075       timing;
4076
4077   if (name instanceof Transition) {
4078     id = name._id, name = name._name;
4079   } else {
4080     id = newId(), (timing = defaultTiming).time = now(), name = name == null ? null : name + "";
4081   }
4082
4083   for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
4084     for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
4085       if (node = group[i]) {
4086         schedule(node, name, id, i, group, timing || inherit(node, id));
4087       }
4088     }
4089   }
4090
4091   return new Transition(groups, this._parents, name, id);
4092 };
4093
4094 selection.prototype.interrupt = selection_interrupt;
4095 selection.prototype.transition = selection_transition;
4096
4097 var root$1 = [null];
4098
4099 var active = function(node, name) {
4100   var schedules = node.__transition,
4101       schedule$$1,
4102       i;
4103
4104   if (schedules) {
4105     name = name == null ? null : name + "";
4106     for (i in schedules) {
4107       if ((schedule$$1 = schedules[i]).state > SCHEDULED && schedule$$1.name === name) {
4108         return new Transition([[node]], root$1, name, +i);
4109       }
4110     }
4111   }
4112
4113   return null;
4114 };
4115
4116 var constant$4 = function(x) {
4117   return function() {
4118     return x;
4119   };
4120 };
4121
4122 var BrushEvent = function(target, type, selection) {
4123   this.target = target;
4124   this.type = type;
4125   this.selection = selection;
4126 };
4127
4128 function nopropagation$1() {
4129   event.stopImmediatePropagation();
4130 }
4131
4132 var noevent$1 = function() {
4133   event.preventDefault();
4134   event.stopImmediatePropagation();
4135 };
4136
4137 var MODE_DRAG = {name: "drag"};
4138 var MODE_SPACE = {name: "space"};
4139 var MODE_HANDLE = {name: "handle"};
4140 var MODE_CENTER = {name: "center"};
4141
4142 var X = {
4143   name: "x",
4144   handles: ["e", "w"].map(type),
4145   input: function(x, e) { return x && [[x[0], e[0][1]], [x[1], e[1][1]]]; },
4146   output: function(xy) { return xy && [xy[0][0], xy[1][0]]; }
4147 };
4148
4149 var Y = {
4150   name: "y",
4151   handles: ["n", "s"].map(type),
4152   input: function(y, e) { return y && [[e[0][0], y[0]], [e[1][0], y[1]]]; },
4153   output: function(xy) { return xy && [xy[0][1], xy[1][1]]; }
4154 };
4155
4156 var XY = {
4157   name: "xy",
4158   handles: ["n", "e", "s", "w", "nw", "ne", "se", "sw"].map(type),
4159   input: function(xy) { return xy; },
4160   output: function(xy) { return xy; }
4161 };
4162
4163 var cursors = {
4164   overlay: "crosshair",
4165   selection: "move",
4166   n: "ns-resize",
4167   e: "ew-resize",
4168   s: "ns-resize",
4169   w: "ew-resize",
4170   nw: "nwse-resize",
4171   ne: "nesw-resize",
4172   se: "nwse-resize",
4173   sw: "nesw-resize"
4174 };
4175
4176 var flipX = {
4177   e: "w",
4178   w: "e",
4179   nw: "ne",
4180   ne: "nw",
4181   se: "sw",
4182   sw: "se"
4183 };
4184
4185 var flipY = {
4186   n: "s",
4187   s: "n",
4188   nw: "sw",
4189   ne: "se",
4190   se: "ne",
4191   sw: "nw"
4192 };
4193
4194 var signsX = {
4195   overlay: +1,
4196   selection: +1,
4197   n: null,
4198   e: +1,
4199   s: null,
4200   w: -1,
4201   nw: -1,
4202   ne: +1,
4203   se: +1,
4204   sw: -1
4205 };
4206
4207 var signsY = {
4208   overlay: +1,
4209   selection: +1,
4210   n: -1,
4211   e: null,
4212   s: +1,
4213   w: null,
4214   nw: -1,
4215   ne: -1,
4216   se: +1,
4217   sw: +1
4218 };
4219
4220 function type(t) {
4221   return {type: t};
4222 }
4223
4224 // Ignore right-click, since that should open the context menu.
4225 function defaultFilter() {
4226   return !event.button;
4227 }
4228
4229 function defaultExtent() {
4230   var svg = this.ownerSVGElement || this;
4231   return [[0, 0], [svg.width.baseVal.value, svg.height.baseVal.value]];
4232 }
4233
4234 // Like d3.local, but with the name “__brush” rather than auto-generated.
4235 function local(node) {
4236   while (!node.__brush) if (!(node = node.parentNode)) return;
4237   return node.__brush;
4238 }
4239
4240 function empty(extent) {
4241   return extent[0][0] === extent[1][0]
4242       || extent[0][1] === extent[1][1];
4243 }
4244
4245 function brushSelection(node) {
4246   var state = node.__brush;
4247   return state ? state.dim.output(state.selection) : null;
4248 }
4249
4250 function brushX() {
4251   return brush$1(X);
4252 }
4253
4254 function brushY() {
4255   return brush$1(Y);
4256 }
4257
4258 var brush = function() {
4259   return brush$1(XY);
4260 };
4261
4262 function brush$1(dim) {
4263   var extent = defaultExtent,
4264       filter = defaultFilter,
4265       listeners = dispatch(brush, "start", "brush", "end"),
4266       handleSize = 6,
4267       touchending;
4268
4269   function brush(group) {
4270     var overlay = group
4271         .property("__brush", initialize)
4272       .selectAll(".overlay")
4273       .data([type("overlay")]);
4274
4275     overlay.enter().append("rect")
4276         .attr("class", "overlay")
4277         .attr("pointer-events", "all")
4278         .attr("cursor", cursors.overlay)
4279       .merge(overlay)
4280         .each(function() {
4281           var extent = local(this).extent;
4282           d3_select(this)
4283               .attr("x", extent[0][0])
4284               .attr("y", extent[0][1])
4285               .attr("width", extent[1][0] - extent[0][0])
4286               .attr("height", extent[1][1] - extent[0][1]);
4287         });
4288
4289     group.selectAll(".selection")
4290       .data([type("selection")])
4291       .enter().append("rect")
4292         .attr("class", "selection")
4293         .attr("cursor", cursors.selection)
4294         .attr("fill", "#777")
4295         .attr("fill-opacity", 0.3)
4296         .attr("stroke", "#fff")
4297         .attr("shape-rendering", "crispEdges");
4298
4299     var handle = group.selectAll(".handle")
4300       .data(dim.handles, function(d) { return d.type; });
4301
4302     handle.exit().remove();
4303
4304     handle.enter().append("rect")
4305         .attr("class", function(d) { return "handle handle--" + d.type; })
4306         .attr("cursor", function(d) { return cursors[d.type]; });
4307
4308     group
4309         .each(redraw)
4310         .attr("fill", "none")
4311         .attr("pointer-events", "all")
4312         .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)")
4313         .on("mousedown.brush touchstart.brush", started);
4314   }
4315
4316   brush.move = function(group, selection) {
4317     if (group.selection) {
4318       group
4319           .on("start.brush", function() { emitter(this, arguments).beforestart().start(); })
4320           .on("interrupt.brush end.brush", function() { emitter(this, arguments).end(); })
4321           .tween("brush", function() {
4322             var that = this,
4323                 state = that.__brush,
4324                 emit = emitter(that, arguments),
4325                 selection0 = state.selection,
4326                 selection1 = dim.input(typeof selection === "function" ? selection.apply(this, arguments) : selection, state.extent),
4327                 i = d3_interpolate(selection0, selection1);
4328
4329             function tween(t) {
4330               state.selection = t === 1 && empty(selection1) ? null : i(t);
4331               redraw.call(that);
4332               emit.brush();
4333             }
4334
4335             return selection0 && selection1 ? tween : tween(1);
4336           });
4337     } else {
4338       group
4339           .each(function() {
4340             var that = this,
4341                 args = arguments,
4342                 state = that.__brush,
4343                 selection1 = dim.input(typeof selection === "function" ? selection.apply(that, args) : selection, state.extent),
4344                 emit = emitter(that, args).beforestart();
4345
4346             interrupt(that);
4347             state.selection = selection1 == null || empty(selection1) ? null : selection1;
4348             redraw.call(that);
4349             emit.start().brush().end();
4350           });
4351     }
4352   };
4353
4354   function redraw() {
4355     var group = d3_select(this),
4356         selection = local(this).selection;
4357
4358     if (selection) {
4359       group.selectAll(".selection")
4360           .style("display", null)
4361           .attr("x", selection[0][0])
4362           .attr("y", selection[0][1])
4363           .attr("width", selection[1][0] - selection[0][0])
4364           .attr("height", selection[1][1] - selection[0][1]);
4365
4366       group.selectAll(".handle")
4367           .style("display", null)
4368           .attr("x", function(d) { return d.type[d.type.length - 1] === "e" ? selection[1][0] - handleSize / 2 : selection[0][0] - handleSize / 2; })
4369           .attr("y", function(d) { return d.type[0] === "s" ? selection[1][1] - handleSize / 2 : selection[0][1] - handleSize / 2; })
4370           .attr("width", function(d) { return d.type === "n" || d.type === "s" ? selection[1][0] - selection[0][0] + handleSize : handleSize; })
4371           .attr("height", function(d) { return d.type === "e" || d.type === "w" ? selection[1][1] - selection[0][1] + handleSize : handleSize; });
4372     }
4373
4374     else {
4375       group.selectAll(".selection,.handle")
4376           .style("display", "none")
4377           .attr("x", null)
4378           .attr("y", null)
4379           .attr("width", null)
4380           .attr("height", null);
4381     }
4382   }
4383
4384   function emitter(that, args) {
4385     return that.__brush.emitter || new Emitter(that, args);
4386   }
4387
4388   function Emitter(that, args) {
4389     this.that = that;
4390     this.args = args;
4391     this.state = that.__brush;
4392     this.active = 0;
4393   }
4394
4395   Emitter.prototype = {
4396     beforestart: function() {
4397       if (++this.active === 1) this.state.emitter = this, this.starting = true;
4398       return this;
4399     },
4400     start: function() {
4401       if (this.starting) this.starting = false, this.emit("start");
4402       return this;
4403     },
4404     brush: function() {
4405       this.emit("brush");
4406       return this;
4407     },
4408     end: function() {
4409       if (--this.active === 0) delete this.state.emitter, this.emit("end");
4410       return this;
4411     },
4412     emit: function(type) {
4413       customEvent(new BrushEvent(brush, type, dim.output(this.state.selection)), listeners.apply, listeners, [type, this.that, this.args]);
4414     }
4415   };
4416
4417   function started() {
4418     if (event.touches) { if (event.changedTouches.length < event.touches.length) return noevent$1(); }
4419     else if (touchending) return;
4420     if (!filter.apply(this, arguments)) return;
4421
4422     var that = this,
4423         type = event.target.__data__.type,
4424         mode = (event.metaKey ? type = "overlay" : type) === "selection" ? MODE_DRAG : (event.altKey ? MODE_CENTER : MODE_HANDLE),
4425         signX = dim === Y ? null : signsX[type],
4426         signY = dim === X ? null : signsY[type],
4427         state = local(that),
4428         extent = state.extent,
4429         selection = state.selection,
4430         W = extent[0][0], w0, w1,
4431         N = extent[0][1], n0, n1,
4432         E = extent[1][0], e0, e1,
4433         S = extent[1][1], s0, s1,
4434         dx,
4435         dy,
4436         moving,
4437         shifting = signX && signY && event.shiftKey,
4438         lockX,
4439         lockY,
4440         point0 = d3_mouse(that),
4441         point = point0,
4442         emit = emitter(that, arguments).beforestart();
4443
4444     if (type === "overlay") {
4445       state.selection = selection = [
4446         [w0 = dim === Y ? W : point0[0], n0 = dim === X ? N : point0[1]],
4447         [e0 = dim === Y ? E : w0, s0 = dim === X ? S : n0]
4448       ];
4449     } else {
4450       w0 = selection[0][0];
4451       n0 = selection[0][1];
4452       e0 = selection[1][0];
4453       s0 = selection[1][1];
4454     }
4455
4456     w1 = w0;
4457     n1 = n0;
4458     e1 = e0;
4459     s1 = s0;
4460
4461     var group = d3_select(that)
4462         .attr("pointer-events", "none");
4463
4464     var overlay = group.selectAll(".overlay")
4465         .attr("cursor", cursors[type]);
4466
4467     if (event.touches) {
4468       group
4469           .on("touchmove.brush", moved, true)
4470           .on("touchend.brush touchcancel.brush", ended, true);
4471     } else {
4472       var view = d3_select(event.view)
4473           .on("keydown.brush", keydowned, true)
4474           .on("keyup.brush", keyupped, true)
4475           .on("mousemove.brush", moved, true)
4476           .on("mouseup.brush", ended, true);
4477
4478       dragDisable(event.view);
4479     }
4480
4481     nopropagation$1();
4482     interrupt(that);
4483     redraw.call(that);
4484     emit.start();
4485
4486     function moved() {
4487       var point1 = d3_mouse(that);
4488       if (shifting && !lockX && !lockY) {
4489         if (Math.abs(point1[0] - point[0]) > Math.abs(point1[1] - point[1])) lockY = true;
4490         else lockX = true;
4491       }
4492       point = point1;
4493       moving = true;
4494       noevent$1();
4495       move();
4496     }
4497
4498     function move() {
4499       var t;
4500
4501       dx = point[0] - point0[0];
4502       dy = point[1] - point0[1];
4503
4504       switch (mode) {
4505         case MODE_SPACE:
4506         case MODE_DRAG: {
4507           if (signX) dx = Math.max(W - w0, Math.min(E - e0, dx)), w1 = w0 + dx, e1 = e0 + dx;
4508           if (signY) dy = Math.max(N - n0, Math.min(S - s0, dy)), n1 = n0 + dy, s1 = s0 + dy;
4509           break;
4510         }
4511         case MODE_HANDLE: {
4512           if (signX < 0) dx = Math.max(W - w0, Math.min(E - w0, dx)), w1 = w0 + dx, e1 = e0;
4513           else if (signX > 0) dx = Math.max(W - e0, Math.min(E - e0, dx)), w1 = w0, e1 = e0 + dx;
4514           if (signY < 0) dy = Math.max(N - n0, Math.min(S - n0, dy)), n1 = n0 + dy, s1 = s0;
4515           else if (signY > 0) dy = Math.max(N - s0, Math.min(S - s0, dy)), n1 = n0, s1 = s0 + dy;
4516           break;
4517         }
4518         case MODE_CENTER: {
4519           if (signX) w1 = Math.max(W, Math.min(E, w0 - dx * signX)), e1 = Math.max(W, Math.min(E, e0 + dx * signX));
4520           if (signY) n1 = Math.max(N, Math.min(S, n0 - dy * signY)), s1 = Math.max(N, Math.min(S, s0 + dy * signY));
4521           break;
4522         }
4523       }
4524
4525       if (e1 < w1) {
4526         signX *= -1;
4527         t = w0, w0 = e0, e0 = t;
4528         t = w1, w1 = e1, e1 = t;
4529         if (type in flipX) overlay.attr("cursor", cursors[type = flipX[type]]);
4530       }
4531
4532       if (s1 < n1) {
4533         signY *= -1;
4534         t = n0, n0 = s0, s0 = t;
4535         t = n1, n1 = s1, s1 = t;
4536         if (type in flipY) overlay.attr("cursor", cursors[type = flipY[type]]);
4537       }
4538
4539       if (state.selection) selection = state.selection; // May be set by brush.move!
4540       if (lockX) w1 = selection[0][0], e1 = selection[1][0];
4541       if (lockY) n1 = selection[0][1], s1 = selection[1][1];
4542
4543       if (selection[0][0] !== w1
4544           || selection[0][1] !== n1
4545           || selection[1][0] !== e1
4546           || selection[1][1] !== s1) {
4547         state.selection = [[w1, n1], [e1, s1]];
4548         redraw.call(that);
4549         emit.brush();
4550       }
4551     }
4552
4553     function ended() {
4554       nopropagation$1();
4555       if (event.touches) {
4556         if (event.touches.length) return;
4557         if (touchending) clearTimeout(touchending);
4558         touchending = setTimeout(function() { touchending = null; }, 500); // Ghost clicks are delayed!
4559         group.on("touchmove.brush touchend.brush touchcancel.brush", null);
4560       } else {
4561         yesdrag(event.view, moving);
4562         view.on("keydown.brush keyup.brush mousemove.brush mouseup.brush", null);
4563       }
4564       group.attr("pointer-events", "all");
4565       overlay.attr("cursor", cursors.overlay);
4566       if (state.selection) selection = state.selection; // May be set by brush.move (on start)!
4567       if (empty(selection)) state.selection = null, redraw.call(that);
4568       emit.end();
4569     }
4570
4571     function keydowned() {
4572       switch (event.keyCode) {
4573         case 16: { // SHIFT
4574           shifting = signX && signY;
4575           break;
4576         }
4577         case 18: { // ALT
4578           if (mode === MODE_HANDLE) {
4579             if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
4580             if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
4581             mode = MODE_CENTER;
4582             move();
4583           }
4584           break;
4585         }
4586         case 32: { // SPACE; takes priority over ALT
4587           if (mode === MODE_HANDLE || mode === MODE_CENTER) {
4588             if (signX < 0) e0 = e1 - dx; else if (signX > 0) w0 = w1 - dx;
4589             if (signY < 0) s0 = s1 - dy; else if (signY > 0) n0 = n1 - dy;
4590             mode = MODE_SPACE;
4591             overlay.attr("cursor", cursors.selection);
4592             move();
4593           }
4594           break;
4595         }
4596         default: return;
4597       }
4598       noevent$1();
4599     }
4600
4601     function keyupped() {
4602       switch (event.keyCode) {
4603         case 16: { // SHIFT
4604           if (shifting) {
4605             lockX = lockY = shifting = false;
4606             move();
4607           }
4608           break;
4609         }
4610         case 18: { // ALT
4611           if (mode === MODE_CENTER) {
4612             if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
4613             if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
4614             mode = MODE_HANDLE;
4615             move();
4616           }
4617           break;
4618         }
4619         case 32: { // SPACE
4620           if (mode === MODE_SPACE) {
4621             if (event.altKey) {
4622               if (signX) e0 = e1 - dx * signX, w0 = w1 + dx * signX;
4623               if (signY) s0 = s1 - dy * signY, n0 = n1 + dy * signY;
4624               mode = MODE_CENTER;
4625             } else {
4626               if (signX < 0) e0 = e1; else if (signX > 0) w0 = w1;
4627               if (signY < 0) s0 = s1; else if (signY > 0) n0 = n1;
4628               mode = MODE_HANDLE;
4629             }
4630             overlay.attr("cursor", cursors[type]);
4631             move();
4632           }
4633           break;
4634         }
4635         default: return;
4636       }
4637       noevent$1();
4638     }
4639   }
4640
4641   function initialize() {
4642     var state = this.__brush || {selection: null};
4643     state.extent = extent.apply(this, arguments);
4644     state.dim = dim;
4645     return state;
4646   }
4647
4648   brush.extent = function(_) {
4649     return arguments.length ? (extent = typeof _ === "function" ? _ : constant$4([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), brush) : extent;
4650   };
4651
4652   brush.filter = function(_) {
4653     return arguments.length ? (filter = typeof _ === "function" ? _ : constant$4(!!_), brush) : filter;
4654   };
4655
4656   brush.handleSize = function(_) {
4657     return arguments.length ? (handleSize = +_, brush) : handleSize;
4658   };
4659
4660   brush.on = function() {
4661     var value = listeners.on.apply(listeners, arguments);
4662     return value === listeners ? brush : value;
4663   };
4664
4665   return brush;
4666 }
4667
4668 var cos = Math.cos;
4669 var sin = Math.sin;
4670 var pi$1 = Math.PI;
4671 var halfPi$1 = pi$1 / 2;
4672 var tau$1 = pi$1 * 2;
4673 var max$1 = Math.max;
4674
4675 function compareValue(compare) {
4676   return function(a, b) {
4677     return compare(
4678       a.source.value + a.target.value,
4679       b.source.value + b.target.value
4680     );
4681   };
4682 }
4683
4684 var chord = function() {
4685   var padAngle = 0,
4686       sortGroups = null,
4687       sortSubgroups = null,
4688       sortChords = null;
4689
4690   function chord(matrix) {
4691     var n = matrix.length,
4692         groupSums = [],
4693         groupIndex = d3_range(n),
4694         subgroupIndex = [],
4695         chords = [],
4696         groups = chords.groups = new Array(n),
4697         subgroups = new Array(n * n),
4698         k,
4699         x,
4700         x0,
4701         dx,
4702         i,
4703         j;
4704
4705     // Compute the sum.
4706     k = 0, i = -1; while (++i < n) {
4707       x = 0, j = -1; while (++j < n) {
4708         x += matrix[i][j];
4709       }
4710       groupSums.push(x);
4711       subgroupIndex.push(d3_range(n));
4712       k += x;
4713     }
4714
4715     // Sort groups…
4716     if (sortGroups) groupIndex.sort(function(a, b) {
4717       return sortGroups(groupSums[a], groupSums[b]);
4718     });
4719
4720     // Sort subgroups…
4721     if (sortSubgroups) subgroupIndex.forEach(function(d, i) {
4722       d.sort(function(a, b) {
4723         return sortSubgroups(matrix[i][a], matrix[i][b]);
4724       });
4725     });
4726
4727     // Convert the sum to scaling factor for [0, 2pi].
4728     // TODO Allow start and end angle to be specified?
4729     // TODO Allow padding to be specified as percentage?
4730     k = max$1(0, tau$1 - padAngle * n) / k;
4731     dx = k ? padAngle : tau$1 / n;
4732
4733     // Compute the start and end angle for each group and subgroup.
4734     // Note: Opera has a bug reordering object literal properties!
4735     x = 0, i = -1; while (++i < n) {
4736       x0 = x, j = -1; while (++j < n) {
4737         var di = groupIndex[i],
4738             dj = subgroupIndex[di][j],
4739             v = matrix[di][dj],
4740             a0 = x,
4741             a1 = x += v * k;
4742         subgroups[dj * n + di] = {
4743           index: di,
4744           subindex: dj,
4745           startAngle: a0,
4746           endAngle: a1,
4747           value: v
4748         };
4749       }
4750       groups[di] = {
4751         index: di,
4752         startAngle: x0,
4753         endAngle: x,
4754         value: groupSums[di]
4755       };
4756       x += dx;
4757     }
4758
4759     // Generate chords for each (non-empty) subgroup-subgroup link.
4760     i = -1; while (++i < n) {
4761       j = i - 1; while (++j < n) {
4762         var source = subgroups[j * n + i],
4763             target = subgroups[i * n + j];
4764         if (source.value || target.value) {
4765           chords.push(source.value < target.value
4766               ? {source: target, target: source}
4767               : {source: source, target: target});
4768         }
4769       }
4770     }
4771
4772     return sortChords ? chords.sort(sortChords) : chords;
4773   }
4774
4775   chord.padAngle = function(_) {
4776     return arguments.length ? (padAngle = max$1(0, _), chord) : padAngle;
4777   };
4778
4779   chord.sortGroups = function(_) {
4780     return arguments.length ? (sortGroups = _, chord) : sortGroups;
4781   };
4782
4783   chord.sortSubgroups = function(_) {
4784     return arguments.length ? (sortSubgroups = _, chord) : sortSubgroups;
4785   };
4786
4787   chord.sortChords = function(_) {
4788     return arguments.length ? (_ == null ? sortChords = null : (sortChords = compareValue(_))._ = _, chord) : sortChords && sortChords._;
4789   };
4790
4791   return chord;
4792 };
4793
4794 var slice$2 = Array.prototype.slice;
4795
4796 var constant$5 = function(x) {
4797   return function() {
4798     return x;
4799   };
4800 };
4801
4802 var pi$2 = Math.PI;
4803 var tau$2 = 2 * pi$2;
4804 var epsilon$1 = 1e-6;
4805 var tauEpsilon = tau$2 - epsilon$1;
4806
4807 function Path() {
4808   this._x0 = this._y0 = // start of current subpath
4809   this._x1 = this._y1 = null; // end of current subpath
4810   this._ = "";
4811 }
4812
4813 function path() {
4814   return new Path;
4815 }
4816
4817 Path.prototype = path.prototype = {
4818   constructor: Path,
4819   moveTo: function(x, y) {
4820     this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y);
4821   },
4822   closePath: function() {
4823     if (this._x1 !== null) {
4824       this._x1 = this._x0, this._y1 = this._y0;
4825       this._ += "Z";
4826     }
4827   },
4828   lineTo: function(x, y) {
4829     this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y);
4830   },
4831   quadraticCurveTo: function(x1, y1, x, y) {
4832     this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
4833   },
4834   bezierCurveTo: function(x1, y1, x2, y2, x, y) {
4835     this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
4836   },
4837   arcTo: function(x1, y1, x2, y2, r) {
4838     x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;
4839     var x0 = this._x1,
4840         y0 = this._y1,
4841         x21 = x2 - x1,
4842         y21 = y2 - y1,
4843         x01 = x0 - x1,
4844         y01 = y0 - y1,
4845         l01_2 = x01 * x01 + y01 * y01;
4846
4847     // Is the radius negative? Error.
4848     if (r < 0) throw new Error("negative radius: " + r);
4849
4850     // Is this path empty? Move to (x1,y1).
4851     if (this._x1 === null) {
4852       this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1);
4853     }
4854
4855     // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.
4856     else if (!(l01_2 > epsilon$1)) {}
4857
4858     // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?
4859     // Equivalently, is (x1,y1) coincident with (x2,y2)?
4860     // Or, is the radius zero? Line to (x1,y1).
4861     else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon$1) || !r) {
4862       this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1);
4863     }
4864
4865     // Otherwise, draw an arc!
4866     else {
4867       var x20 = x2 - x0,
4868           y20 = y2 - y0,
4869           l21_2 = x21 * x21 + y21 * y21,
4870           l20_2 = x20 * x20 + y20 * y20,
4871           l21 = Math.sqrt(l21_2),
4872           l01 = Math.sqrt(l01_2),
4873           l = r * Math.tan((pi$2 - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),
4874           t01 = l / l01,
4875           t21 = l / l21;
4876
4877       // If the start tangent is not coincident with (x0,y0), line to.
4878       if (Math.abs(t01 - 1) > epsilon$1) {
4879         this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01);
4880       }
4881
4882       this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21);
4883     }
4884   },
4885   arc: function(x, y, r, a0, a1, ccw) {
4886     x = +x, y = +y, r = +r;
4887     var dx = r * Math.cos(a0),
4888         dy = r * Math.sin(a0),
4889         x0 = x + dx,
4890         y0 = y + dy,
4891         cw = 1 ^ ccw,
4892         da = ccw ? a0 - a1 : a1 - a0;
4893
4894     // Is the radius negative? Error.
4895     if (r < 0) throw new Error("negative radius: " + r);
4896
4897     // Is this path empty? Move to (x0,y0).
4898     if (this._x1 === null) {
4899       this._ += "M" + x0 + "," + y0;
4900     }
4901
4902     // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).
4903     else if (Math.abs(this._x1 - x0) > epsilon$1 || Math.abs(this._y1 - y0) > epsilon$1) {
4904       this._ += "L" + x0 + "," + y0;
4905     }
4906
4907     // Is this arc empty? We’re done.
4908     if (!r) return;
4909
4910     // Does the angle go the wrong way? Flip the direction.
4911     if (da < 0) da = da % tau$2 + tau$2;
4912
4913     // Is this a complete circle? Draw two arcs to complete the circle.
4914     if (da > tauEpsilon) {
4915       this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0);
4916     }
4917
4918     // Is this arc non-empty? Draw an arc!
4919     else if (da > epsilon$1) {
4920       this._ += "A" + r + "," + r + ",0," + (+(da >= pi$2)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1));
4921     }
4922   },
4923   rect: function(x, y, w, h) {
4924     this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z";
4925   },
4926   toString: function() {
4927     return this._;
4928   }
4929 };
4930
4931 function defaultSource(d) {
4932   return d.source;
4933 }
4934
4935 function defaultTarget(d) {
4936   return d.target;
4937 }
4938
4939 function defaultRadius(d) {
4940   return d.radius;
4941 }
4942
4943 function defaultStartAngle(d) {
4944   return d.startAngle;
4945 }
4946
4947 function defaultEndAngle(d) {
4948   return d.endAngle;
4949 }
4950
4951 var ribbon = function() {
4952   var source = defaultSource,
4953       target = defaultTarget,
4954       radius = defaultRadius,
4955       startAngle = defaultStartAngle,
4956       endAngle = defaultEndAngle,
4957       context = null;
4958
4959   function ribbon() {
4960     var buffer,
4961         argv = slice$2.call(arguments),
4962         s = source.apply(this, argv),
4963         t = target.apply(this, argv),
4964         sr = +radius.apply(this, (argv[0] = s, argv)),
4965         sa0 = startAngle.apply(this, argv) - halfPi$1,
4966         sa1 = endAngle.apply(this, argv) - halfPi$1,
4967         sx0 = sr * cos(sa0),
4968         sy0 = sr * sin(sa0),
4969         tr = +radius.apply(this, (argv[0] = t, argv)),
4970         ta0 = startAngle.apply(this, argv) - halfPi$1,
4971         ta1 = endAngle.apply(this, argv) - halfPi$1;
4972
4973     if (!context) context = buffer = path();
4974
4975     context.moveTo(sx0, sy0);
4976     context.arc(0, 0, sr, sa0, sa1);
4977     if (sa0 !== ta0 || sa1 !== ta1) { // TODO sr !== tr?
4978       context.quadraticCurveTo(0, 0, tr * cos(ta0), tr * sin(ta0));
4979       context.arc(0, 0, tr, ta0, ta1);
4980     }
4981     context.quadraticCurveTo(0, 0, sx0, sy0);
4982     context.closePath();
4983
4984     if (buffer) return context = null, buffer + "" || null;
4985   }
4986
4987   ribbon.radius = function(_) {
4988     return arguments.length ? (radius = typeof _ === "function" ? _ : constant$5(+_), ribbon) : radius;
4989   };
4990
4991   ribbon.startAngle = function(_) {
4992     return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$5(+_), ribbon) : startAngle;
4993   };
4994
4995   ribbon.endAngle = function(_) {
4996     return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$5(+_), ribbon) : endAngle;
4997   };
4998
4999   ribbon.source = function(_) {
5000     return arguments.length ? (source = _, ribbon) : source;
5001   };
5002
5003   ribbon.target = function(_) {
5004     return arguments.length ? (target = _, ribbon) : target;
5005   };
5006
5007   ribbon.context = function(_) {
5008     return arguments.length ? (context = _ == null ? null : _, ribbon) : context;
5009   };
5010
5011   return ribbon;
5012 };
5013
5014 var prefix = "$";
5015
5016 function Map() {}
5017
5018 Map.prototype = map$1.prototype = {
5019   constructor: Map,
5020   has: function(key) {
5021     return (prefix + key) in this;
5022   },
5023   get: function(key) {
5024     return this[prefix + key];
5025   },
5026   set: function(key, value) {
5027     this[prefix + key] = value;
5028     return this;
5029   },
5030   remove: function(key) {
5031     var property = prefix + key;
5032     return property in this && delete this[property];
5033   },
5034   clear: function() {
5035     for (var property in this) if (property[0] === prefix) delete this[property];
5036   },
5037   keys: function() {
5038     var keys = [];
5039     for (var property in this) if (property[0] === prefix) keys.push(property.slice(1));
5040     return keys;
5041   },
5042   values: function() {
5043     var values = [];
5044     for (var property in this) if (property[0] === prefix) values.push(this[property]);
5045     return values;
5046   },
5047   entries: function() {
5048     var entries = [];
5049     for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]});
5050     return entries;
5051   },
5052   size: function() {
5053     var size = 0;
5054     for (var property in this) if (property[0] === prefix) ++size;
5055     return size;
5056   },
5057   empty: function() {
5058     for (var property in this) if (property[0] === prefix) return false;
5059     return true;
5060   },
5061   each: function(f) {
5062     for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this);
5063   }
5064 };
5065
5066 function map$1(object, f) {
5067   var map = new Map;
5068
5069   // Copy constructor.
5070   if (object instanceof Map) object.each(function(value, key) { map.set(key, value); });
5071
5072   // Index array by numeric index or specified key function.
5073   else if (Array.isArray(object)) {
5074     var i = -1,
5075         n = object.length,
5076         o;
5077
5078     if (f == null) while (++i < n) map.set(i, object[i]);
5079     else while (++i < n) map.set(f(o = object[i], i, object), o);
5080   }
5081
5082   // Convert object to map.
5083   else if (object) for (var key in object) map.set(key, object[key]);
5084
5085   return map;
5086 }
5087
5088 var nest = function() {
5089   var keys = [],
5090       sortKeys = [],
5091       sortValues,
5092       rollup,
5093       nest;
5094
5095   function apply(array, depth, createResult, setResult) {
5096     if (depth >= keys.length) {
5097       if (sortValues != null) array.sort(sortValues);
5098       return rollup != null ? rollup(array) : array;
5099     }
5100
5101     var i = -1,
5102         n = array.length,
5103         key = keys[depth++],
5104         keyValue,
5105         value,
5106         valuesByKey = map$1(),
5107         values,
5108         result = createResult();
5109
5110     while (++i < n) {
5111       if (values = valuesByKey.get(keyValue = key(value = array[i]) + "")) {
5112         values.push(value);
5113       } else {
5114         valuesByKey.set(keyValue, [value]);
5115       }
5116     }
5117
5118     valuesByKey.each(function(values, key) {
5119       setResult(result, key, apply(values, depth, createResult, setResult));
5120     });
5121
5122     return result;
5123   }
5124
5125   function entries(map, depth) {
5126     if (++depth > keys.length) return map;
5127     var array, sortKey = sortKeys[depth - 1];
5128     if (rollup != null && depth >= keys.length) array = map.entries();
5129     else array = [], map.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); });
5130     return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array;
5131   }
5132
5133   return nest = {
5134     object: function(array) { return apply(array, 0, createObject, setObject); },
5135     map: function(array) { return apply(array, 0, createMap, setMap); },
5136     entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); },
5137     key: function(d) { keys.push(d); return nest; },
5138     sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; },
5139     sortValues: function(order) { sortValues = order; return nest; },
5140     rollup: function(f) { rollup = f; return nest; }
5141   };
5142 };
5143
5144 function createObject() {
5145   return {};
5146 }
5147
5148 function setObject(object, key, value) {
5149   object[key] = value;
5150 }
5151
5152 function createMap() {
5153   return map$1();
5154 }
5155
5156 function setMap(map, key, value) {
5157   map.set(key, value);
5158 }
5159
5160 function Set() {}
5161
5162 var proto = map$1.prototype;
5163
5164 Set.prototype = set$2.prototype = {
5165   constructor: Set,
5166   has: proto.has,
5167   add: function(value) {
5168     value += "";
5169     this[prefix + value] = value;
5170     return this;
5171   },
5172   remove: proto.remove,
5173   clear: proto.clear,
5174   values: proto.keys,
5175   size: proto.size,
5176   empty: proto.empty,
5177   each: proto.each
5178 };
5179
5180 function set$2(object, f) {
5181   var set = new Set;
5182
5183   // Copy constructor.
5184   if (object instanceof Set) object.each(function(value) { set.add(value); });
5185
5186   // Otherwise, assume it’s an array.
5187   else if (object) {
5188     var i = -1, n = object.length;
5189     if (f == null) while (++i < n) set.add(object[i]);
5190     else while (++i < n) set.add(f(object[i], i, object));
5191   }
5192
5193   return set;
5194 }
5195
5196 var keys = function(map) {
5197   var keys = [];
5198   for (var key in map) keys.push(key);
5199   return keys;
5200 };
5201
5202 var values = function(map) {
5203   var values = [];
5204   for (var key in map) values.push(map[key]);
5205   return values;
5206 };
5207
5208 var entries = function(map) {
5209   var entries = [];
5210   for (var key in map) entries.push({key: key, value: map[key]});
5211   return entries;
5212 };
5213
5214 var EOL = {};
5215 var EOF = {};
5216 var QUOTE = 34;
5217 var NEWLINE = 10;
5218 var RETURN = 13;
5219
5220 function objectConverter(columns) {
5221   return new Function("d", "return {" + columns.map(function(name, i) {
5222     return JSON.stringify(name) + ": d[" + i + "]";
5223   }).join(",") + "}");
5224 }
5225
5226 function customConverter(columns, f) {
5227   var object = objectConverter(columns);
5228   return function(row, i) {
5229     return f(object(row), i, columns);
5230   };
5231 }
5232
5233 // Compute unique columns in order of discovery.
5234 function inferColumns(rows) {
5235   var columnSet = Object.create(null),
5236       columns = [];
5237
5238   rows.forEach(function(row) {
5239     for (var column in row) {
5240       if (!(column in columnSet)) {
5241         columns.push(columnSet[column] = column);
5242       }
5243     }
5244   });
5245
5246   return columns;
5247 }
5248
5249 var dsv = function(delimiter) {
5250   var reFormat = new RegExp("[\"" + delimiter + "\n\r]"),
5251       DELIMITER = delimiter.charCodeAt(0);
5252
5253   function parse(text, f) {
5254     var convert, columns, rows = parseRows(text, function(row, i) {
5255       if (convert) return convert(row, i - 1);
5256       columns = row, convert = f ? customConverter(row, f) : objectConverter(row);
5257     });
5258     rows.columns = columns;
5259     return rows;
5260   }
5261
5262   function parseRows(text, f) {
5263     var rows = [], // output rows
5264         N = text.length,
5265         I = 0, // current character index
5266         n = 0, // current line number
5267         t, // current token
5268         eof = N <= 0, // current token followed by EOF?
5269         eol = false; // current token followed by EOL?
5270
5271     // Strip the trailing newline.
5272     if (text.charCodeAt(N - 1) === NEWLINE) --N;
5273     if (text.charCodeAt(N - 1) === RETURN) --N;
5274
5275     function token() {
5276       if (eof) return EOF;
5277       if (eol) return eol = false, EOL;
5278
5279       // Unescape quotes.
5280       var i, j = I, c;
5281       if (text.charCodeAt(j) === QUOTE) {
5282         while (I++ < N && text.charCodeAt(I) !== QUOTE || text.charCodeAt(++I) === QUOTE);
5283         if ((i = I) >= N) eof = true;
5284         else if ((c = text.charCodeAt(I++)) === NEWLINE) eol = true;
5285         else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }
5286         return text.slice(j + 1, i - 1).replace(/""/g, "\"");
5287       }
5288
5289       // Find next delimiter or newline.
5290       while (I < N) {
5291         if ((c = text.charCodeAt(i = I++)) === NEWLINE) eol = true;
5292         else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; }
5293         else if (c !== DELIMITER) continue;
5294         return text.slice(j, i);
5295       }
5296
5297       // Return last token before EOF.
5298       return eof = true, text.slice(j, N);
5299     }
5300
5301     while ((t = token()) !== EOF) {
5302       var row = [];
5303       while (t !== EOL && t !== EOF) row.push(t), t = token();
5304       if (f && (row = f(row, n++)) == null) continue;
5305       rows.push(row);
5306     }
5307
5308     return rows;
5309   }
5310
5311   function format(rows, columns) {
5312     if (columns == null) columns = inferColumns(rows);
5313     return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) {
5314       return columns.map(function(column) {
5315         return formatValue(row[column]);
5316       }).join(delimiter);
5317     })).join("\n");
5318   }
5319
5320   function formatRows(rows) {
5321     return rows.map(formatRow).join("\n");
5322   }
5323
5324   function formatRow(row) {
5325     return row.map(formatValue).join(delimiter);
5326   }
5327
5328   function formatValue(text) {
5329     return text == null ? ""
5330         : reFormat.test(text += "") ? "\"" + text.replace(/"/g, "\"\"") + "\""
5331         : text;
5332   }
5333
5334   return {
5335     parse: parse,
5336     parseRows: parseRows,
5337     format: format,
5338     formatRows: formatRows
5339   };
5340 };
5341
5342 var csv = dsv(",");
5343
5344 var csvParse = csv.parse;
5345 var csvParseRows = csv.parseRows;
5346 var csvFormat = csv.format;
5347 var csvFormatRows = csv.formatRows;
5348
5349 var tsv = dsv("\t");
5350
5351 var tsvParse = tsv.parse;
5352 var tsvParseRows = tsv.parseRows;
5353 var tsvFormat = tsv.format;
5354 var tsvFormatRows = tsv.formatRows;
5355
5356 var center$1 = function(x, y) {
5357   var nodes;
5358
5359   if (x == null) x = 0;
5360   if (y == null) y = 0;
5361
5362   function force() {
5363     var i,
5364         n = nodes.length,
5365         node,
5366         sx = 0,
5367         sy = 0;
5368
5369     for (i = 0; i < n; ++i) {
5370       node = nodes[i], sx += node.x, sy += node.y;
5371     }
5372
5373     for (sx = sx / n - x, sy = sy / n - y, i = 0; i < n; ++i) {
5374       node = nodes[i], node.x -= sx, node.y -= sy;
5375     }
5376   }
5377
5378   force.initialize = function(_) {
5379     nodes = _;
5380   };
5381
5382   force.x = function(_) {
5383     return arguments.length ? (x = +_, force) : x;
5384   };
5385
5386   force.y = function(_) {
5387     return arguments.length ? (y = +_, force) : y;
5388   };
5389
5390   return force;
5391 };
5392
5393 var constant$6 = function(x) {
5394   return function() {
5395     return x;
5396   };
5397 };
5398
5399 var jiggle = function() {
5400   return (Math.random() - 0.5) * 1e-6;
5401 };
5402
5403 var tree_add = function(d) {
5404   var x = +this._x.call(null, d),
5405       y = +this._y.call(null, d);
5406   return add(this.cover(x, y), x, y, d);
5407 };
5408
5409 function add(tree, x, y, d) {
5410   if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points
5411
5412   var parent,
5413       node = tree._root,
5414       leaf = {data: d},
5415       x0 = tree._x0,
5416       y0 = tree._y0,
5417       x1 = tree._x1,
5418       y1 = tree._y1,
5419       xm,
5420       ym,
5421       xp,
5422       yp,
5423       right,
5424       bottom,
5425       i,
5426       j;
5427
5428   // If the tree is empty, initialize the root as a leaf.
5429   if (!node) return tree._root = leaf, tree;
5430
5431   // Find the existing leaf for the new point, or add it.
5432   while (node.length) {
5433     if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
5434     if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
5435     if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree;
5436   }
5437
5438   // Is the new point is exactly coincident with the existing point?
5439   xp = +tree._x.call(null, node.data);
5440   yp = +tree._y.call(null, node.data);
5441   if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree;
5442
5443   // Otherwise, split the leaf node until the old and new point are separated.
5444   do {
5445     parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4);
5446     if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
5447     if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
5448   } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm)));
5449   return parent[j] = node, parent[i] = leaf, tree;
5450 }
5451
5452 function addAll(data) {
5453   var d, i, n = data.length,
5454       x,
5455       y,
5456       xz = new Array(n),
5457       yz = new Array(n),
5458       x0 = Infinity,
5459       y0 = Infinity,
5460       x1 = -Infinity,
5461       y1 = -Infinity;
5462
5463   // Compute the points and their extent.
5464   for (i = 0; i < n; ++i) {
5465     if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue;
5466     xz[i] = x;
5467     yz[i] = y;
5468     if (x < x0) x0 = x;
5469     if (x > x1) x1 = x;
5470     if (y < y0) y0 = y;
5471     if (y > y1) y1 = y;
5472   }
5473
5474   // If there were no (valid) points, inherit the existing extent.
5475   if (x1 < x0) x0 = this._x0, x1 = this._x1;
5476   if (y1 < y0) y0 = this._y0, y1 = this._y1;
5477
5478   // Expand the tree to cover the new points.
5479   this.cover(x0, y0).cover(x1, y1);
5480
5481   // Add the new points.
5482   for (i = 0; i < n; ++i) {
5483     add(this, xz[i], yz[i], data[i]);
5484   }
5485
5486   return this;
5487 }
5488
5489 var tree_cover = function(x, y) {
5490   if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points
5491
5492   var x0 = this._x0,
5493       y0 = this._y0,
5494       x1 = this._x1,
5495       y1 = this._y1;
5496
5497   // If the quadtree has no extent, initialize them.
5498   // Integer extent are necessary so that if we later double the extent,
5499   // the existing quadrant boundaries don’t change due to floating point error!
5500   if (isNaN(x0)) {
5501     x1 = (x0 = Math.floor(x)) + 1;
5502     y1 = (y0 = Math.floor(y)) + 1;
5503   }
5504
5505   // Otherwise, double repeatedly to cover.
5506   else if (x0 > x || x > x1 || y0 > y || y > y1) {
5507     var z = x1 - x0,
5508         node = this._root,
5509         parent,
5510         i;
5511
5512     switch (i = (y < (y0 + y1) / 2) << 1 | (x < (x0 + x1) / 2)) {
5513       case 0: {
5514         do parent = new Array(4), parent[i] = node, node = parent;
5515         while (z *= 2, x1 = x0 + z, y1 = y0 + z, x > x1 || y > y1);
5516         break;
5517       }
5518       case 1: {
5519         do parent = new Array(4), parent[i] = node, node = parent;
5520         while (z *= 2, x0 = x1 - z, y1 = y0 + z, x0 > x || y > y1);
5521         break;
5522       }
5523       case 2: {
5524         do parent = new Array(4), parent[i] = node, node = parent;
5525         while (z *= 2, x1 = x0 + z, y0 = y1 - z, x > x1 || y0 > y);
5526         break;
5527       }
5528       case 3: {
5529         do parent = new Array(4), parent[i] = node, node = parent;
5530         while (z *= 2, x0 = x1 - z, y0 = y1 - z, x0 > x || y0 > y);
5531         break;
5532       }
5533     }
5534
5535     if (this._root && this._root.length) this._root = node;
5536   }
5537
5538   // If the quadtree covers the point already, just return.
5539   else return this;
5540
5541   this._x0 = x0;
5542   this._y0 = y0;
5543   this._x1 = x1;
5544   this._y1 = y1;
5545   return this;
5546 };
5547
5548 var tree_data = function() {
5549   var data = [];
5550   this.visit(function(node) {
5551     if (!node.length) do data.push(node.data); while (node = node.next)
5552   });
5553   return data;
5554 };
5555
5556 var tree_extent = function(_) {
5557   return arguments.length
5558       ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1])
5559       : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]];
5560 };
5561
5562 var Quad = function(node, x0, y0, x1, y1) {
5563   this.node = node;
5564   this.x0 = x0;
5565   this.y0 = y0;
5566   this.x1 = x1;
5567   this.y1 = y1;
5568 };
5569
5570 var tree_find = function(x, y, radius) {
5571   var data,
5572       x0 = this._x0,
5573       y0 = this._y0,
5574       x1,
5575       y1,
5576       x2,
5577       y2,
5578       x3 = this._x1,
5579       y3 = this._y1,
5580       quads = [],
5581       node = this._root,
5582       q,
5583       i;
5584
5585   if (node) quads.push(new Quad(node, x0, y0, x3, y3));
5586   if (radius == null) radius = Infinity;
5587   else {
5588     x0 = x - radius, y0 = y - radius;
5589     x3 = x + radius, y3 = y + radius;
5590     radius *= radius;
5591   }
5592
5593   while (q = quads.pop()) {
5594
5595     // Stop searching if this quadrant can’t contain a closer node.
5596     if (!(node = q.node)
5597         || (x1 = q.x0) > x3
5598         || (y1 = q.y0) > y3
5599         || (x2 = q.x1) < x0
5600         || (y2 = q.y1) < y0) continue;
5601
5602     // Bisect the current quadrant.
5603     if (node.length) {
5604       var xm = (x1 + x2) / 2,
5605           ym = (y1 + y2) / 2;
5606
5607       quads.push(
5608         new Quad(node[3], xm, ym, x2, y2),
5609         new Quad(node[2], x1, ym, xm, y2),
5610         new Quad(node[1], xm, y1, x2, ym),
5611         new Quad(node[0], x1, y1, xm, ym)
5612       );
5613
5614       // Visit the closest quadrant first.
5615       if (i = (y >= ym) << 1 | (x >= xm)) {
5616         q = quads[quads.length - 1];
5617         quads[quads.length - 1] = quads[quads.length - 1 - i];
5618         quads[quads.length - 1 - i] = q;
5619       }
5620     }
5621
5622     // Visit this point. (Visiting coincident points isn’t necessary!)
5623     else {
5624       var dx = x - +this._x.call(null, node.data),
5625           dy = y - +this._y.call(null, node.data),
5626           d2 = dx * dx + dy * dy;
5627       if (d2 < radius) {
5628         var d = Math.sqrt(radius = d2);
5629         x0 = x - d, y0 = y - d;
5630         x3 = x + d, y3 = y + d;
5631         data = node.data;
5632       }
5633     }
5634   }
5635
5636   return data;
5637 };
5638
5639 var tree_remove = function(d) {
5640   if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points
5641
5642   var parent,
5643       node = this._root,
5644       retainer,
5645       previous,
5646       next,
5647       x0 = this._x0,
5648       y0 = this._y0,
5649       x1 = this._x1,
5650       y1 = this._y1,
5651       x,
5652       y,
5653       xm,
5654       ym,
5655       right,
5656       bottom,
5657       i,
5658       j;
5659
5660   // If the tree is empty, initialize the root as a leaf.
5661   if (!node) return this;
5662
5663   // Find the leaf node for the point.
5664   // While descending, also retain the deepest parent with a non-removed sibling.
5665   if (node.length) while (true) {
5666     if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
5667     if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
5668     if (!(parent = node, node = node[i = bottom << 1 | right])) return this;
5669     if (!node.length) break;
5670     if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i;
5671   }
5672
5673   // Find the point to remove.
5674   while (node.data !== d) if (!(previous = node, node = node.next)) return this;
5675   if (next = node.next) delete node.next;
5676
5677   // If there are multiple coincident points, remove just the point.
5678   if (previous) return next ? previous.next = next : delete previous.next, this;
5679
5680   // If this is the root point, remove it.
5681   if (!parent) return this._root = next, this;
5682
5683   // Remove this leaf.
5684   next ? parent[i] = next : delete parent[i];
5685
5686   // If the parent now contains exactly one leaf, collapse superfluous parents.
5687   if ((node = parent[0] || parent[1] || parent[2] || parent[3])
5688       && node === (parent[3] || parent[2] || parent[1] || parent[0])
5689       && !node.length) {
5690     if (retainer) retainer[j] = node;
5691     else this._root = node;
5692   }
5693
5694   return this;
5695 };
5696
5697 function removeAll(data) {
5698   for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]);
5699   return this;
5700 }
5701
5702 var tree_root = function() {
5703   return this._root;
5704 };
5705
5706 var tree_size = function() {
5707   var size = 0;
5708   this.visit(function(node) {
5709     if (!node.length) do ++size; while (node = node.next)
5710   });
5711   return size;
5712 };
5713
5714 var tree_visit = function(callback) {
5715   var quads = [], q, node = this._root, child, x0, y0, x1, y1;
5716   if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1));
5717   while (q = quads.pop()) {
5718     if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) {
5719       var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
5720       if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
5721       if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
5722       if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
5723       if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
5724     }
5725   }
5726   return this;
5727 };
5728
5729 var tree_visitAfter = function(callback) {
5730   var quads = [], next = [], q;
5731   if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1));
5732   while (q = quads.pop()) {
5733     var node = q.node;
5734     if (node.length) {
5735       var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
5736       if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
5737       if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
5738       if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
5739       if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
5740     }
5741     next.push(q);
5742   }
5743   while (q = next.pop()) {
5744     callback(q.node, q.x0, q.y0, q.x1, q.y1);
5745   }
5746   return this;
5747 };
5748
5749 function defaultX(d) {
5750   return d[0];
5751 }
5752
5753 var tree_x = function(_) {
5754   return arguments.length ? (this._x = _, this) : this._x;
5755 };
5756
5757 function defaultY(d) {
5758   return d[1];
5759 }
5760
5761 var tree_y = function(_) {
5762   return arguments.length ? (this._y = _, this) : this._y;
5763 };
5764
5765 function quadtree(nodes, x, y) {
5766   var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN);
5767   return nodes == null ? tree : tree.addAll(nodes);
5768 }
5769
5770 function Quadtree(x, y, x0, y0, x1, y1) {
5771   this._x = x;
5772   this._y = y;
5773   this._x0 = x0;
5774   this._y0 = y0;
5775   this._x1 = x1;
5776   this._y1 = y1;
5777   this._root = undefined;
5778 }
5779
5780 function leaf_copy(leaf) {
5781   var copy = {data: leaf.data}, next = copy;
5782   while (leaf = leaf.next) next = next.next = {data: leaf.data};
5783   return copy;
5784 }
5785
5786 var treeProto = quadtree.prototype = Quadtree.prototype;
5787
5788 treeProto.copy = function() {
5789   var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1),
5790       node = this._root,
5791       nodes,
5792       child;
5793
5794   if (!node) return copy;
5795
5796   if (!node.length) return copy._root = leaf_copy(node), copy;
5797
5798   nodes = [{source: node, target: copy._root = new Array(4)}];
5799   while (node = nodes.pop()) {
5800     for (var i = 0; i < 4; ++i) {
5801       if (child = node.source[i]) {
5802         if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)});
5803         else node.target[i] = leaf_copy(child);
5804       }
5805     }
5806   }
5807
5808   return copy;
5809 };
5810
5811 treeProto.add = tree_add;
5812 treeProto.addAll = addAll;
5813 treeProto.cover = tree_cover;
5814 treeProto.data = tree_data;
5815 treeProto.extent = tree_extent;
5816 treeProto.find = tree_find;
5817 treeProto.remove = tree_remove;
5818 treeProto.removeAll = removeAll;
5819 treeProto.root = tree_root;
5820 treeProto.size = tree_size;
5821 treeProto.visit = tree_visit;
5822 treeProto.visitAfter = tree_visitAfter;
5823 treeProto.x = tree_x;
5824 treeProto.y = tree_y;
5825
5826 function x(d) {
5827   return d.x + d.vx;
5828 }
5829
5830 function y(d) {
5831   return d.y + d.vy;
5832 }
5833
5834 var collide = function(radius) {
5835   var nodes,
5836       radii,
5837       strength = 1,
5838       iterations = 1;
5839
5840   if (typeof radius !== "function") radius = constant$6(radius == null ? 1 : +radius);
5841
5842   function force() {
5843     var i, n = nodes.length,
5844         tree,
5845         node,
5846         xi,
5847         yi,
5848         ri,
5849         ri2;
5850
5851     for (var k = 0; k < iterations; ++k) {
5852       tree = quadtree(nodes, x, y).visitAfter(prepare);
5853       for (i = 0; i < n; ++i) {
5854         node = nodes[i];
5855         ri = radii[node.index], ri2 = ri * ri;
5856         xi = node.x + node.vx;
5857         yi = node.y + node.vy;
5858         tree.visit(apply);
5859       }
5860     }
5861
5862     function apply(quad, x0, y0, x1, y1) {
5863       var data = quad.data, rj = quad.r, r = ri + rj;
5864       if (data) {
5865         if (data.index > node.index) {
5866           var x = xi - data.x - data.vx,
5867               y = yi - data.y - data.vy,
5868               l = x * x + y * y;
5869           if (l < r * r) {
5870             if (x === 0) x = jiggle(), l += x * x;
5871             if (y === 0) y = jiggle(), l += y * y;
5872             l = (r - (l = Math.sqrt(l))) / l * strength;
5873             node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj));
5874             node.vy += (y *= l) * r;
5875             data.vx -= x * (r = 1 - r);
5876             data.vy -= y * r;
5877           }
5878         }
5879         return;
5880       }
5881       return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r;
5882     }
5883   }
5884
5885   function prepare(quad) {
5886     if (quad.data) return quad.r = radii[quad.data.index];
5887     for (var i = quad.r = 0; i < 4; ++i) {
5888       if (quad[i] && quad[i].r > quad.r) {
5889         quad.r = quad[i].r;
5890       }
5891     }
5892   }
5893
5894   function initialize() {
5895     if (!nodes) return;
5896     var i, n = nodes.length, node;
5897     radii = new Array(n);
5898     for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes);
5899   }
5900
5901   force.initialize = function(_) {
5902     nodes = _;
5903     initialize();
5904   };
5905
5906   force.iterations = function(_) {
5907     return arguments.length ? (iterations = +_, force) : iterations;
5908   };
5909
5910   force.strength = function(_) {
5911     return arguments.length ? (strength = +_, force) : strength;
5912   };
5913
5914   force.radius = function(_) {
5915     return arguments.length ? (radius = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : radius;
5916   };
5917
5918   return force;
5919 };
5920
5921 function index$1(d) {
5922   return d.index;
5923 }
5924
5925 function find(nodeById, nodeId) {
5926   var node = nodeById.get(nodeId);
5927   if (!node) throw new Error("missing: " + nodeId);
5928   return node;
5929 }
5930
5931 var link = function(links) {
5932   var id = index$1,
5933       strength = defaultStrength,
5934       strengths,
5935       distance = constant$6(30),
5936       distances,
5937       nodes,
5938       count,
5939       bias,
5940       iterations = 1;
5941
5942   if (links == null) links = [];
5943
5944   function defaultStrength(link) {
5945     return 1 / Math.min(count[link.source.index], count[link.target.index]);
5946   }
5947
5948   function force(alpha) {
5949     for (var k = 0, n = links.length; k < iterations; ++k) {
5950       for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) {
5951         link = links[i], source = link.source, target = link.target;
5952         x = target.x + target.vx - source.x - source.vx || jiggle();
5953         y = target.y + target.vy - source.y - source.vy || jiggle();
5954         l = Math.sqrt(x * x + y * y);
5955         l = (l - distances[i]) / l * alpha * strengths[i];
5956         x *= l, y *= l;
5957         target.vx -= x * (b = bias[i]);
5958         target.vy -= y * b;
5959         source.vx += x * (b = 1 - b);
5960         source.vy += y * b;
5961       }
5962     }
5963   }
5964
5965   function initialize() {
5966     if (!nodes) return;
5967
5968     var i,
5969         n = nodes.length,
5970         m = links.length,
5971         nodeById = map$1(nodes, id),
5972         link;
5973
5974     for (i = 0, count = new Array(n); i < m; ++i) {
5975       link = links[i], link.index = i;
5976       if (typeof link.source !== "object") link.source = find(nodeById, link.source);
5977       if (typeof link.target !== "object") link.target = find(nodeById, link.target);
5978       count[link.source.index] = (count[link.source.index] || 0) + 1;
5979       count[link.target.index] = (count[link.target.index] || 0) + 1;
5980     }
5981
5982     for (i = 0, bias = new Array(m); i < m; ++i) {
5983       link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]);
5984     }
5985
5986     strengths = new Array(m), initializeStrength();
5987     distances = new Array(m), initializeDistance();
5988   }
5989
5990   function initializeStrength() {
5991     if (!nodes) return;
5992
5993     for (var i = 0, n = links.length; i < n; ++i) {
5994       strengths[i] = +strength(links[i], i, links);
5995     }
5996   }
5997
5998   function initializeDistance() {
5999     if (!nodes) return;
6000
6001     for (var i = 0, n = links.length; i < n; ++i) {
6002       distances[i] = +distance(links[i], i, links);
6003     }
6004   }
6005
6006   force.initialize = function(_) {
6007     nodes = _;
6008     initialize();
6009   };
6010
6011   force.links = function(_) {
6012     return arguments.length ? (links = _, initialize(), force) : links;
6013   };
6014
6015   force.id = function(_) {
6016     return arguments.length ? (id = _, force) : id;
6017   };
6018
6019   force.iterations = function(_) {
6020     return arguments.length ? (iterations = +_, force) : iterations;
6021   };
6022
6023   force.strength = function(_) {
6024     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initializeStrength(), force) : strength;
6025   };
6026
6027   force.distance = function(_) {
6028     return arguments.length ? (distance = typeof _ === "function" ? _ : constant$6(+_), initializeDistance(), force) : distance;
6029   };
6030
6031   return force;
6032 };
6033
6034 function x$1(d) {
6035   return d.x;
6036 }
6037
6038 function y$1(d) {
6039   return d.y;
6040 }
6041
6042 var initialRadius = 10;
6043 var initialAngle = Math.PI * (3 - Math.sqrt(5));
6044
6045 var simulation = function(nodes) {
6046   var simulation,
6047       alpha = 1,
6048       alphaMin = 0.001,
6049       alphaDecay = 1 - Math.pow(alphaMin, 1 / 300),
6050       alphaTarget = 0,
6051       velocityDecay = 0.6,
6052       forces = map$1(),
6053       stepper = timer(step),
6054       event = dispatch("tick", "end");
6055
6056   if (nodes == null) nodes = [];
6057
6058   function step() {
6059     tick();
6060     event.call("tick", simulation);
6061     if (alpha < alphaMin) {
6062       stepper.stop();
6063       event.call("end", simulation);
6064     }
6065   }
6066
6067   function tick() {
6068     var i, n = nodes.length, node;
6069
6070     alpha += (alphaTarget - alpha) * alphaDecay;
6071
6072     forces.each(function(force) {
6073       force(alpha);
6074     });
6075
6076     for (i = 0; i < n; ++i) {
6077       node = nodes[i];
6078       if (node.fx == null) node.x += node.vx *= velocityDecay;
6079       else node.x = node.fx, node.vx = 0;
6080       if (node.fy == null) node.y += node.vy *= velocityDecay;
6081       else node.y = node.fy, node.vy = 0;
6082     }
6083   }
6084
6085   function initializeNodes() {
6086     for (var i = 0, n = nodes.length, node; i < n; ++i) {
6087       node = nodes[i], node.index = i;
6088       if (isNaN(node.x) || isNaN(node.y)) {
6089         var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle;
6090         node.x = radius * Math.cos(angle);
6091         node.y = radius * Math.sin(angle);
6092       }
6093       if (isNaN(node.vx) || isNaN(node.vy)) {
6094         node.vx = node.vy = 0;
6095       }
6096     }
6097   }
6098
6099   function initializeForce(force) {
6100     if (force.initialize) force.initialize(nodes);
6101     return force;
6102   }
6103
6104   initializeNodes();
6105
6106   return simulation = {
6107     tick: tick,
6108
6109     restart: function() {
6110       return stepper.restart(step), simulation;
6111     },
6112
6113     stop: function() {
6114       return stepper.stop(), simulation;
6115     },
6116
6117     nodes: function(_) {
6118       return arguments.length ? (nodes = _, initializeNodes(), forces.each(initializeForce), simulation) : nodes;
6119     },
6120
6121     alpha: function(_) {
6122       return arguments.length ? (alpha = +_, simulation) : alpha;
6123     },
6124
6125     alphaMin: function(_) {
6126       return arguments.length ? (alphaMin = +_, simulation) : alphaMin;
6127     },
6128
6129     alphaDecay: function(_) {
6130       return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay;
6131     },
6132
6133     alphaTarget: function(_) {
6134       return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget;
6135     },
6136
6137     velocityDecay: function(_) {
6138       return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay;
6139     },
6140
6141     force: function(name, _) {
6142       return arguments.length > 1 ? (_ == null ? forces.remove(name) : forces.set(name, initializeForce(_)), simulation) : forces.get(name);
6143     },
6144
6145     find: function(x, y, radius) {
6146       var i = 0,
6147           n = nodes.length,
6148           dx,
6149           dy,
6150           d2,
6151           node,
6152           closest;
6153
6154       if (radius == null) radius = Infinity;
6155       else radius *= radius;
6156
6157       for (i = 0; i < n; ++i) {
6158         node = nodes[i];
6159         dx = x - node.x;
6160         dy = y - node.y;
6161         d2 = dx * dx + dy * dy;
6162         if (d2 < radius) closest = node, radius = d2;
6163       }
6164
6165       return closest;
6166     },
6167
6168     on: function(name, _) {
6169       return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name);
6170     }
6171   };
6172 };
6173
6174 var manyBody = function() {
6175   var nodes,
6176       node,
6177       alpha,
6178       strength = constant$6(-30),
6179       strengths,
6180       distanceMin2 = 1,
6181       distanceMax2 = Infinity,
6182       theta2 = 0.81;
6183
6184   function force(_) {
6185     var i, n = nodes.length, tree = quadtree(nodes, x$1, y$1).visitAfter(accumulate);
6186     for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply);
6187   }
6188
6189   function initialize() {
6190     if (!nodes) return;
6191     var i, n = nodes.length, node;
6192     strengths = new Array(n);
6193     for (i = 0; i < n; ++i) node = nodes[i], strengths[node.index] = +strength(node, i, nodes);
6194   }
6195
6196   function accumulate(quad) {
6197     var strength = 0, q, c, weight = 0, x, y, i;
6198
6199     // For internal nodes, accumulate forces from child quadrants.
6200     if (quad.length) {
6201       for (x = y = i = 0; i < 4; ++i) {
6202         if ((q = quad[i]) && (c = Math.abs(q.value))) {
6203           strength += q.value, weight += c, x += c * q.x, y += c * q.y;
6204         }
6205       }
6206       quad.x = x / weight;
6207       quad.y = y / weight;
6208     }
6209
6210     // For leaf nodes, accumulate forces from coincident quadrants.
6211     else {
6212       q = quad;
6213       q.x = q.data.x;
6214       q.y = q.data.y;
6215       do strength += strengths[q.data.index];
6216       while (q = q.next);
6217     }
6218
6219     quad.value = strength;
6220   }
6221
6222   function apply(quad, x1, _, x2) {
6223     if (!quad.value) return true;
6224
6225     var x = quad.x - node.x,
6226         y = quad.y - node.y,
6227         w = x2 - x1,
6228         l = x * x + y * y;
6229
6230     // Apply the Barnes-Hut approximation if possible.
6231     // Limit forces for very close nodes; randomize direction if coincident.
6232     if (w * w / theta2 < l) {
6233       if (l < distanceMax2) {
6234         if (x === 0) x = jiggle(), l += x * x;
6235         if (y === 0) y = jiggle(), l += y * y;
6236         if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
6237         node.vx += x * quad.value * alpha / l;
6238         node.vy += y * quad.value * alpha / l;
6239       }
6240       return true;
6241     }
6242
6243     // Otherwise, process points directly.
6244     else if (quad.length || l >= distanceMax2) return;
6245
6246     // Limit forces for very close nodes; randomize direction if coincident.
6247     if (quad.data !== node || quad.next) {
6248       if (x === 0) x = jiggle(), l += x * x;
6249       if (y === 0) y = jiggle(), l += y * y;
6250       if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l);
6251     }
6252
6253     do if (quad.data !== node) {
6254       w = strengths[quad.data.index] * alpha / l;
6255       node.vx += x * w;
6256       node.vy += y * w;
6257     } while (quad = quad.next);
6258   }
6259
6260   force.initialize = function(_) {
6261     nodes = _;
6262     initialize();
6263   };
6264
6265   force.strength = function(_) {
6266     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
6267   };
6268
6269   force.distanceMin = function(_) {
6270     return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2);
6271   };
6272
6273   force.distanceMax = function(_) {
6274     return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2);
6275   };
6276
6277   force.theta = function(_) {
6278     return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2);
6279   };
6280
6281   return force;
6282 };
6283
6284 var radial = function(radius, x, y) {
6285   var nodes,
6286       strength = constant$6(0.1),
6287       strengths,
6288       radiuses;
6289
6290   if (typeof radius !== "function") radius = constant$6(+radius);
6291   if (x == null) x = 0;
6292   if (y == null) y = 0;
6293
6294   function force(alpha) {
6295     for (var i = 0, n = nodes.length; i < n; ++i) {
6296       var node = nodes[i],
6297           dx = node.x - x || 1e-6,
6298           dy = node.y - y || 1e-6,
6299           r = Math.sqrt(dx * dx + dy * dy),
6300           k = (radiuses[i] - r) * strengths[i] * alpha / r;
6301       node.vx += dx * k;
6302       node.vy += dy * k;
6303     }
6304   }
6305
6306   function initialize() {
6307     if (!nodes) return;
6308     var i, n = nodes.length;
6309     strengths = new Array(n);
6310     radiuses = new Array(n);
6311     for (i = 0; i < n; ++i) {
6312       radiuses[i] = +radius(nodes[i], i, nodes);
6313       strengths[i] = isNaN(radiuses[i]) ? 0 : +strength(nodes[i], i, nodes);
6314     }
6315   }
6316
6317   force.initialize = function(_) {
6318     nodes = _, initialize();
6319   };
6320
6321   force.strength = function(_) {
6322     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
6323   };
6324
6325   force.radius = function(_) {
6326     return arguments.length ? (radius = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : radius;
6327   };
6328
6329   force.x = function(_) {
6330     return arguments.length ? (x = +_, force) : x;
6331   };
6332
6333   force.y = function(_) {
6334     return arguments.length ? (y = +_, force) : y;
6335   };
6336
6337   return force;
6338 };
6339
6340 var x$2 = function(x) {
6341   var strength = constant$6(0.1),
6342       nodes,
6343       strengths,
6344       xz;
6345
6346   if (typeof x !== "function") x = constant$6(x == null ? 0 : +x);
6347
6348   function force(alpha) {
6349     for (var i = 0, n = nodes.length, node; i < n; ++i) {
6350       node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha;
6351     }
6352   }
6353
6354   function initialize() {
6355     if (!nodes) return;
6356     var i, n = nodes.length;
6357     strengths = new Array(n);
6358     xz = new Array(n);
6359     for (i = 0; i < n; ++i) {
6360       strengths[i] = isNaN(xz[i] = +x(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
6361     }
6362   }
6363
6364   force.initialize = function(_) {
6365     nodes = _;
6366     initialize();
6367   };
6368
6369   force.strength = function(_) {
6370     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
6371   };
6372
6373   force.x = function(_) {
6374     return arguments.length ? (x = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : x;
6375   };
6376
6377   return force;
6378 };
6379
6380 var y$2 = function(y) {
6381   var strength = constant$6(0.1),
6382       nodes,
6383       strengths,
6384       yz;
6385
6386   if (typeof y !== "function") y = constant$6(y == null ? 0 : +y);
6387
6388   function force(alpha) {
6389     for (var i = 0, n = nodes.length, node; i < n; ++i) {
6390       node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha;
6391     }
6392   }
6393
6394   function initialize() {
6395     if (!nodes) return;
6396     var i, n = nodes.length;
6397     strengths = new Array(n);
6398     yz = new Array(n);
6399     for (i = 0; i < n; ++i) {
6400       strengths[i] = isNaN(yz[i] = +y(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes);
6401     }
6402   }
6403
6404   force.initialize = function(_) {
6405     nodes = _;
6406     initialize();
6407   };
6408
6409   force.strength = function(_) {
6410     return arguments.length ? (strength = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : strength;
6411   };
6412
6413   force.y = function(_) {
6414     return arguments.length ? (y = typeof _ === "function" ? _ : constant$6(+_), initialize(), force) : y;
6415   };
6416
6417   return force;
6418 };
6419
6420 // Computes the decimal coefficient and exponent of the specified number x with
6421 // significant digits p, where x is positive and p is in [1, 21] or undefined.
6422 // For example, formatDecimal(1.23) returns ["123", 0].
6423 var formatDecimal = function(x, p) {
6424   if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity
6425   var i, coefficient = x.slice(0, i);
6426
6427   // The string returned by toExponential either has the form \d\.\d+e[-+]\d+
6428   // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3).
6429   return [
6430     coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient,
6431     +x.slice(i + 1)
6432   ];
6433 };
6434
6435 var exponent$1 = function(x) {
6436   return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN;
6437 };
6438
6439 var formatGroup = function(grouping, thousands) {
6440   return function(value, width) {
6441     var i = value.length,
6442         t = [],
6443         j = 0,
6444         g = grouping[0],
6445         length = 0;
6446
6447     while (i > 0 && g > 0) {
6448       if (length + g + 1 > width) g = Math.max(1, width - length);
6449       t.push(value.substring(i -= g, i + g));
6450       if ((length += g + 1) > width) break;
6451       g = grouping[j = (j + 1) % grouping.length];
6452     }
6453
6454     return t.reverse().join(thousands);
6455   };
6456 };
6457
6458 var formatNumerals = function(numerals) {
6459   return function(value) {
6460     return value.replace(/[0-9]/g, function(i) {
6461       return numerals[+i];
6462     });
6463   };
6464 };
6465
6466 var formatDefault = function(x, p) {
6467   x = x.toPrecision(p);
6468
6469   out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) {
6470     switch (x[i]) {
6471       case ".": i0 = i1 = i; break;
6472       case "0": if (i0 === 0) i0 = i; i1 = i; break;
6473       case "e": break out;
6474       default: if (i0 > 0) i0 = 0; break;
6475     }
6476   }
6477
6478   return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x;
6479 };
6480
6481 var prefixExponent;
6482
6483 var formatPrefixAuto = function(x, p) {
6484   var d = formatDecimal(x, p);
6485   if (!d) return x + "";
6486   var coefficient = d[0],
6487       exponent = d[1],
6488       i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1,
6489       n = coefficient.length;
6490   return i === n ? coefficient
6491       : i > n ? coefficient + new Array(i - n + 1).join("0")
6492       : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i)
6493       : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y!
6494 };
6495
6496 var formatRounded = function(x, p) {
6497   var d = formatDecimal(x, p);
6498   if (!d) return x + "";
6499   var coefficient = d[0],
6500       exponent = d[1];
6501   return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient
6502       : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1)
6503       : coefficient + new Array(exponent - coefficient.length + 2).join("0");
6504 };
6505
6506 var formatTypes = {
6507   "": formatDefault,
6508   "%": function(x, p) { return (x * 100).toFixed(p); },
6509   "b": function(x) { return Math.round(x).toString(2); },
6510   "c": function(x) { return x + ""; },
6511   "d": function(x) { return Math.round(x).toString(10); },
6512   "e": function(x, p) { return x.toExponential(p); },
6513   "f": function(x, p) { return x.toFixed(p); },
6514   "g": function(x, p) { return x.toPrecision(p); },
6515   "o": function(x) { return Math.round(x).toString(8); },
6516   "p": function(x, p) { return formatRounded(x * 100, p); },
6517   "r": formatRounded,
6518   "s": formatPrefixAuto,
6519   "X": function(x) { return Math.round(x).toString(16).toUpperCase(); },
6520   "x": function(x) { return Math.round(x).toString(16); }
6521 };
6522
6523 // [[fill]align][sign][symbol][0][width][,][.precision][type]
6524 var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i;
6525
6526 function formatSpecifier(specifier) {
6527   return new FormatSpecifier(specifier);
6528 }
6529
6530 formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof
6531
6532 function FormatSpecifier(specifier) {
6533   if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier);
6534
6535   var match,
6536       fill = match[1] || " ",
6537       align = match[2] || ">",
6538       sign = match[3] || "-",
6539       symbol = match[4] || "",
6540       zero = !!match[5],
6541       width = match[6] && +match[6],
6542       comma = !!match[7],
6543       precision = match[8] && +match[8].slice(1),
6544       type = match[9] || "";
6545
6546   // The "n" type is an alias for ",g".
6547   if (type === "n") comma = true, type = "g";
6548
6549   // Map invalid types to the default format.
6550   else if (!formatTypes[type]) type = "";
6551
6552   // If zero fill is specified, padding goes after sign and before digits.
6553   if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "=";
6554
6555   this.fill = fill;
6556   this.align = align;
6557   this.sign = sign;
6558   this.symbol = symbol;
6559   this.zero = zero;
6560   this.width = width;
6561   this.comma = comma;
6562   this.precision = precision;
6563   this.type = type;
6564 }
6565
6566 FormatSpecifier.prototype.toString = function() {
6567   return this.fill
6568       + this.align
6569       + this.sign
6570       + this.symbol
6571       + (this.zero ? "0" : "")
6572       + (this.width == null ? "" : Math.max(1, this.width | 0))
6573       + (this.comma ? "," : "")
6574       + (this.precision == null ? "" : "." + Math.max(0, this.precision | 0))
6575       + this.type;
6576 };
6577
6578 var identity$3 = function(x) {
6579   return x;
6580 };
6581
6582 var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"];
6583
6584 var formatLocale = function(locale) {
6585   var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity$3,
6586       currency = locale.currency,
6587       decimal = locale.decimal,
6588       numerals = locale.numerals ? formatNumerals(locale.numerals) : identity$3,
6589       percent = locale.percent || "%";
6590
6591   function newFormat(specifier) {
6592     specifier = formatSpecifier(specifier);
6593
6594     var fill = specifier.fill,
6595         align = specifier.align,
6596         sign = specifier.sign,
6597         symbol = specifier.symbol,
6598         zero = specifier.zero,
6599         width = specifier.width,
6600         comma = specifier.comma,
6601         precision = specifier.precision,
6602         type = specifier.type;
6603
6604     // Compute the prefix and suffix.
6605     // For SI-prefix, the suffix is lazily computed.
6606     var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "",
6607         suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? percent : "";
6608
6609     // What format function should we use?
6610     // Is this an integer type?
6611     // Can this type generate exponential notation?
6612     var formatType = formatTypes[type],
6613         maybeSuffix = !type || /[defgprs%]/.test(type);
6614
6615     // Set the default precision if not specified,
6616     // or clamp the specified precision to the supported range.
6617     // For significant precision, it must be in [1, 21].
6618     // For fixed precision, it must be in [0, 20].
6619     precision = precision == null ? (type ? 6 : 12)
6620         : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision))
6621         : Math.max(0, Math.min(20, precision));
6622
6623     function format(value) {
6624       var valuePrefix = prefix,
6625           valueSuffix = suffix,
6626           i, n, c;
6627
6628       if (type === "c") {
6629         valueSuffix = formatType(value) + valueSuffix;
6630         value = "";
6631       } else {
6632         value = +value;
6633
6634         // Perform the initial formatting.
6635         var valueNegative = value < 0;
6636         value = formatType(Math.abs(value), precision);
6637
6638         // If a negative value rounds to zero during formatting, treat as positive.
6639         if (valueNegative && +value === 0) valueNegative = false;
6640
6641         // Compute the prefix and suffix.
6642         valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix;
6643         valueSuffix = valueSuffix + (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + (valueNegative && sign === "(" ? ")" : "");
6644
6645         // Break the formatted value into the integer “value” part that can be
6646         // grouped, and fractional or exponential “suffix” part that is not.
6647         if (maybeSuffix) {
6648           i = -1, n = value.length;
6649           while (++i < n) {
6650             if (c = value.charCodeAt(i), 48 > c || c > 57) {
6651               valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix;
6652               value = value.slice(0, i);
6653               break;
6654             }
6655           }
6656         }
6657       }
6658
6659       // If the fill character is not "0", grouping is applied before padding.
6660       if (comma && !zero) value = group(value, Infinity);
6661
6662       // Compute the padding.
6663       var length = valuePrefix.length + value.length + valueSuffix.length,
6664           padding = length < width ? new Array(width - length + 1).join(fill) : "";
6665
6666       // If the fill character is "0", grouping is applied after padding.
6667       if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = "";
6668
6669       // Reconstruct the final output based on the desired alignment.
6670       switch (align) {
6671         case "<": value = valuePrefix + value + valueSuffix + padding; break;
6672         case "=": value = valuePrefix + padding + value + valueSuffix; break;
6673         case "^": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break;
6674         default: value = padding + valuePrefix + value + valueSuffix; break;
6675       }
6676
6677       return numerals(value);
6678     }
6679
6680     format.toString = function() {
6681       return specifier + "";
6682     };
6683
6684     return format;
6685   }
6686
6687   function formatPrefix(specifier, value) {
6688     var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)),
6689         e = Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3,
6690         k = Math.pow(10, -e),
6691         prefix = prefixes[8 + e / 3];
6692     return function(value) {
6693       return f(k * value) + prefix;
6694     };
6695   }
6696
6697   return {
6698     format: newFormat,
6699     formatPrefix: formatPrefix
6700   };
6701 };
6702
6703 var locale;
6704 var format;
6705 var formatPrefix;
6706
6707 defaultLocale({
6708   decimal: ".",
6709   thousands: ",",
6710   grouping: [3],
6711   currency: ["$", ""]
6712 });
6713
6714 function defaultLocale(definition) {
6715   locale = formatLocale(definition);
6716   format = locale.format;
6717   formatPrefix = locale.formatPrefix;
6718   return locale;
6719 }
6720
6721 var precisionFixed = function(step) {
6722   return Math.max(0, -exponent$1(Math.abs(step)));
6723 };
6724
6725 var precisionPrefix = function(step, value) {
6726   return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent$1(value) / 3))) * 3 - exponent$1(Math.abs(step)));
6727 };
6728
6729 var precisionRound = function(step, max) {
6730   step = Math.abs(step), max = Math.abs(max) - step;
6731   return Math.max(0, exponent$1(max) - exponent$1(step)) + 1;
6732 };
6733
6734 // Adds floating point numbers with twice the normal precision.
6735 // Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and
6736 // Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3)
6737 // 305–363 (1997).
6738 // Code adapted from GeographicLib by Charles F. F. Karney,
6739 // http://geographiclib.sourceforge.net/
6740
6741 var adder = function() {
6742   return new Adder;
6743 };
6744
6745 function Adder() {
6746   this.reset();
6747 }
6748
6749 Adder.prototype = {
6750   constructor: Adder,
6751   reset: function() {
6752     this.s = // rounded value
6753     this.t = 0; // exact error
6754   },
6755   add: function(y) {
6756     add$1(temp, y, this.t);
6757     add$1(this, temp.s, this.s);
6758     if (this.s) this.t += temp.t;
6759     else this.s = temp.t;
6760   },
6761   valueOf: function() {
6762     return this.s;
6763   }
6764 };
6765
6766 var temp = new Adder;
6767
6768 function add$1(adder, a, b) {
6769   var x = adder.s = a + b,
6770       bv = x - a,
6771       av = x - bv;
6772   adder.t = (a - av) + (b - bv);
6773 }
6774
6775 var epsilon$2 = 1e-6;
6776 var epsilon2$1 = 1e-12;
6777 var pi$3 = Math.PI;
6778 var halfPi$2 = pi$3 / 2;
6779 var quarterPi = pi$3 / 4;
6780 var tau$3 = pi$3 * 2;
6781
6782 var degrees$1 = 180 / pi$3;
6783 var radians = pi$3 / 180;
6784
6785 var abs = Math.abs;
6786 var atan = Math.atan;
6787 var atan2 = Math.atan2;
6788 var cos$1 = Math.cos;
6789 var ceil = Math.ceil;
6790 var exp = Math.exp;
6791
6792 var log = Math.log;
6793 var pow = Math.pow;
6794 var sin$1 = Math.sin;
6795 var sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; };
6796 var sqrt = Math.sqrt;
6797 var tan = Math.tan;
6798
6799 function acos(x) {
6800   return x > 1 ? 0 : x < -1 ? pi$3 : Math.acos(x);
6801 }
6802
6803 function asin(x) {
6804   return x > 1 ? halfPi$2 : x < -1 ? -halfPi$2 : Math.asin(x);
6805 }
6806
6807 function haversin(x) {
6808   return (x = sin$1(x / 2)) * x;
6809 }
6810
6811 function noop$1() {}
6812
6813 function streamGeometry(geometry, stream) {
6814   if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) {
6815     streamGeometryType[geometry.type](geometry, stream);
6816   }
6817 }
6818
6819 var streamObjectType = {
6820   Feature: function(object, stream) {
6821     streamGeometry(object.geometry, stream);
6822   },
6823   FeatureCollection: function(object, stream) {
6824     var features = object.features, i = -1, n = features.length;
6825     while (++i < n) streamGeometry(features[i].geometry, stream);
6826   }
6827 };
6828
6829 var streamGeometryType = {
6830   Sphere: function(object, stream) {
6831     stream.sphere();
6832   },
6833   Point: function(object, stream) {
6834     object = object.coordinates;
6835     stream.point(object[0], object[1], object[2]);
6836   },
6837   MultiPoint: function(object, stream) {
6838     var coordinates = object.coordinates, i = -1, n = coordinates.length;
6839     while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]);
6840   },
6841   LineString: function(object, stream) {
6842     streamLine(object.coordinates, stream, 0);
6843   },
6844   MultiLineString: function(object, stream) {
6845     var coordinates = object.coordinates, i = -1, n = coordinates.length;
6846     while (++i < n) streamLine(coordinates[i], stream, 0);
6847   },
6848   Polygon: function(object, stream) {
6849     streamPolygon(object.coordinates, stream);
6850   },
6851   MultiPolygon: function(object, stream) {
6852     var coordinates = object.coordinates, i = -1, n = coordinates.length;
6853     while (++i < n) streamPolygon(coordinates[i], stream);
6854   },
6855   GeometryCollection: function(object, stream) {
6856     var geometries = object.geometries, i = -1, n = geometries.length;
6857     while (++i < n) streamGeometry(geometries[i], stream);
6858   }
6859 };
6860
6861 function streamLine(coordinates, stream, closed) {
6862   var i = -1, n = coordinates.length - closed, coordinate;
6863   stream.lineStart();
6864   while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]);
6865   stream.lineEnd();
6866 }
6867
6868 function streamPolygon(coordinates, stream) {
6869   var i = -1, n = coordinates.length;
6870   stream.polygonStart();
6871   while (++i < n) streamLine(coordinates[i], stream, 1);
6872   stream.polygonEnd();
6873 }
6874
6875 var d3_geoStream = function(object, stream) {
6876   if (object && streamObjectType.hasOwnProperty(object.type)) {
6877     streamObjectType[object.type](object, stream);
6878   } else {
6879     streamGeometry(object, stream);
6880   }
6881 };
6882
6883 var areaRingSum = adder();
6884
6885 var areaSum = adder();
6886 var lambda00;
6887 var phi00;
6888 var lambda0;
6889 var cosPhi0;
6890 var sinPhi0;
6891
6892 var areaStream = {
6893   point: noop$1,
6894   lineStart: noop$1,
6895   lineEnd: noop$1,
6896   polygonStart: function() {
6897     areaRingSum.reset();
6898     areaStream.lineStart = areaRingStart;
6899     areaStream.lineEnd = areaRingEnd;
6900   },
6901   polygonEnd: function() {
6902     var areaRing = +areaRingSum;
6903     areaSum.add(areaRing < 0 ? tau$3 + areaRing : areaRing);
6904     this.lineStart = this.lineEnd = this.point = noop$1;
6905   },
6906   sphere: function() {
6907     areaSum.add(tau$3);
6908   }
6909 };
6910
6911 function areaRingStart() {
6912   areaStream.point = areaPointFirst;
6913 }
6914
6915 function areaRingEnd() {
6916   areaPoint(lambda00, phi00);
6917 }
6918
6919 function areaPointFirst(lambda, phi) {
6920   areaStream.point = areaPoint;
6921   lambda00 = lambda, phi00 = phi;
6922   lambda *= radians, phi *= radians;
6923   lambda0 = lambda, cosPhi0 = cos$1(phi = phi / 2 + quarterPi), sinPhi0 = sin$1(phi);
6924 }
6925
6926 function areaPoint(lambda, phi) {
6927   lambda *= radians, phi *= radians;
6928   phi = phi / 2 + quarterPi; // half the angular distance from south pole
6929
6930   // Spherical excess E for a spherical triangle with vertices: south pole,
6931   // previous point, current point.  Uses a formula derived from Cagnoli’s
6932   // theorem.  See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2).
6933   var dLambda = lambda - lambda0,
6934       sdLambda = dLambda >= 0 ? 1 : -1,
6935       adLambda = sdLambda * dLambda,
6936       cosPhi = cos$1(phi),
6937       sinPhi = sin$1(phi),
6938       k = sinPhi0 * sinPhi,
6939       u = cosPhi0 * cosPhi + k * cos$1(adLambda),
6940       v = k * sdLambda * sin$1(adLambda);
6941   areaRingSum.add(atan2(v, u));
6942
6943   // Advance the previous points.
6944   lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi;
6945 }
6946
6947 var d3_geoArea = function(object) {
6948   areaSum.reset();
6949   d3_geoStream(object, areaStream);
6950   return areaSum * 2;
6951 };
6952
6953 function spherical(cartesian) {
6954   return [atan2(cartesian[1], cartesian[0]), asin(cartesian[2])];
6955 }
6956
6957 function cartesian(spherical) {
6958   var lambda = spherical[0], phi = spherical[1], cosPhi = cos$1(phi);
6959   return [cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)];
6960 }
6961
6962 function cartesianDot(a, b) {
6963   return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
6964 }
6965
6966 function cartesianCross(a, b) {
6967   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]];
6968 }
6969
6970 // TODO return a
6971 function cartesianAddInPlace(a, b) {
6972   a[0] += b[0], a[1] += b[1], a[2] += b[2];
6973 }
6974
6975 function cartesianScale(vector, k) {
6976   return [vector[0] * k, vector[1] * k, vector[2] * k];
6977 }
6978
6979 // TODO return d
6980 function cartesianNormalizeInPlace(d) {
6981   var l = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
6982   d[0] /= l, d[1] /= l, d[2] /= l;
6983 }
6984
6985 var lambda0$1;
6986 var phi0;
6987 var lambda1;
6988 var phi1;
6989 var lambda2;
6990 var lambda00$1;
6991 var phi00$1;
6992 var p0;
6993 var deltaSum = adder();
6994 var ranges;
6995 var range;
6996
6997 var boundsStream = {
6998   point: boundsPoint,
6999   lineStart: boundsLineStart,
7000   lineEnd: boundsLineEnd,
7001   polygonStart: function() {
7002     boundsStream.point = boundsRingPoint;
7003     boundsStream.lineStart = boundsRingStart;
7004     boundsStream.lineEnd = boundsRingEnd;
7005     deltaSum.reset();
7006     areaStream.polygonStart();
7007   },
7008   polygonEnd: function() {
7009     areaStream.polygonEnd();
7010     boundsStream.point = boundsPoint;
7011     boundsStream.lineStart = boundsLineStart;
7012     boundsStream.lineEnd = boundsLineEnd;
7013     if (areaRingSum < 0) lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90);
7014     else if (deltaSum > epsilon$2) phi1 = 90;
7015     else if (deltaSum < -epsilon$2) phi0 = -90;
7016     range[0] = lambda0$1, range[1] = lambda1;
7017   }
7018 };
7019
7020 function boundsPoint(lambda, phi) {
7021   ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);
7022   if (phi < phi0) phi0 = phi;
7023   if (phi > phi1) phi1 = phi;
7024 }
7025
7026 function linePoint(lambda, phi) {
7027   var p = cartesian([lambda * radians, phi * radians]);
7028   if (p0) {
7029     var normal = cartesianCross(p0, p),
7030         equatorial = [normal[1], -normal[0], 0],
7031         inflection = cartesianCross(equatorial, normal);
7032     cartesianNormalizeInPlace(inflection);
7033     inflection = spherical(inflection);
7034     var delta = lambda - lambda2,
7035         sign$$1 = delta > 0 ? 1 : -1,
7036         lambdai = inflection[0] * degrees$1 * sign$$1,
7037         phii,
7038         antimeridian = abs(delta) > 180;
7039     if (antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {
7040       phii = inflection[1] * degrees$1;
7041       if (phii > phi1) phi1 = phii;
7042     } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign$$1 * lambda2 < lambdai && lambdai < sign$$1 * lambda)) {
7043       phii = -inflection[1] * degrees$1;
7044       if (phii < phi0) phi0 = phii;
7045     } else {
7046       if (phi < phi0) phi0 = phi;
7047       if (phi > phi1) phi1 = phi;
7048     }
7049     if (antimeridian) {
7050       if (lambda < lambda2) {
7051         if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
7052       } else {
7053         if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
7054       }
7055     } else {
7056       if (lambda1 >= lambda0$1) {
7057         if (lambda < lambda0$1) lambda0$1 = lambda;
7058         if (lambda > lambda1) lambda1 = lambda;
7059       } else {
7060         if (lambda > lambda2) {
7061           if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
7062         } else {
7063           if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
7064         }
7065       }
7066     }
7067   } else {
7068     ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);
7069   }
7070   if (phi < phi0) phi0 = phi;
7071   if (phi > phi1) phi1 = phi;
7072   p0 = p, lambda2 = lambda;
7073 }
7074
7075 function boundsLineStart() {
7076   boundsStream.point = linePoint;
7077 }
7078
7079 function boundsLineEnd() {
7080   range[0] = lambda0$1, range[1] = lambda1;
7081   boundsStream.point = boundsPoint;
7082   p0 = null;
7083 }
7084
7085 function boundsRingPoint(lambda, phi) {
7086   if (p0) {
7087     var delta = lambda - lambda2;
7088     deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta);
7089   } else {
7090     lambda00$1 = lambda, phi00$1 = phi;
7091   }
7092   areaStream.point(lambda, phi);
7093   linePoint(lambda, phi);
7094 }
7095
7096 function boundsRingStart() {
7097   areaStream.lineStart();
7098 }
7099
7100 function boundsRingEnd() {
7101   boundsRingPoint(lambda00$1, phi00$1);
7102   areaStream.lineEnd();
7103   if (abs(deltaSum) > epsilon$2) lambda0$1 = -(lambda1 = 180);
7104   range[0] = lambda0$1, range[1] = lambda1;
7105   p0 = null;
7106 }
7107
7108 // Finds the left-right distance between two longitudes.
7109 // This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want
7110 // the distance between ±180° to be 360°.
7111 function angle(lambda0, lambda1) {
7112   return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1;
7113 }
7114
7115 function rangeCompare(a, b) {
7116   return a[0] - b[0];
7117 }
7118
7119 function rangeContains(range, x) {
7120   return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;
7121 }
7122
7123 var d3_geoBounds = function(feature) {
7124   var i, n, a, b, merged, deltaMax, delta;
7125
7126   phi1 = lambda1 = -(lambda0$1 = phi0 = Infinity);
7127   ranges = [];
7128   d3_geoStream(feature, boundsStream);
7129
7130   // First, sort ranges by their minimum longitudes.
7131   if (n = ranges.length) {
7132     ranges.sort(rangeCompare);
7133
7134     // Then, merge any ranges that overlap.
7135     for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) {
7136       b = ranges[i];
7137       if (rangeContains(a, b[0]) || rangeContains(a, b[1])) {
7138         if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1];
7139         if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0];
7140       } else {
7141         merged.push(a = b);
7142       }
7143     }
7144
7145     // Finally, find the largest gap between the merged ranges.
7146     // The final bounding box will be the inverse of this gap.
7147     for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) {
7148       b = merged[i];
7149       if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0$1 = b[0], lambda1 = a[1];
7150     }
7151   }
7152
7153   ranges = range = null;
7154
7155   return lambda0$1 === Infinity || phi0 === Infinity
7156       ? [[NaN, NaN], [NaN, NaN]]
7157       : [[lambda0$1, phi0], [lambda1, phi1]];
7158 };
7159
7160 var W0;
7161 var W1;
7162 var X0;
7163 var Y0;
7164 var Z0;
7165 var X1;
7166 var Y1;
7167 var Z1;
7168 var X2;
7169 var Y2;
7170 var Z2;
7171 var lambda00$2;
7172 var phi00$2;
7173 var x0;
7174 var y0;
7175 var z0; // previous point
7176
7177 var centroidStream = {
7178   sphere: noop$1,
7179   point: centroidPoint,
7180   lineStart: centroidLineStart,
7181   lineEnd: centroidLineEnd,
7182   polygonStart: function() {
7183     centroidStream.lineStart = centroidRingStart;
7184     centroidStream.lineEnd = centroidRingEnd;
7185   },
7186   polygonEnd: function() {
7187     centroidStream.lineStart = centroidLineStart;
7188     centroidStream.lineEnd = centroidLineEnd;
7189   }
7190 };
7191
7192 // Arithmetic mean of Cartesian vectors.
7193 function centroidPoint(lambda, phi) {
7194   lambda *= radians, phi *= radians;
7195   var cosPhi = cos$1(phi);
7196   centroidPointCartesian(cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi));
7197 }
7198
7199 function centroidPointCartesian(x, y, z) {
7200   ++W0;
7201   X0 += (x - X0) / W0;
7202   Y0 += (y - Y0) / W0;
7203   Z0 += (z - Z0) / W0;
7204 }
7205
7206 function centroidLineStart() {
7207   centroidStream.point = centroidLinePointFirst;
7208 }
7209
7210 function centroidLinePointFirst(lambda, phi) {
7211   lambda *= radians, phi *= radians;
7212   var cosPhi = cos$1(phi);
7213   x0 = cosPhi * cos$1(lambda);
7214   y0 = cosPhi * sin$1(lambda);
7215   z0 = sin$1(phi);
7216   centroidStream.point = centroidLinePoint;
7217   centroidPointCartesian(x0, y0, z0);
7218 }
7219
7220 function centroidLinePoint(lambda, phi) {
7221   lambda *= radians, phi *= radians;
7222   var cosPhi = cos$1(phi),
7223       x = cosPhi * cos$1(lambda),
7224       y = cosPhi * sin$1(lambda),
7225       z = sin$1(phi),
7226       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);
7227   W1 += w;
7228   X1 += w * (x0 + (x0 = x));
7229   Y1 += w * (y0 + (y0 = y));
7230   Z1 += w * (z0 + (z0 = z));
7231   centroidPointCartesian(x0, y0, z0);
7232 }
7233
7234 function centroidLineEnd() {
7235   centroidStream.point = centroidPoint;
7236 }
7237
7238 // See J. E. Brock, The Inertia Tensor for a Spherical Triangle,
7239 // J. Applied Mechanics 42, 239 (1975).
7240 function centroidRingStart() {
7241   centroidStream.point = centroidRingPointFirst;
7242 }
7243
7244 function centroidRingEnd() {
7245   centroidRingPoint(lambda00$2, phi00$2);
7246   centroidStream.point = centroidPoint;
7247 }
7248
7249 function centroidRingPointFirst(lambda, phi) {
7250   lambda00$2 = lambda, phi00$2 = phi;
7251   lambda *= radians, phi *= radians;
7252   centroidStream.point = centroidRingPoint;
7253   var cosPhi = cos$1(phi);
7254   x0 = cosPhi * cos$1(lambda);
7255   y0 = cosPhi * sin$1(lambda);
7256   z0 = sin$1(phi);
7257   centroidPointCartesian(x0, y0, z0);
7258 }
7259
7260 function centroidRingPoint(lambda, phi) {
7261   lambda *= radians, phi *= radians;
7262   var cosPhi = cos$1(phi),
7263       x = cosPhi * cos$1(lambda),
7264       y = cosPhi * sin$1(lambda),
7265       z = sin$1(phi),
7266       cx = y0 * z - z0 * y,
7267       cy = z0 * x - x0 * z,
7268       cz = x0 * y - y0 * x,
7269       m = sqrt(cx * cx + cy * cy + cz * cz),
7270       w = asin(m), // line weight = angle
7271       v = m && -w / m; // area weight multiplier
7272   X2 += v * cx;
7273   Y2 += v * cy;
7274   Z2 += v * cz;
7275   W1 += w;
7276   X1 += w * (x0 + (x0 = x));
7277   Y1 += w * (y0 + (y0 = y));
7278   Z1 += w * (z0 + (z0 = z));
7279   centroidPointCartesian(x0, y0, z0);
7280 }
7281
7282 var d3_geoCentroid = function(object) {
7283   W0 = W1 =
7284   X0 = Y0 = Z0 =
7285   X1 = Y1 = Z1 =
7286   X2 = Y2 = Z2 = 0;
7287   d3_geoStream(object, centroidStream);
7288
7289   var x = X2,
7290       y = Y2,
7291       z = Z2,
7292       m = x * x + y * y + z * z;
7293
7294   // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid.
7295   if (m < epsilon2$1) {
7296     x = X1, y = Y1, z = Z1;
7297     // If the feature has zero length, fall back to arithmetic mean of point vectors.
7298     if (W1 < epsilon$2) x = X0, y = Y0, z = Z0;
7299     m = x * x + y * y + z * z;
7300     // If the feature still has an undefined ccentroid, then return.
7301     if (m < epsilon2$1) return [NaN, NaN];
7302   }
7303
7304   return [atan2(y, x) * degrees$1, asin(z / sqrt(m)) * degrees$1];
7305 };
7306
7307 var constant$7 = function(x) {
7308   return function() {
7309     return x;
7310   };
7311 };
7312
7313 var compose = function(a, b) {
7314
7315   function compose(x, y) {
7316     return x = a(x, y), b(x[0], x[1]);
7317   }
7318
7319   if (a.invert && b.invert) compose.invert = function(x, y) {
7320     return x = b.invert(x, y), x && a.invert(x[0], x[1]);
7321   };
7322
7323   return compose;
7324 };
7325
7326 function rotationIdentity(lambda, phi) {
7327   return [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi];
7328 }
7329
7330 rotationIdentity.invert = rotationIdentity;
7331
7332 function rotateRadians(deltaLambda, deltaPhi, deltaGamma) {
7333   return (deltaLambda %= tau$3) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma))
7334     : rotationLambda(deltaLambda))
7335     : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma)
7336     : rotationIdentity);
7337 }
7338
7339 function forwardRotationLambda(deltaLambda) {
7340   return function(lambda, phi) {
7341     return lambda += deltaLambda, [lambda > pi$3 ? lambda - tau$3 : lambda < -pi$3 ? lambda + tau$3 : lambda, phi];
7342   };
7343 }
7344
7345 function rotationLambda(deltaLambda) {
7346   var rotation = forwardRotationLambda(deltaLambda);
7347   rotation.invert = forwardRotationLambda(-deltaLambda);
7348   return rotation;
7349 }
7350
7351 function rotationPhiGamma(deltaPhi, deltaGamma) {
7352   var cosDeltaPhi = cos$1(deltaPhi),
7353       sinDeltaPhi = sin$1(deltaPhi),
7354       cosDeltaGamma = cos$1(deltaGamma),
7355       sinDeltaGamma = sin$1(deltaGamma);
7356
7357   function rotation(lambda, phi) {
7358     var cosPhi = cos$1(phi),
7359         x = cos$1(lambda) * cosPhi,
7360         y = sin$1(lambda) * cosPhi,
7361         z = sin$1(phi),
7362         k = z * cosDeltaPhi + x * sinDeltaPhi;
7363     return [
7364       atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi),
7365       asin(k * cosDeltaGamma + y * sinDeltaGamma)
7366     ];
7367   }
7368
7369   rotation.invert = function(lambda, phi) {
7370     var cosPhi = cos$1(phi),
7371         x = cos$1(lambda) * cosPhi,
7372         y = sin$1(lambda) * cosPhi,
7373         z = sin$1(phi),
7374         k = z * cosDeltaGamma - y * sinDeltaGamma;
7375     return [
7376       atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi),
7377       asin(k * cosDeltaPhi - x * sinDeltaPhi)
7378     ];
7379   };
7380
7381   return rotation;
7382 }
7383
7384 var rotation = function(rotate) {
7385   rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0);
7386
7387   function forward(coordinates) {
7388     coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians);
7389     return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;
7390   }
7391
7392   forward.invert = function(coordinates) {
7393     coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians);
7394     return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates;
7395   };
7396
7397   return forward;
7398 };
7399
7400 // Generates a circle centered at [0°, 0°], with a given radius and precision.
7401 function circleStream(stream, radius, delta, direction, t0, t1) {
7402   if (!delta) return;
7403   var cosRadius = cos$1(radius),
7404       sinRadius = sin$1(radius),
7405       step = direction * delta;
7406   if (t0 == null) {
7407     t0 = radius + direction * tau$3;
7408     t1 = radius - step / 2;
7409   } else {
7410     t0 = circleRadius(cosRadius, t0);
7411     t1 = circleRadius(cosRadius, t1);
7412     if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau$3;
7413   }
7414   for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) {
7415     point = spherical([cosRadius, -sinRadius * cos$1(t), -sinRadius * sin$1(t)]);
7416     stream.point(point[0], point[1]);
7417   }
7418 }
7419
7420 // Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0].
7421 function circleRadius(cosRadius, point) {
7422   point = cartesian(point), point[0] -= cosRadius;
7423   cartesianNormalizeInPlace(point);
7424   var radius = acos(-point[1]);
7425   return ((-point[2] < 0 ? -radius : radius) + tau$3 - epsilon$2) % tau$3;
7426 }
7427
7428 var circle = function() {
7429   var center = constant$7([0, 0]),
7430       radius = constant$7(90),
7431       precision = constant$7(6),
7432       ring,
7433       rotate,
7434       stream = {point: point};
7435
7436   function point(x, y) {
7437     ring.push(x = rotate(x, y));
7438     x[0] *= degrees$1, x[1] *= degrees$1;
7439   }
7440
7441   function circle() {
7442     var c = center.apply(this, arguments),
7443         r = radius.apply(this, arguments) * radians,
7444         p = precision.apply(this, arguments) * radians;
7445     ring = [];
7446     rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert;
7447     circleStream(stream, r, p, 1);
7448     c = {type: "Polygon", coordinates: [ring]};
7449     ring = rotate = null;
7450     return c;
7451   }
7452
7453   circle.center = function(_) {
7454     return arguments.length ? (center = typeof _ === "function" ? _ : constant$7([+_[0], +_[1]]), circle) : center;
7455   };
7456
7457   circle.radius = function(_) {
7458     return arguments.length ? (radius = typeof _ === "function" ? _ : constant$7(+_), circle) : radius;
7459   };
7460
7461   circle.precision = function(_) {
7462     return arguments.length ? (precision = typeof _ === "function" ? _ : constant$7(+_), circle) : precision;
7463   };
7464
7465   return circle;
7466 };
7467
7468 var clipBuffer = function() {
7469   var lines = [],
7470       line;
7471   return {
7472     point: function(x, y) {
7473       line.push([x, y]);
7474     },
7475     lineStart: function() {
7476       lines.push(line = []);
7477     },
7478     lineEnd: noop$1,
7479     rejoin: function() {
7480       if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));
7481     },
7482     result: function() {
7483       var result = lines;
7484       lines = [];
7485       line = null;
7486       return result;
7487     }
7488   };
7489 };
7490
7491 var pointEqual = function(a, b) {
7492   return abs(a[0] - b[0]) < epsilon$2 && abs(a[1] - b[1]) < epsilon$2;
7493 };
7494
7495 function Intersection(point, points, other, entry) {
7496   this.x = point;
7497   this.z = points;
7498   this.o = other; // another intersection
7499   this.e = entry; // is an entry?
7500   this.v = false; // visited
7501   this.n = this.p = null; // next & previous
7502 }
7503
7504 // A generalized polygon clipping algorithm: given a polygon that has been cut
7505 // into its visible line segments, and rejoins the segments by interpolating
7506 // along the clip edge.
7507 var clipRejoin = function(segments, compareIntersection, startInside, interpolate, stream) {
7508   var subject = [],
7509       clip = [],
7510       i,
7511       n;
7512
7513   segments.forEach(function(segment) {
7514     if ((n = segment.length - 1) <= 0) return;
7515     var n, p0 = segment[0], p1 = segment[n], x;
7516
7517     // If the first and last points of a segment are coincident, then treat as a
7518     // closed ring. TODO if all rings are closed, then the winding order of the
7519     // exterior ring should be checked.
7520     if (pointEqual(p0, p1)) {
7521       stream.lineStart();
7522       for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]);
7523       stream.lineEnd();
7524       return;
7525     }
7526
7527     subject.push(x = new Intersection(p0, segment, null, true));
7528     clip.push(x.o = new Intersection(p0, null, x, false));
7529     subject.push(x = new Intersection(p1, segment, null, false));
7530     clip.push(x.o = new Intersection(p1, null, x, true));
7531   });
7532
7533   if (!subject.length) return;
7534
7535   clip.sort(compareIntersection);
7536   link$1(subject);
7537   link$1(clip);
7538
7539   for (i = 0, n = clip.length; i < n; ++i) {
7540     clip[i].e = startInside = !startInside;
7541   }
7542
7543   var start = subject[0],
7544       points,
7545       point;
7546
7547   while (1) {
7548     // Find first unvisited intersection.
7549     var current = start,
7550         isSubject = true;
7551     while (current.v) if ((current = current.n) === start) return;
7552     points = current.z;
7553     stream.lineStart();
7554     do {
7555       current.v = current.o.v = true;
7556       if (current.e) {
7557         if (isSubject) {
7558           for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]);
7559         } else {
7560           interpolate(current.x, current.n.x, 1, stream);
7561         }
7562         current = current.n;
7563       } else {
7564         if (isSubject) {
7565           points = current.p.z;
7566           for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]);
7567         } else {
7568           interpolate(current.x, current.p.x, -1, stream);
7569         }
7570         current = current.p;
7571       }
7572       current = current.o;
7573       points = current.z;
7574       isSubject = !isSubject;
7575     } while (!current.v);
7576     stream.lineEnd();
7577   }
7578 };
7579
7580 function link$1(array) {
7581   if (!(n = array.length)) return;
7582   var n,
7583       i = 0,
7584       a = array[0],
7585       b;
7586   while (++i < n) {
7587     a.n = b = array[i];
7588     b.p = a;
7589     a = b;
7590   }
7591   a.n = b = array[0];
7592   b.p = a;
7593 }
7594
7595 var sum$1 = adder();
7596
7597 var polygonContains = function(polygon, point) {
7598   var lambda = point[0],
7599       phi = point[1],
7600       normal = [sin$1(lambda), -cos$1(lambda), 0],
7601       angle = 0,
7602       winding = 0;
7603
7604   sum$1.reset();
7605
7606   for (var i = 0, n = polygon.length; i < n; ++i) {
7607     if (!(m = (ring = polygon[i]).length)) continue;
7608     var ring,
7609         m,
7610         point0 = ring[m - 1],
7611         lambda0 = point0[0],
7612         phi0 = point0[1] / 2 + quarterPi,
7613         sinPhi0 = sin$1(phi0),
7614         cosPhi0 = cos$1(phi0);
7615
7616     for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) {
7617       var point1 = ring[j],
7618           lambda1 = point1[0],
7619           phi1 = point1[1] / 2 + quarterPi,
7620           sinPhi1 = sin$1(phi1),
7621           cosPhi1 = cos$1(phi1),
7622           delta = lambda1 - lambda0,
7623           sign$$1 = delta >= 0 ? 1 : -1,
7624           absDelta = sign$$1 * delta,
7625           antimeridian = absDelta > pi$3,
7626           k = sinPhi0 * sinPhi1;
7627
7628       sum$1.add(atan2(k * sign$$1 * sin$1(absDelta), cosPhi0 * cosPhi1 + k * cos$1(absDelta)));
7629       angle += antimeridian ? delta + sign$$1 * tau$3 : delta;
7630
7631       // Are the longitudes either side of the point’s meridian (lambda),
7632       // and are the latitudes smaller than the parallel (phi)?
7633       if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) {
7634         var arc = cartesianCross(cartesian(point0), cartesian(point1));
7635         cartesianNormalizeInPlace(arc);
7636         var intersection = cartesianCross(normal, arc);
7637         cartesianNormalizeInPlace(intersection);
7638         var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin(intersection[2]);
7639         if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) {
7640           winding += antimeridian ^ delta >= 0 ? 1 : -1;
7641         }
7642       }
7643     }
7644   }
7645
7646   // First, determine whether the South pole is inside or outside:
7647   //
7648   // It is inside if:
7649   // * the polygon winds around it in a clockwise direction.
7650   // * the polygon does not (cumulatively) wind around it, but has a negative
7651   //   (counter-clockwise) area.
7652   //
7653   // Second, count the (signed) number of times a segment crosses a lambda
7654   // from the point to the South pole.  If it is zero, then the point is the
7655   // same side as the South pole.
7656
7657   return (angle < -epsilon$2 || angle < epsilon$2 && sum$1 < -epsilon$2) ^ (winding & 1);
7658 };
7659
7660 var clip = function(pointVisible, clipLine, interpolate, start) {
7661   return function(sink) {
7662     var line = clipLine(sink),
7663         ringBuffer = clipBuffer(),
7664         ringSink = clipLine(ringBuffer),
7665         polygonStarted = false,
7666         polygon,
7667         segments,
7668         ring;
7669
7670     var clip = {
7671       point: point,
7672       lineStart: lineStart,
7673       lineEnd: lineEnd,
7674       polygonStart: function() {
7675         clip.point = pointRing;
7676         clip.lineStart = ringStart;
7677         clip.lineEnd = ringEnd;
7678         segments = [];
7679         polygon = [];
7680       },
7681       polygonEnd: function() {
7682         clip.point = point;
7683         clip.lineStart = lineStart;
7684         clip.lineEnd = lineEnd;
7685         segments = merge(segments);
7686         var startInside = polygonContains(polygon, start);
7687         if (segments.length) {
7688           if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
7689           clipRejoin(segments, compareIntersection, startInside, interpolate, sink);
7690         } else if (startInside) {
7691           if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
7692           sink.lineStart();
7693           interpolate(null, null, 1, sink);
7694           sink.lineEnd();
7695         }
7696         if (polygonStarted) sink.polygonEnd(), polygonStarted = false;
7697         segments = polygon = null;
7698       },
7699       sphere: function() {
7700         sink.polygonStart();
7701         sink.lineStart();
7702         interpolate(null, null, 1, sink);
7703         sink.lineEnd();
7704         sink.polygonEnd();
7705       }
7706     };
7707
7708     function point(lambda, phi) {
7709       if (pointVisible(lambda, phi)) sink.point(lambda, phi);
7710     }
7711
7712     function pointLine(lambda, phi) {
7713       line.point(lambda, phi);
7714     }
7715
7716     function lineStart() {
7717       clip.point = pointLine;
7718       line.lineStart();
7719     }
7720
7721     function lineEnd() {
7722       clip.point = point;
7723       line.lineEnd();
7724     }
7725
7726     function pointRing(lambda, phi) {
7727       ring.push([lambda, phi]);
7728       ringSink.point(lambda, phi);
7729     }
7730
7731     function ringStart() {
7732       ringSink.lineStart();
7733       ring = [];
7734     }
7735
7736     function ringEnd() {
7737       pointRing(ring[0][0], ring[0][1]);
7738       ringSink.lineEnd();
7739
7740       var clean = ringSink.clean(),
7741           ringSegments = ringBuffer.result(),
7742           i, n = ringSegments.length, m,
7743           segment,
7744           point;
7745
7746       ring.pop();
7747       polygon.push(ring);
7748       ring = null;
7749
7750       if (!n) return;
7751
7752       // No intersections.
7753       if (clean & 1) {
7754         segment = ringSegments[0];
7755         if ((m = segment.length - 1) > 0) {
7756           if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
7757           sink.lineStart();
7758           for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]);
7759           sink.lineEnd();
7760         }
7761         return;
7762       }
7763
7764       // Rejoin connected segments.
7765       // TODO reuse ringBuffer.rejoin()?
7766       if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
7767
7768       segments.push(ringSegments.filter(validSegment));
7769     }
7770
7771     return clip;
7772   };
7773 };
7774
7775 function validSegment(segment) {
7776   return segment.length > 1;
7777 }
7778
7779 // Intersections are sorted along the clip edge. For both antimeridian cutting
7780 // and circle clipping, the same comparison is used.
7781 function compareIntersection(a, b) {
7782   return ((a = a.x)[0] < 0 ? a[1] - halfPi$2 - epsilon$2 : halfPi$2 - a[1])
7783        - ((b = b.x)[0] < 0 ? b[1] - halfPi$2 - epsilon$2 : halfPi$2 - b[1]);
7784 }
7785
7786 var clipAntimeridian = clip(
7787   function() { return true; },
7788   clipAntimeridianLine,
7789   clipAntimeridianInterpolate,
7790   [-pi$3, -halfPi$2]
7791 );
7792
7793 // Takes a line and cuts into visible segments. Return values: 0 - there were
7794 // intersections or the line was empty; 1 - no intersections; 2 - there were
7795 // intersections, and the first and last segments should be rejoined.
7796 function clipAntimeridianLine(stream) {
7797   var lambda0 = NaN,
7798       phi0 = NaN,
7799       sign0 = NaN,
7800       clean; // no intersections
7801
7802   return {
7803     lineStart: function() {
7804       stream.lineStart();
7805       clean = 1;
7806     },
7807     point: function(lambda1, phi1) {
7808       var sign1 = lambda1 > 0 ? pi$3 : -pi$3,
7809           delta = abs(lambda1 - lambda0);
7810       if (abs(delta - pi$3) < epsilon$2) { // line crosses a pole
7811         stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi$2 : -halfPi$2);
7812         stream.point(sign0, phi0);
7813         stream.lineEnd();
7814         stream.lineStart();
7815         stream.point(sign1, phi0);
7816         stream.point(lambda1, phi0);
7817         clean = 0;
7818       } else if (sign0 !== sign1 && delta >= pi$3) { // line crosses antimeridian
7819         if (abs(lambda0 - sign0) < epsilon$2) lambda0 -= sign0 * epsilon$2; // handle degeneracies
7820         if (abs(lambda1 - sign1) < epsilon$2) lambda1 -= sign1 * epsilon$2;
7821         phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1);
7822         stream.point(sign0, phi0);
7823         stream.lineEnd();
7824         stream.lineStart();
7825         stream.point(sign1, phi0);
7826         clean = 0;
7827       }
7828       stream.point(lambda0 = lambda1, phi0 = phi1);
7829       sign0 = sign1;
7830     },
7831     lineEnd: function() {
7832       stream.lineEnd();
7833       lambda0 = phi0 = NaN;
7834     },
7835     clean: function() {
7836       return 2 - clean; // if intersections, rejoin first and last segments
7837     }
7838   };
7839 }
7840
7841 function clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) {
7842   var cosPhi0,
7843       cosPhi1,
7844       sinLambda0Lambda1 = sin$1(lambda0 - lambda1);
7845   return abs(sinLambda0Lambda1) > epsilon$2
7846       ? atan((sin$1(phi0) * (cosPhi1 = cos$1(phi1)) * sin$1(lambda1)
7847           - sin$1(phi1) * (cosPhi0 = cos$1(phi0)) * sin$1(lambda0))
7848           / (cosPhi0 * cosPhi1 * sinLambda0Lambda1))
7849       : (phi0 + phi1) / 2;
7850 }
7851
7852 function clipAntimeridianInterpolate(from, to, direction, stream) {
7853   var phi;
7854   if (from == null) {
7855     phi = direction * halfPi$2;
7856     stream.point(-pi$3, phi);
7857     stream.point(0, phi);
7858     stream.point(pi$3, phi);
7859     stream.point(pi$3, 0);
7860     stream.point(pi$3, -phi);
7861     stream.point(0, -phi);
7862     stream.point(-pi$3, -phi);
7863     stream.point(-pi$3, 0);
7864     stream.point(-pi$3, phi);
7865   } else if (abs(from[0] - to[0]) > epsilon$2) {
7866     var lambda = from[0] < to[0] ? pi$3 : -pi$3;
7867     phi = direction * lambda / 2;
7868     stream.point(-lambda, phi);
7869     stream.point(0, phi);
7870     stream.point(lambda, phi);
7871   } else {
7872     stream.point(to[0], to[1]);
7873   }
7874 }
7875
7876 var clipCircle = function(radius) {
7877   var cr = cos$1(radius),
7878       delta = 6 * radians,
7879       smallRadius = cr > 0,
7880       notHemisphere = abs(cr) > epsilon$2; // TODO optimise for this common case
7881
7882   function interpolate(from, to, direction, stream) {
7883     circleStream(stream, radius, delta, direction, from, to);
7884   }
7885
7886   function visible(lambda, phi) {
7887     return cos$1(lambda) * cos$1(phi) > cr;
7888   }
7889
7890   // Takes a line and cuts into visible segments. Return values used for polygon
7891   // clipping: 0 - there were intersections or the line was empty; 1 - no
7892   // intersections 2 - there were intersections, and the first and last segments
7893   // should be rejoined.
7894   function clipLine(stream) {
7895     var point0, // previous point
7896         c0, // code for previous point
7897         v0, // visibility of previous point
7898         v00, // visibility of first point
7899         clean; // no intersections
7900     return {
7901       lineStart: function() {
7902         v00 = v0 = false;
7903         clean = 1;
7904       },
7905       point: function(lambda, phi) {
7906         var point1 = [lambda, phi],
7907             point2,
7908             v = visible(lambda, phi),
7909             c = smallRadius
7910               ? v ? 0 : code(lambda, phi)
7911               : v ? code(lambda + (lambda < 0 ? pi$3 : -pi$3), phi) : 0;
7912         if (!point0 && (v00 = v0 = v)) stream.lineStart();
7913         // Handle degeneracies.
7914         // TODO ignore if not clipping polygons.
7915         if (v !== v0) {
7916           point2 = intersect(point0, point1);
7917           if (!point2 || pointEqual(point0, point2) || pointEqual(point1, point2)) {
7918             point1[0] += epsilon$2;
7919             point1[1] += epsilon$2;
7920             v = visible(point1[0], point1[1]);
7921           }
7922         }
7923         if (v !== v0) {
7924           clean = 0;
7925           if (v) {
7926             // outside going in
7927             stream.lineStart();
7928             point2 = intersect(point1, point0);
7929             stream.point(point2[0], point2[1]);
7930           } else {
7931             // inside going out
7932             point2 = intersect(point0, point1);
7933             stream.point(point2[0], point2[1]);
7934             stream.lineEnd();
7935           }
7936           point0 = point2;
7937         } else if (notHemisphere && point0 && smallRadius ^ v) {
7938           var t;
7939           // If the codes for two points are different, or are both zero,
7940           // and there this segment intersects with the small circle.
7941           if (!(c & c0) && (t = intersect(point1, point0, true))) {
7942             clean = 0;
7943             if (smallRadius) {
7944               stream.lineStart();
7945               stream.point(t[0][0], t[0][1]);
7946               stream.point(t[1][0], t[1][1]);
7947               stream.lineEnd();
7948             } else {
7949               stream.point(t[1][0], t[1][1]);
7950               stream.lineEnd();
7951               stream.lineStart();
7952               stream.point(t[0][0], t[0][1]);
7953             }
7954           }
7955         }
7956         if (v && (!point0 || !pointEqual(point0, point1))) {
7957           stream.point(point1[0], point1[1]);
7958         }
7959         point0 = point1, v0 = v, c0 = c;
7960       },
7961       lineEnd: function() {
7962         if (v0) stream.lineEnd();
7963         point0 = null;
7964       },
7965       // Rejoin first and last segments if there were intersections and the first
7966       // and last points were visible.
7967       clean: function() {
7968         return clean | ((v00 && v0) << 1);
7969       }
7970     };
7971   }
7972
7973   // Intersects the great circle between a and b with the clip circle.
7974   function intersect(a, b, two) {
7975     var pa = cartesian(a),
7976         pb = cartesian(b);
7977
7978     // We have two planes, n1.p = d1 and n2.p = d2.
7979     // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2).
7980     var n1 = [1, 0, 0], // normal
7981         n2 = cartesianCross(pa, pb),
7982         n2n2 = cartesianDot(n2, n2),
7983         n1n2 = n2[0], // cartesianDot(n1, n2),
7984         determinant = n2n2 - n1n2 * n1n2;
7985
7986     // Two polar points.
7987     if (!determinant) return !two && a;
7988
7989     var c1 =  cr * n2n2 / determinant,
7990         c2 = -cr * n1n2 / determinant,
7991         n1xn2 = cartesianCross(n1, n2),
7992         A = cartesianScale(n1, c1),
7993         B = cartesianScale(n2, c2);
7994     cartesianAddInPlace(A, B);
7995
7996     // Solve |p(t)|^2 = 1.
7997     var u = n1xn2,
7998         w = cartesianDot(A, u),
7999         uu = cartesianDot(u, u),
8000         t2 = w * w - uu * (cartesianDot(A, A) - 1);
8001
8002     if (t2 < 0) return;
8003
8004     var t = sqrt(t2),
8005         q = cartesianScale(u, (-w - t) / uu);
8006     cartesianAddInPlace(q, A);
8007     q = spherical(q);
8008
8009     if (!two) return q;
8010
8011     // Two intersection points.
8012     var lambda0 = a[0],
8013         lambda1 = b[0],
8014         phi0 = a[1],
8015         phi1 = b[1],
8016         z;
8017
8018     if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z;
8019
8020     var delta = lambda1 - lambda0,
8021         polar = abs(delta - pi$3) < epsilon$2,
8022         meridian = polar || delta < epsilon$2;
8023
8024     if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z;
8025
8026     // Check that the first point is between a and b.
8027     if (meridian
8028         ? polar
8029           ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon$2 ? phi0 : phi1)
8030           : phi0 <= q[1] && q[1] <= phi1
8031         : delta > pi$3 ^ (lambda0 <= q[0] && q[0] <= lambda1)) {
8032       var q1 = cartesianScale(u, (-w + t) / uu);
8033       cartesianAddInPlace(q1, A);
8034       return [q, spherical(q1)];
8035     }
8036   }
8037
8038   // Generates a 4-bit vector representing the location of a point relative to
8039   // the small circle's bounding box.
8040   function code(lambda, phi) {
8041     var r = smallRadius ? radius : pi$3 - radius,
8042         code = 0;
8043     if (lambda < -r) code |= 1; // left
8044     else if (lambda > r) code |= 2; // right
8045     if (phi < -r) code |= 4; // below
8046     else if (phi > r) code |= 8; // above
8047     return code;
8048   }
8049
8050   return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi$3, radius - pi$3]);
8051 };
8052
8053 var clipLine = function(a, b, x0, y0, x1, y1) {
8054   var ax = a[0],
8055       ay = a[1],
8056       bx = b[0],
8057       by = b[1],
8058       t0 = 0,
8059       t1 = 1,
8060       dx = bx - ax,
8061       dy = by - ay,
8062       r;
8063
8064   r = x0 - ax;
8065   if (!dx && r > 0) return;
8066   r /= dx;
8067   if (dx < 0) {
8068     if (r < t0) return;
8069     if (r < t1) t1 = r;
8070   } else if (dx > 0) {
8071     if (r > t1) return;
8072     if (r > t0) t0 = r;
8073   }
8074
8075   r = x1 - ax;
8076   if (!dx && r < 0) return;
8077   r /= dx;
8078   if (dx < 0) {
8079     if (r > t1) return;
8080     if (r > t0) t0 = r;
8081   } else if (dx > 0) {
8082     if (r < t0) return;
8083     if (r < t1) t1 = r;
8084   }
8085
8086   r = y0 - ay;
8087   if (!dy && r > 0) return;
8088   r /= dy;
8089   if (dy < 0) {
8090     if (r < t0) return;
8091     if (r < t1) t1 = r;
8092   } else if (dy > 0) {
8093     if (r > t1) return;
8094     if (r > t0) t0 = r;
8095   }
8096
8097   r = y1 - ay;
8098   if (!dy && r < 0) return;
8099   r /= dy;
8100   if (dy < 0) {
8101     if (r > t1) return;
8102     if (r > t0) t0 = r;
8103   } else if (dy > 0) {
8104     if (r < t0) return;
8105     if (r < t1) t1 = r;
8106   }
8107
8108   if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy;
8109   if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy;
8110   return true;
8111 };
8112
8113 var clipMax = 1e9;
8114 var clipMin = -clipMax;
8115
8116 // TODO Use d3-polygon’s polygonContains here for the ring check?
8117 // TODO Eliminate duplicate buffering in clipBuffer and polygon.push?
8118
8119 function clipRectangle(x0, y0, x1, y1) {
8120
8121   function visible(x, y) {
8122     return x0 <= x && x <= x1 && y0 <= y && y <= y1;
8123   }
8124
8125   function interpolate(from, to, direction, stream) {
8126     var a = 0, a1 = 0;
8127     if (from == null
8128         || (a = corner(from, direction)) !== (a1 = corner(to, direction))
8129         || comparePoint(from, to) < 0 ^ direction > 0) {
8130       do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);
8131       while ((a = (a + direction + 4) % 4) !== a1);
8132     } else {
8133       stream.point(to[0], to[1]);
8134     }
8135   }
8136
8137   function corner(p, direction) {
8138     return abs(p[0] - x0) < epsilon$2 ? direction > 0 ? 0 : 3
8139         : abs(p[0] - x1) < epsilon$2 ? direction > 0 ? 2 : 1
8140         : abs(p[1] - y0) < epsilon$2 ? direction > 0 ? 1 : 0
8141         : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon
8142   }
8143
8144   function compareIntersection(a, b) {
8145     return comparePoint(a.x, b.x);
8146   }
8147
8148   function comparePoint(a, b) {
8149     var ca = corner(a, 1),
8150         cb = corner(b, 1);
8151     return ca !== cb ? ca - cb
8152         : ca === 0 ? b[1] - a[1]
8153         : ca === 1 ? a[0] - b[0]
8154         : ca === 2 ? a[1] - b[1]
8155         : b[0] - a[0];
8156   }
8157
8158   return function(stream) {
8159     var activeStream = stream,
8160         bufferStream = clipBuffer(),
8161         segments,
8162         polygon,
8163         ring,
8164         x__, y__, v__, // first point
8165         x_, y_, v_, // previous point
8166         first,
8167         clean;
8168
8169     var clipStream = {
8170       point: point,
8171       lineStart: lineStart,
8172       lineEnd: lineEnd,
8173       polygonStart: polygonStart,
8174       polygonEnd: polygonEnd
8175     };
8176
8177     function point(x, y) {
8178       if (visible(x, y)) activeStream.point(x, y);
8179     }
8180
8181     function polygonInside() {
8182       var winding = 0;
8183
8184       for (var i = 0, n = polygon.length; i < n; ++i) {
8185         for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) {
8186           a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1];
8187           if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; }
8188           else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; }
8189         }
8190       }
8191
8192       return winding;
8193     }
8194
8195     // Buffer geometry within a polygon and then clip it en masse.
8196     function polygonStart() {
8197       activeStream = bufferStream, segments = [], polygon = [], clean = true;
8198     }
8199
8200     function polygonEnd() {
8201       var startInside = polygonInside(),
8202           cleanInside = clean && startInside,
8203           visible = (segments = merge(segments)).length;
8204       if (cleanInside || visible) {
8205         stream.polygonStart();
8206         if (cleanInside) {
8207           stream.lineStart();
8208           interpolate(null, null, 1, stream);
8209           stream.lineEnd();
8210         }
8211         if (visible) {
8212           clipRejoin(segments, compareIntersection, startInside, interpolate, stream);
8213         }
8214         stream.polygonEnd();
8215       }
8216       activeStream = stream, segments = polygon = ring = null;
8217     }
8218
8219     function lineStart() {
8220       clipStream.point = linePoint;
8221       if (polygon) polygon.push(ring = []);
8222       first = true;
8223       v_ = false;
8224       x_ = y_ = NaN;
8225     }
8226
8227     // TODO rather than special-case polygons, simply handle them separately.
8228     // Ideally, coincident intersection points should be jittered to avoid
8229     // clipping issues.
8230     function lineEnd() {
8231       if (segments) {
8232         linePoint(x__, y__);
8233         if (v__ && v_) bufferStream.rejoin();
8234         segments.push(bufferStream.result());
8235       }
8236       clipStream.point = point;
8237       if (v_) activeStream.lineEnd();
8238     }
8239
8240     function linePoint(x, y) {
8241       var v = visible(x, y);
8242       if (polygon) ring.push([x, y]);
8243       if (first) {
8244         x__ = x, y__ = y, v__ = v;
8245         first = false;
8246         if (v) {
8247           activeStream.lineStart();
8248           activeStream.point(x, y);
8249         }
8250       } else {
8251         if (v && v_) activeStream.point(x, y);
8252         else {
8253           var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))],
8254               b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))];
8255           if (clipLine(a, b, x0, y0, x1, y1)) {
8256             if (!v_) {
8257               activeStream.lineStart();
8258               activeStream.point(a[0], a[1]);
8259             }
8260             activeStream.point(b[0], b[1]);
8261             if (!v) activeStream.lineEnd();
8262             clean = false;
8263           } else if (v) {
8264             activeStream.lineStart();
8265             activeStream.point(x, y);
8266             clean = false;
8267           }
8268         }
8269       }
8270       x_ = x, y_ = y, v_ = v;
8271     }
8272
8273     return clipStream;
8274   };
8275 }
8276
8277 var extent$1 = function() {
8278   var x0 = 0,
8279       y0 = 0,
8280       x1 = 960,
8281       y1 = 500,
8282       cache,
8283       cacheStream,
8284       clip;
8285
8286   return clip = {
8287     stream: function(stream) {
8288       return cache && cacheStream === stream ? cache : cache = clipRectangle(x0, y0, x1, y1)(cacheStream = stream);
8289     },
8290     extent: function(_) {
8291       return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]];
8292     }
8293   };
8294 };
8295
8296 var lengthSum = adder();
8297 var lambda0$2;
8298 var sinPhi0$1;
8299 var cosPhi0$1;
8300
8301 var lengthStream = {
8302   sphere: noop$1,
8303   point: noop$1,
8304   lineStart: lengthLineStart,
8305   lineEnd: noop$1,
8306   polygonStart: noop$1,
8307   polygonEnd: noop$1
8308 };
8309
8310 function lengthLineStart() {
8311   lengthStream.point = lengthPointFirst;
8312   lengthStream.lineEnd = lengthLineEnd;
8313 }
8314
8315 function lengthLineEnd() {
8316   lengthStream.point = lengthStream.lineEnd = noop$1;
8317 }
8318
8319 function lengthPointFirst(lambda, phi) {
8320   lambda *= radians, phi *= radians;
8321   lambda0$2 = lambda, sinPhi0$1 = sin$1(phi), cosPhi0$1 = cos$1(phi);
8322   lengthStream.point = lengthPoint;
8323 }
8324
8325 function lengthPoint(lambda, phi) {
8326   lambda *= radians, phi *= radians;
8327   var sinPhi = sin$1(phi),
8328       cosPhi = cos$1(phi),
8329       delta = abs(lambda - lambda0$2),
8330       cosDelta = cos$1(delta),
8331       sinDelta = sin$1(delta),
8332       x = cosPhi * sinDelta,
8333       y = cosPhi0$1 * sinPhi - sinPhi0$1 * cosPhi * cosDelta,
8334       z = sinPhi0$1 * sinPhi + cosPhi0$1 * cosPhi * cosDelta;
8335   lengthSum.add(atan2(sqrt(x * x + y * y), z));
8336   lambda0$2 = lambda, sinPhi0$1 = sinPhi, cosPhi0$1 = cosPhi;
8337 }
8338
8339 var d3_geoLength = function(object) {
8340   lengthSum.reset();
8341   d3_geoStream(object, lengthStream);
8342   return +lengthSum;
8343 };
8344
8345 var coordinates = [null, null];
8346 var object$1 = {type: "LineString", coordinates: coordinates};
8347
8348 var distance = function(a, b) {
8349   coordinates[0] = a;
8350   coordinates[1] = b;
8351   return d3_geoLength(object$1);
8352 };
8353
8354 var containsObjectType = {
8355   Feature: function(object, point) {
8356     return containsGeometry(object.geometry, point);
8357   },
8358   FeatureCollection: function(object, point) {
8359     var features = object.features, i = -1, n = features.length;
8360     while (++i < n) if (containsGeometry(features[i].geometry, point)) return true;
8361     return false;
8362   }
8363 };
8364
8365 var containsGeometryType = {
8366   Sphere: function() {
8367     return true;
8368   },
8369   Point: function(object, point) {
8370     return containsPoint(object.coordinates, point);
8371   },
8372   MultiPoint: function(object, point) {
8373     var coordinates = object.coordinates, i = -1, n = coordinates.length;
8374     while (++i < n) if (containsPoint(coordinates[i], point)) return true;
8375     return false;
8376   },
8377   LineString: function(object, point) {
8378     return containsLine(object.coordinates, point);
8379   },
8380   MultiLineString: function(object, point) {
8381     var coordinates = object.coordinates, i = -1, n = coordinates.length;
8382     while (++i < n) if (containsLine(coordinates[i], point)) return true;
8383     return false;
8384   },
8385   Polygon: function(object, point) {
8386     return containsPolygon(object.coordinates, point);
8387   },
8388   MultiPolygon: function(object, point) {
8389     var coordinates = object.coordinates, i = -1, n = coordinates.length;
8390     while (++i < n) if (containsPolygon(coordinates[i], point)) return true;
8391     return false;
8392   },
8393   GeometryCollection: function(object, point) {
8394     var geometries = object.geometries, i = -1, n = geometries.length;
8395     while (++i < n) if (containsGeometry(geometries[i], point)) return true;
8396     return false;
8397   }
8398 };
8399
8400 function containsGeometry(geometry, point) {
8401   return geometry && containsGeometryType.hasOwnProperty(geometry.type)
8402       ? containsGeometryType[geometry.type](geometry, point)
8403       : false;
8404 }
8405
8406 function containsPoint(coordinates, point) {
8407   return distance(coordinates, point) === 0;
8408 }
8409
8410 function containsLine(coordinates, point) {
8411   var ab = distance(coordinates[0], coordinates[1]),
8412       ao = distance(coordinates[0], point),
8413       ob = distance(point, coordinates[1]);
8414   return ao + ob <= ab + epsilon$2;
8415 }
8416
8417 function containsPolygon(coordinates, point) {
8418   return !!polygonContains(coordinates.map(ringRadians), pointRadians(point));
8419 }
8420
8421 function ringRadians(ring) {
8422   return ring = ring.map(pointRadians), ring.pop(), ring;
8423 }
8424
8425 function pointRadians(point) {
8426   return [point[0] * radians, point[1] * radians];
8427 }
8428
8429 var contains = function(object, point) {
8430   return (object && containsObjectType.hasOwnProperty(object.type)
8431       ? containsObjectType[object.type]
8432       : containsGeometry)(object, point);
8433 };
8434
8435 function graticuleX(y0, y1, dy) {
8436   var y = d3_range(y0, y1 - epsilon$2, dy).concat(y1);
8437   return function(x) { return y.map(function(y) { return [x, y]; }); };
8438 }
8439
8440 function graticuleY(x0, x1, dx) {
8441   var x = d3_range(x0, x1 - epsilon$2, dx).concat(x1);
8442   return function(y) { return x.map(function(x) { return [x, y]; }); };
8443 }
8444
8445 function graticule() {
8446   var x1, x0, X1, X0,
8447       y1, y0, Y1, Y0,
8448       dx = 10, dy = dx, DX = 90, DY = 360,
8449       x, y, X, Y,
8450       precision = 2.5;
8451
8452   function graticule() {
8453     return {type: "MultiLineString", coordinates: lines()};
8454   }
8455
8456   function lines() {
8457     return d3_range(ceil(X0 / DX) * DX, X1, DX).map(X)
8458         .concat(d3_range(ceil(Y0 / DY) * DY, Y1, DY).map(Y))
8459         .concat(d3_range(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon$2; }).map(x))
8460         .concat(d3_range(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon$2; }).map(y));
8461   }
8462
8463   graticule.lines = function() {
8464     return lines().map(function(coordinates) { return {type: "LineString", coordinates: coordinates}; });
8465   };
8466
8467   graticule.outline = function() {
8468     return {
8469       type: "Polygon",
8470       coordinates: [
8471         X(X0).concat(
8472         Y(Y1).slice(1),
8473         X(X1).reverse().slice(1),
8474         Y(Y0).reverse().slice(1))
8475       ]
8476     };
8477   };
8478
8479   graticule.extent = function(_) {
8480     if (!arguments.length) return graticule.extentMinor();
8481     return graticule.extentMajor(_).extentMinor(_);
8482   };
8483
8484   graticule.extentMajor = function(_) {
8485     if (!arguments.length) return [[X0, Y0], [X1, Y1]];
8486     X0 = +_[0][0], X1 = +_[1][0];
8487     Y0 = +_[0][1], Y1 = +_[1][1];
8488     if (X0 > X1) _ = X0, X0 = X1, X1 = _;
8489     if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;
8490     return graticule.precision(precision);
8491   };
8492
8493   graticule.extentMinor = function(_) {
8494     if (!arguments.length) return [[x0, y0], [x1, y1]];
8495     x0 = +_[0][0], x1 = +_[1][0];
8496     y0 = +_[0][1], y1 = +_[1][1];
8497     if (x0 > x1) _ = x0, x0 = x1, x1 = _;
8498     if (y0 > y1) _ = y0, y0 = y1, y1 = _;
8499     return graticule.precision(precision);
8500   };
8501
8502   graticule.step = function(_) {
8503     if (!arguments.length) return graticule.stepMinor();
8504     return graticule.stepMajor(_).stepMinor(_);
8505   };
8506
8507   graticule.stepMajor = function(_) {
8508     if (!arguments.length) return [DX, DY];
8509     DX = +_[0], DY = +_[1];
8510     return graticule;
8511   };
8512
8513   graticule.stepMinor = function(_) {
8514     if (!arguments.length) return [dx, dy];
8515     dx = +_[0], dy = +_[1];
8516     return graticule;
8517   };
8518
8519   graticule.precision = function(_) {
8520     if (!arguments.length) return precision;
8521     precision = +_;
8522     x = graticuleX(y0, y1, 90);
8523     y = graticuleY(x0, x1, precision);
8524     X = graticuleX(Y0, Y1, 90);
8525     Y = graticuleY(X0, X1, precision);
8526     return graticule;
8527   };
8528
8529   return graticule
8530       .extentMajor([[-180, -90 + epsilon$2], [180, 90 - epsilon$2]])
8531       .extentMinor([[-180, -80 - epsilon$2], [180, 80 + epsilon$2]]);
8532 }
8533
8534 function graticule10() {
8535   return graticule()();
8536 }
8537
8538 var interpolate$1 = function(a, b) {
8539   var x0 = a[0] * radians,
8540       y0 = a[1] * radians,
8541       x1 = b[0] * radians,
8542       y1 = b[1] * radians,
8543       cy0 = cos$1(y0),
8544       sy0 = sin$1(y0),
8545       cy1 = cos$1(y1),
8546       sy1 = sin$1(y1),
8547       kx0 = cy0 * cos$1(x0),
8548       ky0 = cy0 * sin$1(x0),
8549       kx1 = cy1 * cos$1(x1),
8550       ky1 = cy1 * sin$1(x1),
8551       d = 2 * asin(sqrt(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))),
8552       k = sin$1(d);
8553
8554   var interpolate = d ? function(t) {
8555     var B = sin$1(t *= d) / k,
8556         A = sin$1(d - t) / k,
8557         x = A * kx0 + B * kx1,
8558         y = A * ky0 + B * ky1,
8559         z = A * sy0 + B * sy1;
8560     return [
8561       atan2(y, x) * degrees$1,
8562       atan2(z, sqrt(x * x + y * y)) * degrees$1
8563     ];
8564   } : function() {
8565     return [x0 * degrees$1, y0 * degrees$1];
8566   };
8567
8568   interpolate.distance = d;
8569
8570   return interpolate;
8571 };
8572
8573 var identity$4 = function(x) {
8574   return x;
8575 };
8576
8577 var areaSum$1 = adder();
8578 var areaRingSum$1 = adder();
8579 var x00;
8580 var y00;
8581 var x0$1;
8582 var y0$1;
8583
8584 var areaStream$1 = {
8585   point: noop$1,
8586   lineStart: noop$1,
8587   lineEnd: noop$1,
8588   polygonStart: function() {
8589     areaStream$1.lineStart = areaRingStart$1;
8590     areaStream$1.lineEnd = areaRingEnd$1;
8591   },
8592   polygonEnd: function() {
8593     areaStream$1.lineStart = areaStream$1.lineEnd = areaStream$1.point = noop$1;
8594     areaSum$1.add(abs(areaRingSum$1));
8595     areaRingSum$1.reset();
8596   },
8597   result: function() {
8598     var area = areaSum$1 / 2;
8599     areaSum$1.reset();
8600     return area;
8601   }
8602 };
8603
8604 function areaRingStart$1() {
8605   areaStream$1.point = areaPointFirst$1;
8606 }
8607
8608 function areaPointFirst$1(x, y) {
8609   areaStream$1.point = areaPoint$1;
8610   x00 = x0$1 = x, y00 = y0$1 = y;
8611 }
8612
8613 function areaPoint$1(x, y) {
8614   areaRingSum$1.add(y0$1 * x - x0$1 * y);
8615   x0$1 = x, y0$1 = y;
8616 }
8617
8618 function areaRingEnd$1() {
8619   areaPoint$1(x00, y00);
8620 }
8621
8622 var x0$2 = Infinity;
8623 var y0$2 = x0$2;
8624 var x1 = -x0$2;
8625 var y1 = x1;
8626
8627 var boundsStream$1 = {
8628   point: boundsPoint$1,
8629   lineStart: noop$1,
8630   lineEnd: noop$1,
8631   polygonStart: noop$1,
8632   polygonEnd: noop$1,
8633   result: function() {
8634     var bounds = [[x0$2, y0$2], [x1, y1]];
8635     x1 = y1 = -(y0$2 = x0$2 = Infinity);
8636     return bounds;
8637   }
8638 };
8639
8640 function boundsPoint$1(x, y) {
8641   if (x < x0$2) x0$2 = x;
8642   if (x > x1) x1 = x;
8643   if (y < y0$2) y0$2 = y;
8644   if (y > y1) y1 = y;
8645 }
8646
8647 // TODO Enforce positive area for exterior, negative area for interior?
8648
8649 var X0$1 = 0;
8650 var Y0$1 = 0;
8651 var Z0$1 = 0;
8652 var X1$1 = 0;
8653 var Y1$1 = 0;
8654 var Z1$1 = 0;
8655 var X2$1 = 0;
8656 var Y2$1 = 0;
8657 var Z2$1 = 0;
8658 var x00$1;
8659 var y00$1;
8660 var x0$3;
8661 var y0$3;
8662
8663 var centroidStream$1 = {
8664   point: centroidPoint$1,
8665   lineStart: centroidLineStart$1,
8666   lineEnd: centroidLineEnd$1,
8667   polygonStart: function() {
8668     centroidStream$1.lineStart = centroidRingStart$1;
8669     centroidStream$1.lineEnd = centroidRingEnd$1;
8670   },
8671   polygonEnd: function() {
8672     centroidStream$1.point = centroidPoint$1;
8673     centroidStream$1.lineStart = centroidLineStart$1;
8674     centroidStream$1.lineEnd = centroidLineEnd$1;
8675   },
8676   result: function() {
8677     var centroid = Z2$1 ? [X2$1 / Z2$1, Y2$1 / Z2$1]
8678         : Z1$1 ? [X1$1 / Z1$1, Y1$1 / Z1$1]
8679         : Z0$1 ? [X0$1 / Z0$1, Y0$1 / Z0$1]
8680         : [NaN, NaN];
8681     X0$1 = Y0$1 = Z0$1 =
8682     X1$1 = Y1$1 = Z1$1 =
8683     X2$1 = Y2$1 = Z2$1 = 0;
8684     return centroid;
8685   }
8686 };
8687
8688 function centroidPoint$1(x, y) {
8689   X0$1 += x;
8690   Y0$1 += y;
8691   ++Z0$1;
8692 }
8693
8694 function centroidLineStart$1() {
8695   centroidStream$1.point = centroidPointFirstLine;
8696 }
8697
8698 function centroidPointFirstLine(x, y) {
8699   centroidStream$1.point = centroidPointLine;
8700   centroidPoint$1(x0$3 = x, y0$3 = y);
8701 }
8702
8703 function centroidPointLine(x, y) {
8704   var dx = x - x0$3, dy = y - y0$3, z = sqrt(dx * dx + dy * dy);
8705   X1$1 += z * (x0$3 + x) / 2;
8706   Y1$1 += z * (y0$3 + y) / 2;
8707   Z1$1 += z;
8708   centroidPoint$1(x0$3 = x, y0$3 = y);
8709 }
8710
8711 function centroidLineEnd$1() {
8712   centroidStream$1.point = centroidPoint$1;
8713 }
8714
8715 function centroidRingStart$1() {
8716   centroidStream$1.point = centroidPointFirstRing;
8717 }
8718
8719 function centroidRingEnd$1() {
8720   centroidPointRing(x00$1, y00$1);
8721 }
8722
8723 function centroidPointFirstRing(x, y) {
8724   centroidStream$1.point = centroidPointRing;
8725   centroidPoint$1(x00$1 = x0$3 = x, y00$1 = y0$3 = y);
8726 }
8727
8728 function centroidPointRing(x, y) {
8729   var dx = x - x0$3,
8730       dy = y - y0$3,
8731       z = sqrt(dx * dx + dy * dy);
8732
8733   X1$1 += z * (x0$3 + x) / 2;
8734   Y1$1 += z * (y0$3 + y) / 2;
8735   Z1$1 += z;
8736
8737   z = y0$3 * x - x0$3 * y;
8738   X2$1 += z * (x0$3 + x);
8739   Y2$1 += z * (y0$3 + y);
8740   Z2$1 += z * 3;
8741   centroidPoint$1(x0$3 = x, y0$3 = y);
8742 }
8743
8744 function PathContext(context) {
8745   this._context = context;
8746 }
8747
8748 PathContext.prototype = {
8749   _radius: 4.5,
8750   pointRadius: function(_) {
8751     return this._radius = _, this;
8752   },
8753   polygonStart: function() {
8754     this._line = 0;
8755   },
8756   polygonEnd: function() {
8757     this._line = NaN;
8758   },
8759   lineStart: function() {
8760     this._point = 0;
8761   },
8762   lineEnd: function() {
8763     if (this._line === 0) this._context.closePath();
8764     this._point = NaN;
8765   },
8766   point: function(x, y) {
8767     switch (this._point) {
8768       case 0: {
8769         this._context.moveTo(x, y);
8770         this._point = 1;
8771         break;
8772       }
8773       case 1: {
8774         this._context.lineTo(x, y);
8775         break;
8776       }
8777       default: {
8778         this._context.moveTo(x + this._radius, y);
8779         this._context.arc(x, y, this._radius, 0, tau$3);
8780         break;
8781       }
8782     }
8783   },
8784   result: noop$1
8785 };
8786
8787 var lengthSum$1 = adder();
8788 var lengthRing;
8789 var x00$2;
8790 var y00$2;
8791 var x0$4;
8792 var y0$4;
8793
8794 var lengthStream$1 = {
8795   point: noop$1,
8796   lineStart: function() {
8797     lengthStream$1.point = lengthPointFirst$1;
8798   },
8799   lineEnd: function() {
8800     if (lengthRing) lengthPoint$1(x00$2, y00$2);
8801     lengthStream$1.point = noop$1;
8802   },
8803   polygonStart: function() {
8804     lengthRing = true;
8805   },
8806   polygonEnd: function() {
8807     lengthRing = null;
8808   },
8809   result: function() {
8810     var length = +lengthSum$1;
8811     lengthSum$1.reset();
8812     return length;
8813   }
8814 };
8815
8816 function lengthPointFirst$1(x, y) {
8817   lengthStream$1.point = lengthPoint$1;
8818   x00$2 = x0$4 = x, y00$2 = y0$4 = y;
8819 }
8820
8821 function lengthPoint$1(x, y) {
8822   x0$4 -= x, y0$4 -= y;
8823   lengthSum$1.add(sqrt(x0$4 * x0$4 + y0$4 * y0$4));
8824   x0$4 = x, y0$4 = y;
8825 }
8826
8827 function PathString() {
8828   this._string = [];
8829 }
8830
8831 PathString.prototype = {
8832   _radius: 4.5,
8833   _circle: circle$1(4.5),
8834   pointRadius: function(_) {
8835     if ((_ = +_) !== this._radius) this._radius = _, this._circle = null;
8836     return this;
8837   },
8838   polygonStart: function() {
8839     this._line = 0;
8840   },
8841   polygonEnd: function() {
8842     this._line = NaN;
8843   },
8844   lineStart: function() {
8845     this._point = 0;
8846   },
8847   lineEnd: function() {
8848     if (this._line === 0) this._string.push("Z");
8849     this._point = NaN;
8850   },
8851   point: function(x, y) {
8852     switch (this._point) {
8853       case 0: {
8854         this._string.push("M", x, ",", y);
8855         this._point = 1;
8856         break;
8857       }
8858       case 1: {
8859         this._string.push("L", x, ",", y);
8860         break;
8861       }
8862       default: {
8863         if (this._circle == null) this._circle = circle$1(this._radius);
8864         this._string.push("M", x, ",", y, this._circle);
8865         break;
8866       }
8867     }
8868   },
8869   result: function() {
8870     if (this._string.length) {
8871       var result = this._string.join("");
8872       this._string = [];
8873       return result;
8874     } else {
8875       return null;
8876     }
8877   }
8878 };
8879
8880 function circle$1(radius) {
8881   return "m0," + radius
8882       + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius
8883       + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius
8884       + "z";
8885 }
8886
8887 var d3_geoPath = function(projection, context) {
8888   var pointRadius = 4.5,
8889       projectionStream,
8890       contextStream;
8891
8892   function path(object) {
8893     if (object) {
8894       if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments));
8895       d3_geoStream(object, projectionStream(contextStream));
8896     }
8897     return contextStream.result();
8898   }
8899
8900   path.area = function(object) {
8901     d3_geoStream(object, projectionStream(areaStream$1));
8902     return areaStream$1.result();
8903   };
8904
8905   path.measure = function(object) {
8906     d3_geoStream(object, projectionStream(lengthStream$1));
8907     return lengthStream$1.result();
8908   };
8909
8910   path.bounds = function(object) {
8911     d3_geoStream(object, projectionStream(boundsStream$1));
8912     return boundsStream$1.result();
8913   };
8914
8915   path.centroid = function(object) {
8916     d3_geoStream(object, projectionStream(centroidStream$1));
8917     return centroidStream$1.result();
8918   };
8919
8920   path.projection = function(_) {
8921     return arguments.length ? (projectionStream = _ == null ? (projection = null, identity$4) : (projection = _).stream, path) : projection;
8922   };
8923
8924   path.context = function(_) {
8925     if (!arguments.length) return context;
8926     contextStream = _ == null ? (context = null, new PathString) : new PathContext(context = _);
8927     if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius);
8928     return path;
8929   };
8930
8931   path.pointRadius = function(_) {
8932     if (!arguments.length) return pointRadius;
8933     pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_);
8934     return path;
8935   };
8936
8937   return path.projection(projection).context(context);
8938 };
8939
8940 var d3_geoTransform = function(methods) {
8941   return {
8942     stream: transformer(methods)
8943   };
8944 };
8945
8946 function transformer(methods) {
8947   return function(stream) {
8948     var s = new TransformStream;
8949     for (var key in methods) s[key] = methods[key];
8950     s.stream = stream;
8951     return s;
8952   };
8953 }
8954
8955 function TransformStream() {}
8956
8957 TransformStream.prototype = {
8958   constructor: TransformStream,
8959   point: function(x, y) { this.stream.point(x, y); },
8960   sphere: function() { this.stream.sphere(); },
8961   lineStart: function() { this.stream.lineStart(); },
8962   lineEnd: function() { this.stream.lineEnd(); },
8963   polygonStart: function() { this.stream.polygonStart(); },
8964   polygonEnd: function() { this.stream.polygonEnd(); }
8965 };
8966
8967 function fitExtent(projection, extent, object) {
8968   var w = extent[1][0] - extent[0][0],
8969       h = extent[1][1] - extent[0][1],
8970       clip = projection.clipExtent && projection.clipExtent();
8971
8972   projection
8973       .scale(150)
8974       .translate([0, 0]);
8975
8976   if (clip != null) projection.clipExtent(null);
8977
8978   d3_geoStream(object, projection.stream(boundsStream$1));
8979
8980   var b = boundsStream$1.result(),
8981       k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])),
8982       x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2,
8983       y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;
8984
8985   if (clip != null) projection.clipExtent(clip);
8986
8987   return projection
8988       .scale(k * 150)
8989       .translate([x, y]);
8990 }
8991
8992 function fitSize(projection, size, object) {
8993   return fitExtent(projection, [[0, 0], size], object);
8994 }
8995
8996 var maxDepth = 16;
8997 var cosMinDistance = cos$1(30 * radians); // cos(minimum angular distance)
8998
8999 var resample = function(project, delta2) {
9000   return +delta2 ? resample$1(project, delta2) : resampleNone(project);
9001 };
9002
9003 function resampleNone(project) {
9004   return transformer({
9005     point: function(x, y) {
9006       x = project(x, y);
9007       this.stream.point(x[0], x[1]);
9008     }
9009   });
9010 }
9011
9012 function resample$1(project, delta2) {
9013
9014   function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) {
9015     var dx = x1 - x0,
9016         dy = y1 - y0,
9017         d2 = dx * dx + dy * dy;
9018     if (d2 > 4 * delta2 && depth--) {
9019       var a = a0 + a1,
9020           b = b0 + b1,
9021           c = c0 + c1,
9022           m = sqrt(a * a + b * b + c * c),
9023           phi2 = asin(c /= m),
9024           lambda2 = abs(abs(c) - 1) < epsilon$2 || abs(lambda0 - lambda1) < epsilon$2 ? (lambda0 + lambda1) / 2 : atan2(b, a),
9025           p = project(lambda2, phi2),
9026           x2 = p[0],
9027           y2 = p[1],
9028           dx2 = x2 - x0,
9029           dy2 = y2 - y0,
9030           dz = dy * dx2 - dx * dy2;
9031       if (dz * dz / d2 > delta2 // perpendicular projected distance
9032           || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end
9033           || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance
9034         resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream);
9035         stream.point(x2, y2);
9036         resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream);
9037       }
9038     }
9039   }
9040   return function(stream) {
9041     var lambda00, x00, y00, a00, b00, c00, // first point
9042         lambda0, x0, y0, a0, b0, c0; // previous point
9043
9044     var resampleStream = {
9045       point: point,
9046       lineStart: lineStart,
9047       lineEnd: lineEnd,
9048       polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; },
9049       polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; }
9050     };
9051
9052     function point(x, y) {
9053       x = project(x, y);
9054       stream.point(x[0], x[1]);
9055     }
9056
9057     function lineStart() {
9058       x0 = NaN;
9059       resampleStream.point = linePoint;
9060       stream.lineStart();
9061     }
9062
9063     function linePoint(lambda, phi) {
9064       var c = cartesian([lambda, phi]), p = project(lambda, phi);
9065       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);
9066       stream.point(x0, y0);
9067     }
9068
9069     function lineEnd() {
9070       resampleStream.point = point;
9071       stream.lineEnd();
9072     }
9073
9074     function ringStart() {
9075       lineStart();
9076       resampleStream.point = ringPoint;
9077       resampleStream.lineEnd = ringEnd;
9078     }
9079
9080     function ringPoint(lambda, phi) {
9081       linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;
9082       resampleStream.point = linePoint;
9083     }
9084
9085     function ringEnd() {
9086       resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream);
9087       resampleStream.lineEnd = lineEnd;
9088       lineEnd();
9089     }
9090
9091     return resampleStream;
9092   };
9093 }
9094
9095 var transformRadians = transformer({
9096   point: function(x, y) {
9097     this.stream.point(x * radians, y * radians);
9098   }
9099 });
9100
9101 function transformRotate(rotate) {
9102   return transformer({
9103     point: function(x, y) {
9104       var r = rotate(x, y);
9105       return this.stream.point(r[0], r[1]);
9106     }
9107   });
9108 }
9109
9110 function projection(project) {
9111   return projectionMutator(function() { return project; })();
9112 }
9113
9114 function projectionMutator(projectAt) {
9115   var project,
9116       k = 150, // scale
9117       x = 480, y = 250, // translate
9118       dx, dy, lambda = 0, phi = 0, // center
9119       deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, projectRotate, // rotate
9120       theta = null, preclip = clipAntimeridian, // clip angle
9121       x0 = null, y0, x1, y1, postclip = identity$4, // clip extent
9122       delta2 = 0.5, projectResample = resample(projectTransform, delta2), // precision
9123       cache,
9124       cacheStream;
9125
9126   function projection(point) {
9127     point = projectRotate(point[0] * radians, point[1] * radians);
9128     return [point[0] * k + dx, dy - point[1] * k];
9129   }
9130
9131   function invert(point) {
9132     point = projectRotate.invert((point[0] - dx) / k, (dy - point[1]) / k);
9133     return point && [point[0] * degrees$1, point[1] * degrees$1];
9134   }
9135
9136   function projectTransform(x, y) {
9137     return x = project(x, y), [x[0] * k + dx, dy - x[1] * k];
9138   }
9139
9140   projection.stream = function(stream) {
9141     return cache && cacheStream === stream ? cache : cache = transformRadians(transformRotate(rotate)(preclip(projectResample(postclip(cacheStream = stream)))));
9142   };
9143
9144   projection.preclip = function(_) {
9145     return arguments.length ? (preclip = _, theta = undefined, reset()) : preclip;
9146   };
9147
9148   projection.postclip = function(_) {
9149     return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip;
9150   };
9151
9152   projection.clipAngle = function(_) {
9153     return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees$1;
9154   };
9155
9156   projection.clipExtent = function(_) {
9157     return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipRectangle(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
9158   };
9159
9160   projection.scale = function(_) {
9161     return arguments.length ? (k = +_, recenter()) : k;
9162   };
9163
9164   projection.translate = function(_) {
9165     return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y];
9166   };
9167
9168   projection.center = function(_) {
9169     return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees$1, phi * degrees$1];
9170   };
9171
9172   projection.rotate = function(_) {
9173     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];
9174   };
9175
9176   projection.precision = function(_) {
9177     return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt(delta2);
9178   };
9179
9180   projection.fitExtent = function(extent, object) {
9181     return fitExtent(projection, extent, object);
9182   };
9183
9184   projection.fitSize = function(size, object) {
9185     return fitSize(projection, size, object);
9186   };
9187
9188   function recenter() {
9189     projectRotate = compose(rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma), project);
9190     var center = project(lambda, phi);
9191     dx = x - center[0] * k;
9192     dy = y + center[1] * k;
9193     return reset();
9194   }
9195
9196   function reset() {
9197     cache = cacheStream = null;
9198     return projection;
9199   }
9200
9201   return function() {
9202     project = projectAt.apply(this, arguments);
9203     projection.invert = project.invert && invert;
9204     return recenter();
9205   };
9206 }
9207
9208 function conicProjection(projectAt) {
9209   var phi0 = 0,
9210       phi1 = pi$3 / 3,
9211       m = projectionMutator(projectAt),
9212       p = m(phi0, phi1);
9213
9214   p.parallels = function(_) {
9215     return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees$1, phi1 * degrees$1];
9216   };
9217
9218   return p;
9219 }
9220
9221 function cylindricalEqualAreaRaw(phi0) {
9222   var cosPhi0 = cos$1(phi0);
9223
9224   function forward(lambda, phi) {
9225     return [lambda * cosPhi0, sin$1(phi) / cosPhi0];
9226   }
9227
9228   forward.invert = function(x, y) {
9229     return [x / cosPhi0, asin(y * cosPhi0)];
9230   };
9231
9232   return forward;
9233 }
9234
9235 function conicEqualAreaRaw(y0, y1) {
9236   var sy0 = sin$1(y0), n = (sy0 + sin$1(y1)) / 2;
9237
9238   // Are the parallels symmetrical around the Equator?
9239   if (abs(n) < epsilon$2) return cylindricalEqualAreaRaw(y0);
9240
9241   var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt(c) / n;
9242
9243   function project(x, y) {
9244     var r = sqrt(c - 2 * n * sin$1(y)) / n;
9245     return [r * sin$1(x *= n), r0 - r * cos$1(x)];
9246   }
9247
9248   project.invert = function(x, y) {
9249     var r0y = r0 - y;
9250     return [atan2(x, abs(r0y)) / n * sign(r0y), asin((c - (x * x + r0y * r0y) * n * n) / (2 * n))];
9251   };
9252
9253   return project;
9254 }
9255
9256 var conicEqualArea = function() {
9257   return conicProjection(conicEqualAreaRaw)
9258       .scale(155.424)
9259       .center([0, 33.6442]);
9260 };
9261
9262 var albers = function() {
9263   return conicEqualArea()
9264       .parallels([29.5, 45.5])
9265       .scale(1070)
9266       .translate([480, 250])
9267       .rotate([96, 0])
9268       .center([-0.6, 38.7]);
9269 };
9270
9271 // The projections must have mutually exclusive clip regions on the sphere,
9272 // as this will avoid emitting interleaving lines and polygons.
9273 function multiplex(streams) {
9274   var n = streams.length;
9275   return {
9276     point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); },
9277     sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); },
9278     lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); },
9279     lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); },
9280     polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); },
9281     polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); }
9282   };
9283 }
9284
9285 // A composite projection for the United States, configured by default for
9286 // 960×500. The projection also works quite well at 960×600 if you change the
9287 // scale to 1285 and adjust the translate accordingly. The set of standard
9288 // parallels for each region comes from USGS, which is published here:
9289 // http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
9290 var albersUsa = function() {
9291   var cache,
9292       cacheStream,
9293       lower48 = albers(), lower48Point,
9294       alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338
9295       hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007
9296       point, pointStream = {point: function(x, y) { point = [x, y]; }};
9297
9298   function albersUsa(coordinates) {
9299     var x = coordinates[0], y = coordinates[1];
9300     return point = null, (lower48Point.point(x, y), point)
9301         || (alaskaPoint.point(x, y), point)
9302         || (hawaiiPoint.point(x, y), point);
9303   }
9304
9305   albersUsa.invert = function(coordinates) {
9306     var k = lower48.scale(),
9307         t = lower48.translate(),
9308         x = (coordinates[0] - t[0]) / k,
9309         y = (coordinates[1] - t[1]) / k;
9310     return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska
9311         : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii
9312         : lower48).invert(coordinates);
9313   };
9314
9315   albersUsa.stream = function(stream) {
9316     return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]);
9317   };
9318
9319   albersUsa.precision = function(_) {
9320     if (!arguments.length) return lower48.precision();
9321     lower48.precision(_), alaska.precision(_), hawaii.precision(_);
9322     return reset();
9323   };
9324
9325   albersUsa.scale = function(_) {
9326     if (!arguments.length) return lower48.scale();
9327     lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_);
9328     return albersUsa.translate(lower48.translate());
9329   };
9330
9331   albersUsa.translate = function(_) {
9332     if (!arguments.length) return lower48.translate();
9333     var k = lower48.scale(), x = +_[0], y = +_[1];
9334
9335     lower48Point = lower48
9336         .translate(_)
9337         .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]])
9338         .stream(pointStream);
9339
9340     alaskaPoint = alaska
9341         .translate([x - 0.307 * k, y + 0.201 * k])
9342         .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]])
9343         .stream(pointStream);
9344
9345     hawaiiPoint = hawaii
9346         .translate([x - 0.205 * k, y + 0.212 * k])
9347         .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]])
9348         .stream(pointStream);
9349
9350     return reset();
9351   };
9352
9353   albersUsa.fitExtent = function(extent, object) {
9354     return fitExtent(albersUsa, extent, object);
9355   };
9356
9357   albersUsa.fitSize = function(size, object) {
9358     return fitSize(albersUsa, size, object);
9359   };
9360
9361   function reset() {
9362     cache = cacheStream = null;
9363     return albersUsa;
9364   }
9365
9366   return albersUsa.scale(1070);
9367 };
9368
9369 function azimuthalRaw(scale) {
9370   return function(x, y) {
9371     var cx = cos$1(x),
9372         cy = cos$1(y),
9373         k = scale(cx * cy);
9374     return [
9375       k * cy * sin$1(x),
9376       k * sin$1(y)
9377     ];
9378   }
9379 }
9380
9381 function azimuthalInvert(angle) {
9382   return function(x, y) {
9383     var z = sqrt(x * x + y * y),
9384         c = angle(z),
9385         sc = sin$1(c),
9386         cc = cos$1(c);
9387     return [
9388       atan2(x * sc, z * cc),
9389       asin(z && y * sc / z)
9390     ];
9391   }
9392 }
9393
9394 var azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) {
9395   return sqrt(2 / (1 + cxcy));
9396 });
9397
9398 azimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) {
9399   return 2 * asin(z / 2);
9400 });
9401
9402 var azimuthalEqualArea = function() {
9403   return projection(azimuthalEqualAreaRaw)
9404       .scale(124.75)
9405       .clipAngle(180 - 1e-3);
9406 };
9407
9408 var azimuthalEquidistantRaw = azimuthalRaw(function(c) {
9409   return (c = acos(c)) && c / sin$1(c);
9410 });
9411
9412 azimuthalEquidistantRaw.invert = azimuthalInvert(function(z) {
9413   return z;
9414 });
9415
9416 var azimuthalEquidistant = function() {
9417   return projection(azimuthalEquidistantRaw)
9418       .scale(79.4188)
9419       .clipAngle(180 - 1e-3);
9420 };
9421
9422 function mercatorRaw(lambda, phi) {
9423   return [lambda, log(tan((halfPi$2 + phi) / 2))];
9424 }
9425
9426 mercatorRaw.invert = function(x, y) {
9427   return [x, 2 * atan(exp(y)) - halfPi$2];
9428 };
9429
9430 var mercator = function() {
9431   return mercatorProjection(mercatorRaw)
9432       .scale(961 / tau$3);
9433 };
9434
9435 function mercatorProjection(project) {
9436   var m = projection(project),
9437       center = m.center,
9438       scale = m.scale,
9439       translate = m.translate,
9440       clipExtent = m.clipExtent,
9441       x0 = null, y0, x1, y1; // clip extent
9442
9443   m.scale = function(_) {
9444     return arguments.length ? (scale(_), reclip()) : scale();
9445   };
9446
9447   m.translate = function(_) {
9448     return arguments.length ? (translate(_), reclip()) : translate();
9449   };
9450
9451   m.center = function(_) {
9452     return arguments.length ? (center(_), reclip()) : center();
9453   };
9454
9455   m.clipExtent = function(_) {
9456     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]];
9457   };
9458
9459   function reclip() {
9460     var k = pi$3 * scale(),
9461         t = m(rotation(m.rotate()).invert([0, 0]));
9462     return clipExtent(x0 == null
9463         ? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project === mercatorRaw
9464         ? [[Math.max(t[0] - k, x0), y0], [Math.min(t[0] + k, x1), y1]]
9465         : [[x0, Math.max(t[1] - k, y0)], [x1, Math.min(t[1] + k, y1)]]);
9466   }
9467
9468   return reclip();
9469 }
9470
9471 function tany(y) {
9472   return tan((halfPi$2 + y) / 2);
9473 }
9474
9475 function conicConformalRaw(y0, y1) {
9476   var cy0 = cos$1(y0),
9477       n = y0 === y1 ? sin$1(y0) : log(cy0 / cos$1(y1)) / log(tany(y1) / tany(y0)),
9478       f = cy0 * pow(tany(y0), n) / n;
9479
9480   if (!n) return mercatorRaw;
9481
9482   function project(x, y) {
9483     if (f > 0) { if (y < -halfPi$2 + epsilon$2) y = -halfPi$2 + epsilon$2; }
9484     else { if (y > halfPi$2 - epsilon$2) y = halfPi$2 - epsilon$2; }
9485     var r = f / pow(tany(y), n);
9486     return [r * sin$1(n * x), f - r * cos$1(n * x)];
9487   }
9488
9489   project.invert = function(x, y) {
9490     var fy = f - y, r = sign(n) * sqrt(x * x + fy * fy);
9491     return [atan2(x, abs(fy)) / n * sign(fy), 2 * atan(pow(f / r, 1 / n)) - halfPi$2];
9492   };
9493
9494   return project;
9495 }
9496
9497 var conicConformal = function() {
9498   return conicProjection(conicConformalRaw)
9499       .scale(109.5)
9500       .parallels([30, 30]);
9501 };
9502
9503 function equirectangularRaw(lambda, phi) {
9504   return [lambda, phi];
9505 }
9506
9507 equirectangularRaw.invert = equirectangularRaw;
9508
9509 var equirectangular = function() {
9510   return projection(equirectangularRaw)
9511       .scale(152.63);
9512 };
9513
9514 function conicEquidistantRaw(y0, y1) {
9515   var cy0 = cos$1(y0),
9516       n = y0 === y1 ? sin$1(y0) : (cy0 - cos$1(y1)) / (y1 - y0),
9517       g = cy0 / n + y0;
9518
9519   if (abs(n) < epsilon$2) return equirectangularRaw;
9520
9521   function project(x, y) {
9522     var gy = g - y, nx = n * x;
9523     return [gy * sin$1(nx), g - gy * cos$1(nx)];
9524   }
9525
9526   project.invert = function(x, y) {
9527     var gy = g - y;
9528     return [atan2(x, abs(gy)) / n * sign(gy), g - sign(n) * sqrt(x * x + gy * gy)];
9529   };
9530
9531   return project;
9532 }
9533
9534 var conicEquidistant = function() {
9535   return conicProjection(conicEquidistantRaw)
9536       .scale(131.154)
9537       .center([0, 13.9389]);
9538 };
9539
9540 function gnomonicRaw(x, y) {
9541   var cy = cos$1(y), k = cos$1(x) * cy;
9542   return [cy * sin$1(x) / k, sin$1(y) / k];
9543 }
9544
9545 gnomonicRaw.invert = azimuthalInvert(atan);
9546
9547 var gnomonic = function() {
9548   return projection(gnomonicRaw)
9549       .scale(144.049)
9550       .clipAngle(60);
9551 };
9552
9553 function scaleTranslate(kx, ky, tx, ty) {
9554   return kx === 1 && ky === 1 && tx === 0 && ty === 0 ? identity$4 : transformer({
9555     point: function(x, y) {
9556       this.stream.point(x * kx + tx, y * ky + ty);
9557     }
9558   });
9559 }
9560
9561 var d3_geoIdentity = function() {
9562   var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, transform = identity$4, // scale, translate and reflect
9563       x0 = null, y0, x1, y1, // clip extent
9564       postclip = identity$4,
9565       cache,
9566       cacheStream,
9567       projection;
9568
9569   function reset() {
9570     cache = cacheStream = null;
9571     return projection;
9572   }
9573
9574   return projection = {
9575     stream: function(stream) {
9576       return cache && cacheStream === stream ? cache : cache = transform(postclip(cacheStream = stream));
9577     },
9578     postclip: function(_) {
9579       return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip;
9580     },
9581     clipExtent: function(_) {
9582       return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$4) : clipRectangle(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
9583     },
9584     scale: function(_) {
9585       return arguments.length ? (transform = scaleTranslate((k = +_) * sx, k * sy, tx, ty), reset()) : k;
9586     },
9587     translate: function(_) {
9588       return arguments.length ? (transform = scaleTranslate(k * sx, k * sy, tx = +_[0], ty = +_[1]), reset()) : [tx, ty];
9589     },
9590     reflectX: function(_) {
9591       return arguments.length ? (transform = scaleTranslate(k * (sx = _ ? -1 : 1), k * sy, tx, ty), reset()) : sx < 0;
9592     },
9593     reflectY: function(_) {
9594       return arguments.length ? (transform = scaleTranslate(k * sx, k * (sy = _ ? -1 : 1), tx, ty), reset()) : sy < 0;
9595     },
9596     fitExtent: function(extent, object) {
9597       return fitExtent(projection, extent, object);
9598     },
9599     fitSize: function(size, object) {
9600       return fitSize(projection, size, object);
9601     }
9602   };
9603 };
9604
9605 function naturalEarth1Raw(lambda, phi) {
9606   var phi2 = phi * phi, phi4 = phi2 * phi2;
9607   return [
9608     lambda * (0.8707 - 0.131979 * phi2 + phi4 * (-0.013791 + phi4 * (0.003971 * phi2 - 0.001529 * phi4))),
9609     phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4)))
9610   ];
9611 }
9612
9613 naturalEarth1Raw.invert = function(x, y) {
9614   var phi = y, i = 25, delta;
9615   do {
9616     var phi2 = phi * phi, phi4 = phi2 * phi2;
9617     phi -= delta = (phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4))) - y) /
9618         (1.007226 + phi2 * (0.015085 * 3 + phi4 * (-0.044475 * 7 + 0.028874 * 9 * phi2 - 0.005916 * 11 * phi4)));
9619   } while (abs(delta) > epsilon$2 && --i > 0);
9620   return [
9621     x / (0.8707 + (phi2 = phi * phi) * (-0.131979 + phi2 * (-0.013791 + phi2 * phi2 * phi2 * (0.003971 - 0.001529 * phi2)))),
9622     phi
9623   ];
9624 };
9625
9626 var naturalEarth1 = function() {
9627   return projection(naturalEarth1Raw)
9628       .scale(175.295);
9629 };
9630
9631 function orthographicRaw(x, y) {
9632   return [cos$1(y) * sin$1(x), sin$1(y)];
9633 }
9634
9635 orthographicRaw.invert = azimuthalInvert(asin);
9636
9637 var orthographic = function() {
9638   return projection(orthographicRaw)
9639       .scale(249.5)
9640       .clipAngle(90 + epsilon$2);
9641 };
9642
9643 function stereographicRaw(x, y) {
9644   var cy = cos$1(y), k = 1 + cos$1(x) * cy;
9645   return [cy * sin$1(x) / k, sin$1(y) / k];
9646 }
9647
9648 stereographicRaw.invert = azimuthalInvert(function(z) {
9649   return 2 * atan(z);
9650 });
9651
9652 var stereographic = function() {
9653   return projection(stereographicRaw)
9654       .scale(250)
9655       .clipAngle(142);
9656 };
9657
9658 function transverseMercatorRaw(lambda, phi) {
9659   return [log(tan((halfPi$2 + phi) / 2)), -lambda];
9660 }
9661
9662 transverseMercatorRaw.invert = function(x, y) {
9663   return [-y, 2 * atan(exp(x)) - halfPi$2];
9664 };
9665
9666 var transverseMercator = function() {
9667   var m = mercatorProjection(transverseMercatorRaw),
9668       center = m.center,
9669       rotate = m.rotate;
9670
9671   m.center = function(_) {
9672     return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]);
9673   };
9674
9675   m.rotate = function(_) {
9676     return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]);
9677   };
9678
9679   return rotate([0, 0, 90])
9680       .scale(159.155);
9681 };
9682
9683 function defaultSeparation(a, b) {
9684   return a.parent === b.parent ? 1 : 2;
9685 }
9686
9687 function meanX(children) {
9688   return children.reduce(meanXReduce, 0) / children.length;
9689 }
9690
9691 function meanXReduce(x, c) {
9692   return x + c.x;
9693 }
9694
9695 function maxY(children) {
9696   return 1 + children.reduce(maxYReduce, 0);
9697 }
9698
9699 function maxYReduce(y, c) {
9700   return Math.max(y, c.y);
9701 }
9702
9703 function leafLeft(node) {
9704   var children;
9705   while (children = node.children) node = children[0];
9706   return node;
9707 }
9708
9709 function leafRight(node) {
9710   var children;
9711   while (children = node.children) node = children[children.length - 1];
9712   return node;
9713 }
9714
9715 var cluster = function() {
9716   var separation = defaultSeparation,
9717       dx = 1,
9718       dy = 1,
9719       nodeSize = false;
9720
9721   function cluster(root) {
9722     var previousNode,
9723         x = 0;
9724
9725     // First walk, computing the initial x & y values.
9726     root.eachAfter(function(node) {
9727       var children = node.children;
9728       if (children) {
9729         node.x = meanX(children);
9730         node.y = maxY(children);
9731       } else {
9732         node.x = previousNode ? x += separation(node, previousNode) : 0;
9733         node.y = 0;
9734         previousNode = node;
9735       }
9736     });
9737
9738     var left = leafLeft(root),
9739         right = leafRight(root),
9740         x0 = left.x - separation(left, right) / 2,
9741         x1 = right.x + separation(right, left) / 2;
9742
9743     // Second walk, normalizing x & y to the desired size.
9744     return root.eachAfter(nodeSize ? function(node) {
9745       node.x = (node.x - root.x) * dx;
9746       node.y = (root.y - node.y) * dy;
9747     } : function(node) {
9748       node.x = (node.x - x0) / (x1 - x0) * dx;
9749       node.y = (1 - (root.y ? node.y / root.y : 1)) * dy;
9750     });
9751   }
9752
9753   cluster.separation = function(x) {
9754     return arguments.length ? (separation = x, cluster) : separation;
9755   };
9756
9757   cluster.size = function(x) {
9758     return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? null : [dx, dy]);
9759   };
9760
9761   cluster.nodeSize = function(x) {
9762     return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? [dx, dy] : null);
9763   };
9764
9765   return cluster;
9766 };
9767
9768 function count(node) {
9769   var sum = 0,
9770       children = node.children,
9771       i = children && children.length;
9772   if (!i) sum = 1;
9773   else while (--i >= 0) sum += children[i].value;
9774   node.value = sum;
9775 }
9776
9777 var node_count = function() {
9778   return this.eachAfter(count);
9779 };
9780
9781 var node_each = function(callback) {
9782   var node = this, current, next = [node], children, i, n;
9783   do {
9784     current = next.reverse(), next = [];
9785     while (node = current.pop()) {
9786       callback(node), children = node.children;
9787       if (children) for (i = 0, n = children.length; i < n; ++i) {
9788         next.push(children[i]);
9789       }
9790     }
9791   } while (next.length);
9792   return this;
9793 };
9794
9795 var node_eachBefore = function(callback) {
9796   var node = this, nodes = [node], children, i;
9797   while (node = nodes.pop()) {
9798     callback(node), children = node.children;
9799     if (children) for (i = children.length - 1; i >= 0; --i) {
9800       nodes.push(children[i]);
9801     }
9802   }
9803   return this;
9804 };
9805
9806 var node_eachAfter = function(callback) {
9807   var node = this, nodes = [node], next = [], children, i, n;
9808   while (node = nodes.pop()) {
9809     next.push(node), children = node.children;
9810     if (children) for (i = 0, n = children.length; i < n; ++i) {
9811       nodes.push(children[i]);
9812     }
9813   }
9814   while (node = next.pop()) {
9815     callback(node);
9816   }
9817   return this;
9818 };
9819
9820 var node_sum = function(value) {
9821   return this.eachAfter(function(node) {
9822     var sum = +value(node.data) || 0,
9823         children = node.children,
9824         i = children && children.length;
9825     while (--i >= 0) sum += children[i].value;
9826     node.value = sum;
9827   });
9828 };
9829
9830 var node_sort = function(compare) {
9831   return this.eachBefore(function(node) {
9832     if (node.children) {
9833       node.children.sort(compare);
9834     }
9835   });
9836 };
9837
9838 var node_path = function(end) {
9839   var start = this,
9840       ancestor = leastCommonAncestor(start, end),
9841       nodes = [start];
9842   while (start !== ancestor) {
9843     start = start.parent;
9844     nodes.push(start);
9845   }
9846   var k = nodes.length;
9847   while (end !== ancestor) {
9848     nodes.splice(k, 0, end);
9849     end = end.parent;
9850   }
9851   return nodes;
9852 };
9853
9854 function leastCommonAncestor(a, b) {
9855   if (a === b) return a;
9856   var aNodes = a.ancestors(),
9857       bNodes = b.ancestors(),
9858       c = null;
9859   a = aNodes.pop();
9860   b = bNodes.pop();
9861   while (a === b) {
9862     c = a;
9863     a = aNodes.pop();
9864     b = bNodes.pop();
9865   }
9866   return c;
9867 }
9868
9869 var node_ancestors = function() {
9870   var node = this, nodes = [node];
9871   while (node = node.parent) {
9872     nodes.push(node);
9873   }
9874   return nodes;
9875 };
9876
9877 var node_descendants = function() {
9878   var nodes = [];
9879   this.each(function(node) {
9880     nodes.push(node);
9881   });
9882   return nodes;
9883 };
9884
9885 var node_leaves = function() {
9886   var leaves = [];
9887   this.eachBefore(function(node) {
9888     if (!node.children) {
9889       leaves.push(node);
9890     }
9891   });
9892   return leaves;
9893 };
9894
9895 var node_links = function() {
9896   var root = this, links = [];
9897   root.each(function(node) {
9898     if (node !== root) { // Don’t include the root’s parent, if any.
9899       links.push({source: node.parent, target: node});
9900     }
9901   });
9902   return links;
9903 };
9904
9905 function hierarchy(data, children) {
9906   var root = new Node(data),
9907       valued = +data.value && (root.value = data.value),
9908       node,
9909       nodes = [root],
9910       child,
9911       childs,
9912       i,
9913       n;
9914
9915   if (children == null) children = defaultChildren;
9916
9917   while (node = nodes.pop()) {
9918     if (valued) node.value = +node.data.value;
9919     if ((childs = children(node.data)) && (n = childs.length)) {
9920       node.children = new Array(n);
9921       for (i = n - 1; i >= 0; --i) {
9922         nodes.push(child = node.children[i] = new Node(childs[i]));
9923         child.parent = node;
9924         child.depth = node.depth + 1;
9925       }
9926     }
9927   }
9928
9929   return root.eachBefore(computeHeight);
9930 }
9931
9932 function node_copy() {
9933   return hierarchy(this).eachBefore(copyData);
9934 }
9935
9936 function defaultChildren(d) {
9937   return d.children;
9938 }
9939
9940 function copyData(node) {
9941   node.data = node.data.data;
9942 }
9943
9944 function computeHeight(node) {
9945   var height = 0;
9946   do node.height = height;
9947   while ((node = node.parent) && (node.height < ++height));
9948 }
9949
9950 function Node(data) {
9951   this.data = data;
9952   this.depth =
9953   this.height = 0;
9954   this.parent = null;
9955 }
9956
9957 Node.prototype = hierarchy.prototype = {
9958   constructor: Node,
9959   count: node_count,
9960   each: node_each,
9961   eachAfter: node_eachAfter,
9962   eachBefore: node_eachBefore,
9963   sum: node_sum,
9964   sort: node_sort,
9965   path: node_path,
9966   ancestors: node_ancestors,
9967   descendants: node_descendants,
9968   leaves: node_leaves,
9969   links: node_links,
9970   copy: node_copy
9971 };
9972
9973 var slice$3 = Array.prototype.slice;
9974
9975 function shuffle$1(array) {
9976   var m = array.length,
9977       t,
9978       i;
9979
9980   while (m) {
9981     i = Math.random() * m-- | 0;
9982     t = array[m];
9983     array[m] = array[i];
9984     array[i] = t;
9985   }
9986
9987   return array;
9988 }
9989
9990 var enclose = function(circles) {
9991   var i = 0, n = (circles = shuffle$1(slice$3.call(circles))).length, B = [], p, e;
9992
9993   while (i < n) {
9994     p = circles[i];
9995     if (e && enclosesWeak(e, p)) ++i;
9996     else e = encloseBasis(B = extendBasis(B, p)), i = 0;
9997   }
9998
9999   return e;
10000 };
10001
10002 function extendBasis(B, p) {
10003   var i, j;
10004
10005   if (enclosesWeakAll(p, B)) return [p];
10006
10007   // If we get here then B must have at least one element.
10008   for (i = 0; i < B.length; ++i) {
10009     if (enclosesNot(p, B[i])
10010         && enclosesWeakAll(encloseBasis2(B[i], p), B)) {
10011       return [B[i], p];
10012     }
10013   }
10014
10015   // If we get here then B must have at least two elements.
10016   for (i = 0; i < B.length - 1; ++i) {
10017     for (j = i + 1; j < B.length; ++j) {
10018       if (enclosesNot(encloseBasis2(B[i], B[j]), p)
10019           && enclosesNot(encloseBasis2(B[i], p), B[j])
10020           && enclosesNot(encloseBasis2(B[j], p), B[i])
10021           && enclosesWeakAll(encloseBasis3(B[i], B[j], p), B)) {
10022         return [B[i], B[j], p];
10023       }
10024     }
10025   }
10026
10027   // If we get here then something is very wrong.
10028   throw new Error;
10029 }
10030
10031 function enclosesNot(a, b) {
10032   var dr = a.r - b.r, dx = b.x - a.x, dy = b.y - a.y;
10033   return dr < 0 || dr * dr < dx * dx + dy * dy;
10034 }
10035
10036 function enclosesWeak(a, b) {
10037   var dr = a.r - b.r + 1e-6, dx = b.x - a.x, dy = b.y - a.y;
10038   return dr > 0 && dr * dr > dx * dx + dy * dy;
10039 }
10040
10041 function enclosesWeakAll(a, B) {
10042   for (var i = 0; i < B.length; ++i) {
10043     if (!enclosesWeak(a, B[i])) {
10044       return false;
10045     }
10046   }
10047   return true;
10048 }
10049
10050 function encloseBasis(B) {
10051   switch (B.length) {
10052     case 1: return encloseBasis1(B[0]);
10053     case 2: return encloseBasis2(B[0], B[1]);
10054     case 3: return encloseBasis3(B[0], B[1], B[2]);
10055   }
10056 }
10057
10058 function encloseBasis1(a) {
10059   return {
10060     x: a.x,
10061     y: a.y,
10062     r: a.r
10063   };
10064 }
10065
10066 function encloseBasis2(a, b) {
10067   var x1 = a.x, y1 = a.y, r1 = a.r,
10068       x2 = b.x, y2 = b.y, r2 = b.r,
10069       x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1,
10070       l = Math.sqrt(x21 * x21 + y21 * y21);
10071   return {
10072     x: (x1 + x2 + x21 / l * r21) / 2,
10073     y: (y1 + y2 + y21 / l * r21) / 2,
10074     r: (l + r1 + r2) / 2
10075   };
10076 }
10077
10078 function encloseBasis3(a, b, c) {
10079   var x1 = a.x, y1 = a.y, r1 = a.r,
10080       x2 = b.x, y2 = b.y, r2 = b.r,
10081       x3 = c.x, y3 = c.y, r3 = c.r,
10082       a2 = x1 - x2,
10083       a3 = x1 - x3,
10084       b2 = y1 - y2,
10085       b3 = y1 - y3,
10086       c2 = r2 - r1,
10087       c3 = r3 - r1,
10088       d1 = x1 * x1 + y1 * y1 - r1 * r1,
10089       d2 = d1 - x2 * x2 - y2 * y2 + r2 * r2,
10090       d3 = d1 - x3 * x3 - y3 * y3 + r3 * r3,
10091       ab = a3 * b2 - a2 * b3,
10092       xa = (b2 * d3 - b3 * d2) / (ab * 2) - x1,
10093       xb = (b3 * c2 - b2 * c3) / ab,
10094       ya = (a3 * d2 - a2 * d3) / (ab * 2) - y1,
10095       yb = (a2 * c3 - a3 * c2) / ab,
10096       A = xb * xb + yb * yb - 1,
10097       B = 2 * (r1 + xa * xb + ya * yb),
10098       C = xa * xa + ya * ya - r1 * r1,
10099       r = -(A ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A) : C / B);
10100   return {
10101     x: x1 + xa + xb * r,
10102     y: y1 + ya + yb * r,
10103     r: r
10104   };
10105 }
10106
10107 function place(a, b, c) {
10108   var ax = a.x,
10109       ay = a.y,
10110       da = b.r + c.r,
10111       db = a.r + c.r,
10112       dx = b.x - ax,
10113       dy = b.y - ay,
10114       dc = dx * dx + dy * dy;
10115   if (dc) {
10116     var x = 0.5 + ((db *= db) - (da *= da)) / (2 * dc),
10117         y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc);
10118     c.x = ax + x * dx + y * dy;
10119     c.y = ay + x * dy - y * dx;
10120   } else {
10121     c.x = ax + db;
10122     c.y = ay;
10123   }
10124 }
10125
10126 function intersects(a, b) {
10127   var dx = b.x - a.x,
10128       dy = b.y - a.y,
10129       dr = a.r + b.r;
10130   return dr * dr - 1e-6 > dx * dx + dy * dy;
10131 }
10132
10133 function score(node) {
10134   var a = node._,
10135       b = node.next._,
10136       ab = a.r + b.r,
10137       dx = (a.x * b.r + b.x * a.r) / ab,
10138       dy = (a.y * b.r + b.y * a.r) / ab;
10139   return dx * dx + dy * dy;
10140 }
10141
10142 function Node$1(circle) {
10143   this._ = circle;
10144   this.next = null;
10145   this.previous = null;
10146 }
10147
10148 function packEnclose(circles) {
10149   if (!(n = circles.length)) return 0;
10150
10151   var a, b, c, n, aa, ca, i, j, k, sj, sk;
10152
10153   // Place the first circle.
10154   a = circles[0], a.x = 0, a.y = 0;
10155   if (!(n > 1)) return a.r;
10156
10157   // Place the second circle.
10158   b = circles[1], a.x = -b.r, b.x = a.r, b.y = 0;
10159   if (!(n > 2)) return a.r + b.r;
10160
10161   // Place the third circle.
10162   place(b, a, c = circles[2]);
10163
10164   // Initialize the front-chain using the first three circles a, b and c.
10165   a = new Node$1(a), b = new Node$1(b), c = new Node$1(c);
10166   a.next = c.previous = b;
10167   b.next = a.previous = c;
10168   c.next = b.previous = a;
10169
10170   // Attempt to place each remaining circle…
10171   pack: for (i = 3; i < n; ++i) {
10172     place(a._, b._, c = circles[i]), c = new Node$1(c);
10173
10174     // Find the closest intersecting circle on the front-chain, if any.
10175     // “Closeness” is determined by linear distance along the front-chain.
10176     // “Ahead” or “behind” is likewise determined by linear distance.
10177     j = b.next, k = a.previous, sj = b._.r, sk = a._.r;
10178     do {
10179       if (sj <= sk) {
10180         if (intersects(j._, c._)) {
10181           b = j, a.next = b, b.previous = a, --i;
10182           continue pack;
10183         }
10184         sj += j._.r, j = j.next;
10185       } else {
10186         if (intersects(k._, c._)) {
10187           a = k, a.next = b, b.previous = a, --i;
10188           continue pack;
10189         }
10190         sk += k._.r, k = k.previous;
10191       }
10192     } while (j !== k.next);
10193
10194     // Success! Insert the new circle c between a and b.
10195     c.previous = a, c.next = b, a.next = b.previous = b = c;
10196
10197     // Compute the new closest circle pair to the centroid.
10198     aa = score(a);
10199     while ((c = c.next) !== b) {
10200       if ((ca = score(c)) < aa) {
10201         a = c, aa = ca;
10202       }
10203     }
10204     b = a.next;
10205   }
10206
10207   // Compute the enclosing circle of the front chain.
10208   a = [b._], c = b; while ((c = c.next) !== b) a.push(c._); c = enclose(a);
10209
10210   // Translate the circles to put the enclosing circle around the origin.
10211   for (i = 0; i < n; ++i) a = circles[i], a.x -= c.x, a.y -= c.y;
10212
10213   return c.r;
10214 }
10215
10216 var siblings = function(circles) {
10217   packEnclose(circles);
10218   return circles;
10219 };
10220
10221 function optional(f) {
10222   return f == null ? null : required(f);
10223 }
10224
10225 function required(f) {
10226   if (typeof f !== "function") throw new Error;
10227   return f;
10228 }
10229
10230 function constantZero() {
10231   return 0;
10232 }
10233
10234 var constant$8 = function(x) {
10235   return function() {
10236     return x;
10237   };
10238 };
10239
10240 function defaultRadius$1(d) {
10241   return Math.sqrt(d.value);
10242 }
10243
10244 var index$2 = function() {
10245   var radius = null,
10246       dx = 1,
10247       dy = 1,
10248       padding = constantZero;
10249
10250   function pack(root) {
10251     root.x = dx / 2, root.y = dy / 2;
10252     if (radius) {
10253       root.eachBefore(radiusLeaf(radius))
10254           .eachAfter(packChildren(padding, 0.5))
10255           .eachBefore(translateChild(1));
10256     } else {
10257       root.eachBefore(radiusLeaf(defaultRadius$1))
10258           .eachAfter(packChildren(constantZero, 1))
10259           .eachAfter(packChildren(padding, root.r / Math.min(dx, dy)))
10260           .eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r)));
10261     }
10262     return root;
10263   }
10264
10265   pack.radius = function(x) {
10266     return arguments.length ? (radius = optional(x), pack) : radius;
10267   };
10268
10269   pack.size = function(x) {
10270     return arguments.length ? (dx = +x[0], dy = +x[1], pack) : [dx, dy];
10271   };
10272
10273   pack.padding = function(x) {
10274     return arguments.length ? (padding = typeof x === "function" ? x : constant$8(+x), pack) : padding;
10275   };
10276
10277   return pack;
10278 };
10279
10280 function radiusLeaf(radius) {
10281   return function(node) {
10282     if (!node.children) {
10283       node.r = Math.max(0, +radius(node) || 0);
10284     }
10285   };
10286 }
10287
10288 function packChildren(padding, k) {
10289   return function(node) {
10290     if (children = node.children) {
10291       var children,
10292           i,
10293           n = children.length,
10294           r = padding(node) * k || 0,
10295           e;
10296
10297       if (r) for (i = 0; i < n; ++i) children[i].r += r;
10298       e = packEnclose(children);
10299       if (r) for (i = 0; i < n; ++i) children[i].r -= r;
10300       node.r = e + r;
10301     }
10302   };
10303 }
10304
10305 function translateChild(k) {
10306   return function(node) {
10307     var parent = node.parent;
10308     node.r *= k;
10309     if (parent) {
10310       node.x = parent.x + k * node.x;
10311       node.y = parent.y + k * node.y;
10312     }
10313   };
10314 }
10315
10316 var roundNode = function(node) {
10317   node.x0 = Math.round(node.x0);
10318   node.y0 = Math.round(node.y0);
10319   node.x1 = Math.round(node.x1);
10320   node.y1 = Math.round(node.y1);
10321 };
10322
10323 var treemapDice = function(parent, x0, y0, x1, y1) {
10324   var nodes = parent.children,
10325       node,
10326       i = -1,
10327       n = nodes.length,
10328       k = parent.value && (x1 - x0) / parent.value;
10329
10330   while (++i < n) {
10331     node = nodes[i], node.y0 = y0, node.y1 = y1;
10332     node.x0 = x0, node.x1 = x0 += node.value * k;
10333   }
10334 };
10335
10336 var partition = function() {
10337   var dx = 1,
10338       dy = 1,
10339       padding = 0,
10340       round = false;
10341
10342   function partition(root) {
10343     var n = root.height + 1;
10344     root.x0 =
10345     root.y0 = padding;
10346     root.x1 = dx;
10347     root.y1 = dy / n;
10348     root.eachBefore(positionNode(dy, n));
10349     if (round) root.eachBefore(roundNode);
10350     return root;
10351   }
10352
10353   function positionNode(dy, n) {
10354     return function(node) {
10355       if (node.children) {
10356         treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n);
10357       }
10358       var x0 = node.x0,
10359           y0 = node.y0,
10360           x1 = node.x1 - padding,
10361           y1 = node.y1 - padding;
10362       if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
10363       if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
10364       node.x0 = x0;
10365       node.y0 = y0;
10366       node.x1 = x1;
10367       node.y1 = y1;
10368     };
10369   }
10370
10371   partition.round = function(x) {
10372     return arguments.length ? (round = !!x, partition) : round;
10373   };
10374
10375   partition.size = function(x) {
10376     return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy];
10377   };
10378
10379   partition.padding = function(x) {
10380     return arguments.length ? (padding = +x, partition) : padding;
10381   };
10382
10383   return partition;
10384 };
10385
10386 var keyPrefix$1 = "$";
10387 var preroot = {depth: -1};
10388 var ambiguous = {};
10389
10390 function defaultId(d) {
10391   return d.id;
10392 }
10393
10394 function defaultParentId(d) {
10395   return d.parentId;
10396 }
10397
10398 var stratify = function() {
10399   var id = defaultId,
10400       parentId = defaultParentId;
10401
10402   function stratify(data) {
10403     var d,
10404         i,
10405         n = data.length,
10406         root,
10407         parent,
10408         node,
10409         nodes = new Array(n),
10410         nodeId,
10411         nodeKey,
10412         nodeByKey = {};
10413
10414     for (i = 0; i < n; ++i) {
10415       d = data[i], node = nodes[i] = new Node(d);
10416       if ((nodeId = id(d, i, data)) != null && (nodeId += "")) {
10417         nodeKey = keyPrefix$1 + (node.id = nodeId);
10418         nodeByKey[nodeKey] = nodeKey in nodeByKey ? ambiguous : node;
10419       }
10420     }
10421
10422     for (i = 0; i < n; ++i) {
10423       node = nodes[i], nodeId = parentId(data[i], i, data);
10424       if (nodeId == null || !(nodeId += "")) {
10425         if (root) throw new Error("multiple roots");
10426         root = node;
10427       } else {
10428         parent = nodeByKey[keyPrefix$1 + nodeId];
10429         if (!parent) throw new Error("missing: " + nodeId);
10430         if (parent === ambiguous) throw new Error("ambiguous: " + nodeId);
10431         if (parent.children) parent.children.push(node);
10432         else parent.children = [node];
10433         node.parent = parent;
10434       }
10435     }
10436
10437     if (!root) throw new Error("no root");
10438     root.parent = preroot;
10439     root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight);
10440     root.parent = null;
10441     if (n > 0) throw new Error("cycle");
10442
10443     return root;
10444   }
10445
10446   stratify.id = function(x) {
10447     return arguments.length ? (id = required(x), stratify) : id;
10448   };
10449
10450   stratify.parentId = function(x) {
10451     return arguments.length ? (parentId = required(x), stratify) : parentId;
10452   };
10453
10454   return stratify;
10455 };
10456
10457 function defaultSeparation$1(a, b) {
10458   return a.parent === b.parent ? 1 : 2;
10459 }
10460
10461 // function radialSeparation(a, b) {
10462 //   return (a.parent === b.parent ? 1 : 2) / a.depth;
10463 // }
10464
10465 // This function is used to traverse the left contour of a subtree (or
10466 // subforest). It returns the successor of v on this contour. This successor is
10467 // either given by the leftmost child of v or by the thread of v. The function
10468 // returns null if and only if v is on the highest level of its subtree.
10469 function nextLeft(v) {
10470   var children = v.children;
10471   return children ? children[0] : v.t;
10472 }
10473
10474 // This function works analogously to nextLeft.
10475 function nextRight(v) {
10476   var children = v.children;
10477   return children ? children[children.length - 1] : v.t;
10478 }
10479
10480 // Shifts the current subtree rooted at w+. This is done by increasing
10481 // prelim(w+) and mod(w+) by shift.
10482 function moveSubtree(wm, wp, shift) {
10483   var change = shift / (wp.i - wm.i);
10484   wp.c -= change;
10485   wp.s += shift;
10486   wm.c += change;
10487   wp.z += shift;
10488   wp.m += shift;
10489 }
10490
10491 // All other shifts, applied to the smaller subtrees between w- and w+, are
10492 // performed by this function. To prepare the shifts, we have to adjust
10493 // change(w+), shift(w+), and change(w-).
10494 function executeShifts(v) {
10495   var shift = 0,
10496       change = 0,
10497       children = v.children,
10498       i = children.length,
10499       w;
10500   while (--i >= 0) {
10501     w = children[i];
10502     w.z += shift;
10503     w.m += shift;
10504     shift += w.s + (change += w.c);
10505   }
10506 }
10507
10508 // If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise,
10509 // returns the specified (default) ancestor.
10510 function nextAncestor(vim, v, ancestor) {
10511   return vim.a.parent === v.parent ? vim.a : ancestor;
10512 }
10513
10514 function TreeNode(node, i) {
10515   this._ = node;
10516   this.parent = null;
10517   this.children = null;
10518   this.A = null; // default ancestor
10519   this.a = this; // ancestor
10520   this.z = 0; // prelim
10521   this.m = 0; // mod
10522   this.c = 0; // change
10523   this.s = 0; // shift
10524   this.t = null; // thread
10525   this.i = i; // number
10526 }
10527
10528 TreeNode.prototype = Object.create(Node.prototype);
10529
10530 function treeRoot(root) {
10531   var tree = new TreeNode(root, 0),
10532       node,
10533       nodes = [tree],
10534       child,
10535       children,
10536       i,
10537       n;
10538
10539   while (node = nodes.pop()) {
10540     if (children = node._.children) {
10541       node.children = new Array(n = children.length);
10542       for (i = n - 1; i >= 0; --i) {
10543         nodes.push(child = node.children[i] = new TreeNode(children[i], i));
10544         child.parent = node;
10545       }
10546     }
10547   }
10548
10549   (tree.parent = new TreeNode(null, 0)).children = [tree];
10550   return tree;
10551 }
10552
10553 // Node-link tree diagram using the Reingold-Tilford "tidy" algorithm
10554 var tree = function() {
10555   var separation = defaultSeparation$1,
10556       dx = 1,
10557       dy = 1,
10558       nodeSize = null;
10559
10560   function tree(root) {
10561     var t = treeRoot(root);
10562
10563     // Compute the layout using Buchheim et al.’s algorithm.
10564     t.eachAfter(firstWalk), t.parent.m = -t.z;
10565     t.eachBefore(secondWalk);
10566
10567     // If a fixed node size is specified, scale x and y.
10568     if (nodeSize) root.eachBefore(sizeNode);
10569
10570     // If a fixed tree size is specified, scale x and y based on the extent.
10571     // Compute the left-most, right-most, and depth-most nodes for extents.
10572     else {
10573       var left = root,
10574           right = root,
10575           bottom = root;
10576       root.eachBefore(function(node) {
10577         if (node.x < left.x) left = node;
10578         if (node.x > right.x) right = node;
10579         if (node.depth > bottom.depth) bottom = node;
10580       });
10581       var s = left === right ? 1 : separation(left, right) / 2,
10582           tx = s - left.x,
10583           kx = dx / (right.x + s + tx),
10584           ky = dy / (bottom.depth || 1);
10585       root.eachBefore(function(node) {
10586         node.x = (node.x + tx) * kx;
10587         node.y = node.depth * ky;
10588       });
10589     }
10590
10591     return root;
10592   }
10593
10594   // Computes a preliminary x-coordinate for v. Before that, FIRST WALK is
10595   // applied recursively to the children of v, as well as the function
10596   // APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the
10597   // node v is placed to the midpoint of its outermost children.
10598   function firstWalk(v) {
10599     var children = v.children,
10600         siblings = v.parent.children,
10601         w = v.i ? siblings[v.i - 1] : null;
10602     if (children) {
10603       executeShifts(v);
10604       var midpoint = (children[0].z + children[children.length - 1].z) / 2;
10605       if (w) {
10606         v.z = w.z + separation(v._, w._);
10607         v.m = v.z - midpoint;
10608       } else {
10609         v.z = midpoint;
10610       }
10611     } else if (w) {
10612       v.z = w.z + separation(v._, w._);
10613     }
10614     v.parent.A = apportion(v, w, v.parent.A || siblings[0]);
10615   }
10616
10617   // Computes all real x-coordinates by summing up the modifiers recursively.
10618   function secondWalk(v) {
10619     v._.x = v.z + v.parent.m;
10620     v.m += v.parent.m;
10621   }
10622
10623   // The core of the algorithm. Here, a new subtree is combined with the
10624   // previous subtrees. Threads are used to traverse the inside and outside
10625   // contours of the left and right subtree up to the highest common level. The
10626   // vertices used for the traversals are vi+, vi-, vo-, and vo+, where the
10627   // superscript o means outside and i means inside, the subscript - means left
10628   // subtree and + means right subtree. For summing up the modifiers along the
10629   // contour, we use respective variables si+, si-, so-, and so+. Whenever two
10630   // nodes of the inside contours conflict, we compute the left one of the
10631   // greatest uncommon ancestors using the function ANCESTOR and call MOVE
10632   // SUBTREE to shift the subtree and prepare the shifts of smaller subtrees.
10633   // Finally, we add a new thread (if necessary).
10634   function apportion(v, w, ancestor) {
10635     if (w) {
10636       var vip = v,
10637           vop = v,
10638           vim = w,
10639           vom = vip.parent.children[0],
10640           sip = vip.m,
10641           sop = vop.m,
10642           sim = vim.m,
10643           som = vom.m,
10644           shift;
10645       while (vim = nextRight(vim), vip = nextLeft(vip), vim && vip) {
10646         vom = nextLeft(vom);
10647         vop = nextRight(vop);
10648         vop.a = v;
10649         shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);
10650         if (shift > 0) {
10651           moveSubtree(nextAncestor(vim, v, ancestor), v, shift);
10652           sip += shift;
10653           sop += shift;
10654         }
10655         sim += vim.m;
10656         sip += vip.m;
10657         som += vom.m;
10658         sop += vop.m;
10659       }
10660       if (vim && !nextRight(vop)) {
10661         vop.t = vim;
10662         vop.m += sim - sop;
10663       }
10664       if (vip && !nextLeft(vom)) {
10665         vom.t = vip;
10666         vom.m += sip - som;
10667         ancestor = v;
10668       }
10669     }
10670     return ancestor;
10671   }
10672
10673   function sizeNode(node) {
10674     node.x *= dx;
10675     node.y = node.depth * dy;
10676   }
10677
10678   tree.separation = function(x) {
10679     return arguments.length ? (separation = x, tree) : separation;
10680   };
10681
10682   tree.size = function(x) {
10683     return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], tree) : (nodeSize ? null : [dx, dy]);
10684   };
10685
10686   tree.nodeSize = function(x) {
10687     return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], tree) : (nodeSize ? [dx, dy] : null);
10688   };
10689
10690   return tree;
10691 };
10692
10693 var treemapSlice = function(parent, x0, y0, x1, y1) {
10694   var nodes = parent.children,
10695       node,
10696       i = -1,
10697       n = nodes.length,
10698       k = parent.value && (y1 - y0) / parent.value;
10699
10700   while (++i < n) {
10701     node = nodes[i], node.x0 = x0, node.x1 = x1;
10702     node.y0 = y0, node.y1 = y0 += node.value * k;
10703   }
10704 };
10705
10706 var phi = (1 + Math.sqrt(5)) / 2;
10707
10708 function squarifyRatio(ratio, parent, x0, y0, x1, y1) {
10709   var rows = [],
10710       nodes = parent.children,
10711       row,
10712       nodeValue,
10713       i0 = 0,
10714       i1 = 0,
10715       n = nodes.length,
10716       dx, dy,
10717       value = parent.value,
10718       sumValue,
10719       minValue,
10720       maxValue,
10721       newRatio,
10722       minRatio,
10723       alpha,
10724       beta;
10725
10726   while (i0 < n) {
10727     dx = x1 - x0, dy = y1 - y0;
10728
10729     // Find the next non-empty node.
10730     do sumValue = nodes[i1++].value; while (!sumValue && i1 < n);
10731     minValue = maxValue = sumValue;
10732     alpha = Math.max(dy / dx, dx / dy) / (value * ratio);
10733     beta = sumValue * sumValue * alpha;
10734     minRatio = Math.max(maxValue / beta, beta / minValue);
10735
10736     // Keep adding nodes while the aspect ratio maintains or improves.
10737     for (; i1 < n; ++i1) {
10738       sumValue += nodeValue = nodes[i1].value;
10739       if (nodeValue < minValue) minValue = nodeValue;
10740       if (nodeValue > maxValue) maxValue = nodeValue;
10741       beta = sumValue * sumValue * alpha;
10742       newRatio = Math.max(maxValue / beta, beta / minValue);
10743       if (newRatio > minRatio) { sumValue -= nodeValue; break; }
10744       minRatio = newRatio;
10745     }
10746
10747     // Position and record the row orientation.
10748     rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)});
10749     if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1);
10750     else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1);
10751     value -= sumValue, i0 = i1;
10752   }
10753
10754   return rows;
10755 }
10756
10757 var squarify = (function custom(ratio) {
10758
10759   function squarify(parent, x0, y0, x1, y1) {
10760     squarifyRatio(ratio, parent, x0, y0, x1, y1);
10761   }
10762
10763   squarify.ratio = function(x) {
10764     return custom((x = +x) > 1 ? x : 1);
10765   };
10766
10767   return squarify;
10768 })(phi);
10769
10770 var index$3 = function() {
10771   var tile = squarify,
10772       round = false,
10773       dx = 1,
10774       dy = 1,
10775       paddingStack = [0],
10776       paddingInner = constantZero,
10777       paddingTop = constantZero,
10778       paddingRight = constantZero,
10779       paddingBottom = constantZero,
10780       paddingLeft = constantZero;
10781
10782   function treemap(root) {
10783     root.x0 =
10784     root.y0 = 0;
10785     root.x1 = dx;
10786     root.y1 = dy;
10787     root.eachBefore(positionNode);
10788     paddingStack = [0];
10789     if (round) root.eachBefore(roundNode);
10790     return root;
10791   }
10792
10793   function positionNode(node) {
10794     var p = paddingStack[node.depth],
10795         x0 = node.x0 + p,
10796         y0 = node.y0 + p,
10797         x1 = node.x1 - p,
10798         y1 = node.y1 - p;
10799     if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
10800     if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
10801     node.x0 = x0;
10802     node.y0 = y0;
10803     node.x1 = x1;
10804     node.y1 = y1;
10805     if (node.children) {
10806       p = paddingStack[node.depth + 1] = paddingInner(node) / 2;
10807       x0 += paddingLeft(node) - p;
10808       y0 += paddingTop(node) - p;
10809       x1 -= paddingRight(node) - p;
10810       y1 -= paddingBottom(node) - p;
10811       if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
10812       if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
10813       tile(node, x0, y0, x1, y1);
10814     }
10815   }
10816
10817   treemap.round = function(x) {
10818     return arguments.length ? (round = !!x, treemap) : round;
10819   };
10820
10821   treemap.size = function(x) {
10822     return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy];
10823   };
10824
10825   treemap.tile = function(x) {
10826     return arguments.length ? (tile = required(x), treemap) : tile;
10827   };
10828
10829   treemap.padding = function(x) {
10830     return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner();
10831   };
10832
10833   treemap.paddingInner = function(x) {
10834     return arguments.length ? (paddingInner = typeof x === "function" ? x : constant$8(+x), treemap) : paddingInner;
10835   };
10836
10837   treemap.paddingOuter = function(x) {
10838     return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop();
10839   };
10840
10841   treemap.paddingTop = function(x) {
10842     return arguments.length ? (paddingTop = typeof x === "function" ? x : constant$8(+x), treemap) : paddingTop;
10843   };
10844
10845   treemap.paddingRight = function(x) {
10846     return arguments.length ? (paddingRight = typeof x === "function" ? x : constant$8(+x), treemap) : paddingRight;
10847   };
10848
10849   treemap.paddingBottom = function(x) {
10850     return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant$8(+x), treemap) : paddingBottom;
10851   };
10852
10853   treemap.paddingLeft = function(x) {
10854     return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant$8(+x), treemap) : paddingLeft;
10855   };
10856
10857   return treemap;
10858 };
10859
10860 var binary = function(parent, x0, y0, x1, y1) {
10861   var nodes = parent.children,
10862       i, n = nodes.length,
10863       sum, sums = new Array(n + 1);
10864
10865   for (sums[0] = sum = i = 0; i < n; ++i) {
10866     sums[i + 1] = sum += nodes[i].value;
10867   }
10868
10869   partition(0, n, parent.value, x0, y0, x1, y1);
10870
10871   function partition(i, j, value, x0, y0, x1, y1) {
10872     if (i >= j - 1) {
10873       var node = nodes[i];
10874       node.x0 = x0, node.y0 = y0;
10875       node.x1 = x1, node.y1 = y1;
10876       return;
10877     }
10878
10879     var valueOffset = sums[i],
10880         valueTarget = (value / 2) + valueOffset,
10881         k = i + 1,
10882         hi = j - 1;
10883
10884     while (k < hi) {
10885       var mid = k + hi >>> 1;
10886       if (sums[mid] < valueTarget) k = mid + 1;
10887       else hi = mid;
10888     }
10889
10890     if ((valueTarget - sums[k - 1]) < (sums[k] - valueTarget) && i + 1 < k) --k;
10891
10892     var valueLeft = sums[k] - valueOffset,
10893         valueRight = value - valueLeft;
10894
10895     if ((x1 - x0) > (y1 - y0)) {
10896       var xk = (x0 * valueRight + x1 * valueLeft) / value;
10897       partition(i, k, valueLeft, x0, y0, xk, y1);
10898       partition(k, j, valueRight, xk, y0, x1, y1);
10899     } else {
10900       var yk = (y0 * valueRight + y1 * valueLeft) / value;
10901       partition(i, k, valueLeft, x0, y0, x1, yk);
10902       partition(k, j, valueRight, x0, yk, x1, y1);
10903     }
10904   }
10905 };
10906
10907 var sliceDice = function(parent, x0, y0, x1, y1) {
10908   (parent.depth & 1 ? treemapSlice : treemapDice)(parent, x0, y0, x1, y1);
10909 };
10910
10911 var resquarify = (function custom(ratio) {
10912
10913   function resquarify(parent, x0, y0, x1, y1) {
10914     if ((rows = parent._squarify) && (rows.ratio === ratio)) {
10915       var rows,
10916           row,
10917           nodes,
10918           i,
10919           j = -1,
10920           n,
10921           m = rows.length,
10922           value = parent.value;
10923
10924       while (++j < m) {
10925         row = rows[j], nodes = row.children;
10926         for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value;
10927         if (row.dice) treemapDice(row, x0, y0, x1, y0 += (y1 - y0) * row.value / value);
10928         else treemapSlice(row, x0, y0, x0 += (x1 - x0) * row.value / value, y1);
10929         value -= row.value;
10930       }
10931     } else {
10932       parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1);
10933       rows.ratio = ratio;
10934     }
10935   }
10936
10937   resquarify.ratio = function(x) {
10938     return custom((x = +x) > 1 ? x : 1);
10939   };
10940
10941   return resquarify;
10942 })(phi);
10943
10944 var d3_polygonArea = function(polygon) {
10945   var i = -1,
10946       n = polygon.length,
10947       a,
10948       b = polygon[n - 1],
10949       area = 0;
10950
10951   while (++i < n) {
10952     a = b;
10953     b = polygon[i];
10954     area += a[1] * b[0] - a[0] * b[1];
10955   }
10956
10957   return area / 2;
10958 };
10959
10960 var d3_polygonCentroid = function(polygon) {
10961   var i = -1,
10962       n = polygon.length,
10963       x = 0,
10964       y = 0,
10965       a,
10966       b = polygon[n - 1],
10967       c,
10968       k = 0;
10969
10970   while (++i < n) {
10971     a = b;
10972     b = polygon[i];
10973     k += c = a[0] * b[1] - b[0] * a[1];
10974     x += (a[0] + b[0]) * c;
10975     y += (a[1] + b[1]) * c;
10976   }
10977
10978   return k *= 3, [x / k, y / k];
10979 };
10980
10981 // Returns the 2D cross product of AB and AC vectors, i.e., the z-component of
10982 // the 3D cross product in a quadrant I Cartesian coordinate system (+x is
10983 // right, +y is up). Returns a positive value if ABC is counter-clockwise,
10984 // negative if clockwise, and zero if the points are collinear.
10985 var cross$1 = function(a, b, c) {
10986   return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
10987 };
10988
10989 function lexicographicOrder(a, b) {
10990   return a[0] - b[0] || a[1] - b[1];
10991 }
10992
10993 // Computes the upper convex hull per the monotone chain algorithm.
10994 // Assumes points.length >= 3, is sorted by x, unique in y.
10995 // Returns an array of indices into points in left-to-right order.
10996 function computeUpperHullIndexes(points) {
10997   var n = points.length,
10998       indexes = [0, 1],
10999       size = 2;
11000
11001   for (var i = 2; i < n; ++i) {
11002     while (size > 1 && cross$1(points[indexes[size - 2]], points[indexes[size - 1]], points[i]) <= 0) --size;
11003     indexes[size++] = i;
11004   }
11005
11006   return indexes.slice(0, size); // remove popped points
11007 }
11008
11009 var d3_polygonHull = function(points) {
11010   if ((n = points.length) < 3) return null;
11011
11012   var i,
11013       n,
11014       sortedPoints = new Array(n),
11015       flippedPoints = new Array(n);
11016
11017   for (i = 0; i < n; ++i) sortedPoints[i] = [+points[i][0], +points[i][1], i];
11018   sortedPoints.sort(lexicographicOrder);
11019   for (i = 0; i < n; ++i) flippedPoints[i] = [sortedPoints[i][0], -sortedPoints[i][1]];
11020
11021   var upperIndexes = computeUpperHullIndexes(sortedPoints),
11022       lowerIndexes = computeUpperHullIndexes(flippedPoints);
11023
11024   // Construct the hull polygon, removing possible duplicate endpoints.
11025   var skipLeft = lowerIndexes[0] === upperIndexes[0],
11026       skipRight = lowerIndexes[lowerIndexes.length - 1] === upperIndexes[upperIndexes.length - 1],
11027       hull = [];
11028
11029   // Add upper hull in right-to-l order.
11030   // Then add lower hull in left-to-right order.
11031   for (i = upperIndexes.length - 1; i >= 0; --i) hull.push(points[sortedPoints[upperIndexes[i]][2]]);
11032   for (i = +skipLeft; i < lowerIndexes.length - skipRight; ++i) hull.push(points[sortedPoints[lowerIndexes[i]][2]]);
11033
11034   return hull;
11035 };
11036
11037 var contains$1 = function(polygon, point) {
11038   var n = polygon.length,
11039       p = polygon[n - 1],
11040       x = point[0], y = point[1],
11041       x0 = p[0], y0 = p[1],
11042       x1, y1,
11043       inside = false;
11044
11045   for (var i = 0; i < n; ++i) {
11046     p = polygon[i], x1 = p[0], y1 = p[1];
11047     if (((y1 > y) !== (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside;
11048     x0 = x1, y0 = y1;
11049   }
11050
11051   return inside;
11052 };
11053
11054 var length$1 = function(polygon) {
11055   var i = -1,
11056       n = polygon.length,
11057       b = polygon[n - 1],
11058       xa,
11059       ya,
11060       xb = b[0],
11061       yb = b[1],
11062       perimeter = 0;
11063
11064   while (++i < n) {
11065     xa = xb;
11066     ya = yb;
11067     b = polygon[i];
11068     xb = b[0];
11069     yb = b[1];
11070     xa -= xb;
11071     ya -= yb;
11072     perimeter += Math.sqrt(xa * xa + ya * ya);
11073   }
11074
11075   return perimeter;
11076 };
11077
11078 var slice$4 = [].slice;
11079
11080 var noabort = {};
11081
11082 function Queue(size) {
11083   this._size = size;
11084   this._call =
11085   this._error = null;
11086   this._tasks = [];
11087   this._data = [];
11088   this._waiting =
11089   this._active =
11090   this._ended =
11091   this._start = 0; // inside a synchronous task callback?
11092 }
11093
11094 Queue.prototype = queue.prototype = {
11095   constructor: Queue,
11096   defer: function(callback) {
11097     if (typeof callback !== "function") throw new Error("invalid callback");
11098     if (this._call) throw new Error("defer after await");
11099     if (this._error != null) return this;
11100     var t = slice$4.call(arguments, 1);
11101     t.push(callback);
11102     ++this._waiting, this._tasks.push(t);
11103     poke$1(this);
11104     return this;
11105   },
11106   abort: function() {
11107     if (this._error == null) abort(this, new Error("abort"));
11108     return this;
11109   },
11110   await: function(callback) {
11111     if (typeof callback !== "function") throw new Error("invalid callback");
11112     if (this._call) throw new Error("multiple await");
11113     this._call = function(error, results) { callback.apply(null, [error].concat(results)); };
11114     maybeNotify(this);
11115     return this;
11116   },
11117   awaitAll: function(callback) {
11118     if (typeof callback !== "function") throw new Error("invalid callback");
11119     if (this._call) throw new Error("multiple await");
11120     this._call = callback;
11121     maybeNotify(this);
11122     return this;
11123   }
11124 };
11125
11126 function poke$1(q) {
11127   if (!q._start) {
11128     try { start$1(q); } // let the current task complete
11129     catch (e) {
11130       if (q._tasks[q._ended + q._active - 1]) abort(q, e); // task errored synchronously
11131       else if (!q._data) throw e; // await callback errored synchronously
11132     }
11133   }
11134 }
11135
11136 function start$1(q) {
11137   while (q._start = q._waiting && q._active < q._size) {
11138     var i = q._ended + q._active,
11139         t = q._tasks[i],
11140         j = t.length - 1,
11141         c = t[j];
11142     t[j] = end(q, i);
11143     --q._waiting, ++q._active;
11144     t = c.apply(null, t);
11145     if (!q._tasks[i]) continue; // task finished synchronously
11146     q._tasks[i] = t || noabort;
11147   }
11148 }
11149
11150 function end(q, i) {
11151   return function(e, r) {
11152     if (!q._tasks[i]) return; // ignore multiple callbacks
11153     --q._active, ++q._ended;
11154     q._tasks[i] = null;
11155     if (q._error != null) return; // ignore secondary errors
11156     if (e != null) {
11157       abort(q, e);
11158     } else {
11159       q._data[i] = r;
11160       if (q._waiting) poke$1(q);
11161       else maybeNotify(q);
11162     }
11163   };
11164 }
11165
11166 function abort(q, e) {
11167   var i = q._tasks.length, t;
11168   q._error = e; // ignore active callbacks
11169   q._data = undefined; // allow gc
11170   q._waiting = NaN; // prevent starting
11171
11172   while (--i >= 0) {
11173     if (t = q._tasks[i]) {
11174       q._tasks[i] = null;
11175       if (t.abort) {
11176         try { t.abort(); }
11177         catch (e) { /* ignore */ }
11178       }
11179     }
11180   }
11181
11182   q._active = NaN; // allow notification
11183   maybeNotify(q);
11184 }
11185
11186 function maybeNotify(q) {
11187   if (!q._active && q._call) {
11188     var d = q._data;
11189     q._data = undefined; // allow gc
11190     q._call(q._error, d);
11191   }
11192 }
11193
11194 function queue(concurrency) {
11195   if (concurrency == null) concurrency = Infinity;
11196   else if (!((concurrency = +concurrency) >= 1)) throw new Error("invalid concurrency");
11197   return new Queue(concurrency);
11198 }
11199
11200 var defaultSource$1 = function() {
11201   return Math.random();
11202 };
11203
11204 var uniform = (function sourceRandomUniform(source) {
11205   function randomUniform(min, max) {
11206     min = min == null ? 0 : +min;
11207     max = max == null ? 1 : +max;
11208     if (arguments.length === 1) max = min, min = 0;
11209     else max -= min;
11210     return function() {
11211       return source() * max + min;
11212     };
11213   }
11214
11215   randomUniform.source = sourceRandomUniform;
11216
11217   return randomUniform;
11218 })(defaultSource$1);
11219
11220 var normal = (function sourceRandomNormal(source) {
11221   function randomNormal(mu, sigma) {
11222     var x, r;
11223     mu = mu == null ? 0 : +mu;
11224     sigma = sigma == null ? 1 : +sigma;
11225     return function() {
11226       var y;
11227
11228       // If available, use the second previously-generated uniform random.
11229       if (x != null) y = x, x = null;
11230
11231       // Otherwise, generate a new x and y.
11232       else do {
11233         x = source() * 2 - 1;
11234         y = source() * 2 - 1;
11235         r = x * x + y * y;
11236       } while (!r || r > 1);
11237
11238       return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r);
11239     };
11240   }
11241
11242   randomNormal.source = sourceRandomNormal;
11243
11244   return randomNormal;
11245 })(defaultSource$1);
11246
11247 var logNormal = (function sourceRandomLogNormal(source) {
11248   function randomLogNormal() {
11249     var randomNormal = normal.source(source).apply(this, arguments);
11250     return function() {
11251       return Math.exp(randomNormal());
11252     };
11253   }
11254
11255   randomLogNormal.source = sourceRandomLogNormal;
11256
11257   return randomLogNormal;
11258 })(defaultSource$1);
11259
11260 var irwinHall = (function sourceRandomIrwinHall(source) {
11261   function randomIrwinHall(n) {
11262     return function() {
11263       for (var sum = 0, i = 0; i < n; ++i) sum += source();
11264       return sum;
11265     };
11266   }
11267
11268   randomIrwinHall.source = sourceRandomIrwinHall;
11269
11270   return randomIrwinHall;
11271 })(defaultSource$1);
11272
11273 var bates = (function sourceRandomBates(source) {
11274   function randomBates(n) {
11275     var randomIrwinHall = irwinHall.source(source)(n);
11276     return function() {
11277       return randomIrwinHall() / n;
11278     };
11279   }
11280
11281   randomBates.source = sourceRandomBates;
11282
11283   return randomBates;
11284 })(defaultSource$1);
11285
11286 var exponential$1 = (function sourceRandomExponential(source) {
11287   function randomExponential(lambda) {
11288     return function() {
11289       return -Math.log(1 - source()) / lambda;
11290     };
11291   }
11292
11293   randomExponential.source = sourceRandomExponential;
11294
11295   return randomExponential;
11296 })(defaultSource$1);
11297
11298 var d3_request = function(url, callback) {
11299   var request,
11300       event = dispatch("beforesend", "progress", "load", "error"),
11301       mimeType,
11302       headers = map$1(),
11303       xhr = new XMLHttpRequest,
11304       user = null,
11305       password = null,
11306       response,
11307       responseType,
11308       timeout = 0;
11309
11310   // If IE does not support CORS, use XDomainRequest.
11311   if (typeof XDomainRequest !== "undefined"
11312       && !("withCredentials" in xhr)
11313       && /^(http(s)?:)?\/\//.test(url)) xhr = new XDomainRequest;
11314
11315   "onload" in xhr
11316       ? xhr.onload = xhr.onerror = xhr.ontimeout = respond
11317       : xhr.onreadystatechange = function(o) { xhr.readyState > 3 && respond(o); };
11318
11319   function respond(o) {
11320     var status = xhr.status, result;
11321     if (!status && hasResponse(xhr)
11322         || status >= 200 && status < 300
11323         || status === 304) {
11324       if (response) {
11325         try {
11326           result = response.call(request, xhr);
11327         } catch (e) {
11328           event.call("error", request, e);
11329           return;
11330         }
11331       } else {
11332         result = xhr;
11333       }
11334       event.call("load", request, result);
11335     } else {
11336       event.call("error", request, o);
11337     }
11338   }
11339
11340   xhr.onprogress = function(e) {
11341     event.call("progress", request, e);
11342   };
11343
11344   request = {
11345     header: function(name, value) {
11346       name = (name + "").toLowerCase();
11347       if (arguments.length < 2) return headers.get(name);
11348       if (value == null) headers.remove(name);
11349       else headers.set(name, value + "");
11350       return request;
11351     },
11352
11353     // If mimeType is non-null and no Accept header is set, a default is used.
11354     mimeType: function(value) {
11355       if (!arguments.length) return mimeType;
11356       mimeType = value == null ? null : value + "";
11357       return request;
11358     },
11359
11360     // Specifies what type the response value should take;
11361     // for instance, arraybuffer, blob, document, or text.
11362     responseType: function(value) {
11363       if (!arguments.length) return responseType;
11364       responseType = value;
11365       return request;
11366     },
11367
11368     timeout: function(value) {
11369       if (!arguments.length) return timeout;
11370       timeout = +value;
11371       return request;
11372     },
11373
11374     user: function(value) {
11375       return arguments.length < 1 ? user : (user = value == null ? null : value + "", request);
11376     },
11377
11378     password: function(value) {
11379       return arguments.length < 1 ? password : (password = value == null ? null : value + "", request);
11380     },
11381
11382     // Specify how to convert the response content to a specific type;
11383     // changes the callback value on "load" events.
11384     response: function(value) {
11385       response = value;
11386       return request;
11387     },
11388
11389     // Alias for send("GET", …).
11390     get: function(data, callback) {
11391       return request.send("GET", data, callback);
11392     },
11393
11394     // Alias for send("POST", …).
11395     post: function(data, callback) {
11396       return request.send("POST", data, callback);
11397     },
11398
11399     // If callback is non-null, it will be used for error and load events.
11400     send: function(method, data, callback) {
11401       xhr.open(method, url, true, user, password);
11402       if (mimeType != null && !headers.has("accept")) headers.set("accept", mimeType + ",*/*");
11403       if (xhr.setRequestHeader) headers.each(function(value, name) { xhr.setRequestHeader(name, value); });
11404       if (mimeType != null && xhr.overrideMimeType) xhr.overrideMimeType(mimeType);
11405       if (responseType != null) xhr.responseType = responseType;
11406       if (timeout > 0) xhr.timeout = timeout;
11407       if (callback == null && typeof data === "function") callback = data, data = null;
11408       if (callback != null && callback.length === 1) callback = fixCallback(callback);
11409       if (callback != null) request.on("error", callback).on("load", function(xhr) { callback(null, xhr); });
11410       event.call("beforesend", request, xhr);
11411       xhr.send(data == null ? null : data);
11412       return request;
11413     },
11414
11415     abort: function() {
11416       xhr.abort();
11417       return request;
11418     },
11419
11420     on: function() {
11421       var value = event.on.apply(event, arguments);
11422       return value === event ? request : value;
11423     }
11424   };
11425
11426   if (callback != null) {
11427     if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
11428     return request.get(callback);
11429   }
11430
11431   return request;
11432 };
11433
11434 function fixCallback(callback) {
11435   return function(error, xhr) {
11436     callback(error == null ? xhr : null);
11437   };
11438 }
11439
11440 function hasResponse(xhr) {
11441   var type = xhr.responseType;
11442   return type && type !== "text"
11443       ? xhr.response // null on error
11444       : xhr.responseText; // "" on error
11445 }
11446
11447 var type$1 = function(defaultMimeType, response) {
11448   return function(url, callback) {
11449     var r = d3_request(url).mimeType(defaultMimeType).response(response);
11450     if (callback != null) {
11451       if (typeof callback !== "function") throw new Error("invalid callback: " + callback);
11452       return r.get(callback);
11453     }
11454     return r;
11455   };
11456 };
11457
11458 var html = type$1("text/html", function(xhr) {
11459   return document.createRange().createContextualFragment(xhr.responseText);
11460 });
11461
11462 var d3_json = type$1("application/json", function(xhr) {
11463   return JSON.parse(xhr.responseText);
11464 });
11465
11466 var d3_text = type$1("text/plain", function(xhr) {
11467   return xhr.responseText;
11468 });
11469
11470 var d3_xml = type$1("application/xml", function(xhr) {
11471   var xml = xhr.responseXML;
11472   if (!xml) throw new Error("parse error");
11473   return xml;
11474 });
11475
11476 var dsv$1 = function(defaultMimeType, parse) {
11477   return function(url, row, callback) {
11478     if (arguments.length < 3) callback = row, row = null;
11479     var r = d3_request(url).mimeType(defaultMimeType);
11480     r.row = function(_) { return arguments.length ? r.response(responseOf(parse, row = _)) : row; };
11481     r.row(row);
11482     return callback ? r.get(callback) : r;
11483   };
11484 };
11485
11486 function responseOf(parse, row) {
11487   return function(request) {
11488     return parse(request.responseText, row);
11489   };
11490 }
11491
11492 var csv$1 = dsv$1("text/csv", csvParse);
11493
11494 var tsv$1 = dsv$1("text/tab-separated-values", tsvParse);
11495
11496 var array$2 = Array.prototype;
11497
11498 var map$3 = array$2.map;
11499 var slice$5 = array$2.slice;
11500
11501 var implicit = {name: "implicit"};
11502
11503 function ordinal(range) {
11504   var index = map$1(),
11505       domain = [],
11506       unknown = implicit;
11507
11508   range = range == null ? [] : slice$5.call(range);
11509
11510   function scale(d) {
11511     var key = d + "", i = index.get(key);
11512     if (!i) {
11513       if (unknown !== implicit) return unknown;
11514       index.set(key, i = domain.push(d));
11515     }
11516     return range[(i - 1) % range.length];
11517   }
11518
11519   scale.domain = function(_) {
11520     if (!arguments.length) return domain.slice();
11521     domain = [], index = map$1();
11522     var i = -1, n = _.length, d, key;
11523     while (++i < n) if (!index.has(key = (d = _[i]) + "")) index.set(key, domain.push(d));
11524     return scale;
11525   };
11526
11527   scale.range = function(_) {
11528     return arguments.length ? (range = slice$5.call(_), scale) : range.slice();
11529   };
11530
11531   scale.unknown = function(_) {
11532     return arguments.length ? (unknown = _, scale) : unknown;
11533   };
11534
11535   scale.copy = function() {
11536     return ordinal()
11537         .domain(domain)
11538         .range(range)
11539         .unknown(unknown);
11540   };
11541
11542   return scale;
11543 }
11544
11545 function band() {
11546   var scale = ordinal().unknown(undefined),
11547       domain = scale.domain,
11548       ordinalRange = scale.range,
11549       range$$1 = [0, 1],
11550       step,
11551       bandwidth,
11552       round = false,
11553       paddingInner = 0,
11554       paddingOuter = 0,
11555       align = 0.5;
11556
11557   delete scale.unknown;
11558
11559   function rescale() {
11560     var n = domain().length,
11561         reverse = range$$1[1] < range$$1[0],
11562         start = range$$1[reverse - 0],
11563         stop = range$$1[1 - reverse];
11564     step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);
11565     if (round) step = Math.floor(step);
11566     start += (stop - start - step * (n - paddingInner)) * align;
11567     bandwidth = step * (1 - paddingInner);
11568     if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);
11569     var values = d3_range(n).map(function(i) { return start + step * i; });
11570     return ordinalRange(reverse ? values.reverse() : values);
11571   }
11572
11573   scale.domain = function(_) {
11574     return arguments.length ? (domain(_), rescale()) : domain();
11575   };
11576
11577   scale.range = function(_) {
11578     return arguments.length ? (range$$1 = [+_[0], +_[1]], rescale()) : range$$1.slice();
11579   };
11580
11581   scale.rangeRound = function(_) {
11582     return range$$1 = [+_[0], +_[1]], round = true, rescale();
11583   };
11584
11585   scale.bandwidth = function() {
11586     return bandwidth;
11587   };
11588
11589   scale.step = function() {
11590     return step;
11591   };
11592
11593   scale.round = function(_) {
11594     return arguments.length ? (round = !!_, rescale()) : round;
11595   };
11596
11597   scale.padding = function(_) {
11598     return arguments.length ? (paddingInner = paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
11599   };
11600
11601   scale.paddingInner = function(_) {
11602     return arguments.length ? (paddingInner = Math.max(0, Math.min(1, _)), rescale()) : paddingInner;
11603   };
11604
11605   scale.paddingOuter = function(_) {
11606     return arguments.length ? (paddingOuter = Math.max(0, Math.min(1, _)), rescale()) : paddingOuter;
11607   };
11608
11609   scale.align = function(_) {
11610     return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;
11611   };
11612
11613   scale.copy = function() {
11614     return band()
11615         .domain(domain())
11616         .range(range$$1)
11617         .round(round)
11618         .paddingInner(paddingInner)
11619         .paddingOuter(paddingOuter)
11620         .align(align);
11621   };
11622
11623   return rescale();
11624 }
11625
11626 function pointish(scale) {
11627   var copy = scale.copy;
11628
11629   scale.padding = scale.paddingOuter;
11630   delete scale.paddingInner;
11631   delete scale.paddingOuter;
11632
11633   scale.copy = function() {
11634     return pointish(copy());
11635   };
11636
11637   return scale;
11638 }
11639
11640 function point$1() {
11641   return pointish(band().paddingInner(1));
11642 }
11643
11644 var constant$9 = function(x) {
11645   return function() {
11646     return x;
11647   };
11648 };
11649
11650 var number$2 = function(x) {
11651   return +x;
11652 };
11653
11654 var unit = [0, 1];
11655
11656 function deinterpolateLinear(a, b) {
11657   return (b -= (a = +a))
11658       ? function(x) { return (x - a) / b; }
11659       : constant$9(b);
11660 }
11661
11662 function deinterpolateClamp(deinterpolate) {
11663   return function(a, b) {
11664     var d = deinterpolate(a = +a, b = +b);
11665     return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); };
11666   };
11667 }
11668
11669 function reinterpolateClamp(reinterpolate) {
11670   return function(a, b) {
11671     var r = reinterpolate(a = +a, b = +b);
11672     return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); };
11673   };
11674 }
11675
11676 function bimap(domain, range, deinterpolate, reinterpolate) {
11677   var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1];
11678   if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate(r1, r0);
11679   else d0 = deinterpolate(d0, d1), r0 = reinterpolate(r0, r1);
11680   return function(x) { return r0(d0(x)); };
11681 }
11682
11683 function polymap(domain, range, deinterpolate, reinterpolate) {
11684   var j = Math.min(domain.length, range.length) - 1,
11685       d = new Array(j),
11686       r = new Array(j),
11687       i = -1;
11688
11689   // Reverse descending domains.
11690   if (domain[j] < domain[0]) {
11691     domain = domain.slice().reverse();
11692     range = range.slice().reverse();
11693   }
11694
11695   while (++i < j) {
11696     d[i] = deinterpolate(domain[i], domain[i + 1]);
11697     r[i] = reinterpolate(range[i], range[i + 1]);
11698   }
11699
11700   return function(x) {
11701     var i = bisectRight(domain, x, 1, j) - 1;
11702     return r[i](d[i](x));
11703   };
11704 }
11705
11706 function copy(source, target) {
11707   return target
11708       .domain(source.domain())
11709       .range(source.range())
11710       .interpolate(source.interpolate())
11711       .clamp(source.clamp());
11712 }
11713
11714 // deinterpolate(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].
11715 // reinterpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding domain value x in [a,b].
11716 function continuous(deinterpolate, reinterpolate) {
11717   var domain = unit,
11718       range = unit,
11719       interpolate$$1 = d3_interpolate,
11720       clamp = false,
11721       piecewise,
11722       output,
11723       input;
11724
11725   function rescale() {
11726     piecewise = Math.min(domain.length, range.length) > 2 ? polymap : bimap;
11727     output = input = null;
11728     return scale;
11729   }
11730
11731   function scale(x) {
11732     return (output || (output = piecewise(domain, range, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate$$1)))(+x);
11733   }
11734
11735   scale.invert = function(y) {
11736     return (input || (input = piecewise(range, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate) : reinterpolate)))(+y);
11737   };
11738
11739   scale.domain = function(_) {
11740     return arguments.length ? (domain = map$3.call(_, number$2), rescale()) : domain.slice();
11741   };
11742
11743   scale.range = function(_) {
11744     return arguments.length ? (range = slice$5.call(_), rescale()) : range.slice();
11745   };
11746
11747   scale.rangeRound = function(_) {
11748     return range = slice$5.call(_), interpolate$$1 = interpolateRound, rescale();
11749   };
11750
11751   scale.clamp = function(_) {
11752     return arguments.length ? (clamp = !!_, rescale()) : clamp;
11753   };
11754
11755   scale.interpolate = function(_) {
11756     return arguments.length ? (interpolate$$1 = _, rescale()) : interpolate$$1;
11757   };
11758
11759   return rescale();
11760 }
11761
11762 var tickFormat = function(domain, count, specifier) {
11763   var start = domain[0],
11764       stop = domain[domain.length - 1],
11765       step = tickStep(start, stop, count == null ? 10 : count),
11766       precision;
11767   specifier = formatSpecifier(specifier == null ? ",f" : specifier);
11768   switch (specifier.type) {
11769     case "s": {
11770       var value = Math.max(Math.abs(start), Math.abs(stop));
11771       if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;
11772       return formatPrefix(specifier, value);
11773     }
11774     case "":
11775     case "e":
11776     case "g":
11777     case "p":
11778     case "r": {
11779       if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e");
11780       break;
11781     }
11782     case "f":
11783     case "%": {
11784       if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2;
11785       break;
11786     }
11787   }
11788   return format(specifier);
11789 };
11790
11791 function linearish(scale) {
11792   var domain = scale.domain;
11793
11794   scale.ticks = function(count) {
11795     var d = domain();
11796     return ticks(d[0], d[d.length - 1], count == null ? 10 : count);
11797   };
11798
11799   scale.tickFormat = function(count, specifier) {
11800     return tickFormat(domain(), count, specifier);
11801   };
11802
11803   scale.nice = function(count) {
11804     if (count == null) count = 10;
11805
11806     var d = domain(),
11807         i0 = 0,
11808         i1 = d.length - 1,
11809         start = d[i0],
11810         stop = d[i1],
11811         step;
11812
11813     if (stop < start) {
11814       step = start, start = stop, stop = step;
11815       step = i0, i0 = i1, i1 = step;
11816     }
11817
11818     step = tickIncrement(start, stop, count);
11819
11820     if (step > 0) {
11821       start = Math.floor(start / step) * step;
11822       stop = Math.ceil(stop / step) * step;
11823       step = tickIncrement(start, stop, count);
11824     } else if (step < 0) {
11825       start = Math.ceil(start * step) / step;
11826       stop = Math.floor(stop * step) / step;
11827       step = tickIncrement(start, stop, count);
11828     }
11829
11830     if (step > 0) {
11831       d[i0] = Math.floor(start / step) * step;
11832       d[i1] = Math.ceil(stop / step) * step;
11833       domain(d);
11834     } else if (step < 0) {
11835       d[i0] = Math.ceil(start * step) / step;
11836       d[i1] = Math.floor(stop * step) / step;
11837       domain(d);
11838     }
11839
11840     return scale;
11841   };
11842
11843   return scale;
11844 }
11845
11846 function linear$2() {
11847   var scale = continuous(deinterpolateLinear, d3_interpolateNumber);
11848
11849   scale.copy = function() {
11850     return copy(scale, linear$2());
11851   };
11852
11853   return linearish(scale);
11854 }
11855
11856 function identity$5() {
11857   var domain = [0, 1];
11858
11859   function scale(x) {
11860     return +x;
11861   }
11862
11863   scale.invert = scale;
11864
11865   scale.domain = scale.range = function(_) {
11866     return arguments.length ? (domain = map$3.call(_, number$2), scale) : domain.slice();
11867   };
11868
11869   scale.copy = function() {
11870     return identity$5().domain(domain);
11871   };
11872
11873   return linearish(scale);
11874 }
11875
11876 var nice = function(domain, interval) {
11877   domain = domain.slice();
11878
11879   var i0 = 0,
11880       i1 = domain.length - 1,
11881       x0 = domain[i0],
11882       x1 = domain[i1],
11883       t;
11884
11885   if (x1 < x0) {
11886     t = i0, i0 = i1, i1 = t;
11887     t = x0, x0 = x1, x1 = t;
11888   }
11889
11890   domain[i0] = interval.floor(x0);
11891   domain[i1] = interval.ceil(x1);
11892   return domain;
11893 };
11894
11895 function deinterpolate(a, b) {
11896   return (b = Math.log(b / a))
11897       ? function(x) { return Math.log(x / a) / b; }
11898       : constant$9(b);
11899 }
11900
11901 function reinterpolate(a, b) {
11902   return a < 0
11903       ? function(t) { return -Math.pow(-b, t) * Math.pow(-a, 1 - t); }
11904       : function(t) { return Math.pow(b, t) * Math.pow(a, 1 - t); };
11905 }
11906
11907 function pow10(x) {
11908   return isFinite(x) ? +("1e" + x) : x < 0 ? 0 : x;
11909 }
11910
11911 function powp(base) {
11912   return base === 10 ? pow10
11913       : base === Math.E ? Math.exp
11914       : function(x) { return Math.pow(base, x); };
11915 }
11916
11917 function logp(base) {
11918   return base === Math.E ? Math.log
11919       : base === 10 && Math.log10
11920       || base === 2 && Math.log2
11921       || (base = Math.log(base), function(x) { return Math.log(x) / base; });
11922 }
11923
11924 function reflect(f) {
11925   return function(x) {
11926     return -f(-x);
11927   };
11928 }
11929
11930 function log$1() {
11931   var scale = continuous(deinterpolate, reinterpolate).domain([1, 10]),
11932       domain = scale.domain,
11933       base = 10,
11934       logs = logp(10),
11935       pows = powp(10);
11936
11937   function rescale() {
11938     logs = logp(base), pows = powp(base);
11939     if (domain()[0] < 0) logs = reflect(logs), pows = reflect(pows);
11940     return scale;
11941   }
11942
11943   scale.base = function(_) {
11944     return arguments.length ? (base = +_, rescale()) : base;
11945   };
11946
11947   scale.domain = function(_) {
11948     return arguments.length ? (domain(_), rescale()) : domain();
11949   };
11950
11951   scale.ticks = function(count) {
11952     var d = domain(),
11953         u = d[0],
11954         v = d[d.length - 1],
11955         r;
11956
11957     if (r = v < u) i = u, u = v, v = i;
11958
11959     var i = logs(u),
11960         j = logs(v),
11961         p,
11962         k,
11963         t,
11964         n = count == null ? 10 : +count,
11965         z = [];
11966
11967     if (!(base % 1) && j - i < n) {
11968       i = Math.round(i) - 1, j = Math.round(j) + 1;
11969       if (u > 0) for (; i < j; ++i) {
11970         for (k = 1, p = pows(i); k < base; ++k) {
11971           t = p * k;
11972           if (t < u) continue;
11973           if (t > v) break;
11974           z.push(t);
11975         }
11976       } else for (; i < j; ++i) {
11977         for (k = base - 1, p = pows(i); k >= 1; --k) {
11978           t = p * k;
11979           if (t < u) continue;
11980           if (t > v) break;
11981           z.push(t);
11982         }
11983       }
11984     } else {
11985       z = ticks(i, j, Math.min(j - i, n)).map(pows);
11986     }
11987
11988     return r ? z.reverse() : z;
11989   };
11990
11991   scale.tickFormat = function(count, specifier) {
11992     if (specifier == null) specifier = base === 10 ? ".0e" : ",";
11993     if (typeof specifier !== "function") specifier = format(specifier);
11994     if (count === Infinity) return specifier;
11995     if (count == null) count = 10;
11996     var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?
11997     return function(d) {
11998       var i = d / pows(Math.round(logs(d)));
11999       if (i * base < base - 0.5) i *= base;
12000       return i <= k ? specifier(d) : "";
12001     };
12002   };
12003
12004   scale.nice = function() {
12005     return domain(nice(domain(), {
12006       floor: function(x) { return pows(Math.floor(logs(x))); },
12007       ceil: function(x) { return pows(Math.ceil(logs(x))); }
12008     }));
12009   };
12010
12011   scale.copy = function() {
12012     return copy(scale, log$1().base(base));
12013   };
12014
12015   return scale;
12016 }
12017
12018 function raise$1(x, exponent) {
12019   return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);
12020 }
12021
12022 function pow$1() {
12023   var exponent = 1,
12024       scale = continuous(deinterpolate, reinterpolate),
12025       domain = scale.domain;
12026
12027   function deinterpolate(a, b) {
12028     return (b = raise$1(b, exponent) - (a = raise$1(a, exponent)))
12029         ? function(x) { return (raise$1(x, exponent) - a) / b; }
12030         : constant$9(b);
12031   }
12032
12033   function reinterpolate(a, b) {
12034     b = raise$1(b, exponent) - (a = raise$1(a, exponent));
12035     return function(t) { return raise$1(a + b * t, 1 / exponent); };
12036   }
12037
12038   scale.exponent = function(_) {
12039     return arguments.length ? (exponent = +_, domain(domain())) : exponent;
12040   };
12041
12042   scale.copy = function() {
12043     return copy(scale, pow$1().exponent(exponent));
12044   };
12045
12046   return linearish(scale);
12047 }
12048
12049 function sqrt$1() {
12050   return pow$1().exponent(0.5);
12051 }
12052
12053 function quantile$$1() {
12054   var domain = [],
12055       range = [],
12056       thresholds = [];
12057
12058   function rescale() {
12059     var i = 0, n = Math.max(1, range.length);
12060     thresholds = new Array(n - 1);
12061     while (++i < n) thresholds[i - 1] = threshold(domain, i / n);
12062     return scale;
12063   }
12064
12065   function scale(x) {
12066     if (!isNaN(x = +x)) return range[bisectRight(thresholds, x)];
12067   }
12068
12069   scale.invertExtent = function(y) {
12070     var i = range.indexOf(y);
12071     return i < 0 ? [NaN, NaN] : [
12072       i > 0 ? thresholds[i - 1] : domain[0],
12073       i < thresholds.length ? thresholds[i] : domain[domain.length - 1]
12074     ];
12075   };
12076
12077   scale.domain = function(_) {
12078     if (!arguments.length) return domain.slice();
12079     domain = [];
12080     for (var i = 0, n = _.length, d; i < n; ++i) if (d = _[i], d != null && !isNaN(d = +d)) domain.push(d);
12081     domain.sort(d3_ascending);
12082     return rescale();
12083   };
12084
12085   scale.range = function(_) {
12086     return arguments.length ? (range = slice$5.call(_), rescale()) : range.slice();
12087   };
12088
12089   scale.quantiles = function() {
12090     return thresholds.slice();
12091   };
12092
12093   scale.copy = function() {
12094     return quantile$$1()
12095         .domain(domain)
12096         .range(range);
12097   };
12098
12099   return scale;
12100 }
12101
12102 function quantize() {
12103   var x0 = 0,
12104       x1 = 1,
12105       n = 1,
12106       domain = [0.5],
12107       range = [0, 1];
12108
12109   function scale(x) {
12110     if (x <= x) return range[bisectRight(domain, x, 0, n)];
12111   }
12112
12113   function rescale() {
12114     var i = -1;
12115     domain = new Array(n);
12116     while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1);
12117     return scale;
12118   }
12119
12120   scale.domain = function(_) {
12121     return arguments.length ? (x0 = +_[0], x1 = +_[1], rescale()) : [x0, x1];
12122   };
12123
12124   scale.range = function(_) {
12125     return arguments.length ? (n = (range = slice$5.call(_)).length - 1, rescale()) : range.slice();
12126   };
12127
12128   scale.invertExtent = function(y) {
12129     var i = range.indexOf(y);
12130     return i < 0 ? [NaN, NaN]
12131         : i < 1 ? [x0, domain[0]]
12132         : i >= n ? [domain[n - 1], x1]
12133         : [domain[i - 1], domain[i]];
12134   };
12135
12136   scale.copy = function() {
12137     return quantize()
12138         .domain([x0, x1])
12139         .range(range);
12140   };
12141
12142   return linearish(scale);
12143 }
12144
12145 function threshold$1() {
12146   var domain = [0.5],
12147       range = [0, 1],
12148       n = 1;
12149
12150   function scale(x) {
12151     if (x <= x) return range[bisectRight(domain, x, 0, n)];
12152   }
12153
12154   scale.domain = function(_) {
12155     return arguments.length ? (domain = slice$5.call(_), n = Math.min(domain.length, range.length - 1), scale) : domain.slice();
12156   };
12157
12158   scale.range = function(_) {
12159     return arguments.length ? (range = slice$5.call(_), n = Math.min(domain.length, range.length - 1), scale) : range.slice();
12160   };
12161
12162   scale.invertExtent = function(y) {
12163     var i = range.indexOf(y);
12164     return [domain[i - 1], domain[i]];
12165   };
12166
12167   scale.copy = function() {
12168     return threshold$1()
12169         .domain(domain)
12170         .range(range);
12171   };
12172
12173   return scale;
12174 }
12175
12176 var t0$1 = new Date;
12177 var t1$1 = new Date;
12178
12179 function newInterval(floori, offseti, count, field) {
12180
12181   function interval(date) {
12182     return floori(date = new Date(+date)), date;
12183   }
12184
12185   interval.floor = interval;
12186
12187   interval.ceil = function(date) {
12188     return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;
12189   };
12190
12191   interval.round = function(date) {
12192     var d0 = interval(date),
12193         d1 = interval.ceil(date);
12194     return date - d0 < d1 - date ? d0 : d1;
12195   };
12196
12197   interval.offset = function(date, step) {
12198     return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;
12199   };
12200
12201   interval.range = function(start, stop, step) {
12202     var range = [];
12203     start = interval.ceil(start);
12204     step = step == null ? 1 : Math.floor(step);
12205     if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date
12206     do range.push(new Date(+start)); while (offseti(start, step), floori(start), start < stop)
12207     return range;
12208   };
12209
12210   interval.filter = function(test) {
12211     return newInterval(function(date) {
12212       if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);
12213     }, function(date, step) {
12214       if (date >= date) {
12215         if (step < 0) while (++step <= 0) {
12216           while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty
12217         } else while (--step >= 0) {
12218           while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty
12219         }
12220       }
12221     });
12222   };
12223
12224   if (count) {
12225     interval.count = function(start, end) {
12226       t0$1.setTime(+start), t1$1.setTime(+end);
12227       floori(t0$1), floori(t1$1);
12228       return Math.floor(count(t0$1, t1$1));
12229     };
12230
12231     interval.every = function(step) {
12232       step = Math.floor(step);
12233       return !isFinite(step) || !(step > 0) ? null
12234           : !(step > 1) ? interval
12235           : interval.filter(field
12236               ? function(d) { return field(d) % step === 0; }
12237               : function(d) { return interval.count(0, d) % step === 0; });
12238     };
12239   }
12240
12241   return interval;
12242 }
12243
12244 var millisecond = newInterval(function() {
12245   // noop
12246 }, function(date, step) {
12247   date.setTime(+date + step);
12248 }, function(start, end) {
12249   return end - start;
12250 });
12251
12252 // An optimized implementation for this simple case.
12253 millisecond.every = function(k) {
12254   k = Math.floor(k);
12255   if (!isFinite(k) || !(k > 0)) return null;
12256   if (!(k > 1)) return millisecond;
12257   return newInterval(function(date) {
12258     date.setTime(Math.floor(date / k) * k);
12259   }, function(date, step) {
12260     date.setTime(+date + step * k);
12261   }, function(start, end) {
12262     return (end - start) / k;
12263   });
12264 };
12265
12266 var milliseconds = millisecond.range;
12267
12268 var durationSecond$1 = 1e3;
12269 var durationMinute$1 = 6e4;
12270 var durationHour$1 = 36e5;
12271 var durationDay$1 = 864e5;
12272 var durationWeek$1 = 6048e5;
12273
12274 var second = newInterval(function(date) {
12275   date.setTime(Math.floor(date / durationSecond$1) * durationSecond$1);
12276 }, function(date, step) {
12277   date.setTime(+date + step * durationSecond$1);
12278 }, function(start, end) {
12279   return (end - start) / durationSecond$1;
12280 }, function(date) {
12281   return date.getUTCSeconds();
12282 });
12283
12284 var seconds = second.range;
12285
12286 var minute = newInterval(function(date) {
12287   date.setTime(Math.floor(date / durationMinute$1) * durationMinute$1);
12288 }, function(date, step) {
12289   date.setTime(+date + step * durationMinute$1);
12290 }, function(start, end) {
12291   return (end - start) / durationMinute$1;
12292 }, function(date) {
12293   return date.getMinutes();
12294 });
12295
12296 var minutes = minute.range;
12297
12298 var hour = newInterval(function(date) {
12299   var offset = date.getTimezoneOffset() * durationMinute$1 % durationHour$1;
12300   if (offset < 0) offset += durationHour$1;
12301   date.setTime(Math.floor((+date - offset) / durationHour$1) * durationHour$1 + offset);
12302 }, function(date, step) {
12303   date.setTime(+date + step * durationHour$1);
12304 }, function(start, end) {
12305   return (end - start) / durationHour$1;
12306 }, function(date) {
12307   return date.getHours();
12308 });
12309
12310 var hours = hour.range;
12311
12312 var day = newInterval(function(date) {
12313   date.setHours(0, 0, 0, 0);
12314 }, function(date, step) {
12315   date.setDate(date.getDate() + step);
12316 }, function(start, end) {
12317   return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute$1) / durationDay$1;
12318 }, function(date) {
12319   return date.getDate() - 1;
12320 });
12321
12322 var days = day.range;
12323
12324 function weekday(i) {
12325   return newInterval(function(date) {
12326     date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);
12327     date.setHours(0, 0, 0, 0);
12328   }, function(date, step) {
12329     date.setDate(date.getDate() + step * 7);
12330   }, function(start, end) {
12331     return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute$1) / durationWeek$1;
12332   });
12333 }
12334
12335 var sunday = weekday(0);
12336 var monday = weekday(1);
12337 var tuesday = weekday(2);
12338 var wednesday = weekday(3);
12339 var thursday = weekday(4);
12340 var friday = weekday(5);
12341 var saturday = weekday(6);
12342
12343 var sundays = sunday.range;
12344 var mondays = monday.range;
12345 var tuesdays = tuesday.range;
12346 var wednesdays = wednesday.range;
12347 var thursdays = thursday.range;
12348 var fridays = friday.range;
12349 var saturdays = saturday.range;
12350
12351 var month = newInterval(function(date) {
12352   date.setDate(1);
12353   date.setHours(0, 0, 0, 0);
12354 }, function(date, step) {
12355   date.setMonth(date.getMonth() + step);
12356 }, function(start, end) {
12357   return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;
12358 }, function(date) {
12359   return date.getMonth();
12360 });
12361
12362 var months = month.range;
12363
12364 var year = newInterval(function(date) {
12365   date.setMonth(0, 1);
12366   date.setHours(0, 0, 0, 0);
12367 }, function(date, step) {
12368   date.setFullYear(date.getFullYear() + step);
12369 }, function(start, end) {
12370   return end.getFullYear() - start.getFullYear();
12371 }, function(date) {
12372   return date.getFullYear();
12373 });
12374
12375 // An optimized implementation for this simple case.
12376 year.every = function(k) {
12377   return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
12378     date.setFullYear(Math.floor(date.getFullYear() / k) * k);
12379     date.setMonth(0, 1);
12380     date.setHours(0, 0, 0, 0);
12381   }, function(date, step) {
12382     date.setFullYear(date.getFullYear() + step * k);
12383   });
12384 };
12385
12386 var years = year.range;
12387
12388 var utcMinute = newInterval(function(date) {
12389   date.setUTCSeconds(0, 0);
12390 }, function(date, step) {
12391   date.setTime(+date + step * durationMinute$1);
12392 }, function(start, end) {
12393   return (end - start) / durationMinute$1;
12394 }, function(date) {
12395   return date.getUTCMinutes();
12396 });
12397
12398 var utcMinutes = utcMinute.range;
12399
12400 var utcHour = newInterval(function(date) {
12401   date.setUTCMinutes(0, 0, 0);
12402 }, function(date, step) {
12403   date.setTime(+date + step * durationHour$1);
12404 }, function(start, end) {
12405   return (end - start) / durationHour$1;
12406 }, function(date) {
12407   return date.getUTCHours();
12408 });
12409
12410 var utcHours = utcHour.range;
12411
12412 var utcDay = newInterval(function(date) {
12413   date.setUTCHours(0, 0, 0, 0);
12414 }, function(date, step) {
12415   date.setUTCDate(date.getUTCDate() + step);
12416 }, function(start, end) {
12417   return (end - start) / durationDay$1;
12418 }, function(date) {
12419   return date.getUTCDate() - 1;
12420 });
12421
12422 var utcDays = utcDay.range;
12423
12424 function utcWeekday(i) {
12425   return newInterval(function(date) {
12426     date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);
12427     date.setUTCHours(0, 0, 0, 0);
12428   }, function(date, step) {
12429     date.setUTCDate(date.getUTCDate() + step * 7);
12430   }, function(start, end) {
12431     return (end - start) / durationWeek$1;
12432   });
12433 }
12434
12435 var utcSunday = utcWeekday(0);
12436 var utcMonday = utcWeekday(1);
12437 var utcTuesday = utcWeekday(2);
12438 var utcWednesday = utcWeekday(3);
12439 var utcThursday = utcWeekday(4);
12440 var utcFriday = utcWeekday(5);
12441 var utcSaturday = utcWeekday(6);
12442
12443 var utcSundays = utcSunday.range;
12444 var utcMondays = utcMonday.range;
12445 var utcTuesdays = utcTuesday.range;
12446 var utcWednesdays = utcWednesday.range;
12447 var utcThursdays = utcThursday.range;
12448 var utcFridays = utcFriday.range;
12449 var utcSaturdays = utcSaturday.range;
12450
12451 var utcMonth = newInterval(function(date) {
12452   date.setUTCDate(1);
12453   date.setUTCHours(0, 0, 0, 0);
12454 }, function(date, step) {
12455   date.setUTCMonth(date.getUTCMonth() + step);
12456 }, function(start, end) {
12457   return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;
12458 }, function(date) {
12459   return date.getUTCMonth();
12460 });
12461
12462 var utcMonths = utcMonth.range;
12463
12464 var utcYear = newInterval(function(date) {
12465   date.setUTCMonth(0, 1);
12466   date.setUTCHours(0, 0, 0, 0);
12467 }, function(date, step) {
12468   date.setUTCFullYear(date.getUTCFullYear() + step);
12469 }, function(start, end) {
12470   return end.getUTCFullYear() - start.getUTCFullYear();
12471 }, function(date) {
12472   return date.getUTCFullYear();
12473 });
12474
12475 // An optimized implementation for this simple case.
12476 utcYear.every = function(k) {
12477   return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
12478     date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);
12479     date.setUTCMonth(0, 1);
12480     date.setUTCHours(0, 0, 0, 0);
12481   }, function(date, step) {
12482     date.setUTCFullYear(date.getUTCFullYear() + step * k);
12483   });
12484 };
12485
12486 var utcYears = utcYear.range;
12487
12488 function localDate(d) {
12489   if (0 <= d.y && d.y < 100) {
12490     var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);
12491     date.setFullYear(d.y);
12492     return date;
12493   }
12494   return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);
12495 }
12496
12497 function utcDate(d) {
12498   if (0 <= d.y && d.y < 100) {
12499     var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));
12500     date.setUTCFullYear(d.y);
12501     return date;
12502   }
12503   return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));
12504 }
12505
12506 function newYear(y) {
12507   return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0};
12508 }
12509
12510 function formatLocale$1(locale) {
12511   var locale_dateTime = locale.dateTime,
12512       locale_date = locale.date,
12513       locale_time = locale.time,
12514       locale_periods = locale.periods,
12515       locale_weekdays = locale.days,
12516       locale_shortWeekdays = locale.shortDays,
12517       locale_months = locale.months,
12518       locale_shortMonths = locale.shortMonths;
12519
12520   var periodRe = formatRe(locale_periods),
12521       periodLookup = formatLookup(locale_periods),
12522       weekdayRe = formatRe(locale_weekdays),
12523       weekdayLookup = formatLookup(locale_weekdays),
12524       shortWeekdayRe = formatRe(locale_shortWeekdays),
12525       shortWeekdayLookup = formatLookup(locale_shortWeekdays),
12526       monthRe = formatRe(locale_months),
12527       monthLookup = formatLookup(locale_months),
12528       shortMonthRe = formatRe(locale_shortMonths),
12529       shortMonthLookup = formatLookup(locale_shortMonths);
12530
12531   var formats = {
12532     "a": formatShortWeekday,
12533     "A": formatWeekday,
12534     "b": formatShortMonth,
12535     "B": formatMonth,
12536     "c": null,
12537     "d": formatDayOfMonth,
12538     "e": formatDayOfMonth,
12539     "H": formatHour24,
12540     "I": formatHour12,
12541     "j": formatDayOfYear,
12542     "L": formatMilliseconds,
12543     "m": formatMonthNumber,
12544     "M": formatMinutes,
12545     "p": formatPeriod,
12546     "S": formatSeconds,
12547     "U": formatWeekNumberSunday,
12548     "w": formatWeekdayNumber,
12549     "W": formatWeekNumberMonday,
12550     "x": null,
12551     "X": null,
12552     "y": formatYear,
12553     "Y": formatFullYear,
12554     "Z": formatZone,
12555     "%": formatLiteralPercent
12556   };
12557
12558   var utcFormats = {
12559     "a": formatUTCShortWeekday,
12560     "A": formatUTCWeekday,
12561     "b": formatUTCShortMonth,
12562     "B": formatUTCMonth,
12563     "c": null,
12564     "d": formatUTCDayOfMonth,
12565     "e": formatUTCDayOfMonth,
12566     "H": formatUTCHour24,
12567     "I": formatUTCHour12,
12568     "j": formatUTCDayOfYear,
12569     "L": formatUTCMilliseconds,
12570     "m": formatUTCMonthNumber,
12571     "M": formatUTCMinutes,
12572     "p": formatUTCPeriod,
12573     "S": formatUTCSeconds,
12574     "U": formatUTCWeekNumberSunday,
12575     "w": formatUTCWeekdayNumber,
12576     "W": formatUTCWeekNumberMonday,
12577     "x": null,
12578     "X": null,
12579     "y": formatUTCYear,
12580     "Y": formatUTCFullYear,
12581     "Z": formatUTCZone,
12582     "%": formatLiteralPercent
12583   };
12584
12585   var parses = {
12586     "a": parseShortWeekday,
12587     "A": parseWeekday,
12588     "b": parseShortMonth,
12589     "B": parseMonth,
12590     "c": parseLocaleDateTime,
12591     "d": parseDayOfMonth,
12592     "e": parseDayOfMonth,
12593     "H": parseHour24,
12594     "I": parseHour24,
12595     "j": parseDayOfYear,
12596     "L": parseMilliseconds,
12597     "m": parseMonthNumber,
12598     "M": parseMinutes,
12599     "p": parsePeriod,
12600     "S": parseSeconds,
12601     "U": parseWeekNumberSunday,
12602     "w": parseWeekdayNumber,
12603     "W": parseWeekNumberMonday,
12604     "x": parseLocaleDate,
12605     "X": parseLocaleTime,
12606     "y": parseYear,
12607     "Y": parseFullYear,
12608     "Z": parseZone,
12609     "%": parseLiteralPercent
12610   };
12611
12612   // These recursive directive definitions must be deferred.
12613   formats.x = newFormat(locale_date, formats);
12614   formats.X = newFormat(locale_time, formats);
12615   formats.c = newFormat(locale_dateTime, formats);
12616   utcFormats.x = newFormat(locale_date, utcFormats);
12617   utcFormats.X = newFormat(locale_time, utcFormats);
12618   utcFormats.c = newFormat(locale_dateTime, utcFormats);
12619
12620   function newFormat(specifier, formats) {
12621     return function(date) {
12622       var string = [],
12623           i = -1,
12624           j = 0,
12625           n = specifier.length,
12626           c,
12627           pad,
12628           format;
12629
12630       if (!(date instanceof Date)) date = new Date(+date);
12631
12632       while (++i < n) {
12633         if (specifier.charCodeAt(i) === 37) {
12634           string.push(specifier.slice(j, i));
12635           if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);
12636           else pad = c === "e" ? " " : "0";
12637           if (format = formats[c]) c = format(date, pad);
12638           string.push(c);
12639           j = i + 1;
12640         }
12641       }
12642
12643       string.push(specifier.slice(j, i));
12644       return string.join("");
12645     };
12646   }
12647
12648   function newParse(specifier, newDate) {
12649     return function(string) {
12650       var d = newYear(1900),
12651           i = parseSpecifier(d, specifier, string += "", 0);
12652       if (i != string.length) return null;
12653
12654       // The am-pm flag is 0 for AM, and 1 for PM.
12655       if ("p" in d) d.H = d.H % 12 + d.p * 12;
12656
12657       // Convert day-of-week and week-of-year to day-of-year.
12658       if ("W" in d || "U" in d) {
12659         if (!("w" in d)) d.w = "W" in d ? 1 : 0;
12660         var day$$1 = "Z" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(newYear(d.y)).getDay();
12661         d.m = 0;
12662         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;
12663       }
12664
12665       // If a time zone is specified, all fields are interpreted as UTC and then
12666       // offset according to the specified time zone.
12667       if ("Z" in d) {
12668         d.H += d.Z / 100 | 0;
12669         d.M += d.Z % 100;
12670         return utcDate(d);
12671       }
12672
12673       // Otherwise, all fields are in local time.
12674       return newDate(d);
12675     };
12676   }
12677
12678   function parseSpecifier(d, specifier, string, j) {
12679     var i = 0,
12680         n = specifier.length,
12681         m = string.length,
12682         c,
12683         parse;
12684
12685     while (i < n) {
12686       if (j >= m) return -1;
12687       c = specifier.charCodeAt(i++);
12688       if (c === 37) {
12689         c = specifier.charAt(i++);
12690         parse = parses[c in pads ? specifier.charAt(i++) : c];
12691         if (!parse || ((j = parse(d, string, j)) < 0)) return -1;
12692       } else if (c != string.charCodeAt(j++)) {
12693         return -1;
12694       }
12695     }
12696
12697     return j;
12698   }
12699
12700   function parsePeriod(d, string, i) {
12701     var n = periodRe.exec(string.slice(i));
12702     return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1;
12703   }
12704
12705   function parseShortWeekday(d, string, i) {
12706     var n = shortWeekdayRe.exec(string.slice(i));
12707     return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
12708   }
12709
12710   function parseWeekday(d, string, i) {
12711     var n = weekdayRe.exec(string.slice(i));
12712     return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1;
12713   }
12714
12715   function parseShortMonth(d, string, i) {
12716     var n = shortMonthRe.exec(string.slice(i));
12717     return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
12718   }
12719
12720   function parseMonth(d, string, i) {
12721     var n = monthRe.exec(string.slice(i));
12722     return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1;
12723   }
12724
12725   function parseLocaleDateTime(d, string, i) {
12726     return parseSpecifier(d, locale_dateTime, string, i);
12727   }
12728
12729   function parseLocaleDate(d, string, i) {
12730     return parseSpecifier(d, locale_date, string, i);
12731   }
12732
12733   function parseLocaleTime(d, string, i) {
12734     return parseSpecifier(d, locale_time, string, i);
12735   }
12736
12737   function formatShortWeekday(d) {
12738     return locale_shortWeekdays[d.getDay()];
12739   }
12740
12741   function formatWeekday(d) {
12742     return locale_weekdays[d.getDay()];
12743   }
12744
12745   function formatShortMonth(d) {
12746     return locale_shortMonths[d.getMonth()];
12747   }
12748
12749   function formatMonth(d) {
12750     return locale_months[d.getMonth()];
12751   }
12752
12753   function formatPeriod(d) {
12754     return locale_periods[+(d.getHours() >= 12)];
12755   }
12756
12757   function formatUTCShortWeekday(d) {
12758     return locale_shortWeekdays[d.getUTCDay()];
12759   }
12760
12761   function formatUTCWeekday(d) {
12762     return locale_weekdays[d.getUTCDay()];
12763   }
12764
12765   function formatUTCShortMonth(d) {
12766     return locale_shortMonths[d.getUTCMonth()];
12767   }
12768
12769   function formatUTCMonth(d) {
12770     return locale_months[d.getUTCMonth()];
12771   }
12772
12773   function formatUTCPeriod(d) {
12774     return locale_periods[+(d.getUTCHours() >= 12)];
12775   }
12776
12777   return {
12778     format: function(specifier) {
12779       var f = newFormat(specifier += "", formats);
12780       f.toString = function() { return specifier; };
12781       return f;
12782     },
12783     parse: function(specifier) {
12784       var p = newParse(specifier += "", localDate);
12785       p.toString = function() { return specifier; };
12786       return p;
12787     },
12788     utcFormat: function(specifier) {
12789       var f = newFormat(specifier += "", utcFormats);
12790       f.toString = function() { return specifier; };
12791       return f;
12792     },
12793     utcParse: function(specifier) {
12794       var p = newParse(specifier, utcDate);
12795       p.toString = function() { return specifier; };
12796       return p;
12797     }
12798   };
12799 }
12800
12801 var pads = {"-": "", "_": " ", "0": "0"};
12802 var numberRe = /^\s*\d+/;
12803 var percentRe = /^%/;
12804 var requoteRe = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
12805
12806 function pad(value, fill, width) {
12807   var sign = value < 0 ? "-" : "",
12808       string = (sign ? -value : value) + "",
12809       length = string.length;
12810   return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);
12811 }
12812
12813 function requote(s) {
12814   return s.replace(requoteRe, "\\$&");
12815 }
12816
12817 function formatRe(names) {
12818   return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i");
12819 }
12820
12821 function formatLookup(names) {
12822   var map = {}, i = -1, n = names.length;
12823   while (++i < n) map[names[i].toLowerCase()] = i;
12824   return map;
12825 }
12826
12827 function parseWeekdayNumber(d, string, i) {
12828   var n = numberRe.exec(string.slice(i, i + 1));
12829   return n ? (d.w = +n[0], i + n[0].length) : -1;
12830 }
12831
12832 function parseWeekNumberSunday(d, string, i) {
12833   var n = numberRe.exec(string.slice(i));
12834   return n ? (d.U = +n[0], i + n[0].length) : -1;
12835 }
12836
12837 function parseWeekNumberMonday(d, string, i) {
12838   var n = numberRe.exec(string.slice(i));
12839   return n ? (d.W = +n[0], i + n[0].length) : -1;
12840 }
12841
12842 function parseFullYear(d, string, i) {
12843   var n = numberRe.exec(string.slice(i, i + 4));
12844   return n ? (d.y = +n[0], i + n[0].length) : -1;
12845 }
12846
12847 function parseYear(d, string, i) {
12848   var n = numberRe.exec(string.slice(i, i + 2));
12849   return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;
12850 }
12851
12852 function parseZone(d, string, i) {
12853   var n = /^(Z)|([+-]\d\d)(?:\:?(\d\d))?/.exec(string.slice(i, i + 6));
12854   return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1;
12855 }
12856
12857 function parseMonthNumber(d, string, i) {
12858   var n = numberRe.exec(string.slice(i, i + 2));
12859   return n ? (d.m = n[0] - 1, i + n[0].length) : -1;
12860 }
12861
12862 function parseDayOfMonth(d, string, i) {
12863   var n = numberRe.exec(string.slice(i, i + 2));
12864   return n ? (d.d = +n[0], i + n[0].length) : -1;
12865 }
12866
12867 function parseDayOfYear(d, string, i) {
12868   var n = numberRe.exec(string.slice(i, i + 3));
12869   return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;
12870 }
12871
12872 function parseHour24(d, string, i) {
12873   var n = numberRe.exec(string.slice(i, i + 2));
12874   return n ? (d.H = +n[0], i + n[0].length) : -1;
12875 }
12876
12877 function parseMinutes(d, string, i) {
12878   var n = numberRe.exec(string.slice(i, i + 2));
12879   return n ? (d.M = +n[0], i + n[0].length) : -1;
12880 }
12881
12882 function parseSeconds(d, string, i) {
12883   var n = numberRe.exec(string.slice(i, i + 2));
12884   return n ? (d.S = +n[0], i + n[0].length) : -1;
12885 }
12886
12887 function parseMilliseconds(d, string, i) {
12888   var n = numberRe.exec(string.slice(i, i + 3));
12889   return n ? (d.L = +n[0], i + n[0].length) : -1;
12890 }
12891
12892 function parseLiteralPercent(d, string, i) {
12893   var n = percentRe.exec(string.slice(i, i + 1));
12894   return n ? i + n[0].length : -1;
12895 }
12896
12897 function formatDayOfMonth(d, p) {
12898   return pad(d.getDate(), p, 2);
12899 }
12900
12901 function formatHour24(d, p) {
12902   return pad(d.getHours(), p, 2);
12903 }
12904
12905 function formatHour12(d, p) {
12906   return pad(d.getHours() % 12 || 12, p, 2);
12907 }
12908
12909 function formatDayOfYear(d, p) {
12910   return pad(1 + day.count(year(d), d), p, 3);
12911 }
12912
12913 function formatMilliseconds(d, p) {
12914   return pad(d.getMilliseconds(), p, 3);
12915 }
12916
12917 function formatMonthNumber(d, p) {
12918   return pad(d.getMonth() + 1, p, 2);
12919 }
12920
12921 function formatMinutes(d, p) {
12922   return pad(d.getMinutes(), p, 2);
12923 }
12924
12925 function formatSeconds(d, p) {
12926   return pad(d.getSeconds(), p, 2);
12927 }
12928
12929 function formatWeekNumberSunday(d, p) {
12930   return pad(sunday.count(year(d), d), p, 2);
12931 }
12932
12933 function formatWeekdayNumber(d) {
12934   return d.getDay();
12935 }
12936
12937 function formatWeekNumberMonday(d, p) {
12938   return pad(monday.count(year(d), d), p, 2);
12939 }
12940
12941 function formatYear(d, p) {
12942   return pad(d.getFullYear() % 100, p, 2);
12943 }
12944
12945 function formatFullYear(d, p) {
12946   return pad(d.getFullYear() % 10000, p, 4);
12947 }
12948
12949 function formatZone(d) {
12950   var z = d.getTimezoneOffset();
12951   return (z > 0 ? "-" : (z *= -1, "+"))
12952       + pad(z / 60 | 0, "0", 2)
12953       + pad(z % 60, "0", 2);
12954 }
12955
12956 function formatUTCDayOfMonth(d, p) {
12957   return pad(d.getUTCDate(), p, 2);
12958 }
12959
12960 function formatUTCHour24(d, p) {
12961   return pad(d.getUTCHours(), p, 2);
12962 }
12963
12964 function formatUTCHour12(d, p) {
12965   return pad(d.getUTCHours() % 12 || 12, p, 2);
12966 }
12967
12968 function formatUTCDayOfYear(d, p) {
12969   return pad(1 + utcDay.count(utcYear(d), d), p, 3);
12970 }
12971
12972 function formatUTCMilliseconds(d, p) {
12973   return pad(d.getUTCMilliseconds(), p, 3);
12974 }
12975
12976 function formatUTCMonthNumber(d, p) {
12977   return pad(d.getUTCMonth() + 1, p, 2);
12978 }
12979
12980 function formatUTCMinutes(d, p) {
12981   return pad(d.getUTCMinutes(), p, 2);
12982 }
12983
12984 function formatUTCSeconds(d, p) {
12985   return pad(d.getUTCSeconds(), p, 2);
12986 }
12987
12988 function formatUTCWeekNumberSunday(d, p) {
12989   return pad(utcSunday.count(utcYear(d), d), p, 2);
12990 }
12991
12992 function formatUTCWeekdayNumber(d) {
12993   return d.getUTCDay();
12994 }
12995
12996 function formatUTCWeekNumberMonday(d, p) {
12997   return pad(utcMonday.count(utcYear(d), d), p, 2);
12998 }
12999
13000 function formatUTCYear(d, p) {
13001   return pad(d.getUTCFullYear() % 100, p, 2);
13002 }
13003
13004 function formatUTCFullYear(d, p) {
13005   return pad(d.getUTCFullYear() % 10000, p, 4);
13006 }
13007
13008 function formatUTCZone() {
13009   return "+0000";
13010 }
13011
13012 function formatLiteralPercent() {
13013   return "%";
13014 }
13015
13016 var locale$1;
13017 var timeFormat;
13018 var timeParse;
13019 var utcFormat;
13020 var utcParse;
13021
13022 defaultLocale$1({
13023   dateTime: "%x, %X",
13024   date: "%-m/%-d/%Y",
13025   time: "%-I:%M:%S %p",
13026   periods: ["AM", "PM"],
13027   days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
13028   shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
13029   months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
13030   shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
13031 });
13032
13033 function defaultLocale$1(definition) {
13034   locale$1 = formatLocale$1(definition);
13035   timeFormat = locale$1.format;
13036   timeParse = locale$1.parse;
13037   utcFormat = locale$1.utcFormat;
13038   utcParse = locale$1.utcParse;
13039   return locale$1;
13040 }
13041
13042 var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ";
13043
13044 function formatIsoNative(date) {
13045   return date.toISOString();
13046 }
13047
13048 var formatIso = Date.prototype.toISOString
13049     ? formatIsoNative
13050     : utcFormat(isoSpecifier);
13051
13052 function parseIsoNative(string) {
13053   var date = new Date(string);
13054   return isNaN(date) ? null : date;
13055 }
13056
13057 var parseIso = +new Date("2000-01-01T00:00:00.000Z")
13058     ? parseIsoNative
13059     : utcParse(isoSpecifier);
13060
13061 var durationSecond = 1000;
13062 var durationMinute = durationSecond * 60;
13063 var durationHour = durationMinute * 60;
13064 var durationDay = durationHour * 24;
13065 var durationWeek = durationDay * 7;
13066 var durationMonth = durationDay * 30;
13067 var durationYear = durationDay * 365;
13068
13069 function date$1(t) {
13070   return new Date(t);
13071 }
13072
13073 function number$3(t) {
13074   return t instanceof Date ? +t : +new Date(+t);
13075 }
13076
13077 function calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format) {
13078   var scale = continuous(deinterpolateLinear, d3_interpolateNumber),
13079       invert = scale.invert,
13080       domain = scale.domain;
13081
13082   var formatMillisecond = format(".%L"),
13083       formatSecond = format(":%S"),
13084       formatMinute = format("%I:%M"),
13085       formatHour = format("%I %p"),
13086       formatDay = format("%a %d"),
13087       formatWeek = format("%b %d"),
13088       formatMonth = format("%B"),
13089       formatYear = format("%Y");
13090
13091   var tickIntervals = [
13092     [second$$1,  1,      durationSecond],
13093     [second$$1,  5,  5 * durationSecond],
13094     [second$$1, 15, 15 * durationSecond],
13095     [second$$1, 30, 30 * durationSecond],
13096     [minute$$1,  1,      durationMinute],
13097     [minute$$1,  5,  5 * durationMinute],
13098     [minute$$1, 15, 15 * durationMinute],
13099     [minute$$1, 30, 30 * durationMinute],
13100     [  hour$$1,  1,      durationHour  ],
13101     [  hour$$1,  3,  3 * durationHour  ],
13102     [  hour$$1,  6,  6 * durationHour  ],
13103     [  hour$$1, 12, 12 * durationHour  ],
13104     [   day$$1,  1,      durationDay   ],
13105     [   day$$1,  2,  2 * durationDay   ],
13106     [  week,  1,      durationWeek  ],
13107     [ month$$1,  1,      durationMonth ],
13108     [ month$$1,  3,  3 * durationMonth ],
13109     [  year$$1,  1,      durationYear  ]
13110   ];
13111
13112   function tickFormat(date) {
13113     return (second$$1(date) < date ? formatMillisecond
13114         : minute$$1(date) < date ? formatSecond
13115         : hour$$1(date) < date ? formatMinute
13116         : day$$1(date) < date ? formatHour
13117         : month$$1(date) < date ? (week(date) < date ? formatDay : formatWeek)
13118         : year$$1(date) < date ? formatMonth
13119         : formatYear)(date);
13120   }
13121
13122   function tickInterval(interval, start, stop, step) {
13123     if (interval == null) interval = 10;
13124
13125     // If a desired tick count is specified, pick a reasonable tick interval
13126     // based on the extent of the domain and a rough estimate of tick size.
13127     // Otherwise, assume interval is already a time interval and use it.
13128     if (typeof interval === "number") {
13129       var target = Math.abs(stop - start) / interval,
13130           i = d3_bisector(function(i) { return i[2]; }).right(tickIntervals, target);
13131       if (i === tickIntervals.length) {
13132         step = tickStep(start / durationYear, stop / durationYear, interval);
13133         interval = year$$1;
13134       } else if (i) {
13135         i = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];
13136         step = i[1];
13137         interval = i[0];
13138       } else {
13139         step = tickStep(start, stop, interval);
13140         interval = millisecond$$1;
13141       }
13142     }
13143
13144     return step == null ? interval : interval.every(step);
13145   }
13146
13147   scale.invert = function(y) {
13148     return new Date(invert(y));
13149   };
13150
13151   scale.domain = function(_) {
13152     return arguments.length ? domain(map$3.call(_, number$3)) : domain().map(date$1);
13153   };
13154
13155   scale.ticks = function(interval, step) {
13156     var d = domain(),
13157         t0 = d[0],
13158         t1 = d[d.length - 1],
13159         r = t1 < t0,
13160         t;
13161     if (r) t = t0, t0 = t1, t1 = t;
13162     t = tickInterval(interval, t0, t1, step);
13163     t = t ? t.range(t0, t1 + 1) : []; // inclusive stop
13164     return r ? t.reverse() : t;
13165   };
13166
13167   scale.tickFormat = function(count, specifier) {
13168     return specifier == null ? tickFormat : format(specifier);
13169   };
13170
13171   scale.nice = function(interval, step) {
13172     var d = domain();
13173     return (interval = tickInterval(interval, d[0], d[d.length - 1], step))
13174         ? domain(nice(d, interval))
13175         : scale;
13176   };
13177
13178   scale.copy = function() {
13179     return copy(scale, calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format));
13180   };
13181
13182   return scale;
13183 }
13184
13185 var time = function() {
13186   return calendar(year, month, sunday, day, hour, minute, second, millisecond, timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]);
13187 };
13188
13189 var utcTime = function() {
13190   return calendar(utcYear, utcMonth, utcSunday, utcDay, utcHour, utcMinute, second, millisecond, utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]);
13191 };
13192
13193 var colors = function(s) {
13194   return s.match(/.{6}/g).map(function(x) {
13195     return "#" + x;
13196   });
13197 };
13198
13199 var category10 = colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf");
13200
13201 var category20b = colors("393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6");
13202
13203 var category20c = colors("3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9");
13204
13205 var category20 = colors("1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5");
13206
13207 var cubehelix$3 = cubehelixLong(cubehelix(300, 0.5, 0.0), cubehelix(-240, 0.5, 1.0));
13208
13209 var warm = cubehelixLong(cubehelix(-100, 0.75, 0.35), cubehelix(80, 1.50, 0.8));
13210
13211 var cool = cubehelixLong(cubehelix(260, 0.75, 0.35), cubehelix(80, 1.50, 0.8));
13212
13213 var rainbow = cubehelix();
13214
13215 var rainbow$1 = function(t) {
13216   if (t < 0 || t > 1) t -= Math.floor(t);
13217   var ts = Math.abs(t - 0.5);
13218   rainbow.h = 360 * t - 100;
13219   rainbow.s = 1.5 - 1.5 * ts;
13220   rainbow.l = 0.8 - 0.9 * ts;
13221   return rainbow + "";
13222 };
13223
13224 function ramp(range) {
13225   var n = range.length;
13226   return function(t) {
13227     return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];
13228   };
13229 }
13230
13231 var viridis = ramp(colors("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));
13232
13233 var magma = ramp(colors("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf"));
13234
13235 var inferno = ramp(colors("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4"));
13236
13237 var plasma = ramp(colors("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921"));
13238
13239 function sequential(interpolator) {
13240   var x0 = 0,
13241       x1 = 1,
13242       clamp = false;
13243
13244   function scale(x) {
13245     var t = (x - x0) / (x1 - x0);
13246     return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t);
13247   }
13248
13249   scale.domain = function(_) {
13250     return arguments.length ? (x0 = +_[0], x1 = +_[1], scale) : [x0, x1];
13251   };
13252
13253   scale.clamp = function(_) {
13254     return arguments.length ? (clamp = !!_, scale) : clamp;
13255   };
13256
13257   scale.interpolator = function(_) {
13258     return arguments.length ? (interpolator = _, scale) : interpolator;
13259   };
13260
13261   scale.copy = function() {
13262     return sequential(interpolator).domain([x0, x1]).clamp(clamp);
13263   };
13264
13265   return linearish(scale);
13266 }
13267
13268 var constant$10 = function(x) {
13269   return function constant() {
13270     return x;
13271   };
13272 };
13273
13274 var abs$1 = Math.abs;
13275 var atan2$1 = Math.atan2;
13276 var cos$2 = Math.cos;
13277 var max$2 = Math.max;
13278 var min$1 = Math.min;
13279 var sin$2 = Math.sin;
13280 var sqrt$2 = Math.sqrt;
13281
13282 var epsilon$3 = 1e-12;
13283 var pi$4 = Math.PI;
13284 var halfPi$3 = pi$4 / 2;
13285 var tau$4 = 2 * pi$4;
13286
13287 function acos$1(x) {
13288   return x > 1 ? 0 : x < -1 ? pi$4 : Math.acos(x);
13289 }
13290
13291 function asin$1(x) {
13292   return x >= 1 ? halfPi$3 : x <= -1 ? -halfPi$3 : Math.asin(x);
13293 }
13294
13295 function arcInnerRadius(d) {
13296   return d.innerRadius;
13297 }
13298
13299 function arcOuterRadius(d) {
13300   return d.outerRadius;
13301 }
13302
13303 function arcStartAngle(d) {
13304   return d.startAngle;
13305 }
13306
13307 function arcEndAngle(d) {
13308   return d.endAngle;
13309 }
13310
13311 function arcPadAngle(d) {
13312   return d && d.padAngle; // Note: optional!
13313 }
13314
13315 function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
13316   var x10 = x1 - x0, y10 = y1 - y0,
13317       x32 = x3 - x2, y32 = y3 - y2,
13318       t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10);
13319   return [x0 + t * x10, y0 + t * y10];
13320 }
13321
13322 // Compute perpendicular offset line of length rc.
13323 // http://mathworld.wolfram.com/Circle-LineIntersection.html
13324 function cornerTangents(x0, y0, x1, y1, r1, rc, cw) {
13325   var x01 = x0 - x1,
13326       y01 = y0 - y1,
13327       lo = (cw ? rc : -rc) / sqrt$2(x01 * x01 + y01 * y01),
13328       ox = lo * y01,
13329       oy = -lo * x01,
13330       x11 = x0 + ox,
13331       y11 = y0 + oy,
13332       x10 = x1 + ox,
13333       y10 = y1 + oy,
13334       x00 = (x11 + x10) / 2,
13335       y00 = (y11 + y10) / 2,
13336       dx = x10 - x11,
13337       dy = y10 - y11,
13338       d2 = dx * dx + dy * dy,
13339       r = r1 - rc,
13340       D = x11 * y10 - x10 * y11,
13341       d = (dy < 0 ? -1 : 1) * sqrt$2(max$2(0, r * r * d2 - D * D)),
13342       cx0 = (D * dy - dx * d) / d2,
13343       cy0 = (-D * dx - dy * d) / d2,
13344       cx1 = (D * dy + dx * d) / d2,
13345       cy1 = (-D * dx + dy * d) / d2,
13346       dx0 = cx0 - x00,
13347       dy0 = cy0 - y00,
13348       dx1 = cx1 - x00,
13349       dy1 = cy1 - y00;
13350
13351   // Pick the closer of the two intersection points.
13352   // TODO Is there a faster way to determine which intersection to use?
13353   if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
13354
13355   return {
13356     cx: cx0,
13357     cy: cy0,
13358     x01: -ox,
13359     y01: -oy,
13360     x11: cx0 * (r1 / r - 1),
13361     y11: cy0 * (r1 / r - 1)
13362   };
13363 }
13364
13365 var arc = function() {
13366   var innerRadius = arcInnerRadius,
13367       outerRadius = arcOuterRadius,
13368       cornerRadius = constant$10(0),
13369       padRadius = null,
13370       startAngle = arcStartAngle,
13371       endAngle = arcEndAngle,
13372       padAngle = arcPadAngle,
13373       context = null;
13374
13375   function arc() {
13376     var buffer,
13377         r,
13378         r0 = +innerRadius.apply(this, arguments),
13379         r1 = +outerRadius.apply(this, arguments),
13380         a0 = startAngle.apply(this, arguments) - halfPi$3,
13381         a1 = endAngle.apply(this, arguments) - halfPi$3,
13382         da = abs$1(a1 - a0),
13383         cw = a1 > a0;
13384
13385     if (!context) context = buffer = path();
13386
13387     // Ensure that the outer radius is always larger than the inner radius.
13388     if (r1 < r0) r = r1, r1 = r0, r0 = r;
13389
13390     // Is it a point?
13391     if (!(r1 > epsilon$3)) context.moveTo(0, 0);
13392
13393     // Or is it a circle or annulus?
13394     else if (da > tau$4 - epsilon$3) {
13395       context.moveTo(r1 * cos$2(a0), r1 * sin$2(a0));
13396       context.arc(0, 0, r1, a0, a1, !cw);
13397       if (r0 > epsilon$3) {
13398         context.moveTo(r0 * cos$2(a1), r0 * sin$2(a1));
13399         context.arc(0, 0, r0, a1, a0, cw);
13400       }
13401     }
13402
13403     // Or is it a circular or annular sector?
13404     else {
13405       var a01 = a0,
13406           a11 = a1,
13407           a00 = a0,
13408           a10 = a1,
13409           da0 = da,
13410           da1 = da,
13411           ap = padAngle.apply(this, arguments) / 2,
13412           rp = (ap > epsilon$3) && (padRadius ? +padRadius.apply(this, arguments) : sqrt$2(r0 * r0 + r1 * r1)),
13413           rc = min$1(abs$1(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),
13414           rc0 = rc,
13415           rc1 = rc,
13416           t0,
13417           t1;
13418
13419       // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.
13420       if (rp > epsilon$3) {
13421         var p0 = asin$1(rp / r0 * sin$2(ap)),
13422             p1 = asin$1(rp / r1 * sin$2(ap));
13423         if ((da0 -= p0 * 2) > epsilon$3) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;
13424         else da0 = 0, a00 = a10 = (a0 + a1) / 2;
13425         if ((da1 -= p1 * 2) > epsilon$3) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;
13426         else da1 = 0, a01 = a11 = (a0 + a1) / 2;
13427       }
13428
13429       var x01 = r1 * cos$2(a01),
13430           y01 = r1 * sin$2(a01),
13431           x10 = r0 * cos$2(a10),
13432           y10 = r0 * sin$2(a10);
13433
13434       // Apply rounded corners?
13435       if (rc > epsilon$3) {
13436         var x11 = r1 * cos$2(a11),
13437             y11 = r1 * sin$2(a11),
13438             x00 = r0 * cos$2(a00),
13439             y00 = r0 * sin$2(a00);
13440
13441         // Restrict the corner radius according to the sector angle.
13442         if (da < pi$4) {
13443           var oc = da0 > epsilon$3 ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10],
13444               ax = x01 - oc[0],
13445               ay = y01 - oc[1],
13446               bx = x11 - oc[0],
13447               by = y11 - oc[1],
13448               kc = 1 / sin$2(acos$1((ax * bx + ay * by) / (sqrt$2(ax * ax + ay * ay) * sqrt$2(bx * bx + by * by))) / 2),
13449               lc = sqrt$2(oc[0] * oc[0] + oc[1] * oc[1]);
13450           rc0 = min$1(rc, (r0 - lc) / (kc - 1));
13451           rc1 = min$1(rc, (r1 - lc) / (kc + 1));
13452         }
13453       }
13454
13455       // Is the sector collapsed to a line?
13456       if (!(da1 > epsilon$3)) context.moveTo(x01, y01);
13457
13458       // Does the sector’s outer ring have rounded corners?
13459       else if (rc1 > epsilon$3) {
13460         t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);
13461         t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);
13462
13463         context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);
13464
13465         // Have the corners merged?
13466         if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw);
13467
13468         // Otherwise, draw the two corners and the ring.
13469         else {
13470           context.arc(t0.cx, t0.cy, rc1, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw);
13471           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);
13472           context.arc(t1.cx, t1.cy, rc1, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw);
13473         }
13474       }
13475
13476       // Or is the outer ring just a circular arc?
13477       else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);
13478
13479       // Is there no inner ring, and it’s a circular sector?
13480       // Or perhaps it’s an annular sector collapsed due to padding?
13481       if (!(r0 > epsilon$3) || !(da0 > epsilon$3)) context.lineTo(x10, y10);
13482
13483       // Does the sector’s inner ring (or point) have rounded corners?
13484       else if (rc0 > epsilon$3) {
13485         t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);
13486         t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);
13487
13488         context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);
13489
13490         // Have the corners merged?
13491         if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t1.y01, t1.x01), !cw);
13492
13493         // Otherwise, draw the two corners and the ring.
13494         else {
13495           context.arc(t0.cx, t0.cy, rc0, atan2$1(t0.y01, t0.x01), atan2$1(t0.y11, t0.x11), !cw);
13496           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);
13497           context.arc(t1.cx, t1.cy, rc0, atan2$1(t1.y11, t1.x11), atan2$1(t1.y01, t1.x01), !cw);
13498         }
13499       }
13500
13501       // Or is the inner ring just a circular arc?
13502       else context.arc(0, 0, r0, a10, a00, cw);
13503     }
13504
13505     context.closePath();
13506
13507     if (buffer) return context = null, buffer + "" || null;
13508   }
13509
13510   arc.centroid = function() {
13511     var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,
13512         a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi$4 / 2;
13513     return [cos$2(a) * r, sin$2(a) * r];
13514   };
13515
13516   arc.innerRadius = function(_) {
13517     return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant$10(+_), arc) : innerRadius;
13518   };
13519
13520   arc.outerRadius = function(_) {
13521     return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant$10(+_), arc) : outerRadius;
13522   };
13523
13524   arc.cornerRadius = function(_) {
13525     return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant$10(+_), arc) : cornerRadius;
13526   };
13527
13528   arc.padRadius = function(_) {
13529     return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant$10(+_), arc) : padRadius;
13530   };
13531
13532   arc.startAngle = function(_) {
13533     return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$10(+_), arc) : startAngle;
13534   };
13535
13536   arc.endAngle = function(_) {
13537     return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$10(+_), arc) : endAngle;
13538   };
13539
13540   arc.padAngle = function(_) {
13541     return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$10(+_), arc) : padAngle;
13542   };
13543
13544   arc.context = function(_) {
13545     return arguments.length ? (context = _ == null ? null : _, arc) : context;
13546   };
13547
13548   return arc;
13549 };
13550
13551 function Linear(context) {
13552   this._context = context;
13553 }
13554
13555 Linear.prototype = {
13556   areaStart: function() {
13557     this._line = 0;
13558   },
13559   areaEnd: function() {
13560     this._line = NaN;
13561   },
13562   lineStart: function() {
13563     this._point = 0;
13564   },
13565   lineEnd: function() {
13566     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
13567     this._line = 1 - this._line;
13568   },
13569   point: function(x, y) {
13570     x = +x, y = +y;
13571     switch (this._point) {
13572       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
13573       case 1: this._point = 2; // proceed
13574       default: this._context.lineTo(x, y); break;
13575     }
13576   }
13577 };
13578
13579 var curveLinear = function(context) {
13580   return new Linear(context);
13581 };
13582
13583 function x$3(p) {
13584   return p[0];
13585 }
13586
13587 function y$3(p) {
13588   return p[1];
13589 }
13590
13591 var line = function() {
13592   var x$$1 = x$3,
13593       y$$1 = y$3,
13594       defined = constant$10(true),
13595       context = null,
13596       curve = curveLinear,
13597       output = null;
13598
13599   function line(data) {
13600     var i,
13601         n = data.length,
13602         d,
13603         defined0 = false,
13604         buffer;
13605
13606     if (context == null) output = curve(buffer = path());
13607
13608     for (i = 0; i <= n; ++i) {
13609       if (!(i < n && defined(d = data[i], i, data)) === defined0) {
13610         if (defined0 = !defined0) output.lineStart();
13611         else output.lineEnd();
13612       }
13613       if (defined0) output.point(+x$$1(d, i, data), +y$$1(d, i, data));
13614     }
13615
13616     if (buffer) return output = null, buffer + "" || null;
13617   }
13618
13619   line.x = function(_) {
13620     return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$10(+_), line) : x$$1;
13621   };
13622
13623   line.y = function(_) {
13624     return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$10(+_), line) : y$$1;
13625   };
13626
13627   line.defined = function(_) {
13628     return arguments.length ? (defined = typeof _ === "function" ? _ : constant$10(!!_), line) : defined;
13629   };
13630
13631   line.curve = function(_) {
13632     return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;
13633   };
13634
13635   line.context = function(_) {
13636     return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;
13637   };
13638
13639   return line;
13640 };
13641
13642 var area = function() {
13643   var x0 = x$3,
13644       x1 = null,
13645       y0 = constant$10(0),
13646       y1 = y$3,
13647       defined = constant$10(true),
13648       context = null,
13649       curve = curveLinear,
13650       output = null;
13651
13652   function area(data) {
13653     var i,
13654         j,
13655         k,
13656         n = data.length,
13657         d,
13658         defined0 = false,
13659         buffer,
13660         x0z = new Array(n),
13661         y0z = new Array(n);
13662
13663     if (context == null) output = curve(buffer = path());
13664
13665     for (i = 0; i <= n; ++i) {
13666       if (!(i < n && defined(d = data[i], i, data)) === defined0) {
13667         if (defined0 = !defined0) {
13668           j = i;
13669           output.areaStart();
13670           output.lineStart();
13671         } else {
13672           output.lineEnd();
13673           output.lineStart();
13674           for (k = i - 1; k >= j; --k) {
13675             output.point(x0z[k], y0z[k]);
13676           }
13677           output.lineEnd();
13678           output.areaEnd();
13679         }
13680       }
13681       if (defined0) {
13682         x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);
13683         output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);
13684       }
13685     }
13686
13687     if (buffer) return output = null, buffer + "" || null;
13688   }
13689
13690   function arealine() {
13691     return line().defined(defined).curve(curve).context(context);
13692   }
13693
13694   area.x = function(_) {
13695     return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$10(+_), x1 = null, area) : x0;
13696   };
13697
13698   area.x0 = function(_) {
13699     return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$10(+_), area) : x0;
13700   };
13701
13702   area.x1 = function(_) {
13703     return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant$10(+_), area) : x1;
13704   };
13705
13706   area.y = function(_) {
13707     return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$10(+_), y1 = null, area) : y0;
13708   };
13709
13710   area.y0 = function(_) {
13711     return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$10(+_), area) : y0;
13712   };
13713
13714   area.y1 = function(_) {
13715     return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant$10(+_), area) : y1;
13716   };
13717
13718   area.lineX0 =
13719   area.lineY0 = function() {
13720     return arealine().x(x0).y(y0);
13721   };
13722
13723   area.lineY1 = function() {
13724     return arealine().x(x0).y(y1);
13725   };
13726
13727   area.lineX1 = function() {
13728     return arealine().x(x1).y(y0);
13729   };
13730
13731   area.defined = function(_) {
13732     return arguments.length ? (defined = typeof _ === "function" ? _ : constant$10(!!_), area) : defined;
13733   };
13734
13735   area.curve = function(_) {
13736     return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;
13737   };
13738
13739   area.context = function(_) {
13740     return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;
13741   };
13742
13743   return area;
13744 };
13745
13746 var descending = function(a, b) {
13747   return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
13748 };
13749
13750 var identity$6 = function(d) {
13751   return d;
13752 };
13753
13754 var pie = function() {
13755   var value = identity$6,
13756       sortValues = descending,
13757       sort = null,
13758       startAngle = constant$10(0),
13759       endAngle = constant$10(tau$4),
13760       padAngle = constant$10(0);
13761
13762   function pie(data) {
13763     var i,
13764         n = data.length,
13765         j,
13766         k,
13767         sum = 0,
13768         index = new Array(n),
13769         arcs = new Array(n),
13770         a0 = +startAngle.apply(this, arguments),
13771         da = Math.min(tau$4, Math.max(-tau$4, endAngle.apply(this, arguments) - a0)),
13772         a1,
13773         p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),
13774         pa = p * (da < 0 ? -1 : 1),
13775         v;
13776
13777     for (i = 0; i < n; ++i) {
13778       if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) {
13779         sum += v;
13780       }
13781     }
13782
13783     // Optionally sort the arcs by previously-computed values or by data.
13784     if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); });
13785     else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); });
13786
13787     // Compute the arcs! They are stored in the original data's order.
13788     for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) {
13789       j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = {
13790         data: data[j],
13791         index: i,
13792         value: v,
13793         startAngle: a0,
13794         endAngle: a1,
13795         padAngle: p
13796       };
13797     }
13798
13799     return arcs;
13800   }
13801
13802   pie.value = function(_) {
13803     return arguments.length ? (value = typeof _ === "function" ? _ : constant$10(+_), pie) : value;
13804   };
13805
13806   pie.sortValues = function(_) {
13807     return arguments.length ? (sortValues = _, sort = null, pie) : sortValues;
13808   };
13809
13810   pie.sort = function(_) {
13811     return arguments.length ? (sort = _, sortValues = null, pie) : sort;
13812   };
13813
13814   pie.startAngle = function(_) {
13815     return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$10(+_), pie) : startAngle;
13816   };
13817
13818   pie.endAngle = function(_) {
13819     return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$10(+_), pie) : endAngle;
13820   };
13821
13822   pie.padAngle = function(_) {
13823     return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$10(+_), pie) : padAngle;
13824   };
13825
13826   return pie;
13827 };
13828
13829 var curveRadialLinear = curveRadial(curveLinear);
13830
13831 function Radial(curve) {
13832   this._curve = curve;
13833 }
13834
13835 Radial.prototype = {
13836   areaStart: function() {
13837     this._curve.areaStart();
13838   },
13839   areaEnd: function() {
13840     this._curve.areaEnd();
13841   },
13842   lineStart: function() {
13843     this._curve.lineStart();
13844   },
13845   lineEnd: function() {
13846     this._curve.lineEnd();
13847   },
13848   point: function(a, r) {
13849     this._curve.point(r * Math.sin(a), r * -Math.cos(a));
13850   }
13851 };
13852
13853 function curveRadial(curve) {
13854
13855   function radial(context) {
13856     return new Radial(curve(context));
13857   }
13858
13859   radial._curve = curve;
13860
13861   return radial;
13862 }
13863
13864 function lineRadial(l) {
13865   var c = l.curve;
13866
13867   l.angle = l.x, delete l.x;
13868   l.radius = l.y, delete l.y;
13869
13870   l.curve = function(_) {
13871     return arguments.length ? c(curveRadial(_)) : c()._curve;
13872   };
13873
13874   return l;
13875 }
13876
13877 var lineRadial$1 = function() {
13878   return lineRadial(line().curve(curveRadialLinear));
13879 };
13880
13881 var areaRadial = function() {
13882   var a = area().curve(curveRadialLinear),
13883       c = a.curve,
13884       x0 = a.lineX0,
13885       x1 = a.lineX1,
13886       y0 = a.lineY0,
13887       y1 = a.lineY1;
13888
13889   a.angle = a.x, delete a.x;
13890   a.startAngle = a.x0, delete a.x0;
13891   a.endAngle = a.x1, delete a.x1;
13892   a.radius = a.y, delete a.y;
13893   a.innerRadius = a.y0, delete a.y0;
13894   a.outerRadius = a.y1, delete a.y1;
13895   a.lineStartAngle = function() { return lineRadial(x0()); }, delete a.lineX0;
13896   a.lineEndAngle = function() { return lineRadial(x1()); }, delete a.lineX1;
13897   a.lineInnerRadius = function() { return lineRadial(y0()); }, delete a.lineY0;
13898   a.lineOuterRadius = function() { return lineRadial(y1()); }, delete a.lineY1;
13899
13900   a.curve = function(_) {
13901     return arguments.length ? c(curveRadial(_)) : c()._curve;
13902   };
13903
13904   return a;
13905 };
13906
13907 var pointRadial = function(x, y) {
13908   return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)];
13909 };
13910
13911 var slice$6 = Array.prototype.slice;
13912
13913 function linkSource(d) {
13914   return d.source;
13915 }
13916
13917 function linkTarget(d) {
13918   return d.target;
13919 }
13920
13921 function link$2(curve) {
13922   var source = linkSource,
13923       target = linkTarget,
13924       x$$1 = x$3,
13925       y$$1 = y$3,
13926       context = null;
13927
13928   function link() {
13929     var buffer, argv = slice$6.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv);
13930     if (!context) context = buffer = path();
13931     curve(context, +x$$1.apply(this, (argv[0] = s, argv)), +y$$1.apply(this, argv), +x$$1.apply(this, (argv[0] = t, argv)), +y$$1.apply(this, argv));
13932     if (buffer) return context = null, buffer + "" || null;
13933   }
13934
13935   link.source = function(_) {
13936     return arguments.length ? (source = _, link) : source;
13937   };
13938
13939   link.target = function(_) {
13940     return arguments.length ? (target = _, link) : target;
13941   };
13942
13943   link.x = function(_) {
13944     return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$10(+_), link) : x$$1;
13945   };
13946
13947   link.y = function(_) {
13948     return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$10(+_), link) : y$$1;
13949   };
13950
13951   link.context = function(_) {
13952     return arguments.length ? (context = _ == null ? null : _, link) : context;
13953   };
13954
13955   return link;
13956 }
13957
13958 function curveHorizontal(context, x0, y0, x1, y1) {
13959   context.moveTo(x0, y0);
13960   context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1);
13961 }
13962
13963 function curveVertical(context, x0, y0, x1, y1) {
13964   context.moveTo(x0, y0);
13965   context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1);
13966 }
13967
13968 function curveRadial$1(context, x0, y0, x1, y1) {
13969   var p0 = pointRadial(x0, y0),
13970       p1 = pointRadial(x0, y0 = (y0 + y1) / 2),
13971       p2 = pointRadial(x1, y0),
13972       p3 = pointRadial(x1, y1);
13973   context.moveTo(p0[0], p0[1]);
13974   context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]);
13975 }
13976
13977 function linkHorizontal() {
13978   return link$2(curveHorizontal);
13979 }
13980
13981 function linkVertical() {
13982   return link$2(curveVertical);
13983 }
13984
13985 function linkRadial() {
13986   var l = link$2(curveRadial$1);
13987   l.angle = l.x, delete l.x;
13988   l.radius = l.y, delete l.y;
13989   return l;
13990 }
13991
13992 var circle$2 = {
13993   draw: function(context, size) {
13994     var r = Math.sqrt(size / pi$4);
13995     context.moveTo(r, 0);
13996     context.arc(0, 0, r, 0, tau$4);
13997   }
13998 };
13999
14000 var cross$2 = {
14001   draw: function(context, size) {
14002     var r = Math.sqrt(size / 5) / 2;
14003     context.moveTo(-3 * r, -r);
14004     context.lineTo(-r, -r);
14005     context.lineTo(-r, -3 * r);
14006     context.lineTo(r, -3 * r);
14007     context.lineTo(r, -r);
14008     context.lineTo(3 * r, -r);
14009     context.lineTo(3 * r, r);
14010     context.lineTo(r, r);
14011     context.lineTo(r, 3 * r);
14012     context.lineTo(-r, 3 * r);
14013     context.lineTo(-r, r);
14014     context.lineTo(-3 * r, r);
14015     context.closePath();
14016   }
14017 };
14018
14019 var tan30 = Math.sqrt(1 / 3);
14020 var tan30_2 = tan30 * 2;
14021
14022 var diamond = {
14023   draw: function(context, size) {
14024     var y = Math.sqrt(size / tan30_2),
14025         x = y * tan30;
14026     context.moveTo(0, -y);
14027     context.lineTo(x, 0);
14028     context.lineTo(0, y);
14029     context.lineTo(-x, 0);
14030     context.closePath();
14031   }
14032 };
14033
14034 var ka = 0.89081309152928522810;
14035 var kr = Math.sin(pi$4 / 10) / Math.sin(7 * pi$4 / 10);
14036 var kx = Math.sin(tau$4 / 10) * kr;
14037 var ky = -Math.cos(tau$4 / 10) * kr;
14038
14039 var star = {
14040   draw: function(context, size) {
14041     var r = Math.sqrt(size * ka),
14042         x = kx * r,
14043         y = ky * r;
14044     context.moveTo(0, -r);
14045     context.lineTo(x, y);
14046     for (var i = 1; i < 5; ++i) {
14047       var a = tau$4 * i / 5,
14048           c = Math.cos(a),
14049           s = Math.sin(a);
14050       context.lineTo(s * r, -c * r);
14051       context.lineTo(c * x - s * y, s * x + c * y);
14052     }
14053     context.closePath();
14054   }
14055 };
14056
14057 var square = {
14058   draw: function(context, size) {
14059     var w = Math.sqrt(size),
14060         x = -w / 2;
14061     context.rect(x, x, w, w);
14062   }
14063 };
14064
14065 var sqrt3 = Math.sqrt(3);
14066
14067 var triangle = {
14068   draw: function(context, size) {
14069     var y = -Math.sqrt(size / (sqrt3 * 3));
14070     context.moveTo(0, y * 2);
14071     context.lineTo(-sqrt3 * y, -y);
14072     context.lineTo(sqrt3 * y, -y);
14073     context.closePath();
14074   }
14075 };
14076
14077 var c = -0.5;
14078 var s = Math.sqrt(3) / 2;
14079 var k = 1 / Math.sqrt(12);
14080 var a = (k / 2 + 1) * 3;
14081
14082 var wye = {
14083   draw: function(context, size) {
14084     var r = Math.sqrt(size / a),
14085         x0 = r / 2,
14086         y0 = r * k,
14087         x1 = x0,
14088         y1 = r * k + r,
14089         x2 = -x1,
14090         y2 = y1;
14091     context.moveTo(x0, y0);
14092     context.lineTo(x1, y1);
14093     context.lineTo(x2, y2);
14094     context.lineTo(c * x0 - s * y0, s * x0 + c * y0);
14095     context.lineTo(c * x1 - s * y1, s * x1 + c * y1);
14096     context.lineTo(c * x2 - s * y2, s * x2 + c * y2);
14097     context.lineTo(c * x0 + s * y0, c * y0 - s * x0);
14098     context.lineTo(c * x1 + s * y1, c * y1 - s * x1);
14099     context.lineTo(c * x2 + s * y2, c * y2 - s * x2);
14100     context.closePath();
14101   }
14102 };
14103
14104 var symbols = [
14105   circle$2,
14106   cross$2,
14107   diamond,
14108   square,
14109   star,
14110   triangle,
14111   wye
14112 ];
14113
14114 var symbol = function() {
14115   var type = constant$10(circle$2),
14116       size = constant$10(64),
14117       context = null;
14118
14119   function symbol() {
14120     var buffer;
14121     if (!context) context = buffer = path();
14122     type.apply(this, arguments).draw(context, +size.apply(this, arguments));
14123     if (buffer) return context = null, buffer + "" || null;
14124   }
14125
14126   symbol.type = function(_) {
14127     return arguments.length ? (type = typeof _ === "function" ? _ : constant$10(_), symbol) : type;
14128   };
14129
14130   symbol.size = function(_) {
14131     return arguments.length ? (size = typeof _ === "function" ? _ : constant$10(+_), symbol) : size;
14132   };
14133
14134   symbol.context = function(_) {
14135     return arguments.length ? (context = _ == null ? null : _, symbol) : context;
14136   };
14137
14138   return symbol;
14139 };
14140
14141 var noop$2 = function() {};
14142
14143 function point$2(that, x, y) {
14144   that._context.bezierCurveTo(
14145     (2 * that._x0 + that._x1) / 3,
14146     (2 * that._y0 + that._y1) / 3,
14147     (that._x0 + 2 * that._x1) / 3,
14148     (that._y0 + 2 * that._y1) / 3,
14149     (that._x0 + 4 * that._x1 + x) / 6,
14150     (that._y0 + 4 * that._y1 + y) / 6
14151   );
14152 }
14153
14154 function Basis(context) {
14155   this._context = context;
14156 }
14157
14158 Basis.prototype = {
14159   areaStart: function() {
14160     this._line = 0;
14161   },
14162   areaEnd: function() {
14163     this._line = NaN;
14164   },
14165   lineStart: function() {
14166     this._x0 = this._x1 =
14167     this._y0 = this._y1 = NaN;
14168     this._point = 0;
14169   },
14170   lineEnd: function() {
14171     switch (this._point) {
14172       case 3: point$2(this, this._x1, this._y1); // proceed
14173       case 2: this._context.lineTo(this._x1, this._y1); break;
14174     }
14175     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
14176     this._line = 1 - this._line;
14177   },
14178   point: function(x, y) {
14179     x = +x, y = +y;
14180     switch (this._point) {
14181       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
14182       case 1: this._point = 2; break;
14183       case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed
14184       default: point$2(this, x, y); break;
14185     }
14186     this._x0 = this._x1, this._x1 = x;
14187     this._y0 = this._y1, this._y1 = y;
14188   }
14189 };
14190
14191 var basis$2 = function(context) {
14192   return new Basis(context);
14193 };
14194
14195 function BasisClosed(context) {
14196   this._context = context;
14197 }
14198
14199 BasisClosed.prototype = {
14200   areaStart: noop$2,
14201   areaEnd: noop$2,
14202   lineStart: function() {
14203     this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =
14204     this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;
14205     this._point = 0;
14206   },
14207   lineEnd: function() {
14208     switch (this._point) {
14209       case 1: {
14210         this._context.moveTo(this._x2, this._y2);
14211         this._context.closePath();
14212         break;
14213       }
14214       case 2: {
14215         this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);
14216         this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);
14217         this._context.closePath();
14218         break;
14219       }
14220       case 3: {
14221         this.point(this._x2, this._y2);
14222         this.point(this._x3, this._y3);
14223         this.point(this._x4, this._y4);
14224         break;
14225       }
14226     }
14227   },
14228   point: function(x, y) {
14229     x = +x, y = +y;
14230     switch (this._point) {
14231       case 0: this._point = 1; this._x2 = x, this._y2 = y; break;
14232       case 1: this._point = 2; this._x3 = x, this._y3 = y; break;
14233       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;
14234       default: point$2(this, x, y); break;
14235     }
14236     this._x0 = this._x1, this._x1 = x;
14237     this._y0 = this._y1, this._y1 = y;
14238   }
14239 };
14240
14241 var basisClosed$1 = function(context) {
14242   return new BasisClosed(context);
14243 };
14244
14245 function BasisOpen(context) {
14246   this._context = context;
14247 }
14248
14249 BasisOpen.prototype = {
14250   areaStart: function() {
14251     this._line = 0;
14252   },
14253   areaEnd: function() {
14254     this._line = NaN;
14255   },
14256   lineStart: function() {
14257     this._x0 = this._x1 =
14258     this._y0 = this._y1 = NaN;
14259     this._point = 0;
14260   },
14261   lineEnd: function() {
14262     if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
14263     this._line = 1 - this._line;
14264   },
14265   point: function(x, y) {
14266     x = +x, y = +y;
14267     switch (this._point) {
14268       case 0: this._point = 1; break;
14269       case 1: this._point = 2; break;
14270       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;
14271       case 3: this._point = 4; // proceed
14272       default: point$2(this, x, y); break;
14273     }
14274     this._x0 = this._x1, this._x1 = x;
14275     this._y0 = this._y1, this._y1 = y;
14276   }
14277 };
14278
14279 var basisOpen = function(context) {
14280   return new BasisOpen(context);
14281 };
14282
14283 function Bundle(context, beta) {
14284   this._basis = new Basis(context);
14285   this._beta = beta;
14286 }
14287
14288 Bundle.prototype = {
14289   lineStart: function() {
14290     this._x = [];
14291     this._y = [];
14292     this._basis.lineStart();
14293   },
14294   lineEnd: function() {
14295     var x = this._x,
14296         y = this._y,
14297         j = x.length - 1;
14298
14299     if (j > 0) {
14300       var x0 = x[0],
14301           y0 = y[0],
14302           dx = x[j] - x0,
14303           dy = y[j] - y0,
14304           i = -1,
14305           t;
14306
14307       while (++i <= j) {
14308         t = i / j;
14309         this._basis.point(
14310           this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),
14311           this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)
14312         );
14313       }
14314     }
14315
14316     this._x = this._y = null;
14317     this._basis.lineEnd();
14318   },
14319   point: function(x, y) {
14320     this._x.push(+x);
14321     this._y.push(+y);
14322   }
14323 };
14324
14325 var bundle = (function custom(beta) {
14326
14327   function bundle(context) {
14328     return beta === 1 ? new Basis(context) : new Bundle(context, beta);
14329   }
14330
14331   bundle.beta = function(beta) {
14332     return custom(+beta);
14333   };
14334
14335   return bundle;
14336 })(0.85);
14337
14338 function point$3(that, x, y) {
14339   that._context.bezierCurveTo(
14340     that._x1 + that._k * (that._x2 - that._x0),
14341     that._y1 + that._k * (that._y2 - that._y0),
14342     that._x2 + that._k * (that._x1 - x),
14343     that._y2 + that._k * (that._y1 - y),
14344     that._x2,
14345     that._y2
14346   );
14347 }
14348
14349 function Cardinal(context, tension) {
14350   this._context = context;
14351   this._k = (1 - tension) / 6;
14352 }
14353
14354 Cardinal.prototype = {
14355   areaStart: function() {
14356     this._line = 0;
14357   },
14358   areaEnd: function() {
14359     this._line = NaN;
14360   },
14361   lineStart: function() {
14362     this._x0 = this._x1 = this._x2 =
14363     this._y0 = this._y1 = this._y2 = NaN;
14364     this._point = 0;
14365   },
14366   lineEnd: function() {
14367     switch (this._point) {
14368       case 2: this._context.lineTo(this._x2, this._y2); break;
14369       case 3: point$3(this, this._x1, this._y1); break;
14370     }
14371     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
14372     this._line = 1 - this._line;
14373   },
14374   point: function(x, y) {
14375     x = +x, y = +y;
14376     switch (this._point) {
14377       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
14378       case 1: this._point = 2; this._x1 = x, this._y1 = y; break;
14379       case 2: this._point = 3; // proceed
14380       default: point$3(this, x, y); break;
14381     }
14382     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
14383     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
14384   }
14385 };
14386
14387 var cardinal = (function custom(tension) {
14388
14389   function cardinal(context) {
14390     return new Cardinal(context, tension);
14391   }
14392
14393   cardinal.tension = function(tension) {
14394     return custom(+tension);
14395   };
14396
14397   return cardinal;
14398 })(0);
14399
14400 function CardinalClosed(context, tension) {
14401   this._context = context;
14402   this._k = (1 - tension) / 6;
14403 }
14404
14405 CardinalClosed.prototype = {
14406   areaStart: noop$2,
14407   areaEnd: noop$2,
14408   lineStart: function() {
14409     this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
14410     this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
14411     this._point = 0;
14412   },
14413   lineEnd: function() {
14414     switch (this._point) {
14415       case 1: {
14416         this._context.moveTo(this._x3, this._y3);
14417         this._context.closePath();
14418         break;
14419       }
14420       case 2: {
14421         this._context.lineTo(this._x3, this._y3);
14422         this._context.closePath();
14423         break;
14424       }
14425       case 3: {
14426         this.point(this._x3, this._y3);
14427         this.point(this._x4, this._y4);
14428         this.point(this._x5, this._y5);
14429         break;
14430       }
14431     }
14432   },
14433   point: function(x, y) {
14434     x = +x, y = +y;
14435     switch (this._point) {
14436       case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
14437       case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
14438       case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
14439       default: point$3(this, x, y); break;
14440     }
14441     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
14442     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
14443   }
14444 };
14445
14446 var cardinalClosed = (function custom(tension) {
14447
14448   function cardinal$$1(context) {
14449     return new CardinalClosed(context, tension);
14450   }
14451
14452   cardinal$$1.tension = function(tension) {
14453     return custom(+tension);
14454   };
14455
14456   return cardinal$$1;
14457 })(0);
14458
14459 function CardinalOpen(context, tension) {
14460   this._context = context;
14461   this._k = (1 - tension) / 6;
14462 }
14463
14464 CardinalOpen.prototype = {
14465   areaStart: function() {
14466     this._line = 0;
14467   },
14468   areaEnd: function() {
14469     this._line = NaN;
14470   },
14471   lineStart: function() {
14472     this._x0 = this._x1 = this._x2 =
14473     this._y0 = this._y1 = this._y2 = NaN;
14474     this._point = 0;
14475   },
14476   lineEnd: function() {
14477     if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
14478     this._line = 1 - this._line;
14479   },
14480   point: function(x, y) {
14481     x = +x, y = +y;
14482     switch (this._point) {
14483       case 0: this._point = 1; break;
14484       case 1: this._point = 2; break;
14485       case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
14486       case 3: this._point = 4; // proceed
14487       default: point$3(this, x, y); break;
14488     }
14489     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
14490     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
14491   }
14492 };
14493
14494 var cardinalOpen = (function custom(tension) {
14495
14496   function cardinal$$1(context) {
14497     return new CardinalOpen(context, tension);
14498   }
14499
14500   cardinal$$1.tension = function(tension) {
14501     return custom(+tension);
14502   };
14503
14504   return cardinal$$1;
14505 })(0);
14506
14507 function point$4(that, x, y) {
14508   var x1 = that._x1,
14509       y1 = that._y1,
14510       x2 = that._x2,
14511       y2 = that._y2;
14512
14513   if (that._l01_a > epsilon$3) {
14514     var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,
14515         n = 3 * that._l01_a * (that._l01_a + that._l12_a);
14516     x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;
14517     y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;
14518   }
14519
14520   if (that._l23_a > epsilon$3) {
14521     var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,
14522         m = 3 * that._l23_a * (that._l23_a + that._l12_a);
14523     x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;
14524     y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;
14525   }
14526
14527   that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);
14528 }
14529
14530 function CatmullRom(context, alpha) {
14531   this._context = context;
14532   this._alpha = alpha;
14533 }
14534
14535 CatmullRom.prototype = {
14536   areaStart: function() {
14537     this._line = 0;
14538   },
14539   areaEnd: function() {
14540     this._line = NaN;
14541   },
14542   lineStart: function() {
14543     this._x0 = this._x1 = this._x2 =
14544     this._y0 = this._y1 = this._y2 = NaN;
14545     this._l01_a = this._l12_a = this._l23_a =
14546     this._l01_2a = this._l12_2a = this._l23_2a =
14547     this._point = 0;
14548   },
14549   lineEnd: function() {
14550     switch (this._point) {
14551       case 2: this._context.lineTo(this._x2, this._y2); break;
14552       case 3: this.point(this._x2, this._y2); break;
14553     }
14554     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
14555     this._line = 1 - this._line;
14556   },
14557   point: function(x, y) {
14558     x = +x, y = +y;
14559
14560     if (this._point) {
14561       var x23 = this._x2 - x,
14562           y23 = this._y2 - y;
14563       this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
14564     }
14565
14566     switch (this._point) {
14567       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
14568       case 1: this._point = 2; break;
14569       case 2: this._point = 3; // proceed
14570       default: point$4(this, x, y); break;
14571     }
14572
14573     this._l01_a = this._l12_a, this._l12_a = this._l23_a;
14574     this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
14575     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
14576     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
14577   }
14578 };
14579
14580 var catmullRom = (function custom(alpha) {
14581
14582   function catmullRom(context) {
14583     return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);
14584   }
14585
14586   catmullRom.alpha = function(alpha) {
14587     return custom(+alpha);
14588   };
14589
14590   return catmullRom;
14591 })(0.5);
14592
14593 function CatmullRomClosed(context, alpha) {
14594   this._context = context;
14595   this._alpha = alpha;
14596 }
14597
14598 CatmullRomClosed.prototype = {
14599   areaStart: noop$2,
14600   areaEnd: noop$2,
14601   lineStart: function() {
14602     this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
14603     this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
14604     this._l01_a = this._l12_a = this._l23_a =
14605     this._l01_2a = this._l12_2a = this._l23_2a =
14606     this._point = 0;
14607   },
14608   lineEnd: function() {
14609     switch (this._point) {
14610       case 1: {
14611         this._context.moveTo(this._x3, this._y3);
14612         this._context.closePath();
14613         break;
14614       }
14615       case 2: {
14616         this._context.lineTo(this._x3, this._y3);
14617         this._context.closePath();
14618         break;
14619       }
14620       case 3: {
14621         this.point(this._x3, this._y3);
14622         this.point(this._x4, this._y4);
14623         this.point(this._x5, this._y5);
14624         break;
14625       }
14626     }
14627   },
14628   point: function(x, y) {
14629     x = +x, y = +y;
14630
14631     if (this._point) {
14632       var x23 = this._x2 - x,
14633           y23 = this._y2 - y;
14634       this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
14635     }
14636
14637     switch (this._point) {
14638       case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
14639       case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
14640       case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
14641       default: point$4(this, x, y); break;
14642     }
14643
14644     this._l01_a = this._l12_a, this._l12_a = this._l23_a;
14645     this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
14646     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
14647     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
14648   }
14649 };
14650
14651 var catmullRomClosed = (function custom(alpha) {
14652
14653   function catmullRom$$1(context) {
14654     return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);
14655   }
14656
14657   catmullRom$$1.alpha = function(alpha) {
14658     return custom(+alpha);
14659   };
14660
14661   return catmullRom$$1;
14662 })(0.5);
14663
14664 function CatmullRomOpen(context, alpha) {
14665   this._context = context;
14666   this._alpha = alpha;
14667 }
14668
14669 CatmullRomOpen.prototype = {
14670   areaStart: function() {
14671     this._line = 0;
14672   },
14673   areaEnd: function() {
14674     this._line = NaN;
14675   },
14676   lineStart: function() {
14677     this._x0 = this._x1 = this._x2 =
14678     this._y0 = this._y1 = this._y2 = NaN;
14679     this._l01_a = this._l12_a = this._l23_a =
14680     this._l01_2a = this._l12_2a = this._l23_2a =
14681     this._point = 0;
14682   },
14683   lineEnd: function() {
14684     if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
14685     this._line = 1 - this._line;
14686   },
14687   point: function(x, y) {
14688     x = +x, y = +y;
14689
14690     if (this._point) {
14691       var x23 = this._x2 - x,
14692           y23 = this._y2 - y;
14693       this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
14694     }
14695
14696     switch (this._point) {
14697       case 0: this._point = 1; break;
14698       case 1: this._point = 2; break;
14699       case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
14700       case 3: this._point = 4; // proceed
14701       default: point$4(this, x, y); break;
14702     }
14703
14704     this._l01_a = this._l12_a, this._l12_a = this._l23_a;
14705     this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
14706     this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
14707     this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
14708   }
14709 };
14710
14711 var catmullRomOpen = (function custom(alpha) {
14712
14713   function catmullRom$$1(context) {
14714     return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);
14715   }
14716
14717   catmullRom$$1.alpha = function(alpha) {
14718     return custom(+alpha);
14719   };
14720
14721   return catmullRom$$1;
14722 })(0.5);
14723
14724 function LinearClosed(context) {
14725   this._context = context;
14726 }
14727
14728 LinearClosed.prototype = {
14729   areaStart: noop$2,
14730   areaEnd: noop$2,
14731   lineStart: function() {
14732     this._point = 0;
14733   },
14734   lineEnd: function() {
14735     if (this._point) this._context.closePath();
14736   },
14737   point: function(x, y) {
14738     x = +x, y = +y;
14739     if (this._point) this._context.lineTo(x, y);
14740     else this._point = 1, this._context.moveTo(x, y);
14741   }
14742 };
14743
14744 var linearClosed = function(context) {
14745   return new LinearClosed(context);
14746 };
14747
14748 function sign$1(x) {
14749   return x < 0 ? -1 : 1;
14750 }
14751
14752 // Calculate the slopes of the tangents (Hermite-type interpolation) based on
14753 // the following paper: Steffen, M. 1990. A Simple Method for Monotonic
14754 // Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.
14755 // NOV(II), P. 443, 1990.
14756 function slope3(that, x2, y2) {
14757   var h0 = that._x1 - that._x0,
14758       h1 = x2 - that._x1,
14759       s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),
14760       s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),
14761       p = (s0 * h1 + s1 * h0) / (h0 + h1);
14762   return (sign$1(s0) + sign$1(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;
14763 }
14764
14765 // Calculate a one-sided slope.
14766 function slope2(that, t) {
14767   var h = that._x1 - that._x0;
14768   return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;
14769 }
14770
14771 // According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations
14772 // "you can express cubic Hermite interpolation in terms of cubic Bézier curves
14773 // with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1".
14774 function point$5(that, t0, t1) {
14775   var x0 = that._x0,
14776       y0 = that._y0,
14777       x1 = that._x1,
14778       y1 = that._y1,
14779       dx = (x1 - x0) / 3;
14780   that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);
14781 }
14782
14783 function MonotoneX(context) {
14784   this._context = context;
14785 }
14786
14787 MonotoneX.prototype = {
14788   areaStart: function() {
14789     this._line = 0;
14790   },
14791   areaEnd: function() {
14792     this._line = NaN;
14793   },
14794   lineStart: function() {
14795     this._x0 = this._x1 =
14796     this._y0 = this._y1 =
14797     this._t0 = NaN;
14798     this._point = 0;
14799   },
14800   lineEnd: function() {
14801     switch (this._point) {
14802       case 2: this._context.lineTo(this._x1, this._y1); break;
14803       case 3: point$5(this, this._t0, slope2(this, this._t0)); break;
14804     }
14805     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
14806     this._line = 1 - this._line;
14807   },
14808   point: function(x, y) {
14809     var t1 = NaN;
14810
14811     x = +x, y = +y;
14812     if (x === this._x1 && y === this._y1) return; // Ignore coincident points.
14813     switch (this._point) {
14814       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
14815       case 1: this._point = 2; break;
14816       case 2: this._point = 3; point$5(this, slope2(this, t1 = slope3(this, x, y)), t1); break;
14817       default: point$5(this, this._t0, t1 = slope3(this, x, y)); break;
14818     }
14819
14820     this._x0 = this._x1, this._x1 = x;
14821     this._y0 = this._y1, this._y1 = y;
14822     this._t0 = t1;
14823   }
14824 };
14825
14826 function MonotoneY(context) {
14827   this._context = new ReflectContext(context);
14828 }
14829
14830 (MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {
14831   MonotoneX.prototype.point.call(this, y, x);
14832 };
14833
14834 function ReflectContext(context) {
14835   this._context = context;
14836 }
14837
14838 ReflectContext.prototype = {
14839   moveTo: function(x, y) { this._context.moveTo(y, x); },
14840   closePath: function() { this._context.closePath(); },
14841   lineTo: function(x, y) { this._context.lineTo(y, x); },
14842   bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }
14843 };
14844
14845 function monotoneX(context) {
14846   return new MonotoneX(context);
14847 }
14848
14849 function monotoneY(context) {
14850   return new MonotoneY(context);
14851 }
14852
14853 function Natural(context) {
14854   this._context = context;
14855 }
14856
14857 Natural.prototype = {
14858   areaStart: function() {
14859     this._line = 0;
14860   },
14861   areaEnd: function() {
14862     this._line = NaN;
14863   },
14864   lineStart: function() {
14865     this._x = [];
14866     this._y = [];
14867   },
14868   lineEnd: function() {
14869     var x = this._x,
14870         y = this._y,
14871         n = x.length;
14872
14873     if (n) {
14874       this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);
14875       if (n === 2) {
14876         this._context.lineTo(x[1], y[1]);
14877       } else {
14878         var px = controlPoints(x),
14879             py = controlPoints(y);
14880         for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {
14881           this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
14882         }
14883       }
14884     }
14885
14886     if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();
14887     this._line = 1 - this._line;
14888     this._x = this._y = null;
14889   },
14890   point: function(x, y) {
14891     this._x.push(+x);
14892     this._y.push(+y);
14893   }
14894 };
14895
14896 // See https://www.particleincell.com/2012/bezier-splines/ for derivation.
14897 function controlPoints(x) {
14898   var i,
14899       n = x.length - 1,
14900       m,
14901       a = new Array(n),
14902       b = new Array(n),
14903       r = new Array(n);
14904   a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];
14905   for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];
14906   a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];
14907   for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];
14908   a[n - 1] = r[n - 1] / b[n - 1];
14909   for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];
14910   b[n - 1] = (x[n] + a[n - 1]) / 2;
14911   for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];
14912   return [a, b];
14913 }
14914
14915 var natural = function(context) {
14916   return new Natural(context);
14917 };
14918
14919 function Step(context, t) {
14920   this._context = context;
14921   this._t = t;
14922 }
14923
14924 Step.prototype = {
14925   areaStart: function() {
14926     this._line = 0;
14927   },
14928   areaEnd: function() {
14929     this._line = NaN;
14930   },
14931   lineStart: function() {
14932     this._x = this._y = NaN;
14933     this._point = 0;
14934   },
14935   lineEnd: function() {
14936     if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);
14937     if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
14938     if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;
14939   },
14940   point: function(x, y) {
14941     x = +x, y = +y;
14942     switch (this._point) {
14943       case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
14944       case 1: this._point = 2; // proceed
14945       default: {
14946         if (this._t <= 0) {
14947           this._context.lineTo(this._x, y);
14948           this._context.lineTo(x, y);
14949         } else {
14950           var x1 = this._x * (1 - this._t) + x * this._t;
14951           this._context.lineTo(x1, this._y);
14952           this._context.lineTo(x1, y);
14953         }
14954         break;
14955       }
14956     }
14957     this._x = x, this._y = y;
14958   }
14959 };
14960
14961 var step = function(context) {
14962   return new Step(context, 0.5);
14963 };
14964
14965 function stepBefore(context) {
14966   return new Step(context, 0);
14967 }
14968
14969 function stepAfter(context) {
14970   return new Step(context, 1);
14971 }
14972
14973 var none$1 = function(series, order) {
14974   if (!((n = series.length) > 1)) return;
14975   for (var i = 1, j, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {
14976     s0 = s1, s1 = series[order[i]];
14977     for (j = 0; j < m; ++j) {
14978       s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];
14979     }
14980   }
14981 };
14982
14983 var none$2 = function(series) {
14984   var n = series.length, o = new Array(n);
14985   while (--n >= 0) o[n] = n;
14986   return o;
14987 };
14988
14989 function stackValue(d, key) {
14990   return d[key];
14991 }
14992
14993 var stack = function() {
14994   var keys = constant$10([]),
14995       order = none$2,
14996       offset = none$1,
14997       value = stackValue;
14998
14999   function stack(data) {
15000     var kz = keys.apply(this, arguments),
15001         i,
15002         m = data.length,
15003         n = kz.length,
15004         sz = new Array(n),
15005         oz;
15006
15007     for (i = 0; i < n; ++i) {
15008       for (var ki = kz[i], si = sz[i] = new Array(m), j = 0, sij; j < m; ++j) {
15009         si[j] = sij = [0, +value(data[j], ki, j, data)];
15010         sij.data = data[j];
15011       }
15012       si.key = ki;
15013     }
15014
15015     for (i = 0, oz = order(sz); i < n; ++i) {
15016       sz[oz[i]].index = i;
15017     }
15018
15019     offset(sz, oz);
15020     return sz;
15021   }
15022
15023   stack.keys = function(_) {
15024     return arguments.length ? (keys = typeof _ === "function" ? _ : constant$10(slice$6.call(_)), stack) : keys;
15025   };
15026
15027   stack.value = function(_) {
15028     return arguments.length ? (value = typeof _ === "function" ? _ : constant$10(+_), stack) : value;
15029   };
15030
15031   stack.order = function(_) {
15032     return arguments.length ? (order = _ == null ? none$2 : typeof _ === "function" ? _ : constant$10(slice$6.call(_)), stack) : order;
15033   };
15034
15035   stack.offset = function(_) {
15036     return arguments.length ? (offset = _ == null ? none$1 : _, stack) : offset;
15037   };
15038
15039   return stack;
15040 };
15041
15042 var expand = function(series, order) {
15043   if (!((n = series.length) > 0)) return;
15044   for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) {
15045     for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0;
15046     if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y;
15047   }
15048   none$1(series, order);
15049 };
15050
15051 var diverging = function(series, order) {
15052   if (!((n = series.length) > 1)) return;
15053   for (var i, j = 0, d, dy, yp, yn, n, m = series[order[0]].length; j < m; ++j) {
15054     for (yp = yn = 0, i = 0; i < n; ++i) {
15055       if ((dy = (d = series[order[i]][j])[1] - d[0]) >= 0) {
15056         d[0] = yp, d[1] = yp += dy;
15057       } else if (dy < 0) {
15058         d[1] = yn, d[0] = yn += dy;
15059       } else {
15060         d[0] = yp;
15061       }
15062     }
15063   }
15064 };
15065
15066 var silhouette = function(series, order) {
15067   if (!((n = series.length) > 0)) return;
15068   for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) {
15069     for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0;
15070     s0[j][1] += s0[j][0] = -y / 2;
15071   }
15072   none$1(series, order);
15073 };
15074
15075 var wiggle = function(series, order) {
15076   if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return;
15077   for (var y = 0, j = 1, s0, m, n; j < m; ++j) {
15078     for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) {
15079       var si = series[order[i]],
15080           sij0 = si[j][1] || 0,
15081           sij1 = si[j - 1][1] || 0,
15082           s3 = (sij0 - sij1) / 2;
15083       for (var k = 0; k < i; ++k) {
15084         var sk = series[order[k]],
15085             skj0 = sk[j][1] || 0,
15086             skj1 = sk[j - 1][1] || 0;
15087         s3 += skj0 - skj1;
15088       }
15089       s1 += sij0, s2 += s3 * sij0;
15090     }
15091     s0[j - 1][1] += s0[j - 1][0] = y;
15092     if (s1) y -= s2 / s1;
15093   }
15094   s0[j - 1][1] += s0[j - 1][0] = y;
15095   none$1(series, order);
15096 };
15097
15098 var ascending$1 = function(series) {
15099   var sums = series.map(sum$2);
15100   return none$2(series).sort(function(a, b) { return sums[a] - sums[b]; });
15101 };
15102
15103 function sum$2(series) {
15104   var s = 0, i = -1, n = series.length, v;
15105   while (++i < n) if (v = +series[i][1]) s += v;
15106   return s;
15107 }
15108
15109 var descending$1 = function(series) {
15110   return ascending$1(series).reverse();
15111 };
15112
15113 var insideOut = function(series) {
15114   var n = series.length,
15115       i,
15116       j,
15117       sums = series.map(sum$2),
15118       order = none$2(series).sort(function(a, b) { return sums[b] - sums[a]; }),
15119       top = 0,
15120       bottom = 0,
15121       tops = [],
15122       bottoms = [];
15123
15124   for (i = 0; i < n; ++i) {
15125     j = order[i];
15126     if (top < bottom) {
15127       top += sums[j];
15128       tops.push(j);
15129     } else {
15130       bottom += sums[j];
15131       bottoms.push(j);
15132     }
15133   }
15134
15135   return bottoms.reverse().concat(tops);
15136 };
15137
15138 var reverse = function(series) {
15139   return none$2(series).reverse();
15140 };
15141
15142 var constant$11 = function(x) {
15143   return function() {
15144     return x;
15145   };
15146 };
15147
15148 function x$4(d) {
15149   return d[0];
15150 }
15151
15152 function y$4(d) {
15153   return d[1];
15154 }
15155
15156 function RedBlackTree() {
15157   this._ = null; // root node
15158 }
15159
15160 function RedBlackNode(node) {
15161   node.U = // parent node
15162   node.C = // color - true for red, false for black
15163   node.L = // left node
15164   node.R = // right node
15165   node.P = // previous node
15166   node.N = null; // next node
15167 }
15168
15169 RedBlackTree.prototype = {
15170   constructor: RedBlackTree,
15171
15172   insert: function(after, node) {
15173     var parent, grandpa, uncle;
15174
15175     if (after) {
15176       node.P = after;
15177       node.N = after.N;
15178       if (after.N) after.N.P = node;
15179       after.N = node;
15180       if (after.R) {
15181         after = after.R;
15182         while (after.L) after = after.L;
15183         after.L = node;
15184       } else {
15185         after.R = node;
15186       }
15187       parent = after;
15188     } else if (this._) {
15189       after = RedBlackFirst(this._);
15190       node.P = null;
15191       node.N = after;
15192       after.P = after.L = node;
15193       parent = after;
15194     } else {
15195       node.P = node.N = null;
15196       this._ = node;
15197       parent = null;
15198     }
15199     node.L = node.R = null;
15200     node.U = parent;
15201     node.C = true;
15202
15203     after = node;
15204     while (parent && parent.C) {
15205       grandpa = parent.U;
15206       if (parent === grandpa.L) {
15207         uncle = grandpa.R;
15208         if (uncle && uncle.C) {
15209           parent.C = uncle.C = false;
15210           grandpa.C = true;
15211           after = grandpa;
15212         } else {
15213           if (after === parent.R) {
15214             RedBlackRotateLeft(this, parent);
15215             after = parent;
15216             parent = after.U;
15217           }
15218           parent.C = false;
15219           grandpa.C = true;
15220           RedBlackRotateRight(this, grandpa);
15221         }
15222       } else {
15223         uncle = grandpa.L;
15224         if (uncle && uncle.C) {
15225           parent.C = uncle.C = false;
15226           grandpa.C = true;
15227           after = grandpa;
15228         } else {
15229           if (after === parent.L) {
15230             RedBlackRotateRight(this, parent);
15231             after = parent;
15232             parent = after.U;
15233           }
15234           parent.C = false;
15235           grandpa.C = true;
15236           RedBlackRotateLeft(this, grandpa);
15237         }
15238       }
15239       parent = after.U;
15240     }
15241     this._.C = false;
15242   },
15243
15244   remove: function(node) {
15245     if (node.N) node.N.P = node.P;
15246     if (node.P) node.P.N = node.N;
15247     node.N = node.P = null;
15248
15249     var parent = node.U,
15250         sibling,
15251         left = node.L,
15252         right = node.R,
15253         next,
15254         red;
15255
15256     if (!left) next = right;
15257     else if (!right) next = left;
15258     else next = RedBlackFirst(right);
15259
15260     if (parent) {
15261       if (parent.L === node) parent.L = next;
15262       else parent.R = next;
15263     } else {
15264       this._ = next;
15265     }
15266
15267     if (left && right) {
15268       red = next.C;
15269       next.C = node.C;
15270       next.L = left;
15271       left.U = next;
15272       if (next !== right) {
15273         parent = next.U;
15274         next.U = node.U;
15275         node = next.R;
15276         parent.L = node;
15277         next.R = right;
15278         right.U = next;
15279       } else {
15280         next.U = parent;
15281         parent = next;
15282         node = next.R;
15283       }
15284     } else {
15285       red = node.C;
15286       node = next;
15287     }
15288
15289     if (node) node.U = parent;
15290     if (red) return;
15291     if (node && node.C) { node.C = false; return; }
15292
15293     do {
15294       if (node === this._) break;
15295       if (node === parent.L) {
15296         sibling = parent.R;
15297         if (sibling.C) {
15298           sibling.C = false;
15299           parent.C = true;
15300           RedBlackRotateLeft(this, parent);
15301           sibling = parent.R;
15302         }
15303         if ((sibling.L && sibling.L.C)
15304             || (sibling.R && sibling.R.C)) {
15305           if (!sibling.R || !sibling.R.C) {
15306             sibling.L.C = false;
15307             sibling.C = true;
15308             RedBlackRotateRight(this, sibling);
15309             sibling = parent.R;
15310           }
15311           sibling.C = parent.C;
15312           parent.C = sibling.R.C = false;
15313           RedBlackRotateLeft(this, parent);
15314           node = this._;
15315           break;
15316         }
15317       } else {
15318         sibling = parent.L;
15319         if (sibling.C) {
15320           sibling.C = false;
15321           parent.C = true;
15322           RedBlackRotateRight(this, parent);
15323           sibling = parent.L;
15324         }
15325         if ((sibling.L && sibling.L.C)
15326           || (sibling.R && sibling.R.C)) {
15327           if (!sibling.L || !sibling.L.C) {
15328             sibling.R.C = false;
15329             sibling.C = true;
15330             RedBlackRotateLeft(this, sibling);
15331             sibling = parent.L;
15332           }
15333           sibling.C = parent.C;
15334           parent.C = sibling.L.C = false;
15335           RedBlackRotateRight(this, parent);
15336           node = this._;
15337           break;
15338         }
15339       }
15340       sibling.C = true;
15341       node = parent;
15342       parent = parent.U;
15343     } while (!node.C);
15344
15345     if (node) node.C = false;
15346   }
15347 };
15348
15349 function RedBlackRotateLeft(tree, node) {
15350   var p = node,
15351       q = node.R,
15352       parent = p.U;
15353
15354   if (parent) {
15355     if (parent.L === p) parent.L = q;
15356     else parent.R = q;
15357   } else {
15358     tree._ = q;
15359   }
15360
15361   q.U = parent;
15362   p.U = q;
15363   p.R = q.L;
15364   if (p.R) p.R.U = p;
15365   q.L = p;
15366 }
15367
15368 function RedBlackRotateRight(tree, node) {
15369   var p = node,
15370       q = node.L,
15371       parent = p.U;
15372
15373   if (parent) {
15374     if (parent.L === p) parent.L = q;
15375     else parent.R = q;
15376   } else {
15377     tree._ = q;
15378   }
15379
15380   q.U = parent;
15381   p.U = q;
15382   p.L = q.R;
15383   if (p.L) p.L.U = p;
15384   q.R = p;
15385 }
15386
15387 function RedBlackFirst(node) {
15388   while (node.L) node = node.L;
15389   return node;
15390 }
15391
15392 function createEdge(left, right, v0, v1) {
15393   var edge = [null, null],
15394       index = edges.push(edge) - 1;
15395   edge.left = left;
15396   edge.right = right;
15397   if (v0) setEdgeEnd(edge, left, right, v0);
15398   if (v1) setEdgeEnd(edge, right, left, v1);
15399   cells[left.index].halfedges.push(index);
15400   cells[right.index].halfedges.push(index);
15401   return edge;
15402 }
15403
15404 function createBorderEdge(left, v0, v1) {
15405   var edge = [v0, v1];
15406   edge.left = left;
15407   return edge;
15408 }
15409
15410 function setEdgeEnd(edge, left, right, vertex) {
15411   if (!edge[0] && !edge[1]) {
15412     edge[0] = vertex;
15413     edge.left = left;
15414     edge.right = right;
15415   } else if (edge.left === right) {
15416     edge[1] = vertex;
15417   } else {
15418     edge[0] = vertex;
15419   }
15420 }
15421
15422 // Liang–Barsky line clipping.
15423 function clipEdge(edge, x0, y0, x1, y1) {
15424   var a = edge[0],
15425       b = edge[1],
15426       ax = a[0],
15427       ay = a[1],
15428       bx = b[0],
15429       by = b[1],
15430       t0 = 0,
15431       t1 = 1,
15432       dx = bx - ax,
15433       dy = by - ay,
15434       r;
15435
15436   r = x0 - ax;
15437   if (!dx && r > 0) return;
15438   r /= dx;
15439   if (dx < 0) {
15440     if (r < t0) return;
15441     if (r < t1) t1 = r;
15442   } else if (dx > 0) {
15443     if (r > t1) return;
15444     if (r > t0) t0 = r;
15445   }
15446
15447   r = x1 - ax;
15448   if (!dx && r < 0) return;
15449   r /= dx;
15450   if (dx < 0) {
15451     if (r > t1) return;
15452     if (r > t0) t0 = r;
15453   } else if (dx > 0) {
15454     if (r < t0) return;
15455     if (r < t1) t1 = r;
15456   }
15457
15458   r = y0 - ay;
15459   if (!dy && r > 0) return;
15460   r /= dy;
15461   if (dy < 0) {
15462     if (r < t0) return;
15463     if (r < t1) t1 = r;
15464   } else if (dy > 0) {
15465     if (r > t1) return;
15466     if (r > t0) t0 = r;
15467   }
15468
15469   r = y1 - ay;
15470   if (!dy && r < 0) return;
15471   r /= dy;
15472   if (dy < 0) {
15473     if (r > t1) return;
15474     if (r > t0) t0 = r;
15475   } else if (dy > 0) {
15476     if (r < t0) return;
15477     if (r < t1) t1 = r;
15478   }
15479
15480   if (!(t0 > 0) && !(t1 < 1)) return true; // TODO Better check?
15481
15482   if (t0 > 0) edge[0] = [ax + t0 * dx, ay + t0 * dy];
15483   if (t1 < 1) edge[1] = [ax + t1 * dx, ay + t1 * dy];
15484   return true;
15485 }
15486
15487 function connectEdge(edge, x0, y0, x1, y1) {
15488   var v1 = edge[1];
15489   if (v1) return true;
15490
15491   var v0 = edge[0],
15492       left = edge.left,
15493       right = edge.right,
15494       lx = left[0],
15495       ly = left[1],
15496       rx = right[0],
15497       ry = right[1],
15498       fx = (lx + rx) / 2,
15499       fy = (ly + ry) / 2,
15500       fm,
15501       fb;
15502
15503   if (ry === ly) {
15504     if (fx < x0 || fx >= x1) return;
15505     if (lx > rx) {
15506       if (!v0) v0 = [fx, y0];
15507       else if (v0[1] >= y1) return;
15508       v1 = [fx, y1];
15509     } else {
15510       if (!v0) v0 = [fx, y1];
15511       else if (v0[1] < y0) return;
15512       v1 = [fx, y0];
15513     }
15514   } else {
15515     fm = (lx - rx) / (ry - ly);
15516     fb = fy - fm * fx;
15517     if (fm < -1 || fm > 1) {
15518       if (lx > rx) {
15519         if (!v0) v0 = [(y0 - fb) / fm, y0];
15520         else if (v0[1] >= y1) return;
15521         v1 = [(y1 - fb) / fm, y1];
15522       } else {
15523         if (!v0) v0 = [(y1 - fb) / fm, y1];
15524         else if (v0[1] < y0) return;
15525         v1 = [(y0 - fb) / fm, y0];
15526       }
15527     } else {
15528       if (ly < ry) {
15529         if (!v0) v0 = [x0, fm * x0 + fb];
15530         else if (v0[0] >= x1) return;
15531         v1 = [x1, fm * x1 + fb];
15532       } else {
15533         if (!v0) v0 = [x1, fm * x1 + fb];
15534         else if (v0[0] < x0) return;
15535         v1 = [x0, fm * x0 + fb];
15536       }
15537     }
15538   }
15539
15540   edge[0] = v0;
15541   edge[1] = v1;
15542   return true;
15543 }
15544
15545 function clipEdges(x0, y0, x1, y1) {
15546   var i = edges.length,
15547       edge;
15548
15549   while (i--) {
15550     if (!connectEdge(edge = edges[i], x0, y0, x1, y1)
15551         || !clipEdge(edge, x0, y0, x1, y1)
15552         || !(Math.abs(edge[0][0] - edge[1][0]) > epsilon$4
15553             || Math.abs(edge[0][1] - edge[1][1]) > epsilon$4)) {
15554       delete edges[i];
15555     }
15556   }
15557 }
15558
15559 function createCell(site) {
15560   return cells[site.index] = {
15561     site: site,
15562     halfedges: []
15563   };
15564 }
15565
15566 function cellHalfedgeAngle(cell, edge) {
15567   var site = cell.site,
15568       va = edge.left,
15569       vb = edge.right;
15570   if (site === vb) vb = va, va = site;
15571   if (vb) return Math.atan2(vb[1] - va[1], vb[0] - va[0]);
15572   if (site === va) va = edge[1], vb = edge[0];
15573   else va = edge[0], vb = edge[1];
15574   return Math.atan2(va[0] - vb[0], vb[1] - va[1]);
15575 }
15576
15577 function cellHalfedgeStart(cell, edge) {
15578   return edge[+(edge.left !== cell.site)];
15579 }
15580
15581 function cellHalfedgeEnd(cell, edge) {
15582   return edge[+(edge.left === cell.site)];
15583 }
15584
15585 function sortCellHalfedges() {
15586   for (var i = 0, n = cells.length, cell, halfedges, j, m; i < n; ++i) {
15587     if ((cell = cells[i]) && (m = (halfedges = cell.halfedges).length)) {
15588       var index = new Array(m),
15589           array = new Array(m);
15590       for (j = 0; j < m; ++j) index[j] = j, array[j] = cellHalfedgeAngle(cell, edges[halfedges[j]]);
15591       index.sort(function(i, j) { return array[j] - array[i]; });
15592       for (j = 0; j < m; ++j) array[j] = halfedges[index[j]];
15593       for (j = 0; j < m; ++j) halfedges[j] = array[j];
15594     }
15595   }
15596 }
15597
15598 function clipCells(x0, y0, x1, y1) {
15599   var nCells = cells.length,
15600       iCell,
15601       cell,
15602       site,
15603       iHalfedge,
15604       halfedges,
15605       nHalfedges,
15606       start,
15607       startX,
15608       startY,
15609       end,
15610       endX,
15611       endY,
15612       cover = true;
15613
15614   for (iCell = 0; iCell < nCells; ++iCell) {
15615     if (cell = cells[iCell]) {
15616       site = cell.site;
15617       halfedges = cell.halfedges;
15618       iHalfedge = halfedges.length;
15619
15620       // Remove any dangling clipped edges.
15621       while (iHalfedge--) {
15622         if (!edges[halfedges[iHalfedge]]) {
15623           halfedges.splice(iHalfedge, 1);
15624         }
15625       }
15626
15627       // Insert any border edges as necessary.
15628       iHalfedge = 0, nHalfedges = halfedges.length;
15629       while (iHalfedge < nHalfedges) {
15630         end = cellHalfedgeEnd(cell, edges[halfedges[iHalfedge]]), endX = end[0], endY = end[1];
15631         start = cellHalfedgeStart(cell, edges[halfedges[++iHalfedge % nHalfedges]]), startX = start[0], startY = start[1];
15632         if (Math.abs(endX - startX) > epsilon$4 || Math.abs(endY - startY) > epsilon$4) {
15633           halfedges.splice(iHalfedge, 0, edges.push(createBorderEdge(site, end,
15634               Math.abs(endX - x0) < epsilon$4 && y1 - endY > epsilon$4 ? [x0, Math.abs(startX - x0) < epsilon$4 ? startY : y1]
15635               : Math.abs(endY - y1) < epsilon$4 && x1 - endX > epsilon$4 ? [Math.abs(startY - y1) < epsilon$4 ? startX : x1, y1]
15636               : Math.abs(endX - x1) < epsilon$4 && endY - y0 > epsilon$4 ? [x1, Math.abs(startX - x1) < epsilon$4 ? startY : y0]
15637               : Math.abs(endY - y0) < epsilon$4 && endX - x0 > epsilon$4 ? [Math.abs(startY - y0) < epsilon$4 ? startX : x0, y0]
15638               : null)) - 1);
15639           ++nHalfedges;
15640         }
15641       }
15642
15643       if (nHalfedges) cover = false;
15644     }
15645   }
15646
15647   // If there weren’t any edges, have the closest site cover the extent.
15648   // It doesn’t matter which corner of the extent we measure!
15649   if (cover) {
15650     var dx, dy, d2, dc = Infinity;
15651
15652     for (iCell = 0, cover = null; iCell < nCells; ++iCell) {
15653       if (cell = cells[iCell]) {
15654         site = cell.site;
15655         dx = site[0] - x0;
15656         dy = site[1] - y0;
15657         d2 = dx * dx + dy * dy;
15658         if (d2 < dc) dc = d2, cover = cell;
15659       }
15660     }
15661
15662     if (cover) {
15663       var v00 = [x0, y0], v01 = [x0, y1], v11 = [x1, y1], v10 = [x1, y0];
15664       cover.halfedges.push(
15665         edges.push(createBorderEdge(site = cover.site, v00, v01)) - 1,
15666         edges.push(createBorderEdge(site, v01, v11)) - 1,
15667         edges.push(createBorderEdge(site, v11, v10)) - 1,
15668         edges.push(createBorderEdge(site, v10, v00)) - 1
15669       );
15670     }
15671   }
15672
15673   // Lastly delete any cells with no edges; these were entirely clipped.
15674   for (iCell = 0; iCell < nCells; ++iCell) {
15675     if (cell = cells[iCell]) {
15676       if (!cell.halfedges.length) {
15677         delete cells[iCell];
15678       }
15679     }
15680   }
15681 }
15682
15683 var circlePool = [];
15684
15685 var firstCircle;
15686
15687 function Circle() {
15688   RedBlackNode(this);
15689   this.x =
15690   this.y =
15691   this.arc =
15692   this.site =
15693   this.cy = null;
15694 }
15695
15696 function attachCircle(arc) {
15697   var lArc = arc.P,
15698       rArc = arc.N;
15699
15700   if (!lArc || !rArc) return;
15701
15702   var lSite = lArc.site,
15703       cSite = arc.site,
15704       rSite = rArc.site;
15705
15706   if (lSite === rSite) return;
15707
15708   var bx = cSite[0],
15709       by = cSite[1],
15710       ax = lSite[0] - bx,
15711       ay = lSite[1] - by,
15712       cx = rSite[0] - bx,
15713       cy = rSite[1] - by;
15714
15715   var d = 2 * (ax * cy - ay * cx);
15716   if (d >= -epsilon2$2) return;
15717
15718   var ha = ax * ax + ay * ay,
15719       hc = cx * cx + cy * cy,
15720       x = (cy * ha - ay * hc) / d,
15721       y = (ax * hc - cx * ha) / d;
15722
15723   var circle = circlePool.pop() || new Circle;
15724   circle.arc = arc;
15725   circle.site = cSite;
15726   circle.x = x + bx;
15727   circle.y = (circle.cy = y + by) + Math.sqrt(x * x + y * y); // y bottom
15728
15729   arc.circle = circle;
15730
15731   var before = null,
15732       node = circles._;
15733
15734   while (node) {
15735     if (circle.y < node.y || (circle.y === node.y && circle.x <= node.x)) {
15736       if (node.L) node = node.L;
15737       else { before = node.P; break; }
15738     } else {
15739       if (node.R) node = node.R;
15740       else { before = node; break; }
15741     }
15742   }
15743
15744   circles.insert(before, circle);
15745   if (!before) firstCircle = circle;
15746 }
15747
15748 function detachCircle(arc) {
15749   var circle = arc.circle;
15750   if (circle) {
15751     if (!circle.P) firstCircle = circle.N;
15752     circles.remove(circle);
15753     circlePool.push(circle);
15754     RedBlackNode(circle);
15755     arc.circle = null;
15756   }
15757 }
15758
15759 var beachPool = [];
15760
15761 function Beach() {
15762   RedBlackNode(this);
15763   this.edge =
15764   this.site =
15765   this.circle = null;
15766 }
15767
15768 function createBeach(site) {
15769   var beach = beachPool.pop() || new Beach;
15770   beach.site = site;
15771   return beach;
15772 }
15773
15774 function detachBeach(beach) {
15775   detachCircle(beach);
15776   beaches.remove(beach);
15777   beachPool.push(beach);
15778   RedBlackNode(beach);
15779 }
15780
15781 function removeBeach(beach) {
15782   var circle = beach.circle,
15783       x = circle.x,
15784       y = circle.cy,
15785       vertex = [x, y],
15786       previous = beach.P,
15787       next = beach.N,
15788       disappearing = [beach];
15789
15790   detachBeach(beach);
15791
15792   var lArc = previous;
15793   while (lArc.circle
15794       && Math.abs(x - lArc.circle.x) < epsilon$4
15795       && Math.abs(y - lArc.circle.cy) < epsilon$4) {
15796     previous = lArc.P;
15797     disappearing.unshift(lArc);
15798     detachBeach(lArc);
15799     lArc = previous;
15800   }
15801
15802   disappearing.unshift(lArc);
15803   detachCircle(lArc);
15804
15805   var rArc = next;
15806   while (rArc.circle
15807       && Math.abs(x - rArc.circle.x) < epsilon$4
15808       && Math.abs(y - rArc.circle.cy) < epsilon$4) {
15809     next = rArc.N;
15810     disappearing.push(rArc);
15811     detachBeach(rArc);
15812     rArc = next;
15813   }
15814
15815   disappearing.push(rArc);
15816   detachCircle(rArc);
15817
15818   var nArcs = disappearing.length,
15819       iArc;
15820   for (iArc = 1; iArc < nArcs; ++iArc) {
15821     rArc = disappearing[iArc];
15822     lArc = disappearing[iArc - 1];
15823     setEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex);
15824   }
15825
15826   lArc = disappearing[0];
15827   rArc = disappearing[nArcs - 1];
15828   rArc.edge = createEdge(lArc.site, rArc.site, null, vertex);
15829
15830   attachCircle(lArc);
15831   attachCircle(rArc);
15832 }
15833
15834 function addBeach(site) {
15835   var x = site[0],
15836       directrix = site[1],
15837       lArc,
15838       rArc,
15839       dxl,
15840       dxr,
15841       node = beaches._;
15842
15843   while (node) {
15844     dxl = leftBreakPoint(node, directrix) - x;
15845     if (dxl > epsilon$4) node = node.L; else {
15846       dxr = x - rightBreakPoint(node, directrix);
15847       if (dxr > epsilon$4) {
15848         if (!node.R) {
15849           lArc = node;
15850           break;
15851         }
15852         node = node.R;
15853       } else {
15854         if (dxl > -epsilon$4) {
15855           lArc = node.P;
15856           rArc = node;
15857         } else if (dxr > -epsilon$4) {
15858           lArc = node;
15859           rArc = node.N;
15860         } else {
15861           lArc = rArc = node;
15862         }
15863         break;
15864       }
15865     }
15866   }
15867
15868   createCell(site);
15869   var newArc = createBeach(site);
15870   beaches.insert(lArc, newArc);
15871
15872   if (!lArc && !rArc) return;
15873
15874   if (lArc === rArc) {
15875     detachCircle(lArc);
15876     rArc = createBeach(lArc.site);
15877     beaches.insert(newArc, rArc);
15878     newArc.edge = rArc.edge = createEdge(lArc.site, newArc.site);
15879     attachCircle(lArc);
15880     attachCircle(rArc);
15881     return;
15882   }
15883
15884   if (!rArc) { // && lArc
15885     newArc.edge = createEdge(lArc.site, newArc.site);
15886     return;
15887   }
15888
15889   // else lArc !== rArc
15890   detachCircle(lArc);
15891   detachCircle(rArc);
15892
15893   var lSite = lArc.site,
15894       ax = lSite[0],
15895       ay = lSite[1],
15896       bx = site[0] - ax,
15897       by = site[1] - ay,
15898       rSite = rArc.site,
15899       cx = rSite[0] - ax,
15900       cy = rSite[1] - ay,
15901       d = 2 * (bx * cy - by * cx),
15902       hb = bx * bx + by * by,
15903       hc = cx * cx + cy * cy,
15904       vertex = [(cy * hb - by * hc) / d + ax, (bx * hc - cx * hb) / d + ay];
15905
15906   setEdgeEnd(rArc.edge, lSite, rSite, vertex);
15907   newArc.edge = createEdge(lSite, site, null, vertex);
15908   rArc.edge = createEdge(site, rSite, null, vertex);
15909   attachCircle(lArc);
15910   attachCircle(rArc);
15911 }
15912
15913 function leftBreakPoint(arc, directrix) {
15914   var site = arc.site,
15915       rfocx = site[0],
15916       rfocy = site[1],
15917       pby2 = rfocy - directrix;
15918
15919   if (!pby2) return rfocx;
15920
15921   var lArc = arc.P;
15922   if (!lArc) return -Infinity;
15923
15924   site = lArc.site;
15925   var lfocx = site[0],
15926       lfocy = site[1],
15927       plby2 = lfocy - directrix;
15928
15929   if (!plby2) return lfocx;
15930
15931   var hl = lfocx - rfocx,
15932       aby2 = 1 / pby2 - 1 / plby2,
15933       b = hl / plby2;
15934
15935   if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx;
15936
15937   return (rfocx + lfocx) / 2;
15938 }
15939
15940 function rightBreakPoint(arc, directrix) {
15941   var rArc = arc.N;
15942   if (rArc) return leftBreakPoint(rArc, directrix);
15943   var site = arc.site;
15944   return site[1] === directrix ? site[0] : Infinity;
15945 }
15946
15947 var epsilon$4 = 1e-6;
15948 var epsilon2$2 = 1e-12;
15949 var beaches;
15950 var cells;
15951 var circles;
15952 var edges;
15953
15954 function triangleArea(a, b, c) {
15955   return (a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]);
15956 }
15957
15958 function lexicographic(a, b) {
15959   return b[1] - a[1]
15960       || b[0] - a[0];
15961 }
15962
15963 function Diagram(sites, extent) {
15964   var site = sites.sort(lexicographic).pop(),
15965       x,
15966       y,
15967       circle;
15968
15969   edges = [];
15970   cells = new Array(sites.length);
15971   beaches = new RedBlackTree;
15972   circles = new RedBlackTree;
15973
15974   while (true) {
15975     circle = firstCircle;
15976     if (site && (!circle || site[1] < circle.y || (site[1] === circle.y && site[0] < circle.x))) {
15977       if (site[0] !== x || site[1] !== y) {
15978         addBeach(site);
15979         x = site[0], y = site[1];
15980       }
15981       site = sites.pop();
15982     } else if (circle) {
15983       removeBeach(circle.arc);
15984     } else {
15985       break;
15986     }
15987   }
15988
15989   sortCellHalfedges();
15990
15991   if (extent) {
15992     var x0 = +extent[0][0],
15993         y0 = +extent[0][1],
15994         x1 = +extent[1][0],
15995         y1 = +extent[1][1];
15996     clipEdges(x0, y0, x1, y1);
15997     clipCells(x0, y0, x1, y1);
15998   }
15999
16000   this.edges = edges;
16001   this.cells = cells;
16002
16003   beaches =
16004   circles =
16005   edges =
16006   cells = null;
16007 }
16008
16009 Diagram.prototype = {
16010   constructor: Diagram,
16011
16012   polygons: function() {
16013     var edges = this.edges;
16014
16015     return this.cells.map(function(cell) {
16016       var polygon = cell.halfedges.map(function(i) { return cellHalfedgeStart(cell, edges[i]); });
16017       polygon.data = cell.site.data;
16018       return polygon;
16019     });
16020   },
16021
16022   triangles: function() {
16023     var triangles = [],
16024         edges = this.edges;
16025
16026     this.cells.forEach(function(cell, i) {
16027       if (!(m = (halfedges = cell.halfedges).length)) return;
16028       var site = cell.site,
16029           halfedges,
16030           j = -1,
16031           m,
16032           s0,
16033           e1 = edges[halfedges[m - 1]],
16034           s1 = e1.left === site ? e1.right : e1.left;
16035
16036       while (++j < m) {
16037         s0 = s1;
16038         e1 = edges[halfedges[j]];
16039         s1 = e1.left === site ? e1.right : e1.left;
16040         if (s0 && s1 && i < s0.index && i < s1.index && triangleArea(site, s0, s1) < 0) {
16041           triangles.push([site.data, s0.data, s1.data]);
16042         }
16043       }
16044     });
16045
16046     return triangles;
16047   },
16048
16049   links: function() {
16050     return this.edges.filter(function(edge) {
16051       return edge.right;
16052     }).map(function(edge) {
16053       return {
16054         source: edge.left.data,
16055         target: edge.right.data
16056       };
16057     });
16058   },
16059
16060   find: function(x, y, radius) {
16061     var that = this, i0, i1 = that._found || 0, n = that.cells.length, cell;
16062
16063     // Use the previously-found cell, or start with an arbitrary one.
16064     while (!(cell = that.cells[i1])) if (++i1 >= n) return null;
16065     var dx = x - cell.site[0], dy = y - cell.site[1], d2 = dx * dx + dy * dy;
16066
16067     // Traverse the half-edges to find a closer cell, if any.
16068     do {
16069       cell = that.cells[i0 = i1], i1 = null;
16070       cell.halfedges.forEach(function(e) {
16071         var edge = that.edges[e], v = edge.left;
16072         if ((v === cell.site || !v) && !(v = edge.right)) return;
16073         var vx = x - v[0], vy = y - v[1], v2 = vx * vx + vy * vy;
16074         if (v2 < d2) d2 = v2, i1 = v.index;
16075       });
16076     } while (i1 !== null);
16077
16078     that._found = i0;
16079
16080     return radius == null || d2 <= radius * radius ? cell.site : null;
16081   }
16082 };
16083
16084 var voronoi = function() {
16085   var x$$1 = x$4,
16086       y$$1 = y$4,
16087       extent = null;
16088
16089   function voronoi(data) {
16090     return new Diagram(data.map(function(d, i) {
16091       var s = [Math.round(x$$1(d, i, data) / epsilon$4) * epsilon$4, Math.round(y$$1(d, i, data) / epsilon$4) * epsilon$4];
16092       s.index = i;
16093       s.data = d;
16094       return s;
16095     }), extent);
16096   }
16097
16098   voronoi.polygons = function(data) {
16099     return voronoi(data).polygons();
16100   };
16101
16102   voronoi.links = function(data) {
16103     return voronoi(data).links();
16104   };
16105
16106   voronoi.triangles = function(data) {
16107     return voronoi(data).triangles();
16108   };
16109
16110   voronoi.x = function(_) {
16111     return arguments.length ? (x$$1 = typeof _ === "function" ? _ : constant$11(+_), voronoi) : x$$1;
16112   };
16113
16114   voronoi.y = function(_) {
16115     return arguments.length ? (y$$1 = typeof _ === "function" ? _ : constant$11(+_), voronoi) : y$$1;
16116   };
16117
16118   voronoi.extent = function(_) {
16119     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]]];
16120   };
16121
16122   voronoi.size = function(_) {
16123     return arguments.length ? (extent = _ == null ? null : [[0, 0], [+_[0], +_[1]]], voronoi) : extent && [extent[1][0] - extent[0][0], extent[1][1] - extent[0][1]];
16124   };
16125
16126   return voronoi;
16127 };
16128
16129 var constant$12 = function(x) {
16130   return function() {
16131     return x;
16132   };
16133 };
16134
16135 function ZoomEvent(target, type, transform) {
16136   this.target = target;
16137   this.type = type;
16138   this.transform = transform;
16139 }
16140
16141 function Transform(k, x, y) {
16142   this.k = k;
16143   this.x = x;
16144   this.y = y;
16145 }
16146
16147 Transform.prototype = {
16148   constructor: Transform,
16149   scale: function(k) {
16150     return k === 1 ? this : new Transform(this.k * k, this.x, this.y);
16151   },
16152   translate: function(x, y) {
16153     return x === 0 & y === 0 ? this : new Transform(this.k, this.x + this.k * x, this.y + this.k * y);
16154   },
16155   apply: function(point) {
16156     return [point[0] * this.k + this.x, point[1] * this.k + this.y];
16157   },
16158   applyX: function(x) {
16159     return x * this.k + this.x;
16160   },
16161   applyY: function(y) {
16162     return y * this.k + this.y;
16163   },
16164   invert: function(location) {
16165     return [(location[0] - this.x) / this.k, (location[1] - this.y) / this.k];
16166   },
16167   invertX: function(x) {
16168     return (x - this.x) / this.k;
16169   },
16170   invertY: function(y) {
16171     return (y - this.y) / this.k;
16172   },
16173   rescaleX: function(x) {
16174     return x.copy().domain(x.range().map(this.invertX, this).map(x.invert, x));
16175   },
16176   rescaleY: function(y) {
16177     return y.copy().domain(y.range().map(this.invertY, this).map(y.invert, y));
16178   },
16179   toString: function() {
16180     return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")";
16181   }
16182 };
16183
16184 var identity$7 = new Transform(1, 0, 0);
16185
16186 transform.prototype = Transform.prototype;
16187
16188 function transform(node) {
16189   return node.__zoom || identity$7;
16190 }
16191
16192 function nopropagation$2() {
16193   event.stopImmediatePropagation();
16194 }
16195
16196 var noevent$2 = function() {
16197   event.preventDefault();
16198   event.stopImmediatePropagation();
16199 };
16200
16201 // Ignore right-click, since that should open the context menu.
16202 function defaultFilter$2() {
16203   return !event.button;
16204 }
16205
16206 function defaultExtent$1() {
16207   var e = this, w, h;
16208   if (e instanceof SVGElement) {
16209     e = e.ownerSVGElement || e;
16210     w = e.width.baseVal.value;
16211     h = e.height.baseVal.value;
16212   } else {
16213     w = e.clientWidth;
16214     h = e.clientHeight;
16215   }
16216   return [[0, 0], [w, h]];
16217 }
16218
16219 function defaultTransform() {
16220   return this.__zoom || identity$7;
16221 }
16222
16223 function defaultWheelDelta() {
16224   return -event.deltaY * (event.deltaMode ? 120 : 1) / 500;
16225 }
16226
16227 function defaultTouchable$1() {
16228   return "ontouchstart" in this;
16229 }
16230
16231 var d3_zoom = function() {
16232   var filter = defaultFilter$2,
16233       extent = defaultExtent$1,
16234       wheelDelta = defaultWheelDelta,
16235       touchable = defaultTouchable$1,
16236       k0 = 0,
16237       k1 = Infinity,
16238       x0 = -k1,
16239       x1 = k1,
16240       y0 = x0,
16241       y1 = x1,
16242       duration = 250,
16243       interpolate = interpolateZoom,
16244       gestures = [],
16245       listeners = dispatch("start", "zoom", "end"),
16246       touchstarting,
16247       touchending,
16248       touchDelay = 500,
16249       wheelDelay = 150,
16250       clickDistance2 = 0;
16251
16252   function zoom(selection) {
16253     selection
16254         .property("__zoom", defaultTransform)
16255         .on("wheel.zoom", wheeled)
16256         .on("mousedown.zoom", mousedowned)
16257         .on("dblclick.zoom", dblclicked)
16258       .filter(touchable)
16259         .on("touchstart.zoom", touchstarted)
16260         .on("touchmove.zoom", touchmoved)
16261         .on("touchend.zoom touchcancel.zoom", touchended)
16262         .style("touch-action", "none")
16263         .style("-webkit-tap-highlight-color", "rgba(0,0,0,0)");
16264   }
16265
16266   zoom.transform = function(collection, transform$$1) {
16267     var selection = collection.selection ? collection.selection() : collection;
16268     selection.property("__zoom", defaultTransform);
16269     if (collection !== selection) {
16270       schedule(collection, transform$$1);
16271     } else {
16272       selection.interrupt().each(function() {
16273         gesture(this, arguments)
16274             .start()
16275             .zoom(null, typeof transform$$1 === "function" ? transform$$1.apply(this, arguments) : transform$$1)
16276             .end();
16277       });
16278     }
16279   };
16280
16281   zoom.scaleBy = function(selection, k) {
16282     zoom.scaleTo(selection, function() {
16283       var k0 = this.__zoom.k,
16284           k1 = typeof k === "function" ? k.apply(this, arguments) : k;
16285       return k0 * k1;
16286     });
16287   };
16288
16289   zoom.scaleTo = function(selection, k) {
16290     zoom.transform(selection, function() {
16291       var e = extent.apply(this, arguments),
16292           t0 = this.__zoom,
16293           p0 = centroid(e),
16294           p1 = t0.invert(p0),
16295           k1 = typeof k === "function" ? k.apply(this, arguments) : k;
16296       return constrain(translate(scale(t0, k1), p0, p1), e);
16297     });
16298   };
16299
16300   zoom.translateBy = function(selection, x, y) {
16301     zoom.transform(selection, function() {
16302       return constrain(this.__zoom.translate(
16303         typeof x === "function" ? x.apply(this, arguments) : x,
16304         typeof y === "function" ? y.apply(this, arguments) : y
16305       ), extent.apply(this, arguments));
16306     });
16307   };
16308
16309   zoom.translateTo = function(selection, x, y) {
16310     zoom.transform(selection, function() {
16311       var e = extent.apply(this, arguments),
16312           t = this.__zoom,
16313           p = centroid(e);
16314       return constrain(identity$7.translate(p[0], p[1]).scale(t.k).translate(
16315         typeof x === "function" ? -x.apply(this, arguments) : -x,
16316         typeof y === "function" ? -y.apply(this, arguments) : -y
16317       ), e);
16318     });
16319   };
16320
16321   function scale(transform$$1, k) {
16322     k = Math.max(k0, Math.min(k1, k));
16323     return k === transform$$1.k ? transform$$1 : new Transform(k, transform$$1.x, transform$$1.y);
16324   }
16325
16326   function translate(transform$$1, p0, p1) {
16327     var x = p0[0] - p1[0] * transform$$1.k, y = p0[1] - p1[1] * transform$$1.k;
16328     return x === transform$$1.x && y === transform$$1.y ? transform$$1 : new Transform(transform$$1.k, x, y);
16329   }
16330
16331   function constrain(transform$$1, extent) {
16332     var dx0 = transform$$1.invertX(extent[0][0]) - x0,
16333         dx1 = transform$$1.invertX(extent[1][0]) - x1,
16334         dy0 = transform$$1.invertY(extent[0][1]) - y0,
16335         dy1 = transform$$1.invertY(extent[1][1]) - y1;
16336     return transform$$1.translate(
16337       dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1),
16338       dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1)
16339     );
16340   }
16341
16342   function centroid(extent) {
16343     return [(+extent[0][0] + +extent[1][0]) / 2, (+extent[0][1] + +extent[1][1]) / 2];
16344   }
16345
16346   function schedule(transition, transform$$1, center) {
16347     transition
16348         .on("start.zoom", function() { gesture(this, arguments).start(); })
16349         .on("interrupt.zoom end.zoom", function() { gesture(this, arguments).end(); })
16350         .tween("zoom", function() {
16351           var that = this,
16352               args = arguments,
16353               g = gesture(that, args),
16354               e = extent.apply(that, args),
16355               p = center || centroid(e),
16356               w = Math.max(e[1][0] - e[0][0], e[1][1] - e[0][1]),
16357               a = that.__zoom,
16358               b = typeof transform$$1 === "function" ? transform$$1.apply(that, args) : transform$$1,
16359               i = interpolate(a.invert(p).concat(w / a.k), b.invert(p).concat(w / b.k));
16360           return function(t) {
16361             if (t === 1) t = b; // Avoid rounding error on end.
16362             else { var l = i(t), k = w / l[2]; t = new Transform(k, p[0] - l[0] * k, p[1] - l[1] * k); }
16363             g.zoom(null, t);
16364           };
16365         });
16366   }
16367
16368   function gesture(that, args) {
16369     for (var i = 0, n = gestures.length, g; i < n; ++i) {
16370       if ((g = gestures[i]).that === that) {
16371         return g;
16372       }
16373     }
16374     return new Gesture(that, args);
16375   }
16376
16377   function Gesture(that, args) {
16378     this.that = that;
16379     this.args = args;
16380     this.index = -1;
16381     this.active = 0;
16382     this.extent = extent.apply(that, args);
16383   }
16384
16385   Gesture.prototype = {
16386     start: function() {
16387       if (++this.active === 1) {
16388         this.index = gestures.push(this) - 1;
16389         this.emit("start");
16390       }
16391       return this;
16392     },
16393     zoom: function(key, transform$$1) {
16394       if (this.mouse && key !== "mouse") this.mouse[1] = transform$$1.invert(this.mouse[0]);
16395       if (this.touch0 && key !== "touch") this.touch0[1] = transform$$1.invert(this.touch0[0]);
16396       if (this.touch1 && key !== "touch") this.touch1[1] = transform$$1.invert(this.touch1[0]);
16397       this.that.__zoom = transform$$1;
16398       this.emit("zoom");
16399       return this;
16400     },
16401     end: function() {
16402       if (--this.active === 0) {
16403         gestures.splice(this.index, 1);
16404         this.index = -1;
16405         this.emit("end");
16406       }
16407       return this;
16408     },
16409     emit: function(type) {
16410       customEvent(new ZoomEvent(zoom, type, this.that.__zoom), listeners.apply, listeners, [type, this.that, this.args]);
16411     }
16412   };
16413
16414   function wheeled() {
16415     if (!filter.apply(this, arguments)) return;
16416     var g = gesture(this, arguments),
16417         t = this.__zoom,
16418         k = Math.max(k0, Math.min(k1, t.k * Math.pow(2, wheelDelta.apply(this, arguments)))),
16419         p = d3_mouse(this);
16420
16421     // If the mouse is in the same location as before, reuse it.
16422     // If there were recent wheel events, reset the wheel idle timeout.
16423     if (g.wheel) {
16424       if (g.mouse[0][0] !== p[0] || g.mouse[0][1] !== p[1]) {
16425         g.mouse[1] = t.invert(g.mouse[0] = p);
16426       }
16427       clearTimeout(g.wheel);
16428     }
16429
16430     // If this wheel event won’t trigger a transform change, ignore it.
16431     else if (t.k === k) return;
16432
16433     // Otherwise, capture the mouse point and location at the start.
16434     else {
16435       g.mouse = [p, t.invert(p)];
16436       interrupt(this);
16437       g.start();
16438     }
16439
16440     noevent$2();
16441     g.wheel = setTimeout(wheelidled, wheelDelay);
16442     g.zoom("mouse", constrain(translate(scale(t, k), g.mouse[0], g.mouse[1]), g.extent));
16443
16444     function wheelidled() {
16445       g.wheel = null;
16446       g.end();
16447     }
16448   }
16449
16450   function mousedowned() {
16451     if (touchending || !filter.apply(this, arguments)) return;
16452     var g = gesture(this, arguments),
16453         v = d3_select(event.view).on("mousemove.zoom", mousemoved, true).on("mouseup.zoom", mouseupped, true),
16454         p = d3_mouse(this),
16455         x0 = event.clientX,
16456         y0 = event.clientY;
16457
16458     dragDisable(event.view);
16459     nopropagation$2();
16460     g.mouse = [p, this.__zoom.invert(p)];
16461     interrupt(this);
16462     g.start();
16463
16464     function mousemoved() {
16465       noevent$2();
16466       if (!g.moved) {
16467         var dx = event.clientX - x0, dy = event.clientY - y0;
16468         g.moved = dx * dx + dy * dy > clickDistance2;
16469       }
16470       g.zoom("mouse", constrain(translate(g.that.__zoom, g.mouse[0] = d3_mouse(g.that), g.mouse[1]), g.extent));
16471     }
16472
16473     function mouseupped() {
16474       v.on("mousemove.zoom mouseup.zoom", null);
16475       yesdrag(event.view, g.moved);
16476       noevent$2();
16477       g.end();
16478     }
16479   }
16480
16481   function dblclicked() {
16482     if (!filter.apply(this, arguments)) return;
16483     var t0 = this.__zoom,
16484         p0 = d3_mouse(this),
16485         p1 = t0.invert(p0),
16486         k1 = t0.k * (event.shiftKey ? 0.5 : 2),
16487         t1 = constrain(translate(scale(t0, k1), p0, p1), extent.apply(this, arguments));
16488
16489     noevent$2();
16490     if (duration > 0) d3_select(this).transition().duration(duration).call(schedule, t1, p0);
16491     else d3_select(this).call(zoom.transform, t1);
16492   }
16493
16494   function touchstarted() {
16495     if (!filter.apply(this, arguments)) return;
16496     var g = gesture(this, arguments),
16497         touches = event.changedTouches,
16498         started,
16499         n = touches.length, i, t, p;
16500
16501     nopropagation$2();
16502     for (i = 0; i < n; ++i) {
16503       t = touches[i], p = touch(this, touches, t.identifier);
16504       p = [p, this.__zoom.invert(p), t.identifier];
16505       if (!g.touch0) g.touch0 = p, started = true;
16506       else if (!g.touch1) g.touch1 = p;
16507     }
16508
16509     // If this is a dbltap, reroute to the (optional) dblclick.zoom handler.
16510     if (touchstarting) {
16511       touchstarting = clearTimeout(touchstarting);
16512       if (!g.touch1) {
16513         g.end();
16514         p = d3_select(this).on("dblclick.zoom");
16515         if (p) p.apply(this, arguments);
16516         return;
16517       }
16518     }
16519
16520     if (started) {
16521       touchstarting = setTimeout(function() { touchstarting = null; }, touchDelay);
16522       interrupt(this);
16523       g.start();
16524     }
16525   }
16526
16527   function touchmoved() {
16528     var g = gesture(this, arguments),
16529         touches = event.changedTouches,
16530         n = touches.length, i, t, p, l;
16531
16532     noevent$2();
16533     if (touchstarting) touchstarting = clearTimeout(touchstarting);
16534     for (i = 0; i < n; ++i) {
16535       t = touches[i], p = touch(this, touches, t.identifier);
16536       if (g.touch0 && g.touch0[2] === t.identifier) g.touch0[0] = p;
16537       else if (g.touch1 && g.touch1[2] === t.identifier) g.touch1[0] = p;
16538     }
16539     t = g.that.__zoom;
16540     if (g.touch1) {
16541       var p0 = g.touch0[0], l0 = g.touch0[1],
16542           p1 = g.touch1[0], l1 = g.touch1[1],
16543           dp = (dp = p1[0] - p0[0]) * dp + (dp = p1[1] - p0[1]) * dp,
16544           dl = (dl = l1[0] - l0[0]) * dl + (dl = l1[1] - l0[1]) * dl;
16545       t = scale(t, Math.sqrt(dp / dl));
16546       p = [(p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2];
16547       l = [(l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2];
16548     }
16549     else if (g.touch0) p = g.touch0[0], l = g.touch0[1];
16550     else return;
16551     g.zoom("touch", constrain(translate(t, p, l), g.extent));
16552   }
16553
16554   function touchended() {
16555     var g = gesture(this, arguments),
16556         touches = event.changedTouches,
16557         n = touches.length, i, t;
16558
16559     nopropagation$2();
16560     if (touchending) clearTimeout(touchending);
16561     touchending = setTimeout(function() { touchending = null; }, touchDelay);
16562     for (i = 0; i < n; ++i) {
16563       t = touches[i];
16564       if (g.touch0 && g.touch0[2] === t.identifier) delete g.touch0;
16565       else if (g.touch1 && g.touch1[2] === t.identifier) delete g.touch1;
16566     }
16567     if (g.touch1 && !g.touch0) g.touch0 = g.touch1, delete g.touch1;
16568     if (g.touch0) g.touch0[1] = this.__zoom.invert(g.touch0[0]);
16569     else g.end();
16570   }
16571
16572   zoom.wheelDelta = function(_) {
16573     return arguments.length ? (wheelDelta = typeof _ === "function" ? _ : constant$12(+_), zoom) : wheelDelta;
16574   };
16575
16576   zoom.filter = function(_) {
16577     return arguments.length ? (filter = typeof _ === "function" ? _ : constant$12(!!_), zoom) : filter;
16578   };
16579
16580   zoom.touchable = function(_) {
16581     return arguments.length ? (touchable = typeof _ === "function" ? _ : constant$12(!!_), zoom) : touchable;
16582   };
16583
16584   zoom.extent = function(_) {
16585     return arguments.length ? (extent = typeof _ === "function" ? _ : constant$12([[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]]), zoom) : extent;
16586   };
16587
16588   zoom.scaleExtent = function(_) {
16589     return arguments.length ? (k0 = +_[0], k1 = +_[1], zoom) : [k0, k1];
16590   };
16591
16592   zoom.translateExtent = function(_) {
16593     return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], zoom) : [[x0, y0], [x1, y1]];
16594   };
16595
16596   zoom.duration = function(_) {
16597     return arguments.length ? (duration = +_, zoom) : duration;
16598   };
16599
16600   zoom.interpolate = function(_) {
16601     return arguments.length ? (interpolate = _, zoom) : interpolate;
16602   };
16603
16604   zoom.on = function() {
16605     var value = listeners.on.apply(listeners, arguments);
16606     return value === listeners ? zoom : value;
16607   };
16608
16609   zoom.clickDistance = function(_) {
16610     return arguments.length ? (clickDistance2 = (_ = +_) * _, zoom) : Math.sqrt(clickDistance2);
16611   };
16612
16613   return zoom;
16614 };
16615
16616
16617
16618 var index = Object.freeze({
16619         version: version,
16620         bisect: bisectRight,
16621         bisectRight: bisectRight,
16622         bisectLeft: bisectLeft,
16623         ascending: d3_ascending,
16624         bisector: d3_bisector,
16625         cross: cross,
16626         descending: d3_descending,
16627         deviation: deviation,
16628         extent: extent,
16629         histogram: histogram,
16630         thresholdFreedmanDiaconis: freedmanDiaconis,
16631         thresholdScott: scott,
16632         thresholdSturges: sturges,
16633         max: max,
16634         mean: mean,
16635         median: d3_median,
16636         merge: merge,
16637         min: min,
16638         pairs: pairs,
16639         permute: permute,
16640         quantile: threshold,
16641         range: d3_range,
16642         scan: scan,
16643         shuffle: shuffle,
16644         sum: sum,
16645         ticks: ticks,
16646         tickIncrement: tickIncrement,
16647         tickStep: tickStep,
16648         transpose: transpose,
16649         variance: variance,
16650         zip: zip,
16651         axisTop: axisTop,
16652         axisRight: axisRight,
16653         axisBottom: axisBottom,
16654         axisLeft: axisLeft,
16655         brush: brush,
16656         brushX: brushX,
16657         brushY: brushY,
16658         brushSelection: brushSelection,
16659         chord: chord,
16660         ribbon: ribbon,
16661         nest: nest,
16662         set: set$2,
16663         map: map$1,
16664         keys: keys,
16665         values: values,
16666         entries: entries,
16667         color: color,
16668         rgb: rgb,
16669         hsl: hsl,
16670         lab: lab,
16671         hcl: hcl,
16672         cubehelix: cubehelix,
16673         dispatch: dispatch,
16674         drag: drag,
16675         dragDisable: dragDisable,
16676         dragEnable: yesdrag,
16677         dsvFormat: dsv,
16678         csvParse: csvParse,
16679         csvParseRows: csvParseRows,
16680         csvFormat: csvFormat,
16681         csvFormatRows: csvFormatRows,
16682         tsvParse: tsvParse,
16683         tsvParseRows: tsvParseRows,
16684         tsvFormat: tsvFormat,
16685         tsvFormatRows: tsvFormatRows,
16686         easeLinear: linear$1,
16687         easeQuad: quadInOut,
16688         easeQuadIn: quadIn,
16689         easeQuadOut: quadOut,
16690         easeQuadInOut: quadInOut,
16691         easeCubic: cubicInOut,
16692         easeCubicIn: cubicIn,
16693         easeCubicOut: cubicOut,
16694         easeCubicInOut: cubicInOut,
16695         easePoly: polyInOut,
16696         easePolyIn: polyIn,
16697         easePolyOut: polyOut,
16698         easePolyInOut: polyInOut,
16699         easeSin: sinInOut,
16700         easeSinIn: sinIn,
16701         easeSinOut: sinOut,
16702         easeSinInOut: sinInOut,
16703         easeExp: expInOut,
16704         easeExpIn: expIn,
16705         easeExpOut: expOut,
16706         easeExpInOut: expInOut,
16707         easeCircle: circleInOut,
16708         easeCircleIn: circleIn,
16709         easeCircleOut: circleOut,
16710         easeCircleInOut: circleInOut,
16711         easeBounce: bounceOut,
16712         easeBounceIn: bounceIn,
16713         easeBounceOut: bounceOut,
16714         easeBounceInOut: bounceInOut,
16715         easeBack: backInOut,
16716         easeBackIn: backIn,
16717         easeBackOut: backOut,
16718         easeBackInOut: backInOut,
16719         easeElastic: elasticOut,
16720         easeElasticIn: elasticIn,
16721         easeElasticOut: elasticOut,
16722         easeElasticInOut: elasticInOut,
16723         forceCenter: center$1,
16724         forceCollide: collide,
16725         forceLink: link,
16726         forceManyBody: manyBody,
16727         forceRadial: radial,
16728         forceSimulation: simulation,
16729         forceX: x$2,
16730         forceY: y$2,
16731         formatDefaultLocale: defaultLocale,
16732         get format () { return format; },
16733         get formatPrefix () { return formatPrefix; },
16734         formatLocale: formatLocale,
16735         formatSpecifier: formatSpecifier,
16736         precisionFixed: precisionFixed,
16737         precisionPrefix: precisionPrefix,
16738         precisionRound: precisionRound,
16739         geoArea: d3_geoArea,
16740         geoBounds: d3_geoBounds,
16741         geoCentroid: d3_geoCentroid,
16742         geoCircle: circle,
16743         geoClipAntimeridian: clipAntimeridian,
16744         geoClipCircle: clipCircle,
16745         geoClipExtent: extent$1,
16746         geoClipRectangle: clipRectangle,
16747         geoContains: contains,
16748         geoDistance: distance,
16749         geoGraticule: graticule,
16750         geoGraticule10: graticule10,
16751         geoInterpolate: interpolate$1,
16752         geoLength: d3_geoLength,
16753         geoPath: d3_geoPath,
16754         geoAlbers: albers,
16755         geoAlbersUsa: albersUsa,
16756         geoAzimuthalEqualArea: azimuthalEqualArea,
16757         geoAzimuthalEqualAreaRaw: azimuthalEqualAreaRaw,
16758         geoAzimuthalEquidistant: azimuthalEquidistant,
16759         geoAzimuthalEquidistantRaw: azimuthalEquidistantRaw,
16760         geoConicConformal: conicConformal,
16761         geoConicConformalRaw: conicConformalRaw,
16762         geoConicEqualArea: conicEqualArea,
16763         geoConicEqualAreaRaw: conicEqualAreaRaw,
16764         geoConicEquidistant: conicEquidistant,
16765         geoConicEquidistantRaw: conicEquidistantRaw,
16766         geoEquirectangular: equirectangular,
16767         geoEquirectangularRaw: equirectangularRaw,
16768         geoGnomonic: gnomonic,
16769         geoGnomonicRaw: gnomonicRaw,
16770         geoIdentity: d3_geoIdentity,
16771         geoProjection: projection,
16772         geoProjectionMutator: projectionMutator,
16773         geoMercator: mercator,
16774         geoMercatorRaw: mercatorRaw,
16775         geoNaturalEarth1: naturalEarth1,
16776         geoNaturalEarth1Raw: naturalEarth1Raw,
16777         geoOrthographic: orthographic,
16778         geoOrthographicRaw: orthographicRaw,
16779         geoStereographic: stereographic,
16780         geoStereographicRaw: stereographicRaw,
16781         geoTransverseMercator: transverseMercator,
16782         geoTransverseMercatorRaw: transverseMercatorRaw,
16783         geoRotation: rotation,
16784         geoStream: d3_geoStream,
16785         geoTransform: d3_geoTransform,
16786         cluster: cluster,
16787         hierarchy: hierarchy,
16788         pack: index$2,
16789         packSiblings: siblings,
16790         packEnclose: enclose,
16791         partition: partition,
16792         stratify: stratify,
16793         tree: tree,
16794         treemap: index$3,
16795         treemapBinary: binary,
16796         treemapDice: treemapDice,
16797         treemapSlice: treemapSlice,
16798         treemapSliceDice: sliceDice,
16799         treemapSquarify: squarify,
16800         treemapResquarify: resquarify,
16801         interpolate: d3_interpolate,
16802         interpolateArray: array$1,
16803         interpolateBasis: basis$1,
16804         interpolateBasisClosed: basisClosed,
16805         interpolateDate: date,
16806         interpolateNumber: d3_interpolateNumber,
16807         interpolateObject: object,
16808         interpolateRound: interpolateRound,
16809         interpolateString: interpolateString,
16810         interpolateTransformCss: interpolateTransformCss,
16811         interpolateTransformSvg: interpolateTransformSvg,
16812         interpolateZoom: interpolateZoom,
16813         interpolateRgb: d3_interpolateRgb,
16814         interpolateRgbBasis: rgbBasis,
16815         interpolateRgbBasisClosed: rgbBasisClosed,
16816         interpolateHsl: hsl$2,
16817         interpolateHslLong: hslLong,
16818         interpolateLab: lab$1,
16819         interpolateHcl: hcl$2,
16820         interpolateHclLong: hclLong,
16821         interpolateCubehelix: cubehelix$2,
16822         interpolateCubehelixLong: cubehelixLong,
16823         quantize: d3_quantize,
16824         path: path,
16825         polygonArea: d3_polygonArea,
16826         polygonCentroid: d3_polygonCentroid,
16827         polygonHull: d3_polygonHull,
16828         polygonContains: contains$1,
16829         polygonLength: length$1,
16830         quadtree: quadtree,
16831         queue: queue,
16832         randomUniform: uniform,
16833         randomNormal: normal,
16834         randomLogNormal: logNormal,
16835         randomBates: bates,
16836         randomIrwinHall: irwinHall,
16837         randomExponential: exponential$1,
16838         request: d3_request,
16839         html: html,
16840         json: d3_json,
16841         text: d3_text,
16842         xml: d3_xml,
16843         csv: csv$1,
16844         tsv: tsv$1,
16845         scaleBand: band,
16846         scalePoint: point$1,
16847         scaleIdentity: identity$5,
16848         scaleLinear: linear$2,
16849         scaleLog: log$1,
16850         scaleOrdinal: ordinal,
16851         scaleImplicit: implicit,
16852         scalePow: pow$1,
16853         scaleSqrt: sqrt$1,
16854         scaleQuantile: quantile$$1,
16855         scaleQuantize: quantize,
16856         scaleThreshold: threshold$1,
16857         scaleTime: time,
16858         scaleUtc: utcTime,
16859         schemeCategory10: category10,
16860         schemeCategory20b: category20b,
16861         schemeCategory20c: category20c,
16862         schemeCategory20: category20,
16863         interpolateCubehelixDefault: cubehelix$3,
16864         interpolateRainbow: rainbow$1,
16865         interpolateWarm: warm,
16866         interpolateCool: cool,
16867         interpolateViridis: viridis,
16868         interpolateMagma: magma,
16869         interpolateInferno: inferno,
16870         interpolatePlasma: plasma,
16871         scaleSequential: sequential,
16872         creator: creator,
16873         local: local$1,
16874         matcher: matcher$1,
16875         mouse: d3_mouse,
16876         namespace: namespace,
16877         namespaces: namespaces,
16878         select: d3_select,
16879         selectAll: d3_selectAll,
16880         selection: selection,
16881         selector: selector,
16882         selectorAll: selectorAll,
16883         style: styleValue,
16884         touch: touch,
16885         touches: d3_touches,
16886         window: defaultView,
16887         get event () { return event; },
16888         customEvent: customEvent,
16889         arc: arc,
16890         area: area,
16891         line: line,
16892         pie: pie,
16893         areaRadial: areaRadial,
16894         radialArea: areaRadial,
16895         lineRadial: lineRadial$1,
16896         radialLine: lineRadial$1,
16897         pointRadial: pointRadial,
16898         linkHorizontal: linkHorizontal,
16899         linkVertical: linkVertical,
16900         linkRadial: linkRadial,
16901         symbol: symbol,
16902         symbols: symbols,
16903         symbolCircle: circle$2,
16904         symbolCross: cross$2,
16905         symbolDiamond: diamond,
16906         symbolSquare: square,
16907         symbolStar: star,
16908         symbolTriangle: triangle,
16909         symbolWye: wye,
16910         curveBasisClosed: basisClosed$1,
16911         curveBasisOpen: basisOpen,
16912         curveBasis: basis$2,
16913         curveBundle: bundle,
16914         curveCardinalClosed: cardinalClosed,
16915         curveCardinalOpen: cardinalOpen,
16916         curveCardinal: cardinal,
16917         curveCatmullRomClosed: catmullRomClosed,
16918         curveCatmullRomOpen: catmullRomOpen,
16919         curveCatmullRom: catmullRom,
16920         curveLinearClosed: linearClosed,
16921         curveLinear: curveLinear,
16922         curveMonotoneX: monotoneX,
16923         curveMonotoneY: monotoneY,
16924         curveNatural: natural,
16925         curveStep: step,
16926         curveStepAfter: stepAfter,
16927         curveStepBefore: stepBefore,
16928         stack: stack,
16929         stackOffsetExpand: expand,
16930         stackOffsetDiverging: diverging,
16931         stackOffsetNone: none$1,
16932         stackOffsetSilhouette: silhouette,
16933         stackOffsetWiggle: wiggle,
16934         stackOrderAscending: ascending$1,
16935         stackOrderDescending: descending$1,
16936         stackOrderInsideOut: insideOut,
16937         stackOrderNone: none$2,
16938         stackOrderReverse: reverse,
16939         timeInterval: newInterval,
16940         timeMillisecond: millisecond,
16941         timeMilliseconds: milliseconds,
16942         utcMillisecond: millisecond,
16943         utcMilliseconds: milliseconds,
16944         timeSecond: second,
16945         timeSeconds: seconds,
16946         utcSecond: second,
16947         utcSeconds: seconds,
16948         timeMinute: minute,
16949         timeMinutes: minutes,
16950         timeHour: hour,
16951         timeHours: hours,
16952         timeDay: day,
16953         timeDays: days,
16954         timeWeek: sunday,
16955         timeWeeks: sundays,
16956         timeSunday: sunday,
16957         timeSundays: sundays,
16958         timeMonday: monday,
16959         timeMondays: mondays,
16960         timeTuesday: tuesday,
16961         timeTuesdays: tuesdays,
16962         timeWednesday: wednesday,
16963         timeWednesdays: wednesdays,
16964         timeThursday: thursday,
16965         timeThursdays: thursdays,
16966         timeFriday: friday,
16967         timeFridays: fridays,
16968         timeSaturday: saturday,
16969         timeSaturdays: saturdays,
16970         timeMonth: month,
16971         timeMonths: months,
16972         timeYear: year,
16973         timeYears: years,
16974         utcMinute: utcMinute,
16975         utcMinutes: utcMinutes,
16976         utcHour: utcHour,
16977         utcHours: utcHours,
16978         utcDay: utcDay,
16979         utcDays: utcDays,
16980         utcWeek: utcSunday,
16981         utcWeeks: utcSundays,
16982         utcSunday: utcSunday,
16983         utcSundays: utcSundays,
16984         utcMonday: utcMonday,
16985         utcMondays: utcMondays,
16986         utcTuesday: utcTuesday,
16987         utcTuesdays: utcTuesdays,
16988         utcWednesday: utcWednesday,
16989         utcWednesdays: utcWednesdays,
16990         utcThursday: utcThursday,
16991         utcThursdays: utcThursdays,
16992         utcFriday: utcFriday,
16993         utcFridays: utcFridays,
16994         utcSaturday: utcSaturday,
16995         utcSaturdays: utcSaturdays,
16996         utcMonth: utcMonth,
16997         utcMonths: utcMonths,
16998         utcYear: utcYear,
16999         utcYears: utcYears,
17000         timeFormatDefaultLocale: defaultLocale$1,
17001         get timeFormat () { return timeFormat; },
17002         get timeParse () { return timeParse; },
17003         get utcFormat () { return utcFormat; },
17004         get utcParse () { return utcParse; },
17005         timeFormatLocale: formatLocale$1,
17006         isoFormat: formatIso,
17007         isoParse: parseIso,
17008         now: now,
17009         timer: timer,
17010         timerFlush: timerFlush,
17011         timeout: d3_timeout,
17012         interval: interval$1,
17013         transition: transition,
17014         active: active,
17015         interrupt: interrupt,
17016         voronoi: voronoi,
17017         zoom: d3_zoom,
17018         zoomTransform: transform,
17019         zoomIdentity: identity$7
17020 });
17021
17022 function actionAddEntity(way) {
17023     return function(graph) {
17024         return graph.replace(way);
17025     };
17026 }
17027
17028 /**
17029  * Creates an array with all falsey values removed. The values `false`, `null`,
17030  * `0`, `""`, `undefined`, and `NaN` are falsey.
17031  *
17032  * @static
17033  * @memberOf _
17034  * @since 0.1.0
17035  * @category Array
17036  * @param {Array} array The array to compact.
17037  * @returns {Array} Returns the new array of filtered values.
17038  * @example
17039  *
17040  * _.compact([0, 1, false, 2, '', 3]);
17041  * // => [1, 2, 3]
17042  */
17043 function compact(array) {
17044   var index = -1,
17045       length = array == null ? 0 : array.length,
17046       resIndex = 0,
17047       result = [];
17048
17049   while (++index < length) {
17050     var value = array[index];
17051     if (value) {
17052       result[resIndex++] = value;
17053     }
17054   }
17055   return result;
17056 }
17057
17058 /** Detect free variable `global` from Node.js. */
17059 var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
17060
17061 /** Detect free variable `self`. */
17062 var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
17063
17064 /** Used as a reference to the global object. */
17065 var root$2 = freeGlobal || freeSelf || Function('return this')();
17066
17067 /** Built-in value references. */
17068 var Symbol = root$2.Symbol;
17069
17070 /** Used for built-in method references. */
17071 var objectProto$2 = Object.prototype;
17072
17073 /** Used to check objects for own properties. */
17074 var hasOwnProperty$2 = objectProto$2.hasOwnProperty;
17075
17076 /**
17077  * Used to resolve the
17078  * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
17079  * of values.
17080  */
17081 var nativeObjectToString = objectProto$2.toString;
17082
17083 /** Built-in value references. */
17084 var symToStringTag$1 = Symbol ? Symbol.toStringTag : undefined;
17085
17086 /**
17087  * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
17088  *
17089  * @private
17090  * @param {*} value The value to query.
17091  * @returns {string} Returns the raw `toStringTag`.
17092  */
17093 function getRawTag(value) {
17094   var isOwn = hasOwnProperty$2.call(value, symToStringTag$1),
17095       tag = value[symToStringTag$1];
17096
17097   try {
17098     value[symToStringTag$1] = undefined;
17099     var unmasked = true;
17100   } catch (e) {}
17101
17102   var result = nativeObjectToString.call(value);
17103   if (unmasked) {
17104     if (isOwn) {
17105       value[symToStringTag$1] = tag;
17106     } else {
17107       delete value[symToStringTag$1];
17108     }
17109   }
17110   return result;
17111 }
17112
17113 /** Used for built-in method references. */
17114 var objectProto$3 = Object.prototype;
17115
17116 /**
17117  * Used to resolve the
17118  * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
17119  * of values.
17120  */
17121 var nativeObjectToString$1 = objectProto$3.toString;
17122
17123 /**
17124  * Converts `value` to a string using `Object.prototype.toString`.
17125  *
17126  * @private
17127  * @param {*} value The value to convert.
17128  * @returns {string} Returns the converted string.
17129  */
17130 function objectToString(value) {
17131   return nativeObjectToString$1.call(value);
17132 }
17133
17134 /** `Object#toString` result references. */
17135 var nullTag = '[object Null]';
17136 var undefinedTag = '[object Undefined]';
17137
17138 /** Built-in value references. */
17139 var symToStringTag = Symbol ? Symbol.toStringTag : undefined;
17140
17141 /**
17142  * The base implementation of `getTag` without fallbacks for buggy environments.
17143  *
17144  * @private
17145  * @param {*} value The value to query.
17146  * @returns {string} Returns the `toStringTag`.
17147  */
17148 function baseGetTag(value) {
17149   if (value == null) {
17150     return value === undefined ? undefinedTag : nullTag;
17151   }
17152   return (symToStringTag && symToStringTag in Object(value))
17153     ? getRawTag(value)
17154     : objectToString(value);
17155 }
17156
17157 /**
17158  * Checks if `value` is the
17159  * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
17160  * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
17161  *
17162  * @static
17163  * @memberOf _
17164  * @since 0.1.0
17165  * @category Lang
17166  * @param {*} value The value to check.
17167  * @returns {boolean} Returns `true` if `value` is an object, else `false`.
17168  * @example
17169  *
17170  * _.isObject({});
17171  * // => true
17172  *
17173  * _.isObject([1, 2, 3]);
17174  * // => true
17175  *
17176  * _.isObject(_.noop);
17177  * // => true
17178  *
17179  * _.isObject(null);
17180  * // => false
17181  */
17182 function isObject(value) {
17183   var type = typeof value;
17184   return value != null && (type == 'object' || type == 'function');
17185 }
17186
17187 /** `Object#toString` result references. */
17188 var asyncTag = '[object AsyncFunction]';
17189 var funcTag = '[object Function]';
17190 var genTag = '[object GeneratorFunction]';
17191 var proxyTag = '[object Proxy]';
17192
17193 /**
17194  * Checks if `value` is classified as a `Function` object.
17195  *
17196  * @static
17197  * @memberOf _
17198  * @since 0.1.0
17199  * @category Lang
17200  * @param {*} value The value to check.
17201  * @returns {boolean} Returns `true` if `value` is a function, else `false`.
17202  * @example
17203  *
17204  * _.isFunction(_);
17205  * // => true
17206  *
17207  * _.isFunction(/abc/);
17208  * // => false
17209  */
17210 function isFunction(value) {
17211   if (!isObject(value)) {
17212     return false;
17213   }
17214   // The use of `Object#toString` avoids issues with the `typeof` operator
17215   // in Safari 9 which returns 'object' for typed arrays and other constructors.
17216   var tag = baseGetTag(value);
17217   return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
17218 }
17219
17220 /** Used to detect overreaching core-js shims. */
17221 var coreJsData = root$2['__core-js_shared__'];
17222
17223 /** Used to detect methods masquerading as native. */
17224 var maskSrcKey = (function() {
17225   var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
17226   return uid ? ('Symbol(src)_1.' + uid) : '';
17227 }());
17228
17229 /**
17230  * Checks if `func` has its source masked.
17231  *
17232  * @private
17233  * @param {Function} func The function to check.
17234  * @returns {boolean} Returns `true` if `func` is masked, else `false`.
17235  */
17236 function isMasked(func) {
17237   return !!maskSrcKey && (maskSrcKey in func);
17238 }
17239
17240 /** Used for built-in method references. */
17241 var funcProto$1 = Function.prototype;
17242
17243 /** Used to resolve the decompiled source of functions. */
17244 var funcToString$1 = funcProto$1.toString;
17245
17246 /**
17247  * Converts `func` to its source code.
17248  *
17249  * @private
17250  * @param {Function} func The function to convert.
17251  * @returns {string} Returns the source code.
17252  */
17253 function toSource(func) {
17254   if (func != null) {
17255     try {
17256       return funcToString$1.call(func);
17257     } catch (e) {}
17258     try {
17259       return (func + '');
17260     } catch (e) {}
17261   }
17262   return '';
17263 }
17264
17265 /**
17266  * Used to match `RegExp`
17267  * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
17268  */
17269 var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
17270
17271 /** Used to detect host constructors (Safari). */
17272 var reIsHostCtor = /^\[object .+?Constructor\]$/;
17273
17274 /** Used for built-in method references. */
17275 var funcProto = Function.prototype;
17276 var objectProto$1 = Object.prototype;
17277
17278 /** Used to resolve the decompiled source of functions. */
17279 var funcToString = funcProto.toString;
17280
17281 /** Used to check objects for own properties. */
17282 var hasOwnProperty$1 = objectProto$1.hasOwnProperty;
17283
17284 /** Used to detect if a method is native. */
17285 var reIsNative = RegExp('^' +
17286   funcToString.call(hasOwnProperty$1).replace(reRegExpChar, '\\$&')
17287   .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
17288 );
17289
17290 /**
17291  * The base implementation of `_.isNative` without bad shim checks.
17292  *
17293  * @private
17294  * @param {*} value The value to check.
17295  * @returns {boolean} Returns `true` if `value` is a native function,
17296  *  else `false`.
17297  */
17298 function baseIsNative(value) {
17299   if (!isObject(value) || isMasked(value)) {
17300     return false;
17301   }
17302   var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
17303   return pattern.test(toSource(value));
17304 }
17305
17306 /**
17307  * Gets the value at `key` of `object`.
17308  *
17309  * @private
17310  * @param {Object} [object] The object to query.
17311  * @param {string} key The key of the property to get.
17312  * @returns {*} Returns the property value.
17313  */
17314 function getValue(object, key) {
17315   return object == null ? undefined : object[key];
17316 }
17317
17318 /**
17319  * Gets the native function at `key` of `object`.
17320  *
17321  * @private
17322  * @param {Object} object The object to query.
17323  * @param {string} key The key of the method to get.
17324  * @returns {*} Returns the function if it's native, else `undefined`.
17325  */
17326 function getNative(object, key) {
17327   var value = getValue(object, key);
17328   return baseIsNative(value) ? value : undefined;
17329 }
17330
17331 var defineProperty = (function() {
17332   try {
17333     var func = getNative(Object, 'defineProperty');
17334     func({}, '', {});
17335     return func;
17336   } catch (e) {}
17337 }());
17338
17339 /**
17340  * The base implementation of `assignValue` and `assignMergeValue` without
17341  * value checks.
17342  *
17343  * @private
17344  * @param {Object} object The object to modify.
17345  * @param {string} key The key of the property to assign.
17346  * @param {*} value The value to assign.
17347  */
17348 function baseAssignValue(object, key, value) {
17349   if (key == '__proto__' && defineProperty) {
17350     defineProperty(object, key, {
17351       'configurable': true,
17352       'enumerable': true,
17353       'value': value,
17354       'writable': true
17355     });
17356   } else {
17357     object[key] = value;
17358   }
17359 }
17360
17361 /**
17362  * Performs a
17363  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
17364  * comparison between two values to determine if they are equivalent.
17365  *
17366  * @static
17367  * @memberOf _
17368  * @since 4.0.0
17369  * @category Lang
17370  * @param {*} value The value to compare.
17371  * @param {*} other The other value to compare.
17372  * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
17373  * @example
17374  *
17375  * var object = { 'a': 1 };
17376  * var other = { 'a': 1 };
17377  *
17378  * _.eq(object, object);
17379  * // => true
17380  *
17381  * _.eq(object, other);
17382  * // => false
17383  *
17384  * _.eq('a', 'a');
17385  * // => true
17386  *
17387  * _.eq('a', Object('a'));
17388  * // => false
17389  *
17390  * _.eq(NaN, NaN);
17391  * // => true
17392  */
17393 function eq(value, other) {
17394   return value === other || (value !== value && other !== other);
17395 }
17396
17397 /** Used for built-in method references. */
17398 var objectProto = Object.prototype;
17399
17400 /** Used to check objects for own properties. */
17401 var hasOwnProperty = objectProto.hasOwnProperty;
17402
17403 /**
17404  * Assigns `value` to `key` of `object` if the existing value is not equivalent
17405  * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
17406  * for equality comparisons.
17407  *
17408  * @private
17409  * @param {Object} object The object to modify.
17410  * @param {string} key The key of the property to assign.
17411  * @param {*} value The value to assign.
17412  */
17413 function assignValue(object, key, value) {
17414   var objValue = object[key];
17415   if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||
17416       (value === undefined && !(key in object))) {
17417     baseAssignValue(object, key, value);
17418   }
17419 }
17420
17421 /**
17422  * Copies properties of `source` to `object`.
17423  *
17424  * @private
17425  * @param {Object} source The object to copy properties from.
17426  * @param {Array} props The property identifiers to copy.
17427  * @param {Object} [object={}] The object to copy properties to.
17428  * @param {Function} [customizer] The function to customize copied values.
17429  * @returns {Object} Returns `object`.
17430  */
17431 function copyObject(source, props, object, customizer) {
17432   var isNew = !object;
17433   object || (object = {});
17434
17435   var index = -1,
17436       length = props.length;
17437
17438   while (++index < length) {
17439     var key = props[index];
17440
17441     var newValue = customizer
17442       ? customizer(object[key], source[key], key, object, source)
17443       : undefined;
17444
17445     if (newValue === undefined) {
17446       newValue = source[key];
17447     }
17448     if (isNew) {
17449       baseAssignValue(object, key, newValue);
17450     } else {
17451       assignValue(object, key, newValue);
17452     }
17453   }
17454   return object;
17455 }
17456
17457 /**
17458  * This method returns the first argument it receives.
17459  *
17460  * @static
17461  * @since 0.1.0
17462  * @memberOf _
17463  * @category Util
17464  * @param {*} value Any value.
17465  * @returns {*} Returns `value`.
17466  * @example
17467  *
17468  * var object = { 'a': 1 };
17469  *
17470  * console.log(_.identity(object) === object);
17471  * // => true
17472  */
17473 function identity$8(value) {
17474   return value;
17475 }
17476
17477 /**
17478  * A faster alternative to `Function#apply`, this function invokes `func`
17479  * with the `this` binding of `thisArg` and the arguments of `args`.
17480  *
17481  * @private
17482  * @param {Function} func The function to invoke.
17483  * @param {*} thisArg The `this` binding of `func`.
17484  * @param {Array} args The arguments to invoke `func` with.
17485  * @returns {*} Returns the result of `func`.
17486  */
17487 function apply(func, thisArg, args) {
17488   switch (args.length) {
17489     case 0: return func.call(thisArg);
17490     case 1: return func.call(thisArg, args[0]);
17491     case 2: return func.call(thisArg, args[0], args[1]);
17492     case 3: return func.call(thisArg, args[0], args[1], args[2]);
17493   }
17494   return func.apply(thisArg, args);
17495 }
17496
17497 /* Built-in method references for those with the same name as other `lodash` methods. */
17498 var nativeMax = Math.max;
17499
17500 /**
17501  * A specialized version of `baseRest` which transforms the rest array.
17502  *
17503  * @private
17504  * @param {Function} func The function to apply a rest parameter to.
17505  * @param {number} [start=func.length-1] The start position of the rest parameter.
17506  * @param {Function} transform The rest array transform.
17507  * @returns {Function} Returns the new function.
17508  */
17509 function overRest(func, start, transform) {
17510   start = nativeMax(start === undefined ? (func.length - 1) : start, 0);
17511   return function() {
17512     var args = arguments,
17513         index = -1,
17514         length = nativeMax(args.length - start, 0),
17515         array = Array(length);
17516
17517     while (++index < length) {
17518       array[index] = args[start + index];
17519     }
17520     index = -1;
17521     var otherArgs = Array(start + 1);
17522     while (++index < start) {
17523       otherArgs[index] = args[index];
17524     }
17525     otherArgs[start] = transform(array);
17526     return apply(func, this, otherArgs);
17527   };
17528 }
17529
17530 /**
17531  * Creates a function that returns `value`.
17532  *
17533  * @static
17534  * @memberOf _
17535  * @since 2.4.0
17536  * @category Util
17537  * @param {*} value The value to return from the new function.
17538  * @returns {Function} Returns the new constant function.
17539  * @example
17540  *
17541  * var objects = _.times(2, _.constant({ 'a': 1 }));
17542  *
17543  * console.log(objects);
17544  * // => [{ 'a': 1 }, { 'a': 1 }]
17545  *
17546  * console.log(objects[0] === objects[1]);
17547  * // => true
17548  */
17549 function constant$13(value) {
17550   return function() {
17551     return value;
17552   };
17553 }
17554
17555 /**
17556  * The base implementation of `setToString` without support for hot loop shorting.
17557  *
17558  * @private
17559  * @param {Function} func The function to modify.
17560  * @param {Function} string The `toString` result.
17561  * @returns {Function} Returns `func`.
17562  */
17563 var baseSetToString = !defineProperty ? identity$8 : function(func, string) {
17564   return defineProperty(func, 'toString', {
17565     'configurable': true,
17566     'enumerable': false,
17567     'value': constant$13(string),
17568     'writable': true
17569   });
17570 };
17571
17572 /** Used to detect hot functions by number of calls within a span of milliseconds. */
17573 var HOT_COUNT = 800;
17574 var HOT_SPAN = 16;
17575
17576 /* Built-in method references for those with the same name as other `lodash` methods. */
17577 var nativeNow = Date.now;
17578
17579 /**
17580  * Creates a function that'll short out and invoke `identity` instead
17581  * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
17582  * milliseconds.
17583  *
17584  * @private
17585  * @param {Function} func The function to restrict.
17586  * @returns {Function} Returns the new shortable function.
17587  */
17588 function shortOut(func) {
17589   var count = 0,
17590       lastCalled = 0;
17591
17592   return function() {
17593     var stamp = nativeNow(),
17594         remaining = HOT_SPAN - (stamp - lastCalled);
17595
17596     lastCalled = stamp;
17597     if (remaining > 0) {
17598       if (++count >= HOT_COUNT) {
17599         return arguments[0];
17600       }
17601     } else {
17602       count = 0;
17603     }
17604     return func.apply(undefined, arguments);
17605   };
17606 }
17607
17608 /**
17609  * Sets the `toString` method of `func` to return `string`.
17610  *
17611  * @private
17612  * @param {Function} func The function to modify.
17613  * @param {Function} string The `toString` result.
17614  * @returns {Function} Returns `func`.
17615  */
17616 var setToString = shortOut(baseSetToString);
17617
17618 /**
17619  * The base implementation of `_.rest` which doesn't validate or coerce arguments.
17620  *
17621  * @private
17622  * @param {Function} func The function to apply a rest parameter to.
17623  * @param {number} [start=func.length-1] The start position of the rest parameter.
17624  * @returns {Function} Returns the new function.
17625  */
17626 function baseRest(func, start) {
17627   return setToString(overRest(func, start, identity$8), func + '');
17628 }
17629
17630 /** Used as references for various `Number` constants. */
17631 var MAX_SAFE_INTEGER = 9007199254740991;
17632
17633 /**
17634  * Checks if `value` is a valid array-like length.
17635  *
17636  * **Note:** This method is loosely based on
17637  * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
17638  *
17639  * @static
17640  * @memberOf _
17641  * @since 4.0.0
17642  * @category Lang
17643  * @param {*} value The value to check.
17644  * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
17645  * @example
17646  *
17647  * _.isLength(3);
17648  * // => true
17649  *
17650  * _.isLength(Number.MIN_VALUE);
17651  * // => false
17652  *
17653  * _.isLength(Infinity);
17654  * // => false
17655  *
17656  * _.isLength('3');
17657  * // => false
17658  */
17659 function isLength(value) {
17660   return typeof value == 'number' &&
17661     value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
17662 }
17663
17664 /**
17665  * Checks if `value` is array-like. A value is considered array-like if it's
17666  * not a function and has a `value.length` that's an integer greater than or
17667  * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
17668  *
17669  * @static
17670  * @memberOf _
17671  * @since 4.0.0
17672  * @category Lang
17673  * @param {*} value The value to check.
17674  * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
17675  * @example
17676  *
17677  * _.isArrayLike([1, 2, 3]);
17678  * // => true
17679  *
17680  * _.isArrayLike(document.body.children);
17681  * // => true
17682  *
17683  * _.isArrayLike('abc');
17684  * // => true
17685  *
17686  * _.isArrayLike(_.noop);
17687  * // => false
17688  */
17689 function isArrayLike(value) {
17690   return value != null && isLength(value.length) && !isFunction(value);
17691 }
17692
17693 /** Used as references for various `Number` constants. */
17694 var MAX_SAFE_INTEGER$1 = 9007199254740991;
17695
17696 /** Used to detect unsigned integer values. */
17697 var reIsUint = /^(?:0|[1-9]\d*)$/;
17698
17699 /**
17700  * Checks if `value` is a valid array-like index.
17701  *
17702  * @private
17703  * @param {*} value The value to check.
17704  * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
17705  * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
17706  */
17707 function isIndex(value, length) {
17708   length = length == null ? MAX_SAFE_INTEGER$1 : length;
17709   return !!length &&
17710     (typeof value == 'number' || reIsUint.test(value)) &&
17711     (value > -1 && value % 1 == 0 && value < length);
17712 }
17713
17714 /**
17715  * Checks if the given arguments are from an iteratee call.
17716  *
17717  * @private
17718  * @param {*} value The potential iteratee value argument.
17719  * @param {*} index The potential iteratee index or key argument.
17720  * @param {*} object The potential iteratee object argument.
17721  * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
17722  *  else `false`.
17723  */
17724 function isIterateeCall(value, index, object) {
17725   if (!isObject(object)) {
17726     return false;
17727   }
17728   var type = typeof index;
17729   if (type == 'number'
17730         ? (isArrayLike(object) && isIndex(index, object.length))
17731         : (type == 'string' && index in object)
17732       ) {
17733     return eq(object[index], value);
17734   }
17735   return false;
17736 }
17737
17738 /**
17739  * Creates a function like `_.assign`.
17740  *
17741  * @private
17742  * @param {Function} assigner The function to assign values.
17743  * @returns {Function} Returns the new assigner function.
17744  */
17745 function createAssigner(assigner) {
17746   return baseRest(function(object, sources) {
17747     var index = -1,
17748         length = sources.length,
17749         customizer = length > 1 ? sources[length - 1] : undefined,
17750         guard = length > 2 ? sources[2] : undefined;
17751
17752     customizer = (assigner.length > 3 && typeof customizer == 'function')
17753       ? (length--, customizer)
17754       : undefined;
17755
17756     if (guard && isIterateeCall(sources[0], sources[1], guard)) {
17757       customizer = length < 3 ? undefined : customizer;
17758       length = 1;
17759     }
17760     object = Object(object);
17761     while (++index < length) {
17762       var source = sources[index];
17763       if (source) {
17764         assigner(object, source, index, customizer);
17765       }
17766     }
17767     return object;
17768   });
17769 }
17770
17771 /**
17772  * The base implementation of `_.times` without support for iteratee shorthands
17773  * or max array length checks.
17774  *
17775  * @private
17776  * @param {number} n The number of times to invoke `iteratee`.
17777  * @param {Function} iteratee The function invoked per iteration.
17778  * @returns {Array} Returns the array of results.
17779  */
17780 function baseTimes(n, iteratee) {
17781   var index = -1,
17782       result = Array(n);
17783
17784   while (++index < n) {
17785     result[index] = iteratee(index);
17786   }
17787   return result;
17788 }
17789
17790 /**
17791  * Checks if `value` is object-like. A value is object-like if it's not `null`
17792  * and has a `typeof` result of "object".
17793  *
17794  * @static
17795  * @memberOf _
17796  * @since 4.0.0
17797  * @category Lang
17798  * @param {*} value The value to check.
17799  * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
17800  * @example
17801  *
17802  * _.isObjectLike({});
17803  * // => true
17804  *
17805  * _.isObjectLike([1, 2, 3]);
17806  * // => true
17807  *
17808  * _.isObjectLike(_.noop);
17809  * // => false
17810  *
17811  * _.isObjectLike(null);
17812  * // => false
17813  */
17814 function isObjectLike(value) {
17815   return value != null && typeof value == 'object';
17816 }
17817
17818 /** `Object#toString` result references. */
17819 var argsTag = '[object Arguments]';
17820
17821 /**
17822  * The base implementation of `_.isArguments`.
17823  *
17824  * @private
17825  * @param {*} value The value to check.
17826  * @returns {boolean} Returns `true` if `value` is an `arguments` object,
17827  */
17828 function baseIsArguments(value) {
17829   return isObjectLike(value) && baseGetTag(value) == argsTag;
17830 }
17831
17832 /** Used for built-in method references. */
17833 var objectProto$5 = Object.prototype;
17834
17835 /** Used to check objects for own properties. */
17836 var hasOwnProperty$4 = objectProto$5.hasOwnProperty;
17837
17838 /** Built-in value references. */
17839 var propertyIsEnumerable = objectProto$5.propertyIsEnumerable;
17840
17841 /**
17842  * Checks if `value` is likely an `arguments` object.
17843  *
17844  * @static
17845  * @memberOf _
17846  * @since 0.1.0
17847  * @category Lang
17848  * @param {*} value The value to check.
17849  * @returns {boolean} Returns `true` if `value` is an `arguments` object,
17850  *  else `false`.
17851  * @example
17852  *
17853  * _.isArguments(function() { return arguments; }());
17854  * // => true
17855  *
17856  * _.isArguments([1, 2, 3]);
17857  * // => false
17858  */
17859 var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) {
17860   return isObjectLike(value) && hasOwnProperty$4.call(value, 'callee') &&
17861     !propertyIsEnumerable.call(value, 'callee');
17862 };
17863
17864 /**
17865  * Checks if `value` is classified as an `Array` object.
17866  *
17867  * @static
17868  * @memberOf _
17869  * @since 0.1.0
17870  * @category Lang
17871  * @param {*} value The value to check.
17872  * @returns {boolean} Returns `true` if `value` is an array, else `false`.
17873  * @example
17874  *
17875  * _.isArray([1, 2, 3]);
17876  * // => true
17877  *
17878  * _.isArray(document.body.children);
17879  * // => false
17880  *
17881  * _.isArray('abc');
17882  * // => false
17883  *
17884  * _.isArray(_.noop);
17885  * // => false
17886  */
17887 var isArray = Array.isArray;
17888
17889 /**
17890  * This method returns `false`.
17891  *
17892  * @static
17893  * @memberOf _
17894  * @since 4.13.0
17895  * @category Util
17896  * @returns {boolean} Returns `false`.
17897  * @example
17898  *
17899  * _.times(2, _.stubFalse);
17900  * // => [false, false]
17901  */
17902 function stubFalse() {
17903   return false;
17904 }
17905
17906 /** Detect free variable `exports`. */
17907 var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;
17908
17909 /** Detect free variable `module`. */
17910 var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;
17911
17912 /** Detect the popular CommonJS extension `module.exports`. */
17913 var moduleExports = freeModule && freeModule.exports === freeExports;
17914
17915 /** Built-in value references. */
17916 var Buffer = moduleExports ? root$2.Buffer : undefined;
17917
17918 /* Built-in method references for those with the same name as other `lodash` methods. */
17919 var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;
17920
17921 /**
17922  * Checks if `value` is a buffer.
17923  *
17924  * @static
17925  * @memberOf _
17926  * @since 4.3.0
17927  * @category Lang
17928  * @param {*} value The value to check.
17929  * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
17930  * @example
17931  *
17932  * _.isBuffer(new Buffer(2));
17933  * // => true
17934  *
17935  * _.isBuffer(new Uint8Array(2));
17936  * // => false
17937  */
17938 var isBuffer = nativeIsBuffer || stubFalse;
17939
17940 /** `Object#toString` result references. */
17941 var argsTag$1 = '[object Arguments]';
17942 var arrayTag = '[object Array]';
17943 var boolTag = '[object Boolean]';
17944 var dateTag = '[object Date]';
17945 var errorTag = '[object Error]';
17946 var funcTag$1 = '[object Function]';
17947 var mapTag = '[object Map]';
17948 var numberTag = '[object Number]';
17949 var objectTag = '[object Object]';
17950 var regexpTag = '[object RegExp]';
17951 var setTag = '[object Set]';
17952 var stringTag = '[object String]';
17953 var weakMapTag = '[object WeakMap]';
17954
17955 var arrayBufferTag = '[object ArrayBuffer]';
17956 var dataViewTag = '[object DataView]';
17957 var float32Tag = '[object Float32Array]';
17958 var float64Tag = '[object Float64Array]';
17959 var int8Tag = '[object Int8Array]';
17960 var int16Tag = '[object Int16Array]';
17961 var int32Tag = '[object Int32Array]';
17962 var uint8Tag = '[object Uint8Array]';
17963 var uint8ClampedTag = '[object Uint8ClampedArray]';
17964 var uint16Tag = '[object Uint16Array]';
17965 var uint32Tag = '[object Uint32Array]';
17966
17967 /** Used to identify `toStringTag` values of typed arrays. */
17968 var typedArrayTags = {};
17969 typedArrayTags[float32Tag] = typedArrayTags[float64Tag] =
17970 typedArrayTags[int8Tag] = typedArrayTags[int16Tag] =
17971 typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] =
17972 typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] =
17973 typedArrayTags[uint32Tag] = true;
17974 typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] =
17975 typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] =
17976 typedArrayTags[dataViewTag] = typedArrayTags[dateTag] =
17977 typedArrayTags[errorTag] = typedArrayTags[funcTag$1] =
17978 typedArrayTags[mapTag] = typedArrayTags[numberTag] =
17979 typedArrayTags[objectTag] = typedArrayTags[regexpTag] =
17980 typedArrayTags[setTag] = typedArrayTags[stringTag] =
17981 typedArrayTags[weakMapTag] = false;
17982
17983 /**
17984  * The base implementation of `_.isTypedArray` without Node.js optimizations.
17985  *
17986  * @private
17987  * @param {*} value The value to check.
17988  * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
17989  */
17990 function baseIsTypedArray(value) {
17991   return isObjectLike(value) &&
17992     isLength(value.length) && !!typedArrayTags[baseGetTag(value)];
17993 }
17994
17995 /**
17996  * The base implementation of `_.unary` without support for storing metadata.
17997  *
17998  * @private
17999  * @param {Function} func The function to cap arguments for.
18000  * @returns {Function} Returns the new capped function.
18001  */
18002 function baseUnary(func) {
18003   return function(value) {
18004     return func(value);
18005   };
18006 }
18007
18008 /** Detect free variable `exports`. */
18009 var freeExports$1 = typeof exports == 'object' && exports && !exports.nodeType && exports;
18010
18011 /** Detect free variable `module`. */
18012 var freeModule$1 = freeExports$1 && typeof module == 'object' && module && !module.nodeType && module;
18013
18014 /** Detect the popular CommonJS extension `module.exports`. */
18015 var moduleExports$1 = freeModule$1 && freeModule$1.exports === freeExports$1;
18016
18017 /** Detect free variable `process` from Node.js. */
18018 var freeProcess = moduleExports$1 && freeGlobal.process;
18019
18020 /** Used to access faster Node.js helpers. */
18021 var nodeUtil = (function() {
18022   try {
18023     return freeProcess && freeProcess.binding && freeProcess.binding('util');
18024   } catch (e) {}
18025 }());
18026
18027 /* Node.js helper references. */
18028 var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
18029
18030 /**
18031  * Checks if `value` is classified as a typed array.
18032  *
18033  * @static
18034  * @memberOf _
18035  * @since 3.0.0
18036  * @category Lang
18037  * @param {*} value The value to check.
18038  * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
18039  * @example
18040  *
18041  * _.isTypedArray(new Uint8Array);
18042  * // => true
18043  *
18044  * _.isTypedArray([]);
18045  * // => false
18046  */
18047 var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray;
18048
18049 /** Used for built-in method references. */
18050 var objectProto$4 = Object.prototype;
18051
18052 /** Used to check objects for own properties. */
18053 var hasOwnProperty$3 = objectProto$4.hasOwnProperty;
18054
18055 /**
18056  * Creates an array of the enumerable property names of the array-like `value`.
18057  *
18058  * @private
18059  * @param {*} value The value to query.
18060  * @param {boolean} inherited Specify returning inherited property names.
18061  * @returns {Array} Returns the array of property names.
18062  */
18063 function arrayLikeKeys(value, inherited) {
18064   var isArr = isArray(value),
18065       isArg = !isArr && isArguments(value),
18066       isBuff = !isArr && !isArg && isBuffer(value),
18067       isType = !isArr && !isArg && !isBuff && isTypedArray(value),
18068       skipIndexes = isArr || isArg || isBuff || isType,
18069       result = skipIndexes ? baseTimes(value.length, String) : [],
18070       length = result.length;
18071
18072   for (var key in value) {
18073     if ((inherited || hasOwnProperty$3.call(value, key)) &&
18074         !(skipIndexes && (
18075            // Safari 9 has enumerable `arguments.length` in strict mode.
18076            key == 'length' ||
18077            // Node.js 0.10 has enumerable non-index properties on buffers.
18078            (isBuff && (key == 'offset' || key == 'parent')) ||
18079            // PhantomJS 2 has enumerable non-index properties on typed arrays.
18080            (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) ||
18081            // Skip index properties.
18082            isIndex(key, length)
18083         ))) {
18084       result.push(key);
18085     }
18086   }
18087   return result;
18088 }
18089
18090 /** Used for built-in method references. */
18091 var objectProto$7 = Object.prototype;
18092
18093 /**
18094  * Checks if `value` is likely a prototype object.
18095  *
18096  * @private
18097  * @param {*} value The value to check.
18098  * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
18099  */
18100 function isPrototype(value) {
18101   var Ctor = value && value.constructor,
18102       proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$7;
18103
18104   return value === proto;
18105 }
18106
18107 /**
18108  * This function is like
18109  * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
18110  * except that it includes inherited enumerable properties.
18111  *
18112  * @private
18113  * @param {Object} object The object to query.
18114  * @returns {Array} Returns the array of property names.
18115  */
18116 function nativeKeysIn(object) {
18117   var result = [];
18118   if (object != null) {
18119     for (var key in Object(object)) {
18120       result.push(key);
18121     }
18122   }
18123   return result;
18124 }
18125
18126 /** Used for built-in method references. */
18127 var objectProto$6 = Object.prototype;
18128
18129 /** Used to check objects for own properties. */
18130 var hasOwnProperty$5 = objectProto$6.hasOwnProperty;
18131
18132 /**
18133  * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
18134  *
18135  * @private
18136  * @param {Object} object The object to query.
18137  * @returns {Array} Returns the array of property names.
18138  */
18139 function baseKeysIn(object) {
18140   if (!isObject(object)) {
18141     return nativeKeysIn(object);
18142   }
18143   var isProto = isPrototype(object),
18144       result = [];
18145
18146   for (var key in object) {
18147     if (!(key == 'constructor' && (isProto || !hasOwnProperty$5.call(object, key)))) {
18148       result.push(key);
18149     }
18150   }
18151   return result;
18152 }
18153
18154 /**
18155  * Creates an array of the own and inherited enumerable property names of `object`.
18156  *
18157  * **Note:** Non-object values are coerced to objects.
18158  *
18159  * @static
18160  * @memberOf _
18161  * @since 3.0.0
18162  * @category Object
18163  * @param {Object} object The object to query.
18164  * @returns {Array} Returns the array of property names.
18165  * @example
18166  *
18167  * function Foo() {
18168  *   this.a = 1;
18169  *   this.b = 2;
18170  * }
18171  *
18172  * Foo.prototype.c = 3;
18173  *
18174  * _.keysIn(new Foo);
18175  * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
18176  */
18177 function keysIn$1(object) {
18178   return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object);
18179 }
18180
18181 /**
18182  * This method is like `_.assign` except that it iterates over own and
18183  * inherited source properties.
18184  *
18185  * **Note:** This method mutates `object`.
18186  *
18187  * @static
18188  * @memberOf _
18189  * @since 4.0.0
18190  * @alias extend
18191  * @category Object
18192  * @param {Object} object The destination object.
18193  * @param {...Object} [sources] The source objects.
18194  * @returns {Object} Returns `object`.
18195  * @see _.assign
18196  * @example
18197  *
18198  * function Foo() {
18199  *   this.a = 1;
18200  * }
18201  *
18202  * function Bar() {
18203  *   this.c = 3;
18204  * }
18205  *
18206  * Foo.prototype.b = 2;
18207  * Bar.prototype.d = 4;
18208  *
18209  * _.assignIn({ 'a': 0 }, new Foo, new Bar);
18210  * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 }
18211  */
18212 var assignIn = createAssigner(function(object, source) {
18213   copyObject(source, keysIn$1(source), object);
18214 });
18215
18216 /**
18217  * A specialized version of `_.filter` for arrays without support for
18218  * iteratee shorthands.
18219  *
18220  * @private
18221  * @param {Array} [array] The array to iterate over.
18222  * @param {Function} predicate The function invoked per iteration.
18223  * @returns {Array} Returns the new filtered array.
18224  */
18225 function arrayFilter(array, predicate) {
18226   var index = -1,
18227       length = array == null ? 0 : array.length,
18228       resIndex = 0,
18229       result = [];
18230
18231   while (++index < length) {
18232     var value = array[index];
18233     if (predicate(value, index, array)) {
18234       result[resIndex++] = value;
18235     }
18236   }
18237   return result;
18238 }
18239
18240 /**
18241  * Creates a base function for methods like `_.forIn` and `_.forOwn`.
18242  *
18243  * @private
18244  * @param {boolean} [fromRight] Specify iterating from right to left.
18245  * @returns {Function} Returns the new base function.
18246  */
18247 function createBaseFor(fromRight) {
18248   return function(object, iteratee, keysFunc) {
18249     var index = -1,
18250         iterable = Object(object),
18251         props = keysFunc(object),
18252         length = props.length;
18253
18254     while (length--) {
18255       var key = props[fromRight ? length : ++index];
18256       if (iteratee(iterable[key], key, iterable) === false) {
18257         break;
18258       }
18259     }
18260     return object;
18261   };
18262 }
18263
18264 /**
18265  * The base implementation of `baseForOwn` which iterates over `object`
18266  * properties returned by `keysFunc` and invokes `iteratee` for each property.
18267  * Iteratee functions may exit iteration early by explicitly returning `false`.
18268  *
18269  * @private
18270  * @param {Object} object The object to iterate over.
18271  * @param {Function} iteratee The function invoked per iteration.
18272  * @param {Function} keysFunc The function to get the keys of `object`.
18273  * @returns {Object} Returns `object`.
18274  */
18275 var baseFor = createBaseFor();
18276
18277 /**
18278  * Creates a unary function that invokes `func` with its argument transformed.
18279  *
18280  * @private
18281  * @param {Function} func The function to wrap.
18282  * @param {Function} transform The argument transform.
18283  * @returns {Function} Returns the new function.
18284  */
18285 function overArg(func, transform) {
18286   return function(arg) {
18287     return func(transform(arg));
18288   };
18289 }
18290
18291 /* Built-in method references for those with the same name as other `lodash` methods. */
18292 var nativeKeys = overArg(Object.keys, Object);
18293
18294 /** Used for built-in method references. */
18295 var objectProto$8 = Object.prototype;
18296
18297 /** Used to check objects for own properties. */
18298 var hasOwnProperty$6 = objectProto$8.hasOwnProperty;
18299
18300 /**
18301  * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
18302  *
18303  * @private
18304  * @param {Object} object The object to query.
18305  * @returns {Array} Returns the array of property names.
18306  */
18307 function baseKeys(object) {
18308   if (!isPrototype(object)) {
18309     return nativeKeys(object);
18310   }
18311   var result = [];
18312   for (var key in Object(object)) {
18313     if (hasOwnProperty$6.call(object, key) && key != 'constructor') {
18314       result.push(key);
18315     }
18316   }
18317   return result;
18318 }
18319
18320 /**
18321  * Creates an array of the own enumerable property names of `object`.
18322  *
18323  * **Note:** Non-object values are coerced to objects. See the
18324  * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
18325  * for more details.
18326  *
18327  * @static
18328  * @since 0.1.0
18329  * @memberOf _
18330  * @category Object
18331  * @param {Object} object The object to query.
18332  * @returns {Array} Returns the array of property names.
18333  * @example
18334  *
18335  * function Foo() {
18336  *   this.a = 1;
18337  *   this.b = 2;
18338  * }
18339  *
18340  * Foo.prototype.c = 3;
18341  *
18342  * _.keys(new Foo);
18343  * // => ['a', 'b'] (iteration order is not guaranteed)
18344  *
18345  * _.keys('hi');
18346  * // => ['0', '1']
18347  */
18348 function keys$1(object) {
18349   return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
18350 }
18351
18352 /**
18353  * The base implementation of `_.forOwn` without support for iteratee shorthands.
18354  *
18355  * @private
18356  * @param {Object} object The object to iterate over.
18357  * @param {Function} iteratee The function invoked per iteration.
18358  * @returns {Object} Returns `object`.
18359  */
18360 function baseForOwn(object, iteratee) {
18361   return object && baseFor(object, iteratee, keys$1);
18362 }
18363
18364 /**
18365  * Creates a `baseEach` or `baseEachRight` function.
18366  *
18367  * @private
18368  * @param {Function} eachFunc The function to iterate over a collection.
18369  * @param {boolean} [fromRight] Specify iterating from right to left.
18370  * @returns {Function} Returns the new base function.
18371  */
18372 function createBaseEach(eachFunc, fromRight) {
18373   return function(collection, iteratee) {
18374     if (collection == null) {
18375       return collection;
18376     }
18377     if (!isArrayLike(collection)) {
18378       return eachFunc(collection, iteratee);
18379     }
18380     var length = collection.length,
18381         index = fromRight ? length : -1,
18382         iterable = Object(collection);
18383
18384     while ((fromRight ? index-- : ++index < length)) {
18385       if (iteratee(iterable[index], index, iterable) === false) {
18386         break;
18387       }
18388     }
18389     return collection;
18390   };
18391 }
18392
18393 /**
18394  * The base implementation of `_.forEach` without support for iteratee shorthands.
18395  *
18396  * @private
18397  * @param {Array|Object} collection The collection to iterate over.
18398  * @param {Function} iteratee The function invoked per iteration.
18399  * @returns {Array|Object} Returns `collection`.
18400  */
18401 var baseEach = createBaseEach(baseForOwn);
18402
18403 /**
18404  * The base implementation of `_.filter` without support for iteratee shorthands.
18405  *
18406  * @private
18407  * @param {Array|Object} collection The collection to iterate over.
18408  * @param {Function} predicate The function invoked per iteration.
18409  * @returns {Array} Returns the new filtered array.
18410  */
18411 function baseFilter(collection, predicate) {
18412   var result = [];
18413   baseEach(collection, function(value, index, collection) {
18414     if (predicate(value, index, collection)) {
18415       result.push(value);
18416     }
18417   });
18418   return result;
18419 }
18420
18421 /**
18422  * Removes all key-value entries from the list cache.
18423  *
18424  * @private
18425  * @name clear
18426  * @memberOf ListCache
18427  */
18428 function listCacheClear() {
18429   this.__data__ = [];
18430   this.size = 0;
18431 }
18432
18433 /**
18434  * Gets the index at which the `key` is found in `array` of key-value pairs.
18435  *
18436  * @private
18437  * @param {Array} array The array to inspect.
18438  * @param {*} key The key to search for.
18439  * @returns {number} Returns the index of the matched value, else `-1`.
18440  */
18441 function assocIndexOf(array, key) {
18442   var length = array.length;
18443   while (length--) {
18444     if (eq(array[length][0], key)) {
18445       return length;
18446     }
18447   }
18448   return -1;
18449 }
18450
18451 /** Used for built-in method references. */
18452 var arrayProto = Array.prototype;
18453
18454 /** Built-in value references. */
18455 var splice = arrayProto.splice;
18456
18457 /**
18458  * Removes `key` and its value from the list cache.
18459  *
18460  * @private
18461  * @name delete
18462  * @memberOf ListCache
18463  * @param {string} key The key of the value to remove.
18464  * @returns {boolean} Returns `true` if the entry was removed, else `false`.
18465  */
18466 function listCacheDelete(key) {
18467   var data = this.__data__,
18468       index = assocIndexOf(data, key);
18469
18470   if (index < 0) {
18471     return false;
18472   }
18473   var lastIndex = data.length - 1;
18474   if (index == lastIndex) {
18475     data.pop();
18476   } else {
18477     splice.call(data, index, 1);
18478   }
18479   --this.size;
18480   return true;
18481 }
18482
18483 /**
18484  * Gets the list cache value for `key`.
18485  *
18486  * @private
18487  * @name get
18488  * @memberOf ListCache
18489  * @param {string} key The key of the value to get.
18490  * @returns {*} Returns the entry value.
18491  */
18492 function listCacheGet(key) {
18493   var data = this.__data__,
18494       index = assocIndexOf(data, key);
18495
18496   return index < 0 ? undefined : data[index][1];
18497 }
18498
18499 /**
18500  * Checks if a list cache value for `key` exists.
18501  *
18502  * @private
18503  * @name has
18504  * @memberOf ListCache
18505  * @param {string} key The key of the entry to check.
18506  * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
18507  */
18508 function listCacheHas(key) {
18509   return assocIndexOf(this.__data__, key) > -1;
18510 }
18511
18512 /**
18513  * Sets the list cache `key` to `value`.
18514  *
18515  * @private
18516  * @name set
18517  * @memberOf ListCache
18518  * @param {string} key The key of the value to set.
18519  * @param {*} value The value to set.
18520  * @returns {Object} Returns the list cache instance.
18521  */
18522 function listCacheSet(key, value) {
18523   var data = this.__data__,
18524       index = assocIndexOf(data, key);
18525
18526   if (index < 0) {
18527     ++this.size;
18528     data.push([key, value]);
18529   } else {
18530     data[index][1] = value;
18531   }
18532   return this;
18533 }
18534
18535 /**
18536  * Creates an list cache object.
18537  *
18538  * @private
18539  * @constructor
18540  * @param {Array} [entries] The key-value pairs to cache.
18541  */
18542 function ListCache(entries) {
18543   var index = -1,
18544       length = entries == null ? 0 : entries.length;
18545
18546   this.clear();
18547   while (++index < length) {
18548     var entry = entries[index];
18549     this.set(entry[0], entry[1]);
18550   }
18551 }
18552
18553 // Add methods to `ListCache`.
18554 ListCache.prototype.clear = listCacheClear;
18555 ListCache.prototype['delete'] = listCacheDelete;
18556 ListCache.prototype.get = listCacheGet;
18557 ListCache.prototype.has = listCacheHas;
18558 ListCache.prototype.set = listCacheSet;
18559
18560 /**
18561  * Removes all key-value entries from the stack.
18562  *
18563  * @private
18564  * @name clear
18565  * @memberOf Stack
18566  */
18567 function stackClear() {
18568   this.__data__ = new ListCache;
18569   this.size = 0;
18570 }
18571
18572 /**
18573  * Removes `key` and its value from the stack.
18574  *
18575  * @private
18576  * @name delete
18577  * @memberOf Stack
18578  * @param {string} key The key of the value to remove.
18579  * @returns {boolean} Returns `true` if the entry was removed, else `false`.
18580  */
18581 function stackDelete(key) {
18582   var data = this.__data__,
18583       result = data['delete'](key);
18584
18585   this.size = data.size;
18586   return result;
18587 }
18588
18589 /**
18590  * Gets the stack value for `key`.
18591  *
18592  * @private
18593  * @name get
18594  * @memberOf Stack
18595  * @param {string} key The key of the value to get.
18596  * @returns {*} Returns the entry value.
18597  */
18598 function stackGet(key) {
18599   return this.__data__.get(key);
18600 }
18601
18602 /**
18603  * Checks if a stack value for `key` exists.
18604  *
18605  * @private
18606  * @name has
18607  * @memberOf Stack
18608  * @param {string} key The key of the entry to check.
18609  * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
18610  */
18611 function stackHas(key) {
18612   return this.__data__.has(key);
18613 }
18614
18615 /* Built-in method references that are verified to be native. */
18616 var Map$1 = getNative(root$2, 'Map');
18617
18618 /* Built-in method references that are verified to be native. */
18619 var nativeCreate = getNative(Object, 'create');
18620
18621 /**
18622  * Removes all key-value entries from the hash.
18623  *
18624  * @private
18625  * @name clear
18626  * @memberOf Hash
18627  */
18628 function hashClear() {
18629   this.__data__ = nativeCreate ? nativeCreate(null) : {};
18630   this.size = 0;
18631 }
18632
18633 /**
18634  * Removes `key` and its value from the hash.
18635  *
18636  * @private
18637  * @name delete
18638  * @memberOf Hash
18639  * @param {Object} hash The hash to modify.
18640  * @param {string} key The key of the value to remove.
18641  * @returns {boolean} Returns `true` if the entry was removed, else `false`.
18642  */
18643 function hashDelete(key) {
18644   var result = this.has(key) && delete this.__data__[key];
18645   this.size -= result ? 1 : 0;
18646   return result;
18647 }
18648
18649 /** Used to stand-in for `undefined` hash values. */
18650 var HASH_UNDEFINED = '__lodash_hash_undefined__';
18651
18652 /** Used for built-in method references. */
18653 var objectProto$9 = Object.prototype;
18654
18655 /** Used to check objects for own properties. */
18656 var hasOwnProperty$7 = objectProto$9.hasOwnProperty;
18657
18658 /**
18659  * Gets the hash value for `key`.
18660  *
18661  * @private
18662  * @name get
18663  * @memberOf Hash
18664  * @param {string} key The key of the value to get.
18665  * @returns {*} Returns the entry value.
18666  */
18667 function hashGet(key) {
18668   var data = this.__data__;
18669   if (nativeCreate) {
18670     var result = data[key];
18671     return result === HASH_UNDEFINED ? undefined : result;
18672   }
18673   return hasOwnProperty$7.call(data, key) ? data[key] : undefined;
18674 }
18675
18676 /** Used for built-in method references. */
18677 var objectProto$10 = Object.prototype;
18678
18679 /** Used to check objects for own properties. */
18680 var hasOwnProperty$8 = objectProto$10.hasOwnProperty;
18681
18682 /**
18683  * Checks if a hash value for `key` exists.
18684  *
18685  * @private
18686  * @name has
18687  * @memberOf Hash
18688  * @param {string} key The key of the entry to check.
18689  * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
18690  */
18691 function hashHas(key) {
18692   var data = this.__data__;
18693   return nativeCreate ? (data[key] !== undefined) : hasOwnProperty$8.call(data, key);
18694 }
18695
18696 /** Used to stand-in for `undefined` hash values. */
18697 var HASH_UNDEFINED$1 = '__lodash_hash_undefined__';
18698
18699 /**
18700  * Sets the hash `key` to `value`.
18701  *
18702  * @private
18703  * @name set
18704  * @memberOf Hash
18705  * @param {string} key The key of the value to set.
18706  * @param {*} value The value to set.
18707  * @returns {Object} Returns the hash instance.
18708  */
18709 function hashSet(key, value) {
18710   var data = this.__data__;
18711   this.size += this.has(key) ? 0 : 1;
18712   data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED$1 : value;
18713   return this;
18714 }
18715
18716 /**
18717  * Creates a hash object.
18718  *
18719  * @private
18720  * @constructor
18721  * @param {Array} [entries] The key-value pairs to cache.
18722  */
18723 function Hash(entries) {
18724   var index = -1,
18725       length = entries == null ? 0 : entries.length;
18726
18727   this.clear();
18728   while (++index < length) {
18729     var entry = entries[index];
18730     this.set(entry[0], entry[1]);
18731   }
18732 }
18733
18734 // Add methods to `Hash`.
18735 Hash.prototype.clear = hashClear;
18736 Hash.prototype['delete'] = hashDelete;
18737 Hash.prototype.get = hashGet;
18738 Hash.prototype.has = hashHas;
18739 Hash.prototype.set = hashSet;
18740
18741 /**
18742  * Removes all key-value entries from the map.
18743  *
18744  * @private
18745  * @name clear
18746  * @memberOf MapCache
18747  */
18748 function mapCacheClear() {
18749   this.size = 0;
18750   this.__data__ = {
18751     'hash': new Hash,
18752     'map': new (Map$1 || ListCache),
18753     'string': new Hash
18754   };
18755 }
18756
18757 /**
18758  * Checks if `value` is suitable for use as unique object key.
18759  *
18760  * @private
18761  * @param {*} value The value to check.
18762  * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
18763  */
18764 function isKeyable(value) {
18765   var type = typeof value;
18766   return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
18767     ? (value !== '__proto__')
18768     : (value === null);
18769 }
18770
18771 /**
18772  * Gets the data for `map`.
18773  *
18774  * @private
18775  * @param {Object} map The map to query.
18776  * @param {string} key The reference key.
18777  * @returns {*} Returns the map data.
18778  */
18779 function getMapData(map, key) {
18780   var data = map.__data__;
18781   return isKeyable(key)
18782     ? data[typeof key == 'string' ? 'string' : 'hash']
18783     : data.map;
18784 }
18785
18786 /**
18787  * Removes `key` and its value from the map.
18788  *
18789  * @private
18790  * @name delete
18791  * @memberOf MapCache
18792  * @param {string} key The key of the value to remove.
18793  * @returns {boolean} Returns `true` if the entry was removed, else `false`.
18794  */
18795 function mapCacheDelete(key) {
18796   var result = getMapData(this, key)['delete'](key);
18797   this.size -= result ? 1 : 0;
18798   return result;
18799 }
18800
18801 /**
18802  * Gets the map value for `key`.
18803  *
18804  * @private
18805  * @name get
18806  * @memberOf MapCache
18807  * @param {string} key The key of the value to get.
18808  * @returns {*} Returns the entry value.
18809  */
18810 function mapCacheGet(key) {
18811   return getMapData(this, key).get(key);
18812 }
18813
18814 /**
18815  * Checks if a map value for `key` exists.
18816  *
18817  * @private
18818  * @name has
18819  * @memberOf MapCache
18820  * @param {string} key The key of the entry to check.
18821  * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
18822  */
18823 function mapCacheHas(key) {
18824   return getMapData(this, key).has(key);
18825 }
18826
18827 /**
18828  * Sets the map `key` to `value`.
18829  *
18830  * @private
18831  * @name set
18832  * @memberOf MapCache
18833  * @param {string} key The key of the value to set.
18834  * @param {*} value The value to set.
18835  * @returns {Object} Returns the map cache instance.
18836  */
18837 function mapCacheSet(key, value) {
18838   var data = getMapData(this, key),
18839       size = data.size;
18840
18841   data.set(key, value);
18842   this.size += data.size == size ? 0 : 1;
18843   return this;
18844 }
18845
18846 /**
18847  * Creates a map cache object to store key-value pairs.
18848  *
18849  * @private
18850  * @constructor
18851  * @param {Array} [entries] The key-value pairs to cache.
18852  */
18853 function MapCache(entries) {
18854   var index = -1,
18855       length = entries == null ? 0 : entries.length;
18856
18857   this.clear();
18858   while (++index < length) {
18859     var entry = entries[index];
18860     this.set(entry[0], entry[1]);
18861   }
18862 }
18863
18864 // Add methods to `MapCache`.
18865 MapCache.prototype.clear = mapCacheClear;
18866 MapCache.prototype['delete'] = mapCacheDelete;
18867 MapCache.prototype.get = mapCacheGet;
18868 MapCache.prototype.has = mapCacheHas;
18869 MapCache.prototype.set = mapCacheSet;
18870
18871 /** Used as the size to enable large array optimizations. */
18872 var LARGE_ARRAY_SIZE = 200;
18873
18874 /**
18875  * Sets the stack `key` to `value`.
18876  *
18877  * @private
18878  * @name set
18879  * @memberOf Stack
18880  * @param {string} key The key of the value to set.
18881  * @param {*} value The value to set.
18882  * @returns {Object} Returns the stack cache instance.
18883  */
18884 function stackSet(key, value) {
18885   var data = this.__data__;
18886   if (data instanceof ListCache) {
18887     var pairs = data.__data__;
18888     if (!Map$1 || (pairs.length < LARGE_ARRAY_SIZE - 1)) {
18889       pairs.push([key, value]);
18890       this.size = ++data.size;
18891       return this;
18892     }
18893     data = this.__data__ = new MapCache(pairs);
18894   }
18895   data.set(key, value);
18896   this.size = data.size;
18897   return this;
18898 }
18899
18900 /**
18901  * Creates a stack cache object to store key-value pairs.
18902  *
18903  * @private
18904  * @constructor
18905  * @param {Array} [entries] The key-value pairs to cache.
18906  */
18907 function Stack(entries) {
18908   var data = this.__data__ = new ListCache(entries);
18909   this.size = data.size;
18910 }
18911
18912 // Add methods to `Stack`.
18913 Stack.prototype.clear = stackClear;
18914 Stack.prototype['delete'] = stackDelete;
18915 Stack.prototype.get = stackGet;
18916 Stack.prototype.has = stackHas;
18917 Stack.prototype.set = stackSet;
18918
18919 /** Used to stand-in for `undefined` hash values. */
18920 var HASH_UNDEFINED$2 = '__lodash_hash_undefined__';
18921
18922 /**
18923  * Adds `value` to the array cache.
18924  *
18925  * @private
18926  * @name add
18927  * @memberOf SetCache
18928  * @alias push
18929  * @param {*} value The value to cache.
18930  * @returns {Object} Returns the cache instance.
18931  */
18932 function setCacheAdd(value) {
18933   this.__data__.set(value, HASH_UNDEFINED$2);
18934   return this;
18935 }
18936
18937 /**
18938  * Checks if `value` is in the array cache.
18939  *
18940  * @private
18941  * @name has
18942  * @memberOf SetCache
18943  * @param {*} value The value to search for.
18944  * @returns {number} Returns `true` if `value` is found, else `false`.
18945  */
18946 function setCacheHas(value) {
18947   return this.__data__.has(value);
18948 }
18949
18950 /**
18951  *
18952  * Creates an array cache object to store unique values.
18953  *
18954  * @private
18955  * @constructor
18956  * @param {Array} [values] The values to cache.
18957  */
18958 function SetCache(values) {
18959   var index = -1,
18960       length = values == null ? 0 : values.length;
18961
18962   this.__data__ = new MapCache;
18963   while (++index < length) {
18964     this.add(values[index]);
18965   }
18966 }
18967
18968 // Add methods to `SetCache`.
18969 SetCache.prototype.add = SetCache.prototype.push = setCacheAdd;
18970 SetCache.prototype.has = setCacheHas;
18971
18972 /**
18973  * A specialized version of `_.some` for arrays without support for iteratee
18974  * shorthands.
18975  *
18976  * @private
18977  * @param {Array} [array] The array to iterate over.
18978  * @param {Function} predicate The function invoked per iteration.
18979  * @returns {boolean} Returns `true` if any element passes the predicate check,
18980  *  else `false`.
18981  */
18982 function arraySome(array, predicate) {
18983   var index = -1,
18984       length = array == null ? 0 : array.length;
18985
18986   while (++index < length) {
18987     if (predicate(array[index], index, array)) {
18988       return true;
18989     }
18990   }
18991   return false;
18992 }
18993
18994 /**
18995  * Checks if a `cache` value for `key` exists.
18996  *
18997  * @private
18998  * @param {Object} cache The cache to query.
18999  * @param {string} key The key of the entry to check.
19000  * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
19001  */
19002 function cacheHas(cache, key) {
19003   return cache.has(key);
19004 }
19005
19006 /** Used to compose bitmasks for value comparisons. */
19007 var COMPARE_PARTIAL_FLAG$2 = 1;
19008 var COMPARE_UNORDERED_FLAG$1 = 2;
19009
19010 /**
19011  * A specialized version of `baseIsEqualDeep` for arrays with support for
19012  * partial deep comparisons.
19013  *
19014  * @private
19015  * @param {Array} array The array to compare.
19016  * @param {Array} other The other array to compare.
19017  * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
19018  * @param {Function} customizer The function to customize comparisons.
19019  * @param {Function} equalFunc The function to determine equivalents of values.
19020  * @param {Object} stack Tracks traversed `array` and `other` objects.
19021  * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
19022  */
19023 function equalArrays(array, other, bitmask, customizer, equalFunc, stack) {
19024   var isPartial = bitmask & COMPARE_PARTIAL_FLAG$2,
19025       arrLength = array.length,
19026       othLength = other.length;
19027
19028   if (arrLength != othLength && !(isPartial && othLength > arrLength)) {
19029     return false;
19030   }
19031   // Assume cyclic values are equal.
19032   var stacked = stack.get(array);
19033   if (stacked && stack.get(other)) {
19034     return stacked == other;
19035   }
19036   var index = -1,
19037       result = true,
19038       seen = (bitmask & COMPARE_UNORDERED_FLAG$1) ? new SetCache : undefined;
19039
19040   stack.set(array, other);
19041   stack.set(other, array);
19042
19043   // Ignore non-index properties.
19044   while (++index < arrLength) {
19045     var arrValue = array[index],
19046         othValue = other[index];
19047
19048     if (customizer) {
19049       var compared = isPartial
19050         ? customizer(othValue, arrValue, index, other, array, stack)
19051         : customizer(arrValue, othValue, index, array, other, stack);
19052     }
19053     if (compared !== undefined) {
19054       if (compared) {
19055         continue;
19056       }
19057       result = false;
19058       break;
19059     }
19060     // Recursively compare arrays (susceptible to call stack limits).
19061     if (seen) {
19062       if (!arraySome(other, function(othValue, othIndex) {
19063             if (!cacheHas(seen, othIndex) &&
19064                 (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {
19065               return seen.push(othIndex);
19066             }
19067           })) {
19068         result = false;
19069         break;
19070       }
19071     } else if (!(
19072           arrValue === othValue ||
19073             equalFunc(arrValue, othValue, bitmask, customizer, stack)
19074         )) {
19075       result = false;
19076       break;
19077     }
19078   }
19079   stack['delete'](array);
19080   stack['delete'](other);
19081   return result;
19082 }
19083
19084 /** Built-in value references. */
19085 var Uint8Array = root$2.Uint8Array;
19086
19087 /**
19088  * Converts `map` to its key-value pairs.
19089  *
19090  * @private
19091  * @param {Object} map The map to convert.
19092  * @returns {Array} Returns the key-value pairs.
19093  */
19094 function mapToArray(map) {
19095   var index = -1,
19096       result = Array(map.size);
19097
19098   map.forEach(function(value, key) {
19099     result[++index] = [key, value];
19100   });
19101   return result;
19102 }
19103
19104 /**
19105  * Converts `set` to an array of its values.
19106  *
19107  * @private
19108  * @param {Object} set The set to convert.
19109  * @returns {Array} Returns the values.
19110  */
19111 function setToArray(set) {
19112   var index = -1,
19113       result = Array(set.size);
19114
19115   set.forEach(function(value) {
19116     result[++index] = value;
19117   });
19118   return result;
19119 }
19120
19121 /** Used to compose bitmasks for value comparisons. */
19122 var COMPARE_PARTIAL_FLAG$3 = 1;
19123 var COMPARE_UNORDERED_FLAG$2 = 2;
19124
19125 /** `Object#toString` result references. */
19126 var boolTag$1 = '[object Boolean]';
19127 var dateTag$1 = '[object Date]';
19128 var errorTag$1 = '[object Error]';
19129 var mapTag$1 = '[object Map]';
19130 var numberTag$1 = '[object Number]';
19131 var regexpTag$1 = '[object RegExp]';
19132 var setTag$1 = '[object Set]';
19133 var stringTag$1 = '[object String]';
19134 var symbolTag = '[object Symbol]';
19135
19136 var arrayBufferTag$1 = '[object ArrayBuffer]';
19137 var dataViewTag$1 = '[object DataView]';
19138
19139 /** Used to convert symbols to primitives and strings. */
19140 var symbolProto = Symbol ? Symbol.prototype : undefined;
19141 var symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;
19142
19143 /**
19144  * A specialized version of `baseIsEqualDeep` for comparing objects of
19145  * the same `toStringTag`.
19146  *
19147  * **Note:** This function only supports comparing values with tags of
19148  * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
19149  *
19150  * @private
19151  * @param {Object} object The object to compare.
19152  * @param {Object} other The other object to compare.
19153  * @param {string} tag The `toStringTag` of the objects to compare.
19154  * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
19155  * @param {Function} customizer The function to customize comparisons.
19156  * @param {Function} equalFunc The function to determine equivalents of values.
19157  * @param {Object} stack Tracks traversed `object` and `other` objects.
19158  * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
19159  */
19160 function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {
19161   switch (tag) {
19162     case dataViewTag$1:
19163       if ((object.byteLength != other.byteLength) ||
19164           (object.byteOffset != other.byteOffset)) {
19165         return false;
19166       }
19167       object = object.buffer;
19168       other = other.buffer;
19169
19170     case arrayBufferTag$1:
19171       if ((object.byteLength != other.byteLength) ||
19172           !equalFunc(new Uint8Array(object), new Uint8Array(other))) {
19173         return false;
19174       }
19175       return true;
19176
19177     case boolTag$1:
19178     case dateTag$1:
19179     case numberTag$1:
19180       // Coerce booleans to `1` or `0` and dates to milliseconds.
19181       // Invalid dates are coerced to `NaN`.
19182       return eq(+object, +other);
19183
19184     case errorTag$1:
19185       return object.name == other.name && object.message == other.message;
19186
19187     case regexpTag$1:
19188     case stringTag$1:
19189       // Coerce regexes to strings and treat strings, primitives and objects,
19190       // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring
19191       // for more details.
19192       return object == (other + '');
19193
19194     case mapTag$1:
19195       var convert = mapToArray;
19196
19197     case setTag$1:
19198       var isPartial = bitmask & COMPARE_PARTIAL_FLAG$3;
19199       convert || (convert = setToArray);
19200
19201       if (object.size != other.size && !isPartial) {
19202         return false;
19203       }
19204       // Assume cyclic values are equal.
19205       var stacked = stack.get(object);
19206       if (stacked) {
19207         return stacked == other;
19208       }
19209       bitmask |= COMPARE_UNORDERED_FLAG$2;
19210
19211       // Recursively compare objects (susceptible to call stack limits).
19212       stack.set(object, other);
19213       var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);
19214       stack['delete'](object);
19215       return result;
19216
19217     case symbolTag:
19218       if (symbolValueOf) {
19219         return symbolValueOf.call(object) == symbolValueOf.call(other);
19220       }
19221   }
19222   return false;
19223 }
19224
19225 /**
19226  * Appends the elements of `values` to `array`.
19227  *
19228  * @private
19229  * @param {Array} array The array to modify.
19230  * @param {Array} values The values to append.
19231  * @returns {Array} Returns `array`.
19232  */
19233 function arrayPush(array, values) {
19234   var index = -1,
19235       length = values.length,
19236       offset = array.length;
19237
19238   while (++index < length) {
19239     array[offset + index] = values[index];
19240   }
19241   return array;
19242 }
19243
19244 /**
19245  * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
19246  * `keysFunc` and `symbolsFunc` to get the enumerable property names and
19247  * symbols of `object`.
19248  *
19249  * @private
19250  * @param {Object} object The object to query.
19251  * @param {Function} keysFunc The function to get the keys of `object`.
19252  * @param {Function} symbolsFunc The function to get the symbols of `object`.
19253  * @returns {Array} Returns the array of property names and symbols.
19254  */
19255 function baseGetAllKeys(object, keysFunc, symbolsFunc) {
19256   var result = keysFunc(object);
19257   return isArray(object) ? result : arrayPush(result, symbolsFunc(object));
19258 }
19259
19260 /**
19261  * This method returns a new empty array.
19262  *
19263  * @static
19264  * @memberOf _
19265  * @since 4.13.0
19266  * @category Util
19267  * @returns {Array} Returns the new empty array.
19268  * @example
19269  *
19270  * var arrays = _.times(2, _.stubArray);
19271  *
19272  * console.log(arrays);
19273  * // => [[], []]
19274  *
19275  * console.log(arrays[0] === arrays[1]);
19276  * // => false
19277  */
19278 function stubArray() {
19279   return [];
19280 }
19281
19282 /** Used for built-in method references. */
19283 var objectProto$13 = Object.prototype;
19284
19285 /** Built-in value references. */
19286 var propertyIsEnumerable$1 = objectProto$13.propertyIsEnumerable;
19287
19288 /* Built-in method references for those with the same name as other `lodash` methods. */
19289 var nativeGetSymbols = Object.getOwnPropertySymbols;
19290
19291 /**
19292  * Creates an array of the own enumerable symbols of `object`.
19293  *
19294  * @private
19295  * @param {Object} object The object to query.
19296  * @returns {Array} Returns the array of symbols.
19297  */
19298 var getSymbols = !nativeGetSymbols ? stubArray : function(object) {
19299   if (object == null) {
19300     return [];
19301   }
19302   object = Object(object);
19303   return arrayFilter(nativeGetSymbols(object), function(symbol) {
19304     return propertyIsEnumerable$1.call(object, symbol);
19305   });
19306 };
19307
19308 /**
19309  * Creates an array of own enumerable property names and symbols of `object`.
19310  *
19311  * @private
19312  * @param {Object} object The object to query.
19313  * @returns {Array} Returns the array of property names and symbols.
19314  */
19315 function getAllKeys(object) {
19316   return baseGetAllKeys(object, keys$1, getSymbols);
19317 }
19318
19319 /** Used to compose bitmasks for value comparisons. */
19320 var COMPARE_PARTIAL_FLAG$4 = 1;
19321
19322 /** Used for built-in method references. */
19323 var objectProto$12 = Object.prototype;
19324
19325 /** Used to check objects for own properties. */
19326 var hasOwnProperty$10 = objectProto$12.hasOwnProperty;
19327
19328 /**
19329  * A specialized version of `baseIsEqualDeep` for objects with support for
19330  * partial deep comparisons.
19331  *
19332  * @private
19333  * @param {Object} object The object to compare.
19334  * @param {Object} other The other object to compare.
19335  * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
19336  * @param {Function} customizer The function to customize comparisons.
19337  * @param {Function} equalFunc The function to determine equivalents of values.
19338  * @param {Object} stack Tracks traversed `object` and `other` objects.
19339  * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
19340  */
19341 function equalObjects(object, other, bitmask, customizer, equalFunc, stack) {
19342   var isPartial = bitmask & COMPARE_PARTIAL_FLAG$4,
19343       objProps = getAllKeys(object),
19344       objLength = objProps.length,
19345       othProps = getAllKeys(other),
19346       othLength = othProps.length;
19347
19348   if (objLength != othLength && !isPartial) {
19349     return false;
19350   }
19351   var index = objLength;
19352   while (index--) {
19353     var key = objProps[index];
19354     if (!(isPartial ? key in other : hasOwnProperty$10.call(other, key))) {
19355       return false;
19356     }
19357   }
19358   // Assume cyclic values are equal.
19359   var stacked = stack.get(object);
19360   if (stacked && stack.get(other)) {
19361     return stacked == other;
19362   }
19363   var result = true;
19364   stack.set(object, other);
19365   stack.set(other, object);
19366
19367   var skipCtor = isPartial;
19368   while (++index < objLength) {
19369     key = objProps[index];
19370     var objValue = object[key],
19371         othValue = other[key];
19372
19373     if (customizer) {
19374       var compared = isPartial
19375         ? customizer(othValue, objValue, key, other, object, stack)
19376         : customizer(objValue, othValue, key, object, other, stack);
19377     }
19378     // Recursively compare objects (susceptible to call stack limits).
19379     if (!(compared === undefined
19380           ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))
19381           : compared
19382         )) {
19383       result = false;
19384       break;
19385     }
19386     skipCtor || (skipCtor = key == 'constructor');
19387   }
19388   if (result && !skipCtor) {
19389     var objCtor = object.constructor,
19390         othCtor = other.constructor;
19391
19392     // Non `Object` object instances with different constructors are not equal.
19393     if (objCtor != othCtor &&
19394         ('constructor' in object && 'constructor' in other) &&
19395         !(typeof objCtor == 'function' && objCtor instanceof objCtor &&
19396           typeof othCtor == 'function' && othCtor instanceof othCtor)) {
19397       result = false;
19398     }
19399   }
19400   stack['delete'](object);
19401   stack['delete'](other);
19402   return result;
19403 }
19404
19405 /* Built-in method references that are verified to be native. */
19406 var DataView = getNative(root$2, 'DataView');
19407
19408 /* Built-in method references that are verified to be native. */
19409 var Promise = getNative(root$2, 'Promise');
19410
19411 /* Built-in method references that are verified to be native. */
19412 var Set$1 = getNative(root$2, 'Set');
19413
19414 /* Built-in method references that are verified to be native. */
19415 var WeakMap = getNative(root$2, 'WeakMap');
19416
19417 /** `Object#toString` result references. */
19418 var mapTag$2 = '[object Map]';
19419 var objectTag$2 = '[object Object]';
19420 var promiseTag = '[object Promise]';
19421 var setTag$2 = '[object Set]';
19422 var weakMapTag$1 = '[object WeakMap]';
19423
19424 var dataViewTag$2 = '[object DataView]';
19425
19426 /** Used to detect maps, sets, and weakmaps. */
19427 var dataViewCtorString = toSource(DataView);
19428 var mapCtorString = toSource(Map$1);
19429 var promiseCtorString = toSource(Promise);
19430 var setCtorString = toSource(Set$1);
19431 var weakMapCtorString = toSource(WeakMap);
19432
19433 /**
19434  * Gets the `toStringTag` of `value`.
19435  *
19436  * @private
19437  * @param {*} value The value to query.
19438  * @returns {string} Returns the `toStringTag`.
19439  */
19440 var getTag = baseGetTag;
19441
19442 // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
19443 if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag$2) ||
19444     (Map$1 && getTag(new Map$1) != mapTag$2) ||
19445     (Promise && getTag(Promise.resolve()) != promiseTag) ||
19446     (Set$1 && getTag(new Set$1) != setTag$2) ||
19447     (WeakMap && getTag(new WeakMap) != weakMapTag$1)) {
19448   getTag = function(value) {
19449     var result = baseGetTag(value),
19450         Ctor = result == objectTag$2 ? value.constructor : undefined,
19451         ctorString = Ctor ? toSource(Ctor) : '';
19452
19453     if (ctorString) {
19454       switch (ctorString) {
19455         case dataViewCtorString: return dataViewTag$2;
19456         case mapCtorString: return mapTag$2;
19457         case promiseCtorString: return promiseTag;
19458         case setCtorString: return setTag$2;
19459         case weakMapCtorString: return weakMapTag$1;
19460       }
19461     }
19462     return result;
19463   };
19464 }
19465
19466 var getTag$1 = getTag;
19467
19468 /** Used to compose bitmasks for value comparisons. */
19469 var COMPARE_PARTIAL_FLAG$1 = 1;
19470
19471 /** `Object#toString` result references. */
19472 var argsTag$2 = '[object Arguments]';
19473 var arrayTag$1 = '[object Array]';
19474 var objectTag$1 = '[object Object]';
19475
19476 /** Used for built-in method references. */
19477 var objectProto$11 = Object.prototype;
19478
19479 /** Used to check objects for own properties. */
19480 var hasOwnProperty$9 = objectProto$11.hasOwnProperty;
19481
19482 /**
19483  * A specialized version of `baseIsEqual` for arrays and objects which performs
19484  * deep comparisons and tracks traversed objects enabling objects with circular
19485  * references to be compared.
19486  *
19487  * @private
19488  * @param {Object} object The object to compare.
19489  * @param {Object} other The other object to compare.
19490  * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
19491  * @param {Function} customizer The function to customize comparisons.
19492  * @param {Function} equalFunc The function to determine equivalents of values.
19493  * @param {Object} [stack] Tracks traversed `object` and `other` objects.
19494  * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
19495  */
19496 function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {
19497   var objIsArr = isArray(object),
19498       othIsArr = isArray(other),
19499       objTag = objIsArr ? arrayTag$1 : getTag$1(object),
19500       othTag = othIsArr ? arrayTag$1 : getTag$1(other);
19501
19502   objTag = objTag == argsTag$2 ? objectTag$1 : objTag;
19503   othTag = othTag == argsTag$2 ? objectTag$1 : othTag;
19504
19505   var objIsObj = objTag == objectTag$1,
19506       othIsObj = othTag == objectTag$1,
19507       isSameTag = objTag == othTag;
19508
19509   if (isSameTag && isBuffer(object)) {
19510     if (!isBuffer(other)) {
19511       return false;
19512     }
19513     objIsArr = true;
19514     objIsObj = false;
19515   }
19516   if (isSameTag && !objIsObj) {
19517     stack || (stack = new Stack);
19518     return (objIsArr || isTypedArray(object))
19519       ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)
19520       : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);
19521   }
19522   if (!(bitmask & COMPARE_PARTIAL_FLAG$1)) {
19523     var objIsWrapped = objIsObj && hasOwnProperty$9.call(object, '__wrapped__'),
19524         othIsWrapped = othIsObj && hasOwnProperty$9.call(other, '__wrapped__');
19525
19526     if (objIsWrapped || othIsWrapped) {
19527       var objUnwrapped = objIsWrapped ? object.value() : object,
19528           othUnwrapped = othIsWrapped ? other.value() : other;
19529
19530       stack || (stack = new Stack);
19531       return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);
19532     }
19533   }
19534   if (!isSameTag) {
19535     return false;
19536   }
19537   stack || (stack = new Stack);
19538   return equalObjects(object, other, bitmask, customizer, equalFunc, stack);
19539 }
19540
19541 /**
19542  * The base implementation of `_.isEqual` which supports partial comparisons
19543  * and tracks traversed objects.
19544  *
19545  * @private
19546  * @param {*} value The value to compare.
19547  * @param {*} other The other value to compare.
19548  * @param {boolean} bitmask The bitmask flags.
19549  *  1 - Unordered comparison
19550  *  2 - Partial comparison
19551  * @param {Function} [customizer] The function to customize comparisons.
19552  * @param {Object} [stack] Tracks traversed `value` and `other` objects.
19553  * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
19554  */
19555 function baseIsEqual(value, other, bitmask, customizer, stack) {
19556   if (value === other) {
19557     return true;
19558   }
19559   if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {
19560     return value !== value && other !== other;
19561   }
19562   return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);
19563 }
19564
19565 /** Used to compose bitmasks for value comparisons. */
19566 var COMPARE_PARTIAL_FLAG = 1;
19567 var COMPARE_UNORDERED_FLAG = 2;
19568
19569 /**
19570  * The base implementation of `_.isMatch` without support for iteratee shorthands.
19571  *
19572  * @private
19573  * @param {Object} object The object to inspect.
19574  * @param {Object} source The object of property values to match.
19575  * @param {Array} matchData The property names, values, and compare flags to match.
19576  * @param {Function} [customizer] The function to customize comparisons.
19577  * @returns {boolean} Returns `true` if `object` is a match, else `false`.
19578  */
19579 function baseIsMatch(object, source, matchData, customizer) {
19580   var index = matchData.length,
19581       length = index,
19582       noCustomizer = !customizer;
19583
19584   if (object == null) {
19585     return !length;
19586   }
19587   object = Object(object);
19588   while (index--) {
19589     var data = matchData[index];
19590     if ((noCustomizer && data[2])
19591           ? data[1] !== object[data[0]]
19592           : !(data[0] in object)
19593         ) {
19594       return false;
19595     }
19596   }
19597   while (++index < length) {
19598     data = matchData[index];
19599     var key = data[0],
19600         objValue = object[key],
19601         srcValue = data[1];
19602
19603     if (noCustomizer && data[2]) {
19604       if (objValue === undefined && !(key in object)) {
19605         return false;
19606       }
19607     } else {
19608       var stack = new Stack;
19609       if (customizer) {
19610         var result = customizer(objValue, srcValue, key, object, source, stack);
19611       }
19612       if (!(result === undefined
19613             ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)
19614             : result
19615           )) {
19616         return false;
19617       }
19618     }
19619   }
19620   return true;
19621 }
19622
19623 /**
19624  * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
19625  *
19626  * @private
19627  * @param {*} value The value to check.
19628  * @returns {boolean} Returns `true` if `value` if suitable for strict
19629  *  equality comparisons, else `false`.
19630  */
19631 function isStrictComparable(value) {
19632   return value === value && !isObject(value);
19633 }
19634
19635 /**
19636  * Gets the property names, values, and compare flags of `object`.
19637  *
19638  * @private
19639  * @param {Object} object The object to query.
19640  * @returns {Array} Returns the match data of `object`.
19641  */
19642 function getMatchData(object) {
19643   var result = keys$1(object),
19644       length = result.length;
19645
19646   while (length--) {
19647     var key = result[length],
19648         value = object[key];
19649
19650     result[length] = [key, value, isStrictComparable(value)];
19651   }
19652   return result;
19653 }
19654
19655 /**
19656  * A specialized version of `matchesProperty` for source values suitable
19657  * for strict equality comparisons, i.e. `===`.
19658  *
19659  * @private
19660  * @param {string} key The key of the property to get.
19661  * @param {*} srcValue The value to match.
19662  * @returns {Function} Returns the new spec function.
19663  */
19664 function matchesStrictComparable(key, srcValue) {
19665   return function(object) {
19666     if (object == null) {
19667       return false;
19668     }
19669     return object[key] === srcValue &&
19670       (srcValue !== undefined || (key in Object(object)));
19671   };
19672 }
19673
19674 /**
19675  * The base implementation of `_.matches` which doesn't clone `source`.
19676  *
19677  * @private
19678  * @param {Object} source The object of property values to match.
19679  * @returns {Function} Returns the new spec function.
19680  */
19681 function baseMatches(source) {
19682   var matchData = getMatchData(source);
19683   if (matchData.length == 1 && matchData[0][2]) {
19684     return matchesStrictComparable(matchData[0][0], matchData[0][1]);
19685   }
19686   return function(object) {
19687     return object === source || baseIsMatch(object, source, matchData);
19688   };
19689 }
19690
19691 /** `Object#toString` result references. */
19692 var symbolTag$1 = '[object Symbol]';
19693
19694 /**
19695  * Checks if `value` is classified as a `Symbol` primitive or object.
19696  *
19697  * @static
19698  * @memberOf _
19699  * @since 4.0.0
19700  * @category Lang
19701  * @param {*} value The value to check.
19702  * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
19703  * @example
19704  *
19705  * _.isSymbol(Symbol.iterator);
19706  * // => true
19707  *
19708  * _.isSymbol('abc');
19709  * // => false
19710  */
19711 function isSymbol(value) {
19712   return typeof value == 'symbol' ||
19713     (isObjectLike(value) && baseGetTag(value) == symbolTag$1);
19714 }
19715
19716 /** Used to match property names within property paths. */
19717 var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/;
19718 var reIsPlainProp = /^\w*$/;
19719
19720 /**
19721  * Checks if `value` is a property name and not a property path.
19722  *
19723  * @private
19724  * @param {*} value The value to check.
19725  * @param {Object} [object] The object to query keys on.
19726  * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
19727  */
19728 function isKey(value, object) {
19729   if (isArray(value)) {
19730     return false;
19731   }
19732   var type = typeof value;
19733   if (type == 'number' || type == 'symbol' || type == 'boolean' ||
19734       value == null || isSymbol(value)) {
19735     return true;
19736   }
19737   return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
19738     (object != null && value in Object(object));
19739 }
19740
19741 /** Error message constants. */
19742 var FUNC_ERROR_TEXT = 'Expected a function';
19743
19744 /**
19745  * Creates a function that memoizes the result of `func`. If `resolver` is
19746  * provided, it determines the cache key for storing the result based on the
19747  * arguments provided to the memoized function. By default, the first argument
19748  * provided to the memoized function is used as the map cache key. The `func`
19749  * is invoked with the `this` binding of the memoized function.
19750  *
19751  * **Note:** The cache is exposed as the `cache` property on the memoized
19752  * function. Its creation may be customized by replacing the `_.memoize.Cache`
19753  * constructor with one whose instances implement the
19754  * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
19755  * method interface of `clear`, `delete`, `get`, `has`, and `set`.
19756  *
19757  * @static
19758  * @memberOf _
19759  * @since 0.1.0
19760  * @category Function
19761  * @param {Function} func The function to have its output memoized.
19762  * @param {Function} [resolver] The function to resolve the cache key.
19763  * @returns {Function} Returns the new memoized function.
19764  * @example
19765  *
19766  * var object = { 'a': 1, 'b': 2 };
19767  * var other = { 'c': 3, 'd': 4 };
19768  *
19769  * var values = _.memoize(_.values);
19770  * values(object);
19771  * // => [1, 2]
19772  *
19773  * values(other);
19774  * // => [3, 4]
19775  *
19776  * object.a = 2;
19777  * values(object);
19778  * // => [1, 2]
19779  *
19780  * // Modify the result cache.
19781  * values.cache.set(object, ['a', 'b']);
19782  * values(object);
19783  * // => ['a', 'b']
19784  *
19785  * // Replace `_.memoize.Cache`.
19786  * _.memoize.Cache = WeakMap;
19787  */
19788 function memoize(func, resolver) {
19789   if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
19790     throw new TypeError(FUNC_ERROR_TEXT);
19791   }
19792   var memoized = function() {
19793     var args = arguments,
19794         key = resolver ? resolver.apply(this, args) : args[0],
19795         cache = memoized.cache;
19796
19797     if (cache.has(key)) {
19798       return cache.get(key);
19799     }
19800     var result = func.apply(this, args);
19801     memoized.cache = cache.set(key, result) || cache;
19802     return result;
19803   };
19804   memoized.cache = new (memoize.Cache || MapCache);
19805   return memoized;
19806 }
19807
19808 // Expose `MapCache`.
19809 memoize.Cache = MapCache;
19810
19811 /** Used as the maximum memoize cache size. */
19812 var MAX_MEMOIZE_SIZE = 500;
19813
19814 /**
19815  * A specialized version of `_.memoize` which clears the memoized function's
19816  * cache when it exceeds `MAX_MEMOIZE_SIZE`.
19817  *
19818  * @private
19819  * @param {Function} func The function to have its output memoized.
19820  * @returns {Function} Returns the new memoized function.
19821  */
19822 function memoizeCapped(func) {
19823   var result = memoize(func, function(key) {
19824     if (cache.size === MAX_MEMOIZE_SIZE) {
19825       cache.clear();
19826     }
19827     return key;
19828   });
19829
19830   var cache = result.cache;
19831   return result;
19832 }
19833
19834 /** Used to match property names within property paths. */
19835 var reLeadingDot = /^\./;
19836 var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
19837
19838 /** Used to match backslashes in property paths. */
19839 var reEscapeChar = /\\(\\)?/g;
19840
19841 /**
19842  * Converts `string` to a property path array.
19843  *
19844  * @private
19845  * @param {string} string The string to convert.
19846  * @returns {Array} Returns the property path array.
19847  */
19848 var stringToPath = memoizeCapped(function(string) {
19849   var result = [];
19850   if (reLeadingDot.test(string)) {
19851     result.push('');
19852   }
19853   string.replace(rePropName, function(match, number, quote, string) {
19854     result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
19855   });
19856   return result;
19857 });
19858
19859 /**
19860  * A specialized version of `_.map` for arrays without support for iteratee
19861  * shorthands.
19862  *
19863  * @private
19864  * @param {Array} [array] The array to iterate over.
19865  * @param {Function} iteratee The function invoked per iteration.
19866  * @returns {Array} Returns the new mapped array.
19867  */
19868 function arrayMap(array, iteratee) {
19869   var index = -1,
19870       length = array == null ? 0 : array.length,
19871       result = Array(length);
19872
19873   while (++index < length) {
19874     result[index] = iteratee(array[index], index, array);
19875   }
19876   return result;
19877 }
19878
19879 /** Used as references for various `Number` constants. */
19880 var INFINITY = 1 / 0;
19881
19882 /** Used to convert symbols to primitives and strings. */
19883 var symbolProto$1 = Symbol ? Symbol.prototype : undefined;
19884 var symbolToString = symbolProto$1 ? symbolProto$1.toString : undefined;
19885
19886 /**
19887  * The base implementation of `_.toString` which doesn't convert nullish
19888  * values to empty strings.
19889  *
19890  * @private
19891  * @param {*} value The value to process.
19892  * @returns {string} Returns the string.
19893  */
19894 function baseToString(value) {
19895   // Exit early for strings to avoid a performance hit in some environments.
19896   if (typeof value == 'string') {
19897     return value;
19898   }
19899   if (isArray(value)) {
19900     // Recursively convert values (susceptible to call stack limits).
19901     return arrayMap(value, baseToString) + '';
19902   }
19903   if (isSymbol(value)) {
19904     return symbolToString ? symbolToString.call(value) : '';
19905   }
19906   var result = (value + '');
19907   return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
19908 }
19909
19910 /**
19911  * Converts `value` to a string. An empty string is returned for `null`
19912  * and `undefined` values. The sign of `-0` is preserved.
19913  *
19914  * @static
19915  * @memberOf _
19916  * @since 4.0.0
19917  * @category Lang
19918  * @param {*} value The value to convert.
19919  * @returns {string} Returns the converted string.
19920  * @example
19921  *
19922  * _.toString(null);
19923  * // => ''
19924  *
19925  * _.toString(-0);
19926  * // => '-0'
19927  *
19928  * _.toString([1, 2, 3]);
19929  * // => '1,2,3'
19930  */
19931 function toString(value) {
19932   return value == null ? '' : baseToString(value);
19933 }
19934
19935 /**
19936  * Casts `value` to a path array if it's not one.
19937  *
19938  * @private
19939  * @param {*} value The value to inspect.
19940  * @param {Object} [object] The object to query keys on.
19941  * @returns {Array} Returns the cast property path array.
19942  */
19943 function castPath(value, object) {
19944   if (isArray(value)) {
19945     return value;
19946   }
19947   return isKey(value, object) ? [value] : stringToPath(toString(value));
19948 }
19949
19950 /** Used as references for various `Number` constants. */
19951 var INFINITY$1 = 1 / 0;
19952
19953 /**
19954  * Converts `value` to a string key if it's not a string or symbol.
19955  *
19956  * @private
19957  * @param {*} value The value to inspect.
19958  * @returns {string|symbol} Returns the key.
19959  */
19960 function toKey(value) {
19961   if (typeof value == 'string' || isSymbol(value)) {
19962     return value;
19963   }
19964   var result = (value + '');
19965   return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result;
19966 }
19967
19968 /**
19969  * The base implementation of `_.get` without support for default values.
19970  *
19971  * @private
19972  * @param {Object} object The object to query.
19973  * @param {Array|string} path The path of the property to get.
19974  * @returns {*} Returns the resolved value.
19975  */
19976 function baseGet(object, path) {
19977   path = castPath(path, object);
19978
19979   var index = 0,
19980       length = path.length;
19981
19982   while (object != null && index < length) {
19983     object = object[toKey(path[index++])];
19984   }
19985   return (index && index == length) ? object : undefined;
19986 }
19987
19988 /**
19989  * Gets the value at `path` of `object`. If the resolved value is
19990  * `undefined`, the `defaultValue` is returned in its place.
19991  *
19992  * @static
19993  * @memberOf _
19994  * @since 3.7.0
19995  * @category Object
19996  * @param {Object} object The object to query.
19997  * @param {Array|string} path The path of the property to get.
19998  * @param {*} [defaultValue] The value returned for `undefined` resolved values.
19999  * @returns {*} Returns the resolved value.
20000  * @example
20001  *
20002  * var object = { 'a': [{ 'b': { 'c': 3 } }] };
20003  *
20004  * _.get(object, 'a[0].b.c');
20005  * // => 3
20006  *
20007  * _.get(object, ['a', '0', 'b', 'c']);
20008  * // => 3
20009  *
20010  * _.get(object, 'a.b.c', 'default');
20011  * // => 'default'
20012  */
20013 function get$2(object, path, defaultValue) {
20014   var result = object == null ? undefined : baseGet(object, path);
20015   return result === undefined ? defaultValue : result;
20016 }
20017
20018 /**
20019  * The base implementation of `_.hasIn` without support for deep paths.
20020  *
20021  * @private
20022  * @param {Object} [object] The object to query.
20023  * @param {Array|string} key The key to check.
20024  * @returns {boolean} Returns `true` if `key` exists, else `false`.
20025  */
20026 function baseHasIn(object, key) {
20027   return object != null && key in Object(object);
20028 }
20029
20030 /**
20031  * Checks if `path` exists on `object`.
20032  *
20033  * @private
20034  * @param {Object} object The object to query.
20035  * @param {Array|string} path The path to check.
20036  * @param {Function} hasFunc The function to check properties.
20037  * @returns {boolean} Returns `true` if `path` exists, else `false`.
20038  */
20039 function hasPath(object, path, hasFunc) {
20040   path = castPath(path, object);
20041
20042   var index = -1,
20043       length = path.length,
20044       result = false;
20045
20046   while (++index < length) {
20047     var key = toKey(path[index]);
20048     if (!(result = object != null && hasFunc(object, key))) {
20049       break;
20050     }
20051     object = object[key];
20052   }
20053   if (result || ++index != length) {
20054     return result;
20055   }
20056   length = object == null ? 0 : object.length;
20057   return !!length && isLength(length) && isIndex(key, length) &&
20058     (isArray(object) || isArguments(object));
20059 }
20060
20061 /**
20062  * Checks if `path` is a direct or inherited property of `object`.
20063  *
20064  * @static
20065  * @memberOf _
20066  * @since 4.0.0
20067  * @category Object
20068  * @param {Object} object The object to query.
20069  * @param {Array|string} path The path to check.
20070  * @returns {boolean} Returns `true` if `path` exists, else `false`.
20071  * @example
20072  *
20073  * var object = _.create({ 'a': _.create({ 'b': 2 }) });
20074  *
20075  * _.hasIn(object, 'a');
20076  * // => true
20077  *
20078  * _.hasIn(object, 'a.b');
20079  * // => true
20080  *
20081  * _.hasIn(object, ['a', 'b']);
20082  * // => true
20083  *
20084  * _.hasIn(object, 'b');
20085  * // => false
20086  */
20087 function hasIn(object, path) {
20088   return object != null && hasPath(object, path, baseHasIn);
20089 }
20090
20091 /** Used to compose bitmasks for value comparisons. */
20092 var COMPARE_PARTIAL_FLAG$5 = 1;
20093 var COMPARE_UNORDERED_FLAG$3 = 2;
20094
20095 /**
20096  * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
20097  *
20098  * @private
20099  * @param {string} path The path of the property to get.
20100  * @param {*} srcValue The value to match.
20101  * @returns {Function} Returns the new spec function.
20102  */
20103 function baseMatchesProperty(path, srcValue) {
20104   if (isKey(path) && isStrictComparable(srcValue)) {
20105     return matchesStrictComparable(toKey(path), srcValue);
20106   }
20107   return function(object) {
20108     var objValue = get$2(object, path);
20109     return (objValue === undefined && objValue === srcValue)
20110       ? hasIn(object, path)
20111       : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG$5 | COMPARE_UNORDERED_FLAG$3);
20112   };
20113 }
20114
20115 /**
20116  * The base implementation of `_.property` without support for deep paths.
20117  *
20118  * @private
20119  * @param {string} key The key of the property to get.
20120  * @returns {Function} Returns the new accessor function.
20121  */
20122 function baseProperty(key) {
20123   return function(object) {
20124     return object == null ? undefined : object[key];
20125   };
20126 }
20127
20128 /**
20129  * A specialized version of `baseProperty` which supports deep paths.
20130  *
20131  * @private
20132  * @param {Array|string} path The path of the property to get.
20133  * @returns {Function} Returns the new accessor function.
20134  */
20135 function basePropertyDeep(path) {
20136   return function(object) {
20137     return baseGet(object, path);
20138   };
20139 }
20140
20141 /**
20142  * Creates a function that returns the value at `path` of a given object.
20143  *
20144  * @static
20145  * @memberOf _
20146  * @since 2.4.0
20147  * @category Util
20148  * @param {Array|string} path The path of the property to get.
20149  * @returns {Function} Returns the new accessor function.
20150  * @example
20151  *
20152  * var objects = [
20153  *   { 'a': { 'b': 2 } },
20154  *   { 'a': { 'b': 1 } }
20155  * ];
20156  *
20157  * _.map(objects, _.property('a.b'));
20158  * // => [2, 1]
20159  *
20160  * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
20161  * // => [1, 2]
20162  */
20163 function property(path) {
20164   return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);
20165 }
20166
20167 /**
20168  * The base implementation of `_.iteratee`.
20169  *
20170  * @private
20171  * @param {*} [value=_.identity] The value to convert to an iteratee.
20172  * @returns {Function} Returns the iteratee.
20173  */
20174 function baseIteratee(value) {
20175   // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
20176   // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
20177   if (typeof value == 'function') {
20178     return value;
20179   }
20180   if (value == null) {
20181     return identity$8;
20182   }
20183   if (typeof value == 'object') {
20184     return isArray(value)
20185       ? baseMatchesProperty(value[0], value[1])
20186       : baseMatches(value);
20187   }
20188   return property(value);
20189 }
20190
20191 /**
20192  * Iterates over elements of `collection`, returning an array of all elements
20193  * `predicate` returns truthy for. The predicate is invoked with three
20194  * arguments: (value, index|key, collection).
20195  *
20196  * **Note:** Unlike `_.remove`, this method returns a new array.
20197  *
20198  * @static
20199  * @memberOf _
20200  * @since 0.1.0
20201  * @category Collection
20202  * @param {Array|Object} collection The collection to iterate over.
20203  * @param {Function} [predicate=_.identity] The function invoked per iteration.
20204  * @returns {Array} Returns the new filtered array.
20205  * @see _.reject
20206  * @example
20207  *
20208  * var users = [
20209  *   { 'user': 'barney', 'age': 36, 'active': true },
20210  *   { 'user': 'fred',   'age': 40, 'active': false }
20211  * ];
20212  *
20213  * _.filter(users, function(o) { return !o.active; });
20214  * // => objects for ['fred']
20215  *
20216  * // The `_.matches` iteratee shorthand.
20217  * _.filter(users, { 'age': 36, 'active': true });
20218  * // => objects for ['barney']
20219  *
20220  * // The `_.matchesProperty` iteratee shorthand.
20221  * _.filter(users, ['active', false]);
20222  * // => objects for ['fred']
20223  *
20224  * // The `_.property` iteratee shorthand.
20225  * _.filter(users, 'active');
20226  * // => objects for ['barney']
20227  */
20228 function filter(collection, predicate) {
20229   var func = isArray(collection) ? arrayFilter : baseFilter;
20230   return func(collection, baseIteratee(predicate, 3));
20231 }
20232
20233 /**
20234  * Creates a `_.find` or `_.findLast` function.
20235  *
20236  * @private
20237  * @param {Function} findIndexFunc The function to find the collection index.
20238  * @returns {Function} Returns the new find function.
20239  */
20240 function createFind(findIndexFunc) {
20241   return function(collection, predicate, fromIndex) {
20242     var iterable = Object(collection);
20243     if (!isArrayLike(collection)) {
20244       var iteratee = baseIteratee(predicate, 3);
20245       collection = keys$1(collection);
20246       predicate = function(key) { return iteratee(iterable[key], key, iterable); };
20247     }
20248     var index = findIndexFunc(collection, predicate, fromIndex);
20249     return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined;
20250   };
20251 }
20252
20253 /**
20254  * The base implementation of `_.findIndex` and `_.findLastIndex` without
20255  * support for iteratee shorthands.
20256  *
20257  * @private
20258  * @param {Array} array The array to inspect.
20259  * @param {Function} predicate The function invoked per iteration.
20260  * @param {number} fromIndex The index to search from.
20261  * @param {boolean} [fromRight] Specify iterating from right to left.
20262  * @returns {number} Returns the index of the matched value, else `-1`.
20263  */
20264 function baseFindIndex(array, predicate, fromIndex, fromRight) {
20265   var length = array.length,
20266       index = fromIndex + (fromRight ? 1 : -1);
20267
20268   while ((fromRight ? index-- : ++index < length)) {
20269     if (predicate(array[index], index, array)) {
20270       return index;
20271     }
20272   }
20273   return -1;
20274 }
20275
20276 /** Used as references for various `Number` constants. */
20277 var NAN = 0 / 0;
20278
20279 /** Used to match leading and trailing whitespace. */
20280 var reTrim = /^\s+|\s+$/g;
20281
20282 /** Used to detect bad signed hexadecimal string values. */
20283 var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
20284
20285 /** Used to detect binary string values. */
20286 var reIsBinary = /^0b[01]+$/i;
20287
20288 /** Used to detect octal string values. */
20289 var reIsOctal = /^0o[0-7]+$/i;
20290
20291 /** Built-in method references without a dependency on `root`. */
20292 var freeParseInt = parseInt;
20293
20294 /**
20295  * Converts `value` to a number.
20296  *
20297  * @static
20298  * @memberOf _
20299  * @since 4.0.0
20300  * @category Lang
20301  * @param {*} value The value to process.
20302  * @returns {number} Returns the number.
20303  * @example
20304  *
20305  * _.toNumber(3.2);
20306  * // => 3.2
20307  *
20308  * _.toNumber(Number.MIN_VALUE);
20309  * // => 5e-324
20310  *
20311  * _.toNumber(Infinity);
20312  * // => Infinity
20313  *
20314  * _.toNumber('3.2');
20315  * // => 3.2
20316  */
20317 function toNumber(value) {
20318   if (typeof value == 'number') {
20319     return value;
20320   }
20321   if (isSymbol(value)) {
20322     return NAN;
20323   }
20324   if (isObject(value)) {
20325     var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
20326     value = isObject(other) ? (other + '') : other;
20327   }
20328   if (typeof value != 'string') {
20329     return value === 0 ? value : +value;
20330   }
20331   value = value.replace(reTrim, '');
20332   var isBinary = reIsBinary.test(value);
20333   return (isBinary || reIsOctal.test(value))
20334     ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
20335     : (reIsBadHex.test(value) ? NAN : +value);
20336 }
20337
20338 /** Used as references for various `Number` constants. */
20339 var INFINITY$2 = 1 / 0;
20340 var MAX_INTEGER = 1.7976931348623157e+308;
20341
20342 /**
20343  * Converts `value` to a finite number.
20344  *
20345  * @static
20346  * @memberOf _
20347  * @since 4.12.0
20348  * @category Lang
20349  * @param {*} value The value to convert.
20350  * @returns {number} Returns the converted number.
20351  * @example
20352  *
20353  * _.toFinite(3.2);
20354  * // => 3.2
20355  *
20356  * _.toFinite(Number.MIN_VALUE);
20357  * // => 5e-324
20358  *
20359  * _.toFinite(Infinity);
20360  * // => 1.7976931348623157e+308
20361  *
20362  * _.toFinite('3.2');
20363  * // => 3.2
20364  */
20365 function toFinite(value) {
20366   if (!value) {
20367     return value === 0 ? value : 0;
20368   }
20369   value = toNumber(value);
20370   if (value === INFINITY$2 || value === -INFINITY$2) {
20371     var sign = (value < 0 ? -1 : 1);
20372     return sign * MAX_INTEGER;
20373   }
20374   return value === value ? value : 0;
20375 }
20376
20377 /**
20378  * Converts `value` to an integer.
20379  *
20380  * **Note:** This method is loosely based on
20381  * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
20382  *
20383  * @static
20384  * @memberOf _
20385  * @since 4.0.0
20386  * @category Lang
20387  * @param {*} value The value to convert.
20388  * @returns {number} Returns the converted integer.
20389  * @example
20390  *
20391  * _.toInteger(3.2);
20392  * // => 3
20393  *
20394  * _.toInteger(Number.MIN_VALUE);
20395  * // => 0
20396  *
20397  * _.toInteger(Infinity);
20398  * // => 1.7976931348623157e+308
20399  *
20400  * _.toInteger('3.2');
20401  * // => 3
20402  */
20403 function toInteger(value) {
20404   var result = toFinite(value),
20405       remainder = result % 1;
20406
20407   return result === result ? (remainder ? result - remainder : result) : 0;
20408 }
20409
20410 /* Built-in method references for those with the same name as other `lodash` methods. */
20411 var nativeMax$1 = Math.max;
20412
20413 /**
20414  * This method is like `_.find` except that it returns the index of the first
20415  * element `predicate` returns truthy for instead of the element itself.
20416  *
20417  * @static
20418  * @memberOf _
20419  * @since 1.1.0
20420  * @category Array
20421  * @param {Array} array The array to inspect.
20422  * @param {Function} [predicate=_.identity] The function invoked per iteration.
20423  * @param {number} [fromIndex=0] The index to search from.
20424  * @returns {number} Returns the index of the found element, else `-1`.
20425  * @example
20426  *
20427  * var users = [
20428  *   { 'user': 'barney',  'active': false },
20429  *   { 'user': 'fred',    'active': false },
20430  *   { 'user': 'pebbles', 'active': true }
20431  * ];
20432  *
20433  * _.findIndex(users, function(o) { return o.user == 'barney'; });
20434  * // => 0
20435  *
20436  * // The `_.matches` iteratee shorthand.
20437  * _.findIndex(users, { 'user': 'fred', 'active': false });
20438  * // => 1
20439  *
20440  * // The `_.matchesProperty` iteratee shorthand.
20441  * _.findIndex(users, ['active', false]);
20442  * // => 0
20443  *
20444  * // The `_.property` iteratee shorthand.
20445  * _.findIndex(users, 'active');
20446  * // => 2
20447  */
20448 function findIndex(array, predicate, fromIndex) {
20449   var length = array == null ? 0 : array.length;
20450   if (!length) {
20451     return -1;
20452   }
20453   var index = fromIndex == null ? 0 : toInteger(fromIndex);
20454   if (index < 0) {
20455     index = nativeMax$1(length + index, 0);
20456   }
20457   return baseFindIndex(array, baseIteratee(predicate, 3), index);
20458 }
20459
20460 /**
20461  * Iterates over elements of `collection`, returning the first element
20462  * `predicate` returns truthy for. The predicate is invoked with three
20463  * arguments: (value, index|key, collection).
20464  *
20465  * @static
20466  * @memberOf _
20467  * @since 0.1.0
20468  * @category Collection
20469  * @param {Array|Object} collection The collection to inspect.
20470  * @param {Function} [predicate=_.identity] The function invoked per iteration.
20471  * @param {number} [fromIndex=0] The index to search from.
20472  * @returns {*} Returns the matched element, else `undefined`.
20473  * @example
20474  *
20475  * var users = [
20476  *   { 'user': 'barney',  'age': 36, 'active': true },
20477  *   { 'user': 'fred',    'age': 40, 'active': false },
20478  *   { 'user': 'pebbles', 'age': 1,  'active': true }
20479  * ];
20480  *
20481  * _.find(users, function(o) { return o.age < 40; });
20482  * // => object for 'barney'
20483  *
20484  * // The `_.matches` iteratee shorthand.
20485  * _.find(users, { 'age': 1, 'active': true });
20486  * // => object for 'pebbles'
20487  *
20488  * // The `_.matchesProperty` iteratee shorthand.
20489  * _.find(users, ['active', false]);
20490  * // => object for 'fred'
20491  *
20492  * // The `_.property` iteratee shorthand.
20493  * _.find(users, 'active');
20494  * // => object for 'barney'
20495  */
20496 var find$1 = createFind(findIndex);
20497
20498 /**
20499  * The base implementation of `_.map` without support for iteratee shorthands.
20500  *
20501  * @private
20502  * @param {Array|Object} collection The collection to iterate over.
20503  * @param {Function} iteratee The function invoked per iteration.
20504  * @returns {Array} Returns the new mapped array.
20505  */
20506 function baseMap(collection, iteratee) {
20507   var index = -1,
20508       result = isArrayLike(collection) ? Array(collection.length) : [];
20509
20510   baseEach(collection, function(value, key, collection) {
20511     result[++index] = iteratee(value, key, collection);
20512   });
20513   return result;
20514 }
20515
20516 /**
20517  * Creates an array of values by running each element in `collection` thru
20518  * `iteratee`. The iteratee is invoked with three arguments:
20519  * (value, index|key, collection).
20520  *
20521  * Many lodash methods are guarded to work as iteratees for methods like
20522  * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
20523  *
20524  * The guarded methods are:
20525  * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
20526  * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
20527  * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
20528  * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
20529  *
20530  * @static
20531  * @memberOf _
20532  * @since 0.1.0
20533  * @category Collection
20534  * @param {Array|Object} collection The collection to iterate over.
20535  * @param {Function} [iteratee=_.identity] The function invoked per iteration.
20536  * @returns {Array} Returns the new mapped array.
20537  * @example
20538  *
20539  * function square(n) {
20540  *   return n * n;
20541  * }
20542  *
20543  * _.map([4, 8], square);
20544  * // => [16, 64]
20545  *
20546  * _.map({ 'a': 4, 'b': 8 }, square);
20547  * // => [16, 64] (iteration order is not guaranteed)
20548  *
20549  * var users = [
20550  *   { 'user': 'barney' },
20551  *   { 'user': 'fred' }
20552  * ];
20553  *
20554  * // The `_.property` iteratee shorthand.
20555  * _.map(users, 'user');
20556  * // => ['barney', 'fred']
20557  */
20558 function map$4(collection, iteratee) {
20559   var func = isArray(collection) ? arrayMap : baseMap;
20560   return func(collection, baseIteratee(iteratee, 3));
20561 }
20562
20563 /**
20564  * The base implementation of `_.values` and `_.valuesIn` which creates an
20565  * array of `object` property values corresponding to the property names
20566  * of `props`.
20567  *
20568  * @private
20569  * @param {Object} object The object to query.
20570  * @param {Array} props The property names to get values for.
20571  * @returns {Object} Returns the array of property values.
20572  */
20573 function baseValues(object, props) {
20574   return arrayMap(props, function(key) {
20575     return object[key];
20576   });
20577 }
20578
20579 /**
20580  * Creates an array of the own enumerable string keyed property values of `object`.
20581  *
20582  * **Note:** Non-object values are coerced to objects.
20583  *
20584  * @static
20585  * @since 0.1.0
20586  * @memberOf _
20587  * @category Object
20588  * @param {Object} object The object to query.
20589  * @returns {Array} Returns the array of property values.
20590  * @example
20591  *
20592  * function Foo() {
20593  *   this.a = 1;
20594  *   this.b = 2;
20595  * }
20596  *
20597  * Foo.prototype.c = 3;
20598  *
20599  * _.values(new Foo);
20600  * // => [1, 2] (iteration order is not guaranteed)
20601  *
20602  * _.values('hi');
20603  * // => ['h', 'i']
20604  */
20605 function values$1(object) {
20606   return object == null ? [] : baseValues(object, keys$1(object));
20607 }
20608
20609 /**
20610  * A specialized version of `_.forEach` for arrays without support for
20611  * iteratee shorthands.
20612  *
20613  * @private
20614  * @param {Array} [array] The array to iterate over.
20615  * @param {Function} iteratee The function invoked per iteration.
20616  * @returns {Array} Returns `array`.
20617  */
20618 function arrayEach(array, iteratee) {
20619   var index = -1,
20620       length = array == null ? 0 : array.length;
20621
20622   while (++index < length) {
20623     if (iteratee(array[index], index, array) === false) {
20624       break;
20625     }
20626   }
20627   return array;
20628 }
20629
20630 /**
20631  * The base implementation of `_.assign` without support for multiple sources
20632  * or `customizer` functions.
20633  *
20634  * @private
20635  * @param {Object} object The destination object.
20636  * @param {Object} source The source object.
20637  * @returns {Object} Returns `object`.
20638  */
20639 function baseAssign(object, source) {
20640   return object && copyObject(source, keys$1(source), object);
20641 }
20642
20643 /**
20644  * The base implementation of `_.assignIn` without support for multiple sources
20645  * or `customizer` functions.
20646  *
20647  * @private
20648  * @param {Object} object The destination object.
20649  * @param {Object} source The source object.
20650  * @returns {Object} Returns `object`.
20651  */
20652 function baseAssignIn(object, source) {
20653   return object && copyObject(source, keysIn$1(source), object);
20654 }
20655
20656 /** Detect free variable `exports`. */
20657 var freeExports$2 = typeof exports == 'object' && exports && !exports.nodeType && exports;
20658
20659 /** Detect free variable `module`. */
20660 var freeModule$2 = freeExports$2 && typeof module == 'object' && module && !module.nodeType && module;
20661
20662 /** Detect the popular CommonJS extension `module.exports`. */
20663 var moduleExports$2 = freeModule$2 && freeModule$2.exports === freeExports$2;
20664
20665 /** Built-in value references. */
20666 var Buffer$1 = moduleExports$2 ? root$2.Buffer : undefined;
20667 var allocUnsafe = Buffer$1 ? Buffer$1.allocUnsafe : undefined;
20668
20669 /**
20670  * Creates a clone of  `buffer`.
20671  *
20672  * @private
20673  * @param {Buffer} buffer The buffer to clone.
20674  * @param {boolean} [isDeep] Specify a deep clone.
20675  * @returns {Buffer} Returns the cloned buffer.
20676  */
20677 function cloneBuffer(buffer, isDeep) {
20678   if (isDeep) {
20679     return buffer.slice();
20680   }
20681   var length = buffer.length,
20682       result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
20683
20684   buffer.copy(result);
20685   return result;
20686 }
20687
20688 /**
20689  * Copies the values of `source` to `array`.
20690  *
20691  * @private
20692  * @param {Array} source The array to copy values from.
20693  * @param {Array} [array=[]] The array to copy values to.
20694  * @returns {Array} Returns `array`.
20695  */
20696 function copyArray(source, array) {
20697   var index = -1,
20698       length = source.length;
20699
20700   array || (array = Array(length));
20701   while (++index < length) {
20702     array[index] = source[index];
20703   }
20704   return array;
20705 }
20706
20707 /**
20708  * Copies own symbols of `source` to `object`.
20709  *
20710  * @private
20711  * @param {Object} source The object to copy symbols from.
20712  * @param {Object} [object={}] The object to copy symbols to.
20713  * @returns {Object} Returns `object`.
20714  */
20715 function copySymbols(source, object) {
20716   return copyObject(source, getSymbols(source), object);
20717 }
20718
20719 /** Built-in value references. */
20720 var getPrototype = overArg(Object.getPrototypeOf, Object);
20721
20722 /* Built-in method references for those with the same name as other `lodash` methods. */
20723 var nativeGetSymbols$1 = Object.getOwnPropertySymbols;
20724
20725 /**
20726  * Creates an array of the own and inherited enumerable symbols of `object`.
20727  *
20728  * @private
20729  * @param {Object} object The object to query.
20730  * @returns {Array} Returns the array of symbols.
20731  */
20732 var getSymbolsIn = !nativeGetSymbols$1 ? stubArray : function(object) {
20733   var result = [];
20734   while (object) {
20735     arrayPush(result, getSymbols(object));
20736     object = getPrototype(object);
20737   }
20738   return result;
20739 };
20740
20741 /**
20742  * Copies own and inherited symbols of `source` to `object`.
20743  *
20744  * @private
20745  * @param {Object} source The object to copy symbols from.
20746  * @param {Object} [object={}] The object to copy symbols to.
20747  * @returns {Object} Returns `object`.
20748  */
20749 function copySymbolsIn(source, object) {
20750   return copyObject(source, getSymbolsIn(source), object);
20751 }
20752
20753 /**
20754  * Creates an array of own and inherited enumerable property names and
20755  * symbols of `object`.
20756  *
20757  * @private
20758  * @param {Object} object The object to query.
20759  * @returns {Array} Returns the array of property names and symbols.
20760  */
20761 function getAllKeysIn(object) {
20762   return baseGetAllKeys(object, keysIn$1, getSymbolsIn);
20763 }
20764
20765 /** Used for built-in method references. */
20766 var objectProto$14 = Object.prototype;
20767
20768 /** Used to check objects for own properties. */
20769 var hasOwnProperty$11 = objectProto$14.hasOwnProperty;
20770
20771 /**
20772  * Initializes an array clone.
20773  *
20774  * @private
20775  * @param {Array} array The array to clone.
20776  * @returns {Array} Returns the initialized clone.
20777  */
20778 function initCloneArray(array) {
20779   var length = array.length,
20780       result = array.constructor(length);
20781
20782   // Add properties assigned by `RegExp#exec`.
20783   if (length && typeof array[0] == 'string' && hasOwnProperty$11.call(array, 'index')) {
20784     result.index = array.index;
20785     result.input = array.input;
20786   }
20787   return result;
20788 }
20789
20790 /**
20791  * Creates a clone of `arrayBuffer`.
20792  *
20793  * @private
20794  * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
20795  * @returns {ArrayBuffer} Returns the cloned array buffer.
20796  */
20797 function cloneArrayBuffer(arrayBuffer) {
20798   var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
20799   new Uint8Array(result).set(new Uint8Array(arrayBuffer));
20800   return result;
20801 }
20802
20803 /**
20804  * Creates a clone of `dataView`.
20805  *
20806  * @private
20807  * @param {Object} dataView The data view to clone.
20808  * @param {boolean} [isDeep] Specify a deep clone.
20809  * @returns {Object} Returns the cloned data view.
20810  */
20811 function cloneDataView(dataView, isDeep) {
20812   var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;
20813   return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
20814 }
20815
20816 /**
20817  * Adds the key-value `pair` to `map`.
20818  *
20819  * @private
20820  * @param {Object} map The map to modify.
20821  * @param {Array} pair The key-value pair to add.
20822  * @returns {Object} Returns `map`.
20823  */
20824 function addMapEntry(map, pair) {
20825   // Don't return `map.set` because it's not chainable in IE 11.
20826   map.set(pair[0], pair[1]);
20827   return map;
20828 }
20829
20830 /**
20831  * A specialized version of `_.reduce` for arrays without support for
20832  * iteratee shorthands.
20833  *
20834  * @private
20835  * @param {Array} [array] The array to iterate over.
20836  * @param {Function} iteratee The function invoked per iteration.
20837  * @param {*} [accumulator] The initial value.
20838  * @param {boolean} [initAccum] Specify using the first element of `array` as
20839  *  the initial value.
20840  * @returns {*} Returns the accumulated value.
20841  */
20842 function arrayReduce(array, iteratee, accumulator, initAccum) {
20843   var index = -1,
20844       length = array == null ? 0 : array.length;
20845
20846   if (initAccum && length) {
20847     accumulator = array[++index];
20848   }
20849   while (++index < length) {
20850     accumulator = iteratee(accumulator, array[index], index, array);
20851   }
20852   return accumulator;
20853 }
20854
20855 /** Used to compose bitmasks for cloning. */
20856 var CLONE_DEEP_FLAG$1 = 1;
20857
20858 /**
20859  * Creates a clone of `map`.
20860  *
20861  * @private
20862  * @param {Object} map The map to clone.
20863  * @param {Function} cloneFunc The function to clone values.
20864  * @param {boolean} [isDeep] Specify a deep clone.
20865  * @returns {Object} Returns the cloned map.
20866  */
20867 function cloneMap(map, isDeep, cloneFunc) {
20868   var array = isDeep ? cloneFunc(mapToArray(map), CLONE_DEEP_FLAG$1) : mapToArray(map);
20869   return arrayReduce(array, addMapEntry, new map.constructor);
20870 }
20871
20872 /** Used to match `RegExp` flags from their coerced string values. */
20873 var reFlags = /\w*$/;
20874
20875 /**
20876  * Creates a clone of `regexp`.
20877  *
20878  * @private
20879  * @param {Object} regexp The regexp to clone.
20880  * @returns {Object} Returns the cloned regexp.
20881  */
20882 function cloneRegExp(regexp) {
20883   var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
20884   result.lastIndex = regexp.lastIndex;
20885   return result;
20886 }
20887
20888 /**
20889  * Adds `value` to `set`.
20890  *
20891  * @private
20892  * @param {Object} set The set to modify.
20893  * @param {*} value The value to add.
20894  * @returns {Object} Returns `set`.
20895  */
20896 function addSetEntry(set, value) {
20897   // Don't return `set.add` because it's not chainable in IE 11.
20898   set.add(value);
20899   return set;
20900 }
20901
20902 /** Used to compose bitmasks for cloning. */
20903 var CLONE_DEEP_FLAG$2 = 1;
20904
20905 /**
20906  * Creates a clone of `set`.
20907  *
20908  * @private
20909  * @param {Object} set The set to clone.
20910  * @param {Function} cloneFunc The function to clone values.
20911  * @param {boolean} [isDeep] Specify a deep clone.
20912  * @returns {Object} Returns the cloned set.
20913  */
20914 function cloneSet(set, isDeep, cloneFunc) {
20915   var array = isDeep ? cloneFunc(setToArray(set), CLONE_DEEP_FLAG$2) : setToArray(set);
20916   return arrayReduce(array, addSetEntry, new set.constructor);
20917 }
20918
20919 /** Used to convert symbols to primitives and strings. */
20920 var symbolProto$2 = Symbol ? Symbol.prototype : undefined;
20921 var symbolValueOf$1 = symbolProto$2 ? symbolProto$2.valueOf : undefined;
20922
20923 /**
20924  * Creates a clone of the `symbol` object.
20925  *
20926  * @private
20927  * @param {Object} symbol The symbol object to clone.
20928  * @returns {Object} Returns the cloned symbol object.
20929  */
20930 function cloneSymbol(symbol) {
20931   return symbolValueOf$1 ? Object(symbolValueOf$1.call(symbol)) : {};
20932 }
20933
20934 /**
20935  * Creates a clone of `typedArray`.
20936  *
20937  * @private
20938  * @param {Object} typedArray The typed array to clone.
20939  * @param {boolean} [isDeep] Specify a deep clone.
20940  * @returns {Object} Returns the cloned typed array.
20941  */
20942 function cloneTypedArray(typedArray, isDeep) {
20943   var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;
20944   return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
20945 }
20946
20947 /** `Object#toString` result references. */
20948 var boolTag$3 = '[object Boolean]';
20949 var dateTag$3 = '[object Date]';
20950 var mapTag$4 = '[object Map]';
20951 var numberTag$3 = '[object Number]';
20952 var regexpTag$3 = '[object RegExp]';
20953 var setTag$4 = '[object Set]';
20954 var stringTag$3 = '[object String]';
20955 var symbolTag$3 = '[object Symbol]';
20956
20957 var arrayBufferTag$3 = '[object ArrayBuffer]';
20958 var dataViewTag$4 = '[object DataView]';
20959 var float32Tag$2 = '[object Float32Array]';
20960 var float64Tag$2 = '[object Float64Array]';
20961 var int8Tag$2 = '[object Int8Array]';
20962 var int16Tag$2 = '[object Int16Array]';
20963 var int32Tag$2 = '[object Int32Array]';
20964 var uint8Tag$2 = '[object Uint8Array]';
20965 var uint8ClampedTag$2 = '[object Uint8ClampedArray]';
20966 var uint16Tag$2 = '[object Uint16Array]';
20967 var uint32Tag$2 = '[object Uint32Array]';
20968
20969 /**
20970  * Initializes an object clone based on its `toStringTag`.
20971  *
20972  * **Note:** This function only supports cloning values with tags of
20973  * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
20974  *
20975  * @private
20976  * @param {Object} object The object to clone.
20977  * @param {string} tag The `toStringTag` of the object to clone.
20978  * @param {Function} cloneFunc The function to clone values.
20979  * @param {boolean} [isDeep] Specify a deep clone.
20980  * @returns {Object} Returns the initialized clone.
20981  */
20982 function initCloneByTag(object, tag, cloneFunc, isDeep) {
20983   var Ctor = object.constructor;
20984   switch (tag) {
20985     case arrayBufferTag$3:
20986       return cloneArrayBuffer(object);
20987
20988     case boolTag$3:
20989     case dateTag$3:
20990       return new Ctor(+object);
20991
20992     case dataViewTag$4:
20993       return cloneDataView(object, isDeep);
20994
20995     case float32Tag$2: case float64Tag$2:
20996     case int8Tag$2: case int16Tag$2: case int32Tag$2:
20997     case uint8Tag$2: case uint8ClampedTag$2: case uint16Tag$2: case uint32Tag$2:
20998       return cloneTypedArray(object, isDeep);
20999
21000     case mapTag$4:
21001       return cloneMap(object, isDeep, cloneFunc);
21002
21003     case numberTag$3:
21004     case stringTag$3:
21005       return new Ctor(object);
21006
21007     case regexpTag$3:
21008       return cloneRegExp(object);
21009
21010     case setTag$4:
21011       return cloneSet(object, isDeep, cloneFunc);
21012
21013     case symbolTag$3:
21014       return cloneSymbol(object);
21015   }
21016 }
21017
21018 /** Built-in value references. */
21019 var objectCreate = Object.create;
21020
21021 /**
21022  * The base implementation of `_.create` without support for assigning
21023  * properties to the created object.
21024  *
21025  * @private
21026  * @param {Object} proto The object to inherit from.
21027  * @returns {Object} Returns the new object.
21028  */
21029 var baseCreate = (function() {
21030   function object() {}
21031   return function(proto) {
21032     if (!isObject(proto)) {
21033       return {};
21034     }
21035     if (objectCreate) {
21036       return objectCreate(proto);
21037     }
21038     object.prototype = proto;
21039     var result = new object;
21040     object.prototype = undefined;
21041     return result;
21042   };
21043 }());
21044
21045 /**
21046  * Initializes an object clone.
21047  *
21048  * @private
21049  * @param {Object} object The object to clone.
21050  * @returns {Object} Returns the initialized clone.
21051  */
21052 function initCloneObject(object) {
21053   return (typeof object.constructor == 'function' && !isPrototype(object))
21054     ? baseCreate(getPrototype(object))
21055     : {};
21056 }
21057
21058 /** Used to compose bitmasks for cloning. */
21059 var CLONE_DEEP_FLAG = 1;
21060 var CLONE_FLAT_FLAG = 2;
21061 var CLONE_SYMBOLS_FLAG$1 = 4;
21062
21063 /** `Object#toString` result references. */
21064 var argsTag$3 = '[object Arguments]';
21065 var arrayTag$2 = '[object Array]';
21066 var boolTag$2 = '[object Boolean]';
21067 var dateTag$2 = '[object Date]';
21068 var errorTag$2 = '[object Error]';
21069 var funcTag$2 = '[object Function]';
21070 var genTag$1 = '[object GeneratorFunction]';
21071 var mapTag$3 = '[object Map]';
21072 var numberTag$2 = '[object Number]';
21073 var objectTag$3 = '[object Object]';
21074 var regexpTag$2 = '[object RegExp]';
21075 var setTag$3 = '[object Set]';
21076 var stringTag$2 = '[object String]';
21077 var symbolTag$2 = '[object Symbol]';
21078 var weakMapTag$2 = '[object WeakMap]';
21079
21080 var arrayBufferTag$2 = '[object ArrayBuffer]';
21081 var dataViewTag$3 = '[object DataView]';
21082 var float32Tag$1 = '[object Float32Array]';
21083 var float64Tag$1 = '[object Float64Array]';
21084 var int8Tag$1 = '[object Int8Array]';
21085 var int16Tag$1 = '[object Int16Array]';
21086 var int32Tag$1 = '[object Int32Array]';
21087 var uint8Tag$1 = '[object Uint8Array]';
21088 var uint8ClampedTag$1 = '[object Uint8ClampedArray]';
21089 var uint16Tag$1 = '[object Uint16Array]';
21090 var uint32Tag$1 = '[object Uint32Array]';
21091
21092 /** Used to identify `toStringTag` values supported by `_.clone`. */
21093 var cloneableTags = {};
21094 cloneableTags[argsTag$3] = cloneableTags[arrayTag$2] =
21095 cloneableTags[arrayBufferTag$2] = cloneableTags[dataViewTag$3] =
21096 cloneableTags[boolTag$2] = cloneableTags[dateTag$2] =
21097 cloneableTags[float32Tag$1] = cloneableTags[float64Tag$1] =
21098 cloneableTags[int8Tag$1] = cloneableTags[int16Tag$1] =
21099 cloneableTags[int32Tag$1] = cloneableTags[mapTag$3] =
21100 cloneableTags[numberTag$2] = cloneableTags[objectTag$3] =
21101 cloneableTags[regexpTag$2] = cloneableTags[setTag$3] =
21102 cloneableTags[stringTag$2] = cloneableTags[symbolTag$2] =
21103 cloneableTags[uint8Tag$1] = cloneableTags[uint8ClampedTag$1] =
21104 cloneableTags[uint16Tag$1] = cloneableTags[uint32Tag$1] = true;
21105 cloneableTags[errorTag$2] = cloneableTags[funcTag$2] =
21106 cloneableTags[weakMapTag$2] = false;
21107
21108 /**
21109  * The base implementation of `_.clone` and `_.cloneDeep` which tracks
21110  * traversed objects.
21111  *
21112  * @private
21113  * @param {*} value The value to clone.
21114  * @param {boolean} bitmask The bitmask flags.
21115  *  1 - Deep clone
21116  *  2 - Flatten inherited properties
21117  *  4 - Clone symbols
21118  * @param {Function} [customizer] The function to customize cloning.
21119  * @param {string} [key] The key of `value`.
21120  * @param {Object} [object] The parent object of `value`.
21121  * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
21122  * @returns {*} Returns the cloned value.
21123  */
21124 function baseClone(value, bitmask, customizer, key, object, stack) {
21125   var result,
21126       isDeep = bitmask & CLONE_DEEP_FLAG,
21127       isFlat = bitmask & CLONE_FLAT_FLAG,
21128       isFull = bitmask & CLONE_SYMBOLS_FLAG$1;
21129
21130   if (customizer) {
21131     result = object ? customizer(value, key, object, stack) : customizer(value);
21132   }
21133   if (result !== undefined) {
21134     return result;
21135   }
21136   if (!isObject(value)) {
21137     return value;
21138   }
21139   var isArr = isArray(value);
21140   if (isArr) {
21141     result = initCloneArray(value);
21142     if (!isDeep) {
21143       return copyArray(value, result);
21144     }
21145   } else {
21146     var tag = getTag$1(value),
21147         isFunc = tag == funcTag$2 || tag == genTag$1;
21148
21149     if (isBuffer(value)) {
21150       return cloneBuffer(value, isDeep);
21151     }
21152     if (tag == objectTag$3 || tag == argsTag$3 || (isFunc && !object)) {
21153       result = (isFlat || isFunc) ? {} : initCloneObject(value);
21154       if (!isDeep) {
21155         return isFlat
21156           ? copySymbolsIn(value, baseAssignIn(result, value))
21157           : copySymbols(value, baseAssign(result, value));
21158       }
21159     } else {
21160       if (!cloneableTags[tag]) {
21161         return object ? value : {};
21162       }
21163       result = initCloneByTag(value, tag, baseClone, isDeep);
21164     }
21165   }
21166   // Check for circular references and return its corresponding clone.
21167   stack || (stack = new Stack);
21168   var stacked = stack.get(value);
21169   if (stacked) {
21170     return stacked;
21171   }
21172   stack.set(value, result);
21173
21174   var keysFunc = isFull
21175     ? (isFlat ? getAllKeysIn : getAllKeys)
21176     : (isFlat ? keysIn : keys$1);
21177
21178   var props = isArr ? undefined : keysFunc(value);
21179   arrayEach(props || value, function(subValue, key) {
21180     if (props) {
21181       key = subValue;
21182       subValue = value[key];
21183     }
21184     // Recursively populate clone (susceptible to call stack limits).
21185     assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
21186   });
21187   return result;
21188 }
21189
21190 /** Used to compose bitmasks for cloning. */
21191 var CLONE_SYMBOLS_FLAG = 4;
21192
21193 /**
21194  * Creates a shallow clone of `value`.
21195  *
21196  * **Note:** This method is loosely based on the
21197  * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
21198  * and supports cloning arrays, array buffers, booleans, date objects, maps,
21199  * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
21200  * arrays. The own enumerable properties of `arguments` objects are cloned
21201  * as plain objects. An empty object is returned for uncloneable values such
21202  * as error objects, functions, DOM nodes, and WeakMaps.
21203  *
21204  * @static
21205  * @memberOf _
21206  * @since 0.1.0
21207  * @category Lang
21208  * @param {*} value The value to clone.
21209  * @returns {*} Returns the cloned value.
21210  * @see _.cloneDeep
21211  * @example
21212  *
21213  * var objects = [{ 'a': 1 }, { 'b': 2 }];
21214  *
21215  * var shallow = _.clone(objects);
21216  * console.log(shallow[0] === objects[0]);
21217  * // => true
21218  */
21219 function clone(value) {
21220   return baseClone(value, CLONE_SYMBOLS_FLAG);
21221 }
21222
21223 /**
21224  * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array
21225  * of key-value pairs for `object` corresponding to the property names of `props`.
21226  *
21227  * @private
21228  * @param {Object} object The object to query.
21229  * @param {Array} props The property names to get values for.
21230  * @returns {Object} Returns the key-value pairs.
21231  */
21232 function baseToPairs(object, props) {
21233   return arrayMap(props, function(key) {
21234     return [key, object[key]];
21235   });
21236 }
21237
21238 /**
21239  * Converts `set` to its value-value pairs.
21240  *
21241  * @private
21242  * @param {Object} set The set to convert.
21243  * @returns {Array} Returns the value-value pairs.
21244  */
21245 function setToPairs(set) {
21246   var index = -1,
21247       result = Array(set.size);
21248
21249   set.forEach(function(value) {
21250     result[++index] = [value, value];
21251   });
21252   return result;
21253 }
21254
21255 /** `Object#toString` result references. */
21256 var mapTag$5 = '[object Map]';
21257 var setTag$5 = '[object Set]';
21258
21259 /**
21260  * Creates a `_.toPairs` or `_.toPairsIn` function.
21261  *
21262  * @private
21263  * @param {Function} keysFunc The function to get the keys of a given object.
21264  * @returns {Function} Returns the new pairs function.
21265  */
21266 function createToPairs(keysFunc) {
21267   return function(object) {
21268     var tag = getTag$1(object);
21269     if (tag == mapTag$5) {
21270       return mapToArray(object);
21271     }
21272     if (tag == setTag$5) {
21273       return setToPairs(object);
21274     }
21275     return baseToPairs(object, keysFunc(object));
21276   };
21277 }
21278
21279 /**
21280  * Creates an array of own enumerable string keyed-value pairs for `object`
21281  * which can be consumed by `_.fromPairs`. If `object` is a map or set, its
21282  * entries are returned.
21283  *
21284  * @static
21285  * @memberOf _
21286  * @since 4.0.0
21287  * @alias entries
21288  * @category Object
21289  * @param {Object} object The object to query.
21290  * @returns {Array} Returns the key-value pairs.
21291  * @example
21292  *
21293  * function Foo() {
21294  *   this.a = 1;
21295  *   this.b = 2;
21296  * }
21297  *
21298  * Foo.prototype.c = 3;
21299  *
21300  * _.toPairs(new Foo);
21301  * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
21302  */
21303 var toPairs = createToPairs(keys$1);
21304
21305 /** Built-in value references. */
21306 var spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;
21307
21308 /**
21309  * Checks if `value` is a flattenable `arguments` object or array.
21310  *
21311  * @private
21312  * @param {*} value The value to check.
21313  * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
21314  */
21315 function isFlattenable(value) {
21316   return isArray(value) || isArguments(value) ||
21317     !!(spreadableSymbol && value && value[spreadableSymbol]);
21318 }
21319
21320 /**
21321  * The base implementation of `_.flatten` with support for restricting flattening.
21322  *
21323  * @private
21324  * @param {Array} array The array to flatten.
21325  * @param {number} depth The maximum recursion depth.
21326  * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
21327  * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
21328  * @param {Array} [result=[]] The initial result value.
21329  * @returns {Array} Returns the new flattened array.
21330  */
21331 function baseFlatten(array, depth, predicate, isStrict, result) {
21332   var index = -1,
21333       length = array.length;
21334
21335   predicate || (predicate = isFlattenable);
21336   result || (result = []);
21337
21338   while (++index < length) {
21339     var value = array[index];
21340     if (depth > 0 && predicate(value)) {
21341       if (depth > 1) {
21342         // Recursively flatten arrays (susceptible to call stack limits).
21343         baseFlatten(value, depth - 1, predicate, isStrict, result);
21344       } else {
21345         arrayPush(result, value);
21346       }
21347     } else if (!isStrict) {
21348       result[result.length] = value;
21349     }
21350   }
21351   return result;
21352 }
21353
21354 /**
21355  * The base implementation of `_.isNaN` without support for number objects.
21356  *
21357  * @private
21358  * @param {*} value The value to check.
21359  * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
21360  */
21361 function baseIsNaN(value) {
21362   return value !== value;
21363 }
21364
21365 /**
21366  * A specialized version of `_.indexOf` which performs strict equality
21367  * comparisons of values, i.e. `===`.
21368  *
21369  * @private
21370  * @param {Array} array The array to inspect.
21371  * @param {*} value The value to search for.
21372  * @param {number} fromIndex The index to search from.
21373  * @returns {number} Returns the index of the matched value, else `-1`.
21374  */
21375 function strictIndexOf(array, value, fromIndex) {
21376   var index = fromIndex - 1,
21377       length = array.length;
21378
21379   while (++index < length) {
21380     if (array[index] === value) {
21381       return index;
21382     }
21383   }
21384   return -1;
21385 }
21386
21387 /**
21388  * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
21389  *
21390  * @private
21391  * @param {Array} array The array to inspect.
21392  * @param {*} value The value to search for.
21393  * @param {number} fromIndex The index to search from.
21394  * @returns {number} Returns the index of the matched value, else `-1`.
21395  */
21396 function baseIndexOf(array, value, fromIndex) {
21397   return value === value
21398     ? strictIndexOf(array, value, fromIndex)
21399     : baseFindIndex(array, baseIsNaN, fromIndex);
21400 }
21401
21402 /**
21403  * A specialized version of `_.includes` for arrays without support for
21404  * specifying an index to search from.
21405  *
21406  * @private
21407  * @param {Array} [array] The array to inspect.
21408  * @param {*} target The value to search for.
21409  * @returns {boolean} Returns `true` if `target` is found, else `false`.
21410  */
21411 function arrayIncludes(array, value) {
21412   var length = array == null ? 0 : array.length;
21413   return !!length && baseIndexOf(array, value, 0) > -1;
21414 }
21415
21416 /**
21417  * This function is like `arrayIncludes` except that it accepts a comparator.
21418  *
21419  * @private
21420  * @param {Array} [array] The array to inspect.
21421  * @param {*} target The value to search for.
21422  * @param {Function} comparator The comparator invoked per element.
21423  * @returns {boolean} Returns `true` if `target` is found, else `false`.
21424  */
21425 function arrayIncludesWith(array, value, comparator) {
21426   var index = -1,
21427       length = array == null ? 0 : array.length;
21428
21429   while (++index < length) {
21430     if (comparator(value, array[index])) {
21431       return true;
21432     }
21433   }
21434   return false;
21435 }
21436
21437 /**
21438  * This method returns `undefined`.
21439  *
21440  * @static
21441  * @memberOf _
21442  * @since 2.3.0
21443  * @category Util
21444  * @example
21445  *
21446  * _.times(2, _.noop);
21447  * // => [undefined, undefined]
21448  */
21449 function noop$3() {
21450   // No operation performed.
21451 }
21452
21453 /** Used as references for various `Number` constants. */
21454 var INFINITY$3 = 1 / 0;
21455
21456 /**
21457  * Creates a set object of `values`.
21458  *
21459  * @private
21460  * @param {Array} values The values to add to the set.
21461  * @returns {Object} Returns the new set.
21462  */
21463 var createSet = !(Set$1 && (1 / setToArray(new Set$1([,-0]))[1]) == INFINITY$3) ? noop$3 : function(values) {
21464   return new Set$1(values);
21465 };
21466
21467 /** Used as the size to enable large array optimizations. */
21468 var LARGE_ARRAY_SIZE$1 = 200;
21469
21470 /**
21471  * The base implementation of `_.uniqBy` without support for iteratee shorthands.
21472  *
21473  * @private
21474  * @param {Array} array The array to inspect.
21475  * @param {Function} [iteratee] The iteratee invoked per element.
21476  * @param {Function} [comparator] The comparator invoked per element.
21477  * @returns {Array} Returns the new duplicate free array.
21478  */
21479 function baseUniq(array, iteratee, comparator) {
21480   var index = -1,
21481       includes = arrayIncludes,
21482       length = array.length,
21483       isCommon = true,
21484       result = [],
21485       seen = result;
21486
21487   if (comparator) {
21488     isCommon = false;
21489     includes = arrayIncludesWith;
21490   }
21491   else if (length >= LARGE_ARRAY_SIZE$1) {
21492     var set = iteratee ? null : createSet(array);
21493     if (set) {
21494       return setToArray(set);
21495     }
21496     isCommon = false;
21497     includes = cacheHas;
21498     seen = new SetCache;
21499   }
21500   else {
21501     seen = iteratee ? [] : result;
21502   }
21503   outer:
21504   while (++index < length) {
21505     var value = array[index],
21506         computed = iteratee ? iteratee(value) : value;
21507
21508     value = (comparator || value !== 0) ? value : 0;
21509     if (isCommon && computed === computed) {
21510       var seenIndex = seen.length;
21511       while (seenIndex--) {
21512         if (seen[seenIndex] === computed) {
21513           continue outer;
21514         }
21515       }
21516       if (iteratee) {
21517         seen.push(computed);
21518       }
21519       result.push(value);
21520     }
21521     else if (!includes(seen, computed, comparator)) {
21522       if (seen !== result) {
21523         seen.push(computed);
21524       }
21525       result.push(value);
21526     }
21527   }
21528   return result;
21529 }
21530
21531 /**
21532  * This method is like `_.isArrayLike` except that it also checks if `value`
21533  * is an object.
21534  *
21535  * @static
21536  * @memberOf _
21537  * @since 4.0.0
21538  * @category Lang
21539  * @param {*} value The value to check.
21540  * @returns {boolean} Returns `true` if `value` is an array-like object,
21541  *  else `false`.
21542  * @example
21543  *
21544  * _.isArrayLikeObject([1, 2, 3]);
21545  * // => true
21546  *
21547  * _.isArrayLikeObject(document.body.children);
21548  * // => true
21549  *
21550  * _.isArrayLikeObject('abc');
21551  * // => false
21552  *
21553  * _.isArrayLikeObject(_.noop);
21554  * // => false
21555  */
21556 function isArrayLikeObject(value) {
21557   return isObjectLike(value) && isArrayLike(value);
21558 }
21559
21560 /**
21561  * Creates an array of unique values, in order, from all given arrays using
21562  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
21563  * for equality comparisons.
21564  *
21565  * @static
21566  * @memberOf _
21567  * @since 0.1.0
21568  * @category Array
21569  * @param {...Array} [arrays] The arrays to inspect.
21570  * @returns {Array} Returns the new array of combined values.
21571  * @example
21572  *
21573  * _.union([2], [1, 2]);
21574  * // => [2, 1]
21575  */
21576 var union = baseRest(function(arrays) {
21577   return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true));
21578 });
21579
21580 /** Used as the size to enable large array optimizations. */
21581 var LARGE_ARRAY_SIZE$2 = 200;
21582
21583 /**
21584  * The base implementation of methods like `_.difference` without support
21585  * for excluding multiple arrays or iteratee shorthands.
21586  *
21587  * @private
21588  * @param {Array} array The array to inspect.
21589  * @param {Array} values The values to exclude.
21590  * @param {Function} [iteratee] The iteratee invoked per element.
21591  * @param {Function} [comparator] The comparator invoked per element.
21592  * @returns {Array} Returns the new array of filtered values.
21593  */
21594 function baseDifference(array, values, iteratee, comparator) {
21595   var index = -1,
21596       includes = arrayIncludes,
21597       isCommon = true,
21598       length = array.length,
21599       result = [],
21600       valuesLength = values.length;
21601
21602   if (!length) {
21603     return result;
21604   }
21605   if (iteratee) {
21606     values = arrayMap(values, baseUnary(iteratee));
21607   }
21608   if (comparator) {
21609     includes = arrayIncludesWith;
21610     isCommon = false;
21611   }
21612   else if (values.length >= LARGE_ARRAY_SIZE$2) {
21613     includes = cacheHas;
21614     isCommon = false;
21615     values = new SetCache(values);
21616   }
21617   outer:
21618   while (++index < length) {
21619     var value = array[index],
21620         computed = iteratee == null ? value : iteratee(value);
21621
21622     value = (comparator || value !== 0) ? value : 0;
21623     if (isCommon && computed === computed) {
21624       var valuesIndex = valuesLength;
21625       while (valuesIndex--) {
21626         if (values[valuesIndex] === computed) {
21627           continue outer;
21628         }
21629       }
21630       result.push(value);
21631     }
21632     else if (!includes(values, computed, comparator)) {
21633       result.push(value);
21634     }
21635   }
21636   return result;
21637 }
21638
21639 /**
21640  * Creates an array excluding all given values using
21641  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
21642  * for equality comparisons.
21643  *
21644  * **Note:** Unlike `_.pull`, this method returns a new array.
21645  *
21646  * @static
21647  * @memberOf _
21648  * @since 0.1.0
21649  * @category Array
21650  * @param {Array} array The array to inspect.
21651  * @param {...*} [values] The values to exclude.
21652  * @returns {Array} Returns the new array of filtered values.
21653  * @see _.difference, _.xor
21654  * @example
21655  *
21656  * _.without([2, 1, 2, 3], 1, 2);
21657  * // => [3]
21658  */
21659 var without = baseRest(function(array, values) {
21660   return isArrayLikeObject(array)
21661     ? baseDifference(array, values)
21662     : [];
21663 });
21664
21665 function osmIsInterestingTag(key) {
21666     return key !== 'attribution' &&
21667         key !== 'created_by' &&
21668         key !== 'source' &&
21669         key !== 'odbl' &&
21670         key.indexOf('tiger:') !== 0;
21671
21672 }
21673
21674
21675 var osmOneWayTags = {
21676     'aerialway': {
21677         'chair_lift': true,
21678         'mixed_lift': true,
21679         't-bar': true,
21680         'j-bar': true,
21681         'platter': true,
21682         'rope_tow': true,
21683         'magic_carpet': true,
21684         'yes': true
21685     },
21686     'highway': {
21687         'motorway': true,
21688         'motorway_link': true
21689     },
21690     'junction': {
21691         'roundabout': true
21692     },
21693     'man_made': {
21694         'piste:halfpipe': true
21695     },
21696     'piste:type': {
21697         'downhill': true,
21698         'sled': true,
21699         'yes': true
21700     },
21701     'waterway': {
21702         'canal': true,
21703         'ditch': true,
21704         'drain': true,
21705         'river': true,
21706         'stream': true
21707     }
21708 };
21709
21710
21711 var osmPavedTags = {
21712     'surface': {
21713         'paved': true,
21714         'asphalt': true,
21715         'concrete': true,
21716         'concrete:lanes': true,
21717         'concrete:plates': true
21718     },
21719     'tracktype': {
21720         'grade1': true
21721     }
21722 };
21723
21724 var wikipedia$1 = [
21725     [
21726         "Abkhazian",
21727         "Аҧсшәа",
21728         "ab"
21729     ],
21730     [
21731         "Achinese",
21732         "Acèh",
21733         "ace"
21734     ],
21735     [
21736         "Adyghe",
21737         "адыгабзэ",
21738         "ady"
21739     ],
21740     [
21741         "Afrikaans",
21742         "Afrikaans",
21743         "af"
21744     ],
21745     [
21746         "Akan",
21747         "Akan",
21748         "ak"
21749     ],
21750     [
21751         "Alemannisch",
21752         "Alemannisch",
21753         "als"
21754     ],
21755     [
21756         "Amharic",
21757         "አማርኛ",
21758         "am"
21759     ],
21760     [
21761         "Aragonese",
21762         "aragonés",
21763         "an"
21764     ],
21765     [
21766         "Old English",
21767         "Ænglisc",
21768         "ang"
21769     ],
21770     [
21771         "Arabic",
21772         "العربية",
21773         "ar"
21774     ],
21775     [
21776         "Aramaic",
21777         "ܐܪܡܝܐ",
21778         "arc"
21779     ],
21780     [
21781         "Egyptian Arabic",
21782         "مصرى",
21783         "arz"
21784     ],
21785     [
21786         "Assamese",
21787         "অসমীয়া",
21788         "as"
21789     ],
21790     [
21791         "Asturian",
21792         "asturianu",
21793         "ast"
21794     ],
21795     [
21796         "Avaric",
21797         "авар",
21798         "av"
21799     ],
21800     [
21801         "Aymara",
21802         "Aymar aru",
21803         "ay"
21804     ],
21805     [
21806         "Azerbaijani",
21807         "azərbaycanca",
21808         "az"
21809     ],
21810     [
21811         "تۆرکجه",
21812         "تۆرکجه",
21813         "azb"
21814     ],
21815     [
21816         "Bashkir",
21817         "башҡортса",
21818         "ba"
21819     ],
21820     [
21821         "Bavarian",
21822         "Boarisch",
21823         "bar"
21824     ],
21825     [
21826         "Samogitian",
21827         "žemaitėška",
21828         "bat-smg"
21829     ],
21830     [
21831         "Bikol Central",
21832         "Bikol Central",
21833         "bcl"
21834     ],
21835     [
21836         "Belarusian",
21837         "беларуская",
21838         "be"
21839     ],
21840     [
21841         "беларуская (тарашкевіца)‎",
21842         "беларуская (тарашкевіца)‎",
21843         "be-x-old"
21844     ],
21845     [
21846         "Bulgarian",
21847         "български",
21848         "bg"
21849     ],
21850     [
21851         "भोजपुरी",
21852         "भोजपुरी",
21853         "bh"
21854     ],
21855     [
21856         "Bislama",
21857         "Bislama",
21858         "bi"
21859     ],
21860     [
21861         "Banjar",
21862         "Bahasa Banjar",
21863         "bjn"
21864     ],
21865     [
21866         "Bambara",
21867         "bamanankan",
21868         "bm"
21869     ],
21870     [
21871         "Bangla",
21872         "বাংলা",
21873         "bn"
21874     ],
21875     [
21876         "Tibetan",
21877         "བོད་ཡིག",
21878         "bo"
21879     ],
21880     [
21881         "Bishnupriya",
21882         "বিষ্ণুপ্রিয়া মণিপুরী",
21883         "bpy"
21884     ],
21885     [
21886         "Breton",
21887         "brezhoneg",
21888         "br"
21889     ],
21890     [
21891         "Bosnian",
21892         "bosanski",
21893         "bs"
21894     ],
21895     [
21896         "Buginese",
21897         "ᨅᨔ ᨕᨘᨁᨗ",
21898         "bug"
21899     ],
21900     [
21901         "буряад",
21902         "буряад",
21903         "bxr"
21904     ],
21905     [
21906         "Catalan",
21907         "català",
21908         "ca"
21909     ],
21910     [
21911         "Chavacano de Zamboanga",
21912         "Chavacano de Zamboanga",
21913         "cbk-zam"
21914     ],
21915     [
21916         "Min Dong Chinese",
21917         "Mìng-dĕ̤ng-ngṳ̄",
21918         "cdo"
21919     ],
21920     [
21921         "Chechen",
21922         "нохчийн",
21923         "ce"
21924     ],
21925     [
21926         "Cebuano",
21927         "Cebuano",
21928         "ceb"
21929     ],
21930     [
21931         "Chamorro",
21932         "Chamoru",
21933         "ch"
21934     ],
21935     [
21936         "Cherokee",
21937         "ᏣᎳᎩ",
21938         "chr"
21939     ],
21940     [
21941         "Cheyenne",
21942         "Tsetsêhestâhese",
21943         "chy"
21944     ],
21945     [
21946         "Central Kurdish",
21947         "کوردیی ناوەندی",
21948         "ckb"
21949     ],
21950     [
21951         "Corsican",
21952         "corsu",
21953         "co"
21954     ],
21955     [
21956         "Cree",
21957         "Nēhiyawēwin / ᓀᐦᐃᔭᐍᐏᐣ",
21958         "cr"
21959     ],
21960     [
21961         "Crimean Turkish",
21962         "qırımtatarca",
21963         "crh"
21964     ],
21965     [
21966         "Czech",
21967         "čeština",
21968         "cs"
21969     ],
21970     [
21971         "Kashubian",
21972         "kaszëbsczi",
21973         "csb"
21974     ],
21975     [
21976         "Church Slavic",
21977         "словѣньскъ / ⰔⰎⰑⰂⰡⰐⰠⰔⰍⰟ",
21978         "cu"
21979     ],
21980     [
21981         "Chuvash",
21982         "Чӑвашла",
21983         "cv"
21984     ],
21985     [
21986         "Welsh",
21987         "Cymraeg",
21988         "cy"
21989     ],
21990     [
21991         "Danish",
21992         "dansk",
21993         "da"
21994     ],
21995     [
21996         "German",
21997         "Deutsch",
21998         "de"
21999     ],
22000     [
22001         "Zazaki",
22002         "Zazaki",
22003         "diq"
22004     ],
22005     [
22006         "Lower Sorbian",
22007         "dolnoserbski",
22008         "dsb"
22009     ],
22010     [
22011         "Divehi",
22012         "ދިވެހިބަސް",
22013         "dv"
22014     ],
22015     [
22016         "Dzongkha",
22017         "ཇོང་ཁ",
22018         "dz"
22019     ],
22020     [
22021         "Ewe",
22022         "eʋegbe",
22023         "ee"
22024     ],
22025     [
22026         "Greek",
22027         "Ελληνικά",
22028         "el"
22029     ],
22030     [
22031         "Emiliano-Romagnolo",
22032         "emiliàn e rumagnòl",
22033         "eml"
22034     ],
22035     [
22036         "English",
22037         "English",
22038         "en"
22039     ],
22040     [
22041         "Esperanto",
22042         "Esperanto",
22043         "eo"
22044     ],
22045     [
22046         "Spanish",
22047         "español",
22048         "es"
22049     ],
22050     [
22051         "Estonian",
22052         "eesti",
22053         "et"
22054     ],
22055     [
22056         "Basque",
22057         "euskara",
22058         "eu"
22059     ],
22060     [
22061         "Extremaduran",
22062         "estremeñu",
22063         "ext"
22064     ],
22065     [
22066         "Persian",
22067         "فارسی",
22068         "fa"
22069     ],
22070     [
22071         "Fulah",
22072         "Fulfulde",
22073         "ff"
22074     ],
22075     [
22076         "Finnish",
22077         "suomi",
22078         "fi"
22079     ],
22080     [
22081         "Võro",
22082         "Võro",
22083         "fiu-vro"
22084     ],
22085     [
22086         "Fijian",
22087         "Na Vosa Vakaviti",
22088         "fj"
22089     ],
22090     [
22091         "Faroese",
22092         "føroyskt",
22093         "fo"
22094     ],
22095     [
22096         "French",
22097         "français",
22098         "fr"
22099     ],
22100     [
22101         "Arpitan",
22102         "arpetan",
22103         "frp"
22104     ],
22105     [
22106         "Northern Frisian",
22107         "Nordfriisk",
22108         "frr"
22109     ],
22110     [
22111         "Friulian",
22112         "furlan",
22113         "fur"
22114     ],
22115     [
22116         "Western Frisian",
22117         "Frysk",
22118         "fy"
22119     ],
22120     [
22121         "Irish",
22122         "Gaeilge",
22123         "ga"
22124     ],
22125     [
22126         "Gagauz",
22127         "Gagauz",
22128         "gag"
22129     ],
22130     [
22131         "Gan Chinese",
22132         "贛語",
22133         "gan"
22134     ],
22135     [
22136         "Scottish Gaelic",
22137         "Gàidhlig",
22138         "gd"
22139     ],
22140     [
22141         "Galician",
22142         "galego",
22143         "gl"
22144     ],
22145     [
22146         "Gilaki",
22147         "گیلکی",
22148         "glk"
22149     ],
22150     [
22151         "Guarani",
22152         "Avañe'ẽ",
22153         "gn"
22154     ],
22155     [
22156         "Goan Konkani",
22157         "गोंयची कोंकणी / Gõychi Konknni",
22158         "gom"
22159     ],
22160     [
22161         "Gothic",
22162         "𐌲𐌿𐍄𐌹𐍃𐌺",
22163         "got"
22164     ],
22165     [
22166         "Gujarati",
22167         "ગુજરાતી",
22168         "gu"
22169     ],
22170     [
22171         "Manx",
22172         "Gaelg",
22173         "gv"
22174     ],
22175     [
22176         "Hausa",
22177         "Hausa",
22178         "ha"
22179     ],
22180     [
22181         "Hakka Chinese",
22182         "客家語/Hak-kâ-ngî",
22183         "hak"
22184     ],
22185     [
22186         "Hawaiian",
22187         "Hawaiʻi",
22188         "haw"
22189     ],
22190     [
22191         "Hebrew",
22192         "עברית",
22193         "he"
22194     ],
22195     [
22196         "Hindi",
22197         "हिन्दी",
22198         "hi"
22199     ],
22200     [
22201         "Fiji Hindi",
22202         "Fiji Hindi",
22203         "hif"
22204     ],
22205     [
22206         "Croatian",
22207         "hrvatski",
22208         "hr"
22209     ],
22210     [
22211         "Upper Sorbian",
22212         "hornjoserbsce",
22213         "hsb"
22214     ],
22215     [
22216         "Haitian Creole",
22217         "Kreyòl ayisyen",
22218         "ht"
22219     ],
22220     [
22221         "Hungarian",
22222         "magyar",
22223         "hu"
22224     ],
22225     [
22226         "Armenian",
22227         "Հայերեն",
22228         "hy"
22229     ],
22230     [
22231         "Interlingua",
22232         "interlingua",
22233         "ia"
22234     ],
22235     [
22236         "Indonesian",
22237         "Bahasa Indonesia",
22238         "id"
22239     ],
22240     [
22241         "Interlingue",
22242         "Interlingue",
22243         "ie"
22244     ],
22245     [
22246         "Igbo",
22247         "Igbo",
22248         "ig"
22249     ],
22250     [
22251         "Inupiaq",
22252         "Iñupiak",
22253         "ik"
22254     ],
22255     [
22256         "Iloko",
22257         "Ilokano",
22258         "ilo"
22259     ],
22260     [
22261         "Ido",
22262         "Ido",
22263         "io"
22264     ],
22265     [
22266         "Icelandic",
22267         "íslenska",
22268         "is"
22269     ],
22270     [
22271         "Italian",
22272         "italiano",
22273         "it"
22274     ],
22275     [
22276         "Inuktitut",
22277         "ᐃᓄᒃᑎᑐᑦ/inuktitut",
22278         "iu"
22279     ],
22280     [
22281         "Japanese",
22282         "日本語",
22283         "ja"
22284     ],
22285     [
22286         "Jamaican Creole English",
22287         "Patois",
22288         "jam"
22289     ],
22290     [
22291         "Lojban",
22292         "la .lojban.",
22293         "jbo"
22294     ],
22295     [
22296         "Javanese",
22297         "Basa Jawa",
22298         "jv"
22299     ],
22300     [
22301         "Georgian",
22302         "ქართული",
22303         "ka"
22304     ],
22305     [
22306         "Kara-Kalpak",
22307         "Qaraqalpaqsha",
22308         "kaa"
22309     ],
22310     [
22311         "Kabyle",
22312         "Taqbaylit",
22313         "kab"
22314     ],
22315     [
22316         "Kabardian",
22317         "Адыгэбзэ",
22318         "kbd"
22319     ],
22320     [
22321         "Kongo",
22322         "Kongo",
22323         "kg"
22324     ],
22325     [
22326         "Kikuyu",
22327         "Gĩkũyũ",
22328         "ki"
22329     ],
22330     [
22331         "Kazakh",
22332         "қазақша",
22333         "kk"
22334     ],
22335     [
22336         "Kalaallisut",
22337         "kalaallisut",
22338         "kl"
22339     ],
22340     [
22341         "Khmer",
22342         "ភាសាខ្មែរ",
22343         "km"
22344     ],
22345     [
22346         "Kannada",
22347         "ಕನ್ನಡ",
22348         "kn"
22349     ],
22350     [
22351         "Korean",
22352         "한국어",
22353         "ko"
22354     ],
22355     [
22356         "Komi-Permyak",
22357         "Перем Коми",
22358         "koi"
22359     ],
22360     [
22361         "Karachay-Balkar",
22362         "къарачай-малкъар",
22363         "krc"
22364     ],
22365     [
22366         "Kashmiri",
22367         "कॉशुर / کٲشُر",
22368         "ks"
22369     ],
22370     [
22371         "Colognian",
22372         "Ripoarisch",
22373         "ksh"
22374     ],
22375     [
22376         "Kurdish",
22377         "Kurdî",
22378         "ku"
22379     ],
22380     [
22381         "Komi",
22382         "коми",
22383         "kv"
22384     ],
22385     [
22386         "Cornish",
22387         "kernowek",
22388         "kw"
22389     ],
22390     [
22391         "Kyrgyz",
22392         "Кыргызча",
22393         "ky"
22394     ],
22395     [
22396         "Latin",
22397         "Latina",
22398         "la"
22399     ],
22400     [
22401         "Ladino",
22402         "Ladino",
22403         "lad"
22404     ],
22405     [
22406         "Luxembourgish",
22407         "Lëtzebuergesch",
22408         "lb"
22409     ],
22410     [
22411         "лакку",
22412         "лакку",
22413         "lbe"
22414     ],
22415     [
22416         "Lezghian",
22417         "лезги",
22418         "lez"
22419     ],
22420     [
22421         "Ganda",
22422         "Luganda",
22423         "lg"
22424     ],
22425     [
22426         "Limburgish",
22427         "Limburgs",
22428         "li"
22429     ],
22430     [
22431         "Ligurian",
22432         "Ligure",
22433         "lij"
22434     ],
22435     [
22436         "Lombard",
22437         "lumbaart",
22438         "lmo"
22439     ],
22440     [
22441         "Lingala",
22442         "lingála",
22443         "ln"
22444     ],
22445     [
22446         "Lao",
22447         "ລາວ",
22448         "lo"
22449     ],
22450     [
22451         "Northern Luri",
22452         "لۊری شومالی",
22453         "lrc"
22454     ],
22455     [
22456         "Lithuanian",
22457         "lietuvių",
22458         "lt"
22459     ],
22460     [
22461         "Latgalian",
22462         "latgaļu",
22463         "ltg"
22464     ],
22465     [
22466         "Latvian",
22467         "latviešu",
22468         "lv"
22469     ],
22470     [
22471         "Maithili",
22472         "मैथिली",
22473         "mai"
22474     ],
22475     [
22476         "Basa Banyumasan",
22477         "Basa Banyumasan",
22478         "map-bms"
22479     ],
22480     [
22481         "Moksha",
22482         "мокшень",
22483         "mdf"
22484     ],
22485     [
22486         "Malagasy",
22487         "Malagasy",
22488         "mg"
22489     ],
22490     [
22491         "Eastern Mari",
22492         "олык марий",
22493         "mhr"
22494     ],
22495     [
22496         "Maori",
22497         "Māori",
22498         "mi"
22499     ],
22500     [
22501         "Minangkabau",
22502         "Baso Minangkabau",
22503         "min"
22504     ],
22505     [
22506         "Macedonian",
22507         "македонски",
22508         "mk"
22509     ],
22510     [
22511         "Malayalam",
22512         "മലയാളം",
22513         "ml"
22514     ],
22515     [
22516         "Mongolian",
22517         "монгол",
22518         "mn"
22519     ],
22520     [
22521         "Marathi",
22522         "मराठी",
22523         "mr"
22524     ],
22525     [
22526         "Western Mari",
22527         "кырык мары",
22528         "mrj"
22529     ],
22530     [
22531         "Malay",
22532         "Bahasa Melayu",
22533         "ms"
22534     ],
22535     [
22536         "Maltese",
22537         "Malti",
22538         "mt"
22539     ],
22540     [
22541         "Mirandese",
22542         "Mirandés",
22543         "mwl"
22544     ],
22545     [
22546         "Burmese",
22547         "မြန်မာဘာသာ",
22548         "my"
22549     ],
22550     [
22551         "Erzya",
22552         "эрзянь",
22553         "myv"
22554     ],
22555     [
22556         "Mazanderani",
22557         "مازِرونی",
22558         "mzn"
22559     ],
22560     [
22561         "Nauru",
22562         "Dorerin Naoero",
22563         "na"
22564     ],
22565     [
22566         "Nāhuatl",
22567         "Nāhuatl",
22568         "nah"
22569     ],
22570     [
22571         "Neapolitan",
22572         "Napulitano",
22573         "nap"
22574     ],
22575     [
22576         "Low German",
22577         "Plattdüütsch",
22578         "nds"
22579     ],
22580     [
22581         "Low Saxon",
22582         "Nedersaksies",
22583         "nds-nl"
22584     ],
22585     [
22586         "Nepali",
22587         "नेपाली",
22588         "ne"
22589     ],
22590     [
22591         "Newari",
22592         "नेपाल भाषा",
22593         "new"
22594     ],
22595     [
22596         "Dutch",
22597         "Nederlands",
22598         "nl"
22599     ],
22600     [
22601         "Norwegian Nynorsk",
22602         "norsk nynorsk",
22603         "nn"
22604     ],
22605     [
22606         "Norwegian",
22607         "norsk bokmål",
22608         "no"
22609     ],
22610     [
22611         "Novial",
22612         "Novial",
22613         "nov"
22614     ],
22615     [
22616         "Nouormand",
22617         "Nouormand",
22618         "nrm"
22619     ],
22620     [
22621         "Northern Sotho",
22622         "Sesotho sa Leboa",
22623         "nso"
22624     ],
22625     [
22626         "Navajo",
22627         "Diné bizaad",
22628         "nv"
22629     ],
22630     [
22631         "Nyanja",
22632         "Chi-Chewa",
22633         "ny"
22634     ],
22635     [
22636         "Occitan",
22637         "occitan",
22638         "oc"
22639     ],
22640     [
22641         "Livvi-Karelian",
22642         "Livvinkarjala",
22643         "olo"
22644     ],
22645     [
22646         "Oromo",
22647         "Oromoo",
22648         "om"
22649     ],
22650     [
22651         "Odia",
22652         "ଓଡ଼ିଆ",
22653         "or"
22654     ],
22655     [
22656         "Ossetic",
22657         "Ирон",
22658         "os"
22659     ],
22660     [
22661         "Punjabi",
22662         "ਪੰਜਾਬੀ",
22663         "pa"
22664     ],
22665     [
22666         "Pangasinan",
22667         "Pangasinan",
22668         "pag"
22669     ],
22670     [
22671         "Pampanga",
22672         "Kapampangan",
22673         "pam"
22674     ],
22675     [
22676         "Papiamento",
22677         "Papiamentu",
22678         "pap"
22679     ],
22680     [
22681         "Picard",
22682         "Picard",
22683         "pcd"
22684     ],
22685     [
22686         "Pennsylvania German",
22687         "Deitsch",
22688         "pdc"
22689     ],
22690     [
22691         "Palatine German",
22692         "Pälzisch",
22693         "pfl"
22694     ],
22695     [
22696         "Pali",
22697         "पालि",
22698         "pi"
22699     ],
22700     [
22701         "Norfuk / Pitkern",
22702         "Norfuk / Pitkern",
22703         "pih"
22704     ],
22705     [
22706         "Polish",
22707         "polski",
22708         "pl"
22709     ],
22710     [
22711         "Piedmontese",
22712         "Piemontèis",
22713         "pms"
22714     ],
22715     [
22716         "Western Punjabi",
22717         "پنجابی",
22718         "pnb"
22719     ],
22720     [
22721         "Pontic",
22722         "Ποντιακά",
22723         "pnt"
22724     ],
22725     [
22726         "Pashto",
22727         "پښتو",
22728         "ps"
22729     ],
22730     [
22731         "Portuguese",
22732         "português",
22733         "pt"
22734     ],
22735     [
22736         "Quechua",
22737         "Runa Simi",
22738         "qu"
22739     ],
22740     [
22741         "Romansh",
22742         "rumantsch",
22743         "rm"
22744     ],
22745     [
22746         "Romani",
22747         "Romani",
22748         "rmy"
22749     ],
22750     [
22751         "Rundi",
22752         "Kirundi",
22753         "rn"
22754     ],
22755     [
22756         "Romanian",
22757         "română",
22758         "ro"
22759     ],
22760     [
22761         "Aromanian",
22762         "armãneashti",
22763         "roa-rup"
22764     ],
22765     [
22766         "tarandíne",
22767         "tarandíne",
22768         "roa-tara"
22769     ],
22770     [
22771         "Russian",
22772         "русский",
22773         "ru"
22774     ],
22775     [
22776         "Rusyn",
22777         "русиньскый",
22778         "rue"
22779     ],
22780     [
22781         "Kinyarwanda",
22782         "Kinyarwanda",
22783         "rw"
22784     ],
22785     [
22786         "Sanskrit",
22787         "संस्कृतम्",
22788         "sa"
22789     ],
22790     [
22791         "Sakha",
22792         "саха тыла",
22793         "sah"
22794     ],
22795     [
22796         "Sardinian",
22797         "sardu",
22798         "sc"
22799     ],
22800     [
22801         "Sicilian",
22802         "sicilianu",
22803         "scn"
22804     ],
22805     [
22806         "Scots",
22807         "Scots",
22808         "sco"
22809     ],
22810     [
22811         "Sindhi",
22812         "سنڌي",
22813         "sd"
22814     ],
22815     [
22816         "Northern Sami",
22817         "sámegiella",
22818         "se"
22819     ],
22820     [
22821         "Sango",
22822         "Sängö",
22823         "sg"
22824     ],
22825     [
22826         "Serbo-Croatian",
22827         "srpskohrvatski / српскохрватски",
22828         "sh"
22829     ],
22830     [
22831         "Sinhala",
22832         "සිංහල",
22833         "si"
22834     ],
22835     [
22836         "Simple English",
22837         "Simple English",
22838         "simple"
22839     ],
22840     [
22841         "Slovak",
22842         "slovenčina",
22843         "sk"
22844     ],
22845     [
22846         "Slovenian",
22847         "slovenščina",
22848         "sl"
22849     ],
22850     [
22851         "Samoan",
22852         "Gagana Samoa",
22853         "sm"
22854     ],
22855     [
22856         "Shona",
22857         "chiShona",
22858         "sn"
22859     ],
22860     [
22861         "Somali",
22862         "Soomaaliga",
22863         "so"
22864     ],
22865     [
22866         "Albanian",
22867         "shqip",
22868         "sq"
22869     ],
22870     [
22871         "Serbian",
22872         "српски / srpski",
22873         "sr"
22874     ],
22875     [
22876         "Sranan Tongo",
22877         "Sranantongo",
22878         "srn"
22879     ],
22880     [
22881         "Swati",
22882         "SiSwati",
22883         "ss"
22884     ],
22885     [
22886         "Southern Sotho",
22887         "Sesotho",
22888         "st"
22889     ],
22890     [
22891         "Saterland Frisian",
22892         "Seeltersk",
22893         "stq"
22894     ],
22895     [
22896         "Sundanese",
22897         "Basa Sunda",
22898         "su"
22899     ],
22900     [
22901         "Swedish",
22902         "svenska",
22903         "sv"
22904     ],
22905     [
22906         "Swahili",
22907         "Kiswahili",
22908         "sw"
22909     ],
22910     [
22911         "Silesian",
22912         "ślůnski",
22913         "szl"
22914     ],
22915     [
22916         "Tamil",
22917         "தமிழ்",
22918         "ta"
22919     ],
22920     [
22921         "Tulu",
22922         "ತುಳು",
22923         "tcy"
22924     ],
22925     [
22926         "Telugu",
22927         "తెలుగు",
22928         "te"
22929     ],
22930     [
22931         "Tetum",
22932         "tetun",
22933         "tet"
22934     ],
22935     [
22936         "Tajik",
22937         "тоҷикӣ",
22938         "tg"
22939     ],
22940     [
22941         "Thai",
22942         "ไทย",
22943         "th"
22944     ],
22945     [
22946         "Tigrinya",
22947         "ትግርኛ",
22948         "ti"
22949     ],
22950     [
22951         "Turkmen",
22952         "Türkmençe",
22953         "tk"
22954     ],
22955     [
22956         "Tagalog",
22957         "Tagalog",
22958         "tl"
22959     ],
22960     [
22961         "Tswana",
22962         "Setswana",
22963         "tn"
22964     ],
22965     [
22966         "Tongan",
22967         "lea faka-Tonga",
22968         "to"
22969     ],
22970     [
22971         "Tok Pisin",
22972         "Tok Pisin",
22973         "tpi"
22974     ],
22975     [
22976         "Turkish",
22977         "Türkçe",
22978         "tr"
22979     ],
22980     [
22981         "Tsonga",
22982         "Xitsonga",
22983         "ts"
22984     ],
22985     [
22986         "Tatar",
22987         "татарча/tatarça",
22988         "tt"
22989     ],
22990     [
22991         "Tumbuka",
22992         "chiTumbuka",
22993         "tum"
22994     ],
22995     [
22996         "Twi",
22997         "Twi",
22998         "tw"
22999     ],
23000     [
23001         "Tahitian",
23002         "reo tahiti",
23003         "ty"
23004     ],
23005     [
23006         "Tuvinian",
23007         "тыва дыл",
23008         "tyv"
23009     ],
23010     [
23011         "Udmurt",
23012         "удмурт",
23013         "udm"
23014     ],
23015     [
23016         "Uyghur",
23017         "ئۇيغۇرچە / Uyghurche",
23018         "ug"
23019     ],
23020     [
23021         "Ukrainian",
23022         "українська",
23023         "uk"
23024     ],
23025     [
23026         "Urdu",
23027         "اردو",
23028         "ur"
23029     ],
23030     [
23031         "Uzbek",
23032         "oʻzbekcha/ўзбекча",
23033         "uz"
23034     ],
23035     [
23036         "Venda",
23037         "Tshivenda",
23038         "ve"
23039     ],
23040     [
23041         "Venetian",
23042         "vèneto",
23043         "vec"
23044     ],
23045     [
23046         "Veps",
23047         "vepsän kel’",
23048         "vep"
23049     ],
23050     [
23051         "Vietnamese",
23052         "Tiếng Việt",
23053         "vi"
23054     ],
23055     [
23056         "West Flemish",
23057         "West-Vlams",
23058         "vls"
23059     ],
23060     [
23061         "Volapük",
23062         "Volapük",
23063         "vo"
23064     ],
23065     [
23066         "Walloon",
23067         "walon",
23068         "wa"
23069     ],
23070     [
23071         "Waray",
23072         "Winaray",
23073         "war"
23074     ],
23075     [
23076         "Wolof",
23077         "Wolof",
23078         "wo"
23079     ],
23080     [
23081         "Wu Chinese",
23082         "吴语",
23083         "wuu"
23084     ],
23085     [
23086         "Kalmyk",
23087         "хальмг",
23088         "xal"
23089     ],
23090     [
23091         "Xhosa",
23092         "isiXhosa",
23093         "xh"
23094     ],
23095     [
23096         "Mingrelian",
23097         "მარგალური",
23098         "xmf"
23099     ],
23100     [
23101         "Yiddish",
23102         "ייִדיש",
23103         "yi"
23104     ],
23105     [
23106         "Yoruba",
23107         "Yorùbá",
23108         "yo"
23109     ],
23110     [
23111         "Zhuang",
23112         "Vahcuengh",
23113         "za"
23114     ],
23115     [
23116         "Zeelandic",
23117         "Zeêuws",
23118         "zea"
23119     ],
23120     [
23121         "Chinese",
23122         "中文",
23123         "zh"
23124     ],
23125     [
23126         "Classical Chinese",
23127         "文言",
23128         "zh-classical"
23129     ],
23130     [
23131         "Chinese (Min Nan)",
23132         "Bân-lâm-gú",
23133         "zh-min-nan"
23134     ],
23135     [
23136         "Cantonese",
23137         "粵語",
23138         "zh-yue"
23139     ],
23140     [
23141         "Zulu",
23142         "isiZulu",
23143         "zu"
23144     ]
23145 ];
23146
23147 var wikipedia$2 = Object.freeze({
23148         default: wikipedia$1
23149 });
23150
23151 var require$$6 = ( wikipedia$2 && wikipedia$1 ) || wikipedia$2;
23152
23153 var wikipedia = require$$6;
23154
23155 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},"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}}};
23156 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}}};
23157 var man_made = {"windmill":{"De Hoop":{"count":57}}};
23158 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}},"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},"Citroën":{"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},"Citroën":{"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},"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},"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},"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},"Ahorramás":{"count":66},"Albert":{"count":245},"Albert Heijn":{"count":766},"Albertsons":{"count":316},"Aldi":{"count":6323},"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},"NORMA":{"count":144},"NP":{"count":251},"Nah & Frisch":{"count":107},"Nahkauf":{"count":324},"Netto":{"count":4429},"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},"Ralphs":{"count":81},"Real":{"count":210},"Real Canadian Superstore":{"count":69},"Reliance Fresh":{"count":95},"Rema 1000":{"count":394},"Rewe":{"count":2808},"Rewe City":{"count":78},"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}}};
23159 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}}};
23160 var dataSuggestions = {
23161         amenity: amenity,
23162         leisure: leisure,
23163         man_made: man_made,
23164         shop: shop,
23165         tourism: tourism
23166 };
23167
23168 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":["at","ch","de"],"format":[["street","housenumber"],["postcode","city"]]},{"countryCodes":["ad","ba","be","cz","dk","es","fi","gr","hr","is","it","li","nl","no","pt","se","si","sk","sm","va"],"format":[["unit","street","housenumber"],["postcode","city"]]},{"countryCodes":["pl"],"format":[["street","housenumber"],["postcode"],["place","city"]]},{"countryCodes":["fr","lu","mo"],"format":[["unit","housenumber","street"],["postcode","city"]]},{"countryCodes":["br"],"format":[["street"],["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"]]}];
23169
23170 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"}}];
23171
23172 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"];
23173
23174 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}};
23175
23176 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","at":"+43 1 123 45 67","ci":"+225 20 12 34 56","bj":"+229 20 12 34 56"};
23177
23178 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"}]}]}];
23179
23180 var type$2 = "FeatureCollection";
23181 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]]]}}];
23182 var dataImperial = {
23183         type: type$2,
23184         features: features
23185 };
23186
23187 var type$3 = "FeatureCollection";
23188 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]]]}}];
23189 var dataDriveLeft = {
23190         type: type$3,
23191         features: features$1
23192 };
23193
23194 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","download_changes":"Download osmChange file","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","source":"Source","description":"Description","resolution":"Resolution","accuracy":"Accuracy","unknown":"Unknown","show_tiles":"Show Tiles","hide_tiles":"Hide Tiles","show_vintage":"Show Vintage","hide_vintage":"Hide Vintage"},"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","layers":{"osm":{"tooltip":"Map data from OpenStreetMap","title":"OpenStreetMap data"}},"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.","osmhidden":"These features have been automatically hidden because the OpenStreetMap layer is hidden."},"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 osmChange file","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"},"openstreetcam_images":{"tooltip":"Street-level photos from OpenStreetCam","title":"Photo Overlay (OpenStreetCam)"},"openstreetcam":{"view_on_openstreetcam":"View this image on OpenStreetCam"},"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 on it on\nthe map. This will highlight the selected feature and load a sidebar with\ndetails about it. If you right-click on it, it will show a menu of things\nyou 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 contour\naround those features. All the points inside the lasso area will be selected.\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 'Upload' to post the changes to\n[OpenStreetMap.org](http://www.openstreetmap.org/), where they will be 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 sidebar showing more information about the road. If you right-click\non it, you'll have a menu of actions you can apply on 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 right-click on it and select the 'Move' tool, or simply press\nthe `M` shortcut key, to move the entire road at one time, and then click\nagain 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 pressing the 'Delete'\nkey or right-clicking it and then clicking the trash can icon.\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 load a sidebar showing more information about the building.\nIf you right-click on it, it will show a menu of actions you can execute\nin the building.\n\n### Modifying\n\nSometimes buildings are incorrectly placed or have incorrect tags.\n\nTo move an entire building, select it and press the 'M' shortcut key,\nor right-click it and select 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 pressing the 'Delete'\nkey, or right-clicking it and then clicking the trash can icon.\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 bottom of the\nsidebar, you can see which relations a feature is a member of, and click on a\nrelation there will select it. When the relation is selected, you can see all of\nits members 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\npress the 'C' shortcut key. Other option is to select both, and then right-click one\nof the and click 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":{"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"},"agrarian":{"label":"Products"},"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"},"boules":{"label":"Type"},"boundary":{"label":"Type"},"brand":{"label":"Brand"},"bridge":{"label":"Type","placeholder":"Default"},"building_area":{"label":"Building"},"building":{"label":"Building"},"bunker_type":{"label":"Type"},"cables":{"label":"Cables","placeholder":"1, 2, 3..."},"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"},"crane/type":{"label":"Crane Type","options":{"portal_crane":"Portal Crane","floor-mounted_crane":"Floor-mounted Crane","travel_lift":"Travel Lift"}},"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"},"devices":{"label":"Devices","placeholder":"1, 2, 3..."},"diaper":{"label":"Diaper Changing Available"},"display":{"label":"Display"},"dock":{"label":"Type"},"drive_through":{"label":"Drive-Through"},"duration":{"label":"Duration","placeholder":"00:00"},"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"}},"fitness_station":{"label":"Equipment Type"},"fixme":{"label":"Fix Me"},"ford":{"label":"Type","placeholder":"Default"},"frequency":{"label":"Operating Frequency"},"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"},"government":{"label":"Type"},"grape_variety":{"label":"Grape Varieties"},"handicap":{"label":"Handicap","placeholder":"1-18"},"handrail":{"label":"Handrail"},"hashtags":{"label":"Suggested Hashtags","placeholder":"#example"},"healthcare":{"label":"Type"},"healthcare/speciality":{"label":"Specialties"},"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"},"intermittent":{"label":"Intermittent"},"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"},"memorial":{"label":"Type"},"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"},"phases":{"label":"Phases","placeholder":"1, 2, 3..."},"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..."},"playground/baby":{"label":"Baby Seat"},"playground/max_age":{"label":"Maximum Age"},"playground/min_age":{"label":"Minimum Age"},"population":{"label":"Population"},"power_supply":{"label":"Power Supply"},"power":{"label":"Type"},"produce":{"label":"Produce"},"product":{"label":"Products"},"railway":{"label":"Type"},"rating":{"label":"Power Rating"},"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_waterway":{"label":"Structure","placeholder":"Unknown","options":{"tunnel":"Tunnel"}},"structure":{"label":"Structure","placeholder":"Unknown","options":{"bridge":"Bridge","tunnel":"Tunnel","embankment":"Embankment","cutting":"Cutting","ford":"Ford"}},"studio":{"label":"Type"},"substance":{"label":"Substance"},"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"},"switch":{"label":"Type","options":{"mechanical":"Mechanical","circuit_breaker":"Circuit Breaker","disconnector":"Disconnector","earthing":"Earthing"}},"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_attraction":{"label":"Tourism"},"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"}},"trade":{"label":"Type"},"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"}},"transformer":{"label":"Type","options":{"distribution":"Distribution","generator":"Generator","converter":"Converter","traction":"Traction","auto":"Autotransformer","phase_angle_regulator":"Phase Angle Regulator","auxiliary":"Auxiliary","yes":"Unknown"}},"trees":{"label":"Trees"},"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)"}},"volcano/status":{"label":"Volcano Status","options":{"active":"Active","dormant":"Dormant","extinct":"Extinct"}},"volcano/type":{"label":"Volcano Type","options":{"stratovolcano":"Stratovolcano","shield":"Shield","scoria":"Scoria"}},"voltage":{"label":"Voltage"},"voltage/primary":{"label":"Primary Voltage"},"voltage/secondary":{"label":"Secondary Voltage"},"voltage/tertiary":{"label":"Tertiary Voltage"},"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"},"windings":{"label":"Windings","placeholder":"1, 2, 3..."},"windings/configuration":{"label":"Windings Configuration","options":{"star":"Star / Wye","delta":"Delta","open-delta":"Open Delta","zigzag":"Zig Zag","open":"Open","scott":"Scott","leblanc":"Leblanc"}}},"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/scrapyard":{"name":"Scrap Yard","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/clinic/abortion":{"name":"Abortion Clinic","terms":""},"amenity/clinic/fertility":{"name":"Fertility Clinic","terms":"egg,fertility,reproductive,sperm,ovulation"},"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/music_school":{"name":"Music School","terms":"school of music"},"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/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/feminine_hygiene":{"name":"Feminine Hygiene Vending Machine","terms":"condom,tampon,pad,woman,women,menstrual hygiene products,personal care"},"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/chimney_sweeper":{"name":"Chimney Sweeper","terms":""},"craft/clockmaker":{"name":"Clockmaker","terms":""},"craft/confectionery":{"name":"Candy Maker","terms":"sweet,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/sculptor":{"name":"Sculptor","terms":""},"craft/shoemaker":{"name":"Shoemaker","terms":"cobbler"},"craft/stonemason":{"name":"Stonemason","terms":"masonry"},"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-raised":{"name":"Raised Street Crossing","terms":"flat top,hump,speed,slow"},"footway/crossing":{"name":"Street Crossing","terms":""},"footway/crosswalk-raised":{"name":"Raised Pedestrian Crosswalk","terms":"zebra crossing,flat top,hump,speed,slow"},"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":{"name":"Healthcare Facility","terms":"clinic,doctor,disease,health,institution,sick,surgery,wellness"},"healthcare/alternative":{"name":"Alternative Medicine","terms":"acupuncture,anthroposophical,applied kinesiology,aromatherapy,ayurveda,herbalism,homeopathy,hydrotherapy,hypnosis,naturopathy,osteopathy,reflexology,reiki,shiatsu,traditional,tuina,unani"},"healthcare/alternative/chiropractic":{"name":"Chiropractor","terms":"back,pain,spine"},"healthcare/audiologist":{"name":"Audiologist","terms":"ear,hearing,sound"},"healthcare/birthing_center":{"name":"Birthing Center","terms":"baby,childbirth,delivery,labour,labor,pregnancy"},"healthcare/blood_donation":{"name":"Blood Donor Center","terms":"blood bank,blood donation,blood transfusion,apheresis,plasmapheresis,plateletpheresis,stem cell donation"},"healthcare/hospice":{"name":"Hospice","terms":"terminal,illness"},"healthcare/midwife":{"name":"Midwife","terms":"baby,childbirth,delivery,labour,labor,pregnancy"},"healthcare/occupational_therapist":{"name":"Occupational Therapist","terms":"therapist,therapy"},"healthcare/optometrist":{"name":"Optometrist","terms":"eye,glasses,lasik,lenses,vision"},"healthcare/physiotherapist":{"name":"Physiotherapist","terms":"physical,therapist,therapy"},"healthcare/podiatrist":{"name":"Podiatrist","terms":"foot,feet,nails"},"healthcare/psychotherapist":{"name":"Psychotherapist","terms":"anxiety,counselor,depression,mental health,mind,suicide,therapist,therapy"},"healthcare/rehabilitation":{"name":"Rehabilitation Facility","terms":"rehab,therapist,therapy"},"healthcare/speech_therapist":{"name":"Speech Therapist","terms":"speech,therapist,therapy,voice"},"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-raised":{"name":"Raised Street Crossing","terms":"flat top,hump,speed,slow"},"highway/crossing":{"name":"Street Crossing","terms":""},"highway/crosswalk-raised":{"name":"Raised Pedestrian Crosswalk","terms":"zebra crossing,flat top,hump,speed,slow"},"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_area":{"name":"Pedestrian Area","terms":"center,centre,plaza,quad,square,walkway"},"highway/pedestrian_line":{"name":"Pedestrian Street","terms":"center,centre,plaza,quad,square,walkway"},"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/brownfield":{"name":"Brownfield","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/greenfield":{"name":"Greenfield","terms":""},"landuse/harbour":{"name":"Harbor","terms":"boat"},"landuse/industrial":{"name":"Industrial Area","terms":""},"landuse/industrial/scrap_yard":{"name":"Scrap Yard","terms":"car,junk,metal,salvage,scrap,u-pull-it,vehicle,wreck,yard"},"landuse/industrial/slaughterhouse":{"name":"Slaughterhouse","terms":"abattoir,beef,butchery,calf,chicken,cow,killing house,meat,pig,pork,poultry,shambles,stockyard"},"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/religious":{"name":"Religious Area","terms":""},"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":"bowling center"},"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":"exercise,fitness,gym,trim trail"},"leisure/fitness_station/balance_beam":{"name":"Exercise Balance Beam","terms":"balance,exercise,fitness,gym,trim trail"},"leisure/fitness_station/box":{"name":"Exercise Box","terms":"box,exercise,fitness,gym,jump,trim trail"},"leisure/fitness_station/horizontal_bar":{"name":"Exercise Horizontal Bar","terms":"bar,chinup,chin up,exercise,fitness,gym,pullup,pull up,trim trail"},"leisure/fitness_station/horizontal_ladder":{"name":"Exercise Monkey Bars","terms":"bar,chinup,chin up,exercise,fitness,gym,ladder,monkey bars,pullup,pull up,trim trail"},"leisure/fitness_station/hyperextension":{"name":"Hyperextension Station","terms":"back,exercise,extension,fitness,gym,roman chair,trim trail"},"leisure/fitness_station/parallel_bars":{"name":"Parallel Bars","terms":"bar,dip,exercise,fitness,gym,trim trail"},"leisure/fitness_station/push-up":{"name":"Push-Up Station","terms":"bar,exercise,fitness,gym,pushup,push up,trim trail"},"leisure/fitness_station/rings":{"name":"Exercise Rings","terms":"exercise,fitness,gym,muscle up,pullup,pull up,trim trail"},"leisure/fitness_station/sign":{"name":"Exercise Instruction Sign","terms":"exercise,fitness,gym,trim trail"},"leisure/fitness_station/sit-up":{"name":"Sit-Up Station","terms":"crunch,exercise,fitness,gym,situp,sit up,trim trail"},"leisure/fitness_station/stairs":{"name":"Exercise Stairs","terms":"exercise,fitness,gym,steps,trim trail"},"leisure/garden":{"name":"Garden","terms":""},"leisure/golf_course":{"name":"Golf Course","terms":"links"},"leisure/hackerspace":{"name":"Hackerspace","terms":"makerspace,hackspace,hacklab"},"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/boules":{"name":"Boules/Bocce Court","terms":"bocce,lyonnaise,pétanque"},"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/sauna":{"name":"Sauna","terms":""},"leisure/slipway":{"name":"Slipway","terms":"boat launch,boat ramp"},"leisure/sports_centre":{"name":"Sports Center / Complex","terms":""},"leisure/sports_centre/swimming":{"name":"Swimming Pool Facility","terms":"dive,water"},"leisure/stadium":{"name":"Stadium","terms":""},"leisure/swimming_pool":{"name":"Swimming Pool","terms":"dive,water"},"leisure/track":{"name":"Racetrack (Non-Motorsport)","terms":"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/crane":{"name":"Crane","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":"trig point,triangulation pillar,trigonometrical station"},"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 Office","terms":""},"office/administrative":{"name":"Administrative Office","terms":""},"office/adoption_agency":{"name":"Adoption Agency","terms":""},"office/advertising_agency":{"name":"Advertising Agency","terms":"ad,ad agency,advert agency,advertising,marketing"},"office/architect":{"name":"Architect Office","terms":""},"office/association":{"name":"Nonprofit Organization Office","terms":"association,non-profit,nonprofit,organization,society"},"office/charity":{"name":"Charity Office","terms":"charitable organization"},"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/energy_supplier":{"name":"Energy Supplier Office","terms":"electricity,energy company,energy utility,gas utility"},"office/estate_agent":{"name":"Real Estate Office","terms":""},"office/financial":{"name":"Financial Office","terms":""},"office/forestry":{"name":"Forestry Office","terms":"forest,ranger"},"office/foundation":{"name":"Foundation Office","terms":""},"office/government":{"name":"Government Office","terms":""},"office/government/register_office":{"name":"Register Office","terms":"clerk,marriage,death,birth,certificate"},"office/government/tax":{"name":"Tax and Revenue Office","terms":"fiscal authorities,revenue office,tax office"},"office/guide":{"name":"Tour Guide Office","terms":"dive guide,mountain guide,tour guide"},"office/insurance":{"name":"Insurance Office","terms":""},"office/it":{"name":"Information Technology Office","terms":"computer,information,software,technology"},"office/lawyer":{"name":"Law Office","terms":""},"office/lawyer/notary":{"name":"Notary Office","terms":"clerk,signature,wills,deeds,estate"},"office/moving_company":{"name":"Moving Company Office","terms":"relocation"},"office/newspaper":{"name":"Newspaper Office","terms":""},"office/ngo":{"name":"NGO Office","terms":"ngo,non government,non-government,organization,organisation"},"office/notary":{"name":"Notary Office","terms":""},"office/political_party":{"name":"Political Party","terms":""},"office/private_investigator":{"name":"Private Investigator Office","terms":"PI,private eye,private detective"},"office/quango":{"name":"Quasi-NGO Office","terms":"ngo,non government,non-government,organization,organisation,quasi autonomous,quasi-autonomous"},"office/research":{"name":"Research Office","terms":""},"office/surveyor":{"name":"Surveyor Office","terms":""},"office/tax_advisor":{"name":"Tax Advisor Office","terms":"tax,tax consultant"},"office/telecommunication":{"name":"Telecom Office","terms":""},"office/therapist":{"name":"Therapist Office","terms":"therapy"},"office/water_utility":{"name":"Water Utility Office","terms":"water board,utility"},"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/islet":{"name":"Islet","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/plot":{"name":"Plot","terms":"tract,land,lot,parcel"},"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":""},"playground/balance_beam":{"name":"Play Balance Beam","terms":""},"playground/basket_spinner":{"name":"Basket Spinner","terms":"basket rotator"},"playground/basket_swing":{"name":"Basket Swing","terms":""},"playground/climbing_frame":{"name":"Climbing Frame","terms":""},"playground/cushion":{"name":"Bouncy Cushion","terms":""},"playground/horizontal_bar":{"name":"Play Horizontal Bar","terms":"high bar"},"playground/rocker":{"name":"Spring Rider","terms":"spring rocker,springy rocker"},"playground/roundabout":{"name":"Play Roundabout","terms":"merry-go-round"},"playground/sandpit":{"name":"Sandpit","terms":""},"playground/seesaw":{"name":"Seesaw","terms":""},"playground/slide":{"name":"Slide","terms":""},"playground/structure":{"name":"Play Structure","terms":""},"playground/swing":{"name":"Swing","terms":""},"playground/zipwire":{"name":"Zip Wire","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/switch":{"name":"Power Switch","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/light_rail":{"name":"Light Rail","terms":"light rail,streetcar,trolley"},"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/furnace":{"name":"Furnace Store","terms":"oven,stove"},"shop/vacant":{"name":"Vacant Shop","terms":""},"shop/agrarian":{"name":"Agriculture Shop","terms":"agricultural inputs,agricultural machines,seeds,pesticides,fertilizer,agricultural tools"},"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":"sweet"},"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/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/tiles":{"name":"Tile Shop","terms":""},"shop/tobacco":{"name":"Tobacco Shop","terms":""},"shop/toys":{"name":"Toy Store","terms":""},"shop/trade":{"name":"Trade Shop","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":"climbing hut"},"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":"Holiday Cottage","terms":"holiday,holiday cottage,holiday home,vacation,vacation home"},"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/wilderness_hut":{"name":"Wilderness Hut","terms":"wilderness hut,backcountry hut,bothy"},"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":"Speed Table","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":""},"type/waterway":{"name":"Waterway","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_intermittent":{"name":"Intermittent Stream","terms":"arroyo,beck,branch,brook,burn,course,creek,drift,flood,flow,gully,run,runnel,rush,spate,spritz,tributary,wadi,wash,watercourse"},"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-Premium-vintage":{"attribution":{"text":"Terms & Feedback"},"description":"Imagery boundaries and capture dates. Labels appear at zoom level 14 and higher.","name":"DigitalGlobe Premium Imagery Vintage"},"DigitalGlobe-Standard":{"attribution":{"text":"Terms & Feedback"},"description":"Standard DigitalGlobe satellite imagery.","name":"DigitalGlobe Standard Imagery"},"DigitalGlobe-Standard-vintage":{"attribution":{"text":"Terms & Feedback"},"description":"Imagery boundaries and capture dates. Labels appear at zoom level 14 and higher.","name":"DigitalGlobe Standard Imagery Vintage"},"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"},"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"},"US-TIGER-Roads-2012":{"name":"TIGER Roads 2012"},"US-TIGER-Roads-2014":{"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":"TIGER Roads 2014"},"US-TIGER-Roads-2017":{"description":"Yellow = Public domain map data from the US Census. Red = Data not found in OpenStreetMap","name":"TIGER Roads 2017"},"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"}}};
23195
23196 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, Malaysia, Myanmar bilingual","type":"tms","template":"http://{switch:a,b,c,d}.tile.osm-tools.org/osm/{zoom}/{x}/{y}.png","scaleExtent":[0,20],"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,d}.tiles.mapbox.com/v4/digitalglobe.316c9a2e/{zoom}/{x}/{y}.png?access_token=pk.eyJ1IjoiZGlnaXRhbGdsb2JlIiwiYSI6ImNqOGRmNXltOTBucm0yd3BtY3E5czl6NmYifQ.qJJsPgCjyzMCm3YG3YWQBQ","scaleExtent":[0,22],"terms_url":"https://wiki.openstreetmap.org/wiki/DigitalGlobe","terms_text":"Terms & Feedback","default":true,"description":"Premium DigitalGlobe satellite imagery.","icon":"data:image/png;base64,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"},{"id":"DigitalGlobe-Premium-vintage","name":"DigitalGlobe Premium Imagery Vintage","type":"tms","template":"https://{switch:a,b,c,d}.tiles.mapbox.com/v4/digitalglobe.2850d66c/{zoom}/{x}/{y}.png?access_token=pk.eyJ1IjoiZGlnaXRhbGdsb2JlIiwiYSI6ImNqOTBkcmZjNzJ5ZnozNHF6NnVkOGd6ODYifQ.grAnqgpCjOaeq-ozqt4QNw","scaleExtent":[0,22],"terms_url":"https://wiki.openstreetmap.org/wiki/DigitalGlobe","terms_text":"Terms & Feedback","description":"Imagery boundaries and capture dates. Labels appear at zoom level 14 and higher.","icon":"data:image/png;base64,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","overlay":true},{"id":"DigitalGlobe-Standard","name":"DigitalGlobe Standard Imagery","type":"tms","template":"https://{switch:a,b,c,d}.tiles.mapbox.com/v4/digitalglobe.0a8e44ba/{zoom}/{x}/{y}.png?access_token=pk.eyJ1IjoiZGlnaXRhbGdsb2JlIiwiYSI6ImNqOGRmNW9qZjBudmgzMnA1a294OGRtNm8ifQ.06mo-nDisy4KmqjYxEVwQw","scaleExtent":[0,22],"terms_url":"https://wiki.openstreetmap.org/wiki/DigitalGlobe","terms_text":"Terms & Feedback","default":true,"description":"Standard DigitalGlobe satellite imagery.","icon":"data:image/png;base64,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"},{"id":"DigitalGlobe-Standard-vintage","name":"DigitalGlobe Standard Imagery Vintage","type":"tms","template":"https://{switch:a,b,c,d}.tiles.mapbox.com/v4/digitalglobe.1412531a/{zoom}/{x}/{y}.png?access_token=pk.eyJ1IjoiZGlnaXRhbGdsb2JlIiwiYSI6ImNqOTBlYWJ1ZDAza2YyeG14NWVodTA4OWUifQ.wVc8ZOuPuYVw39lhS2j3_g","scaleExtent":[0,22],"terms_url":"https://wiki.openstreetmap.org/wiki/DigitalGlobe","terms_text":"Terms & Feedback","description":"Imagery boundaries and capture dates. Labels appear at zoom level 14 and higher.","icon":"data:image/png;base64,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","overlay":true},{"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,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"},{"id":"maaamet.ee-orto","name":"Estonia Ortho (Maaamet)","type":"tms","template":"http://kaart.maakaart.ee/orto/{zoom}/{x}/{y}.jpeg","scaleExtent":[14,18],"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,22],"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://{switch:a,b,c,d}.tiles.mapbox.com/styles/v1/wille/cirnnxni1000jg8nfppc8g7pm/tiles/256/{zoom}/{x}/{y}?access_token=pk.eyJ1Ijoid2lsbGUiLCJhIjoicFNVWk5VWSJ9.hluCd0YGvYHNlFi_utWe2g","scaleExtent":[0,20],"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":"https://{switch:a,b,c,d}.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":"https://{switch:a,b,c,d}.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":"KTBASELSTADT2017","name":"Kanton Basel-Stadt 2017","type":"tms","template":"http://mapproxy.osm.ch:8080/tiles/KTBASELSTADT2017/EPSG900913/{zoom}/{x}/{y}.png?origin=nw","scaleExtent":[8,21],"polygon":[[[7.6713752,47.5952248],[7.6799583,47.6007811],[7.6845073,47.6018228],[7.6943779,47.601707],[7.6939487,47.5966718],[7.6870823,47.5935462],[7.6788425,47.5871208],[7.685709,47.585384],[7.6890564,47.5761205],[7.6941204,47.573399],[7.6924038,47.5669132],[7.6847005,47.5617009],[7.6642513,47.5616429],[7.6487159,47.5568934],[7.6303482,47.558689],[7.6235675,47.5566617],[7.6278591,47.5514483],[7.6273763,47.5365801],[7.6183319,47.5366163],[7.6133537,47.5326179],[7.5996208,47.5191137],[7.5850296,47.5191717],[7.5840854,47.5263589],[7.5771331,47.5316327],[7.581253,47.5398612],[7.5718975,47.5414835],[7.553873,47.5414835],[7.5537872,47.5512166],[7.5565338,47.5582836],[7.5537014,47.5603108],[7.5537872,47.5747308],[7.5643444,47.5812157],[7.5793647,47.579884],[7.583313,47.5901889],[7.5856304,47.5923306],[7.5920677,47.5923885],[7.598505,47.5907098],[7.609148,47.5864261],[7.6092338,47.5810999],[7.6191043,47.580463],[7.6368713,47.593141],[7.6378154,47.595572],[7.6416778,47.5988711],[7.6452827,47.6002602],[7.664938,47.5961798],[7.6713752,47.5952248]]],"terms_text":"Kanton Basel-Stadt OF 2017","best":true},{"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":"https://{switch:a,b,c,d}.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,d}.tiles.mapbox.com/styles/v1/openstreetmap/cj8gojt0i1eau2rnn7q4mdgu7/tiles/256/{zoom}/{x}/{y}?access_token=pk.eyJ1Ijoib3BlbnN0cmVldG1hcCIsImEiOiJhNVlHd29ZIn0.ti6wATGDWOmCnCYen-Ip7Q","scaleExtent":[0,22],"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":"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":"IBGE_Salvador_Streets","name":"Nomes de Ruas IBGE Salvador-BA","type":"tms","template":"https://api.mapbox.com/styles/v1/wille/cj8lp78dn62wl2rquim47qo0g/tiles/256/{zoom}/{x}/{y}?access_token=pk.eyJ1Ijoid2lsbGUiLCJhIjoicFNVWk5VWSJ9.hluCd0YGvYHNlFi_utWe2g","scaleExtent":[0,20],"polygon":[[[-38.489742279052734,-12.811131765117107],[-38.54484558105469,-13.013924052026558],[-38.47755432128906,-13.034662471471638],[-38.33473205566406,-12.946846814654444],[-38.30005645751953,-12.906692193510644],[-38.33953857421875,-12.904349641337422],[-38.35481643676758,-12.830213284310222],[-38.38090896606445,-12.821844374997415],[-38.40717315673828,-12.867535227819912],[-38.46536636352539,-12.815985972925704],[-38.489742279052734,-12.811131765117107]]],"description":"Streets geometry and names of Salvador, Bahia. Source: Faces de Logradouro - IBGE.","overlay":true},{"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,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","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":"https://geodata.nationaalgeoregister.nl/luchtfoto/rgb/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,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"},{"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,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"},{"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":"US-TIGER-Roads-2017","name":"TIGER Roads 2017","type":"tms","template":"https://{switch:a,b,c,d}.tiles.mapbox.com/styles/v1/openstreetmapus/cj8dftc3q1ecn2tnx9qhwyj0c/tiles/256/{zoom}/{x}/{y}?access_token=pk.eyJ1Ijoib3BlbnN0cmVldG1hcHVzIiwiYSI6ImNpcnF4Ym43dDBoOXZmYW04bWhlNWdrY2EifQ.4SFexuTUuKkZeerO3dgtmw","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.1572,68.722],[-164.8554,67.0255],[-168.0022,66.0018],[-169.0087,66.0015],[-169.0075,64.9988],[-172.5143,63.8767],[-173.8197,59.7401],[-178.0001,52.2446],[-177.9993,51.2554],[-171.4689,51.8215],[-162.4025,53.9567],[-159.0076,55.0025],[-158.0191,55.0028],[-151.9963,55.9992],[-151.5003,57.9988],[-151.5013,58.992],[-138.516,58.9953],[-138.515,57.9986],[-133.9948,54.0032],[-130.0044,54.0043],[-130.0071,57.0001],[-131.9759,56.9995],[-135.123,59.7566],[-138.0072,59.9918],[-139.1716,60.4127],[-140.9874,61.0119],[-140.9684,69.9535],[-156.1769,71.5633],[-160.4136,70.7398],[-163.0218,69.9707],[-164.9717,68.9947],[-167.1572,68.722]],[[-68.2,17.8],[-64.32,17.38],[-64.64,18.36],[-65.33,18.57],[-67.9,18.67],[-68.2,17.8]],[[146.2,15.4],[145.7,15.6],[144.2,13.2],[144.8,12.9],[146.2,15.4]],[[179.99,52.2],[172,53.5],[172,52.5],[179.99,51],[179.99,52.2]]],"description":"Yellow = Public domain map data from the US Census. Red = Data not found in OpenStreetMap","icon":"data:image/png;base64,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","overlay":true},{"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"}];
23197
23198 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","vertex","area"],"tags":{"addr:*":"*"},"addTags":{},"removeTags":{},"reference":{"key":"addr"},"name":"Address","matchScore":0.15},"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/scrapyard":{"icon":"car","fields":["name","operator","address","opening_hours"],"geometry":["point","area"],"tags":{"amenity":"scrapyard"},"reference":{"key":"industrial","value":"scrap_yard"},"name":"Scrap Yard","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"],"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"],"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","operator","healthcare/speciality","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["medical","urgentcare"],"tags":{"amenity":"clinic"},"addTags":{"amenity":"clinic","healthcare":"clinic"},"removeTags":{"amenity":"clinic","healthcare":"clinic"},"reference":{"key":"amenity","value":"clinic"},"name":"Clinic"},"amenity/clinic/abortion":{"icon":"hospital","fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"geometry":["point","area"],"terms":[],"tags":{"amenity":"clinic","healthcare":"clinic","healthcare:speciality":"abortion"},"reference":{"key":"amenity","value":"clinic"},"name":"Abortion Clinic"},"amenity/clinic/fertility":{"icon":"hospital","fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["egg","fertility","reproductive","sperm","ovulation"],"tags":{"amenity":"clinic","healthcare":"clinic","healthcare:speciality":"fertility"},"reference":{"key":"amenity","value":"clinic"},"name":"Fertility 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","operator","healthcare/speciality","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["tooth","teeth"],"tags":{"amenity":"dentist"},"addTags":{"amenity":"dentist","healthcare":"dentist"},"removeTags":{"amenity":"dentist","healthcare":"dentist"},"reference":{"key":"amenity","value":"dentist"},"name":"Dentist"},"amenity/doctors":{"icon":"hospital","fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["medic*","physician"],"tags":{"amenity":"doctors"},"addTags":{"amenity":"doctors","healthcare":"doctor"},"removeTags":{"amenity":"doctors","healthcare":"doctor"},"reference":{"key":"amenity","value":"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","healthcare/speciality","address","emergency"],"geometry":["point","area"],"terms":["clinic","doctor","emergency room","health","infirmary","institution","sanatorium","sanitarium","sick","surgery","ward"],"tags":{"amenity":"hospital"},"addTags":{"amenity":"hospital","healthcare":"hospital"},"removeTags":{"amenity":"hospital","healthcare":"hospital"},"reference":{"key":"amenity","value":"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/music_school":{"icon":"school","fields":["name","operator","address"],"geometry":["point","area"],"terms":["school of music"],"tags":{"amenity":"music_school"},"name":"Music School"},"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"},"addTags":{"amenity":"pharmacy","healthcare":"pharmacy"},"removeTags":{"amenity":"pharmacy","healthcare":"pharmacy"},"reference":{"key":"amenity","value":"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_simple","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/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_simple","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/feminine_hygiene":{"icon":"poi-vending-machine","fields":["operator","payment_multi","currency_multi"],"geometry":["point"],"terms":["condom","tampon","pad","woman","women","menstrual hygiene products","personal care"],"tags":{"amenity":"vending_machine","vending":"feminine_hygiene"},"reference":{"key":"vending","value":"feminine_hygiene"},"name":"Feminine Hygiene 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"],"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":{"fields":["name"],"geometry":["area"],"tags":{"area":"yes"},"name":"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/chimney_sweeper":{"icon":"poi-chimney","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"chimney_sweeper"},"name":"Chimney Sweeper"},"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":["sweet","candy"],"tags":{"craft":"confectionery"},"name":"Candy Maker"},"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/sculptor":{"icon":"art-gallery","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"craft":"sculptor"},"name":"Sculptor"},"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/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":["ref","access","opening_hours","indoor","phone"],"geometry":["point","vertex"],"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-raised":{"fields":["crossing","access","surface","kerb","tactile_paving"],"geometry":["line"],"tags":{"highway":"footway","footway":"crossing","traffic_calming":"table"},"reference":{"key":"traffic_calming","value":"table"},"terms":["flat top","hump","speed","slow"],"name":"Raised Street Crossing"},"footway/crossing":{"fields":["crossing","access","surface","kerb","tactile_paving"],"geometry":["line"],"tags":{"highway":"footway","footway":"crossing"},"reference":{"key":"footway","value":"crossing"},"terms":[],"name":"Street Crossing"},"footway/crosswalk-raised":{"icon":"highway-footway","fields":["crossing","access","surface","kerb","tactile_paving"],"geometry":["line"],"tags":{"highway":"footway","footway":"crossing","crossing":"zebra","traffic_calming":"table"},"reference":{"key":"traffic_calming","value":"table"},"terms":["zebra crossing","flat top","hump","speed","slow"],"name":"Raised Pedestrian Crosswalk"},"footway/crosswalk":{"icon":"highway-footway","fields":["crossing","access","surface","kerb","tactile_paving"],"geometry":["line"],"tags":{"highway":"footway","footway":"crossing","crossing":"zebra"},"reference":{"key":"footway","value":"crossing"},"terms":["zebra crossing"],"name":"Pedestrian Crosswalk"},"footway/sidewalk":{"icon":"highway-footway","fields":["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":{"icon":"hospital","fields":["name","healthcare","operator","healthcare/speciality","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"healthcare":"*"},"terms":["clinic","doctor","disease","health","institution","sick","surgery","wellness"],"name":"Healthcare Facility"},"healthcare/alternative":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["acupuncture","anthroposophical","applied kinesiology","aromatherapy","ayurveda","herbalism","homeopathy","hydrotherapy","hypnosis","naturopathy","osteopathy","reflexology","reiki","shiatsu","traditional","tuina","unani"],"tags":{"healthcare":"alternative"},"name":"Alternative Medicine"},"healthcare/alternative/chiropractic":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["back","pain","spine"],"tags":{"healthcare":"alternative","healthcare:speciality":"chiropractic"},"name":"Chiropractor"},"healthcare/audiologist":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["ear","hearing","sound"],"tags":{"healthcare":"audiologist"},"name":"Audiologist"},"healthcare/birthing_center":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["baby","childbirth","delivery","labour","labor","pregnancy"],"tags":{"healthcare":"birthing_center"},"name":"Birthing Center"},"healthcare/blood_donation":{"icon":"blood-bank","fields":["name","operator","healthcare/speciality","blood_components","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["blood bank","blood donation","blood transfusion","apheresis","plasmapheresis","plateletpheresis","stem cell donation"],"tags":{"healthcare":"blood_donation"},"name":"Blood Donor Center"},"healthcare/hospice":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["terminal","illness"],"tags":{"healthcare":"hospice"},"name":"Hospice"},"healthcare/midwife":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["baby","childbirth","delivery","labour","labor","pregnancy"],"tags":{"healthcare":"midwife"},"name":"Midwife"},"healthcare/occupational_therapist":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["therapist","therapy"],"tags":{"healthcare":"occupational_therapist"},"name":"Occupational Therapist"},"healthcare/optometrist":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["eye","glasses","lasik","lenses","vision"],"tags":{"healthcare":"optometrist"},"name":"Optometrist"},"healthcare/physiotherapist":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["physical","therapist","therapy"],"tags":{"healthcare":"physiotherapist"},"name":"Physiotherapist"},"healthcare/podiatrist":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["foot","feet","nails"],"tags":{"healthcare":"podiatrist"},"name":"Podiatrist"},"healthcare/psychotherapist":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["anxiety","counselor","depression","mental health","mind","suicide","therapist","therapy"],"tags":{"healthcare":"psychotherapist"},"name":"Psychotherapist"},"healthcare/rehabilitation":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["rehab","therapist","therapy"],"tags":{"healthcare":"rehabilitation"},"name":"Rehabilitation Facility"},"healthcare/speech_therapist":{"icon":"hospital","fields":["name","operator","healthcare/speciality","building_area","address","opening_hours"],"geometry":["point","area"],"terms":["speech","therapist","therapy","voice"],"tags":{"healthcare":"speech_therapist"},"name":"Speech Therapist"},"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-raised":{"fields":["crossing","kerb","tactile_paving"],"geometry":["vertex"],"tags":{"highway":"crossing","traffic_calming":"table"},"reference":{"key":"traffic_calming","value":"table"},"terms":["flat top","hump","speed","slow"],"name":"Raised Street Crossing"},"highway/crossing":{"fields":["crossing","kerb","tactile_paving"],"geometry":["vertex"],"tags":{"highway":"crossing"},"reference":{"key":"highway","value":"crossing"},"terms":[],"name":"Street Crossing"},"highway/crosswalk-raised":{"icon":"poi-foot","fields":["crossing","kerb","tactile_paving"],"geometry":["vertex"],"tags":{"highway":"crossing","crossing":"zebra","traffic_calming":"table"},"reference":{"key":"traffic_calming","value":"table"},"terms":["zebra crossing","flat top","hump","speed","slow"],"name":"Raised Pedestrian Crosswalk"},"highway/crosswalk":{"icon":"poi-foot","fields":["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"],"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","maxspeed","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_area":{"icon":"poi-foot","fields":["name","surface","lit","width","structure","access"],"geometry":["area"],"tags":{"highway":"pedestrian","area":"yes"},"terms":["center","centre","plaza","quad","square","walkway"],"name":"Pedestrian Area"},"highway/pedestrian_line":{"icon":"highway-footway","fields":["name","surface","lit","width","oneway","structure","access"],"geometry":["line"],"tags":{"highway":"pedestrian"},"terms":["center","centre","plaza","quad","square","walkway"],"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","vertex"],"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","memorial","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/brownfield":{"geometry":["area"],"fields":["name"],"tags":{"landuse":"brownfield"},"terms":[],"name":"Brownfield"},"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/greenfield":{"geometry":["area"],"fields":["name"],"tags":{"landuse":"greenfield"},"terms":[],"name":"Greenfield"},"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/industrial/scrap_yard":{"icon":"car","fields":["name","operator","address","opening_hours"],"geometry":["point","area"],"tags":{"industrial":"scrap_yard"},"addTags":{"landuse":"industrial","industrial":"scrap_yard"},"removeTags":{"landuse":"industrial","industrial":"scrap_yard"},"reference":{"key":"industrial","value":"scrap_yard"},"terms":["car","junk","metal","salvage","scrap","u-pull-it","vehicle","wreck","yard"],"name":"Scrap Yard"},"landuse/industrial/slaughterhouse":{"icon":"slaughterhouse","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"industrial":"slaughterhouse"},"addTags":{"landuse":"industrial","industrial":"slaughterhouse"},"removeTags":{"landuse":"industrial","industrial":"slaughterhouse"},"reference":{"key":"industrial","value":"slaughterhouse"},"terms":["abattoir","beef","butchery","calf","chicken","cow","killing house","meat","pig","pork","poultry","shambles","stockyard"],"name":"Slaughterhouse"},"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/religious":{"geometry":["area"],"fields":["name"],"tags":{"landuse":"religious"},"terms":[],"name":"Religious Area"},"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":["bowling center"],"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":["fitness_station","ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station"},"addTags":{"leisure":"fitness_station","sport":"fitness"},"removeTags":{"leisure":"fitness_station","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["exercise","fitness","gym","trim trail"],"name":"Outdoor Fitness Station"},"leisure/fitness_station/balance_beam":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"balance_beam"},"addTags":{"leisure":"fitness_station","fitness_station":"balance_beam","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"balance_beam","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["balance","exercise","fitness","gym","trim trail"],"name":"Exercise Balance Beam"},"leisure/fitness_station/box":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"box"},"addTags":{"leisure":"fitness_station","fitness_station":"box","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"box","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["box","exercise","fitness","gym","jump","trim trail"],"name":"Exercise Box"},"leisure/fitness_station/horizontal_bar":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"horizontal_bar"},"addTags":{"leisure":"fitness_station","fitness_station":"horizontal_bar","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"horizontal_bar","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["bar","chinup","chin up","exercise","fitness","gym","pullup","pull up","trim trail"],"name":"Exercise Horizontal Bar"},"leisure/fitness_station/horizontal_ladder":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"horizontal_ladder"},"addTags":{"leisure":"fitness_station","fitness_station":"horizontal_ladder","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"horizontal_ladder","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["bar","chinup","chin up","exercise","fitness","gym","ladder","monkey bars","pullup","pull up","trim trail"],"name":"Exercise Monkey Bars"},"leisure/fitness_station/hyperextension":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"hyperextension"},"addTags":{"leisure":"fitness_station","fitness_station":"hyperextension","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"hyperextension","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["back","exercise","extension","fitness","gym","roman chair","trim trail"],"name":"Hyperextension Station"},"leisure/fitness_station/parallel_bars":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"parallel_bars"},"addTags":{"leisure":"fitness_station","fitness_station":"parallel_bars","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"parallel_bars","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["bar","dip","exercise","fitness","gym","trim trail"],"name":"Parallel Bars"},"leisure/fitness_station/push-up":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"push-up"},"addTags":{"leisure":"fitness_station","fitness_station":"push-up","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"push-up","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["bar","exercise","fitness","gym","pushup","push up","trim trail"],"name":"Push-Up Station"},"leisure/fitness_station/rings":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"rings"},"addTags":{"leisure":"fitness_station","fitness_station":"rings","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"rings","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["exercise","fitness","gym","muscle up","pullup","pull up","trim trail"],"name":"Exercise Rings"},"leisure/fitness_station/sign":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"sign"},"addTags":{"leisure":"fitness_station","fitness_station":"sign","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"sign","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["exercise","fitness","gym","trim trail"],"name":"Exercise Instruction Sign"},"leisure/fitness_station/sit-up":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"sit-up"},"addTags":{"leisure":"fitness_station","fitness_station":"sit-up","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"sit-up","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["crunch","exercise","fitness","gym","situp","sit up","trim trail"],"name":"Sit-Up Station"},"leisure/fitness_station/stairs":{"icon":"pitch","fields":["ref","opening_hours"],"geometry":["point","area"],"tags":{"leisure":"fitness_station","fitness_station":"stairs"},"addTags":{"leisure":"fitness_station","fitness_station":"stairs","sport":"fitness"},"removeTags":{"leisure":"fitness_station","fitness_station":"stairs","sport":"fitness"},"reference":{"key":"leisure","value":"fitness_station"},"terms":["exercise","fitness","gym","steps","trim trail"],"name":"Exercise Stairs"},"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/hackerspace":{"icon":"commercial","fields":["name","address","building_area","opening_hours","website"],"geometry":["point","area"],"terms":["makerspace","hackspace","hacklab"],"tags":{"leisure":"hackerspace"},"name":"Hackerspace"},"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/boules":{"icon":"pitch","fields":["boules","surface","lit"],"geometry":["point","area"],"tags":{"leisure":"pitch","sport":"boules"},"reference":{"key":"sport","value":"boules"},"terms":["bocce","lyonnaise","pétanque"],"name":"Boules/Bocce 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","fields":["name","operator","surface","playground/max_age","playground/min_age","access_simple"],"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/sauna":{"fields":["name","operator","address","opening_hours","access_simple","fee"],"geometry":["point","area"],"tags":{"leisure":"sauna"},"name":"Sauna"},"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":{"fields":["name"],"geometry":["line"],"tags":{},"name":"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/crane":{"icon":"poi-crane","fields":["operator","height","crane/type"],"geometry":["point","line","vertex","area"],"tags":{"man_made":"crane"},"name":"Crane"},"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","substance"],"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","vertex"],"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","vertex"],"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"],"terms":["trig point","triangulation pillar","trigonometrical station"],"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","fields":["name","intermittent"],"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","volcano/status","volcano/type"],"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","fields":["name","intermittent"],"geometry":["area"],"tags":{"natural":"water","water":"lake"},"reference":{"key":"natural","value":"water"},"terms":["lakelet","loch","mere"],"name":"Lake"},"natural/water/pond":{"icon":"water","fields":["name","intermittent"],"geometry":["area"],"tags":{"natural":"water","water":"pond"},"reference":{"key":"natural","value":"water"},"terms":["lakelet","millpond","tarn","pool","mere"],"name":"Pond"},"natural/water/reservoir":{"icon":"water","fields":["name","intermittent"],"geometry":["area"],"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":["name","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","area"],"tags":{"office":"physician"},"searchable":false,"name":"Physician"},"office/travel_agent":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","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","area"],"tags":{"office":"accountant"},"terms":[],"name":"Accountant Office"},"office/administrative":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"administrative"},"terms":[],"name":"Administrative Office"},"office/adoption_agency":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"adoption_agency"},"terms":[],"name":"Adoption Agency"},"office/advertising_agency":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"advertising_agency"},"terms":["ad","ad agency","advert agency","advertising","marketing"],"name":"Advertising Agency"},"office/architect":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"architect"},"terms":[],"name":"Architect Office"},"office/association":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"association"},"terms":["association","non-profit","nonprofit","organization","society"],"name":"Nonprofit Organization Office"},"office/charity":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"charity"},"terms":["charitable organization"],"name":"Charity Office"},"office/company":{"icon":"commercial","fields":["name","address","building_area","opening_hours","smoking"],"geometry":["point","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","area"],"tags":{"office":"educational_institution"},"terms":[],"name":"Educational Institution"},"office/employment_agency":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"employment_agency"},"terms":["job"],"name":"Employment Agency"},"office/energy_supplier":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"energy_supplier"},"terms":["electricity","energy company","energy utility","gas utility"],"name":"Energy Supplier Office"},"office/estate_agent":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"estate_agent"},"terms":[],"name":"Real Estate Office"},"office/financial":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"financial"},"terms":[],"name":"Financial Office"},"office/forestry":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"forestry"},"terms":["forest","ranger"],"name":"Forestry Office"},"office/foundation":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"foundation"},"terms":[],"name":"Foundation Office"},"office/government":{"icon":"commercial","fields":["name","government","address","building_area","opening_hours"],"geometry":["point","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/government/tax":{"icon":"town-hall","fields":["name","address","building_area","opening_hours","operator"],"geometry":["point","area"],"terms":["fiscal authorities","revenue office","tax office"],"tags":{"office":"government","government":"tax"},"reference":{"key":"government","value":"tax"},"name":"Tax and Revenue Office"},"office/guide":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"guide"},"terms":["dive guide","mountain guide","tour guide"],"name":"Tour Guide Office"},"office/insurance":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"insurance"},"terms":[],"name":"Insurance Office"},"office/it":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"it"},"terms":["computer","information","software","technology"],"name":"Information Technology Office"},"office/lawyer":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"lawyer"},"terms":[],"name":"Law Office"},"office/lawyer/notary":{"icon":"suitcase","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"lawyer","lawyer":"notary"},"reference":{"key":"office","value":"notary"},"terms":["clerk","signature","wills","deeds","estate"],"name":"Notary Office"},"office/moving_company":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"moving_company"},"terms":["relocation"],"name":"Moving Company Office"},"office/newspaper":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"newspaper"},"terms":[],"name":"Newspaper Office"},"office/ngo":{"icon":"commercial","fields":["name","address","building_area","opening_hours","smoking"],"geometry":["point","area"],"tags":{"office":"ngo"},"terms":["ngo","non government","non-government","organization","organisation"],"name":"NGO Office"},"office/notary":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"notary"},"terms":[],"name":"Notary Office"},"office/political_party":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"political_party"},"terms":[],"name":"Political Party"},"office/private_investigator":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"private_investigator"},"terms":["PI","private eye","private detective"],"name":"Private Investigator Office"},"office/quango":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"quango"},"terms":["ngo","non government","non-government","organization","organisation","quasi autonomous","quasi-autonomous"],"name":"Quasi-NGO Office"},"office/research":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"research"},"terms":[],"name":"Research Office"},"office/surveyor":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"surveyor"},"terms":[],"name":"Surveyor Office"},"office/tax_advisor":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"tax_advisor"},"terms":["tax","tax consultant"],"name":"Tax Advisor Office"},"office/telecommunication":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"telecommunication"},"terms":[],"name":"Telecom Office"},"office/therapist":{"icon":"commercial","fields":["name","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"office":"therapist"},"terms":["therapy"],"name":"Therapist Office"},"office/water_utility":{"icon":"commercial","fields":["name","address","building_area","opening_hours","operator"],"geometry":["point","area"],"tags":{"office":"water_utility"},"terms":["water board","utility"],"name":"Water Utility Office"},"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/islet":{"icon":"mountain","geometry":["point","area"],"fields":["name"],"terms":["archipelago","atoll","bar","cay","isle","islet","key","reef"],"tags":{"place":"islet"},"name":"Islet"},"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/plot":{"icon":"triangle-stroked","fields":["name"],"geometry":["point","area"],"tags":{"place":"plot"},"terms":["tract","land","lot","parcel"],"name":"Plot"},"place/quarter":{"icon":"triangle-stroked","fields":["name","population"],"geometry":["point","area"],"tags":{"place":"quarter"},"terms":["boro","borough","quarter"],"name":"Sub-Borough / Quarter"},"place/square":{"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"},"playground/balance_beam":{"icon":"playground","geometry":["point","line"],"tags":{"playground":"balancebeam"},"name":"Play Balance Beam"},"playground/basket_spinner":{"icon":"playground","geometry":["point"],"terms":["basket rotator"],"tags":{"playground":"basketrotator"},"name":"Basket Spinner"},"playground/basket_swing":{"icon":"playground","geometry":["point"],"tags":{"playground":"basketswing"},"name":"Basket Swing"},"playground/climbing_frame":{"icon":"playground","geometry":["point","area"],"tags":{"playground":"climbingframe"},"name":"Climbing Frame"},"playground/cushion":{"icon":"playground","geometry":["point","area"],"tags":{"playground":"cushion"},"name":"Bouncy Cushion"},"playground/horizontal_bar":{"icon":"pitch","fields":["height"],"geometry":["point"],"terms":["high bar"],"tags":{"playground":"horizontal_bar"},"name":"Play Horizontal Bar"},"playground/rocker":{"icon":"playground","geometry":["point"],"tags":{"playground":"springy"},"name":"Spring Rider","terms":["spring rocker","springy rocker"]},"playground/roundabout":{"icon":"stadium","fields":["bench"],"geometry":["point","area"],"tags":{"playground":"roundabout"},"name":"Play Roundabout","terms":["merry-go-round"]},"playground/sandpit":{"icon":"playground","geometry":["point","area"],"tags":{"playground":"sandpit"},"name":"Sandpit"},"playground/seesaw":{"icon":"playground","geometry":["point"],"tags":{"playground":"seesaw"},"name":"Seesaw"},"playground/slide":{"icon":"playground","geometry":["point","line"],"tags":{"playground":"slide"},"name":"Slide"},"playground/structure":{"icon":"pitch","geometry":["point","area"],"tags":{"playground":"structure"},"name":"Play Structure"},"playground/swing":{"icon":"playground","fields":["playground/baby","wheelchair"],"geometry":["point"],"tags":{"playground":"swing"},"name":"Swing"},"playground/zipwire":{"icon":"playground","geometry":["point","line"],"tags":{"playground":"zipwire"},"name":"Zip Wire"},"point":{"fields":["name"],"geometry":["point"],"tags":{},"name":"Point","matchScore":0.1},"power/sub_station":{"icon":"poi-power","fields":["substation","operator","building","ref"],"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","ref"],"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","ref"],"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","ref"],"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","fields":["name","operator","voltage","ref"],"geometry":["line"],"tags":{"power":"line"},"name":"Power Line"},"power/minor_line":{"icon":"power-line","fields":["name","operator","voltage","ref"],"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":{"fields":["ref"],"geometry":["vertex"],"tags":{"power":"pole"},"name":"Power Pole"},"power/substation":{"icon":"poi-power","fields":["substation","operator","building","ref"],"geometry":["point","area"],"tags":{"power":"substation"},"name":"Substation"},"power/switch":{"icon":"poi-power","fields":["switch","operator","location","cables","voltage","ref"],"geometry":["point","vertex","area"],"tags":{"power":"switch"},"name":"Power Switch"},"power/tower":{"fields":["ref"],"geometry":["vertex"],"tags":{"power":"tower"},"name":"High-Voltage Tower"},"power/transformer":{"icon":"poi-power","fields":["transformer","operator","location","rating","devices","phases","frequency","voltage/primary","voltage/secondary","voltage/tertiary","windings","windings/configuration","ref"],"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/light_rail":{"icon":"railway-light-rail","geometry":["line"],"tags":{"railway":"light_rail"},"fields":["name","structure","gauge","electrified","service_rail"],"terms":["light rail","streetcar","trolley"],"name":"Light Rail"},"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":{"icon":"relation","fields":["name","relation"],"geometry":["relation"],"tags":{},"name":"Relation"},"route/ferry":{"icon":"ferry-line","geometry":["line"],"fields":["name","operator","duration","access"],"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/furnace":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["oven","stove"],"tags":{"shop":"furnace"},"name":"Furnace Store","searchable":false},"shop/vacant":{"icon":"shop","fields":["name","address","building_area"],"geometry":["point","area"],"tags":{"shop":"vacant"},"name":"Vacant Shop","searchable":false},"shop/agrarian":{"icon":"shop","fields":["name","operator","agrarian","address","building_area","opening_hours"],"geometry":["point","area"],"terms":["agricultural inputs","agricultural machines","seeds","pesticides","fertilizer","agricultural tools"],"tags":{"shop":"agrarian"},"name":"Agriculture Shop"},"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","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"],"terms":["sweet"],"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/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/tiles":{"icon":"shop","fields":["name","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"tiles"},"name":"Tile Shop"},"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/trade":{"icon":"shop","fields":["name","trade","operator","address","building_area","opening_hours"],"geometry":["point","area"],"tags":{"shop":"trade"},"name":"Trade Shop"},"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"],"terms":["climbing hut"],"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"],"terms":["holiday","holiday cottage","holiday home","vacation","vacation home"],"tags":{"tourism":"chalet"},"name":"Holiday Cottage"},"tourism/gallery":{"icon":"art-gallery","fields":["name","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/wilderness_hut":{"icon":"lodging","fields":["name","operator","address","building_area"],"geometry":["point","area"],"terms":["wilderness hut","backcountry hut","bothy"],"tags":{"tourism":"wilderness_hut"},"name":"Wilderness Hut"},"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"],"tags":{"traffic_calming":"table"},"terms":["flat top","hump","speed","slow"],"name":"Speed Table"},"type/multipolygon":{"icon":"multipolygon","geometry":["area","relation"],"tags":{"type":"multipolygon"},"removeTags":{},"name":"Multipolygon","searchable":false,"matchScore":0.1},"type/boundary":{"icon":"boundary","fields":["name","boundary"],"geometry":["relation"],"tags":{"type":"boundary"},"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":{"icon":"restriction","fields":["name","restriction","except"],"geometry":["relation"],"tags":{"type":"restriction"},"name":"Restriction"},"type/restriction/no_left_turn":{"icon":"restriction-no-left-turn","fields":["except"],"geometry":["relation"],"tags":{"type":"restriction","restriction":"no_left_turn"},"name":"No Left Turn"},"type/restriction/no_right_turn":{"icon":"restriction-no-right-turn","fields":["except"],"geometry":["relation"],"tags":{"type":"restriction","restriction":"no_right_turn"},"name":"No Right Turn"},"type/restriction/no_straight_on":{"icon":"restriction-no-straight-on","fields":["except"],"geometry":["relation"],"tags":{"type":"restriction","restriction":"no_straight_on"},"name":"No Straight On"},"type/restriction/no_u_turn":{"icon":"restriction-no-u-turn","fields":["except"],"geometry":["relation"],"tags":{"type":"restriction","restriction":"no_u_turn"},"name":"No U-turn"},"type/restriction/only_left_turn":{"icon":"restriction-only-left-turn","fields":["except"],"geometry":["relation"],"tags":{"type":"restriction","restriction":"only_left_turn"},"name":"Left Turn Only"},"type/restriction/only_right_turn":{"icon":"restriction-only-right-turn","fields":["except"],"geometry":["relation"],"tags":{"type":"restriction","restriction":"only_right_turn"},"name":"Right Turn Only"},"type/restriction/only_straight_on":{"icon":"restriction-only-straight-on","fields":["except"],"geometry":["relation"],"tags":{"type":"restriction","restriction":"only_straight_on"},"name":"No Turns"},"type/route_master":{"icon":"route-master","fields":["name","route_master","ref","operator","network"],"geometry":["relation"],"tags":{"type":"route_master"},"name":"Route Master"},"type/route":{"icon":"route","fields":["name","route","ref_route","operator","network"],"geometry":["relation"],"tags":{"type":"route"},"name":"Route"},"type/route/bicycle":{"icon":"route-bicycle","fields":["name","ref_route","network_bicycle","cycle_network"],"geometry":["relation"],"tags":{"type":"route","route":"bicycle"},"name":"Cycle Route"},"type/route/bus":{"icon":"route-bus","fields":["name","ref_route","operator","network"],"geometry":["relation"],"tags":{"type":"route","route":"bus"},"name":"Bus Route"},"type/route/detour":{"icon":"route-detour","fields":["name","ref_route"],"geometry":["relation"],"tags":{"type":"route","route":"detour"},"name":"Detour Route"},"type/route/ferry":{"icon":"route-ferry","fields":["name","ref_route","operator","network"],"geometry":["relation"],"tags":{"type":"route","route":"ferry"},"name":"Ferry Route"},"type/route/foot":{"icon":"route-foot","fields":["name","ref_route","operator","network_foot"],"geometry":["relation"],"tags":{"type":"route","route":"foot"},"name":"Foot Route"},"type/route/hiking":{"icon":"route-foot","fields":["name","ref_route","operator","network_foot"],"geometry":["relation"],"tags":{"type":"route","route":"hiking"},"name":"Hiking Route"},"type/route/horse":{"icon":"route-horse","fields":["name","ref_route","operator","network_horse"],"geometry":["relation"],"tags":{"type":"route","route":"horse"},"name":"Riding Route"},"type/route/pipeline":{"icon":"route-pipeline","fields":["name","ref_route","operator"],"geometry":["relation"],"tags":{"type":"route","route":"pipeline"},"name":"Pipeline Route"},"type/route/power":{"icon":"route-power","fields":["name","ref_route","operator"],"geometry":["relation"],"tags":{"type":"route","route":"power"},"name":"Power Route"},"type/route/road":{"icon":"route-road","fields":["name","ref_route","network_road"],"geometry":["relation"],"tags":{"type":"route","route":"road"},"name":"Road Route"},"type/route/train":{"icon":"route-train","fields":["name","ref_route","operator","network"],"geometry":["relation"],"tags":{"type":"route","route":"train"},"name":"Train Route"},"type/route/tram":{"icon":"route-tram","fields":["name","ref_route","operator","network"],"geometry":["relation"],"tags":{"type":"route","route":"tram"},"name":"Tram Route"},"type/site":{"icon":"relation","fields":["name","site"],"geometry":["relation"],"tags":{"type":"site"},"name":"Site"},"type/waterway":{"icon":"route-water","fields":["name","waterway","ref"],"geometry":["relation"],"tags":{"type":"waterway"},"name":"Waterway"},"vertex":{"fields":["name"],"geometry":["vertex"],"tags":{},"name":"Other","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","intermittent"],"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":["structure_waterway","intermittent"],"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-ditch","fields":["structure_waterway","intermittent"],"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","structure_waterway","width","intermittent"],"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_simple","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_intermittent":{"icon":"waterway-stream","fields":["name","structure_waterway","width","intermittent"],"geometry":["line"],"terms":["arroyo","beck","branch","brook","burn","course","creek","drift","flood","flow","gully","run","runnel","rush","spate","spritz","tributary","wadi","wash","watercourse"],"tags":{"waterway":"stream","intermittent":"yes"},"reference":{"key":"waterway","value":"stream"},"name":"Intermittent Stream"},"waterway/stream":{"icon":"waterway-stream","fields":["name","structure_waterway","width","intermittent"],"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","intermittent"],"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":"ФАП","healthcare":"clinic","amenity":"clinic"},"name":"ФАП","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Aspen Dental":{"tags":{"name":"Aspen Dental","healthcare":"dentist","amenity":"dentist"},"name":"Aspen Dental","icon":"dentist","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Consultorio Dental":{"tags":{"name":"Consultorio Dental","healthcare":"dentist","amenity":"dentist"},"name":"Consultorio Dental","icon":"dentist","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Dentista":{"tags":{"name":"Dentista","healthcare":"dentist","amenity":"dentist"},"name":"Dentista","icon":"dentist","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Family Dentistry":{"tags":{"name":"Family Dentistry","healthcare":"dentist","amenity":"dentist"},"name":"Family Dentistry","icon":"dentist","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Vitaldent":{"tags":{"name":"Vitaldent","healthcare":"dentist","amenity":"dentist"},"name":"Vitaldent","icon":"dentist","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Стоматолог":{"tags":{"name":"Стоматолог","healthcare":"dentist","amenity":"dentist"},"name":"Стоматолог","icon":"dentist","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"suggestion":true},"amenity/dentist/Стоматологія":{"tags":{"name":"Стоматологія","healthcare":"dentist","amenity":"dentist"},"name":"Стоматологія","icon":"dentist","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"suggestion":true},"amenity/doctors/Háziorvosi rendelő":{"tags":{"name":"Háziorvosi rendelő","healthcare":"doctor","amenity":"doctors"},"name":"Háziorvosi rendelő","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","building_area","opening_hours"],"suggestion":true},"amenity/doctors/Инвитро":{"tags":{"name":"Инвитро","healthcare":"doctor","amenity":"doctors"},"name":"Инвитро","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","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","healthcare":"hospital","amenity":"hospital"},"name":"Cruz Roja","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/IMSS":{"tags":{"name":"IMSS","healthcare":"hospital","amenity":"hospital"},"name":"IMSS","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/Инфекционное отделение":{"tags":{"name":"Инфекционное отделение","healthcare":"hospital","amenity":"hospital"},"name":"Инфекционное отделение","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/Кожно-венерологический диспансер":{"tags":{"name":"Кожно-венерологический диспансер","healthcare":"hospital","amenity":"hospital"},"name":"Кожно-венерологический диспансер","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/Районная больница":{"tags":{"name":"Районная больница","healthcare":"hospital","amenity":"hospital"},"name":"Районная больница","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/Роддом":{"tags":{"name":"Роддом","healthcare":"hospital","amenity":"hospital"},"name":"Роддом","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/Родильный дом":{"tags":{"name":"Родильный дом","healthcare":"hospital","amenity":"hospital"},"name":"Родильный дом","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/Скорая помощь":{"tags":{"name":"Скорая помощь","healthcare":"hospital","amenity":"hospital"},"name":"Скорая помощь","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/ЦРБ":{"tags":{"name":"ЦРБ","healthcare":"hospital","amenity":"hospital"},"name":"ЦРБ","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/Центральная районная больница":{"tags":{"name":"Центральная районная больница","healthcare":"hospital","amenity":"hospital"},"name":"Центральная районная больница","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","address","emergency"],"suggestion":true},"amenity/hospital/โรงพยาบาลส่งเสริมสุขภาพตำบล":{"tags":{"name":"โรงพยาบาลส่งเสริมสุขภาพตำบล","healthcare":"hospital","amenity":"hospital"},"name":"โรงพยาบาลส่งเสริมสุขภาพตำบล","icon":"hospital","geometry":["point","area"],"fields":["name","operator","healthcare/speciality","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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ė","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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ė","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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é","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"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","healthcare":"pharmacy","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","healthcare":"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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"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","healthcare":"pharmacy","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","healthcare":"pharmacy","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","healthcare":"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","healthcare":"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","healthcare":"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","healthcare":"pharmacy","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","healthcare":"pharmacy","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":"Айболит","healthcare":"pharmacy","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","healthcare":"pharmacy","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":"Аптека низких цен","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Аптека низких цен","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Аптека низьких цін":{"tags":{"name":"Аптека низьких цін","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Аптека низьких цін","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Аптека от склада":{"tags":{"name":"Аптека от склада","healthcare":"pharmacy","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","healthcare":"pharmacy","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":"Аптечный пункт","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Аптечный пункт","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Арніка":{"tags":{"name":"Арніка","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Арніка","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Бережная аптека":{"tags":{"name":"Бережная аптека","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Бережная аптека","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Будь здоров":{"tags":{"name":"Будь здоров","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Будь здоров","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Вита":{"tags":{"name":"Вита","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Вита","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Горздрав":{"tags":{"name":"Горздрав","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Горздрав","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Живика":{"tags":{"name":"Живика","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Живика","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Здоровье":{"tags":{"name":"Здоровье","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Здоровье","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Имплозия":{"tags":{"name":"Имплозия","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Имплозия","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Классика":{"tags":{"name":"Классика","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Классика","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Ладушка":{"tags":{"name":"Ладушка","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Ладушка","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Мед-сервіс":{"tags":{"name":"Мед-сервіс","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Мед-сервіс","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Мелодия здоровья":{"tags":{"name":"Мелодия здоровья","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Мелодия здоровья","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Невис":{"tags":{"name":"Невис","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Невис","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Норма":{"tags":{"name":"Норма","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Норма","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Озерки":{"tags":{"name":"Озерки","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Озерки","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Панацея":{"tags":{"name":"Панацея","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Панацея","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Первая помощь":{"tags":{"name":"Первая помощь","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Первая помощь","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Планета здоровья":{"tags":{"name":"Планета здоровья","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Планета здоровья","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Ригла":{"tags":{"name":"Ригла","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Ригла","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Семейная":{"tags":{"name":"Семейная","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Семейная","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Социальная аптека":{"tags":{"name":"Социальная аптека","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Социальная аптека","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Столички":{"tags":{"name":"Столички","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Столички","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Фармакопейка":{"tags":{"name":"Фармакопейка","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Фармакопейка","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Фармакор":{"tags":{"name":"Фармакор","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Фармакор","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Фармация":{"tags":{"name":"Фармация","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Фармация","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Фармленд":{"tags":{"name":"Фармленд","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Фармленд","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/Центральная аптека":{"tags":{"name":"Центральная аптека","healthcare":"pharmacy","amenity":"pharmacy"},"name":"Центральная аптека","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/סופר-פארם":{"tags":{"name":"סופר-פארם","healthcare":"pharmacy","amenity":"pharmacy"},"name":"סופר-פארם","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/داروخانه":{"tags":{"name":"داروخانه","healthcare":"pharmacy","amenity":"pharmacy"},"name":"داروخانه","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/داروخانه شبانه روزی":{"tags":{"name":"داروخانه شبانه روزی","healthcare":"pharmacy","amenity":"pharmacy"},"name":"داروخانه شبانه روزی","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/صيدلية":{"tags":{"name":"صيدلية","healthcare":"pharmacy","amenity":"pharmacy"},"name":"صيدلية","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/くすりの福太郎":{"tags":{"name":"くすりの福太郎","healthcare":"pharmacy","amenity":"pharmacy"},"name":"くすりの福太郎","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/さくら薬局":{"tags":{"name":"さくら薬局","healthcare":"pharmacy","amenity":"pharmacy"},"name":"さくら薬局","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/ウエルシア":{"tags":{"name":"ウエルシア","healthcare":"pharmacy","amenity":"pharmacy"},"name":"ウエルシア","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/カワチ薬品":{"tags":{"name":"カワチ薬品","healthcare":"pharmacy","amenity":"pharmacy"},"name":"カワチ薬品","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/クリエイト":{"tags":{"name":"クリエイト","healthcare":"pharmacy","amenity":"pharmacy"},"name":"クリエイト","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/サンドラッグ":{"tags":{"name":"サンドラッグ","healthcare":"pharmacy","amenity":"pharmacy"},"name":"サンドラッグ","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/スギ薬局":{"tags":{"name":"スギ薬局","healthcare":"pharmacy","amenity":"pharmacy"},"name":"スギ薬局","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/セイジョー":{"tags":{"name":"セイジョー","healthcare":"pharmacy","amenity":"pharmacy"},"name":"セイジョー","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/ツルハドラッグ":{"tags":{"name":"ツルハドラッグ","healthcare":"pharmacy","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)","healthcare":"pharmacy","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":"マツモトキヨシ","healthcare":"pharmacy","amenity":"pharmacy"},"name":"マツモトキヨシ","icon":"pharmacy","geometry":["point","area"],"fields":["name","operator","address","building_area","opening_hours","drive_through"],"suggestion":true},"amenity/pharmacy/丁丁藥局":{"tags":{"name":"丁丁藥局","healthcare":"pharmacy","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"],"fields":["name","operator","surface","playground/max_age","playground/min_age","access_simple"],"suggestion":true},"leisure/playground/놀이터":{"tags":{"name":"놀이터","leisure":"playground"},"name":"놀이터","icon":"playground","geometry":["point","area"],"fields":["name","operator","surface","playground/max_age","playground/min_age","access_simple"],"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/Citroën":{"tags":{"name":"Citroën","shop":"car"},"name":"Citroën","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/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/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/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":{"tags":{"name":"Aldi","shop":"supermarket"},"name":"Aldi","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/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":{"tags":{"name":"Netto","shop":"supermarket"},"name":"Netto","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/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/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/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}};
23199
23200 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/waterway","type/multipolygon","type/site","relation"]};
23201
23202 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","landuse/religious"]},"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_line"]},"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"]}};
23203
23204 var fields = {"access_simple":{"key":"access","type":"combo","label":"Allowed Access","options":["yes","permissive","private","customers","no"]},"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"},"agrarian":{"key":"agrarian","type":"semiCombo","label":"Products"},"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"},"boules":{"key":"boules","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"},"cables":{"key":"cables","type":"number","label":"Cables","placeholder":"1, 2, 3..."},"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"},"crane/type":{"key":"crane:type","type":"combo","label":"Crane Type","strings":{"options":{"portal_crane":"Portal Crane","floor-mounted_crane":"Floor-mounted Crane","travel_lift":"Travel Lift"}}},"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},"devices":{"key":"devices","type":"number","label":"Devices","placeholder":"1, 2, 3..."},"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"},"duration":{"key":"duration","type":"text","label":"Duration","placeholder":"00:00"},"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"}}},"fitness_station":{"key":"fitness_station","type":"typeCombo","label":"Equipment Type"},"fixme":{"key":"fixme","type":"textarea","label":"Fix Me","universal":true},"ford":{"key":"ford","type":"typeCombo","label":"Type","placeholder":"Default"},"frequency":{"key":"frequency","type":"combo","label":"Operating Frequency"},"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"},"government":{"key":"government","type":"typeCombo","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":"Suggested Hashtags","placeholder":"#example"},"healthcare":{"key":"healthcare","type":"typeCombo","label":"Type"},"healthcare/speciality":{"key":"healthcare:speciality","type":"semiCombo","reference":{"key":"healthcare"},"label":"Specialties"},"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"},"intermittent":{"key":"intermittent","type":"check","label":"Intermittent"},"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},"memorial":{"key":"memorial","type":"typeCombo","label":"Type"},"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"},"phases":{"key":"phases","type":"number","label":"Phases","placeholder":"1, 2, 3..."},"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..."},"playground/baby":{"key":"baby","type":"check","label":"Baby Seat"},"playground/max_age":{"key":"max_age","type":"number","label":"Maximum Age"},"playground/min_age":{"key":"min_age","type":"number","label":"Minimum Age"},"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"},"rating":{"key":"rating","type":"combo","label":"Power Rating","snake_case":false},"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","snake_case":false,"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_waterway":{"type":"structureRadio","keys":["tunnel"],"label":"Structure","placeholder":"Unknown","strings":{"options":{"tunnel":"Tunnel"}}},"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"},"substance":{"key":"substance","type":"combo","label":"Substance"},"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"},"switch":{"key":"switch","type":"combo","label":"Type","strings":{"options":{"mechanical":"Mechanical","circuit_breaker":"Circuit Breaker","disconnector":"Disconnector","earthing":"Earthing"}}},"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_attraction":{"key":"tourism","default":"attraction","type":"typeCombo","universal":true,"label":"Tourism"},"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"}}},"trade":{"key":"trade","type":"typeCombo","label":"Type"},"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"}}},"transformer":{"key":"transformer","type":"combo","label":"Type","strings":{"options":{"distribution":"Distribution","generator":"Generator","converter":"Converter","traction":"Traction","auto":"Autotransformer","phase_angle_regulator":"Phase Angle Regulator","auxiliary":"Auxiliary","yes":"Unknown"}}},"trees":{"key":"trees","type":"semiCombo","label":"Trees"},"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)"}}},"volcano/status":{"key":"volcano:status","type":"combo","label":"Volcano Status","strings":{"options":{"active":"Active","dormant":"Dormant","extinct":"Extinct"}}},"volcano/type":{"key":"volcano:type","type":"combo","label":"Volcano Type","strings":{"options":{"stratovolcano":"Stratovolcano","shield":"Shield","scoria":"Scoria"}}},"voltage":{"key":"voltage","type":"combo","label":"Voltage"},"voltage/primary":{"key":"voltage:primary","type":"combo","label":"Primary Voltage"},"voltage/secondary":{"key":"voltage:secondary","type":"combo","label":"Secondary Voltage"},"voltage/tertiary":{"key":"voltage:tertiary","type":"combo","label":"Tertiary Voltage"},"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"},"windings":{"key":"windings","type":"number","label":"Windings","placeholder":"1, 2, 3..."},"windings/configuration":{"key":"windings:configuration","type":"combo","label":"Windings Configuration","strings":{"options":{"star":"Star / Wye","delta":"Delta","open-delta":"Open Delta","zigzag":"Zig Zag","open":"Open","scott":"Scott","leblanc":"Leblanc"}}}};
23205
23206 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"];
23207 var all$1 = {
23208         all: all
23209 };
23210
23211 var all$2 = Object.freeze({
23212         all: all,
23213         default: all$1
23214 });
23215
23216 var Airport = ["airfield","airport","heliport","rocket"];
23217 var Dining = ["bakery","bar","beer","cafe","fast-food","ice-cream","restaurant"];
23218 var Education = ["college","school"];
23219 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"];
23220 var Health = ["dentist","doctor","hospital","pharmacy"];
23221 var Outdoors = ["campsite","cemetery","dog-park","garden","golf","park","picnic-site","playground","zoo"];
23222 var Transit = ["bus","ferry"];
23223 var streets = {
23224         Airport: Airport,
23225         Dining: Dining,
23226         Education: Education,
23227         General: General,
23228         Health: Health,
23229         Outdoors: Outdoors,
23230         Transit: Transit,
23231         "Mountain peak": ["mountain","volcano"],
23232         "Rail station": ["entrance","rail","rail-light","rail-metro"]
23233 };
23234
23235 var streets$1 = Object.freeze({
23236         Airport: Airport,
23237         Dining: Dining,
23238         Education: Education,
23239         General: General,
23240         Health: Health,
23241         Outdoors: Outdoors,
23242         Transit: Transit,
23243         default: streets
23244 });
23245
23246 var require$$0$1 = ( all$2 && all$1 ) || all$2;
23247
23248 var require$$1$1 = ( streets$1 && streets ) || streets$1;
23249
23250 var maki = {
23251   layouts: {
23252     all: require$$0$1,
23253     streets: require$$1$1
23254   }
23255 };
23256
23257 var dataFeatureIcons = maki.layouts.all.all;
23258
23259 var data = {
23260     imagery: dataImagery,
23261     presets: {
23262         presets: presets,
23263         defaults: defaults,
23264         categories: categories,
23265         fields: fields
23266     }
23267 };
23268
23269 function osmEntity(attrs) {
23270     // For prototypal inheritance.
23271     if (this instanceof osmEntity) return;
23272
23273     // Create the appropriate subtype.
23274     if (attrs && attrs.type) {
23275         return osmEntity[attrs.type].apply(this, arguments);
23276     } else if (attrs && attrs.id) {
23277         return osmEntity[osmEntity.id.type(attrs.id)].apply(this, arguments);
23278     }
23279
23280     // Initialize a generic Entity (used only in tests).
23281     return (new osmEntity()).initialize(arguments);
23282 }
23283
23284
23285 osmEntity.id = function(type) {
23286     return osmEntity.id.fromOSM(type, osmEntity.id.next[type]--);
23287 };
23288
23289
23290 osmEntity.id.next = {
23291     changeset: -1, node: -1, way: -1, relation: -1
23292 };
23293
23294
23295 osmEntity.id.fromOSM = function(type, id) {
23296     return type[0] + id;
23297 };
23298
23299
23300 osmEntity.id.toOSM = function(id) {
23301     return id.slice(1);
23302 };
23303
23304
23305 osmEntity.id.type = function(id) {
23306     return { 'c': 'changeset', 'n': 'node', 'w': 'way', 'r': 'relation' }[id[0]];
23307 };
23308
23309
23310 // A function suitable for use as the second argument to d3.selection#data().
23311 osmEntity.key = function(entity) {
23312     return entity.id + 'v' + (entity.v || 0);
23313 };
23314
23315
23316 osmEntity.prototype = {
23317
23318     tags: {},
23319
23320
23321     initialize: function(sources) {
23322         for (var i = 0; i < sources.length; ++i) {
23323             var source = sources[i];
23324             for (var prop in source) {
23325                 if (Object.prototype.hasOwnProperty.call(source, prop)) {
23326                     if (source[prop] === undefined) {
23327                         delete this[prop];
23328                     } else {
23329                         this[prop] = source[prop];
23330                     }
23331                 }
23332             }
23333         }
23334
23335         if (!this.id && this.type) {
23336             this.id = osmEntity.id(this.type);
23337         }
23338         if (!this.hasOwnProperty('visible')) {
23339             this.visible = true;
23340         }
23341
23342         if (debug) {
23343             Object.freeze(this);
23344             Object.freeze(this.tags);
23345
23346             if (this.loc) Object.freeze(this.loc);
23347             if (this.nodes) Object.freeze(this.nodes);
23348             if (this.members) Object.freeze(this.members);
23349         }
23350
23351         return this;
23352     },
23353
23354
23355     copy: function(resolver, copies) {
23356         if (copies[this.id])
23357             return copies[this.id];
23358
23359         var copy = osmEntity(this, {id: undefined, user: undefined, version: undefined});
23360         copies[this.id] = copy;
23361
23362         return copy;
23363     },
23364
23365
23366     osmId: function() {
23367         return osmEntity.id.toOSM(this.id);
23368     },
23369
23370
23371     isNew: function() {
23372         return this.osmId() < 0;
23373     },
23374
23375
23376     update: function(attrs) {
23377         return osmEntity(this, attrs, {v: 1 + (this.v || 0)});
23378     },
23379
23380
23381     mergeTags: function(tags) {
23382         var merged = clone(this.tags), changed = false;
23383         for (var k in tags) {
23384             var t1 = merged[k],
23385                 t2 = tags[k];
23386             if (!t1) {
23387                 changed = true;
23388                 merged[k] = t2;
23389             } else if (t1 !== t2) {
23390                 changed = true;
23391                 merged[k] = union(t1.split(/;\s*/), t2.split(/;\s*/)).join(';');
23392             }
23393         }
23394         return changed ? this.update({tags: merged}) : this;
23395     },
23396
23397
23398     intersects: function(extent, resolver) {
23399         return this.extent(resolver).intersects(extent);
23400     },
23401
23402
23403     isUsed: function(resolver) {
23404         return without(Object.keys(this.tags), 'area').length > 0 ||
23405             resolver.parentRelations(this).length > 0;
23406     },
23407
23408
23409     hasInterestingTags: function() {
23410         return keys$1(this.tags).some(osmIsInterestingTag);
23411     },
23412
23413
23414     isHighwayIntersection: function() {
23415         return false;
23416     },
23417
23418     isDegenerate: function() {
23419         return true;
23420     },
23421
23422     deprecatedTags: function() {
23423         var tags = toPairs(this.tags);
23424         var deprecated = {};
23425
23426         dataDeprecated.forEach(function(d) {
23427             var match = toPairs(d.old)[0];
23428             tags.forEach(function(t) {
23429                 if (t[0] === match[0] &&
23430                     (t[1] === match[1] || match[1] === '*')) {
23431                     deprecated[t[0]] = t[1];
23432                 }
23433             });
23434         });
23435
23436         return deprecated;
23437     }
23438 };
23439
23440 /**
23441  * A specialized version of `_.every` for arrays without support for
23442  * iteratee shorthands.
23443  *
23444  * @private
23445  * @param {Array} [array] The array to iterate over.
23446  * @param {Function} predicate The function invoked per iteration.
23447  * @returns {boolean} Returns `true` if all elements pass the predicate check,
23448  *  else `false`.
23449  */
23450 function arrayEvery(array, predicate) {
23451   var index = -1,
23452       length = array == null ? 0 : array.length;
23453
23454   while (++index < length) {
23455     if (!predicate(array[index], index, array)) {
23456       return false;
23457     }
23458   }
23459   return true;
23460 }
23461
23462 /**
23463  * The base implementation of `_.every` without support for iteratee shorthands.
23464  *
23465  * @private
23466  * @param {Array|Object} collection The collection to iterate over.
23467  * @param {Function} predicate The function invoked per iteration.
23468  * @returns {boolean} Returns `true` if all elements pass the predicate check,
23469  *  else `false`
23470  */
23471 function baseEvery(collection, predicate) {
23472   var result = true;
23473   baseEach(collection, function(value, index, collection) {
23474     result = !!predicate(value, index, collection);
23475     return result;
23476   });
23477   return result;
23478 }
23479
23480 /**
23481  * Checks if `predicate` returns truthy for **all** elements of `collection`.
23482  * Iteration is stopped once `predicate` returns falsey. The predicate is
23483  * invoked with three arguments: (value, index|key, collection).
23484  *
23485  * **Note:** This method returns `true` for
23486  * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
23487  * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
23488  * elements of empty collections.
23489  *
23490  * @static
23491  * @memberOf _
23492  * @since 0.1.0
23493  * @category Collection
23494  * @param {Array|Object} collection The collection to iterate over.
23495  * @param {Function} [predicate=_.identity] The function invoked per iteration.
23496  * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
23497  * @returns {boolean} Returns `true` if all elements pass the predicate check,
23498  *  else `false`.
23499  * @example
23500  *
23501  * _.every([true, 1, null, 'yes'], Boolean);
23502  * // => false
23503  *
23504  * var users = [
23505  *   { 'user': 'barney', 'age': 36, 'active': false },
23506  *   { 'user': 'fred',   'age': 40, 'active': false }
23507  * ];
23508  *
23509  * // The `_.matches` iteratee shorthand.
23510  * _.every(users, { 'user': 'barney', 'active': false });
23511  * // => false
23512  *
23513  * // The `_.matchesProperty` iteratee shorthand.
23514  * _.every(users, ['active', false]);
23515  * // => true
23516  *
23517  * // The `_.property` iteratee shorthand.
23518  * _.every(users, 'active');
23519  * // => false
23520  */
23521 function every(collection, predicate, guard) {
23522   var func = isArray(collection) ? arrayEvery : baseEvery;
23523   if (guard && isIterateeCall(collection, predicate, guard)) {
23524     predicate = undefined;
23525   }
23526   return func(collection, baseIteratee(predicate, 3));
23527 }
23528
23529 /**
23530  * The base implementation of `_.some` without support for iteratee shorthands.
23531  *
23532  * @private
23533  * @param {Array|Object} collection The collection to iterate over.
23534  * @param {Function} predicate The function invoked per iteration.
23535  * @returns {boolean} Returns `true` if any element passes the predicate check,
23536  *  else `false`.
23537  */
23538 function baseSome(collection, predicate) {
23539   var result;
23540
23541   baseEach(collection, function(value, index, collection) {
23542     result = predicate(value, index, collection);
23543     return !result;
23544   });
23545   return !!result;
23546 }
23547
23548 /**
23549  * Checks if `predicate` returns truthy for **any** element of `collection`.
23550  * Iteration is stopped once `predicate` returns truthy. The predicate is
23551  * invoked with three arguments: (value, index|key, collection).
23552  *
23553  * @static
23554  * @memberOf _
23555  * @since 0.1.0
23556  * @category Collection
23557  * @param {Array|Object} collection The collection to iterate over.
23558  * @param {Function} [predicate=_.identity] The function invoked per iteration.
23559  * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
23560  * @returns {boolean} Returns `true` if any element passes the predicate check,
23561  *  else `false`.
23562  * @example
23563  *
23564  * _.some([null, 0, 'yes', false], Boolean);
23565  * // => true
23566  *
23567  * var users = [
23568  *   { 'user': 'barney', 'active': true },
23569  *   { 'user': 'fred',   'active': false }
23570  * ];
23571  *
23572  * // The `_.matches` iteratee shorthand.
23573  * _.some(users, { 'user': 'barney', 'active': false });
23574  * // => false
23575  *
23576  * // The `_.matchesProperty` iteratee shorthand.
23577  * _.some(users, ['active', false]);
23578  * // => true
23579  *
23580  * // The `_.property` iteratee shorthand.
23581  * _.some(users, 'active');
23582  * // => true
23583  */
23584 function some(collection, predicate, guard) {
23585   var func = isArray(collection) ? arraySome : baseSome;
23586   if (guard && isIterateeCall(collection, predicate, guard)) {
23587     predicate = undefined;
23588   }
23589   return func(collection, baseIteratee(predicate, 3));
23590 }
23591
23592 function geoRoundCoords(c) {
23593     return [Math.floor(c[0]), Math.floor(c[1])];
23594 }
23595
23596
23597 function geoInterp(p1, p2, t) {
23598     return [p1[0] + (p2[0] - p1[0]) * t,
23599             p1[1] + (p2[1] - p1[1]) * t];
23600 }
23601
23602
23603 // 2D cross product of OA and OB vectors, i.e. z-component of their 3D cross product.
23604 // Returns a positive value, if OAB makes a counter-clockwise turn,
23605 // negative for clockwise turn, and zero if the points are collinear.
23606 function geoCross(o, a, b) {
23607     return (a[0] - o[0]) * (b[1] - o[1]) - (a[1] - o[1]) * (b[0] - o[0]);
23608 }
23609
23610
23611 // http://jsperf.com/id-dist-optimization
23612 function geoEuclideanDistance(a, b) {
23613     var x = a[0] - b[0], y = a[1] - b[1];
23614     return Math.sqrt((x * x) + (y * y));
23615 }
23616
23617
23618 // using WGS84 polar radius (6356752.314245179 m)
23619 // const = 2 * PI * r / 360
23620 function geoLatToMeters(dLat) {
23621     return dLat * 110946.257617;
23622 }
23623
23624
23625 // using WGS84 equatorial radius (6378137.0 m)
23626 // const = 2 * PI * r / 360
23627 function geoLonToMeters(dLon, atLat) {
23628     return Math.abs(atLat) >= 90 ? 0 :
23629         dLon * 111319.490793 * Math.abs(Math.cos(atLat * (Math.PI/180)));
23630 }
23631
23632
23633 // using WGS84 polar radius (6356752.314245179 m)
23634 // const = 2 * PI * r / 360
23635 function geoMetersToLat(m) {
23636     return m / 110946.257617;
23637 }
23638
23639
23640 // using WGS84 equatorial radius (6378137.0 m)
23641 // const = 2 * PI * r / 360
23642 function geoMetersToLon(m, atLat) {
23643     return Math.abs(atLat) >= 90 ? 0 :
23644         m / 111319.490793 / Math.abs(Math.cos(atLat * (Math.PI/180)));
23645 }
23646
23647
23648 function geoOffsetToMeters(offset) {
23649     var equatRadius = 6356752.314245179,
23650         polarRadius = 6378137.0,
23651         tileSize = 256;
23652
23653     return [
23654         offset[0] * 2 * Math.PI * equatRadius / tileSize,
23655         -offset[1] * 2 * Math.PI * polarRadius / tileSize
23656     ];
23657 }
23658
23659
23660 function geoMetersToOffset(meters) {
23661     var equatRadius = 6356752.314245179,
23662         polarRadius = 6378137.0,
23663         tileSize = 256;
23664
23665     return [
23666         meters[0] * tileSize / (2 * Math.PI * equatRadius),
23667         -meters[1] * tileSize / (2 * Math.PI * polarRadius)
23668     ];
23669 }
23670
23671
23672 // Equirectangular approximation of spherical distances on Earth
23673 function geoSphericalDistance(a, b) {
23674     var x = geoLonToMeters(a[0] - b[0], (a[1] + b[1]) / 2),
23675         y = geoLatToMeters(a[1] - b[1]);
23676     return Math.sqrt((x * x) + (y * y));
23677 }
23678
23679
23680 function geoEdgeEqual(a, b) {
23681     return (a[0] === b[0] && a[1] === b[1]) ||
23682         (a[0] === b[1] && a[1] === b[0]);
23683 }
23684
23685
23686 // Return the counterclockwise angle in the range (-pi, pi)
23687 // between the positive X axis and the line intersecting a and b.
23688 function geoAngle(a, b, projection) {
23689     a = projection(a.loc);
23690     b = projection(b.loc);
23691     return Math.atan2(b[1] - a[1], b[0] - a[0]);
23692 }
23693
23694
23695 // Rotate all points counterclockwise around a pivot point by given angle
23696 function geoRotate(points, angle, around) {
23697     return points.map(function(point) {
23698         var radial = [point[0] - around[0], point[1] - around[1]];
23699         return [
23700             radial[0] * Math.cos(angle) - radial[1] * Math.sin(angle) + around[0],
23701             radial[0] * Math.sin(angle) + radial[1] * Math.cos(angle) + around[1]
23702         ];
23703     });
23704 }
23705
23706
23707 // Choose the edge with the minimal distance from `point` to its orthogonal
23708 // projection onto that edge, if such a projection exists, or the distance to
23709 // the closest vertex on that edge. Returns an object with the `index` of the
23710 // chosen edge, the chosen `loc` on that edge, and the `distance` to to it.
23711 function geoChooseEdge(nodes, point, projection) {
23712     var dist = geoEuclideanDistance,
23713         points = nodes.map(function(n) { return projection(n.loc); }),
23714         min = Infinity,
23715         idx, loc;
23716
23717     function dot(p, q) {
23718         return p[0] * q[0] + p[1] * q[1];
23719     }
23720
23721     for (var i = 0; i < points.length - 1; i++) {
23722         var o = points[i],
23723             s = [points[i + 1][0] - o[0],
23724                  points[i + 1][1] - o[1]],
23725             v = [point[0] - o[0],
23726                  point[1] - o[1]],
23727             proj = dot(v, s) / dot(s, s),
23728             p;
23729
23730         if (proj < 0) {
23731             p = o;
23732         } else if (proj > 1) {
23733             p = points[i + 1];
23734         } else {
23735             p = [o[0] + proj * s[0], o[1] + proj * s[1]];
23736         }
23737
23738         var d = dist(p, point);
23739         if (d < min) {
23740             min = d;
23741             idx = i + 1;
23742             loc = projection.invert(p);
23743         }
23744     }
23745
23746     return {
23747         index: idx,
23748         distance: min,
23749         loc: loc
23750     };
23751 }
23752
23753
23754 // Return the intersection point of 2 line segments.
23755 // From https://github.com/pgkelley4/line-segments-intersect
23756 // This uses the vector cross product approach described below:
23757 //  http://stackoverflow.com/a/565282/786339
23758 function geoLineIntersection(a, b) {
23759     function subtractPoints(point1, point2) {
23760         return [point1[0] - point2[0], point1[1] - point2[1]];
23761     }
23762     function crossProduct(point1, point2) {
23763         return point1[0] * point2[1] - point1[1] * point2[0];
23764     }
23765
23766     var p = [a[0][0], a[0][1]],
23767         p2 = [a[1][0], a[1][1]],
23768         q = [b[0][0], b[0][1]],
23769         q2 = [b[1][0], b[1][1]],
23770         r = subtractPoints(p2, p),
23771         s = subtractPoints(q2, q),
23772         uNumerator = crossProduct(subtractPoints(q, p), r),
23773         denominator = crossProduct(r, s);
23774
23775     if (uNumerator && denominator) {
23776         var u = uNumerator / denominator,
23777             t = crossProduct(subtractPoints(q, p), s) / denominator;
23778
23779         if ((t >= 0) && (t <= 1) && (u >= 0) && (u <= 1)) {
23780             return geoInterp(p, p2, t);
23781         }
23782     }
23783
23784     return null;
23785 }
23786
23787
23788 function geoPathIntersections(path1, path2) {
23789     var intersections = [];
23790     for (var i = 0; i < path1.length - 1; i++) {
23791         for (var j = 0; j < path2.length - 1; j++) {
23792             var a = [ path1[i], path1[i+1] ],
23793                 b = [ path2[j], path2[j+1] ],
23794                 hit = geoLineIntersection(a, b);
23795             if (hit) intersections.push(hit);
23796         }
23797     }
23798     return intersections;
23799 }
23800
23801
23802 // Return whether point is contained in polygon.
23803 //
23804 // `point` should be a 2-item array of coordinates.
23805 // `polygon` should be an array of 2-item arrays of coordinates.
23806 //
23807 // From https://github.com/substack/point-in-polygon.
23808 // ray-casting algorithm based on
23809 // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
23810 //
23811 function geoPointInPolygon(point, polygon) {
23812     var x = point[0],
23813         y = point[1],
23814         inside = false;
23815
23816     for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
23817         var xi = polygon[i][0], yi = polygon[i][1];
23818         var xj = polygon[j][0], yj = polygon[j][1];
23819
23820         var intersect = ((yi > y) !== (yj > y)) &&
23821             (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
23822         if (intersect) inside = !inside;
23823     }
23824
23825     return inside;
23826 }
23827
23828
23829 function geoPolygonContainsPolygon(outer, inner) {
23830     return every(inner, function(point) {
23831         return geoPointInPolygon(point, outer);
23832     });
23833 }
23834
23835
23836 function geoPolygonIntersectsPolygon(outer, inner, checkSegments) {
23837     function testSegments(outer, inner) {
23838         for (var i = 0; i < outer.length - 1; i++) {
23839             for (var j = 0; j < inner.length - 1; j++) {
23840                 var a = [ outer[i], outer[i+1] ],
23841                     b = [ inner[j], inner[j+1] ];
23842                 if (geoLineIntersection(a, b)) return true;
23843             }
23844         }
23845         return false;
23846     }
23847
23848     function testPoints(outer, inner) {
23849         return some(inner, function(point) {
23850             return geoPointInPolygon(point, outer);
23851         });
23852     }
23853
23854    return testPoints(outer, inner) || (!!checkSegments && testSegments(outer, inner));
23855 }
23856
23857
23858 function geoPathLength(path) {
23859     var length = 0;
23860     for (var i = 0; i < path.length - 1; i++) {
23861         length += geoEuclideanDistance(path[i], path[i + 1]);
23862     }
23863     return length;
23864 }
23865
23866 function geoExtent(min, max) {
23867     if (!(this instanceof geoExtent)) return new geoExtent(min, max);
23868     if (min instanceof geoExtent) {
23869         return min;
23870     } else if (min && min.length === 2 && min[0].length === 2 && min[1].length === 2) {
23871         this[0] = min[0];
23872         this[1] = min[1];
23873     } else {
23874         this[0] = min        || [ Infinity,  Infinity];
23875         this[1] = max || min || [-Infinity, -Infinity];
23876     }
23877 }
23878
23879 geoExtent.prototype = new Array(2);
23880
23881 assignIn(geoExtent.prototype, {
23882
23883     equals: function (obj) {
23884         return this[0][0] === obj[0][0] &&
23885             this[0][1] === obj[0][1] &&
23886             this[1][0] === obj[1][0] &&
23887             this[1][1] === obj[1][1];
23888     },
23889
23890
23891     extend: function(obj) {
23892         if (!(obj instanceof geoExtent)) obj = new geoExtent(obj);
23893         return geoExtent(
23894             [Math.min(obj[0][0], this[0][0]), Math.min(obj[0][1], this[0][1])],
23895             [Math.max(obj[1][0], this[1][0]), Math.max(obj[1][1], this[1][1])]
23896         );
23897     },
23898
23899
23900     _extend: function(extent) {
23901         this[0][0] = Math.min(extent[0][0], this[0][0]);
23902         this[0][1] = Math.min(extent[0][1], this[0][1]);
23903         this[1][0] = Math.max(extent[1][0], this[1][0]);
23904         this[1][1] = Math.max(extent[1][1], this[1][1]);
23905     },
23906
23907
23908     area: function() {
23909         return Math.abs((this[1][0] - this[0][0]) * (this[1][1] - this[0][1]));
23910     },
23911
23912
23913     center: function() {
23914         return [(this[0][0] + this[1][0]) / 2,
23915                 (this[0][1] + this[1][1]) / 2];
23916     },
23917
23918
23919     rectangle: function() {
23920         return [this[0][0], this[0][1], this[1][0], this[1][1]];
23921     },
23922
23923
23924     bbox: function() {
23925         return { minX: this[0][0], minY: this[0][1], maxX: this[1][0], maxY: this[1][1] };
23926     },
23927
23928
23929     polygon: function() {
23930         return [
23931             [this[0][0], this[0][1]],
23932             [this[0][0], this[1][1]],
23933             [this[1][0], this[1][1]],
23934             [this[1][0], this[0][1]],
23935             [this[0][0], this[0][1]]
23936         ];
23937     },
23938
23939
23940     contains: function(obj) {
23941         if (!(obj instanceof geoExtent)) obj = new geoExtent(obj);
23942         return obj[0][0] >= this[0][0] &&
23943                obj[0][1] >= this[0][1] &&
23944                obj[1][0] <= this[1][0] &&
23945                obj[1][1] <= this[1][1];
23946     },
23947
23948
23949     intersects: function(obj) {
23950         if (!(obj instanceof geoExtent)) obj = new geoExtent(obj);
23951         return obj[0][0] <= this[1][0] &&
23952                obj[0][1] <= this[1][1] &&
23953                obj[1][0] >= this[0][0] &&
23954                obj[1][1] >= this[0][1];
23955     },
23956
23957
23958     intersection: function(obj) {
23959         if (!this.intersects(obj)) return new geoExtent();
23960         return new geoExtent(
23961             [Math.max(obj[0][0], this[0][0]), Math.max(obj[0][1], this[0][1])],
23962             [Math.min(obj[1][0], this[1][0]), Math.min(obj[1][1], this[1][1])]
23963         );
23964     },
23965
23966
23967     percentContainedIn: function(obj) {
23968         if (!(obj instanceof geoExtent)) obj = new geoExtent(obj);
23969         var a1 = this.intersection(obj).area(),
23970             a2 = this.area();
23971
23972         if (a1 === Infinity || a2 === Infinity || a1 === 0 || a2 === 0) {
23973             return 0;
23974         } else {
23975             return a1 / a2;
23976         }
23977     },
23978
23979
23980     padByMeters: function(meters) {
23981         var dLat = geoMetersToLat(meters),
23982             dLon = geoMetersToLon(meters, this.center()[1]);
23983         return geoExtent(
23984             [this[0][0] - dLon, this[0][1] - dLat],
23985             [this[1][0] + dLon, this[1][1] + dLat]
23986         );
23987     },
23988
23989
23990     toParam: function() {
23991         return this.rectangle().join(',');
23992     }
23993
23994 });
23995
23996 /*
23997     Bypasses features of D3's default projection stream pipeline that are unnecessary:
23998     * Antimeridian clipping
23999     * Spherical rotation
24000     * Resampling
24001 */
24002 function geoRawMercator() {
24003     var project = mercatorRaw,
24004         k = 512 / Math.PI, // scale
24005         x = 0, y = 0, // translate
24006         clipExtent = [[0, 0], [0, 0]];
24007
24008
24009     function projection(point) {
24010         point = project(point[0] * Math.PI / 180, point[1] * Math.PI / 180);
24011         return [point[0] * k + x, y - point[1] * k];
24012     }
24013
24014
24015     projection.invert = function(point) {
24016         point = project.invert((point[0] - x) / k, (y - point[1]) / k);
24017         return point && [point[0] * 180 / Math.PI, point[1] * 180 / Math.PI];
24018     };
24019
24020
24021     projection.scale = function(_) {
24022         if (!arguments.length) return k;
24023         k = +_;
24024         return projection;
24025     };
24026
24027
24028     projection.translate = function(_) {
24029         if (!arguments.length) return [x, y];
24030         x = +_[0];
24031         y = +_[1];
24032         return projection;
24033     };
24034
24035
24036     projection.clipExtent = function(_) {
24037         if (!arguments.length) return clipExtent;
24038         clipExtent = _;
24039         return projection;
24040     };
24041
24042
24043     projection.transform = function(_) {
24044         if (!arguments.length) return identity$7.translate(x, y).scale(k);
24045         x = +_.x;
24046         y = +_.y;
24047         k = +_.k;
24048         return projection;
24049     };
24050
24051
24052     projection.stream = d3_geoTransform({
24053         point: function(x, y) {
24054             x = projection([x, y]);
24055             this.stream.point(x[0], x[1]);
24056         }
24057     }).stream;
24058
24059
24060     return projection;
24061 }
24062
24063 function osmChangeset() {
24064     if (!(this instanceof osmChangeset)) {
24065         return (new osmChangeset()).initialize(arguments);
24066     } else if (arguments.length) {
24067         this.initialize(arguments);
24068     }
24069 }
24070
24071
24072 osmEntity.changeset = osmChangeset;
24073
24074 osmChangeset.prototype = Object.create(osmEntity.prototype);
24075
24076 assignIn(osmChangeset.prototype, {
24077
24078     type: 'changeset',
24079
24080
24081     extent: function() {
24082         return new geoExtent();
24083     },
24084
24085
24086     geometry: function() {
24087         return 'changeset';
24088     },
24089
24090
24091     asJXON: function() {
24092         return {
24093             osm: {
24094                 changeset: {
24095                     tag: map$4(this.tags, function(value, key) {
24096                         return { '@k': key, '@v': value };
24097                     }),
24098                     '@version': 0.6,
24099                     '@generator': 'iD'
24100                 }
24101             }
24102         };
24103     },
24104
24105
24106     // Generate [osmChange](http://wiki.openstreetmap.org/wiki/OsmChange)
24107     // XML. Returns a string.
24108     osmChangeJXON: function(changes) {
24109         var changeset_id = this.id;
24110
24111         function nest(x, order) {
24112             var groups = {};
24113             for (var i = 0; i < x.length; i++) {
24114                 var tagName = Object.keys(x[i])[0];
24115                 if (!groups[tagName]) groups[tagName] = [];
24116                 groups[tagName].push(x[i][tagName]);
24117             }
24118             var ordered = {};
24119             order.forEach(function(o) {
24120                 if (groups[o]) ordered[o] = groups[o];
24121             });
24122             return ordered;
24123         }
24124
24125
24126         // sort relations in a changeset by dependencies
24127         function sort(changes) {
24128
24129             // find a referenced relation in the current changeset
24130             function resolve(item) {
24131                 return find$1(relations, function(relation) {
24132                     return item.keyAttributes.type === 'relation'
24133                         && item.keyAttributes.ref === relation['@id'];
24134                 });
24135             }
24136
24137             // a new item is an item that has not been already processed
24138             function isNew(item) {
24139                 return !sorted[ item['@id'] ] && !find$1(processing, function(proc) {
24140                     return proc['@id'] === item['@id'];
24141                 });
24142             }
24143
24144             var processing = [],
24145                 sorted = {},
24146                 relations = changes.relation;
24147
24148             if (!relations) return changes;
24149
24150             for (var i = 0; i < relations.length; i++) {
24151                 var relation = relations[i];
24152
24153                 // skip relation if already sorted
24154                 if (!sorted[relation['@id']]) {
24155                     processing.push(relation);
24156                 }
24157
24158                 while (processing.length > 0) {
24159                     var next = processing[0],
24160                     deps = filter(compact(next.member.map(resolve)), isNew);
24161                     if (deps.length === 0) {
24162                         sorted[next['@id']] = next;
24163                         processing.shift();
24164                     } else {
24165                         processing = deps.concat(processing);
24166                     }
24167                 }
24168             }
24169
24170             changes.relation = values$1(sorted);
24171             return changes;
24172         }
24173
24174         function rep(entity) {
24175             return entity.asJXON(changeset_id);
24176         }
24177
24178         return {
24179             osmChange: {
24180                 '@version': 0.6,
24181                 '@generator': 'iD',
24182                 'create': sort(nest(changes.created.map(rep), ['node', 'way', 'relation'])),
24183                 'modify': nest(changes.modified.map(rep), ['node', 'way', 'relation']),
24184                 'delete': assignIn(nest(changes.deleted.map(rep), ['relation', 'way', 'node']), { '@if-unused': true })
24185             }
24186         };
24187     },
24188
24189
24190     asGeoJSON: function() {
24191         return {};
24192     }
24193
24194 });
24195
24196 function osmNode() {
24197     if (!(this instanceof osmNode)) {
24198         return (new osmNode()).initialize(arguments);
24199     } else if (arguments.length) {
24200         this.initialize(arguments);
24201     }
24202 }
24203
24204 osmEntity.node = osmNode;
24205
24206 osmNode.prototype = Object.create(osmEntity.prototype);
24207
24208 assignIn(osmNode.prototype, {
24209
24210     type: 'node',
24211
24212
24213     extent: function() {
24214         return new geoExtent(this.loc);
24215     },
24216
24217
24218     geometry: function(graph) {
24219         return graph.transient(this, 'geometry', function() {
24220             return graph.isPoi(this) ? 'point' : 'vertex';
24221         });
24222     },
24223
24224
24225     move: function(loc) {
24226         return this.update({loc: loc});
24227     },
24228
24229
24230     isDegenerate: function() {
24231         return !(
24232             Array.isArray(this.loc) && this.loc.length === 2 &&
24233             this.loc[0] >= -180 && this.loc[0] <= 180 &&
24234             this.loc[1] >= -90 && this.loc[1] <= 90
24235         );
24236     },
24237
24238
24239     isEndpoint: function(resolver) {
24240         return resolver.transient(this, 'isEndpoint', function() {
24241             var id = this.id;
24242             return resolver.parentWays(this).filter(function(parent) {
24243                 return !parent.isClosed() && !!parent.affix(id);
24244             }).length > 0;
24245         });
24246     },
24247
24248
24249     isConnected: function(resolver) {
24250         return resolver.transient(this, 'isConnected', function() {
24251             var parents = resolver.parentWays(this);
24252
24253             function isLine(entity) {
24254                 return entity.geometry(resolver) === 'line' &&
24255                     entity.hasInterestingTags();
24256             }
24257
24258             // vertex is connected to multiple parent lines
24259             if (parents.length > 1 && some(parents, isLine)) {
24260                 return true;
24261
24262             } else if (parents.length === 1) {
24263                 var way = parents[0],
24264                     nodes = way.nodes.slice();
24265                 if (way.isClosed()) { nodes.pop(); }  // ignore connecting node if closed
24266
24267                 // return true if vertex appears multiple times (way is self intersecting)
24268                 return nodes.indexOf(this.id) !== nodes.lastIndexOf(this.id);
24269             }
24270
24271             return false;
24272         });
24273     },
24274
24275
24276     isIntersection: function(resolver) {
24277         return resolver.transient(this, 'isIntersection', function() {
24278             return resolver.parentWays(this).filter(function(parent) {
24279                 return (parent.tags.highway ||
24280                     parent.tags.waterway ||
24281                     parent.tags.railway ||
24282                     parent.tags.aeroway) &&
24283                     parent.geometry(resolver) === 'line';
24284             }).length > 1;
24285         });
24286     },
24287
24288
24289     isHighwayIntersection: function(resolver) {
24290         return resolver.transient(this, 'isHighwayIntersection', function() {
24291             return resolver.parentWays(this).filter(function(parent) {
24292                 return parent.tags.highway && parent.geometry(resolver) === 'line';
24293             }).length > 1;
24294         });
24295     },
24296
24297
24298     isOnAddressLine: function(resolver) {
24299         return resolver.transient(this, 'isOnAddressLine', function() {
24300             return resolver.parentWays(this).filter(function(parent) {
24301                 return parent.tags.hasOwnProperty('addr:interpolation') &&
24302                     parent.geometry(resolver) === 'line';
24303             }).length > 0;
24304         });
24305     },
24306
24307
24308     asJXON: function(changeset_id) {
24309         var r = {
24310             node: {
24311                 '@id': this.osmId(),
24312                 '@lon': this.loc[0],
24313                 '@lat': this.loc[1],
24314                 '@version': (this.version || 0),
24315                 tag: map$4(this.tags, function(v, k) {
24316                     return { keyAttributes: { k: k, v: v } };
24317                 })
24318             }
24319         };
24320         if (changeset_id) r.node['@changeset'] = changeset_id;
24321         return r;
24322     },
24323
24324
24325     asGeoJSON: function() {
24326         return {
24327             type: 'Point',
24328             coordinates: this.loc
24329         };
24330     }
24331 });
24332
24333 /** Error message constants. */
24334 var FUNC_ERROR_TEXT$1 = 'Expected a function';
24335
24336 /**
24337  * Creates a function that negates the result of the predicate `func`. The
24338  * `func` predicate is invoked with the `this` binding and arguments of the
24339  * created function.
24340  *
24341  * @static
24342  * @memberOf _
24343  * @since 3.0.0
24344  * @category Function
24345  * @param {Function} predicate The predicate to negate.
24346  * @returns {Function} Returns the new negated function.
24347  * @example
24348  *
24349  * function isEven(n) {
24350  *   return n % 2 == 0;
24351  * }
24352  *
24353  * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
24354  * // => [1, 3, 5]
24355  */
24356 function negate(predicate) {
24357   if (typeof predicate != 'function') {
24358     throw new TypeError(FUNC_ERROR_TEXT$1);
24359   }
24360   return function() {
24361     var args = arguments;
24362     switch (args.length) {
24363       case 0: return !predicate.call(this);
24364       case 1: return !predicate.call(this, args[0]);
24365       case 2: return !predicate.call(this, args[0], args[1]);
24366       case 3: return !predicate.call(this, args[0], args[1], args[2]);
24367     }
24368     return !predicate.apply(this, args);
24369   };
24370 }
24371
24372 /**
24373  * The opposite of `_.filter`; this method returns the elements of `collection`
24374  * that `predicate` does **not** return truthy for.
24375  *
24376  * @static
24377  * @memberOf _
24378  * @since 0.1.0
24379  * @category Collection
24380  * @param {Array|Object} collection The collection to iterate over.
24381  * @param {Function} [predicate=_.identity] The function invoked per iteration.
24382  * @returns {Array} Returns the new filtered array.
24383  * @see _.filter
24384  * @example
24385  *
24386  * var users = [
24387  *   { 'user': 'barney', 'age': 36, 'active': false },
24388  *   { 'user': 'fred',   'age': 40, 'active': true }
24389  * ];
24390  *
24391  * _.reject(users, function(o) { return !o.active; });
24392  * // => objects for ['fred']
24393  *
24394  * // The `_.matches` iteratee shorthand.
24395  * _.reject(users, { 'age': 40, 'active': true });
24396  * // => objects for ['barney']
24397  *
24398  * // The `_.matchesProperty` iteratee shorthand.
24399  * _.reject(users, ['active', false]);
24400  * // => objects for ['fred']
24401  *
24402  * // The `_.property` iteratee shorthand.
24403  * _.reject(users, 'active');
24404  * // => objects for ['barney']
24405  */
24406 function reject(collection, predicate) {
24407   var func = isArray(collection) ? arrayFilter : baseFilter;
24408   return func(collection, negate(baseIteratee(predicate, 3)));
24409 }
24410
24411 /**
24412  * An alternative to `_.reduce`; this method transforms `object` to a new
24413  * `accumulator` object which is the result of running each of its own
24414  * enumerable string keyed properties thru `iteratee`, with each invocation
24415  * potentially mutating the `accumulator` object. If `accumulator` is not
24416  * provided, a new object with the same `[[Prototype]]` will be used. The
24417  * iteratee is invoked with four arguments: (accumulator, value, key, object).
24418  * Iteratee functions may exit iteration early by explicitly returning `false`.
24419  *
24420  * @static
24421  * @memberOf _
24422  * @since 1.3.0
24423  * @category Object
24424  * @param {Object} object The object to iterate over.
24425  * @param {Function} [iteratee=_.identity] The function invoked per iteration.
24426  * @param {*} [accumulator] The custom accumulator value.
24427  * @returns {*} Returns the accumulated value.
24428  * @example
24429  *
24430  * _.transform([2, 3, 4], function(result, n) {
24431  *   result.push(n *= n);
24432  *   return n % 2 == 0;
24433  * }, []);
24434  * // => [4, 9]
24435  *
24436  * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
24437  *   (result[value] || (result[value] = [])).push(key);
24438  * }, {});
24439  * // => { '1': ['a', 'c'], '2': ['b'] }
24440  */
24441 function transform$1(object, iteratee, accumulator) {
24442   var isArr = isArray(object),
24443       isArrLike = isArr || isBuffer(object) || isTypedArray(object);
24444
24445   iteratee = baseIteratee(iteratee, 4);
24446   if (accumulator == null) {
24447     var Ctor = object && object.constructor;
24448     if (isArrLike) {
24449       accumulator = isArr ? new Ctor : [];
24450     }
24451     else if (isObject(object)) {
24452       accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
24453     }
24454     else {
24455       accumulator = {};
24456     }
24457   }
24458   (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) {
24459     return iteratee(accumulator, value, index, object);
24460   });
24461   return accumulator;
24462 }
24463
24464 /*
24465   Order the nodes of a way in reverse order and reverse any direction dependent tags
24466   other than `oneway`. (We assume that correcting a backwards oneway is the primary
24467   reason for reversing a way.)
24468
24469   The following transforms are performed:
24470
24471     Keys:
24472           *:right=* ⟺ *:left=*
24473         *:forward=* ⟺ *:backward=*
24474        direction=up ⟺ direction=down
24475          incline=up ⟺ incline=down
24476             *=right ⟺ *=left
24477
24478     Relation members:
24479        role=forward ⟺ role=backward
24480          role=north ⟺ role=south
24481           role=east ⟺ role=west
24482
24483    In addition, numeric-valued `incline` tags are negated.
24484
24485    The JOSM implementation was used as a guide, but transformations that were of unclear benefit
24486    or adjusted tags that don't seem to be used in practice were omitted.
24487
24488    Also, each node on the way is examined for its own tags and the following transformations are performed
24489    in order to ensure associated nodes (eg a Stop Sign) is also reversed
24490
24491     Node Keys:
24492         direction=forward ⟺ direction=backward
24493         direction=left ⟺ direction=right
24494         *:forward=* ⟺ *:backward=*
24495         *:left=* ⟺ *:right=*
24496
24497    References:
24498       http://wiki.openstreetmap.org/wiki/Forward_%26_backward,_left_%26_right
24499       http://wiki.openstreetmap.org/wiki/Key:direction#Steps
24500       http://wiki.openstreetmap.org/wiki/Key:incline
24501       http://wiki.openstreetmap.org/wiki/Route#Members
24502       http://josm.openstreetmap.de/browser/josm/trunk/src/org/openstreetmap/josm/corrector/ReverseWayTagCorrector.java
24503       http://wiki.openstreetmap.org/wiki/Tag:highway%3Dstop
24504       http://wiki.openstreetmap.org/wiki/Key:traffic_sign#On_a_way_or_area
24505  */
24506 function actionReverse(wayId, options) {
24507     var replacements = [
24508             [/:right$/, ':left'], [/:left$/, ':right'],
24509             [/:forward$/, ':backward'], [/:backward$/, ':forward']
24510         ],
24511         numeric = /^([+\-]?)(?=[\d.])/,
24512         roleReversals = {
24513             forward: 'backward',
24514             backward: 'forward',
24515             north: 'south',
24516             south: 'north',
24517             east: 'west',
24518             west: 'east'
24519         };
24520
24521
24522     function reverseKey(key) {
24523         for (var i = 0; i < replacements.length; ++i) {
24524             var replacement = replacements[i];
24525             if (replacement[0].test(key)) {
24526                 return key.replace(replacement[0], replacement[1]);
24527             }
24528         }
24529         return key;
24530     }
24531
24532
24533     function reverseValue(key, value) {
24534         if (key === 'incline' && numeric.test(value)) {
24535             return value.replace(numeric, function(_, sign) { return sign === '-' ? '' : '-'; });
24536         } else if (key === 'incline' || key === 'direction') {
24537             return {up: 'down', down: 'up'}[value] || value;
24538         } else if (options && options.reverseOneway && key === 'oneway') {
24539             return {yes: '-1', '1': '-1', '-1': 'yes'}[value] || value;
24540         } else {
24541             return {left: 'right', right: 'left'}[value] || value;
24542         }
24543     }
24544
24545
24546     function reverseDirectionTags(node) {
24547         // Update the direction based tags as appropriate then return an updated node
24548         return node.update({tags: transform$1(node.tags, function(acc, tagValue, tagKey) {
24549             // See if this is a direction tag and reverse (or use existing value if not recognised)
24550             if (tagKey === 'direction') {
24551                 acc[tagKey] = {forward: 'backward', backward: 'forward', left: 'right', right: 'left'}[tagValue] || tagValue;
24552             } else {
24553                 // Use the reverseKey method to cater for situations such as traffic_sign:forward=stop
24554                 // This will pass through other tags unchanged
24555                 acc[reverseKey(tagKey)] = tagValue;
24556             }
24557             return acc;
24558         }, {})});
24559     }
24560
24561
24562     function reverseTagsOnNodes(graph, nodeIds) {
24563         // Reverse the direction of appropriate tags attached to the nodes (#3076)
24564         return nodeIds
24565             // Get each node from the graph
24566             .map(function(nodeId) { return graph.entity(nodeId);})
24567             // Check tags on the node, if there aren't any, we can skip
24568             .filter(function(existingNode) { return existingNode.tags !== undefined;})
24569             // Get a new version of each node with the appropriate tags reversed
24570             .map(function(existingNode) { return reverseDirectionTags(existingNode);})
24571             // Chain together consecutive updates to the graph for each updated node and return
24572             .reduce(function (accGraph, value) { return accGraph.replace(value); }, graph);
24573     }
24574
24575
24576     return function(graph) {
24577         var way = graph.entity(wayId),
24578             nodes = way.nodes.slice().reverse(),
24579             tags = {}, key, role;
24580
24581         for (key in way.tags) {
24582             tags[reverseKey(key)] = reverseValue(key, way.tags[key]);
24583         }
24584
24585         graph.parentRelations(way).forEach(function(relation) {
24586             relation.members.forEach(function(member, index) {
24587                 if (member.id === way.id && (role = roleReversals[member.role])) {
24588                     relation = relation.updateMember({role: role}, index);
24589                     graph = graph.replace(relation);
24590                 }
24591             });
24592         });
24593
24594         // Reverse any associated directions on nodes on the way and then replace
24595         // the way itself with the reversed node ids and updated way tags
24596         return reverseTagsOnNodes(graph, nodes).replace(way.update({nodes: nodes, tags: tags}));
24597     };
24598 }
24599
24600 // For fixing up rendering of multipolygons with tags on the outer member.
24601 // https://github.com/openstreetmap/iD/issues/613
24602 function osmIsSimpleMultipolygonOuterMember(entity, graph) {
24603     if (entity.type !== 'way' || Object.keys(entity.tags).filter(osmIsInterestingTag).length === 0)
24604         return false;
24605
24606     var parents = graph.parentRelations(entity);
24607     if (parents.length !== 1)
24608         return false;
24609
24610     var parent = parents[0];
24611     if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1)
24612         return false;
24613
24614     var members = parent.members, member;
24615     for (var i = 0; i < members.length; i++) {
24616         member = members[i];
24617         if (member.id === entity.id && member.role && member.role !== 'outer')
24618             return false; // Not outer member
24619         if (member.id !== entity.id && (!member.role || member.role === 'outer'))
24620             return false; // Not a simple multipolygon
24621     }
24622
24623     return parent;
24624 }
24625
24626
24627 function osmSimpleMultipolygonOuterMember(entity, graph) {
24628     if (entity.type !== 'way')
24629         return false;
24630
24631     var parents = graph.parentRelations(entity);
24632     if (parents.length !== 1)
24633         return false;
24634
24635     var parent = parents[0];
24636     if (!parent.isMultipolygon() || Object.keys(parent.tags).filter(osmIsInterestingTag).length > 1)
24637         return false;
24638
24639     var members = parent.members, member, outerMember;
24640     for (var i = 0; i < members.length; i++) {
24641         member = members[i];
24642         if (!member.role || member.role === 'outer') {
24643             if (outerMember)
24644                 return false; // Not a simple multipolygon
24645             outerMember = member;
24646         }
24647     }
24648
24649     if (!outerMember)
24650         return false;
24651
24652     var outerEntity = graph.hasEntity(outerMember.id);
24653     if (!outerEntity || !Object.keys(outerEntity.tags).filter(osmIsInterestingTag).length)
24654         return false;
24655
24656     return outerEntity;
24657 }
24658
24659
24660 // Join `array` into sequences of connecting ways.
24661 //
24662 // Segments which share identical start/end nodes will, as much as possible,
24663 // be connected with each other.
24664 //
24665 // The return value is a nested array. Each constituent array contains elements
24666 // of `array` which have been determined to connect. Each consitituent array
24667 // also has a `nodes` property whose value is an ordered array of member nodes,
24668 // with appropriate order reversal and start/end coordinate de-duplication.
24669 //
24670 // Members of `array` must have, at minimum, `type` and `id` properties.
24671 // Thus either an array of `osmWay`s or a relation member array may be
24672 // used.
24673 //
24674 // If an member has a `tags` property, its tags will be reversed via
24675 // `actionReverse` in the output.
24676 //
24677 // Incomplete members (those for which `graph.hasEntity(element.id)` returns
24678 // false) and non-way members are ignored.
24679 //
24680 function osmJoinWays(array, graph) {
24681     var joined = [], member, current, nodes, first, last, i, how, what;
24682
24683     array = array.filter(function(member) {
24684         return member.type === 'way' && graph.hasEntity(member.id);
24685     });
24686
24687     function resolve(member) {
24688         return graph.childNodes(graph.entity(member.id));
24689     }
24690
24691     function reverse(member) {
24692         return member.tags ? actionReverse(member.id, { reverseOneway: true })(graph).entity(member.id) : member;
24693     }
24694
24695     while (array.length) {
24696         member = array.shift();
24697         current = [member];
24698         current.nodes = nodes = resolve(member).slice();
24699         joined.push(current);
24700
24701         while (array.length && nodes[0] !== nodes[nodes.length - 1]) {
24702             first = nodes[0];
24703             last  = nodes[nodes.length - 1];
24704
24705             for (i = 0; i < array.length; i++) {
24706                 member = array[i];
24707                 what = resolve(member);
24708
24709                 if (last === what[0]) {
24710                     how  = nodes.push;
24711                     what = what.slice(1);
24712                     break;
24713                 } else if (last === what[what.length - 1]) {
24714                     how  = nodes.push;
24715                     what = what.slice(0, -1).reverse();
24716                     member = reverse(member);
24717                     break;
24718                 } else if (first === what[what.length - 1]) {
24719                     how  = nodes.unshift;
24720                     what = what.slice(0, -1);
24721                     break;
24722                 } else if (first === what[0]) {
24723                     how  = nodes.unshift;
24724                     what = what.slice(1).reverse();
24725                     member = reverse(member);
24726                     break;
24727                 } else {
24728                     what = how = null;
24729                 }
24730             }
24731
24732             if (!what)
24733                 break; // No more joinable ways.
24734
24735             how.apply(current, [member]);
24736             how.apply(nodes, what);
24737
24738             array.splice(i, 1);
24739         }
24740     }
24741
24742     return joined;
24743 }
24744
24745 function osmRelation() {
24746     if (!(this instanceof osmRelation)) {
24747         return (new osmRelation()).initialize(arguments);
24748     } else if (arguments.length) {
24749         this.initialize(arguments);
24750     }
24751 }
24752
24753
24754 osmEntity.relation = osmRelation;
24755
24756 osmRelation.prototype = Object.create(osmEntity.prototype);
24757
24758
24759 osmRelation.creationOrder = function(a, b) {
24760     var aId = parseInt(osmEntity.id.toOSM(a.id), 10);
24761     var bId = parseInt(osmEntity.id.toOSM(b.id), 10);
24762
24763     if (aId < 0 || bId < 0) return aId - bId;
24764     return bId - aId;
24765 };
24766
24767
24768 assignIn(osmRelation.prototype, {
24769     type: 'relation',
24770     members: [],
24771
24772
24773     copy: function(resolver, copies) {
24774         if (copies[this.id])
24775             return copies[this.id];
24776
24777         var copy = osmEntity.prototype.copy.call(this, resolver, copies);
24778
24779         var members = this.members.map(function(member) {
24780             return assignIn({}, member, { id: resolver.entity(member.id).copy(resolver, copies).id });
24781         });
24782
24783         copy = copy.update({members: members});
24784         copies[this.id] = copy;
24785
24786         return copy;
24787     },
24788
24789
24790     extent: function(resolver, memo) {
24791         return resolver.transient(this, 'extent', function() {
24792             if (memo && memo[this.id]) return geoExtent();
24793             memo = memo || {};
24794             memo[this.id] = true;
24795
24796             var extent = geoExtent();
24797             for (var i = 0; i < this.members.length; i++) {
24798                 var member = resolver.hasEntity(this.members[i].id);
24799                 if (member) {
24800                     extent._extend(member.extent(resolver, memo));
24801                 }
24802             }
24803             return extent;
24804         });
24805     },
24806
24807
24808     geometry: function(graph) {
24809         return graph.transient(this, 'geometry', function() {
24810             return this.isMultipolygon() ? 'area' : 'relation';
24811         });
24812     },
24813
24814
24815     isDegenerate: function() {
24816         return this.members.length === 0;
24817     },
24818
24819
24820     // Return an array of members, each extended with an 'index' property whose value
24821     // is the member index.
24822     indexedMembers: function() {
24823         var result = new Array(this.members.length);
24824         for (var i = 0; i < this.members.length; i++) {
24825             result[i] = assignIn({}, this.members[i], {index: i});
24826         }
24827         return result;
24828     },
24829
24830
24831     // Return the first member with the given role. A copy of the member object
24832     // is returned, extended with an 'index' property whose value is the member index.
24833     memberByRole: function(role) {
24834         for (var i = 0; i < this.members.length; i++) {
24835             if (this.members[i].role === role) {
24836                 return assignIn({}, this.members[i], {index: i});
24837             }
24838         }
24839     },
24840
24841
24842     // Return the first member with the given id. A copy of the member object
24843     // is returned, extended with an 'index' property whose value is the member index.
24844     memberById: function(id) {
24845         for (var i = 0; i < this.members.length; i++) {
24846             if (this.members[i].id === id) {
24847                 return assignIn({}, this.members[i], {index: i});
24848             }
24849         }
24850     },
24851
24852
24853     // Return the first member with the given id and role. A copy of the member object
24854     // is returned, extended with an 'index' property whose value is the member index.
24855     memberByIdAndRole: function(id, role) {
24856         for (var i = 0; i < this.members.length; i++) {
24857             if (this.members[i].id === id && this.members[i].role === role) {
24858                 return assignIn({}, this.members[i], {index: i});
24859             }
24860         }
24861     },
24862
24863
24864     addMember: function(member, index) {
24865         var members = this.members.slice();
24866         members.splice(index === undefined ? members.length : index, 0, member);
24867         return this.update({members: members});
24868     },
24869
24870
24871     updateMember: function(member, index) {
24872         var members = this.members.slice();
24873         members.splice(index, 1, assignIn({}, members[index], member));
24874         return this.update({members: members});
24875     },
24876
24877
24878     removeMember: function(index) {
24879         var members = this.members.slice();
24880         members.splice(index, 1);
24881         return this.update({members: members});
24882     },
24883
24884
24885     removeMembersWithID: function(id) {
24886         var members = reject(this.members, function(m) { return m.id === id; });
24887         return this.update({members: members});
24888     },
24889
24890
24891     // Wherever a member appears with id `needle.id`, replace it with a member
24892     // with id `replacement.id`, type `replacement.type`, and the original role,
24893     // unless a member already exists with that id and role. Return an updated
24894     // relation.
24895     replaceMember: function(needle, replacement) {
24896         if (!this.memberById(needle.id))
24897             return this;
24898
24899         var members = [];
24900
24901         for (var i = 0; i < this.members.length; i++) {
24902             var member = this.members[i];
24903             if (member.id !== needle.id) {
24904                 members.push(member);
24905             } else if (!this.memberByIdAndRole(replacement.id, member.role)) {
24906                 members.push({id: replacement.id, type: replacement.type, role: member.role});
24907             }
24908         }
24909
24910         return this.update({members: members});
24911     },
24912
24913
24914     asJXON: function(changeset_id) {
24915         var r = {
24916             relation: {
24917                 '@id': this.osmId(),
24918                 '@version': this.version || 0,
24919                 member: map$4(this.members, function(member) {
24920                     return {
24921                         keyAttributes: {
24922                             type: member.type,
24923                             role: member.role,
24924                             ref: osmEntity.id.toOSM(member.id)
24925                         }
24926                     };
24927                 }),
24928                 tag: map$4(this.tags, function(v, k) {
24929                     return { keyAttributes: { k: k, v: v } };
24930                 })
24931             }
24932         };
24933         if (changeset_id) r.relation['@changeset'] = changeset_id;
24934         return r;
24935     },
24936
24937
24938     asGeoJSON: function(resolver) {
24939         return resolver.transient(this, 'GeoJSON', function () {
24940             if (this.isMultipolygon()) {
24941                 return {
24942                     type: 'MultiPolygon',
24943                     coordinates: this.multipolygon(resolver)
24944                 };
24945             } else {
24946                 return {
24947                     type: 'FeatureCollection',
24948                     properties: this.tags,
24949                     features: this.members.map(function (member) {
24950                         return assignIn({role: member.role}, resolver.entity(member.id).asGeoJSON(resolver));
24951                     })
24952                 };
24953             }
24954         });
24955     },
24956
24957
24958     area: function(resolver) {
24959         return resolver.transient(this, 'area', function() {
24960             return d3_geoArea(this.asGeoJSON(resolver));
24961         });
24962     },
24963
24964
24965     isMultipolygon: function() {
24966         return this.tags.type === 'multipolygon';
24967     },
24968
24969
24970     isComplete: function(resolver) {
24971         for (var i = 0; i < this.members.length; i++) {
24972             if (!resolver.hasEntity(this.members[i].id)) {
24973                 return false;
24974             }
24975         }
24976         return true;
24977     },
24978
24979
24980     isRestriction: function() {
24981         return !!(this.tags.type && this.tags.type.match(/^restriction:?/));
24982     },
24983
24984
24985     // Returns an array [A0, ... An], each Ai being an array of node arrays [Nds0, ... Ndsm],
24986     // where Nds0 is an outer ring and subsequent Ndsi's (if any i > 0) being inner rings.
24987     //
24988     // This corresponds to the structure needed for rendering a multipolygon path using a
24989     // `evenodd` fill rule, as well as the structure of a GeoJSON MultiPolygon geometry.
24990     //
24991     // In the case of invalid geometries, this function will still return a result which
24992     // includes the nodes of all way members, but some Nds may be unclosed and some inner
24993     // rings not matched with the intended outer ring.
24994     //
24995     multipolygon: function(resolver) {
24996         var outers = this.members.filter(function(m) { return 'outer' === (m.role || 'outer'); }),
24997             inners = this.members.filter(function(m) { return 'inner' === m.role; });
24998
24999         outers = osmJoinWays(outers, resolver);
25000         inners = osmJoinWays(inners, resolver);
25001
25002         outers = outers.map(function(outer) { return map$4(outer.nodes, 'loc'); });
25003         inners = inners.map(function(inner) { return map$4(inner.nodes, 'loc'); });
25004
25005         var result = outers.map(function(o) {
25006             // Heuristic for detecting counterclockwise winding order. Assumes
25007             // that OpenStreetMap polygons are not hemisphere-spanning.
25008             return [d3_geoArea({ type: 'Polygon', coordinates: [o] }) > 2 * Math.PI ? o.reverse() : o];
25009         });
25010
25011         function findOuter(inner) {
25012             var o, outer;
25013
25014             for (o = 0; o < outers.length; o++) {
25015                 outer = outers[o];
25016                 if (geoPolygonContainsPolygon(outer, inner))
25017                     return o;
25018             }
25019
25020             for (o = 0; o < outers.length; o++) {
25021                 outer = outers[o];
25022                 if (geoPolygonIntersectsPolygon(outer, inner, false))
25023                     return o;
25024             }
25025         }
25026
25027         for (var i = 0; i < inners.length; i++) {
25028             var inner = inners[i];
25029
25030             if (d3_geoArea({ type: 'Polygon', coordinates: [inner] }) < 2 * Math.PI) {
25031                 inner = inner.reverse();
25032             }
25033
25034             var o = findOuter(inners[i]);
25035             if (o !== undefined)
25036                 result[o].push(inners[i]);
25037             else
25038                 result.push([inners[i]]); // Invalid geometry
25039         }
25040
25041         return result;
25042     }
25043 });
25044
25045 /**
25046  * Creates a duplicate-free version of an array, using
25047  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
25048  * for equality comparisons, in which only the first occurrence of each element
25049  * is kept. The order of result values is determined by the order they occur
25050  * in the array.
25051  *
25052  * @static
25053  * @memberOf _
25054  * @since 0.1.0
25055  * @category Array
25056  * @param {Array} array The array to inspect.
25057  * @returns {Array} Returns the new duplicate free array.
25058  * @example
25059  *
25060  * _.uniq([2, 1, 2]);
25061  * // => [2, 1]
25062  */
25063 function uniq(array) {
25064   return (array && array.length) ? baseUniq(array) : [];
25065 }
25066
25067 /** `Object#toString` result references. */
25068 var numberTag$4 = '[object Number]';
25069
25070 /**
25071  * Checks if `value` is classified as a `Number` primitive or object.
25072  *
25073  * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
25074  * classified as numbers, use the `_.isFinite` method.
25075  *
25076  * @static
25077  * @memberOf _
25078  * @since 0.1.0
25079  * @category Lang
25080  * @param {*} value The value to check.
25081  * @returns {boolean} Returns `true` if `value` is a number, else `false`.
25082  * @example
25083  *
25084  * _.isNumber(3);
25085  * // => true
25086  *
25087  * _.isNumber(Number.MIN_VALUE);
25088  * // => true
25089  *
25090  * _.isNumber(Infinity);
25091  * // => true
25092  *
25093  * _.isNumber('3');
25094  * // => false
25095  */
25096 function isNumber(value) {
25097   return typeof value == 'number' ||
25098     (isObjectLike(value) && baseGetTag(value) == numberTag$4);
25099 }
25100
25101 /** `Object#toString` result references. */
25102 var stringTag$4 = '[object String]';
25103
25104 /**
25105  * Checks if `value` is classified as a `String` primitive or object.
25106  *
25107  * @static
25108  * @since 0.1.0
25109  * @memberOf _
25110  * @category Lang
25111  * @param {*} value The value to check.
25112  * @returns {boolean} Returns `true` if `value` is a string, else `false`.
25113  * @example
25114  *
25115  * _.isString('abc');
25116  * // => true
25117  *
25118  * _.isString(1);
25119  * // => false
25120  */
25121 function isString(value) {
25122   return typeof value == 'string' ||
25123     (!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag$4);
25124 }
25125
25126 /**
25127  * Checks if `value` is `NaN`.
25128  *
25129  * **Note:** This method is based on
25130  * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
25131  * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
25132  * `undefined` and other non-number values.
25133  *
25134  * @static
25135  * @memberOf _
25136  * @since 0.1.0
25137  * @category Lang
25138  * @param {*} value The value to check.
25139  * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
25140  * @example
25141  *
25142  * _.isNaN(NaN);
25143  * // => true
25144  *
25145  * _.isNaN(new Number(NaN));
25146  * // => true
25147  *
25148  * isNaN(undefined);
25149  * // => true
25150  *
25151  * _.isNaN(undefined);
25152  * // => false
25153  */
25154 function isNaN$1(value) {
25155   // An `NaN` primitive is the only value that is not equal to itself.
25156   // Perform the `toStringTag` check first to avoid errors with some
25157   // ActiveX objects in IE.
25158   return isNumber(value) && value != +value;
25159 }
25160
25161 function osmLanes(entity) {
25162     if (entity.type !== 'way') return null;
25163     if (!entity.tags.highway) return null;
25164
25165     var tags = entity.tags;
25166     var isOneWay = entity.isOneWay();
25167     var laneCount = getLaneCount(tags, isOneWay);
25168     var maxspeed = parseMaxspeed(tags);
25169
25170     var laneDirections = parseLaneDirections(tags, isOneWay, laneCount);
25171     var forward = laneDirections.forward;
25172     var backward = laneDirections.backward;
25173     var bothways = laneDirections.bothways;
25174
25175     // parse the piped string 'x|y|z' format
25176     var turnLanes = {};
25177     turnLanes.unspecified = parseTurnLanes(tags['turn:lanes']);
25178     turnLanes.forward = parseTurnLanes(tags['turn:lanes:forward']);
25179     turnLanes.backward = parseTurnLanes(tags['turn:lanes:backward']);
25180
25181     var maxspeedLanes = {};
25182     maxspeedLanes.unspecified = parseMaxspeedLanes(tags['maxspeed:lanes'], maxspeed);
25183     maxspeedLanes.forward = parseMaxspeedLanes(tags['maxspeed:lanes:forward'], maxspeed);
25184     maxspeedLanes.backward = parseMaxspeedLanes(tags['maxspeed:lanes:backward'], maxspeed);
25185
25186     var psvLanes = {};
25187     psvLanes.unspecified = parseMiscLanes(tags['psv:lanes']);
25188     psvLanes.forward = parseMiscLanes(tags['psv:lanes:forward']);
25189     psvLanes.backward = parseMiscLanes(tags['psv:lanes:backward']);
25190
25191     var busLanes = {};
25192     busLanes.unspecified = parseMiscLanes(tags['bus:lanes']);
25193     busLanes.forward = parseMiscLanes(tags['bus:lanes:forward']);
25194     busLanes.backward = parseMiscLanes(tags['bus:lanes:backward']);
25195
25196     var taxiLanes = {};
25197     taxiLanes.unspecified = parseMiscLanes(tags['taxi:lanes']);
25198     taxiLanes.forward = parseMiscLanes(tags['taxi:lanes:forward']);
25199     taxiLanes.backward = parseMiscLanes(tags['taxi:lanes:backward']);
25200
25201     var hovLanes = {};
25202     hovLanes.unspecified = parseMiscLanes(tags['hov:lanes']);
25203     hovLanes.forward = parseMiscLanes(tags['hov:lanes:forward']);
25204     hovLanes.backward = parseMiscLanes(tags['hov:lanes:backward']);
25205
25206     var hgvLanes = {};
25207     hgvLanes.unspecified = parseMiscLanes(tags['hgv:lanes']);
25208     hgvLanes.forward = parseMiscLanes(tags['hgv:lanes:forward']);
25209     hgvLanes.backward = parseMiscLanes(tags['hgv:lanes:backward']);
25210
25211     var bicyclewayLanes = {};
25212     bicyclewayLanes.unspecified = parseBicycleWay(tags['bicycleway:lanes']);
25213     bicyclewayLanes.forward = parseBicycleWay(tags['bicycleway:lanes:forward']);
25214     bicyclewayLanes.backward = parseBicycleWay(tags['bicycleway:lanes:backward']);
25215
25216     var lanesObj = {
25217         forward: [],
25218         backward: [],
25219         unspecified: []
25220     };
25221
25222     // map forward/backward/unspecified of each lane type to lanesObj
25223     mapToLanesObj(lanesObj, turnLanes, 'turnLane');
25224     mapToLanesObj(lanesObj, maxspeedLanes, 'maxspeed');
25225     mapToLanesObj(lanesObj, psvLanes, 'psv');
25226     mapToLanesObj(lanesObj, busLanes, 'bus');
25227     mapToLanesObj(lanesObj, taxiLanes, 'taxi');
25228     mapToLanesObj(lanesObj, hovLanes, 'hov');
25229     mapToLanesObj(lanesObj, hgvLanes, 'hgv');
25230     mapToLanesObj(lanesObj, bicyclewayLanes, 'bicycleway');
25231
25232     return {
25233         metadata: {
25234             count: laneCount,
25235             oneway: isOneWay,
25236             forward: forward,
25237             backward: backward,
25238             bothways: bothways,
25239             turnLanes: turnLanes,
25240             maxspeed: maxspeed,
25241             maxspeedLanes: maxspeedLanes,
25242             psvLanes: psvLanes,
25243             busLanes: busLanes,
25244             taxiLanes: taxiLanes,
25245             hovLanes: hovLanes,
25246             hgvLanes: hgvLanes,
25247             bicyclewayLanes: bicyclewayLanes
25248         },
25249         lanes: lanesObj
25250     };
25251 }
25252
25253
25254 function getLaneCount(tags, isOneWay) {
25255     var count;
25256     if (tags.lanes) {
25257         count = parseInt(tags.lanes, 10);
25258         if (count > 0) {
25259             return count;
25260         }
25261     }
25262
25263
25264     switch (tags.highway) {
25265         case 'trunk':
25266         case 'motorway':
25267             count = isOneWay ? 2 : 4;
25268             break;
25269         default:
25270             count = isOneWay ? 1 : 2;
25271             break;
25272     }
25273
25274     return count;
25275 }
25276
25277
25278 function parseMaxspeed(tags) {
25279     var maxspeed = tags.maxspeed;
25280     if (isNumber(maxspeed)) return maxspeed;
25281     if (isString(maxspeed)) {
25282         maxspeed = maxspeed.match(/^([0-9][\.0-9]+?)(?:[ ]?(?:km\/h|kmh|kph|mph|knots))?$/g);
25283         if (!maxspeed) return;
25284         return parseInt(maxspeed, 10);
25285     }
25286 }
25287
25288
25289 function parseLaneDirections(tags, isOneWay, laneCount) {
25290     var forward = parseInt(tags['lanes:forward'], 10);
25291     var backward = parseInt(tags['lanes:backward'], 10);
25292     var bothways = parseInt(tags['lanes:both_ways'], 10) > 0 ? 1 : 0;
25293
25294     if (parseInt(tags.oneway, 10) === -1) {
25295         forward = 0;
25296         bothways = 0;
25297         backward = laneCount;
25298     }
25299     else if (isOneWay) {
25300         forward = laneCount;
25301         bothways = 0;
25302         backward = 0;
25303     }
25304     else if (isNaN$1(forward) && isNaN$1(backward)) {
25305         backward = Math.floor((laneCount - bothways) / 2);
25306         forward = laneCount - bothways - backward;
25307     }
25308     else if (isNaN$1(forward)) {
25309         if (backward > laneCount - bothways) {
25310             backward = laneCount - bothways;
25311         }
25312         forward = laneCount - bothways - backward;
25313     }
25314     else if (isNaN$1(backward)) {
25315         if (forward > laneCount - bothways) {
25316             forward = laneCount - bothways;
25317         }
25318         backward = laneCount - bothways - forward;
25319     }
25320     return {
25321         forward: forward,
25322         backward: backward,
25323         bothways: bothways
25324     };
25325 }
25326
25327
25328 function parseTurnLanes(tag){
25329     if (!tag) return;
25330
25331     var validValues = [
25332         'left', 'slight_left', 'sharp_left', 'through', 'right', 'slight_right',
25333         'sharp_right', 'reverse', 'merge_to_left', 'merge_to_right', 'none'
25334     ];
25335
25336     return tag.split('|')
25337         .map(function (s) {
25338             if (s === '') s = 'none';
25339             return s.split(';')
25340                 .map(function (d) {
25341                     return validValues.indexOf(d) === -1 ? 'unknown': d;
25342                 });
25343         });
25344 }
25345
25346
25347 function parseMaxspeedLanes(tag, maxspeed) {
25348     if (!tag) return;
25349
25350     return tag.split('|')
25351         .map(function (s) {
25352             if (s === 'none') return s;
25353             var m = parseInt(s, 10);
25354             if (s === '' || m === maxspeed) return null;
25355             return isNaN$1(m) ? 'unknown': m;
25356         });
25357 }
25358
25359
25360 function parseMiscLanes(tag) {
25361     if (!tag) return;
25362
25363     var validValues = [
25364         'yes', 'no', 'designated'
25365     ];
25366
25367     return tag.split('|')
25368         .map(function (s) {
25369             if (s === '') s = 'no';
25370             return validValues.indexOf(s) === -1 ? 'unknown': s;
25371         });
25372 }
25373
25374
25375 function parseBicycleWay(tag) {
25376     if (!tag) return;
25377
25378     var validValues = [
25379         'yes', 'no', 'designated', 'lane'
25380     ];
25381
25382     return tag.split('|')
25383         .map(function (s) {
25384             if (s === '') s = 'no';
25385             return validValues.indexOf(s) === -1 ? 'unknown': s;
25386         });
25387 }
25388
25389
25390 function mapToLanesObj(lanesObj, data, key) {
25391     if (data.forward) data.forward.forEach(function(l, i) {
25392         if (!lanesObj.forward[i]) lanesObj.forward[i] = {};
25393         lanesObj.forward[i][key] = l;
25394     });
25395     if (data.backward) data.backward.forEach(function(l, i) {
25396         if (!lanesObj.backward[i]) lanesObj.backward[i] = {};
25397         lanesObj.backward[i][key] = l;
25398     });
25399     if (data.unspecified) data.unspecified.forEach(function(l, i) {
25400         if (!lanesObj.unspecified[i]) lanesObj.unspecified[i] = {};
25401         lanesObj.unspecified[i][key] = l;
25402     });
25403 }
25404
25405 /** Used to compose bitmasks for cloning. */
25406 var CLONE_DEEP_FLAG$3 = 1;
25407 var CLONE_SYMBOLS_FLAG$2 = 4;
25408
25409 /**
25410  * This method is like `_.clone` except that it recursively clones `value`.
25411  *
25412  * @static
25413  * @memberOf _
25414  * @since 1.0.0
25415  * @category Lang
25416  * @param {*} value The value to recursively clone.
25417  * @returns {*} Returns the deep cloned value.
25418  * @see _.clone
25419  * @example
25420  *
25421  * var objects = [{ 'a': 1 }, { 'b': 2 }];
25422  *
25423  * var deep = _.cloneDeep(objects);
25424  * console.log(deep[0] === objects[0]);
25425  * // => false
25426  */
25427 function cloneDeep(value) {
25428   return baseClone(value, CLONE_DEEP_FLAG$3 | CLONE_SYMBOLS_FLAG$2);
25429 }
25430
25431 /**
25432  * Gets the timestamp of the number of milliseconds that have elapsed since
25433  * the Unix epoch (1 January 1970 00:00:00 UTC).
25434  *
25435  * @static
25436  * @memberOf _
25437  * @since 2.4.0
25438  * @category Date
25439  * @returns {number} Returns the timestamp.
25440  * @example
25441  *
25442  * _.defer(function(stamp) {
25443  *   console.log(_.now() - stamp);
25444  * }, _.now());
25445  * // => Logs the number of milliseconds it took for the deferred invocation.
25446  */
25447 var now$1 = function() {
25448   return root$2.Date.now();
25449 };
25450
25451 /** Error message constants. */
25452 var FUNC_ERROR_TEXT$2 = 'Expected a function';
25453
25454 /* Built-in method references for those with the same name as other `lodash` methods. */
25455 var nativeMax$2 = Math.max;
25456 var nativeMin = Math.min;
25457
25458 /**
25459  * Creates a debounced function that delays invoking `func` until after `wait`
25460  * milliseconds have elapsed since the last time the debounced function was
25461  * invoked. The debounced function comes with a `cancel` method to cancel
25462  * delayed `func` invocations and a `flush` method to immediately invoke them.
25463  * Provide `options` to indicate whether `func` should be invoked on the
25464  * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
25465  * with the last arguments provided to the debounced function. Subsequent
25466  * calls to the debounced function return the result of the last `func`
25467  * invocation.
25468  *
25469  * **Note:** If `leading` and `trailing` options are `true`, `func` is
25470  * invoked on the trailing edge of the timeout only if the debounced function
25471  * is invoked more than once during the `wait` timeout.
25472  *
25473  * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
25474  * until to the next tick, similar to `setTimeout` with a timeout of `0`.
25475  *
25476  * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
25477  * for details over the differences between `_.debounce` and `_.throttle`.
25478  *
25479  * @static
25480  * @memberOf _
25481  * @since 0.1.0
25482  * @category Function
25483  * @param {Function} func The function to debounce.
25484  * @param {number} [wait=0] The number of milliseconds to delay.
25485  * @param {Object} [options={}] The options object.
25486  * @param {boolean} [options.leading=false]
25487  *  Specify invoking on the leading edge of the timeout.
25488  * @param {number} [options.maxWait]
25489  *  The maximum time `func` is allowed to be delayed before it's invoked.
25490  * @param {boolean} [options.trailing=true]
25491  *  Specify invoking on the trailing edge of the timeout.
25492  * @returns {Function} Returns the new debounced function.
25493  * @example
25494  *
25495  * // Avoid costly calculations while the window size is in flux.
25496  * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
25497  *
25498  * // Invoke `sendMail` when clicked, debouncing subsequent calls.
25499  * jQuery(element).on('click', _.debounce(sendMail, 300, {
25500  *   'leading': true,
25501  *   'trailing': false
25502  * }));
25503  *
25504  * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
25505  * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
25506  * var source = new EventSource('/stream');
25507  * jQuery(source).on('message', debounced);
25508  *
25509  * // Cancel the trailing debounced invocation.
25510  * jQuery(window).on('popstate', debounced.cancel);
25511  */
25512 function debounce(func, wait, options) {
25513   var lastArgs,
25514       lastThis,
25515       maxWait,
25516       result,
25517       timerId,
25518       lastCallTime,
25519       lastInvokeTime = 0,
25520       leading = false,
25521       maxing = false,
25522       trailing = true;
25523
25524   if (typeof func != 'function') {
25525     throw new TypeError(FUNC_ERROR_TEXT$2);
25526   }
25527   wait = toNumber(wait) || 0;
25528   if (isObject(options)) {
25529     leading = !!options.leading;
25530     maxing = 'maxWait' in options;
25531     maxWait = maxing ? nativeMax$2(toNumber(options.maxWait) || 0, wait) : maxWait;
25532     trailing = 'trailing' in options ? !!options.trailing : trailing;
25533   }
25534
25535   function invokeFunc(time) {
25536     var args = lastArgs,
25537         thisArg = lastThis;
25538
25539     lastArgs = lastThis = undefined;
25540     lastInvokeTime = time;
25541     result = func.apply(thisArg, args);
25542     return result;
25543   }
25544
25545   function leadingEdge(time) {
25546     // Reset any `maxWait` timer.
25547     lastInvokeTime = time;
25548     // Start the timer for the trailing edge.
25549     timerId = setTimeout(timerExpired, wait);
25550     // Invoke the leading edge.
25551     return leading ? invokeFunc(time) : result;
25552   }
25553
25554   function remainingWait(time) {
25555     var timeSinceLastCall = time - lastCallTime,
25556         timeSinceLastInvoke = time - lastInvokeTime,
25557         result = wait - timeSinceLastCall;
25558
25559     return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
25560   }
25561
25562   function shouldInvoke(time) {
25563     var timeSinceLastCall = time - lastCallTime,
25564         timeSinceLastInvoke = time - lastInvokeTime;
25565
25566     // Either this is the first call, activity has stopped and we're at the
25567     // trailing edge, the system time has gone backwards and we're treating
25568     // it as the trailing edge, or we've hit the `maxWait` limit.
25569     return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
25570       (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
25571   }
25572
25573   function timerExpired() {
25574     var time = now$1();
25575     if (shouldInvoke(time)) {
25576       return trailingEdge(time);
25577     }
25578     // Restart the timer.
25579     timerId = setTimeout(timerExpired, remainingWait(time));
25580   }
25581
25582   function trailingEdge(time) {
25583     timerId = undefined;
25584
25585     // Only invoke if we have `lastArgs` which means `func` has been
25586     // debounced at least once.
25587     if (trailing && lastArgs) {
25588       return invokeFunc(time);
25589     }
25590     lastArgs = lastThis = undefined;
25591     return result;
25592   }
25593
25594   function cancel() {
25595     if (timerId !== undefined) {
25596       clearTimeout(timerId);
25597     }
25598     lastInvokeTime = 0;
25599     lastArgs = lastCallTime = lastThis = timerId = undefined;
25600   }
25601
25602   function flush() {
25603     return timerId === undefined ? result : trailingEdge(now$1());
25604   }
25605
25606   function debounced() {
25607     var time = now$1(),
25608         isInvoking = shouldInvoke(time);
25609
25610     lastArgs = arguments;
25611     lastThis = this;
25612     lastCallTime = time;
25613
25614     if (isInvoking) {
25615       if (timerId === undefined) {
25616         return leadingEdge(lastCallTime);
25617       }
25618       if (maxing) {
25619         // Handle invocations in a tight loop.
25620         timerId = setTimeout(timerExpired, wait);
25621         return invokeFunc(lastCallTime);
25622       }
25623     }
25624     if (timerId === undefined) {
25625       timerId = setTimeout(timerExpired, wait);
25626     }
25627     return result;
25628   }
25629   debounced.cancel = cancel;
25630   debounced.flush = flush;
25631   return debounced;
25632 }
25633
25634 /**
25635  * Casts `value` to `identity` if it's not a function.
25636  *
25637  * @private
25638  * @param {*} value The value to inspect.
25639  * @returns {Function} Returns cast function.
25640  */
25641 function castFunction(value) {
25642   return typeof value == 'function' ? value : identity$8;
25643 }
25644
25645 /**
25646  * Iterates over elements of `collection` and invokes `iteratee` for each element.
25647  * The iteratee is invoked with three arguments: (value, index|key, collection).
25648  * Iteratee functions may exit iteration early by explicitly returning `false`.
25649  *
25650  * **Note:** As with other "Collections" methods, objects with a "length"
25651  * property are iterated like arrays. To avoid this behavior use `_.forIn`
25652  * or `_.forOwn` for object iteration.
25653  *
25654  * @static
25655  * @memberOf _
25656  * @since 0.1.0
25657  * @alias each
25658  * @category Collection
25659  * @param {Array|Object} collection The collection to iterate over.
25660  * @param {Function} [iteratee=_.identity] The function invoked per iteration.
25661  * @returns {Array|Object} Returns `collection`.
25662  * @see _.forEachRight
25663  * @example
25664  *
25665  * _.forEach([1, 2], function(value) {
25666  *   console.log(value);
25667  * });
25668  * // => Logs `1` then `2`.
25669  *
25670  * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
25671  *   console.log(key);
25672  * });
25673  * // => Logs 'a' then 'b' (iteration order is not guaranteed).
25674  */
25675 function forEach(collection, iteratee) {
25676   var func = isArray(collection) ? arrayEach : baseEach;
25677   return func(collection, castFunction(iteratee));
25678 }
25679
25680 /**
25681  * Iterates over own enumerable string keyed properties of an object and
25682  * invokes `iteratee` for each property. The iteratee is invoked with three
25683  * arguments: (value, key, object). Iteratee functions may exit iteration
25684  * early by explicitly returning `false`.
25685  *
25686  * @static
25687  * @memberOf _
25688  * @since 0.3.0
25689  * @category Object
25690  * @param {Object} object The object to iterate over.
25691  * @param {Function} [iteratee=_.identity] The function invoked per iteration.
25692  * @returns {Object} Returns `object`.
25693  * @see _.forOwnRight
25694  * @example
25695  *
25696  * function Foo() {
25697  *   this.a = 1;
25698  *   this.b = 2;
25699  * }
25700  *
25701  * Foo.prototype.c = 3;
25702  *
25703  * _.forOwn(new Foo, function(value, key) {
25704  *   console.log(key);
25705  * });
25706  * // => Logs 'a' then 'b' (iteration order is not guaranteed).
25707  */
25708 function forOwn(object, iteratee) {
25709   return object && baseForOwn(object, castFunction(iteratee));
25710 }
25711
25712 var translations = Object.create(null);
25713
25714 var currentLocale = 'en';
25715 var textDirection = 'ltr';
25716
25717 function setLocale(_) {
25718     if (translations[_] !== undefined) {
25719         currentLocale = _;
25720     } else if (translations[_.split('-')[0]]) {
25721         currentLocale = _.split('-')[0];
25722     }
25723 }
25724
25725 function addTranslation(id, value) {
25726     translations[id] = value;
25727 }
25728
25729 /**
25730  * Given a string identifier, try to find that string in the current
25731  * language, and return it.
25732  *
25733  * @param {string} s string identifier
25734  * @returns {string?} locale string
25735  */
25736 function t(s, o, loc) {
25737     loc = loc || currentLocale;
25738
25739     var path = s
25740         .split('.')
25741         .map(function(s) { return s.replace('<TX_DOT>', '.'); })
25742         .reverse();
25743
25744     var rep = translations[loc];
25745
25746     while (rep !== undefined && path.length) rep = rep[path.pop()];
25747
25748     if (rep !== undefined) {
25749         if (o) for (var k in o) rep = rep.replace('{' + k + '}', o[k]);
25750         return rep;
25751     }
25752
25753     if (loc !== 'en') {
25754         return t(s, o, 'en');
25755     }
25756
25757     if (o && 'default' in o) {
25758         return o.default;
25759     }
25760
25761     var missing = 'Missing ' + loc + ' translation: ' + s;
25762     if (typeof console !== 'undefined') console.error(missing); // eslint-disable-line
25763
25764     return missing;
25765 }
25766
25767 /**
25768  * Given string 'ltr' or 'rtl', save that setting
25769  *
25770  * @param {string} s ltr or rtl
25771  */
25772
25773 function setTextDirection(dir) {
25774     textDirection = dir;
25775 }
25776
25777 /** Used to compose bitmasks for cloning. */
25778 var CLONE_DEEP_FLAG$4 = 1;
25779 var CLONE_SYMBOLS_FLAG$3 = 4;
25780
25781 /**
25782  * This method is like `_.cloneWith` except that it recursively clones `value`.
25783  *
25784  * @static
25785  * @memberOf _
25786  * @since 4.0.0
25787  * @category Lang
25788  * @param {*} value The value to recursively clone.
25789  * @param {Function} [customizer] The function to customize cloning.
25790  * @returns {*} Returns the deep cloned value.
25791  * @see _.cloneWith
25792  * @example
25793  *
25794  * function customizer(value) {
25795  *   if (_.isElement(value)) {
25796  *     return value.cloneNode(true);
25797  *   }
25798  * }
25799  *
25800  * var el = _.cloneDeepWith(document.body, customizer);
25801  *
25802  * console.log(el === document.body);
25803  * // => false
25804  * console.log(el.nodeName);
25805  * // => 'BODY'
25806  * console.log(el.childNodes.length);
25807  * // => 20
25808  */
25809 function cloneDeepWith(value, customizer) {
25810   customizer = typeof customizer == 'function' ? customizer : undefined;
25811   return baseClone(value, CLONE_DEEP_FLAG$4 | CLONE_SYMBOLS_FLAG$3, customizer);
25812 }
25813
25814 /**
25815  * Creates an array of `array` values not included in the other given arrays
25816  * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
25817  * for equality comparisons. The order and references of result values are
25818  * determined by the first array.
25819  *
25820  * **Note:** Unlike `_.pullAll`, this method returns a new array.
25821  *
25822  * @static
25823  * @memberOf _
25824  * @since 0.1.0
25825  * @category Array
25826  * @param {Array} array The array to inspect.
25827  * @param {...Array} [values] The values to exclude.
25828  * @returns {Array} Returns the new array of filtered values.
25829  * @see _.without, _.xor
25830  * @example
25831  *
25832  * _.difference([2, 1], [2, 3]);
25833  * // => [1]
25834  */
25835 var difference = baseRest(function(array, values) {
25836   return isArrayLikeObject(array)
25837     ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
25838     : [];
25839 });
25840
25841 /**
25842  * Flattens `array` a single level deep.
25843  *
25844  * @static
25845  * @memberOf _
25846  * @since 0.1.0
25847  * @category Array
25848  * @param {Array} array The array to flatten.
25849  * @returns {Array} Returns the new flattened array.
25850  * @example
25851  *
25852  * _.flatten([1, [2, [3, [4]], 5]]);
25853  * // => [1, 2, [3, [4]], 5]
25854  */
25855 function flatten(array) {
25856   var length = array == null ? 0 : array.length;
25857   return length ? baseFlatten(array, 1) : [];
25858 }
25859
25860 /**
25861  * A specialized version of `baseAggregator` for arrays.
25862  *
25863  * @private
25864  * @param {Array} [array] The array to iterate over.
25865  * @param {Function} setter The function to set `accumulator` values.
25866  * @param {Function} iteratee The iteratee to transform keys.
25867  * @param {Object} accumulator The initial aggregated object.
25868  * @returns {Function} Returns `accumulator`.
25869  */
25870 function arrayAggregator(array, setter, iteratee, accumulator) {
25871   var index = -1,
25872       length = array == null ? 0 : array.length;
25873
25874   while (++index < length) {
25875     var value = array[index];
25876     setter(accumulator, value, iteratee(value), array);
25877   }
25878   return accumulator;
25879 }
25880
25881 /**
25882  * Aggregates elements of `collection` on `accumulator` with keys transformed
25883  * by `iteratee` and values set by `setter`.
25884  *
25885  * @private
25886  * @param {Array|Object} collection The collection to iterate over.
25887  * @param {Function} setter The function to set `accumulator` values.
25888  * @param {Function} iteratee The iteratee to transform keys.
25889  * @param {Object} accumulator The initial aggregated object.
25890  * @returns {Function} Returns `accumulator`.
25891  */
25892 function baseAggregator(collection, setter, iteratee, accumulator) {
25893   baseEach(collection, function(value, key, collection) {
25894     setter(accumulator, value, iteratee(value), collection);
25895   });
25896   return accumulator;
25897 }
25898
25899 /**
25900  * Creates a function like `_.groupBy`.
25901  *
25902  * @private
25903  * @param {Function} setter The function to set accumulator values.
25904  * @param {Function} [initializer] The accumulator object initializer.
25905  * @returns {Function} Returns the new aggregator function.
25906  */
25907 function createAggregator(setter, initializer) {
25908   return function(collection, iteratee) {
25909     var func = isArray(collection) ? arrayAggregator : baseAggregator,
25910         accumulator = initializer ? initializer() : {};
25911
25912     return func(collection, setter, baseIteratee(iteratee, 2), accumulator);
25913   };
25914 }
25915
25916 /** Used for built-in method references. */
25917 var objectProto$15 = Object.prototype;
25918
25919 /** Used to check objects for own properties. */
25920 var hasOwnProperty$12 = objectProto$15.hasOwnProperty;
25921
25922 /**
25923  * Creates an object composed of keys generated from the results of running
25924  * each element of `collection` thru `iteratee`. The order of grouped values
25925  * is determined by the order they occur in `collection`. The corresponding
25926  * value of each key is an array of elements responsible for generating the
25927  * key. The iteratee is invoked with one argument: (value).
25928  *
25929  * @static
25930  * @memberOf _
25931  * @since 0.1.0
25932  * @category Collection
25933  * @param {Array|Object} collection The collection to iterate over.
25934  * @param {Function} [iteratee=_.identity] The iteratee to transform keys.
25935  * @returns {Object} Returns the composed aggregate object.
25936  * @example
25937  *
25938  * _.groupBy([6.1, 4.2, 6.3], Math.floor);
25939  * // => { '4': [4.2], '6': [6.1, 6.3] }
25940  *
25941  * // The `_.property` iteratee shorthand.
25942  * _.groupBy(['one', 'two', 'three'], 'length');
25943  * // => { '3': ['one', 'two'], '5': ['three'] }
25944  */
25945 var groupBy = createAggregator(function(result, value, key) {
25946   if (hasOwnProperty$12.call(result, key)) {
25947     result[key].push(value);
25948   } else {
25949     baseAssignValue(result, key, [value]);
25950   }
25951 });
25952
25953 /** `Object#toString` result references. */
25954 var mapTag$6 = '[object Map]';
25955 var setTag$6 = '[object Set]';
25956
25957 /** Used for built-in method references. */
25958 var objectProto$16 = Object.prototype;
25959
25960 /** Used to check objects for own properties. */
25961 var hasOwnProperty$13 = objectProto$16.hasOwnProperty;
25962
25963 /**
25964  * Checks if `value` is an empty object, collection, map, or set.
25965  *
25966  * Objects are considered empty if they have no own enumerable string keyed
25967  * properties.
25968  *
25969  * Array-like values such as `arguments` objects, arrays, buffers, strings, or
25970  * jQuery-like collections are considered empty if they have a `length` of `0`.
25971  * Similarly, maps and sets are considered empty if they have a `size` of `0`.
25972  *
25973  * @static
25974  * @memberOf _
25975  * @since 0.1.0
25976  * @category Lang
25977  * @param {*} value The value to check.
25978  * @returns {boolean} Returns `true` if `value` is empty, else `false`.
25979  * @example
25980  *
25981  * _.isEmpty(null);
25982  * // => true
25983  *
25984  * _.isEmpty(true);
25985  * // => true
25986  *
25987  * _.isEmpty(1);
25988  * // => true
25989  *
25990  * _.isEmpty([1, 2, 3]);
25991  * // => false
25992  *
25993  * _.isEmpty({ 'a': 1 });
25994  * // => false
25995  */
25996 function isEmpty(value) {
25997   if (value == null) {
25998     return true;
25999   }
26000   if (isArrayLike(value) &&
26001       (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
26002         isBuffer(value) || isTypedArray(value) || isArguments(value))) {
26003     return !value.length;
26004   }
26005   var tag = getTag$1(value);
26006   if (tag == mapTag$6 || tag == setTag$6) {
26007     return !value.size;
26008   }
26009   if (isPrototype(value)) {
26010     return !baseKeys(value).length;
26011   }
26012   for (var key in value) {
26013     if (hasOwnProperty$13.call(value, key)) {
26014       return false;
26015     }
26016   }
26017   return true;
26018 }
26019
26020 /**
26021  * Gets the last element of `array`.
26022  *
26023  * @static
26024  * @memberOf _
26025  * @since 0.1.0
26026  * @category Array
26027  * @param {Array} array The array to query.
26028  * @returns {*} Returns the last element of `array`.
26029  * @example
26030  *
26031  * _.last([1, 2, 3]);
26032  * // => 3
26033  */
26034 function last(array) {
26035   var length = array == null ? 0 : array.length;
26036   return length ? array[length - 1] : undefined;
26037 }
26038
26039 /**
26040  * The base implementation of `_.slice` without an iteratee call guard.
26041  *
26042  * @private
26043  * @param {Array} array The array to slice.
26044  * @param {number} [start=0] The start position.
26045  * @param {number} [end=array.length] The end position.
26046  * @returns {Array} Returns the slice of `array`.
26047  */
26048 function baseSlice(array, start, end) {
26049   var index = -1,
26050       length = array.length;
26051
26052   if (start < 0) {
26053     start = -start > length ? 0 : (length + start);
26054   }
26055   end = end > length ? length : end;
26056   if (end < 0) {
26057     end += length;
26058   }
26059   length = start > end ? 0 : ((end - start) >>> 0);
26060   start >>>= 0;
26061
26062   var result = Array(length);
26063   while (++index < length) {
26064     result[index] = array[index + start];
26065   }
26066   return result;
26067 }
26068
26069 /**
26070  * Gets the parent value at `path` of `object`.
26071  *
26072  * @private
26073  * @param {Object} object The object to query.
26074  * @param {Array} path The path to get the parent value of.
26075  * @returns {*} Returns the parent value.
26076  */
26077 function parent(object, path) {
26078   return path.length < 2 ? object : baseGet(object, baseSlice(path, 0, -1));
26079 }
26080
26081 /**
26082  * The base implementation of `_.unset`.
26083  *
26084  * @private
26085  * @param {Object} object The object to modify.
26086  * @param {Array|string} path The property path to unset.
26087  * @returns {boolean} Returns `true` if the property is deleted, else `false`.
26088  */
26089 function baseUnset(object, path) {
26090   path = castPath(path, object);
26091   object = parent(object, path);
26092   return object == null || delete object[toKey(last(path))];
26093 }
26094
26095 /** `Object#toString` result references. */
26096 var objectTag$4 = '[object Object]';
26097
26098 /** Used for built-in method references. */
26099 var funcProto$2 = Function.prototype;
26100 var objectProto$17 = Object.prototype;
26101
26102 /** Used to resolve the decompiled source of functions. */
26103 var funcToString$2 = funcProto$2.toString;
26104
26105 /** Used to check objects for own properties. */
26106 var hasOwnProperty$14 = objectProto$17.hasOwnProperty;
26107
26108 /** Used to infer the `Object` constructor. */
26109 var objectCtorString = funcToString$2.call(Object);
26110
26111 /**
26112  * Checks if `value` is a plain object, that is, an object created by the
26113  * `Object` constructor or one with a `[[Prototype]]` of `null`.
26114  *
26115  * @static
26116  * @memberOf _
26117  * @since 0.8.0
26118  * @category Lang
26119  * @param {*} value The value to check.
26120  * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
26121  * @example
26122  *
26123  * function Foo() {
26124  *   this.a = 1;
26125  * }
26126  *
26127  * _.isPlainObject(new Foo);
26128  * // => false
26129  *
26130  * _.isPlainObject([1, 2, 3]);
26131  * // => false
26132  *
26133  * _.isPlainObject({ 'x': 0, 'y': 0 });
26134  * // => true
26135  *
26136  * _.isPlainObject(Object.create(null));
26137  * // => true
26138  */
26139 function isPlainObject(value) {
26140   if (!isObjectLike(value) || baseGetTag(value) != objectTag$4) {
26141     return false;
26142   }
26143   var proto = getPrototype(value);
26144   if (proto === null) {
26145     return true;
26146   }
26147   var Ctor = hasOwnProperty$14.call(proto, 'constructor') && proto.constructor;
26148   return typeof Ctor == 'function' && Ctor instanceof Ctor &&
26149     funcToString$2.call(Ctor) == objectCtorString;
26150 }
26151
26152 /**
26153  * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
26154  * objects.
26155  *
26156  * @private
26157  * @param {*} value The value to inspect.
26158  * @param {string} key The key of the property to inspect.
26159  * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
26160  */
26161 function customOmitClone(value) {
26162   return isPlainObject(value) ? undefined : value;
26163 }
26164
26165 /**
26166  * A specialized version of `baseRest` which flattens the rest array.
26167  *
26168  * @private
26169  * @param {Function} func The function to apply a rest parameter to.
26170  * @returns {Function} Returns the new function.
26171  */
26172 function flatRest(func) {
26173   return setToString(overRest(func, undefined, flatten), func + '');
26174 }
26175
26176 /** Used to compose bitmasks for cloning. */
26177 var CLONE_DEEP_FLAG$5 = 1;
26178 var CLONE_FLAT_FLAG$1 = 2;
26179 var CLONE_SYMBOLS_FLAG$4 = 4;
26180
26181 /**
26182  * The opposite of `_.pick`; this method creates an object composed of the
26183  * own and inherited enumerable property paths of `object` that are not omitted.
26184  *
26185  * **Note:** This method is considerably slower than `_.pick`.
26186  *
26187  * @static
26188  * @since 0.1.0
26189  * @memberOf _
26190  * @category Object
26191  * @param {Object} object The source object.
26192  * @param {...(string|string[])} [paths] The property paths to omit.
26193  * @returns {Object} Returns the new object.
26194  * @example
26195  *
26196  * var object = { 'a': 1, 'b': '2', 'c': 3 };
26197  *
26198  * _.omit(object, ['a', 'c']);
26199  * // => { 'b': '2' }
26200  */
26201 var omit = flatRest(function(object, paths) {
26202   var result = {};
26203   if (object == null) {
26204     return result;
26205   }
26206   var isDeep = false;
26207   paths = arrayMap(paths, function(path) {
26208     path = castPath(path, object);
26209     isDeep || (isDeep = path.length > 1);
26210     return path;
26211   });
26212   copyObject(object, getAllKeysIn(object), result);
26213   if (isDeep) {
26214     result = baseClone(result, CLONE_DEEP_FLAG$5 | CLONE_FLAT_FLAG$1 | CLONE_SYMBOLS_FLAG$4, customOmitClone);
26215   }
26216   var length = paths.length;
26217   while (length--) {
26218     baseUnset(result, paths[length]);
26219   }
26220   return result;
26221 });
26222
26223 var detected;
26224
26225 function utilDetect(force) {
26226     if (detected && !force) return detected;
26227     detected = {};
26228
26229     var ua = navigator.userAgent,
26230         m = null;
26231
26232     m = ua.match(/(edge)\/?\s*(\.?\d+(\.\d+)*)/i);   // Edge
26233     if (m !== null) {
26234         detected.browser = m[1];
26235         detected.version = m[2];
26236     }
26237     if (!detected.browser) {
26238         m = ua.match(/Trident\/.*rv:([0-9]{1,}[\.0-9]{0,})/i);   // IE11
26239         if (m !== null) {
26240             detected.browser = 'msie';
26241             detected.version = m[1];
26242         }
26243     }
26244     if (!detected.browser) {
26245         m = ua.match(/(opr)\/?\s*(\.?\d+(\.\d+)*)/i);   // Opera 15+
26246         if (m !== null) {
26247             detected.browser = 'Opera';
26248             detected.version = m[2];
26249         }
26250     }
26251     if (!detected.browser) {
26252         m = ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
26253         if (m !== null) {
26254             detected.browser = m[1];
26255             detected.version = m[2];
26256             m = ua.match(/version\/([\.\d]+)/i);
26257             if (m !== null) detected.version = m[1];
26258         }
26259     }
26260     if (!detected.browser) {
26261         detected.browser = navigator.appName;
26262         detected.version = navigator.appVersion;
26263     }
26264
26265     // keep major.minor version only..
26266     detected.version = detected.version.split(/\W/).slice(0,2).join('.');
26267
26268     if (detected.browser.toLowerCase() === 'msie') {
26269         detected.ie = true;
26270         detected.browser = 'Internet Explorer';
26271         detected.support = parseFloat(detected.version) >= 11;
26272     } else {
26273         detected.ie = false;
26274         detected.support = true;
26275     }
26276
26277     // Added due to incomplete svg style support. See #715
26278     detected.opera = (detected.browser.toLowerCase() === 'opera' && parseFloat(detected.version) < 15 );
26279
26280     detected.locale = (navigator.language || navigator.userLanguage || 'en-US');
26281     detected.language = detected.locale.split('-')[0];
26282
26283     // Search `navigator.languages` for a better locale.. Prefer the first language,
26284     // unless the second language is a culture-specific version of the first one, see #3842
26285     if (navigator.languages && navigator.languages.length > 0) {
26286         var code0 = navigator.languages[0],
26287             parts0 = code0.split('-');
26288
26289         detected.locale = code0;
26290         detected.language = parts0[0];
26291
26292         if (navigator.languages.length > 1 && parts0.length === 1) {
26293             var code1 = navigator.languages[1],
26294                 parts1 = code1.split('-');
26295
26296             if (parts1[0] === parts0[0]) {
26297                 detected.locale = code1;
26298             }
26299         }
26300     }
26301
26302     // Loaded locale is stored in currentLocale
26303     // return that instead (except in the situation where 'en' might override 'en-US')
26304     var loadedLocale = currentLocale || 'en';
26305     if (loadedLocale !== 'en') {
26306         detected.locale = loadedLocale;
26307         detected.language = detected.locale.split('-')[0];
26308     }
26309
26310     // detect text direction
26311     var q = utilStringQs(window.location.hash.substring(1));
26312     var lang = dataLocales[detected.locale];
26313     if ((lang && lang.rtl) || (q.rtl === 'true')) {
26314         detected.textDirection = 'rtl';
26315     } else {
26316         detected.textDirection = 'ltr';
26317     }
26318     setTextDirection(detected.textDirection);
26319
26320     // detect host
26321     var loc = window.top.location;
26322     var origin = loc.origin;
26323     if (!origin) {  // for unpatched IE11
26324         origin = loc.protocol + '//' + loc.hostname + (loc.port ? ':' + loc.port: '');
26325     }
26326
26327     detected.host = origin + loc.pathname;
26328
26329     detected.filedrop = (window.FileReader && 'ondrop' in window);
26330
26331     detected.download = !(detected.ie || detected.browser.toLowerCase() === 'edge');
26332
26333     function nav(x) {
26334         return navigator.userAgent.indexOf(x) !== -1;
26335     }
26336
26337     if (nav('Win')) {
26338         detected.os = 'win';
26339         detected.platform = 'Windows';
26340     }
26341     else if (nav('Mac')) {
26342         detected.os = 'mac';
26343         detected.platform = 'Macintosh';
26344     }
26345     else if (nav('X11') || nav('Linux')) {
26346         detected.os = 'linux';
26347         detected.platform = 'Linux';
26348     }
26349     else {
26350         detected.os = 'win';
26351         detected.platform = 'Unknown';
26352     }
26353
26354     return detected;
26355 }
26356
26357 var remove$1 = removeDiacritics;
26358
26359 var replacementList = [
26360   {
26361     base: ' ',
26362     chars: "\u00A0",
26363   }, {
26364     base: '0',
26365     chars: "\u07C0",
26366   }, {
26367     base: 'A',
26368     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",
26369   }, {
26370     base: 'AA',
26371     chars: "\uA732",
26372   }, {
26373     base: 'AE',
26374     chars: "\u00C6\u01FC\u01E2",
26375   }, {
26376     base: 'AO',
26377     chars: "\uA734",
26378   }, {
26379     base: 'AU',
26380     chars: "\uA736",
26381   }, {
26382     base: 'AV',
26383     chars: "\uA738\uA73A",
26384   }, {
26385     base: 'AY',
26386     chars: "\uA73C",
26387   }, {
26388     base: 'B',
26389     chars: "\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0181",
26390   }, {
26391     base: 'C',
26392     chars: "\u24b8\uff23\uA73E\u1E08\u0106\u0043\u0108\u010A\u010C\u00C7\u0187\u023B",
26393   }, {
26394     base: 'D',
26395     chars: "\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018A\u0189\u1D05\uA779",
26396   }, {
26397     base: 'Dh',
26398     chars: "\u00D0",
26399   }, {
26400     base: 'DZ',
26401     chars: "\u01F1\u01C4",
26402   }, {
26403     base: 'Dz',
26404     chars: "\u01F2\u01C5",
26405   }, {
26406     base: 'E',
26407     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",
26408   }, {
26409     base: 'F',
26410     chars: "\uA77C\u24BB\uFF26\u1E1E\u0191\uA77B",
26411   }, {
26412     base: 'G',
26413     chars: "\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E\u0262",
26414   }, {
26415     base: 'H',
26416     chars: "\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D",
26417   }, {
26418     base: 'I',
26419     chars: "\u24BE\uFF29\xCC\xCD\xCE\u0128\u012A\u012C\u0130\xCF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197",
26420   }, {
26421     base: 'J',
26422     chars: "\u24BF\uFF2A\u0134\u0248\u0237",
26423   }, {
26424     base: 'K',
26425     chars: "\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2",
26426   }, {
26427     base: 'L',
26428     chars: "\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780",
26429   }, {
26430     base: 'LJ',
26431     chars: "\u01C7",
26432   }, {
26433     base: 'Lj',
26434     chars: "\u01C8",
26435   }, {
26436     base: 'M',
26437     chars: "\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C\u03FB",
26438   }, {
26439     base: 'N',
26440     chars: "\uA7A4\u0220\u24C3\uFF2E\u01F8\u0143\xD1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u019D\uA790\u1D0E",
26441   }, {
26442     base: 'NJ',
26443     chars: "\u01CA",
26444   }, {
26445     base: 'Nj',
26446     chars: "\u01CB",
26447   }, {
26448     base: 'O',
26449     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",
26450   }, {
26451     base: 'OE',
26452     chars: "\u0152",
26453   }, {
26454     base: 'OI',
26455     chars: "\u01A2",
26456   }, {
26457     base: 'OO',
26458     chars: "\uA74E",
26459   }, {
26460     base: 'OU',
26461     chars: "\u0222",
26462   }, {
26463     base: 'P',
26464     chars: "\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754",
26465   }, {
26466     base: 'Q',
26467     chars: "\u24C6\uFF31\uA756\uA758\u024A",
26468   }, {
26469     base: 'R',
26470     chars: "\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782",
26471   }, {
26472     base: 'S',
26473     chars: "\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784",
26474   }, {
26475     base: 'T',
26476     chars: "\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786",
26477   }, {
26478     base: 'Th',
26479     chars: "\u00DE",
26480   }, {
26481     base: 'TZ',
26482     chars: "\uA728",
26483   }, {
26484     base: 'U',
26485     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",
26486   }, {
26487     base: 'V',
26488     chars: "\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245",
26489   }, {
26490     base: 'VY',
26491     chars: "\uA760",
26492   }, {
26493     base: 'W',
26494     chars: "\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72",
26495   }, {
26496     base: 'X',
26497     chars: "\u24CD\uFF38\u1E8A\u1E8C",
26498   }, {
26499     base: 'Y',
26500     chars: "\u24CE\uFF39\u1EF2\xDD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE",
26501   }, {
26502     base: 'Z',
26503     chars: "\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762",
26504   }, {
26505     base: 'a',
26506     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",
26507   }, {
26508     base: 'aa',
26509     chars: "\uA733",
26510   }, {
26511     base: 'ae',
26512     chars: "\u00E6\u01FD\u01E3",
26513   }, {
26514     base: 'ao',
26515     chars: "\uA735",
26516   }, {
26517     base: 'au',
26518     chars: "\uA737",
26519   }, {
26520     base: 'av',
26521     chars: "\uA739\uA73B",
26522   }, {
26523     base: 'ay',
26524     chars: "\uA73D",
26525   }, {
26526     base: 'b',
26527     chars: "\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253\u0182",
26528   }, {
26529     base: 'c',
26530     chars: "\uFF43\u24D2\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184",
26531   }, {
26532     base: 'd',
26533     chars: "\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\u018B\u13E7\u0501\uA7AA",
26534   }, {
26535     base: 'dh',
26536     chars: "\u00F0",
26537   }, {
26538     base: 'dz',
26539     chars: "\u01F3\u01C6",
26540   }, {
26541     base: 'e',
26542     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",
26543   }, {
26544     base: 'f',
26545     chars: "\u24D5\uFF46\u1E1F\u0192",
26546   }, {
26547     base: 'ff',
26548     chars: "\uFB00",
26549   }, {
26550     base: 'fi',
26551     chars: "\uFB01",
26552   }, {
26553     base: 'fl',
26554     chars: "\uFB02",
26555   }, {
26556     base: 'ffi',
26557     chars: "\uFB03",
26558   }, {
26559     base: 'ffl',
26560     chars: "\uFB04",
26561   }, {
26562     base: 'g',
26563     chars: "\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\uA77F\u1D79",
26564   }, {
26565     base: 'h',
26566     chars: "\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265",
26567   }, {
26568     base: 'hv',
26569     chars: "\u0195",
26570   }, {
26571     base: 'i',
26572     chars: "\u24D8\uFF49\xEC\xED\xEE\u0129\u012B\u012D\xEF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131",
26573   }, {
26574     base: 'j',
26575     chars: "\u24D9\uFF4A\u0135\u01F0\u0249",
26576   }, {
26577     base: 'k',
26578     chars: "\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3",
26579   }, {
26580     base: 'l',
26581     chars: "\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747\u026D",
26582   }, {
26583     base: 'lj',
26584     chars: "\u01C9",
26585   }, {
26586     base: 'm',
26587     chars: "\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F",
26588   }, {
26589     base: 'n',
26590     chars: "\u24DD\uFF4E\u01F9\u0144\xF1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5\u043B\u0509",
26591   }, {
26592     base: 'nj',
26593     chars: "\u01CC",
26594   }, {
26595     base: 'o',
26596     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",
26597   }, {
26598     base: 'oe',
26599     chars: "\u0153",
26600   }, {
26601     base: 'oi',
26602     chars: "\u01A3",
26603   }, {
26604     base: 'oo',
26605     chars: "\uA74F",
26606   }, {
26607     base: 'ou',
26608     chars: "\u0223",
26609   }, {
26610     base: 'p',
26611     chars: "\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755\u03C1",
26612   }, {
26613     base: 'q',
26614     chars: "\u24E0\uFF51\u024B\uA757\uA759",
26615   }, {
26616     base: 'r',
26617     chars: "\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783",
26618   }, {
26619     base: 's',
26620     chars: "\u24E2\uFF53\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B\u0282",
26621   }, {
26622     base: 'ss',
26623     chars: "\xDF",
26624   }, {
26625     base: 't',
26626     chars: "\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787",
26627   }, {
26628     base: 'th',
26629     chars: "\u00FE",
26630   }, {
26631     base: 'tz',
26632     chars: "\uA729",
26633   }, {
26634     base: 'u',
26635     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",
26636   }, {
26637     base: 'v',
26638     chars: "\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C",
26639   }, {
26640     base: 'vy',
26641     chars: "\uA761",
26642   }, {
26643     base: 'w',
26644     chars: "\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73",
26645   }, {
26646     base: 'x',
26647     chars: "\u24E7\uFF58\u1E8B\u1E8D",
26648   }, {
26649     base: 'y',
26650     chars: "\u24E8\uFF59\u1EF3\xFD\u0177\u1EF9\u0233\u1E8F\xFF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF",
26651   }, {
26652     base: 'z',
26653     chars: "\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763",
26654   }
26655 ];
26656
26657 var diacriticsMap = {};
26658 for (var i = 0; i < replacementList.length; i += 1) {
26659   var chars = replacementList[i].chars;
26660   for (var j = 0; j < chars.length; j += 1) {
26661     diacriticsMap[chars[j]] = replacementList[i].base;
26662   }
26663 }
26664
26665 function removeDiacritics(str) {
26666   return str.replace(/[^\u0000-\u007e]/g, function(c) {
26667     return diacriticsMap[c] || c;
26668   });
26669 }
26670
26671 // see https://github.com/openstreetmap/iD/pull/3707
26672 // https://gist.github.com/mapmeld/556b09ddec07a2044c76e1ef45f01c60
26673
26674 var chars$1 = {
26675     // madda above alef
26676     1570: { initial: 'آ‎', isolated: 'ﺁ', medial: 'ﺁ', final: 'ﺂ' },
26677
26678     // hamza above and below alef
26679     1571: { initial: 'أ', isolated: 'ﺃ', medial: '', final: 'ﺄ' },
26680     // 1572 is ؤ
26681     1573: { initial: 'إ', isolated: 'ﺇ', medial: '', final: 'ﺈ' },
26682     // 1574 is ئ
26683     1575: { initial: 'ا', isolated: 'ا', medial: '', final: 'ﺎ' },
26684     1576: { initial: 'ﺑ', isolated: 'ﺏ', medial: 'ﺒ', final: 'ﺐ' },
26685
26686     // 1577 ة
26687     1577: { initial: '', isolated: 'ة', medial: '', final: 'ﺔ' },
26688
26689     1578: { initial: 'ﺗ', isolated: 'ﺕ', medial: 'ﺘ', final: 'ﺖ' },
26690     1579: { initial: 'ﺛ', isolated: 'ﺙ', medial: 'ﺜ', final: 'ﺚ' },
26691     1580: { initial: 'ﺟ', isolated: 'ﺝ', medial: 'ﺠ', final: 'ﺞ' },
26692     1581: { initial: 'ﺣ', isolated: 'ﺡ', medial: 'ﺤ', final: 'ﺢ' },
26693     1582: { initial: 'ﺧ', isolated: 'ﺥ', medial: 'ﺨ', final: 'ﺦ' },
26694     1583: { initial: 'ﺩ', isolated: 'ﺩ', medial: '', final: 'ﺪ' },
26695     1584: { initial: 'ﺫ', isolated: 'ﺫ', medial: '', final: 'ﺬ' },
26696     1585: { initial: 'ﺭ', isolated: 'ﺭ', medial: '', final: 'ﺮ' },
26697     1586: { initial: 'ﺯ', isolated: 'ﺯ', medial: '', final: 'ﺰ' },
26698     1688: { initial: 'ﮊ', isolated: 'ﮊ', medial: '', final: 'ﮋ' },
26699     1587: { initial: 'ﺳ', isolated: 'ﺱ', medial: 'ﺴ', final: 'ﺲ' },
26700     1588: { initial: 'ﺷ', isolated: 'ﺵ', medial: 'ﺸ', final: 'ﺶ' },
26701     1589: { initial: 'ﺻ', isolated: 'ﺹ', medial: 'ﺼ', final: 'ﺺ' },
26702     1590: { initial: 'ﺿ', isolated: 'ﺽ', medial: 'ﻀ', final: 'ﺾ' },
26703     1591: { initial: 'ﻃ', isolated: 'ﻁ', medial: 'ﻄ', final: 'ﻂ' },
26704     1592: { initial: 'ﻇ', isolated: 'ﻅ', medial: 'ﻈ', final: 'ﻆ' },
26705     1593: { initial: 'ﻋ', isolated: 'ﻉ', medial: 'ﻌ', final: 'ﻊ' },
26706     1594: { initial: 'ﻏ', isolated: 'ﻍ', medial: 'ﻐ', final: 'ﻎ' },
26707
26708     // 1595 ػ - may be very rare
26709
26710     1601: { initial: 'ﻓ', isolated: 'ﻑ', medial: 'ﻔ', final: 'ﻒ' },
26711     1602: { initial: 'ﻗ', isolated: 'ﻕ', medial: 'ﻘ', final: 'ﻖ' },
26712     1604: { initial: 'ﻟ', isolated: 'ﻝ', medial: 'ﻠ', final: 'ﻞ' },
26713     1605: { initial: 'ﻣ', isolated: 'ﻡ', medial: 'ﻤ', final: 'ﻢ' },
26714     1606: { initial: 'ﻧ', isolated: 'ﻥ', medial: 'ﻨ', final: 'ﻦ' },
26715     1607: { initial: 'ﻫ', isolated: 'ﻩ', medial: 'ﻬ', final: 'ﻪ' },
26716     1608: { initial: 'ﻭ', isolated: 'ﻭ', medial: '', final: 'ﻮ' },
26717
26718     // 1609 ى
26719     1609: { initial: 'ﯨ', isolated: 'ﻯ', medial: 'ﯩ', final: 'ﻰ' },
26720     // 1610 ي
26721     1610: { initial: 'ﻳ', isolated: 'ﻱ', medial: 'ﻴ', final: 'ﻲ' },
26722
26723     // short vowel sounds / tashkil markings
26724
26725     1662: { initial: 'ﭘ', isolated: 'ﭖ', medial: 'ﭙ', final: 'ﭗ' },
26726
26727     1670: { initial: 'ﭼ', isolated: 'ﭺ', medial: 'ﭽ', final: 'ﭻ' },
26728     1603: { initial: 'ﻛ', isolated: 'ﻙ', medial: 'ﻜ', final: 'ﻚ' },
26729     1705: { initial: 'ﻛ', isolated: 'ﮎ', medial: 'ﻜ', final: 'ﮏ' },
26730     1711: { initial: 'ﮔ', isolated: 'ﮒ', medial: 'ﮕ', final: 'ﮓ' },
26731     1740: { initial: 'ﻳ', isolated: 'ﻯ', medial: 'ﻴ', final: 'ﻰ' },
26732     5000: { initial: 'ﻻ', isolated: 'ﻻ', medial: '', final: 'ﻼ' }
26733 };
26734
26735 var rtlRegex = /[\u0590-\u05FF\u0600-\u06FF\u0780-\u07BF]/;
26736
26737 function fixRTLTextForSvg(inputText) {
26738     var context = true;
26739     var ret = '';
26740     var rtlBuffer = [];
26741     var arabicRegex = /[\u0600-\u06FF]/g;
26742     var arabicTashkil = /[\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED]/;
26743     var thaanaVowel = /[\u07A6-\u07B0]/;
26744     var hebrewSign = /[\u0591-\u05bd\u05bf\u05c1-\u05c5\u05c7]/;
26745
26746     if (!arabicRegex.test(inputText)) {
26747         // Hebrew or Thaana RTL script
26748         for (var n = 0; n < inputText.length; n++) {
26749             var c = inputText[n];
26750             if ((thaanaVowel.test(c) || hebrewSign.test(c)) && rtlBuffer.length) {
26751                 rtlBuffer[rtlBuffer.length - 1] += c;
26752             } else if (rtlRegex.test(c)) {
26753                 rtlBuffer.push(c);
26754             } else if (c === ' ' && rtlBuffer.length) {
26755                 // whitespace within RTL text
26756                 rtlBuffer = [rtlBuffer.reverse().join('') + ' '];
26757             } else {
26758                 // non-RTL character
26759                 ret += rtlBuffer.reverse().join('') + c;
26760                 rtlBuffer = [];
26761             }
26762         }
26763     } else {
26764         for (var i = 0, l = inputText.length; i < l; i++) {
26765             var code = inputText[i].charCodeAt(0);
26766             var nextCode = inputText[i + 1] ? inputText[i + 1].charCodeAt(0) : 0;
26767
26768             if (!chars$1[code]) {
26769                 if (code === 32 && rtlBuffer.length) {
26770                     // whitespace
26771                     rtlBuffer = [rtlBuffer.reverse().join('') + ' '];
26772                 } else if (arabicTashkil.test(inputText[i]) && rtlBuffer.length) {
26773                     // tashkil mark
26774                     rtlBuffer[rtlBuffer.length - 1] += inputText[i];
26775                 } else {
26776                     // non-RTL character
26777                     ret += rtlBuffer.reverse().join('') + inputText[i];
26778                     rtlBuffer = [];
26779                 }
26780                 continue;
26781             }
26782             if (context) {
26783                 if (i === l - 1 || nextCode === 32) {
26784                     rtlBuffer.push(chars$1[code].isolated);
26785                 } else {
26786                     // special case for لا
26787                     if (code === 1604 && nextCode === 1575) {
26788                         rtlBuffer.push(chars$1[5000].initial);
26789                         i++;
26790                         context = true;
26791                         continue;
26792                     }
26793                     rtlBuffer.push(chars$1[code].initial);
26794                 }
26795             } else {
26796                 if (i === l - 1 || nextCode === 32){
26797                     rtlBuffer.push(chars$1[code].final);
26798                 } else {
26799                     // special case for ﻼ
26800                     if (code === 1604 && nextCode === 1575){
26801                         rtlBuffer.push(chars$1[5000].final);
26802                         i++;
26803                         context = true;
26804                         continue;
26805                     }
26806                     if (chars$1[code].medial === ''){
26807                         rtlBuffer.push(chars$1[code].final);
26808                     } else {
26809                         rtlBuffer.push(chars$1[code].medial);
26810                     }
26811                 }
26812             }
26813             context = (chars$1[code].medial === '') || nextCode === 32;
26814         }
26815     }
26816     ret += rtlBuffer.reverse().join('');
26817     return ret;
26818 }
26819
26820 function utilTagText(entity) {
26821     return map$4(entity.tags, function(v, k) {
26822         return k + '=' + v;
26823     }).join(', ');
26824 }
26825
26826
26827 function utilEntitySelector(ids) {
26828     return ids.length ? '.' + ids.join(',.') : 'nothing';
26829 }
26830
26831
26832 function utilEntityOrMemberSelector(ids, graph) {
26833     var s = utilEntitySelector(ids);
26834
26835     ids.forEach(function(id) {
26836         var entity = graph.hasEntity(id);
26837         if (entity && entity.type === 'relation') {
26838             entity.members.forEach(function(member) {
26839                 s += ',.' + member.id;
26840             });
26841         }
26842     });
26843
26844     return s;
26845 }
26846
26847
26848 function utilGetAllNodes(ids, graph) {
26849     var seen = {};
26850     var nodes = [];
26851     ids.forEach(getNodes);
26852     return nodes;
26853
26854     function getNodes(id) {
26855         if (seen[id]) return;
26856         seen[id] = true;
26857
26858         var entity = graph.hasEntity(id);
26859         if (!entity) return;
26860
26861         if (entity.type === 'node') {
26862             nodes.push(entity);
26863         } else if (entity.type === 'way') {
26864             entity.nodes.forEach(getNodes);
26865         } else {
26866             entity.members.map(function(member) { return member.id; }).forEach(getNodes);
26867         }
26868     }
26869 }
26870
26871
26872 function utilDisplayName(entity) {
26873     var localizedNameKey = 'name:' + utilDetect().locale.toLowerCase().split('-')[0],
26874         name = entity.tags[localizedNameKey] || entity.tags.name || '',
26875         network = entity.tags.cycle_network || entity.tags.network;
26876
26877     if (!name && entity.tags.ref) {
26878         name = entity.tags.ref;
26879         if (network) {
26880             name = network + ' ' + name;
26881         }
26882     }
26883
26884     return name;
26885 }
26886
26887
26888 function utilDisplayNameForPath(entity) {
26889     var name = utilDisplayName(entity);
26890     var isFirefox = utilDetect().browser.toLowerCase().indexOf('firefox') > -1;
26891
26892     if (!isFirefox && name && rtlRegex.test(name)) {
26893         name = fixRTLTextForSvg(name);
26894     }
26895
26896     return name;
26897 }
26898
26899
26900 function utilDisplayType(id) {
26901     return {
26902         n: t('inspector.node'),
26903         w: t('inspector.way'),
26904         r: t('inspector.relation')
26905     }[id.charAt(0)];
26906 }
26907
26908
26909 function utilStringQs(str) {
26910     return str.split('&').reduce(function(obj, pair){
26911         var parts = pair.split('=');
26912         if (parts.length === 2) {
26913             obj[parts[0]] = (null === parts[1]) ? '' : decodeURIComponent(parts[1]);
26914         }
26915         return obj;
26916     }, {});
26917 }
26918
26919
26920 function utilQsString(obj, noencode) {
26921     function softEncode(s) {
26922       // encode everything except special characters used in certain hash parameters:
26923       // "/" in map states, ":", ",", {" and "}" in background
26924       return encodeURIComponent(s).replace(/(%2F|%3A|%2C|%7B|%7D)/g, decodeURIComponent);
26925     }
26926     return Object.keys(obj).sort().map(function(key) {
26927         return encodeURIComponent(key) + '=' + (
26928             noencode ? softEncode(obj[key]) : encodeURIComponent(obj[key]));
26929     }).join('&');
26930 }
26931
26932
26933 function utilPrefixDOMProperty(property) {
26934     var prefixes = ['webkit', 'ms', 'moz', 'o'],
26935         i = -1,
26936         n = prefixes.length,
26937         s = document.body;
26938
26939     if (property in s)
26940         return property;
26941
26942     property = property.substr(0, 1).toUpperCase() + property.substr(1);
26943
26944     while (++i < n)
26945         if (prefixes[i] + property in s)
26946             return prefixes[i] + property;
26947
26948     return false;
26949 }
26950
26951
26952 function utilPrefixCSSProperty(property) {
26953     var prefixes = ['webkit', 'ms', 'Moz', 'O'],
26954         i = -1,
26955         n = prefixes.length,
26956         s = document.body.style;
26957
26958     if (property.toLowerCase() in s)
26959         return property.toLowerCase();
26960
26961     while (++i < n)
26962         if (prefixes[i] + property in s)
26963             return '-' + prefixes[i].toLowerCase() + property.replace(/([A-Z])/g, '-$1').toLowerCase();
26964
26965     return false;
26966 }
26967
26968
26969 var transformProperty;
26970 function utilSetTransform(el, x, y, scale) {
26971     var prop = transformProperty = transformProperty || utilPrefixCSSProperty('Transform'),
26972         translate = utilDetect().opera ?
26973             'translate('   + x + 'px,' + y + 'px)' :
26974             'translate3d(' + x + 'px,' + y + 'px,0)';
26975     return el.style(prop, translate + (scale ? ' scale(' + scale + ')' : ''));
26976 }
26977
26978
26979 // Calculates Levenshtein distance between two strings
26980 // see:  https://en.wikipedia.org/wiki/Levenshtein_distance
26981 // first converts the strings to lowercase and replaces diacritic marks with ascii equivalents.
26982 function utilEditDistance(a, b) {
26983     a = remove$1(a.toLowerCase());
26984     b = remove$1(b.toLowerCase());
26985     if (a.length === 0) return b.length;
26986     if (b.length === 0) return a.length;
26987     var matrix = [];
26988     for (var i = 0; i <= b.length; i++) { matrix[i] = [i]; }
26989     for (var j = 0; j <= a.length; j++) { matrix[0][j] = j; }
26990     for (i = 1; i <= b.length; i++) {
26991         for (j = 1; j <= a.length; j++) {
26992             if (b.charAt(i-1) === a.charAt(j-1)) {
26993                 matrix[i][j] = matrix[i-1][j-1];
26994             } else {
26995                 matrix[i][j] = Math.min(matrix[i-1][j-1] + 1, // substitution
26996                     Math.min(matrix[i][j-1] + 1, // insertion
26997                     matrix[i-1][j] + 1)); // deletion
26998             }
26999         }
27000     }
27001     return matrix[b.length][a.length];
27002 }
27003
27004
27005 // a d3.mouse-alike which
27006 // 1. Only works on HTML elements, not SVG
27007 // 2. Does not cause style recalculation
27008 function utilFastMouse(container) {
27009     var rect = container.getBoundingClientRect(),
27010         rectLeft = rect.left,
27011         rectTop = rect.top,
27012         clientLeft = +container.clientLeft,
27013         clientTop = +container.clientTop;
27014     if (textDirection === 'rtl') {
27015         rectLeft = 0;
27016     }
27017     return function(e) {
27018         return [
27019             e.clientX - rectLeft - clientLeft,
27020             e.clientY - rectTop - clientTop];
27021     };
27022 }
27023
27024
27025 /* eslint-disable no-proto */
27026 var utilGetPrototypeOf = Object.getPrototypeOf || function(obj) { return obj.__proto__; };
27027 /* eslint-enable no-proto */
27028
27029
27030 function utilAsyncMap(inputs, func, callback) {
27031     var remaining = inputs.length,
27032         results = [],
27033         errors = [];
27034
27035     inputs.forEach(function(d, i) {
27036         func(d, function done(err, data) {
27037             errors[i] = err;
27038             results[i] = data;
27039             remaining--;
27040             if (!remaining) callback(errors, results);
27041         });
27042     });
27043 }
27044
27045
27046 // wraps an index to an interval [0..length-1]
27047 function utilWrap(index, length) {
27048     if (index < 0)
27049         index += Math.ceil(-index/length)*length;
27050     return index % length;
27051 }
27052
27053
27054 /**
27055  * a replacement for functor
27056  *
27057  * @param {*} value any value
27058  * @returns {Function} a function that returns that value or the value if it's a function
27059  */
27060 function utilFunctor(value) {
27061     if (typeof value === 'function') return value;
27062     return function() {
27063         return value;
27064     };
27065 }
27066
27067
27068 function utilNoAuto(selection) {
27069     var isText = (selection.size() && selection.node().tagName.toLowerCase() === 'textarea');
27070
27071     return selection
27072         .attr('autocomplete', 'off')
27073         .attr('autocorrect', 'off')
27074         .attr('autocapitalize', 'off')
27075         .attr('spellcheck', isText ? 'true' : 'false');
27076 }
27077
27078 // note the function should be of low priority
27079 // and should not be returning a value.
27080 function utilCallWhenIdle(func, timeout) {
27081     return function() {
27082         var args = arguments;
27083         var that = this;
27084         window.requestIdleCallback(function() {
27085             func.apply(that, args);
27086         }, {timeout: timeout});
27087     };
27088 }
27089
27090 // Like selection.property('value', ...), but avoids no-op value sets,
27091 // which can result in layout/repaint thrashing in some situations.
27092 function utilGetSetValue(selection, value) {
27093     function d3_selection_value(value) {
27094         function valueNull() {
27095             delete this.value;
27096         }
27097
27098         function valueConstant() {
27099             if (this.value !== value) {
27100                 this.value = value;
27101             }
27102         }
27103
27104         function valueFunction() {
27105             var x = value.apply(this, arguments);
27106             if (x == null) {
27107                 delete this.value;
27108             } else if (this.value !== x) {
27109                 this.value = x;
27110             }
27111         }
27112
27113         return value == null
27114             ? valueNull : (typeof value === 'function'
27115             ? valueFunction : valueConstant);
27116     }
27117
27118     if (arguments.length === 1) {
27119         return selection.property('value');
27120     }
27121
27122     return selection.each(d3_selection_value(value));
27123 }
27124
27125 function utilIdleWorker(tasks, processor, callback) {
27126     var results = [], result;
27127     for (var i = 0; i < tasks.length; i++) {
27128         result = processor(tasks[i]);
27129         if (result) results.push(result);
27130     }
27131     callback(results);
27132
27133     // var processed = [];
27134     // var currentPos = 0;
27135     // var totalTasks = tasks.length;
27136
27137     // function worker(deadline) {
27138     //     while (deadline.timeRemaining() > 0 && currentPos < totalTasks) {
27139     //         var result = processor(tasks[currentPos]);
27140
27141     //         // if falsy dont add to the processed list
27142     //         if (result) processed.push(result);
27143     //         currentPos++;
27144     //     }
27145
27146     //     // more tasks are left, we might need more idleCallbacks
27147     //     if (currentPos < totalTasks) {
27148     //         return window.requestIdleCallback(function(deadline) {worker(deadline);});
27149     //     }
27150
27151     //     // tasks are completed
27152     //     return callback(processed);
27153     // }
27154
27155     // window.requestIdleCallback(function(deadline) {worker(deadline);});
27156 }
27157
27158 // shim
27159 window.requestIdleCallback =
27160     window.requestIdleCallback ||
27161     function(cb) {
27162         var start = Date.now();
27163         return setTimeout(function() {
27164             cb({
27165                 didTimeout: false,
27166                 timeRemaining: function() {
27167                     return Math.max(0, 50 - (Date.now() - start));
27168                 }
27169             });
27170         }, 1);
27171     };
27172
27173 window.cancelIdleCallback =
27174     window.cancelIdleCallback ||
27175     function(id) {
27176         clearTimeout(id);
27177     };
27178
27179 // Copies a variable number of methods from source to target.
27180 function utilRebind(target, source) {
27181     var i = 1, n = arguments.length, method;
27182     while (++i < n) {
27183         target[method = arguments[i]] = d3_rebind(target, source, source[method]);
27184     }
27185     return target;
27186 }
27187
27188 // Method is assumed to be a standard D3 getter-setter:
27189 // If passed with no arguments, gets the value.
27190 // If passed with arguments, sets the value and returns the target.
27191 function d3_rebind(target, source, method) {
27192     return function() {
27193         var value = method.apply(source, arguments);
27194         return value === source ? target : value;
27195     };
27196 }
27197
27198 // A per-domain session mutex backed by a cookie and dead man's
27199 // switch. If the session crashes, the mutex will auto-release
27200 // after 5 seconds.
27201
27202 function utilSessionMutex(name) {
27203     var mutex = {},
27204         intervalID;
27205
27206     function renew() {
27207         var expires = new Date();
27208         expires.setSeconds(expires.getSeconds() + 5);
27209         document.cookie = name + '=1; expires=' + expires.toUTCString();
27210     }
27211
27212     mutex.lock = function() {
27213         if (intervalID) return true;
27214         var cookie = document.cookie.replace(new RegExp('(?:(?:^|.*;)\\s*' + name + '\\s*\\=\\s*([^;]*).*$)|^.*$'), '$1');
27215         if (cookie) return false;
27216         renew();
27217         intervalID = window.setInterval(renew, 4000);
27218         return true;
27219     };
27220
27221     mutex.unlock = function() {
27222         if (!intervalID) return;
27223         document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:00 GMT';
27224         clearInterval(intervalID);
27225         intervalID = null;
27226     };
27227
27228     mutex.locked = function() {
27229         return !!intervalID;
27230     };
27231
27232     return mutex;
27233 }
27234
27235 function utilSuggestNames(preset, suggestions) {
27236     preset = preset.id.split('/', 2);
27237     var k = preset[0],
27238         v = preset[1];
27239
27240     return function(value, callback) {
27241         var result = [];
27242         if (value && value.length > 2) {
27243             if (suggestions[k] && suggestions[k][v]) {
27244                 for (var sugg in suggestions[k][v]) {
27245                     var dist = utilEditDistance(value, sugg.substring(0, value.length));
27246                     if (dist < 3) {
27247                         result.push({
27248                             title: sugg,
27249                             value: sugg,
27250                             dist: dist
27251                         });
27252                     }
27253                 }
27254             }
27255             result.sort(function(a, b) {
27256                 return a.dist - b.dist;
27257             });
27258         }
27259         result = result.slice(0,3);
27260         callback(result);
27261     };
27262 }
27263
27264 function utilTriggerEvent(target, type) {
27265     target.each(function() {
27266         var evt = document.createEvent('HTMLEvents');
27267         evt.initEvent(type, true, true);
27268         this.dispatchEvent(evt);
27269     });
27270 }
27271
27272 function validationDeprecatedTag() {
27273
27274     var validation = function(changes) {
27275         var warnings = [];
27276         for (var i = 0; i < changes.created.length; i++) {
27277             var change = changes.created[i],
27278                 deprecatedTags = change.deprecatedTags();
27279
27280             if (!isEmpty(deprecatedTags)) {
27281                 var tags = utilTagText({ tags: deprecatedTags });
27282                 warnings.push({
27283                     id: 'deprecated_tags',
27284                     message: t('validations.deprecated_tags', { tags: tags }),
27285                     entity: change
27286                 });
27287             }
27288         }
27289
27290         return warnings;
27291     };
27292
27293
27294     return validation;
27295 }
27296
27297 function validationDisconnectedHighway() {
27298
27299     function isDisconnectedHighway(entity, graph) {
27300         if (!entity.tags.highway) return false;
27301         if (entity.geometry(graph) !== 'line') return false;
27302
27303         return graph.childNodes(entity)
27304             .every(function(vertex) {
27305                 var parents = graph.parentWays(vertex);
27306                 if (parents.length === 1) {  // standalone vertex
27307                     return true;
27308                 } else {                     // shared vertex
27309                     return !vertex.tags.entrance &&
27310                         parents.filter(function(parent) {
27311                             return parent.tags.highway && parent !== entity;
27312                         }).length === 0;
27313                 }
27314             });
27315     }
27316
27317
27318     var validation = function(changes, graph) {
27319         var warnings = [];
27320         for (var i = 0; i < changes.created.length; i++) {
27321             var entity = changes.created[i];
27322
27323             if (isDisconnectedHighway(entity, graph)) {
27324                 warnings.push({
27325                     id: 'disconnected_highway',
27326                     message: t('validations.disconnected_highway'),
27327                     tooltip: t('validations.disconnected_highway_tooltip'),
27328                     entity: entity
27329                 });
27330             }
27331         }
27332
27333         return warnings;
27334     };
27335
27336
27337     return validation;
27338 }
27339
27340 function validationManyDeletions() {
27341     var threshold = 100;
27342
27343     var validation = function(changes) {
27344         var warnings = [];
27345         if (changes.deleted.length > threshold) {
27346             warnings.push({
27347                 id: 'many_deletions',
27348                 message: t('validations.many_deletions', { n: changes.deleted.length })
27349             });
27350         }
27351
27352         return warnings;
27353     };
27354
27355
27356     return validation;
27357 }
27358
27359 function validationMissingTag() {
27360
27361     // Slightly stricter check than Entity#isUsed (#3091)
27362     function hasTags(entity, graph) {
27363         return without(Object.keys(entity.tags), 'area', 'name').length > 0 ||
27364             graph.parentRelations(entity).length > 0;
27365     }
27366
27367     var validation = function(changes, graph) {
27368         var types = ['point', 'line', 'area', 'relation'],
27369             warnings = [];
27370
27371         for (var i = 0; i < changes.created.length; i++) {
27372             var change = changes.created[i],
27373                 geometry = change.geometry(graph);
27374
27375             if (types.indexOf(geometry) !== -1 && !hasTags(change, graph)) {
27376                 warnings.push({
27377                     id: 'missing_tag',
27378                     message: t('validations.untagged_' + geometry),
27379                     tooltip: t('validations.untagged_' + geometry + '_tooltip'),
27380                     entity: change
27381                 });
27382             }
27383         }
27384
27385         return warnings;
27386     };
27387
27388
27389     return validation;
27390 }
27391
27392 function validationOldMultipolygon() {
27393
27394     return function validation(changes, graph) {
27395         var warnings = [];
27396         for (var i = 0; i < changes.created.length; i++) {
27397             var entity = changes.created[i];
27398             var parent = osmIsSimpleMultipolygonOuterMember(entity, graph);
27399             if (parent) {
27400                 warnings.push({
27401                     id: 'old_multipolygon',
27402                     message: t('validations.old_multipolygon'),
27403                     tooltip: t('validations.old_multipolygon_tooltip'),
27404                     entity: parent
27405                 });
27406             }
27407         }
27408         return warnings;
27409     };
27410 }
27411
27412 // https://github.com/openstreetmap/josm/blob/mirror/src/org/
27413 // openstreetmap/josm/data/validation/tests/UnclosedWays.java#L80
27414 function validationTagSuggestsArea() {
27415
27416     function tagSuggestsArea(tags) {
27417         if (isEmpty(tags)) return false;
27418
27419         var presence = ['landuse', 'amenities', 'tourism', 'shop'];
27420         for (var i = 0; i < presence.length; i++) {
27421             if (tags[presence[i]] !== undefined) {
27422                 return presence[i] + '=' + tags[presence[i]];
27423             }
27424         }
27425
27426         if (tags.building && tags.building === 'yes') return 'building=yes';
27427     }
27428
27429
27430     var validation = function(changes, graph) {
27431         var warnings = [];
27432         for (var i = 0; i < changes.created.length; i++) {
27433             var change = changes.created[i],
27434                 geometry = change.geometry(graph),
27435                 suggestion = (geometry === 'line' ? tagSuggestsArea(change.tags) : undefined);
27436
27437             if (suggestion) {
27438                 warnings.push({
27439                     id: 'tag_suggests_area',
27440                     message: t('validations.tag_suggests_area', { tag: suggestion }),
27441                     entity: change
27442                 });
27443             }
27444         }
27445
27446         return warnings;
27447     };
27448
27449
27450     return validation;
27451 }
27452
27453
27454
27455 var Validations = Object.freeze({
27456         validationDeprecatedTag: validationDeprecatedTag,
27457         validationDisconnectedHighway: validationDisconnectedHighway,
27458         validationManyDeletions: validationManyDeletions,
27459         validationMissingTag: validationMissingTag,
27460         validationOldMultipolygon: validationOldMultipolygon,
27461         validationTagSuggestsArea: validationTagSuggestsArea
27462 });
27463
27464 /**
27465  * Performs a deep comparison between two values to determine if they are
27466  * equivalent.
27467  *
27468  * **Note:** This method supports comparing arrays, array buffers, booleans,
27469  * date objects, error objects, maps, numbers, `Object` objects, regexes,
27470  * sets, strings, symbols, and typed arrays. `Object` objects are compared
27471  * by their own, not inherited, enumerable properties. Functions and DOM
27472  * nodes are compared by strict equality, i.e. `===`.
27473  *
27474  * @static
27475  * @memberOf _
27476  * @since 0.1.0
27477  * @category Lang
27478  * @param {*} value The value to compare.
27479  * @param {*} other The other value to compare.
27480  * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
27481  * @example
27482  *
27483  * var object = { 'a': 1 };
27484  * var other = { 'a': 1 };
27485  *
27486  * _.isEqual(object, other);
27487  * // => true
27488  *
27489  * object === other;
27490  * // => false
27491  */
27492 function isEqual(value, other) {
27493   return baseIsEqual(value, other);
27494 }
27495
27496 /*
27497     iD.Difference represents the difference between two graphs.
27498     It knows how to calculate the set of entities that were
27499     created, modified, or deleted, and also contains the logic
27500     for recursively extending a difference to the complete set
27501     of entities that will require a redraw, taking into account
27502     child and parent relationships.
27503  */
27504 function coreDifference(base, head) {
27505     var changes = {},
27506         difference$$1 = {},
27507         length = 0;
27508
27509
27510     function changed(h, b) {
27511         return h !== b && !isEqual(omit(h, 'v'), omit(b, 'v'));
27512     }
27513
27514
27515     forEach(head.entities, function(h, id) {
27516         var b = base.entities[id];
27517         if (changed(h, b)) {
27518             changes[id] = {base: b, head: h};
27519             length++;
27520         }
27521     });
27522
27523
27524     forEach(base.entities, function(b, id) {
27525         var h = head.entities[id];
27526         if (!changes[id] && changed(h, b)) {
27527             changes[id] = {base: b, head: h};
27528             length++;
27529         }
27530     });
27531
27532
27533     function addParents(parents, result) {
27534         for (var i = 0; i < parents.length; i++) {
27535             var parent = parents[i];
27536
27537             if (parent.id in result)
27538                 continue;
27539
27540             result[parent.id] = parent;
27541             addParents(head.parentRelations(parent), result);
27542         }
27543     }
27544
27545
27546     difference$$1.length = function() {
27547         return length;
27548     };
27549
27550
27551     difference$$1.changes = function() {
27552         return changes;
27553     };
27554
27555
27556     difference$$1.extantIDs = function() {
27557         var result = [];
27558         forEach(changes, function(change, id) {
27559             if (change.head) result.push(id);
27560         });
27561         return result;
27562     };
27563
27564
27565     difference$$1.modified = function() {
27566         var result = [];
27567         forEach(changes, function(change) {
27568             if (change.base && change.head) result.push(change.head);
27569         });
27570         return result;
27571     };
27572
27573
27574     difference$$1.created = function() {
27575         var result = [];
27576         forEach(changes, function(change) {
27577             if (!change.base && change.head) result.push(change.head);
27578         });
27579         return result;
27580     };
27581
27582
27583     difference$$1.deleted = function() {
27584         var result = [];
27585         forEach(changes, function(change) {
27586             if (change.base && !change.head) result.push(change.base);
27587         });
27588         return result;
27589     };
27590
27591
27592     difference$$1.summary = function() {
27593         var relevant = {};
27594
27595         function addEntity(entity, graph, changeType) {
27596             relevant[entity.id] = {
27597                 entity: entity,
27598                 graph: graph,
27599                 changeType: changeType
27600             };
27601         }
27602
27603         function addParents(entity) {
27604             var parents = head.parentWays(entity);
27605             for (var j = parents.length - 1; j >= 0; j--) {
27606                 var parent = parents[j];
27607                 if (!(parent.id in relevant)) addEntity(parent, head, 'modified');
27608             }
27609         }
27610
27611         forEach(changes, function(change) {
27612             if (change.head && change.head.geometry(head) !== 'vertex') {
27613                 addEntity(change.head, head, change.base ? 'modified' : 'created');
27614
27615             } else if (change.base && change.base.geometry(base) !== 'vertex') {
27616                 addEntity(change.base, base, 'deleted');
27617
27618             } else if (change.base && change.head) { // modified vertex
27619                 var moved    = !isEqual(change.base.loc,  change.head.loc),
27620                     retagged = !isEqual(change.base.tags, change.head.tags);
27621
27622                 if (moved) {
27623                     addParents(change.head);
27624                 }
27625
27626                 if (retagged || (moved && change.head.hasInterestingTags())) {
27627                     addEntity(change.head, head, 'modified');
27628                 }
27629
27630             } else if (change.head && change.head.hasInterestingTags()) { // created vertex
27631                 addEntity(change.head, head, 'created');
27632
27633             } else if (change.base && change.base.hasInterestingTags()) { // deleted vertex
27634                 addEntity(change.base, base, 'deleted');
27635             }
27636         });
27637
27638         return values$1(relevant);
27639     };
27640
27641
27642     difference$$1.complete = function(extent) {
27643         var result = {}, id, change;
27644
27645         for (id in changes) {
27646             change = changes[id];
27647
27648             var h = change.head,
27649                 b = change.base,
27650                 entity = h || b;
27651
27652             if (extent &&
27653                 (!h || !h.intersects(extent, head)) &&
27654                 (!b || !b.intersects(extent, base)))
27655                 continue;
27656
27657             result[id] = h;
27658
27659             if (entity.type === 'way') {
27660                 var nh = h ? h.nodes : [],
27661                     nb = b ? b.nodes : [],
27662                     diff, i;
27663
27664                 diff = difference(nh, nb);
27665                 for (i = 0; i < diff.length; i++) {
27666                     result[diff[i]] = head.hasEntity(diff[i]);
27667                 }
27668
27669                 diff = difference(nb, nh);
27670                 for (i = 0; i < diff.length; i++) {
27671                     result[diff[i]] = head.hasEntity(diff[i]);
27672                 }
27673             }
27674
27675             addParents(head.parentWays(entity), result);
27676             addParents(head.parentRelations(entity), result);
27677         }
27678
27679         return result;
27680     };
27681
27682
27683     return difference$$1;
27684 }
27685
27686 /** Used for built-in method references. */
27687 var objectProto$18 = Object.prototype;
27688
27689 /** Used to check objects for own properties. */
27690 var hasOwnProperty$15 = objectProto$18.hasOwnProperty;
27691
27692 /**
27693  * Assigns own enumerable string keyed properties of source objects to the
27694  * destination object. Source objects are applied from left to right.
27695  * Subsequent sources overwrite property assignments of previous sources.
27696  *
27697  * **Note:** This method mutates `object` and is loosely based on
27698  * [`Object.assign`](https://mdn.io/Object/assign).
27699  *
27700  * @static
27701  * @memberOf _
27702  * @since 0.10.0
27703  * @category Object
27704  * @param {Object} object The destination object.
27705  * @param {...Object} [sources] The source objects.
27706  * @returns {Object} Returns `object`.
27707  * @see _.assignIn
27708  * @example
27709  *
27710  * function Foo() {
27711  *   this.a = 1;
27712  * }
27713  *
27714  * function Bar() {
27715  *   this.c = 3;
27716  * }
27717  *
27718  * Foo.prototype.b = 2;
27719  * Bar.prototype.d = 4;
27720  *
27721  * _.assign({ 'a': 0 }, new Foo, new Bar);
27722  * // => { 'a': 1, 'c': 3 }
27723  */
27724 var assign = createAssigner(function(object, source) {
27725   if (isPrototype(source) || isArrayLike(source)) {
27726     copyObject(source, keys$1(source), object);
27727     return;
27728   }
27729   for (var key in source) {
27730     if (hasOwnProperty$15.call(source, key)) {
27731       assignValue(object, key, source[key]);
27732     }
27733   }
27734 });
27735
27736 /* Built-in method references for those with the same name as other `lodash` methods. */
27737 var nativeMax$3 = Math.max;
27738
27739 /**
27740  * Checks if `value` is in `collection`. If `collection` is a string, it's
27741  * checked for a substring of `value`, otherwise
27742  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
27743  * is used for equality comparisons. If `fromIndex` is negative, it's used as
27744  * the offset from the end of `collection`.
27745  *
27746  * @static
27747  * @memberOf _
27748  * @since 0.1.0
27749  * @category Collection
27750  * @param {Array|Object|string} collection The collection to inspect.
27751  * @param {*} value The value to search for.
27752  * @param {number} [fromIndex=0] The index to search from.
27753  * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
27754  * @returns {boolean} Returns `true` if `value` is found, else `false`.
27755  * @example
27756  *
27757  * _.includes([1, 2, 3], 1);
27758  * // => true
27759  *
27760  * _.includes([1, 2, 3], 1, 2);
27761  * // => false
27762  *
27763  * _.includes({ 'a': 1, 'b': 2 }, 1);
27764  * // => true
27765  *
27766  * _.includes('abcd', 'bc');
27767  * // => true
27768  */
27769 function includes(collection, value, fromIndex, guard) {
27770   collection = isArrayLike(collection) ? collection : values$1(collection);
27771   fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
27772
27773   var length = collection.length;
27774   if (fromIndex < 0) {
27775     fromIndex = nativeMax$3(length + fromIndex, 0);
27776   }
27777   return isString(collection)
27778     ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
27779     : (!!length && baseIndexOf(collection, value, fromIndex) > -1);
27780 }
27781
27782 function coreGraph(other, mutable) {
27783     if (!(this instanceof coreGraph)) return new coreGraph(other, mutable);
27784
27785     if (other instanceof coreGraph) {
27786         var base = other.base();
27787         this.entities = assign(Object.create(base.entities), other.entities);
27788         this._parentWays = assign(Object.create(base.parentWays), other._parentWays);
27789         this._parentRels = assign(Object.create(base.parentRels), other._parentRels);
27790
27791     } else {
27792         this.entities = Object.create({});
27793         this._parentWays = Object.create({});
27794         this._parentRels = Object.create({});
27795         this.rebase(other || [], [this]);
27796     }
27797
27798     this.transients = {};
27799     this._childNodes = {};
27800     this.frozen = !mutable;
27801 }
27802
27803
27804 coreGraph.prototype = {
27805
27806     hasEntity: function(id) {
27807         return this.entities[id];
27808     },
27809
27810
27811     entity: function(id) {
27812         var entity = this.entities[id];
27813
27814         //https://github.com/openstreetmap/iD/issues/3973#issuecomment-307052376
27815         if (!entity) {
27816             entity = this.entities.__proto__[id];  // eslint-disable-line no-proto
27817         }
27818
27819         if (!entity) {
27820             throw new Error('entity ' + id + ' not found');
27821         }
27822         return entity;
27823     },
27824
27825
27826     transient: function(entity, key, fn) {
27827         var id = entity.id,
27828             transients = this.transients[id] ||
27829             (this.transients[id] = {});
27830
27831         if (transients[key] !== undefined) {
27832             return transients[key];
27833         }
27834
27835         transients[key] = fn.call(entity);
27836
27837         return transients[key];
27838     },
27839
27840
27841     parentWays: function(entity) {
27842         var parents = this._parentWays[entity.id],
27843             result = [];
27844
27845         if (parents) {
27846             for (var i = 0; i < parents.length; i++) {
27847                 result.push(this.entity(parents[i]));
27848             }
27849         }
27850         return result;
27851     },
27852
27853
27854     isPoi: function(entity) {
27855         var parentWays = this._parentWays[entity.id];
27856         return !parentWays || parentWays.length === 0;
27857     },
27858
27859
27860     isShared: function(entity) {
27861         var parentWays = this._parentWays[entity.id];
27862         return parentWays && parentWays.length > 1;
27863     },
27864
27865
27866     parentRelations: function(entity) {
27867         var parents = this._parentRels[entity.id],
27868             result = [];
27869
27870         if (parents) {
27871             for (var i = 0; i < parents.length; i++) {
27872                 result.push(this.entity(parents[i]));
27873             }
27874         }
27875         return result;
27876     },
27877
27878
27879     childNodes: function(entity) {
27880         if (this._childNodes[entity.id]) return this._childNodes[entity.id];
27881         if (!entity.nodes) return [];
27882
27883         var nodes = [];
27884         for (var i = 0; i < entity.nodes.length; i++) {
27885             nodes[i] = this.entity(entity.nodes[i]);
27886         }
27887
27888         if (debug) Object.freeze(nodes);
27889
27890         this._childNodes[entity.id] = nodes;
27891         return this._childNodes[entity.id];
27892     },
27893
27894
27895     base: function() {
27896         return {
27897             'entities': utilGetPrototypeOf(this.entities),
27898             'parentWays': utilGetPrototypeOf(this._parentWays),
27899             'parentRels': utilGetPrototypeOf(this._parentRels)
27900         };
27901     },
27902
27903
27904     // Unlike other graph methods, rebase mutates in place. This is because it
27905     // is used only during the history operation that merges newly downloaded
27906     // data into each state. To external consumers, it should appear as if the
27907     // graph always contained the newly downloaded data.
27908     rebase: function(entities, stack, force) {
27909         var base = this.base(),
27910             i, j, k, id;
27911
27912         for (i = 0; i < entities.length; i++) {
27913             var entity = entities[i];
27914
27915             if (!entity.visible || (!force && base.entities[entity.id]))
27916                 continue;
27917
27918             // Merging data into the base graph
27919             base.entities[entity.id] = entity;
27920             this._updateCalculated(undefined, entity, base.parentWays, base.parentRels);
27921
27922             // Restore provisionally-deleted nodes that are discovered to have an extant parent
27923             if (entity.type === 'way') {
27924                 for (j = 0; j < entity.nodes.length; j++) {
27925                     id = entity.nodes[j];
27926                     for (k = 1; k < stack.length; k++) {
27927                         var ents = stack[k].entities;
27928                         if (ents.hasOwnProperty(id) && ents[id] === undefined) {
27929                             delete ents[id];
27930                         }
27931                     }
27932                 }
27933             }
27934         }
27935
27936         for (i = 0; i < stack.length; i++) {
27937             stack[i]._updateRebased();
27938         }
27939     },
27940
27941
27942     _updateRebased: function() {
27943         var base = this.base(),
27944             i, k, child, id, keys;
27945
27946         keys = Object.keys(this._parentWays);
27947         for (i = 0; i < keys.length; i++) {
27948             child = keys[i];
27949             if (base.parentWays[child]) {
27950                 for (k = 0; k < base.parentWays[child].length; k++) {
27951                     id = base.parentWays[child][k];
27952                     if (!this.entities.hasOwnProperty(id) && !includes(this._parentWays[child], id)) {
27953                         this._parentWays[child].push(id);
27954                     }
27955                 }
27956             }
27957         }
27958
27959         keys = Object.keys(this._parentRels);
27960         for (i = 0; i < keys.length; i++) {
27961             child = keys[i];
27962             if (base.parentRels[child]) {
27963                 for (k = 0; k < base.parentRels[child].length; k++) {
27964                     id = base.parentRels[child][k];
27965                     if (!this.entities.hasOwnProperty(id) && !includes(this._parentRels[child], id)) {
27966                         this._parentRels[child].push(id);
27967                     }
27968                 }
27969             }
27970         }
27971
27972         this.transients = {};
27973
27974         // this._childNodes is not updated, under the assumption that
27975         // ways are always downloaded with their child nodes.
27976     },
27977
27978
27979     // Updates calculated properties (parentWays, parentRels) for the specified change
27980     _updateCalculated: function(oldentity, entity, parentWays, parentRels) {
27981
27982         parentWays = parentWays || this._parentWays;
27983         parentRels = parentRels || this._parentRels;
27984
27985         var type = entity && entity.type || oldentity && oldentity.type,
27986             removed, added, ways, rels, i;
27987
27988
27989         if (type === 'way') {
27990
27991             // Update parentWays
27992             if (oldentity && entity) {
27993                 removed = difference(oldentity.nodes, entity.nodes);
27994                 added = difference(entity.nodes, oldentity.nodes);
27995             } else if (oldentity) {
27996                 removed = oldentity.nodes;
27997                 added = [];
27998             } else if (entity) {
27999                 removed = [];
28000                 added = entity.nodes;
28001             }
28002             for (i = 0; i < removed.length; i++) {
28003                 parentWays[removed[i]] = without(parentWays[removed[i]], oldentity.id);
28004             }
28005             for (i = 0; i < added.length; i++) {
28006                 ways = without(parentWays[added[i]], entity.id);
28007                 ways.push(entity.id);
28008                 parentWays[added[i]] = ways;
28009             }
28010
28011         } else if (type === 'relation') {
28012
28013             // Update parentRels
28014             if (oldentity && entity) {
28015                 removed = difference(oldentity.members, entity.members);
28016                 added = difference(entity.members, oldentity);
28017             } else if (oldentity) {
28018                 removed = oldentity.members;
28019                 added = [];
28020             } else if (entity) {
28021                 removed = [];
28022                 added = entity.members;
28023             }
28024             for (i = 0; i < removed.length; i++) {
28025                 parentRels[removed[i].id] = without(parentRels[removed[i].id], oldentity.id);
28026             }
28027             for (i = 0; i < added.length; i++) {
28028                 rels = without(parentRels[added[i].id], entity.id);
28029                 rels.push(entity.id);
28030                 parentRels[added[i].id] = rels;
28031             }
28032         }
28033     },
28034
28035
28036     replace: function(entity) {
28037         if (this.entities[entity.id] === entity)
28038             return this;
28039
28040         return this.update(function() {
28041             this._updateCalculated(this.entities[entity.id], entity);
28042             this.entities[entity.id] = entity;
28043         });
28044     },
28045
28046
28047     remove: function(entity) {
28048         return this.update(function() {
28049             this._updateCalculated(entity, undefined);
28050             this.entities[entity.id] = undefined;
28051         });
28052     },
28053
28054
28055     revert: function(id) {
28056         var baseEntity = this.base().entities[id],
28057             headEntity = this.entities[id];
28058
28059         if (headEntity === baseEntity)
28060             return this;
28061
28062         return this.update(function() {
28063             this._updateCalculated(headEntity, baseEntity);
28064             delete this.entities[id];
28065         });
28066     },
28067
28068
28069     update: function() {
28070         var graph = this.frozen ? coreGraph(this, true) : this;
28071
28072         for (var i = 0; i < arguments.length; i++) {
28073             arguments[i].call(graph, graph);
28074         }
28075
28076         if (this.frozen) graph.frozen = true;
28077
28078         return graph;
28079     },
28080
28081
28082     // Obliterates any existing entities
28083     load: function(entities) {
28084         var base = this.base();
28085         this.entities = Object.create(base.entities);
28086
28087         for (var i in entities) {
28088             this.entities[i] = entities[i];
28089             this._updateCalculated(base.entities[i], this.entities[i]);
28090         }
28091
28092         return this;
28093     }
28094 };
28095
28096 var quickselect = partialSort;
28097
28098 // Floyd-Rivest selection algorithm:
28099 // Rearrange items so that all items in the [left, k] range are smaller than all items in (k, right];
28100 // The k-th element will have the (k - left + 1)th smallest value in [left, right]
28101
28102 function partialSort(arr, k, left, right, compare) {
28103     left = left || 0;
28104     right = right || (arr.length - 1);
28105     compare = compare || defaultCompare;
28106
28107     while (right > left) {
28108         if (right - left > 600) {
28109             var n = right - left + 1;
28110             var m = k - left + 1;
28111             var z = Math.log(n);
28112             var s = 0.5 * Math.exp(2 * z / 3);
28113             var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);
28114             var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));
28115             var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));
28116             partialSort(arr, k, newLeft, newRight, compare);
28117         }
28118
28119         var t = arr[k];
28120         var i = left;
28121         var j = right;
28122
28123         swap(arr, left, k);
28124         if (compare(arr[right], t) > 0) swap(arr, left, right);
28125
28126         while (i < j) {
28127             swap(arr, i, j);
28128             i++;
28129             j--;
28130             while (compare(arr[i], t) < 0) i++;
28131             while (compare(arr[j], t) > 0) j--;
28132         }
28133
28134         if (compare(arr[left], t) === 0) swap(arr, left, j);
28135         else {
28136             j++;
28137             swap(arr, j, right);
28138         }
28139
28140         if (j <= k) left = j + 1;
28141         if (k <= j) right = j - 1;
28142     }
28143 }
28144
28145 function swap(arr, i, j) {
28146     var tmp = arr[i];
28147     arr[i] = arr[j];
28148     arr[j] = tmp;
28149 }
28150
28151 function defaultCompare(a, b) {
28152     return a < b ? -1 : a > b ? 1 : 0;
28153 }
28154
28155 var rbush_1 = rbush;
28156
28157
28158
28159 function rbush(maxEntries, format) {
28160     if (!(this instanceof rbush)) return new rbush(maxEntries, format);
28161
28162     // max entries in a node is 9 by default; min node fill is 40% for best performance
28163     this._maxEntries = Math.max(4, maxEntries || 9);
28164     this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));
28165
28166     if (format) {
28167         this._initFormat(format);
28168     }
28169
28170     this.clear();
28171 }
28172
28173 rbush.prototype = {
28174
28175     all: function () {
28176         return this._all(this.data, []);
28177     },
28178
28179     search: function (bbox) {
28180
28181         var node = this.data,
28182             result = [],
28183             toBBox = this.toBBox;
28184
28185         if (!intersects$1(bbox, node)) return result;
28186
28187         var nodesToSearch = [],
28188             i, len, child, childBBox;
28189
28190         while (node) {
28191             for (i = 0, len = node.children.length; i < len; i++) {
28192
28193                 child = node.children[i];
28194                 childBBox = node.leaf ? toBBox(child) : child;
28195
28196                 if (intersects$1(bbox, childBBox)) {
28197                     if (node.leaf) result.push(child);
28198                     else if (contains$2(bbox, childBBox)) this._all(child, result);
28199                     else nodesToSearch.push(child);
28200                 }
28201             }
28202             node = nodesToSearch.pop();
28203         }
28204
28205         return result;
28206     },
28207
28208     collides: function (bbox) {
28209
28210         var node = this.data,
28211             toBBox = this.toBBox;
28212
28213         if (!intersects$1(bbox, node)) return false;
28214
28215         var nodesToSearch = [],
28216             i, len, child, childBBox;
28217
28218         while (node) {
28219             for (i = 0, len = node.children.length; i < len; i++) {
28220
28221                 child = node.children[i];
28222                 childBBox = node.leaf ? toBBox(child) : child;
28223
28224                 if (intersects$1(bbox, childBBox)) {
28225                     if (node.leaf || contains$2(bbox, childBBox)) return true;
28226                     nodesToSearch.push(child);
28227                 }
28228             }
28229             node = nodesToSearch.pop();
28230         }
28231
28232         return false;
28233     },
28234
28235     load: function (data) {
28236         if (!(data && data.length)) return this;
28237
28238         if (data.length < this._minEntries) {
28239             for (var i = 0, len = data.length; i < len; i++) {
28240                 this.insert(data[i]);
28241             }
28242             return this;
28243         }
28244
28245         // recursively build the tree with the given data from stratch using OMT algorithm
28246         var node = this._build(data.slice(), 0, data.length - 1, 0);
28247
28248         if (!this.data.children.length) {
28249             // save as is if tree is empty
28250             this.data = node;
28251
28252         } else if (this.data.height === node.height) {
28253             // split root if trees have the same height
28254             this._splitRoot(this.data, node);
28255
28256         } else {
28257             if (this.data.height < node.height) {
28258                 // swap trees if inserted one is bigger
28259                 var tmpNode = this.data;
28260                 this.data = node;
28261                 node = tmpNode;
28262             }
28263
28264             // insert the small tree into the large tree at appropriate level
28265             this._insert(node, this.data.height - node.height - 1, true);
28266         }
28267
28268         return this;
28269     },
28270
28271     insert: function (item) {
28272         if (item) this._insert(item, this.data.height - 1);
28273         return this;
28274     },
28275
28276     clear: function () {
28277         this.data = createNode([]);
28278         return this;
28279     },
28280
28281     remove: function (item, equalsFn) {
28282         if (!item) return this;
28283
28284         var node = this.data,
28285             bbox = this.toBBox(item),
28286             path = [],
28287             indexes = [],
28288             i, parent, index, goingUp;
28289
28290         // depth-first iterative tree traversal
28291         while (node || path.length) {
28292
28293             if (!node) { // go up
28294                 node = path.pop();
28295                 parent = path[path.length - 1];
28296                 i = indexes.pop();
28297                 goingUp = true;
28298             }
28299
28300             if (node.leaf) { // check current node
28301                 index = findItem(item, node.children, equalsFn);
28302
28303                 if (index !== -1) {
28304                     // item found, remove the item and condense tree upwards
28305                     node.children.splice(index, 1);
28306                     path.push(node);
28307                     this._condense(path);
28308                     return this;
28309                 }
28310             }
28311
28312             if (!goingUp && !node.leaf && contains$2(node, bbox)) { // go down
28313                 path.push(node);
28314                 indexes.push(i);
28315                 i = 0;
28316                 parent = node;
28317                 node = node.children[0];
28318
28319             } else if (parent) { // go right
28320                 i++;
28321                 node = parent.children[i];
28322                 goingUp = false;
28323
28324             } else node = null; // nothing found
28325         }
28326
28327         return this;
28328     },
28329
28330     toBBox: function (item) { return item; },
28331
28332     compareMinX: compareNodeMinX,
28333     compareMinY: compareNodeMinY,
28334
28335     toJSON: function () { return this.data; },
28336
28337     fromJSON: function (data) {
28338         this.data = data;
28339         return this;
28340     },
28341
28342     _all: function (node, result) {
28343         var nodesToSearch = [];
28344         while (node) {
28345             if (node.leaf) result.push.apply(result, node.children);
28346             else nodesToSearch.push.apply(nodesToSearch, node.children);
28347
28348             node = nodesToSearch.pop();
28349         }
28350         return result;
28351     },
28352
28353     _build: function (items, left, right, height) {
28354
28355         var N = right - left + 1,
28356             M = this._maxEntries,
28357             node;
28358
28359         if (N <= M) {
28360             // reached leaf level; return leaf
28361             node = createNode(items.slice(left, right + 1));
28362             calcBBox(node, this.toBBox);
28363             return node;
28364         }
28365
28366         if (!height) {
28367             // target height of the bulk-loaded tree
28368             height = Math.ceil(Math.log(N) / Math.log(M));
28369
28370             // target number of root entries to maximize storage utilization
28371             M = Math.ceil(N / Math.pow(M, height - 1));
28372         }
28373
28374         node = createNode([]);
28375         node.leaf = false;
28376         node.height = height;
28377
28378         // split the items into M mostly square tiles
28379
28380         var N2 = Math.ceil(N / M),
28381             N1 = N2 * Math.ceil(Math.sqrt(M)),
28382             i, j, right2, right3;
28383
28384         multiSelect(items, left, right, N1, this.compareMinX);
28385
28386         for (i = left; i <= right; i += N1) {
28387
28388             right2 = Math.min(i + N1 - 1, right);
28389
28390             multiSelect(items, i, right2, N2, this.compareMinY);
28391
28392             for (j = i; j <= right2; j += N2) {
28393
28394                 right3 = Math.min(j + N2 - 1, right2);
28395
28396                 // pack each entry recursively
28397                 node.children.push(this._build(items, j, right3, height - 1));
28398             }
28399         }
28400
28401         calcBBox(node, this.toBBox);
28402
28403         return node;
28404     },
28405
28406     _chooseSubtree: function (bbox, node, level, path) {
28407
28408         var i, len, child, targetNode, area, enlargement, minArea, minEnlargement;
28409
28410         while (true) {
28411             path.push(node);
28412
28413             if (node.leaf || path.length - 1 === level) break;
28414
28415             minArea = minEnlargement = Infinity;
28416
28417             for (i = 0, len = node.children.length; i < len; i++) {
28418                 child = node.children[i];
28419                 area = bboxArea(child);
28420                 enlargement = enlargedArea(bbox, child) - area;
28421
28422                 // choose entry with the least area enlargement
28423                 if (enlargement < minEnlargement) {
28424                     minEnlargement = enlargement;
28425                     minArea = area < minArea ? area : minArea;
28426                     targetNode = child;
28427
28428                 } else if (enlargement === minEnlargement) {
28429                     // otherwise choose one with the smallest area
28430                     if (area < minArea) {
28431                         minArea = area;
28432                         targetNode = child;
28433                     }
28434                 }
28435             }
28436
28437             node = targetNode || node.children[0];
28438         }
28439
28440         return node;
28441     },
28442
28443     _insert: function (item, level, isNode) {
28444
28445         var toBBox = this.toBBox,
28446             bbox = isNode ? item : toBBox(item),
28447             insertPath = [];
28448
28449         // find the best node for accommodating the item, saving all nodes along the path too
28450         var node = this._chooseSubtree(bbox, this.data, level, insertPath);
28451
28452         // put the item into the node
28453         node.children.push(item);
28454         extend$1(node, bbox);
28455
28456         // split on node overflow; propagate upwards if necessary
28457         while (level >= 0) {
28458             if (insertPath[level].children.length > this._maxEntries) {
28459                 this._split(insertPath, level);
28460                 level--;
28461             } else break;
28462         }
28463
28464         // adjust bboxes along the insertion path
28465         this._adjustParentBBoxes(bbox, insertPath, level);
28466     },
28467
28468     // split overflowed node into two
28469     _split: function (insertPath, level) {
28470
28471         var node = insertPath[level],
28472             M = node.children.length,
28473             m = this._minEntries;
28474
28475         this._chooseSplitAxis(node, m, M);
28476
28477         var splitIndex = this._chooseSplitIndex(node, m, M);
28478
28479         var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));
28480         newNode.height = node.height;
28481         newNode.leaf = node.leaf;
28482
28483         calcBBox(node, this.toBBox);
28484         calcBBox(newNode, this.toBBox);
28485
28486         if (level) insertPath[level - 1].children.push(newNode);
28487         else this._splitRoot(node, newNode);
28488     },
28489
28490     _splitRoot: function (node, newNode) {
28491         // split root node
28492         this.data = createNode([node, newNode]);
28493         this.data.height = node.height + 1;
28494         this.data.leaf = false;
28495         calcBBox(this.data, this.toBBox);
28496     },
28497
28498     _chooseSplitIndex: function (node, m, M) {
28499
28500         var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index;
28501
28502         minOverlap = minArea = Infinity;
28503
28504         for (i = m; i <= M - m; i++) {
28505             bbox1 = distBBox(node, 0, i, this.toBBox);
28506             bbox2 = distBBox(node, i, M, this.toBBox);
28507
28508             overlap = intersectionArea(bbox1, bbox2);
28509             area = bboxArea(bbox1) + bboxArea(bbox2);
28510
28511             // choose distribution with minimum overlap
28512             if (overlap < minOverlap) {
28513                 minOverlap = overlap;
28514                 index = i;
28515
28516                 minArea = area < minArea ? area : minArea;
28517
28518             } else if (overlap === minOverlap) {
28519                 // otherwise choose distribution with minimum area
28520                 if (area < minArea) {
28521                     minArea = area;
28522                     index = i;
28523                 }
28524             }
28525         }
28526
28527         return index;
28528     },
28529
28530     // sorts node children by the best axis for split
28531     _chooseSplitAxis: function (node, m, M) {
28532
28533         var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX,
28534             compareMinY = node.leaf ? this.compareMinY : compareNodeMinY,
28535             xMargin = this._allDistMargin(node, m, M, compareMinX),
28536             yMargin = this._allDistMargin(node, m, M, compareMinY);
28537
28538         // if total distributions margin value is minimal for x, sort by minX,
28539         // otherwise it's already sorted by minY
28540         if (xMargin < yMargin) node.children.sort(compareMinX);
28541     },
28542
28543     // total margin of all possible split distributions where each node is at least m full
28544     _allDistMargin: function (node, m, M, compare) {
28545
28546         node.children.sort(compare);
28547
28548         var toBBox = this.toBBox,
28549             leftBBox = distBBox(node, 0, m, toBBox),
28550             rightBBox = distBBox(node, M - m, M, toBBox),
28551             margin = bboxMargin(leftBBox) + bboxMargin(rightBBox),
28552             i, child;
28553
28554         for (i = m; i < M - m; i++) {
28555             child = node.children[i];
28556             extend$1(leftBBox, node.leaf ? toBBox(child) : child);
28557             margin += bboxMargin(leftBBox);
28558         }
28559
28560         for (i = M - m - 1; i >= m; i--) {
28561             child = node.children[i];
28562             extend$1(rightBBox, node.leaf ? toBBox(child) : child);
28563             margin += bboxMargin(rightBBox);
28564         }
28565
28566         return margin;
28567     },
28568
28569     _adjustParentBBoxes: function (bbox, path, level) {
28570         // adjust bboxes along the given tree path
28571         for (var i = level; i >= 0; i--) {
28572             extend$1(path[i], bbox);
28573         }
28574     },
28575
28576     _condense: function (path) {
28577         // go through the path, removing empty nodes and updating bboxes
28578         for (var i = path.length - 1, siblings; i >= 0; i--) {
28579             if (path[i].children.length === 0) {
28580                 if (i > 0) {
28581                     siblings = path[i - 1].children;
28582                     siblings.splice(siblings.indexOf(path[i]), 1);
28583
28584                 } else this.clear();
28585
28586             } else calcBBox(path[i], this.toBBox);
28587         }
28588     },
28589
28590     _initFormat: function (format) {
28591         // data format (minX, minY, maxX, maxY accessors)
28592
28593         // uses eval-type function compilation instead of just accepting a toBBox function
28594         // because the algorithms are very sensitive to sorting functions performance,
28595         // so they should be dead simple and without inner calls
28596
28597         var compareArr = ['return a', ' - b', ';'];
28598
28599         this.compareMinX = new Function('a', 'b', compareArr.join(format[0]));
28600         this.compareMinY = new Function('a', 'b', compareArr.join(format[1]));
28601
28602         this.toBBox = new Function('a',
28603             'return {minX: a' + format[0] +
28604             ', minY: a' + format[1] +
28605             ', maxX: a' + format[2] +
28606             ', maxY: a' + format[3] + '};');
28607     }
28608 };
28609
28610 function findItem(item, items, equalsFn) {
28611     if (!equalsFn) return items.indexOf(item);
28612
28613     for (var i = 0; i < items.length; i++) {
28614         if (equalsFn(item, items[i])) return i;
28615     }
28616     return -1;
28617 }
28618
28619 // calculate node's bbox from bboxes of its children
28620 function calcBBox(node, toBBox) {
28621     distBBox(node, 0, node.children.length, toBBox, node);
28622 }
28623
28624 // min bounding rectangle of node children from k to p-1
28625 function distBBox(node, k, p, toBBox, destNode) {
28626     if (!destNode) destNode = createNode(null);
28627     destNode.minX = Infinity;
28628     destNode.minY = Infinity;
28629     destNode.maxX = -Infinity;
28630     destNode.maxY = -Infinity;
28631
28632     for (var i = k, child; i < p; i++) {
28633         child = node.children[i];
28634         extend$1(destNode, node.leaf ? toBBox(child) : child);
28635     }
28636
28637     return destNode;
28638 }
28639
28640 function extend$1(a, b) {
28641     a.minX = Math.min(a.minX, b.minX);
28642     a.minY = Math.min(a.minY, b.minY);
28643     a.maxX = Math.max(a.maxX, b.maxX);
28644     a.maxY = Math.max(a.maxY, b.maxY);
28645     return a;
28646 }
28647
28648 function compareNodeMinX(a, b) { return a.minX - b.minX; }
28649 function compareNodeMinY(a, b) { return a.minY - b.minY; }
28650
28651 function bboxArea(a)   { return (a.maxX - a.minX) * (a.maxY - a.minY); }
28652 function bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); }
28653
28654 function enlargedArea(a, b) {
28655     return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *
28656            (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));
28657 }
28658
28659 function intersectionArea(a, b) {
28660     var minX = Math.max(a.minX, b.minX),
28661         minY = Math.max(a.minY, b.minY),
28662         maxX = Math.min(a.maxX, b.maxX),
28663         maxY = Math.min(a.maxY, b.maxY);
28664
28665     return Math.max(0, maxX - minX) *
28666            Math.max(0, maxY - minY);
28667 }
28668
28669 function contains$2(a, b) {
28670     return a.minX <= b.minX &&
28671            a.minY <= b.minY &&
28672            b.maxX <= a.maxX &&
28673            b.maxY <= a.maxY;
28674 }
28675
28676 function intersects$1(a, b) {
28677     return b.minX <= a.maxX &&
28678            b.minY <= a.maxY &&
28679            b.maxX >= a.minX &&
28680            b.maxY >= a.minY;
28681 }
28682
28683 function createNode(children) {
28684     return {
28685         children: children,
28686         height: 1,
28687         leaf: true,
28688         minX: Infinity,
28689         minY: Infinity,
28690         maxX: -Infinity,
28691         maxY: -Infinity
28692     };
28693 }
28694
28695 // sort an array so that items come in groups of n unsorted items, with groups sorted between each other;
28696 // combines selection algorithm with binary divide & conquer approach
28697
28698 function multiSelect(arr, left, right, n, compare) {
28699     var stack = [left, right],
28700         mid;
28701
28702     while (stack.length) {
28703         right = stack.pop();
28704         left = stack.pop();
28705
28706         if (right - left <= n) continue;
28707
28708         mid = left + Math.ceil((right - left) / n / 2) * n;
28709         quickselect(arr, mid, left, right, compare);
28710
28711         stack.push(left, mid, mid, right);
28712     }
28713 }
28714
28715 function coreTree(head) {
28716     var rtree = rbush_1(),
28717         bboxes = {},
28718         tree = {};
28719
28720
28721     function entityBBox(entity) {
28722         var bbox = entity.extent(head).bbox();
28723         bbox.id = entity.id;
28724         bboxes[entity.id] = bbox;
28725         return bbox;
28726     }
28727
28728
28729     function updateParents(entity, insertions, memo) {
28730         head.parentWays(entity).forEach(function(way) {
28731             if (bboxes[way.id]) {
28732                 rtree.remove(bboxes[way.id]);
28733                 insertions[way.id] = way;
28734             }
28735             updateParents(way, insertions, memo);
28736         });
28737
28738         head.parentRelations(entity).forEach(function(relation) {
28739             if (memo[entity.id]) return;
28740             memo[entity.id] = true;
28741             if (bboxes[relation.id]) {
28742                 rtree.remove(bboxes[relation.id]);
28743                 insertions[relation.id] = relation;
28744             }
28745             updateParents(relation, insertions, memo);
28746         });
28747     }
28748
28749
28750     tree.rebase = function(entities, force) {
28751         var insertions = {};
28752
28753         for (var i = 0; i < entities.length; i++) {
28754             var entity = entities[i];
28755
28756             if (!entity.visible)
28757                 continue;
28758
28759             if (head.entities.hasOwnProperty(entity.id) || bboxes[entity.id]) {
28760                 if (!force) {
28761                     continue;
28762                 } else if (bboxes[entity.id]) {
28763                     rtree.remove(bboxes[entity.id]);
28764                 }
28765             }
28766
28767             insertions[entity.id] = entity;
28768             updateParents(entity, insertions, {});
28769         }
28770
28771         rtree.load(map$4(insertions, entityBBox));
28772
28773         return tree;
28774     };
28775
28776
28777     tree.intersects = function(extent, graph) {
28778         if (graph !== head) {
28779             var diff = coreDifference(head, graph),
28780                 insertions = {};
28781
28782             head = graph;
28783
28784             diff.deleted().forEach(function(entity) {
28785                 rtree.remove(bboxes[entity.id]);
28786                 delete bboxes[entity.id];
28787             });
28788
28789             diff.modified().forEach(function(entity) {
28790                 rtree.remove(bboxes[entity.id]);
28791                 insertions[entity.id] = entity;
28792                 updateParents(entity, insertions, {});
28793             });
28794
28795             diff.created().forEach(function(entity) {
28796                 insertions[entity.id] = entity;
28797             });
28798
28799             rtree.load(map$4(insertions, entityBBox));
28800         }
28801
28802         return rtree.search(extent.bbox()).map(function(bbox) {
28803             return head.entity(bbox.id);
28804         });
28805     };
28806
28807
28808     return tree;
28809 }
28810
28811 /*
28812  * This code is licensed under the MIT license.
28813  *
28814  * Copyright © 2013, iD authors.
28815  *
28816  * Portions copyright © 2011, Keith Cirkel
28817  * See https://github.com/keithamus/jwerty
28818  *
28819  */
28820 function d3keybinding(namespace) {
28821     var bindings = [];
28822
28823
28824     function testBindings(isCapturing) {
28825         var didMatch = false,
28826             i, binding;
28827
28828         // Most key shortcuts will accept either lower or uppercase ('h' or 'H'),
28829         // so we don't strictly match on the shift key, but we prioritize
28830         // shifted bindings first, and fallback to unshifted only if no match.
28831         // (This lets us differentiate between '←'/'⇧←' or '⌘Z'/'⌘⇧Z')
28832
28833         // priority match shifted bindings first
28834         for (i = 0; i < bindings.length; i++) {
28835             binding = bindings[i];
28836             if (!binding.event.modifiers.shiftKey) continue;  // no shift
28837             if (!!binding.capture !== isCapturing) continue;
28838             if (matches(binding, true)) {
28839                 binding.callback();
28840                 didMatch = true;
28841             }
28842         }
28843
28844         // then unshifted bindings
28845         if (didMatch) return;
28846         for (i = 0; i < bindings.length; i++) {
28847             binding = bindings[i];
28848             if (binding.event.modifiers.shiftKey) continue;   // shift
28849             if (!!binding.capture !== isCapturing) continue;
28850             if (matches(binding, false)) {
28851                 binding.callback();
28852             }
28853         }
28854
28855
28856         function matches(binding, testShift) {
28857             var event$$1 = event;
28858             if (event$$1.key !== undefined) {
28859                 if (binding.event.key === undefined) {
28860                     return false;
28861                 } else if (Array.isArray(binding.event.key)) {
28862                     if (binding.event.key.map(function(s) { return s.toLowerCase(); }).indexOf(event$$1.key.toLowerCase()) === -1)
28863                         return false;
28864                 } else {
28865                     if (event$$1.key.toLowerCase() !== binding.event.key.toLowerCase())
28866                         return false;
28867                 }
28868             } else {
28869                 // check keycodes if browser doesn't support KeyboardEvent.key
28870                 if (event$$1.keyCode !== binding.event.keyCode)
28871                     return false;
28872             }
28873
28874             // test modifier keys
28875             if (!(event$$1.ctrlKey && event$$1.altKey)) {  // if both are set, assume AltGr and skip it - #4096
28876                 if (event$$1.ctrlKey !== binding.event.modifiers.ctrlKey) return false;
28877                 if (event$$1.altKey !== binding.event.modifiers.altKey) return false;
28878             }
28879             if (event$$1.metaKey !== binding.event.modifiers.metaKey) return false;
28880             if (testShift && event$$1.shiftKey !== binding.event.modifiers.shiftKey) return false;
28881
28882             return true;
28883         }
28884     }
28885
28886
28887     function capture() {
28888         testBindings(true);
28889     }
28890
28891
28892     function bubble() {
28893         var tagName = d3_select(event.target).node().tagName;
28894         if (tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA') {
28895             return;
28896         }
28897         testBindings(false);
28898     }
28899
28900
28901     function keybinding(selection) {
28902         selection = selection || d3_select(document);
28903         selection.on('keydown.capture' + namespace, capture, true);
28904         selection.on('keydown.bubble' + namespace, bubble, false);
28905         return keybinding;
28906     }
28907
28908
28909     keybinding.off = function(selection) {
28910         bindings = [];
28911         selection = selection || d3_select(document);
28912         selection.on('keydown.capture' + namespace, null);
28913         selection.on('keydown.bubble' + namespace, null);
28914         return keybinding;
28915     };
28916
28917
28918     keybinding.on = function(codes, callback, capture) {
28919         var arr = [].concat(codes);
28920         for (var i = 0; i < arr.length; i++) {
28921             var code = arr[i];
28922             var binding = {
28923                 event: {
28924                     key: undefined,
28925                     keyCode: 0, // only for browsers that don't support KeyboardEvent.key
28926                     modifiers: {
28927                         shiftKey: false,
28928                         ctrlKey: false,
28929                         altKey: false,
28930                         metaKey: false
28931                     }
28932                 },
28933                 capture: capture,
28934                 callback: callback
28935             };
28936
28937             code = code.toLowerCase().match(/(?:(?:[^+⇧⌃⌥⌘])+|[⇧⌃⌥⌘]|\+\+|^\+$)/g);
28938
28939             for (var j = 0; j < code.length; j++) {
28940                 // Normalise matching errors
28941                 if (code[j] === '++') code[j] = '+';
28942
28943                 if (code[j] in d3keybinding.modifierCodes) {
28944                     binding.event.modifiers[d3keybinding.modifierProperties[d3keybinding.modifierCodes[code[j]]]] = true;
28945                 } else {
28946                     binding.event.key = d3keybinding.keys[code[j]] || code[j];
28947                     if (code[j] in d3keybinding.keyCodes) {
28948                         binding.event.keyCode = d3keybinding.keyCodes[code[j]];
28949                     }
28950                 }
28951             }
28952
28953             bindings.push(binding);
28954         }
28955
28956         return keybinding;
28957     };
28958
28959     return keybinding;
28960 }
28961
28962
28963 d3keybinding.modifierCodes = {
28964     // Shift key, ⇧
28965     '⇧': 16, shift: 16,
28966     // CTRL key, on Mac: ⌃
28967     '⌃': 17, ctrl: 17,
28968     // ALT key, on Mac: ⌥ (Alt)
28969     '⌥': 18, alt: 18, option: 18,
28970     // META, on Mac: ⌘ (CMD), on Windows (Win), on Linux (Super)
28971     '⌘': 91, meta: 91, cmd: 91, 'super': 91, win: 91
28972 };
28973
28974 d3keybinding.modifierProperties = {
28975     16: 'shiftKey',
28976     17: 'ctrlKey',
28977     18: 'altKey',
28978     91: 'metaKey'
28979 };
28980
28981 d3keybinding.keys = {
28982     // Backspace key, on Mac: ⌫ (Backspace)
28983     '⌫': 'Backspace', backspace: 'Backspace',
28984     // Tab Key, on Mac: ⇥ (Tab), on Windows ⇥⇥
28985     '⇥': 'Tab', '⇆': 'Tab', tab: 'Tab',
28986     // Return key, ↩
28987     '↩': 'Enter', 'return': 'Enter', enter: 'Enter', '⌅': 'Enter',
28988     // Pause/Break key
28989     'pause': 'Pause', 'pause-break': 'Pause',
28990     // Caps Lock key, ⇪
28991     '⇪': 'CapsLock', caps: 'CapsLock', 'caps-lock': 'CapsLock',
28992     // Escape key, on Mac: ⎋, on Windows: Esc
28993     '⎋': ['Escape', 'Esc'], escape: ['Escape', 'Esc'], esc: ['Escape', 'Esc'],
28994     // Space key
28995     space: [' ', 'Spacebar'],
28996     // Page-Up key, or pgup, on Mac: ↖
28997     '↖': 'PageUp', pgup: 'PageUp', 'page-up': 'PageUp',
28998     // Page-Down key, or pgdown, on Mac: ↘
28999     '↘': 'PageDown', pgdown: 'PageDown', 'page-down': 'PageDown',
29000     // END key, on Mac: ⇟
29001     '⇟': 'End', end: 'End',
29002     // HOME key, on Mac: ⇞
29003     '⇞': 'Home', home: 'Home',
29004     // Insert key, or ins
29005     ins: 'Insert', insert: 'Insert',
29006     // Delete key, on Mac: ⌦ (Delete)
29007     '⌦': ['Delete', 'Del'], del: ['Delete', 'Del'], 'delete': ['Delete', 'Del'],
29008     // Left Arrow Key, or ←
29009     '←': ['ArrowLeft', 'Left'], left: ['ArrowLeft', 'Left'], 'arrow-left': ['ArrowLeft', 'Left'],
29010     // Up Arrow Key, or ↑
29011     '↑': ['ArrowUp', 'Up'], up: ['ArrowUp', 'Up'], 'arrow-up': ['ArrowUp', 'Up'],
29012     // Right Arrow Key, or →
29013     '→': ['ArrowRight', 'Right'], right: ['ArrowRight', 'Right'], 'arrow-right': ['ArrowRight', 'Right'],
29014     // Up Arrow Key, or ↓
29015     '↓': ['ArrowDown', 'Down'], down: ['ArrowDown', 'Down'], 'arrow-down': ['ArrowDown', 'Down'],
29016     // odities, stuff for backward compatibility (browsers and code):
29017     // Num-Multiply, or *
29018     '*': ['*', 'Multiply'], star: ['*', 'Multiply'], asterisk: ['*', 'Multiply'], multiply: ['*', 'Multiply'],
29019     // Num-Plus or +
29020     '+': ['+', 'Add'], 'plus': ['+', 'Add'],
29021     // Num-Subtract, or -
29022     '-': ['-', 'Subtract'], subtract: ['-', 'Subtract'], 'dash': ['-', 'Subtract'],
29023     // Semicolon
29024     semicolon: ';',
29025     // = or equals
29026     equals: '=',
29027     // Comma, or ,
29028     comma: ',',
29029     // Period, or ., or full-stop
29030     period: '.', 'full-stop': '.',
29031     // Slash, or /, or forward-slash
29032     slash: '/', 'forward-slash': '/',
29033     // Tick, or `, or back-quote
29034     tick: '`', 'back-quote': '`',
29035     // Open bracket, or [
29036     'open-bracket': '[',
29037     // Back slash, or \
29038     'back-slash': '\\',
29039     // Close backet, or ]
29040     'close-bracket': ']',
29041     // Apostrophe, or Quote, or '
29042     quote: '\'', apostrophe: '\'',
29043     // NUMPAD 0-9
29044     'num-0': '0',
29045     'num-1': '1',
29046     'num-2': '2',
29047     'num-3': '3',
29048     'num-4': '4',
29049     'num-5': '5',
29050     'num-6': '6',
29051     'num-7': '7',
29052     'num-8': '8',
29053     'num-9': '9',
29054     // F1-F25
29055     f1: 'F1',
29056     f2: 'F2',
29057     f3: 'F3',
29058     f4: 'F4',
29059     f5: 'F5',
29060     f6: 'F6',
29061     f7: 'F7',
29062     f8: 'F8',
29063     f9: 'F9',
29064     f10: 'F10',
29065     f11: 'F11',
29066     f12: 'F12',
29067     f13: 'F13',
29068     f14: 'F14',
29069     f15: 'F15',
29070     f16: 'F16',
29071     f17: 'F17',
29072     f18: 'F18',
29073     f19: 'F19',
29074     f20: 'F20',
29075     f21: 'F21',
29076     f22: 'F22',
29077     f23: 'F23',
29078     f24: 'F24',
29079     f25: 'F25'
29080 };
29081
29082 d3keybinding.keyCodes = {
29083     // Backspace key, on Mac: ⌫ (Backspace)
29084     '⌫': 8, backspace: 8,
29085     // Tab Key, on Mac: ⇥ (Tab), on Windows ⇥⇥
29086     '⇥': 9, '⇆': 9, tab: 9,
29087     // Return key, ↩
29088     '↩': 13, 'return': 13, enter: 13, '⌅': 13,
29089     // Pause/Break key
29090     'pause': 19, 'pause-break': 19,
29091     // Caps Lock key, ⇪
29092     '⇪': 20, caps: 20, 'caps-lock': 20,
29093     // Escape key, on Mac: ⎋, on Windows: Esc
29094     '⎋': 27, escape: 27, esc: 27,
29095     // Space key
29096     space: 32,
29097     // Page-Up key, or pgup, on Mac: ↖
29098     '↖': 33, pgup: 33, 'page-up': 33,
29099     // Page-Down key, or pgdown, on Mac: ↘
29100     '↘': 34, pgdown: 34, 'page-down': 34,
29101     // END key, on Mac: ⇟
29102     '⇟': 35, end: 35,
29103     // HOME key, on Mac: ⇞
29104     '⇞': 36, home: 36,
29105     // Insert key, or ins
29106     ins: 45, insert: 45,
29107     // Delete key, on Mac: ⌦ (Delete)
29108     '⌦': 46, del: 46, 'delete': 46,
29109     // Left Arrow Key, or ←
29110     '←': 37, left: 37, 'arrow-left': 37,
29111     // Up Arrow Key, or ↑
29112     '↑': 38, up: 38, 'arrow-up': 38,
29113     // Right Arrow Key, or →
29114     '→': 39, right: 39, 'arrow-right': 39,
29115     // Up Arrow Key, or ↓
29116     '↓': 40, down: 40, 'arrow-down': 40,
29117     // odities, printing characters that come out wrong:
29118     // Firefox Equals
29119     'ffequals': 61,
29120     // Num-Multiply, or *
29121     '*': 106, star: 106, asterisk: 106, multiply: 106,
29122     // Num-Plus or +
29123     '+': 107, 'plus': 107,
29124     // Num-Subtract, or -
29125     '-': 109, subtract: 109,
29126     // Firefox Plus
29127     'ffplus': 171,
29128     // Firefox Minus
29129     'ffminus': 173,
29130     // Semicolon
29131     ';': 186, semicolon: 186,
29132     // = or equals
29133     '=': 187, 'equals': 187,
29134     // Comma, or ,
29135     ',': 188, comma: 188,
29136     // Dash / Underscore key
29137     'dash': 189,
29138     // Period, or ., or full-stop
29139     '.': 190, period: 190, 'full-stop': 190,
29140     // Slash, or /, or forward-slash
29141     '/': 191, slash: 191, 'forward-slash': 191,
29142     // Tick, or `, or back-quote
29143     '`': 192, tick: 192, 'back-quote': 192,
29144     // Open bracket, or [
29145     '[': 219, 'open-bracket': 219,
29146     // Back slash, or \
29147     '\\': 220, 'back-slash': 220,
29148     // Close backet, or ]
29149     ']': 221, 'close-bracket': 221,
29150     // Apostrophe, or Quote, or '
29151     '\'': 222, quote: 222, apostrophe: 222
29152 };
29153
29154 // NUMPAD 0-9
29155 var i$1 = 95;
29156 var n = 0;
29157 while (++i$1 < 106) {
29158     d3keybinding.keyCodes['num-' + n] = i$1;
29159     ++n;
29160 }
29161
29162 // 0-9
29163 i$1 = 47; n = 0;
29164 while (++i$1 < 58) {
29165     d3keybinding.keyCodes[n] = i$1;
29166     ++n;
29167 }
29168
29169 // F1-F25
29170 i$1 = 111; n = 1;
29171 while (++i$1 < 136) {
29172     d3keybinding.keyCodes['f' + n] = i$1;
29173     ++n;
29174 }
29175
29176 // a-z
29177 i$1 = 64;
29178 while (++i$1 < 91) {
29179     d3keybinding.keyCodes[String.fromCharCode(i$1).toLowerCase()] = i$1;
29180 }
29181
29182 function tooltip() {
29183   var tooltip = function(selection) {
29184       selection.each(setup);
29185     },
29186     animation = utilFunctor(false),
29187     html = utilFunctor(false),
29188     title = function() {
29189       var title = this.getAttribute('data-original-title');
29190       if (title) {
29191         return title;
29192       } else {
29193         title = this.getAttribute('title');
29194         this.removeAttribute('title');
29195         this.setAttribute('data-original-title', title);
29196       }
29197       return title;
29198     },
29199     over = 'mouseenter.tooltip',
29200     out = 'mouseleave.tooltip',
29201     placement = utilFunctor('top');
29202
29203
29204   tooltip.title = function(_) {
29205     if (arguments.length) {
29206       title = utilFunctor(_);
29207       return tooltip;
29208     } else {
29209       return title;
29210     }
29211   };
29212
29213
29214   tooltip.html = function(_) {
29215     if (arguments.length) {
29216       html = utilFunctor(_);
29217       return tooltip;
29218     } else {
29219       return html;
29220     }
29221   };
29222
29223
29224   tooltip.placement = function(_) {
29225     if (arguments.length) {
29226       placement = utilFunctor(_);
29227       return tooltip;
29228     } else {
29229       return placement;
29230     }
29231   };
29232
29233
29234   tooltip.show = function(selection) {
29235     selection.each(show);
29236   };
29237
29238
29239   tooltip.hide = function(selection) {
29240     selection.each(hide);
29241   };
29242
29243
29244   tooltip.toggle = function(selection) {
29245     selection.each(toggle);
29246   };
29247
29248
29249   tooltip.destroy = function(selection) {
29250     selection
29251       .on(over, null)
29252       .on(out, null)
29253       .attr('title', function() {
29254         return this.getAttribute('data-original-title') || this.getAttribute('title');
29255       })
29256       .attr('data-original-title', null)
29257       .selectAll('.tooltip')
29258       .remove();
29259   };
29260
29261
29262   function setup() {
29263     var root = d3_select(this),
29264         animate = animation.apply(this, arguments),
29265         tip = root.selectAll('.tooltip').data([0]);
29266
29267     var enter = tip.enter()
29268       .append('div')
29269       .attr('class', 'tooltip');
29270
29271     enter
29272       .append('div')
29273       .attr('class', 'tooltip-arrow');
29274
29275     enter
29276       .append('div')
29277       .attr('class', 'tooltip-inner');
29278
29279     tip = enter
29280       .merge(tip);
29281
29282     if (animate) {
29283       tip.classed('fade', true);
29284     }
29285
29286     var place = placement.apply(this, arguments);
29287     tip.classed(place, true);
29288
29289     root.on(over, show);
29290     root.on(out, hide);
29291   }
29292
29293
29294   function show() {
29295     var root = d3_select(this),
29296       content = title.apply(this, arguments),
29297       tip = root.selectAll('.tooltip')
29298         .classed('in', true),
29299       markup = html.apply(this, arguments);
29300
29301     tip.selectAll('.tooltip-inner')[markup ? 'html' : 'text'](content);
29302     var place = placement.apply(this, arguments),
29303       outer = getPosition(root.node()),
29304       inner = getPosition(tip.node()),
29305       pos;
29306
29307     switch (place) {
29308       case 'top':
29309         pos = {x: outer.x + (outer.w - inner.w) / 2, y: outer.y - inner.h};
29310         break;
29311       case 'right':
29312         pos = {x: outer.x + outer.w, y: outer.y + (outer.h - inner.h) / 2};
29313         break;
29314       case 'left':
29315         pos = {x: outer.x - inner.w, y: outer.y + (outer.h - inner.h) / 2};
29316         break;
29317       case 'bottom':
29318         pos = {x: Math.max(0, outer.x + (outer.w - inner.w) / 2), y: outer.y + outer.h};
29319         break;
29320     }
29321
29322     if (pos) {
29323       tip.style('left', ~~pos.x + 'px').style('top', ~~pos.y + 'px');
29324     } else {
29325       tip.style('left', null).style('top', null);
29326     }
29327
29328     this.tooltipVisible = true;
29329   }
29330
29331
29332   function hide() {
29333     d3_select(this).selectAll('.tooltip')
29334       .classed('in', false);
29335
29336     this.tooltipVisible = false;
29337   }
29338
29339
29340   function toggle() {
29341     if (this.tooltipVisible) {
29342       hide.apply(this, arguments);
29343     } else {
29344       show.apply(this, arguments);
29345     }
29346   }
29347
29348   return tooltip;
29349 }
29350
29351
29352 function getPosition(node) {
29353   var mode = d3_select(node).style('position');
29354   if (mode === 'absolute' || mode === 'static') {
29355     return {
29356       x: node.offsetLeft,
29357       y: node.offsetTop,
29358       w: node.offsetWidth,
29359       h: node.offsetHeight
29360     };
29361   } else {
29362     return {
29363       x: 0,
29364       y: 0,
29365       w: node.offsetWidth,
29366       h: node.offsetHeight
29367     };
29368   }
29369 }
29370
29371 function behaviorEdit(context) {
29372
29373     function edit() {
29374         context.map()
29375             .minzoom(context.minEditableZoom());
29376     }
29377
29378
29379     edit.off = function() {
29380         context.map()
29381             .minzoom(0);
29382     };
29383
29384
29385     return edit;
29386 }
29387
29388 /*
29389    The hover behavior adds the `.hover` class on mouseover to all elements to which
29390    the identical datum is bound, and removes it on mouseout.
29391
29392    The :hover pseudo-class is insufficient for iD's purposes because a datum's visual
29393    representation may consist of several elements scattered throughout the DOM hierarchy.
29394    Only one of these elements can have the :hover pseudo-class, but all of them will
29395    have the .hover class.
29396  */
29397 function behaviorHover(context) {
29398     var dispatch$$1 = dispatch('hover'),
29399         _selection = d3_select(null),
29400         newId = null,
29401         buttonDown,
29402         altDisables,
29403         target;
29404
29405
29406     function keydown() {
29407         if (altDisables && event.keyCode === d3keybinding.modifierCodes.alt) {
29408             _selection.selectAll('.hover')
29409                 .classed('hover-suppressed', true)
29410                 .classed('hover', false);
29411
29412             _selection
29413                 .classed('hover-disabled', true);
29414
29415             dispatch$$1.call('hover', this, null);
29416         }
29417     }
29418
29419
29420     function keyup() {
29421         if (altDisables && event.keyCode === d3keybinding.modifierCodes.alt) {
29422             _selection.selectAll('.hover-suppressed')
29423                 .classed('hover-suppressed', false)
29424                 .classed('hover', true);
29425
29426             _selection
29427                 .classed('hover-disabled', false);
29428
29429             dispatch$$1.call('hover', this, target ? target.id : null);
29430         }
29431     }
29432
29433
29434     var hover = function(selection) {
29435         _selection = selection;
29436         newId = null;
29437
29438         _selection
29439             .on('mouseover.hover', mouseover)
29440             .on('mouseout.hover', mouseout)
29441             .on('mousedown.hover', mousedown);
29442
29443         d3_select(window)
29444             .on('keydown.hover', keydown)
29445             .on('keyup.hover', keyup);
29446
29447
29448         function mouseover() {
29449             if (buttonDown) return;
29450             var target = event.target;
29451             enter(target ? target.__data__ : null);
29452         }
29453
29454
29455         function mouseout() {
29456             if (buttonDown) return;
29457             var target = event.relatedTarget;
29458             enter(target ? target.__data__ : null);
29459         }
29460
29461
29462         function mousedown() {
29463             buttonDown = true;
29464             d3_select(window)
29465                 .on('mouseup.hover', mouseup, true);
29466         }
29467
29468
29469         function mouseup() {
29470             buttonDown = false;
29471             d3_select(window)
29472                 .on('mouseup.hover', null, true);
29473         }
29474
29475
29476         function enter(d) {
29477             if (d === target) return;
29478             target = d;
29479
29480             _selection.selectAll('.hover')
29481                 .classed('hover', false);
29482             _selection.selectAll('.hover-suppressed')
29483                 .classed('hover-suppressed', false);
29484
29485             if (target instanceof osmEntity && target.id !== newId) {
29486
29487                 // If drawing a way, don't hover on a node that was just placed. #3974
29488                 var mode = context.mode() && context.mode().id;
29489                 if ((mode === 'draw-line' || mode === 'draw-area') && !newId && target.type === 'node') {
29490                     newId = target.id;
29491                     return;
29492                 }
29493
29494                 var selector = '.' + target.id;
29495
29496                 if (target.type === 'relation') {
29497                     target.members.forEach(function(member) {
29498                         selector += ', .' + member.id;
29499                     });
29500                 }
29501
29502                 var suppressed = altDisables && event && event.altKey;
29503
29504                 _selection.selectAll(selector)
29505                     .classed(suppressed ? 'hover-suppressed' : 'hover', true);
29506
29507                 dispatch$$1.call('hover', this, !suppressed && target.id);
29508
29509             } else {
29510                 dispatch$$1.call('hover', this, null);
29511             }
29512         }
29513
29514     };
29515
29516
29517     hover.off = function(selection) {
29518         selection.selectAll('.hover')
29519             .classed('hover', false);
29520         selection.selectAll('.hover-suppressed')
29521             .classed('hover-suppressed', false);
29522         selection
29523             .classed('hover-disabled', false);
29524
29525
29526         selection
29527             .on('mouseover.hover', null)
29528             .on('mouseout.hover', null)
29529             .on('mousedown.hover', null);
29530
29531         d3_select(window)
29532             .on('keydown.hover', null)
29533             .on('keyup.hover', null);
29534     };
29535
29536
29537     hover.altDisables = function(_) {
29538         if (!arguments.length) return altDisables;
29539         altDisables = _;
29540         return hover;
29541     };
29542
29543
29544     return utilRebind(hover, dispatch$$1, 'on');
29545 }
29546
29547 function refresh(selection, node) {
29548     var cr = node.getBoundingClientRect();
29549     var prop = [cr.width, cr.height];
29550     selection.property('__dimensions__', prop);
29551     return prop;
29552 }
29553
29554 function utilGetDimensions(selection, force) {
29555     if (!selection || selection.empty()) {
29556         return [0, 0];
29557     }
29558     var node = selection.node(),
29559         cached = selection.property('__dimensions__');
29560     return (!cached || force) ? refresh(selection, node) : cached;
29561 }
29562
29563
29564 function utilSetDimensions(selection, dimensions) {
29565     if (!selection || selection.empty()) {
29566         return selection;
29567     }
29568     var node = selection.node();
29569     if (dimensions === null) {
29570         refresh(selection, node);
29571         return selection;
29572     }
29573     return selection
29574         .property('__dimensions__', [dimensions[0], dimensions[1]])
29575         .attr('width', dimensions[0])
29576         .attr('height', dimensions[1]);
29577 }
29578
29579 function behaviorTail() {
29580     var text,
29581         container,
29582         xmargin = 25,
29583         tooltipSize = [0, 0],
29584         selectionSize = [0, 0];
29585
29586
29587     function tail(selection) {
29588         if (!text) return;
29589
29590         d3_select(window)
29591             .on('resize.tail', function() { selectionSize = utilGetDimensions(selection); });
29592
29593         container = d3_select(document.body)
29594             .append('div')
29595             .style('display', 'none')
29596             .attr('class', 'tail tooltip-inner');
29597
29598         container.append('div')
29599             .text(text);
29600
29601         selection
29602             .on('mousemove.tail', mousemove)
29603             .on('mouseenter.tail', mouseenter)
29604             .on('mouseleave.tail', mouseleave);
29605
29606         container
29607             .on('mousemove.tail', mousemove);
29608
29609         tooltipSize = utilGetDimensions(container);
29610         selectionSize = utilGetDimensions(selection);
29611
29612
29613         function show() {
29614             container.style('display', 'block');
29615             tooltipSize = utilGetDimensions(container);
29616         }
29617
29618
29619         function mousemove() {
29620             if (container.style('display') === 'none') show();
29621             var xoffset = ((event.clientX + tooltipSize[0] + xmargin) > selectionSize[0]) ?
29622                 -tooltipSize[0] - xmargin : xmargin;
29623             container.classed('left', xoffset > 0);
29624             utilSetTransform(container, event.clientX + xoffset, event.clientY);
29625         }
29626
29627
29628         function mouseleave() {
29629             if (event.relatedTarget !== container.node()) {
29630                 container.style('display', 'none');
29631             }
29632         }
29633
29634
29635         function mouseenter() {
29636             if (event.relatedTarget !== container.node()) {
29637                 show();
29638             }
29639         }
29640     }
29641
29642
29643     tail.off = function(selection) {
29644         if (!text) return;
29645
29646         container
29647             .on('mousemove.tail', null)
29648             .remove();
29649
29650         selection
29651             .on('mousemove.tail', null)
29652             .on('mouseenter.tail', null)
29653             .on('mouseleave.tail', null);
29654
29655         d3_select(window)
29656             .on('resize.tail', null);
29657     };
29658
29659
29660     tail.text = function(_) {
29661         if (!arguments.length) return text;
29662         text = _;
29663         return tail;
29664     };
29665
29666
29667     return tail;
29668 }
29669
29670 var usedTails = {};
29671 var disableSpace = false;
29672 var lastSpace = null;
29673
29674
29675 function behaviorDraw(context) {
29676     var dispatch$$1 = dispatch('move', 'click', 'clickWay',
29677             'clickNode', 'undo', 'cancel', 'finish'),
29678         keybinding = d3keybinding('draw'),
29679         hover = behaviorHover(context)
29680             .altDisables(true)
29681             .on('hover', context.ui().sidebar.hover),
29682         tail = behaviorTail(),
29683         edit = behaviorEdit(context),
29684         closeTolerance = 4,
29685         tolerance = 12,
29686         mouseLeave = false,
29687         lastMouse = null;
29688
29689
29690     function datum() {
29691         if (event.altKey) return {};
29692
29693         if (event.type === 'keydown') {
29694             return (lastMouse && lastMouse.target.__data__) || {};
29695         } else {
29696             return event.target.__data__ || {};
29697         }
29698     }
29699
29700
29701     function mousedown() {
29702
29703         function point() {
29704             var p = context.container().node();
29705             return touchId !== null ? d3_touches(p).filter(function(p) {
29706                 return p.identifier === touchId;
29707             })[0] : d3_mouse(p);
29708         }
29709
29710         var element = d3_select(this),
29711             touchId = event.touches ? event.changedTouches[0].identifier : null,
29712             t1 = +new Date(),
29713             p1 = point();
29714
29715         element.on('mousemove.draw', null);
29716
29717         d3_select(window).on('mouseup.draw', function() {
29718             var t2 = +new Date(),
29719                 p2 = point(),
29720                 dist = geoEuclideanDistance(p1, p2);
29721
29722             element.on('mousemove.draw', mousemove);
29723             d3_select(window).on('mouseup.draw', null);
29724
29725             if (dist < closeTolerance || (dist < tolerance && (t2 - t1) < 500)) {
29726                 // Prevent a quick second click
29727                 d3_select(window).on('click.draw-block', function() {
29728                     event.stopPropagation();
29729                 }, true);
29730
29731                 context.map().dblclickEnable(false);
29732
29733                 window.setTimeout(function() {
29734                     context.map().dblclickEnable(true);
29735                     d3_select(window).on('click.draw-block', null);
29736                 }, 500);
29737
29738                 click();
29739             }
29740         }, true);
29741     }
29742
29743
29744     function mousemove() {
29745         lastMouse = event;
29746         dispatch$$1.call('move', this, datum());
29747     }
29748
29749
29750     function mouseenter() {
29751         mouseLeave = false;
29752     }
29753
29754
29755     function mouseleave() {
29756         mouseLeave = true;
29757     }
29758
29759
29760     function click() {
29761         var d = datum();
29762         if (d.type === 'way') {
29763             var dims = context.map().dimensions(),
29764                 mouse$$1 = context.mouse(),
29765                 pad = 5,
29766                 trySnap = mouse$$1[0] > pad && mouse$$1[0] < dims[0] - pad &&
29767                     mouse$$1[1] > pad && mouse$$1[1] < dims[1] - pad;
29768
29769             if (trySnap) {
29770                 var choice = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection),
29771                     edge = [d.nodes[choice.index - 1], d.nodes[choice.index]];
29772                 dispatch$$1.call('clickWay', this, choice.loc, edge);
29773             } else {
29774                 dispatch$$1.call('click', this, context.map().mouseCoordinates());
29775             }
29776
29777         } else if (d.type === 'node') {
29778             dispatch$$1.call('clickNode', this, d);
29779
29780         } else {
29781             dispatch$$1.call('click', this, context.map().mouseCoordinates());
29782         }
29783     }
29784
29785
29786     function space() {
29787         event.preventDefault();
29788         event.stopPropagation();
29789
29790         var currSpace = context.mouse();
29791         if (disableSpace && lastSpace) {
29792             var dist = geoEuclideanDistance(lastSpace, currSpace);
29793             if (dist > tolerance) {
29794                 disableSpace = false;
29795             }
29796         }
29797
29798         if (disableSpace || mouseLeave || !lastMouse) return;
29799
29800         // user must move mouse or release space bar to allow another click
29801         lastSpace = currSpace;
29802         disableSpace = true;
29803
29804         d3_select(window).on('keyup.space-block', function() {
29805             event.preventDefault();
29806             event.stopPropagation();
29807             disableSpace = false;
29808             d3_select(window).on('keyup.space-block', null);
29809         });
29810
29811         click();
29812     }
29813
29814
29815     function backspace() {
29816         event.preventDefault();
29817         dispatch$$1.call('undo');
29818     }
29819
29820
29821     function del() {
29822         event.preventDefault();
29823         dispatch$$1.call('cancel');
29824     }
29825
29826
29827     function ret() {
29828         event.preventDefault();
29829         dispatch$$1.call('finish');
29830     }
29831
29832
29833     function draw(selection) {
29834         context.install(hover);
29835         context.install(edit);
29836
29837         if (!context.inIntro() && !usedTails[tail.text()]) {
29838             context.install(tail);
29839         }
29840
29841         keybinding
29842             .on('⌫', backspace)
29843             .on('⌦', del)
29844             .on('⎋', ret)
29845             .on('↩', ret)
29846             .on('space', space)
29847             .on('⌥space', space);
29848
29849         selection
29850             .on('mouseenter.draw', mouseenter)
29851             .on('mouseleave.draw', mouseleave)
29852             .on('mousedown.draw', mousedown)
29853             .on('mousemove.draw', mousemove);
29854
29855         d3_select(document)
29856             .call(keybinding);
29857
29858         return draw;
29859     }
29860
29861
29862     draw.off = function(selection) {
29863         context.ui().sidebar.hover.cancel();
29864         context.uninstall(hover);
29865         context.uninstall(edit);
29866
29867         if (!context.inIntro() && !usedTails[tail.text()]) {
29868             context.uninstall(tail);
29869             usedTails[tail.text()] = true;
29870         }
29871
29872         selection
29873             .on('mouseenter.draw', null)
29874             .on('mouseleave.draw', null)
29875             .on('mousedown.draw', null)
29876             .on('mousemove.draw', null);
29877
29878         d3_select(window)
29879             .on('mouseup.draw', null);
29880             // note: keyup.space-block, click.draw-block should remain
29881
29882         d3_select(document)
29883             .call(keybinding.off);
29884     };
29885
29886
29887     draw.tail = function(_) {
29888         tail.text(_);
29889         return draw;
29890     };
29891
29892
29893     return utilRebind(draw, dispatch$$1, 'on');
29894 }
29895
29896 function modeAddArea(context) {
29897     var mode = {
29898         id: 'add-area',
29899         button: 'area',
29900         title: t('modes.add_area.title'),
29901         description: t('modes.add_area.description'),
29902         key: '3'
29903     };
29904
29905     var behavior = behaviorAddWay(context)
29906             .tail(t('modes.add_area.tail'))
29907             .on('start', start)
29908             .on('startFromWay', startFromWay)
29909             .on('startFromNode', startFromNode),
29910         defaultTags = { area: 'yes' };
29911
29912
29913     function actionClose(wayId) {
29914         return function (graph) {
29915             return graph.replace(graph.entity(wayId).close());
29916         };
29917     }
29918
29919
29920     function start(loc) {
29921         var startGraph = context.graph(),
29922             node = osmNode({ loc: loc }),
29923             way = osmWay({ tags: defaultTags });
29924
29925         context.perform(
29926             actionAddEntity(node),
29927             actionAddEntity(way),
29928             actionAddVertex(way.id, node.id),
29929             actionClose(way.id)
29930         );
29931
29932         context.enter(modeDrawArea(context, way.id, startGraph));
29933     }
29934
29935
29936     function startFromWay(loc, edge) {
29937         var startGraph = context.graph(),
29938             node = osmNode({ loc: loc }),
29939             way = osmWay({ tags: defaultTags });
29940
29941         context.perform(
29942             actionAddEntity(node),
29943             actionAddEntity(way),
29944             actionAddVertex(way.id, node.id),
29945             actionClose(way.id),
29946             actionAddMidpoint({ loc: loc, edge: edge }, node)
29947         );
29948
29949         context.enter(modeDrawArea(context, way.id, startGraph));
29950     }
29951
29952
29953     function startFromNode(node) {
29954         var startGraph = context.graph(),
29955             way = osmWay({ tags: defaultTags });
29956
29957         context.perform(
29958             actionAddEntity(way),
29959             actionAddVertex(way.id, node.id),
29960             actionClose(way.id)
29961         );
29962
29963         context.enter(modeDrawArea(context, way.id, startGraph));
29964     }
29965
29966
29967     mode.enter = function() {
29968         context.install(behavior);
29969     };
29970
29971
29972     mode.exit = function() {
29973         context.uninstall(behavior);
29974     };
29975
29976
29977     return mode;
29978 }
29979
29980 function modeAddLine(context) {
29981     var mode = {
29982         id: 'add-line',
29983         button: 'line',
29984         title: t('modes.add_line.title'),
29985         description: t('modes.add_line.description'),
29986         key: '2'
29987     };
29988
29989     var behavior = behaviorAddWay(context)
29990         .tail(t('modes.add_line.tail'))
29991         .on('start', start)
29992         .on('startFromWay', startFromWay)
29993         .on('startFromNode', startFromNode);
29994
29995
29996     function start(loc) {
29997         var startGraph = context.graph(),
29998             node = osmNode({ loc: loc }),
29999             way = osmWay();
30000
30001         context.perform(
30002             actionAddEntity(node),
30003             actionAddEntity(way),
30004             actionAddVertex(way.id, node.id)
30005         );
30006
30007         context.enter(modeDrawLine(context, way.id, startGraph));
30008     }
30009
30010
30011     function startFromWay(loc, edge) {
30012         var startGraph = context.graph(),
30013             node = osmNode({ loc: loc }),
30014             way = osmWay();
30015
30016         context.perform(
30017             actionAddEntity(node),
30018             actionAddEntity(way),
30019             actionAddVertex(way.id, node.id),
30020             actionAddMidpoint({ loc: loc, edge: edge }, node)
30021         );
30022
30023         context.enter(modeDrawLine(context, way.id, startGraph));
30024     }
30025
30026
30027     function startFromNode(node) {
30028         var startGraph = context.graph(),
30029             way = osmWay();
30030
30031         context.perform(
30032             actionAddEntity(way),
30033             actionAddVertex(way.id, node.id)
30034         );
30035
30036         context.enter(modeDrawLine(context, way.id, startGraph));
30037     }
30038
30039
30040     mode.enter = function() {
30041         context.install(behavior);
30042     };
30043
30044
30045     mode.exit = function() {
30046         context.uninstall(behavior);
30047     };
30048
30049     return mode;
30050 }
30051
30052 function modeAddPoint(context) {
30053     var mode = {
30054         id: 'add-point',
30055         button: 'point',
30056         title: t('modes.add_point.title'),
30057         description: t('modes.add_point.description'),
30058         key: '1'
30059     };
30060
30061     var behavior = behaviorDraw(context)
30062         .tail(t('modes.add_point.tail'))
30063         .on('click', add)
30064         .on('clickWay', addWay)
30065         .on('clickNode', addNode)
30066         .on('cancel', cancel)
30067         .on('finish', cancel);
30068
30069
30070     function add(loc) {
30071         var node = osmNode({ loc: loc });
30072
30073         context.perform(
30074             actionAddEntity(node),
30075             t('operations.add.annotation.point')
30076         );
30077
30078         context.enter(
30079             modeSelect(context, [node.id]).newFeature(true)
30080         );
30081     }
30082
30083
30084     function addWay(loc) {
30085         add(loc);
30086     }
30087
30088
30089     function addNode(node) {
30090         add(node.loc);
30091     }
30092
30093
30094     function cancel() {
30095         context.enter(modeBrowse(context));
30096     }
30097
30098
30099     mode.enter = function() {
30100         context.install(behavior);
30101     };
30102
30103
30104     mode.exit = function() {
30105         context.uninstall(behavior);
30106     };
30107
30108
30109     return mode;
30110 }
30111
30112 function modeDragNode(context) {
30113     var mode = {
30114         id: 'drag-node',
30115         button: 'browse'
30116     };
30117
30118     var nudgeInterval,
30119         activeIDs,
30120         wasMidpoint,
30121         isCancelled,
30122         lastLoc,
30123         selectedIDs = [],
30124         hover = behaviorHover(context).altDisables(true).on('hover', context.ui().sidebar.hover),
30125         edit = behaviorEdit(context);
30126
30127
30128     function vecSub(a, b) {
30129         return [a[0] - b[0], a[1] - b[1]];
30130     }
30131
30132     function edge(point, size) {
30133         var pad = [80, 20, 50, 20],   // top, right, bottom, left
30134             x = 0,
30135             y = 0;
30136
30137         if (point[0] > size[0] - pad[1])
30138             x = -10;
30139         if (point[0] < pad[3])
30140             x = 10;
30141         if (point[1] > size[1] - pad[2])
30142             y = -10;
30143         if (point[1] < pad[0])
30144             y = 10;
30145
30146         if (x || y) {
30147             return [x, y];
30148         } else {
30149             return null;
30150         }
30151     }
30152
30153
30154     function startNudge(entity, nudge) {
30155         if (nudgeInterval) window.clearInterval(nudgeInterval);
30156         nudgeInterval = window.setInterval(function() {
30157             context.pan(nudge);
30158             doMove(entity, nudge);
30159         }, 50);
30160     }
30161
30162
30163     function stopNudge() {
30164         if (nudgeInterval) {
30165             window.clearInterval(nudgeInterval);
30166             nudgeInterval = null;
30167         }
30168     }
30169
30170
30171     function moveAnnotation(entity) {
30172         return t('operations.move.annotation.' + entity.geometry(context.graph()));
30173     }
30174
30175
30176     function connectAnnotation(entity) {
30177         return t('operations.connect.annotation.' + entity.geometry(context.graph()));
30178     }
30179
30180
30181     function origin(entity) {
30182         return context.projection(entity.loc);
30183     }
30184
30185
30186     function start(entity) {
30187         wasMidpoint = entity.type === 'midpoint';
30188
30189         isCancelled = event.sourceEvent.shiftKey ||
30190             context.features().hasHiddenConnections(entity, context.graph());
30191
30192         if (isCancelled) {
30193             return behavior.cancel();
30194         }
30195
30196         if (wasMidpoint) {
30197             var midpoint = entity;
30198             entity = osmNode();
30199             context.perform(actionAddMidpoint(midpoint, entity));
30200
30201             var vertex = context.surface().selectAll('.' + entity.id);
30202             behavior.target(vertex.node(), entity);
30203
30204         } else {
30205             context.perform(actionNoop());
30206         }
30207
30208         // activeIDs generate no pointer events.  This prevents the node or vertex
30209         // being dragged from trying to connect to itself or its parent element.
30210         activeIDs = map$4(context.graph().parentWays(entity), 'id');
30211         activeIDs.push(entity.id);
30212         setActiveElements();
30213
30214         context.enter(mode);
30215     }
30216
30217
30218     function datum() {
30219         var event$$1 = event && event.sourceEvent;
30220         if (!event$$1 || event$$1.altKey) {
30221             return {};
30222         } else {
30223             return event$$1.target.__data__ || {};
30224         }
30225     }
30226
30227
30228     function doMove(entity, nudge) {
30229         nudge = nudge || [0, 0];
30230
30231         var currPoint = (event && event.point) || context.projection(lastLoc),
30232             currMouse = vecSub(currPoint, nudge),
30233             loc = context.projection.invert(currMouse),
30234             d = datum();
30235
30236         if (!nudgeInterval) {
30237             if (d.type === 'node' && d.id !== entity.id) {
30238                 loc = d.loc;
30239             } else if (d.type === 'way' && !d3_select(event.sourceEvent.target).classed('fill')) {
30240                 loc = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection).loc;
30241             }
30242         }
30243
30244         context.replace(
30245             actionMoveNode(entity.id, loc),
30246             moveAnnotation(entity)
30247         );
30248
30249         lastLoc = loc;
30250     }
30251
30252
30253     function move(entity) {
30254         if (isCancelled) return;
30255         event.sourceEvent.stopPropagation();
30256         lastLoc = context.projection.invert(event.point);
30257
30258         doMove(entity);
30259         var nudge = edge(event.point, context.map().dimensions());
30260         if (nudge) {
30261             startNudge(entity, nudge);
30262         } else {
30263             stopNudge();
30264         }
30265     }
30266
30267
30268     function end(entity) {
30269         if (isCancelled) return;
30270
30271         var d = datum();
30272
30273         if (d.type === 'way') {
30274             var choice = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection);
30275             context.replace(
30276                 actionAddMidpoint({ loc: choice.loc, edge: [d.nodes[choice.index - 1], d.nodes[choice.index]] }, entity),
30277                 connectAnnotation(d)
30278             );
30279
30280         } else if (d.type === 'node' && d.id !== entity.id) {
30281             context.replace(
30282                 actionConnect([d.id, entity.id]),
30283                 connectAnnotation(d)
30284             );
30285
30286         } else if (wasMidpoint) {
30287             context.replace(
30288                 actionNoop(),
30289                 t('operations.add.annotation.vertex')
30290             );
30291
30292         } else {
30293             context.replace(
30294                 actionNoop(),
30295                 moveAnnotation(entity)
30296             );
30297         }
30298
30299         var reselection = selectedIDs.filter(function(id) {
30300             return context.graph().hasEntity(id);
30301         });
30302
30303         if (reselection.length) {
30304             context.enter(modeSelect(context, reselection));
30305         } else {
30306             context.enter(modeBrowse(context));
30307         }
30308     }
30309
30310
30311     function cancel() {
30312         behavior.cancel();
30313         context.enter(modeBrowse(context));
30314     }
30315
30316
30317     function setActiveElements() {
30318         context.surface().selectAll(utilEntitySelector(activeIDs))
30319             .classed('active', true);
30320     }
30321
30322
30323     var behavior = behaviorDrag()
30324         .selector('g.node, g.point, g.midpoint')
30325         .surface(d3_select('#map').node())
30326         .origin(origin)
30327         .on('start', start)
30328         .on('move', move)
30329         .on('end', end);
30330
30331
30332     mode.enter = function() {
30333         context.install(hover);
30334         context.install(edit);
30335
30336         context.history()
30337             .on('undone.drag-node', cancel);
30338
30339         context.map()
30340             .on('drawn.drag-node', setActiveElements);
30341
30342         setActiveElements();
30343     };
30344
30345
30346     mode.exit = function() {
30347         context.ui().sidebar.hover.cancel();
30348         context.uninstall(hover);
30349         context.uninstall(edit);
30350
30351         context.history()
30352             .on('undone.drag-node', null);
30353
30354         context.map()
30355             .on('drawn.drag-node', null);
30356
30357         context.surface()
30358             .selectAll('.active')
30359             .classed('active', false);
30360
30361         stopNudge();
30362     };
30363
30364
30365     mode.selectedIDs = function(_) {
30366         if (!arguments.length) return selectedIDs;
30367         selectedIDs = _;
30368         return mode;
30369     };
30370
30371
30372     mode.behavior = behavior;
30373
30374
30375     return mode;
30376 }
30377
30378 function modeBrowse(context) {
30379     var mode = {
30380         button: 'browse',
30381         id: 'browse',
30382         title: t('modes.browse.title'),
30383         description: t('modes.browse.description')
30384     }, sidebar;
30385
30386     var behaviors = [
30387         behaviorPaste(context),
30388         behaviorHover(context).on('hover', context.ui().sidebar.hover),
30389         behaviorSelect(context),
30390         behaviorLasso(context),
30391         modeDragNode(context).behavior
30392     ];
30393
30394
30395     mode.enter = function() {
30396         behaviors.forEach(function(behavior) {
30397             context.install(behavior);
30398         });
30399
30400         // Get focus on the body.
30401         if (document.activeElement && document.activeElement.blur) {
30402             document.activeElement.blur();
30403         }
30404
30405         if (sidebar) {
30406             context.ui().sidebar.show(sidebar);
30407         } else {
30408             context.ui().sidebar.select(null);
30409         }
30410     };
30411
30412
30413     mode.exit = function() {
30414         context.ui().sidebar.hover.cancel();
30415         behaviors.forEach(function(behavior) {
30416             context.uninstall(behavior);
30417         });
30418
30419         if (sidebar) {
30420             context.ui().sidebar.hide();
30421         }
30422     };
30423
30424
30425     mode.sidebar = function(_) {
30426         if (!arguments.length) return sidebar;
30427         sidebar = _;
30428         return mode;
30429     };
30430
30431
30432     return mode;
30433 }
30434
30435 function modeDrawArea(context, wayId, startGraph) {
30436     var mode = {
30437         button: 'area',
30438         id: 'draw-area'
30439     };
30440
30441     var behavior;
30442
30443
30444     mode.enter = function() {
30445         var way = context.entity(wayId);
30446
30447         behavior = behaviorDrawWay(context, wayId, undefined, mode, startGraph)
30448             .tail(t('modes.draw_area.tail'));
30449
30450         var addNode = behavior.addNode;
30451
30452         behavior.addNode = function(node) {
30453             var length = way.nodes.length,
30454                 penultimate = length > 2 ? way.nodes[length - 2] : null;
30455
30456             if (node.id === way.first() || node.id === penultimate) {
30457                 behavior.finish();
30458             } else {
30459                 addNode(node);
30460             }
30461         };
30462
30463         context.install(behavior);
30464     };
30465
30466
30467     mode.exit = function() {
30468         context.uninstall(behavior);
30469     };
30470
30471
30472     mode.selectedIDs = function() {
30473         return [wayId];
30474     };
30475
30476
30477     return mode;
30478 }
30479
30480 function modeDrawLine(context, wayId, startGraph, affix) {
30481     var mode = {
30482         button: 'line',
30483         id: 'draw-line'
30484     };
30485
30486     var behavior;
30487
30488
30489     mode.enter = function() {
30490         var way = context.entity(wayId),
30491             index = (affix === 'prefix') ? 0 : undefined,
30492             headId = (affix === 'prefix') ? way.first() : way.last();
30493
30494         behavior = behaviorDrawWay(context, wayId, index, mode, startGraph)
30495             .tail(t('modes.draw_line.tail'));
30496
30497         var addNode = behavior.addNode;
30498
30499         behavior.addNode = function(node) {
30500             if (node.id === headId) {
30501                 behavior.finish();
30502             } else {
30503                 addNode(node);
30504             }
30505         };
30506
30507         context.install(behavior);
30508     };
30509
30510
30511     mode.exit = function() {
30512         context.uninstall(behavior);
30513     };
30514
30515
30516     mode.selectedIDs = function() {
30517         return [wayId];
30518     };
30519
30520
30521     return mode;
30522 }
30523
30524 function operationCircularize(selectedIDs, context) {
30525     var entityId = selectedIDs[0],
30526         entity = context.entity(entityId),
30527         extent = entity.extent(context.graph()),
30528         geometry = context.geometry(entityId),
30529         action = actionCircularize(entityId, context.projection);
30530
30531
30532     var operation = function() {
30533         context.perform(action, operation.annotation());
30534     };
30535
30536
30537     operation.available = function() {
30538         return selectedIDs.length === 1 &&
30539             entity.type === 'way' &&
30540             uniq(entity.nodes).length > 1;
30541     };
30542
30543
30544     operation.disabled = function() {
30545         var reason;
30546         if (extent.percentContainedIn(context.extent()) < 0.8) {
30547             reason = 'too_large';
30548         } else if (context.hasHiddenConnections(entityId)) {
30549             reason = 'connected_to_hidden';
30550         }
30551         return action.disabled(context.graph()) || reason;
30552     };
30553
30554
30555     operation.tooltip = function() {
30556         var disable = operation.disabled();
30557         return disable ?
30558             t('operations.circularize.' + disable) :
30559             t('operations.circularize.description.' + geometry);
30560     };
30561
30562
30563     operation.annotation = function() {
30564         return t('operations.circularize.annotation.' + geometry);
30565     };
30566
30567
30568     operation.id = 'circularize';
30569     operation.keys = [t('operations.circularize.key')];
30570     operation.title = t('operations.circularize.title');
30571     operation.behavior = behaviorOperation(context).which(operation);
30572
30573     return operation;
30574 }
30575
30576 function operationContinue(selectedIDs, context) {
30577     var graph = context.graph(),
30578         entities = selectedIDs.map(function(id) { return graph.entity(id); }),
30579         geometries = assignIn({ line: [], vertex: [] },
30580             groupBy(entities, function(entity) { return entity.geometry(graph); })),
30581         vertex = geometries.vertex[0];
30582
30583
30584     function candidateWays() {
30585         return graph.parentWays(vertex).filter(function(parent) {
30586             return parent.geometry(graph) === 'line' &&
30587                 !parent.isClosed() &&
30588                 parent.affix(vertex.id) &&
30589                 (geometries.line.length === 0 || geometries.line[0] === parent);
30590         });
30591     }
30592
30593
30594     var operation = function() {
30595         var candidate = candidateWays()[0];
30596         context.enter(
30597             modeDrawLine(context, candidate.id, context.graph(), candidate.affix(vertex.id))
30598         );
30599     };
30600
30601
30602     operation.available = function() {
30603         return geometries.vertex.length === 1 && geometries.line.length <= 1 &&
30604             !context.features().hasHiddenConnections(vertex, context.graph());
30605     };
30606
30607
30608     operation.disabled = function() {
30609         var candidates = candidateWays();
30610         if (candidates.length === 0)
30611             return 'not_eligible';
30612         if (candidates.length > 1)
30613             return 'multiple';
30614     };
30615
30616
30617     operation.tooltip = function() {
30618         var disable = operation.disabled();
30619         return disable ?
30620             t('operations.continue.' + disable) :
30621             t('operations.continue.description');
30622     };
30623
30624
30625     operation.annotation = function() {
30626         return t('operations.continue.annotation.line');
30627     };
30628
30629
30630     operation.id = 'continue';
30631     operation.keys = [t('operations.continue.key')];
30632     operation.title = t('operations.continue.title');
30633     operation.behavior = behaviorOperation(context).which(operation);
30634
30635     return operation;
30636 }
30637
30638 function operationDelete(selectedIDs, context) {
30639     var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
30640         action = actionDeleteMultiple(selectedIDs),
30641         extent = selectedIDs.reduce(function(extent, id) {
30642                 return extent.extend(context.entity(id).extent(context.graph()));
30643             }, geoExtent());
30644
30645
30646     var operation = function() {
30647         var nextSelectedID;
30648
30649         if (selectedIDs.length === 1) {
30650             var id = selectedIDs[0],
30651                 entity = context.entity(id),
30652                 geometry = context.geometry(id),
30653                 parents = context.graph().parentWays(entity),
30654                 parent = parents[0];
30655
30656             // Select the next closest node in the way.
30657             if (geometry === 'vertex' && parent.nodes.length > 2) {
30658                 var nodes = parent.nodes,
30659                     i = nodes.indexOf(id);
30660
30661                 if (i === 0) {
30662                     i++;
30663                 } else if (i === nodes.length - 1) {
30664                     i--;
30665                 } else {
30666                     var a = geoSphericalDistance(entity.loc, context.entity(nodes[i - 1]).loc),
30667                         b = geoSphericalDistance(entity.loc, context.entity(nodes[i + 1]).loc);
30668                     i = a < b ? i - 1 : i + 1;
30669                 }
30670
30671                 nextSelectedID = nodes[i];
30672             }
30673         }
30674
30675         context.perform(action, operation.annotation());
30676
30677         if (nextSelectedID && context.hasEntity(nextSelectedID)) {
30678             context.enter(modeSelect(context, [nextSelectedID]).follow(true));
30679         } else {
30680             context.enter(modeBrowse(context));
30681         }
30682
30683     };
30684
30685
30686     operation.available = function() {
30687         return true;
30688     };
30689
30690
30691     operation.disabled = function() {
30692         var reason;
30693         if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
30694             reason = 'too_large';
30695         } else if (some(selectedIDs, context.hasHiddenConnections)) {
30696             reason = 'connected_to_hidden';
30697         } else if (some(selectedIDs, protectedMember)) {
30698             reason = 'part_of_relation';
30699         } else if (some(selectedIDs, incompleteRelation)) {
30700             reason = 'incomplete_relation';
30701         }
30702         return reason;
30703
30704         function incompleteRelation(id) {
30705             var entity = context.entity(id);
30706             return entity.type === 'relation' && !entity.isComplete(context.graph());
30707         }
30708
30709         function protectedMember(id) {
30710             var entity = context.entity(id);
30711             if (entity.type !== 'way') return false;
30712
30713             var parents = context.graph().parentRelations(entity);
30714             for (var i = 0; i < parents.length; i++) {
30715                 var parent = parents[i],
30716                     type = parent.tags.type,
30717                     role = parent.memberById(id).role || 'outer';
30718                 if (type === 'route' || type === 'boundary' || (type === 'multipolygon' && role === 'outer')) {
30719                     return true;
30720                 }
30721             }
30722             return false;
30723         }
30724
30725     };
30726
30727
30728     operation.tooltip = function() {
30729         var disable = operation.disabled();
30730         return disable ?
30731             t('operations.delete.' + disable + '.' + multi) :
30732             t('operations.delete.description' + '.' + multi);
30733     };
30734
30735
30736     operation.annotation = function() {
30737         return selectedIDs.length === 1 ?
30738             t('operations.delete.annotation.' + context.geometry(selectedIDs[0])) :
30739             t('operations.delete.annotation.multiple', { n: selectedIDs.length });
30740     };
30741
30742
30743     operation.id = 'delete';
30744     operation.keys = [uiCmd('⌘⌫'), uiCmd('⌘⌦'), uiCmd('⌦')];
30745     operation.title = t('operations.delete.title');
30746     operation.behavior = behaviorOperation(context).which(operation);
30747
30748     return operation;
30749 }
30750
30751 function operationDisconnect(selectedIDs, context) {
30752     var vertices = filter(selectedIDs, function(entityId) {
30753         return context.geometry(entityId) === 'vertex';
30754     });
30755
30756     var entityId = vertices[0],
30757         action = actionDisconnect(entityId);
30758
30759     if (selectedIDs.length > 1) {
30760         action.limitWays(without(selectedIDs, entityId));
30761     }
30762
30763
30764     var operation = function() {
30765         context.perform(action, operation.annotation());
30766     };
30767
30768
30769     operation.available = function() {
30770         return vertices.length === 1;
30771     };
30772
30773
30774     operation.disabled = function() {
30775         var reason;
30776         if (some(selectedIDs, context.hasHiddenConnections)) {
30777             reason = 'connected_to_hidden';
30778         }
30779         return action.disabled(context.graph()) || reason;
30780     };
30781
30782
30783     operation.tooltip = function() {
30784         var disable = operation.disabled();
30785         return disable ?
30786             t('operations.disconnect.' + disable) :
30787             t('operations.disconnect.description');
30788     };
30789
30790
30791     operation.annotation = function() {
30792         return t('operations.disconnect.annotation');
30793     };
30794
30795
30796     operation.id = 'disconnect';
30797     operation.keys = [t('operations.disconnect.key')];
30798     operation.title = t('operations.disconnect.title');
30799     operation.behavior = behaviorOperation(context).which(operation);
30800
30801     return operation;
30802 }
30803
30804 function operationMerge(selectedIDs, context) {
30805
30806     function updatePresetTags(newGraph, ids) {
30807         var id = ids[0],
30808             newEntity = newGraph.hasEntity(id);
30809
30810         if (!newEntity) return;
30811
30812         var newPreset = context.presets().match(newEntity, newGraph);
30813
30814         context.replace(actionChangePreset(id, null, newPreset), operation.annotation());
30815     }
30816
30817
30818     var join = actionJoin(selectedIDs),
30819         merge = actionMerge(selectedIDs),
30820         mergePolygon = actionMergePolygon(selectedIDs);
30821
30822
30823     var operation = function() {
30824         var origGraph = context.graph(),
30825             action;
30826
30827         if (!join.disabled(origGraph)) {
30828             action = join;
30829         } else if (!merge.disabled(origGraph)) {
30830             action = merge;
30831         } else {
30832             action = mergePolygon;
30833         }
30834
30835         context.perform(action, operation.annotation());
30836
30837         var ids = selectedIDs.filter(function(id) {
30838             var entity = context.hasEntity(id);
30839             return entity && entity.type !== 'node';
30840         });
30841
30842         // if we merged tags, rematch preset to update tags if necessary (#3851)
30843         if (action === merge) {
30844             updatePresetTags(context.graph(), ids);
30845         }
30846
30847         context.enter(modeSelect(context, ids));
30848     };
30849
30850
30851     operation.available = function() {
30852         return selectedIDs.length >= 2;
30853     };
30854
30855
30856     operation.disabled = function() {
30857         return join.disabled(context.graph()) &&
30858             merge.disabled(context.graph()) &&
30859             mergePolygon.disabled(context.graph());
30860     };
30861
30862
30863     operation.tooltip = function() {
30864         var j = join.disabled(context.graph()),
30865             m = merge.disabled(context.graph()),
30866             p = mergePolygon.disabled(context.graph());
30867
30868         if (j === 'restriction' && m && p) {
30869             return t('operations.merge.restriction',
30870                 { relation: context.presets().item('type/restriction').name() });
30871         }
30872
30873         if (p === 'incomplete_relation' && j && m) {
30874             return t('operations.merge.incomplete_relation');
30875         }
30876
30877         if (j && m && p) {
30878             return t('operations.merge.' + j);
30879         }
30880
30881         return t('operations.merge.description');
30882     };
30883
30884
30885     operation.annotation = function() {
30886         return t('operations.merge.annotation', { n: selectedIDs.length });
30887     };
30888
30889
30890     operation.id = 'merge';
30891     operation.keys = [t('operations.merge.key')];
30892     operation.title = t('operations.merge.title');
30893     operation.behavior = behaviorOperation(context).which(operation);
30894
30895     return operation;
30896 }
30897
30898 function operationMove(selectedIDs, context) {
30899     var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
30900         extent = selectedIDs.reduce(function(extent, id) {
30901             return extent.extend(context.entity(id).extent(context.graph()));
30902         }, geoExtent());
30903
30904
30905     var operation = function() {
30906         context.enter(modeMove(context, selectedIDs));
30907     };
30908
30909
30910     operation.available = function() {
30911         return selectedIDs.length > 1 ||
30912             context.entity(selectedIDs[0]).type !== 'node';
30913     };
30914
30915
30916     operation.disabled = function() {
30917         var reason;
30918         if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
30919             reason = 'too_large';
30920         } else if (some(selectedIDs, context.hasHiddenConnections)) {
30921             reason = 'connected_to_hidden';
30922         } else if (some(selectedIDs, incompleteRelation)) {
30923             reason = 'incomplete_relation';
30924         }
30925         return reason;
30926
30927         function incompleteRelation(id) {
30928             var entity = context.entity(id);
30929             return entity.type === 'relation' && !entity.isComplete(context.graph());
30930         }
30931     };
30932
30933
30934     operation.tooltip = function() {
30935         var disable = operation.disabled();
30936         return disable ?
30937             t('operations.move.' + disable + '.' + multi) :
30938             t('operations.move.description.' + multi);
30939     };
30940
30941
30942     operation.annotation = function() {
30943         return selectedIDs.length === 1 ?
30944             t('operations.move.annotation.' + context.geometry(selectedIDs[0])) :
30945             t('operations.move.annotation.multiple');
30946     };
30947
30948
30949     operation.id = 'move';
30950     operation.keys = [t('operations.move.key')];
30951     operation.title = t('operations.move.title');
30952     operation.behavior = behaviorOperation(context).which(operation);
30953
30954     return operation;
30955 }
30956
30957 function operationOrthogonalize(selectedIDs, context) {
30958     var entityId = selectedIDs[0],
30959         entity = context.entity(entityId),
30960         extent = entity.extent(context.graph()),
30961         geometry = context.geometry(entityId),
30962         action = actionOrthogonalize(entityId, context.projection);
30963
30964
30965     var operation = function() {
30966         context.perform(action, operation.annotation());
30967     };
30968
30969
30970     operation.available = function() {
30971         return selectedIDs.length === 1 &&
30972             entity.type === 'way' &&
30973             entity.isClosed() &&
30974             uniq(entity.nodes).length > 2;
30975     };
30976
30977
30978     operation.disabled = function() {
30979         var reason;
30980         if (extent.percentContainedIn(context.extent()) < 0.8) {
30981             reason = 'too_large';
30982         } else if (context.hasHiddenConnections(entityId)) {
30983             reason = 'connected_to_hidden';
30984         }
30985         return action.disabled(context.graph()) || reason;
30986     };
30987
30988
30989     operation.tooltip = function() {
30990         var disable = operation.disabled();
30991         return disable ?
30992             t('operations.orthogonalize.' + disable) :
30993             t('operations.orthogonalize.description.' + geometry);
30994     };
30995
30996
30997     operation.annotation = function() {
30998         return t('operations.orthogonalize.annotation.' + geometry);
30999     };
31000
31001
31002     operation.id = 'orthogonalize';
31003     operation.keys = [t('operations.orthogonalize.key')];
31004     operation.title = t('operations.orthogonalize.title');
31005     operation.behavior = behaviorOperation(context).which(operation);
31006
31007     return operation;
31008 }
31009
31010 /**
31011  * This method is like `_.uniq` except that it accepts `iteratee` which is
31012  * invoked for each element in `array` to generate the criterion by which
31013  * uniqueness is computed. The order of result values is determined by the
31014  * order they occur in the array. The iteratee is invoked with one argument:
31015  * (value).
31016  *
31017  * @static
31018  * @memberOf _
31019  * @since 4.0.0
31020  * @category Array
31021  * @param {Array} array The array to inspect.
31022  * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
31023  * @returns {Array} Returns the new duplicate free array.
31024  * @example
31025  *
31026  * _.uniqBy([2.1, 1.2, 2.3], Math.floor);
31027  * // => [2.1, 1.2]
31028  *
31029  * // The `_.property` iteratee shorthand.
31030  * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
31031  * // => [{ 'x': 1 }, { 'x': 2 }]
31032  */
31033 function uniqBy(array, iteratee) {
31034   return (array && array.length) ? baseUniq(array, baseIteratee(iteratee, 2)) : [];
31035 }
31036
31037 function operationReflectShort(selectedIDs, context) {
31038     return operationReflect(selectedIDs, context, 'short');
31039 }
31040
31041
31042 function operationReflectLong(selectedIDs, context) {
31043     return operationReflect(selectedIDs, context, 'long');
31044 }
31045
31046
31047 function operationReflect(selectedIDs, context, axis) {
31048     axis = axis || 'long';
31049     var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
31050         extent = selectedIDs.reduce(function(extent, id) {
31051             return extent.extend(context.entity(id).extent(context.graph()));
31052         }, geoExtent());
31053
31054
31055     var operation = function() {
31056         var action = actionReflect(selectedIDs, context.projection)
31057             .useLongAxis(Boolean(axis === 'long'));
31058         context.perform(action, operation.annotation());
31059     };
31060
31061
31062     operation.available = function() {
31063         var nodes = utilGetAllNodes(selectedIDs, context.graph());
31064         return uniqBy(nodes, function(n) { return n.loc; }).length >= 3;
31065     };
31066
31067
31068     operation.disabled = function() {
31069         var reason;
31070         if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
31071             reason = 'too_large';
31072         } else if (some(selectedIDs, context.hasHiddenConnections)) {
31073             reason = 'connected_to_hidden';
31074         } else if (some(selectedIDs, incompleteRelation)) {
31075             reason = 'incomplete_relation';
31076         }
31077         return reason;
31078
31079         function incompleteRelation(id) {
31080             var entity = context.entity(id);
31081             return entity.type === 'relation' && !entity.isComplete(context.graph());
31082         }
31083     };
31084
31085
31086     operation.tooltip = function() {
31087         var disable = operation.disabled();
31088         return disable ?
31089             t('operations.reflect.' + disable + '.' + multi) :
31090             t('operations.reflect.description.' + axis + '.' + multi);
31091     };
31092
31093
31094     operation.annotation = function() {
31095         return t('operations.reflect.annotation.' + axis + '.' + multi);
31096     };
31097
31098
31099     operation.id = 'reflect-' + axis;
31100     operation.keys = [t('operations.reflect.key.' + axis)];
31101     operation.title = t('operations.reflect.title.' + axis);
31102     operation.behavior = behaviorOperation(context).which(operation);
31103
31104     return operation;
31105 }
31106
31107 function operationReverse(selectedIDs, context) {
31108     var entityId = selectedIDs[0];
31109
31110     var operation = function() {
31111         context.perform(actionReverse(entityId), operation.annotation());
31112     };
31113
31114
31115     operation.available = function() {
31116         return selectedIDs.length === 1 && context.geometry(entityId) === 'line';
31117     };
31118
31119
31120     operation.disabled = function() {
31121         return false;
31122     };
31123
31124
31125     operation.tooltip = function() {
31126         return t('operations.reverse.description');
31127     };
31128
31129
31130     operation.annotation = function() {
31131         return t('operations.reverse.annotation');
31132     };
31133
31134
31135     operation.id = 'reverse';
31136     operation.keys = [t('operations.reverse.key')];
31137     operation.title = t('operations.reverse.title');
31138     operation.behavior = behaviorOperation(context).which(operation);
31139
31140     return operation;
31141 }
31142
31143 function operationRotate(selectedIDs, context) {
31144     var multi = (selectedIDs.length === 1 ? 'single' : 'multiple'),
31145         extent = selectedIDs.reduce(function(extent, id) {
31146             return extent.extend(context.entity(id).extent(context.graph()));
31147         }, geoExtent());
31148
31149
31150     var operation = function() {
31151         context.enter(modeRotate(context, selectedIDs));
31152     };
31153
31154
31155     operation.available = function() {
31156         var nodes = utilGetAllNodes(selectedIDs, context.graph());
31157         return uniqBy(nodes, function(n) { return n.loc; }).length >= 2;
31158     };
31159
31160
31161     operation.disabled = function() {
31162         var reason;
31163         if (extent.area() && extent.percentContainedIn(context.extent()) < 0.8) {
31164             reason = 'too_large';
31165         } else if (some(selectedIDs, context.hasHiddenConnections)) {
31166             reason = 'connected_to_hidden';
31167         } else if (some(selectedIDs, incompleteRelation)) {
31168             reason = 'incomplete_relation';
31169         }
31170         return reason;
31171
31172         function incompleteRelation(id) {
31173             var entity = context.entity(id);
31174             return entity.type === 'relation' && !entity.isComplete(context.graph());
31175         }
31176     };
31177
31178
31179     operation.tooltip = function() {
31180         var disable = operation.disabled();
31181         return disable ?
31182             t('operations.rotate.' + disable + '.' + multi) :
31183             t('operations.rotate.description.' + multi);
31184     };
31185
31186
31187     operation.annotation = function() {
31188         return selectedIDs.length === 1 ?
31189             t('operations.rotate.annotation.' + context.geometry(selectedIDs[0])) :
31190             t('operations.rotate.annotation.multiple');
31191     };
31192
31193
31194     operation.id = 'rotate';
31195     operation.keys = [t('operations.rotate.key')];
31196     operation.title = t('operations.rotate.title');
31197     operation.behavior = behaviorOperation(context).which(operation);
31198
31199     return operation;
31200 }
31201
31202 function operationSplit(selectedIDs, context) {
31203     var vertices = filter(selectedIDs, function(entityId) {
31204         return context.geometry(entityId) === 'vertex';
31205     });
31206
31207     var entityId = vertices[0],
31208         action = actionSplit(entityId),
31209         ways = [];
31210
31211     if (vertices.length === 1) {
31212         if (selectedIDs.length > 1) {
31213             action.limitWays(without(selectedIDs, entityId));
31214         }
31215         ways = action.ways(context.graph());
31216     }
31217
31218
31219     var operation = function() {
31220         var difference = context.perform(action, operation.annotation());
31221         context.enter(modeSelect(context, difference.extantIDs()));
31222     };
31223
31224
31225     operation.available = function() {
31226         return vertices.length === 1;
31227     };
31228
31229
31230     operation.disabled = function() {
31231         var reason;
31232         if (some(selectedIDs, context.hasHiddenConnections)) {
31233             reason = 'connected_to_hidden';
31234         }
31235         return action.disabled(context.graph()) || reason;
31236     };
31237
31238
31239     operation.tooltip = function() {
31240         var disable = operation.disabled();
31241         if (disable) {
31242             return t('operations.split.' + disable);
31243         }
31244         if (ways.length === 1) {
31245             return t('operations.split.description.' + context.geometry(ways[0].id));
31246         } else {
31247             return t('operations.split.description.multiple');
31248         }
31249     };
31250
31251
31252     operation.annotation = function() {
31253         return ways.length === 1 ?
31254             t('operations.split.annotation.' + context.geometry(ways[0].id)) :
31255             t('operations.split.annotation.multiple', { n: ways.length });
31256     };
31257
31258
31259     operation.id = 'split';
31260     operation.keys = [t('operations.split.key')];
31261     operation.title = t('operations.split.title');
31262     operation.behavior = behaviorOperation(context).which(operation);
31263
31264     return operation;
31265 }
31266
31267 function operationStraighten(selectedIDs, context) {
31268     var entityId = selectedIDs[0],
31269         action = actionStraighten(entityId, context.projection);
31270
31271
31272     function operation() {
31273         context.perform(action, operation.annotation());
31274     }
31275
31276
31277     operation.available = function() {
31278         var entity = context.entity(entityId);
31279         return selectedIDs.length === 1 &&
31280             entity.type === 'way' &&
31281             !entity.isClosed() &&
31282             uniq(entity.nodes).length > 2;
31283     };
31284
31285
31286     operation.disabled = function() {
31287         var reason;
31288         if (context.hasHiddenConnections(entityId)) {
31289             reason = 'connected_to_hidden';
31290         }
31291         return action.disabled(context.graph()) || reason;
31292     };
31293
31294
31295     operation.tooltip = function() {
31296         var disable = operation.disabled();
31297         return disable ?
31298             t('operations.straighten.' + disable) :
31299             t('operations.straighten.description');
31300     };
31301
31302
31303     operation.annotation = function() {
31304         return t('operations.straighten.annotation');
31305     };
31306
31307
31308     operation.id = 'straighten';
31309     operation.keys = [t('operations.straighten.key')];
31310     operation.title = t('operations.straighten.title');
31311     operation.behavior = behaviorOperation(context).which(operation);
31312
31313     return operation;
31314 }
31315
31316
31317
31318 var Operations = Object.freeze({
31319         operationCircularize: operationCircularize,
31320         operationContinue: operationContinue,
31321         operationDelete: operationDelete,
31322         operationDisconnect: operationDisconnect,
31323         operationMerge: operationMerge,
31324         operationMove: operationMove,
31325         operationOrthogonalize: operationOrthogonalize,
31326         operationReflectShort: operationReflectShort,
31327         operationReflectLong: operationReflectLong,
31328         operationReverse: operationReverse,
31329         operationRotate: operationRotate,
31330         operationSplit: operationSplit,
31331         operationStraighten: operationStraighten
31332 });
31333
31334 function modeMove(context, entityIDs, baseGraph) {
31335     var mode = {
31336         id: 'move',
31337         button: 'browse'
31338     };
31339
31340     var keybinding = d3keybinding('move'),
31341         behaviors = [
31342             behaviorEdit(context),
31343             operationCircularize(entityIDs, context).behavior,
31344             operationDelete(entityIDs, context).behavior,
31345             operationOrthogonalize(entityIDs, context).behavior,
31346             operationReflectLong(entityIDs, context).behavior,
31347             operationReflectShort(entityIDs, context).behavior,
31348             operationRotate(entityIDs, context).behavior
31349         ],
31350         annotation = entityIDs.length === 1 ?
31351             t('operations.move.annotation.' + context.geometry(entityIDs[0])) :
31352             t('operations.move.annotation.multiple'),
31353         prevGraph,
31354         cache,
31355         origin,
31356         nudgeInterval;
31357
31358
31359     function vecSub(a, b) {
31360         return [a[0] - b[0], a[1] - b[1]];
31361     }
31362
31363
31364     function edge(point, size) {
31365         var pad = [80, 20, 50, 20],   // top, right, bottom, left
31366             x = 0,
31367             y = 0;
31368
31369         if (point[0] > size[0] - pad[1])
31370             x = -10;
31371         if (point[0] < pad[3])
31372             x = 10;
31373         if (point[1] > size[1] - pad[2])
31374             y = -10;
31375         if (point[1] < pad[0])
31376             y = 10;
31377
31378         if (x || y) {
31379             return [x, y];
31380         } else {
31381             return null;
31382         }
31383     }
31384
31385
31386     function doMove(nudge) {
31387         nudge = nudge || [0, 0];
31388
31389         var fn;
31390         if (prevGraph !== context.graph()) {
31391             cache = {};
31392             origin = context.map().mouseCoordinates();
31393             fn = context.perform;
31394         } else {
31395             fn = context.overwrite;
31396         }
31397
31398         var currMouse = context.mouse(),
31399             origMouse = context.projection(origin),
31400             delta = vecSub(vecSub(currMouse, origMouse), nudge);
31401
31402         fn(actionMove(entityIDs, delta, context.projection, cache), annotation);
31403         prevGraph = context.graph();
31404     }
31405
31406
31407     function startNudge(nudge) {
31408         if (nudgeInterval) window.clearInterval(nudgeInterval);
31409         nudgeInterval = window.setInterval(function() {
31410             context.pan(nudge);
31411             doMove(nudge);
31412         }, 50);
31413     }
31414
31415
31416     function stopNudge() {
31417         if (nudgeInterval) {
31418             window.clearInterval(nudgeInterval);
31419             nudgeInterval = null;
31420         }
31421     }
31422
31423
31424     function move() {
31425         doMove();
31426         var nudge = edge(context.mouse(), context.map().dimensions());
31427         if (nudge) {
31428             startNudge(nudge);
31429         } else {
31430             stopNudge();
31431         }
31432     }
31433
31434
31435     function finish() {
31436         event.stopPropagation();
31437         context.enter(modeSelect(context, entityIDs));
31438         stopNudge();
31439     }
31440
31441
31442     function cancel() {
31443         if (baseGraph) {
31444             while (context.graph() !== baseGraph) context.pop();
31445             context.enter(modeBrowse(context));
31446         } else {
31447             context.pop();
31448             context.enter(modeSelect(context, entityIDs));
31449         }
31450         stopNudge();
31451     }
31452
31453
31454     function undone() {
31455         context.enter(modeBrowse(context));
31456     }
31457
31458
31459     mode.enter = function() {
31460         origin = context.map().mouseCoordinates();
31461         prevGraph = null;
31462         cache = {};
31463
31464         behaviors.forEach(function(behavior) {
31465             context.install(behavior);
31466         });
31467
31468         context.surface()
31469             .on('mousemove.move', move)
31470             .on('click.move', finish);
31471
31472         context.history()
31473             .on('undone.move', undone);
31474
31475         keybinding
31476             .on('⎋', cancel)
31477             .on('↩', finish);
31478
31479         d3_select(document)
31480             .call(keybinding);
31481     };
31482
31483
31484     mode.exit = function() {
31485         stopNudge();
31486
31487         behaviors.forEach(function(behavior) {
31488             context.uninstall(behavior);
31489         });
31490
31491         context.surface()
31492             .on('mousemove.move', null)
31493             .on('click.move', null);
31494
31495         context.history()
31496             .on('undone.move', null);
31497
31498         keybinding.off();
31499     };
31500
31501
31502     return mode;
31503 }
31504
31505 function modeRotate(context, entityIDs) {
31506     var mode = {
31507         id: 'rotate',
31508         button: 'browse'
31509     };
31510
31511     var keybinding = d3keybinding('rotate'),
31512         behaviors = [
31513             behaviorEdit(context),
31514             operationCircularize(entityIDs, context).behavior,
31515             operationDelete(entityIDs, context).behavior,
31516             operationMove(entityIDs, context).behavior,
31517             operationOrthogonalize(entityIDs, context).behavior,
31518             operationReflectLong(entityIDs, context).behavior,
31519             operationReflectShort(entityIDs, context).behavior
31520         ],
31521         annotation = entityIDs.length === 1 ?
31522             t('operations.rotate.annotation.' + context.geometry(entityIDs[0])) :
31523             t('operations.rotate.annotation.multiple'),
31524         prevGraph,
31525         prevAngle,
31526         prevTransform,
31527         pivot;
31528
31529
31530     function doRotate() {
31531         var fn;
31532         if (context.graph() !== prevGraph) {
31533             fn = context.perform;
31534         } else {
31535             fn = context.replace;
31536         }
31537
31538         // projection changed, recalculate pivot
31539         var projection = context.projection;
31540         var currTransform = projection.transform();
31541         if (!prevTransform ||
31542             currTransform.k !== prevTransform.k ||
31543             currTransform.x !== prevTransform.x ||
31544             currTransform.y !== prevTransform.y) {
31545
31546             var nodes = utilGetAllNodes(entityIDs, context.graph()),
31547                 points = nodes.map(function(n) { return projection(n.loc); });
31548
31549             if (points.length === 1) {  // degenerate case
31550                 pivot = points[0];
31551             } else if (points.length === 2) {
31552                 pivot = geoInterp(points[0], points[1], 0.5);
31553             } else {
31554                 pivot = d3_polygonCentroid(d3_polygonHull(points));
31555             }
31556             prevAngle = undefined;
31557         }
31558
31559
31560         var currMouse = context.mouse(),
31561             currAngle = Math.atan2(currMouse[1] - pivot[1], currMouse[0] - pivot[0]);
31562
31563         if (typeof prevAngle === 'undefined') prevAngle = currAngle;
31564         var delta = currAngle - prevAngle;
31565
31566         fn(actionRotate(entityIDs, pivot, delta, projection), annotation);
31567
31568         prevTransform = currTransform;
31569         prevAngle = currAngle;
31570         prevGraph = context.graph();
31571     }
31572
31573
31574     function finish() {
31575         event.stopPropagation();
31576         context.enter(modeSelect(context, entityIDs));
31577     }
31578
31579
31580     function cancel() {
31581         context.pop();
31582         context.enter(modeSelect(context, entityIDs));
31583     }
31584
31585
31586     function undone() {
31587         context.enter(modeBrowse(context));
31588     }
31589
31590
31591     mode.enter = function() {
31592         behaviors.forEach(function(behavior) {
31593             context.install(behavior);
31594         });
31595
31596         context.surface()
31597             .on('mousemove.rotate', doRotate)
31598             .on('click.rotate', finish);
31599
31600         context.history()
31601             .on('undone.rotate', undone);
31602
31603         keybinding
31604             .on('⎋', cancel)
31605             .on('↩', finish);
31606
31607         d3_select(document)
31608             .call(keybinding);
31609     };
31610
31611
31612     mode.exit = function() {
31613         behaviors.forEach(function(behavior) {
31614             context.uninstall(behavior);
31615         });
31616
31617         context.surface()
31618             .on('mousemove.rotate', null)
31619             .on('click.rotate', null);
31620
31621         context.history()
31622             .on('undone.rotate', null);
31623
31624         keybinding.off();
31625     };
31626
31627
31628     return mode;
31629 }
31630
31631 /**
31632  * The base implementation of `_.reduce` and `_.reduceRight`, without support
31633  * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
31634  *
31635  * @private
31636  * @param {Array|Object} collection The collection to iterate over.
31637  * @param {Function} iteratee The function invoked per iteration.
31638  * @param {*} accumulator The initial value.
31639  * @param {boolean} initAccum Specify using the first or last element of
31640  *  `collection` as the initial value.
31641  * @param {Function} eachFunc The function to iterate over `collection`.
31642  * @returns {*} Returns the accumulated value.
31643  */
31644 function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {
31645   eachFunc(collection, function(value, index, collection) {
31646     accumulator = initAccum
31647       ? (initAccum = false, value)
31648       : iteratee(accumulator, value, index, collection);
31649   });
31650   return accumulator;
31651 }
31652
31653 /**
31654  * Reduces `collection` to a value which is the accumulated result of running
31655  * each element in `collection` thru `iteratee`, where each successive
31656  * invocation is supplied the return value of the previous. If `accumulator`
31657  * is not given, the first element of `collection` is used as the initial
31658  * value. The iteratee is invoked with four arguments:
31659  * (accumulator, value, index|key, collection).
31660  *
31661  * Many lodash methods are guarded to work as iteratees for methods like
31662  * `_.reduce`, `_.reduceRight`, and `_.transform`.
31663  *
31664  * The guarded methods are:
31665  * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
31666  * and `sortBy`
31667  *
31668  * @static
31669  * @memberOf _
31670  * @since 0.1.0
31671  * @category Collection
31672  * @param {Array|Object} collection The collection to iterate over.
31673  * @param {Function} [iteratee=_.identity] The function invoked per iteration.
31674  * @param {*} [accumulator] The initial value.
31675  * @returns {*} Returns the accumulated value.
31676  * @see _.reduceRight
31677  * @example
31678  *
31679  * _.reduce([1, 2], function(sum, n) {
31680  *   return sum + n;
31681  * }, 0);
31682  * // => 3
31683  *
31684  * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
31685  *   (result[value] || (result[value] = [])).push(key);
31686  *   return result;
31687  * }, {});
31688  * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
31689  */
31690 function reduce(collection, iteratee, accumulator) {
31691   var func = isArray(collection) ? arrayReduce : baseReduce,
31692       initAccum = arguments.length < 3;
31693
31694   return func(collection, baseIteratee(iteratee, 4), accumulator, initAccum, baseEach);
31695 }
31696
31697 function modeSave(context) {
31698     var mode = {
31699         id: 'save'
31700     };
31701
31702     var keybinding = d3keybinding('select');
31703
31704     var commit = uiCommit(context)
31705         .on('cancel', cancel)
31706         .on('save', save);
31707
31708
31709     function cancel(selectedID) {
31710         if (selectedID) {
31711             context.enter(modeSelect(context, [selectedID]));
31712         } else {
31713             context.enter(modeBrowse(context));
31714         }
31715     }
31716
31717
31718     function save(changeset, tryAgain) {
31719
31720         var osm = context.connection(),
31721             loading = uiLoading(context).message(t('save.uploading')).blocking(true),
31722             history = context.history(),
31723             origChanges = history.changes(actionDiscardTags(history.difference())),
31724             localGraph = context.graph(),
31725             remoteGraph = coreGraph(history.base(), true),
31726             modified = filter(history.difference().summary(), {changeType: 'modified'}),
31727             toCheck = map$4(map$4(modified, 'entity'), 'id'),
31728             toLoad = withChildNodes(toCheck, localGraph),
31729             conflicts = [],
31730             errors = [];
31731
31732         if (!osm) return;
31733
31734         if (!tryAgain) {
31735             history.perform(actionNoop());  // checkpoint
31736         }
31737
31738         context.container().call(loading);
31739
31740         if (toCheck.length) {
31741             osm.loadMultiple(toLoad, loaded);
31742         } else {
31743             upload();
31744         }
31745
31746
31747         function withChildNodes(ids, graph) {
31748             return uniq(reduce(ids, function(result, id) {
31749                 var entity = graph.entity(id);
31750                 if (entity.type === 'way') {
31751                     try {
31752                         var cn = graph.childNodes(entity);
31753                         result.push.apply(result, map$4(filter(cn, 'version'), 'id'));
31754                     } catch (err) {
31755                         /* eslint-disable no-console */
31756                         if (typeof console !== 'undefined') console.error(err);
31757                         /* eslint-enable no-console */
31758                     }
31759                 }
31760                 return result;
31761             }, clone(ids)));
31762         }
31763
31764
31765         // Reload modified entities into an alternate graph and check for conflicts..
31766         function loaded(err, result) {
31767             if (errors.length) return;
31768
31769             if (err) {
31770                 errors.push({
31771                     msg: err.responseText,
31772                     details: [ t('save.status_code', { code: err.status }) ]
31773                 });
31774                 showErrors();
31775
31776             } else {
31777                 var loadMore = [];
31778                 forEach(result.data, function(entity) {
31779                     remoteGraph.replace(entity);
31780                     toLoad = without(toLoad, entity.id);
31781
31782                     // Because loadMultiple doesn't download /full like loadEntity,
31783                     // need to also load children that aren't already being checked..
31784                     if (!entity.visible) return;
31785                     if (entity.type === 'way') {
31786                         loadMore.push.apply(loadMore,
31787                             difference(entity.nodes, toCheck, toLoad, loadMore));
31788                     } else if (entity.type === 'relation' && entity.isMultipolygon()) {
31789                         loadMore.push.apply(loadMore,
31790                             difference(map$4(entity.members, 'id'), toCheck, toLoad, loadMore));
31791                     }
31792                 });
31793
31794                 if (loadMore.length) {
31795                     toLoad.push.apply(toLoad, loadMore);
31796                     osm.loadMultiple(loadMore, loaded);
31797                 }
31798
31799                 if (!toLoad.length) {
31800                     checkConflicts();
31801                 }
31802             }
31803         }
31804
31805
31806         function checkConflicts() {
31807             function choice(id, text, action) {
31808                 return { id: id, text: text, action: function() { history.replace(action); } };
31809             }
31810             function formatUser(d) {
31811                 return '<a href="' + osm.userURL(d) + '" target="_blank">' + d + '</a>';
31812             }
31813             function entityName(entity) {
31814                 return utilDisplayName(entity) || (utilDisplayType(entity.id) + ' ' + entity.id);
31815             }
31816
31817             function compareVersions(local, remote) {
31818                 if (local.version !== remote.version) return false;
31819
31820                 if (local.type === 'way') {
31821                     var children = union(local.nodes, remote.nodes);
31822
31823                     for (var i = 0; i < children.length; i++) {
31824                         var a = localGraph.hasEntity(children[i]),
31825                             b = remoteGraph.hasEntity(children[i]);
31826
31827                         if (a && b && a.version !== b.version) return false;
31828                     }
31829                 }
31830
31831                 return true;
31832             }
31833
31834             forEach(toCheck, function(id) {
31835                 var local = localGraph.entity(id),
31836                     remote = remoteGraph.entity(id);
31837
31838                 if (compareVersions(local, remote)) return;
31839
31840                 var action = actionMergeRemoteChanges,
31841                     merge = action(id, localGraph, remoteGraph, formatUser);
31842
31843                 history.replace(merge);
31844
31845                 var mergeConflicts = merge.conflicts();
31846                 if (!mergeConflicts.length) return;  // merged safely
31847
31848                 var forceLocal = action(id, localGraph, remoteGraph).withOption('force_local'),
31849                     forceRemote = action(id, localGraph, remoteGraph).withOption('force_remote'),
31850                     keepMine = t('save.conflict.' + (remote.visible ? 'keep_local' : 'restore')),
31851                     keepTheirs = t('save.conflict.' + (remote.visible ? 'keep_remote' : 'delete'));
31852
31853                 conflicts.push({
31854                     id: id,
31855                     name: entityName(local),
31856                     details: mergeConflicts,
31857                     chosen: 1,
31858                     choices: [
31859                         choice(id, keepMine, forceLocal),
31860                         choice(id, keepTheirs, forceRemote)
31861                     ]
31862                 });
31863             });
31864
31865             upload();
31866         }
31867
31868
31869         function upload() {
31870             if (conflicts.length) {
31871                 conflicts.sort(function(a,b) { return b.id.localeCompare(a.id); });
31872                 showConflicts();
31873             } else if (errors.length) {
31874                 showErrors();
31875             } else {
31876                 var changes = history.changes(actionDiscardTags(history.difference()));
31877                 if (changes.modified.length || changes.created.length || changes.deleted.length) {
31878                     osm.putChangeset(changeset, changes, uploadCallback);
31879                 } else {        // changes were insignificant or reverted by user
31880                     d3_select('.inspector-wrap *').remove();
31881                     loading.close();
31882                     context.flush();
31883                     cancel();
31884                 }
31885             }
31886         }
31887
31888
31889         function uploadCallback(err, changeset) {
31890             if (err) {
31891                 errors.push({
31892                     msg: err.responseText,
31893                     details: [ t('save.status_code', { code: err.status }) ]
31894                 });
31895                 showErrors();
31896             } else {
31897                 history.clearSaved();
31898                 success(changeset);
31899                 // Add delay to allow for postgres replication #1646 #2678
31900                 window.setTimeout(function() {
31901                     d3_select('.inspector-wrap *').remove();
31902                     loading.close();
31903                     context.flush();
31904                 }, 2500);
31905             }
31906         }
31907
31908
31909         function showConflicts() {
31910             var selection = context.container()
31911                 .select('#sidebar')
31912                 .append('div')
31913                 .attr('class','sidebar-component');
31914
31915             loading.close();
31916
31917             selection.call(uiConflicts(context)
31918                 .list(conflicts)
31919                 .origChanges(origChanges)
31920                 .on('cancel', function() {
31921                     history.pop();
31922                     selection.remove();
31923                 })
31924                 .on('save', function() {
31925                     for (var i = 0; i < conflicts.length; i++) {
31926                         if (conflicts[i].chosen === 1) {  // user chose "keep theirs"
31927                             var entity = context.hasEntity(conflicts[i].id);
31928                             if (entity && entity.type === 'way') {
31929                                 var children = uniq(entity.nodes);
31930                                 for (var j = 0; j < children.length; j++) {
31931                                     history.replace(actionRevert(children[j]));
31932                                 }
31933                             }
31934                             history.replace(actionRevert(conflicts[i].id));
31935                         }
31936                     }
31937
31938                     selection.remove();
31939                     save(changeset, true);
31940                 })
31941             );
31942         }
31943
31944
31945         function showErrors() {
31946             var selection = uiConfirm(context.container());
31947
31948             history.pop();
31949             loading.close();
31950
31951             selection
31952                 .select('.modal-section.header')
31953                 .append('h3')
31954                 .text(t('save.error'));
31955
31956             addErrors(selection, errors);
31957             selection.okButton();
31958         }
31959
31960
31961         function addErrors(selection, data) {
31962             var message = selection
31963                 .select('.modal-section.message-text');
31964
31965             var items = message
31966                 .selectAll('.error-container')
31967                 .data(data);
31968
31969             var enter = items.enter()
31970                 .append('div')
31971                 .attr('class', 'error-container');
31972
31973             enter
31974                 .append('a')
31975                 .attr('class', 'error-description')
31976                 .attr('href', '#')
31977                 .classed('hide-toggle', true)
31978                 .text(function(d) { return d.msg || t('save.unknown_error_details'); })
31979                 .on('click', function() {
31980                     var error = d3_select(this),
31981                         detail = d3_select(this.nextElementSibling),
31982                         exp = error.classed('expanded');
31983
31984                     detail.style('display', exp ? 'none' : 'block');
31985                     error.classed('expanded', !exp);
31986
31987                     event.preventDefault();
31988                 });
31989
31990             var details = enter
31991                 .append('div')
31992                 .attr('class', 'error-detail-container')
31993                 .style('display', 'none');
31994
31995             details
31996                 .append('ul')
31997                 .attr('class', 'error-detail-list')
31998                 .selectAll('li')
31999                 .data(function(d) { return d.details || []; })
32000                 .enter()
32001                 .append('li')
32002                 .attr('class', 'error-detail-item')
32003                 .text(function(d) { return d; });
32004
32005             items.exit()
32006                 .remove();
32007         }
32008
32009     }
32010
32011
32012     function success(changeset) {
32013         commit.reset();
32014         context.enter(modeBrowse(context)
32015             .sidebar(uiSuccess(context)
32016                 .changeset(changeset)
32017                 .on('cancel', function() {
32018                     context.ui().sidebar.hide();
32019                 })
32020             )
32021         );
32022     }
32023
32024
32025     mode.enter = function() {
32026         function done() {
32027             context.ui().sidebar.show(commit);
32028         }
32029
32030         keybinding
32031             .on('⎋', cancel, true);
32032
32033         d3_select(document)
32034             .call(keybinding);
32035
32036         context.container().selectAll('#content')
32037             .attr('class', 'inactive');
32038
32039         var osm = context.connection();
32040         if (!osm) return;
32041
32042         if (osm.authenticated()) {
32043             done();
32044         } else {
32045             osm.authenticate(function(err) {
32046                 if (err) {
32047                     cancel();
32048                 } else {
32049                     done();
32050                 }
32051             });
32052         }
32053     };
32054
32055
32056     mode.exit = function() {
32057         keybinding.off();
32058
32059         context.container().selectAll('#content')
32060             .attr('class', 'active');
32061
32062         context.ui().sidebar.hide();
32063     };
32064
32065     return mode;
32066 }
32067
32068 /* Built-in method references for those with the same name as other `lodash` methods. */
32069 var nativeMin$1 = Math.min;
32070
32071 /**
32072  * The base implementation of methods like `_.intersection`, without support
32073  * for iteratee shorthands, that accepts an array of arrays to inspect.
32074  *
32075  * @private
32076  * @param {Array} arrays The arrays to inspect.
32077  * @param {Function} [iteratee] The iteratee invoked per element.
32078  * @param {Function} [comparator] The comparator invoked per element.
32079  * @returns {Array} Returns the new array of shared values.
32080  */
32081 function baseIntersection(arrays, iteratee, comparator) {
32082   var includes = comparator ? arrayIncludesWith : arrayIncludes,
32083       length = arrays[0].length,
32084       othLength = arrays.length,
32085       othIndex = othLength,
32086       caches = Array(othLength),
32087       maxLength = Infinity,
32088       result = [];
32089
32090   while (othIndex--) {
32091     var array = arrays[othIndex];
32092     if (othIndex && iteratee) {
32093       array = arrayMap(array, baseUnary(iteratee));
32094     }
32095     maxLength = nativeMin$1(array.length, maxLength);
32096     caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120))
32097       ? new SetCache(othIndex && array)
32098       : undefined;
32099   }
32100   array = arrays[0];
32101
32102   var index = -1,
32103       seen = caches[0];
32104
32105   outer:
32106   while (++index < length && result.length < maxLength) {
32107     var value = array[index],
32108         computed = iteratee ? iteratee(value) : value;
32109
32110     value = (comparator || value !== 0) ? value : 0;
32111     if (!(seen
32112           ? cacheHas(seen, computed)
32113           : includes(result, computed, comparator)
32114         )) {
32115       othIndex = othLength;
32116       while (--othIndex) {
32117         var cache = caches[othIndex];
32118         if (!(cache
32119               ? cacheHas(cache, computed)
32120               : includes(arrays[othIndex], computed, comparator))
32121             ) {
32122           continue outer;
32123         }
32124       }
32125       if (seen) {
32126         seen.push(computed);
32127       }
32128       result.push(value);
32129     }
32130   }
32131   return result;
32132 }
32133
32134 /**
32135  * Casts `value` to an empty array if it's not an array like object.
32136  *
32137  * @private
32138  * @param {*} value The value to inspect.
32139  * @returns {Array|Object} Returns the cast array-like object.
32140  */
32141 function castArrayLikeObject(value) {
32142   return isArrayLikeObject(value) ? value : [];
32143 }
32144
32145 /**
32146  * Creates an array of unique values that are included in all given arrays
32147  * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
32148  * for equality comparisons. The order and references of result values are
32149  * determined by the first array.
32150  *
32151  * @static
32152  * @memberOf _
32153  * @since 0.1.0
32154  * @category Array
32155  * @param {...Array} [arrays] The arrays to inspect.
32156  * @returns {Array} Returns the new array of intersecting values.
32157  * @example
32158  *
32159  * _.intersection([2, 1], [2, 3]);
32160  * // => [2]
32161  */
32162 var intersection = baseRest(function(arrays) {
32163   var mapped = arrayMap(arrays, castArrayLikeObject);
32164   return (mapped.length && mapped[0] === arrays[0])
32165     ? baseIntersection(mapped)
32166     : [];
32167 });
32168
32169 // Translate a MacOS key command into the appropriate Windows/Linux equivalent.
32170 // For example, ⌘Z -> Ctrl+Z
32171 var uiCmd = function (code) {
32172     var detected = utilDetect();
32173
32174     if (detected.os === 'mac') {
32175         return code;
32176     }
32177
32178     if (detected.os === 'win') {
32179         if (code === '⌘⇧Z') return 'Ctrl+Y';
32180     }
32181
32182     var result = '',
32183         replacements = {
32184             '⌘': 'Ctrl',
32185             '⇧': 'Shift',
32186             '⌥': 'Alt',
32187             '⌫': 'Backspace',
32188             '⌦': 'Delete'
32189         };
32190
32191     for (var i = 0; i < code.length; i++) {
32192         if (code[i] in replacements) {
32193             result += replacements[code[i]] + (i < code.length - 1 ? '+' : '');
32194         } else {
32195             result += code[i];
32196         }
32197     }
32198
32199     return result;
32200 };
32201
32202
32203 // return a display-focused string for a given keyboard code
32204 uiCmd.display = function(code) {
32205     if (code.length !== 1) return code;
32206
32207     var detected = utilDetect();
32208     var mac = (detected.os === 'mac');
32209     var replacements = {
32210         '⌘': mac ? '⌘ ' + t('shortcuts.key.cmd')    : t('shortcuts.key.ctrl'),
32211         '⇧': mac ? '⇧ ' + t('shortcuts.key.shift')  : t('shortcuts.key.shift'),
32212         '⌥': mac ? '⌥ ' + t('shortcuts.key.option') : t('shortcuts.key.alt'),
32213         '⌃': mac ? '⌃ ' + t('shortcuts.key.ctrl')   : t('shortcuts.key.ctrl'),
32214         '⌫': mac ? '⌫ ' + t('shortcuts.key.delete') : t('shortcuts.key.backspace'),
32215         '⌦': mac ? '⌦ ' + t('shortcuts.key.del')    : t('shortcuts.key.del'),
32216         '↖': mac ? '↖ ' + t('shortcuts.key.pgup')   : t('shortcuts.key.pgup'),
32217         '↘': mac ? '↘ ' + t('shortcuts.key.pgdn')   : t('shortcuts.key.pgdn'),
32218         '⇞': mac ? '⇞ ' + t('shortcuts.key.home')   : t('shortcuts.key.home'),
32219         '⇟': mac ? '⇟ ' + t('shortcuts.key.end')    : t('shortcuts.key.end'),
32220         '↵': mac ? '↵ ' + t('shortcuts.key.return') : t('shortcuts.key.enter'),
32221         '⎋': mac ? '⎋ ' + t('shortcuts.key.esc')    : t('shortcuts.key.esc'),
32222     };
32223
32224     return replacements[code] || code;
32225 };
32226
32227 // deprecation warning - Radial Menu to be removed in iD v3
32228 var relatedParent;
32229
32230
32231 function modeSelect(context, selectedIDs) {
32232     var mode = {
32233         id: 'select',
32234         button: 'browse'
32235     };
32236
32237     var keybinding = d3keybinding('select'),
32238         timeout = null,
32239         behaviors = [
32240             behaviorCopy(context),
32241             behaviorPaste(context),
32242             behaviorBreathe(context),
32243             behaviorHover(context),
32244             behaviorSelect(context),
32245             behaviorLasso(context),
32246             modeDragNode(context).selectedIDs(selectedIDs).behavior
32247         ],
32248         inspector,
32249         editMenu,
32250         newFeature = false,
32251         suppressMenu = true,
32252         follow = false;
32253
32254
32255     var wrap = context.container()
32256         .select('.inspector-wrap');
32257
32258
32259     function singular() {
32260         if (selectedIDs.length === 1) {
32261             return context.hasEntity(selectedIDs[0]);
32262         }
32263     }
32264
32265
32266     function checkSelectedIDs() {
32267         var ids = [];
32268         if (Array.isArray(selectedIDs)) {
32269             ids = selectedIDs.filter(function(id) {
32270                 return context.hasEntity(id);
32271             });
32272         }
32273
32274         if (ids.length) {
32275             selectedIDs = ids;
32276         } else {
32277             context.enter(modeBrowse(context));
32278         }
32279         return !!ids.length;
32280     }
32281
32282
32283     // find the common parent ways for nextVertex, previousVertex
32284     function commonParents() {
32285         var graph = context.graph(),
32286             commonParents = [];
32287
32288         for (var i = 0; i < selectedIDs.length; i++) {
32289             var entity = context.hasEntity(selectedIDs[i]);
32290             if (!entity || entity.geometry(graph) !== 'vertex') {
32291                 return [];  // selection includes some not vertexes
32292             }
32293
32294             var currParents = map$4(graph.parentWays(entity), 'id');
32295             if (!commonParents.length) {
32296                 commonParents = currParents;
32297                 continue;
32298             }
32299
32300             commonParents = intersection(commonParents, currParents);
32301             if (!commonParents.length) {
32302                 return [];
32303             }
32304         }
32305
32306         return commonParents;
32307     }
32308
32309
32310     function singularParent() {
32311         var parents = commonParents();
32312         if (!parents || parents.length === 0) {
32313             relatedParent = null;
32314             return null;
32315         }
32316
32317         // relatedParent is used when we visit a vertex with multiple
32318         // parents, and we want to remember which parent line we started on.
32319
32320         if (parents.length === 1) {
32321             relatedParent = parents[0];  // remember this parent for later
32322             return relatedParent;
32323         }
32324
32325         if (parents.indexOf(relatedParent) !== -1) {
32326             return relatedParent;   // prefer the previously seen parent
32327         }
32328
32329         return parents[0];
32330     }
32331
32332
32333     function closeMenu() {
32334         if (editMenu) {
32335             context.surface().call(editMenu.close);
32336         }
32337     }
32338
32339
32340     function positionMenu() {
32341         if (!editMenu) { return; }
32342
32343         var entity = singular();
32344         if (entity && context.geometry(entity.id) === 'relation') {
32345             suppressMenu = true;
32346         } else {
32347             var point = context.mouse(),
32348                 viewport = geoExtent(context.projection.clipExtent()).polygon();
32349
32350             if (point && geoPointInPolygon(point, viewport)) {
32351                 editMenu.center(point);
32352             } else {
32353                 suppressMenu = true;
32354             }
32355         }
32356     }
32357
32358
32359     function showMenu() {
32360         closeMenu();
32361         if (editMenu) {
32362             context.surface().call(editMenu);
32363         }
32364     }
32365
32366
32367     function toggleMenu() {
32368         // deprecation warning - Radial Menu to be removed in iD v3
32369         if (d3_select('.edit-menu, .radial-menu').empty()) {
32370             positionMenu();
32371             showMenu();
32372         } else {
32373             closeMenu();
32374         }
32375     }
32376
32377
32378     mode.selectedIDs = function() {
32379         return selectedIDs;
32380     };
32381
32382
32383     mode.reselect = function() {
32384         if (!checkSelectedIDs()) return;
32385
32386         var surfaceNode = context.surface().node();
32387         if (surfaceNode.focus) {   // FF doesn't support it
32388             surfaceNode.focus();
32389         }
32390
32391         positionMenu();
32392         if (!suppressMenu) {
32393             showMenu();
32394         }
32395     };
32396
32397
32398     mode.newFeature = function(_) {
32399         if (!arguments.length) return newFeature;
32400         newFeature = _;
32401         return mode;
32402     };
32403
32404
32405     mode.suppressMenu = function(_) {
32406         if (!arguments.length) return suppressMenu;
32407         suppressMenu = _;
32408         return mode;
32409     };
32410
32411
32412     mode.follow = function(_) {
32413         if (!arguments.length) return follow;
32414         follow = _;
32415         return mode;
32416     };
32417
32418
32419     mode.enter = function() {
32420
32421         function update() {
32422             closeMenu();
32423             checkSelectedIDs();
32424         }
32425
32426
32427         function dblclick() {
32428             var target = d3_select(event.target),
32429                 datum = target.datum();
32430
32431             if (datum instanceof osmWay && !target.classed('fill')) {
32432                 var choice = geoChooseEdge(context.childNodes(datum), context.mouse(), context.projection),
32433                     prev = datum.nodes[choice.index - 1],
32434                     next = datum.nodes[choice.index];
32435
32436                 context.perform(
32437                     actionAddMidpoint({loc: choice.loc, edge: [prev, next]}, osmNode()),
32438                     t('operations.add.annotation.vertex')
32439                 );
32440
32441                 event.preventDefault();
32442                 event.stopPropagation();
32443
32444             } else if (datum.type === 'midpoint') {
32445                 context.perform(
32446                     actionAddMidpoint({loc: datum.loc, edge: datum.edge}, osmNode()),
32447                     t('operations.add.annotation.vertex'));
32448
32449                 event.preventDefault();
32450                 event.stopPropagation();
32451             }
32452         }
32453
32454
32455         function selectElements(drawn) {
32456             if (!checkSelectedIDs()) return;
32457
32458             var surface = context.surface(),
32459                 entity = singular();
32460
32461             if (entity && context.geometry(entity.id) === 'relation') {
32462                 suppressMenu = true;
32463                 return;
32464             }
32465
32466             surface.selectAll('.related')
32467                 .classed('related', false);
32468
32469             singularParent();
32470             if (relatedParent) {
32471                 surface.selectAll(utilEntitySelector([relatedParent]))
32472                     .classed('related', true);
32473             }
32474
32475             var selection = context.surface()
32476                 .selectAll(utilEntityOrMemberSelector(selectedIDs, context.graph()));
32477
32478             if (selection.empty()) {
32479                 // Return to browse mode if selected DOM elements have
32480                 // disappeared because the user moved them out of view..
32481                 var source = event && event.type === 'zoom' && event.sourceEvent;
32482                 if (drawn && source && (source.type === 'mousemove' || source.type === 'touchmove')) {
32483                     context.enter(modeBrowse(context));
32484                 }
32485             } else {
32486                 selection
32487                     .classed('selected', true);
32488             }
32489         }
32490
32491
32492         function esc() {
32493             context.enter(modeBrowse(context));
32494         }
32495
32496
32497         function firstVertex() {
32498             event.preventDefault();
32499             var parent = singularParent();
32500             if (parent) {
32501                 var way = context.entity(parent);
32502                 context.enter(
32503                     modeSelect(context, [way.first()]).follow(true)
32504                 );
32505             }
32506         }
32507
32508
32509         function lastVertex() {
32510             event.preventDefault();
32511             var parent = singularParent();
32512             if (parent) {
32513                 var way = context.entity(parent);
32514                 context.enter(
32515                     modeSelect(context, [way.last()]).follow(true)
32516                 );
32517             }
32518         }
32519
32520
32521         function previousVertex() {
32522             event.preventDefault();
32523             var parent = singularParent();
32524             if (!parent) return;
32525
32526             var way = context.entity(parent),
32527                 length = way.nodes.length,
32528                 curr = way.nodes.indexOf(selectedIDs[0]),
32529                 index = -1;
32530
32531             if (curr > 0) {
32532                 index = curr - 1;
32533             } else if (way.isClosed()) {
32534                 index = length - 2;
32535             }
32536
32537             if (index !== -1) {
32538                 context.enter(
32539                     modeSelect(context, [way.nodes[index]]).follow(true)
32540                 );
32541             }
32542         }
32543
32544
32545         function nextVertex() {
32546             event.preventDefault();
32547             var parent = singularParent();
32548             if (!parent) return;
32549
32550             var way = context.entity(parent),
32551                 length = way.nodes.length,
32552                 curr = way.nodes.indexOf(selectedIDs[0]),
32553                 index = -1;
32554
32555             if (curr < length - 1) {
32556                 index = curr + 1;
32557             } else if (way.isClosed()) {
32558                 index = 0;
32559             }
32560
32561             if (index !== -1) {
32562                 context.enter(
32563                     modeSelect(context, [way.nodes[index]]).follow(true)
32564                 );
32565             }
32566         }
32567
32568
32569         function nextParent() {
32570             event.preventDefault();
32571             var parents = uniq(commonParents());
32572             if (!parents || parents.length < 2) return;
32573
32574             var index = parents.indexOf(relatedParent);
32575             if (index < 0 || index > parents.length - 2) {
32576                 relatedParent = parents[0];
32577             } else {
32578                 relatedParent = parents[index + 1];
32579             }
32580
32581             var surface = context.surface();
32582             surface.selectAll('.related')
32583                 .classed('related', false);
32584
32585             if (relatedParent) {
32586                 surface.selectAll(utilEntitySelector([relatedParent]))
32587                     .classed('related', true);
32588             }
32589         }
32590
32591
32592         if (!checkSelectedIDs()) return;
32593
32594         var operations = without(values$1(Operations), operationDelete)
32595                 .map(function(o) { return o(selectedIDs, context); })
32596                 .filter(function(o) { return o.available(); });
32597
32598         // deprecation warning - Radial Menu to be removed in iD v3
32599         var isRadialMenu = context.storage('edit-menu-style') === 'radial';
32600         if (isRadialMenu) {
32601             operations = operations.slice(0,7);
32602             operations.unshift(operationDelete(selectedIDs, context));
32603         } else {
32604             operations.push(operationDelete(selectedIDs, context));
32605         }
32606
32607         operations.forEach(function(operation) {
32608             if (operation.behavior) {
32609                 behaviors.push(operation.behavior);
32610             }
32611         });
32612
32613         behaviors.forEach(function(behavior) {
32614             context.install(behavior);
32615         });
32616
32617         keybinding
32618             .on(['[', 'pgup'], previousVertex)
32619             .on([']', 'pgdown'], nextVertex)
32620             .on(['{', uiCmd('⌘['), 'home'], firstVertex)
32621             .on(['}', uiCmd('⌘]'), 'end'], lastVertex)
32622             .on(['\\', 'pause'], nextParent)
32623             .on('⎋', esc, true)
32624             .on('space', toggleMenu);
32625
32626         d3_select(document)
32627             .call(keybinding);
32628
32629
32630         // deprecation warning - Radial Menu to be removed in iD v3
32631         editMenu = isRadialMenu
32632             ? uiRadialMenu(context, operations)
32633             : uiEditMenu(context, operations);
32634
32635         context.ui().sidebar
32636             .select(singular() ? singular().id : null, newFeature);
32637
32638         context.history()
32639             .on('undone.select', update)
32640             .on('redone.select', update);
32641
32642         context.map()
32643             .on('move.select', closeMenu)
32644             .on('drawn.select', selectElements);
32645
32646         context.surface()
32647             .on('dblclick.select', dblclick);
32648
32649
32650         selectElements();
32651
32652         if (selectedIDs.length > 1) {
32653             var entities = uiSelectionList(context, selectedIDs);
32654             context.ui().sidebar.show(entities);
32655         }
32656
32657         if (follow) {
32658             var extent = geoExtent(),
32659                 graph = context.graph();
32660             selectedIDs.forEach(function(id) {
32661                 var entity = context.entity(id);
32662                 extent._extend(entity.extent(graph));
32663             });
32664
32665             var loc = extent.center();
32666             context.map().centerEase(loc);
32667         } else if (singular() && singular().type === 'way') {
32668             context.map().pan([0,0]);  // full redraw, to adjust z-sorting #2914
32669         }
32670
32671         timeout = window.setTimeout(function() {
32672             positionMenu();
32673             if (!suppressMenu) {
32674                 showMenu();
32675             }
32676         }, 270);  /* after any centerEase completes */
32677
32678     };
32679
32680
32681     mode.exit = function() {
32682         if (timeout) window.clearTimeout(timeout);
32683
32684         if (inspector) wrap.call(inspector.close);
32685
32686         behaviors.forEach(function(behavior) {
32687             context.uninstall(behavior);
32688         });
32689
32690         keybinding.off();
32691         closeMenu();
32692         editMenu = undefined;
32693
32694         context.history()
32695             .on('undone.select', null)
32696             .on('redone.select', null);
32697
32698         var surface = context.surface();
32699
32700         surface
32701             .on('dblclick.select', null);
32702
32703         surface
32704             .selectAll('.selected')
32705             .classed('selected', false);
32706
32707         surface
32708             .selectAll('.related')
32709             .classed('related', false);
32710
32711         context.map().on('drawn.select', null);
32712         context.ui().sidebar.hide();
32713     };
32714
32715
32716     return mode;
32717 }
32718
32719 function behaviorAddWay(context) {
32720     var dispatch$$1 = dispatch('start', 'startFromWay', 'startFromNode'),
32721         draw = behaviorDraw(context);
32722
32723     var addWay = function(surface) {
32724         draw.on('click', function() { dispatch$$1.apply('start', this, arguments); })
32725             .on('clickWay', function() { dispatch$$1.apply('startFromWay', this, arguments); })
32726             .on('clickNode', function() { dispatch$$1.apply('startFromNode', this, arguments); })
32727             .on('cancel', addWay.cancel)
32728             .on('finish', addWay.cancel);
32729
32730         context.map()
32731             .dblclickEnable(false);
32732
32733         surface.call(draw);
32734     };
32735
32736
32737     addWay.off = function(surface) {
32738         surface.call(draw.off);
32739     };
32740
32741
32742     addWay.cancel = function() {
32743         window.setTimeout(function() {
32744             context.map().dblclickEnable(true);
32745         }, 1000);
32746
32747         context.enter(modeBrowse(context));
32748     };
32749
32750
32751     addWay.tail = function(text) {
32752         draw.tail(text);
32753         return addWay;
32754     };
32755
32756
32757     return utilRebind(addWay, dispatch$$1, 'on');
32758 }
32759
32760 function behaviorBreathe() {
32761     var duration = 800,
32762         steps = 4,
32763         selector = '.selected.shadow, .selected .shadow',
32764         selected = d3_select(null),
32765         classed = '',
32766         params = {},
32767         done = false,
32768         timer$$1;
32769
32770
32771     function ratchetyInterpolator(a, b, steps, units) {
32772         a = parseFloat(a);
32773         b = parseFloat(b);
32774         var sample = quantize()
32775             .domain([0, 1])
32776             .range(d3_quantize(d3_interpolateNumber(a, b), steps));
32777
32778         return function(t) {
32779             return String(sample(t)) + (units || '');
32780         };
32781     }
32782
32783
32784     function reset(selection) {
32785         selection
32786             .style('stroke-opacity', null)
32787             .style('stroke-width', null)
32788             .style('fill-opacity', null)
32789             .style('r', null);
32790     }
32791
32792
32793     function setAnimationParams(transition, fromTo) {
32794         var toFrom = (fromTo === 'from' ? 'to' : 'from');
32795
32796         transition
32797             .styleTween('stroke-opacity', function(d) {
32798                 return ratchetyInterpolator(
32799                     params[d.id][toFrom].opacity,
32800                     params[d.id][fromTo].opacity,
32801                     steps
32802                 );
32803             })
32804             .styleTween('stroke-width', function(d) {
32805                 return ratchetyInterpolator(
32806                     params[d.id][toFrom].width,
32807                     params[d.id][fromTo].width,
32808                     steps,
32809                     'px'
32810                 );
32811             })
32812             .styleTween('fill-opacity', function(d) {
32813                 return ratchetyInterpolator(
32814                     params[d.id][toFrom].opacity,
32815                     params[d.id][fromTo].opacity,
32816                     steps
32817                 );
32818             })
32819             .styleTween('r', function(d) {
32820                 return ratchetyInterpolator(
32821                     params[d.id][toFrom].width,
32822                     params[d.id][fromTo].width,
32823                     steps,
32824                     'px'
32825                 );
32826             });
32827     }
32828
32829
32830     function calcAnimationParams(selection) {
32831         selection
32832             .call(reset)
32833             .each(function(d) {
32834                 var s = d3_select(this),
32835                     tag = s.node().tagName,
32836                     p = {'from': {}, 'to': {}},
32837                     opacity, width;
32838
32839                 // determine base opacity and width
32840                 if (tag === 'circle') {
32841                     opacity = parseFloat(s.style('fill-opacity') || 0.5);
32842                     width = parseFloat(s.style('r') || 15.5);
32843                 } else {
32844                     opacity = parseFloat(s.style('stroke-opacity') || 0.7);
32845                     width = parseFloat(s.style('stroke-width') || 10);
32846                 }
32847
32848                 // calculate from/to interpolation params..
32849                 p.tag = tag;
32850                 p.from.opacity = opacity * 0.6;
32851                 p.to.opacity = opacity * 1.25;
32852                 p.from.width = width * 0.7;
32853                 p.to.width = width * (tag === 'circle' ? 1.5 : 1);
32854                 params[d.id] = p;
32855             });
32856     }
32857
32858
32859     function run(surface, fromTo) {
32860         var toFrom = (fromTo === 'from' ? 'to' : 'from'),
32861             currSelected = surface.selectAll(selector),
32862             currClassed = surface.attr('class');
32863
32864         if (done || currSelected.empty()) {
32865             selected.call(reset);
32866             return;
32867         }
32868
32869         if (!isEqual(currSelected.data(), selected.data()) || currClassed !== classed) {
32870             selected.call(reset);
32871             classed = currClassed;
32872             selected = currSelected.call(calcAnimationParams);
32873         }
32874
32875         selected
32876             .transition()
32877             .duration(duration)
32878             .call(setAnimationParams, fromTo)
32879             .on('end', function() {
32880                 surface.call(run, toFrom);
32881             });
32882     }
32883
32884
32885     var breathe = function(surface) {
32886         done = false;
32887         timer$$1 = timer(function() {
32888             // wait for elements to actually become selected
32889             if (surface.selectAll(selector).empty()) {
32890                 return false;
32891             }
32892
32893             surface.call(run, 'from');
32894             timer$$1.stop();
32895             return true;
32896         }, 20);
32897     };
32898
32899
32900     breathe.off = function() {
32901         done = true;
32902         if (timer$$1) {
32903             timer$$1.stop();
32904         }
32905         selected
32906             .interrupt()
32907             .call(reset);
32908     };
32909
32910
32911     return breathe;
32912 }
32913
32914 function behaviorCopy(context) {
32915     var keybinding = d3keybinding('copy');
32916
32917
32918     function groupEntities(ids, graph) {
32919         var entities = ids.map(function (id) { return graph.entity(id); });
32920         return assignIn({relation: [], way: [], node: []},
32921             groupBy(entities, function(entity) { return entity.type; }));
32922     }
32923
32924
32925     function getDescendants(id, graph, descendants) {
32926         var entity = graph.entity(id),
32927             i, children;
32928
32929         descendants = descendants || {};
32930
32931         if (entity.type === 'relation') {
32932             children = map$4(entity.members, 'id');
32933         } else if (entity.type === 'way') {
32934             children = entity.nodes;
32935         } else {
32936             children = [];
32937         }
32938
32939         for (i = 0; i < children.length; i++) {
32940             if (!descendants[children[i]]) {
32941                 descendants[children[i]] = true;
32942                 descendants = getDescendants(children[i], graph, descendants);
32943             }
32944         }
32945
32946         return descendants;
32947     }
32948
32949
32950     function doCopy() {
32951         if (!getSelectionText()) event.preventDefault();
32952
32953         var graph = context.graph(),
32954             selected = groupEntities(context.selectedIDs(), graph),
32955             canCopy = [],
32956             skip = {},
32957             i, entity;
32958
32959         for (i = 0; i < selected.relation.length; i++) {
32960             entity = selected.relation[i];
32961             if (!skip[entity.id] && entity.isComplete(graph)) {
32962                 canCopy.push(entity.id);
32963                 skip = getDescendants(entity.id, graph, skip);
32964             }
32965         }
32966         for (i = 0; i < selected.way.length; i++) {
32967             entity = selected.way[i];
32968             if (!skip[entity.id]) {
32969                 canCopy.push(entity.id);
32970                 skip = getDescendants(entity.id, graph, skip);
32971             }
32972         }
32973         for (i = 0; i < selected.node.length; i++) {
32974             entity = selected.node[i];
32975             if (!skip[entity.id]) {
32976                 canCopy.push(entity.id);
32977             }
32978         }
32979
32980         context.copyIDs(canCopy);
32981     }
32982
32983
32984     function copy() {
32985         keybinding.on(uiCmd('⌘C'), doCopy);
32986         d3_select(document).call(keybinding);
32987         return copy;
32988     }
32989
32990     function getSelectionText() {
32991         return window.getSelection().toString();
32992     }
32993
32994     copy.off = function() {
32995         d3_select(document).call(keybinding.off);
32996     };
32997
32998
32999     return copy;
33000 }
33001
33002 /*
33003     `behaviorDrag` is like `d3_behavior.drag`, with the following differences:
33004
33005     * The `origin` function is expected to return an [x, y] tuple rather than an
33006       {x, y} object.
33007     * The events are `start`, `move`, and `end`.
33008       (https://github.com/mbostock/d3/issues/563)
33009     * The `start` event is not dispatched until the first cursor movement occurs.
33010       (https://github.com/mbostock/d3/pull/368)
33011     * The `move` event has a `point` and `delta` [x, y] tuple properties rather
33012       than `x`, `y`, `dx`, and `dy` properties.
33013     * The `end` event is not dispatched if no movement occurs.
33014     * An `off` function is available that unbinds the drag's internal event handlers.
33015  */
33016
33017 function behaviorDrag() {
33018     var event$$1 = dispatch('start', 'move', 'end'),
33019         origin = null,
33020         selector = '',
33021         filter = null,
33022         event_, target, surface;
33023
33024
33025     var d3_event_userSelectProperty = utilPrefixCSSProperty('UserSelect'),
33026         d3_event_userSelectSuppress = function() {
33027             var selection$$1 = selection(),
33028                 select$$1 = selection$$1.style(d3_event_userSelectProperty);
33029             selection$$1.style(d3_event_userSelectProperty, 'none');
33030             return function() {
33031                 selection$$1.style(d3_event_userSelectProperty, select$$1);
33032             };
33033         };
33034
33035
33036     function d3_eventCancel() {
33037         event.stopPropagation();
33038         event.preventDefault();
33039     }
33040
33041
33042     function eventOf(thiz, argumentz) {
33043         return function(e1) {
33044             e1.target = drag;
33045             customEvent(e1, event$$1.apply, event$$1, [e1.type, thiz, argumentz]);
33046         };
33047     }
33048
33049
33050     function dragstart() {
33051         target = this;
33052         event_ = eventOf(target, arguments);
33053
33054         var eventTarget = event.target,
33055             touchId = event.touches ? event.changedTouches[0].identifier : null,
33056             offset,
33057             origin_ = point(),
33058             started = false,
33059             selectEnable = d3_event_userSelectSuppress(touchId !== null ? 'drag-' + touchId : 'drag');
33060
33061         d3_select(window)
33062             .on(touchId !== null ? 'touchmove.drag-' + touchId : 'mousemove.drag', dragmove)
33063             .on(touchId !== null ? 'touchend.drag-' + touchId : 'mouseup.drag', dragend, true);
33064
33065         if (origin) {
33066             offset = origin.apply(target, arguments);
33067             offset = [offset[0] - origin_[0], offset[1] - origin_[1]];
33068         } else {
33069             offset = [0, 0];
33070         }
33071
33072         if (touchId === null) {
33073             event.stopPropagation();
33074         }
33075
33076
33077         function point() {
33078             var p = surface || target.parentNode;
33079             return touchId !== null ? d3_touches(p).filter(function(p) {
33080                 return p.identifier === touchId;
33081             })[0] : d3_mouse(p);
33082         }
33083
33084
33085         function dragmove() {
33086             var p = point(),
33087                 dx = p[0] - origin_[0],
33088                 dy = p[1] - origin_[1];
33089
33090             if (dx === 0 && dy === 0)
33091                 return;
33092
33093             if (!started) {
33094                 started = true;
33095                 event_({ type: 'start' });
33096             }
33097
33098             origin_ = p;
33099             d3_eventCancel();
33100
33101             event_({
33102                 type: 'move',
33103                 point: [p[0] + offset[0],  p[1] + offset[1]],
33104                 delta: [dx, dy]
33105             });
33106         }
33107
33108
33109         function dragend() {
33110             if (started) {
33111                 event_({ type: 'end' });
33112
33113                 d3_eventCancel();
33114                 if (event.target === eventTarget) {
33115                     d3_select(window)
33116                         .on('click.drag', click, true);
33117                 }
33118             }
33119
33120             d3_select(window)
33121                 .on(touchId !== null ? 'touchmove.drag-' + touchId : 'mousemove.drag', null)
33122                 .on(touchId !== null ? 'touchend.drag-' + touchId : 'mouseup.drag', null);
33123
33124             selectEnable();
33125         }
33126
33127
33128         function click() {
33129             d3_eventCancel();
33130             d3_select(window)
33131                 .on('click.drag', null);
33132         }
33133     }
33134
33135
33136     function drag(selection$$1) {
33137         var matchesSelector = utilPrefixDOMProperty('matchesSelector'),
33138             delegate = dragstart;
33139
33140         if (selector) {
33141             delegate = function() {
33142                 var root = this,
33143                     target = event.target;
33144                 for (; target && target !== root; target = target.parentNode) {
33145                     if (target[matchesSelector](selector) &&
33146                             (!filter || filter(target.__data__))) {
33147                         return dragstart.call(target, target.__data__);
33148                     }
33149                 }
33150             };
33151         }
33152
33153         selection$$1
33154             .on('mousedown.drag' + selector, delegate)
33155             .on('touchstart.drag' + selector, delegate);
33156     }
33157
33158
33159     drag.off = function(selection$$1) {
33160         selection$$1
33161             .on('mousedown.drag' + selector, null)
33162             .on('touchstart.drag' + selector, null);
33163     };
33164
33165
33166     drag.selector = function(_) {
33167         if (!arguments.length) return selector;
33168         selector = _;
33169         return drag;
33170     };
33171
33172
33173     drag.filter = function(_) {
33174         if (!arguments.length) return origin;
33175         filter = _;
33176         return drag;
33177     };
33178
33179
33180     drag.origin = function (_) {
33181         if (!arguments.length) return origin;
33182         origin = _;
33183         return drag;
33184     };
33185
33186
33187     drag.cancel = function() {
33188         d3_select(window)
33189             .on('mousemove.drag', null)
33190             .on('mouseup.drag', null);
33191         return drag;
33192     };
33193
33194
33195     drag.target = function() {
33196         if (!arguments.length) return target;
33197         target = arguments[0];
33198         event_ = eventOf(target, Array.prototype.slice.call(arguments, 1));
33199         return drag;
33200     };
33201
33202
33203     drag.surface = function() {
33204         if (!arguments.length) return surface;
33205         surface = arguments[0];
33206         return drag;
33207     };
33208
33209
33210     return utilRebind(drag, event$$1, 'on');
33211 }
33212
33213 function behaviorDrawWay(context, wayId, index, mode, startGraph) {
33214
33215     var origWay = context.entity(wayId),
33216         isArea = context.geometry(wayId) === 'area',
33217         tempEdits = 0,
33218         annotation = t((origWay.isDegenerate() ?
33219             'operations.start.annotation.' :
33220             'operations.continue.annotation.') + context.geometry(wayId)),
33221         draw = behaviorDraw(context),
33222         startIndex,
33223         start,
33224         end,
33225         segment;
33226
33227
33228     // initialize the temporary drawing entities
33229     if (!isArea) {
33230         startIndex = typeof index === 'undefined' ? origWay.nodes.length - 1 : 0;
33231         start = osmNode({ id: 'nStart', loc: context.entity(origWay.nodes[startIndex]).loc });
33232         end = osmNode({ id: 'nEnd', loc: context.map().mouseCoordinates() });
33233         segment = osmWay({ id: 'wTemp',
33234             nodes: typeof index === 'undefined' ? [start.id, end.id] : [end.id, start.id],
33235             tags: clone(origWay.tags)
33236         });
33237     } else {
33238         end = osmNode({ loc: context.map().mouseCoordinates() });
33239     }
33240
33241     // Push an annotated state for undo to return back to.
33242     // We must make sure to remove this edit later.
33243     context.perform(actionNoop(), annotation);
33244     tempEdits++;
33245
33246     // Add the temporary drawing entities to the graph.
33247     // We must make sure to remove this edit later.
33248     context.perform(AddDrawEntities());
33249     tempEdits++;
33250
33251
33252     function move(datum) {
33253         var loc;
33254
33255         if (datum.type === 'node' && datum.id !== end.id) {
33256             loc = datum.loc;
33257
33258         } else if (datum.type === 'way') {
33259             var dims = context.map().dimensions(),
33260                 mouse = context.mouse(),
33261                 pad = 5,
33262                 trySnap = mouse[0] > pad && mouse[0] < dims[0] - pad &&
33263                     mouse[1] > pad && mouse[1] < dims[1] - pad;
33264
33265             if (trySnap) {
33266                 loc = geoChooseEdge(context.childNodes(datum), context.mouse(), context.projection).loc;
33267             }
33268         }
33269
33270         if (!loc) {
33271             loc = context.map().mouseCoordinates();
33272         }
33273
33274         context.replace(actionMoveNode(end.id, loc));
33275         end = context.entity(end.id);
33276     }
33277
33278
33279     function undone() {
33280         // Undo popped the history back to the initial annotated no-op edit.
33281         // Remove initial no-op edit and whatever edit happened immediately before it.
33282         context.pop(2);
33283         tempEdits = 0;
33284
33285         if (context.hasEntity(wayId)) {
33286             context.enter(mode);
33287         } else {
33288             context.enter(modeBrowse(context));
33289         }
33290     }
33291
33292
33293     function setActiveElements() {
33294         var active = isArea ? [wayId, end.id] : [segment.id, start.id, end.id];
33295         context.surface().selectAll(utilEntitySelector(active))
33296             .classed('active', true);
33297     }
33298
33299
33300     var drawWay = function(surface) {
33301         draw.on('move', move)
33302             .on('click', drawWay.add)
33303             .on('clickWay', drawWay.addWay)
33304             .on('clickNode', drawWay.addNode)
33305             .on('undo', context.undo)
33306             .on('cancel', drawWay.cancel)
33307             .on('finish', drawWay.finish);
33308
33309         context.map()
33310             .dblclickEnable(false)
33311             .on('drawn.draw', setActiveElements);
33312
33313         setActiveElements();
33314
33315         surface.call(draw);
33316
33317         context.history()
33318             .on('undone.draw', undone);
33319     };
33320
33321
33322     drawWay.off = function(surface) {
33323         // Drawing was interrupted unexpectedly.
33324         // This can happen if the user changes modes,
33325         // clicks geolocate button, a hashchange event occurs, etc.
33326         if (tempEdits) {
33327             context.pop(tempEdits);
33328             while (context.graph() !== startGraph) {
33329                 context.pop();
33330             }
33331         }
33332
33333         context.map()
33334             .on('drawn.draw', null);
33335
33336         surface.call(draw.off)
33337             .selectAll('.active')
33338             .classed('active', false);
33339
33340         context.history()
33341             .on('undone.draw', null);
33342     };
33343
33344
33345     function AddDrawEntities() {
33346         return function(graph) {
33347             if (isArea) {
33348                 // For area drawing, there is no need for a temporary node.
33349                 // `end` gets inserted into the way as the penultimate node.
33350                 return graph
33351                     .replace(end)
33352                     .replace(origWay.addNode(end.id));
33353             } else {
33354                 // For line drawing, add a temporary start, end, and segment to the graph.
33355                 // This allows us to class the new segment as `active`, but still
33356                 // connect it back to parts of the way that have already been drawn.
33357                 return graph
33358                     .replace(start)
33359                     .replace(end)
33360                     .replace(segment);
33361             }
33362         };
33363     }
33364
33365
33366     function ReplaceDrawEntities(newNode) {
33367         return function(graph) {
33368             if (isArea) {
33369                 // For area drawing, we didn't create a temporary node.
33370                 // `newNode` gets inserted into the _original_ way as the penultimate node.
33371                 return graph
33372                     .replace(origWay.addNode(newNode.id))
33373                     .remove(end);
33374             } else {
33375                 // For line drawing, add the `newNode` to the way at specified index,
33376                 // and remove the temporary start, end, and segment.
33377                 return graph
33378                     .replace(origWay.addNode(newNode.id, index))
33379                     .remove(end)
33380                     .remove(segment)
33381                     .remove(start);
33382             }
33383         };
33384     }
33385
33386
33387     // Accept the current position of the temporary node and continue drawing.
33388     drawWay.add = function(loc) {
33389         // prevent duplicate nodes
33390         var last = context.hasEntity(origWay.nodes[origWay.nodes.length - (isArea ? 2 : 1)]);
33391         if (last && last.loc[0] === loc[0] && last.loc[1] === loc[1]) return;
33392
33393         context.pop(tempEdits);
33394
33395         if (isArea) {
33396             context.perform(
33397                 AddDrawEntities(),
33398                 annotation
33399             );
33400         } else {
33401             var newNode = osmNode({loc: loc});
33402             context.perform(
33403                 actionAddEntity(newNode),
33404                 ReplaceDrawEntities(newNode),
33405                 annotation
33406             );
33407         }
33408
33409         tempEdits = 0;
33410         context.enter(mode);
33411     };
33412
33413
33414     // Connect the way to an existing way.
33415     drawWay.addWay = function(loc, edge) {
33416         if (isArea) {
33417             context.pop(tempEdits);
33418
33419             context.perform(
33420                 AddDrawEntities(),
33421                 actionAddMidpoint({ loc: loc, edge: edge}, end),
33422                 annotation
33423             );
33424         } else {
33425             var previousEdge = startIndex ?
33426                 [origWay.nodes[startIndex], origWay.nodes[startIndex - 1]] :
33427                 [origWay.nodes[0], origWay.nodes[1]];
33428
33429             // Avoid creating duplicate segments
33430             if (geoEdgeEqual(edge, previousEdge))
33431                 return;
33432
33433             context.pop(tempEdits);
33434
33435             var newNode = osmNode({ loc: loc });
33436             context.perform(
33437                 actionAddMidpoint({ loc: loc, edge: edge}, newNode),
33438                 ReplaceDrawEntities(newNode),
33439                 annotation
33440             );
33441         }
33442
33443         tempEdits = 0;
33444         context.enter(mode);
33445     };
33446
33447
33448     // Connect the way to an existing node and continue drawing.
33449     drawWay.addNode = function(node) {
33450         // Avoid creating duplicate segments
33451         if (origWay.areAdjacent(node.id, origWay.nodes[origWay.nodes.length - 1])) return;
33452
33453         // Clicks should not occur on the drawing node, however a space keypress can
33454         // sometimes grab that node's datum (before it gets classed as `active`?)  #4016
33455         if (node.id === end.id) {
33456             drawWay.add(node.loc);
33457             return;
33458         }
33459
33460         context.pop(tempEdits);
33461
33462         context.perform(
33463             ReplaceDrawEntities(node),
33464             annotation
33465         );
33466
33467         tempEdits = 0;
33468         context.enter(mode);
33469     };
33470
33471
33472     // Finish the draw operation, removing the temporary edits.
33473     // If the way has enough nodes to be valid, it's selected.
33474     // Otherwise, delete everything and return to browse mode.
33475     drawWay.finish = function() {
33476         context.pop(tempEdits);
33477         tempEdits = 0;
33478
33479         var way = context.hasEntity(wayId);
33480         if (!way || way.isDegenerate()) {
33481             drawWay.cancel();
33482             return;
33483         }
33484
33485         window.setTimeout(function() {
33486             context.map().dblclickEnable(true);
33487         }, 1000);
33488
33489         context.enter(modeSelect(context, [wayId]).newFeature(true));
33490     };
33491
33492
33493     // Cancel the draw operation, delete everything, and return to browse mode.
33494     drawWay.cancel = function() {
33495         context.pop(tempEdits);
33496         tempEdits = 0;
33497
33498         while (context.graph() !== startGraph) {
33499             context.pop();
33500         }
33501
33502         window.setTimeout(function() {
33503             context.map().dblclickEnable(true);
33504         }, 1000);
33505
33506         context.enter(modeBrowse(context));
33507     };
33508
33509
33510     drawWay.tail = function(text) {
33511         draw.tail(text);
33512         return drawWay;
33513     };
33514
33515
33516     return drawWay;
33517 }
33518
33519 /** Error message constants. */
33520 var FUNC_ERROR_TEXT$3 = 'Expected a function';
33521
33522 /**
33523  * Creates a throttled function that only invokes `func` at most once per
33524  * every `wait` milliseconds. The throttled function comes with a `cancel`
33525  * method to cancel delayed `func` invocations and a `flush` method to
33526  * immediately invoke them. Provide `options` to indicate whether `func`
33527  * should be invoked on the leading and/or trailing edge of the `wait`
33528  * timeout. The `func` is invoked with the last arguments provided to the
33529  * throttled function. Subsequent calls to the throttled function return the
33530  * result of the last `func` invocation.
33531  *
33532  * **Note:** If `leading` and `trailing` options are `true`, `func` is
33533  * invoked on the trailing edge of the timeout only if the throttled function
33534  * is invoked more than once during the `wait` timeout.
33535  *
33536  * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
33537  * until to the next tick, similar to `setTimeout` with a timeout of `0`.
33538  *
33539  * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
33540  * for details over the differences between `_.throttle` and `_.debounce`.
33541  *
33542  * @static
33543  * @memberOf _
33544  * @since 0.1.0
33545  * @category Function
33546  * @param {Function} func The function to throttle.
33547  * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
33548  * @param {Object} [options={}] The options object.
33549  * @param {boolean} [options.leading=true]
33550  *  Specify invoking on the leading edge of the timeout.
33551  * @param {boolean} [options.trailing=true]
33552  *  Specify invoking on the trailing edge of the timeout.
33553  * @returns {Function} Returns the new throttled function.
33554  * @example
33555  *
33556  * // Avoid excessively updating the position while scrolling.
33557  * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
33558  *
33559  * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
33560  * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
33561  * jQuery(element).on('click', throttled);
33562  *
33563  * // Cancel the trailing throttled invocation.
33564  * jQuery(window).on('popstate', throttled.cancel);
33565  */
33566 function throttle(func, wait, options) {
33567   var leading = true,
33568       trailing = true;
33569
33570   if (typeof func != 'function') {
33571     throw new TypeError(FUNC_ERROR_TEXT$3);
33572   }
33573   if (isObject(options)) {
33574     leading = 'leading' in options ? !!options.leading : leading;
33575     trailing = 'trailing' in options ? !!options.trailing : trailing;
33576   }
33577   return debounce(func, wait, {
33578     'leading': leading,
33579     'maxWait': wait,
33580     'trailing': trailing
33581   });
33582 }
33583
33584 function behaviorHash(context) {
33585     var s0 = null, // cached window.location.hash
33586         lat = 90 - 1e-8; // allowable latitude range
33587
33588
33589     var parser = function(map, s) {
33590         var q = utilStringQs(s);
33591         var args = (q.map || '').split('/').map(Number);
33592
33593         if (args.length < 3 || args.some(isNaN)) {
33594             return true; // replace bogus hash
33595
33596         } else if (s !== formatter(map).slice(1)) {   // hash has changed
33597             var mode = context.mode(),
33598                 dist = geoSphericalDistance(map.center(), [args[2], args[1]]),
33599                 maxdist = 500;
33600
33601             // Don't allow the hash location to change too much while drawing
33602             // This can happen if the user accidently hit the back button.  #3996
33603             if (mode && mode.id.match(/^draw/) !== null && dist > maxdist) {
33604                 context.enter(modeBrowse(context));
33605             }
33606
33607             map.centerZoom([args[2], Math.min(lat, Math.max(-lat, args[1]))], args[0]);
33608         }
33609     };
33610
33611
33612     var formatter = function(map) {
33613         var center = map.center(),
33614             zoom = map.zoom(),
33615             precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2)),
33616             q = omit(utilStringQs(window.location.hash.substring(1)),
33617                 ['comment', 'hashtags', 'walkthrough']
33618             ),
33619             newParams = {};
33620
33621         delete q.id;
33622         var selected = context.selectedIDs().filter(function(id) {
33623             return !context.entity(id).isNew();
33624         });
33625         if (selected.length) {
33626             newParams.id = selected.join(',');
33627         }
33628
33629         newParams.map = zoom.toFixed(2) +
33630             '/' + center[1].toFixed(precision) +
33631             '/' + center[0].toFixed(precision);
33632
33633         return '#' + utilQsString(assign(q, newParams), true);
33634     };
33635
33636
33637     function update() {
33638         if (context.inIntro()) return;
33639         var s1 = formatter(context.map());
33640         if (s0 !== s1) {
33641             window.location.replace(s0 = s1);  // don't recenter the map!
33642         }
33643     }
33644
33645
33646     var throttledUpdate = throttle(update, 500);
33647
33648
33649     function hashchange() {
33650         if (window.location.hash === s0) return;  // ignore spurious hashchange events
33651         if (parser(context.map(), (s0 = window.location.hash).substring(1))) {
33652             update(); // replace bogus hash
33653         }
33654     }
33655
33656
33657     function hash() {
33658         context.map()
33659             .on('move.hash', throttledUpdate);
33660
33661         context
33662             .on('enter.hash', throttledUpdate);
33663
33664         d3_select(window)
33665             .on('hashchange.hash', hashchange);
33666
33667         if (window.location.hash) {
33668
33669             var q = utilStringQs(window.location.hash.substring(1));
33670
33671             if (q.id) {
33672                 context.zoomToEntity(q.id.split(',')[0], !q.map);
33673             }
33674
33675             if (q.comment) {
33676                 context.storage('comment', q.comment);
33677                 context.storage('commentDate', Date.now());
33678             }
33679
33680             if (q.hashtags) {
33681                 context.storage('hashtags', q.hashtags);
33682             }
33683
33684             if (q.walkthrough === 'true') {
33685                 hash.startWalkthrough = true;
33686             }
33687
33688             hashchange();
33689
33690             if (q.map) {
33691                 hash.hadHash = true;
33692             }
33693         }
33694     }
33695
33696
33697     hash.off = function() {
33698         throttledUpdate.cancel();
33699
33700         context.map()
33701             .on('move.hash', null);
33702
33703         context
33704             .on('enter.hash', null);
33705
33706         d3_select(window)
33707             .on('hashchange.hash', null);
33708
33709         window.location.hash = '';
33710     };
33711
33712
33713     return hash;
33714 }
33715
33716 function behaviorLasso(context) {
33717
33718     var behavior = function(selection) {
33719         var lasso;
33720
33721
33722         function mousedown() {
33723             var button = 0;  // left
33724             if (event.button === button && event.shiftKey === true) {
33725                 lasso = null;
33726
33727                 d3_select(window)
33728                     .on('mousemove.lasso', mousemove)
33729                     .on('mouseup.lasso', mouseup);
33730
33731                 event.stopPropagation();
33732             }
33733         }
33734
33735
33736         function mousemove() {
33737             if (!lasso) {
33738                 lasso = uiLasso(context);
33739                 context.surface().call(lasso);
33740             }
33741
33742             lasso.p(context.mouse());
33743         }
33744
33745
33746         function normalize(a, b) {
33747             return [
33748                 [Math.min(a[0], b[0]), Math.min(a[1], b[1])],
33749                 [Math.max(a[0], b[0]), Math.max(a[1], b[1])]];
33750         }
33751
33752
33753         function lassoed() {
33754             if (!lasso) return [];
33755
33756             var graph = context.graph(),
33757                 bounds = lasso.extent().map(context.projection.invert),
33758                 extent = geoExtent(normalize(bounds[0], bounds[1]));
33759
33760             return map$4(context.intersects(extent).filter(function(entity) {
33761                 return entity.type === 'node' &&
33762                     geoPointInPolygon(context.projection(entity.loc), lasso.coordinates) &&
33763                     !context.features().isHidden(entity, graph, entity.geometry(graph));
33764             }), 'id');
33765         }
33766
33767
33768         function mouseup() {
33769             d3_select(window)
33770                 .on('mousemove.lasso', null)
33771                 .on('mouseup.lasso', null);
33772
33773             if (!lasso) return;
33774
33775             var ids = lassoed();
33776             lasso.close();
33777
33778             if (ids.length) {
33779                 context.enter(modeSelect(context, ids));
33780             }
33781         }
33782
33783         selection
33784             .on('mousedown.lasso', mousedown);
33785     };
33786
33787
33788     behavior.off = function(selection) {
33789         selection.on('mousedown.lasso', null);
33790     };
33791
33792
33793     return behavior;
33794 }
33795
33796 /* Creates a keybinding behavior for an operation */
33797 function behaviorOperation() {
33798     var which, keybinding;
33799
33800
33801     function drawIcon(selection) {
33802         var button = selection
33803             .append('svg')
33804             .attr('class', 'operation-icon')
33805             .append('g')
33806             .attr('class', 'radial-menu-item radial-menu-item-' + which.id)
33807             .attr('transform', 'translate(10,10)')
33808             .classed('disabled', which.disabled());
33809
33810         button
33811             .append('circle')
33812             .attr('r', 9);
33813
33814         button
33815             .append('use')
33816             .attr('transform', 'translate(-7,-7)')
33817             .attr('width', '14')
33818             .attr('height', '14')
33819             .attr('xlink:href', '#operation-' + which.id);
33820
33821         return selection;
33822     }
33823
33824
33825     var behavior = function () {
33826         if (which && which.available()) {
33827             keybinding = d3keybinding('behavior.key.' + which.id);
33828             keybinding.on(which.keys, function() {
33829                 event.preventDefault();
33830                 var disabled = which.disabled();
33831
33832                 if (disabled) {
33833                     uiFlash(3000)
33834                         .html('')
33835                         .call(drawIcon)
33836                         .append('div')
33837                         .attr('class', 'operation-tip')
33838                         .text(which.tooltip);
33839
33840                 } else {
33841                     uiFlash(1500)
33842                         .html('')
33843                         .call(drawIcon)
33844                         .append('div')
33845                         .attr('class', 'operation-tip')
33846                         .text(which.annotation() || which.title);
33847
33848                     which();
33849                 }
33850             });
33851             d3_select(document).call(keybinding);
33852         }
33853         return behavior;
33854     };
33855
33856
33857     behavior.off = function() {
33858         if (keybinding) {
33859             d3_select(document).call(keybinding.off);
33860         }
33861     };
33862
33863
33864     behavior.which = function (_) {
33865         if (!arguments.length) return which;
33866         which = _;
33867         return behavior;
33868     };
33869
33870
33871     return behavior;
33872 }
33873
33874 /**
33875  * The base implementation of `_.invert` and `_.invertBy` which inverts
33876  * `object` with values transformed by `iteratee` and set by `setter`.
33877  *
33878  * @private
33879  * @param {Object} object The object to iterate over.
33880  * @param {Function} setter The function to set `accumulator` values.
33881  * @param {Function} iteratee The iteratee to transform values.
33882  * @param {Object} accumulator The initial inverted object.
33883  * @returns {Function} Returns `accumulator`.
33884  */
33885 function baseInverter(object, setter, iteratee, accumulator) {
33886   baseForOwn(object, function(value, key, object) {
33887     setter(accumulator, iteratee(value), key, object);
33888   });
33889   return accumulator;
33890 }
33891
33892 /**
33893  * Creates a function like `_.invertBy`.
33894  *
33895  * @private
33896  * @param {Function} setter The function to set accumulator values.
33897  * @param {Function} toIteratee The function to resolve iteratees.
33898  * @returns {Function} Returns the new inverter function.
33899  */
33900 function createInverter(setter, toIteratee) {
33901   return function(object, iteratee) {
33902     return baseInverter(object, setter, toIteratee(iteratee), {});
33903   };
33904 }
33905
33906 /**
33907  * Creates an object composed of the inverted keys and values of `object`.
33908  * If `object` contains duplicate values, subsequent values overwrite
33909  * property assignments of previous values.
33910  *
33911  * @static
33912  * @memberOf _
33913  * @since 0.7.0
33914  * @category Object
33915  * @param {Object} object The object to invert.
33916  * @returns {Object} Returns the new inverted object.
33917  * @example
33918  *
33919  * var object = { 'a': 1, 'b': 2, 'c': 1 };
33920  *
33921  * _.invert(object);
33922  * // => { '1': 'c', '2': 'b' }
33923  */
33924 var invert = createInverter(function(result, value, key) {
33925   result[value] = key;
33926 }, constant$13(identity$8));
33927
33928 /**
33929  * Creates an object with the same keys as `object` and values generated
33930  * by running each own enumerable string keyed property of `object` thru
33931  * `iteratee`. The iteratee is invoked with three arguments:
33932  * (value, key, object).
33933  *
33934  * @static
33935  * @memberOf _
33936  * @since 2.4.0
33937  * @category Object
33938  * @param {Object} object The object to iterate over.
33939  * @param {Function} [iteratee=_.identity] The function invoked per iteration.
33940  * @returns {Object} Returns the new mapped object.
33941  * @see _.mapKeys
33942  * @example
33943  *
33944  * var users = {
33945  *   'fred':    { 'user': 'fred',    'age': 40 },
33946  *   'pebbles': { 'user': 'pebbles', 'age': 1 }
33947  * };
33948  *
33949  * _.mapValues(users, function(o) { return o.age; });
33950  * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
33951  *
33952  * // The `_.property` iteratee shorthand.
33953  * _.mapValues(users, 'age');
33954  * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
33955  */
33956 function mapValues(object, iteratee) {
33957   var result = {};
33958   iteratee = baseIteratee(iteratee, 3);
33959
33960   baseForOwn(object, function(value, key, object) {
33961     baseAssignValue(result, key, iteratee(value, key, object));
33962   });
33963   return result;
33964 }
33965
33966 function behaviorPaste(context) {
33967     var keybinding = d3keybinding('paste');
33968
33969
33970     function doPaste() {
33971         event.preventDefault();
33972
33973         var baseGraph = context.graph(),
33974             mouse = context.mouse(),
33975             projection = context.projection,
33976             viewport = geoExtent(projection.clipExtent()).polygon();
33977
33978         if (!geoPointInPolygon(mouse, viewport)) return;
33979
33980         var extent = geoExtent(),
33981             oldIDs = context.copyIDs(),
33982             oldGraph = context.copyGraph(),
33983             newIDs = [];
33984
33985         if (!oldIDs.length) return;
33986
33987         var action = actionCopyEntities(oldIDs, oldGraph);
33988         context.perform(action);
33989
33990         var copies = action.copies();
33991         var originals = invert(mapValues(copies, 'id'));
33992         for (var id in copies) {
33993             var oldEntity = oldGraph.entity(id),
33994                 newEntity = copies[id];
33995
33996             extent._extend(oldEntity.extent(oldGraph));
33997
33998             // Exclude child nodes from newIDs if their parent way was also copied.
33999             var parents = context.graph().parentWays(newEntity),
34000                 parentCopied = false;
34001             for (var i = 0; i < parents.length; i++) {
34002                 if (originals[parents[i].id]) {
34003                     parentCopied = true;
34004                     break;
34005                 }
34006             }
34007
34008             if (!parentCopied) {
34009                 newIDs.push(newEntity.id);
34010             }
34011         }
34012
34013         // Put pasted objects where mouse pointer is..
34014         var center = projection(extent.center()),
34015             delta = [ mouse[0] - center[0], mouse[1] - center[1] ];
34016
34017         context.perform(actionMove(newIDs, delta, projection));
34018         context.enter(modeMove(context, newIDs, baseGraph));
34019     }
34020
34021
34022     function paste() {
34023         keybinding.on(uiCmd('⌘V'), doPaste);
34024         d3_select(document).call(keybinding);
34025         return paste;
34026     }
34027
34028
34029     paste.off = function() {
34030         d3_select(document).call(keybinding.off);
34031     };
34032
34033
34034     return paste;
34035 }
34036
34037 function behaviorSelect(context) {
34038     var lastMouse = null,
34039         suppressMenu = true,
34040         tolerance = 4,
34041         p1 = null;
34042
34043
34044     function point() {
34045         return d3_mouse(context.container().node());
34046     }
34047
34048
34049     function keydown() {
34050         var e = event;
34051         if (e && e.shiftKey) {
34052             context.surface()
34053                 .classed('behavior-multiselect', true);
34054         }
34055
34056         if (e && e.keyCode === 93) {  // context menu
34057             e.preventDefault();
34058             e.stopPropagation();
34059         }
34060     }
34061
34062
34063     function keyup() {
34064         var e = event;
34065         if (!e || !e.shiftKey) {
34066             context.surface()
34067                 .classed('behavior-multiselect', false);
34068         }
34069
34070
34071         if (e && e.keyCode === 93) {  // context menu
34072             e.preventDefault();
34073             e.stopPropagation();
34074             contextmenu();
34075         }
34076     }
34077
34078
34079     function mousedown() {
34080         if (!p1) p1 = point();
34081         d3_select(window)
34082             .on('mouseup.select', mouseup, true);
34083
34084         var isShowAlways = +context.storage('edit-menu-show-always') === 1;
34085         suppressMenu = !isShowAlways;
34086     }
34087
34088
34089     function mousemove() {
34090         if (event) lastMouse = event;
34091     }
34092
34093
34094     function mouseup() {
34095         click();
34096     }
34097
34098
34099     function contextmenu() {
34100         var e = event;
34101         e.preventDefault();
34102         e.stopPropagation();
34103
34104         if (!+e.clientX && !+e.clientY) {
34105             if (lastMouse) {
34106                 e.sourceEvent = lastMouse;
34107             } else {
34108                 return;
34109             }
34110         }
34111
34112         if (!p1) p1 = point();
34113         suppressMenu = false;
34114         click();
34115     }
34116
34117
34118     function click() {
34119         d3_select(window)
34120             .on('mouseup.select', null, true);
34121
34122         if (!p1) return;
34123         var p2 = point(),
34124             dist = geoEuclideanDistance(p1, p2);
34125
34126         p1 = null;
34127         if (dist > tolerance) {
34128             return;
34129         }
34130
34131         var isMultiselect = event.shiftKey || d3_select('#surface .lasso').node(),
34132             isShowAlways = +context.storage('edit-menu-show-always') === 1,
34133             datum = event.target.__data__ || (lastMouse && lastMouse.target.__data__),
34134             mode = context.mode();
34135
34136
34137         if (datum && datum.type === 'midpoint') {
34138             datum = datum.parents[0];
34139         }
34140
34141         if (!(datum instanceof osmEntity)) {
34142             // clicked nothing..
34143             if (!isMultiselect && mode.id !== 'browse') {
34144                 context.enter(modeBrowse(context));
34145             }
34146
34147         } else {
34148             // clicked an entity..
34149             var selectedIDs = context.selectedIDs();
34150
34151             if (!isMultiselect) {
34152                 if (selectedIDs.length > 1 && (!suppressMenu && !isShowAlways)) {
34153                     // multiple things already selected, just show the menu...
34154                     mode.suppressMenu(false).reselect();
34155                 } else {
34156                     // select a single thing..
34157                     context.enter(modeSelect(context, [datum.id]).suppressMenu(suppressMenu));
34158                 }
34159
34160             } else {
34161                 if (selectedIDs.indexOf(datum.id) !== -1) {
34162                     // clicked entity is already in the selectedIDs list..
34163                     if (!suppressMenu && !isShowAlways) {
34164                         // don't deselect clicked entity, just show the menu.
34165                         mode.suppressMenu(false).reselect();
34166                     } else {
34167                         // deselect clicked entity, then reenter select mode or return to browse mode..
34168                         selectedIDs = without(selectedIDs, datum.id);
34169                         context.enter(selectedIDs.length ? modeSelect(context, selectedIDs) : modeBrowse(context));
34170                     }
34171                 } else {
34172                     // clicked entity is not in the selected list, add it..
34173                     selectedIDs = selectedIDs.concat([datum.id]);
34174                     context.enter(modeSelect(context, selectedIDs).suppressMenu(suppressMenu));
34175                 }
34176             }
34177         }
34178
34179         // reset for next time..
34180         suppressMenu = true;
34181     }
34182
34183
34184     var behavior = function(selection) {
34185         lastMouse = null;
34186         suppressMenu = true;
34187         p1 = null;
34188
34189         d3_select(window)
34190             .on('keydown.select', keydown)
34191             .on('keyup.select', keyup)
34192             .on('contextmenu.select-window', function() {
34193                 // Edge and IE really like to show the contextmenu on the
34194                 // menubar when user presses a keyboard menu button
34195                 // even after we've already preventdefaulted the key event.
34196                 var e = event;
34197                 if (+e.clientX === 0 && +e.clientY === 0) {
34198                     event.preventDefault();
34199                     event.stopPropagation();
34200                 }
34201             });
34202
34203         selection
34204             .on('mousedown.select', mousedown)
34205             .on('mousemove.select', mousemove)
34206             .on('contextmenu.select', contextmenu);
34207
34208         if (event && event.shiftKey) {
34209             context.surface()
34210                 .classed('behavior-multiselect', true);
34211         }
34212     };
34213
34214
34215     behavior.off = function(selection) {
34216         d3_select(window)
34217             .on('keydown.select', null)
34218             .on('keyup.select', null)
34219             .on('contextmenu.select-window', null)
34220             .on('mouseup.select', null, true);
34221
34222         selection
34223             .on('mousedown.select', null)
34224             .on('mousemove.select', null)
34225             .on('contextmenu.select', null);
34226
34227         context.surface()
34228             .classed('behavior-multiselect', false);
34229     };
34230
34231
34232     return behavior;
34233 }
34234
34235 function d3geoTile() {
34236   var size = [960, 500],
34237       scale = 256,
34238       scaleExtent = [0, 20],
34239       translate = [size[0] / 2, size[1] / 2],
34240       zoomDelta = 0;
34241
34242   function bound(_) {
34243       return Math.min(scaleExtent[1], Math.max(scaleExtent[0], _));
34244   }
34245
34246   function tile() {
34247     var z = Math.max(Math.log(scale) / Math.LN2 - 8, 0),
34248         z0 = bound(Math.round(z + zoomDelta)),
34249         k = Math.pow(2, z - z0 + 8),
34250         origin = [(translate[0] - scale / 2) / k, (translate[1] - scale / 2) / k],
34251         tiles = [],
34252         cols = d3_range(Math.max(0, Math.floor(-origin[0])), Math.max(0, Math.ceil(size[0] / k - origin[0]))),
34253         rows = d3_range(Math.max(0, Math.floor(-origin[1])), Math.max(0, Math.ceil(size[1] / k - origin[1])));
34254
34255     rows.forEach(function(y) {
34256       cols.forEach(function(x) {
34257         tiles.push([x, y, z0]);
34258       });
34259     });
34260
34261     tiles.translate = origin;
34262     tiles.scale = k;
34263
34264     return tiles;
34265   }
34266
34267   tile.scaleExtent = function(_) {
34268     if (!arguments.length) return scaleExtent;
34269     scaleExtent = _;
34270     return tile;
34271   };
34272
34273   tile.size = function(_) {
34274     if (!arguments.length) return size;
34275     size = _;
34276     return tile;
34277   };
34278
34279   tile.scale = function(_) {
34280     if (!arguments.length) return scale;
34281     scale = _;
34282     return tile;
34283   };
34284
34285   tile.translate = function(_) {
34286     if (!arguments.length) return translate;
34287     translate = _;
34288     return tile;
34289   };
34290
34291   tile.zoomDelta = function(_) {
34292     if (!arguments.length) return zoomDelta;
34293     zoomDelta = +_;
34294     return tile;
34295   };
34296
34297   return tile;
34298 }
34299
34300 /* global Mapillary:false */
34301 var apibase = 'https://a.mapillary.com/v3/';
34302 var viewercss = 'mapillary-js/mapillary.min.css';
34303 var viewerjs = 'mapillary-js/mapillary.min.js';
34304 var clientId = 'NzNRM2otQkR2SHJzaXJmNmdQWVQ0dzo1ZWYyMmYwNjdmNDdlNmVi';
34305 var maxResults = 1000;
34306 var tileZoom = 14;
34307 var dispatch$1 = dispatch('loadedImages', 'loadedSigns');
34308 var _mlyCache;
34309 var _mlyClicks;
34310 var _mlySelectedImage;
34311 var _mlySignDefs;
34312 var _mlySignSprite;
34313 var _mlyViewer;
34314
34315
34316 function abortRequest(i) {
34317     i.abort();
34318 }
34319
34320
34321 function nearNullIsland(x, y, z) {
34322     if (z >= 7) {
34323         var center = Math.pow(2, z - 1),
34324             width = Math.pow(2, z - 6),
34325             min = center - (width / 2),
34326             max = center + (width / 2) - 1;
34327         return x >= min && x <= max && y >= min && y <= max;
34328     }
34329     return false;
34330 }
34331
34332
34333 function maxPageAtZoom(z) {
34334     if (z < 15)   return 2;
34335     if (z === 15) return 5;
34336     if (z === 16) return 10;
34337     if (z === 17) return 20;
34338     if (z === 18) return 40;
34339     if (z > 18)   return 80;
34340 }
34341
34342
34343 function localeTimestamp(s) {
34344     if (!s) return null;
34345     var d = new Date(s);
34346     if (isNaN(d.getTime())) return null;
34347     return d.toLocaleString(undefined, { timeZone: 'UTC' });
34348 }
34349
34350
34351 function getTiles(projection) {
34352     var s = projection.scale() * 2 * Math.PI,
34353         z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
34354         ts = 256 * Math.pow(2, z - tileZoom),
34355         origin = [
34356             s / 2 - projection.translate()[0],
34357             s / 2 - projection.translate()[1]];
34358
34359     return d3geoTile()
34360         .scaleExtent([tileZoom, tileZoom])
34361         .scale(s)
34362         .size(projection.clipExtent()[1])
34363         .translate(projection.translate())()
34364         .map(function(tile) {
34365             var x = tile[0] * ts - origin[0],
34366                 y = tile[1] * ts - origin[1];
34367
34368             return {
34369                 id: tile.toString(),
34370                 xyz: tile,
34371                 extent: geoExtent(
34372                     projection.invert([x, y + ts]),
34373                     projection.invert([x + ts, y])
34374                 )
34375             };
34376         });
34377 }
34378
34379
34380 function loadTiles(which, url, projection) {
34381     var s = projection.scale() * 2 * Math.PI,
34382         currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0));
34383
34384     var tiles = getTiles(projection).filter(function(t) {
34385             return !nearNullIsland(t.xyz[0], t.xyz[1], t.xyz[2]);
34386         });
34387
34388     filter(which.inflight, function(v, k) {
34389         var wanted = find$1(tiles, function(tile) { return k === (tile.id + ',0'); });
34390         if (!wanted) delete which.inflight[k];
34391         return !wanted;
34392     }).map(abortRequest);
34393
34394     tiles.forEach(function(tile) {
34395         loadNextTilePage(which, currZoom, url, tile);
34396     });
34397 }
34398
34399
34400 function loadNextTilePage(which, currZoom, url, tile) {
34401     var cache = _mlyCache[which],
34402         rect = tile.extent.rectangle(),
34403         maxPages = maxPageAtZoom(currZoom),
34404         nextPage = cache.nextPage[tile.id] || 0,
34405         nextURL = cache.nextURL[tile.id] || url +
34406             utilQsString({
34407                 per_page: maxResults,
34408                 page: nextPage,
34409                 client_id: clientId,
34410                 bbox: [rect[0], rect[1], rect[2], rect[3]].join(','),
34411             });
34412
34413     if (nextPage > maxPages) return;
34414
34415     var id = tile.id + ',' + String(nextPage);
34416     if (cache.loaded[id] || cache.inflight[id]) return;
34417     cache.inflight[id] = d3_request(nextURL)
34418         .mimeType('application/json')
34419         .response(function(xhr) {
34420             var linkHeader = xhr.getResponseHeader('Link');
34421             if (linkHeader) {
34422                 var pagination = parsePagination(xhr.getResponseHeader('Link'));
34423                 if (pagination.next) {
34424                     cache.nextURL[tile.id] = pagination.next;
34425                 }
34426             }
34427             return JSON.parse(xhr.responseText);
34428         })
34429         .get(function(err, data) {
34430             cache.loaded[id] = true;
34431             delete cache.inflight[id];
34432             if (err || !data.features || !data.features.length) return;
34433
34434             var features = data.features.map(function(feature) {
34435                 var loc = feature.geometry.coordinates,
34436                     d;
34437
34438                 if (which === 'images') {
34439                     d = {
34440                         loc: loc,
34441                         key: feature.properties.key,
34442                         ca: feature.properties.ca,
34443                         captured_at: feature.properties.captured_at,
34444                         captured_by: feature.properties.username,
34445                         pano: feature.properties.pano
34446                     };
34447                     cache.forImageKey[d.key] = d;     // cache imageKey -> image
34448
34449                 } else if (which === 'sequences') {
34450                     var sequenceKey = feature.properties.key;
34451                     cache.lineString[sequenceKey] = feature;           // cache sequenceKey -> lineString
34452                     feature.properties.coordinateProperties.image_keys.forEach(function(imageKey) {
34453                         cache.forImageKey[imageKey] = sequenceKey;     // cache imageKey -> sequenceKey
34454                     });
34455                     return false;  // because no `d` data worth loading into an rbush
34456
34457                 } else if (which === 'objects') {
34458                     d = {
34459                         loc: loc,
34460                         key: feature.properties.key,
34461                         value: feature.properties.value,
34462                         package: feature.properties.package,
34463                         detections: feature.properties.detections
34464                     };
34465
34466                     // cache imageKey -> detectionKey
34467                     feature.properties.detections.forEach(function(detection) {
34468                         var imageKey = detection.image_key;
34469                         var detectionKey = detection.detection_key;
34470                         if (!_mlyCache.detections[imageKey]) {
34471                             _mlyCache.detections[imageKey] = {};
34472                         }
34473                         if (!_mlyCache.detections[imageKey][detectionKey]) {
34474                             _mlyCache.detections[imageKey][detectionKey] = {};
34475                         }
34476                     });
34477                 }
34478
34479                 return {
34480                     minX: loc[0], minY: loc[1], maxX: loc[0], maxY: loc[1], data: d
34481                 };
34482
34483             }).filter(Boolean);
34484
34485             cache.rtree.load(features);
34486
34487             if (which === 'images' || which === 'sequences') {
34488                 dispatch$1.call('loadedImages');
34489             } else if (which === 'objects') {
34490                 dispatch$1.call('loadedSigns');
34491             }
34492
34493             if (data.features.length === maxResults) {  // more pages to load
34494                 cache.nextPage[tile.id] = nextPage + 1;
34495                 loadNextTilePage(which, currZoom, url, tile);
34496             } else {
34497                 cache.nextPage[tile.id] = Infinity;     // no more pages to load
34498             }
34499         });
34500 }
34501
34502 // extract links to pages of API results
34503 function parsePagination(links) {
34504     return links.split(',').map(function(rel) {
34505         var elements = rel.split(';');
34506         if (elements.length === 2) {
34507             return [
34508                 /<(.+)>/.exec(elements[0])[1],
34509                 /rel="(.+)"/.exec(elements[1])[1]
34510                 ];
34511         } else {
34512             return ['',''];
34513         }
34514     }).reduce(function(pagination, val) {
34515         pagination[val[1]] = val[0];
34516         return pagination;
34517     }, {});
34518 }
34519
34520
34521 // partition viewport into `psize` x `psize` regions
34522 function partitionViewport(psize, projection) {
34523     var dimensions = projection.clipExtent()[1];
34524     psize = psize || 16;
34525     var cols = d3_range(0, dimensions[0], psize),
34526         rows = d3_range(0, dimensions[1], psize),
34527         partitions = [];
34528
34529     rows.forEach(function(y) {
34530         cols.forEach(function(x) {
34531             var min = [x, y + psize],
34532                 max = [x + psize, y];
34533             partitions.push(
34534                 geoExtent(projection.invert(min), projection.invert(max)));
34535         });
34536     });
34537
34538     return partitions;
34539 }
34540
34541
34542 // no more than `limit` results per partition.
34543 function searchLimited(psize, limit, projection, rtree) {
34544     limit = limit || 3;
34545
34546     var partitions = partitionViewport(psize, projection);
34547     var results;
34548
34549     // console.time('previous');
34550     results =  flatten(map$4(partitions, function(extent) {
34551         return rtree.search(extent.bbox())
34552             .slice(0, limit)
34553             .map(function(d) { return d.data; });
34554     }));
34555     // console.timeEnd('previous');
34556
34557     // console.time('new');
34558     // results = partitions.reduce(function(result, extent) {
34559     //     var found = rtree.search(extent.bbox())
34560     //         .map(function(d) { return d.data; })
34561     //         .sort(function(a, b) {
34562     //             return a.loc[1] - b.loc[1];
34563     //             // return a.key.localeCompare(b.key);
34564     //         })
34565     //         .slice(0, limit);
34566
34567     //     return (found.length ? result.concat(found) : result);
34568     // }, []);
34569     // console.timeEnd('new');
34570
34571     return results;
34572 }
34573
34574
34575
34576 var serviceMapillary = {
34577
34578     init: function() {
34579         if (!_mlyCache) {
34580             this.reset();
34581         }
34582
34583         this.event = utilRebind(this, dispatch$1, 'on');
34584     },
34585
34586     reset: function() {
34587         var cache = _mlyCache;
34588
34589         if (cache) {
34590             if (cache.images && cache.images.inflight) {
34591                 forEach(cache.images.inflight, abortRequest);
34592             }
34593             if (cache.objects && cache.objects.inflight) {
34594                 forEach(cache.objects.inflight, abortRequest);
34595             }
34596             if (cache.sequences && cache.sequences.inflight) {
34597                 forEach(cache.sequences.inflight, abortRequest);
34598             }
34599         }
34600
34601         _mlyCache = {
34602             images: { inflight: {}, loaded: {}, nextPage: {}, nextURL: {}, rtree: rbush_1(), forImageKey: {} },
34603             objects: { inflight: {}, loaded: {}, nextPage: {}, nextURL: {}, rtree: rbush_1() },
34604             sequences: { inflight: {}, loaded: {}, nextPage: {}, nextURL: {}, rtree: rbush_1(), forImageKey: {}, lineString: {} },
34605             detections: {}
34606         };
34607
34608         _mlySelectedImage = null;
34609         _mlyClicks = [];
34610     },
34611
34612
34613     images: function(projection) {
34614         var psize = 16, limit = 3;
34615         return searchLimited(psize, limit, projection, _mlyCache.images.rtree);
34616     },
34617
34618
34619     signs: function(projection) {
34620         var psize = 32, limit = 3;
34621         return searchLimited(psize, limit, projection, _mlyCache.objects.rtree);
34622     },
34623
34624
34625     sequences: function(projection) {
34626         var viewport = projection.clipExtent();
34627         var min = [viewport[0][0], viewport[1][1]];
34628         var max = [viewport[1][0], viewport[0][1]];
34629         var bbox = geoExtent(projection.invert(min), projection.invert(max)).bbox();
34630         var sequenceKeys = {};
34631
34632         // all sequences for images in viewport
34633         _mlyCache.images.rtree.search(bbox)
34634             .forEach(function(d) {
34635                 var sequenceKey = _mlyCache.sequences.forImageKey[d.data.key];
34636                 if (sequenceKey) {
34637                     sequenceKeys[sequenceKey] = true;
34638                 }
34639             });
34640
34641         // Return lineStrings for the sequences
34642         return Object.keys(sequenceKeys).map(function(sequenceKey) {
34643             return _mlyCache.sequences.lineString[sequenceKey];
34644         });
34645     },
34646
34647
34648     signsSupported: function() {
34649         var detected = utilDetect();
34650         if (detected.ie) return false;
34651         if ((detected.browser.toLowerCase() === 'safari') && (parseFloat(detected.version) < 10)) return false;
34652         return true;
34653     },
34654
34655
34656     signHTML: function(d) {
34657         if (!_mlySignDefs || !_mlySignSprite) return;
34658         var position = _mlySignDefs[d.value];
34659         if (!position) return '<div></div>';
34660         var iconStyle = [
34661             'background-image:url(' + _mlySignSprite + ')',
34662             'background-repeat:no-repeat',
34663             'height:' + position.height + 'px',
34664             'width:' + position.width + 'px',
34665             'background-position-x:-' + position.x + 'px',
34666             'background-position-y:-' + position.y + 'px',
34667         ];
34668
34669         return '<div style="' + iconStyle.join(';') +'"></div>';
34670     },
34671
34672
34673     loadImages: function(projection) {
34674         loadTiles('images', apibase + 'images?', projection);
34675         loadTiles('sequences', apibase + 'sequences?', projection);
34676     },
34677
34678
34679     loadSigns: function(context, projection) {
34680         // if we are looking at signs, we'll actually need to fetch images too
34681         loadTiles('images', apibase + 'images?', projection);
34682         loadTiles('objects', apibase + 'objects?', projection);
34683
34684         // load traffic sign defs
34685         if (!_mlySignDefs) {
34686             _mlySignSprite = context.asset('img/traffic-signs/traffic-signs.png');
34687             _mlySignDefs = {};
34688             d3_json(context.asset('img/traffic-signs/traffic-signs.json'), function(err, data) {
34689                 if (err) return;
34690                 _mlySignDefs = data;
34691             });
34692         }
34693     },
34694
34695
34696     loadViewer: function(context) {
34697         // add mly-wrapper
34698         var wrap = d3_select('#photoviewer').selectAll('.mly-wrapper')
34699             .data([0]);
34700
34701         var wrapEnter = wrap.enter()
34702             .append('div')
34703             .attr('id', 'mly')
34704             .attr('class', 'photo-wrapper mly-wrapper')
34705             .classed('hide', true);
34706
34707         wrapEnter
34708             .append('div')
34709             .attr('class', 'photo-attribution fillD');
34710
34711
34712         // load mapillary-viewercss
34713         d3_select('head').selectAll('#mapillary-viewercss')
34714             .data([0])
34715             .enter()
34716             .append('link')
34717             .attr('id', 'mapillary-viewercss')
34718             .attr('rel', 'stylesheet')
34719             .attr('href', context.asset(viewercss));
34720
34721         // load mapillary-viewerjs
34722         d3_select('head').selectAll('#mapillary-viewerjs')
34723             .data([0])
34724             .enter()
34725             .append('script')
34726             .attr('id', 'mapillary-viewerjs')
34727             .attr('src', context.asset(viewerjs));
34728     },
34729
34730
34731     showViewer: function() {
34732         var wrap = d3_select('#photoviewer')
34733             .classed('hide', false);
34734
34735         var isHidden = wrap.selectAll('.photo-wrapper.mly-wrapper.hide').size();
34736
34737         if (isHidden) {
34738             wrap
34739                 .selectAll('.photo-wrapper:not(.mly-wrapper)')
34740                 .classed('hide', true);
34741
34742             wrap
34743                 .selectAll('.photo-wrapper.mly-wrapper')
34744                 .classed('hide', false);
34745
34746             _mlyViewer.resize();
34747         }
34748
34749         return this;
34750     },
34751
34752
34753     hideViewer: function() {
34754         _mlySelectedImage = null;
34755
34756         var viewer = d3_select('#photoviewer');
34757         if (!viewer.empty()) viewer.datum(null);
34758
34759         viewer
34760             .classed('hide', true)
34761             .selectAll('.photo-wrapper')
34762             .classed('hide', true);
34763
34764         d3_selectAll('.viewfield-group, .sequence, .icon-sign')
34765             .classed('selected', false);
34766
34767         return this.setStyles(null, true);
34768     },
34769
34770
34771     parsePagination: parsePagination,
34772
34773
34774     updateViewer: function(imageKey, context) {
34775         if (!imageKey) return this;
34776
34777         if (!_mlyViewer) {
34778             this.initViewer(imageKey, context);
34779         } else {
34780             _mlyViewer.moveToKey(imageKey);
34781         }
34782
34783         return this;
34784     },
34785
34786
34787     initViewer: function(imageKey, context) {
34788         var that = this;
34789         if (Mapillary && imageKey) {
34790             var opts = {
34791                 baseImageSize: 320,
34792                 component: {
34793                     cover: false,
34794                     keyboard: false,
34795                     tag: true
34796                 }
34797             };
34798
34799             _mlyViewer = new Mapillary.Viewer('mly', clientId, imageKey, opts);
34800             _mlyViewer.on('nodechanged', nodeChanged);
34801         }
34802
34803         // nodeChanged: called after the viewer has changed images and is ready.
34804         //
34805         // There is some logic here to batch up clicks into a _mlyClicks array
34806         // because the user might click on a lot of markers quickly and nodechanged
34807         // may be called out of order asychronously.
34808         //
34809         // Clicks are added to the array in `selectedImage` and removed here.
34810         //
34811         function nodeChanged(node) {
34812             _mlyViewer.getComponent('tag').removeAll();  // remove previous detections
34813
34814             var clicks = _mlyClicks;
34815             var index = clicks.indexOf(node.key);
34816             var selectedKey = _mlySelectedImage && _mlySelectedImage.key;
34817
34818             if (index > -1) {              // `nodechanged` initiated from clicking on a marker..
34819                 clicks.splice(index, 1);   // remove the click
34820                 // If `node.key` matches the current _mlySelectedImage, call `selectImage()`
34821                 // one more time to update the detections and attribution..
34822                 if (node.key === selectedKey) {
34823                     that.selectImage(_mlySelectedImage, node.key, true);
34824                 }
34825             } else {             // `nodechanged` initiated from the Mapillary viewer controls..
34826                 var loc = node.computedLatLon ? [node.computedLatLon.lon, node.computedLatLon.lat] : [node.latLon.lon, node.latLon.lat];
34827                 context.map().centerEase(loc);
34828                 that.selectImage(undefined, node.key, true);
34829             }
34830         }
34831     },
34832
34833
34834     // Pass the image datum itself in `d` or the `imageKey` string.
34835     // This allows images to be selected from places that dont have access
34836     // to the full image datum (like the street signs layer or the js viewer)
34837     selectImage: function(d, imageKey, fromViewer) {
34838         if (!d && imageKey) {
34839             // If the user clicked on something that's not an image marker, we
34840             // might get in here.. Cache lookup can fail, e.g. if the user
34841             // clicked a streetsign, but images are loading slowly asynchronously.
34842             // We'll try to carry on anyway if there is no datum.  There just
34843             // might be a delay before user sees detections, captured_at, etc.
34844             d = _mlyCache.images.forImageKey[imageKey];
34845         }
34846
34847         _mlySelectedImage = d;
34848         var viewer = d3_select('#photoviewer');
34849         if (!viewer.empty()) viewer.datum(d);
34850
34851         imageKey = (d && d.key) || imageKey;
34852         if (!fromViewer && imageKey) {
34853             _mlyClicks.push(imageKey);
34854         }
34855
34856         this.setStyles(null, true);
34857
34858         d3_selectAll('.layer-mapillary-signs .icon-sign')
34859             .classed('selected', function(d) {
34860                 return some(d.detections, function(detection) {
34861                     return detection.image_key === imageKey;
34862                 });
34863             });
34864
34865         var wrap = d3_select('#photoviewer .mly-wrapper');
34866         var attribution = wrap.selectAll('.photo-attribution').html('');
34867
34868         if (d) {
34869             if (d.captured_by) {
34870                 attribution
34871                     .append('a')
34872                     .attr('class', 'captured_by')
34873                     .attr('target', '_blank')
34874                     .attr('href', 'https://www.mapillary.com/app/user/' + encodeURIComponent(d.captured_by))
34875                     .text('@' + d.captured_by);
34876
34877                 attribution
34878                     .append('span')
34879                     .text('|');
34880             }
34881
34882             if (d.captured_at) {
34883                 attribution
34884                     .append('span')
34885                     .attr('class', 'captured_at')
34886                     .text(localeTimestamp(d.captured_at));
34887
34888                 attribution
34889                     .append('span')
34890                     .text('|');
34891             }
34892
34893             attribution
34894                 .append('a')
34895                 .attr('class', 'image_link')
34896                 .attr('target', '_blank')
34897                 .attr('href', 'https://www.mapillary.com/app/?pKey=' + encodeURIComponent(d.key) +
34898                     '&focus=photo&lat=' + d.loc[1] + '&lng=' + d.loc[0] + '&z=17')
34899                 .text('mapillary.com');
34900
34901             this.updateDetections(d);
34902         }
34903
34904         return this;
34905     },
34906
34907
34908     getSelectedImage: function() {
34909         return _mlySelectedImage;
34910     },
34911
34912
34913     getSequenceKeyForImage: function(d) {
34914         var imageKey = d && d.key;
34915         return imageKey && _mlyCache.sequences.forImageKey[imageKey];
34916     },
34917
34918
34919     setStyles: function(hovered, reset) {
34920         if (reset) {  // reset all layers
34921             d3_selectAll('.viewfield-group')
34922                 .classed('highlighted', false)
34923                 .classed('hovered', false)
34924                 .classed('selected', false);
34925
34926             d3_selectAll('.sequence')
34927                 .classed('highlighted', false)
34928                 .classed('selected', false);
34929         }
34930
34931         var hoveredImageKey = hovered && hovered.key;
34932         var hoveredSequenceKey = this.getSequenceKeyForImage(hovered);
34933         var hoveredLineString = hoveredSequenceKey && _mlyCache.sequences.lineString[hoveredSequenceKey];
34934         var hoveredImageKeys = (hoveredLineString && hoveredLineString.properties.coordinateProperties.image_keys) || [];
34935
34936         var viewer = d3_select('#photoviewer');
34937         var selected = viewer.empty() ? undefined : viewer.datum();
34938         var selectedImageKey = selected && selected.key;
34939         var selectedSequenceKey = this.getSequenceKeyForImage(selected);
34940         var selectedLineString = selectedSequenceKey && _mlyCache.sequences.lineString[selectedSequenceKey];
34941         var selectedImageKeys = (selectedLineString && selectedLineString.properties.coordinateProperties.image_keys) || [];
34942
34943         // highlight sibling viewfields on either the selected or the hovered sequences
34944         var highlightedImageKeys = union(hoveredImageKeys, selectedImageKeys);
34945
34946         d3_selectAll('.layer-mapillary-images .viewfield-group')
34947             .classed('highlighted', function(d) { return highlightedImageKeys.indexOf(d.key) !== -1; })
34948             .classed('hovered', function(d) { return d.key === hoveredImageKey; })
34949             .classed('selected', function(d) { return d.key === selectedImageKey; });
34950
34951         d3_selectAll('.layer-mapillary-images .sequence')
34952             .classed('highlighted', function(d) { return d.properties.key === hoveredSequenceKey; })
34953             .classed('selected', function(d) { return d.properties.key === selectedSequenceKey; });
34954
34955         return this;
34956     },
34957
34958
34959     updateDetections: function(d) {
34960         if (!_mlyViewer) return;
34961
34962         var imageKey = d && d.key;
34963         var detections = (imageKey && _mlyCache.detections[imageKey]) || [];
34964
34965         forEach(detections, function(data, k) {
34966             if (isEmpty(data)) {
34967                 loadDetection(k);
34968             } else {
34969                 var tag = makeTag(data);
34970                 if (tag) {
34971                     var tagComponent = _mlyViewer.getComponent('tag');
34972                     tagComponent.add([tag]);
34973                 }
34974             }
34975         });
34976
34977
34978         function loadDetection(detectionKey) {
34979             var url = apibase + 'detections/'+
34980                 detectionKey + '?' + utilQsString({
34981                     client_id: clientId,
34982                 });
34983
34984             d3_request(url)
34985                 .mimeType('application/json')
34986                 .response(function(xhr) {
34987                     return JSON.parse(xhr.responseText);
34988                 })
34989                 .get(function(err, data) {
34990                     if (!data || !data.properties) return;
34991
34992                     var imageKey = data.properties.image_key;
34993                     _mlyCache.detections[imageKey][detectionKey] = data;
34994
34995                     var selectedKey = _mlySelectedImage && _mlySelectedImage.key;
34996                     if (imageKey === selectedKey) {
34997                         var tag = makeTag(data);
34998                         if (tag) {
34999                             var tagComponent = _mlyViewer.getComponent('tag');
35000                             tagComponent.add([tag]);
35001                         }
35002                     }
35003                 });
35004         }
35005
35006
35007         function makeTag(data) {
35008             var valueParts = data.properties.value.split('--');
35009             if (valueParts.length !== 3) return;
35010
35011             var text = valueParts[1].replace(/-/g, ' ');
35012             var tag;
35013
35014             // Currently only two shapes <Polygon|Point>
35015             if (data.properties.shape.type === 'Polygon') {
35016                 var polygonGeometry = new Mapillary
35017                     .TagComponent
35018                     .PolygonGeometry(data.properties.shape.coordinates[0]);
35019
35020                 tag = new Mapillary.TagComponent.OutlineTag(
35021                     data.properties.key,
35022                     polygonGeometry,
35023                     {
35024                         text: text,
35025                         textColor: 0xffff00,
35026                         lineColor: 0xffff00,
35027                         lineWidth: 2,
35028                         fillColor: 0xffff00,
35029                         fillOpacity: 0.3,
35030                     }
35031                 );
35032
35033             } else if (data.properties.shape.type === 'Point') {
35034                 var pointGeometry = new Mapillary
35035                     .TagComponent
35036                     .PointGeometry(data.properties.shape.coordinates[0]);
35037
35038                 tag = new Mapillary.TagComponent.SpotTag(
35039                     data.properties.key,
35040                     pointGeometry,
35041                     {
35042                         text: text,
35043                         color: 0xffff00,
35044                         textColor: 0xffff00
35045                     }
35046                 );
35047             }
35048
35049             return tag;
35050         }
35051     },
35052
35053
35054     cache: function() {
35055         return _mlyCache;
35056     },
35057
35058
35059     signDefs: function(_) {
35060         if (!arguments.length) return _mlySignDefs;
35061         _mlySignDefs = _;
35062         return this;
35063     }
35064
35065 };
35066
35067 var apibase$1 = 'https://nominatim.openstreetmap.org/';
35068 var inflight = {};
35069 var nominatimCache;
35070
35071
35072 var serviceNominatim = {
35073
35074     init: function() {
35075         inflight = {};
35076         nominatimCache = rbush_1();
35077     },
35078
35079     reset: function() {
35080         forEach(inflight, function(req) { req.abort(); });
35081         inflight = {};
35082         nominatimCache = rbush_1();
35083     },
35084
35085
35086     countryCode: function (location, callback) {
35087         this.reverse(location, function(err, result) {
35088             if (err) {
35089                 return callback(err);
35090             } else if (result.address) {
35091                 return callback(null, result.address.country_code);
35092             } else {
35093                 return callback('Unable to geocode', null);
35094             }
35095         });
35096     },
35097
35098
35099     reverse: function (location, callback) {
35100         var cached = nominatimCache.search(
35101             { minX: location[0], minY: location[1], maxX: location[0], maxY: location[1] }
35102         );
35103
35104         if (cached.length > 0) {
35105             return callback(null, cached[0].data);
35106         }
35107
35108         var params = { zoom: 13, format: 'json', addressdetails: 1, lat: location[1], lon: location[0] };
35109         var url = apibase$1 + 'reverse?' + utilQsString(params);
35110         if (inflight[url]) return;
35111
35112         inflight[url] = d3_json(url, function(err, result) {
35113             delete inflight[url];
35114
35115             if (err) {
35116                 return callback(err);
35117             } else if (result && result.error) {
35118                 return callback(result.error);
35119             }
35120
35121             var extent = geoExtent(location).padByMeters(200);
35122             nominatimCache.insert(assign(extent.bbox(), {data: result}));
35123
35124             callback(null, result);
35125         });
35126     },
35127
35128
35129     search: function (val, callback) {
35130         var searchVal = encodeURIComponent(val);
35131         var url = apibase$1 + 'search/' + searchVal + '?limit=10&format=json';
35132         if (inflight[url]) return;
35133
35134         inflight[url] = d3_json(url, function(err, result) {
35135             delete inflight[url];
35136             callback(err, result);
35137         });
35138     }
35139
35140 };
35141
35142 var apibase$2 = 'https://openstreetcam.org';
35143 var maxResults$1 = 1000;
35144 var tileZoom$1 = 14;
35145 var dispatch$2 = dispatch('loadedImages');
35146 var _oscCache;
35147 var _oscSelectedImage;
35148
35149
35150 function abortRequest$1(i) {
35151     i.abort();
35152 }
35153
35154
35155 function nearNullIsland$1(x, y, z) {
35156     if (z >= 7) {
35157         var center = Math.pow(2, z - 1),
35158             width = Math.pow(2, z - 6),
35159             min = center - (width / 2),
35160             max = center + (width / 2) - 1;
35161         return x >= min && x <= max && y >= min && y <= max;
35162     }
35163     return false;
35164 }
35165
35166
35167 function maxPageAtZoom$1(z) {
35168     if (z < 15)   return 2;
35169     if (z === 15) return 5;
35170     if (z === 16) return 10;
35171     if (z === 17) return 20;
35172     if (z === 18) return 40;
35173     if (z > 18)   return 80;
35174 }
35175
35176
35177 function getTiles$1(projection) {
35178     var s = projection.scale() * 2 * Math.PI,
35179         z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
35180         ts = 256 * Math.pow(2, z - tileZoom$1),
35181         origin = [
35182             s / 2 - projection.translate()[0],
35183             s / 2 - projection.translate()[1]];
35184
35185     return d3geoTile()
35186         .scaleExtent([tileZoom$1, tileZoom$1])
35187         .scale(s)
35188         .size(projection.clipExtent()[1])
35189         .translate(projection.translate())()
35190         .map(function(tile) {
35191             var x = tile[0] * ts - origin[0],
35192                 y = tile[1] * ts - origin[1];
35193
35194             return {
35195                 id: tile.toString(),
35196                 xyz: tile,
35197                 extent: geoExtent(
35198                     projection.invert([x, y + ts]),
35199                     projection.invert([x + ts, y])
35200                 )
35201             };
35202         });
35203 }
35204
35205
35206 function loadTiles$1(which, url, projection) {
35207     var s = projection.scale() * 2 * Math.PI,
35208         currZoom = Math.floor(Math.max(Math.log(s) / Math.log(2) - 8, 0));
35209
35210     var tiles = getTiles$1(projection).filter(function(t) {
35211             return !nearNullIsland$1(t.xyz[0], t.xyz[1], t.xyz[2]);
35212         });
35213
35214     filter(which.inflight, function(v, k) {
35215         var wanted = find$1(tiles, function(tile) { return k === (tile.id + ',0'); });
35216         if (!wanted) delete which.inflight[k];
35217         return !wanted;
35218     }).map(abortRequest$1);
35219
35220     tiles.forEach(function(tile) {
35221         loadNextTilePage$1(which, currZoom, url, tile);
35222     });
35223 }
35224
35225
35226 function loadNextTilePage$1(which, currZoom, url, tile) {
35227     var cache = _oscCache[which];
35228     var bbox = tile.extent.bbox();
35229     var maxPages = maxPageAtZoom$1(currZoom);
35230     var nextPage = cache.nextPage[tile.id] || 1;
35231     var params = utilQsString({
35232             ipp: maxResults$1,
35233             page: nextPage,
35234             // client_id: clientId,
35235             bbTopLeft: [bbox.maxY, bbox.minX].join(','),
35236             bbBottomRight: [bbox.minY, bbox.maxX].join(',')
35237         }, true);
35238
35239     if (nextPage > maxPages) return;
35240
35241     var id = tile.id + ',' + String(nextPage);
35242     if (cache.loaded[id] || cache.inflight[id]) return;
35243
35244     cache.inflight[id] = d3_request(url)
35245         .mimeType('application/json')
35246         .header('Content-type', 'application/x-www-form-urlencoded')
35247         .response(function(xhr) { return JSON.parse(xhr.responseText); })
35248         .post(params, function(err, data) {
35249             cache.loaded[id] = true;
35250             delete cache.inflight[id];
35251             if (err || !data.currentPageItems || !data.currentPageItems.length) return;
35252
35253             function localeDateString(s) {
35254                 if (!s) return null;
35255                 var d = new Date(s);
35256                 if (isNaN(d.getTime())) return null;
35257                 return d.toLocaleDateString();
35258             }
35259
35260             var features = data.currentPageItems.map(function(item) {
35261                 var loc = [+item.lng, +item.lat],
35262                     d;
35263
35264                 if (which === 'images') {
35265                     d = {
35266                         loc: loc,
35267                         key: item.id,
35268                         ca: +item.heading,
35269                         captured_at: localeDateString(item.shot_date || item.date_added),
35270                         captured_by: item.username,
35271                         imagePath: item.lth_name,
35272                         sequence_id: item.sequence_id,
35273                         sequence_index: +item.sequence_index
35274                     };
35275
35276                     // cache sequence info
35277                     var seq = _oscCache.sequences[d.sequence_id];
35278                     if (!seq) {
35279                         seq = { rotation: 0, images: [] };
35280                         _oscCache.sequences[d.sequence_id] = seq;
35281                     }
35282                     seq.images[d.sequence_index] = d;
35283                 }
35284
35285                 return {
35286                     minX: loc[0], minY: loc[1], maxX: loc[0], maxY: loc[1], data: d
35287                 };
35288             });
35289
35290             cache.rtree.load(features);
35291
35292             if (which === 'images') {
35293                 dispatch$2.call('loadedImages');
35294             }
35295
35296             if (data.currentPageItems.length === maxResults$1) {  // more pages to load
35297                 cache.nextPage[tile.id] = nextPage + 1;
35298                 loadNextTilePage$1(which, currZoom, url, tile);
35299             } else {
35300                 cache.nextPage[tile.id] = Infinity;     // no more pages to load
35301             }
35302         });
35303 }
35304
35305
35306 // partition viewport into `psize` x `psize` regions
35307 function partitionViewport$1(psize, projection) {
35308     var dimensions = projection.clipExtent()[1];
35309     psize = psize || 16;
35310     var cols = d3_range(0, dimensions[0], psize),
35311         rows = d3_range(0, dimensions[1], psize),
35312         partitions = [];
35313
35314     rows.forEach(function(y) {
35315         cols.forEach(function(x) {
35316             var min = [x, y + psize],
35317                 max = [x + psize, y];
35318             partitions.push(
35319                 geoExtent(projection.invert(min), projection.invert(max)));
35320         });
35321     });
35322
35323     return partitions;
35324 }
35325
35326
35327 // no more than `limit` results per partition.
35328 function searchLimited$1(psize, limit, projection, rtree) {
35329     limit = limit || 3;
35330
35331     var partitions = partitionViewport$1(psize, projection);
35332     var results;
35333
35334     results = flatten(map$4(partitions, function(extent) {
35335         return rtree.search(extent.bbox())
35336             .slice(0, limit)
35337             .map(function(d) { return d.data; });
35338     }));
35339     return results;
35340 }
35341
35342
35343
35344 var serviceOpenstreetcam = {
35345
35346     init: function() {
35347         if (!_oscCache) {
35348             this.reset();
35349         }
35350
35351         this.event = utilRebind(this, dispatch$2, 'on');
35352     },
35353
35354     reset: function() {
35355         var cache = _oscCache;
35356
35357         if (cache) {
35358             if (cache.images && cache.images.inflight) {
35359                 forEach(cache.images.inflight, abortRequest$1);
35360             }
35361         }
35362
35363         _oscCache = {
35364             images: { inflight: {}, loaded: {}, nextPage: {}, rtree: rbush_1() },
35365             sequences: {}
35366         };
35367
35368         _oscSelectedImage = null;
35369     },
35370
35371
35372     images: function(projection) {
35373         var psize = 16, limit = 3;
35374         return searchLimited$1(psize, limit, projection, _oscCache.images.rtree);
35375     },
35376
35377
35378     sequences: function(projection) {
35379         var viewport = projection.clipExtent();
35380         var min = [viewport[0][0], viewport[1][1]];
35381         var max = [viewport[1][0], viewport[0][1]];
35382         var bbox = geoExtent(projection.invert(min), projection.invert(max)).bbox();
35383         var sequenceKeys = {};
35384
35385         // all sequences for images in viewport
35386         _oscCache.images.rtree.search(bbox)
35387             .forEach(function(d) { sequenceKeys[d.data.sequence_id] = true; });
35388
35389         // make linestrings from those sequences
35390         var lineStrings = [];
35391         Object.keys(sequenceKeys)
35392             .forEach(function(sequenceKey) {
35393                 var seq = _oscCache.sequences[sequenceKey];
35394                 var images = seq && seq.images;
35395                 if (images) {
35396                     lineStrings.push({
35397                         type: 'LineString',
35398                         coordinates: images.map(function (d) { return d.loc; }).filter(Boolean),
35399                         properties: { key: sequenceKey }
35400                     });
35401                 }
35402             });
35403         return lineStrings;
35404     },
35405
35406
35407     loadImages: function(projection) {
35408         var url = apibase$2 + '/1.0/list/nearby-photos/';
35409         loadTiles$1('images', url, projection);
35410     },
35411
35412
35413     loadViewer: function(context) {
35414         var that = this;
35415
35416         // add osc-wrapper
35417         var wrap = d3_select('#photoviewer').selectAll('.osc-wrapper')
35418             .data([0]);
35419
35420         var wrapEnter = wrap.enter()
35421             .append('div')
35422             .attr('class', 'photo-wrapper osc-wrapper')
35423             .classed('hide', true);
35424
35425         wrapEnter
35426             .append('div')
35427             .attr('class', 'photo-attribution fillD');
35428
35429         var controlsEnter = wrapEnter
35430             .append('div')
35431             .attr('class', 'osc-controls-wrap')
35432             .append('div')
35433             .attr('class', 'osc-controls');
35434
35435         controlsEnter
35436             .append('button')
35437             .on('click.back', step(-1))
35438             .text('◄');
35439
35440         controlsEnter
35441             .append('button')
35442             .on('click.rotate-ccw', rotate(-90))
35443             .text('⤿');
35444
35445         controlsEnter
35446             .append('button')
35447             .on('click.rotate-cw', rotate(90))
35448             .text('⤾');
35449
35450         controlsEnter
35451             .append('button')
35452             .on('click.forward', step(1))
35453             .text('►');
35454
35455
35456         function rotate(deg) {
35457             return function() {
35458                 if (!_oscSelectedImage) return;
35459                 var sequenceKey = _oscSelectedImage.sequence_id;
35460                 var sequence = _oscCache.sequences[sequenceKey];
35461                 if (!sequence) return;
35462
35463                 var r = sequence.rotation || 0;
35464                 r += deg;
35465                 sequence.rotation = r;
35466
35467                 d3_select('#photoviewer .osc-wrapper .osc-image')
35468                     .transition()
35469                     .duration(100)
35470                     .style('transform', 'rotate(' + r + 'deg)');
35471             };
35472         }
35473
35474         function step(stepBy) {
35475             return function() {
35476                 if (!_oscSelectedImage) return;
35477                 var sequenceKey = _oscSelectedImage.sequence_id;
35478                 var sequence = _oscCache.sequences[sequenceKey];
35479                 if (!sequence) return;
35480
35481                 var nextIndex = _oscSelectedImage.sequence_index + stepBy;
35482                 var nextImage = sequence.images[nextIndex];
35483                 if (!nextImage) return;
35484
35485                 context.map().centerEase(nextImage.loc);
35486
35487                 that
35488                     .selectImage(nextImage)
35489                     .updateViewer(nextImage);
35490             };
35491         }
35492     },
35493
35494
35495     showViewer: function() {
35496         var viewer = d3_select('#photoviewer')
35497             .classed('hide', false);
35498
35499         var isHidden = viewer.selectAll('.photo-wrapper.osc-wrapper.hide').size();
35500
35501         if (isHidden) {
35502             viewer
35503                 .selectAll('.photo-wrapper:not(.osc-wrapper)')
35504                 .classed('hide', true);
35505
35506             viewer
35507                 .selectAll('.photo-wrapper.osc-wrapper')
35508                 .classed('hide', false);
35509         }
35510
35511         return this;
35512     },
35513
35514
35515     hideViewer: function() {
35516         _oscSelectedImage = null;
35517
35518         var viewer = d3_select('#photoviewer');
35519         if (!viewer.empty()) viewer.datum(null);
35520
35521         viewer
35522             .classed('hide', true)
35523             .selectAll('.photo-wrapper')
35524             .classed('hide', true);
35525
35526         d3_selectAll('.viewfield-group, .sequence, .icon-sign')
35527             .classed('selected', false);
35528
35529         return this.setStyles(null, true);
35530     },
35531
35532
35533     updateViewer: function(d) {
35534         var wrap = d3_select('#photoviewer .osc-wrapper');
35535
35536         wrap.selectAll('.osc-image')
35537             .remove();
35538
35539         if (d) {
35540             var sequence = _oscCache.sequences[d.sequence_id];
35541             var r = (sequence && sequence.rotation) || 0;
35542
35543             wrap.append('img')
35544                 .attr('class', 'osc-image')
35545                 .style('transform', 'rotate(' + r + 'deg)')
35546                 .attr('src', apibase$2 + '/' + d.imagePath);
35547
35548             var attribution = wrap.selectAll('.photo-attribution').html('');
35549
35550             if (d.captured_by) {
35551                 attribution
35552                     .append('a')
35553                     .attr('class', 'captured_by')
35554                     .attr('target', '_blank')
35555                     .attr('href', 'https://openstreetcam.org/user/' + encodeURIComponent(d.captured_by))
35556                     .text('@' + d.captured_by);
35557
35558                 attribution
35559                     .append('span')
35560                     .text('|');
35561             }
35562
35563             if (d.captured_at) {
35564                 attribution
35565                     .append('span')
35566                     .attr('class', 'captured_at')
35567                     .text(d.captured_at);
35568
35569                 attribution
35570                     .append('span')
35571                     .text('|');
35572             }
35573
35574             attribution
35575                 .append('a')
35576                 .attr('class', 'image_link')
35577                 .attr('target', '_blank')
35578                 .attr('href', 'https://openstreetcam.org/details/' + d.sequence_id + '/' + d.sequence_index)
35579                 .text('openstreetcam.org');
35580         }
35581         return this;
35582     },
35583
35584
35585     selectImage: function(d) {
35586         _oscSelectedImage = d;
35587         var viewer = d3_select('#photoviewer');
35588         if (!viewer.empty()) viewer.datum(d);
35589
35590         this.setStyles(null, true);
35591
35592         d3_selectAll('.icon-sign')
35593             .classed('selected', false);
35594
35595         return this;
35596     },
35597
35598
35599     getSelectedImage: function() {
35600         return _oscSelectedImage;
35601     },
35602
35603
35604     getSequenceKeyForImage: function(d) {
35605         return d && d.sequence_id;
35606     },
35607
35608
35609     setStyles: function(hovered, reset) {
35610         if (reset) {  // reset all layers
35611             d3_selectAll('.viewfield-group')
35612                 .classed('highlighted', false)
35613                 .classed('hovered', false)
35614                 .classed('selected', false);
35615
35616             d3_selectAll('.sequence')
35617                 .classed('highlighted', false)
35618                 .classed('selected', false);
35619         }
35620
35621         var hoveredImageKey = hovered && hovered.key;
35622         var hoveredSequenceKey = this.getSequenceKeyForImage(hovered);
35623         var hoveredSequence = hoveredSequenceKey && _oscCache.sequences[hoveredSequenceKey];
35624         var hoveredImageKeys = (hoveredSequence && hoveredSequence.images.map(function (d) { return d.key; })) || [];
35625
35626         var viewer = d3_select('#photoviewer');
35627         var selected = viewer.empty() ? undefined : viewer.datum();
35628         var selectedImageKey = selected && selected.key;
35629         var selectedSequenceKey = this.getSequenceKeyForImage(selected);
35630         var selectedSequence = selectedSequenceKey && _oscCache.sequences[selectedSequenceKey];
35631         var selectedImageKeys = (selectedSequence && selectedSequence.images.map(function (d) { return d.key; })) || [];
35632
35633         // highlight sibling viewfields on either the selected or the hovered sequences
35634         var highlightedImageKeys = union(hoveredImageKeys, selectedImageKeys);
35635
35636         d3_selectAll('.layer-openstreetcam-images .viewfield-group')
35637             .classed('highlighted', function(d) { return highlightedImageKeys.indexOf(d.key) !== -1; })
35638             .classed('hovered', function(d) { return d.key === hoveredImageKey; })
35639             .classed('selected', function(d) { return d.key === selectedImageKey; });
35640
35641         d3_selectAll('.layer-openstreetcam-images .sequence')
35642             .classed('highlighted', function(d) { return d.properties.key === hoveredSequenceKey; })
35643             .classed('selected', function(d) { return d.properties.key === selectedSequenceKey; });
35644
35645         return this;
35646     },
35647
35648
35649     cache: function() {
35650         return _oscCache;
35651     }
35652
35653 };
35654
35655 /* Built-in method references for those with the same name as other `lodash` methods. */
35656 var nativeCeil = Math.ceil;
35657 var nativeMax$4 = Math.max;
35658
35659 /**
35660  * Creates an array of elements split into groups the length of `size`.
35661  * If `array` can't be split evenly, the final chunk will be the remaining
35662  * elements.
35663  *
35664  * @static
35665  * @memberOf _
35666  * @since 3.0.0
35667  * @category Array
35668  * @param {Array} array The array to process.
35669  * @param {number} [size=1] The length of each chunk
35670  * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
35671  * @returns {Array} Returns the new array of chunks.
35672  * @example
35673  *
35674  * _.chunk(['a', 'b', 'c', 'd'], 2);
35675  * // => [['a', 'b'], ['c', 'd']]
35676  *
35677  * _.chunk(['a', 'b', 'c', 'd'], 3);
35678  * // => [['a', 'b', 'c'], ['d']]
35679  */
35680 function chunk(array, size, guard) {
35681   if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
35682     size = 1;
35683   } else {
35684     size = nativeMax$4(toInteger(size), 0);
35685   }
35686   var length = array == null ? 0 : array.length;
35687   if (!length || size < 1) {
35688     return [];
35689   }
35690   var index = 0,
35691       resIndex = 0,
35692       result = Array(nativeCeil(length / size));
35693
35694   while (index < length) {
35695     result[resIndex++] = baseSlice(array, index, (index += size));
35696   }
35697   return result;
35698 }
35699
35700 var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
35701
35702
35703
35704
35705
35706 function createCommonjsModule(fn, module) {
35707         return module = { exports: {} }, fn(module, module.exports), module.exports;
35708 }
35709
35710 var hashes = createCommonjsModule(function (module, exports) {
35711 /**
35712  * jshashes - https://github.com/h2non/jshashes
35713  * Released under the "New BSD" license
35714  *
35715  * Algorithms specification:
35716  *
35717  * MD5 - http://www.ietf.org/rfc/rfc1321.txt
35718  * RIPEMD-160 - http://homes.esat.kuleuven.be/~bosselae/ripemd160.html
35719  * SHA1   - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
35720  * SHA256 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
35721  * SHA512 - http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
35722  * HMAC - http://www.ietf.org/rfc/rfc2104.txt
35723  */
35724 (function() {
35725   var Hashes;
35726
35727   function utf8Encode(str) {
35728     var x, y, output = '',
35729       i = -1,
35730       l;
35731
35732     if (str && str.length) {
35733       l = str.length;
35734       while ((i += 1) < l) {
35735         /* Decode utf-16 surrogate pairs */
35736         x = str.charCodeAt(i);
35737         y = i + 1 < l ? str.charCodeAt(i + 1) : 0;
35738         if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
35739           x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
35740           i += 1;
35741         }
35742         /* Encode output as utf-8 */
35743         if (x <= 0x7F) {
35744           output += String.fromCharCode(x);
35745         } else if (x <= 0x7FF) {
35746           output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F),
35747             0x80 | (x & 0x3F));
35748         } else if (x <= 0xFFFF) {
35749           output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
35750             0x80 | ((x >>> 6) & 0x3F),
35751             0x80 | (x & 0x3F));
35752         } else if (x <= 0x1FFFFF) {
35753           output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
35754             0x80 | ((x >>> 12) & 0x3F),
35755             0x80 | ((x >>> 6) & 0x3F),
35756             0x80 | (x & 0x3F));
35757         }
35758       }
35759     }
35760     return output;
35761   }
35762
35763   function utf8Decode(str) {
35764     var i, ac, c1, c2, c3, arr = [],
35765       l;
35766     i = ac = c1 = c2 = c3 = 0;
35767
35768     if (str && str.length) {
35769       l = str.length;
35770       str += '';
35771
35772       while (i < l) {
35773         c1 = str.charCodeAt(i);
35774         ac += 1;
35775         if (c1 < 128) {
35776           arr[ac] = String.fromCharCode(c1);
35777           i += 1;
35778         } else if (c1 > 191 && c1 < 224) {
35779           c2 = str.charCodeAt(i + 1);
35780           arr[ac] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));
35781           i += 2;
35782         } else {
35783           c2 = str.charCodeAt(i + 1);
35784           c3 = str.charCodeAt(i + 2);
35785           arr[ac] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
35786           i += 3;
35787         }
35788       }
35789     }
35790     return arr.join('');
35791   }
35792
35793   /**
35794    * Add integers, wrapping at 2^32. This uses 16-bit operations internally
35795    * to work around bugs in some JS interpreters.
35796    */
35797
35798   function safe_add(x, y) {
35799     var lsw = (x & 0xFFFF) + (y & 0xFFFF),
35800       msw = (x >> 16) + (y >> 16) + (lsw >> 16);
35801     return (msw << 16) | (lsw & 0xFFFF);
35802   }
35803
35804   /**
35805    * Bitwise rotate a 32-bit number to the left.
35806    */
35807
35808   function bit_rol(num, cnt) {
35809     return (num << cnt) | (num >>> (32 - cnt));
35810   }
35811
35812   /**
35813    * Convert a raw string to a hex string
35814    */
35815
35816   function rstr2hex(input, hexcase) {
35817     var hex_tab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef',
35818       output = '',
35819       x, i = 0,
35820       l = input.length;
35821     for (; i < l; i += 1) {
35822       x = input.charCodeAt(i);
35823       output += hex_tab.charAt((x >>> 4) & 0x0F) + hex_tab.charAt(x & 0x0F);
35824     }
35825     return output;
35826   }
35827
35828   /**
35829    * Encode a string as utf-16
35830    */
35831
35832   function binb2rstr(input) {
35833     var i, l = input.length * 32,
35834       output = '';
35835     for (i = 0; i < l; i += 8) {
35836       output += String.fromCharCode((input[i >> 5] >>> (24 - i % 32)) & 0xFF);
35837     }
35838     return output;
35839   }
35840
35841   /**
35842    * Convert an array of little-endian words to a string
35843    */
35844
35845   function binl2rstr(input) {
35846     var i, l = input.length * 32,
35847       output = '';
35848     for (i = 0; i < l; i += 8) {
35849       output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
35850     }
35851     return output;
35852   }
35853
35854   /**
35855    * Convert a raw string to an array of little-endian words
35856    * Characters >255 have their high-byte silently ignored.
35857    */
35858
35859   function rstr2binl(input) {
35860     var i, l = input.length * 8,
35861       output = Array(input.length >> 2),
35862       lo = output.length;
35863     for (i = 0; i < lo; i += 1) {
35864       output[i] = 0;
35865     }
35866     for (i = 0; i < l; i += 8) {
35867       output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (i % 32);
35868     }
35869     return output;
35870   }
35871
35872   /**
35873    * Convert a raw string to an array of big-endian words
35874    * Characters >255 have their high-byte silently ignored.
35875    */
35876
35877   function rstr2binb(input) {
35878     var i, l = input.length * 8,
35879       output = Array(input.length >> 2),
35880       lo = output.length;
35881     for (i = 0; i < lo; i += 1) {
35882       output[i] = 0;
35883     }
35884     for (i = 0; i < l; i += 8) {
35885       output[i >> 5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
35886     }
35887     return output;
35888   }
35889
35890   /**
35891    * Convert a raw string to an arbitrary string encoding
35892    */
35893
35894   function rstr2any(input, encoding) {
35895     var divisor = encoding.length,
35896       remainders = Array(),
35897       i, q, x, ld, quotient, dividend, output, full_length;
35898
35899     /* Convert to an array of 16-bit big-endian values, forming the dividend */
35900     dividend = Array(Math.ceil(input.length / 2));
35901     ld = dividend.length;
35902     for (i = 0; i < ld; i += 1) {
35903       dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
35904     }
35905
35906     /**
35907      * Repeatedly perform a long division. The binary array forms the dividend,
35908      * the length of the encoding is the divisor. Once computed, the quotient
35909      * forms the dividend for the next step. We stop when the dividend is zerHashes.
35910      * All remainders are stored for later use.
35911      */
35912     while (dividend.length > 0) {
35913       quotient = Array();
35914       x = 0;
35915       for (i = 0; i < dividend.length; i += 1) {
35916         x = (x << 16) + dividend[i];
35917         q = Math.floor(x / divisor);
35918         x -= q * divisor;
35919         if (quotient.length > 0 || q > 0) {
35920           quotient[quotient.length] = q;
35921         }
35922       }
35923       remainders[remainders.length] = x;
35924       dividend = quotient;
35925     }
35926
35927     /* Convert the remainders to the output string */
35928     output = '';
35929     for (i = remainders.length - 1; i >= 0; i--) {
35930       output += encoding.charAt(remainders[i]);
35931     }
35932
35933     /* Append leading zero equivalents */
35934     full_length = Math.ceil(input.length * 8 / (Math.log(encoding.length) / Math.log(2)));
35935     for (i = output.length; i < full_length; i += 1) {
35936       output = encoding[0] + output;
35937     }
35938     return output;
35939   }
35940
35941   /**
35942    * Convert a raw string to a base-64 string
35943    */
35944
35945   function rstr2b64(input, b64pad) {
35946     var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
35947       output = '',
35948       len = input.length,
35949       i, j, triplet;
35950     b64pad = b64pad || '=';
35951     for (i = 0; i < len; i += 3) {
35952       triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
35953       for (j = 0; j < 4; j += 1) {
35954         if (i * 8 + j * 6 > input.length * 8) {
35955           output += b64pad;
35956         } else {
35957           output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
35958         }
35959       }
35960     }
35961     return output;
35962   }
35963
35964   Hashes = {
35965     /**
35966      * @property {String} version
35967      * @readonly
35968      */
35969     VERSION: '1.0.6',
35970     /**
35971      * @member Hashes
35972      * @class Base64
35973      * @constructor
35974      */
35975     Base64: function() {
35976       // private properties
35977       var tab = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
35978         pad = '=', // default pad according with the RFC standard
35979         url = false, // URL encoding support @todo
35980         utf8 = true; // by default enable UTF-8 support encoding
35981
35982       // public method for encoding
35983       this.encode = function(input) {
35984         var i, j, triplet,
35985           output = '',
35986           len = input.length;
35987
35988         pad = pad || '=';
35989         input = (utf8) ? utf8Encode(input) : input;
35990
35991         for (i = 0; i < len; i += 3) {
35992           triplet = (input.charCodeAt(i) << 16) | (i + 1 < len ? input.charCodeAt(i + 1) << 8 : 0) | (i + 2 < len ? input.charCodeAt(i + 2) : 0);
35993           for (j = 0; j < 4; j += 1) {
35994             if (i * 8 + j * 6 > len * 8) {
35995               output += pad;
35996             } else {
35997               output += tab.charAt((triplet >>> 6 * (3 - j)) & 0x3F);
35998             }
35999           }
36000         }
36001         return output;
36002       };
36003
36004       // public method for decoding
36005       this.decode = function(input) {
36006         // var b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
36007         var i, o1, o2, o3, h1, h2, h3, h4, bits, ac,
36008           dec = '',
36009           arr = [];
36010         if (!input) {
36011           return input;
36012         }
36013
36014         i = ac = 0;
36015         input = input.replace(new RegExp('\\' + pad, 'gi'), ''); // use '='
36016         //input += '';
36017
36018         do { // unpack four hexets into three octets using index points in b64
36019           h1 = tab.indexOf(input.charAt(i += 1));
36020           h2 = tab.indexOf(input.charAt(i += 1));
36021           h3 = tab.indexOf(input.charAt(i += 1));
36022           h4 = tab.indexOf(input.charAt(i += 1));
36023
36024           bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
36025
36026           o1 = bits >> 16 & 0xff;
36027           o2 = bits >> 8 & 0xff;
36028           o3 = bits & 0xff;
36029           ac += 1;
36030
36031           if (h3 === 64) {
36032             arr[ac] = String.fromCharCode(o1);
36033           } else if (h4 === 64) {
36034             arr[ac] = String.fromCharCode(o1, o2);
36035           } else {
36036             arr[ac] = String.fromCharCode(o1, o2, o3);
36037           }
36038         } while (i < input.length);
36039
36040         dec = arr.join('');
36041         dec = (utf8) ? utf8Decode(dec) : dec;
36042
36043         return dec;
36044       };
36045
36046       // set custom pad string
36047       this.setPad = function(str) {
36048         pad = str || pad;
36049         return this;
36050       };
36051       // set custom tab string characters
36052       this.setTab = function(str) {
36053         tab = str || tab;
36054         return this;
36055       };
36056       this.setUTF8 = function(bool) {
36057         if (typeof bool === 'boolean') {
36058           utf8 = bool;
36059         }
36060         return this;
36061       };
36062     },
36063
36064     /**
36065      * CRC-32 calculation
36066      * @member Hashes
36067      * @method CRC32
36068      * @static
36069      * @param {String} str Input String
36070      * @return {String}
36071      */
36072     CRC32: function(str) {
36073       var crc = 0,
36074         x = 0,
36075         y = 0,
36076         table, i, iTop;
36077       str = utf8Encode(str);
36078
36079       table = [
36080         '00000000 77073096 EE0E612C 990951BA 076DC419 706AF48F E963A535 9E6495A3 0EDB8832 ',
36081         '79DCB8A4 E0D5E91E 97D2D988 09B64C2B 7EB17CBD E7B82D07 90BF1D91 1DB71064 6AB020F2 F3B97148 ',
36082         '84BE41DE 1ADAD47D 6DDDE4EB F4D4B551 83D385C7 136C9856 646BA8C0 FD62F97A 8A65C9EC 14015C4F ',
36083         '63066CD9 FA0F3D63 8D080DF5 3B6E20C8 4C69105E D56041E4 A2677172 3C03E4D1 4B04D447 D20D85FD ',
36084         'A50AB56B 35B5A8FA 42B2986C DBBBC9D6 ACBCF940 32D86CE3 45DF5C75 DCD60DCF ABD13D59 26D930AC ',
36085         '51DE003A C8D75180 BFD06116 21B4F4B5 56B3C423 CFBA9599 B8BDA50F 2802B89E 5F058808 C60CD9B2 ',
36086         'B10BE924 2F6F7C87 58684C11 C1611DAB B6662D3D 76DC4190 01DB7106 98D220BC EFD5102A 71B18589 ',
36087         '06B6B51F 9FBFE4A5 E8B8D433 7807C9A2 0F00F934 9609A88E E10E9818 7F6A0DBB 086D3D2D 91646C97 ',
36088         'E6635C01 6B6B51F4 1C6C6162 856530D8 F262004E 6C0695ED 1B01A57B 8208F4C1 F50FC457 65B0D9C6 ',
36089         '12B7E950 8BBEB8EA FCB9887C 62DD1DDF 15DA2D49 8CD37CF3 FBD44C65 4DB26158 3AB551CE A3BC0074 ',
36090         'D4BB30E2 4ADFA541 3DD895D7 A4D1C46D D3D6F4FB 4369E96A 346ED9FC AD678846 DA60B8D0 44042D73 ',
36091         '33031DE5 AA0A4C5F DD0D7CC9 5005713C 270241AA BE0B1010 C90C2086 5768B525 206F85B3 B966D409 ',
36092         'CE61E49F 5EDEF90E 29D9C998 B0D09822 C7D7A8B4 59B33D17 2EB40D81 B7BD5C3B C0BA6CAD EDB88320 ',
36093         '9ABFB3B6 03B6E20C 74B1D29A EAD54739 9DD277AF 04DB2615 73DC1683 E3630B12 94643B84 0D6D6A3E ',
36094         '7A6A5AA8 E40ECF0B 9309FF9D 0A00AE27 7D079EB1 F00F9344 8708A3D2 1E01F268 6906C2FE F762575D ',
36095         '806567CB 196C3671 6E6B06E7 FED41B76 89D32BE0 10DA7A5A 67DD4ACC F9B9DF6F 8EBEEFF9 17B7BE43 ',
36096         '60B08ED5 D6D6A3E8 A1D1937E 38D8C2C4 4FDFF252 D1BB67F1 A6BC5767 3FB506DD 48B2364B D80D2BDA ',
36097         'AF0A1B4C 36034AF6 41047A60 DF60EFC3 A867DF55 316E8EEF 4669BE79 CB61B38C BC66831A 256FD2A0 ',
36098         '5268E236 CC0C7795 BB0B4703 220216B9 5505262F C5BA3BBE B2BD0B28 2BB45A92 5CB36A04 C2D7FFA7 ',
36099         'B5D0CF31 2CD99E8B 5BDEAE1D 9B64C2B0 EC63F226 756AA39C 026D930A 9C0906A9 EB0E363F 72076785 ',
36100         '05005713 95BF4A82 E2B87A14 7BB12BAE 0CB61B38 92D28E9B E5D5BE0D 7CDCEFB7 0BDBDF21 86D3D2D4 ',
36101         'F1D4E242 68DDB3F8 1FDA836E 81BE16CD F6B9265B 6FB077E1 18B74777 88085AE6 FF0F6A70 66063BCA ',
36102         '11010B5C 8F659EFF F862AE69 616BFFD3 166CCF45 A00AE278 D70DD2EE 4E048354 3903B3C2 A7672661 ',
36103         'D06016F7 4969474D 3E6E77DB AED16A4A D9D65ADC 40DF0B66 37D83BF0 A9BCAE53 DEBB9EC5 47B2CF7F ',
36104         '30B5FFE9 BDBDF21C CABAC28A 53B39330 24B4A3A6 BAD03605 CDD70693 54DE5729 23D967BF B3667A2E ',
36105         'C4614AB8 5D681B02 2A6F2B94 B40BBE37 C30C8EA1 5A05DF1B 2D02EF8D'
36106       ].join('');
36107
36108       crc = crc ^ (-1);
36109       for (i = 0, iTop = str.length; i < iTop; i += 1) {
36110         y = (crc ^ str.charCodeAt(i)) & 0xFF;
36111         x = '0x' + table.substr(y * 9, 8);
36112         crc = (crc >>> 8) ^ x;
36113       }
36114       // always return a positive number (that's what >>> 0 does)
36115       return (crc ^ (-1)) >>> 0;
36116     },
36117     /**
36118      * @member Hashes
36119      * @class MD5
36120      * @constructor
36121      * @param {Object} [config]
36122      *
36123      * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
36124      * Digest Algorithm, as defined in RFC 1321.
36125      * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009
36126      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
36127      * See <http://pajhome.org.uk/crypt/md5> for more infHashes.
36128      */
36129     MD5: function(options) {
36130       /**
36131        * Private config properties. You may need to tweak these to be compatible with
36132        * the server-side, but the defaults work in most cases.
36133        * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
36134        */
36135       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
36136         b64pad = (options && typeof options.pad === 'string') ? options.pad : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
36137         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
36138
36139       // privileged (public) methods
36140       this.hex = function(s) {
36141         return rstr2hex(rstr(s, utf8), hexcase);
36142       };
36143       this.b64 = function(s) {
36144         return rstr2b64(rstr(s), b64pad);
36145       };
36146       this.any = function(s, e) {
36147         return rstr2any(rstr(s, utf8), e);
36148       };
36149       this.raw = function(s) {
36150         return rstr(s, utf8);
36151       };
36152       this.hex_hmac = function(k, d) {
36153         return rstr2hex(rstr_hmac(k, d), hexcase);
36154       };
36155       this.b64_hmac = function(k, d) {
36156         return rstr2b64(rstr_hmac(k, d), b64pad);
36157       };
36158       this.any_hmac = function(k, d, e) {
36159         return rstr2any(rstr_hmac(k, d), e);
36160       };
36161       /**
36162        * Perform a simple self-test to see if the VM is working
36163        * @return {String} Hexadecimal hash sample
36164        */
36165       this.vm_test = function() {
36166         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
36167       };
36168       /**
36169        * Enable/disable uppercase hexadecimal returned string
36170        * @param {Boolean}
36171        * @return {Object} this
36172        */
36173       this.setUpperCase = function(a) {
36174         if (typeof a === 'boolean') {
36175           hexcase = a;
36176         }
36177         return this;
36178       };
36179       /**
36180        * Defines a base64 pad string
36181        * @param {String} Pad
36182        * @return {Object} this
36183        */
36184       this.setPad = function(a) {
36185         b64pad = a || b64pad;
36186         return this;
36187       };
36188       /**
36189        * Defines a base64 pad string
36190        * @param {Boolean}
36191        * @return {Object} [this]
36192        */
36193       this.setUTF8 = function(a) {
36194         if (typeof a === 'boolean') {
36195           utf8 = a;
36196         }
36197         return this;
36198       };
36199
36200       // private methods
36201
36202       /**
36203        * Calculate the MD5 of a raw string
36204        */
36205
36206       function rstr(s) {
36207         s = (utf8) ? utf8Encode(s) : s;
36208         return binl2rstr(binl(rstr2binl(s), s.length * 8));
36209       }
36210
36211       /**
36212        * Calculate the HMAC-MD5, of a key and some data (raw strings)
36213        */
36214
36215       function rstr_hmac(key, data) {
36216         var bkey, ipad, opad, hash, i;
36217
36218         key = (utf8) ? utf8Encode(key) : key;
36219         data = (utf8) ? utf8Encode(data) : data;
36220         bkey = rstr2binl(key);
36221         if (bkey.length > 16) {
36222           bkey = binl(bkey, key.length * 8);
36223         }
36224
36225         ipad = Array(16), opad = Array(16);
36226         for (i = 0; i < 16; i += 1) {
36227           ipad[i] = bkey[i] ^ 0x36363636;
36228           opad[i] = bkey[i] ^ 0x5C5C5C5C;
36229         }
36230         hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
36231         return binl2rstr(binl(opad.concat(hash), 512 + 128));
36232       }
36233
36234       /**
36235        * Calculate the MD5 of an array of little-endian words, and a bit length.
36236        */
36237
36238       function binl(x, len) {
36239         var i, olda, oldb, oldc, oldd,
36240           a = 1732584193,
36241           b = -271733879,
36242           c = -1732584194,
36243           d = 271733878;
36244
36245         /* append padding */
36246         x[len >> 5] |= 0x80 << ((len) % 32);
36247         x[(((len + 64) >>> 9) << 4) + 14] = len;
36248
36249         for (i = 0; i < x.length; i += 16) {
36250           olda = a;
36251           oldb = b;
36252           oldc = c;
36253           oldd = d;
36254
36255           a = md5_ff(a, b, c, d, x[i + 0], 7, -680876936);
36256           d = md5_ff(d, a, b, c, x[i + 1], 12, -389564586);
36257           c = md5_ff(c, d, a, b, x[i + 2], 17, 606105819);
36258           b = md5_ff(b, c, d, a, x[i + 3], 22, -1044525330);
36259           a = md5_ff(a, b, c, d, x[i + 4], 7, -176418897);
36260           d = md5_ff(d, a, b, c, x[i + 5], 12, 1200080426);
36261           c = md5_ff(c, d, a, b, x[i + 6], 17, -1473231341);
36262           b = md5_ff(b, c, d, a, x[i + 7], 22, -45705983);
36263           a = md5_ff(a, b, c, d, x[i + 8], 7, 1770035416);
36264           d = md5_ff(d, a, b, c, x[i + 9], 12, -1958414417);
36265           c = md5_ff(c, d, a, b, x[i + 10], 17, -42063);
36266           b = md5_ff(b, c, d, a, x[i + 11], 22, -1990404162);
36267           a = md5_ff(a, b, c, d, x[i + 12], 7, 1804603682);
36268           d = md5_ff(d, a, b, c, x[i + 13], 12, -40341101);
36269           c = md5_ff(c, d, a, b, x[i + 14], 17, -1502002290);
36270           b = md5_ff(b, c, d, a, x[i + 15], 22, 1236535329);
36271
36272           a = md5_gg(a, b, c, d, x[i + 1], 5, -165796510);
36273           d = md5_gg(d, a, b, c, x[i + 6], 9, -1069501632);
36274           c = md5_gg(c, d, a, b, x[i + 11], 14, 643717713);
36275           b = md5_gg(b, c, d, a, x[i + 0], 20, -373897302);
36276           a = md5_gg(a, b, c, d, x[i + 5], 5, -701558691);
36277           d = md5_gg(d, a, b, c, x[i + 10], 9, 38016083);
36278           c = md5_gg(c, d, a, b, x[i + 15], 14, -660478335);
36279           b = md5_gg(b, c, d, a, x[i + 4], 20, -405537848);
36280           a = md5_gg(a, b, c, d, x[i + 9], 5, 568446438);
36281           d = md5_gg(d, a, b, c, x[i + 14], 9, -1019803690);
36282           c = md5_gg(c, d, a, b, x[i + 3], 14, -187363961);
36283           b = md5_gg(b, c, d, a, x[i + 8], 20, 1163531501);
36284           a = md5_gg(a, b, c, d, x[i + 13], 5, -1444681467);
36285           d = md5_gg(d, a, b, c, x[i + 2], 9, -51403784);
36286           c = md5_gg(c, d, a, b, x[i + 7], 14, 1735328473);
36287           b = md5_gg(b, c, d, a, x[i + 12], 20, -1926607734);
36288
36289           a = md5_hh(a, b, c, d, x[i + 5], 4, -378558);
36290           d = md5_hh(d, a, b, c, x[i + 8], 11, -2022574463);
36291           c = md5_hh(c, d, a, b, x[i + 11], 16, 1839030562);
36292           b = md5_hh(b, c, d, a, x[i + 14], 23, -35309556);
36293           a = md5_hh(a, b, c, d, x[i + 1], 4, -1530992060);
36294           d = md5_hh(d, a, b, c, x[i + 4], 11, 1272893353);
36295           c = md5_hh(c, d, a, b, x[i + 7], 16, -155497632);
36296           b = md5_hh(b, c, d, a, x[i + 10], 23, -1094730640);
36297           a = md5_hh(a, b, c, d, x[i + 13], 4, 681279174);
36298           d = md5_hh(d, a, b, c, x[i + 0], 11, -358537222);
36299           c = md5_hh(c, d, a, b, x[i + 3], 16, -722521979);
36300           b = md5_hh(b, c, d, a, x[i + 6], 23, 76029189);
36301           a = md5_hh(a, b, c, d, x[i + 9], 4, -640364487);
36302           d = md5_hh(d, a, b, c, x[i + 12], 11, -421815835);
36303           c = md5_hh(c, d, a, b, x[i + 15], 16, 530742520);
36304           b = md5_hh(b, c, d, a, x[i + 2], 23, -995338651);
36305
36306           a = md5_ii(a, b, c, d, x[i + 0], 6, -198630844);
36307           d = md5_ii(d, a, b, c, x[i + 7], 10, 1126891415);
36308           c = md5_ii(c, d, a, b, x[i + 14], 15, -1416354905);
36309           b = md5_ii(b, c, d, a, x[i + 5], 21, -57434055);
36310           a = md5_ii(a, b, c, d, x[i + 12], 6, 1700485571);
36311           d = md5_ii(d, a, b, c, x[i + 3], 10, -1894986606);
36312           c = md5_ii(c, d, a, b, x[i + 10], 15, -1051523);
36313           b = md5_ii(b, c, d, a, x[i + 1], 21, -2054922799);
36314           a = md5_ii(a, b, c, d, x[i + 8], 6, 1873313359);
36315           d = md5_ii(d, a, b, c, x[i + 15], 10, -30611744);
36316           c = md5_ii(c, d, a, b, x[i + 6], 15, -1560198380);
36317           b = md5_ii(b, c, d, a, x[i + 13], 21, 1309151649);
36318           a = md5_ii(a, b, c, d, x[i + 4], 6, -145523070);
36319           d = md5_ii(d, a, b, c, x[i + 11], 10, -1120210379);
36320           c = md5_ii(c, d, a, b, x[i + 2], 15, 718787259);
36321           b = md5_ii(b, c, d, a, x[i + 9], 21, -343485551);
36322
36323           a = safe_add(a, olda);
36324           b = safe_add(b, oldb);
36325           c = safe_add(c, oldc);
36326           d = safe_add(d, oldd);
36327         }
36328         return Array(a, b, c, d);
36329       }
36330
36331       /**
36332        * These functions implement the four basic operations the algorithm uses.
36333        */
36334
36335       function md5_cmn(q, a, b, x, s, t) {
36336         return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s), b);
36337       }
36338
36339       function md5_ff(a, b, c, d, x, s, t) {
36340         return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
36341       }
36342
36343       function md5_gg(a, b, c, d, x, s, t) {
36344         return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
36345       }
36346
36347       function md5_hh(a, b, c, d, x, s, t) {
36348         return md5_cmn(b ^ c ^ d, a, b, x, s, t);
36349       }
36350
36351       function md5_ii(a, b, c, d, x, s, t) {
36352         return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
36353       }
36354     },
36355     /**
36356      * @member Hashes
36357      * @class Hashes.SHA1
36358      * @param {Object} [config]
36359      * @constructor
36360      *
36361      * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined in FIPS 180-1
36362      * Version 2.2 Copyright Paul Johnston 2000 - 2009.
36363      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
36364      * See http://pajhome.org.uk/crypt/md5 for details.
36365      */
36366     SHA1: function(options) {
36367       /**
36368        * Private config properties. You may need to tweak these to be compatible with
36369        * the server-side, but the defaults work in most cases.
36370        * See {@link Hashes.MD5#method-setUpperCase} and {@link Hashes.SHA1#method-setUpperCase}
36371        */
36372       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase
36373         b64pad = (options && typeof options.pad === 'string') ? options.pad : '=', // base-64 pad character. Defaults to '=' for strict RFC compliance
36374         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true; // enable/disable utf8 encoding
36375
36376       // public methods
36377       this.hex = function(s) {
36378         return rstr2hex(rstr(s, utf8), hexcase);
36379       };
36380       this.b64 = function(s) {
36381         return rstr2b64(rstr(s, utf8), b64pad);
36382       };
36383       this.any = function(s, e) {
36384         return rstr2any(rstr(s, utf8), e);
36385       };
36386       this.raw = function(s) {
36387         return rstr(s, utf8);
36388       };
36389       this.hex_hmac = function(k, d) {
36390         return rstr2hex(rstr_hmac(k, d));
36391       };
36392       this.b64_hmac = function(k, d) {
36393         return rstr2b64(rstr_hmac(k, d), b64pad);
36394       };
36395       this.any_hmac = function(k, d, e) {
36396         return rstr2any(rstr_hmac(k, d), e);
36397       };
36398       /**
36399        * Perform a simple self-test to see if the VM is working
36400        * @return {String} Hexadecimal hash sample
36401        * @public
36402        */
36403       this.vm_test = function() {
36404         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
36405       };
36406       /**
36407        * @description Enable/disable uppercase hexadecimal returned string
36408        * @param {boolean}
36409        * @return {Object} this
36410        * @public
36411        */
36412       this.setUpperCase = function(a) {
36413         if (typeof a === 'boolean') {
36414           hexcase = a;
36415         }
36416         return this;
36417       };
36418       /**
36419        * @description Defines a base64 pad string
36420        * @param {string} Pad
36421        * @return {Object} this
36422        * @public
36423        */
36424       this.setPad = function(a) {
36425         b64pad = a || b64pad;
36426         return this;
36427       };
36428       /**
36429        * @description Defines a base64 pad string
36430        * @param {boolean}
36431        * @return {Object} this
36432        * @public
36433        */
36434       this.setUTF8 = function(a) {
36435         if (typeof a === 'boolean') {
36436           utf8 = a;
36437         }
36438         return this;
36439       };
36440
36441       // private methods
36442
36443       /**
36444        * Calculate the SHA-512 of a raw string
36445        */
36446
36447       function rstr(s) {
36448         s = (utf8) ? utf8Encode(s) : s;
36449         return binb2rstr(binb(rstr2binb(s), s.length * 8));
36450       }
36451
36452       /**
36453        * Calculate the HMAC-SHA1 of a key and some data (raw strings)
36454        */
36455
36456       function rstr_hmac(key, data) {
36457         var bkey, ipad, opad, i, hash;
36458         key = (utf8) ? utf8Encode(key) : key;
36459         data = (utf8) ? utf8Encode(data) : data;
36460         bkey = rstr2binb(key);
36461
36462         if (bkey.length > 16) {
36463           bkey = binb(bkey, key.length * 8);
36464         }
36465         ipad = Array(16), opad = Array(16);
36466         for (i = 0; i < 16; i += 1) {
36467           ipad[i] = bkey[i] ^ 0x36363636;
36468           opad[i] = bkey[i] ^ 0x5C5C5C5C;
36469         }
36470         hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
36471         return binb2rstr(binb(opad.concat(hash), 512 + 160));
36472       }
36473
36474       /**
36475        * Calculate the SHA-1 of an array of big-endian words, and a bit length
36476        */
36477
36478       function binb(x, len) {
36479         var i, j, t, olda, oldb, oldc, oldd, olde,
36480           w = Array(80),
36481           a = 1732584193,
36482           b = -271733879,
36483           c = -1732584194,
36484           d = 271733878,
36485           e = -1009589776;
36486
36487         /* append padding */
36488         x[len >> 5] |= 0x80 << (24 - len % 32);
36489         x[((len + 64 >> 9) << 4) + 15] = len;
36490
36491         for (i = 0; i < x.length; i += 16) {
36492           olda = a;
36493           oldb = b;
36494           oldc = c;
36495           oldd = d;
36496           olde = e;
36497
36498           for (j = 0; j < 80; j += 1) {
36499             if (j < 16) {
36500               w[j] = x[i + j];
36501             } else {
36502               w[j] = bit_rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
36503             }
36504             t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
36505               safe_add(safe_add(e, w[j]), sha1_kt(j)));
36506             e = d;
36507             d = c;
36508             c = bit_rol(b, 30);
36509             b = a;
36510             a = t;
36511           }
36512
36513           a = safe_add(a, olda);
36514           b = safe_add(b, oldb);
36515           c = safe_add(c, oldc);
36516           d = safe_add(d, oldd);
36517           e = safe_add(e, olde);
36518         }
36519         return Array(a, b, c, d, e);
36520       }
36521
36522       /**
36523        * Perform the appropriate triplet combination function for the current
36524        * iteration
36525        */
36526
36527       function sha1_ft(t, b, c, d) {
36528         if (t < 20) {
36529           return (b & c) | ((~b) & d);
36530         }
36531         if (t < 40) {
36532           return b ^ c ^ d;
36533         }
36534         if (t < 60) {
36535           return (b & c) | (b & d) | (c & d);
36536         }
36537         return b ^ c ^ d;
36538       }
36539
36540       /**
36541        * Determine the appropriate additive constant for the current iteration
36542        */
36543
36544       function sha1_kt(t) {
36545         return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
36546           (t < 60) ? -1894007588 : -899497514;
36547       }
36548     },
36549     /**
36550      * @class Hashes.SHA256
36551      * @param {config}
36552      *
36553      * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined in FIPS 180-2
36554      * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
36555      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
36556      * See http://pajhome.org.uk/crypt/md5 for details.
36557      * Also http://anmar.eu.org/projects/jssha2/
36558      */
36559     SHA256: function(options) {
36560       /**
36561        * Private properties configuration variables. You may need to tweak these to be compatible with
36562        * the server-side, but the defaults work in most cases.
36563        * @see this.setUpperCase() method
36564        * @see this.setPad() method
36565        */
36566       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false, // hexadecimal output case format. false - lowercase; true - uppercase  */
36567         b64pad = (options && typeof options.pad === 'string') ? options.pad : '=',
36568         /* base-64 pad character. Default '=' for strict RFC compliance   */
36569         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
36570         /* enable/disable utf8 encoding */
36571         sha256_K;
36572
36573       /* privileged (public) methods */
36574       this.hex = function(s) {
36575         return rstr2hex(rstr(s, utf8));
36576       };
36577       this.b64 = function(s) {
36578         return rstr2b64(rstr(s, utf8), b64pad);
36579       };
36580       this.any = function(s, e) {
36581         return rstr2any(rstr(s, utf8), e);
36582       };
36583       this.raw = function(s) {
36584         return rstr(s, utf8);
36585       };
36586       this.hex_hmac = function(k, d) {
36587         return rstr2hex(rstr_hmac(k, d));
36588       };
36589       this.b64_hmac = function(k, d) {
36590         return rstr2b64(rstr_hmac(k, d), b64pad);
36591       };
36592       this.any_hmac = function(k, d, e) {
36593         return rstr2any(rstr_hmac(k, d), e);
36594       };
36595       /**
36596        * Perform a simple self-test to see if the VM is working
36597        * @return {String} Hexadecimal hash sample
36598        * @public
36599        */
36600       this.vm_test = function() {
36601         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
36602       };
36603       /**
36604        * Enable/disable uppercase hexadecimal returned string
36605        * @param {boolean}
36606        * @return {Object} this
36607        * @public
36608        */
36609       this.setUpperCase = function(a) {
36610         if (typeof a === 'boolean') {
36611           hexcase = a;
36612         }
36613         return this;
36614       };
36615       /**
36616        * @description Defines a base64 pad string
36617        * @param {string} Pad
36618        * @return {Object} this
36619        * @public
36620        */
36621       this.setPad = function(a) {
36622         b64pad = a || b64pad;
36623         return this;
36624       };
36625       /**
36626        * Defines a base64 pad string
36627        * @param {boolean}
36628        * @return {Object} this
36629        * @public
36630        */
36631       this.setUTF8 = function(a) {
36632         if (typeof a === 'boolean') {
36633           utf8 = a;
36634         }
36635         return this;
36636       };
36637
36638       // private methods
36639
36640       /**
36641        * Calculate the SHA-512 of a raw string
36642        */
36643
36644       function rstr(s, utf8) {
36645         s = (utf8) ? utf8Encode(s) : s;
36646         return binb2rstr(binb(rstr2binb(s), s.length * 8));
36647       }
36648
36649       /**
36650        * Calculate the HMAC-sha256 of a key and some data (raw strings)
36651        */
36652
36653       function rstr_hmac(key, data) {
36654         key = (utf8) ? utf8Encode(key) : key;
36655         data = (utf8) ? utf8Encode(data) : data;
36656         var hash, i = 0,
36657           bkey = rstr2binb(key),
36658           ipad = Array(16),
36659           opad = Array(16);
36660
36661         if (bkey.length > 16) {
36662           bkey = binb(bkey, key.length * 8);
36663         }
36664
36665         for (; i < 16; i += 1) {
36666           ipad[i] = bkey[i] ^ 0x36363636;
36667           opad[i] = bkey[i] ^ 0x5C5C5C5C;
36668         }
36669
36670         hash = binb(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
36671         return binb2rstr(binb(opad.concat(hash), 512 + 256));
36672       }
36673
36674       /*
36675        * Main sha256 function, with its support functions
36676        */
36677
36678       function sha256_S(X, n) {
36679         return (X >>> n) | (X << (32 - n));
36680       }
36681
36682       function sha256_R(X, n) {
36683         return (X >>> n);
36684       }
36685
36686       function sha256_Ch(x, y, z) {
36687         return ((x & y) ^ ((~x) & z));
36688       }
36689
36690       function sha256_Maj(x, y, z) {
36691         return ((x & y) ^ (x & z) ^ (y & z));
36692       }
36693
36694       function sha256_Sigma0256(x) {
36695         return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));
36696       }
36697
36698       function sha256_Sigma1256(x) {
36699         return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));
36700       }
36701
36702       function sha256_Gamma0256(x) {
36703         return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));
36704       }
36705
36706       function sha256_Gamma1256(x) {
36707         return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));
36708       }
36709
36710       sha256_K = [
36711         1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993, -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987,
36712         1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522,
36713         264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585,
36714         113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291,
36715         1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885, -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344,
36716         430227734, 506948616, 659060556, 883997877, 958139571, 1322822218,
36717         1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872, -1866530822, -1538233109, -1090935817, -965641998
36718       ];
36719
36720       function binb(m, l) {
36721         var HASH = [1779033703, -1150833019, 1013904242, -1521486534,
36722           1359893119, -1694144372, 528734635, 1541459225
36723         ];
36724         var W = new Array(64);
36725         var a, b, c, d, e, f, g, h;
36726         var i, j, T1, T2;
36727
36728         /* append padding */
36729         m[l >> 5] |= 0x80 << (24 - l % 32);
36730         m[((l + 64 >> 9) << 4) + 15] = l;
36731
36732         for (i = 0; i < m.length; i += 16) {
36733           a = HASH[0];
36734           b = HASH[1];
36735           c = HASH[2];
36736           d = HASH[3];
36737           e = HASH[4];
36738           f = HASH[5];
36739           g = HASH[6];
36740           h = HASH[7];
36741
36742           for (j = 0; j < 64; j += 1) {
36743             if (j < 16) {
36744               W[j] = m[j + i];
36745             } else {
36746               W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]),
36747                 sha256_Gamma0256(W[j - 15])), W[j - 16]);
36748             }
36749
36750             T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)),
36751               sha256_K[j]), W[j]);
36752             T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
36753             h = g;
36754             g = f;
36755             f = e;
36756             e = safe_add(d, T1);
36757             d = c;
36758             c = b;
36759             b = a;
36760             a = safe_add(T1, T2);
36761           }
36762
36763           HASH[0] = safe_add(a, HASH[0]);
36764           HASH[1] = safe_add(b, HASH[1]);
36765           HASH[2] = safe_add(c, HASH[2]);
36766           HASH[3] = safe_add(d, HASH[3]);
36767           HASH[4] = safe_add(e, HASH[4]);
36768           HASH[5] = safe_add(f, HASH[5]);
36769           HASH[6] = safe_add(g, HASH[6]);
36770           HASH[7] = safe_add(h, HASH[7]);
36771         }
36772         return HASH;
36773       }
36774
36775     },
36776
36777     /**
36778      * @class Hashes.SHA512
36779      * @param {config}
36780      *
36781      * A JavaScript implementation of the Secure Hash Algorithm, SHA-512, as defined in FIPS 180-2
36782      * Version 2.2 Copyright Anonymous Contributor, Paul Johnston 2000 - 2009.
36783      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
36784      * See http://pajhome.org.uk/crypt/md5 for details.
36785      */
36786     SHA512: function(options) {
36787       /**
36788        * Private properties configuration variables. You may need to tweak these to be compatible with
36789        * the server-side, but the defaults work in most cases.
36790        * @see this.setUpperCase() method
36791        * @see this.setPad() method
36792        */
36793       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false,
36794         /* hexadecimal output case format. false - lowercase; true - uppercase  */
36795         b64pad = (options && typeof options.pad === 'string') ? options.pad : '=',
36796         /* base-64 pad character. Default '=' for strict RFC compliance   */
36797         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
36798         /* enable/disable utf8 encoding */
36799         sha512_k;
36800
36801       /* privileged (public) methods */
36802       this.hex = function(s) {
36803         return rstr2hex(rstr(s));
36804       };
36805       this.b64 = function(s) {
36806         return rstr2b64(rstr(s), b64pad);
36807       };
36808       this.any = function(s, e) {
36809         return rstr2any(rstr(s), e);
36810       };
36811       this.raw = function(s) {
36812         return rstr(s, utf8);
36813       };
36814       this.hex_hmac = function(k, d) {
36815         return rstr2hex(rstr_hmac(k, d));
36816       };
36817       this.b64_hmac = function(k, d) {
36818         return rstr2b64(rstr_hmac(k, d), b64pad);
36819       };
36820       this.any_hmac = function(k, d, e) {
36821         return rstr2any(rstr_hmac(k, d), e);
36822       };
36823       /**
36824        * Perform a simple self-test to see if the VM is working
36825        * @return {String} Hexadecimal hash sample
36826        * @public
36827        */
36828       this.vm_test = function() {
36829         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
36830       };
36831       /**
36832        * @description Enable/disable uppercase hexadecimal returned string
36833        * @param {boolean}
36834        * @return {Object} this
36835        * @public
36836        */
36837       this.setUpperCase = function(a) {
36838         if (typeof a === 'boolean') {
36839           hexcase = a;
36840         }
36841         return this;
36842       };
36843       /**
36844        * @description Defines a base64 pad string
36845        * @param {string} Pad
36846        * @return {Object} this
36847        * @public
36848        */
36849       this.setPad = function(a) {
36850         b64pad = a || b64pad;
36851         return this;
36852       };
36853       /**
36854        * @description Defines a base64 pad string
36855        * @param {boolean}
36856        * @return {Object} this
36857        * @public
36858        */
36859       this.setUTF8 = function(a) {
36860         if (typeof a === 'boolean') {
36861           utf8 = a;
36862         }
36863         return this;
36864       };
36865
36866       /* private methods */
36867
36868       /**
36869        * Calculate the SHA-512 of a raw string
36870        */
36871
36872       function rstr(s) {
36873         s = (utf8) ? utf8Encode(s) : s;
36874         return binb2rstr(binb(rstr2binb(s), s.length * 8));
36875       }
36876       /*
36877        * Calculate the HMAC-SHA-512 of a key and some data (raw strings)
36878        */
36879
36880       function rstr_hmac(key, data) {
36881         key = (utf8) ? utf8Encode(key) : key;
36882         data = (utf8) ? utf8Encode(data) : data;
36883
36884         var hash, i = 0,
36885           bkey = rstr2binb(key),
36886           ipad = Array(32),
36887           opad = Array(32);
36888
36889         if (bkey.length > 32) {
36890           bkey = binb(bkey, key.length * 8);
36891         }
36892
36893         for (; i < 32; i += 1) {
36894           ipad[i] = bkey[i] ^ 0x36363636;
36895           opad[i] = bkey[i] ^ 0x5C5C5C5C;
36896         }
36897
36898         hash = binb(ipad.concat(rstr2binb(data)), 1024 + data.length * 8);
36899         return binb2rstr(binb(opad.concat(hash), 1024 + 512));
36900       }
36901
36902       /**
36903        * Calculate the SHA-512 of an array of big-endian dwords, and a bit length
36904        */
36905
36906       function binb(x, len) {
36907         var j, i, l,
36908           W = new Array(80),
36909           hash = new Array(16),
36910           //Initial hash values
36911           H = [
36912             new int64(0x6a09e667, -205731576),
36913             new int64(-1150833019, -2067093701),
36914             new int64(0x3c6ef372, -23791573),
36915             new int64(-1521486534, 0x5f1d36f1),
36916             new int64(0x510e527f, -1377402159),
36917             new int64(-1694144372, 0x2b3e6c1f),
36918             new int64(0x1f83d9ab, -79577749),
36919             new int64(0x5be0cd19, 0x137e2179)
36920           ],
36921           T1 = new int64(0, 0),
36922           T2 = new int64(0, 0),
36923           a = new int64(0, 0),
36924           b = new int64(0, 0),
36925           c = new int64(0, 0),
36926           d = new int64(0, 0),
36927           e = new int64(0, 0),
36928           f = new int64(0, 0),
36929           g = new int64(0, 0),
36930           h = new int64(0, 0),
36931           //Temporary variables not specified by the document
36932           s0 = new int64(0, 0),
36933           s1 = new int64(0, 0),
36934           Ch = new int64(0, 0),
36935           Maj = new int64(0, 0),
36936           r1 = new int64(0, 0),
36937           r2 = new int64(0, 0),
36938           r3 = new int64(0, 0);
36939
36940         if (sha512_k === undefined) {
36941           //SHA512 constants
36942           sha512_k = [
36943             new int64(0x428a2f98, -685199838), new int64(0x71374491, 0x23ef65cd),
36944             new int64(-1245643825, -330482897), new int64(-373957723, -2121671748),
36945             new int64(0x3956c25b, -213338824), new int64(0x59f111f1, -1241133031),
36946             new int64(-1841331548, -1357295717), new int64(-1424204075, -630357736),
36947             new int64(-670586216, -1560083902), new int64(0x12835b01, 0x45706fbe),
36948             new int64(0x243185be, 0x4ee4b28c), new int64(0x550c7dc3, -704662302),
36949             new int64(0x72be5d74, -226784913), new int64(-2132889090, 0x3b1696b1),
36950             new int64(-1680079193, 0x25c71235), new int64(-1046744716, -815192428),
36951             new int64(-459576895, -1628353838), new int64(-272742522, 0x384f25e3),
36952             new int64(0xfc19dc6, -1953704523), new int64(0x240ca1cc, 0x77ac9c65),
36953             new int64(0x2de92c6f, 0x592b0275), new int64(0x4a7484aa, 0x6ea6e483),
36954             new int64(0x5cb0a9dc, -1119749164), new int64(0x76f988da, -2096016459),
36955             new int64(-1740746414, -295247957), new int64(-1473132947, 0x2db43210),
36956             new int64(-1341970488, -1728372417), new int64(-1084653625, -1091629340),
36957             new int64(-958395405, 0x3da88fc2), new int64(-710438585, -1828018395),
36958             new int64(0x6ca6351, -536640913), new int64(0x14292967, 0xa0e6e70),
36959             new int64(0x27b70a85, 0x46d22ffc), new int64(0x2e1b2138, 0x5c26c926),
36960             new int64(0x4d2c6dfc, 0x5ac42aed), new int64(0x53380d13, -1651133473),
36961             new int64(0x650a7354, -1951439906), new int64(0x766a0abb, 0x3c77b2a8),
36962             new int64(-2117940946, 0x47edaee6), new int64(-1838011259, 0x1482353b),
36963             new int64(-1564481375, 0x4cf10364), new int64(-1474664885, -1136513023),
36964             new int64(-1035236496, -789014639), new int64(-949202525, 0x654be30),
36965             new int64(-778901479, -688958952), new int64(-694614492, 0x5565a910),
36966             new int64(-200395387, 0x5771202a), new int64(0x106aa070, 0x32bbd1b8),
36967             new int64(0x19a4c116, -1194143544), new int64(0x1e376c08, 0x5141ab53),
36968             new int64(0x2748774c, -544281703), new int64(0x34b0bcb5, -509917016),
36969             new int64(0x391c0cb3, -976659869), new int64(0x4ed8aa4a, -482243893),
36970             new int64(0x5b9cca4f, 0x7763e373), new int64(0x682e6ff3, -692930397),
36971             new int64(0x748f82ee, 0x5defb2fc), new int64(0x78a5636f, 0x43172f60),
36972             new int64(-2067236844, -1578062990), new int64(-1933114872, 0x1a6439ec),
36973             new int64(-1866530822, 0x23631e28), new int64(-1538233109, -561857047),
36974             new int64(-1090935817, -1295615723), new int64(-965641998, -479046869),
36975             new int64(-903397682, -366583396), new int64(-779700025, 0x21c0c207),
36976             new int64(-354779690, -840897762), new int64(-176337025, -294727304),
36977             new int64(0x6f067aa, 0x72176fba), new int64(0xa637dc5, -1563912026),
36978             new int64(0x113f9804, -1090974290), new int64(0x1b710b35, 0x131c471b),
36979             new int64(0x28db77f5, 0x23047d84), new int64(0x32caab7b, 0x40c72493),
36980             new int64(0x3c9ebe0a, 0x15c9bebc), new int64(0x431d67c4, -1676669620),
36981             new int64(0x4cc5d4be, -885112138), new int64(0x597f299c, -60457430),
36982             new int64(0x5fcb6fab, 0x3ad6faec), new int64(0x6c44198c, 0x4a475817)
36983           ];
36984         }
36985
36986         for (i = 0; i < 80; i += 1) {
36987           W[i] = new int64(0, 0);
36988         }
36989
36990         // append padding to the source string. The format is described in the FIPS.
36991         x[len >> 5] |= 0x80 << (24 - (len & 0x1f));
36992         x[((len + 128 >> 10) << 5) + 31] = len;
36993         l = x.length;
36994         for (i = 0; i < l; i += 32) { //32 dwords is the block size
36995           int64copy(a, H[0]);
36996           int64copy(b, H[1]);
36997           int64copy(c, H[2]);
36998           int64copy(d, H[3]);
36999           int64copy(e, H[4]);
37000           int64copy(f, H[5]);
37001           int64copy(g, H[6]);
37002           int64copy(h, H[7]);
37003
37004           for (j = 0; j < 16; j += 1) {
37005             W[j].h = x[i + 2 * j];
37006             W[j].l = x[i + 2 * j + 1];
37007           }
37008
37009           for (j = 16; j < 80; j += 1) {
37010             //sigma1
37011             int64rrot(r1, W[j - 2], 19);
37012             int64revrrot(r2, W[j - 2], 29);
37013             int64shr(r3, W[j - 2], 6);
37014             s1.l = r1.l ^ r2.l ^ r3.l;
37015             s1.h = r1.h ^ r2.h ^ r3.h;
37016             //sigma0
37017             int64rrot(r1, W[j - 15], 1);
37018             int64rrot(r2, W[j - 15], 8);
37019             int64shr(r3, W[j - 15], 7);
37020             s0.l = r1.l ^ r2.l ^ r3.l;
37021             s0.h = r1.h ^ r2.h ^ r3.h;
37022
37023             int64add4(W[j], s1, W[j - 7], s0, W[j - 16]);
37024           }
37025
37026           for (j = 0; j < 80; j += 1) {
37027             //Ch
37028             Ch.l = (e.l & f.l) ^ (~e.l & g.l);
37029             Ch.h = (e.h & f.h) ^ (~e.h & g.h);
37030
37031             //Sigma1
37032             int64rrot(r1, e, 14);
37033             int64rrot(r2, e, 18);
37034             int64revrrot(r3, e, 9);
37035             s1.l = r1.l ^ r2.l ^ r3.l;
37036             s1.h = r1.h ^ r2.h ^ r3.h;
37037
37038             //Sigma0
37039             int64rrot(r1, a, 28);
37040             int64revrrot(r2, a, 2);
37041             int64revrrot(r3, a, 7);
37042             s0.l = r1.l ^ r2.l ^ r3.l;
37043             s0.h = r1.h ^ r2.h ^ r3.h;
37044
37045             //Maj
37046             Maj.l = (a.l & b.l) ^ (a.l & c.l) ^ (b.l & c.l);
37047             Maj.h = (a.h & b.h) ^ (a.h & c.h) ^ (b.h & c.h);
37048
37049             int64add5(T1, h, s1, Ch, sha512_k[j], W[j]);
37050             int64add(T2, s0, Maj);
37051
37052             int64copy(h, g);
37053             int64copy(g, f);
37054             int64copy(f, e);
37055             int64add(e, d, T1);
37056             int64copy(d, c);
37057             int64copy(c, b);
37058             int64copy(b, a);
37059             int64add(a, T1, T2);
37060           }
37061           int64add(H[0], H[0], a);
37062           int64add(H[1], H[1], b);
37063           int64add(H[2], H[2], c);
37064           int64add(H[3], H[3], d);
37065           int64add(H[4], H[4], e);
37066           int64add(H[5], H[5], f);
37067           int64add(H[6], H[6], g);
37068           int64add(H[7], H[7], h);
37069         }
37070
37071         //represent the hash as an array of 32-bit dwords
37072         for (i = 0; i < 8; i += 1) {
37073           hash[2 * i] = H[i].h;
37074           hash[2 * i + 1] = H[i].l;
37075         }
37076         return hash;
37077       }
37078
37079       //A constructor for 64-bit numbers
37080
37081       function int64(h, l) {
37082         this.h = h;
37083         this.l = l;
37084         //this.toString = int64toString;
37085       }
37086
37087       //Copies src into dst, assuming both are 64-bit numbers
37088
37089       function int64copy(dst, src) {
37090         dst.h = src.h;
37091         dst.l = src.l;
37092       }
37093
37094       //Right-rotates a 64-bit number by shift
37095       //Won't handle cases of shift>=32
37096       //The function revrrot() is for that
37097
37098       function int64rrot(dst, x, shift) {
37099         dst.l = (x.l >>> shift) | (x.h << (32 - shift));
37100         dst.h = (x.h >>> shift) | (x.l << (32 - shift));
37101       }
37102
37103       //Reverses the dwords of the source and then rotates right by shift.
37104       //This is equivalent to rotation by 32+shift
37105
37106       function int64revrrot(dst, x, shift) {
37107         dst.l = (x.h >>> shift) | (x.l << (32 - shift));
37108         dst.h = (x.l >>> shift) | (x.h << (32 - shift));
37109       }
37110
37111       //Bitwise-shifts right a 64-bit number by shift
37112       //Won't handle shift>=32, but it's never needed in SHA512
37113
37114       function int64shr(dst, x, shift) {
37115         dst.l = (x.l >>> shift) | (x.h << (32 - shift));
37116         dst.h = (x.h >>> shift);
37117       }
37118
37119       //Adds two 64-bit numbers
37120       //Like the original implementation, does not rely on 32-bit operations
37121
37122       function int64add(dst, x, y) {
37123         var w0 = (x.l & 0xffff) + (y.l & 0xffff);
37124         var w1 = (x.l >>> 16) + (y.l >>> 16) + (w0 >>> 16);
37125         var w2 = (x.h & 0xffff) + (y.h & 0xffff) + (w1 >>> 16);
37126         var w3 = (x.h >>> 16) + (y.h >>> 16) + (w2 >>> 16);
37127         dst.l = (w0 & 0xffff) | (w1 << 16);
37128         dst.h = (w2 & 0xffff) | (w3 << 16);
37129       }
37130
37131       //Same, except with 4 addends. Works faster than adding them one by one.
37132
37133       function int64add4(dst, a, b, c, d) {
37134         var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff);
37135         var w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (w0 >>> 16);
37136         var w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (w1 >>> 16);
37137         var w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (w2 >>> 16);
37138         dst.l = (w0 & 0xffff) | (w1 << 16);
37139         dst.h = (w2 & 0xffff) | (w3 << 16);
37140       }
37141
37142       //Same, except with 5 addends
37143
37144       function int64add5(dst, a, b, c, d, e) {
37145         var w0 = (a.l & 0xffff) + (b.l & 0xffff) + (c.l & 0xffff) + (d.l & 0xffff) + (e.l & 0xffff),
37146           w1 = (a.l >>> 16) + (b.l >>> 16) + (c.l >>> 16) + (d.l >>> 16) + (e.l >>> 16) + (w0 >>> 16),
37147           w2 = (a.h & 0xffff) + (b.h & 0xffff) + (c.h & 0xffff) + (d.h & 0xffff) + (e.h & 0xffff) + (w1 >>> 16),
37148           w3 = (a.h >>> 16) + (b.h >>> 16) + (c.h >>> 16) + (d.h >>> 16) + (e.h >>> 16) + (w2 >>> 16);
37149         dst.l = (w0 & 0xffff) | (w1 << 16);
37150         dst.h = (w2 & 0xffff) | (w3 << 16);
37151       }
37152     },
37153     /**
37154      * @class Hashes.RMD160
37155      * @constructor
37156      * @param {Object} [config]
37157      *
37158      * A JavaScript implementation of the RIPEMD-160 Algorithm
37159      * Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009.
37160      * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
37161      * See http://pajhome.org.uk/crypt/md5 for details.
37162      * Also http://www.ocf.berkeley.edu/~jjlin/jsotp/
37163      */
37164     RMD160: function(options) {
37165       /**
37166        * Private properties configuration variables. You may need to tweak these to be compatible with
37167        * the server-side, but the defaults work in most cases.
37168        * @see this.setUpperCase() method
37169        * @see this.setPad() method
37170        */
37171       var hexcase = (options && typeof options.uppercase === 'boolean') ? options.uppercase : false,
37172         /* hexadecimal output case format. false - lowercase; true - uppercase  */
37173         b64pad = (options && typeof options.pad === 'string') ? options.pa : '=',
37174         /* base-64 pad character. Default '=' for strict RFC compliance   */
37175         utf8 = (options && typeof options.utf8 === 'boolean') ? options.utf8 : true,
37176         /* enable/disable utf8 encoding */
37177         rmd160_r1 = [
37178           0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
37179           7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
37180           3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
37181           1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
37182           4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
37183         ],
37184         rmd160_r2 = [
37185           5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
37186           6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
37187           15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
37188           8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
37189           12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
37190         ],
37191         rmd160_s1 = [
37192           11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
37193           7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
37194           11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
37195           11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
37196           9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
37197         ],
37198         rmd160_s2 = [
37199           8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
37200           9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
37201           9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
37202           15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
37203           8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
37204         ];
37205
37206       /* privileged (public) methods */
37207       this.hex = function(s) {
37208         return rstr2hex(rstr(s, utf8));
37209       };
37210       this.b64 = function(s) {
37211         return rstr2b64(rstr(s, utf8), b64pad);
37212       };
37213       this.any = function(s, e) {
37214         return rstr2any(rstr(s, utf8), e);
37215       };
37216       this.raw = function(s) {
37217         return rstr(s, utf8);
37218       };
37219       this.hex_hmac = function(k, d) {
37220         return rstr2hex(rstr_hmac(k, d));
37221       };
37222       this.b64_hmac = function(k, d) {
37223         return rstr2b64(rstr_hmac(k, d), b64pad);
37224       };
37225       this.any_hmac = function(k, d, e) {
37226         return rstr2any(rstr_hmac(k, d), e);
37227       };
37228       /**
37229        * Perform a simple self-test to see if the VM is working
37230        * @return {String} Hexadecimal hash sample
37231        * @public
37232        */
37233       this.vm_test = function() {
37234         return hex('abc').toLowerCase() === '900150983cd24fb0d6963f7d28e17f72';
37235       };
37236       /**
37237        * @description Enable/disable uppercase hexadecimal returned string
37238        * @param {boolean}
37239        * @return {Object} this
37240        * @public
37241        */
37242       this.setUpperCase = function(a) {
37243         if (typeof a === 'boolean') {
37244           hexcase = a;
37245         }
37246         return this;
37247       };
37248       /**
37249        * @description Defines a base64 pad string
37250        * @param {string} Pad
37251        * @return {Object} this
37252        * @public
37253        */
37254       this.setPad = function(a) {
37255         if (typeof a !== 'undefined') {
37256           b64pad = a;
37257         }
37258         return this;
37259       };
37260       /**
37261        * @description Defines a base64 pad string
37262        * @param {boolean}
37263        * @return {Object} this
37264        * @public
37265        */
37266       this.setUTF8 = function(a) {
37267         if (typeof a === 'boolean') {
37268           utf8 = a;
37269         }
37270         return this;
37271       };
37272
37273       /* private methods */
37274
37275       /**
37276        * Calculate the rmd160 of a raw string
37277        */
37278
37279       function rstr(s) {
37280         s = (utf8) ? utf8Encode(s) : s;
37281         return binl2rstr(binl(rstr2binl(s), s.length * 8));
37282       }
37283
37284       /**
37285        * Calculate the HMAC-rmd160 of a key and some data (raw strings)
37286        */
37287
37288       function rstr_hmac(key, data) {
37289         key = (utf8) ? utf8Encode(key) : key;
37290         data = (utf8) ? utf8Encode(data) : data;
37291         var i, hash,
37292           bkey = rstr2binl(key),
37293           ipad = Array(16),
37294           opad = Array(16);
37295
37296         if (bkey.length > 16) {
37297           bkey = binl(bkey, key.length * 8);
37298         }
37299
37300         for (i = 0; i < 16; i += 1) {
37301           ipad[i] = bkey[i] ^ 0x36363636;
37302           opad[i] = bkey[i] ^ 0x5C5C5C5C;
37303         }
37304         hash = binl(ipad.concat(rstr2binl(data)), 512 + data.length * 8);
37305         return binl2rstr(binl(opad.concat(hash), 512 + 160));
37306       }
37307
37308       /**
37309        * Convert an array of little-endian words to a string
37310        */
37311
37312       function binl2rstr(input) {
37313         var i, output = '',
37314           l = input.length * 32;
37315         for (i = 0; i < l; i += 8) {
37316           output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xFF);
37317         }
37318         return output;
37319       }
37320
37321       /**
37322        * Calculate the RIPE-MD160 of an array of little-endian words, and a bit length.
37323        */
37324
37325       function binl(x, len) {
37326         var T, j, i, l,
37327           h0 = 0x67452301,
37328           h1 = 0xefcdab89,
37329           h2 = 0x98badcfe,
37330           h3 = 0x10325476,
37331           h4 = 0xc3d2e1f0,
37332           A1, B1, C1, D1, E1,
37333           A2, B2, C2, D2, E2;
37334
37335         /* append padding */
37336         x[len >> 5] |= 0x80 << (len % 32);
37337         x[(((len + 64) >>> 9) << 4) + 14] = len;
37338         l = x.length;
37339
37340         for (i = 0; i < l; i += 16) {
37341           A1 = A2 = h0;
37342           B1 = B2 = h1;
37343           C1 = C2 = h2;
37344           D1 = D2 = h3;
37345           E1 = E2 = h4;
37346           for (j = 0; j <= 79; j += 1) {
37347             T = safe_add(A1, rmd160_f(j, B1, C1, D1));
37348             T = safe_add(T, x[i + rmd160_r1[j]]);
37349             T = safe_add(T, rmd160_K1(j));
37350             T = safe_add(bit_rol(T, rmd160_s1[j]), E1);
37351             A1 = E1;
37352             E1 = D1;
37353             D1 = bit_rol(C1, 10);
37354             C1 = B1;
37355             B1 = T;
37356             T = safe_add(A2, rmd160_f(79 - j, B2, C2, D2));
37357             T = safe_add(T, x[i + rmd160_r2[j]]);
37358             T = safe_add(T, rmd160_K2(j));
37359             T = safe_add(bit_rol(T, rmd160_s2[j]), E2);
37360             A2 = E2;
37361             E2 = D2;
37362             D2 = bit_rol(C2, 10);
37363             C2 = B2;
37364             B2 = T;
37365           }
37366
37367           T = safe_add(h1, safe_add(C1, D2));
37368           h1 = safe_add(h2, safe_add(D1, E2));
37369           h2 = safe_add(h3, safe_add(E1, A2));
37370           h3 = safe_add(h4, safe_add(A1, B2));
37371           h4 = safe_add(h0, safe_add(B1, C2));
37372           h0 = T;
37373         }
37374         return [h0, h1, h2, h3, h4];
37375       }
37376
37377       // specific algorithm methods
37378
37379       function rmd160_f(j, x, y, z) {
37380         return (0 <= j && j <= 15) ? (x ^ y ^ z) :
37381           (16 <= j && j <= 31) ? (x & y) | (~x & z) :
37382           (32 <= j && j <= 47) ? (x | ~y) ^ z :
37383           (48 <= j && j <= 63) ? (x & z) | (y & ~z) :
37384           (64 <= j && j <= 79) ? x ^ (y | ~z) :
37385           'rmd160_f: j out of range';
37386       }
37387
37388       function rmd160_K1(j) {
37389         return (0 <= j && j <= 15) ? 0x00000000 :
37390           (16 <= j && j <= 31) ? 0x5a827999 :
37391           (32 <= j && j <= 47) ? 0x6ed9eba1 :
37392           (48 <= j && j <= 63) ? 0x8f1bbcdc :
37393           (64 <= j && j <= 79) ? 0xa953fd4e :
37394           'rmd160_K1: j out of range';
37395       }
37396
37397       function rmd160_K2(j) {
37398         return (0 <= j && j <= 15) ? 0x50a28be6 :
37399           (16 <= j && j <= 31) ? 0x5c4dd124 :
37400           (32 <= j && j <= 47) ? 0x6d703ef3 :
37401           (48 <= j && j <= 63) ? 0x7a6d76e9 :
37402           (64 <= j && j <= 79) ? 0x00000000 :
37403           'rmd160_K2: j out of range';
37404       }
37405     }
37406   };
37407
37408   // exposes Hashes
37409   (function(window, undefined) {
37410     var freeExports = false;
37411     {
37412       freeExports = exports;
37413       if (exports && typeof commonjsGlobal === 'object' && commonjsGlobal && commonjsGlobal === commonjsGlobal.global) {
37414         window = commonjsGlobal;
37415       }
37416     }
37417
37418     if (typeof undefined === 'function' && typeof undefined.amd === 'object' && undefined.amd) {
37419       // define as an anonymous module, so, through path mapping, it can be aliased
37420       undefined(function() {
37421         return Hashes;
37422       });
37423     } else if (freeExports) {
37424       // in Node.js or RingoJS v0.8.0+
37425       if ('object' === 'object' && module && module.exports === freeExports) {
37426         module.exports = Hashes;
37427       }
37428       // in Narwhal or RingoJS v0.7.0-
37429       else {
37430         freeExports.Hashes = Hashes;
37431       }
37432     } else {
37433       // in a browser or Rhino
37434       window.Hashes = Hashes;
37435     }
37436   }(this));
37437 }()); // IIFE
37438 });
37439
37440 var immutable = extend$2;
37441
37442 var hasOwnProperty$16 = Object.prototype.hasOwnProperty;
37443
37444 function extend$2() {
37445     var target = {};
37446
37447     for (var i = 0; i < arguments.length; i++) {
37448         var source = arguments[i];
37449
37450         for (var key in source) {
37451             if (hasOwnProperty$16.call(source, key)) {
37452                 target[key] = source[key];
37453             }
37454         }
37455     }
37456
37457     return target
37458 }
37459
37460 var sha1 = new hashes.SHA1();
37461
37462 var ohauth = {};
37463
37464 ohauth.qsString = function(obj) {
37465     return Object.keys(obj).sort().map(function(key) {
37466         return ohauth.percentEncode(key) + '=' +
37467             ohauth.percentEncode(obj[key]);
37468     }).join('&');
37469 };
37470
37471 ohauth.stringQs = function(str) {
37472     return str.split('&').filter(function (pair) {
37473         return pair !== '';
37474     }).reduce(function(obj, pair){
37475         var parts = pair.split('=');
37476         obj[decodeURIComponent(parts[0])] = (null === parts[1]) ?
37477             '' : decodeURIComponent(parts[1]);
37478         return obj;
37479     }, {});
37480 };
37481
37482 ohauth.rawxhr = function(method, url, data, headers, callback) {
37483     var xhr = new XMLHttpRequest(),
37484         twoHundred = /^20\d$/;
37485     xhr.onreadystatechange = function() {
37486         if (4 === xhr.readyState && 0 !== xhr.status) {
37487             if (twoHundred.test(xhr.status)) callback(null, xhr);
37488             else return callback(xhr, null);
37489         }
37490     };
37491     xhr.onerror = function(e) { return callback(e, null); };
37492     xhr.open(method, url, true);
37493     for (var h in headers) xhr.setRequestHeader(h, headers[h]);
37494     xhr.send(data);
37495     return xhr;
37496 };
37497
37498 ohauth.xhr = function(method, url, auth, data, options, callback) {
37499     var headers = (options && options.header) || {
37500         'Content-Type': 'application/x-www-form-urlencoded'
37501     };
37502     headers.Authorization = 'OAuth ' + ohauth.authHeader(auth);
37503     return ohauth.rawxhr(method, url, data, headers, callback);
37504 };
37505
37506 ohauth.nonce = function() {
37507     for (var o = ''; o.length < 6;) {
37508         o += '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz'[Math.floor(Math.random() * 61)];
37509     }
37510     return o;
37511 };
37512
37513 ohauth.authHeader = function(obj) {
37514     return Object.keys(obj).sort().map(function(key) {
37515         return encodeURIComponent(key) + '="' + encodeURIComponent(obj[key]) + '"';
37516     }).join(', ');
37517 };
37518
37519 ohauth.timestamp = function() { return ~~((+new Date()) / 1000); };
37520
37521 ohauth.percentEncode = function(s) {
37522     return encodeURIComponent(s)
37523         .replace(/\!/g, '%21').replace(/\'/g, '%27')
37524         .replace(/\*/g, '%2A').replace(/\(/g, '%28').replace(/\)/g, '%29');
37525 };
37526
37527 ohauth.baseString = function(method, url, params) {
37528     if (params.oauth_signature) delete params.oauth_signature;
37529     return [
37530         method,
37531         ohauth.percentEncode(url),
37532         ohauth.percentEncode(ohauth.qsString(params))].join('&');
37533 };
37534
37535 ohauth.signature = function(oauth_secret, token_secret, baseString) {
37536     return sha1.b64_hmac(
37537         ohauth.percentEncode(oauth_secret) + '&' +
37538         ohauth.percentEncode(token_secret),
37539         baseString);
37540 };
37541
37542 /**
37543  * Takes an options object for configuration (consumer_key,
37544  * consumer_secret, version, signature_method, token, token_secret)
37545  * and returns a function that generates the Authorization header
37546  * for given data.
37547  *
37548  * The returned function takes these parameters:
37549  * - method: GET/POST/...
37550  * - uri: full URI with protocol, port, path and query string
37551  * - extra_params: any extra parameters (that are passed in the POST data),
37552  *   can be an object or a from-urlencoded string.
37553  *
37554  * Returned function returns full OAuth header with "OAuth" string in it.
37555  */
37556
37557 ohauth.headerGenerator = function(options) {
37558     options = options || {};
37559     var consumer_key = options.consumer_key || '',
37560         consumer_secret = options.consumer_secret || '',
37561         signature_method = options.signature_method || 'HMAC-SHA1',
37562         version = options.version || '1.0',
37563         token = options.token || '',
37564         token_secret = options.token_secret || '';
37565
37566     return function(method, uri, extra_params) {
37567         method = method.toUpperCase();
37568         if (typeof extra_params === 'string' && extra_params.length > 0) {
37569             extra_params = ohauth.stringQs(extra_params);
37570         }
37571
37572         var uri_parts = uri.split('?', 2),
37573         base_uri = uri_parts[0];
37574
37575         var query_params = uri_parts.length === 2 ?
37576             ohauth.stringQs(uri_parts[1]) : {};
37577
37578         var oauth_params = {
37579             oauth_consumer_key: consumer_key,
37580             oauth_signature_method: signature_method,
37581             oauth_version: version,
37582             oauth_timestamp: ohauth.timestamp(),
37583             oauth_nonce: ohauth.nonce()
37584         };
37585
37586         if (token) oauth_params.oauth_token = token;
37587
37588         var all_params = immutable({}, oauth_params, query_params, extra_params),
37589             base_str = ohauth.baseString(method, base_uri, all_params);
37590
37591         oauth_params.oauth_signature = ohauth.signature(consumer_secret, token_secret, base_str);
37592
37593         return 'OAuth ' + ohauth.authHeader(oauth_params);
37594     };
37595 };
37596
37597 var ohauth_1 = ohauth;
37598
37599 var resolveUrl = createCommonjsModule(function (module, exports) {
37600 // Copyright 2014 Simon Lydell
37601 // X11 (“MIT”) Licensed. (See LICENSE.)
37602
37603 void (function(root, factory) {
37604   if (typeof undefined === "function" && undefined.amd) {
37605     undefined(factory);
37606   } else {
37607     module.exports = factory();
37608   }
37609 }(commonjsGlobal, function() {
37610
37611   function resolveUrl(/* ...urls */) {
37612     var numUrls = arguments.length;
37613
37614     if (numUrls === 0) {
37615       throw new Error("resolveUrl requires at least one argument; got none.")
37616     }
37617
37618     var base = document.createElement("base");
37619     base.href = arguments[0];
37620
37621     if (numUrls === 1) {
37622       return base.href
37623     }
37624
37625     var head = document.getElementsByTagName("head")[0];
37626     head.insertBefore(base, head.firstChild);
37627
37628     var a = document.createElement("a");
37629     var resolved;
37630
37631     for (var index = 1; index < numUrls; index++) {
37632       a.href = arguments[index];
37633       resolved = a.href;
37634       base.href = resolved;
37635     }
37636
37637     head.removeChild(base);
37638
37639     return resolved
37640   }
37641
37642   return resolveUrl
37643
37644 }));
37645 });
37646
37647 var assign$1 = make_assign();
37648 var create$2 = make_create();
37649 var trim = make_trim();
37650 var Global = (typeof window !== 'undefined' ? window : commonjsGlobal);
37651
37652 var util = {
37653         assign: assign$1,
37654         create: create$2,
37655         trim: trim,
37656         bind: bind$1,
37657         slice: slice$8,
37658         each: each$1,
37659         map: map$5,
37660         pluck: pluck$1,
37661         isList: isList$1,
37662         isFunction: isFunction$2,
37663         isObject: isObject$3,
37664         Global: Global
37665 };
37666
37667 function make_assign() {
37668         if (Object.assign) {
37669                 return Object.assign
37670         } else {
37671                 return function shimAssign(obj, props1, props2, etc) {
37672                         for (var i = 1; i < arguments.length; i++) {
37673                                 each$1(Object(arguments[i]), function(val, key) {
37674                                         obj[key] = val;
37675                                 });
37676                         }                       
37677                         return obj
37678                 }
37679         }
37680 }
37681
37682 function make_create() {
37683         if (Object.create) {
37684                 return function create(obj, assignProps1, assignProps2, etc) {
37685                         var assignArgsList = slice$8(arguments, 1);
37686                         return assign$1.apply(this, [Object.create(obj)].concat(assignArgsList))
37687                 }
37688         } else {
37689                 function F() {} // eslint-disable-line no-inner-declarations
37690                 return function create(obj, assignProps1, assignProps2, etc) {
37691                         var assignArgsList = slice$8(arguments, 1);
37692                         F.prototype = obj;
37693                         return assign$1.apply(this, [new F()].concat(assignArgsList))
37694                 }
37695         }
37696 }
37697
37698 function make_trim() {
37699         if (String.prototype.trim) {
37700                 return function trim(str) {
37701                         return String.prototype.trim.call(str)
37702                 }
37703         } else {
37704                 return function trim(str) {
37705                         return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '')
37706                 }
37707         }
37708 }
37709
37710 function bind$1(obj, fn) {
37711         return function() {
37712                 return fn.apply(obj, Array.prototype.slice.call(arguments, 0))
37713         }
37714 }
37715
37716 function slice$8(arr, index) {
37717         return Array.prototype.slice.call(arr, index || 0)
37718 }
37719
37720 function each$1(obj, fn) {
37721         pluck$1(obj, function(val, key) {
37722                 fn(val, key);
37723                 return false
37724         });
37725 }
37726
37727 function map$5(obj, fn) {
37728         var res = (isList$1(obj) ? [] : {});
37729         pluck$1(obj, function(v, k) {
37730                 res[k] = fn(v, k);
37731                 return false
37732         });
37733         return res
37734 }
37735
37736 function pluck$1(obj, fn) {
37737         if (isList$1(obj)) {
37738                 for (var i=0; i<obj.length; i++) {
37739                         if (fn(obj[i], i)) {
37740                                 return obj[i]
37741                         }
37742                 }
37743         } else {
37744                 for (var key in obj) {
37745                         if (obj.hasOwnProperty(key)) {
37746                                 if (fn(obj[key], key)) {
37747                                         return obj[key]
37748                                 }
37749                         }
37750                 }
37751         }
37752 }
37753
37754 function isList$1(val) {
37755         return (val != null && typeof val != 'function' && typeof val.length == 'number')
37756 }
37757
37758 function isFunction$2(val) {
37759         return val && {}.toString.call(val) === '[object Function]'
37760 }
37761
37762 function isObject$3(val) {
37763         return val && {}.toString.call(val) === '[object Object]'
37764 }
37765
37766 var slice$7 = util.slice;
37767 var pluck = util.pluck;
37768 var each = util.each;
37769 var bind = util.bind;
37770 var create$1 = util.create;
37771 var isList = util.isList;
37772 var isFunction$1 = util.isFunction;
37773 var isObject$2 = util.isObject;
37774
37775 var storeEngine = {
37776         createStore: createStore
37777 };
37778
37779 var storeAPI = {
37780         version: '2.0.12',
37781         enabled: false,
37782         
37783         // get returns the value of the given key. If that value
37784         // is undefined, it returns optionalDefaultValue instead.
37785         get: function(key, optionalDefaultValue) {
37786                 var data = this.storage.read(this._namespacePrefix + key);
37787                 return this._deserialize(data, optionalDefaultValue)
37788         },
37789
37790         // set will store the given value at key and returns value.
37791         // Calling set with value === undefined is equivalent to calling remove.
37792         set: function(key, value) {
37793                 if (value === undefined) {
37794                         return this.remove(key)
37795                 }
37796                 this.storage.write(this._namespacePrefix + key, this._serialize(value));
37797                 return value
37798         },
37799
37800         // remove deletes the key and value stored at the given key.
37801         remove: function(key) {
37802                 this.storage.remove(this._namespacePrefix + key);
37803         },
37804
37805         // each will call the given callback once for each key-value pair
37806         // in this store.
37807         each: function(callback) {
37808                 var self = this;
37809                 this.storage.each(function(val, namespacedKey) {
37810                         callback.call(self, self._deserialize(val), (namespacedKey || '').replace(self._namespaceRegexp, ''));
37811                 });
37812         },
37813
37814         // clearAll will remove all the stored key-value pairs in this store.
37815         clearAll: function() {
37816                 this.storage.clearAll();
37817         },
37818
37819         // additional functionality that can't live in plugins
37820         // ---------------------------------------------------
37821
37822         // hasNamespace returns true if this store instance has the given namespace.
37823         hasNamespace: function(namespace) {
37824                 return (this._namespacePrefix == '__storejs_'+namespace+'_')
37825         },
37826
37827         // createStore creates a store.js instance with the first
37828         // functioning storage in the list of storage candidates,
37829         // and applies the the given mixins to the instance.
37830         createStore: function() {
37831                 return createStore.apply(this, arguments)
37832         },
37833         
37834         addPlugin: function(plugin) {
37835                 this._addPlugin(plugin);
37836         },
37837         
37838         namespace: function(namespace) {
37839                 return createStore(this.storage, this.plugins, namespace)
37840         }
37841 };
37842
37843 function _warn() {
37844         var _console = (typeof console == 'undefined' ? null : console);
37845         if (!_console) { return }
37846         var fn = (_console.warn ? _console.warn : _console.log);
37847         fn.apply(_console, arguments);
37848 }
37849
37850 function createStore(storages, plugins, namespace) {
37851         if (!namespace) {
37852                 namespace = '';
37853         }
37854         if (storages && !isList(storages)) {
37855                 storages = [storages];
37856         }
37857         if (plugins && !isList(plugins)) {
37858                 plugins = [plugins];
37859         }
37860
37861         var namespacePrefix = (namespace ? '__storejs_'+namespace+'_' : '');
37862         var namespaceRegexp = (namespace ? new RegExp('^'+namespacePrefix) : null);
37863         var legalNamespaces = /^[a-zA-Z0-9_\-]*$/; // alpha-numeric + underscore and dash
37864         if (!legalNamespaces.test(namespace)) {
37865                 throw new Error('store.js namespaces can only have alphanumerics + underscores and dashes')
37866         }
37867         
37868         var _privateStoreProps = {
37869                 _namespacePrefix: namespacePrefix,
37870                 _namespaceRegexp: namespaceRegexp,
37871
37872                 _testStorage: function(storage) {
37873                         try {
37874                                 var testStr = '__storejs__test__';
37875                                 storage.write(testStr, testStr);
37876                                 var ok = (storage.read(testStr) === testStr);
37877                                 storage.remove(testStr);
37878                                 return ok
37879                         } catch(e) {
37880                                 return false
37881                         }
37882                 },
37883
37884                 _assignPluginFnProp: function(pluginFnProp, propName) {
37885                         var oldFn = this[propName];
37886                         this[propName] = function pluginFn() {
37887                                 var args = slice$7(arguments, 0);
37888                                 var self = this;
37889
37890                                 // super_fn calls the old function which was overwritten by
37891                                 // this mixin.
37892                                 function super_fn() {
37893                                         if (!oldFn) { return }
37894                                         each(arguments, function(arg, i) {
37895                                                 args[i] = arg;
37896                                         });
37897                                         return oldFn.apply(self, args)
37898                                 }
37899
37900                                 // Give mixing function access to super_fn by prefixing all mixin function
37901                                 // arguments with super_fn.
37902                                 var newFnArgs = [super_fn].concat(args);
37903
37904                                 return pluginFnProp.apply(self, newFnArgs)
37905                         };
37906                 },
37907
37908                 _serialize: function(obj) {
37909                         return JSON.stringify(obj)
37910                 },
37911
37912                 _deserialize: function(strVal, defaultVal) {
37913                         if (!strVal) { return defaultVal }
37914                         // It is possible that a raw string value has been previously stored
37915                         // in a storage without using store.js, meaning it will be a raw
37916                         // string value instead of a JSON serialized string. By defaulting
37917                         // to the raw string value in case of a JSON parse error, we allow
37918                         // for past stored values to be forwards-compatible with store.js
37919                         var val = '';
37920                         try { val = JSON.parse(strVal); }
37921                         catch(e) { val = strVal; }
37922
37923                         return (val !== undefined ? val : defaultVal)
37924                 },
37925                 
37926                 _addStorage: function(storage) {
37927                         if (this.enabled) { return }
37928                         if (this._testStorage(storage)) {
37929                                 this.storage = storage;
37930                                 this.enabled = true;
37931                         }
37932                 },
37933
37934                 _addPlugin: function(plugin) {
37935                         var self = this;
37936
37937                         // If the plugin is an array, then add all plugins in the array.
37938                         // This allows for a plugin to depend on other plugins.
37939                         if (isList(plugin)) {
37940                                 each(plugin, function(plugin) {
37941                                         self._addPlugin(plugin);
37942                                 });
37943                                 return
37944                         }
37945
37946                         // Keep track of all plugins we've seen so far, so that we
37947                         // don't add any of them twice.
37948                         var seenPlugin = pluck(this.plugins, function(seenPlugin) {
37949                                 return (plugin === seenPlugin)
37950                         });
37951                         if (seenPlugin) {
37952                                 return
37953                         }
37954                         this.plugins.push(plugin);
37955
37956                         // Check that the plugin is properly formed
37957                         if (!isFunction$1(plugin)) {
37958                                 throw new Error('Plugins must be function values that return objects')
37959                         }
37960
37961                         var pluginProperties = plugin.call(this);
37962                         if (!isObject$2(pluginProperties)) {
37963                                 throw new Error('Plugins must return an object of function properties')
37964                         }
37965
37966                         // Add the plugin function properties to this store instance.
37967                         each(pluginProperties, function(pluginFnProp, propName) {
37968                                 if (!isFunction$1(pluginFnProp)) {
37969                                         throw new Error('Bad plugin property: '+propName+' from plugin '+plugin.name+'. Plugins should only return functions.')
37970                                 }
37971                                 self._assignPluginFnProp(pluginFnProp, propName);
37972                         });
37973                 },
37974                 
37975                 // Put deprecated properties in the private API, so as to not expose it to accidential
37976                 // discovery through inspection of the store object.
37977                 
37978                 // Deprecated: addStorage
37979                 addStorage: function(storage) {
37980                         _warn('store.addStorage(storage) is deprecated. Use createStore([storages])');
37981                         this._addStorage(storage);
37982                 }
37983         };
37984
37985         var store = create$1(_privateStoreProps, storeAPI, {
37986                 plugins: []
37987         });
37988         store.raw = {};
37989         each(store, function(prop, propName) {
37990                 if (isFunction$1(prop)) {
37991                         store.raw[propName] = bind(store, prop);                        
37992                 }
37993         });
37994         each(storages, function(storage) {
37995                 store._addStorage(storage);
37996         });
37997         each(plugins, function(plugin) {
37998                 store._addPlugin(plugin);
37999         });
38000         return store
38001 }
38002
38003 var Global$1 = util.Global;
38004
38005 var localStorage_1 = {
38006         name: 'localStorage',
38007         read: read,
38008         write: write,
38009         each: each$2,
38010         remove: remove$2,
38011         clearAll: clearAll,
38012 };
38013
38014 function localStorage$1() {
38015         return Global$1.localStorage
38016 }
38017
38018 function read(key) {
38019         return localStorage$1().getItem(key)
38020 }
38021
38022 function write(key, data) {
38023         return localStorage$1().setItem(key, data)
38024 }
38025
38026 function each$2(fn) {
38027         for (var i = localStorage$1().length - 1; i >= 0; i--) {
38028                 var key = localStorage$1().key(i);
38029                 fn(read(key), key);
38030         }
38031 }
38032
38033 function remove$2(key) {
38034         return localStorage$1().removeItem(key)
38035 }
38036
38037 function clearAll() {
38038         return localStorage$1().clear()
38039 }
38040
38041 // oldFF-globalStorage provides storage for Firefox
38042 // versions 6 and 7, where no localStorage, etc
38043 // is available.
38044
38045
38046 var Global$2 = util.Global;
38047
38048 var oldFFGlobalStorage = {
38049         name: 'oldFF-globalStorage',
38050         read: read$1,
38051         write: write$1,
38052         each: each$3,
38053         remove: remove$3,
38054         clearAll: clearAll$1,
38055 };
38056
38057 var globalStorage = Global$2.globalStorage;
38058
38059 function read$1(key) {
38060         return globalStorage[key]
38061 }
38062
38063 function write$1(key, data) {
38064         globalStorage[key] = data;
38065 }
38066
38067 function each$3(fn) {
38068         for (var i = globalStorage.length - 1; i >= 0; i--) {
38069                 var key = globalStorage.key(i);
38070                 fn(globalStorage[key], key);
38071         }
38072 }
38073
38074 function remove$3(key) {
38075         return globalStorage.removeItem(key)
38076 }
38077
38078 function clearAll$1() {
38079         each$3(function(key, _) {
38080                 delete globalStorage[key];
38081         });
38082 }
38083
38084 // oldIE-userDataStorage provides storage for Internet Explorer
38085 // versions 6 and 7, where no localStorage, sessionStorage, etc
38086 // is available.
38087
38088
38089 var Global$3 = util.Global;
38090
38091 var oldIEUserDataStorage = {
38092         name: 'oldIE-userDataStorage',
38093         write: write$2,
38094         read: read$2,
38095         each: each$4,
38096         remove: remove$4,
38097         clearAll: clearAll$2,
38098 };
38099
38100 var storageName = 'storejs';
38101 var doc = Global$3.document;
38102 var _withStorageEl = _makeIEStorageElFunction();
38103 var disable = (Global$3.navigator ? Global$3.navigator.userAgent : '').match(/ (MSIE 8|MSIE 9|MSIE 10)\./); // MSIE 9.x, MSIE 10.x
38104
38105 function write$2(unfixedKey, data) {
38106         if (disable) { return }
38107         var fixedKey = fixKey(unfixedKey);
38108         _withStorageEl(function(storageEl) {
38109                 storageEl.setAttribute(fixedKey, data);
38110                 storageEl.save(storageName);
38111         });
38112 }
38113
38114 function read$2(unfixedKey) {
38115         if (disable) { return }
38116         var fixedKey = fixKey(unfixedKey);
38117         var res = null;
38118         _withStorageEl(function(storageEl) {
38119                 res = storageEl.getAttribute(fixedKey);
38120         });
38121         return res
38122 }
38123
38124 function each$4(callback) {
38125         _withStorageEl(function(storageEl) {
38126                 var attributes = storageEl.XMLDocument.documentElement.attributes;
38127                 for (var i=attributes.length-1; i>=0; i--) {
38128                         var attr = attributes[i];
38129                         callback(storageEl.getAttribute(attr.name), attr.name);
38130                 }
38131         });
38132 }
38133
38134 function remove$4(unfixedKey) {
38135         var fixedKey = fixKey(unfixedKey);
38136         _withStorageEl(function(storageEl) {
38137                 storageEl.removeAttribute(fixedKey);
38138                 storageEl.save(storageName);
38139         });
38140 }
38141
38142 function clearAll$2() {
38143         _withStorageEl(function(storageEl) {
38144                 var attributes = storageEl.XMLDocument.documentElement.attributes;
38145                 storageEl.load(storageName);
38146                 for (var i=attributes.length-1; i>=0; i--) {
38147                         storageEl.removeAttribute(attributes[i].name);
38148                 }
38149                 storageEl.save(storageName);
38150         });
38151 }
38152
38153 // Helpers
38154 //////////
38155
38156 // In IE7, keys cannot start with a digit or contain certain chars.
38157 // See https://github.com/marcuswestin/store.js/issues/40
38158 // See https://github.com/marcuswestin/store.js/issues/83
38159 var forbiddenCharsRegex = new RegExp("[!\"#$%&'()*+,/\\\\:;<=>?@[\\]^`{|}~]", "g");
38160 function fixKey(key) {
38161         return key.replace(/^\d/, '___$&').replace(forbiddenCharsRegex, '___')
38162 }
38163
38164 function _makeIEStorageElFunction() {
38165         if (!doc || !doc.documentElement || !doc.documentElement.addBehavior) {
38166                 return null
38167         }
38168         var scriptTag = 'script',
38169                 storageOwner,
38170                 storageContainer,
38171                 storageEl;
38172
38173         // Since #userData storage applies only to specific paths, we need to
38174         // somehow link our data to a specific path.  We choose /favicon.ico
38175         // as a pretty safe option, since all browsers already make a request to
38176         // this URL anyway and being a 404 will not hurt us here.  We wrap an
38177         // iframe pointing to the favicon in an ActiveXObject(htmlfile) object
38178         // (see: http://msdn.microsoft.com/en-us/library/aa752574(v=VS.85).aspx)
38179         // since the iframe access rules appear to allow direct access and
38180         // manipulation of the document element, even for a 404 page.  This
38181         // document can be used instead of the current document (which would
38182         // have been limited to the current path) to perform #userData storage.
38183         try {
38184                 /* global ActiveXObject */
38185                 storageContainer = new ActiveXObject('htmlfile');
38186                 storageContainer.open();
38187                 storageContainer.write('<'+scriptTag+'>document.w=window</'+scriptTag+'><iframe src="/favicon.ico"></iframe>');
38188                 storageContainer.close();
38189                 storageOwner = storageContainer.w.frames[0].document;
38190                 storageEl = storageOwner.createElement('div');
38191         } catch(e) {
38192                 // somehow ActiveXObject instantiation failed (perhaps some special
38193                 // security settings or otherwse), fall back to per-path storage
38194                 storageEl = doc.createElement('div');
38195                 storageOwner = doc.body;
38196         }
38197
38198         return function(storeFunction) {
38199                 var args = [].slice.call(arguments, 0);
38200                 args.unshift(storageEl);
38201                 // See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx
38202                 // and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx
38203                 storageOwner.appendChild(storageEl);
38204                 storageEl.addBehavior('#default#userData');
38205                 storageEl.load(storageName);
38206                 storeFunction.apply(this, args);
38207                 storageOwner.removeChild(storageEl);
38208                 return
38209         }
38210 }
38211
38212 // cookieStorage is useful Safari private browser mode, where localStorage
38213 // doesn't work but cookies do. This implementation is adopted from
38214 // https://developer.mozilla.org/en-US/docs/Web/API/Storage/LocalStorage
38215
38216
38217 var Global$4 = util.Global;
38218 var trim$1 = util.trim;
38219
38220 var cookieStorage = {
38221         name: 'cookieStorage',
38222         read: read$3,
38223         write: write$3,
38224         each: each$5,
38225         remove: remove$5,
38226         clearAll: clearAll$3,
38227 };
38228
38229 var doc$1 = Global$4.document;
38230
38231 function read$3(key) {
38232         if (!key || !_has(key)) { return null }
38233         var regexpStr = "(?:^|.*;\\s*)" +
38234                 escape(key).replace(/[\-\.\+\*]/g, "\\$&") +
38235                 "\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*";
38236         return unescape(doc$1.cookie.replace(new RegExp(regexpStr), "$1"))
38237 }
38238
38239 function each$5(callback) {
38240         var cookies = doc$1.cookie.split(/; ?/g);
38241         for (var i = cookies.length - 1; i >= 0; i--) {
38242                 if (!trim$1(cookies[i])) {
38243                         continue
38244                 }
38245                 var kvp = cookies[i].split('=');
38246                 var key = unescape(kvp[0]);
38247                 var val = unescape(kvp[1]);
38248                 callback(val, key);
38249         }
38250 }
38251
38252 function write$3(key, data) {
38253         if(!key) { return }
38254         doc$1.cookie = escape(key) + "=" + escape(data) + "; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/";
38255 }
38256
38257 function remove$5(key) {
38258         if (!key || !_has(key)) {
38259                 return
38260         }
38261         doc$1.cookie = escape(key) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";
38262 }
38263
38264 function clearAll$3() {
38265         each$5(function(_, key) {
38266                 remove$5(key);
38267         });
38268 }
38269
38270 function _has(key) {
38271         return (new RegExp("(?:^|;\\s*)" + escape(key).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(doc$1.cookie)
38272 }
38273
38274 var Global$5 = util.Global;
38275
38276 var sessionStorage_1 = {
38277         name: 'sessionStorage',
38278         read: read$4,
38279         write: write$4,
38280         each: each$6,
38281         remove: remove$6,
38282         clearAll: clearAll$4
38283 };
38284
38285 function sessionStorage() {
38286         return Global$5.sessionStorage
38287 }
38288
38289 function read$4(key) {
38290         return sessionStorage().getItem(key)
38291 }
38292
38293 function write$4(key, data) {
38294         return sessionStorage().setItem(key, data)
38295 }
38296
38297 function each$6(fn) {
38298         for (var i = sessionStorage().length - 1; i >= 0; i--) {
38299                 var key = sessionStorage().key(i);
38300                 fn(read$4(key), key);
38301         }
38302 }
38303
38304 function remove$6(key) {
38305         return sessionStorage().removeItem(key)
38306 }
38307
38308 function clearAll$4() {
38309         return sessionStorage().clear()
38310 }
38311
38312 // memoryStorage is a useful last fallback to ensure that the store
38313 // is functions (meaning store.get(), store.set(), etc will all function).
38314 // However, stored values will not persist when the browser navigates to
38315 // a new page or reloads the current page.
38316
38317 var memoryStorage_1 = {
38318         name: 'memoryStorage',
38319         read: read$5,
38320         write: write$5,
38321         each: each$7,
38322         remove: remove$7,
38323         clearAll: clearAll$5,
38324 };
38325
38326 var memoryStorage = {};
38327
38328 function read$5(key) {
38329         return memoryStorage[key]
38330 }
38331
38332 function write$5(key, data) {
38333         memoryStorage[key] = data;
38334 }
38335
38336 function each$7(callback) {
38337         for (var key in memoryStorage) {
38338                 if (memoryStorage.hasOwnProperty(key)) {
38339                         callback(memoryStorage[key], key);
38340                 }
38341         }
38342 }
38343
38344 function remove$7(key) {
38345         delete memoryStorage[key];
38346 }
38347
38348 function clearAll$5(key) {
38349         memoryStorage = {};
38350 }
38351
38352 var all$3 = [
38353         // Listed in order of usage preference
38354         localStorage_1,
38355         oldFFGlobalStorage,
38356         oldIEUserDataStorage,
38357         cookieStorage,
38358         sessionStorage_1,
38359         memoryStorage_1
38360 ];
38361
38362 /* eslint-disable */
38363
38364 //  json2.js
38365 //  2016-10-28
38366 //  Public Domain.
38367 //  NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
38368 //  See http://www.JSON.org/js.html
38369 //  This code should be minified before deployment.
38370 //  See http://javascript.crockford.com/jsmin.html
38371
38372 //  USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
38373 //  NOT CONTROL.
38374
38375 //  This file creates a global JSON object containing two methods: stringify
38376 //  and parse. This file provides the ES5 JSON capability to ES3 systems.
38377 //  If a project might run on IE8 or earlier, then this file should be included.
38378 //  This file does nothing on ES5 systems.
38379
38380 //      JSON.stringify(value, replacer, space)
38381 //          value       any JavaScript value, usually an object or array.
38382 //          replacer    an optional parameter that determines how object
38383 //                      values are stringified for objects. It can be a
38384 //                      function or an array of strings.
38385 //          space       an optional parameter that specifies the indentation
38386 //                      of nested structures. If it is omitted, the text will
38387 //                      be packed without extra whitespace. If it is a number,
38388 //                      it will specify the number of spaces to indent at each
38389 //                      level. If it is a string (such as "\t" or "&nbsp;"),
38390 //                      it contains the characters used to indent at each level.
38391 //          This method produces a JSON text from a JavaScript value.
38392 //          When an object value is found, if the object contains a toJSON
38393 //          method, its toJSON method will be called and the result will be
38394 //          stringified. A toJSON method does not serialize: it returns the
38395 //          value represented by the name/value pair that should be serialized,
38396 //          or undefined if nothing should be serialized. The toJSON method
38397 //          will be passed the key associated with the value, and this will be
38398 //          bound to the value.
38399
38400 //          For example, this would serialize Dates as ISO strings.
38401
38402 //              Date.prototype.toJSON = function (key) {
38403 //                  function f(n) {
38404 //                      // Format integers to have at least two digits.
38405 //                      return (n < 10)
38406 //                          ? "0" + n
38407 //                          : n;
38408 //                  }
38409 //                  return this.getUTCFullYear()   + "-" +
38410 //                       f(this.getUTCMonth() + 1) + "-" +
38411 //                       f(this.getUTCDate())      + "T" +
38412 //                       f(this.getUTCHours())     + ":" +
38413 //                       f(this.getUTCMinutes())   + ":" +
38414 //                       f(this.getUTCSeconds())   + "Z";
38415 //              };
38416
38417 //          You can provide an optional replacer method. It will be passed the
38418 //          key and value of each member, with this bound to the containing
38419 //          object. The value that is returned from your method will be
38420 //          serialized. If your method returns undefined, then the member will
38421 //          be excluded from the serialization.
38422
38423 //          If the replacer parameter is an array of strings, then it will be
38424 //          used to select the members to be serialized. It filters the results
38425 //          such that only members with keys listed in the replacer array are
38426 //          stringified.
38427
38428 //          Values that do not have JSON representations, such as undefined or
38429 //          functions, will not be serialized. Such values in objects will be
38430 //          dropped; in arrays they will be replaced with null. You can use
38431 //          a replacer function to replace those with JSON values.
38432
38433 //          JSON.stringify(undefined) returns undefined.
38434
38435 //          The optional space parameter produces a stringification of the
38436 //          value that is filled with line breaks and indentation to make it
38437 //          easier to read.
38438
38439 //          If the space parameter is a non-empty string, then that string will
38440 //          be used for indentation. If the space parameter is a number, then
38441 //          the indentation will be that many spaces.
38442
38443 //          Example:
38444
38445 //          text = JSON.stringify(["e", {pluribus: "unum"}]);
38446 //          // text is '["e",{"pluribus":"unum"}]'
38447
38448 //          text = JSON.stringify(["e", {pluribus: "unum"}], null, "\t");
38449 //          // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
38450
38451 //          text = JSON.stringify([new Date()], function (key, value) {
38452 //              return this[key] instanceof Date
38453 //                  ? "Date(" + this[key] + ")"
38454 //                  : value;
38455 //          });
38456 //          // text is '["Date(---current time---)"]'
38457
38458 //      JSON.parse(text, reviver)
38459 //          This method parses a JSON text to produce an object or array.
38460 //          It can throw a SyntaxError exception.
38461
38462 //          The optional reviver parameter is a function that can filter and
38463 //          transform the results. It receives each of the keys and values,
38464 //          and its return value is used instead of the original value.
38465 //          If it returns what it received, then the structure is not modified.
38466 //          If it returns undefined then the member is deleted.
38467
38468 //          Example:
38469
38470 //          // Parse the text. Values that look like ISO date strings will
38471 //          // be converted to Date objects.
38472
38473 //          myData = JSON.parse(text, function (key, value) {
38474 //              var a;
38475 //              if (typeof value === "string") {
38476 //                  a =
38477 //   /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
38478 //                  if (a) {
38479 //                      return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
38480 //                          +a[5], +a[6]));
38481 //                  }
38482 //              }
38483 //              return value;
38484 //          });
38485
38486 //          myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
38487 //              var d;
38488 //              if (typeof value === "string" &&
38489 //                      value.slice(0, 5) === "Date(" &&
38490 //                      value.slice(-1) === ")") {
38491 //                  d = new Date(value.slice(5, -1));
38492 //                  if (d) {
38493 //                      return d;
38494 //                  }
38495 //              }
38496 //              return value;
38497 //          });
38498
38499 //  This is a reference implementation. You are free to copy, modify, or
38500 //  redistribute.
38501
38502 /*jslint
38503     eval, for, this
38504 */
38505
38506 /*property
38507     JSON, apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
38508     getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
38509     lastIndex, length, parse, prototype, push, replace, slice, stringify,
38510     test, toJSON, toString, valueOf
38511 */
38512
38513
38514 // Create a JSON object only if one does not already exist. We create the
38515 // methods in a closure to avoid creating global variables.
38516
38517 if (typeof JSON !== "object") {
38518     JSON = {};
38519 }
38520
38521 (function () {
38522     var rx_one = /^[\],:{}\s]*$/;
38523     var rx_two = /\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g;
38524     var rx_three = /"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g;
38525     var rx_four = /(?:^|:|,)(?:\s*\[)+/g;
38526     var rx_escapable = /[\\"\u0000-\u001f\u007f-\u009f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
38527     var rx_dangerous = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
38528
38529     function f(n) {
38530         // Format integers to have at least two digits.
38531         return n < 10
38532             ? "0" + n
38533             : n;
38534     }
38535
38536     function this_value() {
38537         return this.valueOf();
38538     }
38539
38540     if (typeof Date.prototype.toJSON !== "function") {
38541
38542         Date.prototype.toJSON = function () {
38543
38544             return isFinite(this.valueOf())
38545                 ? this.getUTCFullYear() + "-" +
38546                         f(this.getUTCMonth() + 1) + "-" +
38547                         f(this.getUTCDate()) + "T" +
38548                         f(this.getUTCHours()) + ":" +
38549                         f(this.getUTCMinutes()) + ":" +
38550                         f(this.getUTCSeconds()) + "Z"
38551                 : null;
38552         };
38553
38554         Boolean.prototype.toJSON = this_value;
38555         Number.prototype.toJSON = this_value;
38556         String.prototype.toJSON = this_value;
38557     }
38558
38559     var gap;
38560     var indent;
38561     var meta;
38562     var rep;
38563
38564
38565     function quote(string) {
38566
38567 // If the string contains no control characters, no quote characters, and no
38568 // backslash characters, then we can safely slap some quotes around it.
38569 // Otherwise we must also replace the offending characters with safe escape
38570 // sequences.
38571
38572         rx_escapable.lastIndex = 0;
38573         return rx_escapable.test(string)
38574             ? "\"" + string.replace(rx_escapable, function (a) {
38575                 var c = meta[a];
38576                 return typeof c === "string"
38577                     ? c
38578                     : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
38579             }) + "\""
38580             : "\"" + string + "\"";
38581     }
38582
38583
38584     function str(key, holder) {
38585
38586 // Produce a string from holder[key].
38587
38588         var i;          // The loop counter.
38589         var k;          // The member key.
38590         var v;          // The member value.
38591         var length;
38592         var mind = gap;
38593         var partial;
38594         var value = holder[key];
38595
38596 // If the value has a toJSON method, call it to obtain a replacement value.
38597
38598         if (value && typeof value === "object" &&
38599                 typeof value.toJSON === "function") {
38600             value = value.toJSON(key);
38601         }
38602
38603 // If we were called with a replacer function, then call the replacer to
38604 // obtain a replacement value.
38605
38606         if (typeof rep === "function") {
38607             value = rep.call(holder, key, value);
38608         }
38609
38610 // What happens next depends on the value's type.
38611
38612         switch (typeof value) {
38613         case "string":
38614             return quote(value);
38615
38616         case "number":
38617
38618 // JSON numbers must be finite. Encode non-finite numbers as null.
38619
38620             return isFinite(value)
38621                 ? String(value)
38622                 : "null";
38623
38624         case "boolean":
38625         case "null":
38626
38627 // If the value is a boolean or null, convert it to a string. Note:
38628 // typeof null does not produce "null". The case is included here in
38629 // the remote chance that this gets fixed someday.
38630
38631             return String(value);
38632
38633 // If the type is "object", we might be dealing with an object or an array or
38634 // null.
38635
38636         case "object":
38637
38638 // Due to a specification blunder in ECMAScript, typeof null is "object",
38639 // so watch out for that case.
38640
38641             if (!value) {
38642                 return "null";
38643             }
38644
38645 // Make an array to hold the partial results of stringifying this object value.
38646
38647             gap += indent;
38648             partial = [];
38649
38650 // Is the value an array?
38651
38652             if (Object.prototype.toString.apply(value) === "[object Array]") {
38653
38654 // The value is an array. Stringify every element. Use null as a placeholder
38655 // for non-JSON values.
38656
38657                 length = value.length;
38658                 for (i = 0; i < length; i += 1) {
38659                     partial[i] = str(i, value) || "null";
38660                 }
38661
38662 // Join all of the elements together, separated with commas, and wrap them in
38663 // brackets.
38664
38665                 v = partial.length === 0
38666                     ? "[]"
38667                     : gap
38668                         ? "[\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "]"
38669                         : "[" + partial.join(",") + "]";
38670                 gap = mind;
38671                 return v;
38672             }
38673
38674 // If the replacer is an array, use it to select the members to be stringified.
38675
38676             if (rep && typeof rep === "object") {
38677                 length = rep.length;
38678                 for (i = 0; i < length; i += 1) {
38679                     if (typeof rep[i] === "string") {
38680                         k = rep[i];
38681                         v = str(k, value);
38682                         if (v) {
38683                             partial.push(quote(k) + (
38684                                 gap
38685                                     ? ": "
38686                                     : ":"
38687                             ) + v);
38688                         }
38689                     }
38690                 }
38691             } else {
38692
38693 // Otherwise, iterate through all of the keys in the object.
38694
38695                 for (k in value) {
38696                     if (Object.prototype.hasOwnProperty.call(value, k)) {
38697                         v = str(k, value);
38698                         if (v) {
38699                             partial.push(quote(k) + (
38700                                 gap
38701                                     ? ": "
38702                                     : ":"
38703                             ) + v);
38704                         }
38705                     }
38706                 }
38707             }
38708
38709 // Join all of the member texts together, separated with commas,
38710 // and wrap them in braces.
38711
38712             v = partial.length === 0
38713                 ? "{}"
38714                 : gap
38715                     ? "{\n" + gap + partial.join(",\n" + gap) + "\n" + mind + "}"
38716                     : "{" + partial.join(",") + "}";
38717             gap = mind;
38718             return v;
38719         }
38720     }
38721
38722 // If the JSON object does not yet have a stringify method, give it one.
38723
38724     if (typeof JSON.stringify !== "function") {
38725         meta = {    // table of character substitutions
38726             "\b": "\\b",
38727             "\t": "\\t",
38728             "\n": "\\n",
38729             "\f": "\\f",
38730             "\r": "\\r",
38731             "\"": "\\\"",
38732             "\\": "\\\\"
38733         };
38734         JSON.stringify = function (value, replacer, space) {
38735
38736 // The stringify method takes a value and an optional replacer, and an optional
38737 // space parameter, and returns a JSON text. The replacer can be a function
38738 // that can replace values, or an array of strings that will select the keys.
38739 // A default replacer method can be provided. Use of the space parameter can
38740 // produce text that is more easily readable.
38741
38742             var i;
38743             gap = "";
38744             indent = "";
38745
38746 // If the space parameter is a number, make an indent string containing that
38747 // many spaces.
38748
38749             if (typeof space === "number") {
38750                 for (i = 0; i < space; i += 1) {
38751                     indent += " ";
38752                 }
38753
38754 // If the space parameter is a string, it will be used as the indent string.
38755
38756             } else if (typeof space === "string") {
38757                 indent = space;
38758             }
38759
38760 // If there is a replacer, it must be a function or an array.
38761 // Otherwise, throw an error.
38762
38763             rep = replacer;
38764             if (replacer && typeof replacer !== "function" &&
38765                     (typeof replacer !== "object" ||
38766                     typeof replacer.length !== "number")) {
38767                 throw new Error("JSON.stringify");
38768             }
38769
38770 // Make a fake root object containing our value under the key of "".
38771 // Return the result of stringifying the value.
38772
38773             return str("", {"": value});
38774         };
38775     }
38776
38777
38778 // If the JSON object does not yet have a parse method, give it one.
38779
38780     if (typeof JSON.parse !== "function") {
38781         JSON.parse = function (text, reviver) {
38782
38783 // The parse method takes a text and an optional reviver function, and returns
38784 // a JavaScript value if the text is a valid JSON text.
38785
38786             var j;
38787
38788             function walk(holder, key) {
38789
38790 // The walk method is used to recursively walk the resulting structure so
38791 // that modifications can be made.
38792
38793                 var k;
38794                 var v;
38795                 var value = holder[key];
38796                 if (value && typeof value === "object") {
38797                     for (k in value) {
38798                         if (Object.prototype.hasOwnProperty.call(value, k)) {
38799                             v = walk(value, k);
38800                             if (v !== undefined) {
38801                                 value[k] = v;
38802                             } else {
38803                                 delete value[k];
38804                             }
38805                         }
38806                     }
38807                 }
38808                 return reviver.call(holder, key, value);
38809             }
38810
38811
38812 // Parsing happens in four stages. In the first stage, we replace certain
38813 // Unicode characters with escape sequences. JavaScript handles many characters
38814 // incorrectly, either silently deleting them, or treating them as line endings.
38815
38816             text = String(text);
38817             rx_dangerous.lastIndex = 0;
38818             if (rx_dangerous.test(text)) {
38819                 text = text.replace(rx_dangerous, function (a) {
38820                     return "\\u" +
38821                             ("0000" + a.charCodeAt(0).toString(16)).slice(-4);
38822                 });
38823             }
38824
38825 // In the second stage, we run the text against regular expressions that look
38826 // for non-JSON patterns. We are especially concerned with "()" and "new"
38827 // because they can cause invocation, and "=" because it can cause mutation.
38828 // But just to be safe, we want to reject all unexpected forms.
38829
38830 // We split the second stage into 4 regexp operations in order to work around
38831 // crippling inefficiencies in IE's and Safari's regexp engines. First we
38832 // replace the JSON backslash pairs with "@" (a non-JSON character). Second, we
38833 // replace all simple value tokens with "]" characters. Third, we delete all
38834 // open brackets that follow a colon or comma or that begin the text. Finally,
38835 // we look to see that the remaining characters are only whitespace or "]" or
38836 // "," or ":" or "{" or "}". If that is so, then the text is safe for eval.
38837
38838             if (
38839                 rx_one.test(
38840                     text
38841                         .replace(rx_two, "@")
38842                         .replace(rx_three, "]")
38843                         .replace(rx_four, "")
38844                 )
38845             ) {
38846
38847 // In the third stage we use the eval function to compile the text into a
38848 // JavaScript structure. The "{" operator is subject to a syntactic ambiguity
38849 // in JavaScript: it can begin a block or an object literal. We wrap the text
38850 // in parens to eliminate the ambiguity.
38851
38852                 j = eval("(" + text + ")");
38853
38854 // In the optional fourth stage, we recursively walk the new structure, passing
38855 // each name/value pair to a reviver function for possible transformation.
38856
38857                 return (typeof reviver === "function")
38858                     ? walk({"": j}, "")
38859                     : j;
38860             }
38861
38862 // If the text is not JSON parseable, then a SyntaxError is thrown.
38863
38864             throw new SyntaxError("JSON.parse");
38865         };
38866     }
38867 }());
38868
38869 var json2 = json2Plugin;
38870
38871 function json2Plugin() {
38872         
38873         return {}
38874 }
38875
38876 var plugins = [json2];
38877
38878 var store_legacy = storeEngine.createStore(all$3, plugins);
38879
38880 // # osm-auth
38881 //
38882 // This code is only compatible with IE10+ because the [XDomainRequest](http://bit.ly/LfO7xo)
38883 // object, IE<10's idea of [CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing),
38884 // does not support custom headers, which this uses everywhere.
38885 var osmAuth = function(o) {
38886
38887     var oauth = {};
38888
38889     // authenticated users will also have a request token secret, but it's
38890     // not used in transactions with the server
38891     oauth.authenticated = function() {
38892         return !!(token('oauth_token') && token('oauth_token_secret'));
38893     };
38894
38895     oauth.logout = function() {
38896         token('oauth_token', '');
38897         token('oauth_token_secret', '');
38898         token('oauth_request_token_secret', '');
38899         return oauth;
38900     };
38901
38902     // TODO: detect lack of click event
38903     oauth.authenticate = function(callback) {
38904         if (oauth.authenticated()) return callback();
38905
38906         oauth.logout();
38907
38908         // ## Getting a request token
38909         var params = timenonce(getAuth(o)),
38910             url = o.url + '/oauth/request_token';
38911
38912         params.oauth_signature = ohauth_1.signature(
38913             o.oauth_secret, '',
38914             ohauth_1.baseString('POST', url, params));
38915
38916         if (!o.singlepage) {
38917             // Create a 600x550 popup window in the center of the screen
38918             var w = 600, h = 550,
38919                 settings = [
38920                     ['width', w], ['height', h],
38921                     ['left', screen.width / 2 - w / 2],
38922                     ['top', screen.height / 2 - h / 2]].map(function(x) {
38923                         return x.join('=');
38924                     }).join(','),
38925                 popup = window.open('about:blank', 'oauth_window', settings);
38926         }
38927
38928         // Request a request token. When this is complete, the popup
38929         // window is redirected to OSM's authorization page.
38930         ohauth_1.xhr('POST', url, params, null, {}, reqTokenDone);
38931         o.loading();
38932
38933         function reqTokenDone(err, xhr) {
38934             o.done();
38935             if (err) return callback(err);
38936             var resp = ohauth_1.stringQs(xhr.response);
38937             token('oauth_request_token_secret', resp.oauth_token_secret);
38938             var authorize_url = o.url + '/oauth/authorize?' + ohauth_1.qsString({
38939                 oauth_token: resp.oauth_token,
38940                 oauth_callback: resolveUrl(o.landing)
38941             });
38942
38943             if (o.singlepage) {
38944                 location.href = authorize_url;
38945             } else {
38946                 popup.location = authorize_url;
38947             }
38948         }
38949
38950         // Called by a function in a landing page, in the popup window. The
38951         // window closes itself.
38952         window.authComplete = function(token) {
38953             var oauth_token = ohauth_1.stringQs(token.split('?')[1]);
38954             get_access_token(oauth_token.oauth_token);
38955             delete window.authComplete;
38956         };
38957
38958         // ## Getting an request token
38959         //
38960         // At this point we have an `oauth_token`, brought in from a function
38961         // call on a landing page popup.
38962         function get_access_token(oauth_token) {
38963             var url = o.url + '/oauth/access_token',
38964                 params = timenonce(getAuth(o)),
38965                 request_token_secret = token('oauth_request_token_secret');
38966             params.oauth_token = oauth_token;
38967             params.oauth_signature = ohauth_1.signature(
38968                 o.oauth_secret,
38969                 request_token_secret,
38970                 ohauth_1.baseString('POST', url, params));
38971
38972             // ## Getting an access token
38973             //
38974             // The final token required for authentication. At this point
38975             // we have a `request token secret`
38976             ohauth_1.xhr('POST', url, params, null, {}, accessTokenDone);
38977             o.loading();
38978         }
38979
38980         function accessTokenDone(err, xhr) {
38981             o.done();
38982             if (err) return callback(err);
38983             var access_token = ohauth_1.stringQs(xhr.response);
38984             token('oauth_token', access_token.oauth_token);
38985             token('oauth_token_secret', access_token.oauth_token_secret);
38986             callback(null, oauth);
38987         }
38988     };
38989
38990     oauth.bootstrapToken = function(oauth_token, callback) {
38991         // ## Getting an request token
38992         // At this point we have an `oauth_token`, brought in from a function
38993         // call on a landing page popup.
38994         function get_access_token(oauth_token) {
38995             var url = o.url + '/oauth/access_token',
38996                 params = timenonce(getAuth(o)),
38997                 request_token_secret = token('oauth_request_token_secret');
38998             params.oauth_token = oauth_token;
38999             params.oauth_signature = ohauth_1.signature(
39000                 o.oauth_secret,
39001                 request_token_secret,
39002                 ohauth_1.baseString('POST', url, params));
39003
39004             // ## Getting an access token
39005             // The final token required for authentication. At this point
39006             // we have a `request token secret`
39007             ohauth_1.xhr('POST', url, params, null, {}, accessTokenDone);
39008             o.loading();
39009         }
39010
39011         function accessTokenDone(err, xhr) {
39012             o.done();
39013             if (err) return callback(err);
39014             var access_token = ohauth_1.stringQs(xhr.response);
39015             token('oauth_token', access_token.oauth_token);
39016             token('oauth_token_secret', access_token.oauth_token_secret);
39017             callback(null, oauth);
39018         }
39019
39020         get_access_token(oauth_token);
39021     };
39022
39023     // # xhr
39024     //
39025     // A single XMLHttpRequest wrapper that does authenticated calls if the
39026     // user has logged in.
39027     oauth.xhr = function(options, callback) {
39028         if (!oauth.authenticated()) {
39029             if (o.auto) {
39030                 return oauth.authenticate(run);
39031             } else {
39032                 callback('not authenticated', null);
39033                 return;
39034             }
39035         } else {
39036             return run();
39037         }
39038
39039         function run() {
39040             var params = timenonce(getAuth(o)),
39041                 oauth_token_secret = token('oauth_token_secret'),
39042                 url = (options.prefix !== false) ? o.url + options.path : options.path,
39043                 url_parts = url.replace(/#.*$/, '').split('?', 2),
39044                 base_url = url_parts[0],
39045                 query = (url_parts.length === 2) ? url_parts[1] : '';
39046
39047             // https://tools.ietf.org/html/rfc5849#section-3.4.1.3.1
39048             if ((!options.options || !options.options.header ||
39049                 options.options.header['Content-Type'] === 'application/x-www-form-urlencoded') &&
39050                 options.content) {
39051                 params = immutable(params, ohauth_1.stringQs(options.content));
39052             }
39053
39054             params.oauth_token = token('oauth_token');
39055             params.oauth_signature = ohauth_1.signature(
39056                 o.oauth_secret,
39057                 oauth_token_secret,
39058                 ohauth_1.baseString(options.method, base_url, immutable(params, ohauth_1.stringQs(query)))
39059             );
39060
39061             return ohauth_1.xhr(options.method, url, params, options.content, options.options, done);
39062         }
39063
39064         function done(err, xhr) {
39065             if (err) return callback(err);
39066             else if (xhr.responseXML) return callback(err, xhr.responseXML);
39067             else return callback(err, xhr.response);
39068         }
39069     };
39070
39071     // pre-authorize this object, if we can just get a token and token_secret
39072     // from the start
39073     oauth.preauth = function(c) {
39074         if (!c) return;
39075         if (c.oauth_token) token('oauth_token', c.oauth_token);
39076         if (c.oauth_token_secret) token('oauth_token_secret', c.oauth_token_secret);
39077         return oauth;
39078     };
39079
39080     oauth.options = function(_) {
39081         if (!arguments.length) return o;
39082
39083         o = _;
39084         o.url = o.url || 'https://www.openstreetmap.org';
39085         o.landing = o.landing || 'land.html';
39086         o.singlepage = o.singlepage || false;
39087
39088         // Optional loading and loading-done functions for nice UI feedback.
39089         // by default, no-ops
39090         o.loading = o.loading || function() {};
39091         o.done = o.done || function() {};
39092
39093         return oauth.preauth(o);
39094     };
39095
39096     // 'stamp' an authentication object from `getAuth()`
39097     // with a [nonce](http://en.wikipedia.org/wiki/Cryptographic_nonce)
39098     // and timestamp
39099     function timenonce(o) {
39100         o.oauth_timestamp = ohauth_1.timestamp();
39101         o.oauth_nonce = ohauth_1.nonce();
39102         return o;
39103     }
39104
39105     // get/set tokens. These are prefixed with the base URL so that `osm-auth`
39106     // can be used with multiple APIs and the keys in `localStorage`
39107     // will not clash
39108     var token;
39109
39110     if (store_legacy.enabled) {
39111         token = function (x, y) {
39112             if (arguments.length === 1) return store_legacy.get(o.url + x);
39113             else if (arguments.length === 2) return store_legacy.set(o.url + x, y);
39114         };
39115     } else {
39116         var storage = {};
39117         token = function (x, y) {
39118             if (arguments.length === 1) return storage[o.url + x];
39119             else if (arguments.length === 2) return storage[o.url + x] = y;
39120         };
39121     }
39122
39123     // Get an authentication object. If you just add and remove properties
39124     // from a single object, you'll need to use `delete` to make sure that
39125     // it doesn't contain undesired properties for authentication
39126     function getAuth(o) {
39127         return {
39128             oauth_consumer_key: o.oauth_consumer_key,
39129             oauth_signature_method: 'HMAC-SHA1'
39130         };
39131     }
39132
39133     // potentially pre-authorize
39134     oauth.options(o);
39135
39136     return oauth;
39137 };
39138
39139 var JXON = new (function () {
39140   var
39141     sValueProp = 'keyValue', sAttributesProp = 'keyAttributes', sAttrPref = '@', /* you can customize these values */
39142     aCache = [], rIsNull = /^\s*$/, rIsBool = /^(?:true|false)$/i;
39143
39144   function parseText (sValue) {
39145     if (rIsNull.test(sValue)) { return null; }
39146     if (rIsBool.test(sValue)) { return sValue.toLowerCase() === 'true'; }
39147     if (isFinite(sValue)) { return parseFloat(sValue); }
39148     if (isFinite(Date.parse(sValue))) { return new Date(sValue); }
39149     return sValue;
39150   }
39151
39152   function EmptyTree () { }
39153   EmptyTree.prototype.toString = function () { return 'null'; };
39154   EmptyTree.prototype.valueOf = function () { return null; };
39155
39156   function objectify (vValue) {
39157     return vValue === null ? new EmptyTree() : vValue instanceof Object ? vValue : new vValue.constructor(vValue);
39158   }
39159
39160   function createObjTree (oParentNode, nVerb, bFreeze, bNesteAttr) {
39161     var
39162       nLevelStart = aCache.length, bChildren = oParentNode.hasChildNodes(),
39163       bAttributes = oParentNode.hasAttributes(), bHighVerb = Boolean(nVerb & 2);
39164
39165     var
39166       sProp, vContent, nLength = 0, sCollectedTxt = '',
39167       vResult = bHighVerb ? {} : /* put here the default value for empty nodes: */ true;
39168
39169     if (bChildren) {
39170       for (var oNode, nItem = 0; nItem < oParentNode.childNodes.length; nItem++) {
39171         oNode = oParentNode.childNodes.item(nItem);
39172         if (oNode.nodeType === 4) { sCollectedTxt += oNode.nodeValue; } /* nodeType is 'CDATASection' (4) */
39173         else if (oNode.nodeType === 3) { sCollectedTxt += oNode.nodeValue.trim(); } /* nodeType is 'Text' (3) */
39174         else if (oNode.nodeType === 1 && !oNode.prefix) { aCache.push(oNode); } /* nodeType is 'Element' (1) */
39175       }
39176     }
39177
39178     var nLevelEnd = aCache.length, vBuiltVal = parseText(sCollectedTxt);
39179
39180     if (!bHighVerb && (bChildren || bAttributes)) { vResult = nVerb === 0 ? objectify(vBuiltVal) : {}; }
39181
39182     for (var nElId = nLevelStart; nElId < nLevelEnd; nElId++) {
39183       sProp = aCache[nElId].nodeName.toLowerCase();
39184       vContent = createObjTree(aCache[nElId], nVerb, bFreeze, bNesteAttr);
39185       if (vResult.hasOwnProperty(sProp)) {
39186         if (vResult[sProp].constructor !== Array) { vResult[sProp] = [vResult[sProp]]; }
39187         vResult[sProp].push(vContent);
39188       } else {
39189         vResult[sProp] = vContent;
39190         nLength++;
39191       }
39192     }
39193
39194     if (bAttributes) {
39195       var
39196         nAttrLen = oParentNode.attributes.length,
39197         sAPrefix = bNesteAttr ? '' : sAttrPref, oAttrParent = bNesteAttr ? {} : vResult;
39198
39199       for (var oAttrib, nAttrib = 0; nAttrib < nAttrLen; nLength++, nAttrib++) {
39200         oAttrib = oParentNode.attributes.item(nAttrib);
39201         oAttrParent[sAPrefix + oAttrib.name.toLowerCase()] = parseText(oAttrib.value.trim());
39202       }
39203
39204       if (bNesteAttr) {
39205         if (bFreeze) { Object.freeze(oAttrParent); }
39206         vResult[sAttributesProp] = oAttrParent;
39207         nLength -= nAttrLen - 1;
39208       }
39209     }
39210
39211     if (nVerb === 3 || (nVerb === 2 || nVerb === 1 && nLength > 0) && sCollectedTxt) {
39212       vResult[sValueProp] = vBuiltVal;
39213     } else if (!bHighVerb && nLength === 0 && sCollectedTxt) {
39214       vResult = vBuiltVal;
39215     }
39216
39217     if (bFreeze && (bHighVerb || nLength > 0)) { Object.freeze(vResult); }
39218
39219     aCache.length = nLevelStart;
39220
39221     return vResult;
39222   }
39223
39224   function loadObjTree (oXMLDoc, oParentEl, oParentObj) {
39225     var vValue, oChild;
39226
39227     if (oParentObj instanceof String || oParentObj instanceof Number || oParentObj instanceof Boolean) {
39228       oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toString())); /* verbosity level is 0 */
39229     } else if (oParentObj.constructor === Date) {
39230       oParentEl.appendChild(oXMLDoc.createTextNode(oParentObj.toGMTString()));    
39231     }
39232
39233     for (var sName in oParentObj) {
39234       vValue = oParentObj[sName];
39235       if (isFinite(sName) || vValue instanceof Function) { continue; } /* verbosity level is 0 */
39236       if (sName === sValueProp) {
39237         if (vValue !== null && vValue !== true) { oParentEl.appendChild(oXMLDoc.createTextNode(vValue.constructor === Date ? vValue.toGMTString() : String(vValue))); }
39238       } else if (sName === sAttributesProp) { /* verbosity level is 3 */
39239         for (var sAttrib in vValue) { oParentEl.setAttribute(sAttrib, vValue[sAttrib]); }
39240       } else if (sName.charAt(0) === sAttrPref) {
39241         oParentEl.setAttribute(sName.slice(1), vValue);
39242       } else if (vValue.constructor === Array) {
39243         for (var nItem = 0; nItem < vValue.length; nItem++) {
39244           oChild = oXMLDoc.createElement(sName);
39245           loadObjTree(oXMLDoc, oChild, vValue[nItem]);
39246           oParentEl.appendChild(oChild);
39247         }
39248       } else {
39249         oChild = oXMLDoc.createElement(sName);
39250         if (vValue instanceof Object) {
39251           loadObjTree(oXMLDoc, oChild, vValue);
39252         } else if (vValue !== null && vValue !== true) {
39253           oChild.appendChild(oXMLDoc.createTextNode(vValue.toString()));
39254         }
39255         oParentEl.appendChild(oChild);
39256      }
39257    }
39258   }
39259
39260   this.build = function (oXMLParent, nVerbosity /* optional */, bFreeze /* optional */, bNesteAttributes /* optional */) {
39261     var _nVerb = arguments.length > 1 && typeof nVerbosity === 'number' ? nVerbosity & 3 : /* put here the default verbosity level: */ 1;
39262     return createObjTree(oXMLParent, _nVerb, bFreeze || false, arguments.length > 3 ? bNesteAttributes : _nVerb === 3);    
39263   };
39264
39265   this.unbuild = function (oObjTree) {    
39266     var oNewDoc = document.implementation.createDocument('', '', null);
39267     loadObjTree(oNewDoc, oNewDoc, oObjTree);
39268     return oNewDoc;
39269   };
39270
39271   this.stringify = function (oObjTree) {
39272     return (new XMLSerializer()).serializeToString(JXON.unbuild(oObjTree));
39273   };
39274 })();
39275
39276 // var myObject = JXON.build(doc);
39277 // we got our javascript object! try: alert(JSON.stringify(myObject));
39278
39279 // var newDoc = JXON.unbuild(myObject);
39280 // we got our Document instance! try: alert((new XMLSerializer()).serializeToString(newDoc));
39281
39282 var dispatch$3 = dispatch('authLoading', 'authDone', 'change', 'loading', 'loaded');
39283 var urlroot = 'https://www.openstreetmap.org';
39284 var blacklists = ['.*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*'];
39285 var inflight$1 = {};
39286 var loadedTiles = {};
39287 var entityCache = {};
39288 var connectionId = 1;
39289 var tileZoom$2 = 16;
39290 var oauth = osmAuth({
39291         url: urlroot,
39292         oauth_consumer_key: '5A043yRSEugj4DJ5TljuapfnrflWDte8jTOcWLlT',
39293         oauth_secret: 'aB3jKq1TRsCOUrfOIZ6oQMEDmv2ptV76PA54NGLL',
39294         loading: authLoading,
39295         done: authDone
39296     });
39297 var rateLimitError;
39298 var userChangesets;
39299 var userDetails;
39300 var off;
39301
39302
39303 function authLoading() {
39304     dispatch$3.call('authLoading');
39305 }
39306
39307
39308 function authDone() {
39309     dispatch$3.call('authDone');
39310 }
39311
39312
39313 function abortRequest$2(i) {
39314     if (i) {
39315         i.abort();
39316     }
39317 }
39318
39319
39320 function getLoc(attrs) {
39321     var lon = attrs.lon && attrs.lon.value,
39322         lat = attrs.lat && attrs.lat.value;
39323     return [parseFloat(lon), parseFloat(lat)];
39324 }
39325
39326
39327 function getNodes(obj) {
39328     var elems = obj.getElementsByTagName('nd'),
39329         nodes = new Array(elems.length);
39330     for (var i = 0, l = elems.length; i < l; i++) {
39331         nodes[i] = 'n' + elems[i].attributes.ref.value;
39332     }
39333     return nodes;
39334 }
39335
39336
39337 function getTags(obj) {
39338     var elems = obj.getElementsByTagName('tag'),
39339         tags = {};
39340     for (var i = 0, l = elems.length; i < l; i++) {
39341         var attrs = elems[i].attributes;
39342         tags[attrs.k.value] = attrs.v.value;
39343     }
39344
39345     return tags;
39346 }
39347
39348
39349 function getMembers(obj) {
39350     var elems = obj.getElementsByTagName('member'),
39351         members = new Array(elems.length);
39352     for (var i = 0, l = elems.length; i < l; i++) {
39353         var attrs = elems[i].attributes;
39354         members[i] = {
39355             id: attrs.type.value[0] + attrs.ref.value,
39356             type: attrs.type.value,
39357             role: attrs.role.value
39358         };
39359     }
39360     return members;
39361 }
39362
39363
39364 function getVisible(attrs) {
39365     return (!attrs.visible || attrs.visible.value !== 'false');
39366 }
39367
39368
39369 var parsers = {
39370     node: function nodeData(obj, uid) {
39371         var attrs = obj.attributes;
39372         return new osmNode({
39373             id:uid,
39374             visible: getVisible(attrs),
39375             version: attrs.version.value,
39376             changeset: attrs.changeset && attrs.changeset.value,
39377             timestamp: attrs.timestamp && attrs.timestamp.value,
39378             user: attrs.user && attrs.user.value,
39379             uid: attrs.uid && attrs.uid.value,
39380             loc: getLoc(attrs),
39381             tags: getTags(obj)
39382         });
39383     },
39384
39385     way: function wayData(obj, uid) {
39386         var attrs = obj.attributes;
39387         return new osmWay({
39388             id: uid,
39389             visible: getVisible(attrs),
39390             version: attrs.version.value,
39391             changeset: attrs.changeset && attrs.changeset.value,
39392             timestamp: attrs.timestamp && attrs.timestamp.value,
39393             user: attrs.user && attrs.user.value,
39394             uid: attrs.uid && attrs.uid.value,
39395             tags: getTags(obj),
39396             nodes: getNodes(obj),
39397         });
39398     },
39399
39400     relation: function relationData(obj, uid) {
39401         var attrs = obj.attributes;
39402         return new osmRelation({
39403             id: uid,
39404             visible: getVisible(attrs),
39405             version: attrs.version.value,
39406             changeset: attrs.changeset && attrs.changeset.value,
39407             timestamp: attrs.timestamp && attrs.timestamp.value,
39408             user: attrs.user && attrs.user.value,
39409             uid: attrs.uid && attrs.uid.value,
39410             tags: getTags(obj),
39411             members: getMembers(obj)
39412         });
39413     }
39414 };
39415
39416
39417 function parse(xml$$1, callback, options) {
39418     options = assignIn({ cache: true }, options);
39419     if (!xml$$1 || !xml$$1.childNodes) return;
39420
39421     var root = xml$$1.childNodes[0],
39422         children = root.childNodes;
39423
39424     function parseChild(child) {
39425         var parser = parsers[child.nodeName];
39426         if (parser) {
39427             var uid = osmEntity.id.fromOSM(child.nodeName, child.attributes.id.value);
39428             if (options.cache && entityCache[uid]) {
39429                 return null;
39430             }
39431             return parser(child, uid);
39432         }
39433     }
39434
39435     utilIdleWorker(children, parseChild, callback);
39436 }
39437
39438
39439 var serviceOsm = {
39440
39441     init: function() {
39442         utilRebind(this, dispatch$3, 'on');
39443     },
39444
39445
39446     reset: function() {
39447         connectionId++;
39448         userChangesets = undefined;
39449         userDetails = undefined;
39450         rateLimitError = undefined;
39451         forEach(inflight$1, abortRequest$2);
39452         entityCache = {};
39453         loadedTiles = {};
39454         inflight$1 = {};
39455         return this;
39456     },
39457
39458
39459     getConnectionId: function() {
39460         return connectionId;
39461     },
39462
39463
39464     changesetURL: function(changesetId) {
39465         return urlroot + '/changeset/' + changesetId;
39466     },
39467
39468
39469     changesetsURL: function(center, zoom) {
39470         var precision = Math.max(0, Math.ceil(Math.log(zoom) / Math.LN2));
39471         return urlroot + '/history#map=' +
39472             Math.floor(zoom) + '/' +
39473             center[1].toFixed(precision) + '/' +
39474             center[0].toFixed(precision);
39475     },
39476
39477
39478     entityURL: function(entity) {
39479         return urlroot + '/' + entity.type + '/' + entity.osmId();
39480     },
39481
39482
39483     historyURL: function(entity) {
39484         return urlroot + '/' + entity.type + '/' + entity.osmId() + '/history';
39485     },
39486
39487
39488     userURL: function(username) {
39489         return urlroot + '/user/' + username;
39490     },
39491
39492
39493     loadFromAPI: function(path, callback, options) {
39494         options = assignIn({ cache: true }, options);
39495         var that = this;
39496         var cid = connectionId;
39497
39498         function done(err, xml$$1) {
39499             if (that.getConnectionId() !== cid) {
39500                 if (callback) callback({ message: 'Connection Switched', status: -1 });
39501                 return;
39502             }
39503
39504             var isAuthenticated = that.authenticated();
39505
39506             // 400 Bad Request, 401 Unauthorized, 403 Forbidden
39507             // Logout and retry the request..
39508             if (isAuthenticated && err &&
39509                     (err.status === 400 || err.status === 401 || err.status === 403)) {
39510                 that.logout();
39511                 that.loadFromAPI(path, callback);
39512
39513             // else, no retry..
39514             } else {
39515                 // 509 Bandwidth Limit Exceeded, 429 Too Many Requests
39516                 // Set the rateLimitError flag and trigger a warning..
39517                 if (!isAuthenticated && !rateLimitError && err &&
39518                         (err.status === 509 || err.status === 429)) {
39519                     rateLimitError = err;
39520                     dispatch$3.call('change');
39521                 }
39522
39523                 if (callback) {
39524                     if (err) return callback(err, null);
39525                     parse(xml$$1, function (entities) {
39526                         if (options.cache) {
39527                             for (var i in entities) {
39528                                 entityCache[entities[i].id] = true;
39529                             }
39530                         }
39531                         callback(null, entities);
39532                     }, options);
39533                 }
39534             }
39535         }
39536
39537         if (this.authenticated()) {
39538             return oauth.xhr({ method: 'GET', path: path }, done);
39539         } else {
39540             var url = urlroot + path;
39541             return d3_xml(url).get(done);
39542         }
39543     },
39544
39545
39546     loadEntity: function(id, callback) {
39547         var type = osmEntity.id.type(id),
39548             osmID = osmEntity.id.toOSM(id),
39549             options = { cache: false };
39550
39551         this.loadFromAPI(
39552             '/api/0.6/' + type + '/' + osmID + (type !== 'node' ? '/full' : ''),
39553             function(err, entities) {
39554                 if (callback) callback(err, { data: entities });
39555             },
39556             options
39557         );
39558     },
39559
39560
39561     loadEntityVersion: function(id, version, callback) {
39562         var type = osmEntity.id.type(id),
39563             osmID = osmEntity.id.toOSM(id),
39564             options = { cache: false };
39565
39566         this.loadFromAPI(
39567             '/api/0.6/' + type + '/' + osmID + '/' + version,
39568             function(err, entities) {
39569                 if (callback) callback(err, { data: entities });
39570             },
39571             options
39572         );
39573     },
39574
39575
39576     loadMultiple: function(ids, callback) {
39577         var that = this;
39578
39579         forEach(groupBy(uniq(ids), osmEntity.id.type), function(v, k) {
39580             var type = k + 's',
39581                 osmIDs = map$4(v, osmEntity.id.toOSM),
39582                 options = { cache: false };
39583
39584             forEach(chunk(osmIDs, 150), function(arr) {
39585                 that.loadFromAPI(
39586                     '/api/0.6/' + type + '?' + type + '=' + arr.join(),
39587                     function(err, entities) {
39588                         if (callback) callback(err, { data: entities });
39589                     },
39590                     options
39591                 );
39592             });
39593         });
39594     },
39595
39596
39597     authenticated: function() {
39598         return oauth.authenticated();
39599     },
39600
39601
39602     putChangeset: function(changeset, changes, callback) {
39603         var that = this;
39604         var cid = connectionId;
39605
39606         // Create the changeset..
39607         oauth.xhr({
39608             method: 'PUT',
39609             path: '/api/0.6/changeset/create',
39610             options: { header: { 'Content-Type': 'text/xml' } },
39611             content: JXON.stringify(changeset.asJXON())
39612         }, createdChangeset);
39613
39614
39615         function createdChangeset(err, changeset_id) {
39616             if (err) {
39617                 return callback(err);
39618             }
39619             if (that.getConnectionId() !== cid) {
39620                 return callback({ message: 'Connection Switched', status: -1 });
39621             }
39622
39623             changeset = changeset.update({ id: changeset_id });
39624
39625             // Upload the changeset..
39626             oauth.xhr({
39627                 method: 'POST',
39628                 path: '/api/0.6/changeset/' + changeset_id + '/upload',
39629                 options: { header: { 'Content-Type': 'text/xml' } },
39630                 content: JXON.stringify(changeset.osmChangeJXON(changes))
39631             }, uploadedChangeset);
39632         }
39633
39634
39635         function uploadedChangeset(err) {
39636             if (err) return callback(err);
39637
39638             // Upload was successful, safe to call the callback.
39639             // Add delay to allow for postgres replication #1646 #2678
39640             window.setTimeout(function() {
39641                 callback(null, changeset);
39642             }, 2500);
39643
39644             // At this point, we don't really care if the connection was switched..
39645             // Only try to close the changeset if we're still talking to the same server.
39646             if (that.getConnectionId() === cid) {
39647                 // Still attempt to close changeset, but ignore response because #2667
39648                 oauth.xhr({
39649                     method: 'PUT',
39650                     path: '/api/0.6/changeset/' + changeset.id + '/close',
39651                     options: { header: { 'Content-Type': 'text/xml' } }
39652                 }, function() { return true; });
39653             }
39654         }
39655     },
39656
39657
39658     userDetails: function(callback) {
39659         if (userDetails) {
39660             callback(undefined, userDetails);
39661             return;
39662         }
39663
39664         var that = this;
39665         var cid = connectionId;
39666
39667         function done(err, user_details) {
39668             if (err) {
39669                 return callback(err);
39670             }
39671             if (that.getConnectionId() !== cid) {
39672                 return callback({ message: 'Connection Switched', status: -1 });
39673             }
39674
39675             var u = user_details.getElementsByTagName('user')[0],
39676                 img = u.getElementsByTagName('img'),
39677                 image_url = '';
39678
39679             if (img && img[0] && img[0].getAttribute('href')) {
39680                 image_url = img[0].getAttribute('href');
39681             }
39682
39683             var changesets = u.getElementsByTagName('changesets'),
39684                 changesets_count = 0;
39685
39686             if (changesets && changesets[0] && changesets[0].getAttribute('count')) {
39687                 changesets_count = changesets[0].getAttribute('count');
39688             }
39689
39690             userDetails = {
39691                 id: u.attributes.id.value,
39692                 display_name: u.attributes.display_name.value,
39693                 image_url: image_url,
39694                 changesets_count: changesets_count
39695             };
39696
39697             callback(undefined, userDetails);
39698         }
39699
39700         oauth.xhr({ method: 'GET', path: '/api/0.6/user/details' }, done);
39701     },
39702
39703
39704     userChangesets: function(callback) {
39705         if (userChangesets) {
39706             callback(undefined, userChangesets);
39707             return;
39708         }
39709
39710         var that = this;
39711         var cid = connectionId;
39712
39713         this.userDetails(function(err, user) {
39714             if (err) {
39715                 return callback(err);
39716             }
39717             if (that.getConnectionId() !== cid) {
39718                 return callback({ message: 'Connection Switched', status: -1 });
39719             }
39720
39721             function done(err, changesets) {
39722                 if (err) {
39723                     return callback(err);
39724                 }
39725                 if (that.getConnectionId() !== cid) {
39726                     return callback({ message: 'Connection Switched', status: -1 });
39727                 }
39728
39729                 userChangesets = Array.prototype.map.call(
39730                     changesets.getElementsByTagName('changeset'),
39731                     function (changeset) {
39732                         return { tags: getTags(changeset) };
39733                     }
39734                 ).filter(function (changeset) {
39735                     var comment = changeset.tags.comment;
39736                     return comment && comment !== '';
39737                 });
39738
39739                 callback(undefined, userChangesets);
39740             }
39741
39742             oauth.xhr({ method: 'GET', path: '/api/0.6/changesets?user=' + user.id }, done);
39743         });
39744     },
39745
39746
39747     status: function(callback) {
39748         var that = this;
39749         var cid = connectionId;
39750
39751         function done(xml$$1) {
39752             if (that.getConnectionId() !== cid) {
39753                 return callback({ message: 'Connection Switched', status: -1 }, 'connectionSwitched');
39754             }
39755
39756             // update blacklists
39757             var elements = xml$$1.getElementsByTagName('blacklist'),
39758                 regexes = [];
39759             for (var i = 0; i < elements.length; i++) {
39760                 var regex = elements[i].getAttribute('regex');  // needs unencode?
39761                 if (regex) {
39762                     regexes.push(regex);
39763                 }
39764             }
39765             if (regexes.length) {
39766                 blacklists = regexes;
39767             }
39768
39769
39770             if (rateLimitError) {
39771                 callback(rateLimitError, 'rateLimited');
39772             } else {
39773                 var apiStatus = xml$$1.getElementsByTagName('status'),
39774                     val = apiStatus[0].getAttribute('api');
39775
39776                 callback(undefined, val);
39777             }
39778         }
39779
39780         d3_xml(urlroot + '/api/capabilities').get()
39781             .on('load', done)
39782             .on('error', callback);
39783     },
39784
39785
39786     imageryBlacklists: function() {
39787         return blacklists;
39788     },
39789
39790
39791     tileZoom: function(_) {
39792         if (!arguments.length) return tileZoom$2;
39793         tileZoom$2 = _;
39794         return this;
39795     },
39796
39797
39798     loadTiles: function(projection, dimensions, callback) {
39799         if (off) return;
39800
39801         var that = this,
39802             s = projection.scale() * 2 * Math.PI,
39803             z = Math.max(Math.log(s) / Math.log(2) - 8, 0),
39804             ts = 256 * Math.pow(2, z - tileZoom$2),
39805             origin = [
39806                 s / 2 - projection.translate()[0],
39807                 s / 2 - projection.translate()[1]
39808             ];
39809
39810         var tiles = d3geoTile()
39811             .scaleExtent([tileZoom$2, tileZoom$2])
39812             .scale(s)
39813             .size(dimensions)
39814             .translate(projection.translate())()
39815             .map(function(tile) {
39816                 var x = tile[0] * ts - origin[0],
39817                     y = tile[1] * ts - origin[1];
39818
39819                 return {
39820                     id: tile.toString(),
39821                     extent: geoExtent(
39822                         projection.invert([x, y + ts]),
39823                         projection.invert([x + ts, y]))
39824                 };
39825             });
39826
39827         filter(inflight$1, function(v, i) {
39828             var wanted = find$1(tiles, function(tile) {
39829                 return i === tile.id;
39830             });
39831             if (!wanted) delete inflight$1[i];
39832             return !wanted;
39833         }).map(abortRequest$2);
39834
39835         tiles.forEach(function(tile) {
39836             var id = tile.id;
39837
39838             if (loadedTiles[id] || inflight$1[id]) return;
39839
39840             if (isEmpty(inflight$1)) {
39841                 dispatch$3.call('loading');
39842             }
39843
39844             inflight$1[id] = that.loadFromAPI(
39845                 '/api/0.6/map?bbox=' + tile.extent.toParam(),
39846                 function(err, parsed) {
39847                     delete inflight$1[id];
39848                     if (!err) {
39849                         loadedTiles[id] = true;
39850                     }
39851
39852                     if (callback) {
39853                         callback(err, assignIn({ data: parsed }, tile));
39854                     }
39855
39856                     if (isEmpty(inflight$1)) {
39857                         dispatch$3.call('loaded');
39858                     }
39859                 }
39860             );
39861         });
39862     },
39863
39864
39865     switch: function(options) {
39866         urlroot = options.urlroot;
39867
39868         oauth.options(assignIn({
39869             url: urlroot,
39870             loading: authLoading,
39871             done: authDone
39872         }, options));
39873
39874         this.reset();
39875         this.userChangesets(function() {});  // eagerly load user details/changesets
39876         dispatch$3.call('change');
39877         return this;
39878     },
39879
39880
39881     toggle: function(_) {
39882         off = !_;
39883         return this;
39884     },
39885
39886
39887     loadedTiles: function(_) {
39888         if (!arguments.length) return loadedTiles;
39889         loadedTiles = _;
39890         return this;
39891     },
39892
39893
39894     logout: function() {
39895         userChangesets = undefined;
39896         userDetails = undefined;
39897         oauth.logout();
39898         dispatch$3.call('change');
39899         return this;
39900     },
39901
39902
39903     authenticate: function(callback) {
39904         var that = this;
39905         var cid = connectionId;
39906         userChangesets = undefined;
39907         userDetails = undefined;
39908
39909         function done(err, res) {
39910             if (err) {
39911                 if (callback) callback(err);
39912                 return;
39913             }
39914             if (that.getConnectionId() !== cid) {
39915                 if (callback) callback({ message: 'Connection Switched', status: -1 });
39916                 return;
39917             }
39918             rateLimitError = undefined;
39919             dispatch$3.call('change');
39920             if (callback) callback(err, res);
39921             that.userChangesets(function() {});  // eagerly load user details/changesets
39922         }
39923
39924         return oauth.authenticate(done);
39925     }
39926 };
39927
39928 var apibase$3 = 'https://taginfo.openstreetmap.org/api/4/';
39929 var inflight$2 = {};
39930 var popularKeys = {};
39931 var taginfoCache = {};
39932 var tag_sorts = {
39933         point: 'count_nodes',
39934         vertex: 'count_nodes',
39935         area: 'count_ways',
39936         line: 'count_ways'
39937     };
39938 var tag_sort_members = {
39939         point: 'count_node_members',
39940         vertex: 'count_node_members',
39941         area: 'count_way_members',
39942         line: 'count_way_members',
39943         relation: 'count_relation_members'
39944     };
39945 var tag_filters = {
39946         point: 'nodes',
39947         vertex: 'nodes',
39948         area: 'ways',
39949         line: 'ways'
39950     };
39951 var tag_members_fractions = {
39952         point: 'count_node_members_fraction',
39953         vertex: 'count_node_members_fraction',
39954         area: 'count_way_members_fraction',
39955         line: 'count_way_members_fraction',
39956         relation: 'count_relation_members_fraction'
39957     };
39958
39959
39960 function sets(params, n, o) {
39961     if (params.geometry && o[params.geometry]) {
39962         params[n] = o[params.geometry];
39963     }
39964     return params;
39965 }
39966
39967
39968 function setFilter(params) {
39969     return sets(params, 'filter', tag_filters);
39970 }
39971
39972
39973 function setSort(params) {
39974     return sets(params, 'sortname', tag_sorts);
39975 }
39976
39977
39978 function setSortMembers(params) {
39979     return sets(params, 'sortname', tag_sort_members);
39980 }
39981
39982
39983 function clean(params) {
39984     return omit(params, ['geometry', 'debounce']);
39985 }
39986
39987
39988 function filterKeys(type) {
39989     var count_type = type ? 'count_' + type : 'count_all';
39990     return function(d) {
39991         return parseFloat(d[count_type]) > 2500 || d.in_wiki;
39992     };
39993 }
39994
39995
39996 function filterMultikeys(prefix) {
39997     return function(d) {
39998         // d.key begins with prefix, and d.key contains no additional ':'s
39999         var re = new RegExp('^' + prefix + '(.*)$');
40000         var matches = d.key.match(re) || [];
40001         return (matches.length === 2 && matches[1].indexOf(':') === -1);
40002     };
40003 }
40004
40005
40006 function filterValues(allowUpperCase) {
40007     return function(d) {
40008         if (d.value.match(/[;,]/) !== null) return false;  // exclude some punctuation
40009         if (!allowUpperCase && d.value.match(/[A-Z*]/) !== null) return false;  // exclude uppercase letters
40010         return parseFloat(d.fraction) > 0.0 || d.in_wiki;
40011     };
40012 }
40013
40014
40015 function filterRoles(geometry) {
40016     return function(d) {
40017         if (d.role === '') return false; // exclude empty role
40018         if (d.role.match(/[A-Z*;,]/) !== null) return false;  // exclude uppercase letters and some punctuation
40019         return parseFloat(d[tag_members_fractions[geometry]]) > 0.0;
40020     };
40021 }
40022
40023
40024 function valKey(d) {
40025     return {
40026         value: d.key,
40027         title: d.key
40028     };
40029 }
40030
40031
40032 function valKeyDescription(d) {
40033     return {
40034         value: d.value,
40035         title: d.description || d.value
40036     };
40037 }
40038
40039
40040 function roleKey(d) {
40041     return {
40042         value: d.role,
40043         title: d.role
40044     };
40045 }
40046
40047
40048 // sort keys with ':' lower than keys without ':'
40049 function sortKeys(a, b) {
40050     return (a.key.indexOf(':') === -1 && b.key.indexOf(':') !== -1) ? -1
40051         : (a.key.indexOf(':') !== -1 && b.key.indexOf(':') === -1) ? 1
40052         : 0;
40053 }
40054
40055
40056 var debouncedRequest = debounce(request, 500, { leading: false });
40057
40058 function request(url, params, exactMatch, callback, loaded) {
40059     if (inflight$2[url]) return;
40060
40061     if (checkCache(url, params, exactMatch, callback)) return;
40062
40063     inflight$2[url] = d3_json(url, function (err, data) {
40064         delete inflight$2[url];
40065         loaded(err, data);
40066     });
40067 }
40068
40069
40070 function checkCache(url, params, exactMatch, callback) {
40071     var rp = params.rp || 25,
40072         testQuery = params.query || '',
40073         testUrl = url;
40074
40075     do {
40076         var hit = taginfoCache[testUrl];
40077
40078         // exact match, or shorter match yielding fewer than max results (rp)
40079         if (hit && (url === testUrl || hit.length < rp)) {
40080             callback(null, hit);
40081             return true;
40082         }
40083
40084         // don't try to shorten the query
40085         if (exactMatch || !testQuery.length) return false;
40086
40087         // do shorten the query to see if we already have a cached result
40088         // that has returned fewer than max results (rp)
40089         testQuery = testQuery.slice(0, -1);
40090         testUrl = url.replace(/&query=(.*?)&/, '&query=' + testQuery + '&');
40091     } while (testQuery.length >= 0);
40092
40093     return false;
40094 }
40095
40096
40097 var serviceTaginfo = {
40098
40099     init: function() {
40100         inflight$2 = {};
40101         taginfoCache = {};
40102         popularKeys = {};
40103
40104         // Fetch popular keys.  We'll exclude these from `values`
40105         // lookups because they stress taginfo, and they aren't likely
40106         // to yield meaningful autocomplete results.. see #3955
40107         var params = { rp: 100, sortname: 'values_all', sortorder: 'desc', page: 1, debounce: false };
40108         this.keys(params, function(err, data) {
40109             if (err) return;
40110             data.forEach(function(d) {
40111                 if (d.value === 'opening_hours') return;  // exception
40112                 popularKeys[d.value] = true;
40113             });
40114         });
40115     },
40116
40117
40118     reset: function() {
40119         forEach(inflight$2, function(req) { req.abort(); });
40120         inflight$2 = {};
40121     },
40122
40123
40124     keys: function(params, callback) {
40125         var doRequest = params.debounce ? debouncedRequest : request;
40126         params = clean(setSort(params));
40127         params = assignIn({ rp: 10, sortname: 'count_all', sortorder: 'desc', page: 1 }, params);
40128
40129         var url = apibase$3 + 'keys/all?' + utilQsString(params);
40130         doRequest(url, params, false, callback, function(err, d) {
40131             if (err) {
40132                 callback(err);
40133             } else {
40134                 var f = filterKeys(params.filter);
40135                 var result = d.data.filter(f).sort(sortKeys).map(valKey);
40136                 taginfoCache[url] = result;
40137                 callback(null, result);
40138             }
40139         });
40140     },
40141
40142
40143     multikeys: function(params, callback) {
40144         var doRequest = params.debounce ? debouncedRequest : request;
40145         params = clean(setSort(params));
40146         params = assignIn({ rp: 25, sortname: 'count_all', sortorder: 'desc', page: 1 }, params);
40147         var prefix = params.query;
40148
40149         var url = apibase$3 + 'keys/all?' + utilQsString(params);
40150         doRequest(url, params, true, callback, function(err, d) {
40151             if (err) {
40152                 callback(err);
40153             } else {
40154                 var f = filterMultikeys(prefix);
40155                 var result = d.data.filter(f).map(valKey);
40156                 taginfoCache[url] = result;
40157                 callback(null, result);
40158             }
40159         });
40160     },
40161
40162
40163     values: function(params, callback) {
40164         // Exclude popular keys from values lookups.. see #3955
40165         var key = params.key;
40166         if (key && popularKeys[key]) {
40167             callback(null, []);
40168             return;
40169         }
40170
40171         var doRequest = params.debounce ? debouncedRequest : request;
40172         params = clean(setSort(setFilter(params)));
40173         params = assignIn({ rp: 25, sortname: 'count_all', sortorder: 'desc', page: 1 }, params);
40174
40175         var url = apibase$3 + 'key/values?' + utilQsString(params);
40176         doRequest(url, params, false, callback, function(err, d) {
40177             if (err) {
40178                 callback(err);
40179             } else {
40180                 // In most cases we prefer taginfo value results with lowercase letters.
40181                 // A few OSM keys expect values to contain uppercase values (see #3377).
40182                 // This is not an exhaustive list (e.g. `name` also has uppercase values)
40183                 // but these are the fields where taginfo value lookup is most useful.
40184                 var re = /network|taxon|genus|species|brand|grape_variety|rating|:output|_hours|_times/;
40185                 var allowUpperCase = (params.key.match(re) !== null);
40186                 var f = filterValues(allowUpperCase);
40187
40188                 var result = d.data.filter(f).map(valKeyDescription);
40189                 taginfoCache[url] = result;
40190                 callback(null, result);
40191             }
40192         });
40193     },
40194
40195
40196     roles: function(params, callback) {
40197         var doRequest = params.debounce ? debouncedRequest : request;
40198         var geometry = params.geometry;
40199         params = clean(setSortMembers(params));
40200         params = assignIn({ rp: 25, sortname: 'count_all_members', sortorder: 'desc', page: 1 }, params);
40201
40202         var url = apibase$3 + 'relation/roles?' + utilQsString(params);
40203         doRequest(url, params, true, callback, function(err, d) {
40204             if (err) {
40205                 callback(err);
40206             } else {
40207                 var f = filterRoles(geometry);
40208                 var result = d.data.filter(f).map(roleKey);
40209                 taginfoCache[url] = result;
40210                 callback(null, result);
40211             }
40212         });
40213     },
40214
40215
40216     docs: function(params, callback) {
40217         var doRequest = params.debounce ? debouncedRequest : request;
40218         params = clean(setSort(params));
40219
40220         var path = 'key/wiki_pages?';
40221         if (params.value) path = 'tag/wiki_pages?';
40222         else if (params.rtype) path = 'relation/wiki_pages?';
40223
40224         var url = apibase$3 + path + utilQsString(params);
40225         doRequest(url, params, true, callback, function(err, d) {
40226             if (err) {
40227                 callback(err);
40228             } else {
40229                 taginfoCache[url] = d.data;
40230                 callback(null, d.data);
40231             }
40232         });
40233     },
40234
40235
40236     apibase: function(_) {
40237         if (!arguments.length) return apibase$3;
40238         apibase$3 = _;
40239         return this;
40240     }
40241
40242 };
40243
40244 var jsonpCache = {};
40245 window.jsonpCache = jsonpCache;
40246
40247 function jsonpRequest(url, callback) {
40248
40249   if (window.JSONP_FIX) {
40250     if (window.JSONP_DELAY === 0) {
40251       callback(window.JSONP_FIX);
40252     } else {
40253       setTimeout(function() {
40254         callback(window.JSONP_FIX);
40255       }, window.JSONP_DELAY || 0);
40256     }
40257     return;
40258   }
40259
40260   function rand() {
40261     var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',
40262       c = '', i = -1;
40263     while (++i < 15) c += chars.charAt(Math.floor(Math.random() * 52));
40264     return c;
40265   }
40266
40267   function create(url) {
40268     var e = url.match(/callback=(\w+)/),
40269       c = e ? e[1] : rand();
40270     jsonpCache[c] = function(data) {
40271       callback(data);
40272       delete jsonpCache[c];
40273       script.remove();
40274     };
40275     return 'jsonpCache.' + c;
40276   }
40277
40278   var cb = create(url),
40279     script = d3_select('head')
40280     .append('script')
40281     .attr('type', 'text/javascript')
40282     .attr('src', url.replace(/(\{|%7B)callback(\}|%7D)/, cb));
40283 }
40284
40285 var endpoint = 'https://www.wikidata.org/w/api.php?';
40286
40287 var serviceWikidata = {
40288
40289     init: function() {},
40290     reset: function() {},
40291
40292
40293     // Given a Wikipedia language and article title, return an array of
40294     // corresponding Wikidata entities.
40295     itemsByTitle: function(lang, title, callback) {
40296         if (!title) {
40297             callback('', {});
40298             return;
40299         }
40300
40301         lang = lang || 'en';
40302         jsonpRequest(endpoint + utilQsString({
40303             action: 'wbgetentities',
40304             format: 'json',
40305             sites: lang.replace(/-/g, '_') + 'wiki',
40306             titles: title,
40307             languages: 'en', // shrink response by filtering to one language
40308             callback: '{callback}'
40309         }), function(data) {
40310             if (!data || data.error) {
40311                 callback('', {});
40312             } else {
40313                 callback(title, data.entities || {});
40314             }
40315         });
40316     }
40317
40318 };
40319
40320 var endpoint$1 = 'https://en.wikipedia.org/w/api.php?';
40321
40322 var serviceWikipedia = {
40323
40324     init: function() {},
40325     reset: function() {},
40326
40327
40328     search: function(lang, query, callback) {
40329         if (!query) {
40330             callback('', []);
40331             return;
40332         }
40333
40334         lang = lang || 'en';
40335         jsonpRequest(endpoint$1.replace('en', lang) +
40336             utilQsString({
40337                 action: 'query',
40338                 list: 'search',
40339                 srlimit: '10',
40340                 srinfo: 'suggestion',
40341                 format: 'json',
40342                 callback: '{callback}',
40343                 srsearch: query
40344             }), function(data) {
40345                 if (!data || !data.query || !data.query.search || data.error) {
40346                     callback('', []);
40347                 } else {
40348                     var results = data.query.search.map(function(d) { return d.title; });
40349                     callback(query, results);
40350                 }
40351             }
40352         );
40353     },
40354
40355
40356     suggestions: function(lang, query, callback) {
40357         if (!query) {
40358             callback('', []);
40359             return;
40360         }
40361
40362         lang = lang || 'en';
40363         jsonpRequest(endpoint$1.replace('en', lang) +
40364             utilQsString({
40365                 action: 'opensearch',
40366                 namespace: 0,
40367                 suggest: '',
40368                 format: 'json',
40369                 callback: '{callback}',
40370                 search: query
40371             }), function(data) {
40372                 if (!data || data.error) {
40373                     callback('', []);
40374                 } else {
40375                     callback(data[0], data[1] || []);
40376                 }
40377             }
40378         );
40379     },
40380
40381
40382     translations: function(lang, title, callback) {
40383         if (!title) {
40384             callback({});
40385             return;
40386         }
40387
40388         jsonpRequest(endpoint$1.replace('en', lang) +
40389             utilQsString({
40390                 action: 'query',
40391                 prop: 'langlinks',
40392                 format: 'json',
40393                 callback: '{callback}',
40394                 lllimit: 500,
40395                 titles: title
40396             }), function(data) {
40397                 if (!data || !data.query || !data.query.pages || data.error) {
40398                     callback({});
40399                 } else {
40400                     var list = data.query.pages[Object.keys(data.query.pages)[0]],
40401                         translations = {};
40402                     if (list && list.langlinks) {
40403                         list.langlinks.forEach(function(d) {
40404                             translations[d.lang] = d['*'];
40405                         });
40406                     }
40407                     callback(translations);
40408                 }
40409             }
40410         );
40411     }
40412
40413 };
40414
40415 var services = {
40416     geocoder: serviceNominatim,
40417     mapillary: serviceMapillary,
40418     openstreetcam: serviceOpenstreetcam,
40419     osm: serviceOsm,
40420     taginfo: serviceTaginfo,
40421     wikidata: serviceWikidata,
40422     wikipedia: serviceWikipedia
40423 };
40424
40425 function svgAreas(projection, context) {
40426     // Patterns only work in Firefox when set directly on element.
40427     // (This is not a bug: https://bugzilla.mozilla.org/show_bug.cgi?id=750632)
40428     var patterns = {
40429         beach: 'beach',
40430         cemetery: 'cemetery',
40431         construction: 'construction',
40432         farm: 'farmland',
40433         farmland: 'farmland',
40434         grave_yard: 'cemetery',
40435         meadow: 'meadow',
40436         military: 'construction',
40437         orchard: 'orchard',
40438         sand: 'beach',
40439         scrub: 'scrub',
40440         wetland: 'wetland',
40441     };
40442
40443     var patternKeys = ['landuse', 'natural', 'amenity'];
40444
40445
40446     function setPattern(d) {
40447         for (var i = 0; i < patternKeys.length; i++) {
40448             if (d.tags.building && d.tags.building !== 'no') continue;
40449
40450             if (patterns.hasOwnProperty(d.tags[patternKeys[i]])) {
40451                 this.style.fill = this.style.stroke = 'url("#pattern-' + patterns[d.tags[patternKeys[i]]] + '")';
40452                 return;
40453             }
40454         }
40455         this.style.fill = this.style.stroke = '';
40456     }
40457
40458
40459     return function drawAreas(selection, graph, entities, filter) {
40460         var path = svgPath(projection, graph, true),
40461             areas = {},
40462             multipolygon;
40463
40464         for (var i = 0; i < entities.length; i++) {
40465             var entity = entities[i];
40466             if (entity.geometry(graph) !== 'area') continue;
40467
40468             multipolygon = osmIsSimpleMultipolygonOuterMember(entity, graph);
40469             if (multipolygon) {
40470                 areas[multipolygon.id] = {
40471                     entity: multipolygon.mergeTags(entity.tags),
40472                     area: Math.abs(entity.area(graph))
40473                 };
40474             } else if (!areas[entity.id]) {
40475                 areas[entity.id] = {
40476                     entity: entity,
40477                     area: Math.abs(entity.area(graph))
40478                 };
40479             }
40480         }
40481
40482         areas = values$1(areas).filter(function hasPath(a) { return path(a.entity); });
40483         areas.sort(function areaSort(a, b) { return b.area - a.area; });
40484         areas = map$4(areas, 'entity');
40485
40486         var strokes = areas.filter(function(area) {
40487             return area.type === 'way';
40488         });
40489
40490         var data = {
40491             clip: areas,
40492             shadow: strokes,
40493             stroke: strokes,
40494             fill: areas
40495         };
40496
40497         var clipPaths = context.surface().selectAll('defs').selectAll('.clipPath')
40498            .filter(filter)
40499            .data(data.clip, osmEntity.key);
40500
40501         clipPaths.exit()
40502            .remove();
40503
40504         var clipPathsEnter = clipPaths.enter()
40505            .append('clipPath')
40506            .attr('class', 'clipPath')
40507            .attr('id', function(entity) { return entity.id + '-clippath'; });
40508
40509         clipPathsEnter
40510            .append('path');
40511
40512         clipPaths.merge(clipPathsEnter)
40513            .selectAll('path')
40514            .attr('d', path);
40515
40516
40517         var layer = selection.selectAll('.layer-areas');
40518
40519         var areagroup = layer
40520             .selectAll('g.areagroup')
40521             .data(['fill', 'shadow', 'stroke']);
40522
40523         areagroup = areagroup.enter()
40524             .append('g')
40525             .attr('class', function(d) { return 'areagroup area-' + d; })
40526             .merge(areagroup);
40527
40528         var paths = areagroup
40529             .selectAll('path')
40530             .filter(filter)
40531             .data(function(layer) { return data[layer]; }, osmEntity.key);
40532
40533         paths.exit()
40534             .remove();
40535
40536         var fills = selection.selectAll('.area-fill path.area').nodes();
40537
40538         var bisect = d3_bisector(function(node) {
40539             return -node.__data__.area(graph);
40540         }).left;
40541
40542         function sortedByArea(entity) {
40543             if (this._parent.__data__ === 'fill') {
40544                 return fills[bisect(fills, -entity.area(graph))];
40545             }
40546         }
40547
40548         paths = paths.enter()
40549             .insert('path', sortedByArea)
40550             .merge(paths)
40551             .each(function(entity) {
40552                 var layer = this.parentNode.__data__;
40553
40554                 this.setAttribute('class', entity.type + ' area ' + layer + ' ' + entity.id);
40555
40556                 if (layer === 'fill') {
40557                     this.setAttribute('clip-path', 'url(#' + entity.id + '-clippath)');
40558                     setPattern.apply(this, arguments);
40559                 }
40560             })
40561             .call(svgTagClasses())
40562             .attr('d', path);
40563     };
40564 }
40565
40566 function svgDebug(projection, context) {
40567
40568     function multipolygons(imagery) {
40569         return imagery.map(function(data$$1) {
40570             return {
40571                 type: 'MultiPolygon',
40572                 coordinates: [ data$$1.polygon ]
40573             };
40574         });
40575     }
40576
40577     function drawDebug(selection) {
40578         var showsTile = context.getDebug('tile'),
40579             showsCollision = context.getDebug('collision'),
40580             showsImagery = context.getDebug('imagery'),
40581             showsImperial = context.getDebug('imperial'),
40582             showsDriveLeft = context.getDebug('driveLeft'),
40583             path = d3_geoPath(projection);
40584
40585
40586         var debugData = [];
40587         if (showsTile) {
40588             debugData.push({ class: 'red', label: 'tile' });
40589         }
40590         if (showsCollision) {
40591             debugData.push({ class: 'yellow', label: 'collision' });
40592         }
40593         if (showsImagery) {
40594             debugData.push({ class: 'orange', label: 'imagery' });
40595         }
40596         if (showsImperial) {
40597             debugData.push({ class: 'cyan', label: 'imperial' });
40598         }
40599         if (showsDriveLeft) {
40600             debugData.push({ class: 'green', label: 'driveLeft' });
40601         }
40602
40603
40604         var legend = d3_select('#content')
40605             .selectAll('.debug-legend')
40606             .data(debugData.length ? [0] : []);
40607
40608         legend.exit()
40609             .remove();
40610
40611         legend = legend.enter()
40612             .append('div')
40613             .attr('class', 'fillD debug-legend')
40614             .merge(legend);
40615
40616
40617         var legendItems = legend.selectAll('.debug-legend-item')
40618             .data(debugData, function(d) { return d.label; });
40619
40620         legendItems.exit()
40621             .remove();
40622
40623         legendItems.enter()
40624             .append('span')
40625             .attr('class', function(d) { return 'debug-legend-item ' + d.class; })
40626             .text(function(d) { return d.label; });
40627
40628
40629         var layer = selection.selectAll('.layer-debug')
40630             .data(showsImagery || showsImperial || showsDriveLeft ? [0] : []);
40631
40632         layer.exit()
40633             .remove();
40634
40635         layer = layer.enter()
40636             .append('g')
40637             .attr('class', 'layer-debug')
40638             .merge(layer);
40639
40640
40641         var extent = context.map().extent(),
40642             dataImagery = data.imagery || [],
40643             availableImagery = showsImagery && multipolygons(dataImagery.filter(function(source) {
40644                 if (!source.polygon) return false;
40645                 return source.polygon.some(function(polygon) {
40646                     return geoPolygonIntersectsPolygon(polygon, extent, true);
40647                 });
40648             }));
40649
40650         var imagery = layer.selectAll('path.debug-imagery')
40651             .data(showsImagery ? availableImagery : []);
40652
40653         imagery.exit()
40654             .remove();
40655
40656         imagery.enter()
40657             .append('path')
40658             .attr('class', 'debug-imagery debug orange');
40659
40660
40661         var imperial = layer
40662             .selectAll('path.debug-imperial')
40663             .data(showsImperial ? [dataImperial] : []);
40664
40665         imperial.exit()
40666             .remove();
40667
40668         imperial.enter()
40669             .append('path')
40670             .attr('class', 'debug-imperial debug cyan');
40671
40672
40673         var driveLeft = layer
40674             .selectAll('path.debug-drive-left')
40675             .data(showsDriveLeft ? [dataDriveLeft] : []);
40676
40677         driveLeft.exit()
40678             .remove();
40679
40680         driveLeft.enter()
40681             .append('path')
40682             .attr('class', 'debug-drive-left debug green');
40683
40684
40685         // update
40686         layer.selectAll('path')
40687             .attr('d', path);
40688     }
40689
40690
40691     // This looks strange because `enabled` methods on other layers are
40692     // chainable getter/setters, and this one is just a getter.
40693     drawDebug.enabled = function() {
40694         if (!arguments.length) {
40695             return context.getDebug('tile') ||
40696                 context.getDebug('collision') ||
40697                 context.getDebug('imagery') ||
40698                 context.getDebug('imperial') ||
40699                 context.getDebug('driveLeft');
40700         } else {
40701             return this;
40702         }
40703     };
40704
40705
40706     return drawDebug;
40707 }
40708
40709 /*
40710     A standalone SVG element that contains only a `defs` sub-element. To be
40711     used once globally, since defs IDs must be unique within a document.
40712 */
40713 function svgDefs(context) {
40714
40715     function SVGSpriteDefinition(id, href) {
40716         return function(defs) {
40717             d3_request(href)
40718                 .mimeType('image/svg+xml')
40719                 .response(function(xhr) { return xhr.responseXML; })
40720                 .get(function(err, svg) {
40721                     if (err) return;
40722                     defs.node().appendChild(
40723                         d3_select(svg.documentElement).attr('id', id).node()
40724                     );
40725                 });
40726         };
40727     }
40728
40729
40730     return function drawDefs(selection) {
40731         var defs = selection.append('defs');
40732
40733         // marker
40734         defs.append('marker')
40735             .attr('id', 'oneway-marker')
40736             .attr('viewBox', '0 0 10 10')
40737             .attr('refY', 2.5)
40738             .attr('refX', 5)
40739             .attr('markerWidth', 2)
40740             .attr('markerHeight', 2)
40741             .attr('markerUnits', 'strokeWidth')
40742             .attr('orient', 'auto')
40743
40744             .append('path')
40745             .attr('class', 'oneway')
40746             .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')
40747             .attr('stroke', 'none')
40748             .attr('fill', '#000')
40749             .attr('opacity', '0.75');
40750
40751         // patterns
40752         var patterns = defs.selectAll('pattern')
40753             .data([
40754                 // pattern name, pattern image name
40755                 ['wetland', 'wetland'],
40756                 ['construction', 'construction'],
40757                 ['cemetery', 'cemetery'],
40758                 ['orchard', 'orchard'],
40759                 ['farmland', 'farmland'],
40760                 ['beach', 'dots'],
40761                 ['scrub', 'dots'],
40762                 ['meadow', 'dots']
40763             ])
40764             .enter()
40765             .append('pattern')
40766             .attr('id', function (d) {
40767                 return 'pattern-' + d[0];
40768             })
40769             .attr('width', 32)
40770             .attr('height', 32)
40771             .attr('patternUnits', 'userSpaceOnUse');
40772
40773         patterns.append('rect')
40774             .attr('x', 0)
40775             .attr('y', 0)
40776             .attr('width', 32)
40777             .attr('height', 32)
40778             .attr('class', function (d) {
40779                     return 'pattern-color-' + d[0];
40780             });
40781
40782         patterns.append('image')
40783             .attr('x', 0)
40784             .attr('y', 0)
40785             .attr('width', 32)
40786             .attr('height', 32)
40787             .attr('xlink:href', function (d) {
40788                 return context.imagePath('pattern/' + d[1] + '.png');
40789             });
40790
40791         // clip paths
40792         defs.selectAll()
40793             .data([12, 18, 20, 32, 45])
40794             .enter()
40795             .append('clipPath')
40796             .attr('id', function (d) {
40797                 return 'clip-square-' + d;
40798             })
40799             .append('rect')
40800             .attr('x', 0)
40801             .attr('y', 0)
40802             .attr('width', function (d) {
40803                 return d;
40804             })
40805             .attr('height', function (d) {
40806                 return d;
40807             });
40808
40809         defs.call(SVGSpriteDefinition(
40810             'iD-sprite',
40811             context.imagePath('iD-sprite.svg')));
40812
40813         defs.call(SVGSpriteDefinition(
40814             'maki-sprite',
40815             context.imagePath('maki-sprite.svg')));
40816     };
40817 }
40818
40819 /**
40820  * Checks if `value` is `undefined`.
40821  *
40822  * @static
40823  * @since 0.1.0
40824  * @memberOf _
40825  * @category Lang
40826  * @param {*} value The value to check.
40827  * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
40828  * @example
40829  *
40830  * _.isUndefined(void 0);
40831  * // => true
40832  *
40833  * _.isUndefined(null);
40834  * // => false
40835  */
40836 function isUndefined(value) {
40837   return value === undefined;
40838 }
40839
40840 //[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]
40841 //[4a]          NameChar           ::=          NameStartChar | "-" | "." | [0-9] | #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
40842 //[5]           Name       ::=          NameStartChar (NameChar)*
40843 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
40844 var nameChar = new RegExp("[\\-\\.0-9"+nameStartChar.source.slice(1,-1)+"\\u00B7\\u0300-\\u036F\\u203F-\\u2040]");
40845 var tagNamePattern = new RegExp('^'+nameStartChar.source+nameChar.source+'*(?:\:'+nameStartChar.source+nameChar.source+'*)?$');
40846 //var tagNamePattern = /^[a-zA-Z_][\w\-\.]*(?:\:[a-zA-Z_][\w\-\.]*)?$/
40847 //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(',')
40848
40849 //S_TAG,        S_ATTR, S_EQ,   S_ATTR_NOQUOT_VALUE
40850 //S_ATTR_SPACE, S_ATTR_END,     S_TAG_SPACE, S_TAG_CLOSE
40851 var S_TAG = 0;//tag name offerring
40852 var S_ATTR = 1;//attr name offerring 
40853 var S_ATTR_SPACE=2;//attr name end and space offer
40854 var S_EQ = 3;//=space?
40855 var S_ATTR_NOQUOT_VALUE = 4;//attr value(no quot value only)
40856 var S_ATTR_END = 5;//attr value end and no space(quot end)
40857 var S_TAG_SPACE = 6;//(attr value end || tag end ) && (space offer)
40858 var S_TAG_CLOSE = 7;//closed el<el />
40859
40860 function XMLReader(){
40861         
40862 }
40863
40864 XMLReader.prototype = {
40865         parse:function(source,defaultNSMap,entityMap){
40866                 var domBuilder = this.domBuilder;
40867                 domBuilder.startDocument();
40868                 _copy(defaultNSMap ,defaultNSMap = {});
40869                 parse$1(source,defaultNSMap,entityMap,
40870                                 domBuilder,this.errorHandler);
40871                 domBuilder.endDocument();
40872         }
40873 };
40874 function parse$1(source,defaultNSMapCopy,entityMap,domBuilder,errorHandler){
40875         function fixedFromCharCode(code) {
40876                 // String.prototype.fromCharCode does not supports
40877                 // > 2 bytes unicode chars directly
40878                 if (code > 0xffff) {
40879                         code -= 0x10000;
40880                         var surrogate1 = 0xd800 + (code >> 10)
40881                                 , surrogate2 = 0xdc00 + (code & 0x3ff);
40882
40883                         return String.fromCharCode(surrogate1, surrogate2);
40884                 } else {
40885                         return String.fromCharCode(code);
40886                 }
40887         }
40888         function entityReplacer(a){
40889                 var k = a.slice(1,-1);
40890                 if(k in entityMap){
40891                         return entityMap[k]; 
40892                 }else if(k.charAt(0) === '#'){
40893                         return fixedFromCharCode(parseInt(k.substr(1).replace('x','0x')))
40894                 }else{
40895                         errorHandler.error('entity not found:'+a);
40896                         return a;
40897                 }
40898         }
40899         function appendText(end){//has some bugs
40900                 if(end>start){
40901                         var xt = source.substring(start,end).replace(/&#?\w+;/g,entityReplacer);
40902                         locator&&position(start);
40903                         domBuilder.characters(xt,0,end-start);
40904                         start = end;
40905                 }
40906         }
40907         function position(p,m){
40908                 while(p>=lineEnd && (m = linePattern.exec(source))){
40909                         lineStart = m.index;
40910                         lineEnd = lineStart + m[0].length;
40911                         locator.lineNumber++;
40912                         //console.log('line++:',locator,startPos,endPos)
40913                 }
40914                 locator.columnNumber = p-lineStart+1;
40915         }
40916         var lineStart = 0;
40917         var lineEnd = 0;
40918         var linePattern = /.*(?:\r\n?|\n)|.*$/g;
40919         var locator = domBuilder.locator;
40920         
40921         var parseStack = [{currentNSMap:defaultNSMapCopy}];
40922         var closeMap = {};
40923         var start = 0;
40924         while(true){
40925                 try{
40926                         var tagStart = source.indexOf('<',start);
40927                         if(tagStart<0){
40928                                 if(!source.substr(start).match(/^\s*$/)){
40929                                         var doc = domBuilder.doc;
40930                                 var text = doc.createTextNode(source.substr(start));
40931                                 doc.appendChild(text);
40932                                 domBuilder.currentElement = text;
40933                                 }
40934                                 return;
40935                         }
40936                         if(tagStart>start){
40937                                 appendText(tagStart);
40938                         }
40939                         switch(source.charAt(tagStart+1)){
40940                         case '/':
40941                                 var end = source.indexOf('>',tagStart+3);
40942                                 var tagName = source.substring(tagStart+2,end);
40943                                 var config = parseStack.pop();
40944                                 if(end<0){
40945                                         
40946                                 tagName = source.substring(tagStart+2).replace(/[\s<].*/,'');
40947                                 //console.error('#@@@@@@'+tagName)
40948                                 errorHandler.error("end tag name: "+tagName+' is not complete:'+config.tagName);
40949                                 end = tagStart+1+tagName.length;
40950                         }else if(tagName.match(/\s</)){
40951                                 tagName = tagName.replace(/[\s<].*/,'');
40952                                 errorHandler.error("end tag name: "+tagName+' maybe not complete');
40953                                 end = tagStart+1+tagName.length;
40954                                 }
40955                                 //console.error(parseStack.length,parseStack)
40956                                 //console.error(config);
40957                                 var localNSMap = config.localNSMap;
40958                                 var endMatch = config.tagName == tagName;
40959                                 var endIgnoreCaseMach = endMatch || config.tagName&&config.tagName.toLowerCase() == tagName.toLowerCase();
40960                         if(endIgnoreCaseMach){
40961                                 domBuilder.endElement(config.uri,config.localName,tagName);
40962                                         if(localNSMap){
40963                                                 for(var prefix in localNSMap){
40964                                                         domBuilder.endPrefixMapping(prefix) ;
40965                                                 }
40966                                         }
40967                                         if(!endMatch){
40968                                 errorHandler.fatalError("end tag name: "+tagName+' is not match the current start tagName:'+config.tagName );
40969                                         }
40970                         }else{
40971                                 parseStack.push(config);
40972                         }
40973                                 
40974                                 end++;
40975                                 break;
40976                                 // end elment
40977                         case '?':// <?...?>
40978                                 locator&&position(tagStart);
40979                                 end = parseInstruction(source,tagStart,domBuilder);
40980                                 break;
40981                         case '!':// <!doctype,<![CDATA,<!--
40982                                 locator&&position(tagStart);
40983                                 end = parseDCC(source,tagStart,domBuilder,errorHandler);
40984                                 break;
40985                         default:
40986                                 locator&&position(tagStart);
40987                                 var el = new ElementAttributes();
40988                                 var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
40989                                 //elStartEnd
40990                                 var end = parseElementStartPart(source,tagStart,el,currentNSMap,entityReplacer,errorHandler);
40991                                 var len = el.length;
40992                                 
40993                                 
40994                                 if(!el.closed && fixSelfClosed(source,end,el.tagName,closeMap)){
40995                                         el.closed = true;
40996                                         if(!entityMap.nbsp){
40997                                                 errorHandler.warning('unclosed xml attribute');
40998                                         }
40999                                 }
41000                                 if(locator && len){
41001                                         var locator2 = copyLocator(locator,{});
41002                                         //try{//attribute position fixed
41003                                         for(var i = 0;i<len;i++){
41004                                                 var a = el[i];
41005                                                 position(a.offset);
41006                                                 a.locator = copyLocator(locator,{});
41007                                         }
41008                                         //}catch(e){console.error('@@@@@'+e)}
41009                                         domBuilder.locator = locator2;
41010                                         if(appendElement(el,domBuilder,currentNSMap)){
41011                                                 parseStack.push(el);
41012                                         }
41013                                         domBuilder.locator = locator;
41014                                 }else{
41015                                         if(appendElement(el,domBuilder,currentNSMap)){
41016                                                 parseStack.push(el);
41017                                         }
41018                                 }
41019                                 
41020                                 
41021                                 
41022                                 if(el.uri === 'http://www.w3.org/1999/xhtml' && !el.closed){
41023                                         end = parseHtmlSpecialContent(source,end,el.tagName,entityReplacer,domBuilder);
41024                                 }else{
41025                                         end++;
41026                                 }
41027                         }
41028                 }catch(e){
41029                         errorHandler.error('element parse error: '+e);
41030                         //errorHandler.error('element parse error: '+e);
41031                         end = -1;
41032                         //throw e;
41033                 }
41034                 if(end>start){
41035                         start = end;
41036                 }else{
41037                         //TODO: 这里有可能sax回退,有位置错误风险
41038                         appendText(Math.max(tagStart,start)+1);
41039                 }
41040         }
41041 }
41042 function copyLocator(f,t){
41043         t.lineNumber = f.lineNumber;
41044         t.columnNumber = f.columnNumber;
41045         return t;
41046 }
41047
41048 /**
41049  * @see #appendElement(source,elStartEnd,el,selfClosed,entityReplacer,domBuilder,parseStack);
41050  * @return end of the elementStartPart(end of elementEndPart for selfClosed el)
41051  */
41052 function parseElementStartPart(source,start,el,currentNSMap,entityReplacer,errorHandler){
41053         var attrName;
41054         var value;
41055         var p = ++start;
41056         var s = S_TAG;//status
41057         while(true){
41058                 var c = source.charAt(p);
41059                 switch(c){
41060                 case '=':
41061                         if(s === S_ATTR){//attrName
41062                                 attrName = source.slice(start,p);
41063                                 s = S_EQ;
41064                         }else if(s === S_ATTR_SPACE){
41065                                 s = S_EQ;
41066                         }else{
41067                                 //fatalError: equal must after attrName or space after attrName
41068                                 throw new Error('attribute equal must after attrName');
41069                         }
41070                         break;
41071                 case '\'':
41072                 case '"':
41073                         if(s === S_EQ || s === S_ATTR //|| s == S_ATTR_SPACE
41074                                 ){//equal
41075                                 if(s === S_ATTR){
41076                                         errorHandler.warning('attribute value must after "="');
41077                                         attrName = source.slice(start,p);
41078                                 }
41079                                 start = p+1;
41080                                 p = source.indexOf(c,start);
41081                                 if(p>0){
41082                                         value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
41083                                         el.add(attrName,value,start-1);
41084                                         s = S_ATTR_END;
41085                                 }else{
41086                                         //fatalError: no end quot match
41087                                         throw new Error('attribute value no end \''+c+'\' match');
41088                                 }
41089                         }else if(s == S_ATTR_NOQUOT_VALUE){
41090                                 value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
41091                                 //console.log(attrName,value,start,p)
41092                                 el.add(attrName,value,start);
41093                                 //console.dir(el)
41094                                 errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');
41095                                 start = p+1;
41096                                 s = S_ATTR_END;
41097                         }else{
41098                                 //fatalError: no equal before
41099                                 throw new Error('attribute value must after "="');
41100                         }
41101                         break;
41102                 case '/':
41103                         switch(s){
41104                         case S_TAG:
41105                                 el.setTagName(source.slice(start,p));
41106                         case S_ATTR_END:
41107                         case S_TAG_SPACE:
41108                         case S_TAG_CLOSE:
41109                                 s =S_TAG_CLOSE;
41110                                 el.closed = true;
41111                         case S_ATTR_NOQUOT_VALUE:
41112                         case S_ATTR:
41113                         case S_ATTR_SPACE:
41114                                 break;
41115                         //case S_EQ:
41116                         default:
41117                                 throw new Error("attribute invalid close char('/')")
41118                         }
41119                         break;
41120                 case ''://end document
41121                         //throw new Error('unexpected end of input')
41122                         errorHandler.error('unexpected end of input');
41123                         if(s == S_TAG){
41124                                 el.setTagName(source.slice(start,p));
41125                         }
41126                         return p;
41127                 case '>':
41128                         switch(s){
41129                         case S_TAG:
41130                                 el.setTagName(source.slice(start,p));
41131                         case S_ATTR_END:
41132                         case S_TAG_SPACE:
41133                         case S_TAG_CLOSE:
41134                                 break;//normal
41135                         case S_ATTR_NOQUOT_VALUE://Compatible state
41136                         case S_ATTR:
41137                                 value = source.slice(start,p);
41138                                 if(value.slice(-1) === '/'){
41139                                         el.closed  = true;
41140                                         value = value.slice(0,-1);
41141                                 }
41142                         case S_ATTR_SPACE:
41143                                 if(s === S_ATTR_SPACE){
41144                                         value = attrName;
41145                                 }
41146                                 if(s == S_ATTR_NOQUOT_VALUE){
41147                                         errorHandler.warning('attribute "'+value+'" missed quot(")!!');
41148                                         el.add(attrName,value.replace(/&#?\w+;/g,entityReplacer),start);
41149                                 }else{
41150                                         if(currentNSMap[''] !== 'http://www.w3.org/1999/xhtml' || !value.match(/^(?:disabled|checked|selected)$/i)){
41151                                                 errorHandler.warning('attribute "'+value+'" missed value!! "'+value+'" instead!!');
41152                                         }
41153                                         el.add(value,value,start);
41154                                 }
41155                                 break;
41156                         case S_EQ:
41157                                 throw new Error('attribute value missed!!');
41158                         }
41159 //                      console.log(tagName,tagNamePattern,tagNamePattern.test(tagName))
41160                         return p;
41161                 /*xml space '\x20' | #x9 | #xD | #xA; */
41162                 case '\u0080':
41163                         c = ' ';
41164                 default:
41165                         if(c<= ' '){//space
41166                                 switch(s){
41167                                 case S_TAG:
41168                                         el.setTagName(source.slice(start,p));//tagName
41169                                         s = S_TAG_SPACE;
41170                                         break;
41171                                 case S_ATTR:
41172                                         attrName = source.slice(start,p);
41173                                         s = S_ATTR_SPACE;
41174                                         break;
41175                                 case S_ATTR_NOQUOT_VALUE:
41176                                         var value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
41177                                         errorHandler.warning('attribute "'+value+'" missed quot(")!!');
41178                                         el.add(attrName,value,start);
41179                                 case S_ATTR_END:
41180                                         s = S_TAG_SPACE;
41181                                         break;
41182                                 //case S_TAG_SPACE:
41183                                 //case S_EQ:
41184                                 //case S_ATTR_SPACE:
41185                                 //      void();break;
41186                                 //case S_TAG_CLOSE:
41187                                         //ignore warning
41188                                 }
41189                         }else{//not space
41190 //S_TAG,        S_ATTR, S_EQ,   S_ATTR_NOQUOT_VALUE
41191 //S_ATTR_SPACE, S_ATTR_END,     S_TAG_SPACE, S_TAG_CLOSE
41192                                 switch(s){
41193                                 //case S_TAG:void();break;
41194                                 //case S_ATTR:void();break;
41195                                 //case S_ATTR_NOQUOT_VALUE:void();break;
41196                                 case S_ATTR_SPACE:
41197                                         var tagName =  el.tagName;
41198                                         if(currentNSMap[''] !== 'http://www.w3.org/1999/xhtml' || !attrName.match(/^(?:disabled|checked|selected)$/i)){
41199                                                 errorHandler.warning('attribute "'+attrName+'" missed value!! "'+attrName+'" instead2!!');
41200                                         }
41201                                         el.add(attrName,attrName,start);
41202                                         start = p;
41203                                         s = S_ATTR;
41204                                         break;
41205                                 case S_ATTR_END:
41206                                         errorHandler.warning('attribute space is required"'+attrName+'"!!');
41207                                 case S_TAG_SPACE:
41208                                         s = S_ATTR;
41209                                         start = p;
41210                                         break;
41211                                 case S_EQ:
41212                                         s = S_ATTR_NOQUOT_VALUE;
41213                                         start = p;
41214                                         break;
41215                                 case S_TAG_CLOSE:
41216                                         throw new Error("elements closed character '/' and '>' must be connected to");
41217                                 }
41218                         }
41219                 }//end outer switch
41220                 //console.log('p++',p)
41221                 p++;
41222         }
41223 }
41224 /**
41225  * @return true if has new namespace define
41226  */
41227 function appendElement(el,domBuilder,currentNSMap){
41228         var tagName = el.tagName;
41229         var localNSMap = null;
41230         //var currentNSMap = parseStack[parseStack.length-1].currentNSMap;
41231         var i = el.length;
41232         while(i--){
41233                 var a = el[i];
41234                 var qName = a.qName;
41235                 var value = a.value;
41236                 var nsp = qName.indexOf(':');
41237                 if(nsp>0){
41238                         var prefix = a.prefix = qName.slice(0,nsp);
41239                         var localName = qName.slice(nsp+1);
41240                         var nsPrefix = prefix === 'xmlns' && localName;
41241                 }else{
41242                         localName = qName;
41243                         prefix = null;
41244                         nsPrefix = qName === 'xmlns' && '';
41245                 }
41246                 //can not set prefix,because prefix !== ''
41247                 a.localName = localName ;
41248                 //prefix == null for no ns prefix attribute 
41249                 if(nsPrefix !== false){//hack!!
41250                         if(localNSMap == null){
41251                                 localNSMap = {};
41252                                 //console.log(currentNSMap,0)
41253                                 _copy(currentNSMap,currentNSMap={});
41254                                 //console.log(currentNSMap,1)
41255                         }
41256                         currentNSMap[nsPrefix] = localNSMap[nsPrefix] = value;
41257                         a.uri = 'http://www.w3.org/2000/xmlns/';
41258                         domBuilder.startPrefixMapping(nsPrefix, value); 
41259                 }
41260         }
41261         var i = el.length;
41262         while(i--){
41263                 a = el[i];
41264                 var prefix = a.prefix;
41265                 if(prefix){//no prefix attribute has no namespace
41266                         if(prefix === 'xml'){
41267                                 a.uri = 'http://www.w3.org/XML/1998/namespace';
41268                         }if(prefix !== 'xmlns'){
41269                                 a.uri = currentNSMap[prefix || ''];
41270                                 
41271                                 //{console.log('###'+a.qName,domBuilder.locator.systemId+'',currentNSMap,a.uri)}
41272                         }
41273                 }
41274         }
41275         var nsp = tagName.indexOf(':');
41276         if(nsp>0){
41277                 prefix = el.prefix = tagName.slice(0,nsp);
41278                 localName = el.localName = tagName.slice(nsp+1);
41279         }else{
41280                 prefix = null;//important!!
41281                 localName = el.localName = tagName;
41282         }
41283         //no prefix element has default namespace
41284         var ns = el.uri = currentNSMap[prefix || ''];
41285         domBuilder.startElement(ns,localName,tagName,el);
41286         //endPrefixMapping and startPrefixMapping have not any help for dom builder
41287         //localNSMap = null
41288         if(el.closed){
41289                 domBuilder.endElement(ns,localName,tagName);
41290                 if(localNSMap){
41291                         for(prefix in localNSMap){
41292                                 domBuilder.endPrefixMapping(prefix); 
41293                         }
41294                 }
41295         }else{
41296                 el.currentNSMap = currentNSMap;
41297                 el.localNSMap = localNSMap;
41298                 //parseStack.push(el);
41299                 return true;
41300         }
41301 }
41302 function parseHtmlSpecialContent(source,elStartEnd,tagName,entityReplacer,domBuilder){
41303         if(/^(?:script|textarea)$/i.test(tagName)){
41304                 var elEndStart =  source.indexOf('</'+tagName+'>',elStartEnd);
41305                 var text = source.substring(elStartEnd+1,elEndStart);
41306                 if(/[&<]/.test(text)){
41307                         if(/^script$/i.test(tagName)){
41308                                 //if(!/\]\]>/.test(text)){
41309                                         //lexHandler.startCDATA();
41310                                         domBuilder.characters(text,0,text.length);
41311                                         //lexHandler.endCDATA();
41312                                         return elEndStart;
41313                                 //}
41314                         }//}else{//text area
41315                                 text = text.replace(/&#?\w+;/g,entityReplacer);
41316                                 domBuilder.characters(text,0,text.length);
41317                                 return elEndStart;
41318                         //}
41319                         
41320                 }
41321         }
41322         return elStartEnd+1;
41323 }
41324 function fixSelfClosed(source,elStartEnd,tagName,closeMap){
41325         //if(tagName in closeMap){
41326         var pos = closeMap[tagName];
41327         if(pos == null){
41328                 //console.log(tagName)
41329                 pos =  source.lastIndexOf('</'+tagName+'>');
41330                 if(pos<elStartEnd){//忘记闭合
41331                         pos = source.lastIndexOf('</'+tagName);
41332                 }
41333                 closeMap[tagName] =pos;
41334         }
41335         return pos<elStartEnd;
41336         //} 
41337 }
41338 function _copy(source,target){
41339         for(var n in source){target[n] = source[n];}
41340 }
41341 function parseDCC(source,start,domBuilder,errorHandler){//sure start with '<!'
41342         var next= source.charAt(start+2);
41343         switch(next){
41344         case '-':
41345                 if(source.charAt(start + 3) === '-'){
41346                         var end = source.indexOf('-->',start+4);
41347                         //append comment source.substring(4,end)//<!--
41348                         if(end>start){
41349                                 domBuilder.comment(source,start+4,end-start-4);
41350                                 return end+3;
41351                         }else{
41352                                 errorHandler.error("Unclosed comment");
41353                                 return -1;
41354                         }
41355                 }else{
41356                         //error
41357                         return -1;
41358                 }
41359         default:
41360                 if(source.substr(start+3,6) == 'CDATA['){
41361                         var end = source.indexOf(']]>',start+9);
41362                         domBuilder.startCDATA();
41363                         domBuilder.characters(source,start+9,end-start-9);
41364                         domBuilder.endCDATA(); 
41365                         return end+3;
41366                 }
41367                 //<!DOCTYPE
41368                 //startDTD(java.lang.String name, java.lang.String publicId, java.lang.String systemId) 
41369                 var matchs = split(source,start);
41370                 var len = matchs.length;
41371                 if(len>1 && /!doctype/i.test(matchs[0][0])){
41372                         var name = matchs[1][0];
41373                         var pubid = len>3 && /^public$/i.test(matchs[2][0]) && matchs[3][0];
41374                         var sysid = len>4 && matchs[4][0];
41375                         var lastMatch = matchs[len-1];
41376                         domBuilder.startDTD(name,pubid && pubid.replace(/^(['"])(.*?)\1$/,'$2'),
41377                                         sysid && sysid.replace(/^(['"])(.*?)\1$/,'$2'));
41378                         domBuilder.endDTD();
41379                         
41380                         return lastMatch.index+lastMatch[0].length
41381                 }
41382         }
41383         return -1;
41384 }
41385
41386
41387
41388 function parseInstruction(source,start,domBuilder){
41389         var end = source.indexOf('?>',start);
41390         if(end){
41391                 var match = source.substring(start,end).match(/^<\?(\S*)\s*([\s\S]*?)\s*$/);
41392                 if(match){
41393                         var len = match[0].length;
41394                         domBuilder.processingInstruction(match[1], match[2]) ;
41395                         return end+2;
41396                 }else{//error
41397                         return -1;
41398                 }
41399         }
41400         return -1;
41401 }
41402
41403 /**
41404  * @param source
41405  */
41406 function ElementAttributes(source){
41407         
41408 }
41409 ElementAttributes.prototype = {
41410         setTagName:function(tagName){
41411                 if(!tagNamePattern.test(tagName)){
41412                         throw new Error('invalid tagName:'+tagName)
41413                 }
41414                 this.tagName = tagName;
41415         },
41416         add:function(qName,value,offset){
41417                 if(!tagNamePattern.test(qName)){
41418                         throw new Error('invalid attribute:'+qName)
41419                 }
41420                 this[this.length++] = {qName:qName,value:value,offset:offset};
41421         },
41422         length:0,
41423         getLocalName:function(i){return this[i].localName},
41424         getLocator:function(i){return this[i].locator},
41425         getQName:function(i){return this[i].qName},
41426         getURI:function(i){return this[i].uri},
41427         getValue:function(i){return this[i].value}
41428 //      ,getIndex:function(uri, localName)){
41429 //              if(localName){
41430 //                      
41431 //              }else{
41432 //                      var qName = uri
41433 //              }
41434 //      },
41435 //      getValue:function(){return this.getValue(this.getIndex.apply(this,arguments))},
41436 //      getType:function(uri,localName){}
41437 //      getType:function(i){},
41438 };
41439
41440
41441
41442
41443 function _set_proto_(thiz,parent){
41444         thiz.__proto__ = parent;
41445         return thiz;
41446 }
41447 if(!(_set_proto_({},_set_proto_.prototype) instanceof _set_proto_)){
41448         _set_proto_ = function(thiz,parent){
41449                 function p(){}
41450                 p.prototype = parent;
41451                 p = new p();
41452                 for(parent in thiz){
41453                         p[parent] = thiz[parent];
41454                 }
41455                 return p;
41456         };
41457 }
41458
41459 function split(source,start){
41460         var match;
41461         var buf = [];
41462         var reg = /'[^']+'|"[^"]+"|[^\s<>\/=]+=?|(\/?\s*>|<)/g;
41463         reg.lastIndex = start;
41464         reg.exec(source);//skip <
41465         while(match = reg.exec(source)){
41466                 buf.push(match);
41467                 if(match[1])return buf;
41468         }
41469 }
41470
41471 var XMLReader_1 = XMLReader;
41472
41473 var sax = {
41474         XMLReader: XMLReader_1
41475 };
41476
41477 /*
41478  * DOM Level 2
41479  * Object DOMException
41480  * @see http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html
41481  * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/ecma-script-binding.html
41482  */
41483
41484 function copy$1(src,dest){
41485         for(var p in src){
41486                 dest[p] = src[p];
41487         }
41488 }
41489 /**
41490 ^\w+\.prototype\.([_\w]+)\s*=\s*((?:.*\{\s*?[\r\n][\s\S]*?^})|\S.*?(?=[;\r\n]));?
41491 ^\w+\.prototype\.([_\w]+)\s*=\s*(\S.*?(?=[;\r\n]));?
41492  */
41493 function _extends(Class,Super){
41494         var pt = Class.prototype;
41495         if(Object.create){
41496                 var ppt = Object.create(Super.prototype);
41497                 pt.__proto__ = ppt;
41498         }
41499         if(!(pt instanceof Super)){
41500                 function t(){}
41501                 t.prototype = Super.prototype;
41502                 t = new t();
41503                 copy$1(pt,t);
41504                 Class.prototype = pt = t;
41505         }
41506         if(pt.constructor != Class){
41507                 if(typeof Class != 'function'){
41508                         console.error("unknow Class:"+Class);
41509                 }
41510                 pt.constructor = Class;
41511         }
41512 }
41513 var htmlns = 'http://www.w3.org/1999/xhtml';
41514 // Node Types
41515 var NodeType = {};
41516 var ELEMENT_NODE                = NodeType.ELEMENT_NODE                = 1;
41517 var ATTRIBUTE_NODE              = NodeType.ATTRIBUTE_NODE              = 2;
41518 var TEXT_NODE                   = NodeType.TEXT_NODE                   = 3;
41519 var CDATA_SECTION_NODE          = NodeType.CDATA_SECTION_NODE          = 4;
41520 var ENTITY_REFERENCE_NODE       = NodeType.ENTITY_REFERENCE_NODE       = 5;
41521 var ENTITY_NODE                 = NodeType.ENTITY_NODE                 = 6;
41522 var PROCESSING_INSTRUCTION_NODE = NodeType.PROCESSING_INSTRUCTION_NODE = 7;
41523 var COMMENT_NODE                = NodeType.COMMENT_NODE                = 8;
41524 var DOCUMENT_NODE               = NodeType.DOCUMENT_NODE               = 9;
41525 var DOCUMENT_TYPE_NODE          = NodeType.DOCUMENT_TYPE_NODE          = 10;
41526 var DOCUMENT_FRAGMENT_NODE      = NodeType.DOCUMENT_FRAGMENT_NODE      = 11;
41527 var NOTATION_NODE               = NodeType.NOTATION_NODE               = 12;
41528
41529 // ExceptionCode
41530 var ExceptionCode = {};
41531 var ExceptionMessage = {};
41532 var INDEX_SIZE_ERR              = ExceptionCode.INDEX_SIZE_ERR              = (ExceptionMessage[1]="Index size error", 1);
41533 var DOMSTRING_SIZE_ERR          = ExceptionCode.DOMSTRING_SIZE_ERR          = (ExceptionMessage[2]="DOMString size error", 2);
41534 var HIERARCHY_REQUEST_ERR       = ExceptionCode.HIERARCHY_REQUEST_ERR       = (ExceptionMessage[3]="Hierarchy request error", 3);
41535 var WRONG_DOCUMENT_ERR          = ExceptionCode.WRONG_DOCUMENT_ERR          = (ExceptionMessage[4]="Wrong document", 4);
41536 var INVALID_CHARACTER_ERR       = ExceptionCode.INVALID_CHARACTER_ERR       = (ExceptionMessage[5]="Invalid character", 5);
41537 var NO_DATA_ALLOWED_ERR         = ExceptionCode.NO_DATA_ALLOWED_ERR         = (ExceptionMessage[6]="No data allowed", 6);
41538 var NO_MODIFICATION_ALLOWED_ERR = ExceptionCode.NO_MODIFICATION_ALLOWED_ERR = (ExceptionMessage[7]="No modification allowed", 7);
41539 var NOT_FOUND_ERR               = ExceptionCode.NOT_FOUND_ERR               = (ExceptionMessage[8]="Not found", 8);
41540 var NOT_SUPPORTED_ERR           = ExceptionCode.NOT_SUPPORTED_ERR           = (ExceptionMessage[9]="Not supported", 9);
41541 var INUSE_ATTRIBUTE_ERR         = ExceptionCode.INUSE_ATTRIBUTE_ERR         = (ExceptionMessage[10]="Attribute in use", 10);
41542 //level2
41543 var INVALID_STATE_ERR           = ExceptionCode.INVALID_STATE_ERR               = (ExceptionMessage[11]="Invalid state", 11);
41544 var SYNTAX_ERR                  = ExceptionCode.SYNTAX_ERR                      = (ExceptionMessage[12]="Syntax error", 12);
41545 var INVALID_MODIFICATION_ERR    = ExceptionCode.INVALID_MODIFICATION_ERR        = (ExceptionMessage[13]="Invalid modification", 13);
41546 var NAMESPACE_ERR               = ExceptionCode.NAMESPACE_ERR                   = (ExceptionMessage[14]="Invalid namespace", 14);
41547 var INVALID_ACCESS_ERR          = ExceptionCode.INVALID_ACCESS_ERR              = (ExceptionMessage[15]="Invalid access", 15);
41548
41549
41550 function DOMException(code, message) {
41551         if(message instanceof Error){
41552                 var error = message;
41553         }else{
41554                 error = this;
41555                 Error.call(this, ExceptionMessage[code]);
41556                 this.message = ExceptionMessage[code];
41557                 if(Error.captureStackTrace) Error.captureStackTrace(this, DOMException);
41558         }
41559         error.code = code;
41560         if(message) this.message = this.message + ": " + message;
41561         return error;
41562 }
41563 DOMException.prototype = Error.prototype;
41564 copy$1(ExceptionCode,DOMException);
41565 /**
41566  * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-536297177
41567  * 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.
41568  * The items in the NodeList are accessible via an integral index, starting from 0.
41569  */
41570 function NodeList() {
41571 }
41572 NodeList.prototype = {
41573         /**
41574          * The number of nodes in the list. The range of valid child node indices is 0 to length-1 inclusive.
41575          * @standard level1
41576          */
41577         length:0, 
41578         /**
41579          * 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.
41580          * @standard level1
41581          * @param index  unsigned long 
41582          *   Index into the collection.
41583          * @return Node
41584          *      The node at the indexth position in the NodeList, or null if that is not a valid index. 
41585          */
41586         item: function(index) {
41587                 return this[index] || null;
41588         },
41589         toString:function(isHTML,nodeFilter){
41590                 for(var buf = [], i = 0;i<this.length;i++){
41591                         serializeToString(this[i],buf,isHTML,nodeFilter);
41592                 }
41593                 return buf.join('');
41594         }
41595 };
41596 function LiveNodeList(node,refresh){
41597         this._node = node;
41598         this._refresh = refresh;
41599         _updateLiveList(this);
41600 }
41601 function _updateLiveList(list){
41602         var inc = list._node._inc || list._node.ownerDocument._inc;
41603         if(list._inc != inc){
41604                 var ls = list._refresh(list._node);
41605                 //console.log(ls.length)
41606                 __set__(list,'length',ls.length);
41607                 copy$1(ls,list);
41608                 list._inc = inc;
41609         }
41610 }
41611 LiveNodeList.prototype.item = function(i){
41612         _updateLiveList(this);
41613         return this[i];
41614 };
41615
41616 _extends(LiveNodeList,NodeList);
41617 /**
41618  * 
41619  * 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.
41620  * NamedNodeMap objects in the DOM are live.
41621  * used for attributes or DocumentType entities 
41622  */
41623 function NamedNodeMap() {
41624 }
41625
41626 function _findNodeIndex(list,node){
41627         var i = list.length;
41628         while(i--){
41629                 if(list[i] === node){return i}
41630         }
41631 }
41632
41633 function _addNamedNode(el,list,newAttr,oldAttr){
41634         if(oldAttr){
41635                 list[_findNodeIndex(list,oldAttr)] = newAttr;
41636         }else{
41637                 list[list.length++] = newAttr;
41638         }
41639         if(el){
41640                 newAttr.ownerElement = el;
41641                 var doc = el.ownerDocument;
41642                 if(doc){
41643                         oldAttr && _onRemoveAttribute(doc,el,oldAttr);
41644                         _onAddAttribute(doc,el,newAttr);
41645                 }
41646         }
41647 }
41648 function _removeNamedNode(el,list,attr){
41649         //console.log('remove attr:'+attr)
41650         var i = _findNodeIndex(list,attr);
41651         if(i>=0){
41652                 var lastIndex = list.length-1;
41653                 while(i<lastIndex){
41654                         list[i] = list[++i];
41655                 }
41656                 list.length = lastIndex;
41657                 if(el){
41658                         var doc = el.ownerDocument;
41659                         if(doc){
41660                                 _onRemoveAttribute(doc,el,attr);
41661                                 attr.ownerElement = null;
41662                         }
41663                 }
41664         }else{
41665                 throw DOMException(NOT_FOUND_ERR,new Error(el.tagName+'@'+attr))
41666         }
41667 }
41668 NamedNodeMap.prototype = {
41669         length:0,
41670         item:NodeList.prototype.item,
41671         getNamedItem: function(key) {
41672 //              if(key.indexOf(':')>0 || key == 'xmlns'){
41673 //                      return null;
41674 //              }
41675                 //console.log()
41676                 var i = this.length;
41677                 while(i--){
41678                         var attr = this[i];
41679                         //console.log(attr.nodeName,key)
41680                         if(attr.nodeName == key){
41681                                 return attr;
41682                         }
41683                 }
41684         },
41685         setNamedItem: function(attr) {
41686                 var el = attr.ownerElement;
41687                 if(el && el!=this._ownerElement){
41688                         throw new DOMException(INUSE_ATTRIBUTE_ERR);
41689                 }
41690                 var oldAttr = this.getNamedItem(attr.nodeName);
41691                 _addNamedNode(this._ownerElement,this,attr,oldAttr);
41692                 return oldAttr;
41693         },
41694         /* returns Node */
41695         setNamedItemNS: function(attr) {// raises: WRONG_DOCUMENT_ERR,NO_MODIFICATION_ALLOWED_ERR,INUSE_ATTRIBUTE_ERR
41696                 var el = attr.ownerElement, oldAttr;
41697                 if(el && el!=this._ownerElement){
41698                         throw new DOMException(INUSE_ATTRIBUTE_ERR);
41699                 }
41700                 oldAttr = this.getNamedItemNS(attr.namespaceURI,attr.localName);
41701                 _addNamedNode(this._ownerElement,this,attr,oldAttr);
41702                 return oldAttr;
41703         },
41704
41705         /* returns Node */
41706         removeNamedItem: function(key) {
41707                 var attr = this.getNamedItem(key);
41708                 _removeNamedNode(this._ownerElement,this,attr);
41709                 return attr;
41710                 
41711                 
41712         },// raises: NOT_FOUND_ERR,NO_MODIFICATION_ALLOWED_ERR
41713         
41714         //for level2
41715         removeNamedItemNS:function(namespaceURI,localName){
41716                 var attr = this.getNamedItemNS(namespaceURI,localName);
41717                 _removeNamedNode(this._ownerElement,this,attr);
41718                 return attr;
41719         },
41720         getNamedItemNS: function(namespaceURI, localName) {
41721                 var i = this.length;
41722                 while(i--){
41723                         var node = this[i];
41724                         if(node.localName == localName && node.namespaceURI == namespaceURI){
41725                                 return node;
41726                         }
41727                 }
41728                 return null;
41729         }
41730 };
41731 /**
41732  * @see http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-102161490
41733  */
41734 function DOMImplementation(/* Object */ features) {
41735         this._features = {};
41736         if (features) {
41737                 for (var feature in features) {
41738                          this._features = features[feature];
41739                 }
41740         }
41741 }
41742
41743 DOMImplementation.prototype = {
41744         hasFeature: function(/* string */ feature, /* string */ version) {
41745                 var versions = this._features[feature.toLowerCase()];
41746                 if (versions && (!version || version in versions)) {
41747                         return true;
41748                 } else {
41749                         return false;
41750                 }
41751         },
41752         // Introduced in DOM Level 2:
41753         createDocument:function(namespaceURI,  qualifiedName, doctype){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR,WRONG_DOCUMENT_ERR
41754                 var doc = new Document();
41755                 doc.implementation = this;
41756                 doc.childNodes = new NodeList();
41757                 doc.doctype = doctype;
41758                 if(doctype){
41759                         doc.appendChild(doctype);
41760                 }
41761                 if(qualifiedName){
41762                         var root = doc.createElementNS(namespaceURI,qualifiedName);
41763                         doc.appendChild(root);
41764                 }
41765                 return doc;
41766         },
41767         // Introduced in DOM Level 2:
41768         createDocumentType:function(qualifiedName, publicId, systemId){// raises:INVALID_CHARACTER_ERR,NAMESPACE_ERR
41769                 var node = new DocumentType();
41770                 node.name = qualifiedName;
41771                 node.nodeName = qualifiedName;
41772                 node.publicId = publicId;
41773                 node.systemId = systemId;
41774                 // Introduced in DOM Level 2:
41775                 //readonly attribute DOMString        internalSubset;
41776                 
41777                 //TODO:..
41778                 //  readonly attribute NamedNodeMap     entities;
41779                 //  readonly attribute NamedNodeMap     notations;
41780                 return node;
41781         }
41782 };
41783
41784
41785 /**
41786  * @see http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247
41787  */
41788
41789 function Node$2() {
41790 }
41791
41792 Node$2.prototype = {
41793         firstChild : null,
41794         lastChild : null,
41795         previousSibling : null,
41796         nextSibling : null,
41797         attributes : null,
41798         parentNode : null,
41799         childNodes : null,
41800         ownerDocument : null,
41801         nodeValue : null,
41802         namespaceURI : null,
41803         prefix : null,
41804         localName : null,
41805         // Modified in DOM Level 2:
41806         insertBefore:function(newChild, refChild){//raises 
41807                 return _insertBefore(this,newChild,refChild);
41808         },
41809         replaceChild:function(newChild, oldChild){//raises 
41810                 this.insertBefore(newChild,oldChild);
41811                 if(oldChild){
41812                         this.removeChild(oldChild);
41813                 }
41814         },
41815         removeChild:function(oldChild){
41816                 return _removeChild(this,oldChild);
41817         },
41818         appendChild:function(newChild){
41819                 return this.insertBefore(newChild,null);
41820         },
41821         hasChildNodes:function(){
41822                 return this.firstChild != null;
41823         },
41824         cloneNode:function(deep){
41825                 return cloneNode(this.ownerDocument||this,this,deep);
41826         },
41827         // Modified in DOM Level 2:
41828         normalize:function(){
41829                 var child = this.firstChild;
41830                 while(child){
41831                         var next = child.nextSibling;
41832                         if(next && next.nodeType == TEXT_NODE && child.nodeType == TEXT_NODE){
41833                                 this.removeChild(next);
41834                                 child.appendData(next.data);
41835                         }else{
41836                                 child.normalize();
41837                                 child = next;
41838                         }
41839                 }
41840         },
41841         // Introduced in DOM Level 2:
41842         isSupported:function(feature, version){
41843                 return this.ownerDocument.implementation.hasFeature(feature,version);
41844         },
41845     // Introduced in DOM Level 2:
41846     hasAttributes:function(){
41847         return this.attributes.length>0;
41848     },
41849     lookupPrefix:function(namespaceURI){
41850         var el = this;
41851         while(el){
41852                 var map = el._nsMap;
41853                 //console.dir(map)
41854                 if(map){
41855                         for(var n in map){
41856                                 if(map[n] == namespaceURI){
41857                                         return n;
41858                                 }
41859                         }
41860                 }
41861                 el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
41862         }
41863         return null;
41864     },
41865     // Introduced in DOM Level 3:
41866     lookupNamespaceURI:function(prefix){
41867         var el = this;
41868         while(el){
41869                 var map = el._nsMap;
41870                 //console.dir(map)
41871                 if(map){
41872                         if(prefix in map){
41873                                 return map[prefix] ;
41874                         }
41875                 }
41876                 el = el.nodeType == ATTRIBUTE_NODE?el.ownerDocument : el.parentNode;
41877         }
41878         return null;
41879     },
41880     // Introduced in DOM Level 3:
41881     isDefaultNamespace:function(namespaceURI){
41882         var prefix = this.lookupPrefix(namespaceURI);
41883         return prefix == null;
41884     }
41885 };
41886
41887
41888 function _xmlEncoder(c){
41889         return c == '<' && '&lt;' ||
41890          c == '>' && '&gt;' ||
41891          c == '&' && '&amp;' ||
41892          c == '"' && '&quot;' ||
41893          '&#'+c.charCodeAt()+';'
41894 }
41895
41896
41897 copy$1(NodeType,Node$2);
41898 copy$1(NodeType,Node$2.prototype);
41899
41900 /**
41901  * @param callback return true for continue,false for break
41902  * @return boolean true: break visit;
41903  */
41904 function _visitNode(node,callback){
41905         if(callback(node)){
41906                 return true;
41907         }
41908         if(node = node.firstChild){
41909                 do{
41910                         if(_visitNode(node,callback)){return true}
41911         }while(node=node.nextSibling)
41912     }
41913 }
41914
41915
41916
41917 function Document(){
41918 }
41919 function _onAddAttribute(doc,el,newAttr){
41920         doc && doc._inc++;
41921         var ns = newAttr.namespaceURI;
41922         if(ns == 'http://www.w3.org/2000/xmlns/'){
41923                 //update namespace
41924                 el._nsMap[newAttr.prefix?newAttr.localName:''] = newAttr.value;
41925         }
41926 }
41927 function _onRemoveAttribute(doc,el,newAttr,remove){
41928         doc && doc._inc++;
41929         var ns = newAttr.namespaceURI;
41930         if(ns == 'http://www.w3.org/2000/xmlns/'){
41931                 //update namespace
41932                 delete el._nsMap[newAttr.prefix?newAttr.localName:''];
41933         }
41934 }
41935 function _onUpdateChild(doc,el,newChild){
41936         if(doc && doc._inc){
41937                 doc._inc++;
41938                 //update childNodes
41939                 var cs = el.childNodes;
41940                 if(newChild){
41941                         cs[cs.length++] = newChild;
41942                 }else{
41943                         //console.log(1)
41944                         var child = el.firstChild;
41945                         var i = 0;
41946                         while(child){
41947                                 cs[i++] = child;
41948                                 child =child.nextSibling;
41949                         }
41950                         cs.length = i;
41951                 }
41952         }
41953 }
41954
41955 /**
41956  * attributes;
41957  * children;
41958  * 
41959  * writeable properties:
41960  * nodeValue,Attr:value,CharacterData:data
41961  * prefix
41962  */
41963 function _removeChild(parentNode,child){
41964         var previous = child.previousSibling;
41965         var next = child.nextSibling;
41966         if(previous){
41967                 previous.nextSibling = next;
41968         }else{
41969                 parentNode.firstChild = next;
41970         }
41971         if(next){
41972                 next.previousSibling = previous;
41973         }else{
41974                 parentNode.lastChild = previous;
41975         }
41976         _onUpdateChild(parentNode.ownerDocument,parentNode);
41977         return child;
41978 }
41979 /**
41980  * preformance key(refChild == null)
41981  */
41982 function _insertBefore(parentNode,newChild,nextChild){
41983         var cp = newChild.parentNode;
41984         if(cp){
41985                 cp.removeChild(newChild);//remove and update
41986         }
41987         if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
41988                 var newFirst = newChild.firstChild;
41989                 if (newFirst == null) {
41990                         return newChild;
41991                 }
41992                 var newLast = newChild.lastChild;
41993         }else{
41994                 newFirst = newLast = newChild;
41995         }
41996         var pre = nextChild ? nextChild.previousSibling : parentNode.lastChild;
41997
41998         newFirst.previousSibling = pre;
41999         newLast.nextSibling = nextChild;
42000         
42001         
42002         if(pre){
42003                 pre.nextSibling = newFirst;
42004         }else{
42005                 parentNode.firstChild = newFirst;
42006         }
42007         if(nextChild == null){
42008                 parentNode.lastChild = newLast;
42009         }else{
42010                 nextChild.previousSibling = newLast;
42011         }
42012         do{
42013                 newFirst.parentNode = parentNode;
42014         }while(newFirst !== newLast && (newFirst= newFirst.nextSibling))
42015         _onUpdateChild(parentNode.ownerDocument||parentNode,parentNode);
42016         //console.log(parentNode.lastChild.nextSibling == null)
42017         if (newChild.nodeType == DOCUMENT_FRAGMENT_NODE) {
42018                 newChild.firstChild = newChild.lastChild = null;
42019         }
42020         return newChild;
42021 }
42022 function _appendSingleChild(parentNode,newChild){
42023         var cp = newChild.parentNode;
42024         if(cp){
42025                 var pre = parentNode.lastChild;
42026                 cp.removeChild(newChild);//remove and update
42027                 var pre = parentNode.lastChild;
42028         }
42029         var pre = parentNode.lastChild;
42030         newChild.parentNode = parentNode;
42031         newChild.previousSibling = pre;
42032         newChild.nextSibling = null;
42033         if(pre){
42034                 pre.nextSibling = newChild;
42035         }else{
42036                 parentNode.firstChild = newChild;
42037         }
42038         parentNode.lastChild = newChild;
42039         _onUpdateChild(parentNode.ownerDocument,parentNode,newChild);
42040         return newChild;
42041         //console.log("__aa",parentNode.lastChild.nextSibling == null)
42042 }
42043 Document.prototype = {
42044         //implementation : null,
42045         nodeName :  '#document',
42046         nodeType :  DOCUMENT_NODE,
42047         doctype :  null,
42048         documentElement :  null,
42049         _inc : 1,
42050         
42051         insertBefore :  function(newChild, refChild){//raises 
42052                 if(newChild.nodeType == DOCUMENT_FRAGMENT_NODE){
42053                         var child = newChild.firstChild;
42054                         while(child){
42055                                 var next = child.nextSibling;
42056                                 this.insertBefore(child,refChild);
42057                                 child = next;
42058                         }
42059                         return newChild;
42060                 }
42061                 if(this.documentElement == null && newChild.nodeType == ELEMENT_NODE){
42062                         this.documentElement = newChild;
42063                 }
42064                 
42065                 return _insertBefore(this,newChild,refChild), newChild.ownerDocument = this, newChild;
42066         },
42067         removeChild :  function(oldChild){
42068                 if(this.documentElement == oldChild){
42069                         this.documentElement = null;
42070                 }
42071                 return _removeChild(this,oldChild);
42072         },
42073         // Introduced in DOM Level 2:
42074         importNode : function(importedNode,deep){
42075                 return importNode(this,importedNode,deep);
42076         },
42077         // Introduced in DOM Level 2:
42078         getElementById :        function(id){
42079                 var rtv = null;
42080                 _visitNode(this.documentElement,function(node){
42081                         if(node.nodeType == ELEMENT_NODE){
42082                                 if(node.getAttribute('id') == id){
42083                                         rtv = node;
42084                                         return true;
42085                                 }
42086                         }
42087                 });
42088                 return rtv;
42089         },
42090         
42091         //document factory method:
42092         createElement : function(tagName){
42093                 var node = new Element();
42094                 node.ownerDocument = this;
42095                 node.nodeName = tagName;
42096                 node.tagName = tagName;
42097                 node.childNodes = new NodeList();
42098                 var attrs       = node.attributes = new NamedNodeMap();
42099                 attrs._ownerElement = node;
42100                 return node;
42101         },
42102         createDocumentFragment :        function(){
42103                 var node = new DocumentFragment();
42104                 node.ownerDocument = this;
42105                 node.childNodes = new NodeList();
42106                 return node;
42107         },
42108         createTextNode :        function(data){
42109                 var node = new Text();
42110                 node.ownerDocument = this;
42111                 node.appendData(data);
42112                 return node;
42113         },
42114         createComment : function(data){
42115                 var node = new Comment();
42116                 node.ownerDocument = this;
42117                 node.appendData(data);
42118                 return node;
42119         },
42120         createCDATASection :    function(data){
42121                 var node = new CDATASection();
42122                 node.ownerDocument = this;
42123                 node.appendData(data);
42124                 return node;
42125         },
42126         createProcessingInstruction :   function(target,data){
42127                 var node = new ProcessingInstruction();
42128                 node.ownerDocument = this;
42129                 node.tagName = node.target = target;
42130                 node.nodeValue= node.data = data;
42131                 return node;
42132         },
42133         createAttribute :       function(name){
42134                 var node = new Attr();
42135                 node.ownerDocument      = this;
42136                 node.name = name;
42137                 node.nodeName   = name;
42138                 node.localName = name;
42139                 node.specified = true;
42140                 return node;
42141         },
42142         createEntityReference : function(name){
42143                 var node = new EntityReference();
42144                 node.ownerDocument      = this;
42145                 node.nodeName   = name;
42146                 return node;
42147         },
42148         // Introduced in DOM Level 2:
42149         createElementNS :       function(namespaceURI,qualifiedName){
42150                 var node = new Element();
42151                 var pl = qualifiedName.split(':');
42152                 var attrs       = node.attributes = new NamedNodeMap();
42153                 node.childNodes = new NodeList();
42154                 node.ownerDocument = this;
42155                 node.nodeName = qualifiedName;
42156                 node.tagName = qualifiedName;
42157                 node.namespaceURI = namespaceURI;
42158                 if(pl.length == 2){
42159                         node.prefix = pl[0];
42160                         node.localName = pl[1];
42161                 }else{
42162                         //el.prefix = null;
42163                         node.localName = qualifiedName;
42164                 }
42165                 attrs._ownerElement = node;
42166                 return node;
42167         },
42168         // Introduced in DOM Level 2:
42169         createAttributeNS :     function(namespaceURI,qualifiedName){
42170                 var node = new Attr();
42171                 var pl = qualifiedName.split(':');
42172                 node.ownerDocument = this;
42173                 node.nodeName = qualifiedName;
42174                 node.name = qualifiedName;
42175                 node.namespaceURI = namespaceURI;
42176                 node.specified = true;
42177                 if(pl.length == 2){
42178                         node.prefix = pl[0];
42179                         node.localName = pl[1];
42180                 }else{
42181                         //el.prefix = null;
42182                         node.localName = qualifiedName;
42183                 }
42184                 return node;
42185         }
42186 };
42187 _extends(Document,Node$2);
42188
42189
42190 function Element() {
42191         this._nsMap = {};
42192 }
42193 Element.prototype = {
42194         nodeType : ELEMENT_NODE,
42195         hasAttribute : function(name){
42196                 return this.getAttributeNode(name)!=null;
42197         },
42198         getAttribute : function(name){
42199                 var attr = this.getAttributeNode(name);
42200                 return attr && attr.value || '';
42201         },
42202         getAttributeNode : function(name){
42203                 return this.attributes.getNamedItem(name);
42204         },
42205         setAttribute : function(name, value){
42206                 var attr = this.ownerDocument.createAttribute(name);
42207                 attr.value = attr.nodeValue = "" + value;
42208                 this.setAttributeNode(attr);
42209         },
42210         removeAttribute : function(name){
42211                 var attr = this.getAttributeNode(name);
42212                 attr && this.removeAttributeNode(attr);
42213         },
42214         
42215         //four real opeartion method
42216         appendChild:function(newChild){
42217                 if(newChild.nodeType === DOCUMENT_FRAGMENT_NODE){
42218                         return this.insertBefore(newChild,null);
42219                 }else{
42220                         return _appendSingleChild(this,newChild);
42221                 }
42222         },
42223         setAttributeNode : function(newAttr){
42224                 return this.attributes.setNamedItem(newAttr);
42225         },
42226         setAttributeNodeNS : function(newAttr){
42227                 return this.attributes.setNamedItemNS(newAttr);
42228         },
42229         removeAttributeNode : function(oldAttr){
42230                 //console.log(this == oldAttr.ownerElement)
42231                 return this.attributes.removeNamedItem(oldAttr.nodeName);
42232         },
42233         //get real attribute name,and remove it by removeAttributeNode
42234         removeAttributeNS : function(namespaceURI, localName){
42235                 var old = this.getAttributeNodeNS(namespaceURI, localName);
42236                 old && this.removeAttributeNode(old);
42237         },
42238         
42239         hasAttributeNS : function(namespaceURI, localName){
42240                 return this.getAttributeNodeNS(namespaceURI, localName)!=null;
42241         },
42242         getAttributeNS : function(namespaceURI, localName){
42243                 var attr = this.getAttributeNodeNS(namespaceURI, localName);
42244                 return attr && attr.value || '';
42245         },
42246         setAttributeNS : function(namespaceURI, qualifiedName, value){
42247                 var attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
42248                 attr.value = attr.nodeValue = "" + value;
42249                 this.setAttributeNode(attr);
42250         },
42251         getAttributeNodeNS : function(namespaceURI, localName){
42252                 return this.attributes.getNamedItemNS(namespaceURI, localName);
42253         },
42254         
42255         getElementsByTagName : function(tagName){
42256                 return new LiveNodeList(this,function(base){
42257                         var ls = [];
42258                         _visitNode(base,function(node){
42259                                 if(node !== base && node.nodeType == ELEMENT_NODE && (tagName === '*' || node.tagName == tagName)){
42260                                         ls.push(node);
42261                                 }
42262                         });
42263                         return ls;
42264                 });
42265         },
42266         getElementsByTagNameNS : function(namespaceURI, localName){
42267                 return new LiveNodeList(this,function(base){
42268                         var ls = [];
42269                         _visitNode(base,function(node){
42270                                 if(node !== base && node.nodeType === ELEMENT_NODE && (namespaceURI === '*' || node.namespaceURI === namespaceURI) && (localName === '*' || node.localName == localName)){
42271                                         ls.push(node);
42272                                 }
42273                         });
42274                         return ls;
42275                         
42276                 });
42277         }
42278 };
42279 Document.prototype.getElementsByTagName = Element.prototype.getElementsByTagName;
42280 Document.prototype.getElementsByTagNameNS = Element.prototype.getElementsByTagNameNS;
42281
42282
42283 _extends(Element,Node$2);
42284 function Attr() {
42285 }
42286 Attr.prototype.nodeType = ATTRIBUTE_NODE;
42287 _extends(Attr,Node$2);
42288
42289
42290 function CharacterData() {
42291 }
42292 CharacterData.prototype = {
42293         data : '',
42294         substringData : function(offset, count) {
42295                 return this.data.substring(offset, offset+count);
42296         },
42297         appendData: function(text) {
42298                 text = this.data+text;
42299                 this.nodeValue = this.data = text;
42300                 this.length = text.length;
42301         },
42302         insertData: function(offset,text) {
42303                 this.replaceData(offset,0,text);
42304         
42305         },
42306         appendChild:function(newChild){
42307                 throw new Error(ExceptionMessage[HIERARCHY_REQUEST_ERR])
42308         },
42309         deleteData: function(offset, count) {
42310                 this.replaceData(offset,count,"");
42311         },
42312         replaceData: function(offset, count, text) {
42313                 var start = this.data.substring(0,offset);
42314                 var end = this.data.substring(offset+count);
42315                 text = start + text + end;
42316                 this.nodeValue = this.data = text;
42317                 this.length = text.length;
42318         }
42319 };
42320 _extends(CharacterData,Node$2);
42321 function Text() {
42322 }
42323 Text.prototype = {
42324         nodeName : "#text",
42325         nodeType : TEXT_NODE,
42326         splitText : function(offset) {
42327                 var text = this.data;
42328                 var newText = text.substring(offset);
42329                 text = text.substring(0, offset);
42330                 this.data = this.nodeValue = text;
42331                 this.length = text.length;
42332                 var newNode = this.ownerDocument.createTextNode(newText);
42333                 if(this.parentNode){
42334                         this.parentNode.insertBefore(newNode, this.nextSibling);
42335                 }
42336                 return newNode;
42337         }
42338 };
42339 _extends(Text,CharacterData);
42340 function Comment() {
42341 }
42342 Comment.prototype = {
42343         nodeName : "#comment",
42344         nodeType : COMMENT_NODE
42345 };
42346 _extends(Comment,CharacterData);
42347
42348 function CDATASection() {
42349 }
42350 CDATASection.prototype = {
42351         nodeName : "#cdata-section",
42352         nodeType : CDATA_SECTION_NODE
42353 };
42354 _extends(CDATASection,CharacterData);
42355
42356
42357 function DocumentType() {
42358 }
42359 DocumentType.prototype.nodeType = DOCUMENT_TYPE_NODE;
42360 _extends(DocumentType,Node$2);
42361
42362 function Notation() {
42363 }
42364 Notation.prototype.nodeType = NOTATION_NODE;
42365 _extends(Notation,Node$2);
42366
42367 function Entity() {
42368 }
42369 Entity.prototype.nodeType = ENTITY_NODE;
42370 _extends(Entity,Node$2);
42371
42372 function EntityReference() {
42373 }
42374 EntityReference.prototype.nodeType = ENTITY_REFERENCE_NODE;
42375 _extends(EntityReference,Node$2);
42376
42377 function DocumentFragment() {
42378 }
42379 DocumentFragment.prototype.nodeName =   "#document-fragment";
42380 DocumentFragment.prototype.nodeType =   DOCUMENT_FRAGMENT_NODE;
42381 _extends(DocumentFragment,Node$2);
42382
42383
42384 function ProcessingInstruction() {
42385 }
42386 ProcessingInstruction.prototype.nodeType = PROCESSING_INSTRUCTION_NODE;
42387 _extends(ProcessingInstruction,Node$2);
42388 function XMLSerializer$1(){}
42389 XMLSerializer$1.prototype.serializeToString = function(node,isHtml,nodeFilter){
42390         return nodeSerializeToString.call(node,isHtml,nodeFilter);
42391 };
42392 Node$2.prototype.toString = nodeSerializeToString;
42393 function nodeSerializeToString(isHtml,nodeFilter){
42394         var buf = [];
42395         var refNode = this.nodeType == 9?this.documentElement:this;
42396         var prefix = refNode.prefix;
42397         var uri = refNode.namespaceURI;
42398         
42399         if(uri && prefix == null){
42400                 //console.log(prefix)
42401                 var prefix = refNode.lookupPrefix(uri);
42402                 if(prefix == null){
42403                         //isHTML = true;
42404                         var visibleNamespaces=[
42405                         {namespace:uri,prefix:null}
42406                         //{namespace:uri,prefix:''}
42407                         ];
42408                 }
42409         }
42410         serializeToString(this,buf,isHtml,nodeFilter,visibleNamespaces);
42411         //console.log('###',this.nodeType,uri,prefix,buf.join(''))
42412         return buf.join('');
42413 }
42414 function needNamespaceDefine(node,isHTML, visibleNamespaces) {
42415         var prefix = node.prefix||'';
42416         var uri = node.namespaceURI;
42417         if (!prefix && !uri){
42418                 return false;
42419         }
42420         if (prefix === "xml" && uri === "http://www.w3.org/XML/1998/namespace" 
42421                 || uri == 'http://www.w3.org/2000/xmlns/'){
42422                 return false;
42423         }
42424         
42425         var i = visibleNamespaces.length; 
42426         //console.log('@@@@',node.tagName,prefix,uri,visibleNamespaces)
42427         while (i--) {
42428                 var ns = visibleNamespaces[i];
42429                 // get namespace prefix
42430                 //console.log(node.nodeType,node.tagName,ns.prefix,prefix)
42431                 if (ns.prefix == prefix){
42432                         return ns.namespace != uri;
42433                 }
42434         }
42435         //console.log(isHTML,uri,prefix=='')
42436         //if(isHTML && prefix ==null && uri == 'http://www.w3.org/1999/xhtml'){
42437         //      return false;
42438         //}
42439         //node.flag = '11111'
42440         //console.error(3,true,node.flag,node.prefix,node.namespaceURI)
42441         return true;
42442 }
42443 function serializeToString(node,buf,isHTML,nodeFilter,visibleNamespaces){
42444         if(nodeFilter){
42445                 node = nodeFilter(node);
42446                 if(node){
42447                         if(typeof node == 'string'){
42448                                 buf.push(node);
42449                                 return;
42450                         }
42451                 }else{
42452                         return;
42453                 }
42454                 //buf.sort.apply(attrs, attributeSorter);
42455         }
42456         switch(node.nodeType){
42457         case ELEMENT_NODE:
42458                 if (!visibleNamespaces) visibleNamespaces = [];
42459                 var startVisibleNamespaces = visibleNamespaces.length;
42460                 var attrs = node.attributes;
42461                 var len = attrs.length;
42462                 var child = node.firstChild;
42463                 var nodeName = node.tagName;
42464                 
42465                 isHTML =  (htmlns === node.namespaceURI) ||isHTML; 
42466                 buf.push('<',nodeName);
42467                 
42468                 
42469                 
42470                 for(var i=0;i<len;i++){
42471                         // add namespaces for attributes
42472                         var attr = attrs.item(i);
42473                         if (attr.prefix == 'xmlns') {
42474                                 visibleNamespaces.push({ prefix: attr.localName, namespace: attr.value });
42475                         }else if(attr.nodeName == 'xmlns'){
42476                                 visibleNamespaces.push({ prefix: '', namespace: attr.value });
42477                         }
42478                 }
42479                 for(var i=0;i<len;i++){
42480                         var attr = attrs.item(i);
42481                         if (needNamespaceDefine(attr,isHTML, visibleNamespaces)) {
42482                                 var prefix = attr.prefix||'';
42483                                 var uri = attr.namespaceURI;
42484                                 var ns = prefix ? ' xmlns:' + prefix : " xmlns";
42485                                 buf.push(ns, '="' , uri , '"');
42486                                 visibleNamespaces.push({ prefix: prefix, namespace:uri });
42487                         }
42488                         serializeToString(attr,buf,isHTML,nodeFilter,visibleNamespaces);
42489                 }
42490                 // add namespace for current node               
42491                 if (needNamespaceDefine(node,isHTML, visibleNamespaces)) {
42492                         var prefix = node.prefix||'';
42493                         var uri = node.namespaceURI;
42494                         var ns = prefix ? ' xmlns:' + prefix : " xmlns";
42495                         buf.push(ns, '="' , uri , '"');
42496                         visibleNamespaces.push({ prefix: prefix, namespace:uri });
42497                 }
42498                 
42499                 if(child || isHTML && !/^(?:meta|link|img|br|hr|input)$/i.test(nodeName)){
42500                         buf.push('>');
42501                         //if is cdata child node
42502                         if(isHTML && /^script$/i.test(nodeName)){
42503                                 while(child){
42504                                         if(child.data){
42505                                                 buf.push(child.data);
42506                                         }else{
42507                                                 serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces);
42508                                         }
42509                                         child = child.nextSibling;
42510                                 }
42511                         }else
42512                         {
42513                                 while(child){
42514                                         serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces);
42515                                         child = child.nextSibling;
42516                                 }
42517                         }
42518                         buf.push('</',nodeName,'>');
42519                 }else{
42520                         buf.push('/>');
42521                 }
42522                 // remove added visible namespaces
42523                 //visibleNamespaces.length = startVisibleNamespaces;
42524                 return;
42525         case DOCUMENT_NODE:
42526         case DOCUMENT_FRAGMENT_NODE:
42527                 var child = node.firstChild;
42528                 while(child){
42529                         serializeToString(child,buf,isHTML,nodeFilter,visibleNamespaces);
42530                         child = child.nextSibling;
42531                 }
42532                 return;
42533         case ATTRIBUTE_NODE:
42534                 return buf.push(' ',node.name,'="',node.value.replace(/[<&"]/g,_xmlEncoder),'"');
42535         case TEXT_NODE:
42536                 return buf.push(node.data.replace(/[<&]/g,_xmlEncoder));
42537         case CDATA_SECTION_NODE:
42538                 return buf.push( '<![CDATA[',node.data,']]>');
42539         case COMMENT_NODE:
42540                 return buf.push( "<!--",node.data,"-->");
42541         case DOCUMENT_TYPE_NODE:
42542                 var pubid = node.publicId;
42543                 var sysid = node.systemId;
42544                 buf.push('<!DOCTYPE ',node.name);
42545                 if(pubid){
42546                         buf.push(' PUBLIC "',pubid);
42547                         if (sysid && sysid!='.') {
42548                                 buf.push( '" "',sysid);
42549                         }
42550                         buf.push('">');
42551                 }else if(sysid && sysid!='.'){
42552                         buf.push(' SYSTEM "',sysid,'">');
42553                 }else{
42554                         var sub = node.internalSubset;
42555                         if(sub){
42556                                 buf.push(" [",sub,"]");
42557                         }
42558                         buf.push(">");
42559                 }
42560                 return;
42561         case PROCESSING_INSTRUCTION_NODE:
42562                 return buf.push( "<?",node.target," ",node.data,"?>");
42563         case ENTITY_REFERENCE_NODE:
42564                 return buf.push( '&',node.nodeName,';');
42565         //case ENTITY_NODE:
42566         //case NOTATION_NODE:
42567         default:
42568                 buf.push('??',node.nodeName);
42569         }
42570 }
42571 function importNode(doc,node,deep){
42572         var node2;
42573         switch (node.nodeType) {
42574         case ELEMENT_NODE:
42575                 node2 = node.cloneNode(false);
42576                 node2.ownerDocument = doc;
42577                 //var attrs = node2.attributes;
42578                 //var len = attrs.length;
42579                 //for(var i=0;i<len;i++){
42580                         //node2.setAttributeNodeNS(importNode(doc,attrs.item(i),deep));
42581                 //}
42582         case DOCUMENT_FRAGMENT_NODE:
42583                 break;
42584         case ATTRIBUTE_NODE:
42585                 deep = true;
42586                 break;
42587         //case ENTITY_REFERENCE_NODE:
42588         //case PROCESSING_INSTRUCTION_NODE:
42589         ////case TEXT_NODE:
42590         //case CDATA_SECTION_NODE:
42591         //case COMMENT_NODE:
42592         //      deep = false;
42593         //      break;
42594         //case DOCUMENT_NODE:
42595         //case DOCUMENT_TYPE_NODE:
42596         //cannot be imported.
42597         //case ENTITY_NODE:
42598         //case NOTATION_NODE:
42599         //can not hit in level3
42600         //default:throw e;
42601         }
42602         if(!node2){
42603                 node2 = node.cloneNode(false);//false
42604         }
42605         node2.ownerDocument = doc;
42606         node2.parentNode = null;
42607         if(deep){
42608                 var child = node.firstChild;
42609                 while(child){
42610                         node2.appendChild(importNode(doc,child,deep));
42611                         child = child.nextSibling;
42612                 }
42613         }
42614         return node2;
42615 }
42616 //
42617 //var _relationMap = {firstChild:1,lastChild:1,previousSibling:1,nextSibling:1,
42618 //                                      attributes:1,childNodes:1,parentNode:1,documentElement:1,doctype,};
42619 function cloneNode(doc,node,deep){
42620         var node2 = new node.constructor();
42621         for(var n in node){
42622                 var v = node[n];
42623                 if(typeof v != 'object' ){
42624                         if(v != node2[n]){
42625                                 node2[n] = v;
42626                         }
42627                 }
42628         }
42629         if(node.childNodes){
42630                 node2.childNodes = new NodeList();
42631         }
42632         node2.ownerDocument = doc;
42633         switch (node2.nodeType) {
42634         case ELEMENT_NODE:
42635                 var attrs       = node.attributes;
42636                 var attrs2      = node2.attributes = new NamedNodeMap();
42637                 var len = attrs.length;
42638                 attrs2._ownerElement = node2;
42639                 for(var i=0;i<len;i++){
42640                         node2.setAttributeNode(cloneNode(doc,attrs.item(i),true));
42641                 }
42642                 break;;
42643         case ATTRIBUTE_NODE:
42644                 deep = true;
42645         }
42646         if(deep){
42647                 var child = node.firstChild;
42648                 while(child){
42649                         node2.appendChild(cloneNode(doc,child,deep));
42650                         child = child.nextSibling;
42651                 }
42652         }
42653         return node2;
42654 }
42655
42656 function __set__(object,key,value){
42657         object[key] = value;
42658 }
42659 //do dynamic
42660 try{
42661         if(Object.defineProperty){
42662                 Object.defineProperty(LiveNodeList.prototype,'length',{
42663                         get:function(){
42664                                 _updateLiveList(this);
42665                                 return this.$$length;
42666                         }
42667                 });
42668                 Object.defineProperty(Node$2.prototype,'textContent',{
42669                         get:function(){
42670                                 return getTextContent(this);
42671                         },
42672                         set:function(data){
42673                                 switch(this.nodeType){
42674                                 case ELEMENT_NODE:
42675                                 case DOCUMENT_FRAGMENT_NODE:
42676                                         while(this.firstChild){
42677                                                 this.removeChild(this.firstChild);
42678                                         }
42679                                         if(data || String(data)){
42680                                                 this.appendChild(this.ownerDocument.createTextNode(data));
42681                                         }
42682                                         break;
42683                                 default:
42684                                         //TODO:
42685                                         this.data = data;
42686                                         this.value = data;
42687                                         this.nodeValue = data;
42688                                 }
42689                         }
42690                 });
42691                 
42692                 function getTextContent(node){
42693                         switch(node.nodeType){
42694                         case ELEMENT_NODE:
42695                         case DOCUMENT_FRAGMENT_NODE:
42696                                 var buf = [];
42697                                 node = node.firstChild;
42698                                 while(node){
42699                                         if(node.nodeType!==7 && node.nodeType !==8){
42700                                                 buf.push(getTextContent(node));
42701                                         }
42702                                         node = node.nextSibling;
42703                                 }
42704                                 return buf.join('');
42705                         default:
42706                                 return node.nodeValue;
42707                         }
42708                 }
42709                 __set__ = function(object,key,value){
42710                         //console.log(value)
42711                         object['$$'+key] = value;
42712                 };
42713         }
42714 }catch(e){//ie8
42715 }
42716
42717 //if(typeof require == 'function'){
42718         var DOMImplementation_1 = DOMImplementation;
42719         var XMLSerializer_1 = XMLSerializer$1;
42720 //}
42721
42722 var dom = {
42723         DOMImplementation: DOMImplementation_1,
42724         XMLSerializer: XMLSerializer_1
42725 };
42726
42727 var domParser = createCommonjsModule(function (module, exports) {
42728 function DOMParser(options){
42729         this.options = options ||{locator:{}};
42730         
42731 }
42732 DOMParser.prototype.parseFromString = function(source,mimeType){
42733         var options = this.options;
42734         var sax$$1 =  new XMLReader();
42735         var domBuilder = options.domBuilder || new DOMHandler();//contentHandler and LexicalHandler
42736         var errorHandler = options.errorHandler;
42737         var locator = options.locator;
42738         var defaultNSMap = options.xmlns||{};
42739         var entityMap = {'lt':'<','gt':'>','amp':'&','quot':'"','apos':"'"};
42740         if(locator){
42741                 domBuilder.setDocumentLocator(locator);
42742         }
42743         
42744         sax$$1.errorHandler = buildErrorHandler(errorHandler,domBuilder,locator);
42745         sax$$1.domBuilder = options.domBuilder || domBuilder;
42746         if(/\/x?html?$/.test(mimeType)){
42747                 entityMap.nbsp = '\xa0';
42748                 entityMap.copy = '\xa9';
42749                 defaultNSMap['']= 'http://www.w3.org/1999/xhtml';
42750         }
42751         defaultNSMap.xml = defaultNSMap.xml || 'http://www.w3.org/XML/1998/namespace';
42752         if(source){
42753                 sax$$1.parse(source,defaultNSMap,entityMap);
42754         }else{
42755                 sax$$1.errorHandler.error("invalid doc source");
42756         }
42757         return domBuilder.doc;
42758 };
42759 function buildErrorHandler(errorImpl,domBuilder,locator){
42760         if(!errorImpl){
42761                 if(domBuilder instanceof DOMHandler){
42762                         return domBuilder;
42763                 }
42764                 errorImpl = domBuilder ;
42765         }
42766         var errorHandler = {};
42767         var isCallback = errorImpl instanceof Function;
42768         locator = locator||{};
42769         function build(key){
42770                 var fn = errorImpl[key];
42771                 if(!fn && isCallback){
42772                         fn = errorImpl.length == 2?function(msg){errorImpl(key,msg);}:errorImpl;
42773                 }
42774                 errorHandler[key] = fn && function(msg){
42775                         fn('[xmldom '+key+']\t'+msg+_locator(locator));
42776                 }||function(){};
42777         }
42778         build('warning');
42779         build('error');
42780         build('fatalError');
42781         return errorHandler;
42782 }
42783
42784 //console.log('#\n\n\n\n\n\n\n####')
42785 /**
42786  * +ContentHandler+ErrorHandler
42787  * +LexicalHandler+EntityResolver2
42788  * -DeclHandler-DTDHandler 
42789  * 
42790  * DefaultHandler:EntityResolver, DTDHandler, ContentHandler, ErrorHandler
42791  * DefaultHandler2:DefaultHandler,LexicalHandler, DeclHandler, EntityResolver2
42792  * @link http://www.saxproject.org/apidoc/org/xml/sax/helpers/DefaultHandler.html
42793  */
42794 function DOMHandler() {
42795     this.cdata = false;
42796 }
42797 function position(locator,node){
42798         node.lineNumber = locator.lineNumber;
42799         node.columnNumber = locator.columnNumber;
42800 }
42801 /**
42802  * @see org.xml.sax.ContentHandler#startDocument
42803  * @link http://www.saxproject.org/apidoc/org/xml/sax/ContentHandler.html
42804  */ 
42805 DOMHandler.prototype = {
42806         startDocument : function() {
42807         this.doc = new DOMImplementation().createDocument(null, null, null);
42808         if (this.locator) {
42809                 this.doc.documentURI = this.locator.systemId;
42810         }
42811         },
42812         startElement:function(namespaceURI, localName, qName, attrs) {
42813                 var doc = this.doc;
42814             var el = doc.createElementNS(namespaceURI, qName||localName);
42815             var len = attrs.length;
42816             appendElement(this, el);
42817             this.currentElement = el;
42818             
42819                 this.locator && position(this.locator,el);
42820             for (var i = 0 ; i < len; i++) {
42821                 var namespaceURI = attrs.getURI(i);
42822                 var value = attrs.getValue(i);
42823                 var qName = attrs.getQName(i);
42824                         var attr = doc.createAttributeNS(namespaceURI, qName);
42825                         this.locator &&position(attrs.getLocator(i),attr);
42826                         attr.value = attr.nodeValue = value;
42827                         el.setAttributeNode(attr);
42828             }
42829         },
42830         endElement:function(namespaceURI, localName, qName) {
42831                 var current = this.currentElement;
42832                 var tagName = current.tagName;
42833                 this.currentElement = current.parentNode;
42834         },
42835         startPrefixMapping:function(prefix, uri) {
42836         },
42837         endPrefixMapping:function(prefix) {
42838         },
42839         processingInstruction:function(target, data) {
42840             var ins = this.doc.createProcessingInstruction(target, data);
42841             this.locator && position(this.locator,ins);
42842             appendElement(this, ins);
42843         },
42844         ignorableWhitespace:function(ch, start, length) {
42845         },
42846         characters:function(chars, start, length) {
42847                 chars = _toString.apply(this,arguments);
42848                 //console.log(chars)
42849                 if(chars){
42850                         if (this.cdata) {
42851                                 var charNode = this.doc.createCDATASection(chars);
42852                         } else {
42853                                 var charNode = this.doc.createTextNode(chars);
42854                         }
42855                         if(this.currentElement){
42856                                 this.currentElement.appendChild(charNode);
42857                         }else if(/^\s*$/.test(chars)){
42858                                 this.doc.appendChild(charNode);
42859                                 //process xml
42860                         }
42861                         this.locator && position(this.locator,charNode);
42862                 }
42863         },
42864         skippedEntity:function(name) {
42865         },
42866         endDocument:function() {
42867                 this.doc.normalize();
42868         },
42869         setDocumentLocator:function (locator) {
42870             if(this.locator = locator){// && !('lineNumber' in locator)){
42871                 locator.lineNumber = 0;
42872             }
42873         },
42874         //LexicalHandler
42875         comment:function(chars, start, length) {
42876                 chars = _toString.apply(this,arguments);
42877             var comm = this.doc.createComment(chars);
42878             this.locator && position(this.locator,comm);
42879             appendElement(this, comm);
42880         },
42881         
42882         startCDATA:function() {
42883             //used in characters() methods
42884             this.cdata = true;
42885         },
42886         endCDATA:function() {
42887             this.cdata = false;
42888         },
42889         
42890         startDTD:function(name, publicId, systemId) {
42891                 var impl = this.doc.implementation;
42892             if (impl && impl.createDocumentType) {
42893                 var dt = impl.createDocumentType(name, publicId, systemId);
42894                 this.locator && position(this.locator,dt);
42895                 appendElement(this, dt);
42896             }
42897         },
42898         /**
42899          * @see org.xml.sax.ErrorHandler
42900          * @link http://www.saxproject.org/apidoc/org/xml/sax/ErrorHandler.html
42901          */
42902         warning:function(error) {
42903                 console.warn('[xmldom warning]\t'+error,_locator(this.locator));
42904         },
42905         error:function(error) {
42906                 console.error('[xmldom error]\t'+error,_locator(this.locator));
42907         },
42908         fatalError:function(error) {
42909                 console.error('[xmldom fatalError]\t'+error,_locator(this.locator));
42910             throw error;
42911         }
42912 };
42913 function _locator(l){
42914         if(l){
42915                 return '\n@'+(l.systemId ||'')+'#[line:'+l.lineNumber+',col:'+l.columnNumber+']'
42916         }
42917 }
42918 function _toString(chars,start,length){
42919         if(typeof chars == 'string'){
42920                 return chars.substr(start,length)
42921         }else{//java sax connect width xmldom on rhino(what about: "? && !(chars instanceof String)")
42922                 if(chars.length >= start+length || start){
42923                         return new java.lang.String(chars,start,length)+'';
42924                 }
42925                 return chars;
42926         }
42927 }
42928
42929 /*
42930  * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/LexicalHandler.html
42931  * used method of org.xml.sax.ext.LexicalHandler:
42932  *  #comment(chars, start, length)
42933  *  #startCDATA()
42934  *  #endCDATA()
42935  *  #startDTD(name, publicId, systemId)
42936  *
42937  *
42938  * IGNORED method of org.xml.sax.ext.LexicalHandler:
42939  *  #endDTD()
42940  *  #startEntity(name)
42941  *  #endEntity(name)
42942  *
42943  *
42944  * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/DeclHandler.html
42945  * IGNORED method of org.xml.sax.ext.DeclHandler
42946  *      #attributeDecl(eName, aName, type, mode, value)
42947  *  #elementDecl(name, model)
42948  *  #externalEntityDecl(name, publicId, systemId)
42949  *  #internalEntityDecl(name, value)
42950  * @link http://www.saxproject.org/apidoc/org/xml/sax/ext/EntityResolver2.html
42951  * IGNORED method of org.xml.sax.EntityResolver2
42952  *  #resolveEntity(String name,String publicId,String baseURI,String systemId)
42953  *  #resolveEntity(publicId, systemId)
42954  *  #getExternalSubset(name, baseURI)
42955  * @link http://www.saxproject.org/apidoc/org/xml/sax/DTDHandler.html
42956  * IGNORED method of org.xml.sax.DTDHandler
42957  *  #notationDecl(name, publicId, systemId) {};
42958  *  #unparsedEntityDecl(name, publicId, systemId, notationName) {};
42959  */
42960 "endDTD,startEntity,endEntity,attributeDecl,elementDecl,externalEntityDecl,internalEntityDecl,resolveEntity,getExternalSubset,notationDecl,unparsedEntityDecl".replace(/\w+/g,function(key){
42961         DOMHandler.prototype[key] = function(){return null};
42962 });
42963
42964 /* 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 */
42965 function appendElement (hander,node) {
42966     if (!hander.currentElement) {
42967         hander.doc.appendChild(node);
42968     } else {
42969         hander.currentElement.appendChild(node);
42970     }
42971 }//appendChild and setAttributeNS are preformance key
42972
42973 //if(typeof require == 'function'){
42974         var XMLReader = sax.XMLReader;
42975         var DOMImplementation = exports.DOMImplementation = dom.DOMImplementation;
42976         exports.XMLSerializer = dom.XMLSerializer ;
42977         exports.DOMParser = DOMParser;
42978 //}
42979 });
42980
42981 var domParser_1 = domParser.DOMImplementation;
42982 var domParser_2 = domParser.XMLSerializer;
42983 var domParser_3 = domParser.DOMParser;
42984
42985 var togeojson = createCommonjsModule(function (module, exports) {
42986 var toGeoJSON = (function() {
42987     var removeSpace = /\s*/g,
42988         trimSpace = /^\s*|\s*$/g,
42989         splitSpace = /\s+/;
42990     // generate a short, numeric hash of a string
42991     function okhash(x) {
42992         if (!x || !x.length) return 0;
42993         for (var i = 0, h = 0; i < x.length; i++) {
42994             h = ((h << 5) - h) + x.charCodeAt(i) | 0;
42995         } return h;
42996     }
42997     // all Y children of X
42998     function get(x, y) { return x.getElementsByTagName(y); }
42999     function attr(x, y) { return x.getAttribute(y); }
43000     function attrf(x, y) { return parseFloat(attr(x, y)); }
43001     // one Y child of X, if any, otherwise null
43002     function get1(x, y) { var n = get(x, y); return n.length ? n[0] : null; }
43003     // https://developer.mozilla.org/en-US/docs/Web/API/Node.normalize
43004     function norm(el) { if (el.normalize) { el.normalize(); } return el; }
43005     // cast array x into numbers
43006     function numarray(x) {
43007         for (var j = 0, o = []; j < x.length; j++) { o[j] = parseFloat(x[j]); }
43008         return o;
43009     }
43010     // get the content of a text node, if any
43011     function nodeVal(x) {
43012         if (x) { norm(x); }
43013         return (x && x.textContent) || '';
43014     }
43015     // get the contents of multiple text nodes, if present
43016     function getMulti(x, ys) {
43017         var o = {}, n, k;
43018         for (k = 0; k < ys.length; k++) {
43019             n = get1(x, ys[k]);
43020             if (n) o[ys[k]] = nodeVal(n);
43021         }
43022         return o;
43023     }
43024     // add properties of Y to X, overwriting if present in both
43025     function extend(x, y) { for (var k in y) x[k] = y[k]; }
43026     // get one coordinate from a coordinate array, if any
43027     function coord1(v) { return numarray(v.replace(removeSpace, '').split(',')); }
43028     // get all coordinates from a coordinate array as [[],[]]
43029     function coord(v) {
43030         var coords = v.replace(trimSpace, '').split(splitSpace),
43031             o = [];
43032         for (var i = 0; i < coords.length; i++) {
43033             o.push(coord1(coords[i]));
43034         }
43035         return o;
43036     }
43037     function coordPair(x) {
43038         var ll = [attrf(x, 'lon'), attrf(x, 'lat')],
43039             ele = get1(x, 'ele'),
43040             // handle namespaced attribute in browser
43041             heartRate = get1(x, 'gpxtpx:hr') || get1(x, 'hr'),
43042             time = get1(x, 'time'),
43043             e;
43044         if (ele) {
43045             e = parseFloat(nodeVal(ele));
43046             if (!isNaN(e)) {
43047                 ll.push(e);
43048             }
43049         }
43050         return {
43051             coordinates: ll,
43052             time: time ? nodeVal(time) : null,
43053             heartRate: heartRate ? parseFloat(nodeVal(heartRate)) : null
43054         };
43055     }
43056
43057     // create a new feature collection parent object
43058     function fc() {
43059         return {
43060             type: 'FeatureCollection',
43061             features: []
43062         };
43063     }
43064
43065     var serializer;
43066     if (typeof XMLSerializer !== 'undefined') {
43067         /* istanbul ignore next */
43068         serializer = new XMLSerializer();
43069     // only require xmldom in a node environment
43070     } else if ('object' === 'object' && typeof process === 'object' && !process.browser) {
43071         serializer = new (domParser.XMLSerializer)();
43072     }
43073     function xml2str(str) {
43074         // IE9 will create a new XMLSerializer but it'll crash immediately.
43075         // This line is ignored because we don't run coverage tests in IE9
43076         /* istanbul ignore next */
43077         if (str.xml !== undefined) return str.xml;
43078         return serializer.serializeToString(str);
43079     }
43080
43081     var t = {
43082         kml: function(doc) {
43083
43084             var gj = fc(),
43085                 // styleindex keeps track of hashed styles in order to match features
43086                 styleIndex = {}, styleByHash = {},
43087                 // stylemapindex keeps track of style maps to expose in properties
43088                 styleMapIndex = {},
43089                 // atomic geospatial types supported by KML - MultiGeometry is
43090                 // handled separately
43091                 geotypes = ['Polygon', 'LineString', 'Point', 'Track', 'gx:Track'],
43092                 // all root placemarks in the file
43093                 placemarks = get(doc, 'Placemark'),
43094                 styles = get(doc, 'Style'),
43095                 styleMaps = get(doc, 'StyleMap');
43096
43097             for (var k = 0; k < styles.length; k++) {
43098                 var hash = okhash(xml2str(styles[k])).toString(16);
43099                 styleIndex['#' + attr(styles[k], 'id')] = hash;
43100                 styleByHash[hash] = styles[k];
43101             }
43102             for (var l = 0; l < styleMaps.length; l++) {
43103                 styleIndex['#' + attr(styleMaps[l], 'id')] = okhash(xml2str(styleMaps[l])).toString(16);
43104                 var pairs = get(styleMaps[l], 'Pair');
43105                 var pairsMap = {};
43106                 for (var m = 0; m < pairs.length; m++) {
43107                     pairsMap[nodeVal(get1(pairs[m], 'key'))] = nodeVal(get1(pairs[m], 'styleUrl'));
43108                 }
43109                 styleMapIndex['#' + attr(styleMaps[l], 'id')] = pairsMap;
43110
43111             }
43112             for (var j = 0; j < placemarks.length; j++) {
43113                 gj.features = gj.features.concat(getPlacemark(placemarks[j]));
43114             }
43115             function kmlColor(v) {
43116                 var color, opacity;
43117                 v = v || '';
43118                 if (v.substr(0, 1) === '#') { v = v.substr(1); }
43119                 if (v.length === 6 || v.length === 3) { color = v; }
43120                 if (v.length === 8) {
43121                     opacity = parseInt(v.substr(0, 2), 16) / 255;
43122                     color = '#' + v.substr(6, 2) +
43123                         v.substr(4, 2) +
43124                         v.substr(2, 2);
43125                 }
43126                 return [color, isNaN(opacity) ? undefined : opacity];
43127             }
43128             function gxCoord(v) { return numarray(v.split(' ')); }
43129             function gxCoords(root) {
43130                 var elems = get(root, 'coord', 'gx'), coords = [], times = [];
43131                 if (elems.length === 0) elems = get(root, 'gx:coord');
43132                 for (var i = 0; i < elems.length; i++) coords.push(gxCoord(nodeVal(elems[i])));
43133                 var timeElems = get(root, 'when');
43134                 for (var j = 0; j < timeElems.length; j++) times.push(nodeVal(timeElems[j]));
43135                 return {
43136                     coords: coords,
43137                     times: times
43138                 };
43139             }
43140             function getGeometry(root) {
43141                 var geomNode, geomNodes, i, j, k, geoms = [], coordTimes = [];
43142                 if (get1(root, 'MultiGeometry')) { return getGeometry(get1(root, 'MultiGeometry')); }
43143                 if (get1(root, 'MultiTrack')) { return getGeometry(get1(root, 'MultiTrack')); }
43144                 if (get1(root, 'gx:MultiTrack')) { return getGeometry(get1(root, 'gx:MultiTrack')); }
43145                 for (i = 0; i < geotypes.length; i++) {
43146                     geomNodes = get(root, geotypes[i]);
43147                     if (geomNodes) {
43148                         for (j = 0; j < geomNodes.length; j++) {
43149                             geomNode = geomNodes[j];
43150                             if (geotypes[i] === 'Point') {
43151                                 geoms.push({
43152                                     type: 'Point',
43153                                     coordinates: coord1(nodeVal(get1(geomNode, 'coordinates')))
43154                                 });
43155                             } else if (geotypes[i] === 'LineString') {
43156                                 geoms.push({
43157                                     type: 'LineString',
43158                                     coordinates: coord(nodeVal(get1(geomNode, 'coordinates')))
43159                                 });
43160                             } else if (geotypes[i] === 'Polygon') {
43161                                 var rings = get(geomNode, 'LinearRing'),
43162                                     coords = [];
43163                                 for (k = 0; k < rings.length; k++) {
43164                                     coords.push(coord(nodeVal(get1(rings[k], 'coordinates'))));
43165                                 }
43166                                 geoms.push({
43167                                     type: 'Polygon',
43168                                     coordinates: coords
43169                                 });
43170                             } else if (geotypes[i] === 'Track' ||
43171                                 geotypes[i] === 'gx:Track') {
43172                                 var track = gxCoords(geomNode);
43173                                 geoms.push({
43174                                     type: 'LineString',
43175                                     coordinates: track.coords
43176                                 });
43177                                 if (track.times.length) coordTimes.push(track.times);
43178                             }
43179                         }
43180                     }
43181                 }
43182                 return {
43183                     geoms: geoms,
43184                     coordTimes: coordTimes
43185                 };
43186             }
43187             function getPlacemark(root) {
43188                 var geomsAndTimes = getGeometry(root), i, properties = {},
43189                     name = nodeVal(get1(root, 'name')),
43190                     address = nodeVal(get1(root, 'address')),
43191                     styleUrl = nodeVal(get1(root, 'styleUrl')),
43192                     description = nodeVal(get1(root, 'description')),
43193                     timeSpan = get1(root, 'TimeSpan'),
43194                     timeStamp = get1(root, 'TimeStamp'),
43195                     extendedData = get1(root, 'ExtendedData'),
43196                     lineStyle = get1(root, 'LineStyle'),
43197                     polyStyle = get1(root, 'PolyStyle'),
43198                     visibility = get1(root, 'visibility');
43199
43200                 if (!geomsAndTimes.geoms.length) return [];
43201                 if (name) properties.name = name;
43202                 if (address) properties.address = address;
43203                 if (styleUrl) {
43204                     if (styleUrl[0] !== '#') {
43205                         styleUrl = '#' + styleUrl;
43206                     }
43207
43208                     properties.styleUrl = styleUrl;
43209                     if (styleIndex[styleUrl]) {
43210                         properties.styleHash = styleIndex[styleUrl];
43211                     }
43212                     if (styleMapIndex[styleUrl]) {
43213                         properties.styleMapHash = styleMapIndex[styleUrl];
43214                         properties.styleHash = styleIndex[styleMapIndex[styleUrl].normal];
43215                     }
43216                     // Try to populate the lineStyle or polyStyle since we got the style hash
43217                     var style = styleByHash[properties.styleHash];
43218                     if (style) {
43219                         if (!lineStyle) lineStyle = get1(style, 'LineStyle');
43220                         if (!polyStyle) polyStyle = get1(style, 'PolyStyle');
43221                     }
43222                 }
43223                 if (description) properties.description = description;
43224                 if (timeSpan) {
43225                     var begin = nodeVal(get1(timeSpan, 'begin'));
43226                     var end = nodeVal(get1(timeSpan, 'end'));
43227                     properties.timespan = { begin: begin, end: end };
43228                 }
43229                 if (timeStamp) {
43230                     properties.timestamp = nodeVal(get1(timeStamp, 'when'));
43231                 }
43232                 if (lineStyle) {
43233                     var linestyles = kmlColor(nodeVal(get1(lineStyle, 'color'))),
43234                         color = linestyles[0],
43235                         opacity = linestyles[1],
43236                         width = parseFloat(nodeVal(get1(lineStyle, 'width')));
43237                     if (color) properties.stroke = color;
43238                     if (!isNaN(opacity)) properties['stroke-opacity'] = opacity;
43239                     if (!isNaN(width)) properties['stroke-width'] = width;
43240                 }
43241                 if (polyStyle) {
43242                     var polystyles = kmlColor(nodeVal(get1(polyStyle, 'color'))),
43243                         pcolor = polystyles[0],
43244                         popacity = polystyles[1],
43245                         fill = nodeVal(get1(polyStyle, 'fill')),
43246                         outline = nodeVal(get1(polyStyle, 'outline'));
43247                     if (pcolor) properties.fill = pcolor;
43248                     if (!isNaN(popacity)) properties['fill-opacity'] = popacity;
43249                     if (fill) properties['fill-opacity'] = fill === '1' ? properties['fill-opacity'] || 1 : 0;
43250                     if (outline) properties['stroke-opacity'] = outline === '1' ? properties['stroke-opacity'] || 1 : 0;
43251                 }
43252                 if (extendedData) {
43253                     var datas = get(extendedData, 'Data'),
43254                         simpleDatas = get(extendedData, 'SimpleData');
43255
43256                     for (i = 0; i < datas.length; i++) {
43257                         properties[datas[i].getAttribute('name')] = nodeVal(get1(datas[i], 'value'));
43258                     }
43259                     for (i = 0; i < simpleDatas.length; i++) {
43260                         properties[simpleDatas[i].getAttribute('name')] = nodeVal(simpleDatas[i]);
43261                     }
43262                 }
43263                 if (visibility) {
43264                     properties.visibility = nodeVal(visibility);
43265                 }
43266                 if (geomsAndTimes.coordTimes.length) {
43267                     properties.coordTimes = (geomsAndTimes.coordTimes.length === 1) ?
43268                         geomsAndTimes.coordTimes[0] : geomsAndTimes.coordTimes;
43269                 }
43270                 var feature = {
43271                     type: 'Feature',
43272                     geometry: (geomsAndTimes.geoms.length === 1) ? geomsAndTimes.geoms[0] : {
43273                         type: 'GeometryCollection',
43274                         geometries: geomsAndTimes.geoms
43275                     },
43276                     properties: properties
43277                 };
43278                 if (attr(root, 'id')) feature.id = attr(root, 'id');
43279                 return [feature];
43280             }
43281             return gj;
43282         },
43283         gpx: function(doc) {
43284             var i,
43285                 tracks = get(doc, 'trk'),
43286                 routes = get(doc, 'rte'),
43287                 waypoints = get(doc, 'wpt'),
43288                 // a feature collection
43289                 gj = fc(),
43290                 feature;
43291             for (i = 0; i < tracks.length; i++) {
43292                 feature = getTrack(tracks[i]);
43293                 if (feature) gj.features.push(feature);
43294             }
43295             for (i = 0; i < routes.length; i++) {
43296                 feature = getRoute(routes[i]);
43297                 if (feature) gj.features.push(feature);
43298             }
43299             for (i = 0; i < waypoints.length; i++) {
43300                 gj.features.push(getPoint(waypoints[i]));
43301             }
43302             function getPoints(node, pointname) {
43303                 var pts = get(node, pointname),
43304                     line = [],
43305                     times = [],
43306                     heartRates = [],
43307                     l = pts.length;
43308                 if (l < 2) return {};  // Invalid line in GeoJSON
43309                 for (var i = 0; i < l; i++) {
43310                     var c = coordPair(pts[i]);
43311                     line.push(c.coordinates);
43312                     if (c.time) times.push(c.time);
43313                     if (c.heartRate) heartRates.push(c.heartRate);
43314                 }
43315                 return {
43316                     line: line,
43317                     times: times,
43318                     heartRates: heartRates
43319                 };
43320             }
43321             function getTrack(node) {
43322                 var segments = get(node, 'trkseg'),
43323                     track = [],
43324                     times = [],
43325                     heartRates = [],
43326                     line;
43327                 for (var i = 0; i < segments.length; i++) {
43328                     line = getPoints(segments[i], 'trkpt');
43329                     if (line) {
43330                         if (line.line) track.push(line.line);
43331                         if (line.times && line.times.length) times.push(line.times);
43332                         if (line.heartRates && line.heartRates.length) heartRates.push(line.heartRates);
43333                     }
43334                 }
43335                 if (track.length === 0) return;
43336                 var properties = getProperties(node);
43337                 extend(properties, getLineStyle(get1(node, 'extensions')));
43338                 if (times.length) properties.coordTimes = track.length === 1 ? times[0] : times;
43339                 if (heartRates.length) properties.heartRates = track.length === 1 ? heartRates[0] : heartRates;
43340                 return {
43341                     type: 'Feature',
43342                     properties: properties,
43343                     geometry: {
43344                         type: track.length === 1 ? 'LineString' : 'MultiLineString',
43345                         coordinates: track.length === 1 ? track[0] : track
43346                     }
43347                 };
43348             }
43349             function getRoute(node) {
43350                 var line = getPoints(node, 'rtept');
43351                 if (!line.line) return;
43352                 var prop = getProperties(node);
43353                 extend(prop, getLineStyle(get1(node, 'extensions')));
43354                 var routeObj = {
43355                     type: 'Feature',
43356                     properties: prop,
43357                     geometry: {
43358                         type: 'LineString',
43359                         coordinates: line.line
43360                     }
43361                 };
43362                 return routeObj;
43363             }
43364             function getPoint(node) {
43365                 var prop = getProperties(node);
43366                 extend(prop, getMulti(node, ['sym']));
43367                 return {
43368                     type: 'Feature',
43369                     properties: prop,
43370                     geometry: {
43371                         type: 'Point',
43372                         coordinates: coordPair(node).coordinates
43373                     }
43374                 };
43375             }
43376             function getLineStyle(extensions) {
43377                 var style = {};
43378                 if (extensions) {
43379                     var lineStyle = get1(extensions, 'line');
43380                     if (lineStyle) {
43381                         var color = nodeVal(get1(lineStyle, 'color')),
43382                             opacity = parseFloat(nodeVal(get1(lineStyle, 'opacity'))),
43383                             width = parseFloat(nodeVal(get1(lineStyle, 'width')));
43384                         if (color) style.stroke = color;
43385                         if (!isNaN(opacity)) style['stroke-opacity'] = opacity;
43386                         // GPX width is in mm, convert to px with 96 px per inch
43387                         if (!isNaN(width)) style['stroke-width'] = width * 96 / 25.4;
43388                     }
43389                 }
43390                 return style;
43391             }
43392             function getProperties(node) {
43393                 var prop = getMulti(node, ['name', 'cmt', 'desc', 'type', 'time', 'keywords']),
43394                     links = get(node, 'link');
43395                 if (links.length) prop.links = [];
43396                 for (var i = 0, link; i < links.length; i++) {
43397                     link = { href: attr(links[i], 'href') };
43398                     extend(link, getMulti(links[i], ['text', 'type']));
43399                     prop.links.push(link);
43400                 }
43401                 return prop;
43402             }
43403             return gj;
43404         }
43405     };
43406     return t;
43407 })();
43408
43409 module.exports = toGeoJSON;
43410 });
43411
43412 function svgGpx(projection, context, dispatch) {
43413     var showLabels = true,
43414         detected = utilDetect(),
43415         layer,
43416         src;
43417
43418
43419     function init() {
43420         if (svgGpx.initialized) return;  // run once
43421
43422         svgGpx.geojson = {};
43423         svgGpx.enabled = true;
43424
43425         function over() {
43426             event.stopPropagation();
43427             event.preventDefault();
43428             event.dataTransfer.dropEffect = 'copy';
43429         }
43430
43431         d3_select('body')
43432             .attr('dropzone', 'copy')
43433             .on('drop.localgpx', function() {
43434                 event.stopPropagation();
43435                 event.preventDefault();
43436                 if (!detected.filedrop) return;
43437                 drawGpx.files(event.dataTransfer.files);
43438             })
43439             .on('dragenter.localgpx', over)
43440             .on('dragexit.localgpx', over)
43441             .on('dragover.localgpx', over);
43442
43443         svgGpx.initialized = true;
43444     }
43445
43446
43447     function drawGpx(selection) {
43448         var geojson = svgGpx.geojson,
43449             enabled = svgGpx.enabled;
43450
43451         layer = selection.selectAll('.layer-gpx')
43452             .data(enabled ? [0] : []);
43453
43454         layer.exit()
43455             .remove();
43456
43457         layer = layer.enter()
43458             .append('g')
43459             .attr('class', 'layer-gpx')
43460             .merge(layer);
43461
43462
43463         var paths = layer
43464             .selectAll('path')
43465             .data([geojson]);
43466
43467         paths.exit()
43468             .remove();
43469
43470         paths = paths.enter()
43471             .append('path')
43472             .attr('class', 'gpx')
43473             .merge(paths);
43474
43475
43476         var path = d3_geoPath(projection);
43477
43478         paths
43479             .attr('d', path);
43480
43481
43482         var labels = layer.selectAll('text')
43483             .data(showLabels && geojson.features ? geojson.features : []);
43484
43485         labels.exit()
43486             .remove();
43487
43488         labels = labels.enter()
43489             .append('text')
43490             .attr('class', 'gpx')
43491             .merge(labels);
43492
43493         labels
43494             .text(function(d) {
43495                 return d.properties.desc || d.properties.name;
43496             })
43497             .attr('x', function(d) {
43498                 var centroid = path.centroid(d);
43499                 return centroid[0] + 7;
43500             })
43501             .attr('y', function(d) {
43502                 var centroid = path.centroid(d);
43503                 return centroid[1];
43504             });
43505
43506     }
43507
43508
43509     function toDom(x) {
43510         return (new DOMParser()).parseFromString(x, 'text/xml');
43511     }
43512
43513
43514     function getExtension(fileName) {
43515         if (isUndefined(fileName)) {
43516             return '';
43517         }
43518
43519         var lastDotIndex = fileName.lastIndexOf('.');
43520         if (lastDotIndex < 0) {
43521             return '';
43522         }
43523
43524         return fileName.substr(lastDotIndex);
43525     }
43526
43527
43528     function parseSaveAndZoom(extension, data) {
43529         switch (extension) {
43530             default:
43531                 drawGpx.geojson(togeojson.gpx(toDom(data))).fitZoom();
43532                 break;
43533             case '.kml':
43534                 drawGpx.geojson(togeojson.kml(toDom(data))).fitZoom();
43535                 break;
43536             case '.geojson':
43537             case '.json':
43538                 drawGpx.geojson(JSON.parse(data)).fitZoom();
43539                 break;
43540         }
43541     }
43542
43543
43544     drawGpx.showLabels = function(_) {
43545         if (!arguments.length) return showLabels;
43546         showLabels = _;
43547         return this;
43548     };
43549
43550
43551     drawGpx.enabled = function(_) {
43552         if (!arguments.length) return svgGpx.enabled;
43553         svgGpx.enabled = _;
43554         dispatch.call('change');
43555         return this;
43556     };
43557
43558
43559     drawGpx.hasGpx = function() {
43560         var geojson = svgGpx.geojson;
43561         return (!(isEmpty(geojson) || isEmpty(geojson.features)));
43562     };
43563
43564
43565     drawGpx.geojson = function(gj) {
43566         if (!arguments.length) return svgGpx.geojson;
43567         if (isEmpty(gj) || isEmpty(gj.features)) return this;
43568         svgGpx.geojson = gj;
43569         dispatch.call('change');
43570         return this;
43571     };
43572
43573
43574     drawGpx.url = function(url) {
43575         d3_text(url, function(err, data) {
43576             if (!err) {
43577                 src = url;
43578
43579                 var extension = getExtension(url);
43580                 parseSaveAndZoom(extension, data);
43581             }
43582         });
43583         return this;
43584     };
43585
43586
43587     drawGpx.files = function(fileList) {
43588         if (!fileList.length) return this;
43589         var f = fileList[0],
43590             reader = new FileReader();
43591
43592         reader.onload = (function(file) {
43593             src = file.name;
43594
43595             var extension = getExtension(file.name);
43596
43597             return function (e) {
43598                 parseSaveAndZoom(extension, e.target.result);
43599             };
43600         })(f);
43601
43602         reader.readAsText(f);
43603         return this;
43604     };
43605
43606     drawGpx.getSrc = function () {
43607       return src;
43608     };
43609
43610     drawGpx.fitZoom = function() {
43611         if (!this.hasGpx()) return this;
43612         var geojson = svgGpx.geojson;
43613
43614         var map = context.map(),
43615             viewport = map.trimmedExtent().polygon(),
43616             coords = reduce(geojson.features, function(coords, feature) {
43617                 var c = feature.geometry.coordinates;
43618
43619                 /* eslint-disable no-fallthrough */
43620                 switch (feature.geometry.type) {
43621                     case 'Point':
43622                         c = [c];
43623                     case 'MultiPoint':
43624                     case 'LineString':
43625                         break;
43626
43627                     case 'MultiPolygon':
43628                         c = flatten(c);
43629                     case 'Polygon':
43630                     case 'MultiLineString':
43631                         c = flatten(c);
43632                         break;
43633                 }
43634                 /* eslint-enable no-fallthrough */
43635
43636                 return union(coords, c);
43637             }, []);
43638
43639         if (!geoPolygonIntersectsPolygon(viewport, coords, true)) {
43640             var extent = geoExtent(d3_geoBounds({ type: 'LineString', coordinates: coords }));
43641             map.centerZoom(extent.center(), map.trimmedExtentZoom(extent));
43642         }
43643
43644         return this;
43645     };
43646
43647
43648     init();
43649     return drawGpx;
43650 }
43651
43652 function svgIcon(name, svgklass, useklass) {
43653     return function drawIcon(selection) {
43654         selection.selectAll('svg')
43655             .data([0])
43656             .enter()
43657             .append('svg')
43658             .attr('class', 'icon ' + (svgklass || ''))
43659             .append('use')
43660             .attr('xlink:href', name)
43661             .attr('class', useklass);
43662     };
43663 }
43664
43665 function svgLabels(projection, context) {
43666     var path = d3_geoPath(projection),
43667         detected = utilDetect(),
43668         baselineHack = (detected.ie || detected.browser.toLowerCase() === 'edge'),
43669         rdrawn = rbush_1(),
43670         rskipped = rbush_1(),
43671         textWidthCache = {},
43672         entitybboxes = {};
43673
43674     // Listed from highest to lowest priority
43675     var labelStack = [
43676         ['line', 'aeroway', '*', 12],
43677         ['line', 'highway', 'motorway', 12],
43678         ['line', 'highway', 'trunk', 12],
43679         ['line', 'highway', 'primary', 12],
43680         ['line', 'highway', 'secondary', 12],
43681         ['line', 'highway', 'tertiary', 12],
43682         ['line', 'highway', '*', 12],
43683         ['line', 'railway', '*', 12],
43684         ['line', 'waterway', '*', 12],
43685         ['area', 'aeroway', '*', 12],
43686         ['area', 'amenity', '*', 12],
43687         ['area', 'building', '*', 12],
43688         ['area', 'historic', '*', 12],
43689         ['area', 'leisure', '*', 12],
43690         ['area', 'man_made', '*', 12],
43691         ['area', 'natural', '*', 12],
43692         ['area', 'shop', '*', 12],
43693         ['area', 'tourism', '*', 12],
43694         ['area', 'camp_site', '*', 12],
43695         ['point', 'aeroway', '*', 10],
43696         ['point', 'amenity', '*', 10],
43697         ['point', 'building', '*', 10],
43698         ['point', 'historic', '*', 10],
43699         ['point', 'leisure', '*', 10],
43700         ['point', 'man_made', '*', 10],
43701         ['point', 'natural', '*', 10],
43702         ['point', 'shop', '*', 10],
43703         ['point', 'tourism', '*', 10],
43704         ['point', 'camp_site', '*', 10],
43705         ['line', 'name', '*', 12],
43706         ['area', 'name', '*', 12],
43707         ['point', 'name', '*', 10]
43708     ];
43709
43710
43711     function blacklisted(preset) {
43712         var noIcons = ['building', 'landuse', 'natural'];
43713         return some(noIcons, function(s) {
43714             return preset.id.indexOf(s) >= 0;
43715         });
43716     }
43717
43718
43719     function get(array, prop) {
43720         return function(d, i) { return array[i][prop]; };
43721     }
43722
43723
43724     function textWidth(text, size, elem) {
43725         var c = textWidthCache[size];
43726         if (!c) c = textWidthCache[size] = {};
43727
43728         if (c[text]) {
43729             return c[text];
43730
43731         } else if (elem) {
43732             c[text] = elem.getComputedTextLength();
43733             return c[text];
43734
43735         } else {
43736             var str = encodeURIComponent(text).match(/%[CDEFcdef]/g);
43737             if (str === null) {
43738                 return size / 3 * 2 * text.length;
43739             } else {
43740                 return size / 3 * (2 * text.length + str.length);
43741             }
43742         }
43743     }
43744
43745
43746     function drawLinePaths(selection, entities, filter, classes, labels) {
43747         var paths = selection.selectAll('path')
43748             .filter(filter)
43749             .data(entities, osmEntity.key);
43750
43751         paths.exit()
43752             .remove();
43753
43754         paths.enter()
43755             .append('path')
43756             .style('stroke-width', get(labels, 'font-size'))
43757             .attr('id', function(d) { return 'labelpath-' + d.id; })
43758             .attr('class', classes)
43759             .merge(paths)
43760             .attr('d', get(labels, 'lineString'));
43761     }
43762
43763
43764     function drawLineLabels(selection, entities, filter, classes, labels) {
43765         var texts = selection.selectAll('text.' + classes)
43766             .filter(filter)
43767             .data(entities, osmEntity.key);
43768
43769         texts.exit()
43770             .remove();
43771
43772         texts.enter()
43773             .append('text')
43774             .attr('class', function(d, i) { return classes + ' ' + labels[i].classes + ' ' + d.id; })
43775             .attr('dy', baselineHack ? '0.35em' : null)
43776             .append('textPath')
43777             .attr('class', 'textpath');
43778
43779         texts = selection.selectAll('text.' + classes);
43780
43781         texts.selectAll('.textpath')
43782             .filter(filter)
43783             .data(entities, osmEntity.key)
43784             .attr('startOffset', '50%')
43785             .attr('xlink:href', function(d) { return '#labelpath-' + d.id; })
43786             .text(utilDisplayNameForPath);
43787     }
43788
43789
43790     function drawPointLabels(selection, entities, filter, classes, labels) {
43791         var texts = selection.selectAll('text.' + classes)
43792             .filter(filter)
43793             .data(entities, osmEntity.key);
43794
43795         texts.exit()
43796             .remove();
43797
43798         texts = texts.enter()
43799             .append('text')
43800             .attr('class', function(d, i) {
43801                 return classes + ' ' + labels[i].classes + ' ' + d.id;
43802             })
43803             .merge(texts);
43804
43805         texts
43806             .attr('x', get(labels, 'x'))
43807             .attr('y', get(labels, 'y'))
43808             .style('text-anchor', get(labels, 'textAnchor'))
43809             .text(utilDisplayName)
43810             .each(function(d, i) {
43811                 textWidth(utilDisplayName(d), labels[i].height, this);
43812             });
43813     }
43814
43815
43816     function drawAreaLabels(selection, entities, filter, classes, labels) {
43817         entities = entities.filter(hasText);
43818         labels = labels.filter(hasText);
43819         drawPointLabels(selection, entities, filter, classes, labels);
43820
43821         function hasText(d, i) {
43822             return labels[i].hasOwnProperty('x') && labels[i].hasOwnProperty('y');
43823         }
43824     }
43825
43826
43827     function drawAreaIcons(selection, entities, filter, classes, labels) {
43828         var icons = selection.selectAll('use.' + classes)
43829             .filter(filter)
43830             .data(entities, osmEntity.key);
43831
43832         icons.exit()
43833             .remove();
43834
43835         icons = icons.enter()
43836             .append('use')
43837             .attr('class', 'icon ' + classes)
43838             .attr('width', '17px')
43839             .attr('height', '17px')
43840             .merge(icons);
43841
43842         icons
43843             .attr('transform', get(labels, 'transform'))
43844             .attr('xlink:href', function(d) {
43845                 var preset = context.presets().match(d, context.graph()),
43846                     picon = preset && preset.icon;
43847
43848                 if (!picon)
43849                     return '';
43850                 else {
43851                     var isMaki = dataFeatureIcons.indexOf(picon) !== -1;
43852                     return '#' + picon + (isMaki ? '-15' : '');
43853                 }
43854             });
43855     }
43856
43857
43858     function drawCollisionBoxes(selection, rtree, which) {
43859         var showDebug = context.getDebug('collision'),
43860             classes = 'debug ' + which + ' ' +
43861                 (which === 'debug-skipped' ? 'orange' : 'yellow');
43862
43863         var debug = selection.selectAll('.layer-label-debug')
43864                 .data(showDebug ? [true] : []);
43865
43866         debug.exit()
43867             .remove();
43868
43869         debug = debug.enter()
43870             .append('g')
43871             .attr('class', 'layer-label-debug')
43872             .merge(debug);
43873
43874         if (showDebug) {
43875             var gj = rtree.all().map(function(d) {
43876                 return { type: 'Polygon', coordinates: [[
43877                     [d.minX, d.minY],
43878                     [d.maxX, d.minY],
43879                     [d.maxX, d.maxY],
43880                     [d.minX, d.maxY],
43881                     [d.minX, d.minY]
43882                 ]]};
43883             });
43884
43885             var debugboxes = debug.selectAll('.' + which)
43886                 .data(gj);
43887
43888             debugboxes.exit()
43889                 .remove();
43890
43891             debugboxes = debugboxes.enter()
43892                 .append('path')
43893                 .attr('class', classes)
43894                 .merge(debugboxes);
43895
43896             debugboxes
43897                 .attr('d', d3_geoPath());
43898         }
43899     }
43900
43901
43902     function drawLabels(selection, graph, entities, filter, dimensions, fullRedraw) {
43903         var lowZoom = context.surface().classed('low-zoom');
43904
43905         var labelable = [], i, j, k, entity, geometry;
43906         for (i = 0; i < labelStack.length; i++) {
43907             labelable.push([]);
43908         }
43909
43910         if (fullRedraw) {
43911             rdrawn.clear();
43912             rskipped.clear();
43913             entitybboxes = {};
43914         } else {
43915             for (i = 0; i < entities.length; i++) {
43916                 entity = entities[i];
43917                 var toRemove = []
43918                     .concat(entitybboxes[entity.id] || [])
43919                     .concat(entitybboxes[entity.id + 'I'] || []);
43920
43921                 for (j = 0; j < toRemove.length; j++) {
43922                     rdrawn.remove(toRemove[j]);
43923                     rskipped.remove(toRemove[j]);
43924                 }
43925             }
43926         }
43927
43928         // Split entities into groups specified by labelStack
43929         for (i = 0; i < entities.length; i++) {
43930             entity = entities[i];
43931             geometry = entity.geometry(graph);
43932             if (geometry === 'vertex') { geometry = 'point'; }  // treat vertex like point
43933
43934             var preset = geometry === 'area' && context.presets().match(entity, graph),
43935                 icon = preset && !blacklisted(preset) && preset.icon;
43936
43937             if (!icon && !utilDisplayName(entity))
43938                 continue;
43939
43940             for (k = 0; k < labelStack.length; k++) {
43941                 var matchGeom = labelStack[k][0],
43942                     matchKey = labelStack[k][1],
43943                     matchVal = labelStack[k][2],
43944                     hasVal = entity.tags[matchKey];
43945
43946                 if (geometry === matchGeom && hasVal && (matchVal === '*' || matchVal === hasVal)) {
43947                     labelable[k].push(entity);
43948                     break;
43949                 }
43950             }
43951         }
43952
43953         var positions = {
43954             point: [],
43955             line: [],
43956             area: []
43957         };
43958
43959         var labelled = {
43960             point: [],
43961             line: [],
43962             area: []
43963         };
43964
43965         // Try and find a valid label for labellable entities
43966         for (k = 0; k < labelable.length; k++) {
43967             var fontSize = labelStack[k][3];
43968             for (i = 0; i < labelable[k].length; i++) {
43969                 entity = labelable[k][i];
43970                 geometry = entity.geometry(graph);
43971
43972                 var getName = (geometry === 'line') ? utilDisplayNameForPath : utilDisplayName,
43973                     name = getName(entity),
43974                     width = name && textWidth(name, fontSize),
43975                     p = null;
43976
43977                 if (geometry === 'point') {
43978                     p = getPointLabel(entity, width, fontSize, geometry);
43979                 } else if (geometry === 'vertex' && !lowZoom) {
43980                     // don't label vertices at low zoom because they don't have icons
43981                     p = getPointLabel(entity, width, fontSize, geometry);
43982                 } else if (geometry === 'line') {
43983                     p = getLineLabel(entity, width, fontSize);
43984                 } else if (geometry === 'area') {
43985                     p = getAreaLabel(entity, width, fontSize);
43986                 }
43987
43988                 if (p) {
43989                     if (geometry === 'vertex') { geometry = 'point'; }  // treat vertex like point
43990                     p.classes = geometry + ' tag-' + labelStack[k][1];
43991                     positions[geometry].push(p);
43992                     labelled[geometry].push(entity);
43993                 }
43994             }
43995         }
43996
43997
43998         function getPointLabel(entity, width, height, geometry) {
43999             var y = (geometry === 'point' ? -12 : 0),
44000                 pointOffsets = {
44001                     ltr: [15, y, 'start'],
44002                     rtl: [-15, y, 'end']
44003                 };
44004
44005             var coord = projection(entity.loc),
44006                 margin = 2,
44007                 offset = pointOffsets[textDirection],
44008                 p = {
44009                     height: height,
44010                     width: width,
44011                     x: coord[0] + offset[0],
44012                     y: coord[1] + offset[1],
44013                     textAnchor: offset[2]
44014                 },
44015                 bbox;
44016
44017             if (textDirection === 'rtl') {
44018                 bbox = {
44019                     minX: p.x - width - margin,
44020                     minY: p.y - (height / 2) - margin,
44021                     maxX: p.x + margin,
44022                     maxY: p.y + (height / 2) + margin
44023                 };
44024             } else {
44025                 bbox = {
44026                     minX: p.x - margin,
44027                     minY: p.y - (height / 2) - margin,
44028                     maxX: p.x + width + margin,
44029                     maxY: p.y + (height / 2) + margin
44030                 };
44031             }
44032
44033             if (tryInsert([bbox], entity.id, true)) {
44034                 return p;
44035             }
44036         }
44037
44038
44039         function getLineLabel(entity, width, height) {
44040             var viewport = geoExtent(context.projection.clipExtent()).polygon(),
44041                 nodes = map$4(graph.childNodes(entity), 'loc').map(projection),
44042                 length = geoPathLength(nodes);
44043
44044             if (length < width + 20) return;
44045
44046             // % along the line to attempt to place the label
44047             var lineOffsets = [50, 45, 55, 40, 60, 35, 65, 30, 70,
44048                                25, 75, 20, 80, 15, 95, 10, 90, 5, 95];
44049             var margin = 3;
44050
44051             for (var i = 0; i < lineOffsets.length; i++) {
44052                 var offset = lineOffsets[i],
44053                     middle = offset / 100 * length,
44054                     start = middle - width / 2;
44055
44056                 if (start < 0 || start + width > length) continue;
44057
44058                 // generate subpath and ignore paths that are invalid or don't cross viewport.
44059                 var sub = subpath(nodes, start, start + width);
44060                 if (!sub || !geoPolygonIntersectsPolygon(viewport, sub, true)) {
44061                     continue;
44062                 }
44063
44064                 var isReverse = reverse(sub);
44065                 if (isReverse) {
44066                     sub = sub.reverse();
44067                 }
44068
44069                 var bboxes = [],
44070                     boxsize = (height + 2) / 2;
44071
44072                 for (var j = 0; j < sub.length - 1; j++) {
44073                     var a = sub[j];
44074                     var b = sub[j + 1];
44075                     var num = Math.max(1, Math.floor(geoEuclideanDistance(a, b) / boxsize / 2));
44076
44077                     for (var box = 0; box < num; box++) {
44078                         var p = geoInterp(a, b, box / num);
44079                         var x0 = p[0] - boxsize - margin;
44080                         var y0 = p[1] - boxsize - margin;
44081                         var x1 = p[0] + boxsize + margin;
44082                         var y1 = p[1] + boxsize + margin;
44083
44084                         bboxes.push({
44085                             minX: Math.min(x0, x1),
44086                             minY: Math.min(y0, y1),
44087                             maxX: Math.max(x0, x1),
44088                             maxY: Math.max(y0, y1)
44089                         });
44090                     }
44091                 }
44092
44093                 if (tryInsert(bboxes, entity.id, false)) {
44094                     return {
44095                         'font-size': height + 2,
44096                         lineString: lineString(sub),
44097                         startOffset: offset + '%'
44098                     };
44099                 }
44100             }
44101
44102             function reverse(p) {
44103                 var angle = Math.atan2(p[1][1] - p[0][1], p[1][0] - p[0][0]);
44104                 return !(p[0][0] < p[p.length - 1][0] && angle < Math.PI/2 && angle > -Math.PI/2);
44105             }
44106
44107             function lineString(nodes) {
44108                 return 'M' + nodes.join('L');
44109             }
44110
44111             function subpath(nodes, from, to) {
44112                 var sofar = 0,
44113                     start, end, i0, i1;
44114
44115                 for (var i = 0; i < nodes.length - 1; i++) {
44116                     var a = nodes[i],
44117                         b = nodes[i + 1];
44118                     var current = geoEuclideanDistance(a, b);
44119                     var portion;
44120                     if (!start && sofar + current >= from) {
44121                         portion = (from - sofar) / current;
44122                         start = [
44123                             a[0] + portion * (b[0] - a[0]),
44124                             a[1] + portion * (b[1] - a[1])
44125                         ];
44126                         i0 = i + 1;
44127                     }
44128                     if (!end && sofar + current >= to) {
44129                         portion = (to - sofar) / current;
44130                         end = [
44131                             a[0] + portion * (b[0] - a[0]),
44132                             a[1] + portion * (b[1] - a[1])
44133                         ];
44134                         i1 = i + 1;
44135                     }
44136                     sofar += current;
44137                 }
44138
44139                 var ret = nodes.slice(i0, i1);
44140                 ret.unshift(start);
44141                 ret.push(end);
44142                 return ret;
44143             }
44144         }
44145
44146
44147         function getAreaLabel(entity, width, height) {
44148             var centroid = path.centroid(entity.asGeoJSON(graph, true)),
44149                 extent = entity.extent(graph),
44150                 areaWidth = projection(extent[1])[0] - projection(extent[0])[0];
44151
44152             if (isNaN(centroid[0]) || areaWidth < 20) return;
44153
44154             var preset = context.presets().match(entity, context.graph()),
44155                 picon = preset && preset.icon,
44156                 iconSize = 17,
44157                 margin = 2,
44158                 p = {};
44159
44160             if (picon) {  // icon and label..
44161                 if (addIcon()) {
44162                     addLabel(iconSize + margin);
44163                     return p;
44164                 }
44165             } else {   // label only..
44166                 if (addLabel(0)) {
44167                     return p;
44168                 }
44169             }
44170
44171
44172             function addIcon() {
44173                 var iconX = centroid[0] - (iconSize / 2);
44174                 var iconY = centroid[1] - (iconSize / 2);
44175                 var bbox = {
44176                     minX: iconX,
44177                     minY: iconY,
44178                     maxX: iconX + iconSize,
44179                     maxY: iconY + iconSize
44180                 };
44181
44182                 if (tryInsert([bbox], entity.id + 'I', true)) {
44183                     p.transform = 'translate(' + iconX + ',' + iconY + ')';
44184                     return true;
44185                 }
44186                 return false;
44187             }
44188
44189             function addLabel(yOffset) {
44190                 if (width && areaWidth >= width + 20) {
44191                     var labelX = centroid[0];
44192                     var labelY = centroid[1] + yOffset;
44193                     var bbox = {
44194                         minX: labelX - (width / 2) - margin,
44195                         minY: labelY - (height / 2) - margin,
44196                         maxX: labelX + (width / 2) + margin,
44197                         maxY: labelY + (height / 2) + margin
44198                     };
44199
44200                     if (tryInsert([bbox], entity.id, true)) {
44201                         p.x = labelX;
44202                         p.y = labelY;
44203                         p.textAnchor = 'middle';
44204                         p.height = height;
44205                         return true;
44206                     }
44207                 }
44208                 return false;
44209             }
44210         }
44211
44212
44213         function tryInsert(bboxes, id, saveSkipped) {
44214             var skipped = false,
44215                 bbox;
44216
44217             for (var i = 0; i < bboxes.length; i++) {
44218                 bbox = bboxes[i];
44219                 bbox.id = id;
44220
44221                 // Check that label is visible
44222                 if (bbox.minX < 0 || bbox.minY < 0 || bbox.maxX > dimensions[0] || bbox.maxY > dimensions[1]) {
44223                     skipped = true;
44224                     break;
44225                 }
44226                 if (rdrawn.collides(bbox)) {
44227                     skipped = true;
44228                     break;
44229                 }
44230             }
44231
44232             entitybboxes[id] = bboxes;
44233
44234             if (skipped) {
44235                 if (saveSkipped) {
44236                     rskipped.load(bboxes);
44237                 }
44238             } else {
44239                 rdrawn.load(bboxes);
44240             }
44241
44242             return !skipped;
44243         }
44244
44245
44246         var label = selection.selectAll('.layer-label'),
44247             halo = selection.selectAll('.layer-halo');
44248
44249         // points
44250         drawPointLabels(label, labelled.point, filter, 'pointlabel', positions.point);
44251         drawPointLabels(halo, labelled.point, filter, 'pointlabel-halo', positions.point);
44252
44253         // lines
44254         drawLinePaths(halo, labelled.line, filter, '', positions.line);
44255         drawLineLabels(label, labelled.line, filter, 'linelabel', positions.line);
44256         drawLineLabels(halo, labelled.line, filter, 'linelabel-halo', positions.line);
44257
44258         // areas
44259         drawAreaLabels(label, labelled.area, filter, 'arealabel', positions.area);
44260         drawAreaLabels(halo, labelled.area, filter, 'arealabel-halo', positions.area);
44261         drawAreaIcons(label, labelled.area, filter, 'areaicon', positions.area);
44262         drawAreaIcons(halo, labelled.area, filter, 'areaicon-halo', positions.area);
44263
44264         // debug
44265         drawCollisionBoxes(label, rskipped, 'debug-skipped');
44266         drawCollisionBoxes(label, rdrawn, 'debug-drawn');
44267
44268         selection.call(filterLabels);
44269     }
44270
44271
44272     function filterLabels(selection) {
44273         var layers = selection
44274             .selectAll('.layer-label, .layer-halo');
44275
44276         layers.selectAll('.proximate')
44277             .classed('proximate', false);
44278
44279         var mouse = context.mouse(),
44280             graph = context.graph(),
44281             selectedIDs = context.selectedIDs(),
44282             ids = [],
44283             pad, bbox;
44284
44285         // hide labels near the mouse
44286         if (mouse) {
44287             pad = 20;
44288             bbox = { minX: mouse[0] - pad, minY: mouse[1] - pad, maxX: mouse[0] + pad, maxY: mouse[1] + pad };
44289             ids.push.apply(ids, map$4(rdrawn.search(bbox), 'id'));
44290         }
44291
44292         // hide labels along selected ways, or near selected vertices
44293         for (var i = 0; i < selectedIDs.length; i++) {
44294             var entity = graph.hasEntity(selectedIDs[i]);
44295             if (!entity) continue;
44296             var geometry = entity.geometry(graph);
44297
44298             if (geometry === 'line') {
44299                 ids.push(selectedIDs[i]);
44300             } else if (geometry === 'vertex') {
44301                 var point = context.projection(entity.loc);
44302                 pad = 10;
44303                 bbox = { minX: point[0] - pad, minY: point[1] - pad, maxX: point[0] + pad, maxY: point[1] + pad };
44304                 ids.push.apply(ids, map$4(rdrawn.search(bbox), 'id'));
44305             }
44306         }
44307
44308         layers.selectAll(utilEntitySelector(ids))
44309             .classed('proximate', true);
44310     }
44311
44312
44313     var throttleFilterLabels = throttle(utilCallWhenIdle(filterLabels), 100);
44314
44315
44316     drawLabels.observe = function(selection) {
44317         var listener = function() { throttleFilterLabels(selection); };
44318         selection.on('mousemove.hidelabels', listener);
44319         context.on('enter.hidelabels', listener);
44320     };
44321
44322
44323     drawLabels.off = function(selection) {
44324         throttleFilterLabels.cancel();
44325         selection.on('mousemove.hidelabels', null);
44326         context.on('enter.hidelabels', null);
44327     };
44328
44329
44330     return drawLabels;
44331 }
44332
44333 function svgPointTransform(projection) {
44334     return function(entity) {
44335         // http://jsperf.com/short-array-join
44336         var pt = projection(entity.loc);
44337         return 'translate(' + pt[0] + ',' + pt[1] + ')';
44338     };
44339 }
44340
44341 function svgMapillaryImages(projection, context, dispatch) {
44342     var throttledRedraw = throttle(function () { dispatch.call('change'); }, 1000),
44343         minZoom = 12,
44344         minMarkerZoom = 16,
44345         minViewfieldZoom = 18,
44346         layer = d3_select(null),
44347         _mapillary;
44348
44349
44350     function init() {
44351         if (svgMapillaryImages.initialized) return;  // run once
44352         svgMapillaryImages.enabled = false;
44353         svgMapillaryImages.initialized = true;
44354     }
44355
44356
44357     function getService() {
44358         if (services.mapillary && !_mapillary) {
44359             _mapillary = services.mapillary;
44360             _mapillary.event.on('loadedImages', throttledRedraw);
44361         } else if (!services.mapillary && _mapillary) {
44362             _mapillary = null;
44363         }
44364
44365         return _mapillary;
44366     }
44367
44368
44369     function showLayer() {
44370         var service = getService();
44371         if (!service) return;
44372
44373         service.loadViewer(context);
44374         editOn();
44375
44376         layer
44377             .style('opacity', 0)
44378             .transition()
44379             .duration(250)
44380             .style('opacity', 1)
44381             .on('end', function () { dispatch.call('change'); });
44382     }
44383
44384
44385     function hideLayer() {
44386         var service = getService();
44387         if (service) {
44388             service.hideViewer();
44389         }
44390
44391         throttledRedraw.cancel();
44392
44393         layer
44394             .transition()
44395             .duration(250)
44396             .style('opacity', 0)
44397             .on('end', editOff);
44398     }
44399
44400
44401     function editOn() {
44402         layer.style('display', 'block');
44403     }
44404
44405
44406     function editOff() {
44407         layer.selectAll('.viewfield-group').remove();
44408         layer.style('display', 'none');
44409     }
44410
44411
44412     function click(d) {
44413         var service = getService();
44414         if (!service) return;
44415
44416         service
44417             .selectImage(d)
44418             .updateViewer(d.key, context)
44419             .showViewer();
44420
44421         context.map().centerEase(d.loc);
44422     }
44423
44424
44425     function mouseover(d) {
44426         var service = getService();
44427         if (service) service.setStyles(d);
44428     }
44429
44430
44431     function mouseout() {
44432         var service = getService();
44433         if (service) service.setStyles(null);
44434     }
44435
44436
44437     function transform(d) {
44438         var t = svgPointTransform(projection)(d);
44439         if (d.ca) {
44440             t += ' rotate(' + Math.floor(d.ca) + ',0,0)';
44441         }
44442         return t;
44443     }
44444
44445
44446     function update() {
44447         var viewer = d3_select('#photoviewer');
44448         var selected = viewer.empty() ? undefined : viewer.datum();
44449
44450         var z = ~~context.map().zoom();
44451         var showMarkers = (z >= minMarkerZoom);
44452         var showViewfields = (z >= minViewfieldZoom);
44453
44454         var service = getService();
44455         var sequences = (service ? service.sequences(projection) : []);
44456         var images = (service && showMarkers ? service.images(projection) : []);
44457
44458         var clip = d3_geoIdentity().clipExtent(projection.clipExtent()).stream;
44459         var project = projection.stream;
44460         var makePath = d3_geoPath().projection({ stream: function(output) {
44461             return project(clip(output));
44462         }});
44463
44464         var traces = layer.selectAll('.sequences').selectAll('.sequence')
44465             .data(sequences, function(d) { return d.properties.key; });
44466
44467         traces.exit()
44468             .remove();
44469
44470         traces = traces.enter()
44471             .append('path')
44472             .attr('class', 'sequence')
44473             .merge(traces);
44474
44475         traces
44476             .attr('d', makePath);
44477
44478
44479         var groups = layer.selectAll('.markers').selectAll('.viewfield-group')
44480             .data(images, function(d) { return d.key; });
44481
44482         // exit
44483         groups.exit()
44484             .remove();
44485
44486         // enter
44487         var groupsEnter = groups.enter()
44488             .append('g')
44489             .attr('class', 'viewfield-group')
44490             .on('mouseover', mouseover)
44491             .on('mouseout', mouseout)
44492             .on('click', click);
44493
44494         groupsEnter
44495             .append('g')
44496             .attr('class', 'viewfield-scale');
44497
44498         // update
44499         var markers = groups
44500             .merge(groupsEnter)
44501             .sort(function(a, b) {
44502                 return (a === selected) ? 1
44503                     : (b === selected) ? -1
44504                     : b.loc[1] - a.loc[1];  // sort Y
44505             })
44506             .attr('transform', transform)
44507             .select('.viewfield-scale');
44508
44509
44510         markers.selectAll('circle')
44511             .data([0])
44512             .enter()
44513             .append('circle')
44514             .attr('dx', '0')
44515             .attr('dy', '0')
44516             .attr('r', '6');
44517
44518         var viewfields = markers.selectAll('.viewfield')
44519             .data(showViewfields ? [0] : []);
44520
44521         viewfields.exit()
44522             .remove();
44523
44524         viewfields.enter()               // viewfields may or may not be drawn...
44525             .insert('path', 'circle')    // but if they are, draw below the circles
44526             .attr('class', 'viewfield')
44527             .attr('transform', 'scale(1.5,1.5),translate(-8, -13)')
44528             .attr('d', viewfieldPath);
44529
44530         function viewfieldPath() {
44531             var d = this.parentNode.__data__;
44532             if (d.pano) {
44533                 return 'M 8,13 m -10,0 a 10,10 0 1,0 20,0 a 10,10 0 1,0 -20,0';
44534             } else {
44535                 return 'M 6,9 C 8,8.4 8,8.4 10,9 L 16,-2 C 12,-5 4,-5 0,-2 z';
44536             }
44537         }
44538     }
44539
44540
44541     function drawImages(selection) {
44542         var enabled = svgMapillaryImages.enabled,
44543             service = getService();
44544
44545         layer = selection.selectAll('.layer-mapillary-images')
44546             .data(service ? [0] : []);
44547
44548         layer.exit()
44549             .remove();
44550
44551         var layerEnter = layer.enter()
44552             .append('g')
44553             .attr('class', 'layer-mapillary-images')
44554             .style('display', enabled ? 'block' : 'none');
44555
44556         layerEnter
44557             .append('g')
44558             .attr('class', 'sequences');
44559
44560         layerEnter
44561             .append('g')
44562             .attr('class', 'markers');
44563
44564         layer = layerEnter
44565             .merge(layer);
44566
44567         if (enabled) {
44568             if (service && ~~context.map().zoom() >= minZoom) {
44569                 editOn();
44570                 update();
44571                 service.loadImages(projection);
44572             } else {
44573                 editOff();
44574             }
44575         }
44576     }
44577
44578
44579     drawImages.enabled = function(_) {
44580         if (!arguments.length) return svgMapillaryImages.enabled;
44581         svgMapillaryImages.enabled = _;
44582         if (svgMapillaryImages.enabled) {
44583             showLayer();
44584         } else {
44585             hideLayer();
44586         }
44587         dispatch.call('change');
44588         return this;
44589     };
44590
44591
44592     drawImages.supported = function() {
44593         return !!getService();
44594     };
44595
44596
44597     init();
44598     return drawImages;
44599 }
44600
44601 function svgMapillarySigns(projection, context, dispatch) {
44602     var throttledRedraw = throttle(function () { dispatch.call('change'); }, 1000),
44603         minZoom = 12,
44604         layer = d3_select(null),
44605         _mapillary;
44606
44607
44608     function init() {
44609         if (svgMapillarySigns.initialized) return;  // run once
44610         svgMapillarySigns.enabled = false;
44611         svgMapillarySigns.initialized = true;
44612     }
44613
44614
44615     function getService() {
44616         if (services.mapillary && !_mapillary) {
44617             _mapillary = services.mapillary;
44618             _mapillary.event.on('loadedSigns', throttledRedraw);
44619         } else if (!services.mapillary && _mapillary) {
44620             _mapillary = null;
44621         }
44622         return _mapillary;
44623     }
44624
44625
44626     function showLayer() {
44627         var service = getService();
44628         if (!service) return;
44629
44630         service.loadViewer(context);
44631         editOn();
44632     }
44633
44634
44635     function hideLayer() {
44636         throttledRedraw.cancel();
44637         editOff();
44638     }
44639
44640
44641     function editOn() {
44642         layer.style('display', 'block');
44643     }
44644
44645
44646     function editOff() {
44647         layer.selectAll('.icon-sign').remove();
44648         layer.style('display', 'none');
44649     }
44650
44651
44652     function click(d) {
44653         var service = getService();
44654         if (!service) return;
44655
44656         context.map().centerEase(d.loc);
44657
44658         var selected = service.getSelectedImage();
44659         var selectedImageKey = selected && selected.key;
44660         var imageKey;
44661
44662         // Pick one of the images the sign was detected in,
44663         // preference given to an image already selected.
44664         d.detections.forEach(function(detection) {
44665             if (!imageKey || selectedImageKey === detection.image_key) {
44666                 imageKey = detection.image_key;
44667             }
44668         });
44669
44670         service
44671             .selectImage(null, imageKey)
44672             .updateViewer(imageKey, context)
44673             .showViewer();
44674     }
44675
44676
44677     function update() {
44678         var service = getService();
44679         var data = (service ? service.signs(projection) : []);
44680         var viewer = d3_select('#photoviewer');
44681         var selected = viewer.empty() ? undefined : viewer.datum();
44682         var selectedImageKey = selected && selected.key;
44683
44684         var signs = layer.selectAll('.icon-sign')
44685             .data(data, function(d) { return d.key; });
44686
44687         signs.exit()
44688             .remove();
44689
44690         var enter = signs.enter()
44691             .append('foreignObject')
44692             .attr('class', 'icon-sign')
44693             .attr('width', '24px')      // for Firefox
44694             .attr('height', '24px')     // for Firefox
44695             .classed('selected', function(d) {
44696                 return some(d.detections, function(detection) {
44697                     return detection.image_key === selectedImageKey;
44698                 });
44699             })
44700             .on('click', click);
44701
44702         enter
44703             .append('xhtml:body')
44704             .attr('class', 'icon-sign-body')
44705             .html(service.signHTML);
44706
44707         signs
44708             .merge(enter)
44709             .attr('x', function(d) { return projection(d.loc)[0] - 12; })   // offset by -12px to
44710             .attr('y', function(d) { return projection(d.loc)[1] - 12; });  // center signs on loc
44711     }
44712
44713
44714     function drawSigns(selection) {
44715         var enabled = svgMapillarySigns.enabled,
44716             service = getService();
44717
44718         layer = selection.selectAll('.layer-mapillary-signs')
44719             .data(service ? [0] : []);
44720
44721         layer.exit()
44722             .remove();
44723
44724         layer = layer.enter()
44725             .append('g')
44726             .attr('class', 'layer-mapillary-signs')
44727             .style('display', enabled ? 'block' : 'none')
44728             .merge(layer);
44729
44730         if (enabled) {
44731             if (service && ~~context.map().zoom() >= minZoom) {
44732                 editOn();
44733                 update();
44734                 service.loadSigns(context, projection);
44735             } else {
44736                 editOff();
44737             }
44738         }
44739     }
44740
44741
44742     drawSigns.enabled = function(_) {
44743         if (!arguments.length) return svgMapillarySigns.enabled;
44744         svgMapillarySigns.enabled = _;
44745         if (svgMapillarySigns.enabled) {
44746             showLayer();
44747         } else {
44748             hideLayer();
44749         }
44750         dispatch.call('change');
44751         return this;
44752     };
44753
44754
44755     drawSigns.supported = function() {
44756         var service = getService();
44757         return (service && service.signsSupported());
44758     };
44759
44760
44761     init();
44762     return drawSigns;
44763 }
44764
44765 function svgOpenstreetcamImages(projection, context, dispatch) {
44766     var throttledRedraw = throttle(function () { dispatch.call('change'); }, 1000),
44767         minZoom = 12,
44768         minMarkerZoom = 16,
44769         minViewfieldZoom = 18,
44770         layer = d3_select(null),
44771         _openstreetcam;
44772
44773
44774     function init() {
44775         if (svgOpenstreetcamImages.initialized) return;  // run once
44776         svgOpenstreetcamImages.enabled = false;
44777         svgOpenstreetcamImages.initialized = true;
44778     }
44779
44780
44781     function getService() {
44782         if (services.openstreetcam && !_openstreetcam) {
44783             _openstreetcam = services.openstreetcam;
44784             _openstreetcam.event.on('loadedImages', throttledRedraw);
44785         } else if (!services.openstreetcam && _openstreetcam) {
44786             _openstreetcam = null;
44787         }
44788
44789         return _openstreetcam;
44790     }
44791
44792
44793     function showLayer() {
44794         var service = getService();
44795         if (!service) return;
44796
44797         service.loadViewer(context);
44798         editOn();
44799
44800         layer
44801             .style('opacity', 0)
44802             .transition()
44803             .duration(250)
44804             .style('opacity', 1)
44805             .on('end', function () { dispatch.call('change'); });
44806     }
44807
44808
44809     function hideLayer() {
44810         var service = getService();
44811         if (service) {
44812             service.hideViewer();
44813         }
44814
44815         throttledRedraw.cancel();
44816
44817         layer
44818             .transition()
44819             .duration(250)
44820             .style('opacity', 0)
44821             .on('end', editOff);
44822     }
44823
44824
44825     function editOn() {
44826         layer.style('display', 'block');
44827     }
44828
44829
44830     function editOff() {
44831         layer.selectAll('.viewfield-group').remove();
44832         layer.style('display', 'none');
44833     }
44834
44835
44836     function click(d) {
44837         var service = getService();
44838         if (!service) return;
44839
44840         service
44841             .selectImage(d)
44842             .updateViewer(d)
44843             .showViewer();
44844
44845         context.map().centerEase(d.loc);
44846     }
44847
44848
44849     function mouseover(d) {
44850         var service = getService();
44851         if (service) service.setStyles(d);
44852     }
44853
44854
44855     function mouseout() {
44856         var service = getService();
44857         if (service) service.setStyles(null);
44858     }
44859
44860
44861     function transform(d) {
44862         var t = svgPointTransform(projection)(d);
44863         if (d.ca) {
44864             t += ' rotate(' + Math.floor(d.ca) + ',0,0)';
44865         }
44866         return t;
44867     }
44868
44869
44870     function update() {
44871         var viewer = d3_select('#photoviewer');
44872         var selected = viewer.empty() ? undefined : viewer.datum();
44873
44874         var z = ~~context.map().zoom();
44875         var showMarkers = (z >= minMarkerZoom);
44876         var showViewfields = (z >= minViewfieldZoom);
44877
44878         var service = getService();
44879         var sequences = (service ? service.sequences(projection) : []);
44880         var images = (service && showMarkers ? service.images(projection) : []);
44881
44882         var clip = d3_geoIdentity().clipExtent(projection.clipExtent()).stream;
44883         var project = projection.stream;
44884         var makePath = d3_geoPath().projection({ stream: function(output) {
44885             return project(clip(output));
44886         }});
44887
44888         var traces = layer.selectAll('.sequences').selectAll('.sequence')
44889             .data(sequences, function(d) { return d.properties.key; });
44890
44891         traces.exit()
44892             .remove();
44893
44894         traces = traces.enter()
44895             .append('path')
44896             .attr('class', 'sequence')
44897             .merge(traces);
44898
44899         traces
44900             .attr('d', makePath);
44901
44902
44903         var groups = layer.selectAll('.markers').selectAll('.viewfield-group')
44904             .data(images, function(d) { return d.key; });
44905
44906         // exit
44907         groups.exit()
44908             .remove();
44909
44910         // enter
44911         var groupsEnter = groups.enter()
44912             .append('g')
44913             .attr('class', 'viewfield-group')
44914             .on('mouseover', mouseover)
44915             .on('mouseout', mouseout)
44916             .on('click', click);
44917
44918         groupsEnter
44919             .append('g')
44920             .attr('class', 'viewfield-scale');
44921
44922         // update
44923         var markers = groups
44924             .merge(groupsEnter)
44925             .sort(function(a, b) {
44926                 return (a === selected) ? 1
44927                     : (b === selected) ? -1
44928                     : b.loc[1] - a.loc[1];  // sort Y
44929             })
44930             .attr('transform', transform)
44931             .select('.viewfield-scale');
44932
44933
44934         markers.selectAll('circle')
44935             .data([0])
44936             .enter()
44937             .append('circle')
44938             .attr('dx', '0')
44939             .attr('dy', '0')
44940             .attr('r', '6');
44941
44942         var viewfields = markers.selectAll('.viewfield')
44943             .data(showViewfields ? [0] : []);
44944
44945         viewfields.exit()
44946             .remove();
44947
44948         viewfields.enter()               // viewfields may or may not be drawn...
44949             .insert('path', 'circle')    // but if they are, draw below the circles
44950             .attr('class', 'viewfield')
44951             .attr('transform', 'scale(1.5,1.5),translate(-8, -13)')
44952             .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');
44953     }
44954
44955
44956     function drawImages(selection) {
44957         var enabled = svgOpenstreetcamImages.enabled,
44958             service = getService();
44959
44960         layer = selection.selectAll('.layer-openstreetcam-images')
44961             .data(service ? [0] : []);
44962
44963         layer.exit()
44964             .remove();
44965
44966         var layerEnter = layer.enter()
44967             .append('g')
44968             .attr('class', 'layer-openstreetcam-images')
44969             .style('display', enabled ? 'block' : 'none');
44970
44971         layerEnter
44972             .append('g')
44973             .attr('class', 'sequences');
44974
44975         layerEnter
44976             .append('g')
44977             .attr('class', 'markers');
44978
44979         layer = layerEnter
44980             .merge(layer);
44981
44982         if (enabled) {
44983             if (service && ~~context.map().zoom() >= minZoom) {
44984                 editOn();
44985                 update();
44986                 service.loadImages(projection);
44987             } else {
44988                 editOff();
44989             }
44990         }
44991     }
44992
44993
44994     drawImages.enabled = function(_) {
44995         if (!arguments.length) return svgOpenstreetcamImages.enabled;
44996         svgOpenstreetcamImages.enabled = _;
44997         if (svgOpenstreetcamImages.enabled) {
44998             showLayer();
44999         } else {
45000             hideLayer();
45001         }
45002         dispatch.call('change');
45003         return this;
45004     };
45005
45006
45007     drawImages.supported = function() {
45008         return !!getService();
45009     };
45010
45011
45012     init();
45013     return drawImages;
45014 }
45015
45016 function svgOsm(projection, context, dispatch) {
45017     var enabled = true;
45018
45019
45020     function drawOsm(selection) {
45021         selection.selectAll('.layer-osm')
45022             .data(['areas', 'lines', 'hit', 'halo', 'label'])
45023             .enter()
45024             .append('g')
45025             .attr('class', function(d) { return 'layer-osm layer-' + d; });
45026     }
45027
45028
45029     function showLayer() {
45030         var layer = context.surface().selectAll('.data-layer-osm');
45031         layer.interrupt();
45032
45033         layer
45034             .classed('disabled', false)
45035             .style('opacity', 0)
45036             .transition()
45037             .duration(250)
45038             .style('opacity', 1)
45039             .on('end interrupt', function () {
45040                 dispatch.call('change');
45041             });
45042     }
45043
45044
45045     function hideLayer() {
45046         var layer = context.surface().selectAll('.data-layer-osm');
45047         layer.interrupt();
45048
45049         layer
45050             .transition()
45051             .duration(250)
45052             .style('opacity', 0)
45053             .on('end interrupt', function () {
45054                 layer.classed('disabled', true);
45055                 dispatch.call('change');
45056             });
45057     }
45058
45059
45060     drawOsm.enabled = function(_) {
45061         if (!arguments.length) return enabled;
45062         enabled = _;
45063
45064         if (enabled) {
45065             showLayer();
45066         } else {
45067             hideLayer();
45068         }
45069
45070         dispatch.call('change');
45071         return this;
45072     };
45073
45074
45075     return drawOsm;
45076 }
45077
45078 function svgLayers(projection, context) {
45079     var dispatch$$1 = dispatch('change'),
45080         svg = d3_select(null),
45081         layers = [
45082             { id: 'osm', layer: svgOsm(projection, context, dispatch$$1) },
45083             { id: 'gpx', layer: svgGpx(projection, context, dispatch$$1) },
45084             { id: 'mapillary-images', layer: svgMapillaryImages(projection, context, dispatch$$1) },
45085             { id: 'mapillary-signs',  layer: svgMapillarySigns(projection, context, dispatch$$1) },
45086             { id: 'openstreetcam-images', layer: svgOpenstreetcamImages(projection, context, dispatch$$1) },
45087             { id: 'debug', layer: svgDebug(projection, context, dispatch$$1) }
45088         ];
45089
45090
45091     function drawLayers(selection) {
45092         svg = selection.selectAll('.surface')
45093             .data([0]);
45094
45095         svg = svg.enter()
45096             .append('svg')
45097             .attr('class', 'surface')
45098             .merge(svg);
45099
45100         var defs = svg.selectAll('.surface-defs')
45101             .data([0]);
45102
45103         defs.enter()
45104             .append('defs')
45105             .attr('class', 'surface-defs');
45106
45107         var groups = svg.selectAll('.data-layer')
45108             .data(layers);
45109
45110         groups.exit()
45111             .remove();
45112
45113         groups.enter()
45114             .append('g')
45115             .attr('class', function(d) { return 'data-layer data-layer-' + d.id; })
45116             .merge(groups)
45117             .each(function(d) { d3_select(this).call(d.layer); });
45118     }
45119
45120
45121     drawLayers.all = function() {
45122         return layers;
45123     };
45124
45125
45126     drawLayers.layer = function(id) {
45127         var obj = find$1(layers, function(o) {return o.id === id;});
45128         return obj && obj.layer;
45129     };
45130
45131
45132     drawLayers.only = function(what) {
45133         var arr = [].concat(what);
45134         drawLayers.remove(difference(map$4(layers, 'id'), arr));
45135         return this;
45136     };
45137
45138
45139     drawLayers.remove = function(what) {
45140         var arr = [].concat(what);
45141         arr.forEach(function(id) {
45142             layers = reject(layers, function(o) {return o.id === id;});
45143         });
45144         dispatch$$1.call('change');
45145         return this;
45146     };
45147
45148
45149     drawLayers.add = function(what) {
45150         var arr = [].concat(what);
45151         arr.forEach(function(obj) {
45152             if ('id' in obj && 'layer' in obj) {
45153                 layers.push(obj);
45154             }
45155         });
45156         dispatch$$1.call('change');
45157         return this;
45158     };
45159
45160
45161     drawLayers.dimensions = function(_) {
45162         if (!arguments.length) return utilGetDimensions(svg);
45163         utilSetDimensions(svg, _);
45164         return this;
45165     };
45166
45167
45168     return utilRebind(drawLayers, dispatch$$1, 'on');
45169 }
45170
45171 function svgLines(projection, context) {
45172     var detected = utilDetect();
45173
45174     var highway_stack = {
45175         motorway: 0,
45176         motorway_link: 1,
45177         trunk: 2,
45178         trunk_link: 3,
45179         primary: 4,
45180         primary_link: 5,
45181         secondary: 6,
45182         tertiary: 7,
45183         unclassified: 8,
45184         residential: 9,
45185         service: 10,
45186         footway: 11
45187     };
45188
45189
45190     function drawLines(selection, graph, entities, filter$$1) {
45191
45192
45193         function waystack(a, b) {
45194             var selected = context.selectedIDs(),
45195                 scoreA = selected.indexOf(a.id) !== -1 ? 20 : 0,
45196                 scoreB = selected.indexOf(b.id) !== -1 ? 20 : 0;
45197
45198             if (a.tags.highway) { scoreA -= highway_stack[a.tags.highway]; }
45199             if (b.tags.highway) { scoreB -= highway_stack[b.tags.highway]; }
45200             return scoreA - scoreB;
45201         }
45202
45203
45204         function drawLineGroup(selection, klass, isSelected) {
45205             var lines = selection
45206                 .selectAll('path')
45207                 .filter(filter$$1)
45208                 .data(getPathData(isSelected), osmEntity.key);
45209
45210             lines.exit()
45211                 .remove();
45212
45213             // Optimization: call simple TagClasses only on enter selection. This
45214             // works because osmEntity.key is defined to include the entity v attribute.
45215             lines.enter()
45216                 .append('path')
45217                 .attr('class', function(d) {
45218                     return 'way line ' + klass + ' ' + d.id + (isSelected ? ' selected' : '') +
45219                         (oldMultiPolygonOuters[d.id] ? ' old-multipolygon' : '');
45220                 })
45221                 .call(svgTagClasses())
45222                 .merge(lines)
45223                 .sort(waystack)
45224                 .attr('d', getPath)
45225                 .call(svgTagClasses().tags(svgRelationMemberTags(graph)));
45226
45227             return selection;
45228         }
45229
45230
45231         function getPathData(isSelected) {
45232             return function() {
45233                 var layer = this.parentNode.__data__;
45234                 var data = pathdata[layer] || [];
45235                 return data.filter(function(d) {
45236                     if (isSelected)
45237                         return context.selectedIDs().indexOf(d.id) !== -1;
45238                     else
45239                         return context.selectedIDs().indexOf(d.id) === -1;
45240                 });
45241             };
45242         }
45243
45244
45245         var getPath = svgPath(projection, graph),
45246             ways = [],
45247             pathdata = {},
45248             onewaydata = {},
45249             oldMultiPolygonOuters = {};
45250
45251         for (var i = 0; i < entities.length; i++) {
45252             var entity = entities[i],
45253                 outer = osmSimpleMultipolygonOuterMember(entity, graph);
45254             if (outer) {
45255                 ways.push(entity.mergeTags(outer.tags));
45256                 oldMultiPolygonOuters[outer.id] = true;
45257             } else if (entity.geometry(graph) === 'line') {
45258                 ways.push(entity);
45259             }
45260         }
45261
45262         ways = ways.filter(getPath);
45263         pathdata = groupBy(ways, function(way) { return way.layer(); });
45264
45265         forOwn(pathdata, function(v, k) {
45266             var arr = filter(v, function(d) { return d.isOneWay(); });
45267             onewaydata[k] = flatten(map$4(arr, svgOneWaySegments(projection, graph, 35)));
45268         });
45269
45270
45271         var layer = selection.selectAll('.layer-lines');
45272
45273         var layergroup = layer
45274             .selectAll('g.layergroup')
45275             .data(d3_range(-10, 11));
45276
45277         layergroup = layergroup.enter()
45278             .append('g')
45279             .attr('class', function(d) { return 'layergroup layer' + String(d); })
45280             .merge(layergroup);
45281
45282         layergroup
45283             .selectAll('g.linegroup')
45284             .data(['shadow', 'casing', 'stroke', 'shadow-highlighted', 'casing-highlighted', 'stroke-highlighted'])
45285             .enter()
45286             .append('g')
45287             .attr('class', function(d) { return 'linegroup line-' + d; });
45288
45289
45290         layergroup.selectAll('g.line-shadow')
45291             .call(drawLineGroup, 'shadow', false);
45292         layergroup.selectAll('g.line-casing')
45293             .call(drawLineGroup, 'casing', false);
45294         layergroup.selectAll('g.line-stroke')
45295             .call(drawLineGroup, 'stroke', false);
45296
45297         layergroup.selectAll('g.line-shadow-highlighted')
45298             .call(drawLineGroup, 'shadow', true);
45299         layergroup.selectAll('g.line-casing-highlighted')
45300             .call(drawLineGroup, 'casing', true);
45301         layergroup.selectAll('g.line-stroke-highlighted')
45302             .call(drawLineGroup, 'stroke', true);
45303
45304
45305         var onewaygroup = layergroup
45306             .selectAll('g.onewaygroup')
45307             .data(['oneway']);
45308
45309         onewaygroup = onewaygroup.enter()
45310             .append('g')
45311             .attr('class', 'onewaygroup')
45312             .merge(onewaygroup);
45313
45314         var oneways = onewaygroup
45315             .selectAll('path')
45316             .filter(filter$$1)
45317             .data(
45318                 function() { return onewaydata[this.parentNode.__data__] || []; },
45319                 function(d) { return [d.id, d.index]; }
45320             );
45321
45322         oneways.exit()
45323             .remove();
45324
45325         oneways = oneways.enter()
45326             .append('path')
45327             .attr('class', 'oneway')
45328             .attr('marker-mid', 'url(#oneway-marker)')
45329             .merge(oneways)
45330             .attr('d', function(d) { return d.d; });
45331
45332         if (detected.ie) {
45333             oneways.each(function() { this.parentNode.insertBefore(this, this); });
45334         }
45335     }
45336
45337
45338     return drawLines;
45339 }
45340
45341 function svgMidpoints(projection, context) {
45342
45343     return function drawMidpoints(selection, graph, entities, filter, extent) {
45344         var layer = selection.selectAll('.layer-hit');
45345
45346         var mode = context.mode();
45347         if (mode && mode.id !== 'select') {
45348             layer.selectAll('g.midpoint').remove();
45349             return;
45350         }
45351
45352         var poly = extent.polygon(),
45353             midpoints = {};
45354
45355         for (var i = 0; i < entities.length; i++) {
45356             var entity = entities[i];
45357
45358             if (entity.type !== 'way')
45359                 continue;
45360             if (!filter(entity))
45361                 continue;
45362             if (context.selectedIDs().indexOf(entity.id) < 0)
45363                 continue;
45364
45365             var nodes = graph.childNodes(entity);
45366             for (var j = 0; j < nodes.length - 1; j++) {
45367
45368                 var a = nodes[j],
45369                     b = nodes[j + 1],
45370                     id = [a.id, b.id].sort().join('-');
45371
45372                 if (midpoints[id]) {
45373                     midpoints[id].parents.push(entity);
45374                 } else {
45375                     if (geoEuclideanDistance(projection(a.loc), projection(b.loc)) > 40) {
45376                         var point = geoInterp(a.loc, b.loc, 0.5),
45377                             loc = null;
45378
45379                         if (extent.intersects(point)) {
45380                             loc = point;
45381                         } else {
45382                             for (var k = 0; k < 4; k++) {
45383                                 point = geoLineIntersection([a.loc, b.loc], [poly[k], poly[k + 1]]);
45384                                 if (point &&
45385                                     geoEuclideanDistance(projection(a.loc), projection(point)) > 20 &&
45386                                     geoEuclideanDistance(projection(b.loc), projection(point)) > 20)
45387                                 {
45388                                     loc = point;
45389                                     break;
45390                                 }
45391                             }
45392                         }
45393
45394                         if (loc) {
45395                             midpoints[id] = {
45396                                 type: 'midpoint',
45397                                 id: id,
45398                                 loc: loc,
45399                                 edge: [a.id, b.id],
45400                                 parents: [entity]
45401                             };
45402                         }
45403                     }
45404                 }
45405             }
45406         }
45407
45408
45409         function midpointFilter(d) {
45410             if (midpoints[d.id])
45411                 return true;
45412
45413             for (var i = 0; i < d.parents.length; i++) {
45414                 if (filter(d.parents[i])) {
45415                     return true;
45416                 }
45417             }
45418
45419             return false;
45420         }
45421
45422
45423         var groups = layer
45424             .selectAll('g.midpoint')
45425             .filter(midpointFilter)
45426             .data(values$1(midpoints), function(d) { return d.id; });
45427
45428         groups.exit()
45429             .remove();
45430
45431         var enter = groups.enter()
45432             .insert('g', ':first-child')
45433             .attr('class', 'midpoint');
45434
45435         enter.append('polygon')
45436             .attr('points', '-6,8 10,0 -6,-8')
45437             .attr('class', 'shadow');
45438
45439         enter.append('polygon')
45440             .attr('points', '-3,4 5,0 -3,-4')
45441             .attr('class', 'fill');
45442
45443         groups = groups
45444             .merge(enter)
45445             .attr('transform', function(d) {
45446                 var translate = svgPointTransform(projection),
45447                     a = graph.entity(d.edge[0]),
45448                     b = graph.entity(d.edge[1]),
45449                     angleVal = Math.round(geoAngle(a, b, projection) * (180 / Math.PI));
45450                 return translate(d) + ' rotate(' + angleVal + ')';
45451             })
45452             .call(svgTagClasses().tags(
45453                 function(d) { return d.parents[0].tags; }
45454             ));
45455
45456         // Propagate data bindings.
45457         groups.select('polygon.shadow');
45458         groups.select('polygon.fill');
45459
45460     };
45461 }
45462
45463 function svgOneWaySegments(projection, graph, dt) {
45464     return function(entity) {
45465         var a,
45466             b,
45467             i = 0,
45468             offset = dt,
45469             segments = [],
45470             clip = d3_geoIdentity().clipExtent(projection.clipExtent()).stream,
45471             coordinates = graph.childNodes(entity).map(function(n) {
45472                 return n.loc;
45473             });
45474
45475         if (entity.tags.oneway === '-1') coordinates.reverse();
45476
45477         d3_geoStream({
45478             type: 'LineString',
45479             coordinates: coordinates
45480         }, projection.stream(clip({
45481             lineStart: function() {},
45482             lineEnd: function() {
45483                 a = null;
45484             },
45485             point: function(x, y) {
45486                 b = [x, y];
45487
45488                 if (a) {
45489                     var span = geoEuclideanDistance(a, b) - offset;
45490
45491                     if (span >= 0) {
45492                         var angle = Math.atan2(b[1] - a[1], b[0] - a[0]),
45493                             dx = dt * Math.cos(angle),
45494                             dy = dt * Math.sin(angle),
45495                             p = [a[0] + offset * Math.cos(angle),
45496                                  a[1] + offset * Math.sin(angle)];
45497
45498                         var segment = 'M' + a[0] + ',' + a[1] +
45499                                       'L' + p[0] + ',' + p[1];
45500
45501                         for (span -= dt; span >= 0; span -= dt) {
45502                             p[0] += dx;
45503                             p[1] += dy;
45504                             segment += 'L' + p[0] + ',' + p[1];
45505                         }
45506
45507                         segment += 'L' + b[0] + ',' + b[1];
45508                         segments.push({id: entity.id, index: i, d: segment});
45509                     }
45510
45511                     offset = -span;
45512                     i++;
45513                 }
45514
45515                 a = b;
45516             }
45517         })));
45518
45519         return segments;
45520     };
45521 }
45522
45523 function svgPath(projection, graph, isArea) {
45524
45525     // Explanation of magic numbers:
45526     // "padding" here allows space for strokes to extend beyond the viewport,
45527     // so that the stroke isn't drawn along the edge of the viewport when
45528     // the shape is clipped.
45529     //
45530     // When drawing lines, pad viewport by 5px.
45531     // When drawing areas, pad viewport by 65px in each direction to allow
45532     // for 60px area fill stroke (see ".fill-partial path.fill" css rule)
45533
45534     var cache = {},
45535         padding = isArea ? 65 : 5,
45536         viewport = projection.clipExtent(),
45537         paddedExtent = [
45538             [viewport[0][0] - padding, viewport[0][1] - padding],
45539             [viewport[1][0] + padding, viewport[1][1] + padding]
45540         ],
45541         clip = d3_geoIdentity().clipExtent(paddedExtent).stream,
45542         project = projection.stream,
45543         path = d3_geoPath()
45544             .projection({stream: function(output) { return project(clip(output)); }});
45545
45546     return function(entity) {
45547         if (entity.id in cache) {
45548             return cache[entity.id];
45549         } else {
45550             return cache[entity.id] = path(entity.asGeoJSON(graph));
45551         }
45552     };
45553 }
45554
45555 function svgPoints(projection, context) {
45556
45557     function markerPath(selection, klass) {
45558         selection
45559             .attr('class', klass)
45560             .attr('transform', 'translate(-8, -23)')
45561             .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');
45562     }
45563
45564     function sortY(a, b) {
45565         return b.loc[1] - a.loc[1];
45566     }
45567
45568
45569     return function drawPoints(selection, graph, entities, filter$$1) {
45570         var wireframe = context.surface().classed('fill-wireframe'),
45571             points = wireframe ? [] : filter(entities, function(e) {
45572                 return e.geometry(graph) === 'point';
45573             });
45574
45575         points.sort(sortY);
45576
45577         var layer = selection.selectAll('.layer-hit');
45578
45579         var groups = layer.selectAll('g.point')
45580             .filter(filter$$1)
45581             .data(points, osmEntity.key);
45582
45583         groups.exit()
45584             .remove();
45585
45586         var enter = groups.enter()
45587             .append('g')
45588             .attr('class', function(d) { return 'node point ' + d.id; })
45589             .order();
45590
45591         enter.append('path')
45592             .call(markerPath, 'shadow');
45593
45594         enter.append('ellipse')
45595             .attr('cx', 0.5)
45596             .attr('cy', 1)
45597             .attr('rx', 6.5)
45598             .attr('ry', 3)
45599             .attr('class', 'stroke');
45600
45601         enter.append('path')
45602             .call(markerPath, 'stroke');
45603
45604         enter.append('use')
45605             .attr('transform', 'translate(-5, -19)')
45606             .attr('class', 'icon')
45607             .attr('width', '11px')
45608             .attr('height', '11px');
45609
45610         groups = groups
45611             .merge(enter)
45612             .attr('transform', svgPointTransform(projection))
45613             .call(svgTagClasses());
45614
45615         // Selecting the following implicitly
45616         // sets the data (point entity) on the element
45617         groups.select('.shadow');
45618         groups.select('.stroke');
45619         groups.select('.icon')
45620             .attr('xlink:href', function(entity) {
45621                 var preset = context.presets().match(entity, graph),
45622                     picon = preset && preset.icon;
45623
45624                 if (!picon)
45625                     return '';
45626                 else {
45627                     var isMaki = dataFeatureIcons.indexOf(picon) !== -1;
45628                     return '#' + picon + (isMaki ? '-11' : '');
45629                 }
45630             });
45631     };
45632 }
45633
45634 function svgRelationMemberTags(graph) {
45635     return function(entity) {
45636         var tags = entity.tags;
45637         graph.parentRelations(entity).forEach(function(relation) {
45638             var type = relation.tags.type;
45639             if (type === 'multipolygon' || type === 'boundary') {
45640                 tags = assignIn({}, relation.tags, tags);
45641             }
45642         });
45643         return tags;
45644     };
45645 }
45646
45647 function svgTagClasses() {
45648     var primaries = [
45649             'building', 'highway', 'railway', 'waterway', 'aeroway',
45650             'motorway', 'boundary', 'power', 'amenity', 'natural', 'landuse',
45651             'leisure', 'military', 'place'
45652         ],
45653         statuses = [
45654             'proposed', 'construction', 'disused', 'abandoned', 'dismantled',
45655             'razed', 'demolished', 'obliterated', 'intermittent'
45656         ],
45657         secondaries = [
45658             'oneway', 'bridge', 'tunnel', 'embankment', 'cutting', 'barrier',
45659             'surface', 'tracktype', 'crossing', 'service', 'sport'
45660         ],
45661         tagClassRe = /^tag-/,
45662         tags = function(entity) { return entity.tags; };
45663
45664
45665     var tagClasses = function(selection) {
45666         selection.each(function tagClassesEach(entity) {
45667             var value = this.className,
45668                 classes, primary, status;
45669
45670             if (value.baseVal !== undefined) value = value.baseVal;
45671
45672             classes = value.trim().split(/\s+/).filter(function(name) {
45673                 return name.length && !tagClassRe.test(name);
45674             }).join(' ');
45675
45676             var t = tags(entity), i, k, v;
45677
45678             // pick at most one primary classification tag..
45679             for (i = 0; i < primaries.length; i++) {
45680                 k = primaries[i];
45681                 v = t[k];
45682                 if (!v || v === 'no') continue;
45683
45684                 primary = k;
45685                 if (statuses.indexOf(v) !== -1) {   // e.g. `railway=abandoned`
45686                     status = v;
45687                     classes += ' tag-' + k;
45688                 } else {
45689                     classes += ' tag-' + k + ' tag-' + k + '-' + v;
45690                 }
45691
45692                 break;
45693             }
45694
45695             // add at most one status tag, only if relates to primary tag..
45696             if (!status) {
45697                 for (i = 0; i < statuses.length; i++) {
45698                     k = statuses[i];
45699                     v = t[k];
45700                     if (!v || v === 'no') continue;
45701
45702                     if (v === 'yes') {   // e.g. `railway=rail + abandoned=yes`
45703                         status = k;
45704                     }
45705                     else if (primary && primary === v) {  // e.g. `railway=rail + abandoned=railway`
45706                         status = k;
45707                     } else if (!primary && primaries.indexOf(v) !== -1) {  // e.g. `abandoned=railway`
45708                         status = k;
45709                         primary = v;
45710                         classes += ' tag-' + v;
45711                     }  // else ignore e.g.  `highway=path + abandoned=railway`
45712
45713                     if (status) break;
45714                 }
45715             }
45716
45717             if (status) {
45718                 classes += ' tag-status tag-status-' + status;
45719             }
45720
45721             // add any secondary (structure) tags
45722             for (i = 0; i < secondaries.length; i++) {
45723                 k = secondaries[i];
45724                 v = t[k];
45725                 if (!v || v === 'no') continue;
45726                 classes += ' tag-' + k + ' tag-' + k + '-' + v;
45727             }
45728
45729             // For highways, look for surface tagging..
45730             if (primary === 'highway') {
45731                 var paved = (t.highway !== 'track');
45732                 for (k in t) {
45733                     v = t[k];
45734                     if (k in osmPavedTags) {
45735                         paved = !!osmPavedTags[k][v];
45736                         break;
45737                     }
45738                 }
45739                 if (!paved) {
45740                     classes += ' tag-unpaved';
45741                 }
45742             }
45743
45744             classes = classes.trim();
45745
45746             if (classes !== value) {
45747                 d3_select(this).attr('class', classes);
45748             }
45749         });
45750     };
45751
45752
45753     tagClasses.tags = function(_) {
45754         if (!arguments.length) return tags;
45755         tags = _;
45756         return tagClasses;
45757     };
45758
45759     return tagClasses;
45760 }
45761
45762 function svgTurns(projection) {
45763
45764     return function drawTurns(selection, graph, turns) {
45765
45766         function key(turn) {
45767             return [turn.from.node + turn.via.node + turn.to.node].join('-');
45768         }
45769
45770         function icon(turn) {
45771             var u = turn.u ? '-u' : '';
45772             if (!turn.restriction)
45773                 return '#turn-yes' + u;
45774             var restriction = graph.entity(turn.restriction).tags.restriction;
45775             return '#turn-' +
45776                 (!turn.indirect_restriction && /^only_/.test(restriction) ? 'only' : 'no') + u;
45777         }
45778
45779         var groups = selection.selectAll('.layer-hit').selectAll('g.turn')
45780             .data(turns, key);
45781
45782         groups.exit()
45783             .remove();
45784
45785
45786         var enter = groups.enter()
45787             .append('g')
45788             .attr('class', 'turn');
45789
45790         var nEnter = enter
45791             .filter(function (turn) { return !turn.u; });
45792
45793         nEnter.append('rect')
45794             .attr('transform', 'translate(-22, -12)')
45795             .attr('width', '44')
45796             .attr('height', '24');
45797
45798         nEnter.append('use')
45799             .attr('transform', 'translate(-22, -12)')
45800             .attr('width', '44')
45801             .attr('height', '24');
45802
45803
45804         var uEnter = enter
45805             .filter(function (turn) { return turn.u; });
45806
45807         uEnter.append('circle')
45808             .attr('r', '16');
45809
45810         uEnter.append('use')
45811             .attr('transform', 'translate(-16, -16)')
45812             .attr('width', '32')
45813             .attr('height', '32');
45814
45815
45816         groups = groups
45817             .merge(enter);
45818
45819         groups
45820             .attr('transform', function (turn) {
45821                 var v = graph.entity(turn.via.node),
45822                     t = graph.entity(turn.to.node),
45823                     a = geoAngle(v, t, projection),
45824                     p = projection(v.loc),
45825                     r = turn.u ? 0 : 60;
45826
45827                 return 'translate(' + (r * Math.cos(a) + p[0]) + ',' + (r * Math.sin(a) + p[1]) + ') ' +
45828                     'rotate(' + a * 180 / Math.PI + ')';
45829             });
45830
45831         groups.select('use')
45832             .attr('xlink:href', icon);
45833
45834         groups.select('rect');
45835         groups.select('circle');
45836
45837         return this;
45838     };
45839 }
45840
45841 function svgVertices(projection, context) {
45842     var radiuses = {
45843         //       z16-, z17, z18+, tagged
45844         shadow: [6,    7.5,   7.5,  11.5],
45845         stroke: [2.5,  3.5,   3.5,  7],
45846         fill:   [1,    1.5,   1.5,  1.5]
45847     };
45848
45849     var hover;
45850
45851
45852     function siblingAndChildVertices(ids, graph, extent) {
45853         var vertices = {};
45854
45855         function addChildVertices(entity) {
45856             if (!context.features().isHiddenFeature(entity, graph, entity.geometry(graph))) {
45857                 var i;
45858                 if (entity.type === 'way') {
45859                     for (i = 0; i < entity.nodes.length; i++) {
45860                         addChildVertices(graph.entity(entity.nodes[i]));
45861                     }
45862                 } else if (entity.type === 'relation') {
45863                     for (i = 0; i < entity.members.length; i++) {
45864                         var member = context.hasEntity(entity.members[i].id);
45865                         if (member) {
45866                             addChildVertices(member);
45867                         }
45868                     }
45869                 } else if (entity.intersects(extent, graph)) {
45870                     vertices[entity.id] = entity;
45871                 }
45872             }
45873         }
45874
45875         ids.forEach(function(id) {
45876             var entity = context.hasEntity(id);
45877             if (entity && entity.type === 'node') {
45878                 vertices[entity.id] = entity;
45879                 context.graph().parentWays(entity).forEach(function(entity) {
45880                     addChildVertices(entity);
45881                 });
45882             } else if (entity) {
45883                 addChildVertices(entity);
45884             }
45885         });
45886
45887         return vertices;
45888     }
45889
45890
45891     function draw(selection, vertices, klass, graph, zoom, siblings) {
45892
45893         function icon(entity) {
45894             if (entity.id in icons) return icons[entity.id];
45895             icons[entity.id] =
45896                 entity.hasInterestingTags() &&
45897                 context.presets().match(entity, graph).icon;
45898             return icons[entity.id];
45899         }
45900
45901         function setClass(klass) {
45902             return function(entity) {
45903                 this.setAttribute('class', 'node vertex ' + klass + ' ' + entity.id);
45904             };
45905         }
45906
45907         function setAttributes(selection) {
45908             ['shadow','stroke','fill'].forEach(function(klass) {
45909                 var rads = radiuses[klass];
45910                 selection.selectAll('.' + klass)
45911                     .each(function(entity) {
45912                         var i = z && icon(entity),
45913                             c = i ? 0.5 : 0,
45914                             r = rads[i ? 3 : z];
45915
45916                         // slightly increase the size of unconnected endpoints #3775
45917                         if (entity.isEndpoint(graph) && !entity.isConnected(graph)) {
45918                             r += 1.5;
45919                         }
45920
45921                         this.setAttribute('cx', c);
45922                         this.setAttribute('cy', -c);
45923                         this.setAttribute('r', r);
45924                         if (i && klass === 'fill') {
45925                             this.setAttribute('visibility', 'hidden');
45926                         } else {
45927                             this.removeAttribute('visibility');
45928                         }
45929                     });
45930             });
45931
45932             selection.selectAll('use')
45933                 .each(function() {
45934                     if (z) {
45935                         this.removeAttribute('visibility');
45936                     } else {
45937                         this.setAttribute('visibility', 'hidden');
45938                     }
45939                 });
45940         }
45941
45942
45943         siblings = siblings || {};
45944
45945         var icons = {},
45946             z = (zoom < 17 ? 0 : zoom < 18 ? 1 : 2);
45947
45948         var groups = selection
45949             .data(vertices, osmEntity.key);
45950
45951         groups.exit()
45952             .remove();
45953
45954         var enter = groups.enter()
45955             .append('g')
45956             .attr('class', function(d) { return 'node vertex ' + klass + ' ' + d.id; });
45957
45958         enter.append('circle')
45959             .each(setClass('shadow'));
45960
45961         enter.append('circle')
45962             .each(setClass('stroke'));
45963
45964         // Vertices with icons get a `use`.
45965         enter.filter(function(d) { return icon(d); })
45966             .append('use')
45967             .attr('transform', 'translate(-5, -6)')
45968             .attr('xlink:href', function(d) {
45969                 var picon = icon(d),
45970                     isMaki = dataFeatureIcons.indexOf(picon) !== -1;
45971                 return '#' + picon + (isMaki ? '-11' : '');
45972             })
45973             .attr('width', '11px')
45974             .attr('height', '11px')
45975             .each(setClass('icon'));
45976
45977         // Vertices with tags get a fill.
45978         enter.filter(function(d) { return d.hasInterestingTags(); })
45979             .append('circle')
45980             .each(setClass('fill'));
45981
45982         groups
45983             .merge(enter)
45984             .attr('transform', svgPointTransform(projection))
45985             .classed('sibling', function(entity) { return entity.id in siblings; })
45986             .classed('shared', function(entity) { return graph.isShared(entity); })
45987             .classed('endpoint', function(entity) { return entity.isEndpoint(graph); })
45988             .call(setAttributes);
45989     }
45990
45991
45992     function drawVertices(selection, graph, entities, filter, extent, zoom) {
45993         var siblings = siblingAndChildVertices(context.selectedIDs(), graph, extent),
45994             wireframe = context.surface().classed('fill-wireframe'),
45995             vertices = [];
45996
45997         for (var i = 0; i < entities.length; i++) {
45998             var entity = entities[i],
45999                 geometry = entity.geometry(graph);
46000
46001             if (wireframe && geometry === 'point') {
46002                 vertices.push(entity);
46003                 continue;
46004             }
46005
46006             if (geometry !== 'vertex')
46007                 continue;
46008
46009             if (entity.id in siblings ||
46010                 entity.hasInterestingTags() ||
46011                 entity.isEndpoint(graph) ||
46012                 entity.isConnected(graph)) {
46013                 vertices.push(entity);
46014             }
46015         }
46016
46017         var layer = selection.selectAll('.layer-hit');
46018         layer.selectAll('g.vertex.vertex-persistent')
46019             .filter(filter)
46020             .call(draw, vertices, 'vertex-persistent', graph, zoom, siblings);
46021
46022         drawHover(selection, graph, extent, zoom);
46023     }
46024
46025
46026     function drawHover(selection, graph, extent, zoom) {
46027         var hovered = hover ? siblingAndChildVertices([hover.id], graph, extent) : {};
46028         var layer = selection.selectAll('.layer-hit');
46029
46030         layer.selectAll('g.vertex.vertex-hover')
46031             .call(draw, values$1(hovered), 'vertex-hover', graph, zoom);
46032     }
46033
46034
46035     drawVertices.drawHover = function(selection, graph, target, extent, zoom) {
46036         if (target === hover) return;
46037         hover = target;
46038         drawHover(selection, graph, extent, zoom);
46039     };
46040
46041     return drawVertices;
46042 }
46043
46044 function uiAccount(context) {
46045     var osm = context.connection();
46046
46047
46048     function update(selection) {
46049         if (!osm) return;
46050
46051         if (!osm.authenticated()) {
46052             selection.selectAll('#userLink, #logoutLink')
46053                 .classed('hide', true);
46054             return;
46055         }
46056
46057         osm.userDetails(function(err, details) {
46058             var userLink = selection.select('#userLink'),
46059                 logoutLink = selection.select('#logoutLink');
46060
46061             userLink.html('');
46062             logoutLink.html('');
46063
46064             if (err) return;
46065
46066             selection.selectAll('#userLink, #logoutLink')
46067                 .classed('hide', false);
46068
46069             // Link
46070             userLink.append('a')
46071                 .attr('href', osm.userURL(details.display_name))
46072                 .attr('target', '_blank');
46073
46074             // Add thumbnail or dont
46075             if (details.image_url) {
46076                 userLink.append('img')
46077                     .attr('class', 'icon pre-text user-icon')
46078                     .attr('src', details.image_url);
46079             } else {
46080                 userLink
46081                     .call(svgIcon('#icon-avatar', 'pre-text light'));
46082             }
46083
46084             // Add user name
46085             userLink.append('span')
46086                 .attr('class', 'label')
46087                 .text(details.display_name);
46088
46089             logoutLink.append('a')
46090                 .attr('class', 'logout')
46091                 .attr('href', '#')
46092                 .text(t('logout'))
46093                 .on('click.logout', function() {
46094                     event.preventDefault();
46095                     osm.logout();
46096                 });
46097         });
46098     }
46099
46100
46101     return function(selection) {
46102         selection.append('li')
46103             .attr('id', 'logoutLink')
46104             .classed('hide', true);
46105
46106         selection.append('li')
46107             .attr('id', 'userLink')
46108             .classed('hide', true);
46109
46110         if (osm) {
46111             osm.on('change.account', function() { update(selection); });
46112             update(selection);
46113         }
46114     };
46115 }
46116
46117 function uiAttribution(context) {
46118     var selection;
46119
46120
46121     function attribution(data, klass) {
46122         var div = selection.selectAll('.' + klass)
46123             .data([0]);
46124
46125         div = div.enter()
46126             .append('div')
46127             .attr('class', klass)
46128             .merge(div);
46129
46130
46131         var background = div.selectAll('.attribution')
46132             .data(data, function(d) { return d.name(); });
46133
46134         background.exit()
46135             .remove();
46136
46137         background = background.enter()
46138             .append('span')
46139             .attr('class', 'attribution')
46140             .each(function(d) {
46141                 if (d.terms_html) {
46142                     d3_select(this)
46143                         .html(d.terms_html);
46144                     return;
46145                 }
46146
46147                 var selection;
46148                 if (d.terms_url) {
46149                     selection = d3_select(this)
46150                         .append('a')
46151                         .attr('href', d.terms_url)
46152                         .attr('target', '_blank');
46153                 } else {
46154                     selection = d3_select(this);
46155                 }
46156
46157
46158                 var id_safe = d.id.replace('.', '<TX_DOT>');
46159                 var terms_text = t('imagery.' + id_safe + '.attribution.text',
46160                     { default: d.terms_text || d.id || d.name() }
46161                 );
46162
46163                 if (d.icon && !d.overlay) {
46164                     selection
46165                         .append('img')
46166                         .attr('class', 'source-image')
46167                         .attr('src', d.icon);
46168                 }
46169
46170                 selection
46171                     .append('span')
46172                     .attr('class', 'attribution-text')
46173                     .text(terms_text);
46174             })
46175             .merge(background);
46176
46177
46178         var copyright = background.selectAll('.copyright-notice')
46179             .data(function(d) {
46180                 var notice = d.copyrightNotices(context.map().zoom(), context.map().extent());
46181                 return notice ? [notice] : [];
46182             });
46183
46184         copyright.exit()
46185             .remove();
46186
46187         copyright = copyright.enter()
46188             .append('span')
46189             .attr('class', 'copyright-notice')
46190             .merge(copyright);
46191
46192         copyright
46193             .text(String);
46194     }
46195
46196
46197     function update() {
46198         attribution([context.background().baseLayerSource()], 'base-layer-attribution');
46199         attribution(context.background().overlayLayerSources().filter(function (s) {
46200             return s.validZoom(context.map().zoom());
46201         }), 'overlay-layer-attribution');
46202     }
46203
46204
46205     return function(select$$1) {
46206         selection = select$$1;
46207
46208         context.background()
46209             .on('change.attribution', update);
46210
46211         context.map()
46212             .on('move.attribution', throttle(update, 400, {leading: false}));
46213
46214         update();
46215     };
46216 }
46217
46218 function localeDateString(s) {
46219     if (!s) return null;
46220     var d = new Date(s);
46221     if (isNaN(d.getTime())) return null;
46222     return d.toLocaleDateString();
46223 }
46224
46225 function vintageRange(vintage) {
46226     var s;
46227     if (vintage.start || vintage.end) {
46228         s = (vintage.start || '?');
46229         if (vintage.start !== vintage.end) {
46230             s += ' - ' + (vintage.end || '?');
46231         }
46232     }
46233     return s;
46234 }
46235
46236
46237 function rendererBackgroundSource(data) {
46238     var source = clone(data),
46239         offset = [0, 0],
46240         name = source.name,
46241         description = source.description,
46242         best = !!source.best,
46243         template = source.template;
46244
46245     source.scaleExtent = data.scaleExtent || [0, 22];
46246     source.overzoom = data.overzoom !== false;
46247
46248
46249     source.offset = function(_) {
46250         if (!arguments.length) return offset;
46251         offset = _;
46252         return source;
46253     };
46254
46255
46256     source.nudge = function(_, zoomlevel) {
46257         offset[0] += _[0] / Math.pow(2, zoomlevel);
46258         offset[1] += _[1] / Math.pow(2, zoomlevel);
46259         return source;
46260     };
46261
46262
46263     source.name = function() {
46264         var id_safe = source.id.replace('.', '<TX_DOT>');
46265         return t('imagery.' + id_safe + '.name', { default: name });
46266     };
46267
46268
46269     source.description = function() {
46270         var id_safe = source.id.replace('.', '<TX_DOT>');
46271         return t('imagery.' + id_safe + '.description', { default: description });
46272     };
46273
46274
46275     source.best = function() {
46276         return best;
46277     };
46278
46279
46280     source.area = function() {
46281         if (!data.polygon) return Number.MAX_VALUE;  // worldwide
46282         var area = d3_geoArea({ type: 'MultiPolygon', coordinates: [ data.polygon ] });
46283         return isNaN(area) ? 0 : area;
46284     };
46285
46286
46287     source.imageryUsed = function() {
46288         return name || source.id;
46289     };
46290
46291
46292     source.template = function(_) {
46293         if (!arguments.length) return template;
46294         if (source.id === 'custom') template = _;
46295         return source;
46296     };
46297
46298
46299     source.url = function(coord) {
46300         return template
46301             .replace('{x}', coord[0])
46302             .replace('{y}', coord[1])
46303             // TMS-flipped y coordinate
46304             .replace(/\{[t-]y\}/, Math.pow(2, coord[2]) - coord[1] - 1)
46305             .replace(/\{z(oom)?\}/, coord[2])
46306             .replace(/\{switch:([^}]+)\}/, function(s, r) {
46307                 var subdomains = r.split(',');
46308                 return subdomains[(coord[0] + coord[1]) % subdomains.length];
46309             })
46310             .replace('{u}', function() {
46311                 var u = '';
46312                 for (var zoom = coord[2]; zoom > 0; zoom--) {
46313                     var b = 0;
46314                     var mask = 1 << (zoom - 1);
46315                     if ((coord[0] & mask) !== 0) b++;
46316                     if ((coord[1] & mask) !== 0) b += 2;
46317                     u += b.toString();
46318                 }
46319                 return u;
46320             });
46321     };
46322
46323
46324     source.intersects = function(extent) {
46325         extent = extent.polygon();
46326         return !data.polygon || data.polygon.some(function(polygon) {
46327             return geoPolygonIntersectsPolygon(polygon, extent, true);
46328         });
46329     };
46330
46331
46332     source.validZoom = function(z) {
46333         return source.scaleExtent[0] <= z &&
46334             (source.overzoom || source.scaleExtent[1] > z);
46335     };
46336
46337
46338     source.isLocatorOverlay = function() {
46339         return source.id === 'mapbox_locator_overlay';
46340     };
46341
46342
46343     /* hides a source from the list, but leaves it available for use */
46344     source.isHidden = function() {
46345         return source.id === 'DigitalGlobe-Premium-vintage' ||
46346             source.id === 'DigitalGlobe-Standard-vintage';
46347     };
46348
46349
46350     source.copyrightNotices = function() {};
46351
46352
46353     source.getMetadata = function(center, tileCoord, callback) {
46354         var vintage = {
46355             start: localeDateString(source.startDate),
46356             end: localeDateString(source.endDate)
46357         };
46358         vintage.range = vintageRange(vintage);
46359
46360         var metadata = { vintage: vintage };
46361         callback(null, metadata);
46362     };
46363
46364
46365     return source;
46366 }
46367
46368
46369 rendererBackgroundSource.Bing = function(data, dispatch) {
46370     // http://msdn.microsoft.com/en-us/library/ff701716.aspx
46371     // http://msdn.microsoft.com/en-us/library/ff701701.aspx
46372
46373     data.template = 'https://ecn.t{switch:0,1,2,3}.tiles.virtualearth.net/tiles/a{u}.jpeg?g=587&mkt=en-gb&n=z';
46374
46375     var bing = rendererBackgroundSource(data),
46376         key = 'Arzdiw4nlOJzRwOz__qailc8NiR31Tt51dN2D7cm57NrnceZnCpgOkmJhNpGoppU', // Same as P2 and JOSM
46377         url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial?include=ImageryProviders&key=' +
46378             key + '&jsonp={callback}',
46379         cache = {},
46380         inflight = {},
46381         providers = [];
46382
46383     jsonpRequest(url, function(json) {
46384         providers = json.resourceSets[0].resources[0].imageryProviders.map(function(provider) {
46385             return {
46386                 attribution: provider.attribution,
46387                 areas: provider.coverageAreas.map(function(area) {
46388                     return {
46389                         zoom: [area.zoomMin, area.zoomMax],
46390                         extent: geoExtent([area.bbox[1], area.bbox[0]], [area.bbox[3], area.bbox[2]])
46391                     };
46392                 })
46393             };
46394         });
46395         dispatch.call('change');
46396     });
46397
46398
46399     bing.copyrightNotices = function(zoom, extent) {
46400         zoom = Math.min(zoom, 21);
46401         return providers.filter(function(provider) {
46402             return some(provider.areas, function(area) {
46403                 return extent.intersects(area.extent) &&
46404                     area.zoom[0] <= zoom &&
46405                     area.zoom[1] >= zoom;
46406             });
46407         }).map(function(provider) {
46408             return provider.attribution;
46409         }).join(', ');
46410     };
46411
46412
46413     bing.getMetadata = function(center, tileCoord, callback) {
46414         var tileId = tileCoord.slice(0, 3).join('/'),
46415             zoom = Math.min(tileCoord[2], 21),
46416             centerPoint = center[1] + ',' + center[0],  // lat,lng
46417             url = 'https://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial/' + centerPoint +
46418                 '?zl=' + zoom + '&key=' + key + '&jsonp={callback}';
46419
46420         if (inflight[tileId]) return;
46421
46422         if (!cache[tileId]) {
46423             cache[tileId] = {};
46424         }
46425         if (cache[tileId] && cache[tileId].metadata) {
46426             return callback(null, cache[tileId].metadata);
46427         }
46428
46429         inflight[tileId] = true;
46430         jsonpRequest(url, function(result) {
46431             delete inflight[tileId];
46432
46433             var err = (!result && 'Unknown Error') || result.errorDetails;
46434             if (err) {
46435                 return callback(err);
46436             } else {
46437                 var vintage = {
46438                     start: localeDateString(result.resourceSets[0].resources[0].vintageStart),
46439                     end: localeDateString(result.resourceSets[0].resources[0].vintageEnd)
46440                 };
46441                 vintage.range = vintageRange(vintage);
46442
46443                 var metadata = { vintage: vintage };
46444                 cache[tileId].metadata = metadata;
46445                 return callback(null, metadata);
46446             }
46447         });
46448     };
46449
46450
46451     bing.terms_url = 'https://blog.openstreetmap.org/2010/11/30/microsoft-imagery-details';
46452
46453
46454     return bing;
46455 };
46456
46457
46458
46459 rendererBackgroundSource.Esri = function(data) {
46460
46461     // don't request blank tiles, instead overzoom real tiles - #4327
46462     // deprecated technique, but it works (for now)
46463     if (data.template.match(/blankTile/) === null) {
46464         data.template = data.template + '?blankTile=false';
46465     }
46466
46467     var esri = rendererBackgroundSource(data),
46468         cache = {},
46469         inflight = {};
46470
46471     esri.getMetadata = function(center, tileCoord, callback) {
46472         var tileId = tileCoord.slice(0, 3).join('/'),
46473             zoom = Math.min(tileCoord[2], esri.scaleExtent[1]),
46474             centerPoint = center[0] + ',' + center[1],  // long, lat (as it should be)
46475             unknown = t('info_panels.background.unknown'),
46476             metadataLayer,
46477             vintage = {},
46478             metadata = {};
46479
46480         if (inflight[tileId]) return;
46481
46482         switch (true) {
46483             case zoom >= 19:
46484                 metadataLayer = 3;
46485                 break;
46486             case zoom >= 17:
46487                 metadataLayer = 2;
46488                 break;
46489             case zoom >= 13:
46490                 metadataLayer = 0;
46491                 break;
46492             default:
46493                 metadataLayer = 99;
46494         }
46495
46496         // build up query using the layer appropriate to the current zoom
46497         var url = 'https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/' + metadataLayer + '/query?returnGeometry=false&geometry=' + centerPoint + '&inSR=4326&geometryType=esriGeometryPoint&outFields=*&f=json&callback={callback}';
46498
46499         if (!cache[tileId]) {
46500             cache[tileId] = {};
46501         }
46502         if (cache[tileId] && cache[tileId].metadata) {
46503             return callback(null, cache[tileId].metadata);
46504         }
46505
46506         // accurate metadata is only available >= 13
46507         if (metadataLayer === 99) {
46508             vintage = {
46509                 start: null,
46510                 end: null,
46511                 range: null
46512             };
46513             metadata = {
46514                 vintage: null,
46515                 source: unknown,
46516                 description: unknown,
46517                 resolution: unknown,
46518                 accuracy: unknown
46519             };
46520
46521             callback(null, metadata);
46522
46523         } else {
46524             inflight[tileId] = true;
46525             jsonpRequest(url, function(result) {
46526                 delete inflight[tileId];
46527
46528                 var err;
46529                 if (!result) {
46530                     err = 'Unknown Error';
46531                 } else if (result.features && result.features.length < 1) {
46532                     err = 'No Results';
46533                 } else if (result.error && result.error.message) {
46534                     err = result.error.message;
46535                 }
46536
46537                 if (err) {
46538                     return callback(err);
46539                 } else {
46540                     // pass through the discrete capture date from metadata
46541                     var captureDate = localeDateString(result.features[0].attributes.SRC_DATE2);
46542                     vintage = {
46543                         start: captureDate,
46544                         end: captureDate,
46545                         range: captureDate
46546                     };
46547                     metadata = {
46548                         vintage: vintage,
46549                         source: clean(result.features[0].attributes.NICE_NAME),
46550                         description: clean(result.features[0].attributes.NICE_DESC),
46551                         resolution: clean(result.features[0].attributes.SRC_RES),
46552                         accuracy: clean(result.features[0].attributes.SRC_ACC)
46553                     };
46554
46555                     // append units - meters
46556                     if (isFinite(metadata.resolution)) {
46557                         metadata.resolution += ' m';
46558                     }
46559                     if (isFinite(metadata.accuracy)) {
46560                         metadata.accuracy += ' m';
46561                     }
46562
46563                     cache[tileId].metadata = metadata;
46564                     return callback(null, metadata);
46565                 }
46566             });
46567         }
46568
46569
46570         function clean(val) {
46571             return String(val).trim() || unknown;
46572         }
46573     };
46574
46575     return esri;
46576 };
46577
46578
46579 rendererBackgroundSource.None = function() {
46580     var source = rendererBackgroundSource({ id: 'none', template: '' });
46581
46582
46583     source.name = function() {
46584         return t('background.none');
46585     };
46586
46587
46588     source.imageryUsed = function() {
46589         return 'None';
46590     };
46591
46592
46593     source.area = function() {
46594         return -1;  // sources in background pane are sorted by area
46595     };
46596
46597
46598     return source;
46599 };
46600
46601
46602 rendererBackgroundSource.Custom = function(template) {
46603     var source = rendererBackgroundSource({ id: 'custom', template: template });
46604
46605
46606     source.name = function() {
46607         return t('background.custom');
46608     };
46609
46610
46611     source.imageryUsed = function() {
46612         return 'Custom (' + source.template() + ')';
46613     };
46614
46615
46616     source.area = function() {
46617         return -2;  // sources in background pane are sorted by area
46618     };
46619
46620
46621     return source;
46622 };
46623
46624 function rendererTileLayer(context) {
46625     var tileSize = 256,
46626         geotile = d3geoTile(),
46627         projection,
46628         cache = {},
46629         tileOrigin,
46630         z,
46631         transformProp = utilPrefixCSSProperty('Transform'),
46632         source;
46633
46634
46635     // blacklist overlay tiles around Null Island..
46636     function nearNullIsland(x, y, z) {
46637         if (z >= 7) {
46638             var center = Math.pow(2, z - 1),
46639                 width = Math.pow(2, z - 6),
46640                 min = center - (width / 2),
46641                 max = center + (width / 2) - 1;
46642             return x >= min && x <= max && y >= min && y <= max;
46643         }
46644         return false;
46645     }
46646
46647
46648     function tileSizeAtZoom(d, z) {
46649         var epsilon = 0.002;
46650         return ((tileSize * Math.pow(2, z - d[2])) / tileSize) + epsilon;
46651     }
46652
46653
46654     function atZoom(t$$1, distance) {
46655         var power = Math.pow(2, distance);
46656         return [
46657             Math.floor(t$$1[0] * power),
46658             Math.floor(t$$1[1] * power),
46659             t$$1[2] + distance
46660         ];
46661     }
46662
46663
46664     function lookUp(d) {
46665         for (var up = -1; up > -d[2]; up--) {
46666             var tile = atZoom(d, up);
46667             if (cache[source.url(tile)] !== false) {
46668                 return tile;
46669             }
46670         }
46671     }
46672
46673
46674     function uniqueBy(a, n) {
46675         var o = [], seen = {};
46676         for (var i = 0; i < a.length; i++) {
46677             if (seen[a[i][n]] === undefined) {
46678                 o.push(a[i]);
46679                 seen[a[i][n]] = true;
46680             }
46681         }
46682         return o;
46683     }
46684
46685
46686     function addSource(d) {
46687         d.push(source.url(d));
46688         return d;
46689     }
46690
46691
46692     // Update tiles based on current state of `projection`.
46693     function background(selection) {
46694         z = Math.max(Math.log(projection.scale() * 2 * Math.PI) / Math.log(2) - 8, 0);
46695
46696         var pixelOffset;
46697         if (source) {
46698             pixelOffset = [
46699                 source.offset()[0] * Math.pow(2, z),
46700                 source.offset()[1] * Math.pow(2, z)
46701             ];
46702         } else {
46703             pixelOffset = [0, 0];
46704         }
46705
46706         var translate = [
46707             projection.translate()[0] + pixelOffset[0],
46708             projection.translate()[1] + pixelOffset[1]
46709         ];
46710
46711         geotile
46712             .scale(projection.scale() * 2 * Math.PI)
46713             .translate(translate);
46714
46715         tileOrigin = [
46716             projection.scale() * Math.PI - translate[0],
46717             projection.scale() * Math.PI - translate[1]
46718         ];
46719
46720         render(selection);
46721     }
46722
46723
46724     // Derive the tiles onscreen, remove those offscreen and position them.
46725     // Important that this part not depend on `projection` because it's
46726     // rentered when tiles load/error (see #644).
46727     function render(selection) {
46728         if (!source) return;
46729         var requests = [];
46730         var showDebug = context.getDebug('tile') && !source.overlay;
46731
46732         if (source.validZoom(z)) {
46733             geotile().forEach(function(d) {
46734                 addSource(d);
46735                 if (d[3] === '') return;
46736                 if (typeof d[3] !== 'string') return; // Workaround for #2295
46737                 requests.push(d);
46738                 if (cache[d[3]] === false && lookUp(d)) {
46739                     requests.push(addSource(lookUp(d)));
46740                 }
46741             });
46742
46743             requests = uniqueBy(requests, 3).filter(function(r) {
46744                 if (!!source.overlay && nearNullIsland(r[0], r[1], r[2])) {
46745                     return false;
46746                 }
46747                 // don't re-request tiles which have failed in the past
46748                 return cache[r[3]] !== false;
46749             });
46750         }
46751
46752
46753         function load(d) {
46754             cache[d[3]] = true;
46755             d3_select(this)
46756                 .on('error', null)
46757                 .on('load', null)
46758                 .classed('tile-loaded', true);
46759             render(selection);
46760         }
46761
46762         function error(d) {
46763             cache[d[3]] = false;
46764             d3_select(this)
46765                 .on('error', null)
46766                 .on('load', null)
46767                 .remove();
46768             render(selection);
46769         }
46770
46771         function imageTransform(d) {
46772             var _ts = tileSize * Math.pow(2, z - d[2]);
46773             var scale = tileSizeAtZoom(d, z);
46774             return 'translate(' +
46775                 ((d[0] * _ts) - tileOrigin[0]) + 'px,' +
46776                 ((d[1] * _ts) - tileOrigin[1]) + 'px) ' +
46777                 'scale(' + scale + ',' + scale + ')';
46778         }
46779
46780         function tileCenter(d) {
46781             var _ts = tileSize * Math.pow(2, z - d[2]);
46782             return [
46783                 ((d[0] * _ts) - tileOrigin[0] + (_ts / 2)),
46784                 ((d[1] * _ts) - tileOrigin[1] + (_ts / 2))
46785             ];
46786         }
46787
46788         function debugTransform(d) {
46789             var coord = tileCenter(d);
46790             return 'translate(' + coord[0] + 'px,' + coord[1] + 'px)';
46791         }
46792
46793
46794         // Pick a representative tile near the center of the viewport
46795         // (This is useful for sampling the imagery vintage)
46796         var dims = geotile.size(),
46797             mapCenter = [dims[0] / 2, dims[1] / 2],
46798             minDist = Math.max(dims[0], dims[1]),
46799             nearCenter;
46800
46801         requests.forEach(function(d) {
46802             var c = tileCenter(d);
46803             var dist = geoEuclideanDistance(c, mapCenter);
46804             if (dist < minDist) {
46805                 minDist = dist;
46806                 nearCenter = d;
46807             }
46808         });
46809
46810
46811         var image = selection.selectAll('img')
46812             .data(requests, function(d) { return d[3]; });
46813
46814         image.exit()
46815             .style(transformProp, imageTransform)
46816             .classed('tile-removing', true)
46817             .classed('tile-center', false)
46818             .each(function() {
46819                 var tile = d3_select(this);
46820                 window.setTimeout(function() {
46821                     if (tile.classed('tile-removing')) {
46822                         tile.remove();
46823                     }
46824                 }, 300);
46825             });
46826
46827         image.enter()
46828           .append('img')
46829             .attr('class', 'tile')
46830             .attr('src', function(d) { return d[3]; })
46831             .on('error', error)
46832             .on('load', load)
46833           .merge(image)
46834             .style(transformProp, imageTransform)
46835             .classed('tile-debug', showDebug)
46836             .classed('tile-removing', false)
46837             .classed('tile-center', function(d) { return d === nearCenter; });
46838
46839
46840
46841         var debug = selection.selectAll('.tile-label-debug')
46842             .data(showDebug ? requests : [], function(d) { return d[3]; });
46843
46844         debug.exit()
46845             .remove();
46846
46847         if (showDebug) {
46848             var debugEnter = debug.enter()
46849                 .append('div')
46850                 .attr('class', 'tile-label-debug');
46851
46852             debugEnter
46853                 .append('div')
46854                 .attr('class', 'tile-label-debug-coord');
46855
46856             debugEnter
46857                 .append('div')
46858                 .attr('class', 'tile-label-debug-vintage');
46859
46860             debug = debug.merge(debugEnter);
46861
46862             debug
46863                 .style(transformProp, debugTransform);
46864
46865             debug
46866                 .selectAll('.tile-label-debug-coord')
46867                 .text(function(d) { return d[2] + ' / ' + d[0] + ' / ' + d[1]; });
46868
46869             debug
46870                 .selectAll('.tile-label-debug-vintage')
46871                 .each(function(d) {
46872                     var span = d3_select(this);
46873                     var center = context.projection.invert(tileCenter(d));
46874                     source.getMetadata(center, d, function(err, result) {
46875                         span.text((result && result.vintage && result.vintage.range) ||
46876                             t('info_panels.background.vintage') + ': ' + t('info_panels.background.unknown')
46877                         );
46878                     });
46879                 });
46880         }
46881
46882     }
46883
46884
46885     background.projection = function(_) {
46886         if (!arguments.length) return projection;
46887         projection = _;
46888         return background;
46889     };
46890
46891
46892     background.dimensions = function(_) {
46893         if (!arguments.length) return geotile.size();
46894         geotile.size(_);
46895         return background;
46896     };
46897
46898
46899     background.source = function(_) {
46900         if (!arguments.length) return source;
46901         source = _;
46902         cache = {};
46903         geotile.scaleExtent(source.scaleExtent);
46904         return background;
46905     };
46906
46907
46908     return background;
46909 }
46910
46911 function rendererBackground(context) {
46912     var dispatch$$1 = dispatch('change'),
46913         baseLayer = rendererTileLayer(context).projection(context.projection),
46914         overlayLayers = [],
46915         backgroundSources;
46916
46917
46918     function background(selection) {
46919         var base = selection.selectAll('.layer-background')
46920             .data([0]);
46921
46922         base.enter()
46923             .insert('div', '.layer-data')
46924             .attr('class', 'layer layer-background')
46925             .merge(base)
46926             .call(baseLayer);
46927
46928         var overlays = selection.selectAll('.layer-overlay')
46929             .data(overlayLayers, function(d) { return d.source().name(); });
46930
46931         overlays.exit()
46932             .remove();
46933
46934         overlays.enter()
46935             .insert('div', '.layer-data')
46936             .attr('class', 'layer layer-overlay')
46937             .merge(overlays)
46938             .each(function(layer) { d3_select(this).call(layer); });
46939     }
46940
46941
46942     background.updateImagery = function() {
46943         if (context.inIntro()) return;
46944
46945         var b = background.baseLayerSource(),
46946             o = overlayLayers
46947                 .filter(function (d) { return !d.source().isLocatorOverlay() && !d.source().isHidden(); })
46948                 .map(function (d) { return d.source().id; })
46949                 .join(','),
46950             meters = geoOffsetToMeters(b.offset()),
46951             epsilon = 0.01,
46952             x = +meters[0].toFixed(2),
46953             y = +meters[1].toFixed(2),
46954             q = utilStringQs(window.location.hash.substring(1));
46955
46956         var id = b.id;
46957         if (id === 'custom') {
46958             id = 'custom:' + b.template();
46959         }
46960
46961         if (id) {
46962             q.background = id;
46963         } else {
46964             delete q.background;
46965         }
46966
46967         if (o) {
46968             q.overlays = o;
46969         } else {
46970             delete q.overlays;
46971         }
46972
46973         if (Math.abs(x) > epsilon || Math.abs(y) > epsilon) {
46974             q.offset = x + ',' + y;
46975         } else {
46976             delete q.offset;
46977         }
46978
46979         if (!window.mocha) {
46980             window.location.replace('#' + utilQsString(q, true));
46981         }
46982
46983         var imageryUsed = [b.imageryUsed()];
46984
46985         overlayLayers
46986             .filter(function (d) { return !d.source().isLocatorOverlay() && !d.source().isHidden(); })
46987             .forEach(function (d) { imageryUsed.push(d.source().imageryUsed()); });
46988
46989         var gpx = context.layers().layer('gpx');
46990         if (gpx && gpx.enabled() && gpx.hasGpx()) {
46991             // Include a string like '.gpx data file' or '.geojson data file'
46992             var match = gpx.getSrc().match(/(kml|gpx|(?:geo)?json)$/i);
46993             var extension = match ? ('.' + match[0].toLowerCase() + ' ') : '';
46994             imageryUsed.push(extension + 'data file');
46995         }
46996
46997         var mapillary_images = context.layers().layer('mapillary-images');
46998         if (mapillary_images && mapillary_images.enabled()) {
46999             imageryUsed.push('Mapillary Images');
47000         }
47001
47002         var mapillary_signs = context.layers().layer('mapillary-signs');
47003         if (mapillary_signs && mapillary_signs.enabled()) {
47004             imageryUsed.push('Mapillary Signs');
47005         }
47006
47007         var openstreetcam_images = context.layers().layer('openstreetcam-images');
47008         if (openstreetcam_images && openstreetcam_images.enabled()) {
47009             imageryUsed.push('OpenStreetCam Images');
47010         }
47011
47012         context.history().imageryUsed(imageryUsed);
47013     };
47014
47015
47016     background.sources = function(extent) {
47017         return backgroundSources.filter(function(source) {
47018             return source.intersects(extent);
47019         });
47020     };
47021
47022
47023     background.dimensions = function(_) {
47024         if (!_) return;
47025         baseLayer.dimensions(_);
47026
47027         overlayLayers.forEach(function(layer) {
47028             layer.dimensions(_);
47029         });
47030     };
47031
47032
47033     background.baseLayerSource = function(d) {
47034         if (!arguments.length) return baseLayer.source();
47035
47036         // test source against OSM imagery blacklists..
47037         var osm = context.connection();
47038         if (!osm) return background;
47039
47040         var blacklists = context.connection().imageryBlacklists();
47041
47042         var template = d.template(),
47043             fail = false,
47044             tested = 0,
47045             regex, i;
47046
47047         for (i = 0; i < blacklists.length; i++) {
47048             try {
47049                 regex = new RegExp(blacklists[i]);
47050                 fail = regex.test(template);
47051                 tested++;
47052                 if (fail) break;
47053             } catch (e) {
47054                 /* noop */
47055             }
47056         }
47057
47058         // ensure at least one test was run.
47059         if (!tested) {
47060             regex = new RegExp('.*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*');
47061             fail = regex.test(template);
47062         }
47063
47064         baseLayer.source(!fail ? d : background.findSource('none'));
47065         dispatch$$1.call('change');
47066         background.updateImagery();
47067         return background;
47068     };
47069
47070
47071     background.findSource = function(id) {
47072         return find$1(backgroundSources, function(d) {
47073             return d.id && d.id === id;
47074         });
47075     };
47076
47077
47078     background.bing = function() {
47079         background.baseLayerSource(background.findSource('Bing'));
47080     };
47081
47082
47083     background.showsLayer = function(d) {
47084         return d.id === baseLayer.source().id ||
47085             overlayLayers.some(function(layer) { return d.id === layer.source().id; });
47086     };
47087
47088
47089     background.overlayLayerSources = function() {
47090         return overlayLayers.map(function (l) { return l.source(); });
47091     };
47092
47093
47094     background.toggleOverlayLayer = function(d) {
47095         var layer;
47096
47097         for (var i = 0; i < overlayLayers.length; i++) {
47098             layer = overlayLayers[i];
47099             if (layer.source() === d) {
47100                 overlayLayers.splice(i, 1);
47101                 dispatch$$1.call('change');
47102                 background.updateImagery();
47103                 return;
47104             }
47105         }
47106
47107         layer = rendererTileLayer(context)
47108             .source(d)
47109             .projection(context.projection)
47110             .dimensions(baseLayer.dimensions());
47111
47112         overlayLayers.push(layer);
47113         dispatch$$1.call('change');
47114         background.updateImagery();
47115     };
47116
47117
47118     background.nudge = function(d, zoom) {
47119         baseLayer.source().nudge(d, zoom);
47120         dispatch$$1.call('change');
47121         background.updateImagery();
47122         return background;
47123     };
47124
47125
47126     background.offset = function(d) {
47127         if (!arguments.length) return baseLayer.source().offset();
47128         baseLayer.source().offset(d);
47129         dispatch$$1.call('change');
47130         background.updateImagery();
47131         return background;
47132     };
47133
47134
47135     background.init = function() {
47136         function parseMap(qmap) {
47137             if (!qmap) return false;
47138             var args = qmap.split('/').map(Number);
47139             if (args.length < 3 || args.some(isNaN)) return false;
47140             return geoExtent([args[2], args[1]]);
47141         }
47142
47143         var dataImagery = data.imagery || [],
47144             q = utilStringQs(window.location.hash.substring(1)),
47145             requested = q.background || q.layer,
47146             extent = parseMap(q.map),
47147             first,
47148             best;
47149
47150         // Add all the available imagery sources
47151         backgroundSources = dataImagery.map(function(source) {
47152             if (source.type === 'bing') {
47153                 return rendererBackgroundSource.Bing(source, dispatch$$1);
47154             } else if (source.id === 'EsriWorldImagery') {
47155                 return rendererBackgroundSource.Esri(source);
47156             } else {
47157                 return rendererBackgroundSource(source);
47158             }
47159         });
47160
47161         first = backgroundSources.length && backgroundSources[0];
47162
47163         // Add 'None'
47164         backgroundSources.unshift(rendererBackgroundSource.None());
47165
47166         // Add 'Custom'
47167         var template = context.storage('background-custom-template') || '';
47168         var custom = rendererBackgroundSource.Custom(template);
47169         backgroundSources.unshift(custom);
47170
47171
47172         // Decide which background layer to display
47173         if (!requested && extent) {
47174             best = find$1(this.sources(extent), function(s) { return s.best(); });
47175         }
47176         if (requested && requested.indexOf('custom:') === 0) {
47177             template = requested.replace(/^custom:/, '');
47178             background.baseLayerSource(custom.template(template));
47179             context.storage('background-custom-template', template);
47180         } else {
47181             background.baseLayerSource(
47182                 background.findSource(requested) ||
47183                 best ||
47184                 background.findSource('Bing') ||
47185                 first ||
47186                 background.findSource('none')
47187             );
47188         }
47189
47190         var locator = find$1(backgroundSources, function(d) {
47191             return d.overlay && d.default;
47192         });
47193
47194         if (locator) {
47195             background.toggleOverlayLayer(locator);
47196         }
47197
47198         var overlays = (q.overlays || '').split(',');
47199         overlays.forEach(function(overlay) {
47200             overlay = background.findSource(overlay);
47201             if (overlay) {
47202                 background.toggleOverlayLayer(overlay);
47203             }
47204         });
47205
47206         if (q.gpx) {
47207             var gpx = context.layers().layer('gpx');
47208             if (gpx) {
47209                 gpx.url(q.gpx);
47210             }
47211         }
47212
47213         if (q.offset) {
47214             var offset = q.offset.replace(/;/g, ',').split(',').map(function(n) {
47215                 return !isNaN(n) && n;
47216             });
47217
47218             if (offset.length === 2) {
47219                 background.offset(geoMetersToOffset(offset));
47220             }
47221         }
47222     };
47223
47224
47225     return utilRebind(background, dispatch$$1, 'on');
47226 }
47227
47228 function rendererFeatures(context) {
47229     var traffic_roads = {
47230         'motorway': true,
47231         'motorway_link': true,
47232         'trunk': true,
47233         'trunk_link': true,
47234         'primary': true,
47235         'primary_link': true,
47236         'secondary': true,
47237         'secondary_link': true,
47238         'tertiary': true,
47239         'tertiary_link': true,
47240         'residential': true,
47241         'unclassified': true,
47242         'living_street': true
47243     };
47244
47245     var service_roads = {
47246         'service': true,
47247         'road': true,
47248         'track': true
47249     };
47250
47251     var paths = {
47252         'path': true,
47253         'footway': true,
47254         'cycleway': true,
47255         'bridleway': true,
47256         'steps': true,
47257         'pedestrian': true,
47258         'corridor': true
47259     };
47260
47261     var past_futures = {
47262         'proposed': true,
47263         'construction': true,
47264         'abandoned': true,
47265         'dismantled': true,
47266         'disused': true,
47267         'razed': true,
47268         'demolished': true,
47269         'obliterated': true
47270     };
47271
47272     var dispatch$$1 = dispatch('change', 'redraw'),
47273         _cullFactor = 1,
47274         _cache = {},
47275         _features = {},
47276         _stats = {},
47277         _keys = [],
47278         _hidden = [];
47279
47280
47281     function update() {
47282         if (!window.mocha) {
47283             var q = utilStringQs(window.location.hash.substring(1));
47284             var disabled = features.disabled();
47285             if (disabled.length) {
47286                 q.disable_features = features.disabled().join(',');
47287             } else {
47288                 delete q.disable_features;
47289             }
47290             window.location.replace('#' + utilQsString(q, true));
47291         }
47292
47293         _hidden = features.hidden();
47294         dispatch$$1.call('change');
47295         dispatch$$1.call('redraw');
47296     }
47297
47298
47299     function defineFeature(k, filter, max) {
47300         var isEnabled = true;
47301
47302         _keys.push(k);
47303         _features[k] = {
47304             filter: filter,
47305             enabled: isEnabled,   // whether the user wants it enabled..
47306             count: 0,
47307             currentMax: (max || Infinity),
47308             defaultMax: (max || Infinity),
47309             enable: function() { this.enabled = true; this.currentMax = this.defaultMax; },
47310             disable: function() { this.enabled = false; this.currentMax = 0; },
47311             hidden: function() { return !context.editable() || this.count > this.currentMax * _cullFactor; },
47312             autoHidden: function() { return this.hidden() && this.currentMax > 0; }
47313         };
47314     }
47315
47316
47317     defineFeature('points', function isPoint(entity, resolver, geometry) {
47318         return geometry === 'point';
47319     }, 200);
47320
47321     defineFeature('traffic_roads', function isTrafficRoad(entity) {
47322         return traffic_roads[entity.tags.highway];
47323     });
47324
47325     defineFeature('service_roads', function isServiceRoad(entity) {
47326         return service_roads[entity.tags.highway];
47327     });
47328
47329     defineFeature('paths', function isPath(entity) {
47330         return paths[entity.tags.highway];
47331     });
47332
47333     defineFeature('buildings', function isBuilding(entity) {
47334         return (
47335             !!entity.tags['building:part'] ||
47336             (!!entity.tags.building && entity.tags.building !== 'no') ||
47337             entity.tags.amenity === 'shelter' ||
47338             entity.tags.parking === 'multi-storey' ||
47339             entity.tags.parking === 'sheds' ||
47340             entity.tags.parking === 'carports' ||
47341             entity.tags.parking === 'garage_boxes'
47342         );
47343     }, 250);
47344
47345     defineFeature('landuse', function isLanduse(entity, resolver, geometry) {
47346         return geometry === 'area' &&
47347             !_features.buildings.filter(entity) &&
47348             !_features.water.filter(entity);
47349     });
47350
47351     defineFeature('boundaries', function isBoundary(entity) {
47352         return !!entity.tags.boundary;
47353     });
47354
47355     defineFeature('water', function isWater(entity) {
47356         return (
47357             !!entity.tags.waterway ||
47358             entity.tags.natural === 'water' ||
47359             entity.tags.natural === 'coastline' ||
47360             entity.tags.natural === 'bay' ||
47361             entity.tags.landuse === 'pond' ||
47362             entity.tags.landuse === 'basin' ||
47363             entity.tags.landuse === 'reservoir' ||
47364             entity.tags.landuse === 'salt_pond'
47365         );
47366     });
47367
47368     defineFeature('rail', function isRail(entity) {
47369         return (
47370             !!entity.tags.railway ||
47371             entity.tags.landuse === 'railway'
47372         ) && !(
47373             traffic_roads[entity.tags.highway] ||
47374             service_roads[entity.tags.highway] ||
47375             paths[entity.tags.highway]
47376         );
47377     });
47378
47379     defineFeature('power', function isPower(entity) {
47380         return !!entity.tags.power;
47381     });
47382
47383     // contains a past/future tag, but not in active use as a road/path/cycleway/etc..
47384     defineFeature('past_future', function isPastFuture(entity) {
47385         if (
47386             traffic_roads[entity.tags.highway] ||
47387             service_roads[entity.tags.highway] ||
47388             paths[entity.tags.highway]
47389         ) { return false; }
47390
47391         var strings = Object.keys(entity.tags);
47392
47393         for (var i = 0; i < strings.length; i++) {
47394             var s = strings[i];
47395             if (past_futures[s] || past_futures[entity.tags[s]]) { return true; }
47396         }
47397         return false;
47398     });
47399
47400     // Lines or areas that don't match another feature filter.
47401     // IMPORTANT: The 'others' feature must be the last one defined,
47402     //   so that code in getMatches can skip this test if `hasMatch = true`
47403     defineFeature('others', function isOther(entity, resolver, geometry) {
47404         return (geometry === 'line' || geometry === 'area');
47405     });
47406
47407
47408     function features() {}
47409
47410
47411     features.features = function() {
47412         return _features;
47413     };
47414
47415
47416     features.keys = function() {
47417         return _keys;
47418     };
47419
47420
47421     features.enabled = function(k) {
47422         if (!arguments.length) {
47423             return _keys.filter(function(k) { return _features[k].enabled; });
47424         }
47425         return _features[k] && _features[k].enabled;
47426     };
47427
47428
47429     features.disabled = function(k) {
47430         if (!arguments.length) {
47431             return _keys.filter(function(k) { return !_features[k].enabled; });
47432         }
47433         return _features[k] && !_features[k].enabled;
47434     };
47435
47436
47437     features.hidden = function(k) {
47438         if (!arguments.length) {
47439             return _keys.filter(function(k) { return _features[k].hidden(); });
47440         }
47441         return _features[k] && _features[k].hidden();
47442     };
47443
47444
47445     features.autoHidden = function(k) {
47446         if (!arguments.length) {
47447             return _keys.filter(function(k) { return _features[k].autoHidden(); });
47448         }
47449         return _features[k] && _features[k].autoHidden();
47450     };
47451
47452
47453     features.enable = function(k) {
47454         if (_features[k] && !_features[k].enabled) {
47455             _features[k].enable();
47456             update();
47457         }
47458     };
47459
47460
47461     features.disable = function(k) {
47462         if (_features[k] && _features[k].enabled) {
47463             _features[k].disable();
47464             update();
47465         }
47466     };
47467
47468
47469     features.toggle = function(k) {
47470         if (_features[k]) {
47471             (function(f) { return f.enabled ? f.disable() : f.enable(); }(_features[k]));
47472             update();
47473         }
47474     };
47475
47476
47477     features.resetStats = function() {
47478         for (var i = 0; i < _keys.length; i++) {
47479             _features[_keys[i]].count = 0;
47480         }
47481         dispatch$$1.call('change');
47482     };
47483
47484
47485     features.gatherStats = function(d, resolver, dimensions) {
47486         var needsRedraw = false,
47487             type = groupBy(d, function(ent) { return ent.type; }),
47488             entities = [].concat(type.relation || [], type.way || [], type.node || []),
47489             currHidden, geometry, matches, i, j;
47490
47491         for (i = 0; i < _keys.length; i++) {
47492             _features[_keys[i]].count = 0;
47493         }
47494
47495         // adjust the threshold for point/building culling based on viewport size..
47496         // a _cullFactor of 1 corresponds to a 1000x1000px viewport..
47497         _cullFactor = dimensions[0] * dimensions[1] / 1000000;
47498
47499         for (i = 0; i < entities.length; i++) {
47500             geometry = entities[i].geometry(resolver);
47501             if (!(geometry === 'vertex' || geometry === 'relation')) {
47502                 matches = Object.keys(features.getMatches(entities[i], resolver, geometry));
47503                 for (j = 0; j < matches.length; j++) {
47504                     _features[matches[j]].count++;
47505                 }
47506             }
47507         }
47508
47509         currHidden = features.hidden();
47510         if (currHidden !== _hidden) {
47511             _hidden = currHidden;
47512             needsRedraw = true;
47513             dispatch$$1.call('change');
47514         }
47515
47516         return needsRedraw;
47517     };
47518
47519
47520     features.stats = function() {
47521         for (var i = 0; i < _keys.length; i++) {
47522             _stats[_keys[i]] = _features[_keys[i]].count;
47523         }
47524
47525         return _stats;
47526     };
47527
47528
47529     features.clear = function(d) {
47530         for (var i = 0; i < d.length; i++) {
47531             features.clearEntity(d[i]);
47532         }
47533     };
47534
47535
47536     features.clearEntity = function(entity) {
47537         delete _cache[osmEntity.key(entity)];
47538     };
47539
47540
47541     features.reset = function() {
47542         _cache = {};
47543     };
47544
47545
47546     features.getMatches = function(entity, resolver, geometry) {
47547         if (geometry === 'vertex' || geometry === 'relation') return {};
47548
47549         var ent = osmEntity.key(entity);
47550         if (!_cache[ent]) {
47551             _cache[ent] = {};
47552         }
47553
47554         if (!_cache[ent].matches) {
47555             var matches = {},
47556                 hasMatch = false;
47557
47558             for (var i = 0; i < _keys.length; i++) {
47559                 if (_keys[i] === 'others') {
47560                     if (hasMatch) continue;
47561
47562                     // Multipolygon members:
47563                     // If an entity...
47564                     //   1. is a way that hasn't matched other 'interesting' feature rules,
47565                     //   2. and it belongs to a single parent multipolygon relation
47566                     // ...then match whatever feature rules the parent multipolygon has matched.
47567                     // see #2548, #2887
47568                     //
47569                     // IMPORTANT:
47570                     // For this to work, getMatches must be called on relations before ways.
47571                     //
47572                     if (entity.type === 'way') {
47573                         var parents = features.getParents(entity, resolver, geometry);
47574                         if (parents.length === 1 && parents[0].isMultipolygon()) {
47575                             var pkey = osmEntity.key(parents[0]);
47576                             if (_cache[pkey] && _cache[pkey].matches) {
47577                                 matches = clone(_cache[pkey].matches);
47578                                 continue;
47579                             }
47580                         }
47581                     }
47582                 }
47583
47584                 if (_features[_keys[i]].filter(entity, resolver, geometry)) {
47585                     matches[_keys[i]] = hasMatch = true;
47586                 }
47587             }
47588             _cache[ent].matches = matches;
47589         }
47590
47591         return _cache[ent].matches;
47592     };
47593
47594
47595     features.getParents = function(entity, resolver, geometry) {
47596         if (geometry === 'point') return [];
47597
47598         var ent = osmEntity.key(entity);
47599         if (!_cache[ent]) {
47600             _cache[ent] = {};
47601         }
47602
47603         if (!_cache[ent].parents) {
47604             var parents = [];
47605             if (geometry === 'vertex') {
47606                 parents = resolver.parentWays(entity);
47607             } else {   // 'line', 'area', 'relation'
47608                 parents = resolver.parentRelations(entity);
47609             }
47610             _cache[ent].parents = parents;
47611         }
47612         return _cache[ent].parents;
47613     };
47614
47615
47616     features.isHiddenFeature = function(entity, resolver, geometry) {
47617         if (!_hidden.length) return false;
47618         if (!entity.version) return false;
47619
47620         var matches = features.getMatches(entity, resolver, geometry);
47621
47622         for (var i = 0; i < _hidden.length; i++) {
47623             if (matches[_hidden[i]]) return true;
47624         }
47625         return false;
47626     };
47627
47628
47629     features.isHiddenChild = function(entity, resolver, geometry) {
47630         if (!_hidden.length) return false;
47631         if (!entity.version || geometry === 'point') return false;
47632
47633         var parents = features.getParents(entity, resolver, geometry);
47634         if (!parents.length) return false;
47635
47636         for (var i = 0; i < parents.length; i++) {
47637             if (!features.isHidden(parents[i], resolver, parents[i].geometry(resolver))) {
47638                 return false;
47639             }
47640         }
47641         return true;
47642     };
47643
47644
47645     features.hasHiddenConnections = function(entity, resolver) {
47646         if (!_hidden.length) return false;
47647         var childNodes, connections;
47648
47649         if (entity.type === 'midpoint') {
47650             childNodes = [resolver.entity(entity.edge[0]), resolver.entity(entity.edge[1])];
47651             connections = [];
47652         } else {
47653             childNodes = entity.nodes ? resolver.childNodes(entity) : [];
47654             connections = features.getParents(entity, resolver, entity.geometry(resolver));
47655         }
47656
47657         // gather ways connected to child nodes..
47658         connections = reduce(childNodes, function(result, e) {
47659             return resolver.isShared(e) ? union(result, resolver.parentWays(e)) : result;
47660         }, connections);
47661
47662         return connections.length ? some(connections, function(e) {
47663             return features.isHidden(e, resolver, e.geometry(resolver));
47664         }) : false;
47665     };
47666
47667
47668     features.isHidden = function(entity, resolver, geometry) {
47669         if (!_hidden.length) return false;
47670         if (!entity.version) return false;
47671
47672         var fn = (geometry === 'vertex' ? features.isHiddenChild : features.isHiddenFeature);
47673         return fn(entity, resolver, geometry);
47674     };
47675
47676
47677     features.filter = function(d, resolver) {
47678         if (!_hidden.length) return d;
47679
47680         var result = [];
47681         for (var i = 0; i < d.length; i++) {
47682             var entity = d[i];
47683             if (!features.isHidden(entity, resolver, entity.geometry(resolver))) {
47684                 result.push(entity);
47685             }
47686         }
47687         return result;
47688     };
47689
47690
47691     features.init = function() {
47692         var q = utilStringQs(window.location.hash.substring(1));
47693
47694         if (q.disable_features) {
47695             var disabled = q.disable_features.replace(/;/g, ',').split(',');
47696             disabled.forEach(features.disable);
47697         }
47698     };
47699
47700     return utilRebind(features, dispatch$$1, 'on');
47701 }
47702
47703 function utilBindOnce(target, type, listener, capture) {
47704     var typeOnce = type + '.once';
47705     function one() {
47706         target.on(typeOnce, null);
47707         listener.apply(this, arguments);
47708     }
47709     target.on(typeOnce, one, capture);
47710     return this;
47711 }
47712
47713 function rendererMap(context) {
47714
47715     var dimensions = [1, 1],
47716         dispatch$$1 = dispatch('move', 'drawn'),
47717         projection = context.projection,
47718         curtainProjection = context.curtainProjection,
47719         dblclickEnabled = true,
47720         redrawEnabled = true,
47721         transformStart = projection.transform(),
47722         transformLast,
47723         transformed = false,
47724         minzoom = 0,
47725         drawLayers = svgLayers(projection, context),
47726         drawPoints = svgPoints(projection, context),
47727         drawVertices = svgVertices(projection, context),
47728         drawLines = svgLines(projection, context),
47729         drawAreas = svgAreas(projection, context),
47730         drawMidpoints = svgMidpoints(projection, context),
47731         drawLabels = svgLabels(projection, context),
47732         supersurface = d3_select(null),
47733         wrapper = d3_select(null),
47734         surface = d3_select(null),
47735         mouse,
47736         mousemove;
47737
47738     var zoom$$1 = d3_zoom()
47739         .scaleExtent([ztok(2), ztok(24)])
47740         .interpolate(d3_interpolate)
47741         .filter(zoomEventFilter)
47742         .on('zoom', zoomPan);
47743
47744     var _selection = d3_select(null);
47745
47746     var scheduleRedraw = throttle(redraw, 750);
47747     // var isRedrawScheduled = false;
47748     // var pendingRedrawCall;
47749     // function scheduleRedraw() {
47750     //     // Only schedule the redraw if one has not already been set.
47751     //     if (isRedrawScheduled) return;
47752     //     isRedrawScheduled = true;
47753     //     var that = this;
47754     //     var args = arguments;
47755     //     pendingRedrawCall = window.requestIdleCallback(function () {
47756     //         // Reset the boolean so future redraws can be set.
47757     //         isRedrawScheduled = false;
47758     //         redraw.apply(that, args);
47759     //     }, { timeout: 1400 });
47760     // }
47761
47762     function cancelPendingRedraw() {
47763         scheduleRedraw.cancel();
47764         // isRedrawScheduled = false;
47765         // window.cancelIdleCallback(pendingRedrawCall);
47766     }
47767
47768     function map(selection) {
47769
47770         _selection = selection;
47771
47772         context
47773             .on('change.map', immediateRedraw);
47774
47775         var osm = context.connection();
47776         if (osm) {
47777             osm.on('change.map', immediateRedraw);
47778         }
47779
47780         context.history()
47781             .on('change.map', immediateRedraw)
47782             .on('undone.map redone.map', function(stack) {
47783                 var mode = context.mode().id;
47784                 if (mode !== 'browse' && mode !== 'select') return;
47785
47786                 var followSelected = false;
47787                 if (Array.isArray(stack.selectedIDs)) {
47788                     followSelected = (stack.selectedIDs.length === 1 && stack.selectedIDs[0][0] === 'n');
47789                     context.enter(
47790                         modeSelect(context, stack.selectedIDs).follow(followSelected)
47791                     );
47792                 }
47793                 if (!followSelected && stack.transform) {
47794                     map.transformEase(stack.transform);
47795                 }
47796             });
47797
47798         context.background()
47799             .on('change.map', immediateRedraw);
47800
47801         context.features()
47802             .on('redraw.map', immediateRedraw);
47803
47804         drawLayers
47805             .on('change.map', function() {
47806                 context.background().updateImagery();
47807                 immediateRedraw();
47808             });
47809
47810         selection
47811             .on('dblclick.map', dblClick)
47812             .call(zoom$$1)
47813             .call(zoom$$1.transform, projection.transform());
47814
47815         supersurface = selection.append('div')
47816             .attr('id', 'supersurface')
47817             .call(utilSetTransform, 0, 0);
47818
47819         // Need a wrapper div because Opera can't cope with an absolutely positioned
47820         // SVG element: http://bl.ocks.org/jfirebaugh/6fbfbd922552bf776c16
47821         wrapper = supersurface
47822             .append('div')
47823             .attr('class', 'layer layer-data');
47824
47825         map.surface = surface = wrapper
47826             .call(drawLayers)
47827             .selectAll('.surface')
47828             .attr('id', 'surface');
47829
47830         surface
47831             .call(drawLabels.observe)
47832             .on('mousedown.zoom', function() {
47833                 if (event.button === 2) {
47834                     event.stopPropagation();
47835                 }
47836             }, true)
47837             .on('mouseup.zoom', function() {
47838                 if (resetTransform()) immediateRedraw();
47839             })
47840             .on('mousemove.map', function() {
47841                 mousemove = event;
47842             })
47843             .on('mouseover.vertices', function() {
47844                 if (map.editable() && !transformed) {
47845                     var hover = event.target.__data__;
47846                     surface.selectAll('.data-layer-osm')
47847                         .call(drawVertices.drawHover, context.graph(), hover, map.extent(), map.zoom());
47848                     dispatch$$1.call('drawn', this, {full: false});
47849                 }
47850             })
47851             .on('mouseout.vertices', function() {
47852                 if (map.editable() && !transformed) {
47853                     var hover = event.relatedTarget && event.relatedTarget.__data__;
47854                     surface.selectAll('.data-layer-osm')
47855                         .call(drawVertices.drawHover, context.graph(), hover, map.extent(), map.zoom());
47856                     dispatch$$1.call('drawn', this, {full: false});
47857                 }
47858             });
47859
47860         supersurface
47861             .call(context.background());
47862
47863         context.on('enter.map', function() {
47864             if (map.editable() && !transformed) {
47865                 var all = context.intersects(map.extent()),
47866                     filter = utilFunctor(true),
47867                     graph = context.graph();
47868
47869                 all = context.features().filter(all, graph);
47870                 surface.selectAll('.data-layer-osm')
47871                     .call(drawVertices, graph, all, filter, map.extent(), map.zoom())
47872                     .call(drawMidpoints, graph, all, filter, map.trimmedExtent());
47873                 dispatch$$1.call('drawn', this, {full: false});
47874             }
47875         });
47876
47877         map.dimensions(utilGetDimensions(selection));
47878     }
47879
47880
47881     function zoomEventFilter() {
47882         // Fix for #2151, (see also d3/d3-zoom#60, d3/d3-brush#18)
47883         // Intercept `mousedown` and check if there is an orphaned zoom gesture.
47884         // This can happen if a previous `mousedown` occurred without a `mouseup`.
47885         // If we detect this, dispatch `mouseup` to complete the orphaned gesture,
47886         // so that d3-zoom won't stop propagation of new `mousedown` events.
47887         if (event.type === 'mousedown') {
47888             var hasOrphan = false;
47889             var listeners = window.__on;
47890             for (var i = 0; i < listeners.length; i++) {
47891                 var listener = listeners[i];
47892                 if (listener.name === 'zoom' && listener.type === 'mouseup') {
47893                     hasOrphan = true;
47894                     break;
47895                 }
47896             }
47897             if (hasOrphan) {
47898                 var event$$1 = window.CustomEvent;
47899                 if (event$$1) {
47900                     event$$1 = new event$$1('mouseup');
47901                 } else {
47902                     event$$1 = window.document.createEvent('Event');
47903                     event$$1.initEvent('mouseup', false, false);
47904                 }
47905                 // Event needs to be dispatched with an event.view property.
47906                 event$$1.view = window;
47907                 window.dispatchEvent(event$$1);
47908             }
47909         }
47910
47911         return event.button !== 2;   // ignore right clicks
47912     }
47913
47914
47915     function ztok(z) {
47916         return 256 * Math.pow(2, z);
47917     }
47918
47919     function ktoz(k) {
47920         return Math.max(Math.log(k) / Math.LN2 - 8, 0);
47921     }
47922
47923     function pxCenter() {
47924         return [dimensions[0] / 2, dimensions[1] / 2];
47925     }
47926
47927
47928     function drawVector(difference, extent) {
47929         var graph = context.graph(),
47930             features = context.features(),
47931             all = context.intersects(map.extent()),
47932             data, filter;
47933
47934         if (difference) {
47935             var complete = difference.complete(map.extent());
47936             data = compact(values$1(complete));
47937             filter = function(d) { return d.id in complete; };
47938             features.clear(data);
47939
47940         } else {
47941             // force a full redraw if gatherStats detects that a feature
47942             // should be auto-hidden (e.g. points or buildings)..
47943             if (features.gatherStats(all, graph, dimensions)) {
47944                 extent = undefined;
47945             }
47946
47947             if (extent) {
47948                 data = context.intersects(map.extent().intersection(extent));
47949                 var set$$1 = set$2(map$4(data, 'id'));
47950                 filter = function(d) { return set$$1.has(d.id); };
47951
47952             } else {
47953                 data = all;
47954                 filter = utilFunctor(true);
47955             }
47956         }
47957
47958         data = features.filter(data, graph);
47959
47960         surface.selectAll('.data-layer-osm')
47961             .call(drawVertices, graph, data, filter, map.extent(), map.zoom())
47962             .call(drawLines, graph, data, filter)
47963             .call(drawAreas, graph, data, filter)
47964             .call(drawMidpoints, graph, data, filter, map.trimmedExtent())
47965             .call(drawLabels, graph, data, filter, dimensions, !difference && !extent)
47966             .call(drawPoints, graph, data, filter);
47967
47968         dispatch$$1.call('drawn', this, {full: true});
47969     }
47970
47971
47972     function editOff() {
47973         context.features().resetStats();
47974         surface.selectAll('.layer-osm *').remove();
47975         context.enter(modeBrowse(context));
47976         dispatch$$1.call('drawn', this, {full: true});
47977     }
47978
47979
47980     function dblClick() {
47981         if (!dblclickEnabled) {
47982             event.preventDefault();
47983             event.stopImmediatePropagation();
47984         }
47985     }
47986
47987
47988     function zoomPan(manualEvent) {
47989         var event$$1 = (manualEvent || event),
47990             source = event$$1.sourceEvent,
47991             eventTransform = event$$1.transform;
47992
47993         if (transformStart.x === eventTransform.x &&
47994             transformStart.y === eventTransform.y &&
47995             transformStart.k === eventTransform.k) {
47996             return;  // no change
47997         }
47998
47999         // Normalize mousewheel - #3029
48000         // If wheel delta is provided in LINE units, recalculate it in PIXEL units
48001         // We are essentially redoing the calculations that occur here:
48002         //   https://github.com/d3/d3-zoom/blob/78563a8348aa4133b07cac92e2595c2227ca7cd7/src/zoom.js#L203
48003         // See this for more info:
48004         //   https://github.com/basilfx/normalize-wheel/blob/master/src/normalizeWheel.js
48005         if (source && source.type === 'wheel' && source.deltaMode === 1 /* LINE */) {
48006             // pick sensible scroll amount if user scrolling fast or slow..
48007             var lines = Math.abs(source.deltaY),
48008                 scroll = lines > 2 ? 40 : lines * 10;
48009
48010             var t0 = transformed ? transformLast : transformStart,
48011                 p0 = mouse(source),
48012                 p1 = t0.invert(p0),
48013                 k2 = t0.k * Math.pow(2, -source.deltaY * scroll / 500),
48014                 x2 = p0[0] - p1[0] * k2,
48015                 y2 = p0[1] - p1[1] * k2;
48016
48017             eventTransform = identity$7.translate(x2,y2).scale(k2);
48018             _selection.node().__zoom = eventTransform;
48019         }
48020
48021         if (ktoz(eventTransform.k * 2 * Math.PI) < minzoom) {
48022             surface.interrupt();
48023             uiFlash().text(t('cannot_zoom'));
48024             setZoom(context.minEditableZoom(), true);
48025             scheduleRedraw();
48026             dispatch$$1.call('move', this, map);
48027             return;
48028         }
48029
48030         projection.transform(eventTransform);
48031
48032         var scale = eventTransform.k / transformStart.k,
48033             tX = (eventTransform.x / scale - transformStart.x) * scale,
48034             tY = (eventTransform.y / scale - transformStart.y) * scale;
48035
48036         if (context.inIntro()) {
48037             curtainProjection.transform({
48038                 x: eventTransform.x - tX,
48039                 y: eventTransform.y - tY,
48040                 k: eventTransform.k
48041             });
48042         }
48043
48044         mousemove = event$$1;
48045         transformed = true;
48046         transformLast = eventTransform;
48047         utilSetTransform(supersurface, tX, tY, scale);
48048         scheduleRedraw();
48049
48050         dispatch$$1.call('move', this, map);
48051     }
48052
48053
48054     function resetTransform() {
48055         if (!transformed) return false;
48056
48057         // deprecation warning - Radial Menu to be removed in iD v3
48058         surface.selectAll('.edit-menu, .radial-menu').interrupt().remove();
48059         utilSetTransform(supersurface, 0, 0);
48060         transformed = false;
48061         if (context.inIntro()) {
48062             curtainProjection.transform(projection.transform());
48063         }
48064         return true;
48065     }
48066
48067
48068     function redraw(difference, extent) {
48069         if (surface.empty() || !redrawEnabled) return;
48070
48071         // If we are in the middle of a zoom/pan, we can't do differenced redraws.
48072         // It would result in artifacts where differenced entities are redrawn with
48073         // one transform and unchanged entities with another.
48074         if (resetTransform()) {
48075             difference = extent = undefined;
48076         }
48077
48078         var z = String(~~map.zoom());
48079         if (surface.attr('data-zoom') !== z) {
48080             surface.attr('data-zoom', z)
48081                 .classed('low-zoom', z <= 16);
48082         }
48083
48084         if (!difference) {
48085             supersurface.call(context.background());
48086         }
48087
48088         wrapper
48089             .call(drawLayers);
48090
48091         // OSM
48092         if (map.editable()) {
48093             context.loadTiles(projection, dimensions);
48094             drawVector(difference, extent);
48095         } else {
48096             editOff();
48097         }
48098
48099         transformStart = projection.transform();
48100
48101         return map;
48102     }
48103
48104
48105
48106     var immediateRedraw = function(difference, extent) {
48107         if (!difference && !extent) cancelPendingRedraw();
48108         redraw(difference, extent);
48109     };
48110
48111
48112     function pointLocation(p) {
48113         var translate = projection.translate(),
48114             scale = projection.scale() * 2 * Math.PI;
48115         return [(p[0] - translate[0]) / scale, (p[1] - translate[1]) / scale];
48116     }
48117
48118
48119     function locationPoint(l) {
48120         var translate = projection.translate(),
48121             scale = projection.scale() * 2 * Math.PI;
48122         return [l[0] * scale + translate[0], l[1] * scale + translate[1]];
48123     }
48124
48125
48126     map.mouse = function() {
48127         var event$$1 = mousemove || event;
48128         if (event$$1) {
48129             var s;
48130             while ((s = event$$1.sourceEvent)) { event$$1 = s; }
48131             return mouse(event$$1);
48132         }
48133         return null;
48134     };
48135
48136
48137     map.mouseCoordinates = function() {
48138         return projection.invert(map.mouse());
48139     };
48140
48141
48142     map.dblclickEnable = function(_) {
48143         if (!arguments.length) return dblclickEnabled;
48144         dblclickEnabled = _;
48145         return map;
48146     };
48147
48148
48149     map.redrawEnable = function(_) {
48150         if (!arguments.length) return redrawEnabled;
48151         redrawEnabled = _;
48152         return map;
48153     };
48154
48155
48156     function setTransform(t2, duration, force) {
48157         var t$$1 = projection.transform();
48158         if (!force && t2.k === t$$1.k && t2.x === t$$1.x && t2.y === t$$1.y) {
48159             return false;
48160         }
48161
48162         if (duration) {
48163             _selection
48164                 .transition()
48165                 .duration(duration)
48166                 .on('start', function() { map.startEase(); })
48167                 .call(zoom$$1.transform, identity$7.translate(t2.x, t2.y).scale(t2.k));
48168         } else {
48169             projection.transform(t2);
48170             transformStart = t2;
48171             _selection.call(zoom$$1.transform, transformStart);
48172         }
48173     }
48174
48175
48176     function setZoom(z2, force, duration) {
48177         if (z2 === map.zoom() && !force) {
48178             return false;
48179         }
48180
48181         var k = projection.scale(),
48182             k2 = Math.max(ztok(2), Math.min(ztok(24), ztok(z2))) / (2 * Math.PI),
48183             center = pxCenter(),
48184             l = pointLocation(center);
48185
48186         projection.scale(k2);
48187
48188         var t$$1 = projection.translate();
48189         l = locationPoint(l);
48190
48191         t$$1[0] += center[0] - l[0];
48192         t$$1[1] += center[1] - l[1];
48193
48194         if (duration) {
48195             projection.scale(k);  // reset scale
48196             _selection
48197                 .transition()
48198                 .duration(duration)
48199                 .on('start', function() { map.startEase(); })
48200                 .call(zoom$$1.transform, identity$7.translate(t$$1[0], t$$1[1]).scale(k2));
48201         } else {
48202             projection.translate(t$$1);
48203             transformStart = projection.transform();
48204             _selection.call(zoom$$1.transform, transformStart);
48205         }
48206
48207         return true;
48208     }
48209
48210
48211     function setCenter(loc2, duration) {
48212         var c = map.center();
48213         if (loc2[0] === c[0] && loc2[1] === c[1]) {
48214             return false;
48215         }
48216
48217         var t$$1 = projection.translate(),
48218             k = projection.scale(),
48219             pxC = pxCenter(),
48220             ll = projection(loc2);
48221
48222         t$$1[0] = t$$1[0] - ll[0] + pxC[0];
48223         t$$1[1] = t$$1[1] - ll[1] + pxC[1];
48224
48225         if (duration) {
48226             _selection
48227                 .transition()
48228                 .duration(duration)
48229                 .on('start', function() { map.startEase(); })
48230                 .call(zoom$$1.transform, identity$7.translate(t$$1[0], t$$1[1]).scale(k));
48231         } else {
48232             projection.translate(t$$1);
48233             transformStart = projection.transform();
48234             _selection.call(zoom$$1.transform, transformStart);
48235         }
48236
48237         return true;
48238     }
48239
48240
48241     map.pan = function(delta, duration) {
48242         var t$$1 = projection.translate(),
48243             k = projection.scale();
48244
48245         t$$1[0] += delta[0];
48246         t$$1[1] += delta[1];
48247
48248         if (duration) {
48249             _selection
48250                 .transition()
48251                 .duration(duration)
48252                 .on('start', function() { map.startEase(); })
48253                 .call(zoom$$1.transform, identity$7.translate(t$$1[0], t$$1[1]).scale(k));
48254         } else {
48255             projection.translate(t$$1);
48256             transformStart = projection.transform();
48257             _selection.call(zoom$$1.transform, transformStart);
48258             dispatch$$1.call('move', this, map);
48259             immediateRedraw();
48260         }
48261
48262         return map;
48263     };
48264
48265
48266     map.dimensions = function(_) {
48267         if (!arguments.length) return dimensions;
48268         var center = map.center();
48269         dimensions = _;
48270         drawLayers.dimensions(dimensions);
48271         context.background().dimensions(dimensions);
48272         projection.clipExtent([[0, 0], dimensions]);
48273         mouse = utilFastMouse(supersurface.node());
48274         setCenter(center);
48275
48276         scheduleRedraw();
48277         return map;
48278     };
48279
48280
48281     function zoomIn(delta) {
48282         setZoom(~~map.zoom() + delta, true, 250);
48283     }
48284
48285     function zoomOut(delta) {
48286         setZoom(~~map.zoom() - delta, true, 250);
48287     }
48288
48289     map.zoomIn = function() { zoomIn(1); };
48290     map.zoomInFurther = function() { zoomIn(4); };
48291
48292     map.zoomOut = function() { zoomOut(1); };
48293     map.zoomOutFurther = function() { zoomOut(4); };
48294
48295
48296     map.center = function(loc2) {
48297         if (!arguments.length) {
48298             return projection.invert(pxCenter());
48299         }
48300
48301         if (setCenter(loc2)) {
48302             dispatch$$1.call('move', this, map);
48303         }
48304
48305         scheduleRedraw();
48306         return map;
48307     };
48308
48309
48310     map.zoom = function(z2) {
48311         if (!arguments.length) {
48312             return Math.max(ktoz(projection.scale() * 2 * Math.PI), 0);
48313         }
48314
48315         if (z2 < minzoom) {
48316             surface.interrupt();
48317             uiFlash().text(t('cannot_zoom'));
48318             z2 = context.minEditableZoom();
48319         }
48320
48321         if (setZoom(z2)) {
48322             dispatch$$1.call('move', this, map);
48323         }
48324
48325         scheduleRedraw();
48326         return map;
48327     };
48328
48329
48330     map.zoomTo = function(entity, zoomLimits) {
48331         var extent = entity.extent(context.graph());
48332         if (!isFinite(extent.area())) return;
48333
48334         var z2 = map.trimmedExtentZoom(extent);
48335         zoomLimits = zoomLimits || [context.minEditableZoom(), 20];
48336         map.centerZoom(extent.center(), Math.min(Math.max(z2, zoomLimits[0]), zoomLimits[1]));
48337     };
48338
48339
48340     map.centerZoom = function(loc2, z2) {
48341         var centered = setCenter(loc2),
48342             zoomed   = setZoom(z2);
48343
48344         if (centered || zoomed) {
48345             dispatch$$1.call('move', this, map);
48346         }
48347
48348         scheduleRedraw();
48349         return map;
48350     };
48351
48352
48353     map.centerEase = function(loc2, duration) {
48354         duration = duration || 250;
48355         setCenter(loc2, duration);
48356         return map;
48357     };
48358
48359
48360     map.zoomEase = function(z2, duration) {
48361         duration = duration || 250;
48362         setZoom(z2, false, duration);
48363         return map;
48364     };
48365
48366
48367     map.transformEase = function(t2, duration) {
48368         duration = duration || 250;
48369         setTransform(t2, duration, false);
48370         return map;
48371     };
48372
48373
48374     map.startEase = function() {
48375         utilBindOnce(surface, 'mousedown.ease', function() {
48376             map.cancelEase();
48377         });
48378         return map;
48379     };
48380
48381
48382     map.cancelEase = function() {
48383         _selection.interrupt();
48384         return map;
48385     };
48386
48387
48388     map.extent = function(_) {
48389         if (!arguments.length) {
48390             return new geoExtent(projection.invert([0, dimensions[1]]),
48391                                  projection.invert([dimensions[0], 0]));
48392         } else {
48393             var extent = geoExtent(_);
48394             map.centerZoom(extent.center(), map.extentZoom(extent));
48395         }
48396     };
48397
48398
48399     map.trimmedExtent = function(_) {
48400         if (!arguments.length) {
48401             var headerY = 60, footerY = 30, pad = 10;
48402             return new geoExtent(projection.invert([pad, dimensions[1] - footerY - pad]),
48403                                  projection.invert([dimensions[0] - pad, headerY + pad]));
48404         } else {
48405             var extent = geoExtent(_);
48406             map.centerZoom(extent.center(), map.trimmedExtentZoom(extent));
48407         }
48408     };
48409
48410
48411     function calcZoom(extent, dim) {
48412         var tl = projection([extent[0][0], extent[1][1]]),
48413             br = projection([extent[1][0], extent[0][1]]);
48414
48415         // Calculate maximum zoom that fits extent
48416         var hFactor = (br[0] - tl[0]) / dim[0],
48417             vFactor = (br[1] - tl[1]) / dim[1],
48418             hZoomDiff = Math.log(Math.abs(hFactor)) / Math.LN2,
48419             vZoomDiff = Math.log(Math.abs(vFactor)) / Math.LN2,
48420             newZoom = map.zoom() - Math.max(hZoomDiff, vZoomDiff);
48421
48422         return newZoom;
48423     }
48424
48425
48426     map.extentZoom = function(_) {
48427         return calcZoom(geoExtent(_), dimensions);
48428     };
48429
48430
48431     map.trimmedExtentZoom = function(_) {
48432         var trimY = 120, trimX = 40,
48433             trimmed = [dimensions[0] - trimX, dimensions[1] - trimY];
48434         return calcZoom(geoExtent(_), trimmed);
48435     };
48436
48437
48438     map.editable = function() {
48439         var osmLayer = surface.selectAll('.data-layer-osm');
48440         if (!osmLayer.empty() && osmLayer.classed('disabled')) return false;
48441
48442         return map.zoom() >= context.minEditableZoom();
48443     };
48444
48445
48446     map.minzoom = function(_) {
48447         if (!arguments.length) return minzoom;
48448         minzoom = _;
48449         return map;
48450     };
48451
48452
48453     map.layers = drawLayers;
48454
48455
48456     return utilRebind(map, dispatch$$1, 'on');
48457 }
48458
48459 var TAU = 2 * Math.PI;
48460 function ztok(z) { return 256 * Math.pow(2, z) / TAU; }
48461 function ktoz(k) { return Math.log(k * TAU) / Math.LN2 - 8; }
48462 function vecSub(a, b) { return [ a[0] - b[0], a[1] - b[1] ]; }
48463 function vecScale(a, b) { return [ a[0] * b, a[1] * b ]; }
48464
48465
48466 function uiMapInMap(context) {
48467
48468
48469     function map_in_map(selection) {
48470         var backgroundLayer = rendererTileLayer(context),
48471             overlayLayers = {},
48472             projection = geoRawMercator(),
48473             gpxLayer = svgGpx(projection, context).showLabels(false),
48474             debugLayer = svgDebug(projection, context),
48475             zoom$$1 = d3_zoom()
48476                 .scaleExtent([ztok(0.5), ztok(24)])
48477                 .on('start', zoomStarted)
48478                 .on('zoom', zoomed)
48479                 .on('end', zoomEnded),
48480             isTransformed = false,
48481             isHidden = true,
48482             skipEvents = false,
48483             gesture = null,
48484             zDiff = 6,    // by default, minimap renders at (main zoom - 6)
48485             wrap = d3_select(null),
48486             tiles = d3_select(null),
48487             viewport = d3_select(null),
48488             tStart,  // transform at start of gesture
48489             tCurr,   // transform at most recent event
48490             timeoutId;
48491
48492
48493         function zoomStarted() {
48494             if (skipEvents) return;
48495             tStart = tCurr = projection.transform();
48496             gesture = null;
48497         }
48498
48499
48500         function zoomed() {
48501             if (skipEvents) return;
48502
48503             var x = event.transform.x,
48504                 y = event.transform.y,
48505                 k = event.transform.k,
48506                 isZooming = (k !== tStart.k),
48507                 isPanning = (x !== tStart.x || y !== tStart.y);
48508
48509             if (!isZooming && !isPanning) {
48510                 return;  // no change
48511             }
48512
48513             // lock in either zooming or panning, don't allow both in minimap.
48514             if (!gesture) {
48515                 gesture = isZooming ? 'zoom' : 'pan';
48516             }
48517
48518             var tMini = projection.transform(),
48519                 tX, tY, scale;
48520
48521             if (gesture === 'zoom') {
48522                 var dMini = utilGetDimensions(wrap),
48523                     cMini = vecScale(dMini, 0.5);
48524                 scale = k / tMini.k;
48525                 tX = (cMini[0] / scale - cMini[0]) * scale;
48526                 tY = (cMini[1] / scale - cMini[1]) * scale;
48527             } else {
48528                 k = tMini.k;
48529                 scale = 1;
48530                 tX = x - tMini.x;
48531                 tY = y - tMini.y;
48532             }
48533
48534             utilSetTransform(tiles, tX, tY, scale);
48535             utilSetTransform(viewport, 0, 0, scale);
48536             isTransformed = true;
48537             tCurr = identity$7.translate(x, y).scale(k);
48538
48539             var zMain = ktoz(context.projection.scale()),
48540                 zMini = ktoz(k);
48541
48542             zDiff = zMain - zMini;
48543
48544             queueRedraw();
48545         }
48546
48547
48548         function zoomEnded() {
48549             if (skipEvents) return;
48550             if (gesture !== 'pan') return;
48551
48552             updateProjection();
48553             gesture = null;
48554             var dMini = utilGetDimensions(wrap),
48555                 cMini = vecScale(dMini, 0.5);
48556             context.map().center(projection.invert(cMini));   // recenter main map..
48557         }
48558
48559
48560         function updateProjection() {
48561             var loc = context.map().center(),
48562                 dMini = utilGetDimensions(wrap),
48563                 cMini = vecScale(dMini, 0.5),
48564                 tMain = context.projection.transform(),
48565                 zMain = ktoz(tMain.k),
48566                 zMini = Math.max(zMain - zDiff, 0.5),
48567                 kMini = ztok(zMini);
48568
48569             projection
48570                 .translate([tMain.x, tMain.y])
48571                 .scale(kMini);
48572
48573             var point = projection(loc),
48574                 mouse = (gesture === 'pan') ? vecSub([tCurr.x, tCurr.y], [tStart.x, tStart.y]) : [0, 0],
48575                 xMini = cMini[0] - point[0] + tMain.x + mouse[0],
48576                 yMini = cMini[1] - point[1] + tMain.y + mouse[1];
48577
48578             projection
48579                 .translate([xMini, yMini])
48580                 .clipExtent([[0, 0], dMini]);
48581
48582             tCurr = projection.transform();
48583
48584             if (isTransformed) {
48585                 utilSetTransform(tiles, 0, 0);
48586                 utilSetTransform(viewport, 0, 0);
48587                 isTransformed = false;
48588             }
48589
48590             zoom$$1
48591                 .scaleExtent([ztok(0.5), ztok(zMain - 3)]);
48592
48593             skipEvents = true;
48594             wrap.call(zoom$$1.transform, tCurr);
48595             skipEvents = false;
48596         }
48597
48598
48599         function redraw() {
48600             clearTimeout(timeoutId);
48601             if (isHidden) return;
48602
48603             updateProjection();
48604
48605             var dMini = utilGetDimensions(wrap),
48606                 zMini = ktoz(projection.scale());
48607
48608             // setup tile container
48609             tiles = wrap
48610                 .selectAll('.map-in-map-tiles')
48611                 .data([0]);
48612
48613             tiles = tiles.enter()
48614                 .append('div')
48615                 .attr('class', 'map-in-map-tiles')
48616                 .merge(tiles);
48617
48618             // redraw background
48619             backgroundLayer
48620                 .source(context.background().baseLayerSource())
48621                 .projection(projection)
48622                 .dimensions(dMini);
48623
48624             var background = tiles
48625                 .selectAll('.map-in-map-background')
48626                 .data([0]);
48627
48628             background.enter()
48629                 .append('div')
48630                 .attr('class', 'map-in-map-background')
48631                 .merge(background)
48632                 .call(backgroundLayer);
48633
48634
48635             // redraw overlay
48636             var overlaySources = context.background().overlayLayerSources();
48637             var activeOverlayLayers = [];
48638             for (var i = 0; i < overlaySources.length; i++) {
48639                 if (overlaySources[i].validZoom(zMini)) {
48640                     if (!overlayLayers[i]) overlayLayers[i] = rendererTileLayer(context);
48641                     activeOverlayLayers.push(overlayLayers[i]
48642                         .source(overlaySources[i])
48643                         .projection(projection)
48644                         .dimensions(dMini));
48645                 }
48646             }
48647
48648             var overlay = tiles
48649                 .selectAll('.map-in-map-overlay')
48650                 .data([0]);
48651
48652             overlay = overlay.enter()
48653                 .append('div')
48654                 .attr('class', 'map-in-map-overlay')
48655                 .merge(overlay);
48656
48657
48658             var overlays = overlay
48659                 .selectAll('div')
48660                 .data(activeOverlayLayers, function(d) { return d.source().name(); });
48661
48662             overlays.exit()
48663                 .remove();
48664
48665             overlays = overlays.enter()
48666                 .append('div')
48667                 .merge(overlays)
48668                 .each(function(layer) { d3_select(this).call(layer); });
48669
48670
48671             var dataLayers = tiles
48672                 .selectAll('.map-in-map-data')
48673                 .data([0]);
48674
48675             dataLayers.exit()
48676                 .remove();
48677
48678             dataLayers = dataLayers.enter()
48679                 .append('svg')
48680                 .attr('class', 'map-in-map-data')
48681                 .merge(dataLayers)
48682                 .call(gpxLayer)
48683                 .call(debugLayer);
48684
48685
48686             // redraw viewport bounding box
48687             if (gesture !== 'pan') {
48688                 var getPath = d3_geoPath(projection),
48689                     bbox = { type: 'Polygon', coordinates: [context.map().extent().polygon()] };
48690
48691                 viewport = wrap.selectAll('.map-in-map-viewport')
48692                     .data([0]);
48693
48694                 viewport = viewport.enter()
48695                     .append('svg')
48696                     .attr('class', 'map-in-map-viewport')
48697                     .merge(viewport);
48698
48699
48700                 var path = viewport.selectAll('.map-in-map-bbox')
48701                     .data([bbox]);
48702
48703                 path.enter()
48704                     .append('path')
48705                     .attr('class', 'map-in-map-bbox')
48706                     .merge(path)
48707                     .attr('d', getPath)
48708                     .classed('thick', function(d) { return getPath.area(d) < 30; });
48709             }
48710         }
48711
48712
48713         function queueRedraw() {
48714             clearTimeout(timeoutId);
48715             timeoutId = setTimeout(function() { redraw(); }, 750);
48716         }
48717
48718
48719         function toggle() {
48720             if (event) event.preventDefault();
48721
48722             isHidden = !isHidden;
48723
48724             var label = d3_select('.minimap-toggle');
48725             label.classed('active', !isHidden)
48726                 .select('input').property('checked', !isHidden);
48727
48728             if (isHidden) {
48729                 wrap
48730                     .style('display', 'block')
48731                     .style('opacity', '1')
48732                     .transition()
48733                     .duration(200)
48734                     .style('opacity', '0')
48735                     .on('end', function() {
48736                         selection.selectAll('.map-in-map')
48737                             .style('display', 'none');
48738                     });
48739             } else {
48740                 wrap
48741                     .style('display', 'block')
48742                     .style('opacity', '0')
48743                     .transition()
48744                     .duration(200)
48745                     .style('opacity', '1')
48746                     .on('end', function() {
48747                         redraw();
48748                     });
48749             }
48750         }
48751
48752
48753         uiMapInMap.toggle = toggle;
48754
48755         wrap = selection.selectAll('.map-in-map')
48756             .data([0]);
48757
48758         wrap = wrap.enter()
48759             .append('div')
48760             .attr('class', 'map-in-map')
48761             .style('display', (isHidden ? 'none' : 'block'))
48762             .call(zoom$$1)
48763             .on('dblclick.zoom', null)
48764             .merge(wrap);
48765
48766         context.map()
48767             .on('drawn.map-in-map', function(drawn) {
48768                 if (drawn.full === true) {
48769                     redraw();
48770                 }
48771             });
48772
48773         redraw();
48774
48775         var keybinding = d3keybinding('map-in-map')
48776             .on(t('background.minimap.key'), toggle);
48777
48778         d3_select(document)
48779             .call(keybinding);
48780     }
48781
48782     return map_in_map;
48783 }
48784
48785 function uiTooltipHtml(text, key, heading) {
48786     var s = '';
48787
48788     if (heading) {
48789         s += '<div class="tooltip-heading"><span>' + heading + '</span></div>';
48790     }
48791     if (text) {
48792         s += '<div class="tooltip-text"><span>' + text + '</span></div>';
48793     }
48794     if (key) {
48795         s += '<div class="keyhint-wrap"><span>' + t('tooltip_keyhint') + '</span>' +
48796             '<span class="keyhint">' + key + '</span></div>';
48797     }
48798
48799     return s;
48800 }
48801
48802 function uiBackground(context) {
48803     var key = t('background.key'),
48804         detected = utilDetect(),
48805         opacities = [1, 0.75, 0.5, 0.25],
48806         directions = [
48807             ['right', [0.5, 0]],
48808             ['top', [0, -0.5]],
48809             ['left', [-0.5, 0]],
48810             ['bottom', [0, 0.5]]],
48811         opacityDefault = (context.storage('background-opacity') !== null) ?
48812             (+context.storage('background-opacity')) : 1.0,
48813         customSource = context.background().findSource('custom'),
48814         previous;
48815
48816     // Can be 0 from <1.3.0 use or due to issue #1923.
48817     if (opacityDefault === 0) opacityDefault = 1.0;
48818
48819
48820     function background(selection) {
48821
48822         function sortSources(a, b) {
48823             return a.best() && !b.best() ? -1
48824                 : b.best() && !a.best() ? 1
48825                 : d3_descending(a.area(), b.area()) || d3_ascending(a.name(), b.name()) || 0;
48826         }
48827
48828
48829         function setOpacity(d) {
48830             var bg = context.container().selectAll('.layer-background')
48831                 .transition()
48832                 .style('opacity', d)
48833                 .attr('data-opacity', d);
48834
48835             if (!detected.opera) {
48836                 utilSetTransform(bg, 0, 0);
48837             }
48838
48839             opacityList.selectAll('li')
48840                 .classed('active', function(_) { return _ === d; });
48841
48842             context.storage('background-opacity', d);
48843         }
48844
48845
48846         function setTooltips(selection) {
48847             selection.each(function(d, i, nodes) {
48848                 var item = d3_select(this).select('label'),
48849                     span = item.select('span'),
48850                     placement = (i < nodes.length / 2) ? 'bottom' : 'top',
48851                     description = d.description(),
48852                     isOverflowing = (span.property('clientWidth') !== span.property('scrollWidth'));
48853
48854                 if (d === previous) {
48855                     item.call(tooltip()
48856                         .placement(placement)
48857                         .html(true)
48858                         .title(function() {
48859                             var tip = '<div>' + t('background.switch') + '</div>';
48860                             return uiTooltipHtml(tip, uiCmd('⌘' + key));
48861                         })
48862                     );
48863                 } else if (description || isOverflowing) {
48864                     item.call(tooltip()
48865                         .placement(placement)
48866                         .title(description || d.name())
48867                     );
48868                 } else {
48869                     item.call(tooltip().destroy);
48870                 }
48871             });
48872         }
48873
48874
48875         function selectLayer() {
48876             function active(d) {
48877                 return context.background().showsLayer(d);
48878             }
48879
48880             content.selectAll('.layer')
48881                 .classed('active', active)
48882                 .classed('switch', function(d) { return d === previous; })
48883                 .call(setTooltips)
48884                 .selectAll('input')
48885                 .property('checked', active);
48886         }
48887
48888
48889         function clickSetSource(d) {
48890             if (d.id === 'custom' && !d.template()) {
48891                 return editCustom();
48892             }
48893
48894             event.preventDefault();
48895             previous = context.background().baseLayerSource();
48896             context.background().baseLayerSource(d);
48897             selectLayer();
48898             document.activeElement.blur();
48899         }
48900
48901
48902         function editCustom() {
48903             event.preventDefault();
48904             var example = 'https://{switch:a,b,c}.tile.openstreetmap.org/{zoom}/{x}/{y}.png';
48905             var template = window.prompt(
48906                 t('background.custom_prompt', { example: example }),
48907                 customSource.template() || example
48908             );
48909
48910             if (template) {
48911                 context.storage('background-custom-template', template);
48912                 customSource.template(template);
48913                 clickSetSource(customSource);
48914             } else {
48915                 selectLayer();
48916             }
48917         }
48918
48919
48920         function clickSetOverlay(d) {
48921             event.preventDefault();
48922             context.background().toggleOverlayLayer(d);
48923             selectLayer();
48924             document.activeElement.blur();
48925         }
48926
48927
48928         function drawList(layerList, type, change, filter) {
48929             var sources = context.background()
48930                 .sources(context.map().extent())
48931                 .filter(filter);
48932
48933             var layerLinks = layerList.selectAll('li.layer')
48934                 .data(sources, function(d) { return d.name(); });
48935
48936             layerLinks.exit()
48937                 .remove();
48938
48939             var enter = layerLinks.enter()
48940                 .append('li')
48941                 .attr('class', 'layer')
48942                 .classed('layer-custom', function(d) { return d.id === 'custom'; })
48943                 .classed('best', function(d) { return d.best(); });
48944
48945             enter.filter(function(d) { return d.id === 'custom'; })
48946                 .append('button')
48947                 .attr('class', 'layer-browse')
48948                 .call(tooltip()
48949                     .title(t('background.custom_button'))
48950                     .placement((textDirection === 'rtl') ? 'right' : 'left'))
48951                 .on('click', editCustom)
48952                 .call(svgIcon('#icon-search'));
48953
48954             enter.filter(function(d) { return d.best(); })
48955                 .append('div')
48956                 .attr('class', 'best')
48957                 .call(tooltip()
48958                     .title(t('background.best_imagery'))
48959                     .placement((textDirection === 'rtl') ? 'right' : 'left'))
48960                 .append('span')
48961                 .html('&#9733;');
48962
48963             var label = enter
48964                 .append('label');
48965
48966             label
48967                 .append('input')
48968                 .attr('type', type)
48969                 .attr('name', 'layers')
48970                 .on('change', change);
48971
48972             label
48973                 .append('span')
48974                 .text(function(d) { return d.name(); });
48975
48976
48977             layerList.selectAll('li.layer')
48978                 .sort(sortSources)
48979                 .style('display', layerList.selectAll('li.layer').data().length > 0 ? 'block' : 'none');
48980         }
48981
48982
48983         function update() {
48984             backgroundList.call(drawList, 'radio', clickSetSource, function(d) { return !d.isHidden() && !d.overlay; });
48985             overlayList.call(drawList, 'checkbox', clickSetOverlay, function(d) { return !d.isHidden() && d.overlay; });
48986
48987             selectLayer();
48988             updateOffsetVal();
48989         }
48990
48991
48992         function updateOffsetVal() {
48993             var meters = geoOffsetToMeters(context.background().offset()),
48994                 x = +meters[0].toFixed(2),
48995                 y = +meters[1].toFixed(2);
48996
48997             d3_selectAll('.nudge-inner-rect')
48998                 .select('input')
48999                 .classed('error', false)
49000                 .property('value', x + ', ' + y);
49001
49002             d3_selectAll('.nudge-reset')
49003                 .classed('disabled', function() {
49004                     return (x === 0 && y === 0);
49005                 });
49006         }
49007
49008
49009         function resetOffset() {
49010             if (event.button !== 0) return;
49011             context.background().offset([0, 0]);
49012             updateOffsetVal();
49013         }
49014
49015
49016         function nudge(d) {
49017             context.background().nudge(d, context.map().zoom());
49018             updateOffsetVal();
49019         }
49020
49021
49022         function buttonOffset(d) {
49023             if (event.button !== 0) return;
49024             var timeout = window.setTimeout(function() {
49025                     interval = window.setInterval(nudge.bind(null, d), 100);
49026                 }, 500),
49027                 interval;
49028
49029             function doneNudge() {
49030                 window.clearTimeout(timeout);
49031                 window.clearInterval(interval);
49032                 d3_select(window)
49033                     .on('mouseup.buttonoffset', null, true)
49034                     .on('mousedown.buttonoffset', null, true);
49035             }
49036
49037             d3_select(window)
49038                 .on('mouseup.buttonoffset', doneNudge, true)
49039                 .on('mousedown.buttonoffset', doneNudge, true);
49040
49041             nudge(d);
49042         }
49043
49044
49045         function inputOffset() {
49046             if (event.button !== 0) return;
49047             var input = d3_select(this);
49048             var d = input.node().value;
49049
49050             if (d === '') return resetOffset();
49051
49052             d = d.replace(/;/g, ',').split(',').map(function(n) {
49053                 // if n is NaN, it will always get mapped to false.
49054                 return !isNaN(n) && n;
49055             });
49056
49057             if (d.length !== 2 || !d[0] || !d[1]) {
49058                 input.classed('error', true);
49059                 return;
49060             }
49061
49062             context.background().offset(geoMetersToOffset(d));
49063             updateOffsetVal();
49064         }
49065
49066
49067         function dragOffset() {
49068             if (event.button !== 0) return;
49069             var origin = [event.clientX, event.clientY];
49070
49071             context.container()
49072                 .append('div')
49073                 .attr('class', 'nudge-surface');
49074
49075             d3_select(window)
49076                 .on('mousemove.offset', function() {
49077                     var latest = [event.clientX, event.clientY];
49078                     var d = [
49079                         -(origin[0] - latest[0]) / 4,
49080                         -(origin[1] - latest[1]) / 4
49081                     ];
49082
49083                     origin = latest;
49084                     nudge(d);
49085                 })
49086                 .on('mouseup.offset', function() {
49087                     if (event.button !== 0) return;
49088                     d3_selectAll('.nudge-surface')
49089                         .remove();
49090
49091                     d3_select(window)
49092                         .on('mousemove.offset', null)
49093                         .on('mouseup.offset', null);
49094                 });
49095
49096             event.preventDefault();
49097         }
49098
49099
49100         function hide() {
49101             setVisible(false);
49102         }
49103
49104
49105         function toggle() {
49106             if (event) {
49107                 event.preventDefault();
49108             }
49109             tooltipBehavior.hide(button);
49110             setVisible(!button.classed('active'));
49111         }
49112
49113
49114         function quickSwitch() {
49115             if (event) {
49116                 event.stopImmediatePropagation();
49117                 event.preventDefault();
49118             }
49119             if (previous) {
49120                 clickSetSource(previous);
49121             }
49122         }
49123
49124
49125         function setVisible(show) {
49126             if (show !== shown) {
49127                 button.classed('active', show);
49128                 shown = show;
49129
49130                 if (show) {
49131                     selection
49132                         .on('mousedown.background-inside', function() {
49133                             event.stopPropagation();
49134                         });
49135
49136                     content
49137                         .style('display', 'block')
49138                         .style('right', '-300px')
49139                         .transition()
49140                         .duration(200)
49141                         .style('right', '0px');
49142
49143                     content.selectAll('.layer')
49144                         .call(setTooltips);
49145
49146                 } else {
49147                     content
49148                         .style('display', 'block')
49149                         .style('right', '0px')
49150                         .transition()
49151                         .duration(200)
49152                         .style('right', '-300px')
49153                         .on('end', function() {
49154                             d3_select(this).style('display', 'none');
49155                         });
49156
49157                     selection
49158                         .on('mousedown.background-inside', null);
49159                 }
49160             }
49161         }
49162
49163
49164         var content = selection
49165                 .append('div')
49166                 .attr('class', 'fillL map-overlay col3 content hide'),
49167             tooltipBehavior = tooltip()
49168                 .placement((textDirection === 'rtl') ? 'right' : 'left')
49169                 .html(true)
49170                 .title(uiTooltipHtml(t('background.description'), key)),
49171             button = selection
49172                 .append('button')
49173                 .attr('tabindex', -1)
49174                 .on('click', toggle)
49175                 .call(svgIcon('#icon-layers', 'light'))
49176                 .call(tooltipBehavior),
49177             shown = false;
49178
49179
49180         /* opacity switcher */
49181
49182         var opawrap = content
49183                 .append('div')
49184                 .attr('class', 'opacity-options-wrapper');
49185
49186         opawrap
49187             .append('h4')
49188             .text(t('background.title'));
49189
49190         var opacityList = opawrap
49191             .append('ul')
49192             .attr('class', 'opacity-options');
49193
49194         opacityList.selectAll('div.opacity')
49195             .data(opacities)
49196             .enter()
49197             .append('li')
49198             .attr('data-original-title', function(d) {
49199                 return t('background.percent_brightness', { opacity: (d * 100) });
49200             })
49201             .on('click.set-opacity', setOpacity)
49202             .html('<div class="select-box"></div>')
49203             .call(tooltip()
49204                 .placement((textDirection === 'rtl') ? 'right' : 'left'))
49205             .append('div')
49206             .attr('class', 'opacity')
49207             .style('opacity', function(d) { return 1.25 - d; });
49208
49209
49210         /* background list */
49211
49212         var backgroundList = content
49213             .append('ul')
49214             .attr('class', 'layer-list')
49215             .attr('dir', 'auto');
49216
49217         content
49218             .append('div')
49219             .attr('class', 'imagery-faq')
49220             .append('a')
49221             .attr('target', '_blank')
49222             .attr('tabindex', -1)
49223             .call(svgIcon('#icon-out-link', 'inline'))
49224             .attr('href', 'https://github.com/openstreetmap/iD/blob/master/FAQ.md#how-can-i-report-an-issue-with-background-imagery')
49225             .append('span')
49226             .text(t('background.imagery_source_faq'));
49227
49228
49229         /* overlay list */
49230
49231         var overlayList = content
49232             .append('ul')
49233             .attr('class', 'layer-list');
49234
49235         var controls = content
49236             .append('div')
49237             .attr('class', 'controls-list');
49238
49239
49240         /* minimap toggle */
49241
49242         var minimapLabel = controls
49243             .append('label')
49244             .call(tooltip()
49245                 .html(true)
49246                 .title(uiTooltipHtml(t('background.minimap.tooltip'), t('background.minimap.key')))
49247                 .placement('top')
49248             );
49249
49250         minimapLabel
49251             .classed('minimap-toggle', true)
49252             .append('input')
49253             .attr('type', 'checkbox')
49254             .on('change', function() {
49255                 uiMapInMap.toggle();
49256                 event.preventDefault();
49257             });
49258
49259         minimapLabel
49260             .append('span')
49261             .text(t('background.minimap.description'));
49262
49263
49264         /* imagery offset controls */
49265
49266         var adjustments = content
49267             .append('div')
49268             .attr('class', 'adjustments');
49269
49270         adjustments
49271             .append('a')
49272             .text(t('background.fix_misalignment'))
49273             .attr('href', '#')
49274             .classed('hide-toggle', true)
49275             .classed('expanded', false)
49276             .on('click', function() {
49277                 if (event.button !== 0) return;
49278                 var exp = d3_select(this).classed('expanded');
49279                 nudgeContainer.style('display', exp ? 'none' : 'block');
49280                 d3_select(this).classed('expanded', !exp);
49281                 event.preventDefault();
49282             });
49283
49284         var nudgeContainer = adjustments
49285             .append('div')
49286             .attr('class', 'nudge-container cf')
49287             .style('display', 'none');
49288
49289         nudgeContainer
49290             .append('div')
49291             .attr('class', 'nudge-instructions')
49292             .text(t('background.offset'));
49293
49294         var nudgeRect = nudgeContainer
49295             .append('div')
49296             .attr('class', 'nudge-outer-rect')
49297             .on('mousedown', dragOffset);
49298
49299         nudgeRect
49300             .append('div')
49301             .attr('class', 'nudge-inner-rect')
49302             .append('input')
49303             .on('change', inputOffset)
49304             .on('mousedown', function() {
49305                 if (event.button !== 0) return;
49306                 event.stopPropagation();
49307             });
49308
49309         nudgeContainer
49310             .append('div')
49311             .selectAll('button')
49312             .data(directions).enter()
49313             .append('button')
49314             .attr('class', function(d) { return d[0] + ' nudge'; })
49315             .on('mousedown', function(d) {
49316                 if (event.button !== 0) return;
49317                 buttonOffset(d[1]);
49318             });
49319
49320         nudgeContainer
49321             .append('button')
49322             .attr('title', t('background.reset'))
49323             .attr('class', 'nudge-reset disabled')
49324             .on('click', resetOffset)
49325             .call(
49326                 (textDirection === 'rtl') ? svgIcon('#icon-redo') : svgIcon('#icon-undo')
49327             );
49328
49329         context.map()
49330             .on('move.background-update', debounce(utilCallWhenIdle(update), 1000));
49331
49332         context.background()
49333             .on('change.background-update', update);
49334
49335
49336         update();
49337         setOpacity(opacityDefault);
49338
49339         var keybinding = d3keybinding('background')
49340             .on(key, toggle)
49341             .on(uiCmd('⌘' + key), quickSwitch)
49342             .on([t('map_data.key'), t('help.key')], hide);
49343
49344         d3_select(document)
49345             .call(keybinding);
49346
49347         context.surface().on('mousedown.background-outside', hide);
49348         context.container().on('mousedown.background-outside', hide);
49349     }
49350
49351     return background;
49352 }
49353
49354 function uiContributors(context) {
49355     var osm = context.connection(),
49356         debouncedUpdate = debounce(function() { update(); }, 1000),
49357         limit = 4,
49358         hidden = false,
49359         wrap = d3_select(null);
49360
49361
49362     function update() {
49363         if (!osm) return;
49364
49365         var users = {},
49366             entities = context.intersects(context.map().extent());
49367
49368         entities.forEach(function(entity) {
49369             if (entity && entity.user) users[entity.user] = true;
49370         });
49371
49372         var u = Object.keys(users),
49373             subset = u.slice(0, u.length > limit ? limit - 1 : limit);
49374
49375         wrap.html('')
49376             .call(svgIcon('#icon-nearby', 'pre-text light'));
49377
49378         var userList = d3_select(document.createElement('span'));
49379
49380         userList.selectAll()
49381             .data(subset)
49382             .enter()
49383             .append('a')
49384             .attr('class', 'user-link')
49385             .attr('href', function(d) { return osm.userURL(d); })
49386             .attr('target', '_blank')
49387             .attr('tabindex', -1)
49388             .text(String);
49389
49390         if (u.length > limit) {
49391             var count = d3_select(document.createElement('span'));
49392
49393             count.append('a')
49394                 .attr('target', '_blank')
49395                 .attr('tabindex', -1)
49396                 .attr('href', function() {
49397                     return osm.changesetsURL(context.map().center(), context.map().zoom());
49398                 })
49399                 .text(u.length - limit + 1);
49400
49401             wrap.append('span')
49402                 .html(t('contributors.truncated_list', { users: userList.html(), count: count.html() }));
49403
49404         } else {
49405             wrap.append('span')
49406                 .html(t('contributors.list', { users: userList.html() }));
49407         }
49408
49409         if (!u.length) {
49410             hidden = true;
49411             wrap
49412                 .transition()
49413                 .style('opacity', 0);
49414
49415         } else if (hidden) {
49416             wrap
49417                 .transition()
49418                 .style('opacity', 1);
49419         }
49420     }
49421
49422
49423     return function(selection) {
49424         if (!osm) return;
49425         wrap = selection;
49426         update();
49427
49428         osm.on('loaded.contributors', debouncedUpdate);
49429         context.map().on('move.contributors', debouncedUpdate);
49430     };
49431 }
49432
49433 function uiFeatureInfo(context) {
49434     function update(selection) {
49435         var features = context.features(),
49436             stats = features.stats(),
49437             count = 0,
49438             hiddenList = compact(map$4(features.hidden(), function(k) {
49439                 if (stats[k]) {
49440                     count += stats[k];
49441                     return String(stats[k]) + ' ' + t('feature.' + k + '.description');
49442                 }
49443             }));
49444
49445         selection.html('');
49446
49447         if (hiddenList.length) {
49448             var tooltipBehavior = tooltip()
49449                 .placement('top')
49450                 .html(true)
49451                 .title(function() {
49452                     return uiTooltipHtml(hiddenList.join('<br/>'));
49453                 });
49454
49455             var warning = selection.append('a')
49456                 .attr('href', '#')
49457                 .attr('tabindex', -1)
49458                 .html(t('feature_info.hidden_warning', { count: count }))
49459                 .call(tooltipBehavior)
49460                 .on('click', function() {
49461                     tooltipBehavior.hide(warning);
49462                     // open map data panel?
49463                     event.preventDefault();
49464                 });
49465         }
49466
49467         selection
49468             .classed('hide', !hiddenList.length);
49469     }
49470
49471
49472     return function(selection) {
49473         update(selection);
49474
49475         context.features().on('change.feature_info', function() {
49476             update(selection);
49477         });
49478     };
49479 }
49480
49481 function uiFullScreen(context) {
49482     var element = context.container().node(),
49483         keybinding = d3keybinding('full-screen');
49484         // button;
49485
49486
49487     function getFullScreenFn() {
49488         if (element.requestFullscreen) {
49489             return element.requestFullscreen;
49490         } else if (element.msRequestFullscreen) {
49491             return element.msRequestFullscreen;
49492         } else if (element.mozRequestFullScreen) {
49493             return element.mozRequestFullScreen;
49494         } else if (element.webkitRequestFullscreen) {
49495             return element.webkitRequestFullscreen;
49496         }
49497     }
49498
49499
49500     function getExitFullScreenFn() {
49501         if (document.exitFullscreen) {
49502             return document.exitFullscreen;
49503         } else if (document.msExitFullscreen) {
49504             return document.msExitFullscreen;
49505         } else if (document.mozCancelFullScreen) {
49506             return document.mozCancelFullScreen;
49507         } else if (document.webkitExitFullscreen) {
49508             return document.webkitExitFullscreen;
49509         }
49510     }
49511
49512
49513     function isFullScreen() {
49514         return document.fullscreenElement ||
49515             document.mozFullScreenElement ||
49516             document.webkitFullscreenElement ||
49517             document.msFullscreenElement;
49518     }
49519
49520
49521     function isSupported() {
49522         return !!getFullScreenFn();
49523     }
49524
49525
49526     function fullScreen() {
49527         event.preventDefault();
49528         if (!isFullScreen()) {
49529             // button.classed('active', true);
49530             getFullScreenFn().apply(element);
49531         } else {
49532             // button.classed('active', false);
49533             getExitFullScreenFn().apply(document);
49534         }
49535     }
49536
49537
49538     return function() { // selection) {
49539         if (!isSupported())
49540             return;
49541
49542         // button = selection.append('button')
49543         //     .attr('title', t('full_screen'))
49544         //     .attr('tabindex', -1)
49545         //     .on('click', fullScreen)
49546         //     .call(tooltip);
49547
49548         // button.append('span')
49549         //     .attr('class', 'icon full-screen');
49550
49551         var detected = utilDetect();
49552         var keys = detected.os === 'mac' ? [uiCmd('⌃⌘F'), 'f11'] : ['f11'];
49553         keybinding.on(keys, fullScreen);
49554
49555         d3_select(document)
49556             .call(keybinding);
49557     };
49558 }
49559
49560 function uiModal(selection, blocking) {
49561     var keybinding = d3keybinding('modal');
49562     var previous = selection.select('div.modal');
49563     var animate = previous.empty();
49564
49565     previous.transition()
49566         .duration(200)
49567         .style('opacity', 0)
49568         .remove();
49569
49570     var shaded = selection
49571         .append('div')
49572         .attr('class', 'shaded')
49573         .style('opacity', 0);
49574
49575     shaded.close = function() {
49576         shaded
49577             .transition()
49578             .duration(200)
49579             .style('opacity',0)
49580             .remove();
49581
49582         modal
49583             .transition()
49584             .duration(200)
49585             .style('top','0px');
49586
49587         keybinding.off();
49588     };
49589
49590
49591     var modal = shaded
49592         .append('div')
49593         .attr('class', 'modal fillL col6');
49594
49595     if (!blocking) {
49596         shaded.on('click.remove-modal', function() {
49597             if (event.target === this) {
49598                 shaded.close();
49599             }
49600         });
49601
49602         modal.append('button')
49603             .attr('class', 'close')
49604             .on('click', shaded.close)
49605             .call(svgIcon('#icon-close'));
49606
49607         keybinding
49608             .on('⌫', shaded.close)
49609             .on('⎋', shaded.close);
49610
49611         d3_select(document)
49612             .call(keybinding);
49613     }
49614
49615     modal
49616         .append('div')
49617         .attr('class', 'content');
49618
49619     if (animate) {
49620         shaded.transition().style('opacity', 1);
49621     } else {
49622         shaded.style('opacity', 1);
49623     }
49624
49625
49626     return shaded;
49627 }
49628
49629 function uiLoading(context) {
49630     var message = '',
49631         blocking = false,
49632         modalSelection;
49633
49634
49635     var loading = function(selection) {
49636         modalSelection = uiModal(selection, blocking);
49637
49638         var loadertext = modalSelection.select('.content')
49639             .classed('loading-modal', true)
49640             .append('div')
49641             .attr('class', 'modal-section fillL');
49642
49643         loadertext
49644             .append('img')
49645             .attr('class', 'loader')
49646             .attr('src', context.imagePath('loader-white.gif'));
49647
49648         loadertext
49649             .append('h3')
49650             .text(message);
49651
49652         modalSelection.select('button.close')
49653             .attr('class', 'hide');
49654
49655         return loading;
49656     };
49657
49658
49659     loading.message = function(_) {
49660         if (!arguments.length) return message;
49661         message = _;
49662         return loading;
49663     };
49664
49665
49666     loading.blocking = function(_) {
49667         if (!arguments.length) return blocking;
49668         blocking = _;
49669         return loading;
49670     };
49671
49672
49673     loading.close = function() {
49674         modalSelection.remove();
49675     };
49676
49677
49678     return loading;
49679 }
49680
49681 function uiGeolocate(context) {
49682     var geoOptions = { enableHighAccuracy: false, timeout: 6000 /* 6sec */ },
49683         locating = uiLoading(context).message(t('geolocate.locating')).blocking(true),
49684         timeoutId;
49685
49686
49687     function click() {
49688         if (context.inIntro()) return;
49689         context.enter(modeBrowse(context));
49690         context.container().call(locating);
49691         navigator.geolocation.getCurrentPosition(success, error, geoOptions);
49692
49693         // This timeout ensures that we still call finish() even if
49694         // the user declines to share their location in Firefox
49695         timeoutId = setTimeout(finish, 10000 /* 10sec */ );
49696     }
49697
49698
49699     function success(position) {
49700         var map = context.map(),
49701             extent = geoExtent([position.coords.longitude, position.coords.latitude])
49702                 .padByMeters(position.coords.accuracy);
49703
49704         map.centerZoom(extent.center(), Math.min(20, map.extentZoom(extent)));
49705         finish();
49706     }
49707
49708
49709     function error() {
49710         finish();
49711     }
49712
49713
49714     function finish() {
49715         locating.close();  // unblock ui
49716         if (timeoutId) { clearTimeout(timeoutId); }
49717         timeoutId = undefined;
49718     }
49719
49720
49721     return function(selection) {
49722         if (!navigator.geolocation) return;
49723
49724         selection
49725             .append('button')
49726             .attr('tabindex', -1)
49727             .attr('title', t('geolocate.title'))
49728             .on('click', click)
49729             .call(svgIcon('#icon-geolocate', 'light'))
49730             .call(tooltip()
49731                 .placement((textDirection === 'rtl') ? 'right' : 'left'));
49732     };
49733 }
49734
49735 var marked = createCommonjsModule(function (module, exports) {
49736 /**
49737  * marked - a markdown parser
49738  * Copyright (c) 2011-2014, Christopher Jeffrey. (MIT Licensed)
49739  * https://github.com/chjj/marked
49740  */
49741
49742 (function() {
49743
49744 /**
49745  * Block-Level Grammar
49746  */
49747
49748 var block = {
49749   newline: /^\n+/,
49750   code: /^( {4}[^\n]+\n*)+/,
49751   fences: noop,
49752   hr: /^( *[-*_]){3,} *(?:\n+|$)/,
49753   heading: /^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,
49754   nptable: noop,
49755   lheading: /^([^\n]+)\n *(=|-){2,} *(?:\n+|$)/,
49756   blockquote: /^( *>[^\n]+(\n(?!def)[^\n]+)*\n*)+/,
49757   list: /^( *)(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,
49758   html: /^ *(?:comment *(?:\n|\s*$)|closed *(?:\n{2,}|\s*$)|closing *(?:\n{2,}|\s*$))/,
49759   def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,
49760   table: noop,
49761   paragraph: /^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/,
49762   text: /^[^\n]+/
49763 };
49764
49765 block.bullet = /(?:[*+-]|\d+\.)/;
49766 block.item = /^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;
49767 block.item = replace(block.item, 'gm')
49768   (/bull/g, block.bullet)
49769   ();
49770
49771 block.list = replace(block.list)
49772   (/bull/g, block.bullet)
49773   ('hr', '\\n+(?=\\1?(?:[-*_] *){3,}(?:\\n+|$))')
49774   ('def', '\\n+(?=' + block.def.source + ')')
49775   ();
49776
49777 block.blockquote = replace(block.blockquote)
49778   ('def', block.def)
49779   ();
49780
49781 block._tag = '(?!(?:'
49782   + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'
49783   + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'
49784   + '|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|[^\\w\\s@]*@)\\b';
49785
49786 block.html = replace(block.html)
49787   ('comment', /<!--[\s\S]*?-->/)
49788   ('closed', /<(tag)[\s\S]+?<\/\1>/)
49789   ('closing', /<tag(?:"[^"]*"|'[^']*'|[^'">])*?>/)
49790   (/tag/g, block._tag)
49791   ();
49792
49793 block.paragraph = replace(block.paragraph)
49794   ('hr', block.hr)
49795   ('heading', block.heading)
49796   ('lheading', block.lheading)
49797   ('blockquote', block.blockquote)
49798   ('tag', '<' + block._tag)
49799   ('def', block.def)
49800   ();
49801
49802 /**
49803  * Normal Block Grammar
49804  */
49805
49806 block.normal = merge({}, block);
49807
49808 /**
49809  * GFM Block Grammar
49810  */
49811
49812 block.gfm = merge({}, block.normal, {
49813   fences: /^ *(`{3,}|~{3,})[ \.]*(\S+)? *\n([\s\S]*?)\s*\1 *(?:\n+|$)/,
49814   paragraph: /^/,
49815   heading: /^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/
49816 });
49817
49818 block.gfm.paragraph = replace(block.paragraph)
49819   ('(?!', '(?!'
49820     + block.gfm.fences.source.replace('\\1', '\\2') + '|'
49821     + block.list.source.replace('\\1', '\\3') + '|')
49822   ();
49823
49824 /**
49825  * GFM + Tables Block Grammar
49826  */
49827
49828 block.tables = merge({}, block.gfm, {
49829   nptable: /^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,
49830   table: /^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/
49831 });
49832
49833 /**
49834  * Block Lexer
49835  */
49836
49837 function Lexer(options) {
49838   this.tokens = [];
49839   this.tokens.links = {};
49840   this.options = options || marked.defaults;
49841   this.rules = block.normal;
49842
49843   if (this.options.gfm) {
49844     if (this.options.tables) {
49845       this.rules = block.tables;
49846     } else {
49847       this.rules = block.gfm;
49848     }
49849   }
49850 }
49851
49852 /**
49853  * Expose Block Rules
49854  */
49855
49856 Lexer.rules = block;
49857
49858 /**
49859  * Static Lex Method
49860  */
49861
49862 Lexer.lex = function(src, options) {
49863   var lexer = new Lexer(options);
49864   return lexer.lex(src);
49865 };
49866
49867 /**
49868  * Preprocessing
49869  */
49870
49871 Lexer.prototype.lex = function(src) {
49872   src = src
49873     .replace(/\r\n|\r/g, '\n')
49874     .replace(/\t/g, '    ')
49875     .replace(/\u00a0/g, ' ')
49876     .replace(/\u2424/g, '\n');
49877
49878   return this.token(src, true);
49879 };
49880
49881 /**
49882  * Lexing
49883  */
49884
49885 Lexer.prototype.token = function(src, top, bq) {
49886   var src = src.replace(/^ +$/gm, '')
49887     , next
49888     , loose
49889     , cap
49890     , bull
49891     , b
49892     , item
49893     , space
49894     , i
49895     , l;
49896
49897   while (src) {
49898     // newline
49899     if (cap = this.rules.newline.exec(src)) {
49900       src = src.substring(cap[0].length);
49901       if (cap[0].length > 1) {
49902         this.tokens.push({
49903           type: 'space'
49904         });
49905       }
49906     }
49907
49908     // code
49909     if (cap = this.rules.code.exec(src)) {
49910       src = src.substring(cap[0].length);
49911       cap = cap[0].replace(/^ {4}/gm, '');
49912       this.tokens.push({
49913         type: 'code',
49914         text: !this.options.pedantic
49915           ? cap.replace(/\n+$/, '')
49916           : cap
49917       });
49918       continue;
49919     }
49920
49921     // fences (gfm)
49922     if (cap = this.rules.fences.exec(src)) {
49923       src = src.substring(cap[0].length);
49924       this.tokens.push({
49925         type: 'code',
49926         lang: cap[2],
49927         text: cap[3] || ''
49928       });
49929       continue;
49930     }
49931
49932     // heading
49933     if (cap = this.rules.heading.exec(src)) {
49934       src = src.substring(cap[0].length);
49935       this.tokens.push({
49936         type: 'heading',
49937         depth: cap[1].length,
49938         text: cap[2]
49939       });
49940       continue;
49941     }
49942
49943     // table no leading pipe (gfm)
49944     if (top && (cap = this.rules.nptable.exec(src))) {
49945       src = src.substring(cap[0].length);
49946
49947       item = {
49948         type: 'table',
49949         header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
49950         align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
49951         cells: cap[3].replace(/\n$/, '').split('\n')
49952       };
49953
49954       for (i = 0; i < item.align.length; i++) {
49955         if (/^ *-+: *$/.test(item.align[i])) {
49956           item.align[i] = 'right';
49957         } else if (/^ *:-+: *$/.test(item.align[i])) {
49958           item.align[i] = 'center';
49959         } else if (/^ *:-+ *$/.test(item.align[i])) {
49960           item.align[i] = 'left';
49961         } else {
49962           item.align[i] = null;
49963         }
49964       }
49965
49966       for (i = 0; i < item.cells.length; i++) {
49967         item.cells[i] = item.cells[i].split(/ *\| */);
49968       }
49969
49970       this.tokens.push(item);
49971
49972       continue;
49973     }
49974
49975     // lheading
49976     if (cap = this.rules.lheading.exec(src)) {
49977       src = src.substring(cap[0].length);
49978       this.tokens.push({
49979         type: 'heading',
49980         depth: cap[2] === '=' ? 1 : 2,
49981         text: cap[1]
49982       });
49983       continue;
49984     }
49985
49986     // hr
49987     if (cap = this.rules.hr.exec(src)) {
49988       src = src.substring(cap[0].length);
49989       this.tokens.push({
49990         type: 'hr'
49991       });
49992       continue;
49993     }
49994
49995     // blockquote
49996     if (cap = this.rules.blockquote.exec(src)) {
49997       src = src.substring(cap[0].length);
49998
49999       this.tokens.push({
50000         type: 'blockquote_start'
50001       });
50002
50003       cap = cap[0].replace(/^ *> ?/gm, '');
50004
50005       // Pass `top` to keep the current
50006       // "toplevel" state. This is exactly
50007       // how markdown.pl works.
50008       this.token(cap, top, true);
50009
50010       this.tokens.push({
50011         type: 'blockquote_end'
50012       });
50013
50014       continue;
50015     }
50016
50017     // list
50018     if (cap = this.rules.list.exec(src)) {
50019       src = src.substring(cap[0].length);
50020       bull = cap[2];
50021
50022       this.tokens.push({
50023         type: 'list_start',
50024         ordered: bull.length > 1
50025       });
50026
50027       // Get each top-level item.
50028       cap = cap[0].match(this.rules.item);
50029
50030       next = false;
50031       l = cap.length;
50032       i = 0;
50033
50034       for (; i < l; i++) {
50035         item = cap[i];
50036
50037         // Remove the list item's bullet
50038         // so it is seen as the next token.
50039         space = item.length;
50040         item = item.replace(/^ *([*+-]|\d+\.) +/, '');
50041
50042         // Outdent whatever the
50043         // list item contains. Hacky.
50044         if (~item.indexOf('\n ')) {
50045           space -= item.length;
50046           item = !this.options.pedantic
50047             ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')
50048             : item.replace(/^ {1,4}/gm, '');
50049         }
50050
50051         // Determine whether the next list item belongs here.
50052         // Backpedal if it does not belong in this list.
50053         if (this.options.smartLists && i !== l - 1) {
50054           b = block.bullet.exec(cap[i + 1])[0];
50055           if (bull !== b && !(bull.length > 1 && b.length > 1)) {
50056             src = cap.slice(i + 1).join('\n') + src;
50057             i = l - 1;
50058           }
50059         }
50060
50061         // Determine whether item is loose or not.
50062         // Use: /(^|\n)(?! )[^\n]+\n\n(?!\s*$)/
50063         // for discount behavior.
50064         loose = next || /\n\n(?!\s*$)/.test(item);
50065         if (i !== l - 1) {
50066           next = item.charAt(item.length - 1) === '\n';
50067           if (!loose) loose = next;
50068         }
50069
50070         this.tokens.push({
50071           type: loose
50072             ? 'loose_item_start'
50073             : 'list_item_start'
50074         });
50075
50076         // Recurse.
50077         this.token(item, false, bq);
50078
50079         this.tokens.push({
50080           type: 'list_item_end'
50081         });
50082       }
50083
50084       this.tokens.push({
50085         type: 'list_end'
50086       });
50087
50088       continue;
50089     }
50090
50091     // html
50092     if (cap = this.rules.html.exec(src)) {
50093       src = src.substring(cap[0].length);
50094       this.tokens.push({
50095         type: this.options.sanitize
50096           ? 'paragraph'
50097           : 'html',
50098         pre: !this.options.sanitizer
50099           && (cap[1] === 'pre' || cap[1] === 'script' || cap[1] === 'style'),
50100         text: cap[0]
50101       });
50102       continue;
50103     }
50104
50105     // def
50106     if ((!bq && top) && (cap = this.rules.def.exec(src))) {
50107       src = src.substring(cap[0].length);
50108       this.tokens.links[cap[1].toLowerCase()] = {
50109         href: cap[2],
50110         title: cap[3]
50111       };
50112       continue;
50113     }
50114
50115     // table (gfm)
50116     if (top && (cap = this.rules.table.exec(src))) {
50117       src = src.substring(cap[0].length);
50118
50119       item = {
50120         type: 'table',
50121         header: cap[1].replace(/^ *| *\| *$/g, '').split(/ *\| */),
50122         align: cap[2].replace(/^ *|\| *$/g, '').split(/ *\| */),
50123         cells: cap[3].replace(/(?: *\| *)?\n$/, '').split('\n')
50124       };
50125
50126       for (i = 0; i < item.align.length; i++) {
50127         if (/^ *-+: *$/.test(item.align[i])) {
50128           item.align[i] = 'right';
50129         } else if (/^ *:-+: *$/.test(item.align[i])) {
50130           item.align[i] = 'center';
50131         } else if (/^ *:-+ *$/.test(item.align[i])) {
50132           item.align[i] = 'left';
50133         } else {
50134           item.align[i] = null;
50135         }
50136       }
50137
50138       for (i = 0; i < item.cells.length; i++) {
50139         item.cells[i] = item.cells[i]
50140           .replace(/^ *\| *| *\| *$/g, '')
50141           .split(/ *\| */);
50142       }
50143
50144       this.tokens.push(item);
50145
50146       continue;
50147     }
50148
50149     // top-level paragraph
50150     if (top && (cap = this.rules.paragraph.exec(src))) {
50151       src = src.substring(cap[0].length);
50152       this.tokens.push({
50153         type: 'paragraph',
50154         text: cap[1].charAt(cap[1].length - 1) === '\n'
50155           ? cap[1].slice(0, -1)
50156           : cap[1]
50157       });
50158       continue;
50159     }
50160
50161     // text
50162     if (cap = this.rules.text.exec(src)) {
50163       // Top-level should never reach here.
50164       src = src.substring(cap[0].length);
50165       this.tokens.push({
50166         type: 'text',
50167         text: cap[0]
50168       });
50169       continue;
50170     }
50171
50172     if (src) {
50173       throw new
50174         Error('Infinite loop on byte: ' + src.charCodeAt(0));
50175     }
50176   }
50177
50178   return this.tokens;
50179 };
50180
50181 /**
50182  * Inline-Level Grammar
50183  */
50184
50185 var inline = {
50186   escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
50187   autolink: /^<([^ >]+(@|:\/)[^ >]+)>/,
50188   url: noop,
50189   tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
50190   link: /^!?\[(inside)\]\(href\)/,
50191   reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
50192   nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
50193   strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
50194   em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
50195   code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
50196   br: /^ {2,}\n(?!\s*$)/,
50197   del: noop,
50198   text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
50199 };
50200
50201 inline._inside = /(?:\[[^\]]*\]|[^\[\]]|\](?=[^\[]*\]))*/;
50202 inline._href = /\s*<?([\s\S]*?)>?(?:\s+['"]([\s\S]*?)['"])?\s*/;
50203
50204 inline.link = replace(inline.link)
50205   ('inside', inline._inside)
50206   ('href', inline._href)
50207   ();
50208
50209 inline.reflink = replace(inline.reflink)
50210   ('inside', inline._inside)
50211   ();
50212
50213 /**
50214  * Normal Inline Grammar
50215  */
50216
50217 inline.normal = merge({}, inline);
50218
50219 /**
50220  * Pedantic Inline Grammar
50221  */
50222
50223 inline.pedantic = merge({}, inline.normal, {
50224   strong: /^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,
50225   em: /^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/
50226 });
50227
50228 /**
50229  * GFM Inline Grammar
50230  */
50231
50232 inline.gfm = merge({}, inline.normal, {
50233   escape: replace(inline.escape)('])', '~|])')(),
50234   url: /^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,
50235   del: /^~~(?=\S)([\s\S]*?\S)~~/,
50236   text: replace(inline.text)
50237     (']|', '~]|')
50238     ('|', '|https?://|')
50239     ()
50240 });
50241
50242 /**
50243  * GFM + Line Breaks Inline Grammar
50244  */
50245
50246 inline.breaks = merge({}, inline.gfm, {
50247   br: replace(inline.br)('{2,}', '*')(),
50248   text: replace(inline.gfm.text)('{2,}', '*')()
50249 });
50250
50251 /**
50252  * Inline Lexer & Compiler
50253  */
50254
50255 function InlineLexer(links, options) {
50256   this.options = options || marked.defaults;
50257   this.links = links;
50258   this.rules = inline.normal;
50259   this.renderer = this.options.renderer || new Renderer;
50260   this.renderer.options = this.options;
50261
50262   if (!this.links) {
50263     throw new
50264       Error('Tokens array requires a `links` property.');
50265   }
50266
50267   if (this.options.gfm) {
50268     if (this.options.breaks) {
50269       this.rules = inline.breaks;
50270     } else {
50271       this.rules = inline.gfm;
50272     }
50273   } else if (this.options.pedantic) {
50274     this.rules = inline.pedantic;
50275   }
50276 }
50277
50278 /**
50279  * Expose Inline Rules
50280  */
50281
50282 InlineLexer.rules = inline;
50283
50284 /**
50285  * Static Lexing/Compiling Method
50286  */
50287
50288 InlineLexer.output = function(src, links, options) {
50289   var inline = new InlineLexer(links, options);
50290   return inline.output(src);
50291 };
50292
50293 /**
50294  * Lexing/Compiling
50295  */
50296
50297 InlineLexer.prototype.output = function(src) {
50298   var out = ''
50299     , link
50300     , text
50301     , href
50302     , cap;
50303
50304   while (src) {
50305     // escape
50306     if (cap = this.rules.escape.exec(src)) {
50307       src = src.substring(cap[0].length);
50308       out += cap[1];
50309       continue;
50310     }
50311
50312     // autolink
50313     if (cap = this.rules.autolink.exec(src)) {
50314       src = src.substring(cap[0].length);
50315       if (cap[2] === '@') {
50316         text = cap[1].charAt(6) === ':'
50317           ? this.mangle(cap[1].substring(7))
50318           : this.mangle(cap[1]);
50319         href = this.mangle('mailto:') + text;
50320       } else {
50321         text = escape(cap[1]);
50322         href = text;
50323       }
50324       out += this.renderer.link(href, null, text);
50325       continue;
50326     }
50327
50328     // url (gfm)
50329     if (!this.inLink && (cap = this.rules.url.exec(src))) {
50330       src = src.substring(cap[0].length);
50331       text = escape(cap[1]);
50332       href = text;
50333       out += this.renderer.link(href, null, text);
50334       continue;
50335     }
50336
50337     // tag
50338     if (cap = this.rules.tag.exec(src)) {
50339       if (!this.inLink && /^<a /i.test(cap[0])) {
50340         this.inLink = true;
50341       } else if (this.inLink && /^<\/a>/i.test(cap[0])) {
50342         this.inLink = false;
50343       }
50344       src = src.substring(cap[0].length);
50345       out += this.options.sanitize
50346         ? this.options.sanitizer
50347           ? this.options.sanitizer(cap[0])
50348           : escape(cap[0])
50349         : cap[0];
50350       continue;
50351     }
50352
50353     // link
50354     if (cap = this.rules.link.exec(src)) {
50355       src = src.substring(cap[0].length);
50356       this.inLink = true;
50357       out += this.outputLink(cap, {
50358         href: cap[2],
50359         title: cap[3]
50360       });
50361       this.inLink = false;
50362       continue;
50363     }
50364
50365     // reflink, nolink
50366     if ((cap = this.rules.reflink.exec(src))
50367         || (cap = this.rules.nolink.exec(src))) {
50368       src = src.substring(cap[0].length);
50369       link = (cap[2] || cap[1]).replace(/\s+/g, ' ');
50370       link = this.links[link.toLowerCase()];
50371       if (!link || !link.href) {
50372         out += cap[0].charAt(0);
50373         src = cap[0].substring(1) + src;
50374         continue;
50375       }
50376       this.inLink = true;
50377       out += this.outputLink(cap, link);
50378       this.inLink = false;
50379       continue;
50380     }
50381
50382     // strong
50383     if (cap = this.rules.strong.exec(src)) {
50384       src = src.substring(cap[0].length);
50385       out += this.renderer.strong(this.output(cap[2] || cap[1]));
50386       continue;
50387     }
50388
50389     // em
50390     if (cap = this.rules.em.exec(src)) {
50391       src = src.substring(cap[0].length);
50392       out += this.renderer.em(this.output(cap[2] || cap[1]));
50393       continue;
50394     }
50395
50396     // code
50397     if (cap = this.rules.code.exec(src)) {
50398       src = src.substring(cap[0].length);
50399       out += this.renderer.codespan(escape(cap[2], true));
50400       continue;
50401     }
50402
50403     // br
50404     if (cap = this.rules.br.exec(src)) {
50405       src = src.substring(cap[0].length);
50406       out += this.renderer.br();
50407       continue;
50408     }
50409
50410     // del (gfm)
50411     if (cap = this.rules.del.exec(src)) {
50412       src = src.substring(cap[0].length);
50413       out += this.renderer.del(this.output(cap[1]));
50414       continue;
50415     }
50416
50417     // text
50418     if (cap = this.rules.text.exec(src)) {
50419       src = src.substring(cap[0].length);
50420       out += this.renderer.text(escape(this.smartypants(cap[0])));
50421       continue;
50422     }
50423
50424     if (src) {
50425       throw new
50426         Error('Infinite loop on byte: ' + src.charCodeAt(0));
50427     }
50428   }
50429
50430   return out;
50431 };
50432
50433 /**
50434  * Compile Link
50435  */
50436
50437 InlineLexer.prototype.outputLink = function(cap, link) {
50438   var href = escape(link.href)
50439     , title = link.title ? escape(link.title) : null;
50440
50441   return cap[0].charAt(0) !== '!'
50442     ? this.renderer.link(href, title, this.output(cap[1]))
50443     : this.renderer.image(href, title, escape(cap[1]));
50444 };
50445
50446 /**
50447  * Smartypants Transformations
50448  */
50449
50450 InlineLexer.prototype.smartypants = function(text) {
50451   if (!this.options.smartypants) return text;
50452   return text
50453     // em-dashes
50454     .replace(/---/g, '\u2014')
50455     // en-dashes
50456     .replace(/--/g, '\u2013')
50457     // opening singles
50458     .replace(/(^|[-\u2014/(\[{"\s])'/g, '$1\u2018')
50459     // closing singles & apostrophes
50460     .replace(/'/g, '\u2019')
50461     // opening doubles
50462     .replace(/(^|[-\u2014/(\[{\u2018\s])"/g, '$1\u201c')
50463     // closing doubles
50464     .replace(/"/g, '\u201d')
50465     // ellipses
50466     .replace(/\.{3}/g, '\u2026');
50467 };
50468
50469 /**
50470  * Mangle Links
50471  */
50472
50473 InlineLexer.prototype.mangle = function(text) {
50474   if (!this.options.mangle) return text;
50475   var out = ''
50476     , l = text.length
50477     , i = 0
50478     , ch;
50479
50480   for (; i < l; i++) {
50481     ch = text.charCodeAt(i);
50482     if (Math.random() > 0.5) {
50483       ch = 'x' + ch.toString(16);
50484     }
50485     out += '&#' + ch + ';';
50486   }
50487
50488   return out;
50489 };
50490
50491 /**
50492  * Renderer
50493  */
50494
50495 function Renderer(options) {
50496   this.options = options || {};
50497 }
50498
50499 Renderer.prototype.code = function(code, lang, escaped) {
50500   if (this.options.highlight) {
50501     var out = this.options.highlight(code, lang);
50502     if (out != null && out !== code) {
50503       escaped = true;
50504       code = out;
50505     }
50506   }
50507
50508   if (!lang) {
50509     return '<pre><code>'
50510       + (escaped ? code : escape(code, true))
50511       + '\n</code></pre>';
50512   }
50513
50514   return '<pre><code class="'
50515     + this.options.langPrefix
50516     + escape(lang, true)
50517     + '">'
50518     + (escaped ? code : escape(code, true))
50519     + '\n</code></pre>\n';
50520 };
50521
50522 Renderer.prototype.blockquote = function(quote) {
50523   return '<blockquote>\n' + quote + '</blockquote>\n';
50524 };
50525
50526 Renderer.prototype.html = function(html) {
50527   return html;
50528 };
50529
50530 Renderer.prototype.heading = function(text, level, raw) {
50531   return '<h'
50532     + level
50533     + ' id="'
50534     + this.options.headerPrefix
50535     + raw.toLowerCase().replace(/[^\w]+/g, '-')
50536     + '">'
50537     + text
50538     + '</h'
50539     + level
50540     + '>\n';
50541 };
50542
50543 Renderer.prototype.hr = function() {
50544   return this.options.xhtml ? '<hr/>\n' : '<hr>\n';
50545 };
50546
50547 Renderer.prototype.list = function(body, ordered) {
50548   var type = ordered ? 'ol' : 'ul';
50549   return '<' + type + '>\n' + body + '</' + type + '>\n';
50550 };
50551
50552 Renderer.prototype.listitem = function(text) {
50553   return '<li>' + text + '</li>\n';
50554 };
50555
50556 Renderer.prototype.paragraph = function(text) {
50557   return '<p>' + text + '</p>\n';
50558 };
50559
50560 Renderer.prototype.table = function(header, body) {
50561   return '<table>\n'
50562     + '<thead>\n'
50563     + header
50564     + '</thead>\n'
50565     + '<tbody>\n'
50566     + body
50567     + '</tbody>\n'
50568     + '</table>\n';
50569 };
50570
50571 Renderer.prototype.tablerow = function(content) {
50572   return '<tr>\n' + content + '</tr>\n';
50573 };
50574
50575 Renderer.prototype.tablecell = function(content, flags) {
50576   var type = flags.header ? 'th' : 'td';
50577   var tag = flags.align
50578     ? '<' + type + ' style="text-align:' + flags.align + '">'
50579     : '<' + type + '>';
50580   return tag + content + '</' + type + '>\n';
50581 };
50582
50583 // span level renderer
50584 Renderer.prototype.strong = function(text) {
50585   return '<strong>' + text + '</strong>';
50586 };
50587
50588 Renderer.prototype.em = function(text) {
50589   return '<em>' + text + '</em>';
50590 };
50591
50592 Renderer.prototype.codespan = function(text) {
50593   return '<code>' + text + '</code>';
50594 };
50595
50596 Renderer.prototype.br = function() {
50597   return this.options.xhtml ? '<br/>' : '<br>';
50598 };
50599
50600 Renderer.prototype.del = function(text) {
50601   return '<del>' + text + '</del>';
50602 };
50603
50604 Renderer.prototype.link = function(href, title, text) {
50605   if (this.options.sanitize) {
50606     try {
50607       var prot = decodeURIComponent(unescape(href))
50608         .replace(/[^\w:]/g, '')
50609         .toLowerCase();
50610     } catch (e) {
50611       return '';
50612     }
50613     if (prot.indexOf('javascript:') === 0 || prot.indexOf('vbscript:') === 0) {
50614       return '';
50615     }
50616   }
50617   var out = '<a href="' + href + '"';
50618   if (title) {
50619     out += ' title="' + title + '"';
50620   }
50621   out += '>' + text + '</a>';
50622   return out;
50623 };
50624
50625 Renderer.prototype.image = function(href, title, text) {
50626   var out = '<img src="' + href + '" alt="' + text + '"';
50627   if (title) {
50628     out += ' title="' + title + '"';
50629   }
50630   out += this.options.xhtml ? '/>' : '>';
50631   return out;
50632 };
50633
50634 Renderer.prototype.text = function(text) {
50635   return text;
50636 };
50637
50638 /**
50639  * Parsing & Compiling
50640  */
50641
50642 function Parser(options) {
50643   this.tokens = [];
50644   this.token = null;
50645   this.options = options || marked.defaults;
50646   this.options.renderer = this.options.renderer || new Renderer;
50647   this.renderer = this.options.renderer;
50648   this.renderer.options = this.options;
50649 }
50650
50651 /**
50652  * Static Parse Method
50653  */
50654
50655 Parser.parse = function(src, options, renderer) {
50656   var parser = new Parser(options, renderer);
50657   return parser.parse(src);
50658 };
50659
50660 /**
50661  * Parse Loop
50662  */
50663
50664 Parser.prototype.parse = function(src) {
50665   this.inline = new InlineLexer(src.links, this.options, this.renderer);
50666   this.tokens = src.reverse();
50667
50668   var out = '';
50669   while (this.next()) {
50670     out += this.tok();
50671   }
50672
50673   return out;
50674 };
50675
50676 /**
50677  * Next Token
50678  */
50679
50680 Parser.prototype.next = function() {
50681   return this.token = this.tokens.pop();
50682 };
50683
50684 /**
50685  * Preview Next Token
50686  */
50687
50688 Parser.prototype.peek = function() {
50689   return this.tokens[this.tokens.length - 1] || 0;
50690 };
50691
50692 /**
50693  * Parse Text Tokens
50694  */
50695
50696 Parser.prototype.parseText = function() {
50697   var body = this.token.text;
50698
50699   while (this.peek().type === 'text') {
50700     body += '\n' + this.next().text;
50701   }
50702
50703   return this.inline.output(body);
50704 };
50705
50706 /**
50707  * Parse Current Token
50708  */
50709
50710 Parser.prototype.tok = function() {
50711   switch (this.token.type) {
50712     case 'space': {
50713       return '';
50714     }
50715     case 'hr': {
50716       return this.renderer.hr();
50717     }
50718     case 'heading': {
50719       return this.renderer.heading(
50720         this.inline.output(this.token.text),
50721         this.token.depth,
50722         this.token.text);
50723     }
50724     case 'code': {
50725       return this.renderer.code(this.token.text,
50726         this.token.lang,
50727         this.token.escaped);
50728     }
50729     case 'table': {
50730       var header = ''
50731         , body = ''
50732         , i
50733         , row
50734         , cell
50735         , flags
50736         , j;
50737
50738       // header
50739       cell = '';
50740       for (i = 0; i < this.token.header.length; i++) {
50741         flags = { header: true, align: this.token.align[i] };
50742         cell += this.renderer.tablecell(
50743           this.inline.output(this.token.header[i]),
50744           { header: true, align: this.token.align[i] }
50745         );
50746       }
50747       header += this.renderer.tablerow(cell);
50748
50749       for (i = 0; i < this.token.cells.length; i++) {
50750         row = this.token.cells[i];
50751
50752         cell = '';
50753         for (j = 0; j < row.length; j++) {
50754           cell += this.renderer.tablecell(
50755             this.inline.output(row[j]),
50756             { header: false, align: this.token.align[j] }
50757           );
50758         }
50759
50760         body += this.renderer.tablerow(cell);
50761       }
50762       return this.renderer.table(header, body);
50763     }
50764     case 'blockquote_start': {
50765       var body = '';
50766
50767       while (this.next().type !== 'blockquote_end') {
50768         body += this.tok();
50769       }
50770
50771       return this.renderer.blockquote(body);
50772     }
50773     case 'list_start': {
50774       var body = ''
50775         , ordered = this.token.ordered;
50776
50777       while (this.next().type !== 'list_end') {
50778         body += this.tok();
50779       }
50780
50781       return this.renderer.list(body, ordered);
50782     }
50783     case 'list_item_start': {
50784       var body = '';
50785
50786       while (this.next().type !== 'list_item_end') {
50787         body += this.token.type === 'text'
50788           ? this.parseText()
50789           : this.tok();
50790       }
50791
50792       return this.renderer.listitem(body);
50793     }
50794     case 'loose_item_start': {
50795       var body = '';
50796
50797       while (this.next().type !== 'list_item_end') {
50798         body += this.tok();
50799       }
50800
50801       return this.renderer.listitem(body);
50802     }
50803     case 'html': {
50804       var html = !this.token.pre && !this.options.pedantic
50805         ? this.inline.output(this.token.text)
50806         : this.token.text;
50807       return this.renderer.html(html);
50808     }
50809     case 'paragraph': {
50810       return this.renderer.paragraph(this.inline.output(this.token.text));
50811     }
50812     case 'text': {
50813       return this.renderer.paragraph(this.parseText());
50814     }
50815   }
50816 };
50817
50818 /**
50819  * Helpers
50820  */
50821
50822 function escape(html, encode) {
50823   return html
50824     .replace(!encode ? /&(?!#?\w+;)/g : /&/g, '&amp;')
50825     .replace(/</g, '&lt;')
50826     .replace(/>/g, '&gt;')
50827     .replace(/"/g, '&quot;')
50828     .replace(/'/g, '&#39;');
50829 }
50830
50831 function unescape(html) {
50832         // explicitly match decimal, hex, and named HTML entities 
50833   return html.replace(/&(#(?:\d+)|(?:#x[0-9A-Fa-f]+)|(?:\w+));?/g, function(_, n) {
50834     n = n.toLowerCase();
50835     if (n === 'colon') return ':';
50836     if (n.charAt(0) === '#') {
50837       return n.charAt(1) === 'x'
50838         ? String.fromCharCode(parseInt(n.substring(2), 16))
50839         : String.fromCharCode(+n.substring(1));
50840     }
50841     return '';
50842   });
50843 }
50844
50845 function replace(regex, opt) {
50846   regex = regex.source;
50847   opt = opt || '';
50848   return function self(name, val) {
50849     if (!name) return new RegExp(regex, opt);
50850     val = val.source || val;
50851     val = val.replace(/(^|[^\[])\^/g, '$1');
50852     regex = regex.replace(name, val);
50853     return self;
50854   };
50855 }
50856
50857 function noop() {}
50858 noop.exec = noop;
50859
50860 function merge(obj) {
50861   var i = 1
50862     , target
50863     , key;
50864
50865   for (; i < arguments.length; i++) {
50866     target = arguments[i];
50867     for (key in target) {
50868       if (Object.prototype.hasOwnProperty.call(target, key)) {
50869         obj[key] = target[key];
50870       }
50871     }
50872   }
50873
50874   return obj;
50875 }
50876
50877
50878 /**
50879  * Marked
50880  */
50881
50882 function marked(src, opt, callback) {
50883   if (callback || typeof opt === 'function') {
50884     if (!callback) {
50885       callback = opt;
50886       opt = null;
50887     }
50888
50889     opt = merge({}, marked.defaults, opt || {});
50890
50891     var highlight = opt.highlight
50892       , tokens
50893       , pending
50894       , i = 0;
50895
50896     try {
50897       tokens = Lexer.lex(src, opt);
50898     } catch (e) {
50899       return callback(e);
50900     }
50901
50902     pending = tokens.length;
50903
50904     var done = function(err) {
50905       if (err) {
50906         opt.highlight = highlight;
50907         return callback(err);
50908       }
50909
50910       var out;
50911
50912       try {
50913         out = Parser.parse(tokens, opt);
50914       } catch (e) {
50915         err = e;
50916       }
50917
50918       opt.highlight = highlight;
50919
50920       return err
50921         ? callback(err)
50922         : callback(null, out);
50923     };
50924
50925     if (!highlight || highlight.length < 3) {
50926       return done();
50927     }
50928
50929     delete opt.highlight;
50930
50931     if (!pending) return done();
50932
50933     for (; i < tokens.length; i++) {
50934       (function(token) {
50935         if (token.type !== 'code') {
50936           return --pending || done();
50937         }
50938         return highlight(token.text, token.lang, function(err, code) {
50939           if (err) return done(err);
50940           if (code == null || code === token.text) {
50941             return --pending || done();
50942           }
50943           token.text = code;
50944           token.escaped = true;
50945           --pending || done();
50946         });
50947       })(tokens[i]);
50948     }
50949
50950     return;
50951   }
50952   try {
50953     if (opt) opt = merge({}, marked.defaults, opt);
50954     return Parser.parse(Lexer.lex(src, opt), opt);
50955   } catch (e) {
50956     e.message += '\nPlease report this to https://github.com/chjj/marked.';
50957     if ((opt || marked.defaults).silent) {
50958       return '<p>An error occured:</p><pre>'
50959         + escape(e.message + '', true)
50960         + '</pre>';
50961     }
50962     throw e;
50963   }
50964 }
50965
50966 /**
50967  * Options
50968  */
50969
50970 marked.options =
50971 marked.setOptions = function(opt) {
50972   merge(marked.defaults, opt);
50973   return marked;
50974 };
50975
50976 marked.defaults = {
50977   gfm: true,
50978   tables: true,
50979   breaks: false,
50980   pedantic: false,
50981   sanitize: false,
50982   sanitizer: null,
50983   mangle: true,
50984   smartLists: false,
50985   silent: false,
50986   highlight: null,
50987   langPrefix: 'lang-',
50988   smartypants: false,
50989   headerPrefix: '',
50990   renderer: new Renderer,
50991   xhtml: false
50992 };
50993
50994 /**
50995  * Expose
50996  */
50997
50998 marked.Parser = Parser;
50999 marked.parser = Parser.parse;
51000
51001 marked.Renderer = Renderer;
51002
51003 marked.Lexer = Lexer;
51004 marked.lexer = Lexer.lex;
51005
51006 marked.InlineLexer = InlineLexer;
51007 marked.inlineLexer = InlineLexer.output;
51008
51009 marked.parse = marked;
51010
51011 {
51012   module.exports = marked;
51013 }
51014
51015 }).call(function() {
51016   return this || (typeof window !== 'undefined' ? window : commonjsGlobal);
51017 }());
51018 });
51019
51020 function pointBox(loc, context) {
51021     var rect = context.surfaceRect();
51022     var point = context.curtainProjection(loc);
51023     return {
51024         left: point[0] + rect.left - 40,
51025         top: point[1] + rect.top - 60,
51026         width: 80,
51027         height: 90
51028     };
51029 }
51030
51031
51032 function pad$1(locOrBox, padding, context) {
51033     var box;
51034     if (locOrBox instanceof Array) {
51035         var rect = context.surfaceRect();
51036         var point = context.curtainProjection(locOrBox);
51037         box = {
51038             left: point[0] + rect.left,
51039             top: point[1] + rect.top
51040         };
51041     } else {
51042         box = locOrBox;
51043     }
51044
51045     return {
51046         left: box.left - padding,
51047         top: box.top - padding,
51048         width: (box.width || 0) + 2 * padding,
51049         height: (box.width || 0) + 2 * padding
51050     };
51051 }
51052
51053
51054 function icon(name, svgklass) {
51055     return '<svg class="icon ' + (svgklass || '') + '">' +
51056          '<use xlink:href="' + name + '"></use></svg>';
51057 }
51058
51059
51060 function slugify(text) {
51061     return text.toString().toLowerCase()
51062         .replace(/\s+/g, '-')           // Replace spaces with -
51063         .replace(/[^\w\-]+/g, '')       // Remove all non-word chars
51064         .replace(/\-\-+/g, '-')         // Replace multiple - with single -
51065         .replace(/^-+/, '')             // Trim - from start of text
51066         .replace(/-+$/, '');            // Trim - from end of text
51067 }
51068
51069
51070 // console warning for missing walkthrough names
51071 var missingStrings = {};
51072 function checkKey(key, text) {
51073     if (t(key, { default: undefined}) === undefined) {
51074         if (missingStrings.hasOwnProperty(key)) return;  // warn once
51075         missingStrings[key] = text;
51076         var missing = key + ': ' + text;
51077         if (typeof console !== 'undefined') console.log(missing); // eslint-disable-line
51078     }
51079 }
51080
51081
51082 function localize(obj) {
51083     var key;
51084
51085     // Assign name if entity has one..
51086     var name = obj.tags && obj.tags.name;
51087     if (name) {
51088         key = 'intro.graph.name.' + slugify(name);
51089         obj.tags.name = t(key, { default: name });
51090         checkKey(key, name);
51091     }
51092
51093     // Assign street name if entity has one..
51094     var street = obj.tags && obj.tags['addr:street'];
51095     if (street) {
51096         key = 'intro.graph.name.' + slugify(street);
51097         obj.tags['addr:street'] = t(key, { default: street });
51098         checkKey(key, street);
51099
51100         // Add address details common across walkthrough..
51101         var addrTags = [
51102             'block_number', 'city', 'county', 'district', 'hamlet', 'neighbourhood',
51103             'postcode', 'province', 'quarter', 'state', 'subdistrict', 'suburb'
51104         ];
51105         addrTags.forEach(function(k) {
51106             var key = 'intro.graph.' + k,
51107                 tag = 'addr:' + k,
51108                 val = obj.tags && obj.tags[tag],
51109                 str = t(key, { default: val });
51110
51111             if (str) {
51112                 if (str.match(/^<.*>$/) !== null) {
51113                     delete obj.tags[tag];
51114                 } else {
51115                     obj.tags[tag] = str;
51116                 }
51117             }
51118         });
51119     }
51120
51121     return obj;
51122 }
51123
51124
51125 // Used to detect squareness.. some duplicataion of code from actionOrthogonalize.
51126 function isMostlySquare(points) {
51127     // note: uses 15 here instead of the 12 from actionOrthogonalize because
51128     // actionOrthogonalize can actually straighten some larger angles as it iterates
51129     var threshold = 15, // degrees within right or straight
51130         lowerBound = Math.cos((90 - threshold) * Math.PI / 180),  // near right
51131         upperBound = Math.cos(threshold * Math.PI / 180),         // near straight
51132         mag;
51133
51134     for (var i = 0; i < points.length; i++) {
51135         mag = Math.abs(normalizedDotProduct(i, points));
51136         if (mag > lowerBound && mag < upperBound) {
51137             return false;
51138         }
51139     }
51140
51141     return true;
51142
51143
51144     function normalizedDotProduct(i, points) {
51145         var a = points[(i - 1 + points.length) % points.length],
51146             b = points[i],
51147             c = points[(i + 1) % points.length],
51148             p = subtractPoints(a, b),
51149             q = subtractPoints(c, b);
51150
51151         p = normalizePoint(p);
51152         q = normalizePoint(q);
51153
51154         return p[0] * q[0] + p[1] * q[1];
51155
51156
51157         function subtractPoints(a, b) {
51158             return [a[0] - b[0], a[1] - b[1]];
51159         }
51160
51161         function normalizePoint(point) {
51162             var vector = [0, 0];
51163             var length = Math.sqrt(point[0] * point[0] + point[1] * point[1]);
51164             if (length !== 0) {
51165                 vector[0] = point[0] / length;
51166                 vector[1] = point[1] / length;
51167             }
51168             return vector;
51169         }
51170     }
51171 }
51172
51173
51174 function selectMenuItem(operation) {
51175     var selector = '.edit-menu .edit-menu-item-' + operation +
51176         ', .radial-menu .radial-menu-item-' + operation;
51177     return d3_select(selector);
51178 }
51179
51180
51181 function transitionTime(point1, point2) {
51182     var distance = geoSphericalDistance(point1, point2);
51183     if (distance === 0)
51184         return 0;
51185     else if (distance < 80)
51186         return 500;
51187     else
51188         return 1000;
51189 }
51190
51191 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"}}};
51192
51193 // toggles the visibility of ui elements, using a combination of the
51194 // hide class, which sets display=none, and a d3 transition for opacity.
51195 // this will cause blinking when called repeatedly, so check that the
51196 // value actually changes between calls.
51197 function uiToggle(show, callback) {
51198     return function(selection) {
51199         selection
51200             .style('opacity', show ? 0 : 1)
51201             .classed('hide', false)
51202             .transition()
51203             .style('opacity', show ? 1 : 0)
51204             .on('end', function() {
51205                 d3_select(this)
51206                     .classed('hide', !show)
51207                     .style('opacity', null);
51208                 if (callback) callback.apply(this);
51209             });
51210     };
51211 }
51212
51213 // Tooltips and svg mask used to highlight certain features
51214 function uiCurtain() {
51215
51216     var surface = d3_select(null),
51217         tooltip = d3_select(null),
51218         darkness = d3_select(null);
51219
51220     function curtain(selection) {
51221         surface = selection
51222             .append('svg')
51223             .attr('id', 'curtain')
51224             .style('z-index', 1000)
51225             .style('pointer-events', 'none')
51226             .style('position', 'absolute')
51227             .style('top', 0)
51228             .style('left', 0);
51229
51230         darkness = surface.append('path')
51231             .attr('x', 0)
51232             .attr('y', 0)
51233             .attr('class', 'curtain-darkness');
51234
51235         d3_select(window).on('resize.curtain', resize);
51236
51237         tooltip = selection.append('div')
51238             .attr('class', 'tooltip')
51239             .style('z-index', 1002);
51240
51241         tooltip
51242             .append('div')
51243             .attr('class', 'tooltip-arrow');
51244
51245         tooltip
51246             .append('div')
51247             .attr('class', 'tooltip-inner');
51248
51249         resize();
51250
51251
51252         function resize() {
51253             surface
51254                 .attr('width', window.innerWidth)
51255                 .attr('height', window.innerHeight);
51256             curtain.cut(darkness.datum());
51257         }
51258     }
51259
51260
51261     /**
51262      * Reveal cuts the curtain to highlight the given box,
51263      * and shows a tooltip with instructions next to the box.
51264      *
51265      * @param  {String|ClientRect} [box]   box used to cut the curtain
51266      * @param  {String}    [text]          text for a tooltip
51267      * @param  {Object}    [options]
51268      * @param  {string}    [options.tooltipClass]    optional class to add to the tooltip
51269      * @param  {integer}   [options.duration]        transition time in milliseconds
51270      * @param  {string}    [options.buttonText]      if set, create a button with this text label
51271      * @param  {function}  [options.buttonCallback]  if set, the callback for the button
51272      * @param  {String|ClientRect} [options.tooltipBox]  box for tooltip position, if different from box for the curtain
51273      */
51274     curtain.reveal = function(box, text, options) {
51275         if (typeof box === 'string') {
51276             box = d3_select(box).node();
51277         }
51278         if (box && box.getBoundingClientRect) {
51279             box = copyBox(box.getBoundingClientRect());
51280         }
51281
51282         options = options || {};
51283
51284         var tooltipBox;
51285         if (options.tooltipBox) {
51286             tooltipBox = options.tooltipBox;
51287             if (typeof tooltipBox === 'string') {
51288                 tooltipBox = d3_select(tooltipBox).node();
51289             }
51290             if (tooltipBox && tooltipBox.getBoundingClientRect) {
51291                 tooltipBox = copyBox(tooltipBox.getBoundingClientRect());
51292             }
51293         } else {
51294             tooltipBox = box;
51295         }
51296
51297         if (tooltipBox && text) {
51298             // pseudo markdown bold text for the instruction section..
51299             var parts = text.split('**');
51300             var html = parts[0] ? '<span>' + parts[0] + '</span>' : '';
51301             if (parts[1]) {
51302                 html += '<span class="instruction">' + parts[1] + '</span>';
51303             }
51304
51305             html = html.replace(/\*(.*?)\*/g, '<em>$1</em>');   // emphasis
51306             html = html.replace(/\{br\}/g, '<br/><br/>');       // linebreak
51307
51308             if (options.buttonText && options.buttonCallback) {
51309                 html += '<div class="button-section">' +
51310                     '<button href="#" class="button action col8">' + options.buttonText + '</button></div>';
51311             }
51312
51313             var classes = 'curtain-tooltip tooltip in ' + (options.tooltipClass || '');
51314             tooltip
51315                 .classed(classes, true)
51316                 .selectAll('.tooltip-inner')
51317                 .html(html);
51318
51319             if (options.buttonText && options.buttonCallback) {
51320                 var button = tooltip.selectAll('.button-section .button.action');
51321                 button
51322                     .on('click', function() {
51323                         event.preventDefault();
51324                         options.buttonCallback();
51325                     });
51326             }
51327
51328             var tip = copyBox(tooltip.node().getBoundingClientRect()),
51329                 w = window.innerWidth,
51330                 h = window.innerHeight,
51331                 tooltipWidth = 200,
51332                 tooltipArrow = 5,
51333                 side, pos;
51334
51335
51336             // hack: this will have bottom placement,
51337             // so need to reserve extra space for the tooltip illustration.
51338             if (options.tooltipClass === 'intro-mouse') {
51339                 tip.height += 80;
51340             }
51341
51342             // trim box dimensions to just the portion that fits in the window..
51343             if (tooltipBox.top + tooltipBox.height > h) {
51344                 tooltipBox.height -= (tooltipBox.top + tooltipBox.height - h);
51345             }
51346             if (tooltipBox.left + tooltipBox.width > w) {
51347                 tooltipBox.width -= (tooltipBox.left + tooltipBox.width - w);
51348             }
51349
51350             // determine tooltip placement..
51351
51352             if (tooltipBox.top + tooltipBox.height < 100) {
51353                 // tooltip below box..
51354                 side = 'bottom';
51355                 pos = [
51356                     tooltipBox.left + tooltipBox.width / 2 - tip.width / 2,
51357                     tooltipBox.top + tooltipBox.height
51358                 ];
51359
51360             } else if (tooltipBox.top > h - 140) {
51361                 // tooltip above box..
51362                 side = 'top';
51363                 pos = [
51364                     tooltipBox.left + tooltipBox.width / 2 - tip.width / 2,
51365                     tooltipBox.top - tip.height
51366                 ];
51367
51368             } else {
51369                 // tooltip to the side of the tooltipBox..
51370                 var tipY = tooltipBox.top + tooltipBox.height / 2 - tip.height / 2;
51371
51372                 if (textDirection === 'rtl') {
51373                     if (tooltipBox.left - tooltipWidth - tooltipArrow < 70) {
51374                         side = 'right';
51375                         pos = [tooltipBox.left + tooltipBox.width + tooltipArrow, tipY];
51376
51377                     } else {
51378                         side = 'left';
51379                         pos = [tooltipBox.left - tooltipWidth - tooltipArrow, tipY];
51380                     }
51381
51382                 } else {
51383                     if (tooltipBox.left + tooltipBox.width + tooltipArrow + tooltipWidth > w - 70) {
51384                         side = 'left';
51385                         pos = [tooltipBox.left - tooltipWidth - tooltipArrow, tipY];
51386                     }
51387                     else {
51388                         side = 'right';
51389                         pos = [tooltipBox.left + tooltipBox.width + tooltipArrow, tipY];
51390                     }
51391                 }
51392             }
51393
51394             if (options.duration !== 0 || !tooltip.classed(side)) {
51395                 tooltip.call(uiToggle(true));
51396             }
51397
51398             tooltip
51399                 .style('top', pos[1] + 'px')
51400                 .style('left', pos[0] + 'px')
51401                 .attr('class', classes + ' ' + side);
51402
51403
51404             // shift tooltip-inner if it is very close to the top or bottom edge
51405             // (doesn't affect the placement of the tooltip-arrow)
51406             var shiftY = 0;
51407             if (side === 'left' || side === 'right') {
51408                 if (pos[1] < 60) {
51409                     shiftY = 60 - pos[1];
51410                 }
51411                 else if (pos[1] + tip.height > h - 100) {
51412                     shiftY = h - pos[1] - tip.height - 100;
51413                 }
51414             }
51415             tooltip.selectAll('.tooltip-inner')
51416                 .style('top', shiftY + 'px');
51417
51418         } else {
51419             tooltip
51420                 .classed('in', false)
51421                 .call(uiToggle(false));
51422         }
51423
51424         curtain.cut(box, options.duration);
51425
51426         return tooltip;
51427     };
51428
51429
51430     curtain.cut = function(datum, duration) {
51431         darkness.datum(datum)
51432             .interrupt();
51433
51434         var selection;
51435         if (duration === 0) {
51436             selection = darkness;
51437         } else {
51438             selection = darkness
51439                 .transition()
51440                 .duration(duration || 600)
51441                 .ease(linear$1);
51442         }
51443
51444         selection
51445             .attr('d', function(d) {
51446                 var string = 'M 0,0 L 0,' + window.innerHeight + ' L ' +
51447                     window.innerWidth + ',' + window.innerHeight + 'L' +
51448                     window.innerWidth + ',0 Z';
51449
51450                 if (!d) return string;
51451                 return string + 'M' +
51452                     d.left + ',' + d.top + 'L' +
51453                     d.left + ',' + (d.top + d.height) + 'L' +
51454                     (d.left + d.width) + ',' + (d.top + d.height) + 'L' +
51455                     (d.left + d.width) + ',' + (d.top) + 'Z';
51456
51457             });
51458     };
51459
51460
51461     curtain.remove = function() {
51462         surface.remove();
51463         tooltip.remove();
51464         d3_select(window).on('resize.curtain', null);
51465     };
51466
51467
51468     // ClientRects are immutable, so copy them to an object,
51469     // in case we need to trim the height/width.
51470     function copyBox(src) {
51471         return {
51472             top: src.top,
51473             right: src.right,
51474             bottom: src.bottom,
51475             left: src.left,
51476             width: src.width,
51477             height: src.height
51478         };
51479     }
51480
51481
51482     return curtain;
51483 }
51484
51485 function uiIntroWelcome(context, reveal) {
51486     var dispatch$$1 = dispatch('done'),
51487         listener = clickListener();
51488
51489     var chapter = {
51490         title: 'intro.welcome.title'
51491     };
51492
51493
51494     function welcome() {
51495         context.map().centerZoom([-85.63591, 41.94285], 19);
51496         reveal('.intro-nav-wrap .chapter-welcome',
51497             t('intro.welcome.welcome'),
51498             { buttonText: t('intro.ok'), buttonCallback: practice }
51499         );
51500     }
51501
51502     function practice() {
51503         reveal('.intro-nav-wrap .chapter-welcome',
51504             t('intro.welcome.practice'),
51505             { buttonText: t('intro.ok'), buttonCallback: words }
51506         );
51507     }
51508
51509     function words() {
51510         reveal('.intro-nav-wrap .chapter-welcome',
51511             t('intro.welcome.words'),
51512             { buttonText: t('intro.ok'), buttonCallback: mouse }
51513         );
51514     }
51515
51516
51517     function mouse() {
51518         reveal('.intro-nav-wrap .chapter-welcome',
51519             t('intro.welcome.mouse'),
51520             { buttonText: t('intro.ok'), buttonCallback: leftClick }
51521         );
51522     }
51523
51524
51525     function leftClick() {
51526         var counter = 0,
51527             times = 5;
51528
51529         var tooltip = reveal('.intro-nav-wrap .chapter-welcome',
51530             t('intro.welcome.leftclick', { num: times }),
51531             { tooltipClass: 'intro-mouse' }
51532         );
51533
51534         tooltip.selectAll('.tooltip-inner')
51535             .insert('svg', 'span')
51536             .attr('class', 'tooltip-illustration')
51537             .append('use')
51538             .attr('xlink:href', '#walkthrough-mouse');
51539
51540         tooltip
51541             .append('div')
51542             .attr('class', 'counter');
51543
51544         tooltip.call(listener);
51545
51546         listener.on('click', function(which) {
51547             if (which === 'left') {
51548                 d3_select('.curtain-tooltip.intro-mouse .counter')
51549                     .text(String(++counter));
51550
51551                 if (counter === times) {
51552                     window.setTimeout(function() { continueTo(rightClick); }, 1000);
51553                 }
51554             }
51555         });
51556
51557         function continueTo(nextStep) {
51558             listener.on('click', null);
51559             tooltip.call(listener.off);
51560             tooltip.select('.counter').remove();
51561             nextStep();
51562         }
51563     }
51564
51565
51566     function rightClick() {
51567         var counter = 0,
51568             times = 5;
51569
51570         var tooltip = reveal('.intro-nav-wrap .chapter-welcome',
51571             t('intro.welcome.rightclick', { num: times }),
51572             { tooltipClass: 'intro-mouse' }
51573         );
51574
51575         tooltip.selectAll('.tooltip-inner')
51576             .insert('svg', 'span')
51577             .attr('class', 'tooltip-illustration')
51578             .append('use')
51579             .attr('xlink:href', '#walkthrough-mouse');
51580
51581         tooltip
51582             .append('div')
51583             .attr('class', 'counter');
51584
51585         tooltip.call(listener);
51586
51587         listener.on('click', function(which) {
51588             if (which === 'right') {
51589                 d3_select('.curtain-tooltip.intro-mouse .counter')
51590                     .text(String(++counter));
51591
51592                 if (counter === times) {
51593                     window.setTimeout(function() { continueTo(chapters); }, 1000);
51594                 }
51595             }
51596         });
51597
51598         function continueTo(nextStep) {
51599             listener.on('click', null);
51600             tooltip.call(listener.off);
51601             tooltip.select('.counter').remove();
51602             nextStep();
51603         }
51604     }
51605
51606
51607     function chapters() {
51608         dispatch$$1.call('done');
51609         reveal('.intro-nav-wrap .chapter-navigation',
51610             t('intro.welcome.chapters', { next: t('intro.navigation.title') })
51611         );
51612     }
51613
51614
51615     chapter.enter = function() {
51616         welcome();
51617     };
51618
51619
51620     chapter.exit = function() {
51621         listener.off();
51622     };
51623
51624
51625     chapter.restart = function() {
51626         chapter.exit();
51627         chapter.enter();
51628     };
51629
51630
51631     return utilRebind(chapter, dispatch$$1, 'on');
51632 }
51633
51634
51635
51636 function clickListener() {
51637     var dispatch$$1 = dispatch('click'),
51638         minTime = 120,
51639         tooltip = d3_select(null),
51640         down = {};
51641
51642     // `down` keeps track of which buttons/keys are down.
51643     // Setting a property in `down` happens immediately.
51644     // Unsetting a property in `down` is delayed because
51645     //   on Windows a contextmenu event happens after keyup/mouseup
51646
51647     function keydown() {
51648         if (event.keyCode === 93)  {   // context menu
51649             event.preventDefault();
51650             event.stopPropagation();
51651             down.menu = event.timeStamp;
51652             tooltip.classed('rightclick', true);
51653         }
51654     }
51655
51656
51657     function keyup() {
51658         if (event.keyCode === 93)  {   // context menu
51659             event.preventDefault();
51660             event.stopPropagation();
51661             var endTime = event.timeStamp,
51662                 startTime = down.menu || endTime,
51663                 delay = (endTime - startTime < minTime) ? minTime : 0;
51664
51665             window.setTimeout(function() {
51666                 tooltip.classed('rightclick', false);
51667                 down.menu = undefined;  // delayed, for Windows
51668             }, delay);
51669
51670             dispatch$$1.call('click', this, 'right');
51671         }
51672     }
51673
51674
51675     function mousedown() {
51676         var button = event.button;
51677         if (button === 0 && !event.ctrlKey) {
51678             tooltip.classed('leftclick', true);
51679         } else if (button === 2) {
51680             tooltip.classed('rightclick', true);
51681         }
51682         down[button] = event.timeStamp;
51683     }
51684
51685
51686     function mouseup() {
51687         var button = event.button,
51688             endTime = event.timeStamp,
51689             startTime = down[button] || endTime,
51690             delay = (endTime - startTime < minTime) ? minTime : 0;
51691
51692         if (button === 0 && !event.ctrlKey) {
51693             window.setTimeout(function() {
51694                 tooltip.classed('leftclick', false);
51695                 down[button] = undefined;  // delayed, for Windows
51696             }, delay);
51697
51698             dispatch$$1.call('click', this, 'left');
51699
51700         } else if (button === 2) {
51701             window.setTimeout(function() {
51702                 tooltip.classed('rightclick', false);
51703                 down[button] = undefined;  // delayed, for Windows
51704             }, delay);
51705
51706             dispatch$$1.call('click', this, 'right');
51707
51708         } else {
51709             window.setTimeout(function() {
51710                 down[button] = undefined;  // delayed, for Windows
51711             }, delay);
51712         }
51713     }
51714
51715
51716     function contextmenu() {
51717         event.preventDefault();
51718         event.stopPropagation();
51719         if (!down[2] && !down.menu) {
51720             tooltip.classed('rightclick', true);
51721             window.setTimeout(function() {
51722                 tooltip.classed('rightclick', false);
51723             }, minTime);
51724             dispatch$$1.call('click', this, 'right');
51725         }
51726     }
51727
51728
51729     var behavior = function(selection) {
51730         tooltip = selection;
51731         down = {};
51732
51733         d3_select(window)
51734             .on('keydown.intro', keydown)
51735             .on('keyup.intro', keyup)
51736             .on('mousedown.intro', mousedown)
51737             .on('mouseup.intro', mouseup)
51738             .on('contextmenu.intro', contextmenu);
51739     };
51740
51741
51742     behavior.off = function() {
51743         d3_select(window)
51744             .on('keydown.intro', null)
51745             .on('keyup.intro', null)
51746             .on('mousedown.intro', null)
51747             .on('mouseup.intro', null)
51748             .on('contextmenu.intro', null);
51749
51750         tooltip
51751             .classed('leftclick', false)
51752             .classed('rightclick', false);
51753     };
51754
51755     return utilRebind(behavior, dispatch$$1, 'on');
51756 }
51757
51758 function uiIntroNavigation(context, reveal) {
51759     var dispatch$$1 = dispatch('done'),
51760         timeouts = [],
51761         hallId = 'n2061',
51762         townHall = [-85.63591, 41.94285],
51763         springStreetId = 'w397',
51764         springStreetEndId = 'n1834',
51765         springStreet = [-85.63582, 41.94255],
51766         onewayField = context.presets().field('oneway'),
51767         maxspeedField = context.presets().field('maxspeed');
51768
51769
51770     var chapter = {
51771         title: 'intro.navigation.title'
51772     };
51773
51774
51775     function timeout(f, t$$1) {
51776         timeouts.push(window.setTimeout(f, t$$1));
51777     }
51778
51779
51780     function eventCancel() {
51781         event.stopPropagation();
51782         event.preventDefault();
51783     }
51784
51785
51786     function isTownHallSelected() {
51787         var ids = context.selectedIDs();
51788         return ids.length === 1 && ids[0] === hallId;
51789     }
51790
51791
51792     function dragMap() {
51793         context.enter(modeBrowse(context));
51794         context.history().reset('initial');
51795
51796         var msec = transitionTime(townHall, context.map().center());
51797         if (msec) { reveal(null, null, { duration: 0 }); }
51798         context.map().zoom(19).centerEase(townHall, msec);
51799
51800         timeout(function() {
51801             var centerStart = context.map().center();
51802
51803             reveal('#surface', t('intro.navigation.drag'));
51804             context.map().on('drawn.intro', function() {
51805                 reveal('#surface', t('intro.navigation.drag'), { duration: 0 });
51806             });
51807
51808             context.map().on('move.intro', function() {
51809                 var centerNow = context.map().center();
51810                 if (centerStart[0] !== centerNow[0] || centerStart[1] !== centerNow[1]) {
51811                     context.map().on('move.intro', null);
51812                     timeout(function() { continueTo(zoomMap); }, 3000);
51813                 }
51814             });
51815
51816         }, msec + 100);
51817
51818         function continueTo(nextStep) {
51819             context.map().on('move.intro drawn.intro', null);
51820             nextStep();
51821         }
51822     }
51823
51824
51825     function zoomMap() {
51826         var zoomStart = context.map().zoom();
51827
51828         reveal('#surface',
51829             t('intro.navigation.zoom', {
51830                 plus: icon('#icon-plus', 'pre-text'),
51831                 minus: icon('#icon-minus', 'pre-text')
51832             })
51833         );
51834
51835         context.map().on('drawn.intro', function() {
51836             reveal('#surface',
51837                 t('intro.navigation.zoom', {
51838                     plus: icon('#icon-plus', 'pre-text'),
51839                     minus: icon('#icon-minus', 'pre-text')
51840                 }), { duration: 0 }
51841             );
51842         });
51843
51844         context.map().on('move.intro', function() {
51845             if (context.map().zoom() !== zoomStart) {
51846                 context.map().on('move.intro', null);
51847                 timeout(function() { continueTo(features); }, 3000);
51848             }
51849         });
51850
51851         function continueTo(nextStep) {
51852             context.map().on('move.intro drawn.intro', null);
51853             nextStep();
51854         }
51855     }
51856
51857
51858     function features() {
51859         var onClick = function() { continueTo(pointsLinesAreas); };
51860
51861         reveal('#surface', t('intro.navigation.features'),
51862             { buttonText: t('intro.ok'), buttonCallback: onClick }
51863         );
51864
51865         context.map().on('drawn.intro', function() {
51866             reveal('#surface', t('intro.navigation.features'),
51867                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
51868             );
51869         });
51870
51871         function continueTo(nextStep) {
51872             context.map().on('drawn.intro', null);
51873             nextStep();
51874         }
51875     }
51876
51877     function pointsLinesAreas() {
51878         var onClick = function() { continueTo(nodesWays); };
51879
51880         reveal('#surface', t('intro.navigation.points_lines_areas'),
51881             { buttonText: t('intro.ok'), buttonCallback: onClick }
51882         );
51883
51884         context.map().on('drawn.intro', function() {
51885             reveal('#surface', t('intro.navigation.points_lines_areas'),
51886                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
51887             );
51888         });
51889
51890         function continueTo(nextStep) {
51891             context.map().on('drawn.intro', null);
51892             nextStep();
51893         }
51894     }
51895
51896     function nodesWays() {
51897         var onClick = function() { continueTo(clickTownHall); };
51898
51899         reveal('#surface', t('intro.navigation.nodes_ways'),
51900             { buttonText: t('intro.ok'), buttonCallback: onClick }
51901         );
51902
51903         context.map().on('drawn.intro', function() {
51904             reveal('#surface', t('intro.navigation.nodes_ways'),
51905                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
51906             );
51907         });
51908
51909         function continueTo(nextStep) {
51910             context.map().on('drawn.intro', null);
51911             nextStep();
51912         }
51913     }
51914
51915     function clickTownHall() {
51916         context.enter(modeBrowse(context));
51917         context.history().reset('initial');
51918
51919         reveal(null, null, { duration: 0 });
51920         context.map().zoomEase(19, 500);
51921
51922         timeout(function() {
51923             var entity = context.hasEntity(hallId);
51924             if (!entity) return;
51925             context.map().centerEase(entity.loc, 500);
51926
51927             timeout(function() {
51928                 var entity = context.hasEntity(hallId);
51929                 if (!entity) return;
51930                 var box = pointBox(entity.loc, context);
51931                 reveal(box, t('intro.navigation.click_townhall'));
51932
51933                 context.map().on('move.intro drawn.intro', function() {
51934                     var entity = context.hasEntity(hallId);
51935                     if (!entity) return;
51936                     var box = pointBox(entity.loc, context);
51937                     reveal(box, t('intro.navigation.click_townhall'), { duration: 0 });
51938                 });
51939
51940                 context.on('enter.intro', function() {
51941                     if (isTownHallSelected()) continueTo(selectedTownHall);
51942                 });
51943
51944             }, 550);  // after centerEase
51945
51946         }, 550); // after zoomEase
51947
51948         context.history().on('change.intro', function() {
51949             if (!context.hasEntity(hallId)) {
51950                 continueTo(clickTownHall);
51951             }
51952         });
51953
51954         function continueTo(nextStep) {
51955             context.on('enter.intro', null);
51956             context.map().on('move.intro drawn.intro', null);
51957             context.history().on('change.intro', null);
51958             nextStep();
51959         }
51960     }
51961
51962
51963     function selectedTownHall() {
51964         if (!isTownHallSelected()) return clickTownHall();
51965
51966         var entity = context.hasEntity(hallId);
51967         if (!entity) return clickTownHall();
51968
51969         var box = pointBox(entity.loc, context);
51970         var onClick = function() { continueTo(editorTownHall); };
51971
51972         reveal(box, t('intro.navigation.selected_townhall'),
51973             { buttonText: t('intro.ok'), buttonCallback: onClick }
51974         );
51975
51976         context.map().on('move.intro drawn.intro', function() {
51977             var entity = context.hasEntity(hallId);
51978             if (!entity) return;
51979             var box = pointBox(entity.loc, context);
51980             reveal(box, t('intro.navigation.selected_townhall'),
51981                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
51982             );
51983         });
51984
51985         context.history().on('change.intro', function() {
51986             if (!context.hasEntity(hallId)) {
51987                 continueTo(clickTownHall);
51988             }
51989         });
51990
51991         function continueTo(nextStep) {
51992             context.map().on('move.intro drawn.intro', null);
51993             context.history().on('change.intro', null);
51994             nextStep();
51995         }
51996     }
51997
51998
51999     function editorTownHall() {
52000         if (!isTownHallSelected()) return clickTownHall();
52001
52002         // disallow scrolling
52003         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
52004
52005         var onClick = function() { continueTo(presetTownHall); };
52006
52007         reveal('.entity-editor-pane',
52008             t('intro.navigation.editor_townhall'),
52009             { buttonText: t('intro.ok'), buttonCallback: onClick }
52010         );
52011
52012         context.on('exit.intro', function() {
52013             continueTo(clickTownHall);
52014         });
52015
52016         context.history().on('change.intro', function() {
52017             if (!context.hasEntity(hallId)) {
52018                 continueTo(clickTownHall);
52019             }
52020         });
52021
52022         function continueTo(nextStep) {
52023             context.on('exit.intro', null);
52024             context.history().on('change.intro', null);
52025             d3_select('.inspector-wrap').on('wheel.intro', null);
52026             nextStep();
52027         }
52028     }
52029
52030
52031     function presetTownHall() {
52032         if (!isTownHallSelected()) return clickTownHall();
52033
52034         // reset pane, in case user happened to change it..
52035         d3_select('.inspector-wrap .panewrap').style('right', '0%');
52036         // disallow scrolling
52037         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
52038
52039         // preset match, in case the user happened to change it.
52040         var entity = context.entity(context.selectedIDs()[0]);
52041         var preset = context.presets().match(entity, context.graph());
52042
52043         var onClick = function() { continueTo(fieldsTownHall); };
52044
52045         context.on('exit.intro', function() {
52046             continueTo(clickTownHall);
52047         });
52048
52049         context.history().on('change.intro', function() {
52050             if (!context.hasEntity(hallId)) {
52051                 continueTo(clickTownHall);
52052             }
52053         });
52054
52055         reveal('.inspector-body .preset-list-item.inspector-inner',
52056             t('intro.navigation.preset_townhall', { preset: preset.name() }),
52057             { buttonText: t('intro.ok'), buttonCallback: onClick }
52058         );
52059
52060         function continueTo(nextStep) {
52061             context.on('exit.intro', null);
52062             context.history().on('change.intro', null);
52063             d3_select('.inspector-wrap').on('wheel.intro', null);
52064             nextStep();
52065         }
52066     }
52067
52068
52069     function fieldsTownHall() {
52070         if (!isTownHallSelected()) return clickTownHall();
52071
52072         // reset pane, in case user happened to change it..
52073         d3_select('.inspector-wrap .panewrap').style('right', '0%');
52074         // disallow scrolling
52075         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
52076
52077         var onClick = function() { continueTo(closeTownHall); };
52078
52079         reveal('.inspector-body .preset-editor',
52080             t('intro.navigation.fields_townhall'),
52081             { buttonText: t('intro.ok'), buttonCallback: onClick }
52082         );
52083
52084         context.on('exit.intro', function() {
52085             continueTo(clickTownHall);
52086         });
52087
52088         context.history().on('change.intro', function() {
52089             if (!context.hasEntity(hallId)) {
52090                 continueTo(clickTownHall);
52091             }
52092         });
52093
52094         function continueTo(nextStep) {
52095             context.on('exit.intro', null);
52096             context.history().on('change.intro', null);
52097             d3_select('.inspector-wrap').on('wheel.intro', null);
52098             nextStep();
52099         }
52100     }
52101
52102
52103     function closeTownHall() {
52104         if (!isTownHallSelected()) return clickTownHall();
52105
52106         var selector = '.entity-editor-pane button.preset-close svg use';
52107         var href = d3_select(selector).attr('href') || '#icon-close';
52108
52109         reveal('.entity-editor-pane',
52110             t('intro.navigation.close_townhall', { button: icon(href, 'pre-text') })
52111         );
52112
52113         context.on('exit.intro', function() {
52114             continueTo(searchStreet);
52115         });
52116
52117         context.history().on('change.intro', function() {
52118             // update the close icon in the tooltip if the user edits something.
52119             var selector = '.entity-editor-pane button.preset-close svg use';
52120             var href = d3_select(selector).attr('href') || '#icon-close';
52121
52122             reveal('.entity-editor-pane',
52123                 t('intro.navigation.close_townhall', { button: icon(href, 'pre-text') }),
52124                 { duration: 0 }
52125             );
52126         });
52127
52128         function continueTo(nextStep) {
52129             context.on('exit.intro', null);
52130             context.history().on('change.intro', null);
52131             nextStep();
52132         }
52133     }
52134
52135
52136     function searchStreet() {
52137         context.enter(modeBrowse(context));
52138         context.history().reset('initial');  // ensure spring street exists
52139
52140         var msec = transitionTime(springStreet, context.map().center());
52141         if (msec) { reveal(null, null, { duration: 0 }); }
52142         context.map().zoom(19).centerEase(springStreet, msec);  // ..and user can see it
52143
52144         timeout(function() {
52145             reveal('.search-header input',
52146                 t('intro.navigation.search_street', { name: t('intro.graph.name.spring-street') })
52147             );
52148
52149             d3_select('.search-header input')
52150                 .on('keyup.intro', checkSearchResult);
52151         }, msec + 100);
52152     }
52153
52154
52155     function checkSearchResult() {
52156         var first = d3_select('.feature-list-item:nth-child(0n+2)'),  // skip "No Results" item
52157             firstName = first.select('.entity-name'),
52158             name = t('intro.graph.name.spring-street');
52159
52160         if (!firstName.empty() && firstName.text() === name) {
52161             reveal(first.node(),
52162                 t('intro.navigation.choose_street', { name: name }),
52163                 { duration: 300 }
52164             );
52165
52166             context.on('exit.intro', function() {
52167                 continueTo(selectedStreet);
52168             });
52169
52170             d3_select('.search-header input')
52171                 .on('keydown.intro', eventCancel, true)
52172                 .on('keyup.intro', null);
52173         }
52174
52175         function continueTo(nextStep) {
52176             context.on('exit.intro', null);
52177             d3_select('.search-header input')
52178                 .on('keydown.intro', null)
52179                 .on('keyup.intro', null);
52180             nextStep();
52181         }
52182     }
52183
52184
52185     function selectedStreet() {
52186         if (!context.hasEntity(springStreetEndId) || !context.hasEntity(springStreetId)) {
52187             return searchStreet();
52188         }
52189
52190         var onClick = function() { continueTo(editorStreet); };
52191         var entity = context.entity(springStreetEndId);
52192         var box = pointBox(entity.loc, context);
52193         box.height = 500;
52194
52195         reveal(box,
52196             t('intro.navigation.selected_street', { name: t('intro.graph.name.spring-street') }),
52197             { duration: 600, buttonText: t('intro.ok'), buttonCallback: onClick }
52198         );
52199
52200         timeout(function() {
52201             context.map().on('move.intro drawn.intro', function() {
52202                 var entity = context.hasEntity(springStreetEndId);
52203                 if (!entity) return;
52204                 var box = pointBox(entity.loc, context);
52205                 box.height = 500;
52206                 reveal(box,
52207                     t('intro.navigation.selected_street', { name: t('intro.graph.name.spring-street') }),
52208                     { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
52209                 );
52210             });
52211         }, 600);  // after reveal.
52212
52213         context.on('enter.intro', function(mode) {
52214             if (!context.hasEntity(springStreetId)) {
52215                 return continueTo(searchStreet);
52216             }
52217             var ids = context.selectedIDs();
52218             if (mode.id !== 'select' || !ids.length || ids[0] !== springStreetId) {
52219                 // keep Spring Street selected..
52220                 context.enter(modeSelect(context, [springStreetId]));
52221             }
52222         });
52223
52224         context.history().on('change.intro', function() {
52225             if (!context.hasEntity(springStreetEndId) || !context.hasEntity(springStreetId)) {
52226                 timeout(function() {
52227                     continueTo(searchStreet);
52228                 }, 300);  // after any transition (e.g. if user deleted intersection)
52229             }
52230         });
52231
52232         function continueTo(nextStep) {
52233             context.map().on('move.intro drawn.intro', null);
52234             context.on('enter.intro', null);
52235             context.history().on('change.intro', null);
52236             nextStep();
52237         }
52238     }
52239
52240
52241     function editorStreet() {
52242         var selector = '.entity-editor-pane button.preset-close svg use';
52243         var href = d3_select(selector).attr('href') || '#icon-close';
52244
52245         reveal('.entity-editor-pane',
52246             t('intro.navigation.editor_street', {
52247                 button: icon(href, 'pre-text'),
52248                 field1: onewayField.label(),
52249                 field2: maxspeedField.label()
52250             })
52251         );
52252
52253         context.on('exit.intro', function() {
52254             continueTo(play);
52255         });
52256
52257         context.history().on('change.intro', function() {
52258             // update the close icon in the tooltip if the user edits something.
52259             var selector = '.entity-editor-pane button.preset-close svg use';
52260             var href = d3_select(selector).attr('href') || '#icon-close';
52261
52262             reveal('.entity-editor-pane',
52263                 t('intro.navigation.editor_street', {
52264                     button: icon(href, 'pre-text'),
52265                     field1: onewayField.label().toLowerCase(),
52266                     field2: maxspeedField.label().toLowerCase()
52267                 }), { duration: 0 }
52268             );
52269         });
52270
52271         function continueTo(nextStep) {
52272             context.on('exit.intro', null);
52273             context.history().on('change.intro', null);
52274             nextStep();
52275         }
52276     }
52277
52278
52279     function play() {
52280         dispatch$$1.call('done');
52281         reveal('#id-container',
52282             t('intro.navigation.play', { next: t('intro.points.title') }), {
52283                 tooltipBox: '.intro-nav-wrap .chapter-point',
52284                 buttonText: t('intro.ok'),
52285                 buttonCallback: function() { reveal('#id-container'); }
52286             }
52287         );
52288     }
52289
52290
52291     chapter.enter = function() {
52292         dragMap();
52293     };
52294
52295
52296     chapter.exit = function() {
52297         timeouts.forEach(window.clearTimeout);
52298         context.on('enter.intro exit.intro', null);
52299         context.map().on('move.intro drawn.intro', null);
52300         context.history().on('change.intro', null);
52301         d3_select('.inspector-wrap').on('wheel.intro', null);
52302         d3_select('.search-header input').on('keydown.intro keyup.intro', null);
52303     };
52304
52305
52306     chapter.restart = function() {
52307         chapter.exit();
52308         chapter.enter();
52309     };
52310
52311
52312     return utilRebind(chapter, dispatch$$1, 'on');
52313 }
52314
52315 function uiIntroPoint(context, reveal) {
52316     var dispatch$$1 = dispatch('done'),
52317         timeouts = [],
52318         intersection = [-85.63279, 41.94394],
52319         building = [-85.632422, 41.944045],
52320         cafePreset = context.presets().item('amenity/cafe'),
52321         pointId = null;
52322
52323
52324     var chapter = {
52325         title: 'intro.points.title'
52326     };
52327
52328
52329     function timeout(f, t$$1) {
52330         timeouts.push(window.setTimeout(f, t$$1));
52331     }
52332
52333
52334     function revealEditMenu(loc, text, options) {
52335         var rect = context.surfaceRect();
52336         var point = context.curtainProjection(loc);
52337         var pad = 40;
52338         var width = 250 + (2 * pad);
52339         var height = 250;
52340         var startX = rect.left + point[0];
52341         var left = (textDirection === 'rtl') ? (startX - width + pad) : (startX - pad);
52342         var box = {
52343             left: left,
52344             top: point[1] + rect.top - 60,
52345             width: width,
52346             height: height
52347         };
52348         reveal(box, text, options);
52349     }
52350
52351
52352     function eventCancel() {
52353         event.stopPropagation();
52354         event.preventDefault();
52355     }
52356
52357
52358     function addPoint() {
52359         context.enter(modeBrowse(context));
52360         context.history().reset('initial');
52361
52362         var msec = transitionTime(intersection, context.map().center());
52363         if (msec) { reveal(null, null, { duration: 0 }); }
52364         context.map().zoom(19).centerEase(intersection, msec);
52365
52366         timeout(function() {
52367             var tooltip = reveal('button.add-point',
52368                 t('intro.points.add_point', { button: icon('#icon-point', 'pre-text') }));
52369
52370             pointId = null;
52371
52372             tooltip.selectAll('.tooltip-inner')
52373                 .insert('svg', 'span')
52374                 .attr('class', 'tooltip-illustration')
52375                 .append('use')
52376                 .attr('xlink:href', '#poi-images');
52377
52378             context.on('enter.intro', function(mode) {
52379                 if (mode.id !== 'add-point') return;
52380                 continueTo(placePoint);
52381             });
52382         }, msec + 100);
52383
52384         function continueTo(nextStep) {
52385             context.on('enter.intro', null);
52386             nextStep();
52387         }
52388     }
52389
52390
52391     function placePoint() {
52392         if (context.mode().id !== 'add-point') {
52393             return chapter.restart();
52394         }
52395
52396         var pointBox$$1 = pad$1(building, 150, context);
52397         reveal(pointBox$$1, t('intro.points.place_point'));
52398
52399         context.map().on('move.intro drawn.intro', function() {
52400             pointBox$$1 = pad$1(building, 150, context);
52401             reveal(pointBox$$1, t('intro.points.place_point'), { duration: 0 });
52402         });
52403
52404         context.on('enter.intro', function(mode) {
52405             if (mode.id !== 'select') return chapter.restart();
52406             pointId = context.mode().selectedIDs()[0];
52407             continueTo(searchPreset);
52408         });
52409
52410         function continueTo(nextStep) {
52411             context.map().on('move.intro drawn.intro', null);
52412             context.on('enter.intro', null);
52413             nextStep();
52414         }
52415     }
52416
52417
52418     function searchPreset() {
52419         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
52420             return addPoint();
52421         }
52422
52423         // disallow scrolling
52424         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
52425
52426         d3_select('.preset-search-input')
52427             .on('keydown.intro', null)
52428             .on('keyup.intro', checkPresetSearch);
52429
52430         reveal('.preset-search-input',
52431             t('intro.points.search_cafe', { preset: cafePreset.name() })
52432         );
52433
52434         context.on('enter.intro', function(mode) {
52435             if (!pointId || !context.hasEntity(pointId)) {
52436                 return continueTo(addPoint);
52437             }
52438
52439             var ids = context.selectedIDs();
52440             if (mode.id !== 'select' || !ids.length || ids[0] !== pointId) {
52441                 // keep the user's point selected..
52442                 context.enter(modeSelect(context, [pointId]));
52443
52444                 // disallow scrolling
52445                 d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
52446
52447                 d3_select('.preset-search-input')
52448                     .on('keydown.intro', null)
52449                     .on('keyup.intro', checkPresetSearch);
52450
52451                 reveal('.preset-search-input',
52452                     t('intro.points.search_cafe', { preset: cafePreset.name() })
52453                 );
52454
52455                 context.history().on('change.intro', null);
52456             }
52457         });
52458
52459
52460         function checkPresetSearch() {
52461             var first = d3_select('.preset-list-item:first-child');
52462
52463             if (first.classed('preset-amenity-cafe')) {
52464                 d3_select('.preset-search-input')
52465                     .on('keydown.intro', eventCancel, true)
52466                     .on('keyup.intro', null);
52467
52468                 reveal(first.select('.preset-list-button').node(),
52469                     t('intro.points.choose_cafe', { preset: cafePreset.name() }),
52470                     { duration: 300 }
52471                 );
52472
52473                 context.history().on('change.intro', function() {
52474                     continueTo(aboutFeatureEditor);
52475                 });
52476             }
52477         }
52478
52479         function continueTo(nextStep) {
52480             context.on('enter.intro', null);
52481             context.history().on('change.intro', null);
52482             d3_select('.inspector-wrap').on('wheel.intro', null);
52483             d3_select('.preset-search-input').on('keydown.intro keyup.intro', null);
52484             nextStep();
52485         }
52486     }
52487
52488
52489     function aboutFeatureEditor() {
52490         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
52491             return addPoint();
52492         }
52493
52494         timeout(function() {
52495             reveal('.entity-editor-pane', t('intro.points.feature_editor'), {
52496                 tooltipClass: 'intro-points-describe',
52497                 buttonText: t('intro.ok'),
52498                 buttonCallback: function() { continueTo(addName); }
52499             });
52500         }, 400);
52501
52502         context.on('exit.intro', function() {
52503             // if user leaves select mode here, just continue with the tutorial.
52504             continueTo(reselectPoint);
52505         });
52506
52507         function continueTo(nextStep) {
52508             context.on('exit.intro', null);
52509             nextStep();
52510         }
52511     }
52512
52513
52514     function addName() {
52515         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
52516             return addPoint();
52517         }
52518
52519         // reset pane, in case user happened to change it..
52520         d3_select('.inspector-wrap .panewrap').style('right', '0%');
52521
52522         timeout(function() {
52523             // It's possible for the user to add a name in a previous step..
52524             // If so, don't tell them to add the name in this step.
52525             // Give them an OK button instead.
52526             var entity = context.entity(pointId);
52527             if (entity.tags.name) {
52528                 var tooltip = reveal('.entity-editor-pane', t('intro.points.add_name'), {
52529                     tooltipClass: 'intro-points-describe',
52530                     buttonText: t('intro.ok'),
52531                     buttonCallback: function() { continueTo(addCloseEditor); }
52532                 });
52533                 tooltip.select('.instruction').style('display', 'none');
52534
52535             } else {
52536                 reveal('.entity-editor-pane', t('intro.points.add_name'),
52537                     { tooltipClass: 'intro-points-describe' }
52538                 );
52539             }
52540         }, 400);
52541
52542         context.history().on('change.intro', function() {
52543             continueTo(addCloseEditor);
52544         });
52545
52546         context.on('exit.intro', function() {
52547             // if user leaves select mode here, just continue with the tutorial.
52548             continueTo(reselectPoint);
52549         });
52550
52551         function continueTo(nextStep) {
52552             context.on('exit.intro', null);
52553             context.history().on('change.intro', null);
52554             nextStep();
52555         }
52556     }
52557
52558
52559     function addCloseEditor() {
52560         // reset pane, in case user happened to change it..
52561         d3_select('.inspector-wrap .panewrap').style('right', '0%');
52562
52563         var selector = '.entity-editor-pane button.preset-close svg use';
52564         var href = d3_select(selector).attr('href') || '#icon-close';
52565
52566         context.on('exit.intro', function() {
52567             continueTo(reselectPoint);
52568         });
52569
52570         reveal('.entity-editor-pane',
52571             t('intro.points.add_close', { button: icon(href, 'pre-text') })
52572         );
52573
52574         function continueTo(nextStep) {
52575             context.on('exit.intro', null);
52576             nextStep();
52577         }
52578     }
52579
52580
52581     function reselectPoint() {
52582         if (!pointId) return chapter.restart();
52583         var entity = context.hasEntity(pointId);
52584         if (!entity) return chapter.restart();
52585
52586         // make sure it's still a cafe, in case user somehow changed it..
52587         var oldPreset = context.presets().match(entity, context.graph());
52588         context.replace(actionChangePreset(pointId, oldPreset, cafePreset));
52589
52590         context.enter(modeBrowse(context));
52591
52592         var msec = transitionTime(entity.loc, context.map().center());
52593         if (msec) { reveal(null, null, { duration: 0 }); }
52594         context.map().centerEase(entity.loc, msec);
52595
52596         timeout(function() {
52597             var box = pointBox(entity.loc, context);
52598             reveal(box, t('intro.points.reselect'), { duration: 600 });
52599
52600             timeout(function() {
52601                 context.map().on('move.intro drawn.intro', function() {
52602                     var entity = context.hasEntity(pointId);
52603                     if (!entity) return chapter.restart();
52604                     var box = pointBox(entity.loc, context);
52605                     reveal(box, t('intro.points.reselect'), { duration: 0 });
52606                 });
52607             }, 600); // after reveal..
52608
52609             context.on('enter.intro', function(mode) {
52610                 if (mode.id !== 'select') return;
52611                 continueTo(updatePoint);
52612             });
52613
52614         }, msec + 100);
52615
52616         function continueTo(nextStep) {
52617             context.map().on('move.intro drawn.intro', null);
52618             context.on('enter.intro', null);
52619             nextStep();
52620         }
52621     }
52622
52623
52624     function updatePoint() {
52625         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
52626             return continueTo(reselectPoint);
52627         }
52628
52629         // reset pane, in case user happened to untag the point..
52630         d3_select('.inspector-wrap .panewrap').style('right', '0%');
52631
52632         context.on('exit.intro', function() {
52633             continueTo(reselectPoint);
52634         });
52635
52636         context.history().on('change.intro', function() {
52637             continueTo(updateCloseEditor);
52638         });
52639
52640         timeout(function() {
52641             reveal('.entity-editor-pane', t('intro.points.update'),
52642                 { tooltipClass: 'intro-points-describe' }
52643             );
52644         }, 400);
52645
52646         function continueTo(nextStep) {
52647             context.on('exit.intro', null);
52648             context.history().on('change.intro', null);
52649             nextStep();
52650         }
52651     }
52652
52653
52654     function updateCloseEditor() {
52655         if (context.mode().id !== 'select' || !pointId || !context.hasEntity(pointId)) {
52656             return continueTo(reselectPoint);
52657         }
52658
52659         // reset pane, in case user happened to change it..
52660         d3_select('.inspector-wrap .panewrap').style('right', '0%');
52661
52662         context.on('exit.intro', function() {
52663             continueTo(rightClickPoint);
52664         });
52665
52666         timeout(function() {
52667             reveal('.entity-editor-pane',
52668                 t('intro.points.update_close', { button: icon('#icon-apply', 'pre-text') })
52669             );
52670         }, 500);
52671
52672         function continueTo(nextStep) {
52673             context.on('exit.intro', null);
52674             nextStep();
52675         }
52676     }
52677
52678
52679     function rightClickPoint() {
52680         if (!pointId) return chapter.restart();
52681         var entity = context.hasEntity(pointId);
52682         if (!entity) return chapter.restart();
52683
52684         context.enter(modeBrowse(context));
52685
52686         var box = pointBox(entity.loc, context);
52687         reveal(box, t('intro.points.rightclick'), { duration: 600 });
52688
52689         timeout(function() {
52690             context.map().on('move.intro drawn.intro', function() {
52691                 var entity = context.hasEntity(pointId);
52692                 if (!entity) return chapter.restart();
52693                 var box = pointBox(entity.loc, context);
52694                 reveal(box, t('intro.points.rightclick'), { duration: 0 });
52695             });
52696         }, 600); // after reveal
52697
52698         context.on('enter.intro', function(mode) {
52699             if (mode.id !== 'select') return;
52700             var ids = context.selectedIDs();
52701             if (ids.length !== 1 || ids[0] !== pointId) return;
52702
52703             timeout(function() {
52704                 var node = selectMenuItem('delete').node();
52705                 if (!node) return;
52706                 continueTo(enterDelete);
52707             }, 300);  // after menu visible
52708         });
52709
52710         function continueTo(nextStep) {
52711             context.on('enter.intro', null);
52712             context.map().on('move.intro drawn.intro', null);
52713             nextStep();
52714         }
52715     }
52716
52717
52718     function enterDelete() {
52719         if (!pointId) return chapter.restart();
52720         var entity = context.hasEntity(pointId);
52721         if (!entity) return chapter.restart();
52722
52723         var node = selectMenuItem('delete').node();
52724         if (!node) { return continueTo(rightClickPoint); }
52725
52726         revealEditMenu(entity.loc,
52727             t('intro.points.delete', { button: icon('#operation-delete', 'pre-text') })
52728         );
52729
52730         timeout(function() {
52731             context.map().on('move.intro drawn.intro', function() {
52732                 revealEditMenu(entity.loc,
52733                     t('intro.points.delete', { button: icon('#operation-delete', 'pre-text') }),
52734                     { duration: 0}
52735                 );
52736             });
52737         }, 300); // after menu visible
52738
52739         context.on('exit.intro', function() {
52740             if (!pointId) return chapter.restart();
52741             var entity = context.hasEntity(pointId);
52742             if (entity) return continueTo(rightClickPoint);  // point still exists
52743         });
52744
52745         context.history().on('change.intro', function(changed) {
52746             if (changed.deleted().length) {
52747                 continueTo(undo);
52748             }
52749         });
52750
52751         function continueTo(nextStep) {
52752             context.map().on('move.intro drawn.intro', null);
52753             context.history().on('change.intro', null);
52754             context.on('exit.intro', null);
52755             nextStep();
52756         }
52757     }
52758
52759
52760     function undo() {
52761         context.history().on('change.intro', function() {
52762             continueTo(play);
52763         });
52764
52765         var iconName = '#icon-' + (textDirection === 'rtl' ? 'redo' : 'undo');
52766         reveal('#bar button.undo-button',
52767             t('intro.points.undo', { button: icon(iconName, 'pre-text') })
52768         );
52769
52770         function continueTo(nextStep) {
52771             context.history().on('change.intro', null);
52772             nextStep();
52773         }
52774     }
52775
52776
52777     function play() {
52778         dispatch$$1.call('done');
52779         reveal('#id-container',
52780             t('intro.points.play', { next: t('intro.areas.title') }), {
52781                 tooltipBox: '.intro-nav-wrap .chapter-area',
52782                 buttonText: t('intro.ok'),
52783                 buttonCallback: function() { reveal('#id-container'); }
52784             }
52785         );
52786     }
52787
52788
52789     chapter.enter = function() {
52790         addPoint();
52791     };
52792
52793
52794     chapter.exit = function() {
52795         timeouts.forEach(window.clearTimeout);
52796         context.on('enter.intro exit.intro', null);
52797         context.map().on('move.intro drawn.intro', null);
52798         context.history().on('change.intro', null);
52799         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
52800         d3_select('.preset-search-input').on('keydown.intro keyup.intro', null);
52801     };
52802
52803
52804     chapter.restart = function() {
52805         chapter.exit();
52806         chapter.enter();
52807     };
52808
52809
52810     return utilRebind(chapter, dispatch$$1, 'on');
52811 }
52812
52813 function uiIntroArea(context, reveal) {
52814     var dispatch$$1 = dispatch('done'),
52815         playground = [-85.63552, 41.94159],
52816         playgroundPreset = context.presets().item('leisure/playground'),
52817         descriptionField = context.presets().field('description'),
52818         timeouts = [],
52819         areaId;
52820
52821
52822     var chapter = {
52823         title: 'intro.areas.title'
52824     };
52825
52826
52827     function timeout(f, t$$1) {
52828         timeouts.push(window.setTimeout(f, t$$1));
52829     }
52830
52831
52832     function eventCancel() {
52833         event.stopPropagation();
52834         event.preventDefault();
52835     }
52836
52837
52838     function revealPlayground(center, text, options) {
52839         var padding = 180 * Math.pow(2, context.map().zoom() - 19.5);
52840         var box = pad$1(center, padding, context);
52841         reveal(box, text, options);
52842     }
52843
52844
52845     function addArea() {
52846         context.enter(modeBrowse(context));
52847         context.history().reset('initial');
52848         areaId = null;
52849
52850         var msec = transitionTime(playground, context.map().center());
52851         if (msec) { reveal(null, null, { duration: 0 }); }
52852         context.map().zoom(19).centerEase(playground, msec);
52853
52854         timeout(function() {
52855             var tooltip = reveal('button.add-area',
52856                 t('intro.areas.add_playground', { button: icon('#icon-area', 'pre-text') }));
52857
52858             tooltip.selectAll('.tooltip-inner')
52859                 .insert('svg', 'span')
52860                 .attr('class', 'tooltip-illustration')
52861                 .append('use')
52862                 .attr('xlink:href', '#landuse-images');
52863
52864             context.on('enter.intro', function(mode) {
52865                 if (mode.id !== 'add-area') return;
52866                 continueTo(startPlayground);
52867             });
52868         }, msec + 100);
52869
52870         function continueTo(nextStep) {
52871             context.on('enter.intro', null);
52872             nextStep();
52873         }
52874     }
52875
52876
52877     function startPlayground() {
52878         if (context.mode().id !== 'add-area') {
52879             return chapter.restart();
52880         }
52881
52882         areaId = null;
52883         context.map().zoomEase(19.5, 500);
52884
52885         timeout(function() {
52886             revealPlayground(playground,
52887                 t('intro.areas.start_playground'), { duration: 250 }
52888             );
52889
52890             timeout(function() {
52891                 context.map().on('move.intro drawn.intro', function() {
52892                     revealPlayground(playground,
52893                         t('intro.areas.start_playground'), { duration: 0 }
52894                     );
52895                 });
52896                 context.on('enter.intro', function(mode) {
52897                     if (mode.id !== 'draw-area') return chapter.restart();
52898                     continueTo(continuePlayground);
52899                 });
52900             }, 250);  // after reveal
52901
52902         }, 550);  // after easing
52903
52904         function continueTo(nextStep) {
52905             context.map().on('move.intro drawn.intro', null);
52906             context.on('enter.intro', null);
52907             nextStep();
52908         }
52909     }
52910
52911
52912     function continuePlayground() {
52913         if (context.mode().id !== 'draw-area') {
52914             return chapter.restart();
52915         }
52916
52917         areaId = null;
52918         revealPlayground(playground,
52919             t('intro.areas.continue_playground', { alt: uiCmd.display('⌥') }),
52920             { duration: 250 }
52921         );
52922
52923         timeout(function() {
52924             context.map().on('move.intro drawn.intro', function() {
52925                 revealPlayground(playground,
52926                     t('intro.areas.continue_playground', { alt: uiCmd.display('⌥') }),
52927                     { duration: 0 }
52928                 );
52929             });
52930         }, 250);  // after reveal
52931
52932         context.on('enter.intro', function(mode) {
52933             if (mode.id === 'draw-area') {
52934                 var entity = context.hasEntity(context.selectedIDs()[0]);
52935                 if (entity && entity.nodes.length >= 6) {
52936                     return continueTo(finishPlayground);
52937                 } else {
52938                     return;
52939                 }
52940             } else if (mode.id === 'select') {
52941                 areaId = context.selectedIDs()[0];
52942                 return continueTo(searchPresets);
52943             } else {
52944                 return chapter.restart();
52945             }
52946         });
52947
52948         function continueTo(nextStep) {
52949             context.map().on('move.intro drawn.intro', null);
52950             context.on('enter.intro', null);
52951             nextStep();
52952         }
52953     }
52954
52955
52956     function finishPlayground() {
52957         if (context.mode().id !== 'draw-area') {
52958             return chapter.restart();
52959         }
52960
52961         areaId = null;
52962         revealPlayground(playground,
52963             t('intro.areas.finish_playground'), { duration: 250 }
52964         );
52965
52966         timeout(function() {
52967             context.map().on('move.intro drawn.intro', function() {
52968                 revealPlayground(playground,
52969                     t('intro.areas.finish_playground'), { duration: 0 }
52970                 );
52971             });
52972         }, 250);  // after reveal
52973
52974         context.on('enter.intro', function(mode) {
52975             if (mode.id === 'draw-area') {
52976                 return;
52977             } else if (mode.id === 'select') {
52978                 areaId = context.selectedIDs()[0];
52979                 return continueTo(searchPresets);
52980             } else {
52981                 return chapter.restart();
52982             }
52983         });
52984
52985         function continueTo(nextStep) {
52986             context.map().on('move.intro drawn.intro', null);
52987             context.on('enter.intro', null);
52988             nextStep();
52989         }
52990     }
52991
52992
52993     function searchPresets() {
52994         if (!areaId || !context.hasEntity(areaId)) {
52995             return addArea();
52996         }
52997         var ids = context.selectedIDs();
52998         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
52999             context.enter(modeSelect(context, [areaId]));
53000         }
53001
53002         // disallow scrolling
53003         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
53004
53005         timeout(function() {
53006             // reset pane, in case user somehow happened to change it..
53007             d3_select('.inspector-wrap .panewrap').style('right', '-100%');
53008
53009             d3_select('.preset-search-input')
53010                 .on('keydown.intro', null)
53011                 .on('keyup.intro', checkPresetSearch);
53012
53013             reveal('.preset-search-input',
53014                 t('intro.areas.search_playground', { preset: playgroundPreset.name() })
53015             );
53016         }, 400);  // after preset list pane visible..
53017
53018         context.on('enter.intro', function(mode) {
53019             if (!areaId || !context.hasEntity(areaId)) {
53020                 return continueTo(addArea);
53021             }
53022
53023             var ids = context.selectedIDs();
53024             if (mode.id !== 'select' || !ids.length || ids[0] !== areaId) {
53025                 // keep the user's area selected..
53026                 context.enter(modeSelect(context, [areaId]));
53027
53028                 // reset pane, in case user somehow happened to change it..
53029                 d3_select('.inspector-wrap .panewrap').style('right', '-100%');
53030                 // disallow scrolling
53031                 d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
53032
53033                 d3_select('.preset-search-input')
53034                     .on('keydown.intro', null)
53035                     .on('keyup.intro', checkPresetSearch);
53036
53037                 reveal('.preset-search-input',
53038                     t('intro.areas.search_playground', { preset: playgroundPreset.name() })
53039                 );
53040
53041                 context.history().on('change.intro', null);
53042             }
53043         });
53044
53045         function checkPresetSearch() {
53046             var first = d3_select('.preset-list-item:first-child');
53047
53048             if (first.classed('preset-leisure-playground')) {
53049                 reveal(first.select('.preset-list-button').node(),
53050                     t('intro.areas.choose_playground', { preset: playgroundPreset.name() }),
53051                     { duration: 300 }
53052                 );
53053
53054                 d3_select('.preset-search-input')
53055                     .on('keydown.intro', eventCancel, true)
53056                     .on('keyup.intro', null);
53057
53058                 context.history().on('change.intro', function() {
53059                     continueTo(clickAddField);
53060                 });
53061             }
53062         }
53063
53064         function continueTo(nextStep) {
53065             d3_select('.inspector-wrap').on('wheel.intro', null);
53066             context.on('enter.intro', null);
53067             context.history().on('change.intro', null);
53068             d3_select('.preset-search-input').on('keydown.intro keyup.intro', null);
53069             nextStep();
53070         }
53071     }
53072
53073
53074     function clickAddField() {
53075         if (!areaId || !context.hasEntity(areaId)) {
53076             return addArea();
53077         }
53078         var ids = context.selectedIDs();
53079         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
53080             return searchPresets();
53081         }
53082
53083         if (!d3_select('.form-field-description').empty()) {
53084             return continueTo(describePlayground);
53085         }
53086
53087         // disallow scrolling
53088         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
53089
53090         timeout(function() {
53091             // reset pane, in case user somehow happened to change it..
53092             d3_select('.inspector-wrap .panewrap').style('right', '0%');
53093
53094             // It's possible for the user to add a description in a previous step..
53095             // If they did this already, just continue to next step.
53096             var entity = context.entity(areaId);
53097             if (entity.tags.description) {
53098                 return continueTo(play);
53099             }
53100
53101             // scroll "Add field" into view
53102             var box = d3_select('.more-fields').node().getBoundingClientRect();
53103             if (box.top > 300) {
53104                 var pane = d3_select('.entity-editor-pane .inspector-body');
53105                 var start = pane.node().scrollTop;
53106                 var end = start + (box.top - 300);
53107
53108                 pane
53109                     .transition()
53110                     .duration(250)
53111                     .tween('scroll.inspector', function() {
53112                         var node = this;
53113                         var i = d3_interpolateNumber(start, end);
53114                         return function(t$$1) {
53115                             node.scrollTop = i(t$$1);
53116                         };
53117                     });
53118             }
53119
53120             timeout(function() {
53121                 reveal('.more-fields .combobox-input',
53122                     t('intro.areas.add_field'),
53123                     { duration: 300 }
53124                 );
53125
53126                 d3_select('.more-fields .combobox-input')
53127                     .on('click.intro', function() {
53128                         continueTo(chooseDescriptionField);
53129                     });
53130             }, 300);  // after "Add Field" visible
53131
53132         }, 400);  // after editor pane visible
53133
53134         context.on('exit.intro', function() {
53135             return continueTo(searchPresets);
53136         });
53137
53138         function continueTo(nextStep) {
53139             d3_select('.inspector-wrap').on('wheel.intro', null);
53140             d3_select('.more-fields .combobox-input').on('click.intro', null);
53141             context.on('exit.intro', null);
53142             nextStep();
53143         }
53144     }
53145
53146
53147     function chooseDescriptionField() {
53148         if (!areaId || !context.hasEntity(areaId)) {
53149             return addArea();
53150         }
53151         var ids = context.selectedIDs();
53152         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
53153             return searchPresets();
53154         }
53155
53156         if (!d3_select('.form-field-description').empty()) {
53157             return continueTo(describePlayground);
53158         }
53159
53160         // Make sure combobox is ready..
53161         if (d3_select('div.combobox').empty()) {
53162             return continueTo(clickAddField);
53163         }
53164         // Watch for the combobox to go away..
53165         var watcher;
53166         watcher = window.setInterval(function() {
53167             if (d3_select('div.combobox').empty()) {
53168                 window.clearInterval(watcher);
53169                 timeout(function() {
53170                     if (d3_select('.form-field-description').empty()) {
53171                         continueTo(retryChooseDescription);
53172                     } else {
53173                         continueTo(describePlayground);
53174                     }
53175                 }, 300);  // after description field added.
53176             }
53177         }, 300);
53178
53179         reveal('div.combobox',
53180             t('intro.areas.choose_field', { field: descriptionField.label() }),
53181             { duration: 300 }
53182         );
53183
53184         context.on('exit.intro', function() {
53185             return continueTo(searchPresets);
53186         });
53187
53188         function continueTo(nextStep) {
53189             if (watcher) window.clearInterval(watcher);
53190             context.on('exit.intro', null);
53191             nextStep();
53192         }
53193     }
53194
53195
53196     function describePlayground() {
53197         if (!areaId || !context.hasEntity(areaId)) {
53198             return addArea();
53199         }
53200         var ids = context.selectedIDs();
53201         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
53202             return searchPresets();
53203         }
53204
53205         // reset pane, in case user happened to change it..
53206         d3_select('.inspector-wrap .panewrap').style('right', '0%');
53207
53208         if (d3_select('.form-field-description').empty()) {
53209             return continueTo(retryChooseDescription);
53210         }
53211
53212         context.on('exit.intro', function() {
53213             continueTo(play);
53214         });
53215
53216         reveal('.entity-editor-pane',
53217             t('intro.areas.describe_playground', { button: icon('#icon-apply', 'pre-text') }),
53218             { duration: 300 }
53219         );
53220
53221         function continueTo(nextStep) {
53222             context.on('exit.intro', null);
53223             nextStep();
53224         }
53225     }
53226
53227
53228     function retryChooseDescription() {
53229         if (!areaId || !context.hasEntity(areaId)) {
53230             return addArea();
53231         }
53232         var ids = context.selectedIDs();
53233         if (context.mode().id !== 'select' || !ids.length || ids[0] !== areaId) {
53234             return searchPresets();
53235         }
53236
53237         // reset pane, in case user happened to change it..
53238         d3_select('.inspector-wrap .panewrap').style('right', '0%');
53239
53240         reveal('.entity-editor-pane',
53241             t('intro.areas.retry_add_field', { field: descriptionField.label() }), {
53242             buttonText: t('intro.ok'),
53243             buttonCallback: function() { continueTo(clickAddField); }
53244         });
53245
53246         context.on('exit.intro', function() {
53247             return continueTo(searchPresets);
53248         });
53249
53250         function continueTo(nextStep) {
53251             context.on('exit.intro', null);
53252             nextStep();
53253         }
53254     }
53255
53256
53257     function play() {
53258         dispatch$$1.call('done');
53259         reveal('#id-container',
53260             t('intro.areas.play', { next: t('intro.lines.title') }), {
53261                 tooltipBox: '.intro-nav-wrap .chapter-line',
53262                 buttonText: t('intro.ok'),
53263                 buttonCallback: function() { reveal('#id-container'); }
53264             }
53265         );
53266     }
53267
53268
53269     chapter.enter = function() {
53270         addArea();
53271     };
53272
53273
53274     chapter.exit = function() {
53275         timeouts.forEach(window.clearTimeout);
53276         context.on('enter.intro exit.intro', null);
53277         context.map().on('move.intro drawn.intro', null);
53278         context.history().on('change.intro', null);
53279         d3_select('.inspector-wrap').on('wheel.intro', null);
53280         d3_select('.preset-search-input').on('keydown.intro keyup.intro', null);
53281         d3_select('.more-fields .combobox-input').on('click.intro', null);
53282     };
53283
53284
53285     chapter.restart = function() {
53286         chapter.exit();
53287         chapter.enter();
53288     };
53289
53290
53291     return utilRebind(chapter, dispatch$$1, 'on');
53292 }
53293
53294 function uiIntroLine(context, reveal) {
53295     var dispatch$$1 = dispatch('done'),
53296         timeouts = [],
53297         tulipRoadId = null,
53298         flowerRoadId = 'w646',
53299         tulipRoadStart = [-85.6297754121684, 41.95805253325314],
53300         tulipRoadMidpoint = [-85.62975395449628, 41.95787501510204],
53301         tulipRoadIntersection = [-85.62974496187628, 41.95742515554585],
53302         roadCategory = context.presets().item('category-road'),
53303         residentialPreset = context.presets().item('highway/residential'),
53304         woodRoadId = 'w525',
53305         woodRoadEndId = 'n2862',
53306         woodRoadAddNode = [-85.62390110349587, 41.95397111462291],
53307         woodRoadDragEndpoint = [-85.623867390213, 41.95466987786487],
53308         woodRoadDragMidpoint = [-85.62386254803509, 41.95430395953872],
53309         washingtonStreetId = 'w522',
53310         twelfthAvenueId = 'w1',
53311         eleventhAvenueEndId = 'n3550',
53312         twelfthAvenueEndId = 'n5',
53313         washingtonSegmentId = null,
53314         eleventhAvenueEnd = context.entity(eleventhAvenueEndId).loc,
53315         twelfthAvenueEnd = context.entity(twelfthAvenueEndId).loc,
53316         deleteLinesLoc = [-85.6219395542764, 41.95228033922477],
53317         twelfthAvenue = [-85.62219310052491, 41.952505413152956];
53318
53319
53320     var chapter = {
53321         title: 'intro.lines.title'
53322     };
53323
53324
53325     function timeout(f, t$$1) {
53326         timeouts.push(window.setTimeout(f, t$$1));
53327     }
53328
53329
53330     function eventCancel() {
53331         event.stopPropagation();
53332         event.preventDefault();
53333     }
53334
53335
53336     function revealEditMenu(loc, text, options) {
53337         var rect = context.surfaceRect();
53338         var point = context.curtainProjection(loc);
53339         var pad = 40;
53340         var width = 250 + (2 * pad);
53341         var height = 350;
53342         var startX = rect.left + point[0];
53343         var left = (textDirection === 'rtl') ? (startX - width + pad) : (startX - pad);
53344         var box = {
53345             left: left,
53346             top: point[1] + rect.top - 60,
53347             width: width,
53348             height: height
53349         };
53350         reveal(box, text, options);
53351     }
53352
53353
53354     function addLine() {
53355         context.enter(modeBrowse(context));
53356         context.history().reset('initial');
53357
53358         var msec = transitionTime(tulipRoadStart, context.map().center());
53359         if (msec) { reveal(null, null, { duration: 0 }); }
53360         context.map().zoom(18.5).centerEase(tulipRoadStart, msec);
53361
53362         timeout(function() {
53363             var tooltip = reveal('button.add-line',
53364                 t('intro.lines.add_line', { button: icon('#icon-line', 'pre-text') }));
53365
53366             tooltip.selectAll('.tooltip-inner')
53367                 .insert('svg', 'span')
53368                 .attr('class', 'tooltip-illustration')
53369                 .append('use')
53370                 .attr('xlink:href', '#feature-images');
53371
53372             context.on('enter.intro', function(mode) {
53373                 if (mode.id !== 'add-line') return;
53374                 continueTo(startLine);
53375             });
53376         }, msec + 100);
53377
53378         function continueTo(nextStep) {
53379             context.on('enter.intro', null);
53380             nextStep();
53381         }
53382     }
53383
53384
53385     function startLine() {
53386         if (context.mode().id !== 'add-line') {
53387             return chapter.restart();
53388         }
53389
53390         tulipRoadId = null;
53391
53392         var padding = 70 * Math.pow(2, context.map().zoom() - 18);
53393         var box = pad$1(tulipRoadStart, padding, context);
53394         box.height = box.height + 100;
53395         reveal(box, t('intro.lines.start_line'));
53396
53397         context.map().on('move.intro drawn.intro', function() {
53398             padding = 70 * Math.pow(2, context.map().zoom() - 18);
53399             box = pad$1(tulipRoadStart, padding, context);
53400             box.height = box.height + 100;
53401             reveal(box, t('intro.lines.start_line'), { duration: 0 });
53402         });
53403
53404         context.on('enter.intro', function(mode) {
53405             if (mode.id !== 'draw-line') return chapter.restart();
53406             continueTo(drawLine);
53407         });
53408
53409         function continueTo(nextStep) {
53410             context.map().on('move.intro drawn.intro', null);
53411             context.on('enter.intro', null);
53412             nextStep();
53413         }
53414     }
53415
53416
53417     function drawLine() {
53418         if (context.mode().id !== 'draw-line') {
53419             return chapter.restart();
53420         }
53421
53422         tulipRoadId = context.mode().selectedIDs()[0];
53423         context.map().centerEase(tulipRoadMidpoint, 500);
53424
53425         timeout(function() {
53426             var padding = 200 * Math.pow(2, context.map().zoom() - 18.5);
53427             var box = pad$1(tulipRoadMidpoint, padding, context);
53428             box.height = box.height * 2;
53429             reveal(box,
53430                 t('intro.lines.intersect', { name: t('intro.graph.name.flower-street') })
53431             );
53432
53433             context.map().on('move.intro drawn.intro', function() {
53434                 padding = 200 * Math.pow(2, context.map().zoom() - 18.5);
53435                 box = pad$1(tulipRoadMidpoint, padding, context);
53436                 box.height = box.height * 2;
53437                 reveal(box,
53438                     t('intro.lines.intersect', { name: t('intro.graph.name.flower-street') }),
53439                     { duration: 0 }
53440                 );
53441             });
53442         }, 550);  // after easing..
53443
53444         context.history().on('change.intro', function() {
53445             var entity = tulipRoadId && context.hasEntity(tulipRoadId);
53446             if (!entity) return chapter.restart();
53447
53448             if (isLineConnected()) {
53449                 continueTo(continueLine);
53450             }
53451         });
53452
53453         context.on('enter.intro', function(mode) {
53454             if (mode.id === 'draw-line')
53455                 return;
53456             else if (mode.id === 'select') {
53457                 continueTo(retryIntersect);
53458                 return;
53459             }
53460             else
53461                 return chapter.restart();
53462         });
53463
53464         function continueTo(nextStep) {
53465             context.map().on('move.intro drawn.intro', null);
53466             context.history().on('change.intro', null);
53467             context.on('enter.intro', null);
53468             nextStep();
53469         }
53470     }
53471
53472
53473     function isLineConnected() {
53474         var entity = tulipRoadId && context.hasEntity(tulipRoadId);
53475         if (!entity) return false;
53476
53477         var drawNodes = context.graph().childNodes(entity);
53478         return some(drawNodes, function(node) {
53479             return some(context.graph().parentWays(node), function(parent) {
53480                 return parent.id === flowerRoadId;
53481             });
53482         });
53483     }
53484
53485
53486     function retryIntersect() {
53487         d3_select(window).on('mousedown.intro', eventCancel, true);
53488
53489         var box = pad$1(tulipRoadIntersection, 80, context);
53490         reveal(box,
53491             t('intro.lines.retry_intersect', { name: t('intro.graph.name.flower-street') })
53492         );
53493
53494         timeout(chapter.restart, 3000);
53495     }
53496
53497
53498     function continueLine() {
53499         if (context.mode().id !== 'draw-line') return chapter.restart();
53500         var entity = tulipRoadId && context.hasEntity(tulipRoadId);
53501         if (!entity) return chapter.restart();
53502
53503         context.map().centerEase(tulipRoadIntersection, 500);
53504
53505         reveal('#surface', t('intro.lines.continue_line'));
53506
53507         context.on('enter.intro', function(mode) {
53508             if (mode.id === 'draw-line')
53509                 return;
53510             else if (mode.id === 'select')
53511                 return continueTo(chooseCategoryRoad);
53512             else
53513                 return chapter.restart();
53514         });
53515
53516         function continueTo(nextStep) {
53517             context.on('enter.intro', null);
53518             nextStep();
53519         }
53520     }
53521
53522
53523     function chooseCategoryRoad() {
53524         if (context.mode().id !== 'select') {
53525             return chapter.restart();
53526         }
53527
53528         context.on('exit.intro', function() {
53529             return chapter.restart();
53530         });
53531
53532         var button = d3_select('.preset-category-road .preset-list-button');
53533         if (button.empty()) return chapter.restart();
53534
53535         // disallow scrolling
53536         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
53537
53538         timeout(function() {
53539             // reset pane, in case user somehow happened to change it..
53540             d3_select('.inspector-wrap .panewrap').style('right', '-100%');
53541
53542             reveal(button.node(),
53543                 t('intro.lines.choose_category_road', { category: roadCategory.name() })
53544             );
53545
53546             button.on('click.intro', function() {
53547                 continueTo(choosePresetResidential);
53548             });
53549
53550         }, 400);  // after editor pane visible
53551
53552         function continueTo(nextStep) {
53553             d3_select('.inspector-wrap').on('wheel.intro', null);
53554             d3_select('.preset-list-button').on('click.intro', null);
53555             context.on('exit.intro', null);
53556             nextStep();
53557         }
53558     }
53559
53560
53561     function choosePresetResidential() {
53562         if (context.mode().id !== 'select') {
53563             return chapter.restart();
53564         }
53565
53566         context.on('exit.intro', function() {
53567             return chapter.restart();
53568         });
53569
53570         var subgrid = d3_select('.preset-category-road .subgrid');
53571         if (subgrid.empty()) return chapter.restart();
53572
53573         subgrid.selectAll(':not(.preset-highway-residential) .preset-list-button')
53574             .on('click.intro', function() {
53575                 continueTo(retryPresetResidential);
53576             });
53577
53578         subgrid.selectAll('.preset-highway-residential .preset-list-button')
53579             .on('click.intro', function() {
53580                 continueTo(nameRoad);
53581             });
53582
53583         timeout(function() {
53584             reveal(subgrid.node(),
53585                 t('intro.lines.choose_preset_residential', { preset: residentialPreset.name() }),
53586                 { tooltipBox: '.preset-highway-residential .preset-list-button', duration: 300 }
53587             );
53588         }, 300);
53589
53590         function continueTo(nextStep) {
53591             d3_select('.preset-list-button').on('click.intro', null);
53592             context.on('exit.intro', null);
53593             nextStep();
53594         }
53595     }
53596
53597
53598     // selected wrong road type
53599     function retryPresetResidential() {
53600         if (context.mode().id !== 'select') {
53601             return chapter.restart();
53602         }
53603
53604         context.on('exit.intro', function() {
53605             return chapter.restart();
53606         });
53607
53608         // disallow scrolling
53609         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
53610
53611         timeout(function() {
53612             var button = d3_select('.entity-editor-pane .preset-list-button');
53613
53614             reveal(button.node(),
53615                 t('intro.lines.retry_preset_residential', { preset: residentialPreset.name() })
53616             );
53617
53618             button.on('click.intro', function() {
53619                 continueTo(chooseCategoryRoad);
53620             });
53621
53622         }, 500);
53623
53624         function continueTo(nextStep) {
53625             d3_select('.inspector-wrap').on('wheel.intro', null);
53626             d3_select('.preset-list-button').on('click.intro', null);
53627             context.on('exit.intro', null);
53628             nextStep();
53629         }
53630     }
53631
53632
53633     function nameRoad() {
53634         context.on('exit.intro', function() {
53635             continueTo(didNameRoad);
53636         });
53637
53638         timeout(function() {
53639             reveal('.entity-editor-pane',
53640                 t('intro.lines.name_road', { button: icon('#icon-apply', 'pre-text') }),
53641                 { tooltipClass: 'intro-lines-name_road' }
53642             );
53643         }, 500);
53644
53645         function continueTo(nextStep) {
53646             context.on('exit.intro', null);
53647             nextStep();
53648         }
53649     }
53650
53651
53652     function didNameRoad() {
53653         context.history().checkpoint('doneAddLine');
53654
53655         timeout(function() {
53656             reveal('#surface', t('intro.lines.did_name_road'), {
53657                 buttonText: t('intro.ok'),
53658                 buttonCallback: function() { continueTo(updateLine); }
53659             });
53660         }, 500);
53661
53662         function continueTo(nextStep) {
53663             nextStep();
53664         }
53665     }
53666
53667
53668     function updateLine() {
53669         context.history().reset('doneAddLine');
53670         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
53671             return chapter.restart();
53672         }
53673
53674         var msec = transitionTime(woodRoadDragMidpoint, context.map().center());
53675         if (msec) { reveal(null, null, { duration: 0 }); }
53676         context.map().zoom(19).centerEase(woodRoadDragMidpoint, msec);
53677
53678         timeout(function() {
53679             var padding = 250 * Math.pow(2, context.map().zoom() - 19);
53680             var box = pad$1(woodRoadDragMidpoint, padding, context);
53681             var advance = function() { continueTo(addNode); };
53682
53683             reveal(box, t('intro.lines.update_line'),
53684                 { buttonText: t('intro.ok'), buttonCallback: advance }
53685             );
53686
53687             context.map().on('move.intro drawn.intro', function() {
53688                 var padding = 250 * Math.pow(2, context.map().zoom() - 19);
53689                 var box = pad$1(woodRoadDragMidpoint, padding, context);
53690                 reveal(box, t('intro.lines.update_line'),
53691                     { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance }
53692                 );
53693             });
53694         }, msec + 100);
53695
53696         function continueTo(nextStep) {
53697             context.map().on('move.intro drawn.intro', null);
53698             nextStep();
53699         }
53700     }
53701
53702
53703     function addNode() {
53704         context.history().reset('doneAddLine');
53705         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
53706             return chapter.restart();
53707         }
53708
53709         var padding = 40 * Math.pow(2, context.map().zoom() - 19);
53710         var box = pad$1(woodRoadAddNode, padding, context);
53711         reveal(box, t('intro.lines.add_node'));
53712
53713         context.map().on('move.intro drawn.intro', function() {
53714             var padding = 40 * Math.pow(2, context.map().zoom() - 19);
53715             var box = pad$1(woodRoadAddNode, padding, context);
53716             reveal(box, t('intro.lines.add_node'), { duration: 0 });
53717         });
53718
53719         context.history().on('change.intro', function(changed) {
53720             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
53721                 return continueTo(updateLine);
53722             }
53723             if (changed.created().length === 1) {
53724                 timeout(function() { continueTo(startDragEndpoint); }, 500);
53725             }
53726         });
53727
53728         context.on('enter.intro', function(mode) {
53729             if (mode.id !== 'select') {
53730                 continueTo(updateLine);
53731             }
53732         });
53733
53734         function continueTo(nextStep) {
53735             context.map().on('move.intro drawn.intro', null);
53736             context.history().on('change.intro', null);
53737             context.on('enter.intro', null);
53738             nextStep();
53739         }
53740     }
53741
53742
53743     function startDragEndpoint() {
53744         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
53745             return continueTo(updateLine);
53746         }
53747         if (context.selectedIDs().indexOf(woodRoadId) === -1) {
53748             context.enter(modeSelect(context, [woodRoadId]));
53749         }
53750
53751         var padding = 100 * Math.pow(2, context.map().zoom() - 19);
53752         var box = pad$1(woodRoadDragEndpoint, padding, context);
53753         reveal(box, t('intro.lines.start_drag_endpoint'));
53754
53755         context.map().on('move.intro drawn.intro', function() {
53756             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
53757                 return continueTo(updateLine);
53758             }
53759             var padding = 100 * Math.pow(2, context.map().zoom() - 19);
53760             var box = pad$1(woodRoadDragEndpoint, padding, context);
53761             reveal(box, t('intro.lines.start_drag_endpoint'), { duration: 0 });
53762
53763             var entity = context.entity(woodRoadEndId);
53764             if (geoSphericalDistance(entity.loc, woodRoadDragEndpoint) <= 4) {
53765                 continueTo(finishDragEndpoint);
53766             }
53767         });
53768
53769         context.on('enter.intro', function(mode) {
53770             if (mode.id !== 'select') {
53771                 // keep Wood Road selected so endpoint stays draggable..
53772                 context.enter(modeSelect(context, [woodRoadId]));
53773             }
53774         });
53775
53776         function continueTo(nextStep) {
53777             context.map().on('move.intro drawn.intro', null);
53778             context.on('enter.intro', null);
53779             nextStep();
53780         }
53781     }
53782
53783
53784     function finishDragEndpoint() {
53785         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
53786             return continueTo(updateLine);
53787         }
53788
53789         var padding = 100 * Math.pow(2, context.map().zoom() - 19);
53790         var box = pad$1(woodRoadDragEndpoint, padding, context);
53791         reveal(box, t('intro.lines.finish_drag_endpoint'));
53792
53793         context.map().on('move.intro drawn.intro', function() {
53794             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
53795                 return continueTo(updateLine);
53796             }
53797             var padding = 100 * Math.pow(2, context.map().zoom() - 19);
53798             var box = pad$1(woodRoadDragEndpoint, padding, context);
53799             reveal(box, t('intro.lines.finish_drag_endpoint'), { duration: 0 });
53800
53801             var entity = context.entity(woodRoadEndId);
53802             if (geoSphericalDistance(entity.loc, woodRoadDragEndpoint) > 4) {
53803                 continueTo(startDragEndpoint);
53804             }
53805         });
53806
53807         context.on('enter.intro', function() {
53808             continueTo(startDragMidpoint);
53809         });
53810
53811         function continueTo(nextStep) {
53812             context.map().on('move.intro drawn.intro', null);
53813             context.on('enter.intro', null);
53814             nextStep();
53815         }
53816     }
53817
53818
53819     function startDragMidpoint() {
53820         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
53821             return continueTo(updateLine);
53822         }
53823         if (context.selectedIDs().indexOf(woodRoadId) === -1) {
53824             context.enter(modeSelect(context, [woodRoadId]));
53825         }
53826
53827         var padding = 80 * Math.pow(2, context.map().zoom() - 19);
53828         var box = pad$1(woodRoadDragMidpoint, padding, context);
53829         reveal(box, t('intro.lines.start_drag_midpoint'));
53830
53831         context.map().on('move.intro drawn.intro', function() {
53832             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
53833                 return continueTo(updateLine);
53834             }
53835             var padding = 80 * Math.pow(2, context.map().zoom() - 19);
53836             var box = pad$1(woodRoadDragMidpoint, padding, context);
53837             reveal(box, t('intro.lines.start_drag_midpoint'), { duration: 0 });
53838         });
53839
53840         context.history().on('change.intro', function(changed) {
53841             if (changed.created().length === 1) {
53842                 continueTo(continueDragMidpoint);
53843             }
53844         });
53845
53846         context.on('enter.intro', function(mode) {
53847             if (mode.id !== 'select') {
53848                 // keep Wood Road selected so midpoint triangles are drawn..
53849                 context.enter(modeSelect(context, [woodRoadId]));
53850             }
53851         });
53852
53853         function continueTo(nextStep) {
53854             context.map().on('move.intro drawn.intro', null);
53855             context.history().on('change.intro', null);
53856             context.on('enter.intro', null);
53857             nextStep();
53858         }
53859     }
53860
53861
53862     function continueDragMidpoint() {
53863         if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
53864             return continueTo(updateLine);
53865         }
53866
53867         var padding = 100 * Math.pow(2, context.map().zoom() - 19);
53868         var box = pad$1(woodRoadDragEndpoint, padding, context);
53869         box.height += 400;
53870
53871         var advance = function() {
53872             context.history().checkpoint('doneUpdateLine');
53873             continueTo(deleteLines);
53874         };
53875
53876         reveal(box, t('intro.lines.continue_drag_midpoint'),
53877             { buttonText: t('intro.ok'), buttonCallback: advance }
53878         );
53879
53880         context.map().on('move.intro drawn.intro', function() {
53881             if (!context.hasEntity(woodRoadId) || !context.hasEntity(woodRoadEndId)) {
53882                 return continueTo(updateLine);
53883             }
53884             var padding = 100 * Math.pow(2, context.map().zoom() - 19);
53885             var box = pad$1(woodRoadDragEndpoint, padding, context);
53886             box.height += 400;
53887             reveal(box, t('intro.lines.continue_drag_midpoint'),
53888                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance }
53889             );
53890         });
53891
53892         function continueTo(nextStep) {
53893             context.map().on('move.intro drawn.intro', null);
53894             nextStep();
53895         }
53896     }
53897
53898
53899     function deleteLines() {
53900         context.history().reset('doneUpdateLine');
53901         context.enter(modeBrowse(context));
53902
53903         if (!context.hasEntity(washingtonStreetId) ||
53904             !context.hasEntity(twelfthAvenueId) ||
53905             !context.hasEntity(eleventhAvenueEndId)) {
53906             return chapter.restart();
53907         }
53908
53909         var msec = transitionTime(deleteLinesLoc, context.map().center());
53910         if (msec) { reveal(null, null, { duration: 0 }); }
53911         context.map().zoom(18).centerEase(deleteLinesLoc, msec);
53912
53913         timeout(function() {
53914             var padding = 200 * Math.pow(2, context.map().zoom() - 18);
53915             var box = pad$1(deleteLinesLoc, padding, context);
53916             box.top -= 200;
53917             box.height += 400;
53918             var advance = function() { continueTo(rightClickIntersection); };
53919
53920             reveal(box, t('intro.lines.delete_lines', { street: t('intro.graph.name.12th-avenue') }),
53921                 { buttonText: t('intro.ok'), buttonCallback: advance }
53922             );
53923
53924             context.map().on('move.intro drawn.intro', function() {
53925                 var padding = 200 * Math.pow(2, context.map().zoom() - 18);
53926                 var box = pad$1(deleteLinesLoc, padding, context);
53927                 box.top -= 200;
53928                 box.height += 400;
53929                 reveal(box, t('intro.lines.delete_lines', { street: t('intro.graph.name.12th-avenue') }),
53930                     { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance }
53931                 );
53932             });
53933
53934             context.history().on('change.intro', function() {
53935                 timeout(function() {
53936                     continueTo(deleteLines);
53937                 }, 500);  // after any transition (e.g. if user deleted intersection)
53938             });
53939
53940         }, msec + 100);
53941
53942         function continueTo(nextStep) {
53943             context.map().on('move.intro drawn.intro', null);
53944             context.history().on('change.intro', null);
53945             nextStep();
53946         }
53947     }
53948
53949
53950     function rightClickIntersection() {
53951         context.history().reset('doneUpdateLine');
53952         context.enter(modeBrowse(context));
53953
53954         context.map().zoom(18).centerEase(eleventhAvenueEnd, 500);
53955
53956         timeout(function() {
53957             var padding = 60 * Math.pow(2, context.map().zoom() - 18);
53958             var box = pad$1(eleventhAvenueEnd, padding, context);
53959             reveal(box, t('intro.lines.rightclick_intersection',
53960                 { street1: t('intro.graph.name.11th-avenue'), street2: t('intro.graph.name.washington-street') })
53961             );
53962
53963             context.map().on('move.intro drawn.intro', function() {
53964                 var padding = 60 * Math.pow(2, context.map().zoom() - 18);
53965                 var box = pad$1(eleventhAvenueEnd, padding, context);
53966                 reveal(box, t('intro.lines.rightclick_intersection',
53967                     { street1: t('intro.graph.name.11th-avenue'), street2: t('intro.graph.name.washington-street') }),
53968                     { duration: 0 }
53969                 );
53970             });
53971
53972             context.on('enter.intro', function(mode) {
53973                 if (mode.id !== 'select') return;
53974                 var ids = context.selectedIDs();
53975                 if (ids.length !== 1 || ids[0] !== eleventhAvenueEndId) return;
53976
53977                 timeout(function() {
53978                     var node = selectMenuItem('split').node();
53979                     if (!node) return;
53980                     continueTo(splitIntersection);
53981                 }, 300);  // after menu visible
53982             });
53983
53984             context.history().on('change.intro', function() {
53985                 timeout(function() {
53986                     continueTo(deleteLines);
53987                 }, 300);  // after any transition (e.g. if user deleted intersection)
53988             });
53989
53990         }, 600);
53991
53992         function continueTo(nextStep) {
53993             context.map().on('move.intro drawn.intro', null);
53994             context.on('enter.intro', null);
53995             context.history().on('change.intro', null);
53996             nextStep();
53997         }
53998     }
53999
54000
54001     function splitIntersection() {
54002         if (!context.hasEntity(washingtonStreetId) ||
54003             !context.hasEntity(twelfthAvenueId) ||
54004             !context.hasEntity(eleventhAvenueEndId)) {
54005             return continueTo(deleteLines);
54006         }
54007
54008         var node = selectMenuItem('split').node();
54009         if (!node) { return continueTo(rightClickIntersection); }
54010
54011         var wasChanged = false;
54012         var menuCoords = context.map().mouseCoordinates();
54013         washingtonSegmentId = null;
54014
54015         revealEditMenu(menuCoords, t('intro.lines.split_intersection',
54016             { button: icon('#operation-split', 'pre-text'), street: t('intro.graph.name.washington-street') })
54017         );
54018
54019         context.map().on('move.intro drawn.intro', function() {
54020             var node = selectMenuItem('split').node();
54021             if (!wasChanged && !node) { return continueTo(rightClickIntersection); }
54022
54023             revealEditMenu(menuCoords, t('intro.lines.split_intersection',
54024                 { button: icon('#operation-split', 'pre-text'), street: t('intro.graph.name.washington-street') }),
54025                 { duration: 0 }
54026             );
54027         });
54028
54029         context.history().on('change.intro', function(changed) {
54030             wasChanged = true;
54031             timeout(function() {
54032                 if (context.history().undoAnnotation() === t('operations.split.annotation.line')) {
54033                     washingtonSegmentId = changed.created()[0].id;
54034                     continueTo(didSplit);
54035                 } else {
54036                     washingtonSegmentId = null;
54037                     continueTo(retrySplit);
54038                 }
54039             }, 300);  // after any transition (e.g. if user deleted intersection)
54040         });
54041
54042         function continueTo(nextStep) {
54043             context.map().on('move.intro drawn.intro', null);
54044             context.history().on('change.intro', null);
54045             nextStep();
54046         }
54047     }
54048
54049
54050     function retrySplit() {
54051         context.enter(modeBrowse(context));
54052         context.map().zoom(18).centerEase(eleventhAvenueEnd, 500);
54053         var advance = function() { continueTo(rightClickIntersection); };
54054
54055         var padding = 60 * Math.pow(2, context.map().zoom() - 18);
54056         var box = pad$1(eleventhAvenueEnd, padding, context);
54057         reveal(box, t('intro.lines.retry_split'),
54058             { buttonText: t('intro.ok'), buttonCallback: advance }
54059         );
54060
54061         context.map().on('move.intro drawn.intro', function() {
54062             var padding = 60 * Math.pow(2, context.map().zoom() - 18);
54063             var box = pad$1(eleventhAvenueEnd, padding, context);
54064             reveal(box, t('intro.lines.retry_split'),
54065                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: advance }
54066             );
54067         });
54068
54069         function continueTo(nextStep) {
54070             context.map().on('move.intro drawn.intro', null);
54071             nextStep();
54072         }
54073     }
54074
54075
54076     function didSplit() {
54077         if (!washingtonSegmentId ||
54078             !context.hasEntity(washingtonSegmentId) ||
54079             !context.hasEntity(washingtonStreetId) ||
54080             !context.hasEntity(twelfthAvenueId) ||
54081             !context.hasEntity(eleventhAvenueEndId)) {
54082             return continueTo(rightClickIntersection);
54083         }
54084
54085         var ids = context.selectedIDs();
54086         var string = 'intro.lines.did_split_' + (ids.length > 1 ? 'multi' : 'single');
54087         var street = t('intro.graph.name.washington-street');
54088
54089         var padding = 200 * Math.pow(2, context.map().zoom() - 18);
54090         var box = pad$1(twelfthAvenue, padding, context);
54091         box.width = box.width / 2;
54092         reveal(box, t(string, { street1: street, street2: street }),
54093             { duration: 500 }
54094         );
54095
54096         timeout(function() {
54097             context.map().zoom(18).centerEase(twelfthAvenue, 500);
54098
54099             context.map().on('move.intro drawn.intro', function() {
54100                 var padding = 200 * Math.pow(2, context.map().zoom() - 18);
54101                 var box = pad$1(twelfthAvenue, padding, context);
54102                 box.width = box.width / 2;
54103                 reveal(box, t(string, { street1: street, street2: street }),
54104                     { duration: 0 }
54105                 );
54106             });
54107         }, 600);  // after initial reveal and curtain cut
54108
54109         context.on('enter.intro', function() {
54110             var ids = context.selectedIDs();
54111             if (ids.length === 1 && ids[0] === washingtonSegmentId) {
54112                 continueTo(multiSelect);
54113             }
54114         });
54115
54116         context.history().on('change.intro', function() {
54117             if (!washingtonSegmentId ||
54118                 !context.hasEntity(washingtonSegmentId) ||
54119                 !context.hasEntity(washingtonStreetId) ||
54120                 !context.hasEntity(twelfthAvenueId) ||
54121                 !context.hasEntity(eleventhAvenueEndId)) {
54122                 return continueTo(rightClickIntersection);
54123             }
54124         });
54125
54126         function continueTo(nextStep) {
54127             context.map().on('move.intro drawn.intro', null);
54128             context.on('enter.intro', null);
54129             context.history().on('change.intro', null);
54130             nextStep();
54131         }
54132     }
54133
54134
54135     function multiSelect() {
54136         if (!washingtonSegmentId ||
54137             !context.hasEntity(washingtonSegmentId) ||
54138             !context.hasEntity(washingtonStreetId) ||
54139             !context.hasEntity(twelfthAvenueId) ||
54140             !context.hasEntity(eleventhAvenueEndId)) {
54141             return continueTo(rightClickIntersection);
54142         }
54143
54144         var ids = context.selectedIDs();
54145         var hasWashington = ids.indexOf(washingtonSegmentId) !== -1;
54146         var hasTwelfth = ids.indexOf(twelfthAvenueId) !== -1;
54147
54148         if (hasWashington && hasTwelfth) {
54149             return continueTo(multiRightClick);
54150         } else if (!hasWashington && !hasTwelfth) {
54151             return continueTo(didSplit);
54152         }
54153
54154         context.map().zoom(18).centerEase(twelfthAvenue, 500);
54155
54156         timeout(function() {
54157             var selected, other, padding, box;
54158             if (hasWashington) {
54159                 selected = t('intro.graph.name.washington-street');
54160                 other = t('intro.graph.name.12th-avenue');
54161                 padding = 60 * Math.pow(2, context.map().zoom() - 18);
54162                 box = pad$1(twelfthAvenueEnd, padding, context);
54163                 box.width *= 3;
54164             } else {
54165                 selected = t('intro.graph.name.12th-avenue');
54166                 other = t('intro.graph.name.washington-street');
54167                 padding = 200 * Math.pow(2, context.map().zoom() - 18);
54168                 box = pad$1(twelfthAvenue, padding, context);
54169                 box.width /= 2;
54170             }
54171
54172             reveal(box,
54173                 t('intro.lines.multi_select', { selected: selected, other1: other, other2: other })
54174             );
54175
54176             context.map().on('move.intro drawn.intro', function() {
54177                 if (hasWashington) {
54178                     selected = t('intro.graph.name.washington-street');
54179                     other = t('intro.graph.name.12th-avenue');
54180                     padding = 60 * Math.pow(2, context.map().zoom() - 18);
54181                     box = pad$1(twelfthAvenueEnd, padding, context);
54182                     box.width *= 3;
54183                 } else {
54184                     selected = t('intro.graph.name.12th-avenue');
54185                     other = t('intro.graph.name.washington-street');
54186                     padding = 200 * Math.pow(2, context.map().zoom() - 18);
54187                     box = pad$1(twelfthAvenue, padding, context);
54188                     box.width /= 2;
54189                 }
54190
54191                 reveal(box,
54192                     t('intro.lines.multi_select', { selected: selected, other1: other, other2: other }),
54193                     { duration: 0 }
54194                 );
54195             });
54196
54197             context.on('enter.intro', function() {
54198                 continueTo(multiSelect);
54199             });
54200
54201             context.history().on('change.intro', function() {
54202                 if (!washingtonSegmentId ||
54203                     !context.hasEntity(washingtonSegmentId) ||
54204                     !context.hasEntity(washingtonStreetId) ||
54205                     !context.hasEntity(twelfthAvenueId) ||
54206                     !context.hasEntity(eleventhAvenueEndId)) {
54207                     return continueTo(rightClickIntersection);
54208                 }
54209             });
54210         }, 600);
54211
54212         function continueTo(nextStep) {
54213             context.map().on('move.intro drawn.intro', null);
54214             context.on('enter.intro', null);
54215             context.history().on('change.intro', null);
54216             nextStep();
54217         }
54218     }
54219
54220
54221     function multiRightClick() {
54222         if (!washingtonSegmentId ||
54223             !context.hasEntity(washingtonSegmentId) ||
54224             !context.hasEntity(washingtonStreetId) ||
54225             !context.hasEntity(twelfthAvenueId) ||
54226             !context.hasEntity(eleventhAvenueEndId)) {
54227             return continueTo(rightClickIntersection);
54228         }
54229
54230         var padding = 200 * Math.pow(2, context.map().zoom() - 18);
54231         var box = pad$1(twelfthAvenue, padding, context);
54232         reveal(box, t('intro.lines.multi_rightclick'));
54233
54234         context.map().on('move.intro drawn.intro', function() {
54235             var padding = 200 * Math.pow(2, context.map().zoom() - 18);
54236             var box = pad$1(twelfthAvenue, padding, context);
54237             reveal(box, t('intro.lines.multi_rightclick'), { duration: 0 });
54238         });
54239
54240         d3_select(window).on('click.intro contextmenu.intro', function() {
54241             timeout(function() {
54242                 var ids = context.selectedIDs();
54243                 if (ids.length === 2 &&
54244                     ids.indexOf(twelfthAvenueId) !== -1 &&
54245                     ids.indexOf(washingtonSegmentId) !== -1) {
54246                         var node = selectMenuItem('delete').node();
54247                         if (!node) return;
54248                         continueTo(multiDelete);
54249                 } else if (ids.length === 1 &&
54250                     ids.indexOf(washingtonSegmentId) !== -1) {
54251                     return continueTo(multiSelect);
54252                 } else {
54253                     return continueTo(didSplit);
54254                 }
54255             }, 300);  // after edit menu visible
54256         }, true);
54257
54258         context.history().on('change.intro', function() {
54259             if (!washingtonSegmentId ||
54260                 !context.hasEntity(washingtonSegmentId) ||
54261                 !context.hasEntity(washingtonStreetId) ||
54262                 !context.hasEntity(twelfthAvenueId) ||
54263                 !context.hasEntity(eleventhAvenueEndId)) {
54264                 return continueTo(rightClickIntersection);
54265             }
54266         });
54267
54268         function continueTo(nextStep) {
54269             context.map().on('move.intro drawn.intro', null);
54270             d3_select(window).on('click.intro contextmenu.intro', null, true);
54271             context.history().on('change.intro', null);
54272             nextStep();
54273         }
54274     }
54275
54276
54277     function multiDelete() {
54278         if (!washingtonSegmentId ||
54279             !context.hasEntity(washingtonSegmentId) ||
54280             !context.hasEntity(washingtonStreetId) ||
54281             !context.hasEntity(twelfthAvenueId) ||
54282             !context.hasEntity(eleventhAvenueEndId)) {
54283             return continueTo(rightClickIntersection);
54284         }
54285
54286         var node = selectMenuItem('delete').node();
54287         if (!node) return continueTo(multiRightClick);
54288
54289         var menuCoords = context.map().mouseCoordinates();
54290         revealEditMenu(menuCoords,
54291             t('intro.lines.multi_delete', { button: icon('#operation-delete', 'pre-text') })
54292         );
54293
54294         context.map().on('move.intro drawn.intro', function() {
54295             revealEditMenu(menuCoords,
54296                 t('intro.lines.multi_delete', { button: icon('#operation-delete', 'pre-text') }),
54297                 { duration: 0 }
54298             );
54299         });
54300
54301         context.on('exit.intro', function() {
54302             if (context.hasEntity(washingtonSegmentId) || context.hasEntity(twelfthAvenueId)) {
54303                 return continueTo(multiSelect);  // left select mode but roads still exist
54304             }
54305         });
54306
54307         context.history().on('change.intro', function() {
54308             if (context.hasEntity(washingtonSegmentId) || context.hasEntity(twelfthAvenueId)) {
54309                 continueTo(retryDelete);         // changed something but roads still exist
54310             } else {
54311                 continueTo(play);
54312             }
54313         });
54314
54315         function continueTo(nextStep) {
54316             context.map().on('move.intro drawn.intro', null);
54317             context.on('exit.intro', null);
54318             context.history().on('change.intro', null);
54319             nextStep();
54320         }
54321     }
54322
54323
54324     function retryDelete() {
54325         context.enter(modeBrowse(context));
54326
54327         var padding = 200 * Math.pow(2, context.map().zoom() - 18);
54328         var box = pad$1(twelfthAvenue, padding, context);
54329         reveal(box, t('intro.lines.retry_delete'), {
54330             buttonText: t('intro.ok'),
54331             buttonCallback: function() { continueTo(multiSelect); }
54332         });
54333
54334         function continueTo(nextStep) {
54335             nextStep();
54336         }
54337     }
54338
54339
54340     function play() {
54341         dispatch$$1.call('done');
54342         reveal('#id-container',
54343             t('intro.lines.play', { next: t('intro.buildings.title') }), {
54344                 tooltipBox: '.intro-nav-wrap .chapter-building',
54345                 buttonText: t('intro.ok'),
54346                 buttonCallback: function() { reveal('#id-container'); }
54347             }
54348         );
54349    }
54350
54351
54352     chapter.enter = function() {
54353         addLine();
54354     };
54355
54356
54357     chapter.exit = function() {
54358         timeouts.forEach(window.clearTimeout);
54359         d3_select(window).on('mousedown.intro', null, true);
54360         context.on('enter.intro exit.intro', null);
54361         context.map().on('move.intro drawn.intro', null);
54362         context.history().on('change.intro', null);
54363         d3_select('.inspector-wrap').on('wheel.intro', null);
54364         d3_select('.preset-list-button').on('click.intro', null);
54365     };
54366
54367
54368     chapter.restart = function() {
54369         chapter.exit();
54370         chapter.enter();
54371     };
54372
54373
54374     return utilRebind(chapter, dispatch$$1, 'on');
54375 }
54376
54377 function uiIntroBuilding(context, reveal) {
54378     var dispatch$$1 = dispatch('done'),
54379         house = [-85.62815, 41.95638],
54380         tank = [-85.62732, 41.95347],
54381         buildingCatetory = context.presets().item('category-building'),
54382         housePreset = context.presets().item('building/house'),
54383         tankPreset = context.presets().item('man_made/storage_tank'),
54384         timeouts = [],
54385         houseId = null,
54386         tankId = null;
54387
54388
54389     var chapter = {
54390         title: 'intro.buildings.title'
54391     };
54392
54393
54394     function timeout(f, t$$1) {
54395         timeouts.push(window.setTimeout(f, t$$1));
54396     }
54397
54398
54399     function eventCancel() {
54400         event.stopPropagation();
54401         event.preventDefault();
54402     }
54403
54404
54405     function revealHouse(center, text, options) {
54406         var padding = 160 * Math.pow(2, context.map().zoom() - 20);
54407         var box = pad$1(center, padding, context);
54408         reveal(box, text, options);
54409     }
54410
54411
54412     function revealTank(center, text, options) {
54413         var padding = 190 * Math.pow(2, context.map().zoom() - 19.5);
54414         var box = pad$1(center, padding, context);
54415         reveal(box, text, options);
54416     }
54417
54418
54419     function revealEditMenu(loc, text, options) {
54420         var rect = context.surfaceRect();
54421         var point = context.curtainProjection(loc);
54422         var pad = 40;
54423         var width = 250 + (2 * pad);
54424         var height = 350;
54425         var startX = rect.left + point[0];
54426         var left = (textDirection === 'rtl') ? (startX - width + pad) : (startX - pad);
54427         var box = {
54428             left: left,
54429             top: point[1] + rect.top - 60,
54430             width: width,
54431             height: height
54432         };
54433         reveal(box, text, options);
54434     }
54435
54436
54437     function addHouse() {
54438         context.enter(modeBrowse(context));
54439         context.history().reset('initial');
54440         houseId = null;
54441
54442         var msec = transitionTime(house, context.map().center());
54443         if (msec) { reveal(null, null, { duration: 0 }); }
54444         context.map().zoom(19).centerEase(house, msec);
54445
54446         timeout(function() {
54447             var tooltip = reveal('button.add-area',
54448                 t('intro.buildings.add_building', { button: icon('#icon-area', 'pre-text') }));
54449
54450             tooltip.selectAll('.tooltip-inner')
54451                 .insert('svg', 'span')
54452                 .attr('class', 'tooltip-illustration')
54453                 .append('use')
54454                 .attr('xlink:href', '#building-images');
54455
54456             context.on('enter.intro', function(mode) {
54457                 if (mode.id !== 'add-area') return;
54458                 continueTo(startHouse);
54459             });
54460         }, msec + 100);
54461
54462         function continueTo(nextStep) {
54463             context.on('enter.intro', null);
54464             nextStep();
54465         }
54466     }
54467
54468
54469     function startHouse() {
54470         if (context.mode().id !== 'add-area') {
54471             return continueTo(addHouse);
54472         }
54473
54474         houseId = null;
54475         context.map().zoomEase(20, 500);
54476
54477         timeout(function() {
54478             revealHouse(house, t('intro.buildings.start_building'));
54479
54480             context.map().on('move.intro drawn.intro', function() {
54481                 revealHouse(house, t('intro.buildings.start_building'), { duration: 0 });
54482             });
54483
54484             context.on('enter.intro', function(mode) {
54485                 if (mode.id !== 'draw-area') return chapter.restart();
54486                 continueTo(continueHouse);
54487             });
54488
54489         }, 550);  // after easing
54490
54491         function continueTo(nextStep) {
54492             context.map().on('move.intro drawn.intro', null);
54493             context.on('enter.intro', null);
54494             nextStep();
54495         }
54496     }
54497
54498
54499     function continueHouse() {
54500         if (context.mode().id !== 'draw-area') {
54501             return continueTo(addHouse);
54502         }
54503
54504         houseId = null;
54505
54506         revealHouse(house, t('intro.buildings.continue_building'));
54507
54508         context.map().on('move.intro drawn.intro', function() {
54509             revealHouse(house, t('intro.buildings.continue_building'), { duration: 0 });
54510         });
54511
54512         context.on('enter.intro', function(mode) {
54513             if (mode.id === 'draw-area') {
54514                 return;
54515             } else if (mode.id === 'select') {
54516                 var graph = context.graph(),
54517                     way = context.entity(context.selectedIDs()[0]),
54518                     nodes = graph.childNodes(way),
54519                     points = uniq(nodes).map(function(n) { return context.projection(n.loc); });
54520
54521                 if (isMostlySquare(points)) {
54522                     houseId = way.id;
54523                     return continueTo(chooseCategoryBuilding);
54524                 } else {
54525                     return continueTo(retryHouse);
54526                 }
54527
54528             } else {
54529                 return chapter.restart();
54530             }
54531         });
54532
54533         function continueTo(nextStep) {
54534             context.map().on('move.intro drawn.intro', null);
54535             context.on('enter.intro', null);
54536             nextStep();
54537         }
54538     }
54539
54540
54541     function retryHouse() {
54542         var onClick = function() { continueTo(addHouse); };
54543
54544         revealHouse(house, t('intro.buildings.retry_building'),
54545             { buttonText: t('intro.ok'), buttonCallback: onClick }
54546         );
54547
54548         context.map().on('move.intro drawn.intro', function() {
54549             revealHouse(house, t('intro.buildings.retry_building'),
54550                 { duration: 0, buttonText: t('intro.ok'), buttonCallback: onClick }
54551             );
54552         });
54553
54554         function continueTo(nextStep) {
54555             context.map().on('move.intro drawn.intro', null);
54556             nextStep();
54557         }
54558     }
54559
54560
54561     function chooseCategoryBuilding() {
54562         if (!houseId || !context.hasEntity(houseId)) {
54563             return addHouse();
54564         }
54565         var ids = context.selectedIDs();
54566         if (context.mode().id !== 'select' || !ids.length || ids[0] !== houseId) {
54567             context.enter(modeSelect(context, [houseId]));
54568         }
54569
54570         // disallow scrolling
54571         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
54572
54573         timeout(function() {
54574             // reset pane, in case user somehow happened to change it..
54575             d3_select('.inspector-wrap .panewrap').style('right', '-100%');
54576
54577             var button = d3_select('.preset-category-building .preset-list-button');
54578
54579             reveal(button.node(),
54580                 t('intro.buildings.choose_category_building', { category: buildingCatetory.name() })
54581             );
54582
54583             button.on('click.intro', function() {
54584                 button.on('click.intro', null);
54585                 continueTo(choosePresetHouse);
54586             });
54587
54588         }, 400);  // after preset list pane visible..
54589
54590
54591         context.on('enter.intro', function(mode) {
54592             if (!houseId || !context.hasEntity(houseId)) {
54593                 return continueTo(addHouse);
54594             }
54595             var ids = context.selectedIDs();
54596             if (mode.id !== 'select' || !ids.length || ids[0] !== houseId) {
54597                 return continueTo(chooseCategoryBuilding);
54598             }
54599         });
54600
54601         function continueTo(nextStep) {
54602             d3_select('.inspector-wrap').on('wheel.intro', null);
54603             d3_select('.preset-list-button').on('click.intro', null);
54604             context.on('enter.intro', null);
54605             nextStep();
54606         }
54607     }
54608
54609
54610     function choosePresetHouse() {
54611         if (!houseId || !context.hasEntity(houseId)) {
54612             return addHouse();
54613         }
54614         var ids = context.selectedIDs();
54615         if (context.mode().id !== 'select' || !ids.length || ids[0] !== houseId) {
54616             context.enter(modeSelect(context, [houseId]));
54617         }
54618
54619         // disallow scrolling
54620         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
54621
54622         timeout(function() {
54623             // reset pane, in case user somehow happened to change it..
54624             d3_select('.inspector-wrap .panewrap').style('right', '-100%');
54625
54626             var button = d3_select('.preset-building-house .preset-list-button');
54627
54628             reveal(button.node(),
54629                 t('intro.buildings.choose_preset_house', { preset: housePreset.name() }),
54630                 { duration: 300 }
54631             );
54632
54633             button.on('click.intro', function() {
54634                 button.on('click.intro', null);
54635                 continueTo(closeEditorHouse);
54636             });
54637
54638
54639         }, 400);  // after preset list pane visible..
54640
54641         context.on('enter.intro', function(mode) {
54642             if (!houseId || !context.hasEntity(houseId)) {
54643                 return continueTo(addHouse);
54644             }
54645             var ids = context.selectedIDs();
54646             if (mode.id !== 'select' || !ids.length || ids[0] !== houseId) {
54647                 return continueTo(chooseCategoryBuilding);
54648             }
54649         });
54650
54651         function continueTo(nextStep) {
54652             d3_select('.inspector-wrap').on('wheel.intro', null);
54653             d3_select('.preset-list-button').on('click.intro', null);
54654             context.on('enter.intro', null);
54655             nextStep();
54656         }
54657     }
54658
54659
54660     function closeEditorHouse() {
54661         if (!houseId || !context.hasEntity(houseId)) {
54662             return addHouse();
54663         }
54664         var ids = context.selectedIDs();
54665         if (context.mode().id !== 'select' || !ids.length || ids[0] !== houseId) {
54666             context.enter(modeSelect(context, [houseId]));
54667         }
54668
54669         context.history().checkpoint('hasHouse');
54670
54671         context.on('exit.intro', function() {
54672             continueTo(rightClickHouse);
54673         });
54674
54675         timeout(function() {
54676             reveal('.entity-editor-pane',
54677                 t('intro.buildings.close', { button: icon('#icon-apply', 'pre-text') })
54678             );
54679         }, 500);
54680
54681         function continueTo(nextStep) {
54682             context.on('exit.intro', null);
54683             nextStep();
54684         }
54685     }
54686
54687
54688     function rightClickHouse() {
54689         if (!houseId) return chapter.restart();
54690
54691         context.enter(modeBrowse(context));
54692         context.history().reset('hasHouse');
54693         context.map().centerEase(house, 500);
54694
54695         timeout(function() {
54696             if (context.map().zoom() < 20) {
54697                 context.map().zoomEase(20, 500);
54698             }
54699         }, 520);
54700
54701         context.on('enter.intro', function(mode) {
54702             if (mode.id !== 'select') return;
54703             var ids = context.selectedIDs();
54704             if (ids.length !== 1 || ids[0] !== houseId) return;
54705
54706             timeout(function() {
54707                 var node = selectMenuItem('orthogonalize').node();
54708                 if (!node) return;
54709                 continueTo(clickSquare);
54710             }, 300);  // after menu visible
54711         });
54712
54713         context.map().on('move.intro drawn.intro', function() {
54714             revealHouse(house, t('intro.buildings.rightclick_building'), { duration: 0 });
54715         });
54716
54717         context.history().on('change.intro', function() {
54718             continueTo(rightClickHouse);
54719         });
54720
54721         function continueTo(nextStep) {
54722             context.on('enter.intro', null);
54723             context.map().on('move.intro drawn.intro', null);
54724             context.history().on('change.intro', null);
54725             nextStep();
54726         }
54727     }
54728
54729
54730     function clickSquare() {
54731         if (!houseId) return chapter.restart();
54732         var entity = context.hasEntity(houseId);
54733         if (!entity) return continueTo(rightClickHouse);
54734
54735         var node = selectMenuItem('orthogonalize').node();
54736         if (!node) { return continueTo(rightClickHouse); }
54737
54738         var wasChanged = false;
54739         var menuCoords = context.map().mouseCoordinates();
54740
54741         revealEditMenu(menuCoords,
54742             t('intro.buildings.square_building', { button: icon('#operation-orthogonalize', 'pre-text') })
54743         );
54744
54745         context.on('enter.intro', function(mode) {
54746             if (mode.id === 'browse') {
54747                 continueTo(rightClickHouse);
54748             } else if (mode.id === 'move' || mode.id === 'rotate') {
54749                 continueTo(retryClickSquare);
54750             }
54751         });
54752
54753         context.map().on('move.intro drawn.intro', function() {
54754             var node = selectMenuItem('orthogonalize').node();
54755             if (!wasChanged && !node) { return continueTo(rightClickHouse); }
54756
54757             revealEditMenu(menuCoords,
54758                 t('intro.buildings.square_building', { button: icon('#operation-orthogonalize', 'pre-text') }),
54759                 { duration: 0 }
54760             );
54761         });
54762
54763         context.history().on('change.intro', function() {
54764             wasChanged = true;
54765             context.history().on('change.intro', null);
54766
54767             // Something changed.  Wait for transition to complete and check undo annotation.
54768             timeout(function() {
54769                 if (context.history().undoAnnotation() === t('operations.orthogonalize.annotation.area')) {
54770                     continueTo(doneSquare);
54771                 } else {
54772                     continueTo(retryClickSquare);
54773                 }
54774             }, 500);  // after transitioned actions
54775         });
54776
54777         function continueTo(nextStep) {
54778             context.on('enter.intro', null);
54779             context.map().on('move.intro drawn.intro', null);
54780             context.history().on('change.intro', null);
54781             nextStep();
54782         }
54783     }
54784
54785
54786     function retryClickSquare() {
54787         context.enter(modeBrowse(context));
54788
54789         revealHouse(house, t('intro.buildings.retry_square'), {
54790             buttonText: t('intro.ok'),
54791             buttonCallback: function() { continueTo(rightClickHouse); }
54792         });
54793
54794         function continueTo(nextStep) {
54795             nextStep();
54796         }
54797     }
54798
54799
54800     function doneSquare() {
54801         context.history().checkpoint('doneSquare');
54802
54803         revealHouse(house, t('intro.buildings.done_square'), {
54804             buttonText: t('intro.ok'),
54805             buttonCallback: function() { continueTo(addTank); }
54806         });
54807
54808         function continueTo(nextStep) {
54809             nextStep();
54810         }
54811     }
54812
54813
54814     function addTank() {
54815         context.enter(modeBrowse(context));
54816         context.history().reset('doneSquare');
54817         tankId = null;
54818
54819         var msec = transitionTime(tank, context.map().center());
54820         if (msec) { reveal(null, null, { duration: 0 }); }
54821         context.map().zoom(19.5).centerEase(tank, msec);
54822
54823         timeout(function() {
54824             reveal('button.add-area',
54825                 t('intro.buildings.add_tank', { button: icon('#icon-area', 'pre-text') })
54826             );
54827
54828             context.on('enter.intro', function(mode) {
54829                 if (mode.id !== 'add-area') return;
54830                 continueTo(startTank);
54831             });
54832         }, msec + 100);
54833
54834         function continueTo(nextStep) {
54835             context.on('enter.intro', null);
54836             nextStep();
54837         }
54838     }
54839
54840
54841     function startTank() {
54842         if (context.mode().id !== 'add-area') {
54843             return continueTo(addTank);
54844         }
54845
54846         tankId = null;
54847
54848         timeout(function() {
54849             revealTank(tank, t('intro.buildings.start_tank'));
54850
54851             context.map().on('move.intro drawn.intro', function() {
54852                 revealTank(tank, t('intro.buildings.start_tank'), { duration: 0 });
54853             });
54854
54855             context.on('enter.intro', function(mode) {
54856                 if (mode.id !== 'draw-area') return chapter.restart();
54857                 continueTo(continueTank);
54858             });
54859
54860         }, 550);  // after easing
54861
54862         function continueTo(nextStep) {
54863             context.map().on('move.intro drawn.intro', null);
54864             context.on('enter.intro', null);
54865             nextStep();
54866         }
54867     }
54868
54869
54870     function continueTank() {
54871         if (context.mode().id !== 'draw-area') {
54872             return continueTo(addTank);
54873         }
54874
54875         tankId = null;
54876
54877         revealTank(tank, t('intro.buildings.continue_tank'));
54878
54879         context.map().on('move.intro drawn.intro', function() {
54880             revealTank(tank, t('intro.buildings.continue_tank'), { duration: 0 });
54881         });
54882
54883         context.on('enter.intro', function(mode) {
54884             if (mode.id === 'draw-area') {
54885                 return;
54886             } else if (mode.id === 'select') {
54887                 tankId = context.selectedIDs()[0];
54888                 return continueTo(searchPresetTank);
54889             } else {
54890                 return continueTo(addTank);
54891             }
54892         });
54893
54894         function continueTo(nextStep) {
54895             context.map().on('move.intro drawn.intro', null);
54896             context.on('enter.intro', null);
54897             nextStep();
54898         }
54899     }
54900
54901
54902     function searchPresetTank() {
54903         if (!tankId || !context.hasEntity(tankId)) {
54904             return addTank();
54905         }
54906         var ids = context.selectedIDs();
54907         if (context.mode().id !== 'select' || !ids.length || ids[0] !== tankId) {
54908             context.enter(modeSelect(context, [tankId]));
54909         }
54910
54911         // disallow scrolling
54912         d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
54913
54914         timeout(function() {
54915             // reset pane, in case user somehow happened to change it..
54916             d3_select('.inspector-wrap .panewrap').style('right', '-100%');
54917
54918             d3_select('.preset-search-input')
54919                 .on('keydown.intro', null)
54920                 .on('keyup.intro', checkPresetSearch);
54921
54922             reveal('.preset-search-input',
54923                 t('intro.buildings.search_tank', { preset: tankPreset.name() })
54924             );
54925         }, 400);  // after preset list pane visible..
54926
54927         context.on('enter.intro', function(mode) {
54928             if (!tankId || !context.hasEntity(tankId)) {
54929                 return continueTo(addTank);
54930             }
54931
54932             var ids = context.selectedIDs();
54933             if (mode.id !== 'select' || !ids.length || ids[0] !== tankId) {
54934                 // keep the user's area selected..
54935                 context.enter(modeSelect(context, [tankId]));
54936
54937                 // reset pane, in case user somehow happened to change it..
54938                 d3_select('.inspector-wrap .panewrap').style('right', '-100%');
54939                 // disallow scrolling
54940                 d3_select('.inspector-wrap').on('wheel.intro', eventCancel);
54941
54942                 d3_select('.preset-search-input')
54943                     .on('keydown.intro', null)
54944                     .on('keyup.intro', checkPresetSearch);
54945
54946                 reveal('.preset-search-input',
54947                     t('intro.buildings.search_tank', { preset: tankPreset.name() })
54948                 );
54949
54950                 context.history().on('change.intro', null);
54951             }
54952         });
54953
54954         function checkPresetSearch() {
54955             var first = d3_select('.preset-list-item:first-child');
54956
54957             if (first.classed('preset-man_made-storage_tank')) {
54958                 reveal(first.select('.preset-list-button').node(),
54959                     t('intro.buildings.choose_tank', { preset: tankPreset.name() }),
54960                     { duration: 300 }
54961                 );
54962
54963                 d3_select('.preset-search-input')
54964                     .on('keydown.intro', eventCancel, true)
54965                     .on('keyup.intro', null);
54966
54967                 context.history().on('change.intro', function() {
54968                     continueTo(closeEditorTank);
54969                 });
54970             }
54971         }
54972
54973         function continueTo(nextStep) {
54974             d3_select('.inspector-wrap').on('wheel.intro', null);
54975             context.on('enter.intro', null);
54976             context.history().on('change.intro', null);
54977             d3_select('.preset-search-input').on('keydown.intro keyup.intro', null);
54978             nextStep();
54979         }
54980     }
54981
54982
54983     function closeEditorTank() {
54984         if (!tankId || !context.hasEntity(tankId)) {
54985             return addTank();
54986         }
54987         var ids = context.selectedIDs();
54988         if (context.mode().id !== 'select' || !ids.length || ids[0] !== tankId) {
54989             context.enter(modeSelect(context, [tankId]));
54990         }
54991
54992         context.history().checkpoint('hasTank');
54993
54994         context.on('exit.intro', function() {
54995             continueTo(rightClickTank);
54996         });
54997
54998         timeout(function() {
54999             reveal('.entity-editor-pane',
55000                 t('intro.buildings.close', { button: icon('#icon-apply', 'pre-text') })
55001             );
55002         }, 500);
55003
55004         function continueTo(nextStep) {
55005             context.on('exit.intro', null);
55006             nextStep();
55007         }
55008     }
55009
55010
55011     function rightClickTank() {
55012         if (!tankId) return continueTo(addTank);
55013
55014         context.enter(modeBrowse(context));
55015         context.history().reset('hasTank');
55016         context.map().centerEase(tank, 500);
55017
55018         timeout(function() {
55019             context.on('enter.intro', function(mode) {
55020                 if (mode.id !== 'select') return;
55021                 var ids = context.selectedIDs();
55022                 if (ids.length !== 1 || ids[0] !== tankId) return;
55023
55024                 timeout(function() {
55025                     var node = selectMenuItem('circularize').node();
55026                     if (!node) return;
55027                     continueTo(clickCircle);
55028                 }, 300);  // after menu visible
55029             });
55030
55031             revealTank(tank, t('intro.buildings.rightclick_tank'));
55032
55033             context.map().on('move.intro drawn.intro', function() {
55034                 revealTank(tank, t('intro.buildings.rightclick_tank'), { duration: 0 });
55035             });
55036
55037             context.history().on('change.intro', function() {
55038                 continueTo(rightClickTank);
55039             });
55040
55041         }, 600);
55042
55043         function continueTo(nextStep) {
55044             context.on('enter.intro', null);
55045             context.map().on('move.intro drawn.intro', null);
55046             context.history().on('change.intro', null);
55047             nextStep();
55048         }
55049     }
55050
55051
55052     function clickCircle() {
55053         if (!tankId) return chapter.restart();
55054         var entity = context.hasEntity(tankId);
55055         if (!entity) return continueTo(rightClickTank);
55056
55057         var node = selectMenuItem('circularize').node();
55058         if (!node) { return continueTo(rightClickTank); }
55059
55060         var wasChanged = false;
55061         var menuCoords = context.map().mouseCoordinates();
55062
55063         revealEditMenu(menuCoords,
55064             t('intro.buildings.circle_tank', { button: icon('#operation-circularize', 'pre-text') })
55065         );
55066
55067         context.on('enter.intro', function(mode) {
55068             if (mode.id === 'browse') {
55069                 continueTo(rightClickTank);
55070             } else if (mode.id === 'move' || mode.id === 'rotate') {
55071                 continueTo(retryClickCircle);
55072             }
55073         });
55074
55075         context.map().on('move.intro drawn.intro', function() {
55076             var node = selectMenuItem('circularize').node();
55077             if (!wasChanged && !node) { return continueTo(rightClickTank); }
55078
55079             revealEditMenu(menuCoords,
55080                 t('intro.buildings.circle_tank', { button: icon('#operation-circularize', 'pre-text') }),
55081                 { duration: 0 }
55082             );
55083         });
55084
55085         context.history().on('change.intro', function() {
55086             wasChanged = true;
55087             context.history().on('change.intro', null);
55088
55089             // Something changed.  Wait for transition to complete and check undo annotation.
55090             timeout(function() {
55091                 if (context.history().undoAnnotation() === t('operations.circularize.annotation.area')) {
55092                     continueTo(play);
55093                 } else {
55094                     continueTo(retryClickCircle);
55095                 }
55096             }, 500);  // after transitioned actions
55097         });
55098
55099         function continueTo(nextStep) {
55100             context.on('enter.intro', null);
55101             context.map().on('move.intro drawn.intro', null);
55102             context.history().on('change.intro', null);
55103             nextStep();
55104         }
55105     }
55106
55107
55108     function retryClickCircle() {
55109         context.enter(modeBrowse(context));
55110
55111         revealTank(tank, t('intro.buildings.retry_circle'), {
55112             buttonText: t('intro.ok'),
55113             buttonCallback: function() { continueTo(rightClickTank); }
55114         });
55115
55116         function continueTo(nextStep) {
55117             nextStep();
55118         }
55119     }
55120
55121
55122     function play() {
55123         dispatch$$1.call('done');
55124         reveal('#id-container',
55125             t('intro.buildings.play', { next: t('intro.startediting.title') }), {
55126                 tooltipBox: '.intro-nav-wrap .chapter-startEditing',
55127                 buttonText: t('intro.ok'),
55128                 buttonCallback: function() { reveal('#id-container'); }
55129             }
55130         );
55131     }
55132
55133
55134     chapter.enter = function() {
55135         addHouse();
55136     };
55137
55138
55139     chapter.exit = function() {
55140         timeouts.forEach(window.clearTimeout);
55141         context.on('enter.intro exit.intro', null);
55142         context.map().on('move.intro drawn.intro', null);
55143         context.history().on('change.intro', null);
55144         d3_select('.inspector-wrap').on('wheel.intro', null);
55145         d3_select('.preset-search-input').on('keydown.intro keyup.intro', null);
55146         d3_select('.more-fields .combobox-input').on('click.intro', null);
55147     };
55148
55149
55150     chapter.restart = function() {
55151         chapter.exit();
55152         chapter.enter();
55153     };
55154
55155
55156     return utilRebind(chapter, dispatch$$1, 'on');
55157 }
55158
55159 function uiIntroStartEditing(context, reveal) {
55160     var dispatch$$1 = dispatch('done', 'startEditing'),
55161         modalSelection = d3_select(null);
55162
55163
55164     var chapter = {
55165         title: 'intro.startediting.title'
55166     };
55167
55168     function showHelp() {
55169         reveal('.map-control.help-control',
55170             t('intro.startediting.help', { button: icon('#icon-help', 'pre-text'), key: t('help.key') }), {
55171                 buttonText: t('intro.ok'),
55172                 buttonCallback: function() { shortcuts(); }
55173             }
55174         );
55175     }
55176
55177     function shortcuts() {
55178         reveal('.map-control.help-control',
55179             t('intro.startediting.shortcuts', { key: t('shortcuts.toggle.key') }), {
55180                 buttonText: t('intro.ok'),
55181                 buttonCallback: function() { showSave(); }
55182             }
55183         );
55184     }
55185
55186     function showSave() {
55187         d3_selectAll('.shaded').remove();  // in case user opened keyboard shortcuts
55188         reveal('#bar button.save',
55189             t('intro.startediting.save'), {
55190                 buttonText: t('intro.ok'),
55191                 buttonCallback: function() { showStart(); }
55192             }
55193         );
55194     }
55195
55196     function showStart() {
55197         d3_selectAll('.shaded').remove();  // in case user opened keyboard shortcuts
55198
55199         modalSelection = uiModal(context.container());
55200
55201         modalSelection.select('.modal')
55202             .attr('class', 'modal-splash modal col6');
55203
55204         modalSelection.selectAll('.close').remove();
55205
55206         var startbutton = modalSelection.select('.content')
55207             .attr('class', 'fillL')
55208             .append('button')
55209                 .attr('class', 'modal-section huge-modal-button')
55210                 .on('click', function() {
55211                     modalSelection.remove();
55212                 });
55213
55214             startbutton
55215                 .append('svg')
55216                 .attr('class', 'illustration')
55217                 .append('use')
55218                 .attr('xlink:href', '#logo-walkthrough');
55219
55220             startbutton
55221                 .append('h2')
55222                 .text(t('intro.startediting.start'));
55223
55224         dispatch$$1.call('startEditing');
55225     }
55226
55227
55228     chapter.enter = function() {
55229         showHelp();
55230     };
55231
55232
55233     chapter.exit = function() {
55234         modalSelection.remove();
55235         d3_selectAll('.shaded').remove();  // in case user opened keyboard shortcuts
55236     };
55237
55238
55239     return utilRebind(chapter, dispatch$$1, 'on');
55240 }
55241
55242 var chapterUi = {
55243     welcome: uiIntroWelcome,
55244     navigation: uiIntroNavigation,
55245     point: uiIntroPoint,
55246     area: uiIntroArea,
55247     line: uiIntroLine,
55248     building: uiIntroBuilding,
55249     startEditing: uiIntroStartEditing
55250 };
55251
55252 var chapterFlow = [
55253     'welcome',
55254     'navigation',
55255     'point',
55256     'area',
55257     'line',
55258     'building',
55259     'startEditing'
55260 ];
55261
55262
55263 function uiIntro(context) {
55264     var introGraph = {},
55265         currChapter;
55266
55267
55268     // create entities for intro graph and localize names
55269     for (var id in dataIntroGraph) {
55270         introGraph[id] = osmEntity(localize(dataIntroGraph[id]));
55271     }
55272
55273
55274     function intro(selection) {
55275         context.enter(modeBrowse(context));
55276
55277         // Save current map state
55278         var osm = context.connection(),
55279             history = context.history().toJSON(),
55280             hash = window.location.hash,
55281             center = context.map().center(),
55282             zoom = context.map().zoom(),
55283             background = context.background().baseLayerSource(),
55284             overlays = context.background().overlayLayerSources(),
55285             opacity = d3_selectAll('#map .layer-background').style('opacity'),
55286             loadedTiles = osm && osm.loadedTiles(),
55287             baseEntities = context.history().graph().base().entities,
55288             countryCode = services.geocoder.countryCode;
55289
55290         // Block saving
55291         context.inIntro(true);
55292
55293         // Load semi-real data used in intro
55294         if (osm) { osm.toggle(false).reset(); }
55295         context.history().reset();
55296         context.history().merge(values$1(coreGraph().load(introGraph).entities));
55297         context.history().checkpoint('initial');
55298
55299         var esri = context.background().findSource('EsriWorldImagery');
55300         if (esri) {
55301             context.background().baseLayerSource(esri);
55302         } else {
55303             context.background().bing();
55304         }
55305         overlays.forEach(function (d) {
55306             context.background().toggleOverlayLayer(d);
55307         });
55308
55309         // Mock geocoder
55310         services.geocoder.countryCode = function(location, callback) {
55311             callback(null, t('intro.graph.countrycode'));
55312         };
55313
55314         d3_selectAll('#map .layer-background').style('opacity', 1);
55315
55316         var curtain = uiCurtain();
55317         selection.call(curtain);
55318
55319         // store that the user started the walkthrough..
55320         context.storage('walkthrough_started', 'yes');
55321
55322         // restore previous walkthrough progress..
55323         var storedProgress = context.storage('walkthrough_progress') || '';
55324         var progress = storedProgress.split(';').filter(Boolean);
55325
55326         var chapters = chapterFlow.map(function(chapter, i) {
55327             var s = chapterUi[chapter](context, curtain.reveal)
55328                 .on('done', function() {
55329                     context.presets().init();  // clear away "recent" presets
55330
55331                     buttons.filter(function(d) {
55332                         return d.title === s.title;
55333                     }).classed('finished', true);
55334
55335                     if (i < chapterFlow.length - 1) {
55336                         var next = chapterFlow[i + 1];
55337                         d3_select('button.chapter-' + next)
55338                             .classed('next', true);
55339                     }
55340
55341                     // store walkthrough progress..
55342                     progress.push(chapter);
55343                     context.storage('walkthrough_progress', uniq(progress).join(';'));
55344                 });
55345             return s;
55346         });
55347
55348         chapters[chapters.length - 1].on('startEditing', function() {
55349             // store walkthrough progress..
55350             progress.push('startEditing');
55351             context.storage('walkthrough_progress', uniq(progress).join(';'));
55352
55353             // store if walkthrough is completed..
55354             var incomplete = difference(chapterFlow, progress);
55355             if (!incomplete.length) {
55356                 context.storage('walkthrough_completed', 'yes');
55357             }
55358
55359             curtain.remove();
55360             navwrap.remove();
55361             d3_selectAll('#map .layer-background').style('opacity', opacity);
55362             if (osm) { osm.toggle(true).reset().loadedTiles(loadedTiles); }
55363             context.history().reset().merge(values$1(baseEntities));
55364             context.background().baseLayerSource(background);
55365             overlays.forEach(function (d) { context.background().toggleOverlayLayer(d); });
55366             if (history) { context.history().fromJSON(history, false); }
55367             context.map().centerZoom(center, zoom);
55368             window.location.replace(hash);
55369             services.geocoder.countryCode = countryCode;
55370             context.inIntro(false);
55371         });
55372
55373         var navwrap = selection
55374             .append('div')
55375             .attr('class', 'intro-nav-wrap fillD');
55376
55377         navwrap
55378             .append('svg')
55379             .attr('class', 'intro-nav-wrap-logo')
55380             .append('use')
55381             .attr('xlink:href', '#logo-walkthrough');
55382
55383         var buttonwrap = navwrap
55384             .append('div')
55385             .attr('class', 'joined')
55386             .selectAll('button.chapter');
55387
55388         var buttons = buttonwrap
55389             .data(chapters)
55390             .enter()
55391             .append('button')
55392             .attr('class', function(d, i) { return 'chapter chapter-' + chapterFlow[i]; })
55393             .on('click', enterChapter);
55394
55395         buttons
55396             .append('span')
55397             .text(function(d) { return t(d.title); });
55398
55399         buttons
55400             .append('span')
55401             .attr('class', 'status')
55402             .call(svgIcon((textDirection === 'rtl' ? '#icon-backward' : '#icon-forward'), 'inline'));
55403
55404         enterChapter(chapters[0]);
55405
55406
55407         function enterChapter(newChapter) {
55408             if (currChapter) { currChapter.exit(); }
55409             context.enter(modeBrowse(context));
55410
55411             currChapter = newChapter;
55412             currChapter.enter();
55413
55414             buttons
55415                 .classed('next', false)
55416                 .classed('active', function(d) {
55417                     return d.title === currChapter.title;
55418                 });
55419         }
55420     }
55421
55422
55423     return intro;
55424 }
55425
55426 function uiShortcuts() {
55427     var detected = utilDetect();
55428     var activeTab = 0;
55429     var modalSelection;
55430     var savedSelection;
55431
55432
55433     var keybinding = d3keybinding('shortcuts')
55434         .on(t('shortcuts.toggle.key'), function () {
55435             if (d3_selectAll('.modal-shortcuts').size()) {  // already showing
55436                 if (modalSelection) {
55437                     modalSelection.close();
55438                     modalSelection = null;
55439                 }
55440             } else {
55441                 modalSelection = uiModal(savedSelection);
55442                 shortcutsModal(modalSelection);
55443             }
55444         });
55445
55446     d3_select(document)
55447         .call(keybinding);
55448
55449
55450
55451     function shortcutsModal(modalSelection) {
55452         modalSelection.select('.modal')
55453             .classed('modal-shortcuts', true);
55454
55455         var shortcutsModal = modalSelection.select('.content');
55456
55457         shortcutsModal
55458             .append('div')
55459             .attr('class', 'modal-section')
55460             .append('h3')
55461             .text(t('shortcuts.title'));
55462
55463         shortcutsModal
55464             .call(render);
55465     }
55466
55467
55468     function render(selection) {
55469         var wrapper = selection
55470             .selectAll('.wrapper')
55471             .data([0]);
55472
55473         var wrapperEnter = wrapper
55474             .enter()
55475             .append('div')
55476             .attr('class', 'wrapper modal-section');
55477
55478         var tabsBar = wrapperEnter
55479             .append('div')
55480             .attr('class', 'tabs-bar');
55481
55482         var shortcutsList = wrapperEnter
55483             .append('div')
55484             .attr('class', 'shortcuts-list');
55485
55486         wrapper = wrapper.merge(wrapperEnter);
55487
55488         var tabs = tabsBar
55489             .selectAll('.tab')
55490             .data(dataShortcuts);
55491
55492         var tabsEnter = tabs
55493             .enter()
55494             .append('div')
55495             .attr('class', 'tab')
55496             .on('click', function (d, i) {
55497                 activeTab = i;
55498                 render(selection);
55499             });
55500
55501         tabsEnter
55502             .append('span')
55503             .text(function (d) { return t(d.text); });
55504
55505         tabs = tabs
55506             .merge(tabsEnter);
55507
55508         // Update
55509         wrapper.selectAll('.tab')
55510             .classed('active', function (d, i) {
55511                 return i === activeTab;
55512             });
55513
55514
55515         var shortcuts = shortcutsList
55516             .selectAll('.shortcut-tab')
55517             .data(dataShortcuts);
55518
55519         var shortcutsEnter = shortcuts
55520             .enter()
55521             .append('div')
55522             .attr('class', function(d) { return 'shortcut-tab shortcut-tab-' + d.tab; });
55523
55524         var columnsEnter = shortcutsEnter
55525             .selectAll('.shortcut-column')
55526             .data(function (d) { return d.columns; })
55527             .enter()
55528             .append('table')
55529             .attr('class', 'shortcut-column');
55530
55531         var rowsEnter = columnsEnter
55532             .selectAll('.shortcut-row')
55533             .data(function (d) { return d.rows; })
55534             .enter()
55535             .append('tr')
55536             .attr('class', 'shortcut-row');
55537
55538
55539         var sectionRows = rowsEnter
55540             .filter(function (d) { return !d.shortcuts; });
55541
55542         sectionRows
55543             .append('td');
55544
55545         sectionRows
55546             .append('td')
55547             .attr('class', 'shortcut-section')
55548             .append('h3')
55549             .text(function (d) { return t(d.text); });
55550
55551
55552         var shortcutRows = rowsEnter
55553             .filter(function (d) { return d.shortcuts; });
55554
55555         var shortcutKeys = shortcutRows
55556             .append('td')
55557             .attr('class', 'shortcut-keys');
55558
55559         var modifierKeys = shortcutKeys
55560             .filter(function (d) { return d.modifiers; });
55561
55562         modifierKeys
55563             .selectAll('kbd.modifier')
55564             .data(function (d) {
55565                 if (detected.os === 'win' && d.text === 'shortcuts.editing.commands.redo') {
55566                     return ['⌘'];
55567                 } else if (detected.os !== 'mac' && d.text === 'shortcuts.browsing.display_options.fullscreen') {
55568                     return [];
55569                 } else {
55570                     return d.modifiers;
55571                 }
55572             })
55573             .enter()
55574             .each(function () {
55575                 var selection = d3_select(this);
55576
55577                 selection
55578                     .append('kbd')
55579                     .attr('class', 'modifier')
55580                     .text(function (d) { return uiCmd.display(d); });
55581
55582                 selection
55583                     .append('span')
55584                     .text('+');
55585             });
55586
55587
55588         shortcutKeys
55589             .selectAll('kbd.shortcut')
55590             .data(function (d) {
55591                 var arr = d.shortcuts;
55592                 if (detected.os === 'win' && d.text === 'shortcuts.editing.commands.redo') {
55593                     arr = ['Y'];
55594                 } else if (detected.os !== 'mac' && d.text === 'shortcuts.browsing.display_options.fullscreen') {
55595                     arr = ['F11'];
55596                 }
55597
55598                 return arr.map(function(s) {
55599                     return {
55600                         shortcut: s,
55601                         separator: d.separator
55602                     };
55603                 });
55604             })
55605             .enter()
55606             .each(function (d, i, nodes) {
55607                 var selection = d3_select(this);
55608                 var click = d.shortcut.toLowerCase().match(/(.*).click/);
55609
55610                 if (click && click[1]) {
55611                     selection
55612                         .call(svgIcon('#walkthrough-mouse', 'mouseclick', click[1]));
55613                 } else {
55614                     selection
55615                         .append('kbd')
55616                         .attr('class', 'shortcut')
55617                         .text(function (d) {
55618                             var key = d.shortcut;
55619                             return key.indexOf('.') !== -1 ? uiCmd.display(t(key)) : uiCmd.display(key);
55620                         });
55621                 }
55622
55623                 if (i < nodes.length - 1) {
55624                     selection
55625                         .append('span')
55626                         .text(d.separator || '\u00a0' + t('shortcuts.or') + '\u00a0');
55627                 }
55628             });
55629
55630
55631         shortcutKeys
55632             .filter(function(d) { return d.gesture; })
55633             .each(function () {
55634                 var selection = d3_select(this);
55635
55636                 selection
55637                     .append('span')
55638                     .text('+');
55639
55640                 selection
55641                     .append('span')
55642                     .attr('class', 'gesture')
55643                     .text(function (d) { return t(d.gesture); });
55644             });
55645
55646
55647         shortcutRows
55648             .append('td')
55649             .attr('class', 'shortcut-desc')
55650             .text(function (d) { return d.text ? t(d.text) : '\u00a0'; });
55651
55652
55653         shortcuts = shortcuts
55654             .merge(shortcutsEnter);
55655
55656         // Update
55657         wrapper.selectAll('.shortcut-tab')
55658             .style('display', function (d, i) {
55659                 return i === activeTab ? 'flex' : 'none';
55660             });
55661     }
55662
55663
55664     return function(selection, show) {
55665         savedSelection = selection;
55666         if (show) {
55667             modalSelection = uiModal(selection);
55668             shortcutsModal(modalSelection);
55669         }
55670     };
55671 }
55672
55673 function uiHelp(context) {
55674     var key = t('help.key');
55675
55676     var docKeys = [
55677         'help.help',
55678         'help.editing_saving',
55679         'help.roads',
55680         'help.gps',
55681         'help.imagery',
55682         'help.addresses',
55683         'help.inspector',
55684         'help.buildings',
55685         'help.relations'];
55686
55687     var docs = docKeys.map(function(key) {
55688         var text = t(key);
55689         return {
55690             title: text.split('\n')[0].replace('#', '').trim(),
55691             html: marked(text.split('\n').slice(1).join('\n'))
55692         };
55693     });
55694
55695
55696     function help(selection) {
55697
55698         function hide() {
55699             setVisible(false);
55700         }
55701
55702
55703         function toggle() {
55704             if (event) event.preventDefault();
55705             tooltipBehavior.hide(button);
55706             setVisible(!button.classed('active'));
55707         }
55708
55709
55710         function setVisible(show) {
55711             if (show !== shown) {
55712                 button.classed('active', show);
55713                 shown = show;
55714
55715                 if (show) {
55716                     selection.on('mousedown.help-inside', function() {
55717                         return event.stopPropagation();
55718                     });
55719                     pane.style('display', 'block')
55720                         .style('right', '-500px')
55721                         .transition()
55722                         .duration(200)
55723                         .style('right', '0px');
55724                 } else {
55725                     pane.style('right', '0px')
55726                         .transition()
55727                         .duration(200)
55728                         .style('right', '-500px')
55729                         .on('end', function() {
55730                             d3_select(this).style('display', 'none');
55731                         });
55732                     selection.on('mousedown.help-inside', null);
55733                 }
55734             }
55735         }
55736
55737
55738         function clickHelp(d, i) {
55739             var rtl = (textDirection === 'rtl');
55740             pane.property('scrollTop', 0);
55741             doctitle.html(d.title);
55742
55743             body.html(d.html);
55744             body.selectAll('a')
55745                 .attr('target', '_blank');
55746             menuItems.classed('selected', function(m) {
55747                 return m.title === d.title;
55748             });
55749
55750             nav.html('');
55751             if (rtl) {
55752                 nav.call(drawNext).call(drawPrevious);
55753             } else {
55754                 nav.call(drawPrevious).call(drawNext);
55755             }
55756
55757
55758             function drawNext(selection) {
55759                 if (i < docs.length - 1) {
55760                     var nextLink = selection
55761                         .append('a')
55762                         .attr('class', 'next')
55763                         .on('click', function() {
55764                             clickHelp(docs[i + 1], i + 1);
55765                         });
55766
55767                     nextLink
55768                         .append('span')
55769                         .text(docs[i + 1].title)
55770                         .call(svgIcon((rtl ? '#icon-backward' : '#icon-forward'), 'inline'));
55771                 }
55772             }
55773
55774
55775             function drawPrevious(selection) {
55776                 if (i > 0) {
55777                     var prevLink = selection
55778                         .append('a')
55779                         .attr('class', 'previous')
55780                         .on('click', function() {
55781                             clickHelp(docs[i - 1], i - 1);
55782                         });
55783
55784                     prevLink
55785                         .call(svgIcon((rtl ? '#icon-forward' : '#icon-backward'), 'inline'))
55786                         .append('span')
55787                         .text(docs[i - 1].title);
55788                 }
55789             }
55790         }
55791
55792
55793         function clickWalkthrough() {
55794             if (context.inIntro()) return;
55795             context.container().call(uiIntro(context));
55796             setVisible(false);
55797         }
55798
55799
55800         function clickShortcuts() {
55801             context.container().call(uiShortcuts(context), true);
55802         }
55803
55804
55805         var pane = selection.append('div')
55806                 .attr('class', 'help-wrap map-overlay fillL col5 content hide'),
55807             tooltipBehavior = tooltip()
55808                 .placement((textDirection === 'rtl') ? 'right' : 'left')
55809                 .html(true)
55810                 .title(uiTooltipHtml(t('help.title'), key)),
55811             button = selection.append('button')
55812                 .attr('tabindex', -1)
55813                 .on('click', toggle)
55814                 .call(svgIcon('#icon-help', 'light'))
55815                 .call(tooltipBehavior),
55816             shown = false;
55817
55818
55819         var toc = pane.append('ul')
55820             .attr('class', 'toc');
55821
55822         var menuItems = toc.selectAll('li')
55823             .data(docs)
55824             .enter()
55825             .append('li')
55826             .append('a')
55827             .html(function(d) { return d.title; })
55828             .on('click', clickHelp);
55829
55830         var shortcuts = toc
55831             .append('li')
55832             .attr('class', 'shortcuts')
55833             .call(tooltip()
55834                 .html(true)
55835                 .title(uiTooltipHtml(t('shortcuts.tooltip'), '?'))
55836                 .placement('top')
55837             )
55838             .append('a')
55839             .on('click', clickShortcuts);
55840
55841         shortcuts
55842             .append('div')
55843             .text(t('shortcuts.title'));
55844
55845         var walkthrough = toc
55846             .append('li')
55847             .attr('class', 'walkthrough')
55848             .append('a')
55849             .on('click', clickWalkthrough);
55850
55851         walkthrough
55852             .append('svg')
55853             .attr('class', 'logo logo-walkthrough')
55854             .append('use')
55855             .attr('xlink:href', '#logo-walkthrough');
55856
55857         walkthrough
55858             .append('div')
55859             .text(t('splash.walkthrough'));
55860
55861
55862         var content = pane.append('div')
55863             .attr('class', 'left-content');
55864
55865         var doctitle = content.append('h2')
55866             .text(t('help.title'));
55867
55868         var body = content.append('div')
55869             .attr('class', 'body');
55870
55871         var nav = content.append('div')
55872             .attr('class', 'nav');
55873
55874         clickHelp(docs[0], 0);
55875
55876         var keybinding = d3keybinding('help')
55877             .on(key, toggle)
55878             .on([t('background.key'), t('map_data.key')], hide);
55879
55880         d3_select(document)
55881             .call(keybinding);
55882
55883         context.surface().on('mousedown.help-outside', hide);
55884         context.container().on('mousedown.help-outside', hide);
55885     }
55886
55887     return help;
55888 }
55889
55890 function uiPanelBackground(context) {
55891     var background = context.background();
55892     var currSourceName = null;
55893     var metadata = {};
55894     var metadataKeys = [
55895         'zoom', 'vintage', 'source', 'description', 'resolution', 'accuracy'
55896     ];
55897
55898     var debouncedRedraw = debounce(redraw, 250);
55899
55900     function redraw(selection) {
55901         var source = background.baseLayerSource(),
55902             isDG = (source.id.match(/^DigitalGlobe/i) !== null);
55903
55904         if (currSourceName !== source.name()) {
55905             currSourceName = source.name();
55906             metadata = {};
55907         }
55908
55909         selection.html('');
55910
55911         var list = selection
55912             .append('ul')
55913             .attr('class', 'background-info');
55914
55915         list
55916             .append('li')
55917             .text(currSourceName);
55918
55919         metadataKeys.forEach(function(k) {
55920             // DigitalGlobe vintage is available in raster layers for now.
55921             if (isDG && k === 'vintage') return;
55922
55923             list
55924                 .append('li')
55925                 .attr('class', 'background-info-list-' + k)
55926                 .classed('hide', !metadata[k])
55927                 .text(t('info_panels.background.' + k) + ': ')
55928                 .append('span')
55929                 .attr('class', 'background-info-span-' + k)
55930                 .text(metadata[k]);
55931         });
55932
55933         debouncedGetMetadata(selection);
55934
55935         var toggleTiles = context.getDebug('tile') ? 'hide_tiles' : 'show_tiles';
55936
55937         selection
55938             .append('a')
55939             .text(t('info_panels.background.' + toggleTiles))
55940             .attr('href', '#')
55941             .attr('class', 'button button-toggle-tiles')
55942             .on('click', function() {
55943                 event.preventDefault();
55944                 context.setDebug('tile', !context.getDebug('tile'));
55945                 selection.call(redraw);
55946             });
55947
55948         if (isDG) {
55949             var key = source.id + '-vintage';
55950             var sourceVintage = context.background().findSource(key);
55951             var showsVintage = context.background().showsLayer(sourceVintage);
55952             var toggleVintage = showsVintage ? 'hide_vintage' : 'show_vintage';
55953             selection
55954                 .append('a')
55955                 .text(t('info_panels.background.' + toggleVintage))
55956                 .attr('href', '#')
55957                 .attr('class', 'button button-toggle-vintage')
55958                 .on('click', function() {
55959                     event.preventDefault();
55960                     context.background().toggleOverlayLayer(sourceVintage);
55961                     selection.call(redraw);
55962                 });
55963         }
55964
55965         // disable if necessary
55966         ['DigitalGlobe-Premium', 'DigitalGlobe-Standard'].forEach(function(layerId) {
55967             if (source.id !== layerId) {
55968                 var key = layerId + '-vintage';
55969                 var sourceVintage = context.background().findSource(key);
55970                 if (context.background().showsLayer(sourceVintage)) {
55971                     context.background().toggleOverlayLayer(sourceVintage);
55972                 }
55973             }
55974         });
55975     }
55976
55977
55978     var debouncedGetMetadata = debounce(getMetadata, 250);
55979
55980     function getMetadata(selection) {
55981         var tile = d3_select('.layer-background img.tile-center');   // tile near viewport center
55982         if (tile.empty()) return;
55983
55984         var sourceName = currSourceName,
55985             d = tile.datum(),
55986             zoom = (d && d.length >= 3 && d[2]) || Math.floor(context.map().zoom()),
55987             center = context.map().center();
55988
55989         // update zoom
55990         metadata.zoom = String(zoom);
55991         selection.selectAll('.background-info-list-zoom')
55992             .classed('hide', false)
55993             .selectAll('.background-info-span-zoom')
55994             .text(metadata.zoom);
55995
55996         if (!d || !d.length >= 3) return;
55997
55998         background.baseLayerSource().getMetadata(center, d, function(err, result) {
55999             if (err || currSourceName !== sourceName) return;
56000
56001             // update vintage
56002             var vintage = result.vintage;
56003             metadata.vintage = (vintage && vintage.range) || t('info_panels.background.unknown');
56004             selection.selectAll('.background-info-list-vintage')
56005                 .classed('hide', false)
56006                 .selectAll('.background-info-span-vintage')
56007                 .text(metadata.vintage);
56008
56009             // update other metdata
56010             without(metadataKeys, 'zoom', 'vintage')
56011                 .forEach(function(k) {
56012                     var val = result[k];
56013                     metadata[k] = val;
56014                     selection.selectAll('.background-info-list-' + k)
56015                         .classed('hide', !val)
56016                         .selectAll('.background-info-span-' + k)
56017                         .text(val);
56018                 });
56019         });
56020     }
56021
56022
56023     var panel = function(selection) {
56024         selection.call(redraw);
56025
56026         context.map()
56027             .on('drawn.info-background', function() {
56028                 selection.call(debouncedRedraw);
56029             })
56030             .on('move.info-background', function() {
56031                 selection.call(debouncedGetMetadata);
56032             });
56033
56034     };
56035
56036     panel.off = function() {
56037         context.map()
56038             .on('drawn.info-background', null)
56039             .on('move.info-background', null);
56040     };
56041
56042     panel.id = 'background';
56043     panel.title = t('info_panels.background.title');
56044     panel.key = t('info_panels.background.key');
56045
56046
56047     return panel;
56048 }
56049
56050 function uiPanelHistory(context) {
56051     var osm;
56052
56053     function displayTimestamp(entity) {
56054         if (!entity.timestamp) return t('info_panels.history.unknown');
56055
56056         var d = new Date(entity.timestamp);
56057         if (isNaN(d.getTime())) return t('info_panels.history.unknown');
56058
56059         return d.toLocaleString();
56060     }
56061
56062
56063     function displayUser(selection, entity) {
56064         if (!entity.user) {
56065             selection
56066                 .append('span')
56067                 .text(t('info_panels.history.unknown'));
56068             return;
56069         }
56070
56071         selection
56072             .append('span')
56073             .attr('class', 'user-name')
56074             .text(entity.user);
56075
56076         var links = selection
56077             .append('div')
56078             .attr('class', 'links');
56079
56080         if (osm) {
56081             links
56082                 .append('a')
56083                 .attr('class', 'user-osm-link')
56084                 .attr('href', osm.userURL(entity.user))
56085                 .attr('target', '_blank')
56086                 .attr('tabindex', -1)
56087                 .text('OSM');
56088         }
56089
56090         links
56091             .append('a')
56092             .attr('class', 'user-hdyc-link')
56093             .attr('href', 'https://hdyc.neis-one.org/?' + entity.user)
56094             .attr('target', '_blank')
56095             .attr('tabindex', -1)
56096             .text('HDYC');
56097     }
56098
56099
56100     function displayChangeset(selection, entity) {
56101         if (!entity.changeset) {
56102             selection
56103                 .append('span')
56104                 .text(t('info_panels.history.unknown'));
56105             return;
56106         }
56107
56108         selection
56109             .append('span')
56110             .attr('class', 'changeset-id')
56111             .text(entity.changeset);
56112
56113         var links = selection
56114             .append('div')
56115             .attr('class', 'links');
56116
56117         if (osm) {
56118             links
56119                 .append('a')
56120                 .attr('class', 'changeset-osm-link')
56121                 .attr('href', osm.changesetURL(entity.changeset))
56122                 .attr('target', '_blank')
56123                 .attr('tabindex', -1)
56124                 .text('OSM');
56125         }
56126
56127         links
56128             .append('a')
56129             .attr('class', 'changeset-osmcha-link')
56130             .attr('href', 'https://osmcha.mapbox.com/changesets/' + entity.changeset)
56131             .attr('target', '_blank')
56132             .attr('tabindex', -1)
56133             .text('OSMCha');
56134     }
56135
56136
56137     function redraw(selection) {
56138         var selected = filter(context.selectedIDs(), function(e) { return context.hasEntity(e); }),
56139             singular = selected.length === 1 ? selected[0] : null;
56140
56141         osm = context.connection();
56142
56143         selection.html('');
56144
56145         selection
56146             .append('h4')
56147             .attr('class', 'history-heading')
56148             .text(singular || t('info_panels.history.selected', { n: selected.length }));
56149
56150         if (!singular) return;
56151
56152         var entity = context.entity(singular);
56153
56154         var list = selection
56155             .append('ul');
56156
56157         list
56158             .append('li')
56159             .text(t('info_panels.history.version') + ': ' + entity.version);
56160
56161         list
56162             .append('li')
56163             .text(t('info_panels.history.last_edit') + ': ' + displayTimestamp(entity));
56164
56165         list
56166             .append('li')
56167             .text(t('info_panels.history.edited_by') + ': ')
56168             .call(displayUser, entity);
56169
56170         list
56171             .append('li')
56172             .text(t('info_panels.history.changeset') + ': ')
56173             .call(displayChangeset, entity);
56174
56175         if (osm) {
56176             selection
56177                 .append('a')
56178                 .attr('class', 'view-history-on-osm')
56179                 .attr('target', '_blank')
56180                 .attr('tabindex', -1)
56181                 .attr('href', osm.historyURL(entity))
56182                 .call(svgIcon('#icon-out-link', 'inline'))
56183                 .append('span')
56184                 .text(t('info_panels.history.link_text'));
56185         }
56186     }
56187
56188
56189     var panel = function(selection) {
56190         selection.call(redraw);
56191
56192         context.map()
56193             .on('drawn.info-history', function() {
56194                 selection.call(redraw);
56195             });
56196     };
56197
56198     panel.off = function() {
56199         context.map()
56200             .on('drawn.info-history', null);
56201     };
56202
56203     panel.id = 'history';
56204     panel.title = t('info_panels.history.title');
56205     panel.key = t('info_panels.history.key');
56206
56207
56208     return panel;
56209 }
56210
56211 function uiPanelLocation(context) {
56212     var currLocation = '';
56213     var OSM_PRECISION = 7;
56214
56215
56216     function wrap(x, min, max) {
56217         var d = max - min;
56218         return ((x - min) % d + d) % d + min;
56219     }
56220
56221
56222     function clamp(x, min, max) {
56223         return Math.max(min, Math.min(x, max));
56224     }
56225
56226
56227     function redraw(selection) {
56228         selection.html('');
56229
56230         var list = selection
56231             .append('ul');
56232
56233         // Mouse coordinates
56234         var coord = context.map().mouseCoordinates();
56235         if (coord.some(isNaN)) {
56236             coord = context.map().center();
56237         }
56238
56239         var coordStr =
56240             clamp(coord[1], -90, 90).toFixed(OSM_PRECISION) + ', ' +
56241             wrap(coord[0], -180, 180).toFixed(OSM_PRECISION);
56242
56243         list
56244             .append('li')
56245             .text(coordStr);
56246
56247         // Location Info
56248         selection
56249             .append('div')
56250             .attr('class', 'location-info')
56251             .text(currLocation || ' ');
56252
56253         debouncedGetLocation(selection, coord);
56254     }
56255
56256
56257     var debouncedGetLocation = debounce(getLocation, 250);
56258     function getLocation(selection, coord) {
56259         if (!services.geocoder) {
56260             currLocation = t('info_panels.location.unknown_location');
56261             selection.selectAll('.location-info')
56262                 .text(currLocation);
56263         } else {
56264             services.geocoder.reverse(coord, function(err, result) {
56265                 currLocation = result ? result.display_name : t('info_panels.location.unknown_location');
56266                 selection.selectAll('.location-info')
56267                     .text(currLocation);
56268             });
56269         }
56270     }
56271
56272
56273     var panel = function(selection) {
56274         selection.call(redraw);
56275
56276         context.surface()
56277             .on('mousemove.info-location', function() {
56278                 selection.call(redraw);
56279             });
56280     };
56281
56282     panel.off = function() {
56283         context.surface()
56284             .on('mousemove.info-location', null);
56285     };
56286
56287     panel.id = 'location';
56288     panel.title = t('info_panels.location.title');
56289     panel.key = t('info_panels.location.key');
56290
56291
56292     return panel;
56293 }
56294
56295 function uiPanelMeasurement(context) {
56296     var isImperial = (utilDetect().locale.toLowerCase() === 'en-us');
56297     var OSM_PRECISION = 7;
56298
56299
56300     function radiansToMeters(r) {
56301         // using WGS84 authalic radius (6371007.1809 m)
56302         return r * 6371007.1809;
56303     }
56304
56305     function steradiansToSqmeters(r) {
56306         // http://gis.stackexchange.com/a/124857/40446
56307         return r / (4 * Math.PI) * 510065621724000;
56308     }
56309
56310
56311     function toLineString(feature) {
56312         if (feature.type === 'LineString') return feature;
56313
56314         var result = { type: 'LineString', coordinates: [] };
56315         if (feature.type === 'Polygon') {
56316             result.coordinates = feature.coordinates[0];
56317         } else if (feature.type === 'MultiPolygon') {
56318             result.coordinates = feature.coordinates[0][0];
56319         }
56320
56321         return result;
56322     }
56323
56324
56325     function displayLength(m) {
56326         var d = m * (isImperial ? 3.28084 : 1),
56327             p, unit;
56328
56329         if (isImperial) {
56330             if (d >= 5280) {
56331                 d /= 5280;
56332                 unit = 'mi';
56333             } else {
56334                 unit = 'ft';
56335             }
56336         } else {
56337             if (d >= 1000) {
56338                 d /= 1000;
56339                 unit = 'km';
56340             } else {
56341                 unit = 'm';
56342             }
56343         }
56344
56345         // drop unnecessary precision
56346         p = d > 1000 ? 0 : d > 100 ? 1 : 2;
56347
56348         return String(d.toFixed(p)) + ' ' + unit;
56349     }
56350
56351
56352     function displayArea(m2) {
56353         var d = m2 * (isImperial ? 10.7639111056 : 1),
56354             d1, d2, p1, p2, unit1, unit2;
56355
56356         if (isImperial) {
56357             if (d >= 6969600) {     // > 0.25mi² show mi²
56358                 d1 = d / 27878400;
56359                 unit1 = 'mi²';
56360             } else {
56361                 d1 = d;
56362                 unit1 = 'ft²';
56363             }
56364
56365             if (d > 4356 && d < 43560000) {   // 0.1 - 1000 acres
56366                 d2 = d / 43560;
56367                 unit2 = 'ac';
56368             }
56369
56370         } else {
56371             if (d >= 250000) {    // > 0.25km² show km²
56372                 d1 = d / 1000000;
56373                 unit1 = 'km²';
56374             } else {
56375                 d1 = d;
56376                 unit1 = 'm²';
56377             }
56378
56379             if (d > 1000 && d < 10000000) {   // 0.1 - 1000 hectares
56380                 d2 = d / 10000;
56381                 unit2 = 'ha';
56382             }
56383         }
56384
56385         // drop unnecessary precision
56386         p1 = d1 > 1000 ? 0 : d1 > 100 ? 1 : 2;
56387         p2 = d2 > 1000 ? 0 : d2 > 100 ? 1 : 2;
56388
56389         return String(d1.toFixed(p1)) + ' ' + unit1 +
56390             (d2 ? ' (' + String(d2.toFixed(p2)) + ' ' + unit2 + ')' : '');
56391     }
56392
56393
56394     function redraw(selection) {
56395         var resolver = context.graph(),
56396             selected = filter(context.selectedIDs(), function(e) { return context.hasEntity(e); }),
56397             singular = selected.length === 1 ? selected[0] : null,
56398             extent = geoExtent(),
56399             entity;
56400
56401         selection.html('');
56402
56403         selection
56404             .append('h4')
56405             .attr('class', 'measurement-heading')
56406             .text(singular || t('info_panels.measurement.selected', { n: selected.length }));
56407
56408         if (!selected.length) return;
56409
56410         var center;
56411         for (var i = 0; i < selected.length; i++) {
56412             entity = context.entity(selected[i]);
56413             extent._extend(entity.extent(resolver));
56414         }
56415         center = extent.center();
56416
56417
56418         var list = selection
56419             .append('ul');
56420
56421         // multiple features, just display extent center..
56422         if (!singular) {
56423             list
56424                 .append('li')
56425                 .text(t('info_panels.measurement.center') + ': ' +
56426                     center[1].toFixed(OSM_PRECISION) + ', ' + center[0].toFixed(OSM_PRECISION)
56427                 );
56428             return;
56429         }
56430
56431         // single feature, display details..
56432         if (!entity) return;
56433         var geometry = entity.geometry(resolver);
56434
56435         if (geometry === 'line' || geometry === 'area') {
56436             var closed = (entity.type === 'relation') || (entity.isClosed() && !entity.isDegenerate()),
56437                 feature = entity.asGeoJSON(resolver),
56438                 length = radiansToMeters(d3_geoLength(toLineString(feature))),
56439                 lengthLabel = t('info_panels.measurement.' + (closed ? 'perimeter' : 'length')),
56440                 centroid = d3_geoCentroid(feature);
56441
56442             list
56443                 .append('li')
56444                 .text(t('info_panels.measurement.geometry') + ': ' +
56445                     (closed ? t('info_panels.measurement.closed') + ' ' : '') + t('geometry.' + geometry) );
56446
56447             if (closed) {
56448                 var area = steradiansToSqmeters(entity.area(resolver));
56449                 list
56450                     .append('li')
56451                     .text(t('info_panels.measurement.area') + ': ' + displayArea(area));
56452             }
56453
56454             list
56455                 .append('li')
56456                 .text(lengthLabel + ': ' + displayLength(length));
56457
56458             list
56459                 .append('li')
56460                 .text(t('info_panels.measurement.centroid') + ': ' +
56461                     centroid[1].toFixed(OSM_PRECISION) + ', ' + centroid[0].toFixed(OSM_PRECISION)
56462                 );
56463
56464
56465             var toggle  = isImperial ? 'imperial' : 'metric';
56466
56467             selection
56468                 .append('a')
56469                 .text(t('info_panels.measurement.' + toggle))
56470                 .attr('href', '#')
56471                 .attr('class', 'button button-toggle-units')
56472                 .on('click', function() {
56473                     event.preventDefault();
56474                     isImperial = !isImperial;
56475                     selection.call(redraw);
56476                 });
56477
56478         } else {
56479             var centerLabel = t('info_panels.measurement.' + (entity.type === 'node' ? 'location' : 'center'));
56480
56481             list
56482                 .append('li')
56483                 .text(t('info_panels.measurement.geometry') + ': ' + t('geometry.' + geometry));
56484
56485             list
56486                 .append('li')
56487                 .text(centerLabel + ': ' +
56488                     center[1].toFixed(OSM_PRECISION) + ', ' + center[0].toFixed(OSM_PRECISION)
56489                 );
56490         }
56491     }
56492
56493
56494     var panel = function(selection) {
56495         selection.call(redraw);
56496
56497         context.map()
56498             .on('drawn.info-measurement', function() {
56499                 selection.call(redraw);
56500             });
56501     };
56502
56503     panel.off = function() {
56504         context.map()
56505             .on('drawn.info-measurement', null);
56506     };
56507
56508     panel.id = 'measurement';
56509     panel.title = t('info_panels.measurement.title');
56510     panel.key = t('info_panels.measurement.key');
56511
56512
56513     return panel;
56514 }
56515
56516 var uiInfoPanels = {
56517     background: uiPanelBackground,
56518     history: uiPanelHistory,
56519     location: uiPanelLocation,
56520     measurement: uiPanelMeasurement,
56521 };
56522
56523 function uiInfo(context) {
56524     var ids = Object.keys(uiInfoPanels),
56525         wasActive = ['measurement'],
56526         panels = {},
56527         active = {};
56528
56529     // create panels
56530     ids.forEach(function(k) {
56531         if (!panels[k]) {
56532             panels[k] = uiInfoPanels[k](context);
56533             active[k] = false;
56534         }
56535     });
56536
56537
56538     function info(selection) {
56539
56540         function redraw() {
56541             var activeids = ids.filter(function(k) { return active[k]; }).sort();
56542
56543             var containers = infoPanels.selectAll('.panel-container')
56544                 .data(activeids, function(k) { return k; });
56545
56546             containers.exit()
56547                 .style('opacity', 1)
56548                 .transition()
56549                 .duration(200)
56550                 .style('opacity', 0)
56551                 .on('end', function(d) {
56552                     d3_select(this)
56553                         .call(panels[d].off)
56554                         .remove();
56555                 });
56556
56557             var enter = containers.enter()
56558                 .append('div')
56559                 .attr('class', function(d) { return 'fillD2 panel-container panel-container-' + d; });
56560
56561             enter
56562                 .style('opacity', 0)
56563                 .transition()
56564                 .duration(200)
56565                 .style('opacity', 1);
56566
56567             var title = enter
56568                 .append('div')
56569                 .attr('class', 'panel-title fillD2');
56570
56571             title
56572                 .append('h3')
56573                 .text(function(d) { return panels[d].title; });
56574
56575             title
56576                 .append('button')
56577                 .attr('class', 'close')
56578                 .on('click', function (d) { toggle(d); })
56579                 .call(svgIcon('#icon-close'));
56580
56581             enter
56582                 .append('div')
56583                 .attr('class', function(d) { return 'panel-content panel-content-' + d; });
56584
56585
56586             // redraw the panels
56587             infoPanels.selectAll('.panel-content')
56588                 .each(function(d) {
56589                     d3_select(this).call(panels[d]);
56590                 });
56591         }
56592
56593
56594         function toggle(which) {
56595             if (event) {
56596                 event.stopImmediatePropagation();
56597                 event.preventDefault();
56598             }
56599
56600             var activeids = ids.filter(function(k) { return active[k]; });
56601
56602             if (which) {  // toggle one
56603                 active[which] = !active[which];
56604                 if (activeids.length === 1 && activeids[0] === which) {  // none active anymore
56605                     wasActive = [which];
56606                 }
56607             } else {      // toggle all
56608                 if (activeids.length) {
56609                     wasActive = activeids;
56610                     activeids.forEach(function(k) { active[k] = false; });
56611                 } else {
56612                     wasActive.forEach(function(k) { active[k] = true; });
56613                 }
56614             }
56615
56616             redraw();
56617         }
56618
56619
56620         var infoPanels = selection.selectAll('.info-panels')
56621             .data([0]);
56622
56623         infoPanels = infoPanels.enter()
56624             .append('div')
56625             .attr('class', 'info-panels')
56626             .merge(infoPanels);
56627
56628         redraw();
56629
56630         var keybinding = d3keybinding('info')
56631             .on(uiCmd('⌘' + t('info_panels.key')), toggle);
56632
56633         ids.forEach(function(k) {
56634             var key = t('info_panels.' + k + '.key', { default: null });
56635             if (!key) return;
56636             keybinding
56637                 .on(uiCmd('⌘⇧' + key), function() { toggle(k); });
56638         });
56639
56640         d3_select(document)
56641             .call(keybinding);
56642     }
56643
56644     return info;
56645 }
56646
56647 function uiMapData(context) {
56648     var key = t('map_data.key'),
56649         features = context.features().keys(),
56650         layers = context.layers(),
56651         fills = ['wireframe', 'partial', 'full'],
56652         fillDefault = context.storage('area-fill') || 'partial',
56653         fillSelected = fillDefault;
56654
56655
56656     function map_data(selection) {
56657
56658         function showsFeature(d) {
56659             return context.features().enabled(d);
56660         }
56661
56662
56663         function autoHiddenFeature(d) {
56664             return context.features().autoHidden(d);
56665         }
56666
56667
56668         function clickFeature(d) {
56669             context.features().toggle(d);
56670             update();
56671         }
56672
56673
56674         function showsFill(d) {
56675             return fillSelected === d;
56676         }
56677
56678
56679         function setFill(d) {
56680             fills.forEach(function(opt) {
56681                 context.surface().classed('fill-' + opt, Boolean(opt === d));
56682             });
56683
56684             fillSelected = d;
56685             if (d !== 'wireframe') {
56686                 fillDefault = d;
56687                 context.storage('area-fill', d);
56688             }
56689             update();
56690         }
56691
56692
56693         function showsLayer(which) {
56694             var layer = layers.layer(which);
56695             if (layer) {
56696                 return layer.enabled();
56697             }
56698             return false;
56699         }
56700
56701
56702         function setLayer(which, enabled) {
56703             var layer = layers.layer(which);
56704             if (layer) {
56705                 layer.enabled(enabled);
56706                 update();
56707             }
56708         }
56709
56710
56711         function toggleLayer(which) {
56712             setLayer(which, !showsLayer(which));
56713         }
56714
56715
56716         function drawPhotoItems(selection) {
56717             var photoKeys = ['mapillary-images', 'mapillary-signs', 'openstreetcam-images'];
56718             var photoLayers = layers.all().filter(function(obj) { return photoKeys.indexOf(obj.id) !== -1; });
56719             var data = photoLayers.filter(function(obj) { return obj.layer.supported(); });
56720
56721             function layerSupported(d) {
56722                 return d.layer && d.layer.supported();
56723             }
56724             function layerEnabled(d) {
56725                 return layerSupported(d) && d.layer.enabled();
56726             }
56727
56728             var ul = selection
56729                 .selectAll('.layer-list-photos')
56730                 .data([0]);
56731
56732             ul = ul.enter()
56733                 .append('ul')
56734                 .attr('class', 'layer-list layer-list-photos')
56735                 .merge(ul);
56736
56737             var li = ul.selectAll('.list-item-photos')
56738                 .data(data);
56739
56740             li.exit()
56741                 .remove();
56742
56743             var liEnter = li.enter()
56744                 .append('li')
56745                 .attr('class', function(d) { return 'list-item-photos list-item-' + d.id; });
56746
56747             var labelEnter = liEnter
56748                 .append('label')
56749                 .each(function(d) {
56750                     d3_select(this)
56751                         .call(tooltip()
56752                             .title(t(d.id.replace('-', '_') + '.tooltip'))
56753                             .placement('top')
56754                         );
56755                 });
56756
56757             labelEnter
56758                 .append('input')
56759                 .attr('type', 'checkbox')
56760                 .on('change', function(d) { toggleLayer(d.id); });
56761
56762             labelEnter
56763                 .append('span')
56764                 .text(function(d) { return t(d.id.replace('-', '_') + '.title'); });
56765
56766
56767             // Update
56768             li = li
56769                 .merge(liEnter);
56770
56771             li
56772                 .classed('active', layerEnabled)
56773                 .selectAll('input')
56774                 .property('checked', layerEnabled);
56775         }
56776
56777
56778         function drawOsmItem(selection) {
56779             var osm = layers.layer('osm'),
56780                 showsOsm = osm.enabled();
56781
56782             var ul = selection
56783                 .selectAll('.layer-list-osm')
56784                 .data(osm ? [0] : []);
56785
56786             // Exit
56787             ul.exit()
56788                 .remove();
56789
56790             // Enter
56791             var ulEnter = ul.enter()
56792                 .append('ul')
56793                 .attr('class', 'layer-list layer-list-osm');
56794
56795             var liEnter = ulEnter
56796                 .append('li')
56797                 .attr('class', 'list-item-osm');
56798
56799             var labelEnter = liEnter
56800                 .append('label')
56801                 .call(tooltip()
56802                     .title(t('map_data.layers.osm.tooltip'))
56803                     .placement('top')
56804                 );
56805
56806             labelEnter
56807                 .append('input')
56808                 .attr('type', 'checkbox')
56809                 .on('change', function() { toggleLayer('osm'); });
56810
56811             labelEnter
56812                 .append('span')
56813                 .text(t('map_data.layers.osm.title'));
56814
56815             // Update
56816             ul = ul
56817                 .merge(ulEnter);
56818
56819             ul.selectAll('.list-item-osm')
56820                 .classed('active', showsOsm)
56821                 .selectAll('input')
56822                 .property('checked', showsOsm);
56823         }
56824
56825
56826         function drawGpxItem(selection) {
56827             var gpx = layers.layer('gpx'),
56828                 hasGpx = gpx && gpx.hasGpx(),
56829                 showsGpx = hasGpx && gpx.enabled();
56830
56831             var ul = selection
56832                 .selectAll('.layer-list-gpx')
56833                 .data(gpx ? [0] : []);
56834
56835             // Exit
56836             ul.exit()
56837                 .remove();
56838
56839             // Enter
56840             var ulEnter = ul.enter()
56841                 .append('ul')
56842                 .attr('class', 'layer-list layer-list-gpx');
56843
56844             var liEnter = ulEnter
56845                 .append('li')
56846                 .attr('class', 'list-item-gpx');
56847
56848             liEnter
56849                 .append('button')
56850                 .attr('class', 'list-item-gpx-extent')
56851                 .call(tooltip()
56852                     .title(t('gpx.zoom'))
56853                     .placement((textDirection === 'rtl') ? 'right' : 'left'))
56854                 .on('click', function() {
56855                     event.preventDefault();
56856                     event.stopPropagation();
56857                     gpx.fitZoom();
56858                 })
56859                 .call(svgIcon('#icon-search'));
56860
56861             liEnter
56862                 .append('button')
56863                 .attr('class', 'list-item-gpx-browse')
56864                 .call(tooltip()
56865                     .title(t('gpx.browse'))
56866                     .placement((textDirection === 'rtl') ? 'right' : 'left')
56867                 )
56868                 .on('click', function() {
56869                     d3_select(document.createElement('input'))
56870                         .attr('type', 'file')
56871                         .on('change', function() {
56872                             gpx.files(event.target.files);
56873                         })
56874                         .node().click();
56875                 })
56876                 .call(svgIcon('#icon-geolocate'));
56877
56878             var labelEnter = liEnter
56879                 .append('label')
56880                 .call(tooltip()
56881                     .title(t('gpx.drag_drop'))
56882                     .placement('top')
56883                 );
56884
56885             labelEnter
56886                 .append('input')
56887                 .attr('type', 'checkbox')
56888                 .on('change', function() { toggleLayer('gpx'); });
56889
56890             labelEnter
56891                 .append('span')
56892                 .text(t('gpx.local_layer'));
56893
56894             // Update
56895             ul = ul
56896                 .merge(ulEnter);
56897
56898             ul.selectAll('.list-item-gpx')
56899                 .classed('active', showsGpx)
56900                 .selectAll('label')
56901                 .classed('deemphasize', !hasGpx)
56902                 .selectAll('input')
56903                 .property('disabled', !hasGpx)
56904                 .property('checked', showsGpx);
56905         }
56906
56907
56908         function drawList(selection, data, type, name, change, active) {
56909             var items = selection.selectAll('li')
56910                 .data(data);
56911
56912             // Exit
56913             items.exit()
56914                 .remove();
56915
56916             // Enter
56917             var enter = items.enter()
56918                 .append('li')
56919                 .attr('class', 'layer')
56920                 .call(tooltip()
56921                     .html(true)
56922                     .title(function(d) {
56923                         var tip = t(name + '.' + d + '.tooltip'),
56924                             key = (d === 'wireframe' ? t('area_fill.wireframe.key') : null);
56925
56926                         if (name === 'feature' && autoHiddenFeature(d)) {
56927                             var msg = showsLayer('osm') ? t('map_data.autohidden') : t('map_data.osmhidden');
56928                             tip += '<div>' + msg + '</div>';
56929                         }
56930                         return uiTooltipHtml(tip, key);
56931                     })
56932                     .placement('top')
56933                 );
56934
56935             var label = enter
56936                 .append('label');
56937
56938             label
56939                 .append('input')
56940                 .attr('type', type)
56941                 .attr('name', name)
56942                 .on('change', change);
56943
56944             label
56945                 .append('span')
56946                 .text(function(d) { return t(name + '.' + d + '.description'); });
56947
56948             // Update
56949             items = items
56950                 .merge(enter);
56951
56952             items
56953                 .classed('active', active)
56954                 .selectAll('input')
56955                 .property('checked', active)
56956                 .property('indeterminate', function(d) {
56957                     return (name === 'feature' && autoHiddenFeature(d));
56958                 });
56959         }
56960
56961
56962         function update() {
56963             dataLayerContainer
56964                 .call(drawOsmItem)
56965                 .call(drawPhotoItems)
56966                 .call(drawGpxItem);
56967
56968             fillList
56969                 .call(drawList, fills, 'radio', 'area_fill', setFill, showsFill);
56970
56971             featureList
56972                 .call(drawList, features, 'checkbox', 'feature', clickFeature, showsFeature);
56973         }
56974
56975
56976         function hidePanel() {
56977             setVisible(false);
56978         }
56979
56980
56981         function togglePanel() {
56982             if (event) event.preventDefault();
56983             tooltipBehavior.hide(button);
56984             setVisible(!button.classed('active'));
56985         }
56986
56987
56988         function toggleWireframe() {
56989             if (event) {
56990                 event.preventDefault();
56991                 event.stopPropagation();
56992             }
56993             setFill((fillSelected === 'wireframe' ? fillDefault : 'wireframe'));
56994             context.map().pan([0,0]);  // trigger a redraw
56995         }
56996
56997
56998         function setVisible(show) {
56999             if (show !== shown) {
57000                 button.classed('active', show);
57001                 shown = show;
57002
57003                 if (show) {
57004                     update();
57005                     selection.on('mousedown.map_data-inside', function() {
57006                         return event.stopPropagation();
57007                     });
57008                     content.style('display', 'block')
57009                         .style('right', '-300px')
57010                         .transition()
57011                         .duration(200)
57012                         .style('right', '0px');
57013                 } else {
57014                     content.style('display', 'block')
57015                         .style('right', '0px')
57016                         .transition()
57017                         .duration(200)
57018                         .style('right', '-300px')
57019                         .on('end', function() {
57020                             d3_select(this).style('display', 'none');
57021                         });
57022                     selection.on('mousedown.map_data-inside', null);
57023                 }
57024             }
57025         }
57026
57027
57028         var content = selection
57029                 .append('div')
57030                 .attr('class', 'fillL map-overlay col3 content hide'),
57031             tooltipBehavior = tooltip()
57032                 .placement((textDirection === 'rtl') ? 'right' : 'left')
57033                 .html(true)
57034                 .title(uiTooltipHtml(t('map_data.description'), key)),
57035             button = selection
57036                 .append('button')
57037                 .attr('tabindex', -1)
57038                 .on('click', togglePanel)
57039                 .call(svgIcon('#icon-data', 'light'))
57040                 .call(tooltipBehavior),
57041             shown = false;
57042
57043         content
57044             .append('h4')
57045             .text(t('map_data.title'));
57046
57047
57048         // data layers
57049         content
57050             .append('a')
57051             .text(t('map_data.data_layers'))
57052             .attr('href', '#')
57053             .classed('hide-toggle', true)
57054             .classed('expanded', true)
57055             .on('click', function() {
57056                 var exp = d3_select(this).classed('expanded');
57057                 dataLayerContainer.style('display', exp ? 'none' : 'block');
57058                 d3_select(this).classed('expanded', !exp);
57059                 event.preventDefault();
57060             });
57061
57062         var dataLayerContainer = content
57063             .append('div')
57064             .attr('class', 'data-data-layers')
57065             .style('display', 'block');
57066
57067
57068         // area fills
57069         content
57070             .append('a')
57071             .text(t('map_data.fill_area'))
57072             .attr('href', '#')
57073             .classed('hide-toggle', true)
57074             .classed('expanded', false)
57075             .on('click', function() {
57076                 var exp = d3_select(this).classed('expanded');
57077                 fillContainer.style('display', exp ? 'none' : 'block');
57078                 d3_select(this).classed('expanded', !exp);
57079                 event.preventDefault();
57080             });
57081
57082         var fillContainer = content
57083             .append('div')
57084             .attr('class', 'data-area-fills')
57085             .style('display', 'none');
57086
57087         var fillList = fillContainer
57088             .append('ul')
57089             .attr('class', 'layer-list layer-fill-list');
57090
57091
57092         // feature filters
57093         content
57094             .append('a')
57095             .text(t('map_data.map_features'))
57096             .attr('href', '#')
57097             .classed('hide-toggle', true)
57098             .classed('expanded', false)
57099             .on('click', function() {
57100                 var exp = d3_select(this).classed('expanded');
57101                 featureContainer.style('display', exp ? 'none' : 'block');
57102                 d3_select(this).classed('expanded', !exp);
57103                 event.preventDefault();
57104             });
57105
57106         var featureContainer = content
57107             .append('div')
57108             .attr('class', 'data-feature-filters')
57109             .style('display', 'none');
57110
57111         var featureList = featureContainer
57112             .append('ul')
57113             .attr('class', 'layer-list layer-feature-list');
57114
57115
57116         context.features()
57117             .on('change.map_data-update', update);
57118
57119         setFill(fillDefault);
57120
57121         var keybinding = d3keybinding('features')
57122             .on(key, togglePanel)
57123             .on(t('area_fill.wireframe.key'), toggleWireframe)
57124             .on([t('background.key'), t('help.key')], hidePanel);
57125
57126         d3_select(document)
57127             .call(keybinding);
57128
57129         context.surface().on('mousedown.map_data-outside', hidePanel);
57130         context.container().on('mousedown.map_data-outside', hidePanel);
57131     }
57132
57133
57134     return map_data;
57135 }
57136
57137 function uiModes(context) {
57138     var modes = [
57139         modeAddPoint(context),
57140         modeAddLine(context),
57141         modeAddArea(context)
57142     ];
57143
57144
57145     function editable() {
57146         return context.editable() && context.mode().id !== 'save';
57147     }
57148
57149
57150     return function(selection) {
57151         var buttons = selection.selectAll('button.add-button')
57152             .data(modes);
57153
57154         buttons = buttons.enter()
57155             .append('button')
57156             .attr('tabindex', -1)
57157             .attr('class', function(mode) { return mode.id + ' add-button col4'; })
57158             .on('click.mode-buttons', function(mode) {
57159                 // When drawing, ignore accidental clicks on mode buttons - #4042
57160                 var currMode = context.mode().id;
57161                 if (currMode.match(/^draw/) !== null) return;
57162
57163                 if (mode.id === currMode) {
57164                     context.enter(modeBrowse(context));
57165                 } else {
57166                     context.enter(mode);
57167                 }
57168             })
57169             .call(tooltip()
57170                 .placement('bottom')
57171                 .html(true)
57172                 .title(function(mode) {
57173                     return uiTooltipHtml(mode.description, mode.key);
57174                 })
57175             );
57176
57177         buttons
57178             .each(function(d) {
57179                 d3_select(this)
57180                     .call(svgIcon('#icon-' + d.button, 'pre-text'));
57181             });
57182
57183         buttons
57184             .append('span')
57185             .attr('class', 'label')
57186             .text(function(mode) { return mode.title; });
57187
57188         context
57189             .on('enter.editor', function(entered) {
57190                 selection.selectAll('button.add-button')
57191                     .classed('active', function(mode) { return entered.button === mode.button; });
57192                 context.container()
57193                     .classed('mode-' + entered.id, true);
57194             });
57195
57196         context
57197             .on('exit.editor', function(exited) {
57198                 context.container()
57199                     .classed('mode-' + exited.id, false);
57200             });
57201
57202         var keybinding = d3keybinding('mode-buttons');
57203
57204         modes.forEach(function(mode) {
57205             keybinding.on(mode.key, function() {
57206                 if (editable()) {
57207                     if (mode.id === context.mode().id) {
57208                         context.enter(modeBrowse(context));
57209                     } else {
57210                         context.enter(mode);
57211                     }
57212                 }
57213             });
57214         });
57215
57216         d3_select(document)
57217             .call(keybinding);
57218
57219
57220         var debouncedUpdate = debounce(update, 500, { leading: true, trailing: true });
57221
57222         context.map()
57223             .on('move.modes', debouncedUpdate)
57224             .on('drawn.modes', debouncedUpdate);
57225
57226         context
57227             .on('enter.modes', update);
57228
57229
57230
57231         function update() {
57232             selection.selectAll('button.add-button')
57233                 .property('disabled', !editable());
57234         }
57235     };
57236 }
57237
57238 function uiNotice(context) {
57239
57240     return function(selection) {
57241         var div = selection
57242             .append('div')
57243             .attr('class', 'notice');
57244
57245         var button = div
57246             .append('button')
57247             .attr('class', 'zoom-to notice fillD')
57248             .on('click', function() {
57249                 context.map().zoomEase(context.minEditableZoom());
57250             })
57251             .on('wheel', function() {   // let wheel events pass through #4482
57252                 var e2 = new WheelEvent(event.type, event);
57253                 context.surface().node().dispatchEvent(e2);
57254             });
57255
57256         button
57257             .call(svgIcon('#icon-plus', 'pre-text'))
57258             .append('span')
57259             .attr('class', 'label')
57260             .text(t('zoom_in_edit'));
57261
57262
57263         function disableTooHigh() {
57264             var canEdit = context.map().zoom() >= context.minEditableZoom();
57265             div.style('display', canEdit ? 'none' : 'block');
57266         }
57267
57268         context.map()
57269             .on('move.notice', debounce(disableTooHigh, 500));
57270
57271         disableTooHigh();
57272     };
57273 }
57274
57275 function uiRestore(context) {
57276
57277     return function(selection) {
57278         if (!context.history().lock() || !context.history().restorableChanges())
57279             return;
57280
57281         var modalSelection = uiModal(selection, true);
57282
57283         modalSelection.select('.modal')
57284             .attr('class', 'modal fillL col6');
57285
57286         var introModal = modalSelection.select('.content');
57287
57288         introModal
57289             .attr('class','cf');
57290
57291         introModal
57292             .append('div')
57293             .attr('class', 'modal-section')
57294             .append('h3')
57295             .text(t('restore.heading'));
57296
57297         introModal
57298             .append('div')
57299             .attr('class','modal-section')
57300             .append('p')
57301             .text(t('restore.description'));
57302
57303         var buttonWrap = introModal
57304             .append('div')
57305             .attr('class', 'modal-actions cf');
57306
57307         var restore = buttonWrap
57308             .append('button')
57309             .attr('class', 'restore col6')
57310             .on('click', function() {
57311                 context.history().restore();
57312                 modalSelection.remove();
57313             });
57314
57315         restore
57316             .append('svg')
57317             .attr('class', 'logo logo-restore')
57318             .append('use')
57319             .attr('xlink:href', '#logo-restore');
57320
57321         restore
57322             .append('div')
57323             .text(t('restore.restore'));
57324
57325         var reset = buttonWrap
57326             .append('button')
57327             .attr('class', 'reset col6')
57328             .on('click', function() {
57329                 context.history().clearSaved();
57330                 modalSelection.remove();
57331             });
57332
57333         reset
57334             .append('svg')
57335             .attr('class', 'logo logo-reset')
57336             .append('use')
57337             .attr('xlink:href', '#logo-reset');
57338
57339         reset
57340             .append('div')
57341             .text(t('restore.reset'));
57342
57343         restore.node().focus();
57344     };
57345 }
57346
57347 function uiSave(context) {
57348     var history = context.history(),
57349         key = uiCmd('⌘S');
57350
57351
57352     function saving() {
57353         return context.mode().id === 'save';
57354     }
57355
57356
57357     function save() {
57358         event.preventDefault();
57359         if (!context.inIntro() && !saving() && history.hasChanges()) {
57360             context.enter(modeSave(context));
57361         }
57362     }
57363
57364
57365     function getBackground(numChanges) {
57366         var step;
57367         if (numChanges === 0) {
57368             return null;
57369         } else if (numChanges <= 50) {
57370             step = numChanges / 50;
57371             return d3_interpolateRgb('#fff', '#ff8')(step);  // white -> yellow
57372         } else {
57373             step = Math.min((numChanges - 50) / 50, 1.0);
57374             return d3_interpolateRgb('#ff8', '#f88')(step);  // yellow -> red
57375         }
57376     }
57377
57378
57379     return function(selection) {
57380         var numChanges = 0;
57381
57382         function updateCount() {
57383             var _ = history.difference().summary().length;
57384             if (_ === numChanges) return;
57385             numChanges = _;
57386
57387             tooltipBehavior
57388                 .title(uiTooltipHtml(
57389                     t(numChanges > 0 ? 'save.help' : 'save.no_changes'), key)
57390                 );
57391
57392             var background = getBackground(numChanges);
57393
57394             button
57395                 .classed('disabled', numChanges === 0)
57396                 .classed('has-count', numChanges > 0)
57397                 .style('background', background);
57398
57399             button.select('span.count')
57400                 .text(numChanges)
57401                 .style('background', background)
57402                 .style('border-color', background);
57403         }
57404
57405
57406         var tooltipBehavior = tooltip()
57407             .placement('bottom')
57408             .html(true)
57409             .title(uiTooltipHtml(t('save.no_changes'), key));
57410
57411         var button = selection
57412             .append('button')
57413             .attr('class', 'save col12 disabled')
57414             .attr('tabindex', -1)
57415             .on('click', save)
57416             .call(tooltipBehavior);
57417
57418         button
57419             .call(svgIcon('#icon-save', 'pre-text'))
57420             .append('span')
57421             .attr('class', 'label')
57422             .text(t('save.title'));
57423
57424         button
57425             .append('span')
57426             .attr('class', 'count')
57427             .text('0');
57428
57429         updateCount();
57430
57431
57432         var keybinding = d3keybinding('save')
57433             .on(key, save, true);
57434
57435         d3_select(document)
57436             .call(keybinding);
57437
57438         context.history()
57439             .on('change.save', updateCount);
57440
57441         context
57442             .on('enter.save', function() {
57443                 button.property('disabled', saving());
57444                 if (saving()) button.call(tooltipBehavior.hide);
57445             });
57446     };
57447 }
57448
57449 function uiScale(context) {
57450     var projection = context.projection,
57451         isImperial = (utilDetect().locale.toLowerCase() === 'en-us'),
57452         maxLength = 180,
57453         tickHeight = 8;
57454
57455
57456     function scaleDefs(loc1, loc2) {
57457         var lat = (loc2[1] + loc1[1]) / 2,
57458             conversion = (isImperial ? 3.28084 : 1),
57459             dist = geoLonToMeters(loc2[0] - loc1[0], lat) * conversion,
57460             scale = { dist: 0, px: 0, text: '' },
57461             buckets, i, val, dLon;
57462
57463         if (isImperial) {
57464             buckets = [5280000, 528000, 52800, 5280, 500, 50, 5, 1];
57465         } else {
57466             buckets = [5000000, 500000, 50000, 5000, 500, 50, 5, 1];
57467         }
57468
57469         // determine a user-friendly endpoint for the scale
57470         for (i = 0; i < buckets.length; i++) {
57471             val = buckets[i];
57472             if (dist >= val) {
57473                 scale.dist = Math.floor(dist / val) * val;
57474                 break;
57475             } else {
57476                 scale.dist = +dist.toFixed(2);
57477             }
57478         }
57479
57480         dLon = geoMetersToLon(scale.dist / conversion, lat);
57481         scale.px = Math.round(projection([loc1[0] + dLon, loc1[1]])[0]);
57482
57483         if (isImperial) {
57484             if (scale.dist >= 5280) {
57485                 scale.dist /= 5280;
57486                 scale.text = String(scale.dist) + ' mi';
57487             } else {
57488                 scale.text = String(scale.dist) + ' ft';
57489             }
57490         } else {
57491             if (scale.dist >= 1000) {
57492                 scale.dist /= 1000;
57493                 scale.text = String(scale.dist) + ' km';
57494             } else {
57495                 scale.text = String(scale.dist) + ' m';
57496             }
57497         }
57498
57499         return scale;
57500     }
57501
57502
57503     function update(selection) {
57504         // choose loc1, loc2 along bottom of viewport (near where the scale will be drawn)
57505         var dims = context.map().dimensions(),
57506             loc1 = projection.invert([0, dims[1]]),
57507             loc2 = projection.invert([maxLength, dims[1]]),
57508             scale = scaleDefs(loc1, loc2);
57509
57510         selection.select('#scale-path')
57511             .attr('d', 'M0.5,0.5v' + tickHeight + 'h' + scale.px + 'v-' + tickHeight);
57512
57513         selection.select('#scale-textgroup')
57514             .attr('transform', 'translate(' + (scale.px + 8) + ',' + tickHeight + ')');
57515
57516         selection.select('#scale-text')
57517             .text(scale.text);
57518     }
57519
57520
57521     return function(selection) {
57522         function switchUnits() {
57523             isImperial = !isImperial;
57524             selection.call(update);
57525         }
57526
57527         var scalegroup = selection.append('svg')
57528             .attr('id', 'scale')
57529             .on('click', switchUnits)
57530             .append('g')
57531             .attr('transform', 'translate(10,11)');
57532
57533         scalegroup
57534             .append('path')
57535             .attr('id', 'scale-path');
57536
57537         scalegroup
57538             .append('g')
57539             .attr('id', 'scale-textgroup')
57540             .append('text')
57541             .attr('id', 'scale-text');
57542
57543         selection.call(update);
57544
57545         context.map().on('move.scale', function() {
57546             update(selection);
57547         });
57548     };
57549 }
57550
57551 var pair_1 = pair$1;
57552 function search(x, dims, r) {
57553   if (!dims) dims = 'NSEW';
57554   if (typeof x !== 'string') return { val: null, regex: r };
57555
57556   r = r || /[\s\,]*([NSEW])?\s*([\-|\—|\―]?[0-9.]+)°?\s*(?:([0-9.]+)['’′‘]\s*)?(?:([0-9.]+)(?:''|"|”|″)\s*)?([NSEW])?/gi;
57557
57558   var m = r.exec(x);
57559   if (!m) return { val: null, regex: r };
57560
57561   var dim = m[1] || m[5];
57562   if (dim && dims.indexOf(dim) === -1) return { val: null, regex: r };
57563
57564   return {
57565     val: (((m[2]) ? parseFloat(m[2]) : 0) +
57566           ((m[3] ? parseFloat(m[3]) / 60 : 0)) +
57567           ((m[4] ? parseFloat(m[4]) / 3600 : 0))) *
57568           ((dim === 'S' || dim === 'W') ? -1 : 1),
57569     regex: r,
57570     raw: m[0],
57571     dim: dim
57572   };
57573 }
57574
57575 function pair$1(x, dims) {
57576   x = x.trim();
57577   var one = search(x, dims);
57578   if (one.val === null) return null;
57579   var two = search(x, dims, one.regex);
57580   if (two.val === null) return null;
57581   // null if one/two are not contiguous.
57582   if (one.raw + two.raw !== x) return null;
57583   if (one.dim) {
57584     return swapdim(one.val, two.val, one.dim);
57585   } else {
57586     return [one.val, two.val];
57587   }
57588 }
57589
57590 function swapdim(a, b, dim) {
57591   if (dim === 'N' || dim === 'S') return [a, b];
57592   if (dim === 'W' || dim === 'E') return [b, a];
57593 }
57594
57595 function uiFeatureList(context) {
57596     var geocodeResults;
57597
57598
57599     function featureList(selection) {
57600         var header = selection
57601             .append('div')
57602             .attr('class', 'header fillL cf');
57603
57604         header.append('h3')
57605             .text(t('inspector.feature_list'));
57606
57607         var searchWrap = selection
57608             .append('div')
57609             .attr('class', 'search-header');
57610
57611         var search = searchWrap
57612             .append('input')
57613             .attr('placeholder', t('inspector.search'))
57614             .attr('type', 'search')
57615             .call(utilNoAuto)
57616             .on('keypress', keypress)
57617             .on('input', inputevent);
57618
57619         searchWrap
57620             .call(svgIcon('#icon-search', 'pre-text'));
57621
57622         var listWrap = selection
57623             .append('div')
57624             .attr('class', 'inspector-body');
57625
57626         var list = listWrap
57627             .append('div')
57628             .attr('class', 'feature-list cf');
57629
57630         context
57631             .on('exit.feature-list', clearSearch);
57632         context.map()
57633             .on('drawn.feature-list', mapDrawn);
57634
57635
57636         function keypress() {
57637             var q = search.property('value'),
57638                 items = list.selectAll('.feature-list-item');
57639             if (event.keyCode === 13 && q.length && items.size()) {
57640                 click(items.datum());
57641             }
57642         }
57643
57644
57645         function inputevent() {
57646             geocodeResults = undefined;
57647             drawList();
57648         }
57649
57650
57651         function clearSearch() {
57652             search.property('value', '');
57653             drawList();
57654         }
57655
57656
57657         function mapDrawn(e) {
57658             if (e.full) {
57659                 drawList();
57660             }
57661         }
57662
57663
57664         function features() {
57665             var entities = {},
57666                 result = [],
57667                 graph = context.graph(),
57668                 q = search.property('value').toLowerCase();
57669
57670             if (!q) return result;
57671
57672             var idMatch = q.match(/^([nwr])([0-9]+)$/);
57673
57674             if (idMatch) {
57675                 result.push({
57676                     id: idMatch[0],
57677                     geometry: idMatch[1] === 'n' ? 'point' : idMatch[1] === 'w' ? 'line' : 'relation',
57678                     type: idMatch[1] === 'n' ? t('inspector.node') : idMatch[1] === 'w' ? t('inspector.way') : t('inspector.relation'),
57679                     name: idMatch[2]
57680                 });
57681             }
57682
57683             var locationMatch = pair_1(q.toUpperCase()) || q.match(/^(-?\d+\.?\d*)\s+(-?\d+\.?\d*)$/);
57684
57685             if (locationMatch) {
57686                 var loc = [parseFloat(locationMatch[0]), parseFloat(locationMatch[1])];
57687                 result.push({
57688                     id: -1,
57689                     geometry: 'point',
57690                     type: t('inspector.location'),
57691                     name: loc[0].toFixed(6) + ', ' + loc[1].toFixed(6),
57692                     location: loc
57693                 });
57694             }
57695
57696             function addEntity(entity) {
57697                 if (entity.id in entities || result.length > 200)
57698                     return;
57699
57700                 entities[entity.id] = true;
57701
57702                 var name = utilDisplayName(entity) || '';
57703                 if (name.toLowerCase().indexOf(q) >= 0) {
57704                     var matched = context.presets().match(entity, graph),
57705                         type = (matched && matched.name()) || utilDisplayType(entity.id);
57706                     result.push({
57707                         id: entity.id,
57708                         entity: entity,
57709                         geometry: context.geometry(entity.id),
57710                         type: type,
57711                         name: name
57712                     });
57713                 }
57714
57715                 graph.parentRelations(entity).forEach(function(parent) {
57716                     addEntity(parent);
57717                 });
57718             }
57719
57720             var visible = context.surface().selectAll('.point, .line, .area').nodes();
57721             for (var i = 0; i < visible.length && result.length <= 200; i++) {
57722                 addEntity(visible[i].__data__);
57723             }
57724
57725             (geocodeResults || []).forEach(function(d) {
57726                 // https://github.com/openstreetmap/iD/issues/1890
57727                 if (d.osm_type && d.osm_id) {
57728                     result.push({
57729                         id: osmEntity.id.fromOSM(d.osm_type, d.osm_id),
57730                         geometry: d.osm_type === 'relation' ? 'relation' : d.osm_type === 'way' ? 'line' : 'point',
57731                         type: d.type !== 'yes' ? (d.type.charAt(0).toUpperCase() + d.type.slice(1)).replace('_', ' ')
57732                                                : (d.class.charAt(0).toUpperCase() + d.class.slice(1)).replace('_', ' '),
57733                         name: d.display_name,
57734                         extent: new geoExtent(
57735                             [parseFloat(d.boundingbox[3]), parseFloat(d.boundingbox[0])],
57736                             [parseFloat(d.boundingbox[2]), parseFloat(d.boundingbox[1])])
57737                     });
57738                 }
57739             });
57740
57741             return result;
57742         }
57743
57744
57745         function drawList() {
57746             var value = search.property('value'),
57747                 results = features();
57748
57749             list.classed('filtered', value.length);
57750
57751             var noResultsWorldwide = geocodeResults && geocodeResults.length === 0;
57752
57753             var resultsIndicator = list.selectAll('.no-results-item')
57754                 .data([0])
57755                 .enter().append('button')
57756                 .property('disabled', true)
57757                 .attr('class', 'no-results-item')
57758                 .call(svgIcon('#icon-alert', 'pre-text'));
57759
57760             resultsIndicator.append('span')
57761                 .attr('class', 'entity-name');
57762
57763             list.selectAll('.no-results-item .entity-name')
57764                 .text(noResultsWorldwide ? t('geocoder.no_results_worldwide') : t('geocoder.no_results_visible'));
57765
57766             if (services.geocoder) {
57767               list.selectAll('.geocode-item')
57768                   .data([0])
57769                   .enter().append('button')
57770                   .attr('class', 'geocode-item')
57771                   .on('click', geocoderSearch)
57772                   .append('div')
57773                   .attr('class', 'label')
57774                   .append('span')
57775                   .attr('class', 'entity-name')
57776                   .text(t('geocoder.search'));
57777             }
57778
57779             list.selectAll('.no-results-item')
57780                 .style('display', (value.length && !results.length) ? 'block' : 'none');
57781
57782             list.selectAll('.geocode-item')
57783                 .style('display', (value && geocodeResults === undefined) ? 'block' : 'none');
57784
57785             list.selectAll('.feature-list-item')
57786                 .data([-1])
57787                 .remove();
57788
57789             var items = list.selectAll('.feature-list-item')
57790                 .data(results, function(d) { return d.id; });
57791
57792             var enter = items.enter()
57793                 .insert('button', '.geocode-item')
57794                 .attr('class', 'feature-list-item')
57795                 .on('mouseover', mouseover)
57796                 .on('mouseout', mouseout)
57797                 .on('click', click);
57798
57799             var label = enter
57800                 .append('div')
57801                 .attr('class', 'label');
57802
57803             label.each(function(d) {
57804                 d3_select(this)
57805                     .call(svgIcon('#icon-' + d.geometry, 'pre-text'));
57806             });
57807
57808             label.append('span')
57809                 .attr('class', 'entity-type')
57810                 .text(function(d) { return d.type; });
57811
57812             label.append('span')
57813                 .attr('class', 'entity-name')
57814                 .text(function(d) { return d.name; });
57815
57816             enter.style('opacity', 0)
57817                 .transition()
57818                 .style('opacity', 1);
57819
57820             items.order();
57821
57822             items.exit()
57823                 .remove();
57824         }
57825
57826
57827         function mouseover(d) {
57828             if (d.id === -1) return;
57829
57830             context.surface().selectAll(utilEntityOrMemberSelector([d.id], context.graph()))
57831                 .classed('hover', true);
57832         }
57833
57834
57835         function mouseout() {
57836             context.surface().selectAll('.hover')
57837                 .classed('hover', false);
57838         }
57839
57840
57841         function click(d) {
57842             event.preventDefault();
57843             if (d.location) {
57844                 context.map().centerZoom([d.location[1], d.location[0]], 20);
57845             }
57846             else if (d.entity) {
57847                 if (d.entity.type === 'node') {
57848                     context.map().center(d.entity.loc);
57849                 } else if (d.entity.type === 'way') {
57850                     var center = context.projection(context.map().center()),
57851                         edge = geoChooseEdge(context.childNodes(d.entity), center, context.projection);
57852                     context.map().center(edge.loc);
57853                 }
57854                 context.enter(modeSelect(context, [d.entity.id]));
57855             } else {
57856                 context.zoomToEntity(d.id);
57857             }
57858         }
57859
57860
57861         function geocoderSearch() {
57862             services.geocoder.search(search.property('value'), function (err, resp) {
57863                 geocodeResults = resp || [];
57864                 drawList();
57865             });
57866         }
57867     }
57868
57869
57870     return featureList;
57871 }
57872
57873 function uiPresetIcon() {
57874     var preset, geometry;
57875
57876
57877     function presetIcon(selection) {
57878         selection.each(render);
57879     }
57880
57881
57882     function getIcon(p, geom) {
57883         if (p.icon)
57884             return p.icon;
57885         else if (geom === 'line')
57886             return 'other-line';
57887         else if (geom === 'vertex')
57888             return p.isFallback() ? '' : 'poi-vertex';
57889         else
57890             return 'marker-stroked';
57891     }
57892
57893
57894     function render() {
57895         var selection = d3_select(this),
57896             p = preset.apply(this, arguments),
57897             geom = geometry.apply(this, arguments),
57898             picon = getIcon(p, geom),
57899             isPoi = picon.match(/^poi-/) !== null,
57900             isMaki = dataFeatureIcons.indexOf(picon) !== -1,
57901             isFramed = (geom === 'area' || geom === 'verex');
57902
57903
57904         function tag_classes(p) {
57905             var s = '';
57906             for (var i in p.tags) {
57907                 s += ' tag-' + i;
57908                 if (p.tags[i] !== '*') {
57909                     s += ' tag-' + i + '-' + p.tags[i];
57910                 }
57911             }
57912             return s;
57913         }
57914
57915
57916         var fill = selection.selectAll('.preset-icon-fill')
57917             .data([0]);
57918
57919         fill = fill.enter()
57920             .append('div')
57921             .merge(fill);
57922
57923         fill
57924             .attr('class', function() {
57925                 return 'preset-icon-fill preset-icon-fill-' + geom + tag_classes(p);
57926             });
57927
57928
57929         var areaFrame = selection.selectAll('.preset-icon-frame')
57930             .data((geom === 'area') ? [0] : []);
57931
57932         areaFrame.exit()
57933             .remove();
57934
57935         areaFrame = areaFrame.enter()
57936             .append('div')
57937             .attr('class', 'preset-icon-frame')
57938             .call(svgIcon('#preset-icon-frame'));
57939
57940
57941         var icon = selection.selectAll('.preset-icon')
57942             .data([0]);
57943
57944         icon = icon.enter()
57945             .append('div')
57946             .attr('class', 'preset-icon')
57947             .call(svgIcon(''))
57948             .merge(icon);
57949
57950         icon
57951             .attr('class', 'preset-icon preset-icon-' +
57952                 ((isMaki || isPoi) ? (isFramed ? '24' : '28') : (isFramed ? '44' : '60'))
57953             );
57954
57955         icon.selectAll('svg')
57956             .attr('class', function() {
57957                 return 'icon ' + picon + (isMaki || isPoi ? '' : tag_classes(p));
57958             });
57959
57960         icon.selectAll('use')
57961             .attr('href', '#' + picon + (isMaki ? '-15' : ''));
57962     }
57963
57964
57965     presetIcon.preset = function(_) {
57966         if (!arguments.length) return preset;
57967         preset = utilFunctor(_);
57968         return presetIcon;
57969     };
57970
57971
57972     presetIcon.geometry = function(_) {
57973         if (!arguments.length) return geometry;
57974         geometry = utilFunctor(_);
57975         return presetIcon;
57976     };
57977
57978     return presetIcon;
57979 }
57980
57981 function d3combobox() {
57982     var dispatch$$1 = dispatch('accept'),
57983         container = d3_select(document.body),
57984         data = [],
57985         suggestions = [],
57986         minItems = 2,
57987         caseSensitive = false;
57988
57989     var fetcher = function(val, cb) {
57990         cb(data.filter(function(d) {
57991             return d.value
57992                 .toString()
57993                 .toLowerCase()
57994                 .indexOf(val.toLowerCase()) !== -1;
57995         }));
57996     };
57997
57998     var combobox = function(input, attachTo) {
57999         var idx = -1,
58000             wrapper = container
58001                 .selectAll('div.combobox')
58002                 .filter(function(d) { return d === input.node(); }),
58003             shown = !wrapper.empty();
58004
58005         input
58006             .classed('combobox-input', true)
58007             .on('focus.typeahead', focus)
58008             .on('blur.typeahead', blur)
58009             .on('keydown.typeahead', keydown)
58010             .on('keyup.typeahead', keyup)
58011             .on('input.typeahead', change)
58012             .each(function() {
58013                 var parent = this.parentNode,
58014                     sibling = this.nextSibling;
58015
58016                 var caret = d3_select(parent).selectAll('.combobox-caret')
58017                     .filter(function(d) { return d === input.node(); })
58018                     .data([input.node()]);
58019
58020                 caret = caret.enter()
58021                   .insert('div', function() { return sibling; })
58022                     .attr('class', 'combobox-caret')
58023                   .merge(caret);
58024
58025                 caret
58026                     .on('mousedown', function () {
58027                         // prevent the form element from blurring. it blurs
58028                         // on mousedown
58029                         event.stopPropagation();
58030                         event.preventDefault();
58031                         if (!shown) {
58032                             input.node().focus();
58033                             fetch('', render);
58034                         } else {
58035                             hide();
58036                         }
58037                     });
58038             });
58039
58040         function focus() {
58041             fetch(value(), render);
58042         }
58043
58044         function blur() {
58045             window.setTimeout(hide, 150);
58046         }
58047
58048         function show() {
58049             if (!shown) {
58050                 wrapper = container
58051                     .insert('div', ':first-child')
58052                     .datum(input.node())
58053                     .attr('class', 'combobox')
58054                     .style('position', 'absolute')
58055                     .style('display', 'block')
58056                     .style('left', '0px')
58057                     .on('mousedown', function () {
58058                         // prevent moving focus out of the text field
58059                         event.preventDefault();
58060                     });
58061
58062                 d3_select('body')
58063                     .on('scroll.combobox', render, true);
58064
58065                 shown = true;
58066             }
58067         }
58068
58069         function hide() {
58070             if (shown) {
58071                 idx = -1;
58072                 wrapper.remove();
58073
58074                 d3_select('body')
58075                     .on('scroll.combobox', null);
58076
58077                 shown = false;
58078             }
58079         }
58080
58081         function keydown() {
58082            switch (event.keyCode) {
58083                // backspace, delete
58084                case 8:
58085                case 46:
58086                    input.on('input.typeahead', function() {
58087                        idx = -1;
58088                        render();
58089                        var start = input.property('selectionStart');
58090                        input.node().setSelectionRange(start, start);
58091                        input.on('input.typeahead', change);
58092                    });
58093                    break;
58094                // tab
58095                case 9:
58096                    wrapper.selectAll('a.selected').each(function (d) {
58097                        dispatch$$1.call('accept', this, d);
58098                    });
58099                    hide();
58100                    break;
58101                // return
58102                case 13:
58103                    event.preventDefault();
58104                    break;
58105                // up arrow
58106                case 38:
58107                    nav(-1);
58108                    event.preventDefault();
58109                    break;
58110                // down arrow
58111                case 40:
58112                    nav(+1);
58113                    event.preventDefault();
58114                    break;
58115            }
58116            event.stopPropagation();
58117         }
58118
58119         function keyup() {
58120             switch (event.keyCode) {
58121                 // escape
58122                 case 27:
58123                     hide();
58124                     break;
58125                 // return
58126                 case 13:
58127                     wrapper.selectAll('a.selected').each(function (d) {
58128                        dispatch$$1.call('accept', this, d);
58129                     });
58130                     hide();
58131                     break;
58132             }
58133         }
58134
58135         function change() {
58136             fetch(value(), function() {
58137                 if (input.property('selectionEnd') === input.property('value').length) {
58138                     autocomplete();
58139                 }
58140                 render();
58141             });
58142         }
58143
58144         function nav(dir) {
58145             if (!suggestions.length) return;
58146             idx = Math.max(Math.min(idx + dir, suggestions.length - 1), 0);
58147             input.property('value', suggestions[idx].value);
58148             render();
58149             ensureVisible();
58150         }
58151
58152         function value() {
58153             var value = input.property('value'),
58154                 start = input.property('selectionStart'),
58155                 end = input.property('selectionEnd');
58156
58157             if (start && end) {
58158                 value = value.substring(0, start);
58159             }
58160
58161             return value;
58162         }
58163
58164         function fetch(v, cb) {
58165             fetcher.call(input, v, function(_) {
58166                 suggestions = _;
58167                 cb();
58168             });
58169         }
58170
58171         function autocomplete() {
58172             var v = caseSensitive ? value() : value().toLowerCase();
58173             idx = -1;
58174             if (!v) return;
58175
58176             for (var i = 0; i < suggestions.length; i++) {
58177                 var suggestion = suggestions[i].value,
58178                     compare = caseSensitive ? suggestion : suggestion.toLowerCase();
58179
58180                 if (compare.indexOf(v) === 0) {
58181                     idx = i;
58182                     input.property('value', suggestion);
58183                     input.node().setSelectionRange(v.length, suggestion.length);
58184                     return;
58185                 }
58186             }
58187         }
58188
58189         function render() {
58190             if (suggestions.length >= minItems && document.activeElement === input.node()) {
58191                 show();
58192             } else {
58193                 hide();
58194                 return;
58195             }
58196
58197             var options = wrapper
58198                 .selectAll('a.combobox-option')
58199                 .data(suggestions, function(d) { return d.value; });
58200
58201             options.exit()
58202                 .remove();
58203
58204             options.enter()
58205                 .append('a')
58206                 .attr('class', 'combobox-option')
58207                 .text(function(d) { return d.value; })
58208                 .merge(options)
58209                 .attr('title', function(d) { return d.title; })
58210                 .classed('selected', function(d, i) { return i === idx; })
58211                 .on('mouseover', select$$1)
58212                 .on('click', accept)
58213                 .order();
58214
58215
58216             var node = attachTo ? attachTo.node() : input.node(),
58217                 rect = node.getBoundingClientRect();
58218
58219             wrapper
58220                 .style('left', rect.left + 'px')
58221                 .style('width', rect.width + 'px')
58222                 .style('top', rect.height + rect.top + 'px');
58223         }
58224
58225         function select$$1(d, i) {
58226             idx = i;
58227             render();
58228         }
58229
58230         function ensureVisible() {
58231             var node = wrapper.selectAll('a.selected').node();
58232             if (node) node.scrollIntoView();
58233         }
58234
58235         function accept(d) {
58236             if (!shown) return;
58237             input.property('value', d.value);
58238             utilTriggerEvent(input, 'change');
58239             dispatch$$1.call('accept', this, d);
58240             hide();
58241         }
58242     };
58243
58244     combobox.fetcher = function(_) {
58245         if (!arguments.length) return fetcher;
58246         fetcher = _;
58247         return combobox;
58248     };
58249
58250     combobox.data = function(_) {
58251         if (!arguments.length) return data;
58252         data = _;
58253         return combobox;
58254     };
58255
58256     combobox.minItems = function(_) {
58257         if (!arguments.length) return minItems;
58258         minItems = _;
58259         return combobox;
58260     };
58261
58262     combobox.caseSensitive = function(_) {
58263         if (!arguments.length) return caseSensitive;
58264         caseSensitive = _;
58265         return combobox;
58266     };
58267
58268     combobox.container = function(_) {
58269         if (!arguments.length) return container;
58270         container = _;
58271         return combobox;
58272     };
58273
58274     return utilRebind(combobox, dispatch$$1, 'on');
58275 }
58276
58277
58278 d3combobox.off = function(input) {
58279     input
58280         .on('focus.typeahead', null)
58281         .on('blur.typeahead', null)
58282         .on('keydown.typeahead', null)
58283         .on('keyup.typeahead', null)
58284         .on('input.typeahead', null)
58285         .each(function() {
58286             d3_select(this.parentNode).selectAll('.combobox-caret')
58287                 .filter(function(d) { return d === input.node(); })
58288                 .on('mousedown', null);
58289         });
58290
58291     d3_select('body')
58292         .on('scroll.combobox', null);
58293 };
58294
58295 function uiDisclosure() {
58296     var dispatch$$1 = dispatch('toggled'),
58297         title,
58298         expanded = false,
58299         content = function () {};
58300
58301
58302     var disclosure = function(selection) {
58303         var hideToggle = selection.selectAll('.hide-toggle')
58304             .data([0]);
58305
58306         hideToggle = hideToggle.enter()
58307             .append('a')
58308             .attr('href', '#')
58309             .attr('class', 'hide-toggle')
58310             .merge(hideToggle);
58311
58312         hideToggle
58313             .text(title)
58314             .on('click', toggle)
58315             .classed('expanded', expanded);
58316
58317
58318         var wrap = selection.selectAll('div')
58319             .data([0]);
58320
58321         wrap = wrap.enter()
58322             .append('div')
58323             .merge(wrap);
58324
58325         wrap
58326             .classed('hide', !expanded)
58327             .call(content);
58328
58329
58330         function toggle() {
58331             expanded = !expanded;
58332             hideToggle.classed('expanded', expanded);
58333             wrap.call(uiToggle(expanded));
58334             dispatch$$1.call('toggled', this, expanded);
58335         }
58336     };
58337
58338
58339     disclosure.title = function(_) {
58340         if (!arguments.length) return title;
58341         title = _;
58342         return disclosure;
58343     };
58344
58345
58346     disclosure.expanded = function(_) {
58347         if (!arguments.length) return expanded;
58348         expanded = _;
58349         return disclosure;
58350     };
58351
58352
58353     disclosure.content = function(_) {
58354         if (!arguments.length) return content;
58355         content = _;
58356         return disclosure;
58357     };
58358
58359
58360     return utilRebind(disclosure, dispatch$$1, 'on');
58361 }
58362
58363 function uiRawMemberEditor(context) {
58364     var id,
58365         taginfo = services.taginfo;
58366
58367
58368     function selectMember(d) {
58369         event.preventDefault();
58370         context.enter(modeSelect(context, [d.id]));
58371     }
58372
58373
58374     function changeRole(d) {
58375         var role = d3_select(this).property('value');
58376         var member = { id: d.id, type: d.type, role: role };
58377         context.perform(
58378             actionChangeMember(d.relation.id, member, d.index),
58379             t('operations.change_role.annotation')
58380         );
58381     }
58382
58383
58384     function deleteMember(d) {
58385         context.perform(
58386             actionDeleteMember(d.relation.id, d.index),
58387             t('operations.delete_member.annotation')
58388         );
58389
58390         if (!context.hasEntity(d.relation.id)) {
58391             context.enter(modeBrowse(context));
58392         }
58393     }
58394
58395
58396     function rawMemberEditor(selection) {
58397         var entity = context.entity(id),
58398             memberships = [];
58399
58400         entity.members.slice(0, 1000).forEach(function(member, index) {
58401             memberships.push({
58402                 index: index,
58403                 id: member.id,
58404                 type: member.type,
58405                 role: member.role,
58406                 relation: entity,
58407                 member: context.hasEntity(member.id)
58408             });
58409         });
58410
58411         var gt = entity.members.length > 1000 ? '>' : '';
58412         selection.call(uiDisclosure()
58413             .title(t('inspector.all_members') + ' (' + gt + memberships.length + ')')
58414             .expanded(true)
58415             .on('toggled', toggled)
58416             .content(content)
58417         );
58418
58419
58420         function toggled(expanded) {
58421             if (expanded) {
58422                 selection.node().parentNode.scrollTop += 200;
58423             }
58424         }
58425
58426
58427         function content(wrap) {
58428             var list = wrap.selectAll('.member-list')
58429                 .data([0]);
58430
58431             list = list.enter()
58432                 .append('ul')
58433                 .attr('class', 'member-list')
58434                 .merge(list);
58435
58436
58437             var items = list.selectAll('li')
58438                 .data(memberships, function(d) {
58439                     return osmEntity.key(d.relation) + ',' + d.index + ',' +
58440                         (d.member ? osmEntity.key(d.member) : 'incomplete');
58441                 });
58442
58443             items.exit()
58444                 .each(unbind)
58445                 .remove();
58446
58447             var enter = items.enter()
58448                 .append('li')
58449                 .attr('class', 'member-row form-field')
58450                 .classed('member-incomplete', function(d) { return !d.member; });
58451
58452             enter
58453                 .each(function(d) {
58454                     if (d.member) {
58455                         var label = d3_select(this).append('label')
58456                             .attr('class', 'form-label')
58457                             .append('a')
58458                             .attr('href', '#')
58459                             .on('click', selectMember);
58460
58461                         label.append('span')
58462                             .attr('class', 'member-entity-type')
58463                             .text(function(d) {
58464                                 var matched = context.presets().match(d.member, context.graph());
58465                                 return (matched && matched.name()) || utilDisplayType(d.member.id);
58466                             });
58467
58468                         label.append('span')
58469                             .attr('class', 'member-entity-name')
58470                             .text(function(d) { return utilDisplayName(d.member); });
58471
58472                     } else {
58473                         d3_select(this).append('label')
58474                             .attr('class', 'form-label')
58475                             .text(t('inspector.incomplete', { id: d.id }));
58476                     }
58477                 });
58478
58479             enter
58480                 .append('input')
58481                 .attr('class', 'member-role')
58482                 .property('type', 'text')
58483                 .attr('maxlength', 255)
58484                 .attr('placeholder', t('inspector.role'))
58485                 .call(utilNoAuto)
58486                 .property('value', function(d) { return d.role; })
58487                 .on('change', changeRole);
58488
58489             enter
58490                 .append('button')
58491                 .attr('tabindex', -1)
58492                 .attr('class', 'remove button-input-action member-delete minor')
58493                 .on('click', deleteMember)
58494                 .call(svgIcon('#operation-delete'));
58495
58496             if (taginfo) {
58497                 enter.each(bindTypeahead);
58498             }
58499
58500
58501             function bindTypeahead(d) {
58502                 var row = d3_select(this),
58503                     role = row.selectAll('input.member-role');
58504
58505                 function sort(value, data) {
58506                     var sameletter = [],
58507                         other = [];
58508                     for (var i = 0; i < data.length; i++) {
58509                         if (data[i].value.substring(0, value.length) === value) {
58510                             sameletter.push(data[i]);
58511                         } else {
58512                             other.push(data[i]);
58513                         }
58514                     }
58515                     return sameletter.concat(other);
58516                 }
58517
58518                 role.call(d3combobox()
58519                     .container(context.container())
58520                     .fetcher(function(role, callback) {
58521                         var rtype = entity.tags.type;
58522                         taginfo.roles({
58523                             debounce: true,
58524                             rtype: rtype || '',
58525                             geometry: context.geometry(d.member.id),
58526                             query: role
58527                         }, function(err, data) {
58528                             if (!err) callback(sort(role, data));
58529                         });
58530                     }));
58531             }
58532
58533
58534             function unbind() {
58535                 var row = d3_select(this);
58536
58537                 row.selectAll('input.member-role')
58538                     .call(d3combobox.off);
58539             }
58540         }
58541     }
58542
58543
58544     rawMemberEditor.entityID = function(_) {
58545         if (!arguments.length) return id;
58546         id = _;
58547         return rawMemberEditor;
58548     };
58549
58550
58551     return rawMemberEditor;
58552 }
58553
58554 function uiRawMembershipEditor(context) {
58555     var taginfo = services.taginfo,
58556         id, showBlank;
58557
58558
58559     function selectRelation(d) {
58560         event.preventDefault();
58561         context.enter(modeSelect(context, [d.relation.id]));
58562     }
58563
58564
58565     function changeRole(d) {
58566         var role = d3_select(this).property('value');
58567         context.perform(
58568             actionChangeMember(d.relation.id, assignIn({}, d.member, { role: role }), d.index),
58569             t('operations.change_role.annotation')
58570         );
58571     }
58572
58573
58574     function addMembership(d, role) {
58575         showBlank = false;
58576
58577         if (d.relation) {
58578             context.perform(
58579                 actionAddMember(d.relation.id, { id: id, type: context.entity(id).type, role: role }),
58580                 t('operations.add_member.annotation')
58581             );
58582
58583         } else {
58584             var relation = osmRelation();
58585             context.perform(
58586                 actionAddEntity(relation),
58587                 actionAddMember(relation.id, { id: id, type: context.entity(id).type, role: role }),
58588                 t('operations.add.annotation.relation')
58589             );
58590
58591             context.enter(modeSelect(context, [relation.id]));
58592         }
58593     }
58594
58595
58596     function deleteMembership(d) {
58597         context.perform(
58598             actionDeleteMember(d.relation.id, d.index),
58599             t('operations.delete_member.annotation')
58600         );
58601     }
58602
58603
58604     function relations(q) {
58605         var newRelation = {
58606                 relation: null,
58607                 value: t('inspector.new_relation')
58608             },
58609             result = [],
58610             graph = context.graph();
58611
58612         context.intersects(context.extent()).forEach(function(entity) {
58613             if (entity.type !== 'relation' || entity.id === id)
58614                 return;
58615
58616             var matched = context.presets().match(entity, graph),
58617                 presetName = (matched && matched.name()) || t('inspector.relation'),
58618                 entityName = utilDisplayName(entity) || '';
58619
58620             var value = presetName + ' ' + entityName;
58621             if (q && value.toLowerCase().indexOf(q.toLowerCase()) === -1)
58622                 return;
58623
58624             result.push({
58625                 relation: entity,
58626                 value: value
58627             });
58628         });
58629
58630         result.sort(function(a, b) {
58631             return osmRelation.creationOrder(a.relation, b.relation);
58632         });
58633
58634         // Dedupe identical names by appending relation id - see #2891
58635         var dupeGroups = filter(
58636             groupBy(result, 'value'),
58637             function(v) { return v.length > 1; }
58638         );
58639
58640         dupeGroups.forEach(function(group) {
58641             group.forEach(function(obj) {
58642                 obj.value += ' ' + obj.relation.id;
58643             });
58644         });
58645
58646         result.unshift(newRelation);
58647         return result;
58648     }
58649
58650
58651     function rawMembershipEditor(selection) {
58652         var entity = context.entity(id),
58653             parents = context.graph().parentRelations(entity),
58654             memberships = [];
58655
58656         parents.slice(0, 1000).forEach(function(relation) {
58657             relation.members.forEach(function(member, index) {
58658                 if (member.id === entity.id) {
58659                     memberships.push({ relation: relation, member: member, index: index });
58660                 }
58661             });
58662         });
58663
58664         var gt = parents.length > 1000 ? '>' : '';
58665         selection.call(uiDisclosure()
58666             .title(t('inspector.all_relations') + ' (' + gt + memberships.length + ')')
58667             .expanded(true)
58668             .on('toggled', toggled)
58669             .content(content)
58670         );
58671
58672
58673         function toggled(expanded) {
58674             if (expanded) {
58675                 selection.node().parentNode.scrollTop += 200;
58676             }
58677         }
58678
58679
58680         function content(wrap) {
58681             var list = wrap.selectAll('.member-list')
58682                 .data([0]);
58683
58684             list = list.enter()
58685                 .append('ul')
58686                 .attr('class', 'member-list')
58687                 .merge(list);
58688
58689
58690             var items = list.selectAll('li.member-row-normal')
58691                 .data(memberships, function(d) {
58692                     return osmEntity.key(d.relation) + ',' + d.index;
58693                 });
58694
58695             items.exit()
58696                 .each(unbind)
58697                 .remove();
58698
58699             var enter = items.enter()
58700                 .append('li')
58701                 .attr('class', 'member-row member-row-normal form-field');
58702
58703             var label = enter
58704                 .append('label')
58705                 .attr('class', 'form-label')
58706                 .append('a')
58707                 .attr('href', '#')
58708                 .on('click', selectRelation);
58709
58710             label
58711                 .append('span')
58712                 .attr('class', 'member-entity-type')
58713                 .text(function(d) {
58714                     var matched = context.presets().match(d.relation, context.graph());
58715                     return (matched && matched.name()) || t('inspector.relation');
58716                 });
58717
58718             label
58719                 .append('span')
58720                 .attr('class', 'member-entity-name')
58721                 .text(function(d) { return utilDisplayName(d.relation); });
58722
58723             enter
58724                 .append('input')
58725                 .attr('class', 'member-role')
58726                 .property('type', 'text')
58727                 .attr('maxlength', 255)
58728                 .attr('placeholder', t('inspector.role'))
58729                 .call(utilNoAuto)
58730                 .property('value', function(d) { return d.member.role; })
58731                 .on('change', changeRole);
58732
58733             enter
58734                 .append('button')
58735                 .attr('tabindex', -1)
58736                 .attr('class', 'remove button-input-action member-delete minor')
58737                 .on('click', deleteMembership)
58738                 .call(svgIcon('#operation-delete'));
58739
58740             if (taginfo) {
58741                 enter.each(bindTypeahead);
58742             }
58743
58744
58745             var newrow = list.selectAll('.member-row-new')
58746                 .data(showBlank ? [0] : []);
58747
58748             newrow.exit()
58749                 .remove();
58750
58751             enter = newrow.enter()
58752                 .append('li')
58753                 .attr('class', 'member-row member-row-new form-field');
58754
58755             enter
58756                 .append('input')
58757                 .attr('type', 'text')
58758                 .attr('class', 'member-entity-input')
58759                 .call(utilNoAuto);
58760
58761             enter
58762                 .append('input')
58763                 .attr('class', 'member-role')
58764                 .property('type', 'text')
58765                 .attr('maxlength', 255)
58766                 .attr('placeholder', t('inspector.role'))
58767                 .call(utilNoAuto)
58768                 .on('change', changeRole);
58769
58770             enter
58771                 .append('button')
58772                 .attr('tabindex', -1)
58773                 .attr('class', 'remove button-input-action member-delete minor')
58774                 .on('click', deleteMembership)
58775                 .call(svgIcon('#operation-delete'));
58776
58777             newrow = newrow
58778                 .merge(enter);
58779
58780             newrow.selectAll('.member-entity-input')
58781                 .call(d3combobox()
58782                     .container(context.container())
58783                     .minItems(1)
58784                     .fetcher(function(value, callback) { callback(relations(value)); })
58785                     .on('accept', onAccept)
58786                 );
58787
58788
58789             var addrel = wrap.selectAll('.add-relation')
58790                 .data([0]);
58791
58792             addrel = addrel.enter()
58793                 .append('button')
58794                 .attr('class', 'add-relation')
58795                 .merge(addrel);
58796
58797             addrel
58798                 .call(svgIcon('#icon-plus', 'light'))
58799                 .on('click', function() {
58800                     showBlank = true;
58801                     content(wrap);
58802                     list.selectAll('.member-entity-input').node().focus();
58803                 });
58804
58805
58806             function onAccept(d) {
58807                 var role = list.selectAll('.member-row-new .member-role').property('value');
58808                 addMembership(d, role);
58809             }
58810
58811
58812             function bindTypeahead(d) {
58813                 var row = d3_select(this),
58814                     role = row.selectAll('input.member-role');
58815
58816                 function sort(value, data) {
58817                     var sameletter = [],
58818                         other = [];
58819                     for (var i = 0; i < data.length; i++) {
58820                         if (data[i].value.substring(0, value.length) === value) {
58821                             sameletter.push(data[i]);
58822                         } else {
58823                             other.push(data[i]);
58824                         }
58825                     }
58826                     return sameletter.concat(other);
58827                 }
58828
58829                 role.call(d3combobox()
58830                     .container(context.container())
58831                     .fetcher(function(role, callback) {
58832                         var rtype = d.relation.tags.type;
58833                         taginfo.roles({
58834                             debounce: true,
58835                             rtype: rtype || '',
58836                             geometry: context.geometry(id),
58837                             query: role
58838                         }, function(err, data) {
58839                             if (!err) callback(sort(role, data));
58840                         });
58841                     }));
58842             }
58843
58844
58845             function unbind() {
58846                 var row = d3_select(this);
58847
58848                 row.selectAll('input.member-role')
58849                     .call(d3combobox.off);
58850             }
58851         }
58852     }
58853
58854
58855     rawMembershipEditor.entityID = function(_) {
58856         if (!arguments.length) return id;
58857         id = _;
58858         return rawMembershipEditor;
58859     };
58860
58861
58862     return rawMembershipEditor;
58863 }
58864
58865 function uiTagReference(tag) {
58866     var taginfo = services.taginfo,
58867         tagReference = {},
58868         button = d3_select(null),
58869         body = d3_select(null),
58870         loaded,
58871         showing;
58872
58873
58874     function findLocal(data) {
58875         var locale = utilDetect().locale.toLowerCase(),
58876             localized;
58877
58878         if (locale !== 'pt-br') {  // see #3776, prefer 'pt' over 'pt-br'
58879             localized = find$1(data, function(d) {
58880                 return d.lang.toLowerCase() === locale;
58881             });
58882             if (localized) return localized;
58883         }
58884
58885         // try the non-regional version of a language, like
58886         // 'en' if the language is 'en-US'
58887         if (locale.indexOf('-') !== -1) {
58888             var first = locale.split('-')[0];
58889             localized = find$1(data, function(d) {
58890                 return d.lang.toLowerCase() === first;
58891             });
58892             if (localized) return localized;
58893         }
58894
58895         // finally fall back to english
58896         return find$1(data, function(d) {
58897             return d.lang.toLowerCase() === 'en';
58898         });
58899     }
58900
58901
58902     function load(param) {
58903         if (!taginfo) return;
58904
58905         button
58906             .classed('tag-reference-loading', true);
58907
58908         taginfo.docs(param, function show(err, data) {
58909             var docs;
58910             if (!err && data) {
58911                 docs = findLocal(data);
58912             }
58913
58914             body.html('');
58915
58916             if (!docs || !docs.title) {
58917                 if (param.hasOwnProperty('value')) {
58918                     load(omit(param, 'value'));   // retry with key only
58919                 } else {
58920                     body
58921                         .append('p')
58922                         .attr('class', 'tag-reference-description')
58923                         .text(t('inspector.no_documentation_key'));
58924                     done();
58925                 }
58926                 return;
58927             }
58928
58929             if (docs.image && docs.image.thumb_url_prefix) {
58930                 body
58931                     .append('img')
58932                     .attr('class', 'tag-reference-wiki-image')
58933                     .attr('src', docs.image.thumb_url_prefix + '100' + docs.image.thumb_url_suffix)
58934                     .on('load', function() { done(); })
58935                     .on('error', function() { d3_select(this).remove(); done(); });
58936             } else {
58937                 done();
58938             }
58939
58940             body
58941                 .append('p')
58942                 .attr('class', 'tag-reference-description')
58943                 .text(docs.description || t('inspector.documentation_redirect'));
58944
58945             body
58946                 .append('a')
58947                 .attr('class', 'tag-reference-link')
58948                 .attr('target', '_blank')
58949                 .attr('tabindex', -1)
58950                 .attr('href', 'https://wiki.openstreetmap.org/wiki/' + docs.title)
58951                 .call(svgIcon('#icon-out-link', 'inline'))
58952                 .append('span')
58953                 .text(t('inspector.reference'));
58954
58955             // Add link to info about "good changeset comments" - #2923
58956             if (param.key === 'comment') {
58957                 body
58958                     .append('a')
58959                     .attr('class', 'tag-reference-comment-link')
58960                     .attr('target', '_blank')
58961                     .attr('tabindex', -1)
58962                     .call(svgIcon('#icon-out-link', 'inline'))
58963                     .attr('href', t('commit.about_changeset_comments_link'))
58964                     .append('span')
58965                     .text(t('commit.about_changeset_comments'));
58966             }
58967         });
58968     }
58969
58970
58971     function done() {
58972         loaded = true;
58973
58974         button
58975             .classed('tag-reference-loading', false);
58976
58977         body
58978             .classed('expanded', true)
58979             .transition()
58980             .duration(200)
58981             .style('max-height', '200px')
58982             .style('opacity', '1');
58983
58984         showing = true;
58985     }
58986
58987
58988     function hide() {
58989         body
58990             .transition()
58991             .duration(200)
58992             .style('max-height', '0px')
58993             .style('opacity', '0')
58994             .on('end', function () {
58995                 body.classed('expanded', false);
58996             });
58997
58998         showing = false;
58999     }
59000
59001
59002     tagReference.button = function(selection) {
59003         button = selection.selectAll('.tag-reference-button')
59004             .data([0]);
59005
59006         button = button.enter()
59007             .append('button')
59008             .attr('class', 'tag-reference-button')
59009             .attr('tabindex', -1)
59010             .call(svgIcon('#icon-inspect'))
59011             .merge(button);
59012
59013         button
59014             .on('click', function () {
59015                 event.stopPropagation();
59016                 event.preventDefault();
59017                 if (showing) {
59018                     hide();
59019                 } else if (loaded) {
59020                     done();
59021                 } else {
59022                     load(tag);
59023                 }
59024             });
59025     };
59026
59027
59028     tagReference.body = function(selection) {
59029
59030         var tagid = tag.rtype || (tag.key + '-' + tag.value);
59031
59032         body = selection.selectAll('.tag-reference-body')
59033             .data([tagid], function(d) { return d; });
59034
59035         body.exit()
59036             .remove();
59037
59038         body = body.enter()
59039             .append('div')
59040             .attr('class', 'tag-reference-body cf')
59041             .style('max-height', '0')
59042             .style('opacity', '0')
59043             .merge(body);
59044
59045         if (showing === false) {
59046             hide();
59047         }
59048     };
59049
59050
59051     tagReference.showing = function(_) {
59052         if (!arguments.length) return showing;
59053         showing = _;
59054         return tagReference;
59055     };
59056
59057
59058     return tagReference;
59059 }
59060
59061 function uiRawTagEditor(context) {
59062     var taginfo = services.taginfo,
59063         dispatch$$1 = dispatch('change'),
59064         expandedPreference = (context.storage('raw_tag_editor.expanded') === 'true'),
59065         expandedCurrent = expandedPreference,
59066         updatePreference = true,
59067         readOnlyTags = [],
59068         showBlank = false,
59069         newRow,
59070         state,
59071         preset,
59072         tags,
59073         id;
59074
59075
59076     function rawTagEditor(selection) {
59077         var count = Object.keys(tags).filter(function(d) { return d; }).length;
59078
59079         selection.call(uiDisclosure()
59080             .title(t('inspector.all_tags') + ' (' + count + ')')
59081             .expanded(expandedCurrent)
59082             .on('toggled', toggled)
59083             .content(content)
59084         );
59085
59086         function toggled(expanded) {
59087             expandedCurrent = expanded;
59088             if (updatePreference) {
59089                 expandedPreference = expanded;
59090                 context.storage('raw_tag_editor.expanded', expanded);
59091             }
59092             if (expanded) {
59093                 selection.node().parentNode.scrollTop += 200;
59094             }
59095         }
59096     }
59097
59098
59099     function content(wrap) {
59100         var entries = map$4(tags, function(v, k) {
59101             return { key: k, value: v };
59102         });
59103
59104         if (!entries.length || showBlank) {
59105             showBlank = false;
59106             entries.push({key: '', value: ''});
59107             newRow = '';
59108         }
59109
59110         var list = wrap.selectAll('.tag-list')
59111             .data([0]);
59112
59113         list = list.enter()
59114             .append('ul')
59115             .attr('class', 'tag-list')
59116             .merge(list);
59117
59118         var newTag = wrap.selectAll('.add-tag')
59119             .data([0]);
59120
59121         newTag.enter()
59122             .append('button')
59123             .attr('class', 'add-tag')
59124             .on('click', addTag)
59125             .call(svgIcon('#icon-plus', 'light'));
59126
59127
59128         var items = list.selectAll('.tag-row')
59129             .data(entries, function(d) { return d.key; });
59130
59131         items.exit()
59132             .each(unbind)
59133             .remove();
59134
59135         // Enter
59136
59137         var enter = items.enter()
59138             .append('li')
59139             .attr('class', 'tag-row cf')
59140             .classed('readonly', isReadOnly);
59141
59142         enter
59143             .append('div')
59144             .attr('class', 'key-wrap')
59145             .append('input')
59146             .property('type', 'text')
59147             .attr('class', 'key')
59148             .attr('maxlength', 255)
59149             .call(utilNoAuto)
59150             .on('blur', keyChange)
59151             .on('change', keyChange);
59152
59153         enter
59154             .append('div')
59155             .attr('class', 'input-wrap-position')
59156             .append('input')
59157             .property('type', 'text')
59158             .attr('class', 'value')
59159             .attr('maxlength', 255)
59160             .call(utilNoAuto)
59161             .on('blur', valueChange)
59162             .on('change', valueChange)
59163             .on('keydown.push-more', pushMore);
59164
59165         enter
59166             .append('button')
59167             .attr('tabindex', -1)
59168             .attr('class', 'remove minor')
59169             .call(svgIcon('#operation-delete'));
59170
59171
59172         // Update
59173
59174         items = items
59175             .merge(enter)
59176             .sort(function(a, b) {
59177                 return (a.key === newRow && b.key !== newRow) ? 1
59178                     : (a.key !== newRow && b.key === newRow) ? -1
59179                     : d3_ascending(a.key, b.key);
59180             });
59181
59182         items
59183             .each(function(tag) {
59184                 var row = d3_select(this),
59185                     key = row.select('input.key'),      // propagate bound data to child
59186                     value = row.select('input.value');  // propagate bound data to child
59187
59188                 if (id && taginfo) {
59189                     bindTypeahead(key, value);
59190                 }
59191
59192                 var isRelation = (id && context.entity(id).type === 'relation'),
59193                     reference;
59194
59195                 if (isRelation && tag.key === 'type') {
59196                     reference = uiTagReference({ rtype: tag.value }, context);
59197                 } else {
59198                     reference = uiTagReference({ key: tag.key, value: tag.value }, context);
59199                 }
59200
59201                 if (state === 'hover') {
59202                     reference.showing(false);
59203                 }
59204
59205                 row
59206                     .call(reference.button)
59207                     .call(reference.body);
59208             });
59209
59210         items.selectAll('input.key')
59211             .attr('title', function(d) { return d.key; })
59212             .call(utilGetSetValue, function(d) { return d.key; })
59213             .property('disabled', isReadOnly);
59214
59215         items.selectAll('input.value')
59216             .attr('title', function(d) { return d.value; })
59217             .call(utilGetSetValue, function(d) { return d.value; })
59218             .property('disabled', isReadOnly);
59219
59220         items.selectAll('button.remove')
59221             .on('click', removeTag);
59222
59223
59224
59225         function isReadOnly(d) {
59226             for (var i = 0; i < readOnlyTags.length; i++) {
59227                 if (d.key.match(readOnlyTags[i]) !== null) {
59228                     return true;
59229                 }
59230             }
59231             return false;
59232         }
59233
59234
59235         function pushMore() {
59236             if (event.keyCode === 9 && !event.shiftKey &&
59237                 list.selectAll('li:last-child input.value').node() === this) {
59238                 addTag();
59239             }
59240         }
59241
59242
59243         function bindTypeahead(key, value) {
59244             if (isReadOnly({ key: key })) return;
59245             var geometry = context.geometry(id);
59246
59247             key.call(d3combobox()
59248                 .container(context.container())
59249                 .fetcher(function(value, callback) {
59250                     taginfo.keys({
59251                         debounce: true,
59252                         geometry: geometry,
59253                         query: value
59254                     }, function(err, data) {
59255                         if (!err) callback(sort(value, data));
59256                     });
59257                 }));
59258
59259             value.call(d3combobox()
59260                 .container(context.container())
59261                 .fetcher(function(value, callback) {
59262                     taginfo.values({
59263                         debounce: true,
59264                         key: utilGetSetValue(key),
59265                         geometry: geometry,
59266                         query: value
59267                     }, function(err, data) {
59268                         if (!err) callback(sort(value, data));
59269                     });
59270                 }));
59271
59272
59273             function sort(value, data) {
59274                 var sameletter = [],
59275                     other = [];
59276                 for (var i = 0; i < data.length; i++) {
59277                     if (data[i].value.substring(0, value.length) === value) {
59278                         sameletter.push(data[i]);
59279                     } else {
59280                         other.push(data[i]);
59281                     }
59282                 }
59283                 return sameletter.concat(other);
59284             }
59285         }
59286
59287
59288         function unbind() {
59289             var row = d3_select(this);
59290
59291             row.selectAll('input.key')
59292                 .call(d3combobox.off);
59293
59294             row.selectAll('input.value')
59295                 .call(d3combobox.off);
59296         }
59297
59298
59299         function keyChange(d) {
59300             var kOld = d.key,
59301                 kNew = this.value.trim(),
59302                 tag = {};
59303
59304
59305             if (isReadOnly({ key: kNew })) {
59306                 this.value = kOld;
59307                 return;
59308             }
59309
59310             if (kNew && kNew !== kOld) {
59311                 var match = kNew.match(/^(.*?)(?:_(\d+))?$/),
59312                     base = match[1],
59313                     suffix = +(match[2] || 1);
59314                 while (tags[kNew]) {  // rename key if already in use
59315                     kNew = base + '_' + suffix++;
59316                 }
59317             }
59318             tag[kOld] = undefined;
59319             tag[kNew] = d.value;
59320
59321             d.key = kNew; // Maintain DOM identity through the subsequent update.
59322
59323             if (newRow === kOld) {  // see if this row is still a new row
59324                 newRow = ((d.value === '' || kNew === '') ? kNew : undefined);
59325             }
59326
59327             this.value = kNew;
59328             dispatch$$1.call('change', this, tag);
59329         }
59330
59331
59332         function valueChange(d) {
59333             if (isReadOnly(d)) return;
59334             var tag = {};
59335             tag[d.key] = this.value;
59336
59337             if (newRow === d.key && d.key !== '' && d.value !== '') {   // not a new row anymore
59338                 newRow = undefined;
59339             }
59340
59341             dispatch$$1.call('change', this, tag);
59342         }
59343
59344
59345         function removeTag(d) {
59346             if (isReadOnly(d)) return;
59347             var tag = {};
59348             tag[d.key] = undefined;
59349             dispatch$$1.call('change', this, tag);
59350             d3_select(this.parentNode).remove();
59351         }
59352
59353
59354         function addTag() {
59355             // Wrapped in a setTimeout in case it's being called from a blur
59356             // handler. Without the setTimeout, the call to `content` would
59357             // wipe out the pending value change.
59358             setTimeout(function() {
59359                 showBlank = true;
59360                 content(wrap);
59361                 list.selectAll('li:last-child input.key').node().focus();
59362             }, 0);
59363         }
59364     }
59365
59366
59367     rawTagEditor.state = function(_) {
59368         if (!arguments.length) return state;
59369         state = _;
59370         return rawTagEditor;
59371     };
59372
59373
59374     rawTagEditor.preset = function(_) {
59375         if (!arguments.length) return preset;
59376         preset = _;
59377         if (preset.isFallback()) {
59378             expandedCurrent = true;
59379             updatePreference = false;
59380         } else {
59381             expandedCurrent = expandedPreference;
59382             updatePreference = true;
59383         }
59384         return rawTagEditor;
59385     };
59386
59387
59388     rawTagEditor.tags = function(_) {
59389         if (!arguments.length) return tags;
59390         tags = _;
59391         return rawTagEditor;
59392     };
59393
59394
59395     rawTagEditor.entityID = function(_) {
59396         if (!arguments.length) return id;
59397         id = _;
59398         return rawTagEditor;
59399     };
59400
59401
59402     rawTagEditor.expanded = function(_) {
59403         if (!arguments.length) return expandedCurrent;
59404         expandedCurrent = _;
59405         updatePreference = false;
59406         return rawTagEditor;
59407     };
59408
59409
59410     rawTagEditor.readOnlyTags = function(_) {
59411         if (!arguments.length) return readOnlyTags;
59412         readOnlyTags = _;
59413         return rawTagEditor;
59414     };
59415
59416
59417     return utilRebind(rawTagEditor, dispatch$$1, 'on');
59418 }
59419
59420 function uiFieldCheck(field, context) {
59421     var dispatch$$1 = dispatch('change'),
59422         options = field.strings && field.strings.options,
59423         values = [],
59424         texts = [],
59425         input = d3_select(null),
59426         text = d3_select(null),
59427         label = d3_select(null),
59428         reverser = d3_select(null),
59429         impliedYes,
59430         entityId,
59431         value;
59432
59433
59434     if (options) {
59435         for (var k in options) {
59436             values.push(k === 'undefined' ? undefined : k);
59437             texts.push(field.t('options.' + k, { 'default': options[k] }));
59438         }
59439     } else {
59440         values = [undefined, 'yes'];
59441         texts = [t('inspector.unknown'), t('inspector.check.yes')];
59442         if (field.type !== 'defaultCheck') {
59443             values.push('no');
59444             texts.push(t('inspector.check.no'));
59445         }
59446     }
59447
59448
59449     // Checks tags to see whether an undefined value is "Assumed to be Yes"
59450     function checkImpliedYes() {
59451         impliedYes = (field.id === 'oneway_yes');
59452
59453         // hack: pretend `oneway` field is a `oneway_yes` field
59454         // where implied oneway tag exists (e.g. `junction=roundabout`) #2220, #1841
59455         if (field.id === 'oneway') {
59456             var entity = context.entity(entityId);
59457             for (var key in entity.tags) {
59458                 if (key in osmOneWayTags && (entity.tags[key] in osmOneWayTags[key])) {
59459                     impliedYes = true;
59460                     texts[0] = t('presets.fields.oneway_yes.options.undefined');
59461                     break;
59462                 }
59463             }
59464         }
59465     }
59466
59467
59468     function reverserHidden() {
59469         if (!d3_select('div.inspector-hover').empty()) return true;
59470         return !(value === 'yes' || (impliedYes && !value));
59471     }
59472
59473
59474     function reverserSetText(selection) {
59475         var entity = context.hasEntity(entityId);
59476         if (reverserHidden() || !entity) return selection;
59477
59478         var first = entity.first(),
59479             last = entity.isClosed() ? entity.nodes[entity.nodes.length - 2] : entity.last(),
59480             pseudoDirection = first < last,
59481             icon = pseudoDirection ? '#icon-forward' : '#icon-backward';
59482
59483         selection.selectAll('.reverser-span')
59484             .text(t('inspector.check.reverser'))
59485             .call(svgIcon(icon, 'inline'));
59486
59487         return selection;
59488     }
59489
59490
59491     var check = function(selection) {
59492         checkImpliedYes();
59493         selection.classed('checkselect', 'true');
59494
59495         label = selection.selectAll('.preset-input-wrap')
59496             .data([0]);
59497
59498         var enter = label.enter()
59499             .append('label')
59500             .attr('class', 'preset-input-wrap');
59501
59502         enter
59503             .append('input')
59504             .property('indeterminate', field.type !== 'defaultCheck')
59505             .attr('type', 'checkbox')
59506             .attr('id', 'preset-input-' + field.id);
59507
59508         enter
59509             .append('span')
59510             .text(texts[0])
59511             .attr('class', 'value');
59512
59513         if (field.type === 'onewayCheck') {
59514             enter
59515                 .append('a')
59516                 .attr('id', 'preset-input-' + field.id + '-reverser')
59517                 .attr('class', 'reverser button' + (reverserHidden() ? ' hide' : ''))
59518                 .attr('href', '#')
59519                 .append('span')
59520                 .attr('class', 'reverser-span');
59521         }
59522
59523         label = label.merge(enter);
59524         input = label.selectAll('input');
59525         text = label.selectAll('span.value');
59526
59527         input
59528             .on('click', function() {
59529                 var t$$1 = {};
59530                 t$$1[field.key] = values[(values.indexOf(value) + 1) % values.length];
59531                 dispatch$$1.call('change', this, t$$1);
59532                 event.stopPropagation();
59533             });
59534
59535         if (field.type === 'onewayCheck') {
59536             reverser = label.selectAll('.reverser');
59537
59538             reverser
59539                 .call(reverserSetText)
59540                 .on('click', function() {
59541                     event.preventDefault();
59542                     event.stopPropagation();
59543                     context.perform(
59544                         actionReverse(entityId),
59545                         t('operations.reverse.annotation')
59546                     );
59547                     d3_select(this)
59548                         .call(reverserSetText);
59549                 });
59550         }
59551     };
59552
59553
59554     check.entity = function(_) {
59555         if (!arguments.length) return context.hasEntity(entityId);
59556         entityId = _.id;
59557         return check;
59558     };
59559
59560
59561     check.tags = function(tags) {
59562         checkImpliedYes();
59563         value = tags[field.key] && tags[field.key].toLowerCase();
59564
59565         if (field.type === 'onewayCheck' && (value === '1' || value === '-1')) {
59566             value = 'yes';
59567         }
59568
59569         input
59570             .property('indeterminate', field.type !== 'defaultCheck' && !value)
59571             .property('checked', value === 'yes');
59572
59573         text
59574             .text(texts[values.indexOf(value)]);
59575
59576         label
59577             .classed('set', !!value);
59578
59579         if (field.type === 'onewayCheck') {
59580             reverser
59581                 .classed('hide', reverserHidden())
59582                 .call(reverserSetText);
59583         }
59584     };
59585
59586
59587     check.focus = function() {
59588         input.node().focus();
59589     };
59590
59591     return utilRebind(check, dispatch$$1, 'on');
59592 }
59593
59594 /** Used for built-in method references. */
59595 var arrayProto$1 = Array.prototype;
59596
59597 /** Built-in value references. */
59598 var splice$1 = arrayProto$1.splice;
59599
59600 /**
59601  * The base implementation of `_.pullAt` without support for individual
59602  * indexes or capturing the removed elements.
59603  *
59604  * @private
59605  * @param {Array} array The array to modify.
59606  * @param {number[]} indexes The indexes of elements to remove.
59607  * @returns {Array} Returns `array`.
59608  */
59609 function basePullAt(array, indexes) {
59610   var length = array ? indexes.length : 0,
59611       lastIndex = length - 1;
59612
59613   while (length--) {
59614     var index = indexes[length];
59615     if (length == lastIndex || index !== previous) {
59616       var previous = index;
59617       if (isIndex(index)) {
59618         splice$1.call(array, index, 1);
59619       } else {
59620         baseUnset(array, index);
59621       }
59622     }
59623   }
59624   return array;
59625 }
59626
59627 /**
59628  * Removes all elements from `array` that `predicate` returns truthy for
59629  * and returns an array of the removed elements. The predicate is invoked
59630  * with three arguments: (value, index, array).
59631  *
59632  * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
59633  * to pull elements from an array by value.
59634  *
59635  * @static
59636  * @memberOf _
59637  * @since 2.0.0
59638  * @category Array
59639  * @param {Array} array The array to modify.
59640  * @param {Function} [predicate=_.identity] The function invoked per iteration.
59641  * @returns {Array} Returns the new array of removed elements.
59642  * @example
59643  *
59644  * var array = [1, 2, 3, 4];
59645  * var evens = _.remove(array, function(n) {
59646  *   return n % 2 == 0;
59647  * });
59648  *
59649  * console.log(array);
59650  * // => [1, 3]
59651  *
59652  * console.log(evens);
59653  * // => [2, 4]
59654  */
59655 function remove$8(array, predicate) {
59656   var result = [];
59657   if (!(array && array.length)) {
59658     return result;
59659   }
59660   var index = -1,
59661       indexes = [],
59662       length = array.length;
59663
59664   predicate = baseIteratee(predicate, 3);
59665   while (++index < length) {
59666     var value = array[index];
59667     if (predicate(value, index, array)) {
59668       result.push(value);
59669       indexes.push(index);
59670     }
59671   }
59672   basePullAt(array, indexes);
59673   return result;
59674 }
59675
59676 function uiFieldCombo(field, context) {
59677     var dispatch$$1 = dispatch('change'),
59678         nominatim = services.geocoder,
59679         taginfo = services.taginfo,
59680         isMulti = (field.type === 'multiCombo'),
59681         isNetwork = (field.type === 'networkCombo'),
59682         isSemi = (field.type === 'semiCombo'),
59683         optstrings = field.strings && field.strings.options,
59684         optarray = field.options,
59685         snake_case = (field.snake_case || (field.snake_case === undefined)),
59686         combobox = d3combobox()
59687             .container(context.container())
59688             .minItems(isMulti || isSemi ? 1 : 2),
59689         comboData = [],
59690         multiData = [],
59691         container,
59692         input,
59693         entity,
59694         country;
59695
59696     // ensure multiCombo field.key ends with a ':'
59697     if (isMulti && field.key.match(/:$/) === null) {
59698         field.key += ':';
59699     }
59700
59701
59702     function snake(s) {
59703         return s.replace(/\s+/g, '_');
59704     }
59705
59706     function unsnake(s) {
59707         return s.replace(/_+/g, ' ');
59708     }
59709
59710     function clean(s) {
59711         return s.split(';')
59712             .map(function(s) { return s.trim(); })
59713             .join(';');
59714     }
59715
59716
59717     // returns the tag value for a display value
59718     // (for multiCombo, dval should be the key suffix, not the entire key)
59719     function tagValue(dval) {
59720         dval = clean(dval || '');
59721
59722         if (optstrings) {
59723             var match = find$1(comboData, function(o) {
59724                 return o.key && clean(o.value) === dval;
59725             });
59726             if (match) {
59727                 return match.key;
59728             }
59729         }
59730
59731         if (field.type === 'typeCombo' && !dval) {
59732             return 'yes';
59733         }
59734
59735         return (snake_case ? snake(dval) : dval) || undefined;
59736     }
59737
59738
59739     // returns the display value for a tag value
59740     // (for multiCombo, tval should be the key suffix, not the entire key)
59741     function displayValue(tval) {
59742         tval = tval || '';
59743
59744         if (optstrings) {
59745             var match = find$1(comboData, function(o) { return o.key === tval && o.value; });
59746             if (match) {
59747                 return match.value;
59748             }
59749         }
59750
59751         if (field.type === 'typeCombo' && tval.toLowerCase() === 'yes') {
59752             return '';
59753         }
59754
59755         return snake_case ? unsnake(tval) : tval;
59756     }
59757
59758
59759     function objectDifference(a, b) {
59760         return reject(a, function(d1) {
59761             return some(b, function(d2) { return d1.value === d2.value; });
59762         });
59763     }
59764
59765
59766     function initCombo(selection, attachTo) {
59767         if (optstrings) {
59768             selection.attr('readonly', 'readonly');
59769             selection.call(combobox, attachTo);
59770             setStaticValues(setPlaceholder);
59771
59772         } else if (optarray) {
59773             selection.call(combobox, attachTo);
59774             setStaticValues(setPlaceholder);
59775
59776         } else if (taginfo) {
59777             selection.call(combobox.fetcher(setTaginfoValues), attachTo);
59778             setTaginfoValues('', setPlaceholder);
59779         }
59780     }
59781
59782
59783     function setStaticValues(callback) {
59784         if (!(optstrings || optarray)) return;
59785
59786         if (optstrings) {
59787             comboData = Object.keys(optstrings).map(function(k) {
59788                 var v = field.t('options.' + k, { 'default': optstrings[k] });
59789                 return {
59790                     key: k,
59791                     value: v,
59792                     title: v
59793                 };
59794             });
59795
59796         } else if (optarray) {
59797             comboData = optarray.map(function(k) {
59798                 var v = snake_case ? unsnake(k) : k;
59799                 return {
59800                     key: k,
59801                     value: v,
59802                     title: v
59803                 };
59804             });
59805         }
59806
59807         combobox.data(objectDifference(comboData, multiData));
59808         if (callback) callback(comboData);
59809     }
59810
59811
59812     function setTaginfoValues(q, callback) {
59813         var fn = isMulti ? 'multikeys' : 'values';
59814         var query = (isMulti ? field.key : '') + q;
59815         var hasCountryPrefix = isNetwork && country && country.indexOf(q.toLowerCase()) === 0;
59816         if (hasCountryPrefix) {
59817             query = country + ':';
59818         }
59819
59820         var params = {
59821             debounce: (q !== ''),
59822             key: field.key,
59823             query: query
59824         };
59825
59826         if (entity) {
59827             params.geometry = context.geometry(entity.id);
59828         }
59829
59830         taginfo[fn](params, function(err, data) {
59831             if (err) return;
59832             if (hasCountryPrefix) {
59833                 data = filter(data, function(d) {
59834                     return d.value.toLowerCase().indexOf(country + ':') === 0;
59835                 });
59836             }
59837
59838             comboData = map$4(data, function(d) {
59839                 var k = d.value;
59840                 if (isMulti) k = k.replace(field.key, '');
59841                 var v = snake_case ? unsnake(k) : k;
59842                 return {
59843                     key: k,
59844                     value: v,
59845                     title: isMulti ? v : d.title
59846                 };
59847             });
59848
59849             comboData = objectDifference(comboData, multiData);
59850             if (callback) callback(comboData);
59851         });
59852     }
59853
59854
59855     function setPlaceholder(d) {
59856         var ph;
59857
59858         if (isMulti || isSemi) {
59859             ph = field.placeholder() || t('inspector.add');
59860         } else {
59861             var vals = map$4(d, 'value').filter(function(s) { return s.length < 20; }),
59862                 placeholders = vals.length > 1 ? vals : map$4(d, 'key');
59863             ph = field.placeholder() || placeholders.slice(0, 3).join(', ');
59864         }
59865
59866         if (ph.match(/(…|\.\.\.)$/) === null) {
59867             ph += '…';
59868         }
59869
59870         container.selectAll('input')
59871             .attr('placeholder', ph);
59872     }
59873
59874
59875     function change() {
59876         var val = tagValue(utilGetSetValue(input)),
59877             t$$1 = {};
59878
59879         if (isMulti || isSemi) {
59880             if (!val) return;
59881             container.classed('active', false);
59882             utilGetSetValue(input, '');
59883             if (isMulti) {
59884                 field.keys.push(field.key + val);
59885                 t$$1[field.key + val] = 'yes';
59886             } else if (isSemi) {
59887                 var arr = multiData.map(function(d) { return d.key; });
59888                 arr.push(val);
59889                 t$$1[field.key] = compact(uniq(arr)).join(';');
59890             }
59891             window.setTimeout(function() { input.node().focus(); }, 10);
59892
59893         } else {
59894             t$$1[field.key] = val;
59895         }
59896
59897         dispatch$$1.call('change', this, t$$1);
59898     }
59899
59900
59901     function removeMultikey(d) {
59902         event.stopPropagation();
59903         var t$$1 = {};
59904         if (isMulti) {
59905             t$$1[d.key] = undefined;
59906         } else if (isSemi) {
59907             remove$8(multiData, function(md) { return md.key === d.key; });
59908             var arr = multiData.map(function(md) { return md.key; });
59909             arr = compact(uniq(arr));
59910             t$$1[field.key] = arr.length ? arr.join(';') : undefined;
59911         }
59912         dispatch$$1.call('change', this, t$$1);
59913     }
59914
59915
59916     function combo(selection) {
59917         if (isMulti || isSemi) {
59918             container = selection.selectAll('ul').data([0]);
59919
59920             container = container.enter()
59921                 .append('ul')
59922                 .attr('class', 'form-field-multicombo')
59923                 .on('click', function() {
59924                     window.setTimeout(function() { input.node().focus(); }, 10);
59925                 })
59926                 .merge(container);
59927
59928         } else {
59929             container = selection;
59930         }
59931
59932         input = container.selectAll('input')
59933             .data([0]);
59934
59935         input = input.enter()
59936             .append('input')
59937             .attr('type', 'text')
59938             .attr('id', 'preset-input-' + field.id)
59939             .call(utilNoAuto)
59940             .call(initCombo, selection)
59941             .merge(input);
59942
59943         if (isNetwork && nominatim && entity) {
59944             var center = entity.extent(context.graph()).center();
59945             nominatim.countryCode(center, function (err, code) {
59946                 country = code;
59947             });
59948         }
59949
59950         input
59951             .on('change', change)
59952             .on('blur', change);
59953
59954         if (isMulti || isSemi) {
59955             combobox
59956                 .on('accept', function() {
59957                     input.node().blur();
59958                     input.node().focus();
59959                 });
59960
59961             input
59962                 .on('focus', function() { container.classed('active', true); });
59963         }
59964     }
59965
59966
59967     combo.tags = function(tags) {
59968         if (isMulti || isSemi) {
59969             multiData = [];
59970
59971             if (isMulti) {
59972                 // Build multiData array containing keys already set..
59973                 Object.keys(tags).forEach(function(key) {
59974                     if (key.indexOf(field.key) !== 0 || tags[key].toLowerCase() !== 'yes') return;
59975
59976                     var suffix = key.substring(field.key.length);
59977                     multiData.push({
59978                         key: key,
59979                         value: displayValue(suffix)
59980                     });
59981                 });
59982
59983                 // Set keys for form-field modified (needed for undo and reset buttons)..
59984                 field.keys = map$4(multiData, 'key');
59985
59986             } else if (isSemi) {
59987                 var arr = compact(uniq((tags[field.key] || '').split(';')));
59988                 multiData = arr.map(function(key) {
59989                     return {
59990                         key: key,
59991                         value: displayValue(key)
59992                     };
59993                 });
59994             }
59995
59996             // Exclude existing multikeys from combo options..
59997             var available = objectDifference(comboData, multiData);
59998             combobox.data(available);
59999
60000             // Hide 'Add' button if this field uses fixed set of
60001             // translateable optstrings and they're all currently used..
60002             container.selectAll('.combobox-input, .combobox-caret')
60003                 .classed('hide', optstrings && !available.length);
60004
60005
60006             // Render chips
60007             var chips = container.selectAll('.chips')
60008                 .data(multiData);
60009
60010             chips.exit()
60011                 .remove();
60012
60013             var enter = chips.enter()
60014                 .insert('li', 'input')
60015                 .attr('class', 'chips');
60016
60017             enter.append('span');
60018             enter.append('a');
60019
60020             chips = chips.merge(enter);
60021
60022             chips.select('span')
60023                 .text(function(d) { return d.value; });
60024
60025             chips.select('a')
60026                 .on('click', removeMultikey)
60027                 .attr('class', 'remove')
60028                 .text('×');
60029
60030         } else {
60031             utilGetSetValue(input, displayValue(tags[field.key]));
60032         }
60033     };
60034
60035
60036     combo.focus = function() {
60037         input.node().focus();
60038     };
60039
60040
60041     combo.entity = function(_) {
60042         if (!arguments.length) return entity;
60043         entity = _;
60044         return combo;
60045     };
60046
60047
60048     return utilRebind(combo, dispatch$$1, 'on');
60049 }
60050
60051 function uiFieldText(field, context) {
60052     var dispatch$$1 = dispatch('change'),
60053         nominatim = services.geocoder,
60054         input,
60055         entity;
60056
60057
60058     function i(selection) {
60059         var fieldId = 'preset-input-' + field.id;
60060
60061         input = selection.selectAll('input')
60062             .data([0]);
60063
60064         input = input.enter()
60065             .append('input')
60066             .attr('type', field.type)
60067             .attr('id', fieldId)
60068             .attr('placeholder', field.placeholder() || t('inspector.unknown'))
60069             .call(utilNoAuto)
60070             .merge(input);
60071
60072         input
60073             .on('input', change(true))
60074             .on('blur', change())
60075             .on('change', change());
60076
60077         if (field.type === 'tel' && nominatim && entity) {
60078             var center = entity.extent(context.graph()).center();
60079             nominatim.countryCode(center, function (err, countryCode) {
60080                 if (err || !dataPhoneFormats[countryCode]) return;
60081                 selection.selectAll('#' + fieldId)
60082                     .attr('placeholder', dataPhoneFormats[countryCode]);
60083             });
60084
60085         } else if (field.type === 'number') {
60086             var rtl = (textDirection === 'rtl');
60087
60088             input.attr('type', 'text');
60089
60090             var spinControl = selection.selectAll('.spin-control')
60091                 .data([0]);
60092
60093             var enter = spinControl.enter()
60094                 .append('div')
60095                 .attr('class', 'spin-control');
60096
60097             enter
60098                 .append('button')
60099                 .datum(rtl ? 1 : -1)
60100                 .attr('class', rtl ? 'increment' : 'decrement')
60101                 .attr('tabindex', -1);
60102
60103             enter
60104                 .append('button')
60105                 .datum(rtl ? -1 : 1)
60106                 .attr('class', rtl ? 'decrement' : 'increment')
60107                 .attr('tabindex', -1);
60108
60109             spinControl = spinControl
60110                 .merge(enter);
60111
60112             spinControl.selectAll('button')
60113                 .on('click', function(d) {
60114                     event.preventDefault();
60115                     var num = parseInt(input.node().value || 0, 10);
60116                     if (!isNaN(num)) input.node().value = num + d;
60117                     change()();
60118                 });
60119         }
60120     }
60121
60122
60123     function change(onInput) {
60124         return function() {
60125             var t$$1 = {};
60126             t$$1[field.key] = utilGetSetValue(input) || undefined;
60127             dispatch$$1.call('change', this, t$$1, onInput);
60128         };
60129     }
60130
60131
60132     i.entity = function(_) {
60133         if (!arguments.length) return entity;
60134         entity = _;
60135         return i;
60136     };
60137
60138
60139     i.tags = function(tags) {
60140         utilGetSetValue(input, tags[field.key] || '');
60141     };
60142
60143
60144     i.focus = function() {
60145         var node = input.node();
60146         if (node) node.focus();
60147     };
60148
60149     return utilRebind(i, dispatch$$1, 'on');
60150 }
60151
60152 function uiFieldAccess(field, context) {
60153     var dispatch$$1 = dispatch('change'),
60154         items;
60155
60156     function access(selection) {
60157         var wrap = selection.selectAll('.preset-input-wrap')
60158             .data([0]);
60159
60160         wrap = wrap.enter()
60161             .append('div')
60162             .attr('class', 'cf preset-input-wrap')
60163             .append('ul')
60164             .merge(wrap);
60165
60166         var list = wrap.selectAll('ul')
60167             .data([0]);
60168
60169         list = list.enter()
60170             .append('ul')
60171             .merge(list);
60172
60173
60174         items = list.selectAll('li')
60175             .data(field.keys);
60176
60177         // Enter
60178         var enter = items.enter()
60179             .append('li')
60180             .attr('class', function(d) { return 'cf preset-access-' + d; });
60181
60182         enter
60183             .append('span')
60184             .attr('class', 'col6 label preset-label-access')
60185             .attr('for', function(d) { return 'preset-input-access-' + d; })
60186             .text(function(d) { return field.t('types.' + d); });
60187
60188         enter
60189             .append('div')
60190             .attr('class', 'col6 preset-input-access-wrap')
60191             .append('input')
60192             .attr('type', 'text')
60193             .attr('class', 'preset-input-access')
60194             .attr('id', function(d) { return 'preset-input-access-' + d; })
60195             .call(utilNoAuto)
60196             .each(function(d) {
60197                 d3_select(this)
60198                     .call(d3combobox()
60199                         .container(context.container())
60200                         .data(access.options(d))
60201                     );
60202             });
60203
60204
60205         // Update
60206         items = items.merge(enter);
60207
60208         wrap.selectAll('.preset-input-access')
60209             .on('change', change)
60210             .on('blur', change);
60211     }
60212
60213
60214     function change(d) {
60215         var tag = {};
60216         tag[d] = utilGetSetValue(d3_select(this)) || undefined;
60217         dispatch$$1.call('change', this, tag);
60218     }
60219
60220
60221     access.options = function(type) {
60222         var options = ['no', 'permissive', 'private', 'destination'];
60223
60224         if (type !== 'access') {
60225             options.unshift('yes');
60226             options.push('designated');
60227
60228             if (type === 'bicycle') {
60229                 options.push('dismount');
60230             }
60231         }
60232
60233         return options.map(function(option) {
60234             return {
60235                 title: field.t('options.' + option + '.description'),
60236                 value: option
60237             };
60238         });
60239     };
60240
60241
60242     var placeholders = {
60243         footway: {
60244             foot: 'designated',
60245             motor_vehicle: 'no'
60246         },
60247         steps: {
60248             foot: 'yes',
60249             motor_vehicle: 'no',
60250             bicycle: 'no',
60251             horse: 'no'
60252         },
60253         pedestrian: {
60254             foot: 'yes',
60255             motor_vehicle: 'no'
60256         },
60257         cycleway: {
60258             motor_vehicle: 'no',
60259             bicycle: 'designated'
60260         },
60261         bridleway: {
60262             motor_vehicle: 'no',
60263             horse: 'designated'
60264         },
60265         path: {
60266             foot: 'yes',
60267             motor_vehicle: 'no',
60268             bicycle: 'yes',
60269             horse: 'yes'
60270         },
60271         motorway: {
60272             foot: 'no',
60273             motor_vehicle: 'yes',
60274             bicycle: 'no',
60275             horse: 'no'
60276         },
60277         trunk: {
60278             motor_vehicle: 'yes'
60279         },
60280         primary: {
60281             foot: 'yes',
60282             motor_vehicle: 'yes',
60283             bicycle: 'yes',
60284             horse: 'yes'
60285         },
60286         secondary: {
60287             foot: 'yes',
60288             motor_vehicle: 'yes',
60289             bicycle: 'yes',
60290             horse: 'yes'
60291         },
60292         tertiary: {
60293             foot: 'yes',
60294             motor_vehicle: 'yes',
60295             bicycle: 'yes',
60296             horse: 'yes'
60297         },
60298         residential: {
60299             foot: 'yes',
60300             motor_vehicle: 'yes',
60301             bicycle: 'yes',
60302             horse: 'yes'
60303         },
60304         unclassified: {
60305             foot: 'yes',
60306             motor_vehicle: 'yes',
60307             bicycle: 'yes',
60308             horse: 'yes'
60309         },
60310         service: {
60311             foot: 'yes',
60312             motor_vehicle: 'yes',
60313             bicycle: 'yes',
60314             horse: 'yes'
60315         },
60316         motorway_link: {
60317             foot: 'no',
60318             motor_vehicle: 'yes',
60319             bicycle: 'no',
60320             horse: 'no'
60321         },
60322         trunk_link: {
60323             motor_vehicle: 'yes'
60324         },
60325         primary_link: {
60326             foot: 'yes',
60327             motor_vehicle: 'yes',
60328             bicycle: 'yes',
60329             horse: 'yes'
60330         },
60331         secondary_link: {
60332             foot: 'yes',
60333             motor_vehicle: 'yes',
60334             bicycle: 'yes',
60335             horse: 'yes'
60336         },
60337         tertiary_link: {
60338             foot: 'yes',
60339             motor_vehicle: 'yes',
60340             bicycle: 'yes',
60341             horse: 'yes'
60342         }
60343     };
60344
60345
60346     access.tags = function(tags) {
60347         utilGetSetValue(items.selectAll('.preset-input-access'),
60348             function(d) { return tags[d] || ''; })
60349             .attr('placeholder', function() {
60350                 return tags.access ? tags.access : field.placeholder();
60351             });
60352
60353         items.selectAll('#preset-input-access-access')
60354             .attr('placeholder', 'yes');
60355
60356         forEach(placeholders[tags.highway], function(v, k) {
60357             items.selectAll('#preset-input-access-' + k)
60358                 .attr('placeholder', function() { return (tags.access || v); });
60359         });
60360     };
60361
60362
60363     access.focus = function() {
60364         items.selectAll('.preset-input-access')
60365             .node().focus();
60366     };
60367
60368
60369     return utilRebind(access, dispatch$$1, 'on');
60370 }
60371
60372 function uiFieldAddress(field, context) {
60373     var dispatch$$1 = dispatch('init', 'change'),
60374         nominatim = services.geocoder,
60375         wrap = d3_select(null),
60376         isInitialized = false,
60377         entity;
60378
60379     function getNearStreets() {
60380         var extent = entity.extent(context.graph()),
60381             l = extent.center(),
60382             box = geoExtent(l).padByMeters(200);
60383
60384         var streets = context.intersects(box)
60385             .filter(isAddressable)
60386             .map(function(d) {
60387                 var loc = context.projection([
60388                     (extent[0][0] + extent[1][0]) / 2,
60389                     (extent[0][1] + extent[1][1]) / 2]),
60390                     choice = geoChooseEdge(context.childNodes(d), loc, context.projection);
60391                 return {
60392                     title: d.tags.name,
60393                     value: d.tags.name,
60394                     dist: choice.distance
60395                 };
60396             })
60397             .sort(function(a, b) {
60398                 return a.dist - b.dist;
60399             });
60400
60401         return uniqBy(streets, 'value');
60402
60403         function isAddressable(d) {
60404             return d.tags.highway && d.tags.name && d.type === 'way';
60405         }
60406     }
60407
60408
60409     function getNearCities() {
60410         var extent = entity.extent(context.graph()),
60411             l = extent.center(),
60412             box = geoExtent(l).padByMeters(200);
60413
60414         var cities = context.intersects(box)
60415             .filter(isAddressable)
60416             .map(function(d) {
60417                 return {
60418                     title: d.tags['addr:city'] || d.tags.name,
60419                     value: d.tags['addr:city'] || d.tags.name,
60420                     dist: geoSphericalDistance(d.extent(context.graph()).center(), l)
60421                 };
60422             })
60423             .sort(function(a, b) {
60424                 return a.dist - b.dist;
60425             });
60426
60427         return uniqBy(cities, 'value');
60428
60429
60430         function isAddressable(d) {
60431             if (d.tags.name &&
60432                 (d.tags.admin_level === '8' || d.tags.border_type === 'city'))
60433                 return true;
60434
60435             if (d.tags.place && d.tags.name && (
60436                     d.tags.place === 'city' ||
60437                     d.tags.place === 'town' ||
60438                     d.tags.place === 'village'))
60439                 return true;
60440
60441             if (d.tags['addr:city']) return true;
60442
60443             return false;
60444         }
60445     }
60446
60447     function getNearValues(key) {
60448         var extent = entity.extent(context.graph()),
60449             l = extent.center(),
60450             box = geoExtent(l).padByMeters(200);
60451
60452         var results = context.intersects(box)
60453             .filter(function hasTag(d) {
60454                 return d.tags[key];
60455             })
60456             .map(function(d) {
60457                 return {
60458                     title: d.tags[key],
60459                     value: d.tags[key],
60460                     dist: geoSphericalDistance(d.extent(context.graph()).center(), l)
60461                 };
60462             })
60463             .sort(function(a, b) {
60464                 return a.dist - b.dist;
60465             });
60466
60467         return uniqBy(results, 'value');
60468     }
60469
60470
60471     function initCallback(err, countryCode) {
60472         if (err) return;
60473
60474         var addressFormat = find$1(dataAddressFormats, function (a) {
60475             return a && a.countryCodes && includes(a.countryCodes, countryCode.toLowerCase());
60476         }) || dataAddressFormats[0];
60477
60478         var widths = addressFormat.widths || {
60479             housenumber: 1/3, street: 2/3,
60480             city: 2/3, state: 1/4, postcode: 1/3
60481         };
60482
60483         function row(r) {
60484             // Normalize widths.
60485             var total = reduce(r, function(sum, field) {
60486                 return sum + (widths[field] || 0.5);
60487             }, 0);
60488
60489             return r.map(function (field) {
60490                 return {
60491                     id: field,
60492                     width: (widths[field] || 0.5) / total
60493                 };
60494             });
60495         }
60496
60497         wrap.selectAll('div.addr-row')
60498             .data(addressFormat.format)
60499             .enter()
60500             .append('div')
60501             .attr('class', 'addr-row')
60502             .selectAll('input')
60503             .data(row)
60504             .enter()
60505             .append('input')
60506             .property('type', 'text')
60507             .attr('placeholder', function (d) {
60508                 var localkey = d.id + '!' + countryCode.toLowerCase(),
60509                     tkey = field.strings.placeholders[localkey] ? localkey : d.id;
60510                 return field.t('placeholders.' + tkey);
60511             })
60512             .attr('class', function (d) { return 'addr-' + d.id; })
60513             .call(utilNoAuto)
60514             .style('width', function (d) { return d.width * 100 + '%'; });
60515
60516         // Update
60517
60518         // setup dropdowns for common address tags
60519         var dropdowns = addressFormat.dropdowns || [
60520             'city', 'county', 'country', 'district', 'hamlet',
60521             'neighbourhood', 'place', 'postcode', 'province',
60522             'quarter', 'state', 'street', 'subdistrict', 'suburb'
60523         ];
60524
60525         // If fields exist for any of these tags, create dropdowns to pick nearby values..
60526         dropdowns.forEach(function(tag) {
60527             var nearValues = (tag === 'street') ? getNearStreets
60528                     : (tag === 'city') ? getNearCities
60529                     : getNearValues;
60530
60531             wrap.selectAll('input.addr-' + tag)
60532                 .call(d3combobox()
60533                     .container(context.container())
60534                     .minItems(1)
60535                     .fetcher(function(value, callback) {
60536                         callback(nearValues('addr:' + tag));
60537                     })
60538                 );
60539         });
60540
60541         wrap.selectAll('input')
60542             .on('blur', change())
60543             .on('change', change());
60544
60545         wrap.selectAll('input:not(.combobox-input)')
60546             .on('input', change(true));
60547
60548         dispatch$$1.call('init');
60549         isInitialized = true;
60550     }
60551
60552
60553     function address(selection) {
60554         isInitialized = false;
60555
60556         wrap = selection.selectAll('.preset-input-wrap')
60557             .data([0]);
60558
60559         wrap = wrap.enter()
60560             .append('div')
60561             .attr('class', 'preset-input-wrap')
60562             .merge(wrap);
60563
60564         if (nominatim && entity) {
60565             var center = entity.extent(context.graph()).center();
60566             nominatim.countryCode(center, initCallback);
60567         }
60568     }
60569
60570
60571     function change(onInput) {
60572         return function() {
60573             var tags = {};
60574
60575             wrap.selectAll('input')
60576                 .each(function (field) {
60577                     tags['addr:' + field.id] = this.value || undefined;
60578                 });
60579
60580             dispatch$$1.call('change', this, tags, onInput);
60581         };
60582     }
60583
60584
60585     function updateTags(tags) {
60586         utilGetSetValue(wrap.selectAll('input'), function (field) {
60587             return tags['addr:' + field.id] || '';
60588         });
60589     }
60590
60591
60592     address.entity = function(_) {
60593         if (!arguments.length) return entity;
60594         entity = _;
60595         return address;
60596     };
60597
60598
60599     address.tags = function(tags) {
60600         if (isInitialized) {
60601             updateTags(tags);
60602         } else {
60603             dispatch$$1.on('init', function () {
60604                 dispatch$$1.on('init', null);
60605                 updateTags(tags);
60606             });
60607         }
60608     };
60609
60610
60611     address.focus = function() {
60612         var node = wrap.selectAll('input').node();
60613         if (node) node.focus();
60614     };
60615
60616
60617     return utilRebind(address, dispatch$$1, 'on');
60618 }
60619
60620 function uiFieldCycleway(field, context) {
60621     var dispatch$$1 = dispatch('change'),
60622         items = d3_select(null);
60623
60624
60625     function cycleway(selection) {
60626
60627         function stripcolon(s) {
60628             return s.replace(':', '');
60629         }
60630
60631
60632         var wrap = selection.selectAll('.preset-input-wrap')
60633             .data([0]);
60634
60635         wrap = wrap.enter()
60636             .append('div')
60637             .attr('class', 'cf preset-input-wrap')
60638             .merge(wrap);
60639
60640
60641         var div = wrap.selectAll('ul')
60642             .data([0]);
60643
60644         div = div.enter()
60645             .append('ul')
60646             .merge(div);
60647
60648
60649         items = div.selectAll('li')
60650             .data(field.keys);
60651
60652         var enter = items.enter()
60653             .append('li')
60654             .attr('class', function(d) { return 'cf preset-cycleway-' + stripcolon(d); });
60655
60656         enter
60657             .append('span')
60658             .attr('class', 'col6 label preset-label-cycleway')
60659             .attr('for', function(d) { return 'preset-input-cycleway-' + stripcolon(d); })
60660             .text(function(d) { return field.t('types.' + d); });
60661
60662         enter
60663             .append('div')
60664             .attr('class', 'col6 preset-input-cycleway-wrap')
60665             .append('input')
60666             .attr('type', 'text')
60667             .attr('class', function(d) { return 'preset-input-cycleway preset-input-' + stripcolon(d); })
60668             .call(utilNoAuto)
60669             .each(function(d) {
60670                 d3_select(this)
60671                     .call(d3combobox()
60672                         .container(context.container())
60673                         .data(cycleway.options(d))
60674                     );
60675             });
60676
60677
60678         // Update
60679         wrap.selectAll('.preset-input-cycleway')
60680             .on('change', change)
60681             .on('blur', change);
60682     }
60683
60684
60685     function change() {
60686         var left = utilGetSetValue(d3_select('.preset-input-cyclewayleft')),
60687             right = utilGetSetValue(d3_select('.preset-input-cyclewayright')),
60688             tag = {};
60689
60690         if (left === 'none' || left === '') { left = undefined; }
60691         if (right === 'none' || right === '') { right = undefined; }
60692
60693         // Always set both left and right as changing one can affect the other
60694         tag = {
60695             cycleway: undefined,
60696             'cycleway:left': left,
60697             'cycleway:right': right
60698         };
60699
60700         // If the left and right tags match, use the cycleway tag to tag both
60701         // sides the same way
60702         if (left === right) {
60703             tag = {
60704                 cycleway: left,
60705                 'cycleway:left': undefined,
60706                 'cycleway:right': undefined
60707             };
60708         }
60709
60710         dispatch$$1.call('change', this, tag);
60711     }
60712
60713
60714     cycleway.options = function() {
60715         return keys$1(field.strings.options).map(function(option) {
60716             return {
60717                 title: field.t('options.' + option + '.description'),
60718                 value: option
60719             };
60720         });
60721     };
60722
60723
60724     cycleway.tags = function(tags) {
60725         utilGetSetValue(items.selectAll('.preset-input-cycleway'), function(d) {
60726                 // If cycleway is set, always return that
60727                 if (tags.cycleway) {
60728                     return tags.cycleway;
60729                 }
60730                 return tags[d] || '';
60731             })
60732             .attr('placeholder', field.placeholder());
60733     };
60734
60735
60736     cycleway.focus = function() {
60737         items.selectAll('.preset-input-cycleway')
60738             .node().focus();
60739     };
60740
60741
60742     return utilRebind(cycleway, dispatch$$1, 'on');
60743 }
60744
60745 function uiFieldLanes(field, context) {
60746     var dispatch$$1 = dispatch('change'),
60747         LANE_WIDTH = 40,
60748         LANE_HEIGHT = 200,
60749         wayID,
60750         lanesData;
60751
60752     function lanes(selection) {
60753         lanesData = context.entity(wayID).lanes();
60754
60755         if (!d3_select('.inspector-wrap.inspector-hidden').empty() || !selection.node().parentNode) {
60756             selection.call(lanes.off);
60757             return;
60758         }
60759
60760         var wrap = selection.selectAll('.preset-input-wrap')
60761             .data([0]);
60762
60763         wrap = wrap.enter()
60764             .append('div')
60765             .attr('class', 'preset-input-wrap')
60766             .merge(wrap);
60767
60768         var surface =  wrap.selectAll('.surface')
60769             .data([0]);
60770
60771         var d = utilGetDimensions(wrap);
60772         var freeSpace = d[0] - lanesData.lanes.length * LANE_WIDTH * 1.5 + LANE_WIDTH * 0.5;
60773
60774         surface = surface.enter()
60775             .append('svg')
60776             .attr('width', d[0])
60777             .attr('height', 300)
60778             .attr('class', 'surface')
60779             .merge(surface);
60780
60781
60782         var lanesSelection = surface.selectAll('.lanes')
60783             .data([0]);
60784
60785         lanesSelection = lanesSelection.enter()
60786             .append('g')
60787             .attr('class', 'lanes')
60788             .merge(lanesSelection);
60789
60790         lanesSelection
60791             .attr('transform', function () {
60792                 return 'translate(' + (freeSpace / 2) + ', 0)';
60793             });
60794
60795
60796         var lane = lanesSelection.selectAll('.lane')
60797            .data(lanesData.lanes);
60798
60799         lane.exit()
60800             .remove();
60801
60802         var enter = lane.enter()
60803             .append('g')
60804             .attr('class', 'lane');
60805
60806         enter
60807             .append('g')
60808             .append('rect')
60809             .attr('y', 50)
60810             .attr('width', LANE_WIDTH)
60811             .attr('height', LANE_HEIGHT);
60812
60813         enter
60814             .append('g')
60815             .attr('class', 'forward')
60816             .append('text')
60817             .attr('y', 40)
60818             .attr('x', 14)
60819             .text('▲');
60820
60821         enter
60822             .append('g')
60823             .attr('class', 'bothways')
60824             .append('text')
60825             .attr('y', 40)
60826             .attr('x', 14)
60827             .text('▲▼');
60828
60829         enter
60830             .append('g')
60831             .attr('class', 'backward')
60832             .append('text')
60833             .attr('y', 40)
60834             .attr('x', 14)
60835             .text('▼');
60836
60837
60838         lane = lane
60839             .merge(enter);
60840
60841         lane
60842             .attr('transform', function(d) {
60843                 return 'translate(' + (LANE_WIDTH * d.index * 1.5) + ', 0)';
60844             });
60845
60846         lane.select('.forward')
60847             .style('visibility', function(d) {
60848                 return d.direction === 'forward' ? 'visible' : 'hidden';
60849             });
60850
60851         lane.select('.bothways')
60852             .style('visibility', function(d) {
60853                 return d.direction === 'bothways' ? 'visible' : 'hidden';
60854             });
60855
60856         lane.select('.backward')
60857             .style('visibility', function(d) {
60858                 return d.direction === 'backward' ? 'visible' : 'hidden';
60859             });
60860     }
60861
60862
60863     lanes.entity = function(_) {
60864         if (!wayID || wayID !== _.id) {
60865             wayID = _.id;
60866         }
60867     };
60868
60869     lanes.tags = function() {};
60870     lanes.focus = function() {};
60871     lanes.off = function() {};
60872
60873     return utilRebind(lanes, dispatch$$1, 'on');
60874 }
60875
60876 function uiFieldLocalized(field, context) {
60877     var dispatch$$1 = dispatch('change', 'input'),
60878         wikipedia$$1 = services.wikipedia,
60879         input = d3_select(null),
60880         localizedInputs = d3_select(null),
60881         wikiTitles,
60882         entity;
60883
60884
60885     function localized(selection) {
60886         input = selection.selectAll('.localized-main')
60887             .data([0]);
60888
60889         input = input.enter()
60890             .append('input')
60891             .attr('type', 'text')
60892             .attr('id', 'preset-input-' + field.id)
60893             .attr('class', 'localized-main')
60894             .attr('placeholder', field.placeholder())
60895             .call(utilNoAuto)
60896             .merge(input);
60897
60898         if (field.id === 'name') {
60899             var preset = context.presets().match(entity, context.graph());
60900             input
60901                 .call(d3combobox()
60902                     .container(context.container())
60903                     .fetcher(utilSuggestNames(preset, dataSuggestions))
60904                 );
60905         }
60906
60907         input
60908             .on('input', change(true))
60909             .on('blur', change())
60910             .on('change', change());
60911
60912
60913         var translateButton = selection.selectAll('.localized-add')
60914             .data([0]);
60915
60916         translateButton = translateButton.enter()
60917             .append('button')
60918             .attr('class', 'button-input-action localized-add minor')
60919             .attr('tabindex', -1)
60920             .call(svgIcon('#icon-plus'))
60921             .call(tooltip()
60922                 .title(t('translate.translate'))
60923                 .placement('left'))
60924             .merge(translateButton);
60925
60926         translateButton
60927             .on('click', addNew);
60928
60929
60930         localizedInputs = selection.selectAll('.localized-wrap')
60931             .data([0]);
60932
60933         localizedInputs = localizedInputs.enter().append('div')
60934             .attr('class', 'localized-wrap')
60935             .merge(localizedInputs);
60936     }
60937
60938
60939     function addNew() {
60940         event.preventDefault();
60941         var data$$1 = localizedInputs.selectAll('div.entry').data();
60942         var defaultLang = utilDetect().locale.toLowerCase().split('-')[0];
60943         var langExists = find$1(data$$1, function(datum) { return datum.lang === defaultLang;});
60944         var isLangEn = defaultLang.indexOf('en') > -1;
60945         if (isLangEn || langExists) {
60946             defaultLang = '';
60947         }
60948         data$$1.push({ lang: defaultLang, value: '' });
60949         localizedInputs.call(render, data$$1);
60950     }
60951
60952
60953     function change(onInput) {
60954         return function() {
60955             var t$$1 = {};
60956             t$$1[field.key] = utilGetSetValue(d3_select(this)) || undefined;
60957             dispatch$$1.call('change', this, t$$1, onInput);
60958         };
60959     }
60960
60961
60962     function key(lang) {
60963         return field.key + ':' + lang;
60964     }
60965
60966
60967     function changeLang(d) {
60968         var lang = utilGetSetValue(d3_select(this)),
60969             t$$1 = {},
60970             language = find$1(wikipedia, function(d) {
60971                 return d[0].toLowerCase() === lang.toLowerCase() ||
60972                     d[1].toLowerCase() === lang.toLowerCase();
60973             });
60974
60975         if (language) lang = language[2];
60976
60977         if (d.lang && d.lang !== lang) {
60978             t$$1[key(d.lang)] = undefined;
60979         }
60980
60981         var value = utilGetSetValue(d3_select(this.parentNode)
60982             .selectAll('.localized-value'));
60983
60984         if (lang && value) {
60985             t$$1[key(lang)] = value;
60986         } else if (lang && wikiTitles && wikiTitles[d.lang]) {
60987             t$$1[key(lang)] = wikiTitles[d.lang];
60988         }
60989
60990         d.lang = lang;
60991         dispatch$$1.call('change', this, t$$1);
60992     }
60993
60994
60995     function changeValue(d) {
60996         if (!d.lang) return;
60997         var t$$1 = {};
60998         t$$1[key(d.lang)] = utilGetSetValue(d3_select(this)) || undefined;
60999         dispatch$$1.call('change', this, t$$1);
61000     }
61001
61002
61003     function fetcher(value, cb) {
61004         var v = value.toLowerCase();
61005
61006         cb(wikipedia.filter(function(d) {
61007             return d[0].toLowerCase().indexOf(v) >= 0 ||
61008             d[1].toLowerCase().indexOf(v) >= 0 ||
61009             d[2].toLowerCase().indexOf(v) >= 0;
61010         }).map(function(d) {
61011             return { value: d[1] };
61012         }));
61013     }
61014
61015
61016     function render(selection, data$$1) {
61017         var wraps = selection.selectAll('div.entry').
61018             data(data$$1, function(d) { return d.lang; });
61019
61020         wraps.exit()
61021             .transition()
61022             .duration(200)
61023             .style('max-height','0px')
61024             .style('opacity', '0')
61025             .style('top','-10px')
61026             .remove();
61027
61028         var innerWrap = wraps.enter()
61029             .insert('div', ':first-child');
61030
61031         innerWrap.attr('class', 'entry')
61032             .each(function() {
61033                 var wrap = d3_select(this);
61034                 var langcombo = d3combobox()
61035                     .container(context.container())
61036                     .fetcher(fetcher)
61037                     .minItems(0);
61038
61039                 var label = wrap
61040                     .append('label')
61041                     .attr('class','form-label')
61042                     .text(t('translate.localized_translation_label'))
61043                     .attr('for','localized-lang');
61044
61045                 label
61046                     .append('button')
61047                     .attr('class', 'minor remove')
61048                     .on('click', function(d){
61049                         event.preventDefault();
61050                         var t$$1 = {};
61051                         t$$1[key(d.lang)] = undefined;
61052                         dispatch$$1.call('change', this, t$$1);
61053                         d3_select(this.parentNode.parentNode)
61054                             .style('top','0')
61055                             .style('max-height','240px')
61056                             .transition()
61057                             .style('opacity', '0')
61058                             .style('max-height','0px')
61059                             .remove();
61060                     })
61061                     .call(svgIcon('#operation-delete'));
61062
61063                 wrap
61064                     .append('input')
61065                     .attr('class', 'localized-lang')
61066                     .attr('type', 'text')
61067                     .attr('placeholder',t('translate.localized_translation_language'))
61068                     .on('blur', changeLang)
61069                     .on('change', changeLang)
61070                     .call(langcombo);
61071
61072                 wrap
61073                     .append('input')
61074                     .on('blur', changeValue)
61075                     .on('change', changeValue)
61076                     .attr('type', 'text')
61077                     .attr('placeholder', t('translate.localized_translation_name'))
61078                     .attr('class', 'localized-value');
61079             });
61080
61081         innerWrap
61082             .style('margin-top', '0px')
61083             .style('max-height', '0px')
61084             .style('opacity', '0')
61085             .transition()
61086             .duration(200)
61087             .style('margin-top', '10px')
61088             .style('max-height', '240px')
61089             .style('opacity', '1')
61090             .on('end', function() {
61091                 d3_select(this)
61092                     .style('max-height', '')
61093                     .style('overflow', 'visible');
61094             });
61095
61096
61097         var entry = selection.selectAll('.entry');
61098
61099         utilGetSetValue(entry.select('.localized-lang'), function(d) {
61100                 var lang = find$1(wikipedia, function(lang) { return lang[2] === d.lang; });
61101                 return lang ? lang[1] : d.lang;
61102             });
61103
61104         utilGetSetValue(entry.select('.localized-value'),
61105             function(d) { return d.value; });
61106     }
61107
61108
61109     localized.tags = function(tags) {
61110         // Fetch translations from wikipedia
61111         if (tags.wikipedia && !wikiTitles) {
61112             wikiTitles = {};
61113             var wm = tags.wikipedia.match(/([^:]+):(.+)/);
61114             if (wm && wm[0] && wm[1]) {
61115                 wikipedia$$1.translations(wm[1], wm[2], function(d) {
61116                     wikiTitles = d;
61117                 });
61118             }
61119         }
61120
61121         utilGetSetValue(input, tags[field.key] || '');
61122
61123         var postfixed = [], k, m;
61124         for (k in tags) {
61125             m = k.match(/^(.*):([a-zA-Z_-]+)$/);
61126             if (m && m[1] === field.key && m[2]) {
61127                 postfixed.push({ lang: m[2], value: tags[k] });
61128             }
61129         }
61130
61131         localizedInputs.call(render, postfixed.reverse());
61132     };
61133
61134
61135     localized.focus = function() {
61136         input.node().focus();
61137     };
61138
61139
61140     localized.entity = function(_) {
61141         if (!arguments.length) return entity;
61142         entity = _;
61143         return localized;
61144     };
61145
61146     return utilRebind(localized, dispatch$$1, 'on');
61147 }
61148
61149 function uiFieldMaxspeed(field, context) {
61150     var dispatch$$1 = dispatch('change'),
61151         entity,
61152         isImperial,
61153         unitInput = d3_select(null),
61154         input = d3_select(null),
61155         combobox;
61156
61157     var metricValues = [20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120],
61158         imperialValues = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80];
61159
61160
61161     function maxspeed(selection) {
61162         combobox = d3combobox()
61163             .container(context.container());
61164
61165         var unitCombobox = d3combobox()
61166             .container(context.container())
61167             .data(['km/h', 'mph'].map(comboValues));
61168
61169         input = selection.selectAll('#preset-input-' + field.id)
61170             .data([0]);
61171
61172         input = input.enter()
61173             .append('input')
61174             .attr('type', 'text')
61175             .attr('id', 'preset-input-' + field.id)
61176             .attr('placeholder', field.placeholder())
61177             .call(utilNoAuto)
61178             .call(combobox)
61179             .merge(input);
61180
61181         input
61182             .on('change', change)
61183             .on('blur', change);
61184
61185         var childNodes = context.graph().childNodes(context.entity(entity.id)),
61186             loc = childNodes[~~(childNodes.length/2)].loc;
61187
61188         isImperial = some(dataImperial.features, function(f) {
61189             return some(f.geometry.coordinates, function(d) {
61190                 return geoPointInPolygon(loc, d);
61191             });
61192         });
61193
61194         unitInput = selection.selectAll('input.maxspeed-unit')
61195             .data([0]);
61196
61197         unitInput = unitInput.enter()
61198             .append('input')
61199             .attr('type', 'text')
61200             .attr('class', 'maxspeed-unit')
61201             .call(unitCombobox)
61202             .merge(unitInput);
61203
61204         unitInput
61205             .on('blur', changeUnits)
61206             .on('change', changeUnits);
61207
61208
61209         function changeUnits() {
61210             isImperial = utilGetSetValue(unitInput) === 'mph';
61211             utilGetSetValue(unitInput, isImperial ? 'mph' : 'km/h');
61212             setSuggestions();
61213             change();
61214         }
61215     }
61216
61217
61218     function setSuggestions() {
61219         combobox.data((isImperial ? imperialValues : metricValues).map(comboValues));
61220         utilGetSetValue(unitInput, isImperial ? 'mph' : 'km/h');
61221     }
61222
61223
61224     function comboValues(d) {
61225         return {
61226             value: d.toString(),
61227             title: d.toString()
61228         };
61229     }
61230
61231
61232     function change() {
61233         var tag = {},
61234             value = utilGetSetValue(input);
61235
61236         if (!value) {
61237             tag[field.key] = undefined;
61238         } else if (isNaN(value) || !isImperial) {
61239             tag[field.key] = value;
61240         } else {
61241             tag[field.key] = value + ' mph';
61242         }
61243
61244         dispatch$$1.call('change', this, tag);
61245     }
61246
61247
61248     maxspeed.tags = function(tags) {
61249         var value = tags[field.key];
61250
61251         if (value && value.indexOf('mph') >= 0) {
61252             value = parseInt(value, 10);
61253             isImperial = true;
61254         } else if (value) {
61255             isImperial = false;
61256         }
61257
61258         setSuggestions();
61259         utilGetSetValue(input, value || '');
61260     };
61261
61262
61263     maxspeed.focus = function() {
61264         input.node().focus();
61265     };
61266
61267
61268     maxspeed.entity = function(_) {
61269         entity = _;
61270     };
61271
61272
61273     return utilRebind(maxspeed, dispatch$$1, 'on');
61274 }
61275
61276 /**
61277  * This function is like `baseIndexOf` except that it accepts a comparator.
61278  *
61279  * @private
61280  * @param {Array} array The array to inspect.
61281  * @param {*} value The value to search for.
61282  * @param {number} fromIndex The index to search from.
61283  * @param {Function} comparator The comparator invoked per element.
61284  * @returns {number} Returns the index of the matched value, else `-1`.
61285  */
61286 function baseIndexOfWith(array, value, fromIndex, comparator) {
61287   var index = fromIndex - 1,
61288       length = array.length;
61289
61290   while (++index < length) {
61291     if (comparator(array[index], value)) {
61292       return index;
61293     }
61294   }
61295   return -1;
61296 }
61297
61298 /** Used for built-in method references. */
61299 var arrayProto$2 = Array.prototype;
61300
61301 /** Built-in value references. */
61302 var splice$2 = arrayProto$2.splice;
61303
61304 /**
61305  * The base implementation of `_.pullAllBy` without support for iteratee
61306  * shorthands.
61307  *
61308  * @private
61309  * @param {Array} array The array to modify.
61310  * @param {Array} values The values to remove.
61311  * @param {Function} [iteratee] The iteratee invoked per element.
61312  * @param {Function} [comparator] The comparator invoked per element.
61313  * @returns {Array} Returns `array`.
61314  */
61315 function basePullAll(array, values, iteratee, comparator) {
61316   var indexOf = comparator ? baseIndexOfWith : baseIndexOf,
61317       index = -1,
61318       length = values.length,
61319       seen = array;
61320
61321   if (array === values) {
61322     values = copyArray(values);
61323   }
61324   if (iteratee) {
61325     seen = arrayMap(array, baseUnary(iteratee));
61326   }
61327   while (++index < length) {
61328     var fromIndex = 0,
61329         value = values[index],
61330         computed = iteratee ? iteratee(value) : value;
61331
61332     while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) {
61333       if (seen !== array) {
61334         splice$2.call(seen, fromIndex, 1);
61335       }
61336       splice$2.call(array, fromIndex, 1);
61337     }
61338   }
61339   return array;
61340 }
61341
61342 /**
61343  * This method is like `_.pull` except that it accepts an array of values to remove.
61344  *
61345  * **Note:** Unlike `_.difference`, this method mutates `array`.
61346  *
61347  * @static
61348  * @memberOf _
61349  * @since 4.0.0
61350  * @category Array
61351  * @param {Array} array The array to modify.
61352  * @param {Array} values The values to remove.
61353  * @returns {Array} Returns `array`.
61354  * @example
61355  *
61356  * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
61357  *
61358  * _.pullAll(array, ['a', 'c']);
61359  * console.log(array);
61360  * // => ['b', 'b']
61361  */
61362 function pullAll(array, values) {
61363   return (array && array.length && values && values.length)
61364     ? basePullAll(array, values)
61365     : array;
61366 }
61367
61368 /**
61369  * Removes all given values from `array` using
61370  * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
61371  * for equality comparisons.
61372  *
61373  * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
61374  * to remove elements from an array by predicate.
61375  *
61376  * @static
61377  * @memberOf _
61378  * @since 2.0.0
61379  * @category Array
61380  * @param {Array} array The array to modify.
61381  * @param {...*} [values] The values to remove.
61382  * @returns {Array} Returns `array`.
61383  * @example
61384  *
61385  * var array = ['a', 'b', 'c', 'a', 'b', 'c'];
61386  *
61387  * _.pull(array, 'a', 'c');
61388  * console.log(array);
61389  * // => ['b', 'b']
61390  */
61391 var pull = baseRest(pullAll);
61392
61393 function uiFieldRadio(field, context) {
61394     var dispatch$$1 = dispatch('change'),
61395         placeholder = d3_select(null),
61396         wrap = d3_select(null),
61397         labels = d3_select(null),
61398         radios = d3_select(null),
61399         radioData = clone(field.options || field.keys),
61400         typeField,
61401         layerField,
61402         oldType = {},
61403         entity;
61404
61405
61406     function selectedKey() {
61407         var node = wrap.selectAll('.toggle-list label.active input');
61408         return !node.empty() && node.datum();
61409     }
61410
61411
61412     function radio(selection) {
61413         selection.classed('preset-radio', true);
61414
61415         wrap = selection.selectAll('.preset-input-wrap')
61416             .data([0]);
61417
61418         var enter = wrap.enter()
61419             .append('div')
61420             .attr('class', 'preset-input-wrap toggle-list');
61421
61422         enter
61423             .append('span')
61424             .attr('class', 'placeholder');
61425
61426         wrap = wrap
61427             .merge(enter);
61428
61429
61430         placeholder = wrap.selectAll('.placeholder');
61431
61432         labels = wrap.selectAll('label')
61433             .data(radioData);
61434
61435         enter = labels.enter()
61436             .append('label');
61437
61438         enter
61439             .append('input')
61440             .attr('type', 'radio')
61441             .attr('name', field.id)
61442             .attr('value', function(d) { return field.t('options.' + d, { 'default': d }); })
61443             .attr('checked', false);
61444
61445         enter
61446             .append('span')
61447             .text(function(d) { return field.t('options.' + d, { 'default': d }); });
61448
61449         labels = labels
61450             .merge(enter);
61451
61452         radios = labels.selectAll('input')
61453             .on('change', changeRadio);
61454
61455     }
61456
61457
61458     function structureExtras(selection, tags) {
61459         var selected = selectedKey(),
61460             type = context.presets().field(selected),
61461             layer = context.presets().field('layer'),
61462             showLayer = (selected === 'bridge' || selected === 'tunnel');
61463
61464
61465         var extrasWrap = selection.selectAll('.structure-extras-wrap')
61466             .data(selected ? [0] : []);
61467
61468         extrasWrap.exit()
61469             .remove();
61470
61471         extrasWrap = extrasWrap.enter()
61472             .append('div')
61473             .attr('class', 'structure-extras-wrap')
61474             .merge(extrasWrap);
61475
61476         var list = extrasWrap.selectAll('ul')
61477             .data([0]);
61478
61479         list = list.enter()
61480             .append('ul')
61481             .merge(list);
61482
61483
61484         // Type
61485         if (type) {
61486             if (!typeField || typeField.id !== selected) {
61487                 typeField = uiField(context, type, entity, { wrap: false })
61488                     .on('change', changeType);
61489             }
61490             typeField.tags(tags);
61491         } else {
61492             typeField = null;
61493         }
61494
61495         var typeItem = list.selectAll('.structure-type-item')
61496             .data(typeField ? [typeField] : [], function(d) { return d.id; });
61497
61498         // Exit
61499         typeItem.exit()
61500             .remove();
61501
61502         // Enter
61503         var typeEnter = typeItem.enter()
61504             .insert('li', ':first-child')
61505             .attr('class', 'cf structure-type-item');
61506
61507         typeEnter
61508             .append('span')
61509             .attr('class', 'col6 label structure-label-type')
61510             .attr('for', 'preset-input-' + selected)
61511             .text(t('inspector.radio.structure.type'));
61512
61513         typeEnter
61514             .append('div')
61515             .attr('class', 'col6 structure-input-type-wrap');
61516
61517         // Update
61518         typeItem = typeItem
61519             .merge(typeEnter);
61520
61521         if (typeField) {
61522             typeItem.selectAll('.structure-input-type-wrap')
61523                 .call(typeField.render);
61524         }
61525
61526
61527         // Layer
61528         if (layer && showLayer) {
61529             if (!layerField) {
61530                 layerField = uiField(context, layer, entity, { wrap: false })
61531                     .on('change', changeLayer);
61532             }
61533             layerField.tags(tags);
61534             field.keys = union(field.keys, ['layer']);
61535         } else {
61536             layerField = null;
61537             pull(field.keys, 'layer');
61538         }
61539
61540         var layerItem = list.selectAll('.structure-layer-item')
61541             .data(layerField ? [layerField] : []);
61542
61543         // Exit
61544         layerItem.exit()
61545             .remove();
61546
61547         // Enter
61548         var layerEnter = layerItem.enter()
61549             .append('li')
61550             .attr('class', 'cf structure-layer-item');
61551
61552         layerEnter
61553             .append('span')
61554             .attr('class', 'col6 label structure-label-layer')
61555             .attr('for', 'preset-input-layer')
61556             .text(t('inspector.radio.structure.layer'));
61557
61558         layerEnter
61559             .append('div')
61560             .attr('class', 'col6 structure-input-layer-wrap');
61561
61562         // Update
61563         layerItem = layerItem
61564             .merge(layerEnter);
61565
61566         if (layerField) {
61567             layerItem.selectAll('.structure-input-layer-wrap')
61568                 .call(layerField.render);
61569         }
61570     }
61571
61572
61573     function changeType(t$$1, onInput) {
61574         var key = selectedKey();
61575         if (!key) return;
61576
61577         var val = t$$1[key];
61578         if (val !== 'no') {
61579             oldType[key] = val;
61580         }
61581
61582         if (field.type === 'structureRadio') {
61583             // remove layer if it should not be set
61584             if (val === 'no' ||
61585                 (key !== 'bridge' && key !== 'tunnel') ||
61586                 (key === 'tunnel' && val === 'building_passage')) {
61587                 t$$1.layer = undefined;
61588             }
61589             // add layer if it should be set
61590             if (t$$1.layer === undefined) {
61591                 if (key === 'bridge' && val !== 'no') {
61592                     t$$1.layer = '1';
61593                 }
61594                 if (key === 'tunnel' && val !== 'no' && val !== 'building_passage') {
61595                     t$$1.layer = '-1';
61596                 }
61597             }
61598          }
61599
61600         dispatch$$1.call('change', this, t$$1, onInput);
61601     }
61602
61603
61604     function changeLayer(t$$1, onInput) {
61605         if (t$$1.layer === '0') {
61606             t$$1.layer = undefined;
61607         }
61608         dispatch$$1.call('change', this, t$$1, onInput);
61609     }
61610
61611
61612     function changeRadio() {
61613         var t$$1 = {},
61614             activeKey;
61615
61616         if (field.key) {
61617             t$$1[field.key] = undefined;
61618         }
61619
61620         radios.each(function(d) {
61621             var active = d3_select(this).property('checked');
61622             if (active) activeKey = d;
61623
61624             if (field.key) {
61625                 if (active) t$$1[field.key] = d;
61626             } else {
61627                 var val = oldType[activeKey] || 'yes';
61628                 t$$1[d] = active ? val : undefined;
61629             }
61630         });
61631
61632         if (field.type === 'structureRadio') {
61633             if (activeKey === 'bridge') {
61634                 t$$1.layer = '1';
61635             } else if (activeKey === 'tunnel' && t$$1.tunnel !== 'building_passage') {
61636                 t$$1.layer = '-1';
61637             } else {
61638                 t$$1.layer = undefined;
61639             }
61640         }
61641
61642         dispatch$$1.call('change', this, t$$1);
61643     }
61644
61645
61646     radio.tags = function(tags) {
61647         function checked(d) {
61648             if (field.key) {
61649                 return tags[field.key] === d;
61650             } else {
61651                 return !!(tags[d] && tags[d].toLowerCase() !== 'no');
61652             }
61653         }
61654
61655         labels.classed('active', checked);
61656         radios.property('checked', checked);
61657
61658         var selection = radios.filter(function() { return this.checked; });
61659
61660         if (selection.empty()) {
61661             placeholder.text(t('inspector.none'));
61662         } else {
61663             placeholder.text(selection.attr('value'));
61664             oldType[selection.datum()] = tags[selection.datum()];
61665         }
61666
61667         if (field.type === 'structureRadio') {
61668             // For waterways without a tunnel tag, set 'culvert' as
61669             // the oldType to default to if the user picks 'tunnel'
61670             if (!!tags.waterway && !oldType.tunnel) {
61671                 oldType.tunnel = 'culvert';
61672             }
61673
61674             wrap.call(structureExtras, tags);
61675         }
61676     };
61677
61678
61679     radio.focus = function() {
61680         radios.node().focus();
61681     };
61682
61683
61684     radio.entity = function(_) {
61685         if (!arguments.length) return entity;
61686         entity = _;
61687         oldType = {};
61688         return radio;
61689     };
61690
61691
61692     return utilRebind(radio, dispatch$$1, 'on');
61693 }
61694
61695 function uiFieldRestrictions(field, context) {
61696     var dispatch$$1 = dispatch('change'),
61697         breathe = behaviorBreathe(context),
61698         hover = behaviorHover(context),
61699         initialized = false,
61700         vertexID,
61701         fromNodeID;
61702
61703
61704     function restrictions(selection) {
61705         // if form field is hidden or has detached from dom, clean up.
61706         if (!d3_select('.inspector-wrap.inspector-hidden').empty() || !selection.node().parentNode) {
61707             selection.call(restrictions.off);
61708             return;
61709         }
61710
61711         var wrap = selection.selectAll('.preset-input-wrap')
61712             .data([0]);
61713
61714         var enter = wrap.enter()
61715             .append('div')
61716             .attr('class', 'preset-input-wrap');
61717
61718         enter
61719             .append('div')
61720             .attr('class', 'restriction-help');
61721
61722
61723         var intersection = osmIntersection(context.graph(), vertexID),
61724             graph = intersection.graph,
61725             vertex = graph.entity(vertexID),
61726             filter = utilFunctor(true),
61727             extent = geoExtent(),
61728             projection = geoRawMercator();
61729
61730         var d = utilGetDimensions(wrap.merge(enter)),
61731             c = [d[0] / 2, d[1] / 2],
61732             z = 24;
61733
61734         projection
61735             .scale(256 * Math.pow(2, z) / (2 * Math.PI));
61736
61737         var s = projection(vertex.loc);
61738
61739         projection
61740             .translate([c[0] - s[0], c[1] - s[1]])
61741             .clipExtent([[0, 0], d]);
61742
61743         var drawLayers = svgLayers(projection, context).only('osm').dimensions(d),
61744             drawVertices = svgVertices(projection, context),
61745             drawLines = svgLines(projection, context),
61746             drawTurns = svgTurns(projection, context);
61747
61748         enter
61749             .call(drawLayers);
61750
61751         wrap = wrap
61752             .merge(enter);
61753
61754         var surface = wrap.selectAll('.surface');
61755
61756         if (!enter.empty()) {
61757             initialized = true;
61758             surface
61759                 .call(breathe)
61760                 .call(hover);
61761         }
61762
61763         surface
61764             .call(utilSetDimensions, d)
61765             .call(drawVertices, graph, [vertex], filter, extent, z)
61766             .call(drawLines, graph, intersection.ways, filter)
61767             .call(drawTurns, graph, intersection.turns(fromNodeID));
61768
61769         surface
61770             .on('click.restrictions', click)
61771             .on('mouseover.restrictions', mouseover)
61772             .on('mouseout.restrictions', mouseout);
61773
61774         surface
61775             .selectAll('.selected')
61776             .classed('selected', false);
61777
61778         if (fromNodeID) {
61779             surface
61780                 .selectAll('.' + intersection.highways[fromNodeID].id)
61781                 .classed('selected', true);
61782         }
61783
61784         mouseout();
61785
61786         context.history()
61787             .on('change.restrictions', render);
61788
61789         d3_select(window)
61790             .on('resize.restrictions', function() {
61791                 utilSetDimensions(wrap, null);
61792                 render();
61793             });
61794
61795
61796         function click() {
61797             surface
61798                 .call(breathe.off)
61799                 .call(breathe);
61800
61801             var datum = event.target.__data__;
61802             if (datum instanceof osmEntity) {
61803                 fromNodeID = intersection.adjacentNodeId(datum.id);
61804                 render();
61805             } else if (datum instanceof osmTurn) {
61806                 if (datum.restriction) {
61807                     context.perform(
61808                         actionUnrestrictTurn(datum, projection),
61809                         t('operations.restriction.annotation.delete')
61810                     );
61811                 } else {
61812                     context.perform(
61813                         actionRestrictTurn(datum, projection),
61814                         t('operations.restriction.annotation.create')
61815                     );
61816                 }
61817             }
61818         }
61819
61820
61821         function mouseover() {
61822             var datum = event.target.__data__;
61823             if (datum instanceof osmTurn) {
61824                 var graph = context.graph(),
61825                     presets = context.presets(),
61826                     preset;
61827
61828                 if (datum.restriction) {
61829                     preset = presets.match(graph.entity(datum.restriction), graph);
61830                 } else {
61831                     preset = presets.item('type/restriction/' +
61832                         osmInferRestriction(
61833                             graph,
61834                             datum.from,
61835                             datum.via,
61836                             datum.to,
61837                             projection
61838                         )
61839                     );
61840                 }
61841
61842                 wrap.selectAll('.restriction-help')
61843                     .text(t('operations.restriction.help.' +
61844                         (datum.restriction ? 'toggle_off' : 'toggle_on'),
61845                         { restriction: preset.name() })
61846                     );
61847             }
61848         }
61849
61850
61851         function mouseout() {
61852             wrap.selectAll('.restriction-help')
61853                 .text(t('operations.restriction.help.' +
61854                     (fromNodeID ? 'toggle' : 'select'))
61855                 );
61856         }
61857
61858
61859         function render() {
61860             if (context.hasEntity(vertexID)) {
61861                 restrictions(selection);
61862             }
61863         }
61864     }
61865
61866
61867     restrictions.entity = function(_) {
61868         if (!vertexID || vertexID !== _.id) {
61869             fromNodeID = null;
61870             vertexID = _.id;
61871         }
61872     };
61873
61874
61875     restrictions.tags = function() {};
61876     restrictions.focus = function() {};
61877
61878
61879     restrictions.off = function(selection) {
61880         if (!initialized) return;
61881
61882         selection.selectAll('.surface')
61883             .call(hover.off)
61884             .call(breathe.off)
61885             .on('click.restrictions', null)
61886             .on('mouseover.restrictions', null)
61887             .on('mouseout.restrictions', null);
61888
61889         context.history()
61890             .on('change.restrictions', null);
61891
61892         d3_select(window)
61893             .on('resize.restrictions', null);
61894     };
61895
61896
61897     return utilRebind(restrictions, dispatch$$1, 'on');
61898 }
61899
61900 function uiFieldTextarea(field) {
61901     var dispatch$$1 = dispatch('change'),
61902         input = d3_select(null);
61903
61904
61905     function textarea(selection) {
61906         input = selection.selectAll('textarea')
61907             .data([0]);
61908
61909         input = input.enter()
61910             .append('textarea')
61911             .attr('id', 'preset-input-' + field.id)
61912             .attr('placeholder', field.placeholder() || t('inspector.unknown'))
61913             .attr('maxlength', 255)
61914             .call(utilNoAuto)
61915             .on('input', change(true))
61916             .on('blur', change())
61917             .on('change', change())
61918             .merge(input);
61919     }
61920
61921
61922     function change(onInput) {
61923         return function() {
61924             var t$$1 = {};
61925             t$$1[field.key] = utilGetSetValue(input) || undefined;
61926             dispatch$$1.call('change', this, t$$1, onInput);
61927         };
61928     }
61929
61930
61931     textarea.tags = function(tags) {
61932         utilGetSetValue(input, tags[field.key] || '');
61933     };
61934
61935
61936     textarea.focus = function() {
61937         input.node().focus();
61938     };
61939
61940
61941     return utilRebind(textarea, dispatch$$1, 'on');
61942 }
61943
61944 function uiFieldWikipedia(field, context) {
61945     var dispatch$$1 = dispatch('change'),
61946         wikipedia$$1 = services.wikipedia,
61947         wikidata = services.wikidata,
61948         link = d3_select(null),
61949         lang = d3_select(null),
61950         title = d3_select(null),
61951         wikiURL = '',
61952         entity;
61953
61954
61955     function wiki(selection) {
61956         var langcombo = d3combobox()
61957             .container(context.container())
61958             .fetcher(function(value, cb) {
61959                 var v = value.toLowerCase();
61960
61961                 cb(wikipedia.filter(function(d) {
61962                     return d[0].toLowerCase().indexOf(v) >= 0 ||
61963                         d[1].toLowerCase().indexOf(v) >= 0 ||
61964                         d[2].toLowerCase().indexOf(v) >= 0;
61965                 }).map(function(d) {
61966                     return { value: d[1] };
61967                 }));
61968             });
61969
61970         var titlecombo = d3combobox()
61971             .container(context.container())
61972             .fetcher(function(value, cb) {
61973                 if (!value) {
61974                     value = context.entity(entity.id).tags.name || '';
61975                 }
61976
61977                 var searchfn = value.length > 7 ? wikipedia$$1.search : wikipedia$$1.suggestions;
61978                 searchfn(language()[2], value, function(query, data$$1) {
61979                     cb(data$$1.map(function(d) {
61980                         return { value: d };
61981                     }));
61982                 });
61983             });
61984
61985
61986         lang = selection.selectAll('input.wiki-lang')
61987             .data([0]);
61988
61989         lang = lang.enter()
61990             .append('input')
61991             .attr('type', 'text')
61992             .attr('class', 'wiki-lang')
61993             .attr('placeholder', t('translate.localized_translation_language'))
61994             .call(utilNoAuto)
61995             .merge(lang);
61996
61997         utilGetSetValue(lang, language()[1]);
61998
61999         lang
62000             .call(langcombo)
62001             .on('blur', changeLang)
62002             .on('change', changeLang);
62003
62004
62005         title = selection.selectAll('input.wiki-title')
62006             .data([0]);
62007
62008         title = title.enter()
62009             .append('input')
62010             .attr('type', 'text')
62011             .attr('class', 'wiki-title')
62012             .attr('id', 'preset-input-' + field.id)
62013             .call(utilNoAuto)
62014             .merge(title);
62015
62016         title
62017             .call(titlecombo)
62018             .on('blur', blur)
62019             .on('change', change);
62020
62021
62022         link = selection.selectAll('.wiki-link')
62023             .data([0]);
62024
62025         link = link.enter()
62026             .append('button')
62027             .attr('class', 'button-input-action wiki-link minor')
62028             .attr('tabindex', -1)
62029             .call(svgIcon('#icon-out-link'))
62030             .merge(link);
62031
62032         link
62033             .on('click', function() {
62034                 event.preventDefault();
62035                 if (wikiURL) window.open(wikiURL, '_blank');
62036             });
62037     }
62038
62039
62040     function language() {
62041         var value = utilGetSetValue(lang).toLowerCase();
62042         var locale = utilDetect().locale.toLowerCase();
62043         var localeLanguage;
62044         return find$1(wikipedia, function(d) {
62045             if (d[2] === locale) localeLanguage = d;
62046             return d[0].toLowerCase() === value ||
62047                 d[1].toLowerCase() === value ||
62048                 d[2] === value;
62049         }) || localeLanguage || ['English', 'English', 'en'];
62050     }
62051
62052
62053     function changeLang() {
62054         utilGetSetValue(lang, language()[1]);
62055         change(true);
62056     }
62057
62058
62059     function blur() {
62060         change(true);
62061     }
62062
62063
62064     function change(skipWikidata) {
62065         var value = utilGetSetValue(title),
62066             m = value.match(/https?:\/\/([-a-z]+)\.wikipedia\.org\/(?:wiki|\1-[-a-z]+)\/([^#]+)(?:#(.+))?/),
62067             l = m && find$1(wikipedia, function(d) { return m[1] === d[2]; }),
62068             syncTags = {};
62069
62070         if (l) {
62071             // Normalize title http://www.mediawiki.org/wiki/API:Query#Title_normalization
62072             value = decodeURIComponent(m[2]).replace(/_/g, ' ');
62073             if (m[3]) {
62074                 var anchor;
62075                 try {
62076                     // Best-effort `anchordecode:` implementation
62077                     anchor = decodeURIComponent(m[3].replace(/\.([0-9A-F]{2})/g, '%$1'));
62078                 } catch (e) {
62079                     anchor = decodeURIComponent(m[3]);
62080                 }
62081                 value += '#' + anchor.replace(/_/g, ' ');
62082             }
62083             value = value.slice(0, 1).toUpperCase() + value.slice(1);
62084             utilGetSetValue(lang, l[1]);
62085             utilGetSetValue(title, value);
62086         }
62087
62088         if (value) {
62089             syncTags.wikipedia = language()[2] + ':' + value;
62090         } else {
62091             syncTags.wikipedia = undefined;
62092             syncTags.wikidata = undefined;
62093         }
62094
62095         dispatch$$1.call('change', this, syncTags);
62096
62097
62098         if (skipWikidata || !value || !language()[2]) return;
62099
62100         // attempt asynchronous update of wikidata tag..
62101         var initGraph = context.graph(),
62102             initEntityId = entity.id;
62103
62104         wikidata.itemsByTitle(language()[2], value, function(title, data$$1) {
62105             // If graph has changed, we can't apply this update.
62106             if (context.graph() !== initGraph) return;
62107
62108             if (!data$$1 || !Object.keys(data$$1).length) return;
62109
62110             var qids = Object.keys(data$$1);
62111             var value = qids && find$1(qids, function(id) { return id.match(/^Q\d+$/); });
62112             var currTags = clone(context.entity(initEntityId).tags);
62113
62114             currTags.wikidata = value;
62115
62116             // Coalesce the update of wikidata tag into the previous tag change
62117             context.overwrite(
62118                 actionChangeTags(initEntityId, currTags),
62119                 context.history().undoAnnotation()
62120             );
62121
62122             // do not dispatch.call('change') here, because entity_editor
62123             // changeTags() is not intended to be called asynchronously
62124         });
62125     }
62126
62127
62128     wiki.tags = function(tags) {
62129         var value = tags[field.key] || '',
62130             m = value.match(/([^:]+):([^#]+)(?:#(.+))?/),
62131             l = m && find$1(wikipedia, function(d) { return m[1] === d[2]; }),
62132             anchor = m && m[3];
62133
62134         // value in correct format
62135         if (l) {
62136             utilGetSetValue(lang, l[1]);
62137             utilGetSetValue(title, m[2] + (anchor ? ('#' + anchor) : ''));
62138             if (anchor) {
62139                 try {
62140                     // Best-effort `anchorencode:` implementation
62141                     anchor = encodeURIComponent(anchor.replace(/ /g, '_')).replace(/%/g, '.');
62142                 } catch (e) {
62143                     anchor = anchor.replace(/ /g, '_');
62144                 }
62145             }
62146             wikiURL = 'https://' + m[1] + '.wikipedia.org/wiki/' +
62147                 m[2].replace(/ /g, '_') + (anchor ? ('#' + anchor) : '');
62148
62149         // unrecognized value format
62150         } else {
62151             utilGetSetValue(title, value);
62152             if (value && value !== '') {
62153                 utilGetSetValue(lang, '');
62154                 wikiURL = 'https://en.wikipedia.org/wiki/Special:Search?search=' + value;
62155             } else {
62156                 wikiURL = '';
62157             }
62158         }
62159     };
62160
62161
62162     wiki.entity = function(_) {
62163         if (!arguments.length) return entity;
62164         entity = _;
62165         return wiki;
62166     };
62167
62168
62169     wiki.focus = function() {
62170         title.node().focus();
62171     };
62172
62173
62174     return utilRebind(wiki, dispatch$$1, 'on');
62175 }
62176
62177 var uiFields = {
62178     access: uiFieldAccess,
62179     address: uiFieldAddress,
62180     check: uiFieldCheck,
62181     combo: uiFieldCombo,
62182     cycleway: uiFieldCycleway,
62183     defaultCheck: uiFieldCheck,
62184     email: uiFieldText,
62185     lanes: uiFieldLanes,
62186     localized: uiFieldLocalized,
62187     maxspeed: uiFieldMaxspeed,
62188     multiCombo: uiFieldCombo,
62189     networkCombo: uiFieldCombo,
62190     number: uiFieldText,
62191     onewayCheck: uiFieldCheck,
62192     radio: uiFieldRadio,
62193     restrictions: uiFieldRestrictions,
62194     semiCombo: uiFieldCombo,
62195     structureRadio: uiFieldRadio,
62196     tel: uiFieldText,
62197     text: uiFieldText,
62198     textarea: uiFieldTextarea,
62199     typeCombo: uiFieldCombo,
62200     url: uiFieldText,
62201     wikipedia: uiFieldWikipedia
62202 };
62203
62204 function uiField(context, presetField, entity, options) {
62205     options = assignIn({
62206         show: true,
62207         wrap: true,
62208         remove: true,
62209         revert: true,
62210         info: true
62211     }, options);
62212
62213     var dispatch$$1 = dispatch('change'),
62214         field = clone(presetField),
62215         show = options.show,
62216         state = '',
62217         tags = {};
62218
62219
62220     field.impl = uiFields[field.type](field, context)
62221         .on('change', function(t$$1, onInput) {
62222             dispatch$$1.call('change', field, t$$1, onInput);
62223         });
62224
62225     if (entity && field.impl.entity) {
62226         field.impl.entity(entity);
62227     }
62228
62229     field.keys = field.keys || [field.key];
62230
62231
62232     function isModified() {
62233         if (!entity) return false;
62234         var original = context.graph().base().entities[entity.id];
62235         return some(field.keys, function(key) {
62236             return original ? tags[key] !== original.tags[key] : tags[key];
62237         });
62238     }
62239
62240
62241     function isPresent() {
62242         return some(field.keys, function(key) {
62243             return tags[key];
62244         });
62245     }
62246
62247
62248     function revert(d) {
62249         event.stopPropagation();
62250         event.preventDefault();
62251         if (!entity) return false;
62252
62253         var original = context.graph().base().entities[entity.id],
62254             t$$1 = {};
62255         d.keys.forEach(function(key) {
62256             t$$1[key] = original ? original.tags[key] : undefined;
62257         });
62258
62259         dispatch$$1.call('change', d, t$$1);
62260     }
62261
62262
62263     function remove(d) {
62264         event.stopPropagation();
62265         event.preventDefault();
62266
62267         var t$$1 = {};
62268         d.keys.forEach(function(key) {
62269             t$$1[key] = undefined;
62270         });
62271
62272         dispatch$$1.call('change', d, t$$1);
62273     }
62274
62275
62276     field.render = function(selection) {
62277         var container = selection.selectAll('.form-field')
62278             .data([field]);
62279
62280         // Enter
62281         var enter = container.enter()
62282             .append('div')
62283             .attr('class', function(d) { return 'form-field form-field-' + d.id; })
62284             .classed('nowrap', !options.wrap);
62285
62286         if (options.wrap) {
62287             var label = enter
62288                 .append('label')
62289                 .attr('class', 'form-label')
62290                 .attr('for', function(d) { return 'preset-input-' + d.id; })
62291                 .text(function(d) { return d.label(); });
62292
62293             var wrap = label
62294                 .append('div')
62295                 .attr('class', 'form-label-button-wrap');
62296
62297             if (options.remove) {
62298                 wrap
62299                     .append('button')
62300                     .attr('class', 'remove-icon')
62301                     .attr('tabindex', -1)
62302                     .call(svgIcon('#operation-delete'));
62303             }
62304
62305             if (options.revert) {
62306                 wrap
62307                     .append('button')
62308                     .attr('class', 'modified-icon')
62309                     .attr('tabindex', -1)
62310                     .call(
62311                         (textDirection === 'rtl') ? svgIcon('#icon-redo') : svgIcon('#icon-undo')
62312                     );
62313             }
62314         }
62315
62316
62317         // Update
62318         container = container
62319             .merge(enter);
62320
62321         container.selectAll('.form-label-button-wrap .remove-icon')
62322             .on('click', remove);
62323
62324         container.selectAll('.form-label-button-wrap .modified-icon')
62325             .on('click', revert);
62326
62327         container
62328             .classed('modified', isModified())
62329             .classed('present', isPresent())
62330             .each(function(d) {
62331                 if (options.wrap && options.info) {
62332                     var referenceKey = d.key;
62333                     if (d.type === 'multiCombo') {   // lookup key without the trailing ':'
62334                         referenceKey = referenceKey.replace(/:$/, '');
62335                     }
62336                     var reference = uiTagReference(d.reference || { key: referenceKey }, context);
62337
62338                     if (state === 'hover') {
62339                         reference.showing(false);
62340                     }
62341                 }
62342
62343                 d3_select(this)
62344                     .call(d.impl);
62345
62346                 if (options.wrap && options.info) {
62347                     d3_select(this)
62348                         .call(reference.body)
62349                         .select('.form-label-button-wrap')
62350                         .call(reference.button);
62351                 }
62352
62353                 d.impl.tags(tags);
62354             });
62355     };
62356
62357
62358     field.state = function(_) {
62359         if (!arguments.length) return state;
62360         state = _;
62361         return field;
62362     };
62363
62364
62365     field.tags = function(_) {
62366         if (!arguments.length) return tags;
62367         tags = _;
62368         return field;
62369     };
62370
62371
62372     field.show = function() {
62373         show = true;
62374         if (field.default && field.key && tags[field.key] !== field.default) {
62375             var t$$1 = {};
62376             t$$1[field.key] = field.default;
62377             dispatch$$1.call('change', this, t$$1);
62378         }
62379     };
62380
62381
62382     field.isShown = function() {
62383         return show || some(field.keys, function(key) { return !!tags[key]; });
62384     };
62385
62386
62387     field.focus = function() {
62388         field.impl.focus();
62389     };
62390
62391
62392     return utilRebind(field, dispatch$$1, 'on');
62393 }
62394
62395 function uiFormFields(context) {
62396     var fieldsArr;
62397
62398
62399     function formFields(selection, klass) {
62400         render(selection, klass);
62401     }
62402
62403
62404     function render(selection, klass) {
62405
62406         var shown = fieldsArr.filter(function(field) { return field.isShown(); }),
62407             notShown = fieldsArr.filter(function(field) { return !field.isShown(); });
62408
62409         var container = selection.selectAll('.form-fields-container')
62410             .data([0]);
62411
62412         container = container.enter()
62413             .append('div')
62414             .attr('class', 'form-fields-container ' + (klass || ''))
62415             .merge(container);
62416
62417
62418         var fields = container.selectAll('.wrap-form-field')
62419             .data(shown, function(d) { return d.id; });
62420
62421         fields.exit()
62422             .remove();
62423
62424         // Enter
62425         var enter = fields.enter()
62426             .append('div')
62427             .attr('class', function(d) { return 'wrap-form-field wrap-form-field-' + d.id; });
62428
62429         // Update
62430         fields = fields
62431             .merge(enter);
62432
62433         fields
62434             .order()
62435             .each(function(d) {
62436                 d3_select(this)
62437                     .call(d.render);
62438             });
62439
62440
62441         notShown = notShown.map(function(field) {
62442             return {
62443                 title: field.label(),
62444                 value: field.label(),
62445                 field: field
62446             };
62447         });
62448
62449
62450         var more = selection.selectAll('.more-fields')
62451             .data((notShown.length > 0) ? [0] : []);
62452
62453         more.exit()
62454             .remove();
62455
62456         more = more.enter()
62457             .append('div')
62458             .attr('class', 'more-fields')
62459             .append('label')
62460             .text(t('inspector.add_fields'))
62461             .merge(more);
62462
62463
62464         var input = more.selectAll('.value')
62465             .data([0]);
62466
62467         input.exit()
62468             .remove();
62469
62470         input = input.enter()
62471             .append('input')
62472             .attr('class', 'value')
62473             .attr('type', 'text')
62474             .call(utilNoAuto)
62475             .merge(input);
62476
62477         input
62478             .call(utilGetSetValue, '')
62479             .attr('placeholder', function() {
62480                 var placeholder = [];
62481                 for (var field in notShown) {
62482                     placeholder.push(notShown[field].title);
62483                 }
62484                 return placeholder.slice(0,3).join(', ') + ((placeholder.length > 3) ? '…' : '');
62485             })
62486             .call(d3combobox()
62487                 .container(context.container())
62488                 .data(notShown)
62489                 .minItems(1)
62490                 .on('accept', function (d) {
62491                     var field = d.field;
62492                     field.show();
62493                     render(selection);
62494                     if (field.type !== 'semiCombo' && field.type !== 'multiCombo') {
62495                         field.focus();
62496                     }
62497                 })
62498             );
62499     }
62500
62501
62502     formFields.fieldsArr = function(_) {
62503         if (!arguments.length) return fieldsArr;
62504         fieldsArr = _;
62505         return formFields;
62506     };
62507
62508
62509     return formFields;
62510 }
62511
62512 function uiPresetEditor(context) {
62513     var dispatch$$1 = dispatch('change'),
62514         formFields = uiFormFields(context),
62515         expandedPreference = (context.storage('preset_fields.expanded') !== 'false'),
62516         state,
62517         fieldsArr,
62518         preset,
62519         tags,
62520         entityId;
62521
62522
62523     function presetEditor(selection) {
62524         selection.call(uiDisclosure()
62525             .title(t('inspector.all_fields'))
62526             .expanded(expandedPreference)
62527             .on('toggled', toggled)
62528             .content(render)
62529         );
62530
62531         function toggled(expanded) {
62532             expandedPreference = expanded;
62533             context.storage('preset_fields.expanded', expanded);
62534         }
62535     }
62536
62537
62538     function render(selection) {
62539         if (!fieldsArr) {
62540             var entity = context.entity(entityId),
62541                 geometry = context.geometry(entityId),
62542                 presets = context.presets();
62543
62544             fieldsArr = [];
62545
62546             preset.fields.forEach(function(field) {
62547                 if (field.matchGeometry(geometry)) {
62548                     fieldsArr.push(
62549                         uiField(context, field, entity)
62550                     );
62551                 }
62552             });
62553
62554             if (entity.isHighwayIntersection(context.graph()) && presets.field('restrictions')) {
62555                 fieldsArr.push(
62556                     uiField(context, presets.field('restrictions'), entity)
62557                 );
62558             }
62559
62560             presets.universal().forEach(function(field) {
62561                 if (preset.fields.indexOf(field) === -1) {
62562                     fieldsArr.push(
62563                         uiField(context, field, entity, { show: false })
62564                     );
62565                 }
62566             });
62567
62568             fieldsArr.forEach(function(field) {
62569                 field
62570                     .on('change', function(t$$1, onInput) {
62571                         dispatch$$1.call('change', field, t$$1, onInput);
62572                     });
62573             });
62574         }
62575
62576         fieldsArr.forEach(function(field) {
62577             field
62578                 .state(state)
62579                 .tags(tags);
62580         });
62581
62582
62583         selection
62584             .call(formFields.fieldsArr(fieldsArr), 'inspector-inner fillL3');
62585
62586
62587         selection.selectAll('.wrap-form-field input')
62588             .on('keydown', function() {
62589                 // if user presses enter, and combobox is not active, accept edits..
62590                 if (event.keyCode === 13 && d3_select('.combobox').empty()) {
62591                     context.enter(modeBrowse(context));
62592                 }
62593             });
62594     }
62595
62596
62597     presetEditor.preset = function(_) {
62598         if (!arguments.length) return preset;
62599         if (preset && preset.id === _.id) return presetEditor;
62600         preset = _;
62601         fieldsArr = null;
62602         return presetEditor;
62603     };
62604
62605
62606     presetEditor.state = function(_) {
62607         if (!arguments.length) return state;
62608         state = _;
62609         return presetEditor;
62610     };
62611
62612
62613     presetEditor.tags = function(_) {
62614         if (!arguments.length) return tags;
62615         tags = _;
62616         // Don't reset fieldsArr here.
62617         return presetEditor;
62618     };
62619
62620
62621     presetEditor.entityID = function(_) {
62622         if (!arguments.length) return entityId;
62623         if (entityId === _) return presetEditor;
62624         entityId = _;
62625         fieldsArr = null;
62626         return presetEditor;
62627     };
62628
62629
62630     return utilRebind(presetEditor, dispatch$$1, 'on');
62631 }
62632
62633 function uiEntityEditor(context) {
62634     var dispatch$$1 = dispatch('choose'),
62635         state = 'select',
62636         coalesceChanges = false,
62637         modified = false,
62638         base,
62639         entityId,
62640         activePreset,
62641         reference;
62642
62643     var presetEditor = uiPresetEditor(context)
62644         .on('change', changeTags);
62645     var rawTagEditor = uiRawTagEditor(context)
62646         .on('change', changeTags);
62647
62648
62649     function entityEditor(selection) {
62650         var entity = context.entity(entityId),
62651             tags = clone(entity.tags);
62652
62653         // Header
62654         var header = selection.selectAll('.header')
62655             .data([0]);
62656
62657         // Enter
62658         var enter = header.enter()
62659             .append('div')
62660             .attr('class', 'header fillL cf');
62661
62662         enter
62663             .append('button')
62664             .attr('class', 'fl preset-reset preset-choose')
62665             .call(svgIcon((textDirection === 'rtl') ? '#icon-forward' : '#icon-backward'));
62666
62667         enter
62668             .append('button')
62669             .attr('class', 'fr preset-close')
62670             .on('click', function() { context.enter(modeBrowse(context)); })
62671             .call(svgIcon(modified ? '#icon-apply' : '#icon-close'));
62672
62673         enter
62674             .append('h3')
62675             .text(t('inspector.edit'));
62676
62677         // Update
62678         header = header
62679             .merge(enter);
62680
62681         header.selectAll('.preset-reset')
62682             .on('click', function() {
62683                 dispatch$$1.call('choose', this, activePreset);
62684             });
62685
62686
62687         // Body
62688         var body = selection.selectAll('.inspector-body')
62689             .data([0]);
62690
62691         // Enter
62692         enter = body.enter()
62693             .append('div')
62694             .attr('class', 'inspector-body');
62695
62696         enter
62697             .append('div')
62698             .attr('class', 'preset-list-item inspector-inner')
62699             .append('div')
62700             .attr('class', 'preset-list-button-wrap')
62701             .append('button')
62702             .attr('class', 'preset-list-button preset-reset')
62703             .call(tooltip().title(t('inspector.back_tooltip')).placement('bottom'))
62704             .append('div')
62705             .attr('class', 'label');
62706
62707         enter
62708             .append('div')
62709             .attr('class', 'inspector-border preset-editor');
62710
62711         enter
62712             .append('div')
62713             .attr('class', 'inspector-border raw-tag-editor inspector-inner');
62714
62715         enter
62716             .append('div')
62717             .attr('class', 'inspector-border raw-member-editor inspector-inner');
62718
62719         enter
62720             .append('div')
62721             .attr('class', 'raw-membership-editor inspector-inner');
62722
62723         enter
62724             .append('input')
62725             .attr('type', 'text')
62726             .attr('class', 'key-trap');
62727
62728
62729         // Update
62730         body = body
62731             .merge(enter);
62732
62733         body.selectAll('.preset-list-button-wrap')
62734             .call(reference.button);
62735
62736         body.selectAll('.preset-list-item')
62737             .call(reference.body);
62738
62739         body.selectAll('.preset-reset')
62740             .on('click', function() {
62741                 dispatch$$1.call('choose', this, activePreset);
62742             });
62743
62744         body.select('.preset-list-item button')
62745             .call(uiPresetIcon()
62746                 .geometry(context.geometry(entityId))
62747                 .preset(activePreset)
62748             );
62749
62750         body.select('.preset-list-item .label')
62751             .text(activePreset.name());
62752
62753         body.select('.preset-editor')
62754             .call(presetEditor
62755                 .preset(activePreset)
62756                 .entityID(entityId)
62757                 .tags(tags)
62758                 .state(state)
62759             );
62760
62761         body.select('.raw-tag-editor')
62762             .call(rawTagEditor
62763                 .preset(activePreset)
62764                 .entityID(entityId)
62765                 .tags(tags)
62766                 .state(state)
62767             );
62768
62769         if (entity.type === 'relation') {
62770             body.select('.raw-member-editor')
62771                 .style('display', 'block')
62772                 .call(uiRawMemberEditor(context)
62773                     .entityID(entityId)
62774                 );
62775         } else {
62776             body.select('.raw-member-editor')
62777                 .style('display', 'none');
62778         }
62779
62780         body.select('.raw-membership-editor')
62781             .call(uiRawMembershipEditor(context)
62782                 .entityID(entityId)
62783             );
62784
62785         body.select('.key-trap')
62786             .on('keydown.key-trap', function() {
62787                 // On tabbing, send focus back to the first field on the inspector-body
62788                 // (probably the `name` field) #4159
62789                 if (event.keyCode === 9 && !event.shiftKey) {
62790                     event.preventDefault();
62791                     body.select('input').node().focus();
62792                 }
62793             });
62794
62795         context.history()
62796             .on('change.entity-editor', historyChanged);
62797
62798
62799         function historyChanged() {
62800             if (state === 'hide') return;
62801
62802             var entity = context.hasEntity(entityId);
62803             var graph = context.graph();
62804             if (!entity) return;
62805
62806             var match = context.presets().match(entity, graph);
62807             var activePreset = entityEditor.preset();
62808             var weakPreset = activePreset && isEmpty(activePreset.addTags);
62809
62810             // A "weak" preset doesn't set any tags. (e.g. "Address")
62811             // Don't replace a weak preset with a fallback preset (e.g. "Point")
62812             if (!(weakPreset && match.isFallback())) {
62813                 entityEditor.preset(match);
62814             }
62815             entityEditor.modified(base !== graph);
62816             entityEditor(selection);
62817         }
62818     }
62819
62820
62821     function clean(o) {
62822
62823         function cleanVal(k, v) {
62824             function keepSpaces(k) {
62825                 return k.match(/_hours|_times/) !== null;
62826             }
62827
62828             var blacklist = ['description', 'note', 'fixme'];
62829             if (some(blacklist, function(s) { return k.indexOf(s) !== -1; })) return v;
62830
62831             var cleaned = v.split(';')
62832                 .map(function(s) { return s.trim(); })
62833                 .join(keepSpaces(k) ? '; ' : ';');
62834
62835             // The code below is not intended to validate websites and emails.
62836             // It is only intended to prevent obvious copy-paste errors. (#2323)
62837             // clean website- and email-like tags
62838             if (k.indexOf('website') !== -1 ||
62839                 k.indexOf('email') !== -1 ||
62840                 cleaned.indexOf('http') === 0) {
62841                 cleaned = cleaned
62842                     .replace(/[\u200B-\u200F\uFEFF]/g, '');  // strip LRM and other zero width chars
62843
62844             }
62845
62846             return cleaned;
62847         }
62848
62849         var out = {}, k, v;
62850         for (k in o) {
62851             if (k && (v = o[k]) !== undefined) {
62852                 out[k] = cleanVal(k, v);
62853             }
62854         }
62855         return out;
62856     }
62857
62858
62859     // Tag changes that fire on input can all get coalesced into a single
62860     // history operation when the user leaves the field.  #2342
62861     function changeTags(changed, onInput) {
62862         var entity = context.entity(entityId),
62863             annotation = t('operations.change_tags.annotation'),
62864             tags = clone(entity.tags);
62865
62866         forEach(changed, function(v, k) {
62867             if (v !== undefined || tags.hasOwnProperty(k)) {
62868                 tags[k] = v;
62869             }
62870         });
62871
62872         if (!onInput) {
62873             tags = clean(tags);
62874         }
62875
62876         if (!isEqual(entity.tags, tags)) {
62877             if (coalesceChanges) {
62878                 context.overwrite(actionChangeTags(entityId, tags), annotation);
62879             } else {
62880                 context.perform(actionChangeTags(entityId, tags), annotation);
62881                 coalesceChanges = !!onInput;
62882             }
62883         }
62884     }
62885
62886
62887     entityEditor.modified = function(_) {
62888         if (!arguments.length) return modified;
62889         modified = _;
62890         d3_selectAll('button.preset-close use')
62891             .attr('xlink:href', (modified ? '#icon-apply' : '#icon-close'));
62892     };
62893
62894
62895     entityEditor.state = function(_) {
62896         if (!arguments.length) return state;
62897         state = _;
62898         return entityEditor;
62899     };
62900
62901
62902     entityEditor.entityID = function(_) {
62903         if (!arguments.length) return entityId;
62904         entityId = _;
62905         base = context.graph();
62906         entityEditor.preset(context.presets().match(context.entity(entityId), base));
62907         entityEditor.modified(false);
62908         coalesceChanges = false;
62909         return entityEditor;
62910     };
62911
62912
62913     entityEditor.preset = function(_) {
62914         if (!arguments.length) return activePreset;
62915         if (_ !== activePreset) {
62916             activePreset = _;
62917             reference = uiTagReference(activePreset.reference(context.geometry(entityId)), context)
62918                 .showing(false);
62919         }
62920         return entityEditor;
62921     };
62922
62923
62924     return utilRebind(entityEditor, dispatch$$1, 'on');
62925 }
62926
62927 function uiPresetList(context) {
62928     var dispatch$$1 = dispatch('choose'),
62929         id,
62930         currentPreset,
62931         autofocus = false;
62932
62933
62934     function presetList(selection) {
62935         var entity = context.entity(id),
62936             geometry = context.geometry(id);
62937
62938         // Treat entities on addr:interpolation lines as points, not vertices (#3241)
62939         if (geometry === 'vertex' && entity.isOnAddressLine(context.graph())) {
62940             geometry = 'point';
62941         }
62942
62943         var presets = context.presets().matchGeometry(geometry);
62944
62945         selection.html('');
62946
62947         var messagewrap = selection
62948             .append('div')
62949             .attr('class', 'header fillL cf');
62950
62951         var message = messagewrap
62952             .append('h3')
62953             .text(t('inspector.choose'));
62954
62955         if (context.entity(id).isUsed(context.graph())) {
62956             messagewrap
62957                 .append('button')
62958                 .attr('class', 'preset-choose')
62959                 .on('click', function() { dispatch$$1.call('choose', this, currentPreset); })
62960                 .call(svgIcon((textDirection === 'rtl') ? '#icon-backward' : '#icon-forward'));
62961         } else {
62962             messagewrap
62963                 .append('button')
62964                 .attr('class', 'close')
62965                 .on('click', function() {
62966                     context.enter(modeBrowse(context));
62967                 })
62968                 .call(svgIcon('#icon-close'));
62969         }
62970
62971         function keydown() {
62972             // hack to let delete shortcut work when search is autofocused
62973             if (search.property('value').length === 0 &&
62974                 (event.keyCode === d3keybinding.keyCodes['⌫'] ||
62975                  event.keyCode === d3keybinding.keyCodes['⌦'])) {
62976                 event.preventDefault();
62977                 event.stopPropagation();
62978                 operationDelete([id], context)();
62979             } else if (search.property('value').length === 0 &&
62980                 (event.ctrlKey || event.metaKey) &&
62981                 event.keyCode === d3keybinding.keyCodes.z) {
62982                 event.preventDefault();
62983                 event.stopPropagation();
62984                 context.undo();
62985             } else if (!event.ctrlKey && !event.metaKey) {
62986                 d3_select(this).on('keydown', null);
62987             }
62988         }
62989
62990         function keypress() {
62991             // enter
62992             var value = search.property('value');
62993             if (event.keyCode === 13 && value.length) {
62994                 list.selectAll('.preset-list-item:first-child').datum().choose();
62995             }
62996         }
62997
62998         function inputevent() {
62999             var value = search.property('value');
63000             list.classed('filtered', value.length);
63001             if (value.length) {
63002                 var results = presets.search(value, geometry);
63003                 message.text(t('inspector.results', {
63004                     n: results.collection.length,
63005                     search: value
63006                 }));
63007                 list.call(drawList, results);
63008             } else {
63009                 list.call(drawList, context.presets().defaults(geometry, 36));
63010                 message.text(t('inspector.choose'));
63011             }
63012         }
63013
63014         var searchWrap = selection
63015             .append('div')
63016             .attr('class', 'search-header');
63017
63018         var search = searchWrap
63019             .append('input')
63020             .attr('class', 'preset-search-input')
63021             .attr('placeholder', t('inspector.search'))
63022             .attr('type', 'search')
63023             .call(utilNoAuto)
63024             .on('keydown', keydown)
63025             .on('keypress', keypress)
63026             .on('input', inputevent);
63027
63028         searchWrap
63029             .call(svgIcon('#icon-search', 'pre-text'));
63030
63031         if (autofocus) {
63032             search.node().focus();
63033         }
63034
63035         var listWrap = selection
63036             .append('div')
63037             .attr('class', 'inspector-body');
63038
63039         var list = listWrap
63040             .append('div')
63041             .attr('class', 'preset-list fillL cf')
63042             .call(drawList, context.presets().defaults(geometry, 36));
63043     }
63044
63045
63046     function drawList(list, presets) {
63047         var collection = presets.collection.map(function(preset) {
63048             return preset.members ? CategoryItem(preset) : PresetItem(preset);
63049         });
63050
63051         var items = list.selectAll('.preset-list-item')
63052             .data(collection, function(d) { return d.preset.id; });
63053
63054         items.order();
63055
63056         items.exit()
63057             .remove();
63058
63059         items.enter()
63060             .append('div')
63061             .attr('class', function(item) { return 'preset-list-item preset-' + item.preset.id.replace('/', '-'); })
63062             .classed('current', function(item) { return item.preset === currentPreset; })
63063             .each(function(item) { d3_select(this).call(item); })
63064             .style('opacity', 0)
63065             .transition()
63066             .style('opacity', 1);
63067     }
63068
63069
63070     function CategoryItem(preset) {
63071         var box, sublist, shown = false;
63072
63073         function item(selection) {
63074             var wrap = selection.append('div')
63075                 .attr('class', 'preset-list-button-wrap category col12');
63076
63077             var button = wrap
63078                 .append('button')
63079                 .attr('class', 'preset-list-button')
63080                 .classed('expanded', false)
63081                 .call(uiPresetIcon()
63082                     .geometry(context.geometry(id))
63083                     .preset(preset))
63084                 .on('click', function() {
63085                     var isExpanded = d3_select(this).classed('expanded');
63086                     var iconName = isExpanded ?
63087                         (textDirection === 'rtl' ? '#icon-backward' : '#icon-forward') : '#icon-down';
63088                     d3_select(this)
63089                         .classed('expanded', !isExpanded);
63090                     d3_select(this).selectAll('div.label svg.icon use')
63091                         .attr('href', iconName);
63092                     item.choose();
63093                 });
63094
63095             var label = button
63096                 .append('div')
63097                 .attr('class', 'label');
63098
63099             label
63100                 .call(svgIcon((textDirection === 'rtl' ? '#icon-backward' : '#icon-forward'), 'inline'))
63101                 .append('span')
63102                 .html(function() { return preset.name() + '&hellip;'; });
63103
63104             box = selection.append('div')
63105                 .attr('class', 'subgrid col12')
63106                 .style('max-height', '0px')
63107                 .style('opacity', 0);
63108
63109             box.append('div')
63110                 .attr('class', 'arrow');
63111
63112             sublist = box.append('div')
63113                 .attr('class', 'preset-list fillL3 cf fl');
63114         }
63115
63116
63117         item.choose = function() {
63118             if (!box || !sublist) return;
63119
63120             if (shown) {
63121                 shown = false;
63122                 box.transition()
63123                     .duration(200)
63124                     .style('opacity', '0')
63125                     .style('max-height', '0px')
63126                     .style('padding-bottom', '0px');
63127             } else {
63128                 shown = true;
63129                 sublist.call(drawList, preset.members);
63130                 box.transition()
63131                     .duration(200)
63132                     .style('opacity', '1')
63133                     .style('max-height', 200 + preset.members.collection.length * 190 + 'px')
63134                     .style('padding-bottom', '20px');
63135             }
63136         };
63137
63138         item.preset = preset;
63139
63140         return item;
63141     }
63142
63143
63144     function PresetItem(preset) {
63145         function item(selection) {
63146             var wrap = selection.append('div')
63147                 .attr('class', 'preset-list-button-wrap col12');
63148
63149             wrap.append('button')
63150                 .attr('class', 'preset-list-button')
63151                 .call(uiPresetIcon()
63152                     .geometry(context.geometry(id))
63153                     .preset(preset))
63154                 .on('click', item.choose)
63155                 .append('div')
63156                 .attr('class', 'label')
63157                 .text(preset.name());
63158
63159             wrap.call(item.reference.button);
63160             selection.call(item.reference.body);
63161         }
63162
63163         item.choose = function() {
63164             context.presets().choose(preset);
63165
63166             context.perform(
63167                 actionChangePreset(id, currentPreset, preset),
63168                 t('operations.change_tags.annotation')
63169             );
63170
63171             dispatch$$1.call('choose', this, preset);
63172         };
63173
63174         item.help = function() {
63175             event.stopPropagation();
63176             item.reference.toggle();
63177         };
63178
63179         item.preset = preset;
63180         item.reference = uiTagReference(preset.reference(context.geometry(id)), context);
63181
63182         return item;
63183     }
63184
63185
63186     presetList.autofocus = function(_) {
63187         if (!arguments.length) return autofocus;
63188         autofocus = _;
63189         return presetList;
63190     };
63191
63192
63193     presetList.entityID = function(_) {
63194         if (!arguments.length) return id;
63195         id = _;
63196         presetList.preset(context.presets().match(context.entity(id), context.graph()));
63197         return presetList;
63198     };
63199
63200
63201     presetList.preset = function(_) {
63202         if (!arguments.length) return currentPreset;
63203         currentPreset = _;
63204         return presetList;
63205     };
63206
63207
63208     return utilRebind(presetList, dispatch$$1, 'on');
63209 }
63210
63211 function uiViewOnOSM(context) {
63212     var id;
63213
63214     function viewOnOSM(selection) {
63215         var entity = context.entity(id);
63216
63217         selection.style('display', entity.isNew() ? 'none' : null);
63218
63219         var link = selection.selectAll('.view-on-osm')
63220             .data([0]);
63221
63222         var enter = link.enter()
63223             .append('a')
63224             .attr('class', 'view-on-osm')
63225             .attr('target', '_blank')
63226             .call(svgIcon('#icon-out-link', 'inline'));
63227
63228         enter
63229             .append('span')
63230             .text(t('inspector.view_on_osm'));
63231
63232         link
63233             .merge(enter)
63234             .attr('href', context.connection().entityURL(entity));
63235     }
63236
63237
63238     viewOnOSM.entityID = function(_) {
63239         if (!arguments.length) return id;
63240         id = _;
63241         return viewOnOSM;
63242     };
63243
63244     return viewOnOSM;
63245 }
63246
63247 function uiInspector(context) {
63248     var presetList = uiPresetList(context),
63249         entityEditor = uiEntityEditor(context),
63250         state = 'select',
63251         entityID,
63252         newFeature = false;
63253
63254
63255     function inspector(selection) {
63256         presetList
63257             .entityID(entityID)
63258             .autofocus(newFeature)
63259             .on('choose', setPreset);
63260
63261         entityEditor
63262             .state(state)
63263             .entityID(entityID)
63264             .on('choose', showList);
63265
63266         var wrap = selection.selectAll('.panewrap')
63267             .data([0]);
63268
63269         var enter = wrap.enter()
63270             .append('div')
63271             .attr('class', 'panewrap');
63272
63273         enter
63274             .append('div')
63275             .attr('class', 'preset-list-pane pane');
63276
63277         enter
63278             .append('div')
63279             .attr('class', 'entity-editor-pane pane');
63280
63281         wrap = wrap.merge(enter);
63282         var presetPane = wrap.selectAll('.preset-list-pane');
63283         var editorPane = wrap.selectAll('.entity-editor-pane');
63284
63285         var graph = context.graph(),
63286             entity = context.entity(entityID),
63287             showEditor = state === 'hover' ||
63288                 entity.isUsed(graph) ||
63289                 entity.isHighwayIntersection(graph);
63290
63291         if (showEditor) {
63292             wrap.style('right', '0%');
63293             editorPane.call(entityEditor);
63294         } else {
63295             wrap.style('right', '-100%');
63296             presetPane.call(presetList);
63297         }
63298
63299         var footer = selection.selectAll('.footer')
63300             .data([0]);
63301
63302         footer = footer.enter()
63303             .append('div')
63304             .attr('class', 'footer')
63305             .merge(footer);
63306
63307         footer
63308             .call(uiViewOnOSM(context).entityID(entityID));
63309
63310
63311         function showList(preset) {
63312             wrap.transition()
63313                 .styleTween('right', function() { return d3_interpolate('0%', '-100%'); });
63314
63315             presetPane
63316                 .call(presetList.preset(preset).autofocus(true));
63317         }
63318
63319
63320         function setPreset(preset) {
63321             wrap.transition()
63322                 .styleTween('right', function() { return d3_interpolate('-100%', '0%'); });
63323
63324             editorPane
63325                 .call(entityEditor.preset(preset));
63326         }
63327     }
63328
63329
63330     inspector.state = function(_) {
63331         if (!arguments.length) return state;
63332         state = _;
63333         entityEditor.state(state);
63334         return inspector;
63335     };
63336
63337
63338     inspector.entityID = function(_) {
63339         if (!arguments.length) return entityID;
63340         entityID = _;
63341         return inspector;
63342     };
63343
63344
63345     inspector.newFeature = function(_) {
63346         if (!arguments.length) return newFeature;
63347         newFeature = _;
63348         return inspector;
63349     };
63350
63351
63352     return inspector;
63353 }
63354
63355 function uiSidebar(context) {
63356     var inspector = uiInspector(context),
63357         current;
63358
63359
63360     function sidebar(selection) {
63361         var featureListWrap = selection
63362             .append('div')
63363             .attr('class', 'feature-list-pane')
63364             .call(uiFeatureList(context));
63365
63366
63367         var inspectorWrap = selection
63368             .append('div')
63369             .attr('class', 'inspector-hidden inspector-wrap fr');
63370
63371
63372         function hover(id) {
63373             if (!current && context.hasEntity(id)) {
63374                 featureListWrap
63375                     .classed('inspector-hidden', true);
63376
63377                 inspectorWrap
63378                     .classed('inspector-hidden', false)
63379                     .classed('inspector-hover', true);
63380
63381                 if (inspector.entityID() !== id || inspector.state() !== 'hover') {
63382                     inspector
63383                         .state('hover')
63384                         .entityID(id);
63385
63386                     inspectorWrap
63387                         .call(inspector);
63388                 }
63389
63390             } else if (!current) {
63391                 featureListWrap
63392                     .classed('inspector-hidden', false);
63393                 inspectorWrap
63394                     .classed('inspector-hidden', true);
63395                 inspector
63396                     .state('hide');
63397             }
63398         }
63399
63400
63401         sidebar.hover = throttle(hover, 200);
63402
63403
63404         sidebar.select = function(id, newFeature) {
63405             if (!current && id) {
63406                 featureListWrap
63407                     .classed('inspector-hidden', true);
63408
63409                 inspectorWrap
63410                     .classed('inspector-hidden', false)
63411                     .classed('inspector-hover', false);
63412
63413                 if (inspector.entityID() !== id || inspector.state() !== 'select') {
63414                     inspector
63415                         .state('select')
63416                         .entityID(id)
63417                         .newFeature(newFeature);
63418
63419                     inspectorWrap
63420                         .call(inspector);
63421                 }
63422
63423             } else if (!current) {
63424                 featureListWrap
63425                     .classed('inspector-hidden', false);
63426                 inspectorWrap
63427                     .classed('inspector-hidden', true);
63428                 inspector
63429                     .state('hide');
63430             }
63431         };
63432
63433
63434         sidebar.show = function(component) {
63435             featureListWrap
63436                 .classed('inspector-hidden', true);
63437             inspectorWrap
63438                 .classed('inspector-hidden', true);
63439
63440             if (current) current.remove();
63441             current = selection
63442                 .append('div')
63443                 .attr('class', 'sidebar-component')
63444                 .call(component);
63445         };
63446
63447
63448         sidebar.hide = function() {
63449             featureListWrap
63450                 .classed('inspector-hidden', false);
63451             inspectorWrap
63452                 .classed('inspector-hidden', true);
63453
63454             if (current) current.remove();
63455             current = null;
63456         };
63457     }
63458
63459
63460     sidebar.hover = function() {};
63461     sidebar.hover.cancel = function() {};
63462     sidebar.select = function() {};
63463     sidebar.show = function() {};
63464     sidebar.hide = function() {};
63465
63466     return sidebar;
63467 }
63468
63469 function uiSpinner(context) {
63470     var osm = context.connection();
63471
63472
63473     return function(selection) {
63474         var img = selection
63475             .append('img')
63476             .attr('src', context.imagePath('loader-black.gif'))
63477             .style('opacity', 0);
63478
63479         if (osm) {
63480             osm
63481                 .on('loading.spinner', function() {
63482                     img.transition()
63483                         .style('opacity', 1);
63484                 })
63485                 .on('loaded.spinner', function() {
63486                     img.transition()
63487                         .style('opacity', 0);
63488                 });
63489         }
63490     };
63491 }
63492
63493 function uiSplash(context) {
63494
63495     return function(selection) {
63496         if (context.storage('sawSplash'))
63497              return;
63498
63499         context.storage('sawSplash', true);
63500
63501         var modalSelection = uiModal(selection);
63502
63503         modalSelection.select('.modal')
63504             .attr('class', 'modal-splash modal col6');
63505
63506         var introModal = modalSelection.select('.content')
63507             .append('div')
63508             .attr('class', 'fillL');
63509
63510         introModal
63511             .append('div')
63512             .attr('class','modal-section cf')
63513             .append('h3').text(t('splash.welcome'));
63514
63515         introModal
63516             .append('div')
63517             .attr('class','modal-section')
63518             .append('p')
63519             .html(t('splash.text', {
63520                 version: context.version,
63521                 website: '<a href="http://ideditor.com/">ideditor.com</a>',
63522                 github: '<a href="https://github.com/openstreetmap/iD">github.com</a>'
63523             }));
63524
63525         var buttonWrap = introModal
63526             .append('div')
63527             .attr('class', 'modal-actions cf');
63528
63529         var walkthrough = buttonWrap
63530             .append('button')
63531             .attr('class', 'walkthrough col6')
63532             .on('click', function() {
63533                 context.container().call(uiIntro(context));
63534                 modalSelection.close();
63535             });
63536
63537         walkthrough
63538             .append('svg')
63539             .attr('class', 'logo logo-walkthrough')
63540             .append('use')
63541             .attr('xlink:href', '#logo-walkthrough');
63542
63543         walkthrough
63544             .append('div')
63545             .text(t('splash.walkthrough'));
63546
63547         var startEditing = buttonWrap
63548             .append('button')
63549             .attr('class', 'start-editing col6')
63550             .on('click', modalSelection.close);
63551
63552         startEditing
63553             .append('svg')
63554             .attr('class', 'logo logo-features')
63555             .append('use')
63556             .attr('xlink:href', '#logo-features');
63557
63558         startEditing
63559             .append('div')
63560             .text(t('splash.start'));
63561
63562
63563         modalSelection.select('button.close')
63564             .attr('class','hide');
63565
63566     };
63567 }
63568
63569 function uiStatus(context) {
63570     var osm = context.connection();
63571
63572
63573     return function(selection) {
63574         if (!osm) return;
63575
63576         function update() {
63577             osm.status(function(err, apiStatus) {
63578                 selection.html('');
63579
63580                 if (err) {
63581                     if (apiStatus === 'connectionSwitched') {
63582                         // if the connection was just switched, we can't rely on
63583                         // the status (we're getting the status of the previous api)
63584                         return;
63585
63586                     } else if (apiStatus === 'rateLimited') {
63587                         selection
63588                             .text(t('status.rateLimit'))
63589                             .append('a')
63590                             .attr('class', 'api-status-login')
63591                             .attr('target', '_blank')
63592                             .call(svgIcon('#icon-out-link', 'inline'))
63593                             .append('span')
63594                             .text(t('login'))
63595                             .on('click.login', function() {
63596                                 event.preventDefault();
63597                                 osm.authenticate();
63598                             });
63599                     } else {
63600                         // eslint-disable-next-line no-warning-comments
63601                         // TODO: nice messages for different error types
63602                         selection.text(t('status.error'));
63603                     }
63604
63605                 } else if (apiStatus === 'readonly') {
63606                     selection.text(t('status.readonly'));
63607                 } else if (apiStatus === 'offline') {
63608                     selection.text(t('status.offline'));
63609                 }
63610
63611                 selection.attr('class', 'api-status ' + (err ? 'error' : apiStatus));
63612             });
63613         }
63614
63615         osm.on('change', function() { update(selection); });
63616
63617         window.setInterval(update, 90000);
63618         update(selection);
63619     };
63620 }
63621
63622 function uiUndoRedo(context) {
63623     var commands = [{
63624         id: 'undo',
63625         cmd: uiCmd('⌘Z'),
63626         action: function() { if (editable()) context.undo(); },
63627         annotation: function() { return context.history().undoAnnotation(); }
63628     }, {
63629         id: 'redo',
63630         cmd: uiCmd('⌘⇧Z'),
63631         action: function() { if (editable()) context.redo(); },
63632         annotation: function() { return context.history().redoAnnotation(); }
63633     }];
63634
63635
63636     function editable() {
63637         return context.editable() && context.mode().id !== 'save';
63638     }
63639
63640
63641     return function(selection) {
63642         var tooltipBehavior = tooltip()
63643             .placement('bottom')
63644             .html(true)
63645             .title(function (d) {
63646                 return uiTooltipHtml(d.annotation() ?
63647                     t(d.id + '.tooltip', {action: d.annotation()}) :
63648                     t(d.id + '.nothing'), d.cmd);
63649             });
63650
63651         var buttons = selection.selectAll('button')
63652             .data(commands)
63653             .enter()
63654             .append('button')
63655             .attr('class', function(d) { return 'col6 disabled ' + d.id + '-button'; })
63656             .on('click', function(d) { return d.action(); })
63657             .call(tooltipBehavior);
63658
63659         buttons.each(function(d) {
63660             var iconName = d.id;
63661             if (textDirection === 'rtl') {
63662                 if (iconName === 'undo') {
63663                     iconName = 'redo';
63664                 } else if (iconName === 'redo') {
63665                     iconName = 'undo';
63666                 }
63667             }
63668             d3_select(this)
63669                 .call(svgIcon('#icon-' + iconName));
63670         });
63671
63672         var keybinding = d3keybinding('undo')
63673             .on(commands[0].cmd, function() { event.preventDefault(); commands[0].action(); })
63674             .on(commands[1].cmd, function() { event.preventDefault(); commands[1].action(); });
63675
63676         d3_select(document)
63677             .call(keybinding);
63678
63679
63680         var debouncedUpdate = debounce(update, 500, { leading: true, trailing: true });
63681
63682         context.map()
63683             .on('move.undo_redo', debouncedUpdate)
63684             .on('drawn.undo_redo', debouncedUpdate);
63685
63686         context.history()
63687             .on('change.undo_redo', update);
63688
63689         context
63690             .on('enter.undo_redo', update);
63691
63692
63693         function update() {
63694             buttons
63695                 .property('disabled', !editable())
63696                 .classed('disabled', function(d) { return !d.annotation(); })
63697                 .each(function() {
63698                     var selection = d3_select(this);
63699                     if (selection.property('tooltipVisible')) {
63700                         selection.call(tooltipBehavior.show);
63701                     }
63702                 });
63703         }
63704     };
63705 }
63706
63707 // these are module variables so they are preserved through a ui.restart()
63708 var sawVersion = null;
63709 var isNewVersion = false;
63710 var isNewUser = false;
63711
63712
63713 function uiVersion(context) {
63714
63715     var currVersion = context.version,
63716         matchedVersion = currVersion.match(/\d\.\d\.\d.*/);
63717
63718     if (sawVersion === null && matchedVersion !== null) {
63719         isNewVersion = (context.storage('sawVersion') !== currVersion);
63720         isNewUser = !context.storage('sawSplash');
63721         context.storage('sawVersion', currVersion);
63722         sawVersion = currVersion;
63723     }
63724
63725     return function(selection) {
63726         selection
63727             .append('a')
63728             .attr('target', '_blank')
63729             .attr('tabindex', -1)
63730             .attr('href', 'https://github.com/openstreetmap/iD')
63731             .text(currVersion);
63732
63733         // only show new version indicator to users that have used iD before
63734         if (isNewVersion && !isNewUser) {
63735             selection
63736                 .append('div')
63737                 .attr('class', 'badge')
63738                 .append('a')
63739                 .attr('target', '_blank')
63740                 .attr('tabindex', -1)
63741                 .attr('href', 'https://github.com/openstreetmap/iD/blob/master/CHANGELOG.md#whats-new')
63742                 .call(svgIcon('#gift-11'))
63743                 .call(tooltip()
63744                     .title(t('version.whats_new', { version: currVersion }))
63745                     .placement('top')
63746                 );
63747         }
63748     };
63749 }
63750
63751 function uiZoom(context) {
63752     var zooms = [{
63753         id: 'zoom-in',
63754         icon: 'plus',
63755         title: t('zoom.in'),
63756         action: context.zoomIn,
63757         key: '+'
63758     }, {
63759         id: 'zoom-out',
63760         icon: 'minus',
63761         title: t('zoom.out'),
63762         action: context.zoomOut,
63763         key: '-'
63764     }];
63765
63766
63767     function zoomIn() {
63768         event.preventDefault();
63769         context.zoomIn();
63770     }
63771
63772
63773     function zoomOut() {
63774         event.preventDefault();
63775         context.zoomOut();
63776     }
63777
63778
63779     function zoomInFurther() {
63780         event.preventDefault();
63781         context.zoomInFurther();
63782     }
63783
63784
63785     function zoomOutFurther() {
63786         event.preventDefault();
63787         context.zoomOutFurther();
63788     }
63789
63790
63791     return function(selection) {
63792         var button = selection.selectAll('button')
63793             .data(zooms)
63794             .enter()
63795             .append('button')
63796             .attr('tabindex', -1)
63797             .attr('class', function(d) { return d.id; })
63798             .on('click.editor', function(d) { d.action(); })
63799             .call(tooltip()
63800                 .placement((textDirection === 'rtl') ? 'right' : 'left')
63801                 .html(true)
63802                 .title(function(d) {
63803                     return uiTooltipHtml(d.title, d.key);
63804                 })
63805             );
63806
63807         button.each(function(d) {
63808             d3_select(this)
63809                 .call(svgIcon('#icon-' + d.icon, 'light'));
63810         });
63811
63812         var keybinding = d3keybinding('zoom');
63813
63814         ['plus', 'ffplus', '=', 'ffequals'].forEach(function(key) {
63815             keybinding.on([key], zoomIn);
63816             keybinding.on([uiCmd('⌘' + key)], zoomInFurther);
63817         });
63818
63819         ['_', '-', 'ffminus', 'dash'].forEach(function(key) {
63820             keybinding.on([key], zoomOut);
63821             keybinding.on([uiCmd('⌘' + key)], zoomOutFurther);
63822         });
63823
63824         d3_select(document)
63825             .call(keybinding);
63826     };
63827 }
63828
63829 function uiInit(context) {
63830     var uiInitCounter = 0;
63831
63832
63833     function render(container) {
63834         container
63835             .attr('dir', textDirection);
63836
63837         var map = context.map();
63838
63839         var hash = behaviorHash(context);
63840         hash();
63841
63842         if (!hash.hadHash) {
63843             map.centerZoom([0, 0], 2);
63844         }
63845
63846         container
63847             .append('svg')
63848             .attr('id', 'defs')
63849             .call(svgDefs(context));
63850
63851         container
63852             .append('div')
63853             .attr('id', 'sidebar')
63854             .attr('class', 'col4')
63855             .call(ui.sidebar);
63856
63857         var content = container
63858             .append('div')
63859             .attr('id', 'content')
63860             .attr('class', 'active');
63861
63862         var bar = content
63863             .append('div')
63864             .attr('id', 'bar')
63865             .attr('class', 'fillD');
63866
63867         content
63868             .append('div')
63869             .attr('id', 'map')
63870             .attr('dir', 'ltr')
63871             .call(map);
63872
63873         content
63874             .call(uiMapInMap(context))
63875             .call(uiInfo(context))
63876             .call(uiNotice(context));
63877
63878         bar
63879             .append('div')
63880             .attr('class', 'spacer col4');
63881
63882         var limiter = bar.append('div')
63883             .attr('class', 'limiter');
63884
63885         limiter
63886             .append('div')
63887             .attr('class', 'button-wrap joined col3')
63888             .call(uiModes(context), limiter);
63889
63890         limiter
63891             .append('div')
63892             .attr('class', 'button-wrap joined col1')
63893             .call(uiUndoRedo(context));
63894
63895         limiter
63896             .append('div')
63897             .attr('class', 'button-wrap col1')
63898             .call(uiSave(context));
63899
63900         bar
63901             .append('div')
63902             .attr('class', 'full-screen')
63903             .call(uiFullScreen(context));
63904
63905         bar
63906             .append('div')
63907             .attr('class', 'spinner')
63908             .call(uiSpinner(context));
63909
63910
63911         var controls = bar
63912             .append('div')
63913             .attr('class', 'map-controls');
63914
63915         controls
63916             .append('div')
63917             .attr('class', 'map-control zoombuttons')
63918             .call(uiZoom(context));
63919
63920         controls
63921             .append('div')
63922             .attr('class', 'map-control geolocate-control')
63923             .call(uiGeolocate(context));
63924
63925         controls
63926             .append('div')
63927             .attr('class', 'map-control background-control')
63928             .call(uiBackground(context));
63929
63930         controls
63931             .append('div')
63932             .attr('class', 'map-control map-data-control')
63933             .call(uiMapData(context));
63934
63935         controls
63936             .append('div')
63937             .attr('class', 'map-control help-control')
63938             .call(uiHelp(context));
63939
63940
63941         var about = content
63942             .append('div')
63943             .attr('id', 'about');
63944
63945         about
63946             .append('div')
63947             .attr('id', 'attrib')
63948             .attr('dir', 'ltr')
63949             .call(uiAttribution(context));
63950
63951         about
63952             .append('div')
63953             .attr('class', 'api-status')
63954             .call(uiStatus(context));
63955
63956
63957         var footer = about
63958             .append('div')
63959             .attr('id', 'footer')
63960             .attr('class', 'fillD');
63961
63962         footer
63963             .append('div')
63964             .attr('id', 'flash-wrap')
63965             .attr('class', 'footer-hide');
63966
63967         var footerWrap = footer
63968             .append('div')
63969             .attr('id', 'footer-wrap')
63970             .attr('class', 'footer-show');
63971
63972         footerWrap
63973             .append('div')
63974             .attr('id', 'scale-block')
63975             .call(uiScale(context));
63976
63977         var aboutList = footerWrap
63978             .append('div')
63979             .attr('id', 'info-block')
63980             .append('ul')
63981             .attr('id', 'about-list');
63982
63983         if (!context.embed()) {
63984             aboutList
63985                 .call(uiAccount(context));
63986         }
63987
63988         aboutList
63989             .append('li')
63990             .attr('class', 'version')
63991             .call(uiVersion(context));
63992
63993         var issueLinks = aboutList
63994             .append('li');
63995
63996         issueLinks
63997             .append('a')
63998             .attr('target', '_blank')
63999             .attr('tabindex', -1)
64000             .attr('href', 'https://github.com/openstreetmap/iD/issues')
64001             .call(svgIcon('#icon-bug', 'light'))
64002             .call(tooltip().title(t('report_a_bug')).placement('top'));
64003
64004         issueLinks
64005             .append('a')
64006             .attr('target', '_blank')
64007             .attr('tabindex', -1)
64008             .attr('href', 'https://github.com/openstreetmap/iD/blob/master/CONTRIBUTING.md#translating')
64009             .call(svgIcon('#icon-translate', 'light'))
64010             .call(tooltip().title(t('help_translate')).placement('top'));
64011
64012         aboutList
64013             .append('li')
64014             .attr('class', 'feature-warning')
64015             .attr('tabindex', -1)
64016             .call(uiFeatureInfo(context));
64017
64018         aboutList
64019             .append('li')
64020             .attr('class', 'user-list')
64021             .attr('tabindex', -1)
64022             .call(uiContributors(context));
64023
64024
64025         var photoviewer = content
64026             .append('div')
64027             .attr('id', 'photoviewer')
64028             .classed('al', true)       // 'al'=left,  'ar'=right
64029             .classed('hide', true);
64030
64031         photoviewer
64032             .append('button')
64033             .attr('class', 'thumb-hide')
64034             .on('click', function () {
64035                 if (services.mapillary) { services.mapillary.hideViewer(); }
64036                 if (services.openstreetcam) { services.openstreetcam.hideViewer(); }
64037             })
64038             .append('div')
64039             .call(svgIcon('#icon-close'));
64040
64041
64042         window.onbeforeunload = function() {
64043             return context.save();
64044         };
64045
64046         window.onunload = function() {
64047             context.history().unlock();
64048         };
64049
64050         var mapDimensions = map.dimensions();
64051
64052
64053         function onResize() {
64054             mapDimensions = utilGetDimensions(content, true);
64055             map.dimensions(mapDimensions);
64056         }
64057
64058         d3_select(window)
64059             .on('resize.editor', onResize);
64060
64061         onResize();
64062
64063         function pan(d) {
64064             return function() {
64065                 event.preventDefault();
64066                 context.pan(d, 100);
64067             };
64068         }
64069
64070
64071         // pan amount
64072         var pa = 80;
64073
64074         var keybinding = d3keybinding('main')
64075             .on('⌫', function() { event.preventDefault(); })
64076             .on('←', pan([pa, 0]))
64077             .on('↑', pan([0, pa]))
64078             .on('→', pan([-pa, 0]))
64079             .on('↓', pan([0, -pa]))
64080             .on(['⇧←', uiCmd('⌘←')], pan([mapDimensions[0], 0]))
64081             .on(['⇧↑', uiCmd('⌘↑')], pan([0, mapDimensions[1]]))
64082             .on(['⇧→', uiCmd('⌘→')], pan([-mapDimensions[0], 0]))
64083             .on(['⇧↓', uiCmd('⌘↓')], pan([0, -mapDimensions[1]]));
64084
64085         d3_select(document)
64086             .call(keybinding);
64087
64088         context.enter(modeBrowse(context));
64089
64090         if (!uiInitCounter++) {
64091             if (!hash.startWalkthrough) {
64092                 context.container()
64093                     .call(uiSplash(context))
64094                     .call(uiRestore(context));
64095             }
64096
64097             context.container()
64098                 .call(uiShortcuts(context));
64099         }
64100
64101         var osm = context.connection(),
64102             auth = uiLoading(context).message(t('loading_auth')).blocking(true);
64103
64104         if (osm && auth) {
64105             osm
64106                 .on('authLoading.ui', function() {
64107                     context.container()
64108                         .call(auth);
64109                 })
64110                 .on('authDone.ui', function() {
64111                     auth.close();
64112                 });
64113         }
64114
64115         uiInitCounter++;
64116
64117         if (hash.startWalkthrough) {
64118             hash.startWalkthrough = false;
64119             context.container().call(uiIntro(context));
64120         }
64121     }
64122
64123
64124     var renderCallback;
64125
64126     function ui(node, callback) {
64127         renderCallback = callback;
64128         var container = d3_select(node);
64129         context.container(container);
64130         context.loadLocale(function(err) {
64131             if (!err) {
64132                 render(container);
64133             }
64134             if (callback) {
64135                 callback(err);
64136             }
64137         });
64138     }
64139
64140
64141     ui.restart = function(arg) {
64142         context.locale(arg);
64143         context.loadLocale(function(err) {
64144             if (!err) {
64145                 context.container().selectAll('*').remove();
64146                 render(context.container());
64147                 if (renderCallback) renderCallback();
64148             }
64149         });
64150     };
64151
64152
64153     ui.sidebar = uiSidebar(context);
64154
64155     return ui;
64156 }
64157
64158 function uiChangesetEditor(context) {
64159     var dispatch$$1 = dispatch('change'),
64160         formFields = uiFormFields(context),
64161         fieldsArr,
64162         tags,
64163         changesetId;
64164
64165
64166
64167     function changesetEditor(selection) {
64168         render(selection);
64169     }
64170
64171
64172     function render(selection) {
64173         var initial = false;
64174
64175         if (!fieldsArr) {
64176             initial = true;
64177             var presets = context.presets();
64178
64179             fieldsArr = [
64180                 uiField(context, presets.field('comment'), null, { show: true, revert: false }),
64181                 uiField(context, presets.field('source'), null, { show: false, revert: false }),
64182                 uiField(context, presets.field('hashtags'), null, { show: false, revert: false }),
64183             ];
64184
64185             fieldsArr.forEach(function(field) {
64186                 field
64187                     .on('change', function(t$$1, onInput) {
64188                         dispatch$$1.call('change', field, t$$1, onInput);
64189                     });
64190             });
64191         }
64192
64193         fieldsArr.forEach(function(field) {
64194             field
64195                 .tags(tags);
64196         });
64197
64198
64199         selection
64200             .call(formFields.fieldsArr(fieldsArr));
64201
64202
64203         if (initial) {
64204             var commentField = selection.select('#preset-input-comment'),
64205                 commentNode = commentField.node();
64206
64207             if (commentNode) {
64208                 commentNode.focus();
64209                 commentNode.select();
64210             }
64211
64212             // trigger a 'blur' event so that comment field can be cleaned
64213             // and checked for hashtags, even if retrieved from localstorage
64214             utilTriggerEvent(commentField, 'blur');
64215
64216             var osm = context.connection();
64217             if (osm) {
64218                 osm.userChangesets(function (err, changesets) {
64219                     if (err) return;
64220
64221                     var comments = changesets.map(function(changeset) {
64222                         return {
64223                             title: changeset.tags.comment,
64224                             value: changeset.tags.comment
64225                         };
64226                     });
64227
64228                     commentField
64229                         .call(d3combobox()
64230                             .container(context.container())
64231                             .caseSensitive(true)
64232                             .data(uniqBy(comments, 'title'))
64233                         );
64234                 });
64235             }
64236         }
64237
64238         // Add warning if comment mentions Google
64239         var hasGoogle = tags.comment.match(/google/i);
64240         var commentWarning = selection.select('.form-field-comment').selectAll('.comment-warning')
64241             .data(hasGoogle ? [0] : []);
64242
64243         commentWarning.exit()
64244             .transition()
64245             .duration(200)
64246             .style('opacity', 0)
64247             .remove();
64248
64249         var commentEnter = commentWarning.enter()
64250             .insert('div', '.tag-reference-body')
64251             .attr('class', 'field-warning comment-warning')
64252             .style('opacity', 0);
64253
64254         commentEnter
64255             .append('a')
64256             .attr('target', '_blank')
64257             .attr('tabindex', -1)
64258             .call(svgIcon('#icon-alert', 'inline'))
64259             .attr('href', t('commit.google_warning_link'))
64260             .append('span')
64261             .text(t('commit.google_warning'));
64262
64263         commentEnter
64264             .transition()
64265             .duration(200)
64266             .style('opacity', 1);
64267     }
64268
64269
64270     changesetEditor.tags = function(_) {
64271         if (!arguments.length) return tags;
64272         tags = _;
64273         // Don't reset fieldsArr here.
64274         return changesetEditor;
64275     };
64276
64277
64278     changesetEditor.changesetID = function(_) {
64279         if (!arguments.length) return changesetId;
64280         if (changesetId === _) return changesetEditor;
64281         changesetId = _;
64282         fieldsArr = null;
64283         return changesetEditor;
64284     };
64285
64286
64287     return utilRebind(changesetEditor, dispatch$$1, 'on');
64288 }
64289
64290 /**
64291  * This method is like `_.union` except that it accepts `iteratee` which is
64292  * invoked for each element of each `arrays` to generate the criterion by
64293  * which uniqueness is computed. Result values are chosen from the first
64294  * array in which the value occurs. The iteratee is invoked with one argument:
64295  * (value).
64296  *
64297  * @static
64298  * @memberOf _
64299  * @since 4.0.0
64300  * @category Array
64301  * @param {...Array} [arrays] The arrays to inspect.
64302  * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
64303  * @returns {Array} Returns the new array of combined values.
64304  * @example
64305  *
64306  * _.unionBy([2.1], [1.2, 2.3], Math.floor);
64307  * // => [2.1, 1.2]
64308  *
64309  * // The `_.property` iteratee shorthand.
64310  * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
64311  * // => [{ 'x': 1 }, { 'x': 2 }]
64312  */
64313 var unionBy = baseRest(function(arrays) {
64314   var iteratee = last(arrays);
64315   if (isArrayLikeObject(iteratee)) {
64316     iteratee = undefined;
64317   }
64318   return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), baseIteratee(iteratee, 2));
64319 });
64320
64321 function uiCommitChanges(context) {
64322     var _entityID;
64323     var detected = utilDetect();
64324
64325
64326     function commitChanges(selection) {
64327
64328         var history = context.history(),
64329             summary = history.difference().summary();
64330
64331         var container = selection.selectAll('.modal-section.commit-section')
64332             .data([0]);
64333
64334         var containerEnter = container.enter()
64335             .append('div')
64336             .attr('class', 'commit-section modal-section fillL2');
64337
64338         containerEnter
64339             .append('h3')
64340             .text(t('commit.changes', { count: summary.length }));
64341
64342         containerEnter
64343             .append('ul')
64344             .attr('class', 'changeset-list');
64345
64346         container = containerEnter
64347             .merge(container);
64348
64349
64350         var items = container.select('ul').selectAll('li')
64351             .data(summary);
64352
64353         var itemsEnter = items.enter()
64354             .append('li')
64355             .attr('class', 'change-item');
64356
64357         itemsEnter
64358             .each(function(d) {
64359                 d3_select(this)
64360                     .call(svgIcon('#icon-' + d.entity.geometry(d.graph), 'pre-text ' + d.changeType));
64361             });
64362
64363         itemsEnter
64364             .append('span')
64365             .attr('class', 'change-type')
64366             .text(function(d) { return t('commit.' + d.changeType) + ' '; });
64367
64368         itemsEnter
64369             .append('strong')
64370             .attr('class', 'entity-type')
64371             .text(function(d) {
64372                 var matched = context.presets().match(d.entity, d.graph);
64373                 return (matched && matched.name()) || utilDisplayType(d.entity.id);
64374             });
64375
64376         itemsEnter
64377             .append('span')
64378             .attr('class', 'entity-name')
64379             .text(function(d) {
64380                 var name = utilDisplayName(d.entity) || '',
64381                     string = '';
64382                 if (name !== '') {
64383                     string += ':';
64384                 }
64385                 return string += ' ' + name;
64386             });
64387
64388         itemsEnter
64389             .style('opacity', 0)
64390             .transition()
64391             .style('opacity', 1);
64392
64393         items = itemsEnter
64394             .merge(items);
64395
64396         items
64397             .on('mouseover', mouseover)
64398             .on('mouseout', mouseout)
64399             .on('click', click);
64400
64401
64402         // Download changeset link
64403         var changeset = new osmChangeset().update({ id: undefined }),
64404             changes = history.changes(actionDiscardTags(history.difference()));
64405
64406         delete changeset.id;  // Export without chnageset_id
64407
64408         var data = JXON.stringify(changeset.osmChangeJXON(changes)),
64409             blob = new Blob([data], {type: 'text/xml;charset=utf-8;'}),
64410             fileName = 'changes.osc';
64411
64412         var linkEnter = container.selectAll('.download-changes')
64413             .data([0])
64414             .enter()
64415             .append('a')
64416             .attr('class', 'download-changes');
64417
64418         if (detected.download) {      // All except IE11 and Edge
64419             linkEnter                 // download the data as a file
64420                 .attr('href', window.URL.createObjectURL(blob))
64421                 .attr('download', fileName);
64422
64423         } else {                      // IE11 and Edge
64424             linkEnter                 // open data uri in a new tab
64425                 .attr('target', '_blank')
64426                 .on('click.download', function() {
64427                     navigator.msSaveBlob(blob, fileName);
64428                 });
64429         }
64430
64431         linkEnter
64432             .call(svgIcon('#icon-load', 'inline'))
64433             .append('span')
64434             .text(t('commit.download_changes'));
64435
64436
64437         function mouseover(d) {
64438             if (d.entity) {
64439                 context.surface().selectAll(
64440                     utilEntityOrMemberSelector([d.entity.id], context.graph())
64441                 ).classed('hover', true);
64442             }
64443         }
64444
64445
64446         function mouseout() {
64447             context.surface().selectAll('.hover')
64448                 .classed('hover', false);
64449         }
64450
64451
64452         function click(change) {
64453             if (change.changeType === 'deleted') {
64454                 _entityID = null;
64455             } else {
64456                 var entity = change.entity;
64457                 _entityID = change.entity.id;
64458                 context.map().zoomTo(entity);
64459                 context.surface().selectAll(utilEntityOrMemberSelector([_entityID], context.graph()))
64460                     .classed('hover', true);
64461             }
64462         }
64463     }
64464
64465
64466     commitChanges.entityID = function(_) {
64467         if (!arguments.length) return _entityID;
64468         _entityID = _;
64469         return commitChanges;
64470     };
64471
64472
64473
64474     return commitChanges;
64475 }
64476
64477 function uiCommitWarnings(context) {
64478
64479     function commitWarnings(selection) {
64480
64481         var changes = context.history().changes();
64482         var warnings = context.history().validate(changes);
64483
64484         var container = selection.selectAll('.warning-section')
64485             .data(warnings.length ? [0] : []);
64486
64487         container.exit()
64488             .remove();
64489
64490         var containerEnter = container.enter()
64491             .append('div')
64492             .attr('class', 'modal-section warning-section fillL2');
64493
64494         containerEnter
64495             .append('h3')
64496             .text(t('commit.warnings'));
64497
64498         containerEnter
64499             .append('ul')
64500             .attr('class', 'changeset-list');
64501
64502         container = containerEnter
64503             .merge(container);
64504
64505
64506         var items = container.select('ul').selectAll('li')
64507             .data(warnings);
64508
64509         items.exit()
64510             .remove();
64511
64512         var itemsEnter = items.enter()
64513             .append('li')
64514             .attr('class', 'warning-item');
64515
64516         itemsEnter
64517             .call(svgIcon('#icon-alert', 'pre-text'));
64518
64519         itemsEnter
64520             .append('strong')
64521             .text(function(d) { return d.message; });
64522
64523         itemsEnter.filter(function(d) { return d.tooltip; })
64524             .call(tooltip()
64525                 .title(function(d) { return d.tooltip; })
64526                 .placement('top')
64527             );
64528
64529         items = itemsEnter
64530             .merge(items);
64531
64532         items
64533             .on('mouseover', mouseover)
64534             .on('mouseout', mouseout)
64535             .on('click', warningClick);
64536
64537
64538         function mouseover(d) {
64539             if (d.entity) {
64540                 context.surface().selectAll(
64541                     utilEntityOrMemberSelector([d.entity.id], context.graph())
64542                 ).classed('hover', true);
64543             }
64544         }
64545
64546
64547         function mouseout() {
64548             context.surface().selectAll('.hover')
64549                 .classed('hover', false);
64550         }
64551
64552
64553         function warningClick(d) {
64554             if (d.entity) {
64555                 context.map().zoomTo(d.entity);
64556                 context.enter(modeSelect(context, [d.entity.id]));
64557             }
64558         }
64559
64560     }
64561
64562
64563     return commitWarnings;
64564 }
64565
64566 var changeset;
64567 var readOnlyTags = [
64568     /^changesets_count$/,
64569     /^created_by$/,
64570     /^ideditor:/,
64571     /^imagery_used$/,
64572     /^host$/,
64573     /^locale$/
64574 ];
64575
64576 // treat most punctuation (except -, _, +, &) as hashtag delimiters - #4398
64577 // from https://stackoverflow.com/a/25575009
64578 var hashtagRegex = /(#[^\u2000-\u206F\u2E00-\u2E7F\s\\'!"#$%()*,.\/:;<=>?@\[\]^`{|}~]+)/g;
64579
64580
64581 function uiCommit(context) {
64582     var dispatch$$1 = dispatch('cancel', 'save'),
64583         userDetails,
64584         _selection;
64585
64586     var changesetEditor = uiChangesetEditor(context)
64587         .on('change', changeTags);
64588     var rawTagEditor = uiRawTagEditor(context)
64589         .on('change', changeTags);
64590     var commitChanges = uiCommitChanges(context);
64591     var commitWarnings = uiCommitWarnings(context);
64592
64593
64594     function commit(selection) {
64595         _selection = selection;
64596
64597         var osm = context.connection();
64598         if (!osm) return;
64599
64600         // expire stored comment and hashtags after cutoff datetime - #3947
64601         var commentDate = +context.storage('commentDate') || 0,
64602             currDate = Date.now(),
64603             cutoff = 2 * 86400 * 1000;   // 2 days
64604         if (commentDate > currDate || currDate - commentDate > cutoff) {
64605             context.storage('comment', null);
64606             context.storage('hashtags', null);
64607         }
64608
64609         var tags;
64610         if (!changeset) {
64611             var detected = utilDetect();
64612             tags = {
64613                 comment: context.storage('comment') || '',
64614                 created_by: ('iD ' + context.version).substr(0, 255),
64615                 host: detected.host.substr(0, 255),
64616                 locale: detected.locale.substr(0, 255)
64617             };
64618
64619             // call findHashtags initially - this will remove stored
64620             // hashtags if any hashtags are found in the comment - #4304
64621             findHashtags(tags, true);
64622
64623             var hashtags = context.storage('hashtags');
64624             if (hashtags) {
64625                 tags.hashtags = hashtags;
64626             }
64627
64628             changeset = new osmChangeset({ tags: tags });
64629         }
64630
64631         tags = clone(changeset.tags);
64632         tags.imagery_used = context.history().imageryUsed().join(';').substr(0, 255);
64633         changeset = changeset.update({ tags: tags });
64634
64635         var header = selection.selectAll('.header')
64636             .data([0]);
64637
64638         header.enter()
64639             .append('div')
64640             .attr('class', 'header fillL')
64641             .append('h3')
64642             .text(t('commit.title'));
64643
64644         var body = selection.selectAll('.body')
64645             .data([0]);
64646
64647         body = body.enter()
64648             .append('div')
64649             .attr('class', 'body')
64650             .merge(body);
64651
64652
64653         // Changeset Section
64654         var changesetSection = body.selectAll('.changeset-editor')
64655             .data([0]);
64656
64657         changesetSection = changesetSection.enter()
64658             .append('div')
64659             .attr('class', 'modal-section changeset-editor')
64660             .merge(changesetSection);
64661
64662         changesetSection
64663             .call(changesetEditor
64664                 .changesetID(changeset.id)
64665                 .tags(tags)
64666             );
64667
64668
64669         // Warnings
64670         body.call(commitWarnings);
64671
64672
64673         // Upload Explanation
64674         var saveSection = body.selectAll('.save-section')
64675             .data([0]);
64676
64677         saveSection = saveSection.enter()
64678             .append('div')
64679             .attr('class','modal-section save-section fillL cf')
64680             .merge(saveSection);
64681
64682         var prose = saveSection.selectAll('.commit-info')
64683             .data([0]);
64684
64685         prose = prose.enter()
64686             .append('p')
64687             .attr('class', 'commit-info')
64688             .text(t('commit.upload_explanation'))
64689             .merge(prose);
64690
64691         osm.userDetails(function(err, user) {
64692             if (err) return;
64693
64694             var userLink = d3_select(document.createElement('div'));
64695
64696             userDetails = user;
64697
64698             if (user.image_url) {
64699                 userLink
64700                     .append('img')
64701                     .attr('src', user.image_url)
64702                     .attr('class', 'icon pre-text user-icon');
64703             }
64704
64705             userLink
64706                 .append('a')
64707                 .attr('class','user-info')
64708                 .text(user.display_name)
64709                 .attr('href', osm.userURL(user.display_name))
64710                 .attr('tabindex', -1)
64711                 .attr('target', '_blank');
64712
64713             prose
64714                 .html(t('commit.upload_explanation_with_user', { user: userLink.html() }));
64715         });
64716
64717
64718         // Request Review
64719         var requestReview = saveSection.selectAll('.request-review')
64720             .data([0]);
64721
64722         // Enter
64723         var requestReviewEnter = requestReview.enter()
64724             .append('div')
64725             .attr('class', 'request-review');
64726
64727         var labelEnter = requestReviewEnter
64728             .append('label')
64729             .attr('for', 'commit-input-request-review');
64730
64731         labelEnter
64732             .append('input')
64733             .attr('type', 'checkbox')
64734             .attr('id', 'commit-input-request-review');
64735
64736         labelEnter
64737             .append('span')
64738             .text(t('commit.request_review'));
64739
64740         // Update
64741         requestReview = requestReview
64742             .merge(requestReviewEnter);
64743
64744         var requestReviewInput = requestReview.selectAll('input')
64745             .property('checked', isReviewRequested(changeset.tags))
64746             .on('change', toggleRequestReview);
64747
64748
64749         // Buttons
64750         var buttonSection = saveSection.selectAll('.buttons')
64751             .data([0]);
64752
64753         // enter
64754         var buttonEnter = buttonSection.enter()
64755             .append('div')
64756             .attr('class', 'buttons fillL cf');
64757
64758         buttonEnter
64759             .append('button')
64760             .attr('class', 'secondary-action col5 button cancel-button')
64761             .append('span')
64762             .attr('class', 'label')
64763             .text(t('commit.cancel'));
64764
64765         buttonEnter
64766             .append('button')
64767             .attr('class', 'action col5 button save-button')
64768             .append('span')
64769             .attr('class', 'label')
64770             .text(t('commit.save'));
64771
64772         // update
64773         buttonSection = buttonSection
64774             .merge(buttonEnter);
64775
64776         buttonSection.selectAll('.cancel-button')
64777             .on('click.cancel', function() {
64778                 var selectedID = commitChanges.entityID();
64779                 dispatch$$1.call('cancel', this, selectedID);
64780             });
64781
64782         buttonSection.selectAll('.save-button')
64783             .attr('disabled', function() {
64784                 var n = d3_select('#preset-input-comment').node();
64785                 return (n && n.value.length) ? null : true;
64786             })
64787             .on('click.save', function() {
64788                 dispatch$$1.call('save', this, changeset);
64789             });
64790
64791
64792         // Raw Tag Editor
64793         var tagSection = body.selectAll('.tag-section.raw-tag-editor')
64794             .data([0]);
64795
64796         tagSection = tagSection.enter()
64797             .append('div')
64798             .attr('class', 'modal-section tag-section raw-tag-editor')
64799             .merge(tagSection);
64800
64801         var expanded = !tagSection.selectAll('a.hide-toggle.expanded').empty();
64802         tagSection
64803             .call(rawTagEditor
64804                 .expanded(expanded)
64805                 .readOnlyTags(readOnlyTags)
64806                 .tags(clone(changeset.tags))
64807             );
64808
64809
64810         // Change summary
64811         body.call(commitChanges);
64812
64813
64814         function toggleRequestReview() {
64815             var rr = requestReviewInput.property('checked');
64816             updateChangeset({ review_requested: (rr ? 'yes' : undefined) });
64817
64818             var expanded = !tagSection.selectAll('a.hide-toggle.expanded').empty();
64819
64820             tagSection
64821                 .call(rawTagEditor
64822                     .expanded(expanded)
64823                     .readOnlyTags(readOnlyTags)
64824                     .tags(clone(changeset.tags))
64825                 );
64826         }
64827     }
64828
64829
64830     function changeTags(changed, onInput) {
64831         if (changed.hasOwnProperty('comment')) {
64832             if (changed.comment === undefined) {
64833                 changed.comment = '';
64834             }
64835             if (!onInput) {
64836                 context.storage('comment', changed.comment);
64837                 context.storage('commentDate', Date.now());
64838             }
64839         }
64840
64841         updateChangeset(changed, onInput);
64842
64843         if (_selection) {
64844             _selection.call(commit);
64845         }
64846     }
64847
64848
64849     function findHashtags(tags, commentOnly) {
64850         var inComment = commentTags(),
64851             inHashTags = hashTags();
64852
64853         if (inComment !== null) {                    // when hashtags are detected in comment...
64854             context.storage('hashtags', null);       // always remove stored hashtags - #4304
64855             if (commentOnly) { inHashTags = null; }  // optionally override hashtags field
64856         }
64857         return unionBy(inComment, inHashTags, function (s) {
64858             return s.toLowerCase();
64859         });
64860
64861         // Extract hashtags from `comment`
64862         function commentTags() {
64863             return tags.comment
64864                 .replace(/http\S*/g, '')  // drop anything that looks like a URL - #4289
64865                 .match(hashtagRegex);
64866         }
64867
64868         // Extract and clean hashtags from `hashtags`
64869         function hashTags() {
64870             var t$$1 = tags.hashtags || '';
64871             return t$$1
64872                 .split(/[,;\s]+/)
64873                 .map(function (s) {
64874                     if (s[0] !== '#') { s = '#' + s; }    // prepend '#'
64875                     var matched = s.match(hashtagRegex);
64876                     return matched && matched[0];
64877                 }).filter(Boolean);                       // exclude falsey
64878         }
64879     }
64880
64881
64882     function isReviewRequested(tags) {
64883         var rr = tags.review_requested;
64884         if (rr === undefined) return false;
64885         rr = rr.trim().toLowerCase();
64886         return !(rr === '' || rr === 'no');
64887     }
64888
64889
64890     function updateChangeset(changed, onInput) {
64891         var tags = clone(changeset.tags);
64892
64893         forEach(changed, function(v, k) {
64894             k = k.trim().substr(0, 255);
64895             if (readOnlyTags.indexOf(k) !== -1) return;
64896
64897             if (k !== '' && v !== undefined) {
64898                 if (onInput) {
64899                     tags[k] = v;
64900                 } else {
64901                     tags[k] = v.trim().substr(0, 255);
64902                 }
64903             } else {
64904                 delete tags[k];
64905             }
64906         });
64907
64908         if (!onInput) {
64909             // when changing the comment, override hashtags with any found in comment.
64910             var commentOnly = changed.hasOwnProperty('comment') && (changed.comment !== '');
64911             var arr = findHashtags(tags, commentOnly);
64912             if (arr.length) {
64913                 tags.hashtags = arr.join(';').substr(0, 255);
64914                 context.storage('hashtags', tags.hashtags);
64915             } else {
64916                 delete tags.hashtags;
64917                 context.storage('hashtags', null);
64918             }
64919         }
64920
64921         // always update userdetails, just in case user reauthenticates as someone else
64922         if (userDetails && userDetails.changesets_count !== undefined) {
64923             var changesetsCount = parseInt(userDetails.changesets_count, 10) + 1;  // #4283
64924             tags.changesets_count = String(changesetsCount);
64925
64926             // first 100 edits - new user
64927             if (changesetsCount <= 100) {
64928                 var s;
64929                 s = context.storage('walkthrough_completed');
64930                 if (s) {
64931                     tags['ideditor:walkthrough_completed'] = s;
64932                 }
64933
64934                 s = context.storage('walkthrough_progress');
64935                 if (s) {
64936                     tags['ideditor:walkthrough_progress'] = s;
64937                 }
64938
64939                 s = context.storage('walkthrough_started');
64940                 if (s) {
64941                     tags['ideditor:walkthrough_started'] = s;
64942                 }
64943             }
64944         } else {
64945             delete tags.changesets_count;
64946         }
64947
64948         if (!isEqual(changeset.tags, tags)) {
64949             changeset = changeset.update({ tags: tags });
64950         }
64951     }
64952
64953
64954     commit.reset = function() {
64955         changeset = null;
64956     };
64957
64958
64959     return utilRebind(commit, dispatch$$1, 'on');
64960 }
64961
64962 function uiConfirm(selection) {
64963     var modalSelection = uiModal(selection);
64964
64965     modalSelection.select('.modal')
64966         .classed('modal-alert', true);
64967
64968     var section = modalSelection.select('.content');
64969
64970     section.append('div')
64971         .attr('class', 'modal-section header');
64972
64973     section.append('div')
64974         .attr('class', 'modal-section message-text');
64975
64976     var buttons = section.append('div')
64977         .attr('class', 'modal-section buttons cf');
64978
64979
64980     modalSelection.okButton = function() {
64981         buttons
64982             .append('button')
64983             .attr('class', 'action col4')
64984             .on('click.confirm', function() {
64985                 modalSelection.remove();
64986             })
64987             .text(t('confirm.okay'));
64988
64989         return modalSelection;
64990     };
64991
64992
64993     return modalSelection;
64994 }
64995
64996 function uiConflicts(context) {
64997     var dispatch$$1 = dispatch('cancel', 'save'),
64998         origChanges,
64999         conflictList;
65000
65001
65002     function conflicts(selection) {
65003         var header = selection
65004             .append('div')
65005             .attr('class', 'header fillL');
65006
65007         header
65008             .append('button')
65009             .attr('class', 'fr')
65010             .on('click', function() { dispatch$$1.call('cancel'); })
65011             .call(svgIcon('#icon-close'));
65012
65013         header
65014             .append('h3')
65015             .text(t('save.conflict.header'));
65016
65017         var body = selection
65018             .append('div')
65019             .attr('class', 'body fillL');
65020
65021         var conflictsHelp = body
65022             .append('div')
65023             .attr('class', 'conflicts-help')
65024             .text(t('save.conflict.help'));
65025
65026
65027         // Download changes link
65028         var detected = utilDetect(),
65029             changeset = new osmChangeset();
65030
65031         delete changeset.id;  // Export without chnageset_id
65032
65033         var data = JXON.stringify(changeset.osmChangeJXON(origChanges)),
65034             blob = new Blob([data], {type: 'text/xml;charset=utf-8;'}),
65035             fileName = 'changes.osc';
65036
65037         var linkEnter = conflictsHelp.selectAll('.download-changes')
65038             .data([0])
65039             .enter()
65040             .append('a')
65041             .attr('class', 'download-changes');
65042
65043         if (detected.download) {      // All except IE11 and Edge
65044             linkEnter                 // download the data as a file
65045                 .attr('href', window.URL.createObjectURL(blob))
65046                 .attr('download', fileName);
65047
65048         } else {                      // IE11 and Edge
65049             linkEnter                 // open data uri in a new tab
65050                 .attr('target', '_blank')
65051                 .on('click.download', function() {
65052                     navigator.msSaveBlob(blob, fileName);
65053                 });
65054         }
65055
65056         linkEnter
65057             .call(svgIcon('#icon-load', 'inline'))
65058             .append('span')
65059             .text(t('save.conflict.download_changes'));
65060
65061
65062         body
65063             .append('div')
65064             .attr('class', 'conflict-container fillL3')
65065             .call(showConflict, 0);
65066
65067         body
65068             .append('div')
65069             .attr('class', 'conflicts-done')
65070             .attr('opacity', 0)
65071             .style('display', 'none')
65072             .text(t('save.conflict.done'));
65073
65074         var buttons = body
65075             .append('div')
65076             .attr('class','buttons col12 joined conflicts-buttons');
65077
65078         buttons
65079             .append('button')
65080             .attr('disabled', conflictList.length > 1)
65081             .attr('class', 'action conflicts-button col6')
65082             .text(t('save.title'))
65083             .on('click.try_again', function() { dispatch$$1.call('save'); });
65084
65085         buttons
65086             .append('button')
65087             .attr('class', 'secondary-action conflicts-button col6')
65088             .text(t('confirm.cancel'))
65089             .on('click.cancel', function() { dispatch$$1.call('cancel'); });
65090     }
65091
65092
65093     function showConflict(selection, index) {
65094         if (index < 0 || index >= conflictList.length) return;
65095
65096         var parent = d3_select(selection.node().parentNode);
65097
65098         // enable save button if this is the last conflict being reviewed..
65099         if (index === conflictList.length - 1) {
65100             window.setTimeout(function() {
65101                 parent.select('.conflicts-button')
65102                     .attr('disabled', null);
65103
65104                 parent.select('.conflicts-done')
65105                     .transition()
65106                     .attr('opacity', 1)
65107                     .style('display', 'block');
65108             }, 250);
65109         }
65110
65111         var item = selection
65112             .selectAll('.conflict')
65113             .data([conflictList[index]]);
65114
65115         var enter = item.enter()
65116             .append('div')
65117             .attr('class', 'conflict');
65118
65119         enter
65120             .append('h4')
65121             .attr('class', 'conflict-count')
65122             .text(t('save.conflict.count', { num: index + 1, total: conflictList.length }));
65123
65124         enter
65125             .append('a')
65126             .attr('class', 'conflict-description')
65127             .attr('href', '#')
65128             .text(function(d) { return d.name; })
65129             .on('click', function(d) {
65130                 zoomToEntity(d.id);
65131                 event.preventDefault();
65132             });
65133
65134         var details = enter
65135             .append('div')
65136             .attr('class', 'conflict-detail-container');
65137
65138         details
65139             .append('ul')
65140             .attr('class', 'conflict-detail-list')
65141             .selectAll('li')
65142             .data(function(d) { return d.details || []; })
65143             .enter()
65144             .append('li')
65145             .attr('class', 'conflict-detail-item')
65146             .html(function(d) { return d; });
65147
65148         details
65149             .append('div')
65150             .attr('class', 'conflict-choices')
65151             .call(addChoices);
65152
65153         details
65154             .append('div')
65155             .attr('class', 'conflict-nav-buttons joined cf')
65156             .selectAll('button')
65157             .data(['previous', 'next'])
65158             .enter()
65159             .append('button')
65160             .text(function(d) { return t('save.conflict.' + d); })
65161             .attr('class', 'conflict-nav-button action col6')
65162             .attr('disabled', function(d, i) {
65163                 return (i === 0 && index === 0) ||
65164                     (i === 1 && index === conflictList.length - 1) || null;
65165             })
65166             .on('click', function(d, i) {
65167                 var container = parent.select('.conflict-container'),
65168                 sign = (i === 0 ? -1 : 1);
65169
65170                 container
65171                     .selectAll('.conflict')
65172                     .remove();
65173
65174                 container
65175                     .call(showConflict, index + sign);
65176
65177                 event.preventDefault();
65178             });
65179
65180         item.exit()
65181             .remove();
65182     }
65183
65184
65185     function addChoices(selection) {
65186         var choices = selection
65187             .append('ul')
65188             .attr('class', 'layer-list')
65189             .selectAll('li')
65190             .data(function(d) { return d.choices || []; });
65191
65192         var enter = choices.enter()
65193             .append('li')
65194             .attr('class', 'layer');
65195
65196         var label = enter
65197             .append('label');
65198
65199         label
65200             .append('input')
65201             .attr('type', 'radio')
65202             .attr('name', function(d) { return d.id; })
65203             .on('change', function(d, i) {
65204                 var ul = this.parentNode.parentNode.parentNode;
65205                 ul.__data__.chosen = i;
65206                 choose(ul, d);
65207             });
65208
65209         label
65210             .append('span')
65211             .text(function(d) { return d.text; });
65212
65213         choices
65214             .each(function(d, i) {
65215                 var ul = this.parentNode;
65216                 if (ul.__data__.chosen === i) choose(ul, d);
65217             });
65218     }
65219
65220
65221     function choose(ul, datum) {
65222         if (event) event.preventDefault();
65223
65224         d3_select(ul)
65225             .selectAll('li')
65226             .classed('active', function(d) { return d === datum; })
65227             .selectAll('input')
65228             .property('checked', function(d) { return d === datum; });
65229
65230         var extent = geoExtent(),
65231             entity;
65232
65233         entity = context.graph().hasEntity(datum.id);
65234         if (entity) extent._extend(entity.extent(context.graph()));
65235
65236         datum.action();
65237
65238         entity = context.graph().hasEntity(datum.id);
65239         if (entity) extent._extend(entity.extent(context.graph()));
65240
65241         zoomToEntity(datum.id, extent);
65242     }
65243
65244
65245     function zoomToEntity(id, extent) {
65246         context.surface().selectAll('.hover')
65247             .classed('hover', false);
65248
65249         var entity = context.graph().hasEntity(id);
65250         if (entity) {
65251             if (extent) {
65252                 context.map().trimmedExtent(extent);
65253             } else {
65254                 context.map().zoomTo(entity);
65255             }
65256             context.surface().selectAll(
65257                 utilEntityOrMemberSelector([entity.id], context.graph()))
65258                 .classed('hover', true);
65259         }
65260     }
65261
65262
65263     // The conflict list should be an array of objects like:
65264     // {
65265     //     id: id,
65266     //     name: entityName(local),
65267     //     details: merge.conflicts(),
65268     //     chosen: 1,
65269     //     choices: [
65270     //         choice(id, keepMine, forceLocal),
65271     //         choice(id, keepTheirs, forceRemote)
65272     //     ]
65273     // }
65274     conflicts.list = function(_) {
65275         if (!arguments.length) return conflictList;
65276         conflictList = _;
65277         return conflicts;
65278     };
65279
65280
65281     conflicts.origChanges = function(_) {
65282         if (!arguments.length) return origChanges;
65283         origChanges = _;
65284         return conflicts;
65285     };
65286
65287
65288     return utilRebind(conflicts, dispatch$$1, 'on');
65289 }
65290
65291 function uiEditMenu(context, operations) {
65292     var menu,
65293         center = [0, 0],
65294         offset = [0, 0],
65295         tooltip;
65296
65297     var p = 8,               // top padding
65298         m = 4,               // top margin
65299         h = 15,              // height of icon
65300         vpBottomMargin = 45, // viewport bottom margin
65301         vpSideMargin = 35,   // viewport side margin
65302         buttonWidth = 44,
65303         buttonHeight = (2 * p + h),
65304         menuWidth = buttonWidth,
65305         menuHeight = (2 * m) + operations.length * buttonHeight,
65306         menuSideMargin = 10,
65307         tooltipWidth = 200,
65308         tooltipHeight = 200;  // a reasonable guess, real height depends on tooltip contents
65309
65310
65311     var editMenu = function (selection) {
65312         if (!operations.length) return;
65313
65314         selection.node().parentNode.focus();
65315
65316         var isRTL = textDirection === 'rtl',
65317             viewport = context.surfaceRect();
65318
65319         if (!isRTL && (center[0] + menuSideMargin + menuWidth) > (viewport.width - vpSideMargin)) {
65320             // menu is going left-to-right and near right viewport edge, go left instead
65321             isRTL = true;
65322         } else if (isRTL && (center[0] - menuSideMargin - menuWidth) < vpSideMargin) {
65323             // menu is going right-to-left and near left viewport edge, go right instead
65324             isRTL = false;
65325         }
65326
65327         offset[0] = (isRTL ? -1 * (menuSideMargin + menuWidth) : menuSideMargin);
65328
65329         if (center[1] + menuHeight > (viewport.height - vpBottomMargin)) {
65330             // menu is near bottom viewport edge, shift upwards
65331             offset[1] = -1 * (center[1] + menuHeight - viewport.height + vpBottomMargin);
65332         }
65333
65334         var origin = [ center[0] + offset[0], center[1] + offset[1] ];
65335
65336         menu = selection
65337             .append('g')
65338             .attr('class', 'edit-menu')
65339             .attr('transform', 'translate(' + origin + ')')
65340             .attr('opacity', 0);
65341
65342         menu
65343             .transition()
65344             .attr('opacity', 1);
65345
65346         menu
65347             .append('rect')
65348             .attr('class', 'edit-menu-background')
65349             .attr('x', 4)
65350             .attr('rx', 4)
65351             .attr('ry', 4)
65352             .attr('width', menuWidth)
65353             .attr('height', menuHeight)
65354             .attr('stroke-linecap', 'round');
65355
65356
65357         var button = menu.selectAll('.edit-menu-item')
65358             .data(operations)
65359             .enter()
65360             .append('g')
65361             .attr('class', function (d) { return 'edit-menu-item edit-menu-item-' + d.id; })
65362             .classed('disabled', function (d) { return d.disabled(); })
65363             .attr('transform', function (d, i) {
65364                 return 'translate(' + geoRoundCoords([
65365                     0,
65366                     m + i * buttonHeight
65367                 ]).join(',') + ')';
65368             });
65369
65370         button
65371             .append('rect')
65372             .attr('x', 4)
65373             .attr('width', buttonWidth)
65374             .attr('height', buttonHeight)
65375             .on('click', click)
65376             .on('mousedown', mousedown)
65377             .on('mouseover', mouseover)
65378             .on('mouseout', mouseout);
65379
65380         button
65381             .append('use')
65382             .attr('width', '20')
65383             .attr('height', '20')
65384             .attr('transform', function () {
65385                 return 'translate(' + [2 * p, 5] + ')';
65386             })
65387             .attr('xlink:href', function (d) { return '#operation-' + d.id; });
65388
65389         tooltip = d3_select(document.body)
65390             .append('div')
65391             .attr('class', 'tooltip-inner edit-menu-tooltip');
65392
65393
65394         function click(operation) {
65395             event.stopPropagation();
65396             if (operation.disabled()) return;
65397             operation();
65398             editMenu.close();
65399         }
65400
65401         function mousedown() {
65402             event.stopPropagation();  // https://github.com/openstreetmap/iD/issues/1869
65403         }
65404
65405         function mouseover(d, i) {
65406             var tipX, tipY;
65407
65408             if (!isRTL) {
65409                 tipX = viewport.left + origin[0] + menuSideMargin + menuWidth;
65410             } else {
65411                 tipX = viewport.left + origin[0] - 4 - tooltipWidth;
65412             }
65413
65414             if (tipX + tooltipWidth > viewport.right) {
65415                 // tip is going left-to-right and near right viewport edge, go left instead
65416                 tipX = viewport.left + origin[0] - 4 - tooltipWidth;
65417             } else if (tipX < viewport.left) {
65418                 // tip is going right-to-left and near left viewport edge, go right instead
65419                 tipX = viewport.left + origin[0] + menuSideMargin + menuWidth;
65420             }
65421
65422             tipY = viewport.top + origin[1] + (i * buttonHeight);
65423             if (tipY + tooltipHeight > viewport.bottom) {
65424                 // tip is near bottom viewport edge, shift upwards
65425                 tipY -= tipY + tooltipHeight - viewport.bottom;
65426             }
65427
65428             tooltip
65429                 .style('left', tipX + 'px')
65430                 .style('top', tipY + 'px')
65431                 .style('display', 'block')
65432                 .html(uiTooltipHtml(d.tooltip(), d.keys[0], d.title));
65433         }
65434
65435         function mouseout() {
65436             tooltip.style('display', 'none');
65437         }
65438     };
65439
65440
65441     editMenu.close = function () {
65442         if (menu) {
65443             menu
65444                 .style('pointer-events', 'none')
65445                 .transition()
65446                 .attr('opacity', 0)
65447                 .remove();
65448         }
65449
65450         if (tooltip) {
65451             tooltip.remove();
65452         }
65453     };
65454
65455
65456     editMenu.center = function (_) {
65457         if (!arguments.length) return center;
65458         center = _;
65459         return editMenu;
65460     };
65461
65462
65463     return editMenu;
65464 }
65465
65466 var timer$1;
65467
65468
65469 function uiFlash(showDuration) {
65470     showDuration = showDuration || 1500;
65471
65472     if (timer$1) {
65473         timer$1.stop();
65474     }
65475
65476     d3_select('#footer-wrap')
65477         .attr('class', 'footer-hide');
65478     d3_select('#flash-wrap')
65479         .attr('class', 'footer-show');
65480
65481     var content = d3_select('#flash-wrap').selectAll('.content')
65482         .data([0]);
65483
65484     content = content.enter()
65485         .append('div')
65486         .attr('class', 'content')
65487         .merge(content);
65488
65489     timer$1 = d3_timeout(function() {
65490         timer$1 = null;
65491         d3_select('#footer-wrap')
65492             .attr('class', 'footer-show');
65493         d3_select('#flash-wrap')
65494             .attr('class', 'footer-hide');
65495     }, showDuration);
65496
65497
65498     return content;
65499 }
65500
65501 function uiLasso(context) {
65502     var group, polygon;
65503
65504     lasso.coordinates = [];
65505
65506     function lasso(selection) {
65507         context.container()
65508             .classed('lasso', true);
65509
65510         group = selection
65511             .append('g')
65512             .attr('class', 'lasso hide');
65513
65514         polygon = group
65515             .append('path')
65516             .attr('class', 'lasso-path');
65517
65518         group
65519             .call(uiToggle(true));
65520     }
65521
65522
65523     function draw() {
65524         if (polygon) {
65525             polygon.data([lasso.coordinates])
65526                 .attr('d', function(d) { return 'M' + d.join(' L') + ' Z'; });
65527         }
65528     }
65529
65530
65531     lasso.extent = function () {
65532         return lasso.coordinates.reduce(function(extent, point) {
65533             return extent.extend(geoExtent(point));
65534         }, geoExtent());
65535     };
65536
65537
65538     lasso.p = function(_) {
65539         if (!arguments.length) return lasso;
65540         lasso.coordinates.push(_);
65541         draw();
65542         return lasso;
65543     };
65544
65545
65546     lasso.close = function() {
65547         if (group) {
65548             group.call(uiToggle(false, function() {
65549                 d3_select(this).remove();
65550             }));
65551         }
65552         context.container().classed('lasso', false);
65553     };
65554
65555
65556     return lasso;
65557 }
65558
65559 function uiRadialMenu(context, operations) {
65560     var menu,
65561         center = [0, 0],
65562         tooltip;
65563
65564
65565     var radialMenu = function(selection) {
65566         if (!operations.length) return;
65567
65568         selection.node().parentNode.focus();
65569
65570         function click(operation) {
65571             event.stopPropagation();
65572             if (operation.disabled()) return;
65573             operation();
65574             radialMenu.close();
65575         }
65576
65577         menu = selection
65578             .append('g')
65579             .attr('class', 'radial-menu')
65580             .attr('transform', 'translate(' + center + ')')
65581             .attr('opacity', 0);
65582
65583         menu
65584             .transition()
65585             .attr('opacity', 1);
65586
65587         var r = 50,
65588             a = Math.PI / 4,
65589             a0 = -Math.PI / 4,
65590             a1 = a0 + (operations.length - 1) * a;
65591
65592         menu
65593             .append('path')
65594             .attr('class', 'radial-menu-background')
65595             .attr('d', 'M' + r * Math.sin(a0) + ',' +
65596                              r * Math.cos(a0) +
65597                       ' A' + r + ',' + r + ' 0 ' + (operations.length > 5 ? '1' : '0') + ',0 ' +
65598                              (r * Math.sin(a1) + 1e-3) + ',' +
65599                              (r * Math.cos(a1) + 1e-3)) // Force positive-length path (#1305)
65600             .attr('stroke-width', 50)
65601             .attr('stroke-linecap', 'round');
65602
65603         var button = menu.selectAll()
65604             .data(operations)
65605             .enter()
65606             .append('g')
65607             .attr('class', function(d) { return 'radial-menu-item radial-menu-item-' + d.id; })
65608             .classed('disabled', function(d) { return d.disabled(); })
65609             .attr('transform', function(d, i) {
65610                 return 'translate(' + geoRoundCoords([
65611                         r * Math.sin(a0 + i * a),
65612                         r * Math.cos(a0 + i * a)]).join(',') + ')';
65613             });
65614
65615         button
65616             .append('circle')
65617             .attr('r', 15)
65618             .on('click', click)
65619             .on('mousedown', mousedown)
65620             .on('mouseover', mouseover)
65621             .on('mouseout', mouseout);
65622
65623         button
65624             .append('use')
65625             .attr('transform', 'translate(-10,-10)')
65626             .attr('width', '20')
65627             .attr('height', '20')
65628             .attr('xlink:href', function(d) { return '#operation-' + d.id; });
65629
65630         tooltip = d3_select(document.body)
65631             .append('div')
65632             .attr('class', 'tooltip-inner radial-menu-tooltip');
65633
65634         function mousedown() {
65635             event.stopPropagation(); // https://github.com/openstreetmap/iD/issues/1869
65636         }
65637
65638         function mouseover(d, i) {
65639             var rect = context.surfaceRect(),
65640                 angle = a0 + i * a,
65641                 top = rect.top + (r + 25) * Math.cos(angle) + center[1] + 'px',
65642                 left = rect.left + (r + 25) * Math.sin(angle) + center[0] + 'px',
65643                 bottom = rect.height - (r + 25) * Math.cos(angle) - center[1] + 'px',
65644                 right = rect.width - (r + 25) * Math.sin(angle) - center[0] + 'px';
65645
65646             tooltip
65647                 .style('top', null)
65648                 .style('left', null)
65649                 .style('bottom', null)
65650                 .style('right', null)
65651                 .style('display', 'block')
65652                 .html(uiTooltipHtml(d.tooltip(), d.keys[0]));
65653
65654             if (i === 0) {
65655                 tooltip
65656                     .style('right', right)
65657                     .style('top', top);
65658             } else if (i >= 4) {
65659                 tooltip
65660                     .style('left', left)
65661                     .style('bottom', bottom);
65662             } else {
65663                 tooltip
65664                     .style('left', left)
65665                     .style('top', top);
65666             }
65667         }
65668
65669         function mouseout() {
65670             tooltip.style('display', 'none');
65671         }
65672     };
65673
65674
65675     radialMenu.close = function() {
65676         if (menu) {
65677             menu
65678                 .style('pointer-events', 'none')
65679                 .transition()
65680                 .attr('opacity', 0)
65681                 .remove();
65682         }
65683
65684         if (tooltip) {
65685             tooltip.remove();
65686         }
65687     };
65688
65689
65690     radialMenu.center = function(_) {
65691         if (!arguments.length) return center;
65692         center = _;
65693         return radialMenu;
65694     };
65695
65696
65697     return radialMenu;
65698 }
65699
65700 function uiSelectionList(context, selectedIDs) {
65701
65702     function selectEntity(entity) {
65703         context.enter(modeSelect(context, [entity.id]));
65704     }
65705
65706
65707     function deselectEntity(entity) {
65708         event.stopPropagation();
65709         var index = selectedIDs.indexOf(entity.id);
65710         if (index > -1) {
65711             selectedIDs.splice(index, 1);
65712         }
65713         context.enter(modeSelect(context, selectedIDs));
65714     }
65715
65716
65717     function selectionList(selection) {
65718         selection.classed('selection-list-pane', true);
65719
65720         var header = selection
65721             .append('div')
65722             .attr('class', 'header fillL cf');
65723
65724         header
65725             .append('h3')
65726             .text(t('inspector.multiselect'));
65727
65728         var listWrap = selection
65729             .append('div')
65730             .attr('class', 'inspector-body');
65731
65732         var list = listWrap
65733             .append('div')
65734             .attr('class', 'feature-list cf');
65735
65736         context.history().on('change.selection-list', drawList);
65737         drawList();
65738
65739
65740         function drawList() {
65741             var entities = selectedIDs
65742                 .map(function(id) { return context.hasEntity(id); })
65743                 .filter(function(entity) { return entity; });
65744
65745             var items = list.selectAll('.feature-list-item')
65746                 .data(entities, osmEntity.key);
65747
65748             items.exit()
65749                 .remove();
65750
65751             // Enter
65752             var enter = items.enter()
65753                 .append('div')
65754                 .attr('class', 'feature-list-item')
65755                 .on('click', selectEntity);
65756
65757             var label = enter
65758                 .append('button')
65759                 .attr('class', 'label');
65760
65761             enter
65762                 .append('button')
65763                 .attr('class', 'close')
65764                 .on('click', deselectEntity)
65765                 .call(svgIcon('#icon-close'));
65766
65767             label
65768                 .append('span')
65769                 .attr('class', 'entity-geom-icon')
65770                 .call(svgIcon('', 'pre-text'));
65771
65772             label
65773                 .append('span')
65774                 .attr('class', 'entity-type');
65775
65776             label
65777                 .append('span')
65778                 .attr('class', 'entity-name');
65779
65780             // Update
65781             items = items.merge(enter);
65782
65783             items.selectAll('.entity-geom-icon use')
65784                 .attr('href', function() {
65785                     var entity = this.parentNode.parentNode.__data__;
65786                     return '#icon-' + context.geometry(entity.id);
65787                 });
65788
65789             items.selectAll('.entity-type')
65790                 .text(function(entity) { return context.presets().match(entity, context.graph()).name(); });
65791
65792             items.selectAll('.entity-name')
65793                 .text(function(entity) { return utilDisplayName(entity); });
65794         }
65795     }
65796
65797     return selectionList;
65798 }
65799
65800 function uiSourceSwitch(context) {
65801     var keys;
65802
65803
65804     function click() {
65805         event.preventDefault();
65806
65807         var osm = context.connection();
65808         if (!osm) return;
65809
65810         if (context.inIntro()) return;
65811
65812         if (context.history().hasChanges() &&
65813             !window.confirm(t('source_switch.lose_changes'))) return;
65814
65815         var isLive = d3_select(this)
65816             .classed('live');
65817
65818         isLive = !isLive;
65819         context.enter(modeBrowse(context));
65820         context.history().clearSaved();          // remove saved history
65821         context.flush();                         // remove stored data
65822
65823         d3_select(this)
65824             .text(isLive ? t('source_switch.live') : t('source_switch.dev'))
65825             .classed('live', isLive);
65826
65827         osm.switch(isLive ? keys[0] : keys[1]);  // switch connection (warning: dispatches 'change' event)
65828     }
65829
65830     var sourceSwitch = function(selection) {
65831         selection
65832             .append('a')
65833             .attr('href', '#')
65834             .text(t('source_switch.live'))
65835             .classed('live', true)
65836             .attr('tabindex', -1)
65837             .on('click', click);
65838     };
65839
65840
65841     sourceSwitch.keys = function(_) {
65842         if (!arguments.length) return keys;
65843         keys = _;
65844         return sourceSwitch;
65845     };
65846
65847
65848     return sourceSwitch;
65849 }
65850
65851 function uiSuccess(context) {
65852     var dispatch$$1 = dispatch('cancel'),
65853         changeset;
65854
65855
65856     function success(selection) {
65857         var header = selection
65858             .append('div')
65859             .attr('class', 'header fillL');
65860
65861         header
65862             .append('button')
65863             .attr('class', 'fr')
65864             .on('click', function() { dispatch$$1.call('cancel'); })
65865             .call(svgIcon('#icon-close'));
65866
65867         header
65868             .append('h3')
65869             .text(t('success.just_edited'));
65870
65871         var body = selection
65872             .append('div')
65873             .attr('class', 'body save-success fillL');
65874
65875         body
65876             .append('p')
65877             .html(t('success.help_html'));
65878
65879         body
65880             .append('a')
65881             .attr('class', 'details')
65882             .attr('target', '_blank')
65883             .attr('tabindex', -1)
65884             .call(svgIcon('#icon-out-link', 'inline'))
65885             .attr('href', t('success.help_link_url'))
65886             .append('span')
65887             .text(t('success.help_link_text'));
65888
65889         var osm = context.connection();
65890         if (!osm) return;
65891
65892         var changesetURL = osm.changesetURL(changeset.id);
65893
65894         var viewOnOsm = body
65895             .append('a')
65896             .attr('class', 'button col12 osm')
65897             .attr('target', '_blank')
65898             .attr('href', changesetURL);
65899
65900         viewOnOsm
65901             .append('svg')
65902             .attr('class', 'logo logo-osm')
65903             .append('use')
65904             .attr('xlink:href', '#logo-osm');
65905
65906         viewOnOsm
65907             .append('div')
65908             .text(t('success.view_on_osm'));
65909
65910         var message = (changeset.tags.comment || t('success.edited_osm')).substring(0, 130) +
65911             ' ' + changesetURL;
65912
65913         var sharing = [
65914             { key: 'facebook', value: 'https://facebook.com/sharer/sharer.php?u=' + encodeURIComponent(changesetURL) },
65915             { key: 'twitter', value: 'https://twitter.com/intent/tweet?source=webclient&text=' + encodeURIComponent(message) },
65916             { key: 'google', value: 'https://plus.google.com/share?url=' + encodeURIComponent(changesetURL) }
65917         ];
65918
65919         body.selectAll('.button.social')
65920             .data(sharing)
65921             .enter()
65922             .append('a')
65923             .attr('class', 'button social col4')
65924             .attr('target', '_blank')
65925             .attr('href', function(d) { return d.value; })
65926             .call(tooltip()
65927                 .title(function(d) { return t('success.' + d.key); })
65928                 .placement('bottom'))
65929             .each(function(d) { d3_select(this).call(svgIcon('#logo-' + d.key, 'social')); });
65930     }
65931
65932
65933     success.changeset = function(_) {
65934         if (!arguments.length) return changeset;
65935         changeset = _;
65936         return success;
65937     };
65938
65939
65940     return utilRebind(success, dispatch$$1, 'on');
65941 }
65942
65943 function coreHistory(context) {
65944     var imageryUsed = ['Bing'],
65945         dispatch$$1 = dispatch('change', 'undone', 'redone'),
65946         lock = utilSessionMutex('lock'),
65947         duration = 150,
65948         checkpoints = {},
65949         stack, index, tree;
65950
65951
65952     // internal _act, accepts list of actions and eased time
65953     function _act(actions, t) {
65954         actions = Array.prototype.slice.call(actions);
65955
65956         var annotation;
65957
65958         if (!isFunction(actions[actions.length - 1])) {
65959             annotation = actions.pop();
65960         }
65961
65962         stack[index].transform = context.projection.transform();
65963         stack[index].selectedIDs = context.selectedIDs();
65964
65965         var graph = stack[index].graph;
65966         for (var i = 0; i < actions.length; i++) {
65967             graph = actions[i](graph, t);
65968         }
65969
65970         return {
65971             graph: graph,
65972             annotation: annotation,
65973             imageryUsed: imageryUsed
65974         };
65975     }
65976
65977
65978     // internal _perform with eased time
65979     function _perform(args, t) {
65980         var previous = stack[index].graph;
65981         stack = stack.slice(0, index + 1);
65982         stack.push(_act(args, t));
65983         index++;
65984         return change(previous);
65985     }
65986
65987
65988     // internal _replace with eased time
65989     function _replace(args, t) {
65990         var previous = stack[index].graph;
65991         // assert(index == stack.length - 1)
65992         stack[index] = _act(args, t);
65993         return change(previous);
65994     }
65995
65996
65997     // internal _overwrite with eased time
65998     function _overwrite(args, t) {
65999         var previous = stack[index].graph;
66000         if (index > 0) {
66001             index--;
66002             stack.pop();
66003         }
66004         stack = stack.slice(0, index + 1);
66005         stack.push(_act(args, t));
66006         index++;
66007         return change(previous);
66008     }
66009
66010
66011     // determine diffrence and dispatch a change event
66012     function change(previous) {
66013         var difference$$1 = coreDifference(previous, history.graph());
66014         dispatch$$1.call('change', this, difference$$1);
66015         return difference$$1;
66016     }
66017
66018
66019     // iD uses namespaced keys so multiple installations do not conflict
66020     function getKey(n) {
66021         return 'iD_' + window.location.origin + '_' + n;
66022     }
66023
66024
66025     var history = {
66026
66027         graph: function() {
66028             return stack[index].graph;
66029         },
66030
66031
66032         base: function() {
66033             return stack[0].graph;
66034         },
66035
66036
66037         merge: function(entities, extent) {
66038             stack[0].graph.rebase(entities, map$4(stack, 'graph'), false);
66039             tree.rebase(entities, false);
66040
66041             dispatch$$1.call('change', this, undefined, extent);
66042         },
66043
66044
66045         perform: function() {
66046             // complete any transition already in progress
66047             d3_select(document).interrupt('history.perform');
66048
66049             var transitionable = false,
66050                 action0 = arguments[0];
66051
66052             if (arguments.length === 1 ||
66053                 arguments.length === 2 && !isFunction(arguments[1])) {
66054                 transitionable = !!action0.transitionable;
66055             }
66056
66057             if (transitionable) {
66058                 var origArguments = arguments;
66059                 d3_select(document)
66060                     .transition('history.perform')
66061                     .duration(duration)
66062                     .ease(linear$1)
66063                     .tween('history.tween', function() {
66064                         return function(t) {
66065                             if (t < 1) _overwrite([action0], t);
66066                         };
66067                     })
66068                     .on('start', function() {
66069                         _perform([action0], 0);
66070                     })
66071                     .on('end interrupt', function() {
66072                         _overwrite(origArguments, 1);
66073                     });
66074
66075             } else {
66076                 return _perform(arguments);
66077             }
66078         },
66079
66080
66081         replace: function() {
66082             d3_select(document).interrupt('history.perform');
66083             return _replace(arguments, 1);
66084         },
66085
66086
66087         // Same as calling pop and then perform
66088         overwrite: function() {
66089             d3_select(document).interrupt('history.perform');
66090             return _overwrite(arguments, 1);
66091         },
66092
66093
66094         pop: function(n) {
66095             d3_select(document).interrupt('history.perform');
66096
66097             var previous = stack[index].graph;
66098             if (isNaN(+n) || +n < 0) {
66099                 n = 1;
66100             }
66101             while (n-- > 0 && index > 0) {
66102                 index--;
66103                 stack.pop();
66104             }
66105             return change(previous);
66106         },
66107
66108
66109         // Back to the previous annotated state or index = 0.
66110         undo: function() {
66111             d3_select(document).interrupt('history.perform');
66112
66113             var previous = stack[index].graph;
66114             while (index > 0) {
66115                 index--;
66116                 if (stack[index].annotation) break;
66117             }
66118
66119             dispatch$$1.call('undone', this, stack[index]);
66120             return change(previous);
66121         },
66122
66123
66124         // Forward to the next annotated state.
66125         redo: function() {
66126             d3_select(document).interrupt('history.perform');
66127
66128             var previous = stack[index].graph;
66129             var tryIndex = index;
66130             while (tryIndex < stack.length - 1) {
66131                 tryIndex++;
66132                 if (stack[tryIndex].annotation) {
66133                     index = tryIndex;
66134                     dispatch$$1.call('redone', this, stack[index]);
66135                     break;
66136                 }
66137             }
66138
66139             return change(previous);
66140         },
66141
66142
66143         undoAnnotation: function() {
66144             var i = index;
66145             while (i >= 0) {
66146                 if (stack[i].annotation) return stack[i].annotation;
66147                 i--;
66148             }
66149         },
66150
66151
66152         redoAnnotation: function() {
66153             var i = index + 1;
66154             while (i <= stack.length - 1) {
66155                 if (stack[i].annotation) return stack[i].annotation;
66156                 i++;
66157             }
66158         },
66159
66160
66161         intersects: function(extent) {
66162             return tree.intersects(extent, stack[index].graph);
66163         },
66164
66165
66166         difference: function() {
66167             var base = stack[0].graph,
66168                 head = stack[index].graph;
66169             return coreDifference(base, head);
66170         },
66171
66172
66173         changes: function(action) {
66174             var base = stack[0].graph,
66175                 head = stack[index].graph;
66176
66177             if (action) {
66178                 head = action(head);
66179             }
66180
66181             var difference$$1 = coreDifference(base, head);
66182
66183             return {
66184                 modified: difference$$1.modified(),
66185                 created: difference$$1.created(),
66186                 deleted: difference$$1.deleted()
66187             };
66188         },
66189
66190
66191         validate: function(changes) {
66192             return flatten(
66193                 map$4(Validations, function(fn) { return fn()(changes, stack[index].graph); })
66194             );
66195         },
66196
66197
66198         hasChanges: function() {
66199             return this.difference().length() > 0;
66200         },
66201
66202
66203         imageryUsed: function(sources) {
66204             if (sources) {
66205                 imageryUsed = sources;
66206                 return history;
66207             } else {
66208                 var arr = map$4(stack.slice(1, index + 1), 'imageryUsed');
66209                 return without(uniq(flatten(arr)), 'Custom');
66210             }
66211         },
66212
66213
66214         // save the current history state
66215         checkpoint: function(key) {
66216             checkpoints[key] = {
66217                 stack: cloneDeep(stack),
66218                 index: index
66219             };
66220             return history;
66221         },
66222
66223
66224         // restore history state to a given checkpoint or reset completely
66225         reset: function(key) {
66226             if (key !== undefined && checkpoints.hasOwnProperty(key)) {
66227                 stack = cloneDeep(checkpoints[key].stack);
66228                 index = checkpoints[key].index;
66229             } else {
66230                 stack = [{graph: coreGraph()}];
66231                 index = 0;
66232                 tree = coreTree(stack[0].graph);
66233                 checkpoints = {};
66234             }
66235             dispatch$$1.call('change');
66236             return history;
66237         },
66238
66239
66240         toIntroGraph: function() {
66241             var nextId = { n: 0, r: 0, w: 0 },
66242                 permIds = {},
66243                 graph = this.graph(),
66244                 baseEntities = {};
66245
66246             // clone base entities..
66247             forEach(graph.base().entities, function(entity) {
66248                 var copy = cloneDeepWith(entity, customizer);
66249                 baseEntities[copy.id] = copy;
66250             });
66251
66252             // replace base entities with head entities..
66253             forEach(graph.entities, function(entity, id) {
66254                 if (entity) {
66255                     var copy = cloneDeepWith(entity, customizer);
66256                     baseEntities[copy.id] = copy;
66257                 } else {
66258                     delete baseEntities[id];
66259                 }
66260             });
66261
66262             // swap temporary for permanent ids..
66263             forEach(baseEntities, function(entity) {
66264                 if (Array.isArray(entity.nodes)) {
66265                     entity.nodes = entity.nodes.map(function(node) {
66266                         return permIds[node] || node;
66267                     });
66268                 }
66269                 if (Array.isArray(entity.members)) {
66270                     entity.members = entity.members.map(function(member) {
66271                         member.id = permIds[member.id] || member.id;
66272                         return member;
66273                     });
66274                 }
66275             });
66276
66277             return JSON.stringify({ dataIntroGraph: baseEntities });
66278
66279
66280             function customizer(src) {
66281                 var copy = omit(cloneDeep(src), ['type', 'user', 'v', 'version', 'visible']);
66282                 if (isEmpty(copy.tags)) {
66283                     delete copy.tags;
66284                 }
66285
66286                 if (Array.isArray(copy.loc)) {
66287                     copy.loc[0] = +copy.loc[0].toFixed(6);
66288                     copy.loc[1] = +copy.loc[1].toFixed(6);
66289                 }
66290
66291                 var match = src.id.match(/([nrw])-\d*/);  // temporary id
66292                 if (match !== null) {
66293                     var nrw = match[1], permId;
66294                     do { permId = nrw + (++nextId[nrw]); }
66295                     while (baseEntities.hasOwnProperty(permId));
66296
66297                     copy.id = permIds[src.id] = permId;
66298                 }
66299                 return copy;
66300             }
66301         },
66302
66303
66304         toJSON: function() {
66305             if (!this.hasChanges()) return;
66306
66307             var allEntities = {},
66308                 baseEntities = {},
66309                 base = stack[0];
66310
66311             var s = stack.map(function(i) {
66312                 var modified = [], deleted = [];
66313
66314                 forEach(i.graph.entities, function(entity, id) {
66315                     if (entity) {
66316                         var key = osmEntity.key(entity);
66317                         allEntities[key] = entity;
66318                         modified.push(key);
66319                     } else {
66320                         deleted.push(id);
66321                     }
66322
66323                     // make sure that the originals of changed or deleted entities get merged
66324                     // into the base of the stack after restoring the data from JSON.
66325                     if (id in base.graph.entities) {
66326                         baseEntities[id] = base.graph.entities[id];
66327                     }
66328                     // get originals of parent entities too
66329                     forEach(base.graph._parentWays[id], function(parentId) {
66330                         if (parentId in base.graph.entities) {
66331                             baseEntities[parentId] = base.graph.entities[parentId];
66332                         }
66333                     });
66334                 });
66335
66336                 var x = {};
66337
66338                 if (modified.length) x.modified = modified;
66339                 if (deleted.length) x.deleted = deleted;
66340                 if (i.imageryUsed) x.imageryUsed = i.imageryUsed;
66341                 if (i.annotation) x.annotation = i.annotation;
66342
66343                 return x;
66344             });
66345
66346             return JSON.stringify({
66347                 version: 3,
66348                 entities: values$1(allEntities),
66349                 baseEntities: values$1(baseEntities),
66350                 stack: s,
66351                 nextIDs: osmEntity.id.next,
66352                 index: index
66353             });
66354         },
66355
66356
66357         fromJSON: function(json, loadChildNodes) {
66358             var h = JSON.parse(json),
66359                 loadComplete = true;
66360
66361             osmEntity.id.next = h.nextIDs;
66362             index = h.index;
66363
66364             if (h.version === 2 || h.version === 3) {
66365                 var allEntities = {};
66366
66367                 h.entities.forEach(function(entity) {
66368                     allEntities[osmEntity.key(entity)] = osmEntity(entity);
66369                 });
66370
66371                 if (h.version === 3) {
66372                     // This merges originals for changed entities into the base of
66373                     // the stack even if the current stack doesn't have them (for
66374                     // example when iD has been restarted in a different region)
66375                     var baseEntities = h.baseEntities.map(function(d) { return osmEntity(d); });
66376                     stack[0].graph.rebase(baseEntities, map$4(stack, 'graph'), true);
66377                     tree.rebase(baseEntities, true);
66378
66379                     // When we restore a modified way, we also need to fetch any missing
66380                     // childnodes that would normally have been downloaded with it.. #2142
66381                     if (loadChildNodes) {
66382                         var osm = context.connection();
66383                         var nodes = flatten(uniq(map$4(filter(baseEntities, { type: 'way' }), 'nodes')));
66384                         var missing = reject(nodes, function(n) { return stack[0].graph.hasEntity(n); });
66385
66386                         if (!isEmpty(missing) && osm) {
66387                             loadComplete = false;
66388                             context.redrawEnable(false);
66389
66390                             var loading = uiLoading(context).blocking(true);
66391                             context.container().call(loading);
66392
66393                             var childNodesLoaded = function(err, result) {
66394                                 if (!err) {
66395                                     var visible = groupBy(result.data, 'visible');
66396                                     if (!isEmpty(visible.true)) {
66397                                         missing = difference(missing, map$4(visible.true, 'id'));
66398                                         stack[0].graph.rebase(visible.true, map$4(stack, 'graph'), true);
66399                                         tree.rebase(visible.true, true);
66400                                     }
66401
66402                                     // fetch older versions of nodes that were deleted..
66403                                     forEach(visible.false, function(entity) {
66404                                         osm.loadEntityVersion(entity.id, +entity.version - 1, childNodesLoaded);
66405                                     });
66406                                 }
66407
66408                                 if (err || isEmpty(missing)) {
66409                                     loading.close();
66410                                     context.redrawEnable(true);
66411                                     dispatch$$1.call('change');
66412                                 }
66413                             };
66414
66415                             osm.loadMultiple(missing, childNodesLoaded);
66416                         }
66417                     }
66418                 }
66419
66420                 stack = h.stack.map(function(d) {
66421                     var entities = {}, entity;
66422
66423                     if (d.modified) {
66424                         d.modified.forEach(function(key) {
66425                             entity = allEntities[key];
66426                             entities[entity.id] = entity;
66427                         });
66428                     }
66429
66430                     if (d.deleted) {
66431                         d.deleted.forEach(function(id) {
66432                             entities[id] = undefined;
66433                         });
66434                     }
66435
66436                     return {
66437                         graph: coreGraph(stack[0].graph).load(entities),
66438                         annotation: d.annotation,
66439                         imageryUsed: d.imageryUsed
66440                     };
66441                 });
66442
66443             } else { // original version
66444                 stack = h.stack.map(function(d) {
66445                     var entities = {};
66446
66447                     for (var i in d.entities) {
66448                         var entity = d.entities[i];
66449                         entities[i] = entity === 'undefined' ? undefined : osmEntity(entity);
66450                     }
66451
66452                     d.graph = coreGraph(stack[0].graph).load(entities);
66453                     return d;
66454                 });
66455             }
66456
66457             if (loadComplete) {
66458                 dispatch$$1.call('change');
66459             }
66460
66461             return history;
66462         },
66463
66464
66465         save: function() {
66466             if (lock.locked()) context.storage(getKey('saved_history'), history.toJSON() || null);
66467             return history;
66468         },
66469
66470
66471         clearSaved: function() {
66472             context.debouncedSave.cancel();
66473             if (lock.locked()) context.storage(getKey('saved_history'), null);
66474             return history;
66475         },
66476
66477
66478         lock: function() {
66479             return lock.lock();
66480         },
66481
66482
66483         unlock: function() {
66484             lock.unlock();
66485         },
66486
66487
66488         // is iD not open in another window and it detects that
66489         // there's a history stored in localStorage that's recoverable?
66490         restorableChanges: function() {
66491             return lock.locked() && !!context.storage(getKey('saved_history'));
66492         },
66493
66494
66495         // load history from a version stored in localStorage
66496         restore: function() {
66497             if (!lock.locked()) return;
66498
66499             var json = context.storage(getKey('saved_history'));
66500             if (json) history.fromJSON(json, true);
66501         },
66502
66503
66504         _getKey: getKey
66505
66506     };
66507
66508
66509     history.reset();
66510
66511     return utilRebind(history, dispatch$$1, 'on');
66512 }
66513
66514 /** Used to store function metadata. */
66515 var metaMap = WeakMap && new WeakMap;
66516
66517 /**
66518  * The base implementation of `setData` without support for hot loop shorting.
66519  *
66520  * @private
66521  * @param {Function} func The function to associate metadata with.
66522  * @param {*} data The metadata.
66523  * @returns {Function} Returns `func`.
66524  */
66525 var baseSetData = !metaMap ? identity$8 : function(func, data) {
66526   metaMap.set(func, data);
66527   return func;
66528 };
66529
66530 /**
66531  * Creates a function that produces an instance of `Ctor` regardless of
66532  * whether it was invoked as part of a `new` expression or by `call` or `apply`.
66533  *
66534  * @private
66535  * @param {Function} Ctor The constructor to wrap.
66536  * @returns {Function} Returns the new wrapped function.
66537  */
66538 function createCtor(Ctor) {
66539   return function() {
66540     // Use a `switch` statement to work with class constructors. See
66541     // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist
66542     // for more details.
66543     var args = arguments;
66544     switch (args.length) {
66545       case 0: return new Ctor;
66546       case 1: return new Ctor(args[0]);
66547       case 2: return new Ctor(args[0], args[1]);
66548       case 3: return new Ctor(args[0], args[1], args[2]);
66549       case 4: return new Ctor(args[0], args[1], args[2], args[3]);
66550       case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]);
66551       case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]);
66552       case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
66553     }
66554     var thisBinding = baseCreate(Ctor.prototype),
66555         result = Ctor.apply(thisBinding, args);
66556
66557     // Mimic the constructor's `return` behavior.
66558     // See https://es5.github.io/#x13.2.2 for more details.
66559     return isObject(result) ? result : thisBinding;
66560   };
66561 }
66562
66563 /** Used to compose bitmasks for function metadata. */
66564 var WRAP_BIND_FLAG$2 = 1;
66565
66566 /**
66567  * Creates a function that wraps `func` to invoke it with the optional `this`
66568  * binding of `thisArg`.
66569  *
66570  * @private
66571  * @param {Function} func The function to wrap.
66572  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
66573  * @param {*} [thisArg] The `this` binding of `func`.
66574  * @returns {Function} Returns the new wrapped function.
66575  */
66576 function createBind(func, bitmask, thisArg) {
66577   var isBind = bitmask & WRAP_BIND_FLAG$2,
66578       Ctor = createCtor(func);
66579
66580   function wrapper() {
66581     var fn = (this && this !== root$2 && this instanceof wrapper) ? Ctor : func;
66582     return fn.apply(isBind ? thisArg : this, arguments);
66583   }
66584   return wrapper;
66585 }
66586
66587 /* Built-in method references for those with the same name as other `lodash` methods. */
66588 var nativeMax$6 = Math.max;
66589
66590 /**
66591  * Creates an array that is the composition of partially applied arguments,
66592  * placeholders, and provided arguments into a single array of arguments.
66593  *
66594  * @private
66595  * @param {Array} args The provided arguments.
66596  * @param {Array} partials The arguments to prepend to those provided.
66597  * @param {Array} holders The `partials` placeholder indexes.
66598  * @params {boolean} [isCurried] Specify composing for a curried function.
66599  * @returns {Array} Returns the new array of composed arguments.
66600  */
66601 function composeArgs(args, partials, holders, isCurried) {
66602   var argsIndex = -1,
66603       argsLength = args.length,
66604       holdersLength = holders.length,
66605       leftIndex = -1,
66606       leftLength = partials.length,
66607       rangeLength = nativeMax$6(argsLength - holdersLength, 0),
66608       result = Array(leftLength + rangeLength),
66609       isUncurried = !isCurried;
66610
66611   while (++leftIndex < leftLength) {
66612     result[leftIndex] = partials[leftIndex];
66613   }
66614   while (++argsIndex < holdersLength) {
66615     if (isUncurried || argsIndex < argsLength) {
66616       result[holders[argsIndex]] = args[argsIndex];
66617     }
66618   }
66619   while (rangeLength--) {
66620     result[leftIndex++] = args[argsIndex++];
66621   }
66622   return result;
66623 }
66624
66625 /* Built-in method references for those with the same name as other `lodash` methods. */
66626 var nativeMax$7 = Math.max;
66627
66628 /**
66629  * This function is like `composeArgs` except that the arguments composition
66630  * is tailored for `_.partialRight`.
66631  *
66632  * @private
66633  * @param {Array} args The provided arguments.
66634  * @param {Array} partials The arguments to append to those provided.
66635  * @param {Array} holders The `partials` placeholder indexes.
66636  * @params {boolean} [isCurried] Specify composing for a curried function.
66637  * @returns {Array} Returns the new array of composed arguments.
66638  */
66639 function composeArgsRight(args, partials, holders, isCurried) {
66640   var argsIndex = -1,
66641       argsLength = args.length,
66642       holdersIndex = -1,
66643       holdersLength = holders.length,
66644       rightIndex = -1,
66645       rightLength = partials.length,
66646       rangeLength = nativeMax$7(argsLength - holdersLength, 0),
66647       result = Array(rangeLength + rightLength),
66648       isUncurried = !isCurried;
66649
66650   while (++argsIndex < rangeLength) {
66651     result[argsIndex] = args[argsIndex];
66652   }
66653   var offset = argsIndex;
66654   while (++rightIndex < rightLength) {
66655     result[offset + rightIndex] = partials[rightIndex];
66656   }
66657   while (++holdersIndex < holdersLength) {
66658     if (isUncurried || argsIndex < argsLength) {
66659       result[offset + holders[holdersIndex]] = args[argsIndex++];
66660     }
66661   }
66662   return result;
66663 }
66664
66665 /**
66666  * Gets the number of `placeholder` occurrences in `array`.
66667  *
66668  * @private
66669  * @param {Array} array The array to inspect.
66670  * @param {*} placeholder The placeholder to search for.
66671  * @returns {number} Returns the placeholder count.
66672  */
66673 function countHolders(array, placeholder) {
66674   var length = array.length,
66675       result = 0;
66676
66677   while (length--) {
66678     if (array[length] === placeholder) {
66679       ++result;
66680     }
66681   }
66682   return result;
66683 }
66684
66685 /**
66686  * The function whose prototype chain sequence wrappers inherit from.
66687  *
66688  * @private
66689  */
66690 function baseLodash() {
66691   // No operation performed.
66692 }
66693
66694 /** Used as references for the maximum length and index of an array. */
66695 var MAX_ARRAY_LENGTH = 4294967295;
66696
66697 /**
66698  * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation.
66699  *
66700  * @private
66701  * @constructor
66702  * @param {*} value The value to wrap.
66703  */
66704 function LazyWrapper(value) {
66705   this.__wrapped__ = value;
66706   this.__actions__ = [];
66707   this.__dir__ = 1;
66708   this.__filtered__ = false;
66709   this.__iteratees__ = [];
66710   this.__takeCount__ = MAX_ARRAY_LENGTH;
66711   this.__views__ = [];
66712 }
66713
66714 // Ensure `LazyWrapper` is an instance of `baseLodash`.
66715 LazyWrapper.prototype = baseCreate(baseLodash.prototype);
66716 LazyWrapper.prototype.constructor = LazyWrapper;
66717
66718 /**
66719  * Gets metadata for `func`.
66720  *
66721  * @private
66722  * @param {Function} func The function to query.
66723  * @returns {*} Returns the metadata for `func`.
66724  */
66725 var getData = !metaMap ? noop$3 : function(func) {
66726   return metaMap.get(func);
66727 };
66728
66729 /** Used to lookup unminified function names. */
66730 var realNames = {};
66731
66732 /** Used for built-in method references. */
66733 var objectProto$19 = Object.prototype;
66734
66735 /** Used to check objects for own properties. */
66736 var hasOwnProperty$17 = objectProto$19.hasOwnProperty;
66737
66738 /**
66739  * Gets the name of `func`.
66740  *
66741  * @private
66742  * @param {Function} func The function to query.
66743  * @returns {string} Returns the function name.
66744  */
66745 function getFuncName(func) {
66746   var result = (func.name + ''),
66747       array = realNames[result],
66748       length = hasOwnProperty$17.call(realNames, result) ? array.length : 0;
66749
66750   while (length--) {
66751     var data = array[length],
66752         otherFunc = data.func;
66753     if (otherFunc == null || otherFunc == func) {
66754       return data.name;
66755     }
66756   }
66757   return result;
66758 }
66759
66760 /**
66761  * The base constructor for creating `lodash` wrapper objects.
66762  *
66763  * @private
66764  * @param {*} value The value to wrap.
66765  * @param {boolean} [chainAll] Enable explicit method chain sequences.
66766  */
66767 function LodashWrapper(value, chainAll) {
66768   this.__wrapped__ = value;
66769   this.__actions__ = [];
66770   this.__chain__ = !!chainAll;
66771   this.__index__ = 0;
66772   this.__values__ = undefined;
66773 }
66774
66775 LodashWrapper.prototype = baseCreate(baseLodash.prototype);
66776 LodashWrapper.prototype.constructor = LodashWrapper;
66777
66778 /**
66779  * Creates a clone of `wrapper`.
66780  *
66781  * @private
66782  * @param {Object} wrapper The wrapper to clone.
66783  * @returns {Object} Returns the cloned wrapper.
66784  */
66785 function wrapperClone(wrapper) {
66786   if (wrapper instanceof LazyWrapper) {
66787     return wrapper.clone();
66788   }
66789   var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__);
66790   result.__actions__ = copyArray(wrapper.__actions__);
66791   result.__index__  = wrapper.__index__;
66792   result.__values__ = wrapper.__values__;
66793   return result;
66794 }
66795
66796 /** Used for built-in method references. */
66797 var objectProto$20 = Object.prototype;
66798
66799 /** Used to check objects for own properties. */
66800 var hasOwnProperty$18 = objectProto$20.hasOwnProperty;
66801
66802 /**
66803  * Creates a `lodash` object which wraps `value` to enable implicit method
66804  * chain sequences. Methods that operate on and return arrays, collections,
66805  * and functions can be chained together. Methods that retrieve a single value
66806  * or may return a primitive value will automatically end the chain sequence
66807  * and return the unwrapped value. Otherwise, the value must be unwrapped
66808  * with `_#value`.
66809  *
66810  * Explicit chain sequences, which must be unwrapped with `_#value`, may be
66811  * enabled using `_.chain`.
66812  *
66813  * The execution of chained methods is lazy, that is, it's deferred until
66814  * `_#value` is implicitly or explicitly called.
66815  *
66816  * Lazy evaluation allows several methods to support shortcut fusion.
66817  * Shortcut fusion is an optimization to merge iteratee calls; this avoids
66818  * the creation of intermediate arrays and can greatly reduce the number of
66819  * iteratee executions. Sections of a chain sequence qualify for shortcut
66820  * fusion if the section is applied to an array and iteratees accept only
66821  * one argument. The heuristic for whether a section qualifies for shortcut
66822  * fusion is subject to change.
66823  *
66824  * Chaining is supported in custom builds as long as the `_#value` method is
66825  * directly or indirectly included in the build.
66826  *
66827  * In addition to lodash methods, wrappers have `Array` and `String` methods.
66828  *
66829  * The wrapper `Array` methods are:
66830  * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift`
66831  *
66832  * The wrapper `String` methods are:
66833  * `replace` and `split`
66834  *
66835  * The wrapper methods that support shortcut fusion are:
66836  * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`,
66837  * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`,
66838  * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray`
66839  *
66840  * The chainable wrapper methods are:
66841  * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`,
66842  * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`,
66843  * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`,
66844  * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`,
66845  * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`,
66846  * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`,
66847  * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`,
66848  * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`,
66849  * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`,
66850  * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`,
66851  * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`,
66852  * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`,
66853  * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`,
66854  * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`,
66855  * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`,
66856  * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`,
66857  * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`,
66858  * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`,
66859  * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`,
66860  * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`,
66861  * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`,
66862  * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`,
66863  * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`,
66864  * `zipObject`, `zipObjectDeep`, and `zipWith`
66865  *
66866  * The wrapper methods that are **not** chainable by default are:
66867  * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`,
66868  * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`,
66869  * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`,
66870  * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`,
66871  * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`,
66872  * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`,
66873  * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`,
66874  * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`,
66875  * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`,
66876  * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`,
66877  * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`,
66878  * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`,
66879  * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`,
66880  * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`,
66881  * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`,
66882  * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`,
66883  * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`,
66884  * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`,
66885  * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`,
66886  * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`,
66887  * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`,
66888  * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`,
66889  * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`,
66890  * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`,
66891  * `upperFirst`, `value`, and `words`
66892  *
66893  * @name _
66894  * @constructor
66895  * @category Seq
66896  * @param {*} value The value to wrap in a `lodash` instance.
66897  * @returns {Object} Returns the new `lodash` wrapper instance.
66898  * @example
66899  *
66900  * function square(n) {
66901  *   return n * n;
66902  * }
66903  *
66904  * var wrapped = _([1, 2, 3]);
66905  *
66906  * // Returns an unwrapped value.
66907  * wrapped.reduce(_.add);
66908  * // => 6
66909  *
66910  * // Returns a wrapped value.
66911  * var squares = wrapped.map(square);
66912  *
66913  * _.isArray(squares);
66914  * // => false
66915  *
66916  * _.isArray(squares.value());
66917  * // => true
66918  */
66919 function lodash(value) {
66920   if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) {
66921     if (value instanceof LodashWrapper) {
66922       return value;
66923     }
66924     if (hasOwnProperty$18.call(value, '__wrapped__')) {
66925       return wrapperClone(value);
66926     }
66927   }
66928   return new LodashWrapper(value);
66929 }
66930
66931 // Ensure wrappers are instances of `baseLodash`.
66932 lodash.prototype = baseLodash.prototype;
66933 lodash.prototype.constructor = lodash;
66934
66935 /**
66936  * Checks if `func` has a lazy counterpart.
66937  *
66938  * @private
66939  * @param {Function} func The function to check.
66940  * @returns {boolean} Returns `true` if `func` has a lazy counterpart,
66941  *  else `false`.
66942  */
66943 function isLaziable(func) {
66944   var funcName = getFuncName(func),
66945       other = lodash[funcName];
66946
66947   if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) {
66948     return false;
66949   }
66950   if (func === other) {
66951     return true;
66952   }
66953   var data = getData(other);
66954   return !!data && func === data[0];
66955 }
66956
66957 /**
66958  * Sets metadata for `func`.
66959  *
66960  * **Note:** If this function becomes hot, i.e. is invoked a lot in a short
66961  * period of time, it will trip its breaker and transition to an identity
66962  * function to avoid garbage collection pauses in V8. See
66963  * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070)
66964  * for more details.
66965  *
66966  * @private
66967  * @param {Function} func The function to associate metadata with.
66968  * @param {*} data The metadata.
66969  * @returns {Function} Returns `func`.
66970  */
66971 var setData = shortOut(baseSetData);
66972
66973 /** Used to match wrap detail comments. */
66974 var reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/;
66975 var reSplitDetails = /,? & /;
66976
66977 /**
66978  * Extracts wrapper details from the `source` body comment.
66979  *
66980  * @private
66981  * @param {string} source The source to inspect.
66982  * @returns {Array} Returns the wrapper details.
66983  */
66984 function getWrapDetails(source) {
66985   var match = source.match(reWrapDetails);
66986   return match ? match[1].split(reSplitDetails) : [];
66987 }
66988
66989 /** Used to match wrap detail comments. */
66990 var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/;
66991
66992 /**
66993  * Inserts wrapper `details` in a comment at the top of the `source` body.
66994  *
66995  * @private
66996  * @param {string} source The source to modify.
66997  * @returns {Array} details The details to insert.
66998  * @returns {string} Returns the modified source.
66999  */
67000 function insertWrapDetails(source, details) {
67001   var length = details.length;
67002   if (!length) {
67003     return source;
67004   }
67005   var lastIndex = length - 1;
67006   details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex];
67007   details = details.join(length > 2 ? ', ' : ' ');
67008   return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n');
67009 }
67010
67011 /** Used to compose bitmasks for function metadata. */
67012 var WRAP_BIND_FLAG$5 = 1;
67013 var WRAP_BIND_KEY_FLAG$3 = 2;
67014 var WRAP_CURRY_FLAG$3 = 8;
67015 var WRAP_CURRY_RIGHT_FLAG$2 = 16;
67016 var WRAP_PARTIAL_FLAG$3 = 32;
67017 var WRAP_PARTIAL_RIGHT_FLAG$2 = 64;
67018 var WRAP_ARY_FLAG$1 = 128;
67019 var WRAP_REARG_FLAG = 256;
67020 var WRAP_FLIP_FLAG$1 = 512;
67021
67022 /** Used to associate wrap methods with their bit flags. */
67023 var wrapFlags = [
67024   ['ary', WRAP_ARY_FLAG$1],
67025   ['bind', WRAP_BIND_FLAG$5],
67026   ['bindKey', WRAP_BIND_KEY_FLAG$3],
67027   ['curry', WRAP_CURRY_FLAG$3],
67028   ['curryRight', WRAP_CURRY_RIGHT_FLAG$2],
67029   ['flip', WRAP_FLIP_FLAG$1],
67030   ['partial', WRAP_PARTIAL_FLAG$3],
67031   ['partialRight', WRAP_PARTIAL_RIGHT_FLAG$2],
67032   ['rearg', WRAP_REARG_FLAG]
67033 ];
67034
67035 /**
67036  * Updates wrapper `details` based on `bitmask` flags.
67037  *
67038  * @private
67039  * @returns {Array} details The details to modify.
67040  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
67041  * @returns {Array} Returns `details`.
67042  */
67043 function updateWrapDetails(details, bitmask) {
67044   arrayEach(wrapFlags, function(pair) {
67045     var value = '_.' + pair[0];
67046     if ((bitmask & pair[1]) && !arrayIncludes(details, value)) {
67047       details.push(value);
67048     }
67049   });
67050   return details.sort();
67051 }
67052
67053 /**
67054  * Sets the `toString` method of `wrapper` to mimic the source of `reference`
67055  * with wrapper details in a comment at the top of the source body.
67056  *
67057  * @private
67058  * @param {Function} wrapper The function to modify.
67059  * @param {Function} reference The reference function.
67060  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
67061  * @returns {Function} Returns `wrapper`.
67062  */
67063 function setWrapToString(wrapper, reference, bitmask) {
67064   var source = (reference + '');
67065   return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask)));
67066 }
67067
67068 /** Used to compose bitmasks for function metadata. */
67069 var WRAP_BIND_FLAG$4 = 1;
67070 var WRAP_BIND_KEY_FLAG$2 = 2;
67071 var WRAP_CURRY_BOUND_FLAG = 4;
67072 var WRAP_CURRY_FLAG$2 = 8;
67073 var WRAP_PARTIAL_FLAG$2 = 32;
67074 var WRAP_PARTIAL_RIGHT_FLAG$1 = 64;
67075
67076 /**
67077  * Creates a function that wraps `func` to continue currying.
67078  *
67079  * @private
67080  * @param {Function} func The function to wrap.
67081  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
67082  * @param {Function} wrapFunc The function to create the `func` wrapper.
67083  * @param {*} placeholder The placeholder value.
67084  * @param {*} [thisArg] The `this` binding of `func`.
67085  * @param {Array} [partials] The arguments to prepend to those provided to
67086  *  the new function.
67087  * @param {Array} [holders] The `partials` placeholder indexes.
67088  * @param {Array} [argPos] The argument positions of the new function.
67089  * @param {number} [ary] The arity cap of `func`.
67090  * @param {number} [arity] The arity of `func`.
67091  * @returns {Function} Returns the new wrapped function.
67092  */
67093 function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) {
67094   var isCurry = bitmask & WRAP_CURRY_FLAG$2,
67095       newHolders = isCurry ? holders : undefined,
67096       newHoldersRight = isCurry ? undefined : holders,
67097       newPartials = isCurry ? partials : undefined,
67098       newPartialsRight = isCurry ? undefined : partials;
67099
67100   bitmask |= (isCurry ? WRAP_PARTIAL_FLAG$2 : WRAP_PARTIAL_RIGHT_FLAG$1);
67101   bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG$1 : WRAP_PARTIAL_FLAG$2);
67102
67103   if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) {
67104     bitmask &= ~(WRAP_BIND_FLAG$4 | WRAP_BIND_KEY_FLAG$2);
67105   }
67106   var newData = [
67107     func, bitmask, thisArg, newPartials, newHolders, newPartialsRight,
67108     newHoldersRight, argPos, ary, arity
67109   ];
67110
67111   var result = wrapFunc.apply(undefined, newData);
67112   if (isLaziable(func)) {
67113     setData(result, newData);
67114   }
67115   result.placeholder = placeholder;
67116   return setWrapToString(result, func, bitmask);
67117 }
67118
67119 /**
67120  * Gets the argument placeholder value for `func`.
67121  *
67122  * @private
67123  * @param {Function} func The function to inspect.
67124  * @returns {*} Returns the placeholder value.
67125  */
67126 function getHolder(func) {
67127   var object = func;
67128   return object.placeholder;
67129 }
67130
67131 /* Built-in method references for those with the same name as other `lodash` methods. */
67132 var nativeMin$2 = Math.min;
67133
67134 /**
67135  * Reorder `array` according to the specified indexes where the element at
67136  * the first index is assigned as the first element, the element at
67137  * the second index is assigned as the second element, and so on.
67138  *
67139  * @private
67140  * @param {Array} array The array to reorder.
67141  * @param {Array} indexes The arranged array indexes.
67142  * @returns {Array} Returns `array`.
67143  */
67144 function reorder(array, indexes) {
67145   var arrLength = array.length,
67146       length = nativeMin$2(indexes.length, arrLength),
67147       oldArray = copyArray(array);
67148
67149   while (length--) {
67150     var index = indexes[length];
67151     array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined;
67152   }
67153   return array;
67154 }
67155
67156 /** Used as the internal argument placeholder. */
67157 var PLACEHOLDER = '__lodash_placeholder__';
67158
67159 /**
67160  * Replaces all `placeholder` elements in `array` with an internal placeholder
67161  * and returns an array of their indexes.
67162  *
67163  * @private
67164  * @param {Array} array The array to modify.
67165  * @param {*} placeholder The placeholder to replace.
67166  * @returns {Array} Returns the new array of placeholder indexes.
67167  */
67168 function replaceHolders(array, placeholder) {
67169   var index = -1,
67170       length = array.length,
67171       resIndex = 0,
67172       result = [];
67173
67174   while (++index < length) {
67175     var value = array[index];
67176     if (value === placeholder || value === PLACEHOLDER) {
67177       array[index] = PLACEHOLDER;
67178       result[resIndex++] = index;
67179     }
67180   }
67181   return result;
67182 }
67183
67184 /** Used to compose bitmasks for function metadata. */
67185 var WRAP_BIND_FLAG$3 = 1;
67186 var WRAP_BIND_KEY_FLAG$1 = 2;
67187 var WRAP_CURRY_FLAG$1 = 8;
67188 var WRAP_CURRY_RIGHT_FLAG$1 = 16;
67189 var WRAP_ARY_FLAG = 128;
67190 var WRAP_FLIP_FLAG = 512;
67191
67192 /**
67193  * Creates a function that wraps `func` to invoke it with optional `this`
67194  * binding of `thisArg`, partial application, and currying.
67195  *
67196  * @private
67197  * @param {Function|string} func The function or method name to wrap.
67198  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
67199  * @param {*} [thisArg] The `this` binding of `func`.
67200  * @param {Array} [partials] The arguments to prepend to those provided to
67201  *  the new function.
67202  * @param {Array} [holders] The `partials` placeholder indexes.
67203  * @param {Array} [partialsRight] The arguments to append to those provided
67204  *  to the new function.
67205  * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
67206  * @param {Array} [argPos] The argument positions of the new function.
67207  * @param {number} [ary] The arity cap of `func`.
67208  * @param {number} [arity] The arity of `func`.
67209  * @returns {Function} Returns the new wrapped function.
67210  */
67211 function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
67212   var isAry = bitmask & WRAP_ARY_FLAG,
67213       isBind = bitmask & WRAP_BIND_FLAG$3,
67214       isBindKey = bitmask & WRAP_BIND_KEY_FLAG$1,
67215       isCurried = bitmask & (WRAP_CURRY_FLAG$1 | WRAP_CURRY_RIGHT_FLAG$1),
67216       isFlip = bitmask & WRAP_FLIP_FLAG,
67217       Ctor = isBindKey ? undefined : createCtor(func);
67218
67219   function wrapper() {
67220     var length = arguments.length,
67221         args = Array(length),
67222         index = length;
67223
67224     while (index--) {
67225       args[index] = arguments[index];
67226     }
67227     if (isCurried) {
67228       var placeholder = getHolder(wrapper),
67229           holdersCount = countHolders(args, placeholder);
67230     }
67231     if (partials) {
67232       args = composeArgs(args, partials, holders, isCurried);
67233     }
67234     if (partialsRight) {
67235       args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
67236     }
67237     length -= holdersCount;
67238     if (isCurried && length < arity) {
67239       var newHolders = replaceHolders(args, placeholder);
67240       return createRecurry(
67241         func, bitmask, createHybrid, wrapper.placeholder, thisArg,
67242         args, newHolders, argPos, ary, arity - length
67243       );
67244     }
67245     var thisBinding = isBind ? thisArg : this,
67246         fn = isBindKey ? thisBinding[func] : func;
67247
67248     length = args.length;
67249     if (argPos) {
67250       args = reorder(args, argPos);
67251     } else if (isFlip && length > 1) {
67252       args.reverse();
67253     }
67254     if (isAry && ary < length) {
67255       args.length = ary;
67256     }
67257     if (this && this !== root$2 && this instanceof wrapper) {
67258       fn = Ctor || createCtor(fn);
67259     }
67260     return fn.apply(thisBinding, args);
67261   }
67262   return wrapper;
67263 }
67264
67265 /**
67266  * Creates a function that wraps `func` to enable currying.
67267  *
67268  * @private
67269  * @param {Function} func The function to wrap.
67270  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
67271  * @param {number} arity The arity of `func`.
67272  * @returns {Function} Returns the new wrapped function.
67273  */
67274 function createCurry(func, bitmask, arity) {
67275   var Ctor = createCtor(func);
67276
67277   function wrapper() {
67278     var length = arguments.length,
67279         args = Array(length),
67280         index = length,
67281         placeholder = getHolder(wrapper);
67282
67283     while (index--) {
67284       args[index] = arguments[index];
67285     }
67286     var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder)
67287       ? []
67288       : replaceHolders(args, placeholder);
67289
67290     length -= holders.length;
67291     if (length < arity) {
67292       return createRecurry(
67293         func, bitmask, createHybrid, wrapper.placeholder, undefined,
67294         args, holders, undefined, undefined, arity - length);
67295     }
67296     var fn = (this && this !== root$2 && this instanceof wrapper) ? Ctor : func;
67297     return apply(fn, this, args);
67298   }
67299   return wrapper;
67300 }
67301
67302 /** Used to compose bitmasks for function metadata. */
67303 var WRAP_BIND_FLAG$6 = 1;
67304
67305 /**
67306  * Creates a function that wraps `func` to invoke it with the `this` binding
67307  * of `thisArg` and `partials` prepended to the arguments it receives.
67308  *
67309  * @private
67310  * @param {Function} func The function to wrap.
67311  * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
67312  * @param {*} thisArg The `this` binding of `func`.
67313  * @param {Array} partials The arguments to prepend to those provided to
67314  *  the new function.
67315  * @returns {Function} Returns the new wrapped function.
67316  */
67317 function createPartial(func, bitmask, thisArg, partials) {
67318   var isBind = bitmask & WRAP_BIND_FLAG$6,
67319       Ctor = createCtor(func);
67320
67321   function wrapper() {
67322     var argsIndex = -1,
67323         argsLength = arguments.length,
67324         leftIndex = -1,
67325         leftLength = partials.length,
67326         args = Array(leftLength + argsLength),
67327         fn = (this && this !== root$2 && this instanceof wrapper) ? Ctor : func;
67328
67329     while (++leftIndex < leftLength) {
67330       args[leftIndex] = partials[leftIndex];
67331     }
67332     while (argsLength--) {
67333       args[leftIndex++] = arguments[++argsIndex];
67334     }
67335     return apply(fn, isBind ? thisArg : this, args);
67336   }
67337   return wrapper;
67338 }
67339
67340 /** Used as the internal argument placeholder. */
67341 var PLACEHOLDER$1 = '__lodash_placeholder__';
67342
67343 /** Used to compose bitmasks for function metadata. */
67344 var WRAP_BIND_FLAG$7 = 1;
67345 var WRAP_BIND_KEY_FLAG$4 = 2;
67346 var WRAP_CURRY_BOUND_FLAG$1 = 4;
67347 var WRAP_CURRY_FLAG$4 = 8;
67348 var WRAP_ARY_FLAG$2 = 128;
67349 var WRAP_REARG_FLAG$1 = 256;
67350
67351 /* Built-in method references for those with the same name as other `lodash` methods. */
67352 var nativeMin$3 = Math.min;
67353
67354 /**
67355  * Merges the function metadata of `source` into `data`.
67356  *
67357  * Merging metadata reduces the number of wrappers used to invoke a function.
67358  * This is possible because methods like `_.bind`, `_.curry`, and `_.partial`
67359  * may be applied regardless of execution order. Methods like `_.ary` and
67360  * `_.rearg` modify function arguments, making the order in which they are
67361  * executed important, preventing the merging of metadata. However, we make
67362  * an exception for a safe combined case where curried functions have `_.ary`
67363  * and or `_.rearg` applied.
67364  *
67365  * @private
67366  * @param {Array} data The destination metadata.
67367  * @param {Array} source The source metadata.
67368  * @returns {Array} Returns `data`.
67369  */
67370 function mergeData(data, source) {
67371   var bitmask = data[1],
67372       srcBitmask = source[1],
67373       newBitmask = bitmask | srcBitmask,
67374       isCommon = newBitmask < (WRAP_BIND_FLAG$7 | WRAP_BIND_KEY_FLAG$4 | WRAP_ARY_FLAG$2);
67375
67376   var isCombo =
67377     ((srcBitmask == WRAP_ARY_FLAG$2) && (bitmask == WRAP_CURRY_FLAG$4)) ||
67378     ((srcBitmask == WRAP_ARY_FLAG$2) && (bitmask == WRAP_REARG_FLAG$1) && (data[7].length <= source[8])) ||
67379     ((srcBitmask == (WRAP_ARY_FLAG$2 | WRAP_REARG_FLAG$1)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG$4));
67380
67381   // Exit early if metadata can't be merged.
67382   if (!(isCommon || isCombo)) {
67383     return data;
67384   }
67385   // Use source `thisArg` if available.
67386   if (srcBitmask & WRAP_BIND_FLAG$7) {
67387     data[2] = source[2];
67388     // Set when currying a bound function.
67389     newBitmask |= bitmask & WRAP_BIND_FLAG$7 ? 0 : WRAP_CURRY_BOUND_FLAG$1;
67390   }
67391   // Compose partial arguments.
67392   var value = source[3];
67393   if (value) {
67394     var partials = data[3];
67395     data[3] = partials ? composeArgs(partials, value, source[4]) : value;
67396     data[4] = partials ? replaceHolders(data[3], PLACEHOLDER$1) : source[4];
67397   }
67398   // Compose partial right arguments.
67399   value = source[5];
67400   if (value) {
67401     partials = data[5];
67402     data[5] = partials ? composeArgsRight(partials, value, source[6]) : value;
67403     data[6] = partials ? replaceHolders(data[5], PLACEHOLDER$1) : source[6];
67404   }
67405   // Use source `argPos` if available.
67406   value = source[7];
67407   if (value) {
67408     data[7] = value;
67409   }
67410   // Use source `ary` if it's smaller.
67411   if (srcBitmask & WRAP_ARY_FLAG$2) {
67412     data[8] = data[8] == null ? source[8] : nativeMin$3(data[8], source[8]);
67413   }
67414   // Use source `arity` if one is not provided.
67415   if (data[9] == null) {
67416     data[9] = source[9];
67417   }
67418   // Use source `func` and merge bitmasks.
67419   data[0] = source[0];
67420   data[1] = newBitmask;
67421
67422   return data;
67423 }
67424
67425 /** Error message constants. */
67426 var FUNC_ERROR_TEXT$4 = 'Expected a function';
67427
67428 /** Used to compose bitmasks for function metadata. */
67429 var WRAP_BIND_FLAG$1 = 1;
67430 var WRAP_BIND_KEY_FLAG = 2;
67431 var WRAP_CURRY_FLAG = 8;
67432 var WRAP_CURRY_RIGHT_FLAG = 16;
67433 var WRAP_PARTIAL_FLAG$1 = 32;
67434 var WRAP_PARTIAL_RIGHT_FLAG = 64;
67435
67436 /* Built-in method references for those with the same name as other `lodash` methods. */
67437 var nativeMax$5 = Math.max;
67438
67439 /**
67440  * Creates a function that either curries or invokes `func` with optional
67441  * `this` binding and partially applied arguments.
67442  *
67443  * @private
67444  * @param {Function|string} func The function or method name to wrap.
67445  * @param {number} bitmask The bitmask flags.
67446  *    1 - `_.bind`
67447  *    2 - `_.bindKey`
67448  *    4 - `_.curry` or `_.curryRight` of a bound function
67449  *    8 - `_.curry`
67450  *   16 - `_.curryRight`
67451  *   32 - `_.partial`
67452  *   64 - `_.partialRight`
67453  *  128 - `_.rearg`
67454  *  256 - `_.ary`
67455  *  512 - `_.flip`
67456  * @param {*} [thisArg] The `this` binding of `func`.
67457  * @param {Array} [partials] The arguments to be partially applied.
67458  * @param {Array} [holders] The `partials` placeholder indexes.
67459  * @param {Array} [argPos] The argument positions of the new function.
67460  * @param {number} [ary] The arity cap of `func`.
67461  * @param {number} [arity] The arity of `func`.
67462  * @returns {Function} Returns the new wrapped function.
67463  */
67464 function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
67465   var isBindKey = bitmask & WRAP_BIND_KEY_FLAG;
67466   if (!isBindKey && typeof func != 'function') {
67467     throw new TypeError(FUNC_ERROR_TEXT$4);
67468   }
67469   var length = partials ? partials.length : 0;
67470   if (!length) {
67471     bitmask &= ~(WRAP_PARTIAL_FLAG$1 | WRAP_PARTIAL_RIGHT_FLAG);
67472     partials = holders = undefined;
67473   }
67474   ary = ary === undefined ? ary : nativeMax$5(toInteger(ary), 0);
67475   arity = arity === undefined ? arity : toInteger(arity);
67476   length -= holders ? holders.length : 0;
67477
67478   if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) {
67479     var partialsRight = partials,
67480         holdersRight = holders;
67481
67482     partials = holders = undefined;
67483   }
67484   var data = isBindKey ? undefined : getData(func);
67485
67486   var newData = [
67487     func, bitmask, thisArg, partials, holders, partialsRight, holdersRight,
67488     argPos, ary, arity
67489   ];
67490
67491   if (data) {
67492     mergeData(newData, data);
67493   }
67494   func = newData[0];
67495   bitmask = newData[1];
67496   thisArg = newData[2];
67497   partials = newData[3];
67498   holders = newData[4];
67499   arity = newData[9] = newData[9] === undefined
67500     ? (isBindKey ? 0 : func.length)
67501     : nativeMax$5(newData[9] - length, 0);
67502
67503   if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) {
67504     bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG);
67505   }
67506   if (!bitmask || bitmask == WRAP_BIND_FLAG$1) {
67507     var result = createBind(func, bitmask, thisArg);
67508   } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) {
67509     result = createCurry(func, bitmask, arity);
67510   } else if ((bitmask == WRAP_PARTIAL_FLAG$1 || bitmask == (WRAP_BIND_FLAG$1 | WRAP_PARTIAL_FLAG$1)) && !holders.length) {
67511     result = createPartial(func, bitmask, thisArg, partials);
67512   } else {
67513     result = createHybrid.apply(undefined, newData);
67514   }
67515   var setter = data ? baseSetData : setData;
67516   return setWrapToString(setter(result, newData), func, bitmask);
67517 }
67518
67519 /** Used to compose bitmasks for function metadata. */
67520 var WRAP_BIND_FLAG = 1;
67521 var WRAP_PARTIAL_FLAG = 32;
67522
67523 /**
67524  * Creates a function that invokes `func` with the `this` binding of `thisArg`
67525  * and `partials` prepended to the arguments it receives.
67526  *
67527  * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
67528  * may be used as a placeholder for partially applied arguments.
67529  *
67530  * **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
67531  * property of bound functions.
67532  *
67533  * @static
67534  * @memberOf _
67535  * @since 0.1.0
67536  * @category Function
67537  * @param {Function} func The function to bind.
67538  * @param {*} thisArg The `this` binding of `func`.
67539  * @param {...*} [partials] The arguments to be partially applied.
67540  * @returns {Function} Returns the new bound function.
67541  * @example
67542  *
67543  * function greet(greeting, punctuation) {
67544  *   return greeting + ' ' + this.user + punctuation;
67545  * }
67546  *
67547  * var object = { 'user': 'fred' };
67548  *
67549  * var bound = _.bind(greet, object, 'hi');
67550  * bound('!');
67551  * // => 'hi fred!'
67552  *
67553  * // Bound with placeholders.
67554  * var bound = _.bind(greet, object, _, '!');
67555  * bound('hi');
67556  * // => 'hi fred!'
67557  */
67558 var bind$2 = baseRest(function(func, thisArg, partials) {
67559   var bitmask = WRAP_BIND_FLAG;
67560   if (partials.length) {
67561     var holders = replaceHolders(partials, getHolder(bind$2));
67562     bitmask |= WRAP_PARTIAL_FLAG;
67563   }
67564   return createWrap(func, bitmask, thisArg, partials, holders);
67565 });
67566
67567 // Assign default placeholders.
67568 bind$2.placeholder = {};
67569
67570 function presetCollection(collection) {
67571     var maxSearchResults = 50,
67572         maxSuggestionResults = 10;
67573
67574     var presets = {
67575
67576         collection: collection,
67577
67578
67579         item: function(id) {
67580             return find$1(this.collection, function(d) {
67581                 return d.id === id;
67582             });
67583         },
67584
67585
67586         matchGeometry: function(geometry) {
67587             return presetCollection(this.collection.filter(function(d) {
67588                 return d.matchGeometry(geometry);
67589             }));
67590         },
67591
67592
67593         search: function(value, geometry) {
67594             if (!value) return this;
67595
67596             function leading(a) {
67597                 var index = a.indexOf(value);
67598                 return index === 0 || a[index - 1] === ' ';
67599             }
67600
67601             function suggestionName(name) {
67602                 var nameArray = name.split(' - ');
67603                 if (nameArray.length > 1) {
67604                     name = nameArray.slice(0, nameArray.length - 1).join(' - ');
67605                 }
67606                 return name.toLowerCase();
67607             }
67608
67609
67610             value = value.toLowerCase();
67611
67612             var searchable = filter(this.collection, function(a) {
67613                     return a.searchable !== false && a.suggestion !== true;
67614                 }),
67615                 suggestions = filter(this.collection, function(a) {
67616                     return a.suggestion === true;
67617                 });
67618
67619
67620             // matches value to preset.name
67621             var leading_name = filter(searchable, function(a) {
67622                     return leading(a.name().toLowerCase());
67623                 }).sort(function(a, b) {
67624                     var aCompare = a.name().toLowerCase(),
67625                         bCompare = b.name().toLowerCase(),
67626                         i;
67627
67628                     // priority if search string matches preset name exactly - #4325
67629                     if (value === aCompare) return -1;
67630                     if (value === bCompare) return 1;
67631
67632                     // priority for higher matchScore
67633                     i = b.originalScore - a.originalScore;
67634                     if (i !== 0) return i;
67635
67636                     // priority if search string appears earlier in preset name
67637                     i = aCompare.indexOf(value) - bCompare.indexOf(value);
67638                     if (i !== 0) return i;
67639
67640                     // priority for shorter preset names
67641                     return a.name().length - b.name().length;
67642                 });
67643
67644             // matches value to preset.terms values
67645             var leading_terms = filter(searchable, function(a) {
67646                     return some(a.terms() || [], leading);
67647                 });
67648
67649             // matches value to preset.tags values
67650             var leading_tag_values = filter(searchable, function(a) {
67651                     return some(without(values$1(a.tags || {}), '*'), leading);
67652                 });
67653
67654
67655             // finds close matches to value in preset.name
67656             var similar_name = searchable.map(function(a) {
67657                     return {
67658                         preset: a,
67659                         dist: utilEditDistance(value, a.name())
67660                     };
67661                 }).filter(function(a) {
67662                     return a.dist + Math.min(value.length - a.preset.name().length, 0) < 3;
67663                 }).sort(function(a, b) {
67664                     return a.dist - b.dist;
67665                 }).map(function(a) {
67666                     return a.preset;
67667                 });
67668
67669             // finds close matches to value in preset.terms
67670             var similar_terms = filter(searchable, function(a) {
67671                     return some(a.terms() || [], function(b) {
67672                         return utilEditDistance(value, b) + Math.min(value.length - b.length, 0) < 3;
67673                     });
67674                 });
67675
67676             var leading_suggestions = filter(suggestions, function(a) {
67677                     return leading(suggestionName(a.name()));
67678                 }).sort(function(a, b) {
67679                     a = suggestionName(a.name());
67680                     b = suggestionName(b.name());
67681                     var i = a.indexOf(value) - b.indexOf(value);
67682                     if (i === 0) return a.length - b.length;
67683                     else return i;
67684                 });
67685
67686             var similar_suggestions = suggestions.map(function(a) {
67687                     return {
67688                         preset: a,
67689                         dist: utilEditDistance(value, suggestionName(a.name()))
67690                     };
67691                 }).filter(function(a) {
67692                     return a.dist + Math.min(value.length - suggestionName(a.preset.name()).length, 0) < 1;
67693                 }).sort(function(a, b) {
67694                     return a.dist - b.dist;
67695                 }).map(function(a) {
67696                     return a.preset;
67697                 });
67698
67699             var other = presets.item(geometry);
67700
67701             var results = leading_name.concat(
67702                     leading_terms,
67703                     leading_tag_values,
67704                     leading_suggestions.slice(0, maxSuggestionResults + 5),
67705                     similar_name,
67706                     similar_terms,
67707                     similar_suggestions.slice(0, maxSuggestionResults)
67708                 ).slice(0, maxSearchResults - 1);
67709
67710             return presetCollection(uniq(results.concat(other)));
67711         }
67712     };
67713
67714
67715     return presets;
67716 }
67717
67718 function presetCategory(id, category, all) {
67719     category = clone(category);
67720
67721     category.id = id;
67722
67723
67724     category.members = presetCollection(category.members.map(function(id) {
67725         return all.item(id);
67726     }));
67727
67728
67729     category.matchGeometry = function(geometry) {
67730         return category.geometry.indexOf(geometry) >= 0;
67731     };
67732
67733
67734     category.matchScore = function() {
67735         return -1;
67736     };
67737
67738
67739     category.name = function() {
67740         return t('presets.categories.' + id + '.name', {'default': id});
67741     };
67742
67743
67744     category.terms = function() {
67745         return [];
67746     };
67747
67748
67749     return category;
67750 }
67751
67752 function presetField(id, field) {
67753     field = clone(field);
67754
67755     field.id = id;
67756
67757
67758     field.matchGeometry = function(geometry) {
67759         return !field.geometry || field.geometry === geometry;
67760     };
67761
67762
67763     field.t = function(scope, options) {
67764         return t('presets.fields.' + id + '.' + scope, options);
67765     };
67766
67767
67768     field.label = function() {
67769         return field.t('label', {'default': id});
67770     };
67771
67772
67773     var placeholder = field.placeholder;
67774     field.placeholder = function() {
67775         return field.t('placeholder', {'default': placeholder});
67776     };
67777
67778
67779     return field;
67780 }
67781
67782 function presetPreset(id, preset, fields) {
67783     preset = clone(preset);
67784
67785     preset.id = id;
67786     preset.fields = (preset.fields || []).map(getFields);
67787     preset.geometry = (preset.geometry || []);
67788
67789
67790     function getFields(f) {
67791         return fields[f];
67792     }
67793
67794
67795     preset.matchGeometry = function(geometry) {
67796         return preset.geometry.indexOf(geometry) >= 0;
67797     };
67798
67799
67800     preset.originalScore = preset.matchScore || 1;
67801
67802
67803     preset.matchScore = function(entity) {
67804         var tags = preset.tags,
67805             score = 0;
67806
67807         for (var t$$1 in tags) {
67808             if (entity.tags[t$$1] === tags[t$$1]) {
67809                 score += preset.originalScore;
67810             } else if (tags[t$$1] === '*' && t$$1 in entity.tags) {
67811                 score += preset.originalScore / 2;
67812             } else {
67813                 return -1;
67814             }
67815         }
67816
67817         return score;
67818     };
67819
67820
67821     preset.t = function(scope, options) {
67822         return t('presets.presets.' + id + '.' + scope, options);
67823     };
67824
67825
67826     var origName = preset.name || '';
67827     preset.name = function() {
67828         if (preset.suggestion) {
67829             id = id.split('/');
67830             id = id[0] + '/' + id[1];
67831             return origName + ' - ' + t('presets.presets.' + id + '.name');
67832         }
67833         return preset.t('name', { 'default': origName });
67834     };
67835
67836     var origTerms = (preset.terms || []).join();
67837     preset.terms = function() {
67838         return preset.t('terms', { 'default': origTerms }).toLowerCase().trim().split(/\s*,+\s*/);
67839     };
67840
67841
67842     preset.isFallback = function() {
67843         var tagCount = Object.keys(preset.tags).length;
67844         return tagCount === 0 || (tagCount === 1 && preset.tags.hasOwnProperty('area'));
67845     };
67846
67847
67848     var reference = preset.reference || {};
67849     preset.reference = function(geometry) {
67850         var key = reference.key || Object.keys(omit(preset.tags, 'name'))[0],
67851             value = reference.value || preset.tags[key];
67852
67853         if (geometry === 'relation' && key === 'type') {
67854             if (value in preset.tags) {
67855                 key = value;
67856                 value = preset.tags[key];
67857             } else {
67858                 return { rtype: value };
67859             }
67860         }
67861
67862         if (value === '*') {
67863             return { key: key };
67864         } else {
67865             return { key: key, value: value };
67866         }
67867     };
67868
67869
67870     var removeTags = preset.removeTags || preset.tags || {};
67871     preset.removeTags = function(tags, geometry) {
67872         tags = omit(tags, keys$1(removeTags));
67873
67874         for (var f in preset.fields) {
67875             var field = preset.fields[f];
67876             if (field.matchGeometry(geometry) && field.default === tags[field.key]) {
67877                 delete tags[field.key];
67878             }
67879         }
67880
67881         delete tags.area;
67882         return tags;
67883     };
67884
67885
67886     var applyTags = preset.addTags || preset.tags || {};
67887     preset.applyTags = function(tags, geometry) {
67888         var k;
67889
67890         tags = clone(tags);
67891
67892         for (k in applyTags) {
67893             if (applyTags[k] === '*') {
67894                 tags[k] = 'yes';
67895             } else {
67896                 tags[k] = applyTags[k];
67897             }
67898         }
67899
67900         // Add area=yes if necessary.
67901         // This is necessary if the geometry is already an area (e.g. user drew an area) AND any of:
67902         // 1. chosen preset could be either an area or a line (`barrier=city_wall`)
67903         // 2. chosen preset doesn't have a key in areaKeys (`railway=station`)
67904         if (!applyTags.hasOwnProperty('area')) {
67905             delete tags.area;
67906             if (geometry === 'area') {
67907                 var needsAreaTag = true;
67908                 if (preset.geometry.indexOf('line') === -1) {
67909                     for (k in applyTags) {
67910                         if (k in areaKeys) {
67911                             needsAreaTag = false;
67912                             break;
67913                         }
67914                     }
67915                 }
67916                 if (needsAreaTag) {
67917                     tags.area = 'yes';
67918                 }
67919             }
67920         }
67921
67922         for (var f in preset.fields) {
67923             var field = preset.fields[f];
67924             if (field.matchGeometry(geometry) && field.key && !tags[field.key] && field.default) {
67925                 tags[field.key] = field.default;
67926             }
67927         }
67928
67929         return tags;
67930     };
67931
67932
67933     return preset;
67934 }
67935
67936 function presetIndex() {
67937     // a presetCollection with methods for
67938     // loading new data and returning defaults
67939
67940     var all = presetCollection([]),
67941         defaults = { area: all, line: all, point: all, vertex: all, relation: all },
67942         fields = {},
67943         universal = [],
67944         recent = presetCollection([]);
67945
67946     // Index of presets by (geometry, tag key).
67947     var index = {
67948         point: {},
67949         vertex: {},
67950         line: {},
67951         area: {},
67952         relation: {}
67953     };
67954
67955     all.match = function(entity, resolver) {
67956         var geometry = entity.geometry(resolver);
67957         var address;
67958
67959         // Treat entities on addr:interpolation lines as points, not vertices - #3241
67960         if (geometry === 'vertex' && entity.isOnAddressLine(resolver)) {
67961             geometry = 'point';
67962         }
67963
67964         var geometryMatches = index[geometry],
67965             best = -1,
67966             match;
67967
67968         for (var k in entity.tags) {
67969             // If any part of an address is present,
67970             // allow fallback to "Address" preset - #4353
67971             if (k.match(/^addr:/) !== null && geometryMatches['addr:*']) {
67972                 address = geometryMatches['addr:*'][0];
67973             }
67974
67975             var keyMatches = geometryMatches[k];
67976             if (!keyMatches) continue;
67977
67978             for (var i = 0; i < keyMatches.length; i++) {
67979                 var score = keyMatches[i].matchScore(entity);
67980                 if (score > best) {
67981                     best = score;
67982                     match = keyMatches[i];
67983                 }
67984             }
67985         }
67986
67987         if (address && (!match || match.isFallback())) {
67988             match = address;
67989         }
67990
67991         return match || all.item(geometry);
67992     };
67993
67994
67995     // Because of the open nature of tagging, iD will never have a complete
67996     // list of tags used in OSM, so we want it to have logic like "assume
67997     // that a closed way with an amenity tag is an area, unless the amenity
67998     // is one of these specific types". This function computes a structure
67999     // that allows testing of such conditions, based on the presets designated
68000     // as as supporting (or not supporting) the area geometry.
68001     //
68002     // The returned object L is a whitelist/blacklist of tags. A closed way
68003     // with a tag (k, v) is considered to be an area if `k in L && !(v in L[k])`
68004     // (see `Way#isArea()`). In other words, the keys of L form the whitelist,
68005     // and the subkeys form the blacklist.
68006     all.areaKeys = function() {
68007         var areaKeys = {},
68008             ignore = ['barrier', 'highway', 'footway', 'railway', 'type'],  // probably a line..
68009             presets = reject(all.collection, 'suggestion');
68010
68011         // whitelist
68012         presets.forEach(function(d) {
68013             for (var key in d.tags) break;
68014             if (!key) return;
68015             if (ignore.indexOf(key) !== -1) return;
68016
68017             if (d.geometry.indexOf('area') !== -1) {    // probably an area..
68018                 areaKeys[key] = areaKeys[key] || {};
68019             }
68020         });
68021
68022         // blacklist
68023         presets.forEach(function(d) {
68024             for (var key in d.tags) break;
68025             if (!key) return;
68026             if (ignore.indexOf(key) !== -1) return;
68027
68028             var value = d.tags[key];
68029             if (key in areaKeys &&                      // probably an area...
68030                 d.geometry.indexOf('line') !== -1 &&    // but sometimes a line
68031                 value !== '*') {
68032                 areaKeys[key][value] = true;
68033             }
68034         });
68035
68036         return areaKeys;
68037     };
68038
68039
68040     all.init = function() {
68041         var d = data.presets;
68042
68043         all.collection = [];
68044         recent.collection = [];
68045         fields = {};
68046         universal = [];
68047         index = { point: {}, vertex: {}, line: {}, area: {}, relation: {} };
68048
68049         if (d.fields) {
68050             forEach(d.fields, function(d, id) {
68051                 fields[id] = presetField(id, d);
68052                 if (d.universal) universal.push(fields[id]);
68053             });
68054         }
68055
68056         if (d.presets) {
68057             forEach(d.presets, function(d, id) {
68058                 all.collection.push(presetPreset(id, d, fields));
68059             });
68060         }
68061
68062         if (d.categories) {
68063             forEach(d.categories, function(d, id) {
68064                 all.collection.push(presetCategory(id, d, all));
68065             });
68066         }
68067
68068         if (d.defaults) {
68069             var getItem = bind$2(all.item, all);
68070             defaults = {
68071                 area: presetCollection(d.defaults.area.map(getItem)),
68072                 line: presetCollection(d.defaults.line.map(getItem)),
68073                 point: presetCollection(d.defaults.point.map(getItem)),
68074                 vertex: presetCollection(d.defaults.vertex.map(getItem)),
68075                 relation: presetCollection(d.defaults.relation.map(getItem))
68076             };
68077         }
68078
68079         for (var i = 0; i < all.collection.length; i++) {
68080             var preset = all.collection[i],
68081                 geometry = preset.geometry;
68082
68083             for (var j = 0; j < geometry.length; j++) {
68084                 var g = index[geometry[j]];
68085                 for (var k in preset.tags) {
68086                     (g[k] = g[k] || []).push(preset);
68087                 }
68088             }
68089         }
68090
68091         return all;
68092     };
68093
68094     all.field = function(id) {
68095         return fields[id];
68096     };
68097
68098     all.universal = function() {
68099         return universal;
68100     };
68101
68102     all.defaults = function(geometry, n) {
68103         var rec = recent.matchGeometry(geometry).collection.slice(0, 4),
68104             def = uniq(rec.concat(defaults[geometry].collection)).slice(0, n - 1);
68105         return presetCollection(uniq(rec.concat(def).concat(all.item(geometry))));
68106     };
68107
68108     all.choose = function(preset) {
68109         if (!preset.isFallback()) {
68110             recent = presetCollection(uniq([preset].concat(recent.collection)));
68111         }
68112         return all;
68113     };
68114
68115     return all;
68116 }
68117
68118 var areaKeys = {};
68119
68120 function setAreaKeys(value) {
68121     areaKeys = value;
68122 }
68123
68124
68125 function coreContext() {
68126     var context = {};
68127     context.version = '2.5.1';
68128
68129     // create a special translation that contains the keys in place of the strings
68130     var tkeys = cloneDeep(en);
68131     var parents = [];
68132
68133     function traverser(v, k, obj) {
68134         parents.push(k);
68135         if (isObject(v)) {
68136             forOwn(v, traverser);
68137         } else if (isString(v)) {
68138             obj[k] = parents.join('.');
68139         }
68140         parents.pop();
68141     }
68142
68143     forOwn(tkeys, traverser);
68144     addTranslation('_tkeys_', tkeys);
68145
68146     addTranslation('en', en);
68147     setLocale('en');
68148
68149     var dispatch$$1 = dispatch('enter', 'exit', 'change');
68150
68151     // https://github.com/openstreetmap/iD/issues/772
68152     // http://mathiasbynens.be/notes/localstorage-pattern#comment-9
68153     var storage;
68154     try { storage = localStorage; } catch (e) {}  // eslint-disable-line no-empty
68155     storage = storage || (function() {
68156         var s = {};
68157         return {
68158             getItem: function(k) { return s[k]; },
68159             setItem: function(k, v) { s[k] = v; },
68160             removeItem: function(k) { delete s[k]; }
68161         };
68162     })();
68163
68164     context.storage = function(k, v) {
68165         try {
68166             if (arguments.length === 1) return storage.getItem(k);
68167             else if (v === null) storage.removeItem(k);
68168             else storage.setItem(k, v);
68169         } catch (e) {
68170             // localstorage quota exceeded
68171             /* eslint-disable no-console */
68172             if (typeof console !== 'undefined') console.error('localStorage quota exceeded');
68173             /* eslint-enable no-console */
68174         }
68175     };
68176
68177
68178     /* Straight accessors. Avoid using these if you can. */
68179     var ui, connection, history;
68180     context.ui = function() { return ui; };
68181     context.connection = function() { return connection; };
68182     context.history = function() { return history; };
68183
68184
68185     /* Connection */
68186     context.preauth = function(options) {
68187         if (connection) {
68188             connection.switch(options);
68189         }
68190         return context;
68191     };
68192
68193     context.loadTiles = utilCallWhenIdle(function(projection, dimensions, callback) {
68194         var cid;
68195         function done(err, result) {
68196             if (connection.getConnectionId() !== cid) {
68197                 if (callback) callback({ message: 'Connection Switched', status: -1 });
68198                 return;
68199             }
68200             if (!err) history.merge(result.data, result.extent);
68201             if (callback) callback(err, result);
68202         }
68203         if (connection) {
68204             cid = connection.getConnectionId();
68205             connection.loadTiles(projection, dimensions, done);
68206         }
68207     });
68208
68209     context.loadEntity = function(entityId, callback) {
68210         var cid;
68211         function done(err, result) {
68212             if (connection.getConnectionId() !== cid) {
68213                 if (callback) callback({ message: 'Connection Switched', status: -1 });
68214                 return;
68215             }
68216             if (!err) history.merge(result.data, result.extent);
68217             if (callback) callback(err, result);
68218         }
68219         if (connection) {
68220             cid = connection.getConnectionId();
68221             connection.loadEntity(entityId, done);
68222         }
68223     };
68224
68225     context.zoomToEntity = function(entityId, zoomTo) {
68226         if (zoomTo !== false) {
68227             this.loadEntity(entityId, function(err, result) {
68228                 if (err) return;
68229                 var entity = find$1(result.data, function(e) { return e.id === entityId; });
68230                 if (entity) { map.zoomTo(entity); }
68231             });
68232         }
68233
68234         map.on('drawn.zoomToEntity', function() {
68235             if (!context.hasEntity(entityId)) return;
68236             map.on('drawn.zoomToEntity', null);
68237             context.on('enter.zoomToEntity', null);
68238             context.enter(modeSelect(context, [entityId]));
68239         });
68240
68241         context.on('enter.zoomToEntity', function() {
68242             if (mode.id !== 'browse') {
68243                 map.on('drawn.zoomToEntity', null);
68244                 context.on('enter.zoomToEntity', null);
68245             }
68246         });
68247     };
68248
68249     var minEditableZoom = 16;
68250     context.minEditableZoom = function(_) {
68251         if (!arguments.length) return minEditableZoom;
68252         minEditableZoom = _;
68253         if (connection) {
68254             connection.tileZoom(_);
68255         }
68256         return context;
68257     };
68258
68259
68260     /* History */
68261     var inIntro = false;
68262     context.inIntro = function(_) {
68263         if (!arguments.length) return inIntro;
68264         inIntro = _;
68265         return context;
68266     };
68267
68268     context.save = function() {
68269         // no history save, no message onbeforeunload
68270         if (inIntro || d3_select('.modal').size()) return;
68271
68272         var canSave;
68273         if (mode && mode.id === 'save') {
68274             canSave = false;
68275         } else {
68276             canSave = context.selectedIDs().every(function(id) {
68277                 var entity = context.hasEntity(id);
68278                 return entity && !entity.isDegenerate();
68279             });
68280         }
68281
68282         if (canSave) {
68283             history.save();
68284         }
68285         if (history.hasChanges()) {
68286             return t('save.unsaved_changes');
68287         }
68288     };
68289
68290
68291     /* Graph */
68292     context.hasEntity = function(id) {
68293         return history.graph().hasEntity(id);
68294     };
68295     context.entity = function(id) {
68296         return history.graph().entity(id);
68297     };
68298     context.childNodes = function(way) {
68299         return history.graph().childNodes(way);
68300     };
68301     context.geometry = function(id) {
68302         return context.entity(id).geometry(history.graph());
68303     };
68304
68305
68306     /* Modes */
68307     var mode;
68308     context.mode = function() {
68309         return mode;
68310     };
68311     context.enter = function(newMode) {
68312         if (mode) {
68313             mode.exit();
68314             dispatch$$1.call('exit', this, mode);
68315         }
68316
68317         mode = newMode;
68318         mode.enter();
68319         dispatch$$1.call('enter', this, mode);
68320     };
68321
68322     context.selectedIDs = function() {
68323         if (mode && mode.selectedIDs) {
68324             return mode.selectedIDs();
68325         } else {
68326             return [];
68327         }
68328     };
68329
68330
68331     /* Behaviors */
68332     context.install = function(behavior) {
68333         context.surface().call(behavior);
68334     };
68335     context.uninstall = function(behavior) {
68336         context.surface().call(behavior.off);
68337     };
68338
68339
68340     /* Copy/Paste */
68341     var copyIDs = [], copyGraph;
68342     context.copyGraph = function() { return copyGraph; };
68343     context.copyIDs = function(_) {
68344         if (!arguments.length) return copyIDs;
68345         copyIDs = _;
68346         copyGraph = history.graph();
68347         return context;
68348     };
68349
68350
68351     /* Background */
68352     var background;
68353     context.background = function() { return background; };
68354
68355
68356     /* Features */
68357     var features;
68358     context.features = function() { return features; };
68359     context.hasHiddenConnections = function(id) {
68360         var graph = history.graph(),
68361             entity = graph.entity(id);
68362         return features.hasHiddenConnections(entity, graph);
68363     };
68364
68365
68366     /* Presets */
68367     var presets;
68368     context.presets = function() { return presets; };
68369
68370
68371     /* Map */
68372     var map;
68373     context.map = function() { return map; };
68374     context.layers = function() { return map.layers; };
68375     context.surface = function() { return map.surface; };
68376     context.editable = function() { return map.editable(); };
68377     context.surfaceRect = function() {
68378         return map.surface.node().getBoundingClientRect();
68379     };
68380
68381
68382     /* Debug */
68383     var debugFlags = {
68384         tile: false,
68385         collision: false,
68386         imagery: false,
68387         imperial: false,
68388         driveLeft: false
68389     };
68390     context.debugFlags = function() {
68391         return debugFlags;
68392     };
68393     context.setDebug = function(flag, val) {
68394         if (arguments.length === 1) val = true;
68395         debugFlags[flag] = val;
68396         dispatch$$1.call('change');
68397         return context;
68398     };
68399     context.getDebug = function(flag) {
68400         return flag && debugFlags[flag];
68401     };
68402
68403
68404     /* Container */
68405     var container = d3_select(document.body);
68406     context.container = function(_) {
68407         if (!arguments.length) return container;
68408         container = _;
68409         container.classed('id-container', true);
68410         return context;
68411     };
68412     var embed;
68413     context.embed = function(_) {
68414         if (!arguments.length) return embed;
68415         embed = _;
68416         return context;
68417     };
68418
68419
68420     /* Assets */
68421     var assetPath = '';
68422     context.assetPath = function(_) {
68423         if (!arguments.length) return assetPath;
68424         assetPath = _;
68425         return context;
68426     };
68427
68428     var assetMap = {};
68429     context.assetMap = function(_) {
68430         if (!arguments.length) return assetMap;
68431         assetMap = _;
68432         return context;
68433     };
68434
68435     context.asset = function(_) {
68436         var filename = assetPath + _;
68437         return assetMap[filename] || filename;
68438     };
68439
68440     context.imagePath = function(_) {
68441         return context.asset('img/' + _);
68442     };
68443
68444
68445     /* locales */
68446     // `locale` variable contains a "requested locale".
68447     // It won't become the `currentLocale` until after loadLocale() is called.
68448     var locale, localePath;
68449
68450     context.locale = function(loc, path) {
68451         if (!arguments.length) return currentLocale;
68452         locale = loc;
68453         localePath = path;
68454         return context;
68455     };
68456
68457     context.loadLocale = function(callback) {
68458         if (locale && locale !== 'en' && dataLocales.hasOwnProperty(locale)) {
68459             localePath = localePath || context.asset('locales/' + locale + '.json');
68460             d3_json(localePath, function(err, result) {
68461                 if (!err) {
68462                     addTranslation(locale, result[locale]);
68463                     setLocale(locale);
68464                     utilDetect(true);
68465                 }
68466                 if (callback) {
68467                     callback(err);
68468                 }
68469             });
68470         } else {
68471             if (locale) {
68472                 setLocale(locale);
68473                 utilDetect(true);
68474             }
68475             if (callback) {
68476                 callback();
68477             }
68478         }
68479     };
68480
68481
68482     /* reset (aka flush) */
68483     context.reset = context.flush = function() {
68484         context.debouncedSave.cancel();
68485         forEach(services, function(service) {
68486             if (service && typeof service.reset === 'function') {
68487                 service.reset(context);
68488             }
68489         });
68490         features.reset();
68491         history.reset();
68492         return context;
68493     };
68494
68495
68496     /* Init */
68497
68498     context.projection = geoRawMercator();
68499     context.curtainProjection = geoRawMercator();
68500
68501     locale = utilDetect().locale;
68502     if (locale && !dataLocales.hasOwnProperty(locale)) {
68503         locale = locale.split('-')[0];
68504     }
68505
68506     history = coreHistory(context);
68507     context.graph = history.graph;
68508     context.changes = history.changes;
68509     context.intersects = history.intersects;
68510
68511     // Debounce save, since it's a synchronous localStorage write,
68512     // and history changes can happen frequently (e.g. when dragging).
68513     context.debouncedSave = debounce(context.save, 350);
68514     function withDebouncedSave(fn) {
68515         return function() {
68516             var result = fn.apply(history, arguments);
68517             context.debouncedSave();
68518             return result;
68519         };
68520     }
68521
68522     context.perform = withDebouncedSave(history.perform);
68523     context.replace = withDebouncedSave(history.replace);
68524     context.pop = withDebouncedSave(history.pop);
68525     context.overwrite = withDebouncedSave(history.overwrite);
68526     context.undo = withDebouncedSave(history.undo);
68527     context.redo = withDebouncedSave(history.redo);
68528
68529     ui = uiInit(context);
68530
68531     connection = services.osm;
68532     background = rendererBackground(context);
68533     features = rendererFeatures(context);
68534     presets = presetIndex();
68535
68536     map = rendererMap(context);
68537     context.mouse = map.mouse;
68538     context.extent = map.extent;
68539     context.pan = map.pan;
68540     context.zoomIn = map.zoomIn;
68541     context.zoomOut = map.zoomOut;
68542     context.zoomInFurther = map.zoomInFurther;
68543     context.zoomOutFurther = map.zoomOutFurther;
68544     context.redrawEnable = map.redrawEnable;
68545
68546     forEach(services, function(service) {
68547         if (service && typeof service.init === 'function') {
68548             service.init(context);
68549         }
68550     });
68551
68552     background.init();
68553     features.init();
68554     presets.init();
68555     areaKeys = presets.areaKeys();
68556
68557
68558     return utilRebind(context, dispatch$$1, 'on');
68559 }
68560
68561 function osmWay() {
68562     if (!(this instanceof osmWay)) {
68563         return (new osmWay()).initialize(arguments);
68564     } else if (arguments.length) {
68565         this.initialize(arguments);
68566     }
68567 }
68568
68569
68570 osmEntity.way = osmWay;
68571
68572 osmWay.prototype = Object.create(osmEntity.prototype);
68573
68574
68575 assignIn(osmWay.prototype, {
68576     type: 'way',
68577     nodes: [],
68578
68579
68580     copy: function(resolver, copies) {
68581         if (copies[this.id])
68582             return copies[this.id];
68583
68584         var copy = osmEntity.prototype.copy.call(this, resolver, copies);
68585
68586         var nodes = this.nodes.map(function(id) {
68587             return resolver.entity(id).copy(resolver, copies).id;
68588         });
68589
68590         copy = copy.update({ nodes: nodes });
68591         copies[this.id] = copy;
68592
68593         return copy;
68594     },
68595
68596
68597     extent: function(resolver) {
68598         return resolver.transient(this, 'extent', function() {
68599             var extent = geoExtent();
68600             for (var i = 0; i < this.nodes.length; i++) {
68601                 var node = resolver.hasEntity(this.nodes[i]);
68602                 if (node) {
68603                     extent._extend(node.extent());
68604                 }
68605             }
68606             return extent;
68607         });
68608     },
68609
68610
68611     first: function() {
68612         return this.nodes[0];
68613     },
68614
68615
68616     last: function() {
68617         return this.nodes[this.nodes.length - 1];
68618     },
68619
68620
68621     contains: function(node) {
68622         return this.nodes.indexOf(node) >= 0;
68623     },
68624
68625
68626     affix: function(node) {
68627         if (this.nodes[0] === node) return 'prefix';
68628         if (this.nodes[this.nodes.length - 1] === node) return 'suffix';
68629     },
68630
68631
68632     layer: function() {
68633         // explicit layer tag, clamp between -10, 10..
68634         if (isFinite(this.tags.layer)) {
68635             return Math.max(-10, Math.min(+(this.tags.layer), 10));
68636         }
68637
68638         // implied layer tag..
68639         if (this.tags.location === 'overground') return 1;
68640         if (this.tags.location === 'underground') return -1;
68641         if (this.tags.location === 'underwater') return -10;
68642
68643         if (this.tags.power === 'line') return 10;
68644         if (this.tags.power === 'minor_line') return 10;
68645         if (this.tags.aerialway) return 10;
68646         if (this.tags.bridge) return 1;
68647         if (this.tags.cutting) return -1;
68648         if (this.tags.tunnel) return -1;
68649         if (this.tags.waterway) return -1;
68650         if (this.tags.man_made === 'pipeline') return -10;
68651         if (this.tags.boundary) return -10;
68652         return 0;
68653     },
68654
68655
68656     isOneWay: function() {
68657         // explicit oneway tag..
68658         if (['yes', '1', '-1'].indexOf(this.tags.oneway) !== -1) { return true; }
68659         if (['no', '0'].indexOf(this.tags.oneway) !== -1) { return false; }
68660
68661         // implied oneway tag..
68662         for (var key in this.tags) {
68663             if (key in osmOneWayTags && (this.tags[key] in osmOneWayTags[key]))
68664                 return true;
68665         }
68666         return false;
68667     },
68668
68669
68670     lanes: function() {
68671         return osmLanes(this);
68672     },
68673
68674
68675     isClosed: function() {
68676         return this.nodes.length > 1 && this.first() === this.last();
68677     },
68678
68679
68680     isConvex: function(resolver) {
68681         if (!this.isClosed() || this.isDegenerate()) return null;
68682
68683         var nodes = uniq(resolver.childNodes(this)),
68684             coords = map$4(nodes, 'loc'),
68685             curr = 0, prev = 0;
68686
68687         for (var i = 0; i < coords.length; i++) {
68688             var o = coords[(i+1) % coords.length],
68689                 a = coords[i],
68690                 b = coords[(i+2) % coords.length],
68691                 res = geoCross(o, a, b);
68692
68693             curr = (res > 0) ? 1 : (res < 0) ? -1 : 0;
68694             if (curr === 0) {
68695                 continue;
68696             } else if (prev && curr !== prev) {
68697                 return false;
68698             }
68699             prev = curr;
68700         }
68701         return true;
68702     },
68703
68704
68705     isArea: function() {
68706         // `highway` and `railway` are typically linear features, but there
68707         // are a few exceptions that should be treated as areas, even in the
68708         // absence of a proper `area=yes` or `areaKeys` tag.. see #4194
68709         var lineKeys = {
68710             highway: {
68711                 rest_area: true,
68712                 services: true
68713             },
68714             railway: {
68715                 roundhouse: true,
68716                 station: true,
68717                 traverser: true,
68718                 turntable: true,
68719                 wash: true
68720             }
68721         };
68722
68723         if (this.tags.area === 'yes')
68724             return true;
68725         if (!this.isClosed() || this.tags.area === 'no')
68726             return false;
68727         for (var key in this.tags) {
68728             if (key in areaKeys && !(this.tags[key] in areaKeys[key])) {
68729                 return true;
68730             }
68731             if (key in lineKeys && this.tags[key] in lineKeys[key]) {
68732                 return true;
68733             }
68734         }
68735         return false;
68736     },
68737
68738
68739     isDegenerate: function() {
68740         return uniq(this.nodes).length < (this.isArea() ? 3 : 2);
68741     },
68742
68743
68744     areAdjacent: function(n1, n2) {
68745         for (var i = 0; i < this.nodes.length; i++) {
68746             if (this.nodes[i] === n1) {
68747                 if (this.nodes[i - 1] === n2) return true;
68748                 if (this.nodes[i + 1] === n2) return true;
68749             }
68750         }
68751         return false;
68752     },
68753
68754
68755     geometry: function(graph) {
68756         return graph.transient(this, 'geometry', function() {
68757             return this.isArea() ? 'area' : 'line';
68758         });
68759     },
68760
68761
68762     // If this way is not closed, append the beginning node to the end of the nodelist to close it.
68763     close: function() {
68764         if (this.isClosed() || !this.nodes.length) return this;
68765
68766         var nodes = this.nodes.slice();
68767         nodes = nodes.filter(noRepeatNodes);
68768         nodes.push(nodes[0]);
68769         return this.update({ nodes: nodes });
68770     },
68771
68772
68773     // If this way is closed, remove any connector nodes from the end of the nodelist to unclose it.
68774     unclose: function() {
68775         if (!this.isClosed()) return this;
68776
68777         var nodes = this.nodes.slice(),
68778             connector = this.first(),
68779             i = nodes.length - 1;
68780
68781         // remove trailing connectors..
68782         while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
68783             nodes.splice(i, 1);
68784             i = nodes.length - 1;
68785         }
68786
68787         nodes = nodes.filter(noRepeatNodes);
68788         return this.update({ nodes: nodes });
68789     },
68790
68791
68792     // Adds a node (id) in front of the node which is currently at position index.
68793     // If index is undefined, the node will be added to the end of the way for linear ways,
68794     //   or just before the final connecting node for circular ways.
68795     // Consecutive duplicates are eliminated including existing ones.
68796     // Circularity is always preserved when adding a node.
68797     addNode: function(id, index) {
68798         var nodes = this.nodes.slice(),
68799             isClosed = this.isClosed(),
68800             max = isClosed ? nodes.length - 1 : nodes.length;
68801
68802         if (index === undefined) {
68803             index = max;
68804         }
68805
68806         if (index < 0 || index > max) {
68807             throw new RangeError('index ' + index + ' out of range 0..' + max);
68808         }
68809
68810         // If this is a closed way, remove all connector nodes except the first one
68811         // (there may be duplicates) and adjust index if necessary..
68812         if (isClosed) {
68813             var connector = this.first();
68814
68815             // leading connectors..
68816             var i = 1;
68817             while (i < nodes.length && nodes.length > 2 && nodes[i] === connector) {
68818                 nodes.splice(i, 1);
68819                 if (index > i) index--;
68820             }
68821
68822             // trailing connectors..
68823             i = nodes.length - 1;
68824             while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
68825                 nodes.splice(i, 1);
68826                 if (index > i) index--;
68827                 i = nodes.length - 1;
68828             }
68829         }
68830
68831         nodes.splice(index, 0, id);
68832         nodes = nodes.filter(noRepeatNodes);
68833
68834         // If the way was closed before, append a connector node to keep it closed..
68835         if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
68836             nodes.push(nodes[0]);
68837         }
68838
68839         return this.update({ nodes: nodes });
68840     },
68841
68842
68843     // Replaces the node which is currently at position index with the given node (id).
68844     // Consecutive duplicates are eliminated including existing ones.
68845     // Circularity is preserved when updating a node.
68846     updateNode: function(id, index) {
68847         var nodes = this.nodes.slice(),
68848             isClosed = this.isClosed(),
68849             max = nodes.length - 1;
68850
68851         if (index === undefined || index < 0 || index > max) {
68852             throw new RangeError('index ' + index + ' out of range 0..' + max);
68853         }
68854
68855         // If this is a closed way, remove all connector nodes except the first one
68856         // (there may be duplicates) and adjust index if necessary..
68857         if (isClosed) {
68858             var connector = this.first();
68859
68860             // leading connectors..
68861             var i = 1;
68862             while (i < nodes.length && nodes.length > 2 && nodes[i] === connector) {
68863                 nodes.splice(i, 1);
68864                 if (index > i) index--;
68865             }
68866
68867             // trailing connectors..
68868             i = nodes.length - 1;
68869             while (i > 0 && nodes.length > 1 && nodes[i] === connector) {
68870                 nodes.splice(i, 1);
68871                 if (index === i) index = 0;  // update leading connector instead
68872                 i = nodes.length - 1;
68873             }
68874         }
68875
68876         nodes.splice(index, 1, id);
68877         nodes = nodes.filter(noRepeatNodes);
68878
68879         // If the way was closed before, append a connector node to keep it closed..
68880         if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
68881             nodes.push(nodes[0]);
68882         }
68883
68884         return this.update({nodes: nodes});
68885     },
68886
68887
68888     // Replaces each occurrence of node id needle with replacement.
68889     // Consecutive duplicates are eliminated including existing ones.
68890     // Circularity is preserved.
68891     replaceNode: function(needle, replacement) {
68892         var nodes = this.nodes.slice(),
68893             isClosed = this.isClosed();
68894
68895         for (var i = 0; i < nodes.length; i++) {
68896             if (nodes[i] === needle) {
68897                 nodes[i] = replacement;
68898             }
68899         }
68900
68901         nodes = nodes.filter(noRepeatNodes);
68902
68903         // If the way was closed before, append a connector node to keep it closed..
68904         if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
68905             nodes.push(nodes[0]);
68906         }
68907
68908         return this.update({nodes: nodes});
68909     },
68910
68911
68912     // Removes each occurrence of node id needle with replacement.
68913     // Consecutive duplicates are eliminated including existing ones.
68914     // Circularity is preserved.
68915     removeNode: function(id) {
68916         var nodes = this.nodes.slice(),
68917             isClosed = this.isClosed();
68918
68919         nodes = nodes
68920             .filter(function(node) { return node !== id; })
68921             .filter(noRepeatNodes);
68922
68923         // If the way was closed before, append a connector node to keep it closed..
68924         if (isClosed && (nodes.length === 1 || nodes[0] !== nodes[nodes.length - 1])) {
68925             nodes.push(nodes[0]);
68926         }
68927
68928         return this.update({nodes: nodes});
68929     },
68930
68931
68932     asJXON: function(changeset_id) {
68933         var r = {
68934             way: {
68935                 '@id': this.osmId(),
68936                 '@version': this.version || 0,
68937                 nd: map$4(this.nodes, function(id) {
68938                     return { keyAttributes: { ref: osmEntity.id.toOSM(id) } };
68939                 }),
68940                 tag: map$4(this.tags, function(v, k) {
68941                     return { keyAttributes: { k: k, v: v } };
68942                 })
68943             }
68944         };
68945         if (changeset_id) {
68946             r.way['@changeset'] = changeset_id;
68947         }
68948         return r;
68949     },
68950
68951
68952     asGeoJSON: function(resolver) {
68953         return resolver.transient(this, 'GeoJSON', function() {
68954             var coordinates = map$4(resolver.childNodes(this), 'loc');
68955             if (this.isArea() && this.isClosed()) {
68956                 return {
68957                     type: 'Polygon',
68958                     coordinates: [coordinates]
68959                 };
68960             } else {
68961                 return {
68962                     type: 'LineString',
68963                     coordinates: coordinates
68964                 };
68965             }
68966         });
68967     },
68968
68969
68970     area: function(resolver) {
68971         return resolver.transient(this, 'area', function() {
68972             var nodes = resolver.childNodes(this);
68973
68974             var json = {
68975                 type: 'Polygon',
68976                 coordinates: [map$4(nodes, 'loc')]
68977             };
68978
68979             if (!this.isClosed() && nodes.length) {
68980                 json.coordinates[0].push(nodes[0].loc);
68981             }
68982
68983             var area = d3_geoArea(json);
68984
68985             // Heuristic for detecting counterclockwise winding order. Assumes
68986             // that OpenStreetMap polygons are not hemisphere-spanning.
68987             if (area > 2 * Math.PI) {
68988                 json.coordinates[0] = json.coordinates[0].reverse();
68989                 area = d3_geoArea(json);
68990             }
68991
68992             return isNaN(area) ? 0 : area;
68993         });
68994     }
68995 });
68996
68997
68998 // Filter function to eliminate consecutive duplicates.
68999 function noRepeatNodes(node, i, arr) {
69000     return i === 0 || node !== arr[i - 1];
69001 }
69002
69003 /* Built-in method references for those with the same name as other `lodash` methods. */
69004 var nativeMax$8 = Math.max;
69005
69006 /**
69007  * Gets the index at which the first occurrence of `value` is found in `array`
69008  * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
69009  * for equality comparisons. If `fromIndex` is negative, it's used as the
69010  * offset from the end of `array`.
69011  *
69012  * @static
69013  * @memberOf _
69014  * @since 0.1.0
69015  * @category Array
69016  * @param {Array} array The array to inspect.
69017  * @param {*} value The value to search for.
69018  * @param {number} [fromIndex=0] The index to search from.
69019  * @returns {number} Returns the index of the matched value, else `-1`.
69020  * @example
69021  *
69022  * _.indexOf([1, 2, 1, 2], 2);
69023  * // => 1
69024  *
69025  * // Search from the `fromIndex`.
69026  * _.indexOf([1, 2, 1, 2], 2, 2);
69027  * // => 3
69028  */
69029 function indexOf(array, value, fromIndex) {
69030   var length = array == null ? 0 : array.length;
69031   if (!length) {
69032     return -1;
69033   }
69034   var index = fromIndex == null ? 0 : toInteger(fromIndex);
69035   if (index < 0) {
69036     index = nativeMax$8(length + index, 0);
69037   }
69038   return baseIndexOf(array, value, index);
69039 }
69040
69041 function osmTurn(turn) {
69042     if (!(this instanceof osmTurn))
69043         return new osmTurn(turn);
69044     assignIn(this, turn);
69045 }
69046
69047
69048 function osmIntersection(graph, vertexId) {
69049     var vertex = graph.entity(vertexId),
69050         parentWays = graph.parentWays(vertex),
69051         coincident = [],
69052         highways = {};
69053
69054     function addHighway(way, adjacentNodeId) {
69055         if (highways[adjacentNodeId]) {
69056             coincident.push(adjacentNodeId);
69057         } else {
69058             highways[adjacentNodeId] = way;
69059         }
69060     }
69061
69062     // Pre-split ways that would need to be split in
69063     // order to add a restriction. The real split will
69064     // happen when the restriction is added.
69065     parentWays.forEach(function(way) {
69066         if (!way.tags.highway || way.isArea() || way.isDegenerate())
69067             return;
69068
69069         var isFirst = (vertexId === way.first()),
69070             isLast = (vertexId === way.last()),
69071             isAffix = (isFirst || isLast),
69072             isClosingNode = (isFirst && isLast);
69073
69074         if (isAffix && !isClosingNode) {
69075             var index = (isFirst ? 1 : way.nodes.length - 2);
69076             addHighway(way, way.nodes[index]);
69077
69078         } else {
69079             var splitIndex, wayA, wayB, indexA, indexB;
69080             if (isClosingNode) {
69081                 splitIndex = Math.ceil(way.nodes.length / 2);  // split at midpoint
69082                 wayA = osmWay({id: way.id + '-a', tags: way.tags, nodes: way.nodes.slice(0, splitIndex)});
69083                 wayB = osmWay({id: way.id + '-b', tags: way.tags, nodes: way.nodes.slice(splitIndex)});
69084                 indexA = 1;
69085                 indexB = way.nodes.length - 2;
69086             } else {
69087                 splitIndex = indexOf(way.nodes, vertex.id, 1);  // split at vertexid
69088                 wayA = osmWay({id: way.id + '-a', tags: way.tags, nodes: way.nodes.slice(0, splitIndex + 1)});
69089                 wayB = osmWay({id: way.id + '-b', tags: way.tags, nodes: way.nodes.slice(splitIndex)});
69090                 indexA = splitIndex - 1;
69091                 indexB = splitIndex + 1;
69092             }
69093             graph = graph.replace(wayA).replace(wayB);
69094             addHighway(wayA, way.nodes[indexA]);
69095             addHighway(wayB, way.nodes[indexB]);
69096         }
69097     });
69098
69099     // remove any ways from this intersection that are coincident
69100     // (i.e. any adjacent node used by more than one intersecting way)
69101     coincident.forEach(function (n) {
69102         delete highways[n];
69103     });
69104
69105
69106     var intersection = {
69107         highways: highways,
69108         ways: values$1(highways),
69109         graph: graph
69110     };
69111
69112
69113     intersection.adjacentNodeId = function(fromWayId) {
69114         return find$1(keys$1(highways), function(k) {
69115             return highways[k].id === fromWayId;
69116         });
69117     };
69118
69119
69120     intersection.turns = function(fromNodeId) {
69121         var start = highways[fromNodeId];
69122         if (!start)
69123             return [];
69124
69125         if (start.first() === vertex.id && start.tags.oneway === 'yes')
69126             return [];
69127         if (start.last() === vertex.id && start.tags.oneway === '-1')
69128             return [];
69129
69130         function withRestriction(turn) {
69131             graph.parentRelations(graph.entity(turn.from.way)).forEach(function(relation) {
69132                 if (relation.tags.type !== 'restriction')
69133                     return;
69134
69135                 var f = relation.memberByRole('from'),
69136                     t = relation.memberByRole('to'),
69137                     v = relation.memberByRole('via');
69138
69139                 if (f && f.id === turn.from.way &&
69140                     v && v.id === turn.via.node &&
69141                     t && t.id === turn.to.way) {
69142                     turn.restriction = relation.id;
69143                 } else if (/^only_/.test(relation.tags.restriction) &&
69144                     f && f.id === turn.from.way &&
69145                     v && v.id === turn.via.node &&
69146                     t && t.id !== turn.to.way) {
69147                     turn.restriction = relation.id;
69148                     turn.indirect_restriction = true;
69149                 }
69150             });
69151
69152             return osmTurn(turn);
69153         }
69154
69155
69156         var from = {
69157                 node: fromNodeId,
69158                 way: start.id.split(/-(a|b)/)[0]
69159             },
69160             via = { node: vertex.id },
69161             turns = [];
69162
69163         forEach(highways, function(end, adjacentNodeId) {
69164             if (end === start)
69165                 return;
69166
69167             // backward
69168             if (end.first() !== vertex.id && end.tags.oneway !== 'yes') {
69169                 turns.push(withRestriction({
69170                     from: from,
69171                     via: via,
69172                     to: {
69173                         node: adjacentNodeId,
69174                         way: end.id.split(/-(a|b)/)[0]
69175                     }
69176                 }));
69177             }
69178
69179             // forward
69180             if (end.last() !== vertex.id && end.tags.oneway !== '-1') {
69181                 turns.push(withRestriction({
69182                     from: from,
69183                     via: via,
69184                     to: {
69185                         node: adjacentNodeId,
69186                         way: end.id.split(/-(a|b)/)[0]
69187                     }
69188                 }));
69189             }
69190
69191         });
69192
69193         // U-turn
69194         if (start.tags.oneway !== 'yes' && start.tags.oneway !== '-1') {
69195             turns.push(withRestriction({
69196                 from: from,
69197                 via: via,
69198                 to: from,
69199                 u: true
69200             }));
69201         }
69202
69203         return turns;
69204     };
69205
69206     return intersection;
69207 }
69208
69209
69210 function osmInferRestriction(graph, from, via, to, projection) {
69211     var fromWay = graph.entity(from.way),
69212         fromNode = graph.entity(from.node),
69213         toWay = graph.entity(to.way),
69214         toNode = graph.entity(to.node),
69215         viaNode = graph.entity(via.node),
69216         fromOneWay = (fromWay.tags.oneway === 'yes' && fromWay.last() === via.node) ||
69217             (fromWay.tags.oneway === '-1' && fromWay.first() === via.node),
69218         toOneWay = (toWay.tags.oneway === 'yes' && toWay.first() === via.node) ||
69219             (toWay.tags.oneway === '-1' && toWay.last() === via.node),
69220         angle = geoAngle(viaNode, fromNode, projection) -
69221                 geoAngle(viaNode, toNode, projection);
69222
69223     angle = angle * 180 / Math.PI;
69224
69225     while (angle < 0)
69226         angle += 360;
69227
69228     if (fromNode === toNode)
69229         return 'no_u_turn';
69230     if ((angle < 23 || angle > 336) && fromOneWay && toOneWay)
69231         return 'no_u_turn';
69232     if (angle < 158)
69233         return 'no_right_turn';
69234     if (angle > 202)
69235         return 'no_left_turn';
69236
69237     return 'no_straight_on';
69238 }
69239
69240 function actionAddMember(relationId, member, memberIndex) {
69241     return function(graph) {
69242         var relation = graph.entity(relationId);
69243
69244         if (isNaN(memberIndex) && member.type === 'way') {
69245             var members = relation.indexedMembers();
69246             members.push(member);
69247
69248             var joined = osmJoinWays(members, graph);
69249             for (var i = 0; i < joined.length; i++) {
69250                 var segment = joined[i];
69251                 for (var j = 0; j < segment.length && segment.length >= 2; j++) {
69252                     if (segment[j] !== member)
69253                         continue;
69254
69255                     if (j === 0) {
69256                         memberIndex = segment[j + 1].index;
69257                     } else if (j === segment.length - 1) {
69258                         memberIndex = segment[j - 1].index + 1;
69259                     } else {
69260                         memberIndex = Math.min(segment[j - 1].index + 1, segment[j + 1].index + 1);
69261                     }
69262                 }
69263             }
69264         }
69265
69266         return graph.replace(relation.addMember(member, memberIndex));
69267     };
69268 }
69269
69270 function actionAddMidpoint(midpoint, node) {
69271     return function(graph) {
69272         graph = graph.replace(node.move(midpoint.loc));
69273
69274         var parents = intersection(
69275             graph.parentWays(graph.entity(midpoint.edge[0])),
69276             graph.parentWays(graph.entity(midpoint.edge[1])));
69277
69278         parents.forEach(function(way) {
69279             for (var i = 0; i < way.nodes.length - 1; i++) {
69280                 if (geoEdgeEqual([way.nodes[i], way.nodes[i + 1]], midpoint.edge)) {
69281                     graph = graph.replace(graph.entity(way.id).addNode(node.id, i + 1));
69282
69283                     // Add only one midpoint on doubled-back segments,
69284                     // turning them into self-intersections.
69285                     return;
69286                 }
69287             }
69288         });
69289
69290         return graph;
69291     };
69292 }
69293
69294 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/AddNodeToWayAction.as
69295 function actionAddVertex(wayId, nodeId, index) {
69296     return function(graph) {
69297         return graph.replace(graph.entity(wayId).addNode(nodeId, index));
69298     };
69299 }
69300
69301 function actionChangeMember(relationId, member, memberIndex) {
69302     return function(graph) {
69303         return graph.replace(graph.entity(relationId).updateMember(member, memberIndex));
69304     };
69305 }
69306
69307 function actionChangePreset(entityId, oldPreset, newPreset) {
69308     return function(graph) {
69309         var entity = graph.entity(entityId),
69310             geometry = entity.geometry(graph),
69311             tags = entity.tags;
69312
69313         if (oldPreset) tags = oldPreset.removeTags(tags, geometry);
69314         if (newPreset) tags = newPreset.applyTags(tags, geometry);
69315
69316         return graph.replace(entity.update({tags: tags}));
69317     };
69318 }
69319
69320 function actionChangeTags(entityId, tags) {
69321     return function(graph) {
69322         var entity = graph.entity(entityId);
69323         return graph.replace(entity.update({tags: tags}));
69324     };
69325 }
69326
69327 function actionCircularize(wayId, projection, maxAngle) {
69328     maxAngle = (maxAngle || 20) * Math.PI / 180;
69329
69330
69331     var action = function(graph, t) {
69332         if (t === null || !isFinite(t)) t = 1;
69333         t = Math.min(Math.max(+t, 0), 1);
69334
69335         var way = graph.entity(wayId),
69336             origNodes = {};
69337
69338         graph.childNodes(way).forEach(function(node) {
69339             if (!origNodes[node.id]) origNodes[node.id] = node;
69340         });
69341
69342         if (!way.isConvex(graph)) {
69343             graph = action.makeConvex(graph);
69344         }
69345
69346         var nodes = uniq(graph.childNodes(way)),
69347             keyNodes = nodes.filter(function(n) { return graph.parentWays(n).length !== 1; }),
69348             points = nodes.map(function(n) { return projection(n.loc); }),
69349             keyPoints = keyNodes.map(function(n) { return projection(n.loc); }),
69350             centroid = (points.length === 2) ? geoInterp(points[0], points[1], 0.5) : d3_polygonCentroid(points),
69351             radius = d3_median(points, function(p) { return geoEuclideanDistance(centroid, p); }),
69352             sign = d3_polygonArea(points) > 0 ? 1 : -1,
69353             ids;
69354
69355         // we need atleast two key nodes for the algorithm to work
69356         if (!keyNodes.length) {
69357             keyNodes = [nodes[0]];
69358             keyPoints = [points[0]];
69359         }
69360
69361         if (keyNodes.length === 1) {
69362             var index = nodes.indexOf(keyNodes[0]),
69363                 oppositeIndex = Math.floor((index + nodes.length / 2) % nodes.length);
69364
69365             keyNodes.push(nodes[oppositeIndex]);
69366             keyPoints.push(points[oppositeIndex]);
69367         }
69368
69369         // key points and nodes are those connected to the ways,
69370         // they are projected onto the circle, inbetween nodes are moved
69371         // to constant intervals between key nodes, extra inbetween nodes are
69372         // added if necessary.
69373         for (var i = 0; i < keyPoints.length; i++) {
69374             var nextKeyNodeIndex = (i + 1) % keyNodes.length,
69375                 startNode = keyNodes[i],
69376                 endNode = keyNodes[nextKeyNodeIndex],
69377                 startNodeIndex = nodes.indexOf(startNode),
69378                 endNodeIndex = nodes.indexOf(endNode),
69379                 numberNewPoints = -1,
69380                 indexRange = endNodeIndex - startNodeIndex,
69381                 nearNodes = {},
69382                 inBetweenNodes = [],
69383                 startAngle, endAngle, totalAngle, eachAngle,
69384                 angle, loc, node, origNode, j;
69385
69386             if (indexRange < 0) {
69387                 indexRange += nodes.length;
69388             }
69389
69390             // position this key node
69391             var distance = geoEuclideanDistance(centroid, keyPoints[i]);
69392             if (distance === 0) { distance = 1e-4; }
69393             keyPoints[i] = [
69394                 centroid[0] + (keyPoints[i][0] - centroid[0]) / distance * radius,
69395                 centroid[1] + (keyPoints[i][1] - centroid[1]) / distance * radius
69396             ];
69397             loc = projection.invert(keyPoints[i]);
69398             node = keyNodes[i];
69399             origNode = origNodes[node.id];
69400             node = node.move(geoInterp(origNode.loc, loc, t));
69401             graph = graph.replace(node);
69402
69403             // figure out the between delta angle we want to match to
69404             startAngle = Math.atan2(keyPoints[i][1] - centroid[1], keyPoints[i][0] - centroid[0]);
69405             endAngle = Math.atan2(keyPoints[nextKeyNodeIndex][1] - centroid[1], keyPoints[nextKeyNodeIndex][0] - centroid[0]);
69406             totalAngle = endAngle - startAngle;
69407
69408             // detects looping around -pi/pi
69409             if (totalAngle * sign > 0) {
69410                 totalAngle = -sign * (2 * Math.PI - Math.abs(totalAngle));
69411             }
69412
69413             do {
69414                 numberNewPoints++;
69415                 eachAngle = totalAngle / (indexRange + numberNewPoints);
69416             } while (Math.abs(eachAngle) > maxAngle);
69417
69418
69419             // move existing nodes
69420             for (j = 1; j < indexRange; j++) {
69421                 angle = startAngle + j * eachAngle;
69422                 loc = projection.invert([
69423                     centroid[0] + Math.cos(angle) * radius,
69424                     centroid[1] + Math.sin(angle) * radius
69425                 ]);
69426
69427                 node = nodes[(j + startNodeIndex) % nodes.length];
69428                 origNode = origNodes[node.id];
69429                 nearNodes[node.id] = angle;
69430
69431                 node = node.move(geoInterp(origNode.loc, loc, t));
69432                 graph = graph.replace(node);
69433             }
69434
69435             // add new inbetween nodes if necessary
69436             for (j = 0; j < numberNewPoints; j++) {
69437                 angle = startAngle + (indexRange + j) * eachAngle;
69438                 loc = projection.invert([
69439                     centroid[0] + Math.cos(angle) * radius,
69440                     centroid[1] + Math.sin(angle) * radius
69441                 ]);
69442
69443                 // choose a nearnode to use as the original
69444                 var min = Infinity;
69445                 for (var nodeId in nearNodes) {
69446                     var nearAngle = nearNodes[nodeId],
69447                         dist = Math.abs(nearAngle - angle);
69448                     if (dist < min) {
69449                         dist = min;
69450                         origNode = origNodes[nodeId];
69451                     }
69452                 }
69453
69454                 node = osmNode({ loc: geoInterp(origNode.loc, loc, t) });
69455                 graph = graph.replace(node);
69456
69457                 nodes.splice(endNodeIndex + j, 0, node);
69458                 inBetweenNodes.push(node.id);
69459             }
69460
69461             // Check for other ways that share these keyNodes..
69462             // If keyNodes are adjacent in both ways,
69463             // we can add inBetween nodes to that shared way too..
69464             if (indexRange === 1 && inBetweenNodes.length) {
69465                 var startIndex1 = way.nodes.lastIndexOf(startNode.id),
69466                     endIndex1 = way.nodes.lastIndexOf(endNode.id),
69467                     wayDirection1 = (endIndex1 - startIndex1);
69468                 if (wayDirection1 < -1) { wayDirection1 = 1; }
69469
69470                 /* eslint-disable no-loop-func */
69471                 forEach(without(graph.parentWays(keyNodes[i]), way), function(sharedWay) {
69472                     if (sharedWay.areAdjacent(startNode.id, endNode.id)) {
69473                         var startIndex2 = sharedWay.nodes.lastIndexOf(startNode.id),
69474                             endIndex2 = sharedWay.nodes.lastIndexOf(endNode.id),
69475                             wayDirection2 = (endIndex2 - startIndex2),
69476                             insertAt = endIndex2;
69477                         if (wayDirection2 < -1) { wayDirection2 = 1; }
69478
69479                         if (wayDirection1 !== wayDirection2) {
69480                             inBetweenNodes.reverse();
69481                             insertAt = startIndex2;
69482                         }
69483                         for (j = 0; j < inBetweenNodes.length; j++) {
69484                             sharedWay = sharedWay.addNode(inBetweenNodes[j], insertAt + j);
69485                         }
69486                         graph = graph.replace(sharedWay);
69487                     }
69488                 });
69489                 /* eslint-enable no-loop-func */
69490             }
69491
69492         }
69493
69494         // update the way to have all the new nodes
69495         ids = nodes.map(function(n) { return n.id; });
69496         ids.push(ids[0]);
69497
69498         way = way.update({nodes: ids});
69499         graph = graph.replace(way);
69500
69501         return graph;
69502     };
69503
69504
69505     action.makeConvex = function(graph) {
69506         var way = graph.entity(wayId),
69507             nodes = uniq(graph.childNodes(way)),
69508             points = nodes.map(function(n) { return projection(n.loc); }),
69509             sign = d3_polygonArea(points) > 0 ? 1 : -1,
69510             hull = d3_polygonHull(points);
69511
69512         // D3 convex hulls go counterclockwise..
69513         if (sign === -1) {
69514             nodes.reverse();
69515             points.reverse();
69516         }
69517
69518         for (var i = 0; i < hull.length - 1; i++) {
69519             var startIndex = points.indexOf(hull[i]),
69520                 endIndex = points.indexOf(hull[i+1]),
69521                 indexRange = (endIndex - startIndex);
69522
69523             if (indexRange < 0) {
69524                 indexRange += nodes.length;
69525             }
69526
69527             // move interior nodes to the surface of the convex hull..
69528             for (var j = 1; j < indexRange; j++) {
69529                 var point = geoInterp(hull[i], hull[i+1], j / indexRange),
69530                     node = nodes[(j + startIndex) % nodes.length].move(projection.invert(point));
69531                 graph = graph.replace(node);
69532             }
69533         }
69534         return graph;
69535     };
69536
69537
69538     action.disabled = function(graph) {
69539         if (!graph.entity(wayId).isClosed())
69540             return 'not_closed';
69541     };
69542
69543
69544     action.transitionable = true;
69545
69546
69547     return action;
69548 }
69549
69550 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteWayAction.as
69551 function actionDeleteWay(wayId) {
69552
69553
69554     function canDeleteNode(node, graph) {
69555         return !graph.parentWays(node).length &&
69556             !graph.parentRelations(node).length &&
69557             !node.hasInterestingTags();
69558     }
69559
69560
69561     var action = function(graph) {
69562         var way = graph.entity(wayId);
69563
69564         graph.parentRelations(way)
69565             .forEach(function(parent) {
69566                 parent = parent.removeMembersWithID(wayId);
69567                 graph = graph.replace(parent);
69568
69569                 if (parent.isDegenerate()) {
69570                     graph = actionDeleteRelation(parent.id)(graph);
69571                 }
69572             });
69573
69574         uniq(way.nodes).forEach(function(nodeId) {
69575             graph = graph.replace(way.removeNode(nodeId));
69576
69577             var node = graph.entity(nodeId);
69578             if (canDeleteNode(node, graph)) {
69579                 graph = graph.remove(node);
69580             }
69581         });
69582
69583         return graph.remove(way);
69584     };
69585
69586
69587     return action;
69588 }
69589
69590 function actionDeleteMultiple(ids) {
69591     var actions = {
69592         way: actionDeleteWay,
69593         node: actionDeleteNode,
69594         relation: actionDeleteRelation
69595     };
69596
69597
69598     var action = function(graph) {
69599         ids.forEach(function(id) {
69600             if (graph.hasEntity(id)) { // It may have been deleted aready.
69601                 graph = actions[graph.entity(id).type](id)(graph);
69602             }
69603         });
69604
69605         return graph;
69606     };
69607
69608
69609     return action;
69610 }
69611
69612 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteRelationAction.as
69613 function actionDeleteRelation(relationId) {
69614
69615
69616     function canDeleteEntity(entity, graph) {
69617         return !graph.parentWays(entity).length &&
69618             !graph.parentRelations(entity).length &&
69619             !entity.hasInterestingTags();
69620     }
69621
69622
69623     var action = function(graph) {
69624         var relation = graph.entity(relationId);
69625
69626         graph.parentRelations(relation)
69627             .forEach(function(parent) {
69628                 parent = parent.removeMembersWithID(relationId);
69629                 graph = graph.replace(parent);
69630
69631                 if (parent.isDegenerate()) {
69632                     graph = actionDeleteRelation(parent.id)(graph);
69633                 }
69634             });
69635
69636         uniq(map$4(relation.members, 'id')).forEach(function(memberId) {
69637             graph = graph.replace(relation.removeMembersWithID(memberId));
69638
69639             var entity = graph.entity(memberId);
69640             if (canDeleteEntity(entity, graph)) {
69641                 graph = actionDeleteMultiple([memberId])(graph);
69642             }
69643         });
69644
69645         return graph.remove(relation);
69646     };
69647
69648
69649     return action;
69650 }
69651
69652 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteNodeAction.as
69653 function actionDeleteNode(nodeId) {
69654     var action = function(graph) {
69655         var node = graph.entity(nodeId);
69656
69657         graph.parentWays(node)
69658             .forEach(function(parent) {
69659                 parent = parent.removeNode(nodeId);
69660                 graph = graph.replace(parent);
69661
69662                 if (parent.isDegenerate()) {
69663                     graph = actionDeleteWay(parent.id)(graph);
69664                 }
69665             });
69666
69667         graph.parentRelations(node)
69668             .forEach(function(parent) {
69669                 parent = parent.removeMembersWithID(nodeId);
69670                 graph = graph.replace(parent);
69671
69672                 if (parent.isDegenerate()) {
69673                     graph = actionDeleteRelation(parent.id)(graph);
69674                 }
69675             });
69676
69677         return graph.remove(node);
69678     };
69679
69680
69681     return action;
69682 }
69683
69684 // Connect the ways at the given nodes.
69685 //
69686 // The last node will survive. All other nodes will be replaced with
69687 // the surviving node in parent ways, and then removed.
69688 //
69689 // Tags and relation memberships of of non-surviving nodes are merged
69690 // to the survivor.
69691 //
69692 // This is the inverse of `iD.actionDisconnect`.
69693 //
69694 // Reference:
69695 //   https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeNodesAction.as
69696 //   https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/MergeNodesAction.java
69697 //
69698 function actionConnect(nodeIds) {
69699     return function(graph) {
69700         var last = nodeIds[nodeIds.length - 1];
69701         var survivor = graph.entity(last);
69702
69703         for (var i = 0; i < nodeIds.length - 1; i++) {
69704             var node = graph.entity(nodeIds[i]);
69705
69706             /* eslint-disable no-loop-func */
69707             graph.parentWays(node).forEach(function(parent) {
69708                 if (!parent.areAdjacent(node.id, survivor.id)) {
69709                     graph = graph.replace(parent.replaceNode(node.id, survivor.id));
69710                 }
69711             });
69712
69713             graph.parentRelations(node).forEach(function(parent) {
69714                 graph = graph.replace(parent.replaceMember(node, survivor));
69715             });
69716             /* eslint-enable no-loop-func */
69717
69718             survivor = survivor.mergeTags(node.tags);
69719             graph = actionDeleteNode(node.id)(graph);
69720         }
69721
69722         graph = graph.replace(survivor);
69723
69724         return graph;
69725     };
69726 }
69727
69728 function actionCopyEntities(ids, fromGraph) {
69729     var copies = {};
69730
69731
69732     var action = function(graph) {
69733         ids.forEach(function(id) {
69734             fromGraph.entity(id).copy(fromGraph, copies);
69735         });
69736
69737         for (var id in copies) {
69738             graph = graph.replace(copies[id]);
69739         }
69740
69741         return graph;
69742     };
69743
69744
69745     action.copies = function() {
69746         return copies;
69747     };
69748
69749
69750     return action;
69751 }
69752
69753 function actionDeleteMember(relationId, memberIndex) {
69754     return function(graph) {
69755         var relation = graph.entity(relationId)
69756             .removeMember(memberIndex);
69757
69758         graph = graph.replace(relation);
69759
69760         if (relation.isDegenerate())
69761             graph = actionDeleteRelation(relation.id)(graph);
69762
69763         return graph;
69764     };
69765 }
69766
69767 function actionDeprecateTags(entityId) {
69768
69769     return function(graph) {
69770         var entity = graph.entity(entityId),
69771             newtags = clone(entity.tags),
69772             change = false,
69773             rule;
69774
69775         // This handles dataDeprecated tags with a single condition
69776         for (var i = 0; i < dataDeprecated.length; i++) {
69777
69778             rule = dataDeprecated[i];
69779             var match = toPairs(rule.old)[0],
69780                 replacements = rule.replace ? toPairs(rule.replace) : null;
69781
69782             if (entity.tags[match[0]] && match[1] === '*') {
69783
69784                 var value = entity.tags[match[0]];
69785                 if (replacements && !newtags[replacements[0][0]]) {
69786                     newtags[replacements[0][0]] = value;
69787                 }
69788                 delete newtags[match[0]];
69789                 change = true;
69790
69791             } else if (entity.tags[match[0]] === match[1]) {
69792                 newtags = assign({}, rule.replace || {}, omit(newtags, match[0]));
69793                 change = true;
69794             }
69795         }
69796
69797         if (change) {
69798             return graph.replace(entity.update({tags: newtags}));
69799         } else {
69800             return graph;
69801         }
69802     };
69803 }
69804
69805 function actionDiscardTags(difference) {
69806
69807     return function(graph) {
69808         function discardTags(entity) {
69809             if (!isEmpty(entity.tags)) {
69810                 var tags = {};
69811                 forEach(entity.tags, function(v, k) {
69812                     if (v) tags[k] = v;
69813                 });
69814
69815                 graph = graph.replace(entity.update({
69816                     tags: omit(tags, dataDiscarded)
69817                 }));
69818             }
69819         }
69820
69821         difference.modified().forEach(discardTags);
69822         difference.created().forEach(discardTags);
69823
69824         return graph;
69825     };
69826 }
69827
69828 // Disconect the ways at the given node.
69829 //
69830 // Optionally, disconnect only the given ways.
69831 //
69832 // For testing convenience, accepts an ID to assign to the (first) new node.
69833 // Normally, this will be undefined and the way will automatically
69834 // be assigned a new ID.
69835 //
69836 // This is the inverse of `iD.actionConnect`.
69837 //
69838 // Reference:
69839 //   https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/UnjoinNodeAction.as
69840 //   https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/UnGlueAction.java
69841 //
69842 function actionDisconnect(nodeId, newNodeId) {
69843     var wayIds;
69844
69845
69846     var action = function(graph) {
69847         var node = graph.entity(nodeId),
69848             connections = action.connections(graph);
69849
69850         connections.forEach(function(connection) {
69851             var way = graph.entity(connection.wayID),
69852                 newNode = osmNode({id: newNodeId, loc: node.loc, tags: node.tags});
69853
69854             graph = graph.replace(newNode);
69855             if (connection.index === 0 && way.isArea()) {
69856                 // replace shared node with shared node..
69857                 graph = graph.replace(way.replaceNode(way.nodes[0], newNode.id));
69858             } else if (way.isClosed() && connection.index === way.nodes.length - 1) {
69859                 // replace closing node with new new node..
69860                 graph = graph.replace(way.unclose().addNode(newNode.id));
69861             } else {
69862                 // replace shared node with multiple new nodes..
69863                 graph = graph.replace(way.updateNode(newNode.id, connection.index));
69864             }
69865         });
69866
69867         return graph;
69868     };
69869
69870
69871     action.connections = function(graph) {
69872         var candidates = [],
69873             keeping = false,
69874             parentWays = graph.parentWays(graph.entity(nodeId));
69875
69876         parentWays.forEach(function(way) {
69877             if (wayIds && wayIds.indexOf(way.id) === -1) {
69878                 keeping = true;
69879                 return;
69880             }
69881             if (way.isArea() && (way.nodes[0] === nodeId)) {
69882                 candidates.push({ wayID: way.id, index: 0 });
69883             } else {
69884                 way.nodes.forEach(function(waynode, index) {
69885                     if (waynode === nodeId) {
69886                         candidates.push({ wayID: way.id, index: index });
69887                     }
69888                 });
69889             }
69890         });
69891
69892         return keeping ? candidates : candidates.slice(1);
69893     };
69894
69895
69896     action.disabled = function(graph) {
69897         var connections = action.connections(graph);
69898         if (connections.length === 0 || (wayIds && wayIds.length !== connections.length))
69899             return 'not_connected';
69900
69901         var parentWays = graph.parentWays(graph.entity(nodeId)),
69902             seenRelationIds = {},
69903             sharedRelation;
69904
69905         parentWays.forEach(function(way) {
69906             if (wayIds && wayIds.indexOf(way.id) === -1)
69907                 return;
69908
69909             var relations = graph.parentRelations(way);
69910             relations.forEach(function(relation) {
69911                 if (relation.id in seenRelationIds) {
69912                     sharedRelation = relation;
69913                 } else {
69914                     seenRelationIds[relation.id] = true;
69915                 }
69916             });
69917         });
69918
69919         if (sharedRelation)
69920             return 'relation';
69921     };
69922
69923
69924     action.limitWays = function(_) {
69925         if (!arguments.length) return wayIds;
69926         wayIds = _;
69927         return action;
69928     };
69929
69930
69931     return action;
69932 }
69933
69934 // Join ways at the end node they share.
69935 //
69936 // This is the inverse of `iD.actionSplit`.
69937 //
69938 // Reference:
69939 //   https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MergeWaysAction.as
69940 //   https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/actions/CombineWayAction.java
69941 //
69942 function actionJoin(ids) {
69943
69944     function groupEntitiesByGeometry(graph) {
69945         var entities = ids.map(function(id) { return graph.entity(id); });
69946         return assignIn({line: []}, groupBy(entities, function(entity) { return entity.geometry(graph); }));
69947     }
69948
69949
69950     var action = function(graph) {
69951         var ways = ids.map(graph.entity, graph),
69952             survivor = ways[0];
69953
69954         // Prefer to keep an existing way.
69955         for (var i = 0; i < ways.length; i++) {
69956             if (!ways[i].isNew()) {
69957                 survivor = ways[i];
69958                 break;
69959             }
69960         }
69961
69962         var joined = osmJoinWays(ways, graph)[0];
69963
69964         survivor = survivor.update({nodes: map$4(joined.nodes, 'id')});
69965         graph = graph.replace(survivor);
69966
69967         joined.forEach(function(way) {
69968             if (way.id === survivor.id)
69969                 return;
69970
69971             graph.parentRelations(way).forEach(function(parent) {
69972                 graph = graph.replace(parent.replaceMember(way, survivor));
69973             });
69974
69975             survivor = survivor.mergeTags(way.tags);
69976
69977             graph = graph.replace(survivor);
69978             graph = actionDeleteWay(way.id)(graph);
69979         });
69980
69981         return graph;
69982     };
69983
69984
69985     action.disabled = function(graph) {
69986         var geometries = groupEntitiesByGeometry(graph);
69987         if (ids.length < 2 || ids.length !== geometries.line.length)
69988             return 'not_eligible';
69989
69990         var joined = osmJoinWays(ids.map(graph.entity, graph), graph);
69991         if (joined.length > 1)
69992             return 'not_adjacent';
69993
69994         var nodeIds = map$4(joined[0].nodes, 'id').slice(1, -1),
69995             relation,
69996             tags = {},
69997             conflicting = false;
69998
69999         joined[0].forEach(function(way) {
70000             var parents = graph.parentRelations(way);
70001             parents.forEach(function(parent) {
70002                 if (parent.isRestriction() && parent.members.some(function(m) { return nodeIds.indexOf(m.id) >= 0; }))
70003                     relation = parent;
70004             });
70005
70006             for (var k in way.tags) {
70007                 if (!(k in tags)) {
70008                     tags[k] = way.tags[k];
70009                 } else if (tags[k] && osmIsInterestingTag(k) && tags[k] !== way.tags[k]) {
70010                     conflicting = true;
70011                 }
70012             }
70013         });
70014
70015         if (relation)
70016             return 'restriction';
70017
70018         if (conflicting)
70019             return 'conflicting_tags';
70020     };
70021
70022
70023     return action;
70024 }
70025
70026 function actionMerge(ids) {
70027
70028     function groupEntitiesByGeometry(graph) {
70029         var entities = ids.map(function(id) { return graph.entity(id); });
70030         return assignIn({point: [], area: [], line: [], relation: []},
70031             groupBy(entities, function(entity) { return entity.geometry(graph); }));
70032     }
70033
70034
70035     var action = function(graph) {
70036         var geometries = groupEntitiesByGeometry(graph),
70037             target = geometries.area[0] || geometries.line[0],
70038             points = geometries.point;
70039
70040         points.forEach(function(point) {
70041             target = target.mergeTags(point.tags);
70042             graph = graph.replace(target);
70043
70044             graph.parentRelations(point).forEach(function(parent) {
70045                 graph = graph.replace(parent.replaceMember(point, target));
70046             });
70047
70048             var nodes = uniq(graph.childNodes(target)),
70049                 removeNode = point;
70050
70051             for (var i = 0; i < nodes.length; i++) {
70052                 var node = nodes[i];
70053                 if (graph.parentWays(node).length > 1 ||
70054                     graph.parentRelations(node).length ||
70055                     node.hasInterestingTags()) {
70056                     continue;
70057                 }
70058
70059                 // Found an uninteresting child node on the target way.
70060                 // Move orig point into its place to preserve point's history. #3683
70061                 graph = graph.replace(point.update({ tags: {}, loc: node.loc }));
70062                 target = target.replaceNode(node.id, point.id);
70063                 graph = graph.replace(target);
70064                 removeNode = node;
70065                 break;
70066             }
70067
70068             graph = graph.remove(removeNode);
70069         });
70070
70071         return graph;
70072     };
70073
70074
70075     action.disabled = function(graph) {
70076         var geometries = groupEntitiesByGeometry(graph);
70077         if (geometries.point.length === 0 ||
70078             (geometries.area.length + geometries.line.length) !== 1 ||
70079             geometries.relation.length !== 0)
70080             return 'not_eligible';
70081     };
70082
70083
70084     return action;
70085 }
70086
70087 function actionMergePolygon(ids, newRelationId) {
70088
70089     function groupEntities(graph) {
70090         var entities = ids.map(function (id) { return graph.entity(id); });
70091         return assignIn({
70092                 closedWay: [],
70093                 multipolygon: [],
70094                 other: []
70095             }, groupBy(entities, function(entity) {
70096                 if (entity.type === 'way' && entity.isClosed()) {
70097                     return 'closedWay';
70098                 } else if (entity.type === 'relation' && entity.isMultipolygon()) {
70099                     return 'multipolygon';
70100                 } else {
70101                     return 'other';
70102                 }
70103             }));
70104     }
70105
70106
70107     var action = function(graph) {
70108         var entities = groupEntities(graph);
70109
70110         // An array representing all the polygons that are part of the multipolygon.
70111         //
70112         // Each element is itself an array of objects with an id property, and has a
70113         // locs property which is an array of the locations forming the polygon.
70114         var polygons = entities.multipolygon.reduce(function(polygons, m) {
70115             return polygons.concat(osmJoinWays(m.members, graph));
70116         }, []).concat(entities.closedWay.map(function(d) {
70117             var member = [{id: d.id}];
70118             member.nodes = graph.childNodes(d);
70119             return member;
70120         }));
70121
70122         // contained is an array of arrays of boolean values,
70123         // where contained[j][k] is true iff the jth way is
70124         // contained by the kth way.
70125         var contained = polygons.map(function(w, i) {
70126             return polygons.map(function(d, n) {
70127                 if (i === n) return null;
70128                 return geoPolygonContainsPolygon(
70129                     map$4(d.nodes, 'loc'),
70130                     map$4(w.nodes, 'loc'));
70131             });
70132         });
70133
70134         // Sort all polygons as either outer or inner ways
70135         var members = [],
70136             outer = true;
70137
70138         while (polygons.length) {
70139             extractUncontained(polygons);
70140             polygons = polygons.filter(isContained);
70141             contained = contained.filter(isContained).map(filterContained);
70142         }
70143
70144         function isContained(d, i) {
70145             return some(contained[i]);
70146         }
70147
70148         function filterContained(d) {
70149             return d.filter(isContained);
70150         }
70151
70152         function extractUncontained(polygons) {
70153             polygons.forEach(function(d, i) {
70154                 if (!isContained(d, i)) {
70155                     d.forEach(function(member) {
70156                         members.push({
70157                             type: 'way',
70158                             id: member.id,
70159                             role: outer ? 'outer' : 'inner'
70160                         });
70161                     });
70162                 }
70163             });
70164             outer = !outer;
70165         }
70166
70167         // Move all tags to one relation
70168         var relation = entities.multipolygon[0] ||
70169             osmRelation({ id: newRelationId, tags: { type: 'multipolygon' }});
70170
70171         entities.multipolygon.slice(1).forEach(function(m) {
70172             relation = relation.mergeTags(m.tags);
70173             graph = graph.remove(m);
70174         });
70175
70176         entities.closedWay.forEach(function(way) {
70177             function isThisOuter(m) {
70178                 return m.id === way.id && m.role !== 'inner';
70179             }
70180             if (members.some(isThisOuter)) {
70181                 relation = relation.mergeTags(way.tags);
70182                 graph = graph.replace(way.update({ tags: {} }));
70183             }
70184         });
70185
70186         return graph.replace(relation.update({
70187             members: members,
70188             tags: omit(relation.tags, 'area')
70189         }));
70190     };
70191
70192
70193     action.disabled = function(graph) {
70194         var entities = groupEntities(graph);
70195         if (entities.other.length > 0 ||
70196             entities.closedWay.length + entities.multipolygon.length < 2)
70197             return 'not_eligible';
70198         if (!entities.multipolygon.every(function(r) { return r.isComplete(graph); }))
70199             return 'incomplete_relation';
70200     };
70201
70202
70203     return action;
70204 }
70205
70206 // Text diff algorithm following Hunt and McIlroy 1976.
70207 // J. W. Hunt and M. D. McIlroy, An algorithm for differential file
70208 // comparison, Bell Telephone Laboratories CSTR #41 (1976)
70209 // http://www.cs.dartmouth.edu/~doug/
70210 //
70211 // Expects two arrays of strings.
70212 function LCS(file1, file2) {
70213   var equivalenceClasses;
70214   var file2indices;
70215   var newCandidate;
70216   var candidates;
70217   var line;
70218   var c, i, j, jX, r, s;
70219
70220   equivalenceClasses = {};
70221   for (j = 0; j < file2.length; j++) {
70222     line = file2[j];
70223     if (equivalenceClasses[line]) {
70224       equivalenceClasses[line].push(j);
70225     } else {
70226       equivalenceClasses[line] = [j];
70227     }
70228   }
70229
70230   candidates = [
70231     { file1index: -1, file2index: -1, chain: null }
70232   ];
70233
70234   for (i = 0; i < file1.length; i++) {
70235     line = file1[i];
70236     file2indices = equivalenceClasses[line] || [];
70237
70238     r = 0;
70239     c = candidates[0];
70240
70241     for (jX = 0; jX < file2indices.length; jX++) {
70242       j = file2indices[jX];
70243
70244       for (s = r; s < candidates.length; s++) {
70245         if ((candidates[s].file2index < j) && ((s === candidates.length - 1) || (candidates[s + 1].file2index > j))) {
70246           break;
70247         }
70248       }
70249
70250       if (s < candidates.length) {
70251         newCandidate = { file1index: i, file2index: j, chain: candidates[s] };
70252         if (r === candidates.length) {
70253           candidates.push(c);
70254         } else {
70255           candidates[r] = c;
70256         }
70257         r = s + 1;
70258         c = newCandidate;
70259         if (r === candidates.length) {
70260           break; // no point in examining further (j)s
70261         }
70262       }
70263     }
70264
70265     candidates[r] = c;
70266   }
70267
70268   // At this point, we know the LCS: it's in the reverse of the
70269   // linked-list through .chain of candidates[candidates.length - 1].
70270
70271   return candidates[candidates.length - 1];
70272 }
70273
70274
70275 // We apply the LCS to give a simple representation of the
70276 // offsets and lengths of mismatched chunks in the input
70277 // files. This is used by diff3MergeIndices below.
70278 function diffIndices(file1, file2) {
70279   var result = [];
70280   var tail1 = file1.length;
70281   var tail2 = file2.length;
70282
70283   for (var candidate = LCS(file1, file2);
70284      candidate !== null;
70285      candidate = candidate.chain)
70286   {
70287     var mismatchLength1 = tail1 - candidate.file1index - 1;
70288     var mismatchLength2 = tail2 - candidate.file2index - 1;
70289     tail1 = candidate.file1index;
70290     tail2 = candidate.file2index;
70291
70292     if (mismatchLength1 || mismatchLength2) {
70293       result.push({
70294         file1: [tail1 + 1, mismatchLength1],
70295         file2: [tail2 + 1, mismatchLength2]
70296       });
70297     }
70298   }
70299
70300   result.reverse();
70301   return result;
70302 }
70303
70304
70305 // Given three files, A, O, and B, where both A and B are
70306 // independently derived from O, returns a fairly complicated
70307 // internal representation of merge decisions it's taken. The
70308 // interested reader may wish to consult
70309 //
70310 // Sanjeev Khanna, Keshav Kunal, and Benjamin C. Pierce.
70311 // 'A Formal Investigation of ' In Arvind and Prasad,
70312 // editors, Foundations of Software Technology and Theoretical
70313 // Computer Science (FSTTCS), December 2007.
70314 //
70315 // (http://www.cis.upenn.edu/~bcpierce/papers/diff3-short.pdf)
70316 function diff3MergeIndices(a, o, b) {
70317   var i;
70318   var m1 = diffIndices(o, a);
70319   var m2 = diffIndices(o, b);
70320
70321   var hunks = [];
70322   function addHunk(h, side) {
70323     hunks.push([h.file1[0], side, h.file1[1], h.file2[0], h.file2[1]]);
70324   }
70325   for (i = 0; i < m1.length; i++) { addHunk(m1[i], 0); }
70326   for (i = 0; i < m2.length; i++) { addHunk(m2[i], 2); }
70327   hunks.sort(function (x, y) { return x[0] - y[0]; });
70328
70329   var result = [];
70330   var commonOffset = 0;
70331   function copyCommon(targetOffset) {
70332     if (targetOffset > commonOffset) {
70333       result.push([1, commonOffset, targetOffset - commonOffset]);
70334       commonOffset = targetOffset;
70335     }
70336   }
70337
70338   for (var hunkIndex = 0; hunkIndex < hunks.length; hunkIndex++) {
70339     var firstHunkIndex = hunkIndex;
70340     var hunk = hunks[hunkIndex];
70341     var regionLhs = hunk[0];
70342     var regionRhs = regionLhs + hunk[2];
70343     while (hunkIndex < hunks.length - 1) {
70344       var maybeOverlapping = hunks[hunkIndex + 1];
70345       var maybeLhs = maybeOverlapping[0];
70346       if (maybeLhs > regionRhs) {
70347         break;
70348       }
70349       regionRhs = Math.max(regionRhs, maybeLhs + maybeOverlapping[2]);
70350       hunkIndex++;
70351     }
70352
70353     copyCommon(regionLhs);
70354     if (firstHunkIndex === hunkIndex) {
70355       // The 'overlap' was only one hunk long, meaning that
70356       // there's no conflict here. Either a and o were the
70357       // same, or b and o were the same.
70358       if (hunk[4] > 0) {
70359         result.push([hunk[1], hunk[3], hunk[4]]);
70360       }
70361     } else {
70362       // A proper conflict. Determine the extents of the
70363       // regions involved from a, o and b. Effectively merge
70364       // all the hunks on the left into one giant hunk, and
70365       // do the same for the right; then, correct for skew
70366       // in the regions of o that each side changed, and
70367       // report appropriate spans for the three sides.
70368       var regions = {
70369         0: [a.length, -1, o.length, -1],
70370         2: [b.length, -1, o.length, -1]
70371       };
70372       for (i = firstHunkIndex; i <= hunkIndex; i++) {
70373         hunk = hunks[i];
70374         var side = hunk[1];
70375         var r = regions[side];
70376         var oLhs = hunk[0];
70377         var oRhs = oLhs + hunk[2];
70378         var abLhs = hunk[3];
70379         var abRhs = abLhs + hunk[4];
70380         r[0] = Math.min(abLhs, r[0]);
70381         r[1] = Math.max(abRhs, r[1]);
70382         r[2] = Math.min(oLhs, r[2]);
70383         r[3] = Math.max(oRhs, r[3]);
70384       }
70385       var aLhs = regions[0][0] + (regionLhs - regions[0][2]);
70386       var aRhs = regions[0][1] + (regionRhs - regions[0][3]);
70387       var bLhs = regions[2][0] + (regionLhs - regions[2][2]);
70388       var bRhs = regions[2][1] + (regionRhs - regions[2][3]);
70389       result.push([-1,
70390                    aLhs,      aRhs      - aLhs,
70391                    regionLhs, regionRhs - regionLhs,
70392                    bLhs,      bRhs      - bLhs]);
70393     }
70394     commonOffset = regionRhs;
70395   }
70396
70397   copyCommon(o.length);
70398   return result;
70399 }
70400
70401
70402 // Applies the output of diff3MergeIndices to actually
70403 // construct the merged file; the returned result alternates
70404 // between 'ok' and 'conflict' blocks.
70405 function diff3Merge(a, o, b, excludeFalseConflicts) {
70406   var result = [];
70407   var files = [a, o, b];
70408   var indices = diff3MergeIndices(a, o, b);
70409
70410   var okLines = [];
70411   function flushOk() {
70412     if (okLines.length) {
70413       result.push({ok: okLines});
70414     }
70415     okLines = [];
70416   }
70417   function pushOk(xs) {
70418     for (var j = 0; j < xs.length; j++) {
70419       okLines.push(xs[j]);
70420     }
70421   }
70422
70423   function isTrueConflict(rec) {
70424     if (rec[2] !== rec[6]) return true;
70425     var aoff = rec[1];
70426     var boff = rec[5];
70427     for (var j = 0; j < rec[2]; j++) {
70428       if (a[j + aoff] !== b[j + boff]) {
70429         return true;
70430       }
70431     }
70432     return false;
70433   }
70434
70435   for (var i = 0; i < indices.length; i++) {
70436     var x = indices[i];
70437     var side = x[0];
70438     if (side === -1) {
70439       if (excludeFalseConflicts && !isTrueConflict(x)) {
70440         pushOk(files[0].slice(x[1], x[1] + x[2]));
70441       } else {
70442         flushOk();
70443         result.push({
70444           conflict: {
70445             a: a.slice(x[1], x[1] + x[2]),
70446             aIndex: x[1],
70447             o: o.slice(x[3], x[3] + x[4]),
70448             oIndex: x[3],
70449             b: b.slice(x[5], x[5] + x[6]),
70450             bIndex: x[5]
70451           }
70452         });
70453       }
70454     } else {
70455       pushOk(files[side].slice(x[1], x[1] + x[2]));
70456     }
70457   }
70458
70459   flushOk();
70460   return result;
70461 }
70462
70463 function actionMergeRemoteChanges(id, localGraph, remoteGraph, formatUser) {
70464     var option = 'safe',  // 'safe', 'force_local', 'force_remote'
70465         conflicts = [];
70466
70467
70468     function user(d) {
70469         return isFunction(formatUser) ? formatUser(d) : d;
70470     }
70471
70472
70473     function mergeLocation(remote, target) {
70474         function pointEqual(a, b) {
70475             var epsilon = 1e-6;
70476             return (Math.abs(a[0] - b[0]) < epsilon) && (Math.abs(a[1] - b[1]) < epsilon);
70477         }
70478
70479         if (option === 'force_local' || pointEqual(target.loc, remote.loc)) {
70480             return target;
70481         }
70482         if (option === 'force_remote') {
70483             return target.update({loc: remote.loc});
70484         }
70485
70486         conflicts.push(t('merge_remote_changes.conflict.location', { user: user(remote.user) }));
70487         return target;
70488     }
70489
70490
70491     function mergeNodes(base, remote, target) {
70492         if (option === 'force_local' || isEqual(target.nodes, remote.nodes)) {
70493             return target;
70494         }
70495         if (option === 'force_remote') {
70496             return target.update({nodes: remote.nodes});
70497         }
70498
70499         var ccount = conflicts.length,
70500             o = base.nodes || [],
70501             a = target.nodes || [],
70502             b = remote.nodes || [],
70503             nodes = [],
70504             hunks = diff3Merge(a, o, b, true);
70505
70506         for (var i = 0; i < hunks.length; i++) {
70507             var hunk = hunks[i];
70508             if (hunk.ok) {
70509                 nodes.push.apply(nodes, hunk.ok);
70510             } else {
70511                 // for all conflicts, we can assume c.a !== c.b
70512                 // because `diff3Merge` called with `true` option to exclude false conflicts..
70513                 var c = hunk.conflict;
70514                 if (isEqual(c.o, c.a)) {  // only changed remotely
70515                     nodes.push.apply(nodes, c.b);
70516                 } else if (isEqual(c.o, c.b)) {  // only changed locally
70517                     nodes.push.apply(nodes, c.a);
70518                 } else {       // changed both locally and remotely
70519                     conflicts.push(t('merge_remote_changes.conflict.nodelist', { user: user(remote.user) }));
70520                     break;
70521                 }
70522             }
70523         }
70524
70525         return (conflicts.length === ccount) ? target.update({nodes: nodes}) : target;
70526     }
70527
70528
70529     function mergeChildren(targetWay, children, updates, graph) {
70530         function isUsed(node, targetWay) {
70531             var parentWays = map$4(graph.parentWays(node), 'id');
70532             return node.hasInterestingTags() ||
70533                 without(parentWays, targetWay.id).length > 0 ||
70534                 graph.parentRelations(node).length > 0;
70535         }
70536
70537         var ccount = conflicts.length;
70538
70539         for (var i = 0; i < children.length; i++) {
70540             var id = children[i],
70541                 node = graph.hasEntity(id);
70542
70543             // remove unused childNodes..
70544             if (targetWay.nodes.indexOf(id) === -1) {
70545                 if (node && !isUsed(node, targetWay)) {
70546                     updates.removeIds.push(id);
70547                 }
70548                 continue;
70549             }
70550
70551             // restore used childNodes..
70552             var local = localGraph.hasEntity(id),
70553                 remote = remoteGraph.hasEntity(id),
70554                 target;
70555
70556             if (option === 'force_remote' && remote && remote.visible) {
70557                 updates.replacements.push(remote);
70558
70559             } else if (option === 'force_local' && local) {
70560                 target = osmEntity(local);
70561                 if (remote) {
70562                     target = target.update({ version: remote.version });
70563                 }
70564                 updates.replacements.push(target);
70565
70566             } else if (option === 'safe' && local && remote && local.version !== remote.version) {
70567                 target = osmEntity(local, { version: remote.version });
70568                 if (remote.visible) {
70569                     target = mergeLocation(remote, target);
70570                 } else {
70571                     conflicts.push(t('merge_remote_changes.conflict.deleted', { user: user(remote.user) }));
70572                 }
70573
70574                 if (conflicts.length !== ccount) break;
70575                 updates.replacements.push(target);
70576             }
70577         }
70578
70579         return targetWay;
70580     }
70581
70582
70583     function updateChildren(updates, graph) {
70584         for (var i = 0; i < updates.replacements.length; i++) {
70585             graph = graph.replace(updates.replacements[i]);
70586         }
70587         if (updates.removeIds.length) {
70588             graph = actionDeleteMultiple(updates.removeIds)(graph);
70589         }
70590         return graph;
70591     }
70592
70593
70594     function mergeMembers(remote, target) {
70595         if (option === 'force_local' || isEqual(target.members, remote.members)) {
70596             return target;
70597         }
70598         if (option === 'force_remote') {
70599             return target.update({members: remote.members});
70600         }
70601
70602         conflicts.push(t('merge_remote_changes.conflict.memberlist', { user: user(remote.user) }));
70603         return target;
70604     }
70605
70606
70607     function mergeTags(base, remote, target) {
70608         function ignoreKey(k) {
70609             return includes(dataDiscarded, k);
70610         }
70611
70612         if (option === 'force_local' || isEqual(target.tags, remote.tags)) {
70613             return target;
70614         }
70615         if (option === 'force_remote') {
70616             return target.update({tags: remote.tags});
70617         }
70618
70619         var ccount = conflicts.length,
70620             o = base.tags || {},
70621             a = target.tags || {},
70622             b = remote.tags || {},
70623             keys = reject(union(keys$1(o), keys$1(a), keys$1(b)), ignoreKey),
70624             tags = clone(a),
70625             changed = false;
70626
70627         for (var i = 0; i < keys.length; i++) {
70628             var k = keys[i];
70629
70630             if (o[k] !== b[k] && a[k] !== b[k]) {    // changed remotely..
70631                 if (o[k] !== a[k]) {      // changed locally..
70632                     conflicts.push(t('merge_remote_changes.conflict.tags',
70633                         { tag: k, local: a[k], remote: b[k], user: user(remote.user) }));
70634
70635                 } else {                  // unchanged locally, accept remote change..
70636                     if (b.hasOwnProperty(k)) {
70637                         tags[k] = b[k];
70638                     } else {
70639                         delete tags[k];
70640                     }
70641                     changed = true;
70642                 }
70643             }
70644         }
70645
70646         return (changed && conflicts.length === ccount) ? target.update({tags: tags}) : target;
70647     }
70648
70649
70650     //  `graph.base()` is the common ancestor of the two graphs.
70651     //  `localGraph` contains user's edits up to saving
70652     //  `remoteGraph` contains remote edits to modified nodes
70653     //  `graph` must be a descendent of `localGraph` and may include
70654     //      some conflict resolution actions performed on it.
70655     //
70656     //                  --- ... --- `localGraph` -- ... -- `graph`
70657     //                 /
70658     //  `graph.base()` --- ... --- `remoteGraph`
70659     //
70660     var action = function(graph) {
70661         var updates = { replacements: [], removeIds: [] },
70662             base = graph.base().entities[id],
70663             local = localGraph.entity(id),
70664             remote = remoteGraph.entity(id),
70665             target = osmEntity(local, { version: remote.version });
70666
70667         // delete/undelete
70668         if (!remote.visible) {
70669             if (option === 'force_remote') {
70670                 return actionDeleteMultiple([id])(graph);
70671
70672             } else if (option === 'force_local') {
70673                 if (target.type === 'way') {
70674                     target = mergeChildren(target, uniq(local.nodes), updates, graph);
70675                     graph = updateChildren(updates, graph);
70676                 }
70677                 return graph.replace(target);
70678
70679             } else {
70680                 conflicts.push(t('merge_remote_changes.conflict.deleted', { user: user(remote.user) }));
70681                 return graph;  // do nothing
70682             }
70683         }
70684
70685         // merge
70686         if (target.type === 'node') {
70687             target = mergeLocation(remote, target);
70688
70689         } else if (target.type === 'way') {
70690             // pull in any child nodes that may not be present locally..
70691             graph.rebase(remoteGraph.childNodes(remote), [graph], false);
70692             target = mergeNodes(base, remote, target);
70693             target = mergeChildren(target, union(local.nodes, remote.nodes), updates, graph);
70694
70695         } else if (target.type === 'relation') {
70696             target = mergeMembers(remote, target);
70697         }
70698
70699         target = mergeTags(base, remote, target);
70700
70701         if (!conflicts.length) {
70702             graph = updateChildren(updates, graph).replace(target);
70703         }
70704
70705         return graph;
70706     };
70707
70708
70709     action.withOption = function(opt) {
70710         option = opt;
70711         return action;
70712     };
70713
70714
70715     action.conflicts = function() {
70716         return conflicts;
70717     };
70718
70719
70720     return action;
70721 }
70722
70723 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/command/MoveCommand.java
70724 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as
70725 function actionMove(moveIds, tryDelta, projection, cache) {
70726     var delta = tryDelta;
70727
70728     function vecAdd(a, b) { return [a[0] + b[0], a[1] + b[1]]; }
70729     function vecSub(a, b) { return [a[0] - b[0], a[1] - b[1]]; }
70730
70731     function setupCache(graph) {
70732         function canMove(nodeId) {
70733             // Allow movement of any node that is in the selectedIDs list..
70734             if (moveIds.indexOf(nodeId) !== -1) return true;
70735
70736             // Allow movement of a vertex where 2 ways meet..
70737             var parents = map$4(graph.parentWays(graph.entity(nodeId)), 'id');
70738             if (parents.length < 3) return true;
70739
70740             // Restrict movement of a vertex where >2 ways meet, unless all parentWays are moving too..
70741             var parentsMoving = every(parents, function(id) { return cache.moving[id]; });
70742             if (!parentsMoving) delete cache.moving[nodeId];
70743
70744             return parentsMoving;
70745         }
70746
70747         function cacheEntities(ids) {
70748             ids.forEach(function(id) {
70749                 if (cache.moving[id]) return;
70750                 cache.moving[id] = true;
70751
70752                 var entity = graph.hasEntity(id);
70753                 if (!entity) return;
70754
70755                 if (entity.type === 'node') {
70756                     cache.nodes.push(id);
70757                     cache.startLoc[id] = entity.loc;
70758                 } else if (entity.type === 'way') {
70759                     cache.ways.push(id);
70760                     cacheEntities(entity.nodes);
70761                 } else {
70762                     cacheEntities(entity.members.map(function(member) {
70763                         return member.id;
70764                     }));
70765                 }
70766             });
70767         }
70768
70769         function cacheIntersections(ids) {
70770             function isEndpoint(way, id) { return !way.isClosed() && !!way.affix(id); }
70771
70772             ids.forEach(function(id) {
70773                 // consider only intersections with 1 moved and 1 unmoved way.
70774                 var childNodes = graph.childNodes(graph.entity(id));
70775                 childNodes.forEach(function(node) {
70776                     var parents = graph.parentWays(node);
70777                     if (parents.length !== 2) return;
70778
70779                     var moved = graph.entity(id),
70780                         unmoved = find$1(parents, function(way) { return !cache.moving[way.id]; });
70781                     if (!unmoved) return;
70782
70783                     // exclude ways that are overly connected..
70784                     if (intersection(moved.nodes, unmoved.nodes).length > 2) return;
70785
70786                     if (moved.isArea() || unmoved.isArea()) return;
70787
70788                     cache.intersection[node.id] = {
70789                         nodeId: node.id,
70790                         movedId: moved.id,
70791                         unmovedId: unmoved.id,
70792                         movedIsEP: isEndpoint(moved, node.id),
70793                         unmovedIsEP: isEndpoint(unmoved, node.id)
70794                     };
70795                 });
70796             });
70797         }
70798
70799
70800         if (!cache) {
70801             cache = {};
70802         }
70803         if (!cache.ok) {
70804             cache.moving = {};
70805             cache.intersection = {};
70806             cache.replacedVertex = {};
70807             cache.startLoc = {};
70808             cache.nodes = [];
70809             cache.ways = [];
70810
70811             cacheEntities(moveIds);
70812             cacheIntersections(cache.ways);
70813             cache.nodes = filter(cache.nodes, canMove);
70814
70815             cache.ok = true;
70816         }
70817     }
70818
70819
70820     // Place a vertex where the moved vertex used to be, to preserve way shape..
70821     function replaceMovedVertex(nodeId, wayId, graph, delta) {
70822         var way = graph.entity(wayId),
70823             moved = graph.entity(nodeId),
70824             movedIndex = way.nodes.indexOf(nodeId),
70825             len, prevIndex, nextIndex;
70826
70827         if (way.isClosed()) {
70828             len = way.nodes.length - 1;
70829             prevIndex = (movedIndex + len - 1) % len;
70830             nextIndex = (movedIndex + len + 1) % len;
70831         } else {
70832             len = way.nodes.length;
70833             prevIndex = movedIndex - 1;
70834             nextIndex = movedIndex + 1;
70835         }
70836
70837         var prev = graph.hasEntity(way.nodes[prevIndex]),
70838             next = graph.hasEntity(way.nodes[nextIndex]);
70839
70840         // Don't add orig vertex at endpoint..
70841         if (!prev || !next) return graph;
70842
70843         var key = wayId + '_' + nodeId,
70844             orig = cache.replacedVertex[key];
70845         if (!orig) {
70846             orig = osmNode();
70847             cache.replacedVertex[key] = orig;
70848             cache.startLoc[orig.id] = cache.startLoc[nodeId];
70849         }
70850
70851         var start, end;
70852         if (delta) {
70853             start = projection(cache.startLoc[nodeId]);
70854             end = projection.invert(vecAdd(start, delta));
70855         } else {
70856             end = cache.startLoc[nodeId];
70857         }
70858         orig = orig.move(end);
70859
70860         var angle = Math.abs(geoAngle(orig, prev, projection) -
70861                 geoAngle(orig, next, projection)) * 180 / Math.PI;
70862
70863         // Don't add orig vertex if it would just make a straight line..
70864         if (angle > 175 && angle < 185) return graph;
70865
70866         // Don't add orig vertex if another point is already nearby (within 10m)
70867         if (geoSphericalDistance(prev.loc, orig.loc) < 10 ||
70868             geoSphericalDistance(orig.loc, next.loc) < 10) return graph;
70869
70870         // moving forward or backward along way?
70871         var p1 = [prev.loc, orig.loc, moved.loc, next.loc].map(projection),
70872             p2 = [prev.loc, moved.loc, orig.loc, next.loc].map(projection),
70873             d1 = geoPathLength(p1),
70874             d2 = geoPathLength(p2),
70875             insertAt = (d1 < d2) ? movedIndex : nextIndex;
70876
70877         // moving around closed loop?
70878         if (way.isClosed() && insertAt === 0) insertAt = len;
70879
70880         way = way.addNode(orig.id, insertAt);
70881         return graph.replace(orig).replace(way);
70882     }
70883
70884
70885     // Reorder nodes around intersections that have moved..
70886     function unZorroIntersection(intersection$$1, graph) {
70887         var vertex = graph.entity(intersection$$1.nodeId),
70888             way1 = graph.entity(intersection$$1.movedId),
70889             way2 = graph.entity(intersection$$1.unmovedId),
70890             isEP1 = intersection$$1.movedIsEP,
70891             isEP2 = intersection$$1.unmovedIsEP;
70892
70893         // don't move the vertex if it is the endpoint of both ways.
70894         if (isEP1 && isEP2) return graph;
70895
70896         var nodes1 = without(graph.childNodes(way1), vertex),
70897             nodes2 = without(graph.childNodes(way2), vertex);
70898
70899         if (way1.isClosed() && way1.first() === vertex.id) nodes1.push(nodes1[0]);
70900         if (way2.isClosed() && way2.first() === vertex.id) nodes2.push(nodes2[0]);
70901
70902         var edge1 = !isEP1 && geoChooseEdge(nodes1, projection(vertex.loc), projection),
70903             edge2 = !isEP2 && geoChooseEdge(nodes2, projection(vertex.loc), projection),
70904             loc;
70905
70906         // snap vertex to nearest edge (or some point between them)..
70907         if (!isEP1 && !isEP2) {
70908             var epsilon = 1e-4, maxIter = 10;
70909             for (var i = 0; i < maxIter; i++) {
70910                 loc = geoInterp(edge1.loc, edge2.loc, 0.5);
70911                 edge1 = geoChooseEdge(nodes1, projection(loc), projection);
70912                 edge2 = geoChooseEdge(nodes2, projection(loc), projection);
70913                 if (Math.abs(edge1.distance - edge2.distance) < epsilon) break;
70914             }
70915         } else if (!isEP1) {
70916             loc = edge1.loc;
70917         } else {
70918             loc = edge2.loc;
70919         }
70920
70921         graph = graph.replace(vertex.move(loc));
70922
70923         // if zorro happened, reorder nodes..
70924         if (!isEP1 && edge1.index !== way1.nodes.indexOf(vertex.id)) {
70925             way1 = way1.removeNode(vertex.id).addNode(vertex.id, edge1.index);
70926             graph = graph.replace(way1);
70927         }
70928         if (!isEP2 && edge2.index !== way2.nodes.indexOf(vertex.id)) {
70929             way2 = way2.removeNode(vertex.id).addNode(vertex.id, edge2.index);
70930             graph = graph.replace(way2);
70931         }
70932
70933         return graph;
70934     }
70935
70936
70937     function cleanupIntersections(graph) {
70938         forEach(cache.intersection, function(obj) {
70939             graph = replaceMovedVertex(obj.nodeId, obj.movedId, graph, delta);
70940             graph = replaceMovedVertex(obj.nodeId, obj.unmovedId, graph, null);
70941             graph = unZorroIntersection(obj, graph);
70942         });
70943
70944         return graph;
70945     }
70946
70947
70948     // check if moving way endpoint can cross an unmoved way, if so limit delta..
70949     function limitDelta(graph) {
70950         forEach(cache.intersection, function(obj) {
70951             // Don't limit movement if this is vertex joins 2 endpoints..
70952             if (obj.movedIsEP && obj.unmovedIsEP) return;
70953             // Don't limit movement if this vertex is not an endpoint anyway..
70954             if (!obj.movedIsEP) return;
70955
70956             var node = graph.entity(obj.nodeId),
70957                 start = projection(node.loc),
70958                 end = vecAdd(start, delta),
70959                 movedNodes = graph.childNodes(graph.entity(obj.movedId)),
70960                 movedPath = map$4(map$4(movedNodes, 'loc'),
70961                     function(loc) { return vecAdd(projection(loc), delta); }),
70962                 unmovedNodes = graph.childNodes(graph.entity(obj.unmovedId)),
70963                 unmovedPath = map$4(map$4(unmovedNodes, 'loc'), projection),
70964                 hits = geoPathIntersections(movedPath, unmovedPath);
70965
70966             for (var i = 0; i < hits.length; i++) {
70967                 if (isEqual(hits[i], end)) continue;
70968                 var edge = geoChooseEdge(unmovedNodes, end, projection);
70969                 delta = vecSub(projection(edge.loc), start);
70970             }
70971         });
70972     }
70973
70974
70975     var action = function(graph) {
70976         if (delta[0] === 0 && delta[1] === 0) return graph;
70977
70978         setupCache(graph);
70979
70980         if (!isEmpty(cache.intersection)) {
70981             limitDelta(graph);
70982         }
70983
70984         forEach(cache.nodes, function(id) {
70985             var node = graph.entity(id),
70986                 start = projection(node.loc),
70987                 end = vecAdd(start, delta);
70988             graph = graph.replace(node.move(projection.invert(end)));
70989         });
70990
70991         if (!isEmpty(cache.intersection)) {
70992             graph = cleanupIntersections(graph);
70993         }
70994
70995         return graph;
70996     };
70997
70998
70999     action.delta = function() {
71000         return delta;
71001     };
71002
71003
71004     return action;
71005 }
71006
71007 // https://github.com/openstreetmap/josm/blob/mirror/src/org/openstreetmap/josm/command/MoveCommand.java
71008 // https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/MoveNodeAction.as
71009 function actionMoveNode(nodeId, loc) {
71010     return function(graph) {
71011         return graph.replace(graph.entity(nodeId).move(loc));
71012     };
71013 }
71014
71015 function actionNoop() {
71016     return function(graph) {
71017         return graph;
71018     };
71019 }
71020
71021 /*
71022  * Based on https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/potlatch2/tools/Quadrilateralise.as
71023  */
71024 function actionOrthogonalize(wayId, projection) {
71025     var threshold = 12, // degrees within right or straight to alter
71026         lowerThreshold = Math.cos((90 - threshold) * Math.PI / 180),
71027         upperThreshold = Math.cos(threshold * Math.PI / 180);
71028
71029
71030     var action = function(graph, t) {
71031         if (t === null || !isFinite(t)) t = 1;
71032         t = Math.min(Math.max(+t, 0), 1);
71033
71034         var way = graph.entity(wayId),
71035             nodes = graph.childNodes(way),
71036             points = uniq(nodes).map(function(n) { return projection(n.loc); }),
71037             corner = {i: 0, dotp: 1},
71038             epsilon = 1e-4,
71039             node, loc, score, motions, i, j;
71040
71041         if (points.length === 3) {   // move only one vertex for right triangle
71042             for (i = 0; i < 1000; i++) {
71043                 motions = points.map(calcMotion);
71044                 points[corner.i] = addPoints(points[corner.i], motions[corner.i]);
71045                 score = corner.dotp;
71046                 if (score < epsilon) {
71047                     break;
71048                 }
71049             }
71050
71051             node = graph.entity(nodes[corner.i].id);
71052             loc = projection.invert(points[corner.i]);
71053             graph = graph.replace(node.move(geoInterp(node.loc, loc, t)));
71054
71055         } else {
71056             var best,
71057                 originalPoints = clone(points);
71058             score = Infinity;
71059
71060             for (i = 0; i < 1000; i++) {
71061                 motions = points.map(calcMotion);
71062                 for (j = 0; j < motions.length; j++) {
71063                     points[j] = addPoints(points[j],motions[j]);
71064                 }
71065                 var newScore = squareness(points);
71066                 if (newScore < score) {
71067                     best = clone(points);
71068                     score = newScore;
71069                 }
71070                 if (score < epsilon) {
71071                     break;
71072                 }
71073             }
71074
71075             points = best;
71076
71077             for (i = 0; i < points.length; i++) {
71078                 // only move the points that actually moved
71079                 if (originalPoints[i][0] !== points[i][0] || originalPoints[i][1] !== points[i][1]) {
71080                     loc = projection.invert(points[i]);
71081                     node = graph.entity(nodes[i].id);
71082                     graph = graph.replace(node.move(geoInterp(node.loc, loc, t)));
71083                 }
71084             }
71085
71086             // remove empty nodes on straight sections
71087             for (i = 0; t === 1 && i < points.length; i++) {
71088                 node = graph.entity(nodes[i].id);
71089
71090                 if (graph.parentWays(node).length > 1 ||
71091                     graph.parentRelations(node).length ||
71092                     node.hasInterestingTags()) {
71093                     continue;
71094                 }
71095
71096                 var dotp = normalizedDotProduct(i, points);
71097                 if (dotp < -1 + epsilon) {
71098                     graph = actionDeleteNode(node.id)(graph);
71099                 }
71100             }
71101         }
71102
71103         return graph;
71104
71105
71106         function calcMotion(b, i, array) {
71107             var a = array[(i - 1 + array.length) % array.length],
71108                 c = array[(i + 1) % array.length],
71109                 p = subtractPoints(a, b),
71110                 q = subtractPoints(c, b),
71111                 scale, dotp;
71112
71113             scale = 2 * Math.min(geoEuclideanDistance(p, [0, 0]), geoEuclideanDistance(q, [0, 0]));
71114             p = normalizePoint(p, 1.0);
71115             q = normalizePoint(q, 1.0);
71116
71117             dotp = filterDotProduct(p[0] * q[0] + p[1] * q[1]);
71118
71119             // nasty hack to deal with almost-straight segments (angle is closer to 180 than to 90/270).
71120             if (array.length > 3) {
71121                 if (dotp < -0.707106781186547) {
71122                     dotp += 1.0;
71123                 }
71124             } else if (dotp && Math.abs(dotp) < corner.dotp) {
71125                 corner.i = i;
71126                 corner.dotp = Math.abs(dotp);
71127             }
71128
71129             return normalizePoint(addPoints(p, q), 0.1 * dotp * scale);
71130         }
71131     };
71132
71133
71134     function squareness(points) {
71135         return points.reduce(function(sum, val, i, array) {
71136             var dotp = normalizedDotProduct(i, array);
71137
71138             dotp = filterDotProduct(dotp);
71139             return sum + 2.0 * Math.min(Math.abs(dotp - 1.0), Math.min(Math.abs(dotp), Math.abs(dotp + 1)));
71140         }, 0);
71141     }
71142
71143
71144     function normalizedDotProduct(i, points) {
71145         var a = points[(i - 1 + points.length) % points.length],
71146             b = points[i],
71147             c = points[(i + 1) % points.length],
71148             p = subtractPoints(a, b),
71149             q = subtractPoints(c, b);
71150
71151         p = normalizePoint(p, 1.0);
71152         q = normalizePoint(q, 1.0);
71153
71154         return p[0] * q[0] + p[1] * q[1];
71155     }
71156
71157
71158     function subtractPoints(a, b) {
71159         return [a[0] - b[0], a[1] - b[1]];
71160     }
71161
71162
71163     function addPoints(a, b) {
71164         return [a[0] + b[0], a[1] + b[1]];
71165     }
71166
71167
71168     function normalizePoint(point, scale) {
71169         var vector = [0, 0];
71170         var length = Math.sqrt(point[0] * point[0] + point[1] * point[1]);
71171         if (length !== 0) {
71172             vector[0] = point[0] / length;
71173             vector[1] = point[1] / length;
71174         }
71175
71176         vector[0] *= scale;
71177         vector[1] *= scale;
71178
71179         return vector;
71180     }
71181
71182
71183     function filterDotProduct(dotp) {
71184         if (lowerThreshold > Math.abs(dotp) || Math.abs(dotp) > upperThreshold) {
71185             return dotp;
71186         }
71187
71188         return 0;
71189     }
71190
71191
71192     action.disabled = function(graph) {
71193         var way = graph.entity(wayId),
71194             nodes = graph.childNodes(way),
71195             points = uniq(nodes).map(function(n) { return projection(n.loc); });
71196
71197         if (squareness(points)) {
71198             return false;
71199         }
71200
71201         return 'not_squarish';
71202     };
71203
71204
71205     action.transitionable = true;
71206
71207
71208     return action;
71209 }
71210
71211 // Split a way at the given node.
71212 //
71213 // Optionally, split only the given ways, if multiple ways share
71214 // the given node.
71215 //
71216 // This is the inverse of `iD.actionJoin`.
71217 //
71218 // For testing convenience, accepts an ID to assign to the new way.
71219 // Normally, this will be undefined and the way will automatically
71220 // be assigned a new ID.
71221 //
71222 // Reference:
71223 //   https://github.com/systemed/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/SplitWayAction.as
71224 //
71225 function actionSplit(nodeId, newWayIds) {
71226     var wayIds;
71227
71228     // if the way is closed, we need to search for a partner node
71229     // to split the way at.
71230     //
71231     // The following looks for a node that is both far away from
71232     // the initial node in terms of way segment length and nearby
71233     // in terms of beeline-distance. This assures that areas get
71234     // split on the most "natural" points (independent of the number
71235     // of nodes).
71236     // For example: bone-shaped areas get split across their waist
71237     // line, circles across the diameter.
71238     function splitArea(nodes, idxA, graph) {
71239         var lengths = new Array(nodes.length),
71240             length,
71241             i,
71242             best = 0,
71243             idxB;
71244
71245         function wrap(index) {
71246             return utilWrap(index, nodes.length);
71247         }
71248
71249         function dist(nA, nB) {
71250             return geoSphericalDistance(graph.entity(nA).loc, graph.entity(nB).loc);
71251         }
71252
71253         // calculate lengths
71254         length = 0;
71255         for (i = wrap(idxA+1); i !== idxA; i = wrap(i+1)) {
71256             length += dist(nodes[i], nodes[wrap(i-1)]);
71257             lengths[i] = length;
71258         }
71259
71260         length = 0;
71261         for (i = wrap(idxA-1); i !== idxA; i = wrap(i-1)) {
71262             length += dist(nodes[i], nodes[wrap(i+1)]);
71263             if (length < lengths[i])
71264                 lengths[i] = length;
71265         }
71266
71267         // determine best opposite node to split
71268         for (i = 0; i < nodes.length; i++) {
71269             var cost = lengths[i] / dist(nodes[idxA], nodes[i]);
71270             if (cost > best) {
71271                 idxB = i;
71272                 best = cost;
71273             }
71274         }
71275
71276         return idxB;
71277     }
71278
71279
71280     function split(graph, wayA, newWayId) {
71281         var wayB = osmWay({id: newWayId, tags: wayA.tags}),
71282             nodesA,
71283             nodesB,
71284             isArea = wayA.isArea(),
71285             isOuter = osmIsSimpleMultipolygonOuterMember(wayA, graph);
71286
71287         if (wayA.isClosed()) {
71288             var nodes = wayA.nodes.slice(0, -1),
71289                 idxA = indexOf(nodes, nodeId),
71290                 idxB = splitArea(nodes, idxA, graph);
71291
71292             if (idxB < idxA) {
71293                 nodesA = nodes.slice(idxA).concat(nodes.slice(0, idxB + 1));
71294                 nodesB = nodes.slice(idxB, idxA + 1);
71295             } else {
71296                 nodesA = nodes.slice(idxA, idxB + 1);
71297                 nodesB = nodes.slice(idxB).concat(nodes.slice(0, idxA + 1));
71298             }
71299         } else {
71300             var idx = indexOf(wayA.nodes, nodeId, 1);
71301             nodesA = wayA.nodes.slice(0, idx + 1);
71302             nodesB = wayA.nodes.slice(idx);
71303         }
71304
71305         wayA = wayA.update({nodes: nodesA});
71306         wayB = wayB.update({nodes: nodesB});
71307
71308         graph = graph.replace(wayA);
71309         graph = graph.replace(wayB);
71310
71311         graph.parentRelations(wayA).forEach(function(relation) {
71312             if (relation.isRestriction()) {
71313                 var via = relation.memberByRole('via');
71314                 if (via && wayB.contains(via.id)) {
71315                     relation = relation.replaceMember(wayA, wayB);
71316                     graph = graph.replace(relation);
71317                 }
71318             } else {
71319                 if (relation === isOuter) {
71320                     graph = graph.replace(relation.mergeTags(wayA.tags));
71321                     graph = graph.replace(wayA.update({tags: {}}));
71322                     graph = graph.replace(wayB.update({tags: {}}));
71323                 }
71324
71325                 var member = {
71326                     id: wayB.id,
71327                     type: 'way',
71328                     role: relation.memberById(wayA.id).role
71329                 };
71330
71331                 graph = actionAddMember(relation.id, member)(graph);
71332             }
71333         });
71334
71335         if (!isOuter && isArea) {
71336             var multipolygon = osmRelation({
71337                 tags: assignIn({}, wayA.tags, {type: 'multipolygon'}),
71338                 members: [
71339                     {id: wayA.id, role: 'outer', type: 'way'},
71340                     {id: wayB.id, role: 'outer', type: 'way'}
71341                 ]});
71342
71343             graph = graph.replace(multipolygon);
71344             graph = graph.replace(wayA.update({tags: {}}));
71345             graph = graph.replace(wayB.update({tags: {}}));
71346         }
71347
71348         return graph;
71349     }
71350
71351
71352     var action = function(graph) {
71353         var candidates = action.ways(graph);
71354         for (var i = 0; i < candidates.length; i++) {
71355             graph = split(graph, candidates[i], newWayIds && newWayIds[i]);
71356         }
71357         return graph;
71358     };
71359
71360
71361     action.ways = function(graph) {
71362         var node = graph.entity(nodeId),
71363             parents = graph.parentWays(node),
71364             hasLines = some(parents, function(parent) { return parent.geometry(graph) === 'line'; });
71365
71366         return parents.filter(function(parent) {
71367             if (wayIds && wayIds.indexOf(parent.id) === -1)
71368                 return false;
71369
71370             if (!wayIds && hasLines && parent.geometry(graph) !== 'line')
71371                 return false;
71372
71373             if (parent.isClosed()) {
71374                 return true;
71375             }
71376
71377             for (var i = 1; i < parent.nodes.length - 1; i++) {
71378                 if (parent.nodes[i] === nodeId) {
71379                     return true;
71380                 }
71381             }
71382
71383             return false;
71384         });
71385     };
71386
71387
71388     action.disabled = function(graph) {
71389         var candidates = action.ways(graph);
71390         if (candidates.length === 0 || (wayIds && wayIds.length !== candidates.length))
71391             return 'not_eligible';
71392     };
71393
71394
71395     action.limitWays = function(_) {
71396         if (!arguments.length) return wayIds;
71397         wayIds = _;
71398         return action;
71399     };
71400
71401
71402     return action;
71403 }
71404
71405 // Create a restriction relation for `turn`, which must have the following structure:
71406 //
71407 //     {
71408 //         from: { node: <node ID>, way: <way ID> },
71409 //         via:  { node: <node ID> },
71410 //         to:   { node: <node ID>, way: <way ID> },
71411 //         restriction: <'no_right_turn', 'no_left_turn', etc.>
71412 //     }
71413 //
71414 // This specifies a restriction of type `restriction` when traveling from
71415 // `from.node` in `from.way` toward `to.node` in `to.way` via `via.node`.
71416 // (The action does not check that these entities form a valid intersection.)
71417 //
71418 // If `restriction` is not provided, it is automatically determined by
71419 // osmInferRestriction.
71420 //
71421 // If necessary, the `from` and `to` ways are split. In these cases, `from.node`
71422 // and `to.node` are used to determine which portion of the split ways become
71423 // members of the restriction.
71424 //
71425 // For testing convenience, accepts an ID to assign to the new relation.
71426 // Normally, this will be undefined and the relation will automatically
71427 // be assigned a new ID.
71428 //
71429 function actionRestrictTurn(turn, projection, restrictionId) {
71430
71431     return function(graph) {
71432         var from = graph.entity(turn.from.way),
71433             via  = graph.entity(turn.via.node),
71434             to   = graph.entity(turn.to.way);
71435
71436         function isClosingNode(way, nodeId) {
71437             return nodeId === way.first() && nodeId === way.last();
71438         }
71439
71440         function split(toOrFrom) {
71441             var newID = toOrFrom.newID || osmWay().id;
71442             graph = actionSplit(via.id, [newID])
71443                 .limitWays([toOrFrom.way])(graph);
71444
71445             var a = graph.entity(newID),
71446                 b = graph.entity(toOrFrom.way);
71447
71448             if (a.nodes.indexOf(toOrFrom.node) !== -1) {
71449                 return [a, b];
71450             } else {
71451                 return [b, a];
71452             }
71453         }
71454
71455         if (!from.affix(via.id) || isClosingNode(from, via.id)) {
71456             if (turn.from.node === turn.to.node) {
71457                 // U-turn
71458                 from = to = split(turn.from)[0];
71459             } else if (turn.from.way === turn.to.way) {
71460                 // Straight-on or circular
71461                 var s = split(turn.from);
71462                 from = s[0];
71463                 to   = s[1];
71464             } else {
71465                 // Other
71466                 from = split(turn.from)[0];
71467             }
71468         }
71469
71470         if (!to.affix(via.id) || isClosingNode(to, via.id)) {
71471             to = split(turn.to)[0];
71472         }
71473
71474         return graph.replace(osmRelation({
71475             id: restrictionId,
71476             tags: {
71477                 type: 'restriction',
71478                 restriction: turn.restriction ||
71479                     osmInferRestriction(
71480                         graph,
71481                         turn.from,
71482                         turn.via,
71483                         turn.to,
71484                         projection)
71485             },
71486             members: [
71487                 {id: from.id, type: 'way',  role: 'from'},
71488                 {id: via.id,  type: 'node', role: 'via'},
71489                 {id: to.id,   type: 'way',  role: 'to'}
71490             ]
71491         }));
71492     };
71493 }
71494
71495 function actionRevert(id) {
71496     var action = function(graph) {
71497         var entity = graph.hasEntity(id),
71498             base = graph.base().entities[id];
71499
71500         if (entity && !base) {    // entity will be removed..
71501             if (entity.type === 'node') {
71502                 graph.parentWays(entity)
71503                     .forEach(function(parent) {
71504                         parent = parent.removeNode(id);
71505                         graph = graph.replace(parent);
71506
71507                         if (parent.isDegenerate()) {
71508                             graph = actionDeleteWay(parent.id)(graph);
71509                         }
71510                     });
71511             }
71512
71513             graph.parentRelations(entity)
71514                 .forEach(function(parent) {
71515                     parent = parent.removeMembersWithID(id);
71516                     graph = graph.replace(parent);
71517
71518                     if (parent.isDegenerate()) {
71519                         graph = actionDeleteRelation(parent.id)(graph);
71520                     }
71521                 });
71522         }
71523
71524         return graph.revert(id);
71525     };
71526
71527     return action;
71528 }
71529
71530 function actionRotate(rotateIds, pivot, angle, projection) {
71531
71532     var action = function(graph) {
71533         return graph.update(function(graph) {
71534             utilGetAllNodes(rotateIds, graph).forEach(function(node) {
71535                 var point = geoRotate([projection(node.loc)], angle, pivot)[0];
71536                 graph = graph.replace(node.move(projection.invert(point)));
71537             });
71538         });
71539     };
71540
71541     return action;
71542 }
71543
71544 /*
71545  * Based on https://github.com/openstreetmap/potlatch2/net/systemeD/potlatch2/tools/Straighten.as
71546  */
71547 function actionStraighten(wayId, projection) {
71548
71549     function positionAlongWay(n, s, e) {
71550         return ((n[0] - s[0]) * (e[0] - s[0]) + (n[1] - s[1]) * (e[1] - s[1])) /
71551                 (Math.pow(e[0] - s[0], 2) + Math.pow(e[1] - s[1], 2));
71552     }
71553
71554
71555     var action = function(graph, t) {
71556         if (t === null || !isFinite(t)) t = 1;
71557         t = Math.min(Math.max(+t, 0), 1);
71558
71559         var way = graph.entity(wayId),
71560             nodes = graph.childNodes(way),
71561             points = nodes.map(function(n) { return projection(n.loc); }),
71562             startPoint = points[0],
71563             endPoint = points[points.length-1],
71564             toDelete = [],
71565             i;
71566
71567         for (i = 1; i < points.length-1; i++) {
71568             var node = nodes[i],
71569                 point = points[i];
71570
71571             if (t < 1 || graph.parentWays(node).length > 1 ||
71572                 graph.parentRelations(node).length ||
71573                 node.hasInterestingTags()) {
71574
71575                 var u = positionAlongWay(point, startPoint, endPoint),
71576                     p = [
71577                         startPoint[0] + u * (endPoint[0] - startPoint[0]),
71578                         startPoint[1] + u * (endPoint[1] - startPoint[1])
71579                     ],
71580                     loc2 = projection.invert(p);
71581
71582                 graph = graph.replace(node.move(geoInterp(node.loc, loc2, t)));
71583
71584             } else {
71585                 // safe to delete
71586                 if (toDelete.indexOf(node) === -1) {
71587                     toDelete.push(node);
71588                 }
71589             }
71590         }
71591
71592         for (i = 0; i < toDelete.length; i++) {
71593             graph = actionDeleteNode(toDelete[i].id)(graph);
71594         }
71595
71596         return graph;
71597     };
71598
71599
71600     action.disabled = function(graph) {
71601         // check way isn't too bendy
71602         var way = graph.entity(wayId),
71603             nodes = graph.childNodes(way),
71604             points = nodes.map(function(n) { return projection(n.loc); }),
71605             startPoint = points[0],
71606             endPoint = points[points.length-1],
71607             threshold = 0.2 * geoEuclideanDistance(startPoint, endPoint),
71608             i;
71609
71610         if (threshold === 0) {
71611             return 'too_bendy';
71612         }
71613
71614         for (i = 1; i < points.length-1; i++) {
71615             var point = points[i],
71616                 u = positionAlongWay(point, startPoint, endPoint),
71617                 p0 = startPoint[0] + u * (endPoint[0] - startPoint[0]),
71618                 p1 = startPoint[1] + u * (endPoint[1] - startPoint[1]),
71619                 dist = Math.sqrt(Math.pow(p0 - point[0], 2) + Math.pow(p1 - point[1], 2));
71620
71621             // to bendy if point is off by 20% of total start/end distance in projected space
71622             if (isNaN(dist) || dist > threshold) {
71623                 return 'too_bendy';
71624             }
71625         }
71626     };
71627
71628
71629     action.transitionable = true;
71630
71631
71632     return action;
71633 }
71634
71635 // Remove the effects of `turn.restriction` on `turn`, which must have the
71636 // following structure:
71637 //
71638 //     {
71639 //         from: { node: <node ID>, way: <way ID> },
71640 //         via:  { node: <node ID> },
71641 //         to:   { node: <node ID>, way: <way ID> },
71642 //         restriction: <relation ID>
71643 //     }
71644 //
71645 // In the simple case, `restriction` is a reference to a `no_*` restriction
71646 // on the turn itself. In this case, it is simply deleted.
71647 //
71648 // The more complex case is where `restriction` references an `only_*`
71649 // restriction on a different turn in the same intersection. In that case,
71650 // that restriction is also deleted, but at the same time restrictions on
71651 // the turns other than the first two are created.
71652 //
71653 function actionUnrestrictTurn(turn) {
71654     return function(graph) {
71655         return actionDeleteRelation(turn.restriction)(graph);
71656     };
71657 }
71658
71659 /* Reflect the given area around its axis of symmetry */
71660 function actionReflect(reflectIds, projection) {
71661     var useLongAxis = true;
71662
71663
71664     // http://gis.stackexchange.com/questions/22895/finding-minimum-area-rectangle-for-given-points
71665     // http://gis.stackexchange.com/questions/3739/generalisation-strategies-for-building-outlines/3756#3756
71666     function getSmallestSurroundingRectangle(graph, nodes) {
71667         var points = nodes.map(function(n) { return projection(n.loc); }),
71668             hull = d3_polygonHull(points),
71669             centroid = d3_polygonCentroid(hull),
71670             minArea = Infinity,
71671             ssrExtent = [],
71672             ssrAngle = 0,
71673             c1 = hull[0];
71674
71675         for (var i = 0; i <= hull.length - 1; i++) {
71676             var c2 = (i === hull.length - 1) ? hull[0] : hull[i + 1],
71677                 angle = Math.atan2(c2[1] - c1[1], c2[0] - c1[0]),
71678                 poly = geoRotate(hull, -angle, centroid),
71679                 extent = poly.reduce(function(extent, point) {
71680                         return extent.extend(geoExtent(point));
71681                     }, geoExtent()),
71682                 area = extent.area();
71683
71684             if (area < minArea) {
71685                 minArea = area;
71686                 ssrExtent = extent;
71687                 ssrAngle = angle;
71688             }
71689             c1 = c2;
71690         }
71691
71692         return {
71693             poly: geoRotate(ssrExtent.polygon(), ssrAngle, centroid),
71694             angle: ssrAngle
71695         };
71696     }
71697
71698
71699     var action = function(graph, t) {
71700         if (t === null || !isFinite(t)) t = 1;
71701         t = Math.min(Math.max(+t, 0), 1);
71702
71703         var nodes = utilGetAllNodes(reflectIds, graph),
71704             ssr = getSmallestSurroundingRectangle(graph, nodes);
71705
71706         // Choose line pq = axis of symmetry.
71707         // The shape's surrounding rectangle has 2 axes of symmetry.
71708         // Reflect across the longer axis by default.
71709         var p1 = [(ssr.poly[0][0] + ssr.poly[1][0]) / 2, (ssr.poly[0][1] + ssr.poly[1][1]) / 2 ],
71710             q1 = [(ssr.poly[2][0] + ssr.poly[3][0]) / 2, (ssr.poly[2][1] + ssr.poly[3][1]) / 2 ],
71711             p2 = [(ssr.poly[3][0] + ssr.poly[4][0]) / 2, (ssr.poly[3][1] + ssr.poly[4][1]) / 2 ],
71712             q2 = [(ssr.poly[1][0] + ssr.poly[2][0]) / 2, (ssr.poly[1][1] + ssr.poly[2][1]) / 2 ],
71713             p, q;
71714
71715         var isLong = (geoEuclideanDistance(p1, q1) > geoEuclideanDistance(p2, q2));
71716         if ((useLongAxis && isLong) || (!useLongAxis && !isLong)) {
71717             p = p1;
71718             q = q1;
71719         } else {
71720             p = p2;
71721             q = q2;
71722         }
71723
71724         // reflect c across pq
71725         // http://math.stackexchange.com/questions/65503/point-reflection-over-a-line
71726         var dx = q[0] - p[0];
71727         var dy = q[1] - p[1];
71728         var a = (dx * dx - dy * dy) / (dx * dx + dy * dy);
71729         var b = 2 * dx * dy / (dx * dx + dy * dy);
71730         for (var i = 0; i < nodes.length; i++) {
71731             var node = nodes[i];
71732             var c = projection(node.loc);
71733             var c2 = [
71734                 a * (c[0] - p[0]) + b * (c[1] - p[1]) + p[0],
71735                 b * (c[0] - p[0]) - a * (c[1] - p[1]) + p[1]
71736             ];
71737             var loc2 = projection.invert(c2);
71738             node = node.move(geoInterp(node.loc, loc2, t));
71739             graph = graph.replace(node);
71740         }
71741
71742         return graph;
71743     };
71744
71745
71746     action.useLongAxis = function(_) {
71747         if (!arguments.length) return useLongAxis;
71748         useLongAxis = _;
71749         return action;
71750     };
71751
71752
71753     action.transitionable = true;
71754
71755
71756     return action;
71757 }
71758
71759
71760
71761 var index$4 = Object.freeze({
71762         d3combobox: d3combobox,
71763         d3geoTile: d3geoTile,
71764         d3keybinding: d3keybinding
71765 });
71766
71767 /* export some legacy symbols: */
71768 var Connection = services.osm;
71769 var debug = false;
71770
71771
71772
71773
71774 var iD = Object.freeze({
71775         Connection: Connection,
71776         debug: debug,
71777         lib: index$4,
71778         d3: index,
71779         Context: coreContext,
71780         setAreaKeys: setAreaKeys,
71781         Difference: coreDifference,
71782         Graph: coreGraph,
71783         History: coreHistory,
71784         Tree: coreTree,
71785         Entity: osmEntity,
71786         Node: osmNode,
71787         Relation: osmRelation,
71788         Way: osmWay,
71789         BackgroundSource: rendererBackgroundSource,
71790         Background: rendererBackground,
71791         Features: rendererFeatures,
71792         Map: rendererMap,
71793         TileLayer: rendererTileLayer,
71794         Detect: utilDetect,
71795         uiPreset: uiPresetEditor,
71796         actionAddEntity: actionAddEntity,
71797         actionAddMember: actionAddMember,
71798         actionAddMidpoint: actionAddMidpoint,
71799         actionAddVertex: actionAddVertex,
71800         actionChangeMember: actionChangeMember,
71801         actionChangePreset: actionChangePreset,
71802         actionChangeTags: actionChangeTags,
71803         actionCircularize: actionCircularize,
71804         actionConnect: actionConnect,
71805         actionCopyEntities: actionCopyEntities,
71806         actionDeleteMember: actionDeleteMember,
71807         actionDeleteMultiple: actionDeleteMultiple,
71808         actionDeleteNode: actionDeleteNode,
71809         actionDeleteRelation: actionDeleteRelation,
71810         actionDeleteWay: actionDeleteWay,
71811         actionDeprecateTags: actionDeprecateTags,
71812         actionDiscardTags: actionDiscardTags,
71813         actionDisconnect: actionDisconnect,
71814         actionJoin: actionJoin,
71815         actionMerge: actionMerge,
71816         actionMergePolygon: actionMergePolygon,
71817         actionMergeRemoteChanges: actionMergeRemoteChanges,
71818         actionMove: actionMove,
71819         actionMoveNode: actionMoveNode,
71820         actionNoop: actionNoop,
71821         actionOrthogonalize: actionOrthogonalize,
71822         actionRestrictTurn: actionRestrictTurn,
71823         actionReverse: actionReverse,
71824         actionRevert: actionRevert,
71825         actionRotate: actionRotate,
71826         actionSplit: actionSplit,
71827         actionStraighten: actionStraighten,
71828         actionUnrestrictTurn: actionUnrestrictTurn,
71829         actionReflect: actionReflect,
71830         behaviorAddWay: behaviorAddWay,
71831         behaviorBreathe: behaviorBreathe,
71832         behaviorCopy: behaviorCopy,
71833         behaviorDrag: behaviorDrag,
71834         behaviorDrawWay: behaviorDrawWay,
71835         behaviorDraw: behaviorDraw,
71836         behaviorEdit: behaviorEdit,
71837         behaviorHash: behaviorHash,
71838         behaviorHover: behaviorHover,
71839         behaviorLasso: behaviorLasso,
71840         behaviorOperation: behaviorOperation,
71841         behaviorPaste: behaviorPaste,
71842         behaviorSelect: behaviorSelect,
71843         behaviorTail: behaviorTail,
71844         coreContext: coreContext,
71845         coreDifference: coreDifference,
71846         coreGraph: coreGraph,
71847         coreHistory: coreHistory,
71848         coreTree: coreTree,
71849         dataFeatureIcons: dataFeatureIcons,
71850         data: data,
71851         dataWikipedia: wikipedia,
71852         dataSuggestions: dataSuggestions,
71853         dataAddressFormats: dataAddressFormats,
71854         dataDeprecated: dataDeprecated,
71855         dataDiscarded: dataDiscarded,
71856         dataLocales: dataLocales,
71857         dataPhoneFormats: dataPhoneFormats,
71858         dataShortcuts: dataShortcuts,
71859         dataImperial: dataImperial,
71860         dataDriveLeft: dataDriveLeft,
71861         dataEn: en,
71862         geoAngle: geoAngle,
71863         geoChooseEdge: geoChooseEdge,
71864         geoCross: geoCross,
71865         geoEdgeEqual: geoEdgeEqual,
71866         geoEuclideanDistance: geoEuclideanDistance,
71867         geoExtent: geoExtent,
71868         geoInterp: geoInterp,
71869         geoRawMercator: geoRawMercator,
71870         geoRoundCoords: geoRoundCoords,
71871         geoRotate: geoRotate,
71872         geoLatToMeters: geoLatToMeters,
71873         geoLineIntersection: geoLineIntersection,
71874         geoLonToMeters: geoLonToMeters,
71875         geoMetersToLat: geoMetersToLat,
71876         geoMetersToLon: geoMetersToLon,
71877         geoMetersToOffset: geoMetersToOffset,
71878         geoOffsetToMeters: geoOffsetToMeters,
71879         geoPathIntersections: geoPathIntersections,
71880         geoPathLength: geoPathLength,
71881         geoPointInPolygon: geoPointInPolygon,
71882         geoPolygonContainsPolygon: geoPolygonContainsPolygon,
71883         geoPolygonIntersectsPolygon: geoPolygonIntersectsPolygon,
71884         geoSphericalDistance: geoSphericalDistance,
71885         modeAddArea: modeAddArea,
71886         modeAddLine: modeAddLine,
71887         modeAddPoint: modeAddPoint,
71888         modeBrowse: modeBrowse,
71889         modeDragNode: modeDragNode,
71890         modeDrawArea: modeDrawArea,
71891         modeDrawLine: modeDrawLine,
71892         modeMove: modeMove,
71893         modeRotate: modeRotate,
71894         modeSave: modeSave,
71895         modeSelect: modeSelect,
71896         operationCircularize: operationCircularize,
71897         operationContinue: operationContinue,
71898         operationDelete: operationDelete,
71899         operationDisconnect: operationDisconnect,
71900         operationMerge: operationMerge,
71901         operationMove: operationMove,
71902         operationOrthogonalize: operationOrthogonalize,
71903         operationReflectShort: operationReflectShort,
71904         operationReflectLong: operationReflectLong,
71905         operationReverse: operationReverse,
71906         operationRotate: operationRotate,
71907         operationSplit: operationSplit,
71908         operationStraighten: operationStraighten,
71909         osmChangeset: osmChangeset,
71910         osmEntity: osmEntity,
71911         osmNode: osmNode,
71912         osmRelation: osmRelation,
71913         osmWay: osmWay,
71914         osmIntersection: osmIntersection,
71915         osmTurn: osmTurn,
71916         osmInferRestriction: osmInferRestriction,
71917         osmLanes: osmLanes,
71918         osmIsSimpleMultipolygonOuterMember: osmIsSimpleMultipolygonOuterMember,
71919         osmSimpleMultipolygonOuterMember: osmSimpleMultipolygonOuterMember,
71920         osmJoinWays: osmJoinWays,
71921         osmOneWayTags: osmOneWayTags,
71922         osmPavedTags: osmPavedTags,
71923         osmIsInterestingTag: osmIsInterestingTag,
71924         presetCategory: presetCategory,
71925         presetCollection: presetCollection,
71926         presetField: presetField,
71927         presetPreset: presetPreset,
71928         presetIndex: presetIndex,
71929         rendererBackgroundSource: rendererBackgroundSource,
71930         rendererBackground: rendererBackground,
71931         rendererFeatures: rendererFeatures,
71932         rendererMap: rendererMap,
71933         rendererTileLayer: rendererTileLayer,
71934         services: services,
71935         serviceMapillary: serviceMapillary,
71936         serviceNominatim: serviceNominatim,
71937         serviceOpenstreetcam: serviceOpenstreetcam,
71938         serviceOsm: serviceOsm,
71939         serviceTaginfo: serviceTaginfo,
71940         serviceWikidata: serviceWikidata,
71941         serviceWikipedia: serviceWikipedia,
71942         svgAreas: svgAreas,
71943         svgDebug: svgDebug,
71944         svgDefs: svgDefs,
71945         svgGpx: svgGpx,
71946         svgIcon: svgIcon,
71947         svgLabels: svgLabels,
71948         svgLayers: svgLayers,
71949         svgLines: svgLines,
71950         svgMapillaryImages: svgMapillaryImages,
71951         svgMapillarySigns: svgMapillarySigns,
71952         svgMidpoints: svgMidpoints,
71953         svgOneWaySegments: svgOneWaySegments,
71954         svgOpenstreetcamImages: svgOpenstreetcamImages,
71955         svgOsm: svgOsm,
71956         svgPath: svgPath,
71957         svgPointTransform: svgPointTransform,
71958         svgPoints: svgPoints,
71959         svgRelationMemberTags: svgRelationMemberTags,
71960         svgTagClasses: svgTagClasses,
71961         svgTurns: svgTurns,
71962         svgVertices: svgVertices,
71963         uiFields: uiFields,
71964         uiFieldDefaultCheck: uiFieldCheck,
71965         uiFieldOnewayCheck: uiFieldCheck,
71966         uiFieldCheck: uiFieldCheck,
71967         uiFieldMultiCombo: uiFieldCombo,
71968         uiFieldNetworkCombo: uiFieldCombo,
71969         uiFieldSemiCombo: uiFieldCombo,
71970         uiFieldTypeCombo: uiFieldCombo,
71971         uiFieldCombo: uiFieldCombo,
71972         uiFieldUrl: uiFieldText,
71973         uiFieldNumber: uiFieldText,
71974         uiFieldTel: uiFieldText,
71975         uiFieldEmail: uiFieldText,
71976         uiFieldText: uiFieldText,
71977         uiFieldAccess: uiFieldAccess,
71978         uiFieldAddress: uiFieldAddress,
71979         uiFieldCycleway: uiFieldCycleway,
71980         uiFieldLanes: uiFieldLanes,
71981         uiFieldLocalized: uiFieldLocalized,
71982         uiFieldMaxspeed: uiFieldMaxspeed,
71983         uiFieldStructureRadio: uiFieldRadio,
71984         uiFieldRadio: uiFieldRadio,
71985         uiFieldRestrictions: uiFieldRestrictions,
71986         uiFieldTextarea: uiFieldTextarea,
71987         uiFieldWikipedia: uiFieldWikipedia,
71988         uiIntro: uiIntro,
71989         uiInfoPanels: uiInfoPanels,
71990         uiPanelBackground: uiPanelBackground,
71991         uiPanelHistory: uiPanelHistory,
71992         uiPanelLocation: uiPanelLocation,
71993         uiPanelMeasurement: uiPanelMeasurement,
71994         uiInit: uiInit,
71995         uiAccount: uiAccount,
71996         uiAttribution: uiAttribution,
71997         uiBackground: uiBackground,
71998         uiChangesetEditor: uiChangesetEditor,
71999         uiCmd: uiCmd,
72000         uiCommit: uiCommit,
72001         uiCommitChanges: uiCommitChanges,
72002         uiCommitWarnings: uiCommitWarnings,
72003         uiConfirm: uiConfirm,
72004         uiConflicts: uiConflicts,
72005         uiContributors: uiContributors,
72006         uiCurtain: uiCurtain,
72007         uiDisclosure: uiDisclosure,
72008         uiEditMenu: uiEditMenu,
72009         uiEntityEditor: uiEntityEditor,
72010         uiFeatureInfo: uiFeatureInfo,
72011         uiFeatureList: uiFeatureList,
72012         uiField: uiField,
72013         uiFlash: uiFlash,
72014         uiFormFields: uiFormFields,
72015         uiFullScreen: uiFullScreen,
72016         uiGeolocate: uiGeolocate,
72017         uiHelp: uiHelp,
72018         uiInfo: uiInfo,
72019         uiInspector: uiInspector,
72020         uiLasso: uiLasso,
72021         uiLoading: uiLoading,
72022         uiMapData: uiMapData,
72023         uiMapInMap: uiMapInMap,
72024         uiModal: uiModal,
72025         uiModes: uiModes,
72026         uiNotice: uiNotice,
72027         uiPresetEditor: uiPresetEditor,
72028         uiPresetIcon: uiPresetIcon,
72029         uiPresetList: uiPresetList,
72030         uiRadialMenu: uiRadialMenu,
72031         uiRawMemberEditor: uiRawMemberEditor,
72032         uiRawMembershipEditor: uiRawMembershipEditor,
72033         uiRawTagEditor: uiRawTagEditor,
72034         uiRestore: uiRestore,
72035         uiSave: uiSave,
72036         uiScale: uiScale,
72037         uiSelectionList: uiSelectionList,
72038         uiSidebar: uiSidebar,
72039         uiSourceSwitch: uiSourceSwitch,
72040         uiSpinner: uiSpinner,
72041         uiSplash: uiSplash,
72042         uiStatus: uiStatus,
72043         uiSuccess: uiSuccess,
72044         uiTagReference: uiTagReference,
72045         uiToggle: uiToggle,
72046         uiTooltipHtml: uiTooltipHtml,
72047         uiUndoRedo: uiUndoRedo,
72048         uiVersion: uiVersion,
72049         uiViewOnOSM: uiViewOnOSM,
72050         uiZoom: uiZoom,
72051         utilAsyncMap: utilAsyncMap,
72052         utilCallWhenIdle: utilCallWhenIdle,
72053         utilDisplayName: utilDisplayName,
72054         utilDisplayNameForPath: utilDisplayNameForPath,
72055         utilDisplayType: utilDisplayType,
72056         utilEditDistance: utilEditDistance,
72057         utilEntitySelector: utilEntitySelector,
72058         utilEntityOrMemberSelector: utilEntityOrMemberSelector,
72059         utilFastMouse: utilFastMouse,
72060         utilFunctor: utilFunctor,
72061         utilGetAllNodes: utilGetAllNodes,
72062         utilGetPrototypeOf: utilGetPrototypeOf,
72063         utilGetSetValue: utilGetSetValue,
72064         utilIdleWorker: utilIdleWorker,
72065         utilNoAuto: utilNoAuto,
72066         utilPrefixCSSProperty: utilPrefixCSSProperty,
72067         utilPrefixDOMProperty: utilPrefixDOMProperty,
72068         utilQsString: utilQsString,
72069         utilRebind: utilRebind,
72070         utilSetTransform: utilSetTransform,
72071         utilSessionMutex: utilSessionMutex,
72072         utilStringQs: utilStringQs,
72073         utilSuggestNames: utilSuggestNames,
72074         utilTagText: utilTagText,
72075         utilTriggerEvent: utilTriggerEvent,
72076         utilWrap: utilWrap,
72077         d3combobox: d3combobox,
72078         d3geoTile: d3geoTile,
72079         d3keybinding: d3keybinding,
72080         validationDeprecatedTag: validationDeprecatedTag,
72081         validationDisconnectedHighway: validationDisconnectedHighway,
72082         validationManyDeletions: validationManyDeletions,
72083         validationMissingTag: validationMissingTag,
72084         validationOldMultipolygon: validationOldMultipolygon,
72085         validationTagSuggestsArea: validationTagSuggestsArea
72086 });
72087
72088 window.iD = iD;
72089
72090 }());
72091 //# sourceMappingURL=iD.js.map