]> git.openstreetmap.org Git - nominatim-ui.git/blob - dist/build/bundle.js
version 2.0 - converted to Svelte framework
[nominatim-ui.git] / dist / build / bundle.js
1
2 (function(l, r) { if (l.getElementById('livereloadscript')) return; r = l.createElement('script'); r.async = 1; r.src = '//' + (window.location.host || 'localhost').split(':')[0] + ':35729/livereload.js?snipver=1'; r.id = 'livereloadscript'; l.getElementsByTagName('head')[0].appendChild(r) })(window.document);
3 (function () {
4     'use strict';
5
6     function noop() { }
7     function add_location(element, file, line, column, char) {
8         element.__svelte_meta = {
9             loc: { file, line, column, char }
10         };
11     }
12     function run(fn) {
13         return fn();
14     }
15     function blank_object() {
16         return Object.create(null);
17     }
18     function run_all(fns) {
19         fns.forEach(run);
20     }
21     function is_function(thing) {
22         return typeof thing === 'function';
23     }
24     function safe_not_equal(a, b) {
25         return a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');
26     }
27     function is_empty(obj) {
28         return Object.keys(obj).length === 0;
29     }
30     function subscribe(store, ...callbacks) {
31         if (store == null) {
32             return noop;
33         }
34         const unsub = store.subscribe(...callbacks);
35         return unsub.unsubscribe ? () => unsub.unsubscribe() : unsub;
36     }
37     function get_store_value(store) {
38         let value;
39         subscribe(store, _ => value = _)();
40         return value;
41     }
42     function action_destroyer(action_result) {
43         return action_result && is_function(action_result.destroy) ? action_result.destroy : noop;
44     }
45
46     function append(target, node) {
47         target.appendChild(node);
48     }
49     function insert(target, node, anchor) {
50         target.insertBefore(node, anchor || null);
51     }
52     function detach(node) {
53         node.parentNode.removeChild(node);
54     }
55     function destroy_each(iterations, detaching) {
56         for (let i = 0; i < iterations.length; i += 1) {
57             if (iterations[i])
58                 iterations[i].d(detaching);
59         }
60     }
61     function element(name) {
62         return document.createElement(name);
63     }
64     function text(data) {
65         return document.createTextNode(data);
66     }
67     function space() {
68         return text(' ');
69     }
70     function empty() {
71         return text('');
72     }
73     function listen(node, event, handler, options) {
74         node.addEventListener(event, handler, options);
75         return () => node.removeEventListener(event, handler, options);
76     }
77     function prevent_default(fn) {
78         return function (event) {
79             event.preventDefault();
80             // @ts-ignore
81             return fn.call(this, event);
82         };
83     }
84     function stop_propagation(fn) {
85         return function (event) {
86             event.stopPropagation();
87             // @ts-ignore
88             return fn.call(this, event);
89         };
90     }
91     function attr(node, attribute, value) {
92         if (value == null)
93             node.removeAttribute(attribute);
94         else if (node.getAttribute(attribute) !== value)
95             node.setAttribute(attribute, value);
96     }
97     function children(element) {
98         return Array.from(element.childNodes);
99     }
100     function set_style(node, key, value, important) {
101         node.style.setProperty(key, value, important ? 'important' : '');
102     }
103     function select_option(select, value) {
104         for (let i = 0; i < select.options.length; i += 1) {
105             const option = select.options[i];
106             if (option.__value === value) {
107                 option.selected = true;
108                 return;
109             }
110         }
111     }
112     function toggle_class(element, name, toggle) {
113         element.classList[toggle ? 'add' : 'remove'](name);
114     }
115     function custom_event(type, detail) {
116         const e = document.createEvent('CustomEvent');
117         e.initCustomEvent(type, false, false, detail);
118         return e;
119     }
120
121     let current_component;
122     function set_current_component(component) {
123         current_component = component;
124     }
125     function get_current_component() {
126         if (!current_component)
127             throw new Error('Function called outside component initialization');
128         return current_component;
129     }
130     function onMount(fn) {
131         get_current_component().$$.on_mount.push(fn);
132     }
133
134     const dirty_components = [];
135     const binding_callbacks = [];
136     const render_callbacks = [];
137     const flush_callbacks = [];
138     const resolved_promise = Promise.resolve();
139     let update_scheduled = false;
140     function schedule_update() {
141         if (!update_scheduled) {
142             update_scheduled = true;
143             resolved_promise.then(flush);
144         }
145     }
146     function add_render_callback(fn) {
147         render_callbacks.push(fn);
148     }
149     let flushing = false;
150     const seen_callbacks = new Set();
151     function flush() {
152         if (flushing)
153             return;
154         flushing = true;
155         do {
156             // first, call beforeUpdate functions
157             // and update components
158             for (let i = 0; i < dirty_components.length; i += 1) {
159                 const component = dirty_components[i];
160                 set_current_component(component);
161                 update(component.$$);
162             }
163             set_current_component(null);
164             dirty_components.length = 0;
165             while (binding_callbacks.length)
166                 binding_callbacks.pop()();
167             // then, once components are updated, call
168             // afterUpdate functions. This may cause
169             // subsequent updates...
170             for (let i = 0; i < render_callbacks.length; i += 1) {
171                 const callback = render_callbacks[i];
172                 if (!seen_callbacks.has(callback)) {
173                     // ...so guard against infinite loops
174                     seen_callbacks.add(callback);
175                     callback();
176                 }
177             }
178             render_callbacks.length = 0;
179         } while (dirty_components.length);
180         while (flush_callbacks.length) {
181             flush_callbacks.pop()();
182         }
183         update_scheduled = false;
184         flushing = false;
185         seen_callbacks.clear();
186     }
187     function update($$) {
188         if ($$.fragment !== null) {
189             $$.update();
190             run_all($$.before_update);
191             const dirty = $$.dirty;
192             $$.dirty = [-1];
193             $$.fragment && $$.fragment.p($$.ctx, dirty);
194             $$.after_update.forEach(add_render_callback);
195         }
196     }
197     const outroing = new Set();
198     let outros;
199     function group_outros() {
200         outros = {
201             r: 0,
202             c: [],
203             p: outros // parent group
204         };
205     }
206     function check_outros() {
207         if (!outros.r) {
208             run_all(outros.c);
209         }
210         outros = outros.p;
211     }
212     function transition_in(block, local) {
213         if (block && block.i) {
214             outroing.delete(block);
215             block.i(local);
216         }
217     }
218     function transition_out(block, local, detach, callback) {
219         if (block && block.o) {
220             if (outroing.has(block))
221                 return;
222             outroing.add(block);
223             outros.c.push(() => {
224                 outroing.delete(block);
225                 if (callback) {
226                     if (detach)
227                         block.d(1);
228                     callback();
229                 }
230             });
231             block.o(local);
232         }
233     }
234
235     const globals = (typeof window !== 'undefined'
236         ? window
237         : typeof globalThis !== 'undefined'
238             ? globalThis
239             : global);
240     function create_component(block) {
241         block && block.c();
242     }
243     function mount_component(component, target, anchor) {
244         const { fragment, on_mount, on_destroy, after_update } = component.$$;
245         fragment && fragment.m(target, anchor);
246         // onMount happens before the initial afterUpdate
247         add_render_callback(() => {
248             const new_on_destroy = on_mount.map(run).filter(is_function);
249             if (on_destroy) {
250                 on_destroy.push(...new_on_destroy);
251             }
252             else {
253                 // Edge case - component was destroyed immediately,
254                 // most likely as a result of a binding initialising
255                 run_all(new_on_destroy);
256             }
257             component.$$.on_mount = [];
258         });
259         after_update.forEach(add_render_callback);
260     }
261     function destroy_component(component, detaching) {
262         const $$ = component.$$;
263         if ($$.fragment !== null) {
264             run_all($$.on_destroy);
265             $$.fragment && $$.fragment.d(detaching);
266             // TODO null out other refs, including component.$$ (but need to
267             // preserve final state?)
268             $$.on_destroy = $$.fragment = null;
269             $$.ctx = [];
270         }
271     }
272     function make_dirty(component, i) {
273         if (component.$$.dirty[0] === -1) {
274             dirty_components.push(component);
275             schedule_update();
276             component.$$.dirty.fill(0);
277         }
278         component.$$.dirty[(i / 31) | 0] |= (1 << (i % 31));
279     }
280     function init(component, options, instance, create_fragment, not_equal, props, dirty = [-1]) {
281         const parent_component = current_component;
282         set_current_component(component);
283         const prop_values = options.props || {};
284         const $$ = component.$$ = {
285             fragment: null,
286             ctx: null,
287             // state
288             props,
289             update: noop,
290             not_equal,
291             bound: blank_object(),
292             // lifecycle
293             on_mount: [],
294             on_destroy: [],
295             before_update: [],
296             after_update: [],
297             context: new Map(parent_component ? parent_component.$$.context : []),
298             // everything else
299             callbacks: blank_object(),
300             dirty,
301             skip_bound: false
302         };
303         let ready = false;
304         $$.ctx = instance
305             ? instance(component, prop_values, (i, ret, ...rest) => {
306                 const value = rest.length ? rest[0] : ret;
307                 if ($$.ctx && not_equal($$.ctx[i], $$.ctx[i] = value)) {
308                     if (!$$.skip_bound && $$.bound[i])
309                         $$.bound[i](value);
310                     if (ready)
311                         make_dirty(component, i);
312                 }
313                 return ret;
314             })
315             : [];
316         $$.update();
317         ready = true;
318         run_all($$.before_update);
319         // `false` as a special case of no DOM component
320         $$.fragment = create_fragment ? create_fragment($$.ctx) : false;
321         if (options.target) {
322             if (options.hydrate) {
323                 const nodes = children(options.target);
324                 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
325                 $$.fragment && $$.fragment.l(nodes);
326                 nodes.forEach(detach);
327             }
328             else {
329                 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
330                 $$.fragment && $$.fragment.c();
331             }
332             if (options.intro)
333                 transition_in(component.$$.fragment);
334             mount_component(component, options.target, options.anchor);
335             flush();
336         }
337         set_current_component(parent_component);
338     }
339     /**
340      * Base class for Svelte components. Used when dev=false.
341      */
342     class SvelteComponent {
343         $destroy() {
344             destroy_component(this, 1);
345             this.$destroy = noop;
346         }
347         $on(type, callback) {
348             const callbacks = (this.$$.callbacks[type] || (this.$$.callbacks[type] = []));
349             callbacks.push(callback);
350             return () => {
351                 const index = callbacks.indexOf(callback);
352                 if (index !== -1)
353                     callbacks.splice(index, 1);
354             };
355         }
356         $set($$props) {
357             if (this.$$set && !is_empty($$props)) {
358                 this.$$.skip_bound = true;
359                 this.$$set($$props);
360                 this.$$.skip_bound = false;
361             }
362         }
363     }
364
365     function dispatch_dev(type, detail) {
366         document.dispatchEvent(custom_event(type, Object.assign({ version: '3.31.2' }, detail)));
367     }
368     function append_dev(target, node) {
369         dispatch_dev('SvelteDOMInsert', { target, node });
370         append(target, node);
371     }
372     function insert_dev(target, node, anchor) {
373         dispatch_dev('SvelteDOMInsert', { target, node, anchor });
374         insert(target, node, anchor);
375     }
376     function detach_dev(node) {
377         dispatch_dev('SvelteDOMRemove', { node });
378         detach(node);
379     }
380     function listen_dev(node, event, handler, options, has_prevent_default, has_stop_propagation) {
381         const modifiers = options === true ? ['capture'] : options ? Array.from(Object.keys(options)) : [];
382         if (has_prevent_default)
383             modifiers.push('preventDefault');
384         if (has_stop_propagation)
385             modifiers.push('stopPropagation');
386         dispatch_dev('SvelteDOMAddEventListener', { node, event, handler, modifiers });
387         const dispose = listen(node, event, handler, options);
388         return () => {
389             dispatch_dev('SvelteDOMRemoveEventListener', { node, event, handler, modifiers });
390             dispose();
391         };
392     }
393     function attr_dev(node, attribute, value) {
394         attr(node, attribute, value);
395         if (value == null)
396             dispatch_dev('SvelteDOMRemoveAttribute', { node, attribute });
397         else
398             dispatch_dev('SvelteDOMSetAttribute', { node, attribute, value });
399     }
400     function prop_dev(node, property, value) {
401         node[property] = value;
402         dispatch_dev('SvelteDOMSetProperty', { node, property, value });
403     }
404     function set_data_dev(text, data) {
405         data = '' + data;
406         if (text.wholeText === data)
407             return;
408         dispatch_dev('SvelteDOMSetData', { node: text, data });
409         text.data = data;
410     }
411     function validate_each_argument(arg) {
412         if (typeof arg !== 'string' && !(arg && typeof arg === 'object' && 'length' in arg)) {
413             let msg = '{#each} only iterates over array-like objects.';
414             if (typeof Symbol === 'function' && arg && Symbol.iterator in arg) {
415                 msg += ' You can use a spread to convert this iterable into an array.';
416             }
417             throw new Error(msg);
418         }
419     }
420     function validate_slots(name, slot, keys) {
421         for (const slot_key of Object.keys(slot)) {
422             if (!~keys.indexOf(slot_key)) {
423                 console.warn(`<${name}> received an unexpected slot "${slot_key}".`);
424             }
425         }
426     }
427     /**
428      * Base class for Svelte components with some minor dev-enhancements. Used when dev=true.
429      */
430     class SvelteComponentDev extends SvelteComponent {
431         constructor(options) {
432             if (!options || (!options.target && !options.$$inline)) {
433                 throw new Error("'target' is a required option");
434             }
435             super();
436         }
437         $destroy() {
438             super.$destroy();
439             this.$destroy = () => {
440                 console.warn('Component was already destroyed'); // eslint-disable-line no-console
441             };
442         }
443         $capture_state() { }
444         $inject_state() { }
445     }
446
447     var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
448
449     function createCommonjsModule(fn) {
450       var module = { exports: {} };
451         return fn(module, module.exports), module.exports;
452     }
453
454     /*!
455      * jQuery JavaScript Library v3.5.1
456      * https://jquery.com/
457      *
458      * Includes Sizzle.js
459      * https://sizzlejs.com/
460      *
461      * Copyright JS Foundation and other contributors
462      * Released under the MIT license
463      * https://jquery.org/license
464      *
465      * Date: 2020-05-04T22:49Z
466      */
467
468     var jquery = createCommonjsModule(function (module) {
469     ( function( global, factory ) {
470
471         {
472
473                 // For CommonJS and CommonJS-like environments where a proper `window`
474                 // is present, execute the factory and get jQuery.
475                 // For environments that do not have a `window` with a `document`
476                 // (such as Node.js), expose a factory as module.exports.
477                 // This accentuates the need for the creation of a real `window`.
478                 // e.g. var jQuery = require("jquery")(window);
479                 // See ticket #14549 for more info.
480                 module.exports = global.document ?
481                         factory( global, true ) :
482                         function( w ) {
483                                 if ( !w.document ) {
484                                         throw new Error( "jQuery requires a window with a document" );
485                                 }
486                                 return factory( w );
487                         };
488         }
489
490     // Pass this if window is not defined yet
491     } )( typeof window !== "undefined" ? window : commonjsGlobal, function( window, noGlobal ) {
492
493     var arr = [];
494
495     var getProto = Object.getPrototypeOf;
496
497     var slice = arr.slice;
498
499     var flat = arr.flat ? function( array ) {
500         return arr.flat.call( array );
501     } : function( array ) {
502         return arr.concat.apply( [], array );
503     };
504
505
506     var push = arr.push;
507
508     var indexOf = arr.indexOf;
509
510     var class2type = {};
511
512     var toString = class2type.toString;
513
514     var hasOwn = class2type.hasOwnProperty;
515
516     var fnToString = hasOwn.toString;
517
518     var ObjectFunctionString = fnToString.call( Object );
519
520     var support = {};
521
522     var isFunction = function isFunction( obj ) {
523
524           // Support: Chrome <=57, Firefox <=52
525           // In some browsers, typeof returns "function" for HTML <object> elements
526           // (i.e., `typeof document.createElement( "object" ) === "function"`).
527           // We don't want to classify *any* DOM node as a function.
528           return typeof obj === "function" && typeof obj.nodeType !== "number";
529       };
530
531
532     var isWindow = function isWindow( obj ) {
533                 return obj != null && obj === obj.window;
534         };
535
536
537     var document = window.document;
538
539
540
541         var preservedScriptAttributes = {
542                 type: true,
543                 src: true,
544                 nonce: true,
545                 noModule: true
546         };
547
548         function DOMEval( code, node, doc ) {
549                 doc = doc || document;
550
551                 var i, val,
552                         script = doc.createElement( "script" );
553
554                 script.text = code;
555                 if ( node ) {
556                         for ( i in preservedScriptAttributes ) {
557
558                                 // Support: Firefox 64+, Edge 18+
559                                 // Some browsers don't support the "nonce" property on scripts.
560                                 // On the other hand, just using `getAttribute` is not enough as
561                                 // the `nonce` attribute is reset to an empty string whenever it
562                                 // becomes browsing-context connected.
563                                 // See https://github.com/whatwg/html/issues/2369
564                                 // See https://html.spec.whatwg.org/#nonce-attributes
565                                 // The `node.getAttribute` check was added for the sake of
566                                 // `jQuery.globalEval` so that it can fake a nonce-containing node
567                                 // via an object.
568                                 val = node[ i ] || node.getAttribute && node.getAttribute( i );
569                                 if ( val ) {
570                                         script.setAttribute( i, val );
571                                 }
572                         }
573                 }
574                 doc.head.appendChild( script ).parentNode.removeChild( script );
575         }
576
577
578     function toType( obj ) {
579         if ( obj == null ) {
580                 return obj + "";
581         }
582
583         // Support: Android <=2.3 only (functionish RegExp)
584         return typeof obj === "object" || typeof obj === "function" ?
585                 class2type[ toString.call( obj ) ] || "object" :
586                 typeof obj;
587     }
588     /* global Symbol */
589     // Defining this global in .eslintrc.json would create a danger of using the global
590     // unguarded in another place, it seems safer to define global only for this module
591
592
593
594     var
595         version = "3.5.1",
596
597         // Define a local copy of jQuery
598         jQuery = function( selector, context ) {
599
600                 // The jQuery object is actually just the init constructor 'enhanced'
601                 // Need init if jQuery is called (just allow error to be thrown if not included)
602                 return new jQuery.fn.init( selector, context );
603         };
604
605     jQuery.fn = jQuery.prototype = {
606
607         // The current version of jQuery being used
608         jquery: version,
609
610         constructor: jQuery,
611
612         // The default length of a jQuery object is 0
613         length: 0,
614
615         toArray: function() {
616                 return slice.call( this );
617         },
618
619         // Get the Nth element in the matched element set OR
620         // Get the whole matched element set as a clean array
621         get: function( num ) {
622
623                 // Return all the elements in a clean array
624                 if ( num == null ) {
625                         return slice.call( this );
626                 }
627
628                 // Return just the one element from the set
629                 return num < 0 ? this[ num + this.length ] : this[ num ];
630         },
631
632         // Take an array of elements and push it onto the stack
633         // (returning the new matched element set)
634         pushStack: function( elems ) {
635
636                 // Build a new jQuery matched element set
637                 var ret = jQuery.merge( this.constructor(), elems );
638
639                 // Add the old object onto the stack (as a reference)
640                 ret.prevObject = this;
641
642                 // Return the newly-formed element set
643                 return ret;
644         },
645
646         // Execute a callback for every element in the matched set.
647         each: function( callback ) {
648                 return jQuery.each( this, callback );
649         },
650
651         map: function( callback ) {
652                 return this.pushStack( jQuery.map( this, function( elem, i ) {
653                         return callback.call( elem, i, elem );
654                 } ) );
655         },
656
657         slice: function() {
658                 return this.pushStack( slice.apply( this, arguments ) );
659         },
660
661         first: function() {
662                 return this.eq( 0 );
663         },
664
665         last: function() {
666                 return this.eq( -1 );
667         },
668
669         even: function() {
670                 return this.pushStack( jQuery.grep( this, function( _elem, i ) {
671                         return ( i + 1 ) % 2;
672                 } ) );
673         },
674
675         odd: function() {
676                 return this.pushStack( jQuery.grep( this, function( _elem, i ) {
677                         return i % 2;
678                 } ) );
679         },
680
681         eq: function( i ) {
682                 var len = this.length,
683                         j = +i + ( i < 0 ? len : 0 );
684                 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
685         },
686
687         end: function() {
688                 return this.prevObject || this.constructor();
689         },
690
691         // For internal use only.
692         // Behaves like an Array's method, not like a jQuery method.
693         push: push,
694         sort: arr.sort,
695         splice: arr.splice
696     };
697
698     jQuery.extend = jQuery.fn.extend = function() {
699         var options, name, src, copy, copyIsArray, clone,
700                 target = arguments[ 0 ] || {},
701                 i = 1,
702                 length = arguments.length,
703                 deep = false;
704
705         // Handle a deep copy situation
706         if ( typeof target === "boolean" ) {
707                 deep = target;
708
709                 // Skip the boolean and the target
710                 target = arguments[ i ] || {};
711                 i++;
712         }
713
714         // Handle case when target is a string or something (possible in deep copy)
715         if ( typeof target !== "object" && !isFunction( target ) ) {
716                 target = {};
717         }
718
719         // Extend jQuery itself if only one argument is passed
720         if ( i === length ) {
721                 target = this;
722                 i--;
723         }
724
725         for ( ; i < length; i++ ) {
726
727                 // Only deal with non-null/undefined values
728                 if ( ( options = arguments[ i ] ) != null ) {
729
730                         // Extend the base object
731                         for ( name in options ) {
732                                 copy = options[ name ];
733
734                                 // Prevent Object.prototype pollution
735                                 // Prevent never-ending loop
736                                 if ( name === "__proto__" || target === copy ) {
737                                         continue;
738                                 }
739
740                                 // Recurse if we're merging plain objects or arrays
741                                 if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
742                                         ( copyIsArray = Array.isArray( copy ) ) ) ) {
743                                         src = target[ name ];
744
745                                         // Ensure proper type for the source value
746                                         if ( copyIsArray && !Array.isArray( src ) ) {
747                                                 clone = [];
748                                         } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) {
749                                                 clone = {};
750                                         } else {
751                                                 clone = src;
752                                         }
753                                         copyIsArray = false;
754
755                                         // Never move original objects, clone them
756                                         target[ name ] = jQuery.extend( deep, clone, copy );
757
758                                 // Don't bring in undefined values
759                                 } else if ( copy !== undefined ) {
760                                         target[ name ] = copy;
761                                 }
762                         }
763                 }
764         }
765
766         // Return the modified object
767         return target;
768     };
769
770     jQuery.extend( {
771
772         // Unique for each copy of jQuery on the page
773         expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
774
775         // Assume jQuery is ready without the ready module
776         isReady: true,
777
778         error: function( msg ) {
779                 throw new Error( msg );
780         },
781
782         noop: function() {},
783
784         isPlainObject: function( obj ) {
785                 var proto, Ctor;
786
787                 // Detect obvious negatives
788                 // Use toString instead of jQuery.type to catch host objects
789                 if ( !obj || toString.call( obj ) !== "[object Object]" ) {
790                         return false;
791                 }
792
793                 proto = getProto( obj );
794
795                 // Objects with no prototype (e.g., `Object.create( null )`) are plain
796                 if ( !proto ) {
797                         return true;
798                 }
799
800                 // Objects with prototype are plain iff they were constructed by a global Object function
801                 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
802                 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
803         },
804
805         isEmptyObject: function( obj ) {
806                 var name;
807
808                 for ( name in obj ) {
809                         return false;
810                 }
811                 return true;
812         },
813
814         // Evaluates a script in a provided context; falls back to the global one
815         // if not specified.
816         globalEval: function( code, options, doc ) {
817                 DOMEval( code, { nonce: options && options.nonce }, doc );
818         },
819
820         each: function( obj, callback ) {
821                 var length, i = 0;
822
823                 if ( isArrayLike( obj ) ) {
824                         length = obj.length;
825                         for ( ; i < length; i++ ) {
826                                 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
827                                         break;
828                                 }
829                         }
830                 } else {
831                         for ( i in obj ) {
832                                 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
833                                         break;
834                                 }
835                         }
836                 }
837
838                 return obj;
839         },
840
841         // results is for internal usage only
842         makeArray: function( arr, results ) {
843                 var ret = results || [];
844
845                 if ( arr != null ) {
846                         if ( isArrayLike( Object( arr ) ) ) {
847                                 jQuery.merge( ret,
848                                         typeof arr === "string" ?
849                                         [ arr ] : arr
850                                 );
851                         } else {
852                                 push.call( ret, arr );
853                         }
854                 }
855
856                 return ret;
857         },
858
859         inArray: function( elem, arr, i ) {
860                 return arr == null ? -1 : indexOf.call( arr, elem, i );
861         },
862
863         // Support: Android <=4.0 only, PhantomJS 1 only
864         // push.apply(_, arraylike) throws on ancient WebKit
865         merge: function( first, second ) {
866                 var len = +second.length,
867                         j = 0,
868                         i = first.length;
869
870                 for ( ; j < len; j++ ) {
871                         first[ i++ ] = second[ j ];
872                 }
873
874                 first.length = i;
875
876                 return first;
877         },
878
879         grep: function( elems, callback, invert ) {
880                 var callbackInverse,
881                         matches = [],
882                         i = 0,
883                         length = elems.length,
884                         callbackExpect = !invert;
885
886                 // Go through the array, only saving the items
887                 // that pass the validator function
888                 for ( ; i < length; i++ ) {
889                         callbackInverse = !callback( elems[ i ], i );
890                         if ( callbackInverse !== callbackExpect ) {
891                                 matches.push( elems[ i ] );
892                         }
893                 }
894
895                 return matches;
896         },
897
898         // arg is for internal usage only
899         map: function( elems, callback, arg ) {
900                 var length, value,
901                         i = 0,
902                         ret = [];
903
904                 // Go through the array, translating each of the items to their new values
905                 if ( isArrayLike( elems ) ) {
906                         length = elems.length;
907                         for ( ; i < length; i++ ) {
908                                 value = callback( elems[ i ], i, arg );
909
910                                 if ( value != null ) {
911                                         ret.push( value );
912                                 }
913                         }
914
915                 // Go through every key on the object,
916                 } else {
917                         for ( i in elems ) {
918                                 value = callback( elems[ i ], i, arg );
919
920                                 if ( value != null ) {
921                                         ret.push( value );
922                                 }
923                         }
924                 }
925
926                 // Flatten any nested arrays
927                 return flat( ret );
928         },
929
930         // A global GUID counter for objects
931         guid: 1,
932
933         // jQuery.support is not used in Core but other projects attach their
934         // properties to it so it needs to exist.
935         support: support
936     } );
937
938     if ( typeof Symbol === "function" ) {
939         jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
940     }
941
942     // Populate the class2type map
943     jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
944     function( _i, name ) {
945         class2type[ "[object " + name + "]" ] = name.toLowerCase();
946     } );
947
948     function isArrayLike( obj ) {
949
950         // Support: real iOS 8.2 only (not reproducible in simulator)
951         // `in` check used to prevent JIT error (gh-2145)
952         // hasOwn isn't used here due to false negatives
953         // regarding Nodelist length in IE
954         var length = !!obj && "length" in obj && obj.length,
955                 type = toType( obj );
956
957         if ( isFunction( obj ) || isWindow( obj ) ) {
958                 return false;
959         }
960
961         return type === "array" || length === 0 ||
962                 typeof length === "number" && length > 0 && ( length - 1 ) in obj;
963     }
964     var Sizzle =
965     /*!
966      * Sizzle CSS Selector Engine v2.3.5
967      * https://sizzlejs.com/
968      *
969      * Copyright JS Foundation and other contributors
970      * Released under the MIT license
971      * https://js.foundation/
972      *
973      * Date: 2020-03-14
974      */
975     ( function( window ) {
976     var i,
977         support,
978         Expr,
979         getText,
980         isXML,
981         tokenize,
982         compile,
983         select,
984         outermostContext,
985         sortInput,
986         hasDuplicate,
987
988         // Local document vars
989         setDocument,
990         document,
991         docElem,
992         documentIsHTML,
993         rbuggyQSA,
994         rbuggyMatches,
995         matches,
996         contains,
997
998         // Instance-specific data
999         expando = "sizzle" + 1 * new Date(),
1000         preferredDoc = window.document,
1001         dirruns = 0,
1002         done = 0,
1003         classCache = createCache(),
1004         tokenCache = createCache(),
1005         compilerCache = createCache(),
1006         nonnativeSelectorCache = createCache(),
1007         sortOrder = function( a, b ) {
1008                 if ( a === b ) {
1009                         hasDuplicate = true;
1010                 }
1011                 return 0;
1012         },
1013
1014         // Instance methods
1015         hasOwn = ( {} ).hasOwnProperty,
1016         arr = [],
1017         pop = arr.pop,
1018         pushNative = arr.push,
1019         push = arr.push,
1020         slice = arr.slice,
1021
1022         // Use a stripped-down indexOf as it's faster than native
1023         // https://jsperf.com/thor-indexof-vs-for/5
1024         indexOf = function( list, elem ) {
1025                 var i = 0,
1026                         len = list.length;
1027                 for ( ; i < len; i++ ) {
1028                         if ( list[ i ] === elem ) {
1029                                 return i;
1030                         }
1031                 }
1032                 return -1;
1033         },
1034
1035         booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" +
1036                 "ismap|loop|multiple|open|readonly|required|scoped",
1037
1038         // Regular expressions
1039
1040         // http://www.w3.org/TR/css3-selectors/#whitespace
1041         whitespace = "[\\x20\\t\\r\\n\\f]",
1042
1043         // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram
1044         identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace +
1045                 "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",
1046
1047         // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
1048         attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
1049
1050                 // Operator (capture 2)
1051                 "*([*^$|!~]?=)" + whitespace +
1052
1053                 // "Attribute values must be CSS identifiers [capture 5]
1054                 // or strings [capture 3 or capture 4]"
1055                 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" +
1056                 whitespace + "*\\]",
1057
1058         pseudos = ":(" + identifier + ")(?:\\((" +
1059
1060                 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
1061                 // 1. quoted (capture 3; capture 4 or capture 5)
1062                 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
1063
1064                 // 2. simple (capture 6)
1065                 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
1066
1067                 // 3. anything else (capture 2)
1068                 ".*" +
1069                 ")\\)|)",
1070
1071         // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
1072         rwhitespace = new RegExp( whitespace + "+", "g" ),
1073         rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" +
1074                 whitespace + "+$", "g" ),
1075
1076         rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
1077         rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace +
1078                 "*" ),
1079         rdescend = new RegExp( whitespace + "|>" ),
1080
1081         rpseudo = new RegExp( pseudos ),
1082         ridentifier = new RegExp( "^" + identifier + "$" ),
1083
1084         matchExpr = {
1085                 "ID": new RegExp( "^#(" + identifier + ")" ),
1086                 "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
1087                 "TAG": new RegExp( "^(" + identifier + "|[*])" ),
1088                 "ATTR": new RegExp( "^" + attributes ),
1089                 "PSEUDO": new RegExp( "^" + pseudos ),
1090                 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" +
1091                         whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" +
1092                         whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
1093                 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
1094
1095                 // For use in libraries implementing .is()
1096                 // We use this for POS matching in `select`
1097                 "needsContext": new RegExp( "^" + whitespace +
1098                         "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace +
1099                         "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
1100         },
1101
1102         rhtml = /HTML$/i,
1103         rinputs = /^(?:input|select|textarea|button)$/i,
1104         rheader = /^h\d$/i,
1105
1106         rnative = /^[^{]+\{\s*\[native \w/,
1107
1108         // Easily-parseable/retrievable ID or TAG or CLASS selectors
1109         rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
1110
1111         rsibling = /[+~]/,
1112
1113         // CSS escapes
1114         // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
1115         runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ),
1116         funescape = function( escape, nonHex ) {
1117                 var high = "0x" + escape.slice( 1 ) - 0x10000;
1118
1119                 return nonHex ?
1120
1121                         // Strip the backslash prefix from a non-hex escape sequence
1122                         nonHex :
1123
1124                         // Replace a hexadecimal escape sequence with the encoded Unicode code point
1125                         // Support: IE <=11+
1126                         // For values outside the Basic Multilingual Plane (BMP), manually construct a
1127                         // surrogate pair
1128                         high < 0 ?
1129                                 String.fromCharCode( high + 0x10000 ) :
1130                                 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
1131         },
1132
1133         // CSS string/identifier serialization
1134         // https://drafts.csswg.org/cssom/#common-serializing-idioms
1135         rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
1136         fcssescape = function( ch, asCodePoint ) {
1137                 if ( asCodePoint ) {
1138
1139                         // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
1140                         if ( ch === "\0" ) {
1141                                 return "\uFFFD";
1142                         }
1143
1144                         // Control characters and (dependent upon position) numbers get escaped as code points
1145                         return ch.slice( 0, -1 ) + "\\" +
1146                                 ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
1147                 }
1148
1149                 // Other potentially-special ASCII characters get backslash-escaped
1150                 return "\\" + ch;
1151         },
1152
1153         // Used for iframes
1154         // See setDocument()
1155         // Removing the function wrapper causes a "Permission Denied"
1156         // error in IE
1157         unloadHandler = function() {
1158                 setDocument();
1159         },
1160
1161         inDisabledFieldset = addCombinator(
1162                 function( elem ) {
1163                         return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset";
1164                 },
1165                 { dir: "parentNode", next: "legend" }
1166         );
1167
1168     // Optimize for push.apply( _, NodeList )
1169     try {
1170         push.apply(
1171                 ( arr = slice.call( preferredDoc.childNodes ) ),
1172                 preferredDoc.childNodes
1173         );
1174
1175         // Support: Android<4.0
1176         // Detect silently failing push.apply
1177         // eslint-disable-next-line no-unused-expressions
1178         arr[ preferredDoc.childNodes.length ].nodeType;
1179     } catch ( e ) {
1180         push = { apply: arr.length ?
1181
1182                 // Leverage slice if possible
1183                 function( target, els ) {
1184                         pushNative.apply( target, slice.call( els ) );
1185                 } :
1186
1187                 // Support: IE<9
1188                 // Otherwise append directly
1189                 function( target, els ) {
1190                         var j = target.length,
1191                                 i = 0;
1192
1193                         // Can't trust NodeList.length
1194                         while ( ( target[ j++ ] = els[ i++ ] ) ) {}
1195                         target.length = j - 1;
1196                 }
1197         };
1198     }
1199
1200     function Sizzle( selector, context, results, seed ) {
1201         var m, i, elem, nid, match, groups, newSelector,
1202                 newContext = context && context.ownerDocument,
1203
1204                 // nodeType defaults to 9, since context defaults to document
1205                 nodeType = context ? context.nodeType : 9;
1206
1207         results = results || [];
1208
1209         // Return early from calls with invalid selector or context
1210         if ( typeof selector !== "string" || !selector ||
1211                 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
1212
1213                 return results;
1214         }
1215
1216         // Try to shortcut find operations (as opposed to filters) in HTML documents
1217         if ( !seed ) {
1218                 setDocument( context );
1219                 context = context || document;
1220
1221                 if ( documentIsHTML ) {
1222
1223                         // If the selector is sufficiently simple, try using a "get*By*" DOM method
1224                         // (excepting DocumentFragment context, where the methods don't exist)
1225                         if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) {
1226
1227                                 // ID selector
1228                                 if ( ( m = match[ 1 ] ) ) {
1229
1230                                         // Document context
1231                                         if ( nodeType === 9 ) {
1232                                                 if ( ( elem = context.getElementById( m ) ) ) {
1233
1234                                                         // Support: IE, Opera, Webkit
1235                                                         // TODO: identify versions
1236                                                         // getElementById can match elements by name instead of ID
1237                                                         if ( elem.id === m ) {
1238                                                                 results.push( elem );
1239                                                                 return results;
1240                                                         }
1241                                                 } else {
1242                                                         return results;
1243                                                 }
1244
1245                                         // Element context
1246                                         } else {
1247
1248                                                 // Support: IE, Opera, Webkit
1249                                                 // TODO: identify versions
1250                                                 // getElementById can match elements by name instead of ID
1251                                                 if ( newContext && ( elem = newContext.getElementById( m ) ) &&
1252                                                         contains( context, elem ) &&
1253                                                         elem.id === m ) {
1254
1255                                                         results.push( elem );
1256                                                         return results;
1257                                                 }
1258                                         }
1259
1260                                 // Type selector
1261                                 } else if ( match[ 2 ] ) {
1262                                         push.apply( results, context.getElementsByTagName( selector ) );
1263                                         return results;
1264
1265                                 // Class selector
1266                                 } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName &&
1267                                         context.getElementsByClassName ) {
1268
1269                                         push.apply( results, context.getElementsByClassName( m ) );
1270                                         return results;
1271                                 }
1272                         }
1273
1274                         // Take advantage of querySelectorAll
1275                         if ( support.qsa &&
1276                                 !nonnativeSelectorCache[ selector + " " ] &&
1277                                 ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) &&
1278
1279                                 // Support: IE 8 only
1280                                 // Exclude object elements
1281                                 ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) {
1282
1283                                 newSelector = selector;
1284                                 newContext = context;
1285
1286                                 // qSA considers elements outside a scoping root when evaluating child or
1287                                 // descendant combinators, which is not what we want.
1288                                 // In such cases, we work around the behavior by prefixing every selector in the
1289                                 // list with an ID selector referencing the scope context.
1290                                 // The technique has to be used as well when a leading combinator is used
1291                                 // as such selectors are not recognized by querySelectorAll.
1292                                 // Thanks to Andrew Dupont for this technique.
1293                                 if ( nodeType === 1 &&
1294                                         ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) {
1295
1296                                         // Expand context for sibling selectors
1297                                         newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
1298                                                 context;
1299
1300                                         // We can use :scope instead of the ID hack if the browser
1301                                         // supports it & if we're not changing the context.
1302                                         if ( newContext !== context || !support.scope ) {
1303
1304                                                 // Capture the context ID, setting it first if necessary
1305                                                 if ( ( nid = context.getAttribute( "id" ) ) ) {
1306                                                         nid = nid.replace( rcssescape, fcssescape );
1307                                                 } else {
1308                                                         context.setAttribute( "id", ( nid = expando ) );
1309                                                 }
1310                                         }
1311
1312                                         // Prefix every selector in the list
1313                                         groups = tokenize( selector );
1314                                         i = groups.length;
1315                                         while ( i-- ) {
1316                                                 groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " +
1317                                                         toSelector( groups[ i ] );
1318                                         }
1319                                         newSelector = groups.join( "," );
1320                                 }
1321
1322                                 try {
1323                                         push.apply( results,
1324                                                 newContext.querySelectorAll( newSelector )
1325                                         );
1326                                         return results;
1327                                 } catch ( qsaError ) {
1328                                         nonnativeSelectorCache( selector, true );
1329                                 } finally {
1330                                         if ( nid === expando ) {
1331                                                 context.removeAttribute( "id" );
1332                                         }
1333                                 }
1334                         }
1335                 }
1336         }
1337
1338         // All others
1339         return select( selector.replace( rtrim, "$1" ), context, results, seed );
1340     }
1341
1342     /**
1343      * Create key-value caches of limited size
1344      * @returns {function(string, object)} Returns the Object data after storing it on itself with
1345      *  property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
1346      *  deleting the oldest entry
1347      */
1348     function createCache() {
1349         var keys = [];
1350
1351         function cache( key, value ) {
1352
1353                 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
1354                 if ( keys.push( key + " " ) > Expr.cacheLength ) {
1355
1356                         // Only keep the most recent entries
1357                         delete cache[ keys.shift() ];
1358                 }
1359                 return ( cache[ key + " " ] = value );
1360         }
1361         return cache;
1362     }
1363
1364     /**
1365      * Mark a function for special use by Sizzle
1366      * @param {Function} fn The function to mark
1367      */
1368     function markFunction( fn ) {
1369         fn[ expando ] = true;
1370         return fn;
1371     }
1372
1373     /**
1374      * Support testing using an element
1375      * @param {Function} fn Passed the created element and returns a boolean result
1376      */
1377     function assert( fn ) {
1378         var el = document.createElement( "fieldset" );
1379
1380         try {
1381                 return !!fn( el );
1382         } catch ( e ) {
1383                 return false;
1384         } finally {
1385
1386                 // Remove from its parent by default
1387                 if ( el.parentNode ) {
1388                         el.parentNode.removeChild( el );
1389                 }
1390
1391                 // release memory in IE
1392                 el = null;
1393         }
1394     }
1395
1396     /**
1397      * Adds the same handler for all of the specified attrs
1398      * @param {String} attrs Pipe-separated list of attributes
1399      * @param {Function} handler The method that will be applied
1400      */
1401     function addHandle( attrs, handler ) {
1402         var arr = attrs.split( "|" ),
1403                 i = arr.length;
1404
1405         while ( i-- ) {
1406                 Expr.attrHandle[ arr[ i ] ] = handler;
1407         }
1408     }
1409
1410     /**
1411      * Checks document order of two siblings
1412      * @param {Element} a
1413      * @param {Element} b
1414      * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
1415      */
1416     function siblingCheck( a, b ) {
1417         var cur = b && a,
1418                 diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
1419                         a.sourceIndex - b.sourceIndex;
1420
1421         // Use IE sourceIndex if available on both nodes
1422         if ( diff ) {
1423                 return diff;
1424         }
1425
1426         // Check if b follows a
1427         if ( cur ) {
1428                 while ( ( cur = cur.nextSibling ) ) {
1429                         if ( cur === b ) {
1430                                 return -1;
1431                         }
1432                 }
1433         }
1434
1435         return a ? 1 : -1;
1436     }
1437
1438     /**
1439      * Returns a function to use in pseudos for input types
1440      * @param {String} type
1441      */
1442     function createInputPseudo( type ) {
1443         return function( elem ) {
1444                 var name = elem.nodeName.toLowerCase();
1445                 return name === "input" && elem.type === type;
1446         };
1447     }
1448
1449     /**
1450      * Returns a function to use in pseudos for buttons
1451      * @param {String} type
1452      */
1453     function createButtonPseudo( type ) {
1454         return function( elem ) {
1455                 var name = elem.nodeName.toLowerCase();
1456                 return ( name === "input" || name === "button" ) && elem.type === type;
1457         };
1458     }
1459
1460     /**
1461      * Returns a function to use in pseudos for :enabled/:disabled
1462      * @param {Boolean} disabled true for :disabled; false for :enabled
1463      */
1464     function createDisabledPseudo( disabled ) {
1465
1466         // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
1467         return function( elem ) {
1468
1469                 // Only certain elements can match :enabled or :disabled
1470                 // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
1471                 // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
1472                 if ( "form" in elem ) {
1473
1474                         // Check for inherited disabledness on relevant non-disabled elements:
1475                         // * listed form-associated elements in a disabled fieldset
1476                         //   https://html.spec.whatwg.org/multipage/forms.html#category-listed
1477                         //   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
1478                         // * option elements in a disabled optgroup
1479                         //   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
1480                         // All such elements have a "form" property.
1481                         if ( elem.parentNode && elem.disabled === false ) {
1482
1483                                 // Option elements defer to a parent optgroup if present
1484                                 if ( "label" in elem ) {
1485                                         if ( "label" in elem.parentNode ) {
1486                                                 return elem.parentNode.disabled === disabled;
1487                                         } else {
1488                                                 return elem.disabled === disabled;
1489                                         }
1490                                 }
1491
1492                                 // Support: IE 6 - 11
1493                                 // Use the isDisabled shortcut property to check for disabled fieldset ancestors
1494                                 return elem.isDisabled === disabled ||
1495
1496                                         // Where there is no isDisabled, check manually
1497                                         /* jshint -W018 */
1498                                         elem.isDisabled !== !disabled &&
1499                                         inDisabledFieldset( elem ) === disabled;
1500                         }
1501
1502                         return elem.disabled === disabled;
1503
1504                 // Try to winnow out elements that can't be disabled before trusting the disabled property.
1505                 // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
1506                 // even exist on them, let alone have a boolean value.
1507                 } else if ( "label" in elem ) {
1508                         return elem.disabled === disabled;
1509                 }
1510
1511                 // Remaining elements are neither :enabled nor :disabled
1512                 return false;
1513         };
1514     }
1515
1516     /**
1517      * Returns a function to use in pseudos for positionals
1518      * @param {Function} fn
1519      */
1520     function createPositionalPseudo( fn ) {
1521         return markFunction( function( argument ) {
1522                 argument = +argument;
1523                 return markFunction( function( seed, matches ) {
1524                         var j,
1525                                 matchIndexes = fn( [], seed.length, argument ),
1526                                 i = matchIndexes.length;
1527
1528                         // Match elements found at the specified indexes
1529                         while ( i-- ) {
1530                                 if ( seed[ ( j = matchIndexes[ i ] ) ] ) {
1531                                         seed[ j ] = !( matches[ j ] = seed[ j ] );
1532                                 }
1533                         }
1534                 } );
1535         } );
1536     }
1537
1538     /**
1539      * Checks a node for validity as a Sizzle context
1540      * @param {Element|Object=} context
1541      * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
1542      */
1543     function testContext( context ) {
1544         return context && typeof context.getElementsByTagName !== "undefined" && context;
1545     }
1546
1547     // Expose support vars for convenience
1548     support = Sizzle.support = {};
1549
1550     /**
1551      * Detects XML nodes
1552      * @param {Element|Object} elem An element or a document
1553      * @returns {Boolean} True iff elem is a non-HTML XML node
1554      */
1555     isXML = Sizzle.isXML = function( elem ) {
1556         var namespace = elem.namespaceURI,
1557                 docElem = ( elem.ownerDocument || elem ).documentElement;
1558
1559         // Support: IE <=8
1560         // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes
1561         // https://bugs.jquery.com/ticket/4833
1562         return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" );
1563     };
1564
1565     /**
1566      * Sets document-related variables once based on the current document
1567      * @param {Element|Object} [doc] An element or document object to use to set the document
1568      * @returns {Object} Returns the current document
1569      */
1570     setDocument = Sizzle.setDocument = function( node ) {
1571         var hasCompare, subWindow,
1572                 doc = node ? node.ownerDocument || node : preferredDoc;
1573
1574         // Return early if doc is invalid or already selected
1575         // Support: IE 11+, Edge 17 - 18+
1576         // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1577         // two documents; shallow comparisons work.
1578         // eslint-disable-next-line eqeqeq
1579         if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) {
1580                 return document;
1581         }
1582
1583         // Update global variables
1584         document = doc;
1585         docElem = document.documentElement;
1586         documentIsHTML = !isXML( document );
1587
1588         // Support: IE 9 - 11+, Edge 12 - 18+
1589         // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
1590         // Support: IE 11+, Edge 17 - 18+
1591         // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1592         // two documents; shallow comparisons work.
1593         // eslint-disable-next-line eqeqeq
1594         if ( preferredDoc != document &&
1595                 ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) {
1596
1597                 // Support: IE 11, Edge
1598                 if ( subWindow.addEventListener ) {
1599                         subWindow.addEventListener( "unload", unloadHandler, false );
1600
1601                 // Support: IE 9 - 10 only
1602                 } else if ( subWindow.attachEvent ) {
1603                         subWindow.attachEvent( "onunload", unloadHandler );
1604                 }
1605         }
1606
1607         // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only,
1608         // Safari 4 - 5 only, Opera <=11.6 - 12.x only
1609         // IE/Edge & older browsers don't support the :scope pseudo-class.
1610         // Support: Safari 6.0 only
1611         // Safari 6.0 supports :scope but it's an alias of :root there.
1612         support.scope = assert( function( el ) {
1613                 docElem.appendChild( el ).appendChild( document.createElement( "div" ) );
1614                 return typeof el.querySelectorAll !== "undefined" &&
1615                         !el.querySelectorAll( ":scope fieldset div" ).length;
1616         } );
1617
1618         /* Attributes
1619         ---------------------------------------------------------------------- */
1620
1621         // Support: IE<8
1622         // Verify that getAttribute really returns attributes and not properties
1623         // (excepting IE8 booleans)
1624         support.attributes = assert( function( el ) {
1625                 el.className = "i";
1626                 return !el.getAttribute( "className" );
1627         } );
1628
1629         /* getElement(s)By*
1630         ---------------------------------------------------------------------- */
1631
1632         // Check if getElementsByTagName("*") returns only elements
1633         support.getElementsByTagName = assert( function( el ) {
1634                 el.appendChild( document.createComment( "" ) );
1635                 return !el.getElementsByTagName( "*" ).length;
1636         } );
1637
1638         // Support: IE<9
1639         support.getElementsByClassName = rnative.test( document.getElementsByClassName );
1640
1641         // Support: IE<10
1642         // Check if getElementById returns elements by name
1643         // The broken getElementById methods don't pick up programmatically-set names,
1644         // so use a roundabout getElementsByName test
1645         support.getById = assert( function( el ) {
1646                 docElem.appendChild( el ).id = expando;
1647                 return !document.getElementsByName || !document.getElementsByName( expando ).length;
1648         } );
1649
1650         // ID filter and find
1651         if ( support.getById ) {
1652                 Expr.filter[ "ID" ] = function( id ) {
1653                         var attrId = id.replace( runescape, funescape );
1654                         return function( elem ) {
1655                                 return elem.getAttribute( "id" ) === attrId;
1656                         };
1657                 };
1658                 Expr.find[ "ID" ] = function( id, context ) {
1659                         if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1660                                 var elem = context.getElementById( id );
1661                                 return elem ? [ elem ] : [];
1662                         }
1663                 };
1664         } else {
1665                 Expr.filter[ "ID" ] =  function( id ) {
1666                         var attrId = id.replace( runescape, funescape );
1667                         return function( elem ) {
1668                                 var node = typeof elem.getAttributeNode !== "undefined" &&
1669                                         elem.getAttributeNode( "id" );
1670                                 return node && node.value === attrId;
1671                         };
1672                 };
1673
1674                 // Support: IE 6 - 7 only
1675                 // getElementById is not reliable as a find shortcut
1676                 Expr.find[ "ID" ] = function( id, context ) {
1677                         if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
1678                                 var node, i, elems,
1679                                         elem = context.getElementById( id );
1680
1681                                 if ( elem ) {
1682
1683                                         // Verify the id attribute
1684                                         node = elem.getAttributeNode( "id" );
1685                                         if ( node && node.value === id ) {
1686                                                 return [ elem ];
1687                                         }
1688
1689                                         // Fall back on getElementsByName
1690                                         elems = context.getElementsByName( id );
1691                                         i = 0;
1692                                         while ( ( elem = elems[ i++ ] ) ) {
1693                                                 node = elem.getAttributeNode( "id" );
1694                                                 if ( node && node.value === id ) {
1695                                                         return [ elem ];
1696                                                 }
1697                                         }
1698                                 }
1699
1700                                 return [];
1701                         }
1702                 };
1703         }
1704
1705         // Tag
1706         Expr.find[ "TAG" ] = support.getElementsByTagName ?
1707                 function( tag, context ) {
1708                         if ( typeof context.getElementsByTagName !== "undefined" ) {
1709                                 return context.getElementsByTagName( tag );
1710
1711                         // DocumentFragment nodes don't have gEBTN
1712                         } else if ( support.qsa ) {
1713                                 return context.querySelectorAll( tag );
1714                         }
1715                 } :
1716
1717                 function( tag, context ) {
1718                         var elem,
1719                                 tmp = [],
1720                                 i = 0,
1721
1722                                 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
1723                                 results = context.getElementsByTagName( tag );
1724
1725                         // Filter out possible comments
1726                         if ( tag === "*" ) {
1727                                 while ( ( elem = results[ i++ ] ) ) {
1728                                         if ( elem.nodeType === 1 ) {
1729                                                 tmp.push( elem );
1730                                         }
1731                                 }
1732
1733                                 return tmp;
1734                         }
1735                         return results;
1736                 };
1737
1738         // Class
1739         Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) {
1740                 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
1741                         return context.getElementsByClassName( className );
1742                 }
1743         };
1744
1745         /* QSA/matchesSelector
1746         ---------------------------------------------------------------------- */
1747
1748         // QSA and matchesSelector support
1749
1750         // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
1751         rbuggyMatches = [];
1752
1753         // qSa(:focus) reports false when true (Chrome 21)
1754         // We allow this because of a bug in IE8/9 that throws an error
1755         // whenever `document.activeElement` is accessed on an iframe
1756         // So, we allow :focus to pass through QSA all the time to avoid the IE error
1757         // See https://bugs.jquery.com/ticket/13378
1758         rbuggyQSA = [];
1759
1760         if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) {
1761
1762                 // Build QSA regex
1763                 // Regex strategy adopted from Diego Perini
1764                 assert( function( el ) {
1765
1766                         var input;
1767
1768                         // Select is set to empty string on purpose
1769                         // This is to test IE's treatment of not explicitly
1770                         // setting a boolean content attribute,
1771                         // since its presence should be enough
1772                         // https://bugs.jquery.com/ticket/12359
1773                         docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
1774                                 "<select id='" + expando + "-\r\\' msallowcapture=''>" +
1775                                 "<option selected=''></option></select>";
1776
1777                         // Support: IE8, Opera 11-12.16
1778                         // Nothing should be selected when empty strings follow ^= or $= or *=
1779                         // The test attribute must be unknown in Opera but "safe" for WinRT
1780                         // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
1781                         if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) {
1782                                 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
1783                         }
1784
1785                         // Support: IE8
1786                         // Boolean attributes and "value" are not treated correctly
1787                         if ( !el.querySelectorAll( "[selected]" ).length ) {
1788                                 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
1789                         }
1790
1791                         // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
1792                         if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
1793                                 rbuggyQSA.push( "~=" );
1794                         }
1795
1796                         // Support: IE 11+, Edge 15 - 18+
1797                         // IE 11/Edge don't find elements on a `[name='']` query in some cases.
1798                         // Adding a temporary attribute to the document before the selection works
1799                         // around the issue.
1800                         // Interestingly, IE 10 & older don't seem to have the issue.
1801                         input = document.createElement( "input" );
1802                         input.setAttribute( "name", "" );
1803                         el.appendChild( input );
1804                         if ( !el.querySelectorAll( "[name='']" ).length ) {
1805                                 rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" +
1806                                         whitespace + "*(?:''|\"\")" );
1807                         }
1808
1809                         // Webkit/Opera - :checked should return selected option elements
1810                         // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
1811                         // IE8 throws error here and will not see later tests
1812                         if ( !el.querySelectorAll( ":checked" ).length ) {
1813                                 rbuggyQSA.push( ":checked" );
1814                         }
1815
1816                         // Support: Safari 8+, iOS 8+
1817                         // https://bugs.webkit.org/show_bug.cgi?id=136851
1818                         // In-page `selector#id sibling-combinator selector` fails
1819                         if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
1820                                 rbuggyQSA.push( ".#.+[+~]" );
1821                         }
1822
1823                         // Support: Firefox <=3.6 - 5 only
1824                         // Old Firefox doesn't throw on a badly-escaped identifier.
1825                         el.querySelectorAll( "\\\f" );
1826                         rbuggyQSA.push( "[\\r\\n\\f]" );
1827                 } );
1828
1829                 assert( function( el ) {
1830                         el.innerHTML = "<a href='' disabled='disabled'></a>" +
1831                                 "<select disabled='disabled'><option/></select>";
1832
1833                         // Support: Windows 8 Native Apps
1834                         // The type and name attributes are restricted during .innerHTML assignment
1835                         var input = document.createElement( "input" );
1836                         input.setAttribute( "type", "hidden" );
1837                         el.appendChild( input ).setAttribute( "name", "D" );
1838
1839                         // Support: IE8
1840                         // Enforce case-sensitivity of name attribute
1841                         if ( el.querySelectorAll( "[name=d]" ).length ) {
1842                                 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
1843                         }
1844
1845                         // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
1846                         // IE8 throws error here and will not see later tests
1847                         if ( el.querySelectorAll( ":enabled" ).length !== 2 ) {
1848                                 rbuggyQSA.push( ":enabled", ":disabled" );
1849                         }
1850
1851                         // Support: IE9-11+
1852                         // IE's :disabled selector does not pick up the children of disabled fieldsets
1853                         docElem.appendChild( el ).disabled = true;
1854                         if ( el.querySelectorAll( ":disabled" ).length !== 2 ) {
1855                                 rbuggyQSA.push( ":enabled", ":disabled" );
1856                         }
1857
1858                         // Support: Opera 10 - 11 only
1859                         // Opera 10-11 does not throw on post-comma invalid pseudos
1860                         el.querySelectorAll( "*,:x" );
1861                         rbuggyQSA.push( ",.*:" );
1862                 } );
1863         }
1864
1865         if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches ||
1866                 docElem.webkitMatchesSelector ||
1867                 docElem.mozMatchesSelector ||
1868                 docElem.oMatchesSelector ||
1869                 docElem.msMatchesSelector ) ) ) ) {
1870
1871                 assert( function( el ) {
1872
1873                         // Check to see if it's possible to do matchesSelector
1874                         // on a disconnected node (IE 9)
1875                         support.disconnectedMatch = matches.call( el, "*" );
1876
1877                         // This should fail with an exception
1878                         // Gecko does not error, returns false instead
1879                         matches.call( el, "[s!='']:x" );
1880                         rbuggyMatches.push( "!=", pseudos );
1881                 } );
1882         }
1883
1884         rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) );
1885         rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) );
1886
1887         /* Contains
1888         ---------------------------------------------------------------------- */
1889         hasCompare = rnative.test( docElem.compareDocumentPosition );
1890
1891         // Element contains another
1892         // Purposefully self-exclusive
1893         // As in, an element does not contain itself
1894         contains = hasCompare || rnative.test( docElem.contains ) ?
1895                 function( a, b ) {
1896                         var adown = a.nodeType === 9 ? a.documentElement : a,
1897                                 bup = b && b.parentNode;
1898                         return a === bup || !!( bup && bup.nodeType === 1 && (
1899                                 adown.contains ?
1900                                         adown.contains( bup ) :
1901                                         a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
1902                         ) );
1903                 } :
1904                 function( a, b ) {
1905                         if ( b ) {
1906                                 while ( ( b = b.parentNode ) ) {
1907                                         if ( b === a ) {
1908                                                 return true;
1909                                         }
1910                                 }
1911                         }
1912                         return false;
1913                 };
1914
1915         /* Sorting
1916         ---------------------------------------------------------------------- */
1917
1918         // Document order sorting
1919         sortOrder = hasCompare ?
1920         function( a, b ) {
1921
1922                 // Flag for duplicate removal
1923                 if ( a === b ) {
1924                         hasDuplicate = true;
1925                         return 0;
1926                 }
1927
1928                 // Sort on method existence if only one input has compareDocumentPosition
1929                 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
1930                 if ( compare ) {
1931                         return compare;
1932                 }
1933
1934                 // Calculate position if both inputs belong to the same document
1935                 // Support: IE 11+, Edge 17 - 18+
1936                 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1937                 // two documents; shallow comparisons work.
1938                 // eslint-disable-next-line eqeqeq
1939                 compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ?
1940                         a.compareDocumentPosition( b ) :
1941
1942                         // Otherwise we know they are disconnected
1943                         1;
1944
1945                 // Disconnected nodes
1946                 if ( compare & 1 ||
1947                         ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) {
1948
1949                         // Choose the first element that is related to our preferred document
1950                         // Support: IE 11+, Edge 17 - 18+
1951                         // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1952                         // two documents; shallow comparisons work.
1953                         // eslint-disable-next-line eqeqeq
1954                         if ( a == document || a.ownerDocument == preferredDoc &&
1955                                 contains( preferredDoc, a ) ) {
1956                                 return -1;
1957                         }
1958
1959                         // Support: IE 11+, Edge 17 - 18+
1960                         // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1961                         // two documents; shallow comparisons work.
1962                         // eslint-disable-next-line eqeqeq
1963                         if ( b == document || b.ownerDocument == preferredDoc &&
1964                                 contains( preferredDoc, b ) ) {
1965                                 return 1;
1966                         }
1967
1968                         // Maintain original order
1969                         return sortInput ?
1970                                 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
1971                                 0;
1972                 }
1973
1974                 return compare & 4 ? -1 : 1;
1975         } :
1976         function( a, b ) {
1977
1978                 // Exit early if the nodes are identical
1979                 if ( a === b ) {
1980                         hasDuplicate = true;
1981                         return 0;
1982                 }
1983
1984                 var cur,
1985                         i = 0,
1986                         aup = a.parentNode,
1987                         bup = b.parentNode,
1988                         ap = [ a ],
1989                         bp = [ b ];
1990
1991                 // Parentless nodes are either documents or disconnected
1992                 if ( !aup || !bup ) {
1993
1994                         // Support: IE 11+, Edge 17 - 18+
1995                         // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
1996                         // two documents; shallow comparisons work.
1997                         /* eslint-disable eqeqeq */
1998                         return a == document ? -1 :
1999                                 b == document ? 1 :
2000                                 /* eslint-enable eqeqeq */
2001                                 aup ? -1 :
2002                                 bup ? 1 :
2003                                 sortInput ?
2004                                 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
2005                                 0;
2006
2007                 // If the nodes are siblings, we can do a quick check
2008                 } else if ( aup === bup ) {
2009                         return siblingCheck( a, b );
2010                 }
2011
2012                 // Otherwise we need full lists of their ancestors for comparison
2013                 cur = a;
2014                 while ( ( cur = cur.parentNode ) ) {
2015                         ap.unshift( cur );
2016                 }
2017                 cur = b;
2018                 while ( ( cur = cur.parentNode ) ) {
2019                         bp.unshift( cur );
2020                 }
2021
2022                 // Walk down the tree looking for a discrepancy
2023                 while ( ap[ i ] === bp[ i ] ) {
2024                         i++;
2025                 }
2026
2027                 return i ?
2028
2029                         // Do a sibling check if the nodes have a common ancestor
2030                         siblingCheck( ap[ i ], bp[ i ] ) :
2031
2032                         // Otherwise nodes in our document sort first
2033                         // Support: IE 11+, Edge 17 - 18+
2034                         // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2035                         // two documents; shallow comparisons work.
2036                         /* eslint-disable eqeqeq */
2037                         ap[ i ] == preferredDoc ? -1 :
2038                         bp[ i ] == preferredDoc ? 1 :
2039                         /* eslint-enable eqeqeq */
2040                         0;
2041         };
2042
2043         return document;
2044     };
2045
2046     Sizzle.matches = function( expr, elements ) {
2047         return Sizzle( expr, null, null, elements );
2048     };
2049
2050     Sizzle.matchesSelector = function( elem, expr ) {
2051         setDocument( elem );
2052
2053         if ( support.matchesSelector && documentIsHTML &&
2054                 !nonnativeSelectorCache[ expr + " " ] &&
2055                 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
2056                 ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
2057
2058                 try {
2059                         var ret = matches.call( elem, expr );
2060
2061                         // IE 9's matchesSelector returns false on disconnected nodes
2062                         if ( ret || support.disconnectedMatch ||
2063
2064                                 // As well, disconnected nodes are said to be in a document
2065                                 // fragment in IE 9
2066                                 elem.document && elem.document.nodeType !== 11 ) {
2067                                 return ret;
2068                         }
2069                 } catch ( e ) {
2070                         nonnativeSelectorCache( expr, true );
2071                 }
2072         }
2073
2074         return Sizzle( expr, document, null, [ elem ] ).length > 0;
2075     };
2076
2077     Sizzle.contains = function( context, elem ) {
2078
2079         // Set document vars if needed
2080         // Support: IE 11+, Edge 17 - 18+
2081         // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2082         // two documents; shallow comparisons work.
2083         // eslint-disable-next-line eqeqeq
2084         if ( ( context.ownerDocument || context ) != document ) {
2085                 setDocument( context );
2086         }
2087         return contains( context, elem );
2088     };
2089
2090     Sizzle.attr = function( elem, name ) {
2091
2092         // Set document vars if needed
2093         // Support: IE 11+, Edge 17 - 18+
2094         // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
2095         // two documents; shallow comparisons work.
2096         // eslint-disable-next-line eqeqeq
2097         if ( ( elem.ownerDocument || elem ) != document ) {
2098                 setDocument( elem );
2099         }
2100
2101         var fn = Expr.attrHandle[ name.toLowerCase() ],
2102
2103                 // Don't get fooled by Object.prototype properties (jQuery #13807)
2104                 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
2105                         fn( elem, name, !documentIsHTML ) :
2106                         undefined;
2107
2108         return val !== undefined ?
2109                 val :
2110                 support.attributes || !documentIsHTML ?
2111                         elem.getAttribute( name ) :
2112                         ( val = elem.getAttributeNode( name ) ) && val.specified ?
2113                                 val.value :
2114                                 null;
2115     };
2116
2117     Sizzle.escape = function( sel ) {
2118         return ( sel + "" ).replace( rcssescape, fcssescape );
2119     };
2120
2121     Sizzle.error = function( msg ) {
2122         throw new Error( "Syntax error, unrecognized expression: " + msg );
2123     };
2124
2125     /**
2126      * Document sorting and removing duplicates
2127      * @param {ArrayLike} results
2128      */
2129     Sizzle.uniqueSort = function( results ) {
2130         var elem,
2131                 duplicates = [],
2132                 j = 0,
2133                 i = 0;
2134
2135         // Unless we *know* we can detect duplicates, assume their presence
2136         hasDuplicate = !support.detectDuplicates;
2137         sortInput = !support.sortStable && results.slice( 0 );
2138         results.sort( sortOrder );
2139
2140         if ( hasDuplicate ) {
2141                 while ( ( elem = results[ i++ ] ) ) {
2142                         if ( elem === results[ i ] ) {
2143                                 j = duplicates.push( i );
2144                         }
2145                 }
2146                 while ( j-- ) {
2147                         results.splice( duplicates[ j ], 1 );
2148                 }
2149         }
2150
2151         // Clear input after sorting to release objects
2152         // See https://github.com/jquery/sizzle/pull/225
2153         sortInput = null;
2154
2155         return results;
2156     };
2157
2158     /**
2159      * Utility function for retrieving the text value of an array of DOM nodes
2160      * @param {Array|Element} elem
2161      */
2162     getText = Sizzle.getText = function( elem ) {
2163         var node,
2164                 ret = "",
2165                 i = 0,
2166                 nodeType = elem.nodeType;
2167
2168         if ( !nodeType ) {
2169
2170                 // If no nodeType, this is expected to be an array
2171                 while ( ( node = elem[ i++ ] ) ) {
2172
2173                         // Do not traverse comment nodes
2174                         ret += getText( node );
2175                 }
2176         } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
2177
2178                 // Use textContent for elements
2179                 // innerText usage removed for consistency of new lines (jQuery #11153)
2180                 if ( typeof elem.textContent === "string" ) {
2181                         return elem.textContent;
2182                 } else {
2183
2184                         // Traverse its children
2185                         for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2186                                 ret += getText( elem );
2187                         }
2188                 }
2189         } else if ( nodeType === 3 || nodeType === 4 ) {
2190                 return elem.nodeValue;
2191         }
2192
2193         // Do not include comment or processing instruction nodes
2194
2195         return ret;
2196     };
2197
2198     Expr = Sizzle.selectors = {
2199
2200         // Can be adjusted by the user
2201         cacheLength: 50,
2202
2203         createPseudo: markFunction,
2204
2205         match: matchExpr,
2206
2207         attrHandle: {},
2208
2209         find: {},
2210
2211         relative: {
2212                 ">": { dir: "parentNode", first: true },
2213                 " ": { dir: "parentNode" },
2214                 "+": { dir: "previousSibling", first: true },
2215                 "~": { dir: "previousSibling" }
2216         },
2217
2218         preFilter: {
2219                 "ATTR": function( match ) {
2220                         match[ 1 ] = match[ 1 ].replace( runescape, funescape );
2221
2222                         // Move the given value to match[3] whether quoted or unquoted
2223                         match[ 3 ] = ( match[ 3 ] || match[ 4 ] ||
2224                                 match[ 5 ] || "" ).replace( runescape, funescape );
2225
2226                         if ( match[ 2 ] === "~=" ) {
2227                                 match[ 3 ] = " " + match[ 3 ] + " ";
2228                         }
2229
2230                         return match.slice( 0, 4 );
2231                 },
2232
2233                 "CHILD": function( match ) {
2234
2235                         /* matches from matchExpr["CHILD"]
2236                                 1 type (only|nth|...)
2237                                 2 what (child|of-type)
2238                                 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
2239                                 4 xn-component of xn+y argument ([+-]?\d*n|)
2240                                 5 sign of xn-component
2241                                 6 x of xn-component
2242                                 7 sign of y-component
2243                                 8 y of y-component
2244                         */
2245                         match[ 1 ] = match[ 1 ].toLowerCase();
2246
2247                         if ( match[ 1 ].slice( 0, 3 ) === "nth" ) {
2248
2249                                 // nth-* requires argument
2250                                 if ( !match[ 3 ] ) {
2251                                         Sizzle.error( match[ 0 ] );
2252                                 }
2253
2254                                 // numeric x and y parameters for Expr.filter.CHILD
2255                                 // remember that false/true cast respectively to 0/1
2256                                 match[ 4 ] = +( match[ 4 ] ?
2257                                         match[ 5 ] + ( match[ 6 ] || 1 ) :
2258                                         2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) );
2259                                 match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" );
2260
2261                                 // other types prohibit arguments
2262                         } else if ( match[ 3 ] ) {
2263                                 Sizzle.error( match[ 0 ] );
2264                         }
2265
2266                         return match;
2267                 },
2268
2269                 "PSEUDO": function( match ) {
2270                         var excess,
2271                                 unquoted = !match[ 6 ] && match[ 2 ];
2272
2273                         if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) {
2274                                 return null;
2275                         }
2276
2277                         // Accept quoted arguments as-is
2278                         if ( match[ 3 ] ) {
2279                                 match[ 2 ] = match[ 4 ] || match[ 5 ] || "";
2280
2281                         // Strip excess characters from unquoted arguments
2282                         } else if ( unquoted && rpseudo.test( unquoted ) &&
2283
2284                                 // Get excess from tokenize (recursively)
2285                                 ( excess = tokenize( unquoted, true ) ) &&
2286
2287                                 // advance to the next closing parenthesis
2288                                 ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) {
2289
2290                                 // excess is a negative index
2291                                 match[ 0 ] = match[ 0 ].slice( 0, excess );
2292                                 match[ 2 ] = unquoted.slice( 0, excess );
2293                         }
2294
2295                         // Return only captures needed by the pseudo filter method (type and argument)
2296                         return match.slice( 0, 3 );
2297                 }
2298         },
2299
2300         filter: {
2301
2302                 "TAG": function( nodeNameSelector ) {
2303                         var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
2304                         return nodeNameSelector === "*" ?
2305                                 function() {
2306                                         return true;
2307                                 } :
2308                                 function( elem ) {
2309                                         return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
2310                                 };
2311                 },
2312
2313                 "CLASS": function( className ) {
2314                         var pattern = classCache[ className + " " ];
2315
2316                         return pattern ||
2317                                 ( pattern = new RegExp( "(^|" + whitespace +
2318                                         ")" + className + "(" + whitespace + "|$)" ) ) && classCache(
2319                                                 className, function( elem ) {
2320                                                         return pattern.test(
2321                                                                 typeof elem.className === "string" && elem.className ||
2322                                                                 typeof elem.getAttribute !== "undefined" &&
2323                                                                         elem.getAttribute( "class" ) ||
2324                                                                 ""
2325                                                         );
2326                                 } );
2327                 },
2328
2329                 "ATTR": function( name, operator, check ) {
2330                         return function( elem ) {
2331                                 var result = Sizzle.attr( elem, name );
2332
2333                                 if ( result == null ) {
2334                                         return operator === "!=";
2335                                 }
2336                                 if ( !operator ) {
2337                                         return true;
2338                                 }
2339
2340                                 result += "";
2341
2342                                 /* eslint-disable max-len */
2343
2344                                 return operator === "=" ? result === check :
2345                                         operator === "!=" ? result !== check :
2346                                         operator === "^=" ? check && result.indexOf( check ) === 0 :
2347                                         operator === "*=" ? check && result.indexOf( check ) > -1 :
2348                                         operator === "$=" ? check && result.slice( -check.length ) === check :
2349                                         operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
2350                                         operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
2351                                         false;
2352                                 /* eslint-enable max-len */
2353
2354                         };
2355                 },
2356
2357                 "CHILD": function( type, what, _argument, first, last ) {
2358                         var simple = type.slice( 0, 3 ) !== "nth",
2359                                 forward = type.slice( -4 ) !== "last",
2360                                 ofType = what === "of-type";
2361
2362                         return first === 1 && last === 0 ?
2363
2364                                 // Shortcut for :nth-*(n)
2365                                 function( elem ) {
2366                                         return !!elem.parentNode;
2367                                 } :
2368
2369                                 function( elem, _context, xml ) {
2370                                         var cache, uniqueCache, outerCache, node, nodeIndex, start,
2371                                                 dir = simple !== forward ? "nextSibling" : "previousSibling",
2372                                                 parent = elem.parentNode,
2373                                                 name = ofType && elem.nodeName.toLowerCase(),
2374                                                 useCache = !xml && !ofType,
2375                                                 diff = false;
2376
2377                                         if ( parent ) {
2378
2379                                                 // :(first|last|only)-(child|of-type)
2380                                                 if ( simple ) {
2381                                                         while ( dir ) {
2382                                                                 node = elem;
2383                                                                 while ( ( node = node[ dir ] ) ) {
2384                                                                         if ( ofType ?
2385                                                                                 node.nodeName.toLowerCase() === name :
2386                                                                                 node.nodeType === 1 ) {
2387
2388                                                                                 return false;
2389                                                                         }
2390                                                                 }
2391
2392                                                                 // Reverse direction for :only-* (if we haven't yet done so)
2393                                                                 start = dir = type === "only" && !start && "nextSibling";
2394                                                         }
2395                                                         return true;
2396                                                 }
2397
2398                                                 start = [ forward ? parent.firstChild : parent.lastChild ];
2399
2400                                                 // non-xml :nth-child(...) stores cache data on `parent`
2401                                                 if ( forward && useCache ) {
2402
2403                                                         // Seek `elem` from a previously-cached index
2404
2405                                                         // ...in a gzip-friendly way
2406                                                         node = parent;
2407                                                         outerCache = node[ expando ] || ( node[ expando ] = {} );
2408
2409                                                         // Support: IE <9 only
2410                                                         // Defend against cloned attroperties (jQuery gh-1709)
2411                                                         uniqueCache = outerCache[ node.uniqueID ] ||
2412                                                                 ( outerCache[ node.uniqueID ] = {} );
2413
2414                                                         cache = uniqueCache[ type ] || [];
2415                                                         nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
2416                                                         diff = nodeIndex && cache[ 2 ];
2417                                                         node = nodeIndex && parent.childNodes[ nodeIndex ];
2418
2419                                                         while ( ( node = ++nodeIndex && node && node[ dir ] ||
2420
2421                                                                 // Fallback to seeking `elem` from the start
2422                                                                 ( diff = nodeIndex = 0 ) || start.pop() ) ) {
2423
2424                                                                 // When found, cache indexes on `parent` and break
2425                                                                 if ( node.nodeType === 1 && ++diff && node === elem ) {
2426                                                                         uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
2427                                                                         break;
2428                                                                 }
2429                                                         }
2430
2431                                                 } else {
2432
2433                                                         // Use previously-cached element index if available
2434                                                         if ( useCache ) {
2435
2436                                                                 // ...in a gzip-friendly way
2437                                                                 node = elem;
2438                                                                 outerCache = node[ expando ] || ( node[ expando ] = {} );
2439
2440                                                                 // Support: IE <9 only
2441                                                                 // Defend against cloned attroperties (jQuery gh-1709)
2442                                                                 uniqueCache = outerCache[ node.uniqueID ] ||
2443                                                                         ( outerCache[ node.uniqueID ] = {} );
2444
2445                                                                 cache = uniqueCache[ type ] || [];
2446                                                                 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
2447                                                                 diff = nodeIndex;
2448                                                         }
2449
2450                                                         // xml :nth-child(...)
2451                                                         // or :nth-last-child(...) or :nth(-last)?-of-type(...)
2452                                                         if ( diff === false ) {
2453
2454                                                                 // Use the same loop as above to seek `elem` from the start
2455                                                                 while ( ( node = ++nodeIndex && node && node[ dir ] ||
2456                                                                         ( diff = nodeIndex = 0 ) || start.pop() ) ) {
2457
2458                                                                         if ( ( ofType ?
2459                                                                                 node.nodeName.toLowerCase() === name :
2460                                                                                 node.nodeType === 1 ) &&
2461                                                                                 ++diff ) {
2462
2463                                                                                 // Cache the index of each encountered element
2464                                                                                 if ( useCache ) {
2465                                                                                         outerCache = node[ expando ] ||
2466                                                                                                 ( node[ expando ] = {} );
2467
2468                                                                                         // Support: IE <9 only
2469                                                                                         // Defend against cloned attroperties (jQuery gh-1709)
2470                                                                                         uniqueCache = outerCache[ node.uniqueID ] ||
2471                                                                                                 ( outerCache[ node.uniqueID ] = {} );
2472
2473                                                                                         uniqueCache[ type ] = [ dirruns, diff ];
2474                                                                                 }
2475
2476                                                                                 if ( node === elem ) {
2477                                                                                         break;
2478                                                                                 }
2479                                                                         }
2480                                                                 }
2481                                                         }
2482                                                 }
2483
2484                                                 // Incorporate the offset, then check against cycle size
2485                                                 diff -= last;
2486                                                 return diff === first || ( diff % first === 0 && diff / first >= 0 );
2487                                         }
2488                                 };
2489                 },
2490
2491                 "PSEUDO": function( pseudo, argument ) {
2492
2493                         // pseudo-class names are case-insensitive
2494                         // http://www.w3.org/TR/selectors/#pseudo-classes
2495                         // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
2496                         // Remember that setFilters inherits from pseudos
2497                         var args,
2498                                 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
2499                                         Sizzle.error( "unsupported pseudo: " + pseudo );
2500
2501                         // The user may use createPseudo to indicate that
2502                         // arguments are needed to create the filter function
2503                         // just as Sizzle does
2504                         if ( fn[ expando ] ) {
2505                                 return fn( argument );
2506                         }
2507
2508                         // But maintain support for old signatures
2509                         if ( fn.length > 1 ) {
2510                                 args = [ pseudo, pseudo, "", argument ];
2511                                 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
2512                                         markFunction( function( seed, matches ) {
2513                                                 var idx,
2514                                                         matched = fn( seed, argument ),
2515                                                         i = matched.length;
2516                                                 while ( i-- ) {
2517                                                         idx = indexOf( seed, matched[ i ] );
2518                                                         seed[ idx ] = !( matches[ idx ] = matched[ i ] );
2519                                                 }
2520                                         } ) :
2521                                         function( elem ) {
2522                                                 return fn( elem, 0, args );
2523                                         };
2524                         }
2525
2526                         return fn;
2527                 }
2528         },
2529
2530         pseudos: {
2531
2532                 // Potentially complex pseudos
2533                 "not": markFunction( function( selector ) {
2534
2535                         // Trim the selector passed to compile
2536                         // to avoid treating leading and trailing
2537                         // spaces as combinators
2538                         var input = [],
2539                                 results = [],
2540                                 matcher = compile( selector.replace( rtrim, "$1" ) );
2541
2542                         return matcher[ expando ] ?
2543                                 markFunction( function( seed, matches, _context, xml ) {
2544                                         var elem,
2545                                                 unmatched = matcher( seed, null, xml, [] ),
2546                                                 i = seed.length;
2547
2548                                         // Match elements unmatched by `matcher`
2549                                         while ( i-- ) {
2550                                                 if ( ( elem = unmatched[ i ] ) ) {
2551                                                         seed[ i ] = !( matches[ i ] = elem );
2552                                                 }
2553                                         }
2554                                 } ) :
2555                                 function( elem, _context, xml ) {
2556                                         input[ 0 ] = elem;
2557                                         matcher( input, null, xml, results );
2558
2559                                         // Don't keep the element (issue #299)
2560                                         input[ 0 ] = null;
2561                                         return !results.pop();
2562                                 };
2563                 } ),
2564
2565                 "has": markFunction( function( selector ) {
2566                         return function( elem ) {
2567                                 return Sizzle( selector, elem ).length > 0;
2568                         };
2569                 } ),
2570
2571                 "contains": markFunction( function( text ) {
2572                         text = text.replace( runescape, funescape );
2573                         return function( elem ) {
2574                                 return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1;
2575                         };
2576                 } ),
2577
2578                 // "Whether an element is represented by a :lang() selector
2579                 // is based solely on the element's language value
2580                 // being equal to the identifier C,
2581                 // or beginning with the identifier C immediately followed by "-".
2582                 // The matching of C against the element's language value is performed case-insensitively.
2583                 // The identifier C does not have to be a valid language name."
2584                 // http://www.w3.org/TR/selectors/#lang-pseudo
2585                 "lang": markFunction( function( lang ) {
2586
2587                         // lang value must be a valid identifier
2588                         if ( !ridentifier.test( lang || "" ) ) {
2589                                 Sizzle.error( "unsupported lang: " + lang );
2590                         }
2591                         lang = lang.replace( runescape, funescape ).toLowerCase();
2592                         return function( elem ) {
2593                                 var elemLang;
2594                                 do {
2595                                         if ( ( elemLang = documentIsHTML ?
2596                                                 elem.lang :
2597                                                 elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) {
2598
2599                                                 elemLang = elemLang.toLowerCase();
2600                                                 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
2601                                         }
2602                                 } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 );
2603                                 return false;
2604                         };
2605                 } ),
2606
2607                 // Miscellaneous
2608                 "target": function( elem ) {
2609                         var hash = window.location && window.location.hash;
2610                         return hash && hash.slice( 1 ) === elem.id;
2611                 },
2612
2613                 "root": function( elem ) {
2614                         return elem === docElem;
2615                 },
2616
2617                 "focus": function( elem ) {
2618                         return elem === document.activeElement &&
2619                                 ( !document.hasFocus || document.hasFocus() ) &&
2620                                 !!( elem.type || elem.href || ~elem.tabIndex );
2621                 },
2622
2623                 // Boolean properties
2624                 "enabled": createDisabledPseudo( false ),
2625                 "disabled": createDisabledPseudo( true ),
2626
2627                 "checked": function( elem ) {
2628
2629                         // In CSS3, :checked should return both checked and selected elements
2630                         // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
2631                         var nodeName = elem.nodeName.toLowerCase();
2632                         return ( nodeName === "input" && !!elem.checked ) ||
2633                                 ( nodeName === "option" && !!elem.selected );
2634                 },
2635
2636                 "selected": function( elem ) {
2637
2638                         // Accessing this property makes selected-by-default
2639                         // options in Safari work properly
2640                         if ( elem.parentNode ) {
2641                                 // eslint-disable-next-line no-unused-expressions
2642                                 elem.parentNode.selectedIndex;
2643                         }
2644
2645                         return elem.selected === true;
2646                 },
2647
2648                 // Contents
2649                 "empty": function( elem ) {
2650
2651                         // http://www.w3.org/TR/selectors/#empty-pseudo
2652                         // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
2653                         //   but not by others (comment: 8; processing instruction: 7; etc.)
2654                         // nodeType < 6 works because attributes (2) do not appear as children
2655                         for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
2656                                 if ( elem.nodeType < 6 ) {
2657                                         return false;
2658                                 }
2659                         }
2660                         return true;
2661                 },
2662
2663                 "parent": function( elem ) {
2664                         return !Expr.pseudos[ "empty" ]( elem );
2665                 },
2666
2667                 // Element/input types
2668                 "header": function( elem ) {
2669                         return rheader.test( elem.nodeName );
2670                 },
2671
2672                 "input": function( elem ) {
2673                         return rinputs.test( elem.nodeName );
2674                 },
2675
2676                 "button": function( elem ) {
2677                         var name = elem.nodeName.toLowerCase();
2678                         return name === "input" && elem.type === "button" || name === "button";
2679                 },
2680
2681                 "text": function( elem ) {
2682                         var attr;
2683                         return elem.nodeName.toLowerCase() === "input" &&
2684                                 elem.type === "text" &&
2685
2686                                 // Support: IE<8
2687                                 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
2688                                 ( ( attr = elem.getAttribute( "type" ) ) == null ||
2689                                         attr.toLowerCase() === "text" );
2690                 },
2691
2692                 // Position-in-collection
2693                 "first": createPositionalPseudo( function() {
2694                         return [ 0 ];
2695                 } ),
2696
2697                 "last": createPositionalPseudo( function( _matchIndexes, length ) {
2698                         return [ length - 1 ];
2699                 } ),
2700
2701                 "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) {
2702                         return [ argument < 0 ? argument + length : argument ];
2703                 } ),
2704
2705                 "even": createPositionalPseudo( function( matchIndexes, length ) {
2706                         var i = 0;
2707                         for ( ; i < length; i += 2 ) {
2708                                 matchIndexes.push( i );
2709                         }
2710                         return matchIndexes;
2711                 } ),
2712
2713                 "odd": createPositionalPseudo( function( matchIndexes, length ) {
2714                         var i = 1;
2715                         for ( ; i < length; i += 2 ) {
2716                                 matchIndexes.push( i );
2717                         }
2718                         return matchIndexes;
2719                 } ),
2720
2721                 "lt": createPositionalPseudo( function( matchIndexes, length, argument ) {
2722                         var i = argument < 0 ?
2723                                 argument + length :
2724                                 argument > length ?
2725                                         length :
2726                                         argument;
2727                         for ( ; --i >= 0; ) {
2728                                 matchIndexes.push( i );
2729                         }
2730                         return matchIndexes;
2731                 } ),
2732
2733                 "gt": createPositionalPseudo( function( matchIndexes, length, argument ) {
2734                         var i = argument < 0 ? argument + length : argument;
2735                         for ( ; ++i < length; ) {
2736                                 matchIndexes.push( i );
2737                         }
2738                         return matchIndexes;
2739                 } )
2740         }
2741     };
2742
2743     Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ];
2744
2745     // Add button/input type pseudos
2746     for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
2747         Expr.pseudos[ i ] = createInputPseudo( i );
2748     }
2749     for ( i in { submit: true, reset: true } ) {
2750         Expr.pseudos[ i ] = createButtonPseudo( i );
2751     }
2752
2753     // Easy API for creating new setFilters
2754     function setFilters() {}
2755     setFilters.prototype = Expr.filters = Expr.pseudos;
2756     Expr.setFilters = new setFilters();
2757
2758     tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
2759         var matched, match, tokens, type,
2760                 soFar, groups, preFilters,
2761                 cached = tokenCache[ selector + " " ];
2762
2763         if ( cached ) {
2764                 return parseOnly ? 0 : cached.slice( 0 );
2765         }
2766
2767         soFar = selector;
2768         groups = [];
2769         preFilters = Expr.preFilter;
2770
2771         while ( soFar ) {
2772
2773                 // Comma and first run
2774                 if ( !matched || ( match = rcomma.exec( soFar ) ) ) {
2775                         if ( match ) {
2776
2777                                 // Don't consume trailing commas as valid
2778                                 soFar = soFar.slice( match[ 0 ].length ) || soFar;
2779                         }
2780                         groups.push( ( tokens = [] ) );
2781                 }
2782
2783                 matched = false;
2784
2785                 // Combinators
2786                 if ( ( match = rcombinators.exec( soFar ) ) ) {
2787                         matched = match.shift();
2788                         tokens.push( {
2789                                 value: matched,
2790
2791                                 // Cast descendant combinators to space
2792                                 type: match[ 0 ].replace( rtrim, " " )
2793                         } );
2794                         soFar = soFar.slice( matched.length );
2795                 }
2796
2797                 // Filters
2798                 for ( type in Expr.filter ) {
2799                         if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] ||
2800                                 ( match = preFilters[ type ]( match ) ) ) ) {
2801                                 matched = match.shift();
2802                                 tokens.push( {
2803                                         value: matched,
2804                                         type: type,
2805                                         matches: match
2806                                 } );
2807                                 soFar = soFar.slice( matched.length );
2808                         }
2809                 }
2810
2811                 if ( !matched ) {
2812                         break;
2813                 }
2814         }
2815
2816         // Return the length of the invalid excess
2817         // if we're just parsing
2818         // Otherwise, throw an error or return tokens
2819         return parseOnly ?
2820                 soFar.length :
2821                 soFar ?
2822                         Sizzle.error( selector ) :
2823
2824                         // Cache the tokens
2825                         tokenCache( selector, groups ).slice( 0 );
2826     };
2827
2828     function toSelector( tokens ) {
2829         var i = 0,
2830                 len = tokens.length,
2831                 selector = "";
2832         for ( ; i < len; i++ ) {
2833                 selector += tokens[ i ].value;
2834         }
2835         return selector;
2836     }
2837
2838     function addCombinator( matcher, combinator, base ) {
2839         var dir = combinator.dir,
2840                 skip = combinator.next,
2841                 key = skip || dir,
2842                 checkNonElements = base && key === "parentNode",
2843                 doneName = done++;
2844
2845         return combinator.first ?
2846
2847                 // Check against closest ancestor/preceding element
2848                 function( elem, context, xml ) {
2849                         while ( ( elem = elem[ dir ] ) ) {
2850                                 if ( elem.nodeType === 1 || checkNonElements ) {
2851                                         return matcher( elem, context, xml );
2852                                 }
2853                         }
2854                         return false;
2855                 } :
2856
2857                 // Check against all ancestor/preceding elements
2858                 function( elem, context, xml ) {
2859                         var oldCache, uniqueCache, outerCache,
2860                                 newCache = [ dirruns, doneName ];
2861
2862                         // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
2863                         if ( xml ) {
2864                                 while ( ( elem = elem[ dir ] ) ) {
2865                                         if ( elem.nodeType === 1 || checkNonElements ) {
2866                                                 if ( matcher( elem, context, xml ) ) {
2867                                                         return true;
2868                                                 }
2869                                         }
2870                                 }
2871                         } else {
2872                                 while ( ( elem = elem[ dir ] ) ) {
2873                                         if ( elem.nodeType === 1 || checkNonElements ) {
2874                                                 outerCache = elem[ expando ] || ( elem[ expando ] = {} );
2875
2876                                                 // Support: IE <9 only
2877                                                 // Defend against cloned attroperties (jQuery gh-1709)
2878                                                 uniqueCache = outerCache[ elem.uniqueID ] ||
2879                                                         ( outerCache[ elem.uniqueID ] = {} );
2880
2881                                                 if ( skip && skip === elem.nodeName.toLowerCase() ) {
2882                                                         elem = elem[ dir ] || elem;
2883                                                 } else if ( ( oldCache = uniqueCache[ key ] ) &&
2884                                                         oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
2885
2886                                                         // Assign to newCache so results back-propagate to previous elements
2887                                                         return ( newCache[ 2 ] = oldCache[ 2 ] );
2888                                                 } else {
2889
2890                                                         // Reuse newcache so results back-propagate to previous elements
2891                                                         uniqueCache[ key ] = newCache;
2892
2893                                                         // A match means we're done; a fail means we have to keep checking
2894                                                         if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) {
2895                                                                 return true;
2896                                                         }
2897                                                 }
2898                                         }
2899                                 }
2900                         }
2901                         return false;
2902                 };
2903     }
2904
2905     function elementMatcher( matchers ) {
2906         return matchers.length > 1 ?
2907                 function( elem, context, xml ) {
2908                         var i = matchers.length;
2909                         while ( i-- ) {
2910                                 if ( !matchers[ i ]( elem, context, xml ) ) {
2911                                         return false;
2912                                 }
2913                         }
2914                         return true;
2915                 } :
2916                 matchers[ 0 ];
2917     }
2918
2919     function multipleContexts( selector, contexts, results ) {
2920         var i = 0,
2921                 len = contexts.length;
2922         for ( ; i < len; i++ ) {
2923                 Sizzle( selector, contexts[ i ], results );
2924         }
2925         return results;
2926     }
2927
2928     function condense( unmatched, map, filter, context, xml ) {
2929         var elem,
2930                 newUnmatched = [],
2931                 i = 0,
2932                 len = unmatched.length,
2933                 mapped = map != null;
2934
2935         for ( ; i < len; i++ ) {
2936                 if ( ( elem = unmatched[ i ] ) ) {
2937                         if ( !filter || filter( elem, context, xml ) ) {
2938                                 newUnmatched.push( elem );
2939                                 if ( mapped ) {
2940                                         map.push( i );
2941                                 }
2942                         }
2943                 }
2944         }
2945
2946         return newUnmatched;
2947     }
2948
2949     function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
2950         if ( postFilter && !postFilter[ expando ] ) {
2951                 postFilter = setMatcher( postFilter );
2952         }
2953         if ( postFinder && !postFinder[ expando ] ) {
2954                 postFinder = setMatcher( postFinder, postSelector );
2955         }
2956         return markFunction( function( seed, results, context, xml ) {
2957                 var temp, i, elem,
2958                         preMap = [],
2959                         postMap = [],
2960                         preexisting = results.length,
2961
2962                         // Get initial elements from seed or context
2963                         elems = seed || multipleContexts(
2964                                 selector || "*",
2965                                 context.nodeType ? [ context ] : context,
2966                                 []
2967                         ),
2968
2969                         // Prefilter to get matcher input, preserving a map for seed-results synchronization
2970                         matcherIn = preFilter && ( seed || !selector ) ?
2971                                 condense( elems, preMap, preFilter, context, xml ) :
2972                                 elems,
2973
2974                         matcherOut = matcher ?
2975
2976                                 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
2977                                 postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
2978
2979                                         // ...intermediate processing is necessary
2980                                         [] :
2981
2982                                         // ...otherwise use results directly
2983                                         results :
2984                                 matcherIn;
2985
2986                 // Find primary matches
2987                 if ( matcher ) {
2988                         matcher( matcherIn, matcherOut, context, xml );
2989                 }
2990
2991                 // Apply postFilter
2992                 if ( postFilter ) {
2993                         temp = condense( matcherOut, postMap );
2994                         postFilter( temp, [], context, xml );
2995
2996                         // Un-match failing elements by moving them back to matcherIn
2997                         i = temp.length;
2998                         while ( i-- ) {
2999                                 if ( ( elem = temp[ i ] ) ) {
3000                                         matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem );
3001                                 }
3002                         }
3003                 }
3004
3005                 if ( seed ) {
3006                         if ( postFinder || preFilter ) {
3007                                 if ( postFinder ) {
3008
3009                                         // Get the final matcherOut by condensing this intermediate into postFinder contexts
3010                                         temp = [];
3011                                         i = matcherOut.length;
3012                                         while ( i-- ) {
3013                                                 if ( ( elem = matcherOut[ i ] ) ) {
3014
3015                                                         // Restore matcherIn since elem is not yet a final match
3016                                                         temp.push( ( matcherIn[ i ] = elem ) );
3017                                                 }
3018                                         }
3019                                         postFinder( null, ( matcherOut = [] ), temp, xml );
3020                                 }
3021
3022                                 // Move matched elements from seed to results to keep them synchronized
3023                                 i = matcherOut.length;
3024                                 while ( i-- ) {
3025                                         if ( ( elem = matcherOut[ i ] ) &&
3026                                                 ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) {
3027
3028                                                 seed[ temp ] = !( results[ temp ] = elem );
3029                                         }
3030                                 }
3031                         }
3032
3033                 // Add elements to results, through postFinder if defined
3034                 } else {
3035                         matcherOut = condense(
3036                                 matcherOut === results ?
3037                                         matcherOut.splice( preexisting, matcherOut.length ) :
3038                                         matcherOut
3039                         );
3040                         if ( postFinder ) {
3041                                 postFinder( null, results, matcherOut, xml );
3042                         } else {
3043                                 push.apply( results, matcherOut );
3044                         }
3045                 }
3046         } );
3047     }
3048
3049     function matcherFromTokens( tokens ) {
3050         var checkContext, matcher, j,
3051                 len = tokens.length,
3052                 leadingRelative = Expr.relative[ tokens[ 0 ].type ],
3053                 implicitRelative = leadingRelative || Expr.relative[ " " ],
3054                 i = leadingRelative ? 1 : 0,
3055
3056                 // The foundational matcher ensures that elements are reachable from top-level context(s)
3057                 matchContext = addCombinator( function( elem ) {
3058                         return elem === checkContext;
3059                 }, implicitRelative, true ),
3060                 matchAnyContext = addCombinator( function( elem ) {
3061                         return indexOf( checkContext, elem ) > -1;
3062                 }, implicitRelative, true ),
3063                 matchers = [ function( elem, context, xml ) {
3064                         var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
3065                                 ( checkContext = context ).nodeType ?
3066                                         matchContext( elem, context, xml ) :
3067                                         matchAnyContext( elem, context, xml ) );
3068
3069                         // Avoid hanging onto element (issue #299)
3070                         checkContext = null;
3071                         return ret;
3072                 } ];
3073
3074         for ( ; i < len; i++ ) {
3075                 if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) {
3076                         matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ];
3077                 } else {
3078                         matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches );
3079
3080                         // Return special upon seeing a positional matcher
3081                         if ( matcher[ expando ] ) {
3082
3083                                 // Find the next relative operator (if any) for proper handling
3084                                 j = ++i;
3085                                 for ( ; j < len; j++ ) {
3086                                         if ( Expr.relative[ tokens[ j ].type ] ) {
3087                                                 break;
3088                                         }
3089                                 }
3090                                 return setMatcher(
3091                                         i > 1 && elementMatcher( matchers ),
3092                                         i > 1 && toSelector(
3093
3094                                         // If the preceding token was a descendant combinator, insert an implicit any-element `*`
3095                                         tokens
3096                                                 .slice( 0, i - 1 )
3097                                                 .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } )
3098                                         ).replace( rtrim, "$1" ),
3099                                         matcher,
3100                                         i < j && matcherFromTokens( tokens.slice( i, j ) ),
3101                                         j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ),
3102                                         j < len && toSelector( tokens )
3103                                 );
3104                         }
3105                         matchers.push( matcher );
3106                 }
3107         }
3108
3109         return elementMatcher( matchers );
3110     }
3111
3112     function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
3113         var bySet = setMatchers.length > 0,
3114                 byElement = elementMatchers.length > 0,
3115                 superMatcher = function( seed, context, xml, results, outermost ) {
3116                         var elem, j, matcher,
3117                                 matchedCount = 0,
3118                                 i = "0",
3119                                 unmatched = seed && [],
3120                                 setMatched = [],
3121                                 contextBackup = outermostContext,
3122
3123                                 // We must always have either seed elements or outermost context
3124                                 elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ),
3125
3126                                 // Use integer dirruns iff this is the outermost matcher
3127                                 dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ),
3128                                 len = elems.length;
3129
3130                         if ( outermost ) {
3131
3132                                 // Support: IE 11+, Edge 17 - 18+
3133                                 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3134                                 // two documents; shallow comparisons work.
3135                                 // eslint-disable-next-line eqeqeq
3136                                 outermostContext = context == document || context || outermost;
3137                         }
3138
3139                         // Add elements passing elementMatchers directly to results
3140                         // Support: IE<9, Safari
3141                         // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
3142                         for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) {
3143                                 if ( byElement && elem ) {
3144                                         j = 0;
3145
3146                                         // Support: IE 11+, Edge 17 - 18+
3147                                         // IE/Edge sometimes throw a "Permission denied" error when strict-comparing
3148                                         // two documents; shallow comparisons work.
3149                                         // eslint-disable-next-line eqeqeq
3150                                         if ( !context && elem.ownerDocument != document ) {
3151                                                 setDocument( elem );
3152                                                 xml = !documentIsHTML;
3153                                         }
3154                                         while ( ( matcher = elementMatchers[ j++ ] ) ) {
3155                                                 if ( matcher( elem, context || document, xml ) ) {
3156                                                         results.push( elem );
3157                                                         break;
3158                                                 }
3159                                         }
3160                                         if ( outermost ) {
3161                                                 dirruns = dirrunsUnique;
3162                                         }
3163                                 }
3164
3165                                 // Track unmatched elements for set filters
3166                                 if ( bySet ) {
3167
3168                                         // They will have gone through all possible matchers
3169                                         if ( ( elem = !matcher && elem ) ) {
3170                                                 matchedCount--;
3171                                         }
3172
3173                                         // Lengthen the array for every element, matched or not
3174                                         if ( seed ) {
3175                                                 unmatched.push( elem );
3176                                         }
3177                                 }
3178                         }
3179
3180                         // `i` is now the count of elements visited above, and adding it to `matchedCount`
3181                         // makes the latter nonnegative.
3182                         matchedCount += i;
3183
3184                         // Apply set filters to unmatched elements
3185                         // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
3186                         // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
3187                         // no element matchers and no seed.
3188                         // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
3189                         // case, which will result in a "00" `matchedCount` that differs from `i` but is also
3190                         // numerically zero.
3191                         if ( bySet && i !== matchedCount ) {
3192                                 j = 0;
3193                                 while ( ( matcher = setMatchers[ j++ ] ) ) {
3194                                         matcher( unmatched, setMatched, context, xml );
3195                                 }
3196
3197                                 if ( seed ) {
3198
3199                                         // Reintegrate element matches to eliminate the need for sorting
3200                                         if ( matchedCount > 0 ) {
3201                                                 while ( i-- ) {
3202                                                         if ( !( unmatched[ i ] || setMatched[ i ] ) ) {
3203                                                                 setMatched[ i ] = pop.call( results );
3204                                                         }
3205                                                 }
3206                                         }
3207
3208                                         // Discard index placeholder values to get only actual matches
3209                                         setMatched = condense( setMatched );
3210                                 }
3211
3212                                 // Add matches to results
3213                                 push.apply( results, setMatched );
3214
3215                                 // Seedless set matches succeeding multiple successful matchers stipulate sorting
3216                                 if ( outermost && !seed && setMatched.length > 0 &&
3217                                         ( matchedCount + setMatchers.length ) > 1 ) {
3218
3219                                         Sizzle.uniqueSort( results );
3220                                 }
3221                         }
3222
3223                         // Override manipulation of globals by nested matchers
3224                         if ( outermost ) {
3225                                 dirruns = dirrunsUnique;
3226                                 outermostContext = contextBackup;
3227                         }
3228
3229                         return unmatched;
3230                 };
3231
3232         return bySet ?
3233                 markFunction( superMatcher ) :
3234                 superMatcher;
3235     }
3236
3237     compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
3238         var i,
3239                 setMatchers = [],
3240                 elementMatchers = [],
3241                 cached = compilerCache[ selector + " " ];
3242
3243         if ( !cached ) {
3244
3245                 // Generate a function of recursive functions that can be used to check each element
3246                 if ( !match ) {
3247                         match = tokenize( selector );
3248                 }
3249                 i = match.length;
3250                 while ( i-- ) {
3251                         cached = matcherFromTokens( match[ i ] );
3252                         if ( cached[ expando ] ) {
3253                                 setMatchers.push( cached );
3254                         } else {
3255                                 elementMatchers.push( cached );
3256                         }
3257                 }
3258
3259                 // Cache the compiled function
3260                 cached = compilerCache(
3261                         selector,
3262                         matcherFromGroupMatchers( elementMatchers, setMatchers )
3263                 );
3264
3265                 // Save selector and tokenization
3266                 cached.selector = selector;
3267         }
3268         return cached;
3269     };
3270
3271     /**
3272      * A low-level selection function that works with Sizzle's compiled
3273      *  selector functions
3274      * @param {String|Function} selector A selector or a pre-compiled
3275      *  selector function built with Sizzle.compile
3276      * @param {Element} context
3277      * @param {Array} [results]
3278      * @param {Array} [seed] A set of elements to match against
3279      */
3280     select = Sizzle.select = function( selector, context, results, seed ) {
3281         var i, tokens, token, type, find,
3282                 compiled = typeof selector === "function" && selector,
3283                 match = !seed && tokenize( ( selector = compiled.selector || selector ) );
3284
3285         results = results || [];
3286
3287         // Try to minimize operations if there is only one selector in the list and no seed
3288         // (the latter of which guarantees us context)
3289         if ( match.length === 1 ) {
3290
3291                 // Reduce context if the leading compound selector is an ID
3292                 tokens = match[ 0 ] = match[ 0 ].slice( 0 );
3293                 if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" &&
3294                         context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) {
3295
3296                         context = ( Expr.find[ "ID" ]( token.matches[ 0 ]
3297                                 .replace( runescape, funescape ), context ) || [] )[ 0 ];
3298                         if ( !context ) {
3299                                 return results;
3300
3301                         // Precompiled matchers will still verify ancestry, so step up a level
3302                         } else if ( compiled ) {
3303                                 context = context.parentNode;
3304                         }
3305
3306                         selector = selector.slice( tokens.shift().value.length );
3307                 }
3308
3309                 // Fetch a seed set for right-to-left matching
3310                 i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length;
3311                 while ( i-- ) {
3312                         token = tokens[ i ];
3313
3314                         // Abort if we hit a combinator
3315                         if ( Expr.relative[ ( type = token.type ) ] ) {
3316                                 break;
3317                         }
3318                         if ( ( find = Expr.find[ type ] ) ) {
3319
3320                                 // Search, expanding context for leading sibling combinators
3321                                 if ( ( seed = find(
3322                                         token.matches[ 0 ].replace( runescape, funescape ),
3323                                         rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) ||
3324                                                 context
3325                                 ) ) ) {
3326
3327                                         // If seed is empty or no tokens remain, we can return early
3328                                         tokens.splice( i, 1 );
3329                                         selector = seed.length && toSelector( tokens );
3330                                         if ( !selector ) {
3331                                                 push.apply( results, seed );
3332                                                 return results;
3333                                         }
3334
3335                                         break;
3336                                 }
3337                         }
3338                 }
3339         }
3340
3341         // Compile and execute a filtering function if one is not provided
3342         // Provide `match` to avoid retokenization if we modified the selector above
3343         ( compiled || compile( selector, match ) )(
3344                 seed,
3345                 context,
3346                 !documentIsHTML,
3347                 results,
3348                 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
3349         );
3350         return results;
3351     };
3352
3353     // One-time assignments
3354
3355     // Sort stability
3356     support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando;
3357
3358     // Support: Chrome 14-35+
3359     // Always assume duplicates if they aren't passed to the comparison function
3360     support.detectDuplicates = !!hasDuplicate;
3361
3362     // Initialize against the default document
3363     setDocument();
3364
3365     // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
3366     // Detached nodes confoundingly follow *each other*
3367     support.sortDetached = assert( function( el ) {
3368
3369         // Should return 1, but returns 4 (following)
3370         return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1;
3371     } );
3372
3373     // Support: IE<8
3374     // Prevent attribute/property "interpolation"
3375     // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
3376     if ( !assert( function( el ) {
3377         el.innerHTML = "<a href='#'></a>";
3378         return el.firstChild.getAttribute( "href" ) === "#";
3379     } ) ) {
3380         addHandle( "type|href|height|width", function( elem, name, isXML ) {
3381                 if ( !isXML ) {
3382                         return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
3383                 }
3384         } );
3385     }
3386
3387     // Support: IE<9
3388     // Use defaultValue in place of getAttribute("value")
3389     if ( !support.attributes || !assert( function( el ) {
3390         el.innerHTML = "<input/>";
3391         el.firstChild.setAttribute( "value", "" );
3392         return el.firstChild.getAttribute( "value" ) === "";
3393     } ) ) {
3394         addHandle( "value", function( elem, _name, isXML ) {
3395                 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
3396                         return elem.defaultValue;
3397                 }
3398         } );
3399     }
3400
3401     // Support: IE<9
3402     // Use getAttributeNode to fetch booleans when getAttribute lies
3403     if ( !assert( function( el ) {
3404         return el.getAttribute( "disabled" ) == null;
3405     } ) ) {
3406         addHandle( booleans, function( elem, name, isXML ) {
3407                 var val;
3408                 if ( !isXML ) {
3409                         return elem[ name ] === true ? name.toLowerCase() :
3410                                 ( val = elem.getAttributeNode( name ) ) && val.specified ?
3411                                         val.value :
3412                                         null;
3413                 }
3414         } );
3415     }
3416
3417     return Sizzle;
3418
3419     } )( window );
3420
3421
3422
3423     jQuery.find = Sizzle;
3424     jQuery.expr = Sizzle.selectors;
3425
3426     // Deprecated
3427     jQuery.expr[ ":" ] = jQuery.expr.pseudos;
3428     jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
3429     jQuery.text = Sizzle.getText;
3430     jQuery.isXMLDoc = Sizzle.isXML;
3431     jQuery.contains = Sizzle.contains;
3432     jQuery.escapeSelector = Sizzle.escape;
3433
3434
3435
3436
3437     var dir = function( elem, dir, until ) {
3438         var matched = [],
3439                 truncate = until !== undefined;
3440
3441         while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
3442                 if ( elem.nodeType === 1 ) {
3443                         if ( truncate && jQuery( elem ).is( until ) ) {
3444                                 break;
3445                         }
3446                         matched.push( elem );
3447                 }
3448         }
3449         return matched;
3450     };
3451
3452
3453     var siblings = function( n, elem ) {
3454         var matched = [];
3455
3456         for ( ; n; n = n.nextSibling ) {
3457                 if ( n.nodeType === 1 && n !== elem ) {
3458                         matched.push( n );
3459                 }
3460         }
3461
3462         return matched;
3463     };
3464
3465
3466     var rneedsContext = jQuery.expr.match.needsContext;
3467
3468
3469
3470     function nodeName( elem, name ) {
3471
3472       return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
3473
3474     }var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
3475
3476
3477
3478     // Implement the identical functionality for filter and not
3479     function winnow( elements, qualifier, not ) {
3480         if ( isFunction( qualifier ) ) {
3481                 return jQuery.grep( elements, function( elem, i ) {
3482                         return !!qualifier.call( elem, i, elem ) !== not;
3483                 } );
3484         }
3485
3486         // Single element
3487         if ( qualifier.nodeType ) {
3488                 return jQuery.grep( elements, function( elem ) {
3489                         return ( elem === qualifier ) !== not;
3490                 } );
3491         }
3492
3493         // Arraylike of elements (jQuery, arguments, Array)
3494         if ( typeof qualifier !== "string" ) {
3495                 return jQuery.grep( elements, function( elem ) {
3496                         return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
3497                 } );
3498         }
3499
3500         // Filtered directly for both simple and complex selectors
3501         return jQuery.filter( qualifier, elements, not );
3502     }
3503
3504     jQuery.filter = function( expr, elems, not ) {
3505         var elem = elems[ 0 ];
3506
3507         if ( not ) {
3508                 expr = ":not(" + expr + ")";
3509         }
3510
3511         if ( elems.length === 1 && elem.nodeType === 1 ) {
3512                 return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
3513         }
3514
3515         return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
3516                 return elem.nodeType === 1;
3517         } ) );
3518     };
3519
3520     jQuery.fn.extend( {
3521         find: function( selector ) {
3522                 var i, ret,
3523                         len = this.length,
3524                         self = this;
3525
3526                 if ( typeof selector !== "string" ) {
3527                         return this.pushStack( jQuery( selector ).filter( function() {
3528                                 for ( i = 0; i < len; i++ ) {
3529                                         if ( jQuery.contains( self[ i ], this ) ) {
3530                                                 return true;
3531                                         }
3532                                 }
3533                         } ) );
3534                 }
3535
3536                 ret = this.pushStack( [] );
3537
3538                 for ( i = 0; i < len; i++ ) {
3539                         jQuery.find( selector, self[ i ], ret );
3540                 }
3541
3542                 return len > 1 ? jQuery.uniqueSort( ret ) : ret;
3543         },
3544         filter: function( selector ) {
3545                 return this.pushStack( winnow( this, selector || [], false ) );
3546         },
3547         not: function( selector ) {
3548                 return this.pushStack( winnow( this, selector || [], true ) );
3549         },
3550         is: function( selector ) {
3551                 return !!winnow(
3552                         this,
3553
3554                         // If this is a positional/relative selector, check membership in the returned set
3555                         // so $("p:first").is("p:last") won't return true for a doc with two "p".
3556                         typeof selector === "string" && rneedsContext.test( selector ) ?
3557                                 jQuery( selector ) :
3558                                 selector || [],
3559                         false
3560                 ).length;
3561         }
3562     } );
3563
3564
3565     // Initialize a jQuery object
3566
3567
3568     // A central reference to the root jQuery(document)
3569     var rootjQuery,
3570
3571         // A simple way to check for HTML strings
3572         // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
3573         // Strict HTML recognition (#11290: must start with <)
3574         // Shortcut simple #id case for speed
3575         rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
3576
3577         init = jQuery.fn.init = function( selector, context, root ) {
3578                 var match, elem;
3579
3580                 // HANDLE: $(""), $(null), $(undefined), $(false)
3581                 if ( !selector ) {
3582                         return this;
3583                 }
3584
3585                 // Method init() accepts an alternate rootjQuery
3586                 // so migrate can support jQuery.sub (gh-2101)
3587                 root = root || rootjQuery;
3588
3589                 // Handle HTML strings
3590                 if ( typeof selector === "string" ) {
3591                         if ( selector[ 0 ] === "<" &&
3592                                 selector[ selector.length - 1 ] === ">" &&
3593                                 selector.length >= 3 ) {
3594
3595                                 // Assume that strings that start and end with <> are HTML and skip the regex check
3596                                 match = [ null, selector, null ];
3597
3598                         } else {
3599                                 match = rquickExpr.exec( selector );
3600                         }
3601
3602                         // Match html or make sure no context is specified for #id
3603                         if ( match && ( match[ 1 ] || !context ) ) {
3604
3605                                 // HANDLE: $(html) -> $(array)
3606                                 if ( match[ 1 ] ) {
3607                                         context = context instanceof jQuery ? context[ 0 ] : context;
3608
3609                                         // Option to run scripts is true for back-compat
3610                                         // Intentionally let the error be thrown if parseHTML is not present
3611                                         jQuery.merge( this, jQuery.parseHTML(
3612                                                 match[ 1 ],
3613                                                 context && context.nodeType ? context.ownerDocument || context : document,
3614                                                 true
3615                                         ) );
3616
3617                                         // HANDLE: $(html, props)
3618                                         if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
3619                                                 for ( match in context ) {
3620
3621                                                         // Properties of context are called as methods if possible
3622                                                         if ( isFunction( this[ match ] ) ) {
3623                                                                 this[ match ]( context[ match ] );
3624
3625                                                         // ...and otherwise set as attributes
3626                                                         } else {
3627                                                                 this.attr( match, context[ match ] );
3628                                                         }
3629                                                 }
3630                                         }
3631
3632                                         return this;
3633
3634                                 // HANDLE: $(#id)
3635                                 } else {
3636                                         elem = document.getElementById( match[ 2 ] );
3637
3638                                         if ( elem ) {
3639
3640                                                 // Inject the element directly into the jQuery object
3641                                                 this[ 0 ] = elem;
3642                                                 this.length = 1;
3643                                         }
3644                                         return this;
3645                                 }
3646
3647                         // HANDLE: $(expr, $(...))
3648                         } else if ( !context || context.jquery ) {
3649                                 return ( context || root ).find( selector );
3650
3651                         // HANDLE: $(expr, context)
3652                         // (which is just equivalent to: $(context).find(expr)
3653                         } else {
3654                                 return this.constructor( context ).find( selector );
3655                         }
3656
3657                 // HANDLE: $(DOMElement)
3658                 } else if ( selector.nodeType ) {
3659                         this[ 0 ] = selector;
3660                         this.length = 1;
3661                         return this;
3662
3663                 // HANDLE: $(function)
3664                 // Shortcut for document ready
3665                 } else if ( isFunction( selector ) ) {
3666                         return root.ready !== undefined ?
3667                                 root.ready( selector ) :
3668
3669                                 // Execute immediately if ready is not present
3670                                 selector( jQuery );
3671                 }
3672
3673                 return jQuery.makeArray( selector, this );
3674         };
3675
3676     // Give the init function the jQuery prototype for later instantiation
3677     init.prototype = jQuery.fn;
3678
3679     // Initialize central reference
3680     rootjQuery = jQuery( document );
3681
3682
3683     var rparentsprev = /^(?:parents|prev(?:Until|All))/,
3684
3685         // Methods guaranteed to produce a unique set when starting from a unique set
3686         guaranteedUnique = {
3687                 children: true,
3688                 contents: true,
3689                 next: true,
3690                 prev: true
3691         };
3692
3693     jQuery.fn.extend( {
3694         has: function( target ) {
3695                 var targets = jQuery( target, this ),
3696                         l = targets.length;
3697
3698                 return this.filter( function() {
3699                         var i = 0;
3700                         for ( ; i < l; i++ ) {
3701                                 if ( jQuery.contains( this, targets[ i ] ) ) {
3702                                         return true;
3703                                 }
3704                         }
3705                 } );
3706         },
3707
3708         closest: function( selectors, context ) {
3709                 var cur,
3710                         i = 0,
3711                         l = this.length,
3712                         matched = [],
3713                         targets = typeof selectors !== "string" && jQuery( selectors );
3714
3715                 // Positional selectors never match, since there's no _selection_ context
3716                 if ( !rneedsContext.test( selectors ) ) {
3717                         for ( ; i < l; i++ ) {
3718                                 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
3719
3720                                         // Always skip document fragments
3721                                         if ( cur.nodeType < 11 && ( targets ?
3722                                                 targets.index( cur ) > -1 :
3723
3724                                                 // Don't pass non-elements to Sizzle
3725                                                 cur.nodeType === 1 &&
3726                                                         jQuery.find.matchesSelector( cur, selectors ) ) ) {
3727
3728                                                 matched.push( cur );
3729                                                 break;
3730                                         }
3731                                 }
3732                         }
3733                 }
3734
3735                 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
3736         },
3737
3738         // Determine the position of an element within the set
3739         index: function( elem ) {
3740
3741                 // No argument, return index in parent
3742                 if ( !elem ) {
3743                         return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
3744                 }
3745
3746                 // Index in selector
3747                 if ( typeof elem === "string" ) {
3748                         return indexOf.call( jQuery( elem ), this[ 0 ] );
3749                 }
3750
3751                 // Locate the position of the desired element
3752                 return indexOf.call( this,
3753
3754                         // If it receives a jQuery object, the first element is used
3755                         elem.jquery ? elem[ 0 ] : elem
3756                 );
3757         },
3758
3759         add: function( selector, context ) {
3760                 return this.pushStack(
3761                         jQuery.uniqueSort(
3762                                 jQuery.merge( this.get(), jQuery( selector, context ) )
3763                         )
3764                 );
3765         },
3766
3767         addBack: function( selector ) {
3768                 return this.add( selector == null ?
3769                         this.prevObject : this.prevObject.filter( selector )
3770                 );
3771         }
3772     } );
3773
3774     function sibling( cur, dir ) {
3775         while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
3776         return cur;
3777     }
3778
3779     jQuery.each( {
3780         parent: function( elem ) {
3781                 var parent = elem.parentNode;
3782                 return parent && parent.nodeType !== 11 ? parent : null;
3783         },
3784         parents: function( elem ) {
3785                 return dir( elem, "parentNode" );
3786         },
3787         parentsUntil: function( elem, _i, until ) {
3788                 return dir( elem, "parentNode", until );
3789         },
3790         next: function( elem ) {
3791                 return sibling( elem, "nextSibling" );
3792         },
3793         prev: function( elem ) {
3794                 return sibling( elem, "previousSibling" );
3795         },
3796         nextAll: function( elem ) {
3797                 return dir( elem, "nextSibling" );
3798         },
3799         prevAll: function( elem ) {
3800                 return dir( elem, "previousSibling" );
3801         },
3802         nextUntil: function( elem, _i, until ) {
3803                 return dir( elem, "nextSibling", until );
3804         },
3805         prevUntil: function( elem, _i, until ) {
3806                 return dir( elem, "previousSibling", until );
3807         },
3808         siblings: function( elem ) {
3809                 return siblings( ( elem.parentNode || {} ).firstChild, elem );
3810         },
3811         children: function( elem ) {
3812                 return siblings( elem.firstChild );
3813         },
3814         contents: function( elem ) {
3815                 if ( elem.contentDocument != null &&
3816
3817                         // Support: IE 11+
3818                         // <object> elements with no `data` attribute has an object
3819                         // `contentDocument` with a `null` prototype.
3820                         getProto( elem.contentDocument ) ) {
3821
3822                         return elem.contentDocument;
3823                 }
3824
3825                 // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
3826                 // Treat the template element as a regular one in browsers that
3827                 // don't support it.
3828                 if ( nodeName( elem, "template" ) ) {
3829                         elem = elem.content || elem;
3830                 }
3831
3832                 return jQuery.merge( [], elem.childNodes );
3833         }
3834     }, function( name, fn ) {
3835         jQuery.fn[ name ] = function( until, selector ) {
3836                 var matched = jQuery.map( this, fn, until );
3837
3838                 if ( name.slice( -5 ) !== "Until" ) {
3839                         selector = until;
3840                 }
3841
3842                 if ( selector && typeof selector === "string" ) {
3843                         matched = jQuery.filter( selector, matched );
3844                 }
3845
3846                 if ( this.length > 1 ) {
3847
3848                         // Remove duplicates
3849                         if ( !guaranteedUnique[ name ] ) {
3850                                 jQuery.uniqueSort( matched );
3851                         }
3852
3853                         // Reverse order for parents* and prev-derivatives
3854                         if ( rparentsprev.test( name ) ) {
3855                                 matched.reverse();
3856                         }
3857                 }
3858
3859                 return this.pushStack( matched );
3860         };
3861     } );
3862     var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
3863
3864
3865
3866     // Convert String-formatted options into Object-formatted ones
3867     function createOptions( options ) {
3868         var object = {};
3869         jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
3870                 object[ flag ] = true;
3871         } );
3872         return object;
3873     }
3874
3875     /*
3876      * Create a callback list using the following parameters:
3877      *
3878      *  options: an optional list of space-separated options that will change how
3879      *                  the callback list behaves or a more traditional option object
3880      *
3881      * By default a callback list will act like an event callback list and can be
3882      * "fired" multiple times.
3883      *
3884      * Possible options:
3885      *
3886      *  once:                   will ensure the callback list can only be fired once (like a Deferred)
3887      *
3888      *  memory:                 will keep track of previous values and will call any callback added
3889      *                                  after the list has been fired right away with the latest "memorized"
3890      *                                  values (like a Deferred)
3891      *
3892      *  unique:                 will ensure a callback can only be added once (no duplicate in the list)
3893      *
3894      *  stopOnFalse:    interrupt callings when a callback returns false
3895      *
3896      */
3897     jQuery.Callbacks = function( options ) {
3898
3899         // Convert options from String-formatted to Object-formatted if needed
3900         // (we check in cache first)
3901         options = typeof options === "string" ?
3902                 createOptions( options ) :
3903                 jQuery.extend( {}, options );
3904
3905         var // Flag to know if list is currently firing
3906                 firing,
3907
3908                 // Last fire value for non-forgettable lists
3909                 memory,
3910
3911                 // Flag to know if list was already fired
3912                 fired,
3913
3914                 // Flag to prevent firing
3915                 locked,
3916
3917                 // Actual callback list
3918                 list = [],
3919
3920                 // Queue of execution data for repeatable lists
3921                 queue = [],
3922
3923                 // Index of currently firing callback (modified by add/remove as needed)
3924                 firingIndex = -1,
3925
3926                 // Fire callbacks
3927                 fire = function() {
3928
3929                         // Enforce single-firing
3930                         locked = locked || options.once;
3931
3932                         // Execute callbacks for all pending executions,
3933                         // respecting firingIndex overrides and runtime changes
3934                         fired = firing = true;
3935                         for ( ; queue.length; firingIndex = -1 ) {
3936                                 memory = queue.shift();
3937                                 while ( ++firingIndex < list.length ) {
3938
3939                                         // Run callback and check for early termination
3940                                         if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
3941                                                 options.stopOnFalse ) {
3942
3943                                                 // Jump to end and forget the data so .add doesn't re-fire
3944                                                 firingIndex = list.length;
3945                                                 memory = false;
3946                                         }
3947                                 }
3948                         }
3949
3950                         // Forget the data if we're done with it
3951                         if ( !options.memory ) {
3952                                 memory = false;
3953                         }
3954
3955                         firing = false;
3956
3957                         // Clean up if we're done firing for good
3958                         if ( locked ) {
3959
3960                                 // Keep an empty list if we have data for future add calls
3961                                 if ( memory ) {
3962                                         list = [];
3963
3964                                 // Otherwise, this object is spent
3965                                 } else {
3966                                         list = "";
3967                                 }
3968                         }
3969                 },
3970
3971                 // Actual Callbacks object
3972                 self = {
3973
3974                         // Add a callback or a collection of callbacks to the list
3975                         add: function() {
3976                                 if ( list ) {
3977
3978                                         // If we have memory from a past run, we should fire after adding
3979                                         if ( memory && !firing ) {
3980                                                 firingIndex = list.length - 1;
3981                                                 queue.push( memory );
3982                                         }
3983
3984                                         ( function add( args ) {
3985                                                 jQuery.each( args, function( _, arg ) {
3986                                                         if ( isFunction( arg ) ) {
3987                                                                 if ( !options.unique || !self.has( arg ) ) {
3988                                                                         list.push( arg );
3989                                                                 }
3990                                                         } else if ( arg && arg.length && toType( arg ) !== "string" ) {
3991
3992                                                                 // Inspect recursively
3993                                                                 add( arg );
3994                                                         }
3995                                                 } );
3996                                         } )( arguments );
3997
3998                                         if ( memory && !firing ) {
3999                                                 fire();
4000                                         }
4001                                 }
4002                                 return this;
4003                         },
4004
4005                         // Remove a callback from the list
4006                         remove: function() {
4007                                 jQuery.each( arguments, function( _, arg ) {
4008                                         var index;
4009                                         while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
4010                                                 list.splice( index, 1 );
4011
4012                                                 // Handle firing indexes
4013                                                 if ( index <= firingIndex ) {
4014                                                         firingIndex--;
4015                                                 }
4016                                         }
4017                                 } );
4018                                 return this;
4019                         },
4020
4021                         // Check if a given callback is in the list.
4022                         // If no argument is given, return whether or not list has callbacks attached.
4023                         has: function( fn ) {
4024                                 return fn ?
4025                                         jQuery.inArray( fn, list ) > -1 :
4026                                         list.length > 0;
4027                         },
4028
4029                         // Remove all callbacks from the list
4030                         empty: function() {
4031                                 if ( list ) {
4032                                         list = [];
4033                                 }
4034                                 return this;
4035                         },
4036
4037                         // Disable .fire and .add
4038                         // Abort any current/pending executions
4039                         // Clear all callbacks and values
4040                         disable: function() {
4041                                 locked = queue = [];
4042                                 list = memory = "";
4043                                 return this;
4044                         },
4045                         disabled: function() {
4046                                 return !list;
4047                         },
4048
4049                         // Disable .fire
4050                         // Also disable .add unless we have memory (since it would have no effect)
4051                         // Abort any pending executions
4052                         lock: function() {
4053                                 locked = queue = [];
4054                                 if ( !memory && !firing ) {
4055                                         list = memory = "";
4056                                 }
4057                                 return this;
4058                         },
4059                         locked: function() {
4060                                 return !!locked;
4061                         },
4062
4063                         // Call all callbacks with the given context and arguments
4064                         fireWith: function( context, args ) {
4065                                 if ( !locked ) {
4066                                         args = args || [];
4067                                         args = [ context, args.slice ? args.slice() : args ];
4068                                         queue.push( args );
4069                                         if ( !firing ) {
4070                                                 fire();
4071                                         }
4072                                 }
4073                                 return this;
4074                         },
4075
4076                         // Call all the callbacks with the given arguments
4077                         fire: function() {
4078                                 self.fireWith( this, arguments );
4079                                 return this;
4080                         },
4081
4082                         // To know if the callbacks have already been called at least once
4083                         fired: function() {
4084                                 return !!fired;
4085                         }
4086                 };
4087
4088         return self;
4089     };
4090
4091
4092     function Identity( v ) {
4093         return v;
4094     }
4095     function Thrower( ex ) {
4096         throw ex;
4097     }
4098
4099     function adoptValue( value, resolve, reject, noValue ) {
4100         var method;
4101
4102         try {
4103
4104                 // Check for promise aspect first to privilege synchronous behavior
4105                 if ( value && isFunction( ( method = value.promise ) ) ) {
4106                         method.call( value ).done( resolve ).fail( reject );
4107
4108                 // Other thenables
4109                 } else if ( value && isFunction( ( method = value.then ) ) ) {
4110                         method.call( value, resolve, reject );
4111
4112                 // Other non-thenables
4113                 } else {
4114
4115                         // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer:
4116                         // * false: [ value ].slice( 0 ) => resolve( value )
4117                         // * true: [ value ].slice( 1 ) => resolve()
4118                         resolve.apply( undefined, [ value ].slice( noValue ) );
4119                 }
4120
4121         // For Promises/A+, convert exceptions into rejections
4122         // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
4123         // Deferred#then to conditionally suppress rejection.
4124         } catch ( value ) {
4125
4126                 // Support: Android 4.0 only
4127                 // Strict mode functions invoked without .call/.apply get global-object context
4128                 reject.apply( undefined, [ value ] );
4129         }
4130     }
4131
4132     jQuery.extend( {
4133
4134         Deferred: function( func ) {
4135                 var tuples = [
4136
4137                                 // action, add listener, callbacks,
4138                                 // ... .then handlers, argument index, [final state]
4139                                 [ "notify", "progress", jQuery.Callbacks( "memory" ),
4140                                         jQuery.Callbacks( "memory" ), 2 ],
4141                                 [ "resolve", "done", jQuery.Callbacks( "once memory" ),
4142                                         jQuery.Callbacks( "once memory" ), 0, "resolved" ],
4143                                 [ "reject", "fail", jQuery.Callbacks( "once memory" ),
4144                                         jQuery.Callbacks( "once memory" ), 1, "rejected" ]
4145                         ],
4146                         state = "pending",
4147                         promise = {
4148                                 state: function() {
4149                                         return state;
4150                                 },
4151                                 always: function() {
4152                                         deferred.done( arguments ).fail( arguments );
4153                                         return this;
4154                                 },
4155                                 "catch": function( fn ) {
4156                                         return promise.then( null, fn );
4157                                 },
4158
4159                                 // Keep pipe for back-compat
4160                                 pipe: function( /* fnDone, fnFail, fnProgress */ ) {
4161                                         var fns = arguments;
4162
4163                                         return jQuery.Deferred( function( newDefer ) {
4164                                                 jQuery.each( tuples, function( _i, tuple ) {
4165
4166                                                         // Map tuples (progress, done, fail) to arguments (done, fail, progress)
4167                                                         var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ];
4168
4169                                                         // deferred.progress(function() { bind to newDefer or newDefer.notify })
4170                                                         // deferred.done(function() { bind to newDefer or newDefer.resolve })
4171                                                         // deferred.fail(function() { bind to newDefer or newDefer.reject })
4172                                                         deferred[ tuple[ 1 ] ]( function() {
4173                                                                 var returned = fn && fn.apply( this, arguments );
4174                                                                 if ( returned && isFunction( returned.promise ) ) {
4175                                                                         returned.promise()
4176                                                                                 .progress( newDefer.notify )
4177                                                                                 .done( newDefer.resolve )
4178                                                                                 .fail( newDefer.reject );
4179                                                                 } else {
4180                                                                         newDefer[ tuple[ 0 ] + "With" ](
4181                                                                                 this,
4182                                                                                 fn ? [ returned ] : arguments
4183                                                                         );
4184                                                                 }
4185                                                         } );
4186                                                 } );
4187                                                 fns = null;
4188                                         } ).promise();
4189                                 },
4190                                 then: function( onFulfilled, onRejected, onProgress ) {
4191                                         var maxDepth = 0;
4192                                         function resolve( depth, deferred, handler, special ) {
4193                                                 return function() {
4194                                                         var that = this,
4195                                                                 args = arguments,
4196                                                                 mightThrow = function() {
4197                                                                         var returned, then;
4198
4199                                                                         // Support: Promises/A+ section 2.3.3.3.3
4200                                                                         // https://promisesaplus.com/#point-59
4201                                                                         // Ignore double-resolution attempts
4202                                                                         if ( depth < maxDepth ) {
4203                                                                                 return;
4204                                                                         }
4205
4206                                                                         returned = handler.apply( that, args );
4207
4208                                                                         // Support: Promises/A+ section 2.3.1
4209                                                                         // https://promisesaplus.com/#point-48
4210                                                                         if ( returned === deferred.promise() ) {
4211                                                                                 throw new TypeError( "Thenable self-resolution" );
4212                                                                         }
4213
4214                                                                         // Support: Promises/A+ sections 2.3.3.1, 3.5
4215                                                                         // https://promisesaplus.com/#point-54
4216                                                                         // https://promisesaplus.com/#point-75
4217                                                                         // Retrieve `then` only once
4218                                                                         then = returned &&
4219
4220                                                                                 // Support: Promises/A+ section 2.3.4
4221                                                                                 // https://promisesaplus.com/#point-64
4222                                                                                 // Only check objects and functions for thenability
4223                                                                                 ( typeof returned === "object" ||
4224                                                                                         typeof returned === "function" ) &&
4225                                                                                 returned.then;
4226
4227                                                                         // Handle a returned thenable
4228                                                                         if ( isFunction( then ) ) {
4229
4230                                                                                 // Special processors (notify) just wait for resolution
4231                                                                                 if ( special ) {
4232                                                                                         then.call(
4233                                                                                                 returned,
4234                                                                                                 resolve( maxDepth, deferred, Identity, special ),
4235                                                                                                 resolve( maxDepth, deferred, Thrower, special )
4236                                                                                         );
4237
4238                                                                                 // Normal processors (resolve) also hook into progress
4239                                                                                 } else {
4240
4241                                                                                         // ...and disregard older resolution values
4242                                                                                         maxDepth++;
4243
4244                                                                                         then.call(
4245                                                                                                 returned,
4246                                                                                                 resolve( maxDepth, deferred, Identity, special ),
4247                                                                                                 resolve( maxDepth, deferred, Thrower, special ),
4248                                                                                                 resolve( maxDepth, deferred, Identity,
4249                                                                                                         deferred.notifyWith )
4250                                                                                         );
4251                                                                                 }
4252
4253                                                                         // Handle all other returned values
4254                                                                         } else {
4255
4256                                                                                 // Only substitute handlers pass on context
4257                                                                                 // and multiple values (non-spec behavior)
4258                                                                                 if ( handler !== Identity ) {
4259                                                                                         that = undefined;
4260                                                                                         args = [ returned ];
4261                                                                                 }
4262
4263                                                                                 // Process the value(s)
4264                                                                                 // Default process is resolve
4265                                                                                 ( special || deferred.resolveWith )( that, args );
4266                                                                         }
4267                                                                 },
4268
4269                                                                 // Only normal processors (resolve) catch and reject exceptions
4270                                                                 process = special ?
4271                                                                         mightThrow :
4272                                                                         function() {
4273                                                                                 try {
4274                                                                                         mightThrow();
4275                                                                                 } catch ( e ) {
4276
4277                                                                                         if ( jQuery.Deferred.exceptionHook ) {
4278                                                                                                 jQuery.Deferred.exceptionHook( e,
4279                                                                                                         process.stackTrace );
4280                                                                                         }
4281
4282                                                                                         // Support: Promises/A+ section 2.3.3.3.4.1
4283                                                                                         // https://promisesaplus.com/#point-61
4284                                                                                         // Ignore post-resolution exceptions
4285                                                                                         if ( depth + 1 >= maxDepth ) {
4286
4287                                                                                                 // Only substitute handlers pass on context
4288                                                                                                 // and multiple values (non-spec behavior)
4289                                                                                                 if ( handler !== Thrower ) {
4290                                                                                                         that = undefined;
4291                                                                                                         args = [ e ];
4292                                                                                                 }
4293
4294                                                                                                 deferred.rejectWith( that, args );
4295                                                                                         }
4296                                                                                 }
4297                                                                         };
4298
4299                                                         // Support: Promises/A+ section 2.3.3.3.1
4300                                                         // https://promisesaplus.com/#point-57
4301                                                         // Re-resolve promises immediately to dodge false rejection from
4302                                                         // subsequent errors
4303                                                         if ( depth ) {
4304                                                                 process();
4305                                                         } else {
4306
4307                                                                 // Call an optional hook to record the stack, in case of exception
4308                                                                 // since it's otherwise lost when execution goes async
4309                                                                 if ( jQuery.Deferred.getStackHook ) {
4310                                                                         process.stackTrace = jQuery.Deferred.getStackHook();
4311                                                                 }
4312                                                                 window.setTimeout( process );
4313                                                         }
4314                                                 };
4315                                         }
4316
4317                                         return jQuery.Deferred( function( newDefer ) {
4318
4319                                                 // progress_handlers.add( ... )
4320                                                 tuples[ 0 ][ 3 ].add(
4321                                                         resolve(
4322                                                                 0,
4323                                                                 newDefer,
4324                                                                 isFunction( onProgress ) ?
4325                                                                         onProgress :
4326                                                                         Identity,
4327                                                                 newDefer.notifyWith
4328                                                         )
4329                                                 );
4330
4331                                                 // fulfilled_handlers.add( ... )
4332                                                 tuples[ 1 ][ 3 ].add(
4333                                                         resolve(
4334                                                                 0,
4335                                                                 newDefer,
4336                                                                 isFunction( onFulfilled ) ?
4337                                                                         onFulfilled :
4338                                                                         Identity
4339                                                         )
4340                                                 );
4341
4342                                                 // rejected_handlers.add( ... )
4343                                                 tuples[ 2 ][ 3 ].add(
4344                                                         resolve(
4345                                                                 0,
4346                                                                 newDefer,
4347                                                                 isFunction( onRejected ) ?
4348                                                                         onRejected :
4349                                                                         Thrower
4350                                                         )
4351                                                 );
4352                                         } ).promise();
4353                                 },
4354
4355                                 // Get a promise for this deferred
4356                                 // If obj is provided, the promise aspect is added to the object
4357                                 promise: function( obj ) {
4358                                         return obj != null ? jQuery.extend( obj, promise ) : promise;
4359                                 }
4360                         },
4361                         deferred = {};
4362
4363                 // Add list-specific methods
4364                 jQuery.each( tuples, function( i, tuple ) {
4365                         var list = tuple[ 2 ],
4366                                 stateString = tuple[ 5 ];
4367
4368                         // promise.progress = list.add
4369                         // promise.done = list.add
4370                         // promise.fail = list.add
4371                         promise[ tuple[ 1 ] ] = list.add;
4372
4373                         // Handle state
4374                         if ( stateString ) {
4375                                 list.add(
4376                                         function() {
4377
4378                                                 // state = "resolved" (i.e., fulfilled)
4379                                                 // state = "rejected"
4380                                                 state = stateString;
4381                                         },
4382
4383                                         // rejected_callbacks.disable
4384                                         // fulfilled_callbacks.disable
4385                                         tuples[ 3 - i ][ 2 ].disable,
4386
4387                                         // rejected_handlers.disable
4388                                         // fulfilled_handlers.disable
4389                                         tuples[ 3 - i ][ 3 ].disable,
4390
4391                                         // progress_callbacks.lock
4392                                         tuples[ 0 ][ 2 ].lock,
4393
4394                                         // progress_handlers.lock
4395                                         tuples[ 0 ][ 3 ].lock
4396                                 );
4397                         }
4398
4399                         // progress_handlers.fire
4400                         // fulfilled_handlers.fire
4401                         // rejected_handlers.fire
4402                         list.add( tuple[ 3 ].fire );
4403
4404                         // deferred.notify = function() { deferred.notifyWith(...) }
4405                         // deferred.resolve = function() { deferred.resolveWith(...) }
4406                         // deferred.reject = function() { deferred.rejectWith(...) }
4407                         deferred[ tuple[ 0 ] ] = function() {
4408                                 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments );
4409                                 return this;
4410                         };
4411
4412                         // deferred.notifyWith = list.fireWith
4413                         // deferred.resolveWith = list.fireWith
4414                         // deferred.rejectWith = list.fireWith
4415                         deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
4416                 } );
4417
4418                 // Make the deferred a promise
4419                 promise.promise( deferred );
4420
4421                 // Call given func if any
4422                 if ( func ) {
4423                         func.call( deferred, deferred );
4424                 }
4425
4426                 // All done!
4427                 return deferred;
4428         },
4429
4430         // Deferred helper
4431         when: function( singleValue ) {
4432                 var
4433
4434                         // count of uncompleted subordinates
4435                         remaining = arguments.length,
4436
4437                         // count of unprocessed arguments
4438                         i = remaining,
4439
4440                         // subordinate fulfillment data
4441                         resolveContexts = Array( i ),
4442                         resolveValues = slice.call( arguments ),
4443
4444                         // the master Deferred
4445                         master = jQuery.Deferred(),
4446
4447                         // subordinate callback factory
4448                         updateFunc = function( i ) {
4449                                 return function( value ) {
4450                                         resolveContexts[ i ] = this;
4451                                         resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
4452                                         if ( !( --remaining ) ) {
4453                                                 master.resolveWith( resolveContexts, resolveValues );
4454                                         }
4455                                 };
4456                         };
4457
4458                 // Single- and empty arguments are adopted like Promise.resolve
4459                 if ( remaining <= 1 ) {
4460                         adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
4461                                 !remaining );
4462
4463                         // Use .then() to unwrap secondary thenables (cf. gh-3000)
4464                         if ( master.state() === "pending" ||
4465                                 isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
4466
4467                                 return master.then();
4468                         }
4469                 }
4470
4471                 // Multiple arguments are aggregated like Promise.all array elements
4472                 while ( i-- ) {
4473                         adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
4474                 }
4475
4476                 return master.promise();
4477         }
4478     } );
4479
4480
4481     // These usually indicate a programmer mistake during development,
4482     // warn about them ASAP rather than swallowing them by default.
4483     var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
4484
4485     jQuery.Deferred.exceptionHook = function( error, stack ) {
4486
4487         // Support: IE 8 - 9 only
4488         // Console exists when dev tools are open, which can happen at any time
4489         if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
4490                 window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
4491         }
4492     };
4493
4494
4495
4496
4497     jQuery.readyException = function( error ) {
4498         window.setTimeout( function() {
4499                 throw error;
4500         } );
4501     };
4502
4503
4504
4505
4506     // The deferred used on DOM ready
4507     var readyList = jQuery.Deferred();
4508
4509     jQuery.fn.ready = function( fn ) {
4510
4511         readyList
4512                 .then( fn )
4513
4514                 // Wrap jQuery.readyException in a function so that the lookup
4515                 // happens at the time of error handling instead of callback
4516                 // registration.
4517                 .catch( function( error ) {
4518                         jQuery.readyException( error );
4519                 } );
4520
4521         return this;
4522     };
4523
4524     jQuery.extend( {
4525
4526         // Is the DOM ready to be used? Set to true once it occurs.
4527         isReady: false,
4528
4529         // A counter to track how many items to wait for before
4530         // the ready event fires. See #6781
4531         readyWait: 1,
4532
4533         // Handle when the DOM is ready
4534         ready: function( wait ) {
4535
4536                 // Abort if there are pending holds or we're already ready
4537                 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
4538                         return;
4539                 }
4540
4541                 // Remember that the DOM is ready
4542                 jQuery.isReady = true;
4543
4544                 // If a normal DOM Ready event fired, decrement, and wait if need be
4545                 if ( wait !== true && --jQuery.readyWait > 0 ) {
4546                         return;
4547                 }
4548
4549                 // If there are functions bound, to execute
4550                 readyList.resolveWith( document, [ jQuery ] );
4551         }
4552     } );
4553
4554     jQuery.ready.then = readyList.then;
4555
4556     // The ready event handler and self cleanup method
4557     function completed() {
4558         document.removeEventListener( "DOMContentLoaded", completed );
4559         window.removeEventListener( "load", completed );
4560         jQuery.ready();
4561     }
4562
4563     // Catch cases where $(document).ready() is called
4564     // after the browser event has already occurred.
4565     // Support: IE <=9 - 10 only
4566     // Older IE sometimes signals "interactive" too soon
4567     if ( document.readyState === "complete" ||
4568         ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
4569
4570         // Handle it asynchronously to allow scripts the opportunity to delay ready
4571         window.setTimeout( jQuery.ready );
4572
4573     } else {
4574
4575         // Use the handy event callback
4576         document.addEventListener( "DOMContentLoaded", completed );
4577
4578         // A fallback to window.onload, that will always work
4579         window.addEventListener( "load", completed );
4580     }
4581
4582
4583
4584
4585     // Multifunctional method to get and set values of a collection
4586     // The value/s can optionally be executed if it's a function
4587     var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
4588         var i = 0,
4589                 len = elems.length,
4590                 bulk = key == null;
4591
4592         // Sets many values
4593         if ( toType( key ) === "object" ) {
4594                 chainable = true;
4595                 for ( i in key ) {
4596                         access( elems, fn, i, key[ i ], true, emptyGet, raw );
4597                 }
4598
4599         // Sets one value
4600         } else if ( value !== undefined ) {
4601                 chainable = true;
4602
4603                 if ( !isFunction( value ) ) {
4604                         raw = true;
4605                 }
4606
4607                 if ( bulk ) {
4608
4609                         // Bulk operations run against the entire set
4610                         if ( raw ) {
4611                                 fn.call( elems, value );
4612                                 fn = null;
4613
4614                         // ...except when executing function values
4615                         } else {
4616                                 bulk = fn;
4617                                 fn = function( elem, _key, value ) {
4618                                         return bulk.call( jQuery( elem ), value );
4619                                 };
4620                         }
4621                 }
4622
4623                 if ( fn ) {
4624                         for ( ; i < len; i++ ) {
4625                                 fn(
4626                                         elems[ i ], key, raw ?
4627                                         value :
4628                                         value.call( elems[ i ], i, fn( elems[ i ], key ) )
4629                                 );
4630                         }
4631                 }
4632         }
4633
4634         if ( chainable ) {
4635                 return elems;
4636         }
4637
4638         // Gets
4639         if ( bulk ) {
4640                 return fn.call( elems );
4641         }
4642
4643         return len ? fn( elems[ 0 ], key ) : emptyGet;
4644     };
4645
4646
4647     // Matches dashed string for camelizing
4648     var rmsPrefix = /^-ms-/,
4649         rdashAlpha = /-([a-z])/g;
4650
4651     // Used by camelCase as callback to replace()
4652     function fcamelCase( _all, letter ) {
4653         return letter.toUpperCase();
4654     }
4655
4656     // Convert dashed to camelCase; used by the css and data modules
4657     // Support: IE <=9 - 11, Edge 12 - 15
4658     // Microsoft forgot to hump their vendor prefix (#9572)
4659     function camelCase( string ) {
4660         return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
4661     }
4662     var acceptData = function( owner ) {
4663
4664         // Accepts only:
4665         //  - Node
4666         //    - Node.ELEMENT_NODE
4667         //    - Node.DOCUMENT_NODE
4668         //  - Object
4669         //    - Any
4670         return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
4671     };
4672
4673
4674
4675
4676     function Data() {
4677         this.expando = jQuery.expando + Data.uid++;
4678     }
4679
4680     Data.uid = 1;
4681
4682     Data.prototype = {
4683
4684         cache: function( owner ) {
4685
4686                 // Check if the owner object already has a cache
4687                 var value = owner[ this.expando ];
4688
4689                 // If not, create one
4690                 if ( !value ) {
4691                         value = {};
4692
4693                         // We can accept data for non-element nodes in modern browsers,
4694                         // but we should not, see #8335.
4695                         // Always return an empty object.
4696                         if ( acceptData( owner ) ) {
4697
4698                                 // If it is a node unlikely to be stringify-ed or looped over
4699                                 // use plain assignment
4700                                 if ( owner.nodeType ) {
4701                                         owner[ this.expando ] = value;
4702
4703                                 // Otherwise secure it in a non-enumerable property
4704                                 // configurable must be true to allow the property to be
4705                                 // deleted when data is removed
4706                                 } else {
4707                                         Object.defineProperty( owner, this.expando, {
4708                                                 value: value,
4709                                                 configurable: true
4710                                         } );
4711                                 }
4712                         }
4713                 }
4714
4715                 return value;
4716         },
4717         set: function( owner, data, value ) {
4718                 var prop,
4719                         cache = this.cache( owner );
4720
4721                 // Handle: [ owner, key, value ] args
4722                 // Always use camelCase key (gh-2257)
4723                 if ( typeof data === "string" ) {
4724                         cache[ camelCase( data ) ] = value;
4725
4726                 // Handle: [ owner, { properties } ] args
4727                 } else {
4728
4729                         // Copy the properties one-by-one to the cache object
4730                         for ( prop in data ) {
4731                                 cache[ camelCase( prop ) ] = data[ prop ];
4732                         }
4733                 }
4734                 return cache;
4735         },
4736         get: function( owner, key ) {
4737                 return key === undefined ?
4738                         this.cache( owner ) :
4739
4740                         // Always use camelCase key (gh-2257)
4741                         owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
4742         },
4743         access: function( owner, key, value ) {
4744
4745                 // In cases where either:
4746                 //
4747                 //   1. No key was specified
4748                 //   2. A string key was specified, but no value provided
4749                 //
4750                 // Take the "read" path and allow the get method to determine
4751                 // which value to return, respectively either:
4752                 //
4753                 //   1. The entire cache object
4754                 //   2. The data stored at the key
4755                 //
4756                 if ( key === undefined ||
4757                                 ( ( key && typeof key === "string" ) && value === undefined ) ) {
4758
4759                         return this.get( owner, key );
4760                 }
4761
4762                 // When the key is not a string, or both a key and value
4763                 // are specified, set or extend (existing objects) with either:
4764                 //
4765                 //   1. An object of properties
4766                 //   2. A key and value
4767                 //
4768                 this.set( owner, key, value );
4769
4770                 // Since the "set" path can have two possible entry points
4771                 // return the expected data based on which path was taken[*]
4772                 return value !== undefined ? value : key;
4773         },
4774         remove: function( owner, key ) {
4775                 var i,
4776                         cache = owner[ this.expando ];
4777
4778                 if ( cache === undefined ) {
4779                         return;
4780                 }
4781
4782                 if ( key !== undefined ) {
4783
4784                         // Support array or space separated string of keys
4785                         if ( Array.isArray( key ) ) {
4786
4787                                 // If key is an array of keys...
4788                                 // We always set camelCase keys, so remove that.
4789                                 key = key.map( camelCase );
4790                         } else {
4791                                 key = camelCase( key );
4792
4793                                 // If a key with the spaces exists, use it.
4794                                 // Otherwise, create an array by matching non-whitespace
4795                                 key = key in cache ?
4796                                         [ key ] :
4797                                         ( key.match( rnothtmlwhite ) || [] );
4798                         }
4799
4800                         i = key.length;
4801
4802                         while ( i-- ) {
4803                                 delete cache[ key[ i ] ];
4804                         }
4805                 }
4806
4807                 // Remove the expando if there's no more data
4808                 if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
4809
4810                         // Support: Chrome <=35 - 45
4811                         // Webkit & Blink performance suffers when deleting properties
4812                         // from DOM nodes, so set to undefined instead
4813                         // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
4814                         if ( owner.nodeType ) {
4815                                 owner[ this.expando ] = undefined;
4816                         } else {
4817                                 delete owner[ this.expando ];
4818                         }
4819                 }
4820         },
4821         hasData: function( owner ) {
4822                 var cache = owner[ this.expando ];
4823                 return cache !== undefined && !jQuery.isEmptyObject( cache );
4824         }
4825     };
4826     var dataPriv = new Data();
4827
4828     var dataUser = new Data();
4829
4830
4831
4832     //  Implementation Summary
4833     //
4834     //  1. Enforce API surface and semantic compatibility with 1.9.x branch
4835     //  2. Improve the module's maintainability by reducing the storage
4836     //          paths to a single mechanism.
4837     //  3. Use the same single mechanism to support "private" and "user" data.
4838     //  4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
4839     //  5. Avoid exposing implementation details on user objects (eg. expando properties)
4840     //  6. Provide a clear path for implementation upgrade to WeakMap in 2014
4841
4842     var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
4843         rmultiDash = /[A-Z]/g;
4844
4845     function getData( data ) {
4846         if ( data === "true" ) {
4847                 return true;
4848         }
4849
4850         if ( data === "false" ) {
4851                 return false;
4852         }
4853
4854         if ( data === "null" ) {
4855                 return null;
4856         }
4857
4858         // Only convert to a number if it doesn't change the string
4859         if ( data === +data + "" ) {
4860                 return +data;
4861         }
4862
4863         if ( rbrace.test( data ) ) {
4864                 return JSON.parse( data );
4865         }
4866
4867         return data;
4868     }
4869
4870     function dataAttr( elem, key, data ) {
4871         var name;
4872
4873         // If nothing was found internally, try to fetch any
4874         // data from the HTML5 data-* attribute
4875         if ( data === undefined && elem.nodeType === 1 ) {
4876                 name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
4877                 data = elem.getAttribute( name );
4878
4879                 if ( typeof data === "string" ) {
4880                         try {
4881                                 data = getData( data );
4882                         } catch ( e ) {}
4883
4884                         // Make sure we set the data so it isn't changed later
4885                         dataUser.set( elem, key, data );
4886                 } else {
4887                         data = undefined;
4888                 }
4889         }
4890         return data;
4891     }
4892
4893     jQuery.extend( {
4894         hasData: function( elem ) {
4895                 return dataUser.hasData( elem ) || dataPriv.hasData( elem );
4896         },
4897
4898         data: function( elem, name, data ) {
4899                 return dataUser.access( elem, name, data );
4900         },
4901
4902         removeData: function( elem, name ) {
4903                 dataUser.remove( elem, name );
4904         },
4905
4906         // TODO: Now that all calls to _data and _removeData have been replaced
4907         // with direct calls to dataPriv methods, these can be deprecated.
4908         _data: function( elem, name, data ) {
4909                 return dataPriv.access( elem, name, data );
4910         },
4911
4912         _removeData: function( elem, name ) {
4913                 dataPriv.remove( elem, name );
4914         }
4915     } );
4916
4917     jQuery.fn.extend( {
4918         data: function( key, value ) {
4919                 var i, name, data,
4920                         elem = this[ 0 ],
4921                         attrs = elem && elem.attributes;
4922
4923                 // Gets all values
4924                 if ( key === undefined ) {
4925                         if ( this.length ) {
4926                                 data = dataUser.get( elem );
4927
4928                                 if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
4929                                         i = attrs.length;
4930                                         while ( i-- ) {
4931
4932                                                 // Support: IE 11 only
4933                                                 // The attrs elements can be null (#14894)
4934                                                 if ( attrs[ i ] ) {
4935                                                         name = attrs[ i ].name;
4936                                                         if ( name.indexOf( "data-" ) === 0 ) {
4937                                                                 name = camelCase( name.slice( 5 ) );
4938                                                                 dataAttr( elem, name, data[ name ] );
4939                                                         }
4940                                                 }
4941                                         }
4942                                         dataPriv.set( elem, "hasDataAttrs", true );
4943                                 }
4944                         }
4945
4946                         return data;
4947                 }
4948
4949                 // Sets multiple values
4950                 if ( typeof key === "object" ) {
4951                         return this.each( function() {
4952                                 dataUser.set( this, key );
4953                         } );
4954                 }
4955
4956                 return access( this, function( value ) {
4957                         var data;
4958
4959                         // The calling jQuery object (element matches) is not empty
4960                         // (and therefore has an element appears at this[ 0 ]) and the
4961                         // `value` parameter was not undefined. An empty jQuery object
4962                         // will result in `undefined` for elem = this[ 0 ] which will
4963                         // throw an exception if an attempt to read a data cache is made.
4964                         if ( elem && value === undefined ) {
4965
4966                                 // Attempt to get data from the cache
4967                                 // The key will always be camelCased in Data
4968                                 data = dataUser.get( elem, key );
4969                                 if ( data !== undefined ) {
4970                                         return data;
4971                                 }
4972
4973                                 // Attempt to "discover" the data in
4974                                 // HTML5 custom data-* attrs
4975                                 data = dataAttr( elem, key );
4976                                 if ( data !== undefined ) {
4977                                         return data;
4978                                 }
4979
4980                                 // We tried really hard, but the data doesn't exist.
4981                                 return;
4982                         }
4983
4984                         // Set the data...
4985                         this.each( function() {
4986
4987                                 // We always store the camelCased key
4988                                 dataUser.set( this, key, value );
4989                         } );
4990                 }, null, value, arguments.length > 1, null, true );
4991         },
4992
4993         removeData: function( key ) {
4994                 return this.each( function() {
4995                         dataUser.remove( this, key );
4996                 } );
4997         }
4998     } );
4999
5000
5001     jQuery.extend( {
5002         queue: function( elem, type, data ) {
5003                 var queue;
5004
5005                 if ( elem ) {
5006                         type = ( type || "fx" ) + "queue";
5007                         queue = dataPriv.get( elem, type );
5008
5009                         // Speed up dequeue by getting out quickly if this is just a lookup
5010                         if ( data ) {
5011                                 if ( !queue || Array.isArray( data ) ) {
5012                                         queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
5013                                 } else {
5014                                         queue.push( data );
5015                                 }
5016                         }
5017                         return queue || [];
5018                 }
5019         },
5020
5021         dequeue: function( elem, type ) {
5022                 type = type || "fx";
5023
5024                 var queue = jQuery.queue( elem, type ),
5025                         startLength = queue.length,
5026                         fn = queue.shift(),
5027                         hooks = jQuery._queueHooks( elem, type ),
5028                         next = function() {
5029                                 jQuery.dequeue( elem, type );
5030                         };
5031
5032                 // If the fx queue is dequeued, always remove the progress sentinel
5033                 if ( fn === "inprogress" ) {
5034                         fn = queue.shift();
5035                         startLength--;
5036                 }
5037
5038                 if ( fn ) {
5039
5040                         // Add a progress sentinel to prevent the fx queue from being
5041                         // automatically dequeued
5042                         if ( type === "fx" ) {
5043                                 queue.unshift( "inprogress" );
5044                         }
5045
5046                         // Clear up the last queue stop function
5047                         delete hooks.stop;
5048                         fn.call( elem, next, hooks );
5049                 }
5050
5051                 if ( !startLength && hooks ) {
5052                         hooks.empty.fire();
5053                 }
5054         },
5055
5056         // Not public - generate a queueHooks object, or return the current one
5057         _queueHooks: function( elem, type ) {
5058                 var key = type + "queueHooks";
5059                 return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
5060                         empty: jQuery.Callbacks( "once memory" ).add( function() {
5061                                 dataPriv.remove( elem, [ type + "queue", key ] );
5062                         } )
5063                 } );
5064         }
5065     } );
5066
5067     jQuery.fn.extend( {
5068         queue: function( type, data ) {
5069                 var setter = 2;
5070
5071                 if ( typeof type !== "string" ) {
5072                         data = type;
5073                         type = "fx";
5074                         setter--;
5075                 }
5076
5077                 if ( arguments.length < setter ) {
5078                         return jQuery.queue( this[ 0 ], type );
5079                 }
5080
5081                 return data === undefined ?
5082                         this :
5083                         this.each( function() {
5084                                 var queue = jQuery.queue( this, type, data );
5085
5086                                 // Ensure a hooks for this queue
5087                                 jQuery._queueHooks( this, type );
5088
5089                                 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
5090                                         jQuery.dequeue( this, type );
5091                                 }
5092                         } );
5093         },
5094         dequeue: function( type ) {
5095                 return this.each( function() {
5096                         jQuery.dequeue( this, type );
5097                 } );
5098         },
5099         clearQueue: function( type ) {
5100                 return this.queue( type || "fx", [] );
5101         },
5102
5103         // Get a promise resolved when queues of a certain type
5104         // are emptied (fx is the type by default)
5105         promise: function( type, obj ) {
5106                 var tmp,
5107                         count = 1,
5108                         defer = jQuery.Deferred(),
5109                         elements = this,
5110                         i = this.length,
5111                         resolve = function() {
5112                                 if ( !( --count ) ) {
5113                                         defer.resolveWith( elements, [ elements ] );
5114                                 }
5115                         };
5116
5117                 if ( typeof type !== "string" ) {
5118                         obj = type;
5119                         type = undefined;
5120                 }
5121                 type = type || "fx";
5122
5123                 while ( i-- ) {
5124                         tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
5125                         if ( tmp && tmp.empty ) {
5126                                 count++;
5127                                 tmp.empty.add( resolve );
5128                         }
5129                 }
5130                 resolve();
5131                 return defer.promise( obj );
5132         }
5133     } );
5134     var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
5135
5136     var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
5137
5138
5139     var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
5140
5141     var documentElement = document.documentElement;
5142
5143
5144
5145         var isAttached = function( elem ) {
5146                         return jQuery.contains( elem.ownerDocument, elem );
5147                 },
5148                 composed = { composed: true };
5149
5150         // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only
5151         // Check attachment across shadow DOM boundaries when possible (gh-3504)
5152         // Support: iOS 10.0-10.2 only
5153         // Early iOS 10 versions support `attachShadow` but not `getRootNode`,
5154         // leading to errors. We need to check for `getRootNode`.
5155         if ( documentElement.getRootNode ) {
5156                 isAttached = function( elem ) {
5157                         return jQuery.contains( elem.ownerDocument, elem ) ||
5158                                 elem.getRootNode( composed ) === elem.ownerDocument;
5159                 };
5160         }
5161     var isHiddenWithinTree = function( elem, el ) {
5162
5163                 // isHiddenWithinTree might be called from jQuery#filter function;
5164                 // in that case, element will be second argument
5165                 elem = el || elem;
5166
5167                 // Inline style trumps all
5168                 return elem.style.display === "none" ||
5169                         elem.style.display === "" &&
5170
5171                         // Otherwise, check computed style
5172                         // Support: Firefox <=43 - 45
5173                         // Disconnected elements can have computed display: none, so first confirm that elem is
5174                         // in the document.
5175                         isAttached( elem ) &&
5176
5177                         jQuery.css( elem, "display" ) === "none";
5178         };
5179
5180
5181
5182     function adjustCSS( elem, prop, valueParts, tween ) {
5183         var adjusted, scale,
5184                 maxIterations = 20,
5185                 currentValue = tween ?
5186                         function() {
5187                                 return tween.cur();
5188                         } :
5189                         function() {
5190                                 return jQuery.css( elem, prop, "" );
5191                         },
5192                 initial = currentValue(),
5193                 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
5194
5195                 // Starting value computation is required for potential unit mismatches
5196                 initialInUnit = elem.nodeType &&
5197                         ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
5198                         rcssNum.exec( jQuery.css( elem, prop ) );
5199
5200         if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
5201
5202                 // Support: Firefox <=54
5203                 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144)
5204                 initial = initial / 2;
5205
5206                 // Trust units reported by jQuery.css
5207                 unit = unit || initialInUnit[ 3 ];
5208
5209                 // Iteratively approximate from a nonzero starting point
5210                 initialInUnit = +initial || 1;
5211
5212                 while ( maxIterations-- ) {
5213
5214                         // Evaluate and update our best guess (doubling guesses that zero out).
5215                         // Finish if the scale equals or crosses 1 (making the old*new product non-positive).
5216                         jQuery.style( elem, prop, initialInUnit + unit );
5217                         if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) {
5218                                 maxIterations = 0;
5219                         }
5220                         initialInUnit = initialInUnit / scale;
5221
5222                 }
5223
5224                 initialInUnit = initialInUnit * 2;
5225                 jQuery.style( elem, prop, initialInUnit + unit );
5226
5227                 // Make sure we update the tween properties later on
5228                 valueParts = valueParts || [];
5229         }
5230
5231         if ( valueParts ) {
5232                 initialInUnit = +initialInUnit || +initial || 0;
5233
5234                 // Apply relative offset (+=/-=) if specified
5235                 adjusted = valueParts[ 1 ] ?
5236                         initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
5237                         +valueParts[ 2 ];
5238                 if ( tween ) {
5239                         tween.unit = unit;
5240                         tween.start = initialInUnit;
5241                         tween.end = adjusted;
5242                 }
5243         }
5244         return adjusted;
5245     }
5246
5247
5248     var defaultDisplayMap = {};
5249
5250     function getDefaultDisplay( elem ) {
5251         var temp,
5252                 doc = elem.ownerDocument,
5253                 nodeName = elem.nodeName,
5254                 display = defaultDisplayMap[ nodeName ];
5255
5256         if ( display ) {
5257                 return display;
5258         }
5259
5260         temp = doc.body.appendChild( doc.createElement( nodeName ) );
5261         display = jQuery.css( temp, "display" );
5262
5263         temp.parentNode.removeChild( temp );
5264
5265         if ( display === "none" ) {
5266                 display = "block";
5267         }
5268         defaultDisplayMap[ nodeName ] = display;
5269
5270         return display;
5271     }
5272
5273     function showHide( elements, show ) {
5274         var display, elem,
5275                 values = [],
5276                 index = 0,
5277                 length = elements.length;
5278
5279         // Determine new display value for elements that need to change
5280         for ( ; index < length; index++ ) {
5281                 elem = elements[ index ];
5282                 if ( !elem.style ) {
5283                         continue;
5284                 }
5285
5286                 display = elem.style.display;
5287                 if ( show ) {
5288
5289                         // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
5290                         // check is required in this first loop unless we have a nonempty display value (either
5291                         // inline or about-to-be-restored)
5292                         if ( display === "none" ) {
5293                                 values[ index ] = dataPriv.get( elem, "display" ) || null;
5294                                 if ( !values[ index ] ) {
5295                                         elem.style.display = "";
5296                                 }
5297                         }
5298                         if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
5299                                 values[ index ] = getDefaultDisplay( elem );
5300                         }
5301                 } else {
5302                         if ( display !== "none" ) {
5303                                 values[ index ] = "none";
5304
5305                                 // Remember what we're overwriting
5306                                 dataPriv.set( elem, "display", display );
5307                         }
5308                 }
5309         }
5310
5311         // Set the display of the elements in a second loop to avoid constant reflow
5312         for ( index = 0; index < length; index++ ) {
5313                 if ( values[ index ] != null ) {
5314                         elements[ index ].style.display = values[ index ];
5315                 }
5316         }
5317
5318         return elements;
5319     }
5320
5321     jQuery.fn.extend( {
5322         show: function() {
5323                 return showHide( this, true );
5324         },
5325         hide: function() {
5326                 return showHide( this );
5327         },
5328         toggle: function( state ) {
5329                 if ( typeof state === "boolean" ) {
5330                         return state ? this.show() : this.hide();
5331                 }
5332
5333                 return this.each( function() {
5334                         if ( isHiddenWithinTree( this ) ) {
5335                                 jQuery( this ).show();
5336                         } else {
5337                                 jQuery( this ).hide();
5338                         }
5339                 } );
5340         }
5341     } );
5342     var rcheckableType = ( /^(?:checkbox|radio)$/i );
5343
5344     var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i );
5345
5346     var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i );
5347
5348
5349
5350     ( function() {
5351         var fragment = document.createDocumentFragment(),
5352                 div = fragment.appendChild( document.createElement( "div" ) ),
5353                 input = document.createElement( "input" );
5354
5355         // Support: Android 4.0 - 4.3 only
5356         // Check state lost if the name is set (#11217)
5357         // Support: Windows Web Apps (WWA)
5358         // `name` and `type` must use .setAttribute for WWA (#14901)
5359         input.setAttribute( "type", "radio" );
5360         input.setAttribute( "checked", "checked" );
5361         input.setAttribute( "name", "t" );
5362
5363         div.appendChild( input );
5364
5365         // Support: Android <=4.1 only
5366         // Older WebKit doesn't clone checked state correctly in fragments
5367         support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
5368
5369         // Support: IE <=11 only
5370         // Make sure textarea (and checkbox) defaultValue is properly cloned
5371         div.innerHTML = "<textarea>x</textarea>";
5372         support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
5373
5374         // Support: IE <=9 only
5375         // IE <=9 replaces <option> tags with their contents when inserted outside of
5376         // the select element.
5377         div.innerHTML = "<option></option>";
5378         support.option = !!div.lastChild;
5379     } )();
5380
5381
5382     // We have to close these tags to support XHTML (#13200)
5383     var wrapMap = {
5384
5385         // XHTML parsers do not magically insert elements in the
5386         // same way that tag soup parsers do. So we cannot shorten
5387         // this by omitting <tbody> or other required elements.
5388         thead: [ 1, "<table>", "</table>" ],
5389         col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
5390         tr: [ 2, "<table><tbody>", "</tbody></table>" ],
5391         td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
5392
5393         _default: [ 0, "", "" ]
5394     };
5395
5396     wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
5397     wrapMap.th = wrapMap.td;
5398
5399     // Support: IE <=9 only
5400     if ( !support.option ) {
5401         wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ];
5402     }
5403
5404
5405     function getAll( context, tag ) {
5406
5407         // Support: IE <=9 - 11 only
5408         // Use typeof to avoid zero-argument method invocation on host objects (#15151)
5409         var ret;
5410
5411         if ( typeof context.getElementsByTagName !== "undefined" ) {
5412                 ret = context.getElementsByTagName( tag || "*" );
5413
5414         } else if ( typeof context.querySelectorAll !== "undefined" ) {
5415                 ret = context.querySelectorAll( tag || "*" );
5416
5417         } else {
5418                 ret = [];
5419         }
5420
5421         if ( tag === undefined || tag && nodeName( context, tag ) ) {
5422                 return jQuery.merge( [ context ], ret );
5423         }
5424
5425         return ret;
5426     }
5427
5428
5429     // Mark scripts as having already been evaluated
5430     function setGlobalEval( elems, refElements ) {
5431         var i = 0,
5432                 l = elems.length;
5433
5434         for ( ; i < l; i++ ) {
5435                 dataPriv.set(
5436                         elems[ i ],
5437                         "globalEval",
5438                         !refElements || dataPriv.get( refElements[ i ], "globalEval" )
5439                 );
5440         }
5441     }
5442
5443
5444     var rhtml = /<|&#?\w+;/;
5445
5446     function buildFragment( elems, context, scripts, selection, ignored ) {
5447         var elem, tmp, tag, wrap, attached, j,
5448                 fragment = context.createDocumentFragment(),
5449                 nodes = [],
5450                 i = 0,
5451                 l = elems.length;
5452
5453         for ( ; i < l; i++ ) {
5454                 elem = elems[ i ];
5455
5456                 if ( elem || elem === 0 ) {
5457
5458                         // Add nodes directly
5459                         if ( toType( elem ) === "object" ) {
5460
5461                                 // Support: Android <=4.0 only, PhantomJS 1 only
5462                                 // push.apply(_, arraylike) throws on ancient WebKit
5463                                 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
5464
5465                         // Convert non-html into a text node
5466                         } else if ( !rhtml.test( elem ) ) {
5467                                 nodes.push( context.createTextNode( elem ) );
5468
5469                         // Convert html into DOM nodes
5470                         } else {
5471                                 tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
5472
5473                                 // Deserialize a standard representation
5474                                 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
5475                                 wrap = wrapMap[ tag ] || wrapMap._default;
5476                                 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
5477
5478                                 // Descend through wrappers to the right content
5479                                 j = wrap[ 0 ];
5480                                 while ( j-- ) {
5481                                         tmp = tmp.lastChild;
5482                                 }
5483
5484                                 // Support: Android <=4.0 only, PhantomJS 1 only
5485                                 // push.apply(_, arraylike) throws on ancient WebKit
5486                                 jQuery.merge( nodes, tmp.childNodes );
5487
5488                                 // Remember the top-level container
5489                                 tmp = fragment.firstChild;
5490
5491                                 // Ensure the created nodes are orphaned (#12392)
5492                                 tmp.textContent = "";
5493                         }
5494                 }
5495         }
5496
5497         // Remove wrapper from fragment
5498         fragment.textContent = "";
5499
5500         i = 0;
5501         while ( ( elem = nodes[ i++ ] ) ) {
5502
5503                 // Skip elements already in the context collection (trac-4087)
5504                 if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
5505                         if ( ignored ) {
5506                                 ignored.push( elem );
5507                         }
5508                         continue;
5509                 }
5510
5511                 attached = isAttached( elem );
5512
5513                 // Append to fragment
5514                 tmp = getAll( fragment.appendChild( elem ), "script" );
5515
5516                 // Preserve script evaluation history
5517                 if ( attached ) {
5518                         setGlobalEval( tmp );
5519                 }
5520
5521                 // Capture executables
5522                 if ( scripts ) {
5523                         j = 0;
5524                         while ( ( elem = tmp[ j++ ] ) ) {
5525                                 if ( rscriptType.test( elem.type || "" ) ) {
5526                                         scripts.push( elem );
5527                                 }
5528                         }
5529                 }
5530         }
5531
5532         return fragment;
5533     }
5534
5535
5536     var
5537         rkeyEvent = /^key/,
5538         rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
5539         rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
5540
5541     function returnTrue() {
5542         return true;
5543     }
5544
5545     function returnFalse() {
5546         return false;
5547     }
5548
5549     // Support: IE <=9 - 11+
5550     // focus() and blur() are asynchronous, except when they are no-op.
5551     // So expect focus to be synchronous when the element is already active,
5552     // and blur to be synchronous when the element is not already active.
5553     // (focus and blur are always synchronous in other supported browsers,
5554     // this just defines when we can count on it).
5555     function expectSync( elem, type ) {
5556         return ( elem === safeActiveElement() ) === ( type === "focus" );
5557     }
5558
5559     // Support: IE <=9 only
5560     // Accessing document.activeElement can throw unexpectedly
5561     // https://bugs.jquery.com/ticket/13393
5562     function safeActiveElement() {
5563         try {
5564                 return document.activeElement;
5565         } catch ( err ) { }
5566     }
5567
5568     function on( elem, types, selector, data, fn, one ) {
5569         var origFn, type;
5570
5571         // Types can be a map of types/handlers
5572         if ( typeof types === "object" ) {
5573
5574                 // ( types-Object, selector, data )
5575                 if ( typeof selector !== "string" ) {
5576
5577                         // ( types-Object, data )
5578                         data = data || selector;
5579                         selector = undefined;
5580                 }
5581                 for ( type in types ) {
5582                         on( elem, type, selector, data, types[ type ], one );
5583                 }
5584                 return elem;
5585         }
5586
5587         if ( data == null && fn == null ) {
5588
5589                 // ( types, fn )
5590                 fn = selector;
5591                 data = selector = undefined;
5592         } else if ( fn == null ) {
5593                 if ( typeof selector === "string" ) {
5594
5595                         // ( types, selector, fn )
5596                         fn = data;
5597                         data = undefined;
5598                 } else {
5599
5600                         // ( types, data, fn )
5601                         fn = data;
5602                         data = selector;
5603                         selector = undefined;
5604                 }
5605         }
5606         if ( fn === false ) {
5607                 fn = returnFalse;
5608         } else if ( !fn ) {
5609                 return elem;
5610         }
5611
5612         if ( one === 1 ) {
5613                 origFn = fn;
5614                 fn = function( event ) {
5615
5616                         // Can use an empty set, since event contains the info
5617                         jQuery().off( event );
5618                         return origFn.apply( this, arguments );
5619                 };
5620
5621                 // Use same guid so caller can remove using origFn
5622                 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
5623         }
5624         return elem.each( function() {
5625                 jQuery.event.add( this, types, fn, data, selector );
5626         } );
5627     }
5628
5629     /*
5630      * Helper functions for managing events -- not part of the public interface.
5631      * Props to Dean Edwards' addEvent library for many of the ideas.
5632      */
5633     jQuery.event = {
5634
5635         global: {},
5636
5637         add: function( elem, types, handler, data, selector ) {
5638
5639                 var handleObjIn, eventHandle, tmp,
5640                         events, t, handleObj,
5641                         special, handlers, type, namespaces, origType,
5642                         elemData = dataPriv.get( elem );
5643
5644                 // Only attach events to objects that accept data
5645                 if ( !acceptData( elem ) ) {
5646                         return;
5647                 }
5648
5649                 // Caller can pass in an object of custom data in lieu of the handler
5650                 if ( handler.handler ) {
5651                         handleObjIn = handler;
5652                         handler = handleObjIn.handler;
5653                         selector = handleObjIn.selector;
5654                 }
5655
5656                 // Ensure that invalid selectors throw exceptions at attach time
5657                 // Evaluate against documentElement in case elem is a non-element node (e.g., document)
5658                 if ( selector ) {
5659                         jQuery.find.matchesSelector( documentElement, selector );
5660                 }
5661
5662                 // Make sure that the handler has a unique ID, used to find/remove it later
5663                 if ( !handler.guid ) {
5664                         handler.guid = jQuery.guid++;
5665                 }
5666
5667                 // Init the element's event structure and main handler, if this is the first
5668                 if ( !( events = elemData.events ) ) {
5669                         events = elemData.events = Object.create( null );
5670                 }
5671                 if ( !( eventHandle = elemData.handle ) ) {
5672                         eventHandle = elemData.handle = function( e ) {
5673
5674                                 // Discard the second event of a jQuery.event.trigger() and
5675                                 // when an event is called after a page has unloaded
5676                                 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
5677                                         jQuery.event.dispatch.apply( elem, arguments ) : undefined;
5678                         };
5679                 }
5680
5681                 // Handle multiple events separated by a space
5682                 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
5683                 t = types.length;
5684                 while ( t-- ) {
5685                         tmp = rtypenamespace.exec( types[ t ] ) || [];
5686                         type = origType = tmp[ 1 ];
5687                         namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
5688
5689                         // There *must* be a type, no attaching namespace-only handlers
5690                         if ( !type ) {
5691                                 continue;
5692                         }
5693
5694                         // If event changes its type, use the special event handlers for the changed type
5695                         special = jQuery.event.special[ type ] || {};
5696
5697                         // If selector defined, determine special event api type, otherwise given type
5698                         type = ( selector ? special.delegateType : special.bindType ) || type;
5699
5700                         // Update special based on newly reset type
5701                         special = jQuery.event.special[ type ] || {};
5702
5703                         // handleObj is passed to all event handlers
5704                         handleObj = jQuery.extend( {
5705                                 type: type,
5706                                 origType: origType,
5707                                 data: data,
5708                                 handler: handler,
5709                                 guid: handler.guid,
5710                                 selector: selector,
5711                                 needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
5712                                 namespace: namespaces.join( "." )
5713                         }, handleObjIn );
5714
5715                         // Init the event handler queue if we're the first
5716                         if ( !( handlers = events[ type ] ) ) {
5717                                 handlers = events[ type ] = [];
5718                                 handlers.delegateCount = 0;
5719
5720                                 // Only use addEventListener if the special events handler returns false
5721                                 if ( !special.setup ||
5722                                         special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
5723
5724                                         if ( elem.addEventListener ) {
5725                                                 elem.addEventListener( type, eventHandle );
5726                                         }
5727                                 }
5728                         }
5729
5730                         if ( special.add ) {
5731                                 special.add.call( elem, handleObj );
5732
5733                                 if ( !handleObj.handler.guid ) {
5734                                         handleObj.handler.guid = handler.guid;
5735                                 }
5736                         }
5737
5738                         // Add to the element's handler list, delegates in front
5739                         if ( selector ) {
5740                                 handlers.splice( handlers.delegateCount++, 0, handleObj );
5741                         } else {
5742                                 handlers.push( handleObj );
5743                         }
5744
5745                         // Keep track of which events have ever been used, for event optimization
5746                         jQuery.event.global[ type ] = true;
5747                 }
5748
5749         },
5750
5751         // Detach an event or set of events from an element
5752         remove: function( elem, types, handler, selector, mappedTypes ) {
5753
5754                 var j, origCount, tmp,
5755                         events, t, handleObj,
5756                         special, handlers, type, namespaces, origType,
5757                         elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
5758
5759                 if ( !elemData || !( events = elemData.events ) ) {
5760                         return;
5761                 }
5762
5763                 // Once for each type.namespace in types; type may be omitted
5764                 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
5765                 t = types.length;
5766                 while ( t-- ) {
5767                         tmp = rtypenamespace.exec( types[ t ] ) || [];
5768                         type = origType = tmp[ 1 ];
5769                         namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
5770
5771                         // Unbind all events (on this namespace, if provided) for the element
5772                         if ( !type ) {
5773                                 for ( type in events ) {
5774                                         jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
5775                                 }
5776                                 continue;
5777                         }
5778
5779                         special = jQuery.event.special[ type ] || {};
5780                         type = ( selector ? special.delegateType : special.bindType ) || type;
5781                         handlers = events[ type ] || [];
5782                         tmp = tmp[ 2 ] &&
5783                                 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
5784
5785                         // Remove matching events
5786                         origCount = j = handlers.length;
5787                         while ( j-- ) {
5788                                 handleObj = handlers[ j ];
5789
5790                                 if ( ( mappedTypes || origType === handleObj.origType ) &&
5791                                         ( !handler || handler.guid === handleObj.guid ) &&
5792                                         ( !tmp || tmp.test( handleObj.namespace ) ) &&
5793                                         ( !selector || selector === handleObj.selector ||
5794                                                 selector === "**" && handleObj.selector ) ) {
5795                                         handlers.splice( j, 1 );
5796
5797                                         if ( handleObj.selector ) {
5798                                                 handlers.delegateCount--;
5799                                         }
5800                                         if ( special.remove ) {
5801                                                 special.remove.call( elem, handleObj );
5802                                         }
5803                                 }
5804                         }
5805
5806                         // Remove generic event handler if we removed something and no more handlers exist
5807                         // (avoids potential for endless recursion during removal of special event handlers)
5808                         if ( origCount && !handlers.length ) {
5809                                 if ( !special.teardown ||
5810                                         special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
5811
5812                                         jQuery.removeEvent( elem, type, elemData.handle );
5813                                 }
5814
5815                                 delete events[ type ];
5816                         }
5817                 }
5818
5819                 // Remove data and the expando if it's no longer used
5820                 if ( jQuery.isEmptyObject( events ) ) {
5821                         dataPriv.remove( elem, "handle events" );
5822                 }
5823         },
5824
5825         dispatch: function( nativeEvent ) {
5826
5827                 var i, j, ret, matched, handleObj, handlerQueue,
5828                         args = new Array( arguments.length ),
5829
5830                         // Make a writable jQuery.Event from the native event object
5831                         event = jQuery.event.fix( nativeEvent ),
5832
5833                         handlers = (
5834                                         dataPriv.get( this, "events" ) || Object.create( null )
5835                                 )[ event.type ] || [],
5836                         special = jQuery.event.special[ event.type ] || {};
5837
5838                 // Use the fix-ed jQuery.Event rather than the (read-only) native event
5839                 args[ 0 ] = event;
5840
5841                 for ( i = 1; i < arguments.length; i++ ) {
5842                         args[ i ] = arguments[ i ];
5843                 }
5844
5845                 event.delegateTarget = this;
5846
5847                 // Call the preDispatch hook for the mapped type, and let it bail if desired
5848                 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
5849                         return;
5850                 }
5851
5852                 // Determine handlers
5853                 handlerQueue = jQuery.event.handlers.call( this, event, handlers );
5854
5855                 // Run delegates first; they may want to stop propagation beneath us
5856                 i = 0;
5857                 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
5858                         event.currentTarget = matched.elem;
5859
5860                         j = 0;
5861                         while ( ( handleObj = matched.handlers[ j++ ] ) &&
5862                                 !event.isImmediatePropagationStopped() ) {
5863
5864                                 // If the event is namespaced, then each handler is only invoked if it is
5865                                 // specially universal or its namespaces are a superset of the event's.
5866                                 if ( !event.rnamespace || handleObj.namespace === false ||
5867                                         event.rnamespace.test( handleObj.namespace ) ) {
5868
5869                                         event.handleObj = handleObj;
5870                                         event.data = handleObj.data;
5871
5872                                         ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
5873                                                 handleObj.handler ).apply( matched.elem, args );
5874
5875                                         if ( ret !== undefined ) {
5876                                                 if ( ( event.result = ret ) === false ) {
5877                                                         event.preventDefault();
5878                                                         event.stopPropagation();
5879                                                 }
5880                                         }
5881                                 }
5882                         }
5883                 }
5884
5885                 // Call the postDispatch hook for the mapped type
5886                 if ( special.postDispatch ) {
5887                         special.postDispatch.call( this, event );
5888                 }
5889
5890                 return event.result;
5891         },
5892
5893         handlers: function( event, handlers ) {
5894                 var i, handleObj, sel, matchedHandlers, matchedSelectors,
5895                         handlerQueue = [],
5896                         delegateCount = handlers.delegateCount,
5897                         cur = event.target;
5898
5899                 // Find delegate handlers
5900                 if ( delegateCount &&
5901
5902                         // Support: IE <=9
5903                         // Black-hole SVG <use> instance trees (trac-13180)
5904                         cur.nodeType &&
5905
5906                         // Support: Firefox <=42
5907                         // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
5908                         // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
5909                         // Support: IE 11 only
5910                         // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
5911                         !( event.type === "click" && event.button >= 1 ) ) {
5912
5913                         for ( ; cur !== this; cur = cur.parentNode || this ) {
5914
5915                                 // Don't check non-elements (#13208)
5916                                 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
5917                                 if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) {
5918                                         matchedHandlers = [];
5919                                         matchedSelectors = {};
5920                                         for ( i = 0; i < delegateCount; i++ ) {
5921                                                 handleObj = handlers[ i ];
5922
5923                                                 // Don't conflict with Object.prototype properties (#13203)
5924                                                 sel = handleObj.selector + " ";
5925
5926                                                 if ( matchedSelectors[ sel ] === undefined ) {
5927                                                         matchedSelectors[ sel ] = handleObj.needsContext ?
5928                                                                 jQuery( sel, this ).index( cur ) > -1 :
5929                                                                 jQuery.find( sel, this, null, [ cur ] ).length;
5930                                                 }
5931                                                 if ( matchedSelectors[ sel ] ) {
5932                                                         matchedHandlers.push( handleObj );
5933                                                 }
5934                                         }
5935                                         if ( matchedHandlers.length ) {
5936                                                 handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
5937                                         }
5938                                 }
5939                         }
5940                 }
5941
5942                 // Add the remaining (directly-bound) handlers
5943                 cur = this;
5944                 if ( delegateCount < handlers.length ) {
5945                         handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
5946                 }
5947
5948                 return handlerQueue;
5949         },
5950
5951         addProp: function( name, hook ) {
5952                 Object.defineProperty( jQuery.Event.prototype, name, {
5953                         enumerable: true,
5954                         configurable: true,
5955
5956                         get: isFunction( hook ) ?
5957                                 function() {
5958                                         if ( this.originalEvent ) {
5959                                                         return hook( this.originalEvent );
5960                                         }
5961                                 } :
5962                                 function() {
5963                                         if ( this.originalEvent ) {
5964                                                         return this.originalEvent[ name ];
5965                                         }
5966                                 },
5967
5968                         set: function( value ) {
5969                                 Object.defineProperty( this, name, {
5970                                         enumerable: true,
5971                                         configurable: true,
5972                                         writable: true,
5973                                         value: value
5974                                 } );
5975                         }
5976                 } );
5977         },
5978
5979         fix: function( originalEvent ) {
5980                 return originalEvent[ jQuery.expando ] ?
5981                         originalEvent :
5982                         new jQuery.Event( originalEvent );
5983         },
5984
5985         special: {
5986                 load: {
5987
5988                         // Prevent triggered image.load events from bubbling to window.load
5989                         noBubble: true
5990                 },
5991                 click: {
5992
5993                         // Utilize native event to ensure correct state for checkable inputs
5994                         setup: function( data ) {
5995
5996                                 // For mutual compressibility with _default, replace `this` access with a local var.
5997                                 // `|| data` is dead code meant only to preserve the variable through minification.
5998                                 var el = this || data;
5999
6000                                 // Claim the first handler
6001                                 if ( rcheckableType.test( el.type ) &&
6002                                         el.click && nodeName( el, "input" ) ) {
6003
6004                                         // dataPriv.set( el, "click", ... )
6005                                         leverageNative( el, "click", returnTrue );
6006                                 }
6007
6008                                 // Return false to allow normal processing in the caller
6009                                 return false;
6010                         },
6011                         trigger: function( data ) {
6012
6013                                 // For mutual compressibility with _default, replace `this` access with a local var.
6014                                 // `|| data` is dead code meant only to preserve the variable through minification.
6015                                 var el = this || data;
6016
6017                                 // Force setup before triggering a click
6018                                 if ( rcheckableType.test( el.type ) &&
6019                                         el.click && nodeName( el, "input" ) ) {
6020
6021                                         leverageNative( el, "click" );
6022                                 }
6023
6024                                 // Return non-false to allow normal event-path propagation
6025                                 return true;
6026                         },
6027
6028                         // For cross-browser consistency, suppress native .click() on links
6029                         // Also prevent it if we're currently inside a leveraged native-event stack
6030                         _default: function( event ) {
6031                                 var target = event.target;
6032                                 return rcheckableType.test( target.type ) &&
6033                                         target.click && nodeName( target, "input" ) &&
6034                                         dataPriv.get( target, "click" ) ||
6035                                         nodeName( target, "a" );
6036                         }
6037                 },
6038
6039                 beforeunload: {
6040                         postDispatch: function( event ) {
6041
6042                                 // Support: Firefox 20+
6043                                 // Firefox doesn't alert if the returnValue field is not set.
6044                                 if ( event.result !== undefined && event.originalEvent ) {
6045                                         event.originalEvent.returnValue = event.result;
6046                                 }
6047                         }
6048                 }
6049         }
6050     };
6051
6052     // Ensure the presence of an event listener that handles manually-triggered
6053     // synthetic events by interrupting progress until reinvoked in response to
6054     // *native* events that it fires directly, ensuring that state changes have
6055     // already occurred before other listeners are invoked.
6056     function leverageNative( el, type, expectSync ) {
6057
6058         // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add
6059         if ( !expectSync ) {
6060                 if ( dataPriv.get( el, type ) === undefined ) {
6061                         jQuery.event.add( el, type, returnTrue );
6062                 }
6063                 return;
6064         }
6065
6066         // Register the controller as a special universal handler for all event namespaces
6067         dataPriv.set( el, type, false );
6068         jQuery.event.add( el, type, {
6069                 namespace: false,
6070                 handler: function( event ) {
6071                         var notAsync, result,
6072                                 saved = dataPriv.get( this, type );
6073
6074                         if ( ( event.isTrigger & 1 ) && this[ type ] ) {
6075
6076                                 // Interrupt processing of the outer synthetic .trigger()ed event
6077                                 // Saved data should be false in such cases, but might be a leftover capture object
6078                                 // from an async native handler (gh-4350)
6079                                 if ( !saved.length ) {
6080
6081                                         // Store arguments for use when handling the inner native event
6082                                         // There will always be at least one argument (an event object), so this array
6083                                         // will not be confused with a leftover capture object.
6084                                         saved = slice.call( arguments );
6085                                         dataPriv.set( this, type, saved );
6086
6087                                         // Trigger the native event and capture its result
6088                                         // Support: IE <=9 - 11+
6089                                         // focus() and blur() are asynchronous
6090                                         notAsync = expectSync( this, type );
6091                                         this[ type ]();
6092                                         result = dataPriv.get( this, type );
6093                                         if ( saved !== result || notAsync ) {
6094                                                 dataPriv.set( this, type, false );
6095                                         } else {
6096                                                 result = {};
6097                                         }
6098                                         if ( saved !== result ) {
6099
6100                                                 // Cancel the outer synthetic event
6101                                                 event.stopImmediatePropagation();
6102                                                 event.preventDefault();
6103                                                 return result.value;
6104                                         }
6105
6106                                 // If this is an inner synthetic event for an event with a bubbling surrogate
6107                                 // (focus or blur), assume that the surrogate already propagated from triggering the
6108                                 // native event and prevent that from happening again here.
6109                                 // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
6110                                 // bubbling surrogate propagates *after* the non-bubbling base), but that seems
6111                                 // less bad than duplication.
6112                                 } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {
6113                                         event.stopPropagation();
6114                                 }
6115
6116                         // If this is a native event triggered above, everything is now in order
6117                         // Fire an inner synthetic event with the original arguments
6118                         } else if ( saved.length ) {
6119
6120                                 // ...and capture the result
6121                                 dataPriv.set( this, type, {
6122                                         value: jQuery.event.trigger(
6123
6124                                                 // Support: IE <=9 - 11+
6125                                                 // Extend with the prototype to reset the above stopImmediatePropagation()
6126                                                 jQuery.extend( saved[ 0 ], jQuery.Event.prototype ),
6127                                                 saved.slice( 1 ),
6128                                                 this
6129                                         )
6130                                 } );
6131
6132                                 // Abort handling of the native event
6133                                 event.stopImmediatePropagation();
6134                         }
6135                 }
6136         } );
6137     }
6138
6139     jQuery.removeEvent = function( elem, type, handle ) {
6140
6141         // This "if" is needed for plain objects
6142         if ( elem.removeEventListener ) {
6143                 elem.removeEventListener( type, handle );
6144         }
6145     };
6146
6147     jQuery.Event = function( src, props ) {
6148
6149         // Allow instantiation without the 'new' keyword
6150         if ( !( this instanceof jQuery.Event ) ) {
6151                 return new jQuery.Event( src, props );
6152         }
6153
6154         // Event object
6155         if ( src && src.type ) {
6156                 this.originalEvent = src;
6157                 this.type = src.type;
6158
6159                 // Events bubbling up the document may have been marked as prevented
6160                 // by a handler lower down the tree; reflect the correct value.
6161                 this.isDefaultPrevented = src.defaultPrevented ||
6162                                 src.defaultPrevented === undefined &&
6163
6164                                 // Support: Android <=2.3 only
6165                                 src.returnValue === false ?
6166                         returnTrue :
6167                         returnFalse;
6168
6169                 // Create target properties
6170                 // Support: Safari <=6 - 7 only
6171                 // Target should not be a text node (#504, #13143)
6172                 this.target = ( src.target && src.target.nodeType === 3 ) ?
6173                         src.target.parentNode :
6174                         src.target;
6175
6176                 this.currentTarget = src.currentTarget;
6177                 this.relatedTarget = src.relatedTarget;
6178
6179         // Event type
6180         } else {
6181                 this.type = src;
6182         }
6183
6184         // Put explicitly provided properties onto the event object
6185         if ( props ) {
6186                 jQuery.extend( this, props );
6187         }
6188
6189         // Create a timestamp if incoming event doesn't have one
6190         this.timeStamp = src && src.timeStamp || Date.now();
6191
6192         // Mark it as fixed
6193         this[ jQuery.expando ] = true;
6194     };
6195
6196     // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
6197     // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
6198     jQuery.Event.prototype = {
6199         constructor: jQuery.Event,
6200         isDefaultPrevented: returnFalse,
6201         isPropagationStopped: returnFalse,
6202         isImmediatePropagationStopped: returnFalse,
6203         isSimulated: false,
6204
6205         preventDefault: function() {
6206                 var e = this.originalEvent;
6207
6208                 this.isDefaultPrevented = returnTrue;
6209
6210                 if ( e && !this.isSimulated ) {
6211                         e.preventDefault();
6212                 }
6213         },
6214         stopPropagation: function() {
6215                 var e = this.originalEvent;
6216
6217                 this.isPropagationStopped = returnTrue;
6218
6219                 if ( e && !this.isSimulated ) {
6220                         e.stopPropagation();
6221                 }
6222         },
6223         stopImmediatePropagation: function() {
6224                 var e = this.originalEvent;
6225
6226                 this.isImmediatePropagationStopped = returnTrue;
6227
6228                 if ( e && !this.isSimulated ) {
6229                         e.stopImmediatePropagation();
6230                 }
6231
6232                 this.stopPropagation();
6233         }
6234     };
6235
6236     // Includes all common event props including KeyEvent and MouseEvent specific props
6237     jQuery.each( {
6238         altKey: true,
6239         bubbles: true,
6240         cancelable: true,
6241         changedTouches: true,
6242         ctrlKey: true,
6243         detail: true,
6244         eventPhase: true,
6245         metaKey: true,
6246         pageX: true,
6247         pageY: true,
6248         shiftKey: true,
6249         view: true,
6250         "char": true,
6251         code: true,
6252         charCode: true,
6253         key: true,
6254         keyCode: true,
6255         button: true,
6256         buttons: true,
6257         clientX: true,
6258         clientY: true,
6259         offsetX: true,
6260         offsetY: true,
6261         pointerId: true,
6262         pointerType: true,
6263         screenX: true,
6264         screenY: true,
6265         targetTouches: true,
6266         toElement: true,
6267         touches: true,
6268
6269         which: function( event ) {
6270                 var button = event.button;
6271
6272                 // Add which for key events
6273                 if ( event.which == null && rkeyEvent.test( event.type ) ) {
6274                         return event.charCode != null ? event.charCode : event.keyCode;
6275                 }
6276
6277                 // Add which for click: 1 === left; 2 === middle; 3 === right
6278                 if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
6279                         if ( button & 1 ) {
6280                                 return 1;
6281                         }
6282
6283                         if ( button & 2 ) {
6284                                 return 3;
6285                         }
6286
6287                         if ( button & 4 ) {
6288                                 return 2;
6289                         }
6290
6291                         return 0;
6292                 }
6293
6294                 return event.which;
6295         }
6296     }, jQuery.event.addProp );
6297
6298     jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) {
6299         jQuery.event.special[ type ] = {
6300
6301                 // Utilize native event if possible so blur/focus sequence is correct
6302                 setup: function() {
6303
6304                         // Claim the first handler
6305                         // dataPriv.set( this, "focus", ... )
6306                         // dataPriv.set( this, "blur", ... )
6307                         leverageNative( this, type, expectSync );
6308
6309                         // Return false to allow normal processing in the caller
6310                         return false;
6311                 },
6312                 trigger: function() {
6313
6314                         // Force setup before trigger
6315                         leverageNative( this, type );
6316
6317                         // Return non-false to allow normal event-path propagation
6318                         return true;
6319                 },
6320
6321                 delegateType: delegateType
6322         };
6323     } );
6324
6325     // Create mouseenter/leave events using mouseover/out and event-time checks
6326     // so that event delegation works in jQuery.
6327     // Do the same for pointerenter/pointerleave and pointerover/pointerout
6328     //
6329     // Support: Safari 7 only
6330     // Safari sends mouseenter too often; see:
6331     // https://bugs.chromium.org/p/chromium/issues/detail?id=470258
6332     // for the description of the bug (it existed in older Chrome versions as well).
6333     jQuery.each( {
6334         mouseenter: "mouseover",
6335         mouseleave: "mouseout",
6336         pointerenter: "pointerover",
6337         pointerleave: "pointerout"
6338     }, function( orig, fix ) {
6339         jQuery.event.special[ orig ] = {
6340                 delegateType: fix,
6341                 bindType: fix,
6342
6343                 handle: function( event ) {
6344                         var ret,
6345                                 target = this,
6346                                 related = event.relatedTarget,
6347                                 handleObj = event.handleObj;
6348
6349                         // For mouseenter/leave call the handler if related is outside the target.
6350                         // NB: No relatedTarget if the mouse left/entered the browser window
6351                         if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
6352                                 event.type = handleObj.origType;
6353                                 ret = handleObj.handler.apply( this, arguments );
6354                                 event.type = fix;
6355                         }
6356                         return ret;
6357                 }
6358         };
6359     } );
6360
6361     jQuery.fn.extend( {
6362
6363         on: function( types, selector, data, fn ) {
6364                 return on( this, types, selector, data, fn );
6365         },
6366         one: function( types, selector, data, fn ) {
6367                 return on( this, types, selector, data, fn, 1 );
6368         },
6369         off: function( types, selector, fn ) {
6370                 var handleObj, type;
6371                 if ( types && types.preventDefault && types.handleObj ) {
6372
6373                         // ( event )  dispatched jQuery.Event
6374                         handleObj = types.handleObj;
6375                         jQuery( types.delegateTarget ).off(
6376                                 handleObj.namespace ?
6377                                         handleObj.origType + "." + handleObj.namespace :
6378                                         handleObj.origType,
6379                                 handleObj.selector,
6380                                 handleObj.handler
6381                         );
6382                         return this;
6383                 }
6384                 if ( typeof types === "object" ) {
6385
6386                         // ( types-object [, selector] )
6387                         for ( type in types ) {
6388                                 this.off( type, selector, types[ type ] );
6389                         }
6390                         return this;
6391                 }
6392                 if ( selector === false || typeof selector === "function" ) {
6393
6394                         // ( types [, fn] )
6395                         fn = selector;
6396                         selector = undefined;
6397                 }
6398                 if ( fn === false ) {
6399                         fn = returnFalse;
6400                 }
6401                 return this.each( function() {
6402                         jQuery.event.remove( this, types, fn, selector );
6403                 } );
6404         }
6405     } );
6406
6407
6408     var
6409
6410         // Support: IE <=10 - 11, Edge 12 - 13 only
6411         // In IE/Edge using regex groups here causes severe slowdowns.
6412         // See https://connect.microsoft.com/IE/feedback/details/1736512/
6413         rnoInnerhtml = /<script|<style|<link/i,
6414
6415         // checked="checked" or checked
6416         rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
6417         rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
6418
6419     // Prefer a tbody over its parent table for containing new rows
6420     function manipulationTarget( elem, content ) {
6421         if ( nodeName( elem, "table" ) &&
6422                 nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
6423
6424                 return jQuery( elem ).children( "tbody" )[ 0 ] || elem;
6425         }
6426
6427         return elem;
6428     }
6429
6430     // Replace/restore the type attribute of script elements for safe DOM manipulation
6431     function disableScript( elem ) {
6432         elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
6433         return elem;
6434     }
6435     function restoreScript( elem ) {
6436         if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) {
6437                 elem.type = elem.type.slice( 5 );
6438         } else {
6439                 elem.removeAttribute( "type" );
6440         }
6441
6442         return elem;
6443     }
6444
6445     function cloneCopyEvent( src, dest ) {
6446         var i, l, type, pdataOld, udataOld, udataCur, events;
6447
6448         if ( dest.nodeType !== 1 ) {
6449                 return;
6450         }
6451
6452         // 1. Copy private data: events, handlers, etc.
6453         if ( dataPriv.hasData( src ) ) {
6454                 pdataOld = dataPriv.get( src );
6455                 events = pdataOld.events;
6456
6457                 if ( events ) {
6458                         dataPriv.remove( dest, "handle events" );
6459
6460                         for ( type in events ) {
6461                                 for ( i = 0, l = events[ type ].length; i < l; i++ ) {
6462                                         jQuery.event.add( dest, type, events[ type ][ i ] );
6463                                 }
6464                         }
6465                 }
6466         }
6467
6468         // 2. Copy user data
6469         if ( dataUser.hasData( src ) ) {
6470                 udataOld = dataUser.access( src );
6471                 udataCur = jQuery.extend( {}, udataOld );
6472
6473                 dataUser.set( dest, udataCur );
6474         }
6475     }
6476
6477     // Fix IE bugs, see support tests
6478     function fixInput( src, dest ) {
6479         var nodeName = dest.nodeName.toLowerCase();
6480
6481         // Fails to persist the checked state of a cloned checkbox or radio button.
6482         if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
6483                 dest.checked = src.checked;
6484
6485         // Fails to return the selected option to the default selected state when cloning options
6486         } else if ( nodeName === "input" || nodeName === "textarea" ) {
6487                 dest.defaultValue = src.defaultValue;
6488         }
6489     }
6490
6491     function domManip( collection, args, callback, ignored ) {
6492
6493         // Flatten any nested arrays
6494         args = flat( args );
6495
6496         var fragment, first, scripts, hasScripts, node, doc,
6497                 i = 0,
6498                 l = collection.length,
6499                 iNoClone = l - 1,
6500                 value = args[ 0 ],
6501                 valueIsFunction = isFunction( value );
6502
6503         // We can't cloneNode fragments that contain checked, in WebKit
6504         if ( valueIsFunction ||
6505                         ( l > 1 && typeof value === "string" &&
6506                                 !support.checkClone && rchecked.test( value ) ) ) {
6507                 return collection.each( function( index ) {
6508                         var self = collection.eq( index );
6509                         if ( valueIsFunction ) {
6510                                 args[ 0 ] = value.call( this, index, self.html() );
6511                         }
6512                         domManip( self, args, callback, ignored );
6513                 } );
6514         }
6515
6516         if ( l ) {
6517                 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
6518                 first = fragment.firstChild;
6519
6520                 if ( fragment.childNodes.length === 1 ) {
6521                         fragment = first;
6522                 }
6523
6524                 // Require either new content or an interest in ignored elements to invoke the callback
6525                 if ( first || ignored ) {
6526                         scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
6527                         hasScripts = scripts.length;
6528
6529                         // Use the original fragment for the last item
6530                         // instead of the first because it can end up
6531                         // being emptied incorrectly in certain situations (#8070).
6532                         for ( ; i < l; i++ ) {
6533                                 node = fragment;
6534
6535                                 if ( i !== iNoClone ) {
6536                                         node = jQuery.clone( node, true, true );
6537
6538                                         // Keep references to cloned scripts for later restoration
6539                                         if ( hasScripts ) {
6540
6541                                                 // Support: Android <=4.0 only, PhantomJS 1 only
6542                                                 // push.apply(_, arraylike) throws on ancient WebKit
6543                                                 jQuery.merge( scripts, getAll( node, "script" ) );
6544                                         }
6545                                 }
6546
6547                                 callback.call( collection[ i ], node, i );
6548                         }
6549
6550                         if ( hasScripts ) {
6551                                 doc = scripts[ scripts.length - 1 ].ownerDocument;
6552
6553                                 // Reenable scripts
6554                                 jQuery.map( scripts, restoreScript );
6555
6556                                 // Evaluate executable scripts on first document insertion
6557                                 for ( i = 0; i < hasScripts; i++ ) {
6558                                         node = scripts[ i ];
6559                                         if ( rscriptType.test( node.type || "" ) &&
6560                                                 !dataPriv.access( node, "globalEval" ) &&
6561                                                 jQuery.contains( doc, node ) ) {
6562
6563                                                 if ( node.src && ( node.type || "" ).toLowerCase()  !== "module" ) {
6564
6565                                                         // Optional AJAX dependency, but won't run scripts if not present
6566                                                         if ( jQuery._evalUrl && !node.noModule ) {
6567                                                                 jQuery._evalUrl( node.src, {
6568                                                                         nonce: node.nonce || node.getAttribute( "nonce" )
6569                                                                 }, doc );
6570                                                         }
6571                                                 } else {
6572                                                         DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc );
6573                                                 }
6574                                         }
6575                                 }
6576                         }
6577                 }
6578         }
6579
6580         return collection;
6581     }
6582
6583     function remove( elem, selector, keepData ) {
6584         var node,
6585                 nodes = selector ? jQuery.filter( selector, elem ) : elem,
6586                 i = 0;
6587
6588         for ( ; ( node = nodes[ i ] ) != null; i++ ) {
6589                 if ( !keepData && node.nodeType === 1 ) {
6590                         jQuery.cleanData( getAll( node ) );
6591                 }
6592
6593                 if ( node.parentNode ) {
6594                         if ( keepData && isAttached( node ) ) {
6595                                 setGlobalEval( getAll( node, "script" ) );
6596                         }
6597                         node.parentNode.removeChild( node );
6598                 }
6599         }
6600
6601         return elem;
6602     }
6603
6604     jQuery.extend( {
6605         htmlPrefilter: function( html ) {
6606                 return html;
6607         },
6608
6609         clone: function( elem, dataAndEvents, deepDataAndEvents ) {
6610                 var i, l, srcElements, destElements,
6611                         clone = elem.cloneNode( true ),
6612                         inPage = isAttached( elem );
6613
6614                 // Fix IE cloning issues
6615                 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
6616                                 !jQuery.isXMLDoc( elem ) ) {
6617
6618                         // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2
6619                         destElements = getAll( clone );
6620                         srcElements = getAll( elem );
6621
6622                         for ( i = 0, l = srcElements.length; i < l; i++ ) {
6623                                 fixInput( srcElements[ i ], destElements[ i ] );
6624                         }
6625                 }
6626
6627                 // Copy the events from the original to the clone
6628                 if ( dataAndEvents ) {
6629                         if ( deepDataAndEvents ) {
6630                                 srcElements = srcElements || getAll( elem );
6631                                 destElements = destElements || getAll( clone );
6632
6633                                 for ( i = 0, l = srcElements.length; i < l; i++ ) {
6634                                         cloneCopyEvent( srcElements[ i ], destElements[ i ] );
6635                                 }
6636                         } else {
6637                                 cloneCopyEvent( elem, clone );
6638                         }
6639                 }
6640
6641                 // Preserve script evaluation history
6642                 destElements = getAll( clone, "script" );
6643                 if ( destElements.length > 0 ) {
6644                         setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
6645                 }
6646
6647                 // Return the cloned set
6648                 return clone;
6649         },
6650
6651         cleanData: function( elems ) {
6652                 var data, elem, type,
6653                         special = jQuery.event.special,
6654                         i = 0;
6655
6656                 for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
6657                         if ( acceptData( elem ) ) {
6658                                 if ( ( data = elem[ dataPriv.expando ] ) ) {
6659                                         if ( data.events ) {
6660                                                 for ( type in data.events ) {
6661                                                         if ( special[ type ] ) {
6662                                                                 jQuery.event.remove( elem, type );
6663
6664                                                         // This is a shortcut to avoid jQuery.event.remove's overhead
6665                                                         } else {
6666                                                                 jQuery.removeEvent( elem, type, data.handle );
6667                                                         }
6668                                                 }
6669                                         }
6670
6671                                         // Support: Chrome <=35 - 45+
6672                                         // Assign undefined instead of using delete, see Data#remove
6673                                         elem[ dataPriv.expando ] = undefined;
6674                                 }
6675                                 if ( elem[ dataUser.expando ] ) {
6676
6677                                         // Support: Chrome <=35 - 45+
6678                                         // Assign undefined instead of using delete, see Data#remove
6679                                         elem[ dataUser.expando ] = undefined;
6680                                 }
6681                         }
6682                 }
6683         }
6684     } );
6685
6686     jQuery.fn.extend( {
6687         detach: function( selector ) {
6688                 return remove( this, selector, true );
6689         },
6690
6691         remove: function( selector ) {
6692                 return remove( this, selector );
6693         },
6694
6695         text: function( value ) {
6696                 return access( this, function( value ) {
6697                         return value === undefined ?
6698                                 jQuery.text( this ) :
6699                                 this.empty().each( function() {
6700                                         if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6701                                                 this.textContent = value;
6702                                         }
6703                                 } );
6704                 }, null, value, arguments.length );
6705         },
6706
6707         append: function() {
6708                 return domManip( this, arguments, function( elem ) {
6709                         if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6710                                 var target = manipulationTarget( this, elem );
6711                                 target.appendChild( elem );
6712                         }
6713                 } );
6714         },
6715
6716         prepend: function() {
6717                 return domManip( this, arguments, function( elem ) {
6718                         if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
6719                                 var target = manipulationTarget( this, elem );
6720                                 target.insertBefore( elem, target.firstChild );
6721                         }
6722                 } );
6723         },
6724
6725         before: function() {
6726                 return domManip( this, arguments, function( elem ) {
6727                         if ( this.parentNode ) {
6728                                 this.parentNode.insertBefore( elem, this );
6729                         }
6730                 } );
6731         },
6732
6733         after: function() {
6734                 return domManip( this, arguments, function( elem ) {
6735                         if ( this.parentNode ) {
6736                                 this.parentNode.insertBefore( elem, this.nextSibling );
6737                         }
6738                 } );
6739         },
6740
6741         empty: function() {
6742                 var elem,
6743                         i = 0;
6744
6745                 for ( ; ( elem = this[ i ] ) != null; i++ ) {
6746                         if ( elem.nodeType === 1 ) {
6747
6748                                 // Prevent memory leaks
6749                                 jQuery.cleanData( getAll( elem, false ) );
6750
6751                                 // Remove any remaining nodes
6752                                 elem.textContent = "";
6753                         }
6754                 }
6755
6756                 return this;
6757         },
6758
6759         clone: function( dataAndEvents, deepDataAndEvents ) {
6760                 dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
6761                 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
6762
6763                 return this.map( function() {
6764                         return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
6765                 } );
6766         },
6767
6768         html: function( value ) {
6769                 return access( this, function( value ) {
6770                         var elem = this[ 0 ] || {},
6771                                 i = 0,
6772                                 l = this.length;
6773
6774                         if ( value === undefined && elem.nodeType === 1 ) {
6775                                 return elem.innerHTML;
6776                         }
6777
6778                         // See if we can take a shortcut and just use innerHTML
6779                         if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
6780                                 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
6781
6782                                 value = jQuery.htmlPrefilter( value );
6783
6784                                 try {
6785                                         for ( ; i < l; i++ ) {
6786                                                 elem = this[ i ] || {};
6787
6788                                                 // Remove element nodes and prevent memory leaks
6789                                                 if ( elem.nodeType === 1 ) {
6790                                                         jQuery.cleanData( getAll( elem, false ) );
6791                                                         elem.innerHTML = value;
6792                                                 }
6793                                         }
6794
6795                                         elem = 0;
6796
6797                                 // If using innerHTML throws an exception, use the fallback method
6798                                 } catch ( e ) {}
6799                         }
6800
6801                         if ( elem ) {
6802                                 this.empty().append( value );
6803                         }
6804                 }, null, value, arguments.length );
6805         },
6806
6807         replaceWith: function() {
6808                 var ignored = [];
6809
6810                 // Make the changes, replacing each non-ignored context element with the new content
6811                 return domManip( this, arguments, function( elem ) {
6812                         var parent = this.parentNode;
6813
6814                         if ( jQuery.inArray( this, ignored ) < 0 ) {
6815                                 jQuery.cleanData( getAll( this ) );
6816                                 if ( parent ) {
6817                                         parent.replaceChild( elem, this );
6818                                 }
6819                         }
6820
6821                 // Force callback invocation
6822                 }, ignored );
6823         }
6824     } );
6825
6826     jQuery.each( {
6827         appendTo: "append",
6828         prependTo: "prepend",
6829         insertBefore: "before",
6830         insertAfter: "after",
6831         replaceAll: "replaceWith"
6832     }, function( name, original ) {
6833         jQuery.fn[ name ] = function( selector ) {
6834                 var elems,
6835                         ret = [],
6836                         insert = jQuery( selector ),
6837                         last = insert.length - 1,
6838                         i = 0;
6839
6840                 for ( ; i <= last; i++ ) {
6841                         elems = i === last ? this : this.clone( true );
6842                         jQuery( insert[ i ] )[ original ]( elems );
6843
6844                         // Support: Android <=4.0 only, PhantomJS 1 only
6845                         // .get() because push.apply(_, arraylike) throws on ancient WebKit
6846                         push.apply( ret, elems.get() );
6847                 }
6848
6849                 return this.pushStack( ret );
6850         };
6851     } );
6852     var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
6853
6854     var getStyles = function( elem ) {
6855
6856                 // Support: IE <=11 only, Firefox <=30 (#15098, #14150)
6857                 // IE throws on elements created in popups
6858                 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
6859                 var view = elem.ownerDocument.defaultView;
6860
6861                 if ( !view || !view.opener ) {
6862                         view = window;
6863                 }
6864
6865                 return view.getComputedStyle( elem );
6866         };
6867
6868     var swap = function( elem, options, callback ) {
6869         var ret, name,
6870                 old = {};
6871
6872         // Remember the old values, and insert the new ones
6873         for ( name in options ) {
6874                 old[ name ] = elem.style[ name ];
6875                 elem.style[ name ] = options[ name ];
6876         }
6877
6878         ret = callback.call( elem );
6879
6880         // Revert the old values
6881         for ( name in options ) {
6882                 elem.style[ name ] = old[ name ];
6883         }
6884
6885         return ret;
6886     };
6887
6888
6889     var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" );
6890
6891
6892
6893     ( function() {
6894
6895         // Executing both pixelPosition & boxSizingReliable tests require only one layout
6896         // so they're executed at the same time to save the second computation.
6897         function computeStyleTests() {
6898
6899                 // This is a singleton, we need to execute it only once
6900                 if ( !div ) {
6901                         return;
6902                 }
6903
6904                 container.style.cssText = "position:absolute;left:-11111px;width:60px;" +
6905                         "margin-top:1px;padding:0;border:0";
6906                 div.style.cssText =
6907                         "position:relative;display:block;box-sizing:border-box;overflow:scroll;" +
6908                         "margin:auto;border:1px;padding:1px;" +
6909                         "width:60%;top:1%";
6910                 documentElement.appendChild( container ).appendChild( div );
6911
6912                 var divStyle = window.getComputedStyle( div );
6913                 pixelPositionVal = divStyle.top !== "1%";
6914
6915                 // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
6916                 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12;
6917
6918                 // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3
6919                 // Some styles come back with percentage values, even though they shouldn't
6920                 div.style.right = "60%";
6921                 pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36;
6922
6923                 // Support: IE 9 - 11 only
6924                 // Detect misreporting of content dimensions for box-sizing:border-box elements
6925                 boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36;
6926
6927                 // Support: IE 9 only
6928                 // Detect overflow:scroll screwiness (gh-3699)
6929                 // Support: Chrome <=64
6930                 // Don't get tricked when zoom affects offsetWidth (gh-4029)
6931                 div.style.position = "absolute";
6932                 scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12;
6933
6934                 documentElement.removeChild( container );
6935
6936                 // Nullify the div so it wouldn't be stored in the memory and
6937                 // it will also be a sign that checks already performed
6938                 div = null;
6939         }
6940
6941         function roundPixelMeasures( measure ) {
6942                 return Math.round( parseFloat( measure ) );
6943         }
6944
6945         var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal,
6946                 reliableTrDimensionsVal, reliableMarginLeftVal,
6947                 container = document.createElement( "div" ),
6948                 div = document.createElement( "div" );
6949
6950         // Finish early in limited (non-browser) environments
6951         if ( !div.style ) {
6952                 return;
6953         }
6954
6955         // Support: IE <=9 - 11 only
6956         // Style of cloned element affects source element cloned (#8908)
6957         div.style.backgroundClip = "content-box";
6958         div.cloneNode( true ).style.backgroundClip = "";
6959         support.clearCloneStyle = div.style.backgroundClip === "content-box";
6960
6961         jQuery.extend( support, {
6962                 boxSizingReliable: function() {
6963                         computeStyleTests();
6964                         return boxSizingReliableVal;
6965                 },
6966                 pixelBoxStyles: function() {
6967                         computeStyleTests();
6968                         return pixelBoxStylesVal;
6969                 },
6970                 pixelPosition: function() {
6971                         computeStyleTests();
6972                         return pixelPositionVal;
6973                 },
6974                 reliableMarginLeft: function() {
6975                         computeStyleTests();
6976                         return reliableMarginLeftVal;
6977                 },
6978                 scrollboxSize: function() {
6979                         computeStyleTests();
6980                         return scrollboxSizeVal;
6981                 },
6982
6983                 // Support: IE 9 - 11+, Edge 15 - 18+
6984                 // IE/Edge misreport `getComputedStyle` of table rows with width/height
6985                 // set in CSS while `offset*` properties report correct values.
6986                 // Behavior in IE 9 is more subtle than in newer versions & it passes
6987                 // some versions of this test; make sure not to make it pass there!
6988                 reliableTrDimensions: function() {
6989                         var table, tr, trChild, trStyle;
6990                         if ( reliableTrDimensionsVal == null ) {
6991                                 table = document.createElement( "table" );
6992                                 tr = document.createElement( "tr" );
6993                                 trChild = document.createElement( "div" );
6994
6995                                 table.style.cssText = "position:absolute;left:-11111px";
6996                                 tr.style.height = "1px";
6997                                 trChild.style.height = "9px";
6998
6999                                 documentElement
7000                                         .appendChild( table )
7001                                         .appendChild( tr )
7002                                         .appendChild( trChild );
7003
7004                                 trStyle = window.getComputedStyle( tr );
7005                                 reliableTrDimensionsVal = parseInt( trStyle.height ) > 3;
7006
7007                                 documentElement.removeChild( table );
7008                         }
7009                         return reliableTrDimensionsVal;
7010                 }
7011         } );
7012     } )();
7013
7014
7015     function curCSS( elem, name, computed ) {
7016         var width, minWidth, maxWidth, ret,
7017
7018                 // Support: Firefox 51+
7019                 // Retrieving style before computed somehow
7020                 // fixes an issue with getting wrong values
7021                 // on detached elements
7022                 style = elem.style;
7023
7024         computed = computed || getStyles( elem );
7025
7026         // getPropertyValue is needed for:
7027         //   .css('filter') (IE 9 only, #12537)
7028         //   .css('--customProperty) (#3144)
7029         if ( computed ) {
7030                 ret = computed.getPropertyValue( name ) || computed[ name ];
7031
7032                 if ( ret === "" && !isAttached( elem ) ) {
7033                         ret = jQuery.style( elem, name );
7034                 }
7035
7036                 // A tribute to the "awesome hack by Dean Edwards"
7037                 // Android Browser returns percentage for some values,
7038                 // but width seems to be reliably pixels.
7039                 // This is against the CSSOM draft spec:
7040                 // https://drafts.csswg.org/cssom/#resolved-values
7041                 if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) {
7042
7043                         // Remember the original values
7044                         width = style.width;
7045                         minWidth = style.minWidth;
7046                         maxWidth = style.maxWidth;
7047
7048                         // Put in the new values to get a computed value out
7049                         style.minWidth = style.maxWidth = style.width = ret;
7050                         ret = computed.width;
7051
7052                         // Revert the changed values
7053                         style.width = width;
7054                         style.minWidth = minWidth;
7055                         style.maxWidth = maxWidth;
7056                 }
7057         }
7058
7059         return ret !== undefined ?
7060
7061                 // Support: IE <=9 - 11 only
7062                 // IE returns zIndex value as an integer.
7063                 ret + "" :
7064                 ret;
7065     }
7066
7067
7068     function addGetHookIf( conditionFn, hookFn ) {
7069
7070         // Define the hook, we'll check on the first run if it's really needed.
7071         return {
7072                 get: function() {
7073                         if ( conditionFn() ) {
7074
7075                                 // Hook not needed (or it's not possible to use it due
7076                                 // to missing dependency), remove it.
7077                                 delete this.get;
7078                                 return;
7079                         }
7080
7081                         // Hook needed; redefine it so that the support test is not executed again.
7082                         return ( this.get = hookFn ).apply( this, arguments );
7083                 }
7084         };
7085     }
7086
7087
7088     var cssPrefixes = [ "Webkit", "Moz", "ms" ],
7089         emptyStyle = document.createElement( "div" ).style,
7090         vendorProps = {};
7091
7092     // Return a vendor-prefixed property or undefined
7093     function vendorPropName( name ) {
7094
7095         // Check for vendor prefixed names
7096         var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
7097                 i = cssPrefixes.length;
7098
7099         while ( i-- ) {
7100                 name = cssPrefixes[ i ] + capName;
7101                 if ( name in emptyStyle ) {
7102                         return name;
7103                 }
7104         }
7105     }
7106
7107     // Return a potentially-mapped jQuery.cssProps or vendor prefixed property
7108     function finalPropName( name ) {
7109         var final = jQuery.cssProps[ name ] || vendorProps[ name ];
7110
7111         if ( final ) {
7112                 return final;
7113         }
7114         if ( name in emptyStyle ) {
7115                 return name;
7116         }
7117         return vendorProps[ name ] = vendorPropName( name ) || name;
7118     }
7119
7120
7121     var
7122
7123         // Swappable if display is none or starts with table
7124         // except "table", "table-cell", or "table-caption"
7125         // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
7126         rdisplayswap = /^(none|table(?!-c[ea]).+)/,
7127         rcustomProp = /^--/,
7128         cssShow = { position: "absolute", visibility: "hidden", display: "block" },
7129         cssNormalTransform = {
7130                 letterSpacing: "0",
7131                 fontWeight: "400"
7132         };
7133
7134     function setPositiveNumber( _elem, value, subtract ) {
7135
7136         // Any relative (+/-) values have already been
7137         // normalized at this point
7138         var matches = rcssNum.exec( value );
7139         return matches ?
7140
7141                 // Guard against undefined "subtract", e.g., when used as in cssHooks
7142                 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
7143                 value;
7144     }
7145
7146     function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) {
7147         var i = dimension === "width" ? 1 : 0,
7148                 extra = 0,
7149                 delta = 0;
7150
7151         // Adjustment may not be necessary
7152         if ( box === ( isBorderBox ? "border" : "content" ) ) {
7153                 return 0;
7154         }
7155
7156         for ( ; i < 4; i += 2 ) {
7157
7158                 // Both box models exclude margin
7159                 if ( box === "margin" ) {
7160                         delta += jQuery.css( elem, box + cssExpand[ i ], true, styles );
7161                 }
7162
7163                 // If we get here with a content-box, we're seeking "padding" or "border" or "margin"
7164                 if ( !isBorderBox ) {
7165
7166                         // Add padding
7167                         delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
7168
7169                         // For "border" or "margin", add border
7170                         if ( box !== "padding" ) {
7171                                 delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
7172
7173                         // But still keep track of it otherwise
7174                         } else {
7175                                 extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
7176                         }
7177
7178                 // If we get here with a border-box (content + padding + border), we're seeking "content" or
7179                 // "padding" or "margin"
7180                 } else {
7181
7182                         // For "content", subtract padding
7183                         if ( box === "content" ) {
7184                                 delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
7185                         }
7186
7187                         // For "content" or "padding", subtract border
7188                         if ( box !== "margin" ) {
7189                                 delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
7190                         }
7191                 }
7192         }
7193
7194         // Account for positive content-box scroll gutter when requested by providing computedVal
7195         if ( !isBorderBox && computedVal >= 0 ) {
7196
7197                 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border
7198                 // Assuming integer scroll gutter, subtract the rest and round down
7199                 delta += Math.max( 0, Math.ceil(
7200                         elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
7201                         computedVal -
7202                         delta -
7203                         extra -
7204                         0.5
7205
7206                 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter
7207                 // Use an explicit zero to avoid NaN (gh-3964)
7208                 ) ) || 0;
7209         }
7210
7211         return delta;
7212     }
7213
7214     function getWidthOrHeight( elem, dimension, extra ) {
7215
7216         // Start with computed style
7217         var styles = getStyles( elem ),
7218
7219                 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322).
7220                 // Fake content-box until we know it's needed to know the true value.
7221                 boxSizingNeeded = !support.boxSizingReliable() || extra,
7222                 isBorderBox = boxSizingNeeded &&
7223                         jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
7224                 valueIsBorderBox = isBorderBox,
7225
7226                 val = curCSS( elem, dimension, styles ),
7227                 offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 );
7228
7229         // Support: Firefox <=54
7230         // Return a confounding non-pixel value or feign ignorance, as appropriate.
7231         if ( rnumnonpx.test( val ) ) {
7232                 if ( !extra ) {
7233                         return val;
7234                 }
7235                 val = "auto";
7236         }
7237
7238
7239         // Support: IE 9 - 11 only
7240         // Use offsetWidth/offsetHeight for when box sizing is unreliable.
7241         // In those cases, the computed value can be trusted to be border-box.
7242         if ( ( !support.boxSizingReliable() && isBorderBox ||
7243
7244                 // Support: IE 10 - 11+, Edge 15 - 18+
7245                 // IE/Edge misreport `getComputedStyle` of table rows with width/height
7246                 // set in CSS while `offset*` properties report correct values.
7247                 // Interestingly, in some cases IE 9 doesn't suffer from this issue.
7248                 !support.reliableTrDimensions() && nodeName( elem, "tr" ) ||
7249
7250                 // Fall back to offsetWidth/offsetHeight when value is "auto"
7251                 // This happens for inline elements with no explicit setting (gh-3571)
7252                 val === "auto" ||
7253
7254                 // Support: Android <=4.1 - 4.3 only
7255                 // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602)
7256                 !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) &&
7257
7258                 // Make sure the element is visible & connected
7259                 elem.getClientRects().length ) {
7260
7261                 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
7262
7263                 // Where available, offsetWidth/offsetHeight approximate border box dimensions.
7264                 // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the
7265                 // retrieved value as a content box dimension.
7266                 valueIsBorderBox = offsetProp in elem;
7267                 if ( valueIsBorderBox ) {
7268                         val = elem[ offsetProp ];
7269                 }
7270         }
7271
7272         // Normalize "" and auto
7273         val = parseFloat( val ) || 0;
7274
7275         // Adjust for the element's box model
7276         return ( val +
7277                 boxModelAdjustment(
7278                         elem,
7279                         dimension,
7280                         extra || ( isBorderBox ? "border" : "content" ),
7281                         valueIsBorderBox,
7282                         styles,
7283
7284                         // Provide the current computed size to request scroll gutter calculation (gh-3589)
7285                         val
7286                 )
7287         ) + "px";
7288     }
7289
7290     jQuery.extend( {
7291
7292         // Add in style property hooks for overriding the default
7293         // behavior of getting and setting a style property
7294         cssHooks: {
7295                 opacity: {
7296                         get: function( elem, computed ) {
7297                                 if ( computed ) {
7298
7299                                         // We should always get a number back from opacity
7300                                         var ret = curCSS( elem, "opacity" );
7301                                         return ret === "" ? "1" : ret;
7302                                 }
7303                         }
7304                 }
7305         },
7306
7307         // Don't automatically add "px" to these possibly-unitless properties
7308         cssNumber: {
7309                 "animationIterationCount": true,
7310                 "columnCount": true,
7311                 "fillOpacity": true,
7312                 "flexGrow": true,
7313                 "flexShrink": true,
7314                 "fontWeight": true,
7315                 "gridArea": true,
7316                 "gridColumn": true,
7317                 "gridColumnEnd": true,
7318                 "gridColumnStart": true,
7319                 "gridRow": true,
7320                 "gridRowEnd": true,
7321                 "gridRowStart": true,
7322                 "lineHeight": true,
7323                 "opacity": true,
7324                 "order": true,
7325                 "orphans": true,
7326                 "widows": true,
7327                 "zIndex": true,
7328                 "zoom": true
7329         },
7330
7331         // Add in properties whose names you wish to fix before
7332         // setting or getting the value
7333         cssProps: {},
7334
7335         // Get and set the style property on a DOM Node
7336         style: function( elem, name, value, extra ) {
7337
7338                 // Don't set styles on text and comment nodes
7339                 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
7340                         return;
7341                 }
7342
7343                 // Make sure that we're working with the right name
7344                 var ret, type, hooks,
7345                         origName = camelCase( name ),
7346                         isCustomProp = rcustomProp.test( name ),
7347                         style = elem.style;
7348
7349                 // Make sure that we're working with the right name. We don't
7350                 // want to query the value if it is a CSS custom property
7351                 // since they are user-defined.
7352                 if ( !isCustomProp ) {
7353                         name = finalPropName( origName );
7354                 }
7355
7356                 // Gets hook for the prefixed version, then unprefixed version
7357                 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
7358
7359                 // Check if we're setting a value
7360                 if ( value !== undefined ) {
7361                         type = typeof value;
7362
7363                         // Convert "+=" or "-=" to relative numbers (#7345)
7364                         if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
7365                                 value = adjustCSS( elem, name, ret );
7366
7367                                 // Fixes bug #9237
7368                                 type = "number";
7369                         }
7370
7371                         // Make sure that null and NaN values aren't set (#7116)
7372                         if ( value == null || value !== value ) {
7373                                 return;
7374                         }
7375
7376                         // If a number was passed in, add the unit (except for certain CSS properties)
7377                         // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append
7378                         // "px" to a few hardcoded values.
7379                         if ( type === "number" && !isCustomProp ) {
7380                                 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
7381                         }
7382
7383                         // background-* props affect original clone's values
7384                         if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) {
7385                                 style[ name ] = "inherit";
7386                         }
7387
7388                         // If a hook was provided, use that value, otherwise just set the specified value
7389                         if ( !hooks || !( "set" in hooks ) ||
7390                                 ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
7391
7392                                 if ( isCustomProp ) {
7393                                         style.setProperty( name, value );
7394                                 } else {
7395                                         style[ name ] = value;
7396                                 }
7397                         }
7398
7399                 } else {
7400
7401                         // If a hook was provided get the non-computed value from there
7402                         if ( hooks && "get" in hooks &&
7403                                 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
7404
7405                                 return ret;
7406                         }
7407
7408                         // Otherwise just get the value from the style object
7409                         return style[ name ];
7410                 }
7411         },
7412
7413         css: function( elem, name, extra, styles ) {
7414                 var val, num, hooks,
7415                         origName = camelCase( name ),
7416                         isCustomProp = rcustomProp.test( name );
7417
7418                 // Make sure that we're working with the right name. We don't
7419                 // want to modify the value if it is a CSS custom property
7420                 // since they are user-defined.
7421                 if ( !isCustomProp ) {
7422                         name = finalPropName( origName );
7423                 }
7424
7425                 // Try prefixed name followed by the unprefixed name
7426                 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
7427
7428                 // If a hook was provided get the computed value from there
7429                 if ( hooks && "get" in hooks ) {
7430                         val = hooks.get( elem, true, extra );
7431                 }
7432
7433                 // Otherwise, if a way to get the computed value exists, use that
7434                 if ( val === undefined ) {
7435                         val = curCSS( elem, name, styles );
7436                 }
7437
7438                 // Convert "normal" to computed value
7439                 if ( val === "normal" && name in cssNormalTransform ) {
7440                         val = cssNormalTransform[ name ];
7441                 }
7442
7443                 // Make numeric if forced or a qualifier was provided and val looks numeric
7444                 if ( extra === "" || extra ) {
7445                         num = parseFloat( val );
7446                         return extra === true || isFinite( num ) ? num || 0 : val;
7447                 }
7448
7449                 return val;
7450         }
7451     } );
7452
7453     jQuery.each( [ "height", "width" ], function( _i, dimension ) {
7454         jQuery.cssHooks[ dimension ] = {
7455                 get: function( elem, computed, extra ) {
7456                         if ( computed ) {
7457
7458                                 // Certain elements can have dimension info if we invisibly show them
7459                                 // but it must have a current display style that would benefit
7460                                 return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
7461
7462                                         // Support: Safari 8+
7463                                         // Table columns in Safari have non-zero offsetWidth & zero
7464                                         // getBoundingClientRect().width unless display is changed.
7465                                         // Support: IE <=11 only
7466                                         // Running getBoundingClientRect on a disconnected node
7467                                         // in IE throws an error.
7468                                         ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
7469                                                 swap( elem, cssShow, function() {
7470                                                         return getWidthOrHeight( elem, dimension, extra );
7471                                                 } ) :
7472                                                 getWidthOrHeight( elem, dimension, extra );
7473                         }
7474                 },
7475
7476                 set: function( elem, value, extra ) {
7477                         var matches,
7478                                 styles = getStyles( elem ),
7479
7480                                 // Only read styles.position if the test has a chance to fail
7481                                 // to avoid forcing a reflow.
7482                                 scrollboxSizeBuggy = !support.scrollboxSize() &&
7483                                         styles.position === "absolute",
7484
7485                                 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
7486                                 boxSizingNeeded = scrollboxSizeBuggy || extra,
7487                                 isBorderBox = boxSizingNeeded &&
7488                                         jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
7489                                 subtract = extra ?
7490                                         boxModelAdjustment(
7491                                                 elem,
7492                                                 dimension,
7493                                                 extra,
7494                                                 isBorderBox,
7495                                                 styles
7496                                         ) :
7497                                         0;
7498
7499                         // Account for unreliable border-box dimensions by comparing offset* to computed and
7500                         // faking a content-box to get border and padding (gh-3699)
7501                         if ( isBorderBox && scrollboxSizeBuggy ) {
7502                                 subtract -= Math.ceil(
7503                                         elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
7504                                         parseFloat( styles[ dimension ] ) -
7505                                         boxModelAdjustment( elem, dimension, "border", false, styles ) -
7506                                         0.5
7507                                 );
7508                         }
7509
7510                         // Convert to pixels if value adjustment is needed
7511                         if ( subtract && ( matches = rcssNum.exec( value ) ) &&
7512                                 ( matches[ 3 ] || "px" ) !== "px" ) {
7513
7514                                 elem.style[ dimension ] = value;
7515                                 value = jQuery.css( elem, dimension );
7516                         }
7517
7518                         return setPositiveNumber( elem, value, subtract );
7519                 }
7520         };
7521     } );
7522
7523     jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
7524         function( elem, computed ) {
7525                 if ( computed ) {
7526                         return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
7527                                 elem.getBoundingClientRect().left -
7528                                         swap( elem, { marginLeft: 0 }, function() {
7529                                                 return elem.getBoundingClientRect().left;
7530                                         } )
7531                                 ) + "px";
7532                 }
7533         }
7534     );
7535
7536     // These hooks are used by animate to expand properties
7537     jQuery.each( {
7538         margin: "",
7539         padding: "",
7540         border: "Width"
7541     }, function( prefix, suffix ) {
7542         jQuery.cssHooks[ prefix + suffix ] = {
7543                 expand: function( value ) {
7544                         var i = 0,
7545                                 expanded = {},
7546
7547                                 // Assumes a single number if not a string
7548                                 parts = typeof value === "string" ? value.split( " " ) : [ value ];
7549
7550                         for ( ; i < 4; i++ ) {
7551                                 expanded[ prefix + cssExpand[ i ] + suffix ] =
7552                                         parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
7553                         }
7554
7555                         return expanded;
7556                 }
7557         };
7558
7559         if ( prefix !== "margin" ) {
7560                 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
7561         }
7562     } );
7563
7564     jQuery.fn.extend( {
7565         css: function( name, value ) {
7566                 return access( this, function( elem, name, value ) {
7567                         var styles, len,
7568                                 map = {},
7569                                 i = 0;
7570
7571                         if ( Array.isArray( name ) ) {
7572                                 styles = getStyles( elem );
7573                                 len = name.length;
7574
7575                                 for ( ; i < len; i++ ) {
7576                                         map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
7577                                 }
7578
7579                                 return map;
7580                         }
7581
7582                         return value !== undefined ?
7583                                 jQuery.style( elem, name, value ) :
7584                                 jQuery.css( elem, name );
7585                 }, name, value, arguments.length > 1 );
7586         }
7587     } );
7588
7589
7590     function Tween( elem, options, prop, end, easing ) {
7591         return new Tween.prototype.init( elem, options, prop, end, easing );
7592     }
7593     jQuery.Tween = Tween;
7594
7595     Tween.prototype = {
7596         constructor: Tween,
7597         init: function( elem, options, prop, end, easing, unit ) {
7598                 this.elem = elem;
7599                 this.prop = prop;
7600                 this.easing = easing || jQuery.easing._default;
7601                 this.options = options;
7602                 this.start = this.now = this.cur();
7603                 this.end = end;
7604                 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
7605         },
7606         cur: function() {
7607                 var hooks = Tween.propHooks[ this.prop ];
7608
7609                 return hooks && hooks.get ?
7610                         hooks.get( this ) :
7611                         Tween.propHooks._default.get( this );
7612         },
7613         run: function( percent ) {
7614                 var eased,
7615                         hooks = Tween.propHooks[ this.prop ];
7616
7617                 if ( this.options.duration ) {
7618                         this.pos = eased = jQuery.easing[ this.easing ](
7619                                 percent, this.options.duration * percent, 0, 1, this.options.duration
7620                         );
7621                 } else {
7622                         this.pos = eased = percent;
7623                 }
7624                 this.now = ( this.end - this.start ) * eased + this.start;
7625
7626                 if ( this.options.step ) {
7627                         this.options.step.call( this.elem, this.now, this );
7628                 }
7629
7630                 if ( hooks && hooks.set ) {
7631                         hooks.set( this );
7632                 } else {
7633                         Tween.propHooks._default.set( this );
7634                 }
7635                 return this;
7636         }
7637     };
7638
7639     Tween.prototype.init.prototype = Tween.prototype;
7640
7641     Tween.propHooks = {
7642         _default: {
7643                 get: function( tween ) {
7644                         var result;
7645
7646                         // Use a property on the element directly when it is not a DOM element,
7647                         // or when there is no matching style property that exists.
7648                         if ( tween.elem.nodeType !== 1 ||
7649                                 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
7650                                 return tween.elem[ tween.prop ];
7651                         }
7652
7653                         // Passing an empty string as a 3rd parameter to .css will automatically
7654                         // attempt a parseFloat and fallback to a string if the parse fails.
7655                         // Simple values such as "10px" are parsed to Float;
7656                         // complex values such as "rotate(1rad)" are returned as-is.
7657                         result = jQuery.css( tween.elem, tween.prop, "" );
7658
7659                         // Empty strings, null, undefined and "auto" are converted to 0.
7660                         return !result || result === "auto" ? 0 : result;
7661                 },
7662                 set: function( tween ) {
7663
7664                         // Use step hook for back compat.
7665                         // Use cssHook if its there.
7666                         // Use .style if available and use plain properties where available.
7667                         if ( jQuery.fx.step[ tween.prop ] ) {
7668                                 jQuery.fx.step[ tween.prop ]( tween );
7669                         } else if ( tween.elem.nodeType === 1 && (
7670                                         jQuery.cssHooks[ tween.prop ] ||
7671                                         tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {
7672                                 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
7673                         } else {
7674                                 tween.elem[ tween.prop ] = tween.now;
7675                         }
7676                 }
7677         }
7678     };
7679
7680     // Support: IE <=9 only
7681     // Panic based approach to setting things on disconnected nodes
7682     Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
7683         set: function( tween ) {
7684                 if ( tween.elem.nodeType && tween.elem.parentNode ) {
7685                         tween.elem[ tween.prop ] = tween.now;
7686                 }
7687         }
7688     };
7689
7690     jQuery.easing = {
7691         linear: function( p ) {
7692                 return p;
7693         },
7694         swing: function( p ) {
7695                 return 0.5 - Math.cos( p * Math.PI ) / 2;
7696         },
7697         _default: "swing"
7698     };
7699
7700     jQuery.fx = Tween.prototype.init;
7701
7702     // Back compat <1.8 extension point
7703     jQuery.fx.step = {};
7704
7705
7706
7707
7708     var
7709         fxNow, inProgress,
7710         rfxtypes = /^(?:toggle|show|hide)$/,
7711         rrun = /queueHooks$/;
7712
7713     function schedule() {
7714         if ( inProgress ) {
7715                 if ( document.hidden === false && window.requestAnimationFrame ) {
7716                         window.requestAnimationFrame( schedule );
7717                 } else {
7718                         window.setTimeout( schedule, jQuery.fx.interval );
7719                 }
7720
7721                 jQuery.fx.tick();
7722         }
7723     }
7724
7725     // Animations created synchronously will run synchronously
7726     function createFxNow() {
7727         window.setTimeout( function() {
7728                 fxNow = undefined;
7729         } );
7730         return ( fxNow = Date.now() );
7731     }
7732
7733     // Generate parameters to create a standard animation
7734     function genFx( type, includeWidth ) {
7735         var which,
7736                 i = 0,
7737                 attrs = { height: type };
7738
7739         // If we include width, step value is 1 to do all cssExpand values,
7740         // otherwise step value is 2 to skip over Left and Right
7741         includeWidth = includeWidth ? 1 : 0;
7742         for ( ; i < 4; i += 2 - includeWidth ) {
7743                 which = cssExpand[ i ];
7744                 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
7745         }
7746
7747         if ( includeWidth ) {
7748                 attrs.opacity = attrs.width = type;
7749         }
7750
7751         return attrs;
7752     }
7753
7754     function createTween( value, prop, animation ) {
7755         var tween,
7756                 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
7757                 index = 0,
7758                 length = collection.length;
7759         for ( ; index < length; index++ ) {
7760                 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
7761
7762                         // We're done with this property
7763                         return tween;
7764                 }
7765         }
7766     }
7767
7768     function defaultPrefilter( elem, props, opts ) {
7769         var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
7770                 isBox = "width" in props || "height" in props,
7771                 anim = this,
7772                 orig = {},
7773                 style = elem.style,
7774                 hidden = elem.nodeType && isHiddenWithinTree( elem ),
7775                 dataShow = dataPriv.get( elem, "fxshow" );
7776
7777         // Queue-skipping animations hijack the fx hooks
7778         if ( !opts.queue ) {
7779                 hooks = jQuery._queueHooks( elem, "fx" );
7780                 if ( hooks.unqueued == null ) {
7781                         hooks.unqueued = 0;
7782                         oldfire = hooks.empty.fire;
7783                         hooks.empty.fire = function() {
7784                                 if ( !hooks.unqueued ) {
7785                                         oldfire();
7786                                 }
7787                         };
7788                 }
7789                 hooks.unqueued++;
7790
7791                 anim.always( function() {
7792
7793                         // Ensure the complete handler is called before this completes
7794                         anim.always( function() {
7795                                 hooks.unqueued--;
7796                                 if ( !jQuery.queue( elem, "fx" ).length ) {
7797                                         hooks.empty.fire();
7798                                 }
7799                         } );
7800                 } );
7801         }
7802
7803         // Detect show/hide animations
7804         for ( prop in props ) {
7805                 value = props[ prop ];
7806                 if ( rfxtypes.test( value ) ) {
7807                         delete props[ prop ];
7808                         toggle = toggle || value === "toggle";
7809                         if ( value === ( hidden ? "hide" : "show" ) ) {
7810
7811                                 // Pretend to be hidden if this is a "show" and
7812                                 // there is still data from a stopped show/hide
7813                                 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
7814                                         hidden = true;
7815
7816                                 // Ignore all other no-op show/hide data
7817                                 } else {
7818                                         continue;
7819                                 }
7820                         }
7821                         orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
7822                 }
7823         }
7824
7825         // Bail out if this is a no-op like .hide().hide()
7826         propTween = !jQuery.isEmptyObject( props );
7827         if ( !propTween && jQuery.isEmptyObject( orig ) ) {
7828                 return;
7829         }
7830
7831         // Restrict "overflow" and "display" styles during box animations
7832         if ( isBox && elem.nodeType === 1 ) {
7833
7834                 // Support: IE <=9 - 11, Edge 12 - 15
7835                 // Record all 3 overflow attributes because IE does not infer the shorthand
7836                 // from identically-valued overflowX and overflowY and Edge just mirrors
7837                 // the overflowX value there.
7838                 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
7839
7840                 // Identify a display type, preferring old show/hide data over the CSS cascade
7841                 restoreDisplay = dataShow && dataShow.display;
7842                 if ( restoreDisplay == null ) {
7843                         restoreDisplay = dataPriv.get( elem, "display" );
7844                 }
7845                 display = jQuery.css( elem, "display" );
7846                 if ( display === "none" ) {
7847                         if ( restoreDisplay ) {
7848                                 display = restoreDisplay;
7849                         } else {
7850
7851                                 // Get nonempty value(s) by temporarily forcing visibility
7852                                 showHide( [ elem ], true );
7853                                 restoreDisplay = elem.style.display || restoreDisplay;
7854                                 display = jQuery.css( elem, "display" );
7855                                 showHide( [ elem ] );
7856                         }
7857                 }
7858
7859                 // Animate inline elements as inline-block
7860                 if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
7861                         if ( jQuery.css( elem, "float" ) === "none" ) {
7862
7863                                 // Restore the original display value at the end of pure show/hide animations
7864                                 if ( !propTween ) {
7865                                         anim.done( function() {
7866                                                 style.display = restoreDisplay;
7867                                         } );
7868                                         if ( restoreDisplay == null ) {
7869                                                 display = style.display;
7870                                                 restoreDisplay = display === "none" ? "" : display;
7871                                         }
7872                                 }
7873                                 style.display = "inline-block";
7874                         }
7875                 }
7876         }
7877
7878         if ( opts.overflow ) {
7879                 style.overflow = "hidden";
7880                 anim.always( function() {
7881                         style.overflow = opts.overflow[ 0 ];
7882                         style.overflowX = opts.overflow[ 1 ];
7883                         style.overflowY = opts.overflow[ 2 ];
7884                 } );
7885         }
7886
7887         // Implement show/hide animations
7888         propTween = false;
7889         for ( prop in orig ) {
7890
7891                 // General show/hide setup for this element animation
7892                 if ( !propTween ) {
7893                         if ( dataShow ) {
7894                                 if ( "hidden" in dataShow ) {
7895                                         hidden = dataShow.hidden;
7896                                 }
7897                         } else {
7898                                 dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
7899                         }
7900
7901                         // Store hidden/visible for toggle so `.stop().toggle()` "reverses"
7902                         if ( toggle ) {
7903                                 dataShow.hidden = !hidden;
7904                         }
7905
7906                         // Show elements before animating them
7907                         if ( hidden ) {
7908                                 showHide( [ elem ], true );
7909                         }
7910
7911                         /* eslint-disable no-loop-func */
7912
7913                         anim.done( function() {
7914
7915                         /* eslint-enable no-loop-func */
7916
7917                                 // The final step of a "hide" animation is actually hiding the element
7918                                 if ( !hidden ) {
7919                                         showHide( [ elem ] );
7920                                 }
7921                                 dataPriv.remove( elem, "fxshow" );
7922                                 for ( prop in orig ) {
7923                                         jQuery.style( elem, prop, orig[ prop ] );
7924                                 }
7925                         } );
7926                 }
7927
7928                 // Per-property setup
7929                 propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
7930                 if ( !( prop in dataShow ) ) {
7931                         dataShow[ prop ] = propTween.start;
7932                         if ( hidden ) {
7933                                 propTween.end = propTween.start;
7934                                 propTween.start = 0;
7935                         }
7936                 }
7937         }
7938     }
7939
7940     function propFilter( props, specialEasing ) {
7941         var index, name, easing, value, hooks;
7942
7943         // camelCase, specialEasing and expand cssHook pass
7944         for ( index in props ) {
7945                 name = camelCase( index );
7946                 easing = specialEasing[ name ];
7947                 value = props[ index ];
7948                 if ( Array.isArray( value ) ) {
7949                         easing = value[ 1 ];
7950                         value = props[ index ] = value[ 0 ];
7951                 }
7952
7953                 if ( index !== name ) {
7954                         props[ name ] = value;
7955                         delete props[ index ];
7956                 }
7957
7958                 hooks = jQuery.cssHooks[ name ];
7959                 if ( hooks && "expand" in hooks ) {
7960                         value = hooks.expand( value );
7961                         delete props[ name ];
7962
7963                         // Not quite $.extend, this won't overwrite existing keys.
7964                         // Reusing 'index' because we have the correct "name"
7965                         for ( index in value ) {
7966                                 if ( !( index in props ) ) {
7967                                         props[ index ] = value[ index ];
7968                                         specialEasing[ index ] = easing;
7969                                 }
7970                         }
7971                 } else {
7972                         specialEasing[ name ] = easing;
7973                 }
7974         }
7975     }
7976
7977     function Animation( elem, properties, options ) {
7978         var result,
7979                 stopped,
7980                 index = 0,
7981                 length = Animation.prefilters.length,
7982                 deferred = jQuery.Deferred().always( function() {
7983
7984                         // Don't match elem in the :animated selector
7985                         delete tick.elem;
7986                 } ),
7987                 tick = function() {
7988                         if ( stopped ) {
7989                                 return false;
7990                         }
7991                         var currentTime = fxNow || createFxNow(),
7992                                 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
7993
7994                                 // Support: Android 2.3 only
7995                                 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
7996                                 temp = remaining / animation.duration || 0,
7997                                 percent = 1 - temp,
7998                                 index = 0,
7999                                 length = animation.tweens.length;
8000
8001                         for ( ; index < length; index++ ) {
8002                                 animation.tweens[ index ].run( percent );
8003                         }
8004
8005                         deferred.notifyWith( elem, [ animation, percent, remaining ] );
8006
8007                         // If there's more to do, yield
8008                         if ( percent < 1 && length ) {
8009                                 return remaining;
8010                         }
8011
8012                         // If this was an empty animation, synthesize a final progress notification
8013                         if ( !length ) {
8014                                 deferred.notifyWith( elem, [ animation, 1, 0 ] );
8015                         }
8016
8017                         // Resolve the animation and report its conclusion
8018                         deferred.resolveWith( elem, [ animation ] );
8019                         return false;
8020                 },
8021                 animation = deferred.promise( {
8022                         elem: elem,
8023                         props: jQuery.extend( {}, properties ),
8024                         opts: jQuery.extend( true, {
8025                                 specialEasing: {},
8026                                 easing: jQuery.easing._default
8027                         }, options ),
8028                         originalProperties: properties,
8029                         originalOptions: options,
8030                         startTime: fxNow || createFxNow(),
8031                         duration: options.duration,
8032                         tweens: [],
8033                         createTween: function( prop, end ) {
8034                                 var tween = jQuery.Tween( elem, animation.opts, prop, end,
8035                                                 animation.opts.specialEasing[ prop ] || animation.opts.easing );
8036                                 animation.tweens.push( tween );
8037                                 return tween;
8038                         },
8039                         stop: function( gotoEnd ) {
8040                                 var index = 0,
8041
8042                                         // If we are going to the end, we want to run all the tweens
8043                                         // otherwise we skip this part
8044                                         length = gotoEnd ? animation.tweens.length : 0;
8045                                 if ( stopped ) {
8046                                         return this;
8047                                 }
8048                                 stopped = true;
8049                                 for ( ; index < length; index++ ) {
8050                                         animation.tweens[ index ].run( 1 );
8051                                 }
8052
8053                                 // Resolve when we played the last frame; otherwise, reject
8054                                 if ( gotoEnd ) {
8055                                         deferred.notifyWith( elem, [ animation, 1, 0 ] );
8056                                         deferred.resolveWith( elem, [ animation, gotoEnd ] );
8057                                 } else {
8058                                         deferred.rejectWith( elem, [ animation, gotoEnd ] );
8059                                 }
8060                                 return this;
8061                         }
8062                 } ),
8063                 props = animation.props;
8064
8065         propFilter( props, animation.opts.specialEasing );
8066
8067         for ( ; index < length; index++ ) {
8068                 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
8069                 if ( result ) {
8070                         if ( isFunction( result.stop ) ) {
8071                                 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
8072                                         result.stop.bind( result );
8073                         }
8074                         return result;
8075                 }
8076         }
8077
8078         jQuery.map( props, createTween, animation );
8079
8080         if ( isFunction( animation.opts.start ) ) {
8081                 animation.opts.start.call( elem, animation );
8082         }
8083
8084         // Attach callbacks from options
8085         animation
8086                 .progress( animation.opts.progress )
8087                 .done( animation.opts.done, animation.opts.complete )
8088                 .fail( animation.opts.fail )
8089                 .always( animation.opts.always );
8090
8091         jQuery.fx.timer(
8092                 jQuery.extend( tick, {
8093                         elem: elem,
8094                         anim: animation,
8095                         queue: animation.opts.queue
8096                 } )
8097         );
8098
8099         return animation;
8100     }
8101
8102     jQuery.Animation = jQuery.extend( Animation, {
8103
8104         tweeners: {
8105                 "*": [ function( prop, value ) {
8106                         var tween = this.createTween( prop, value );
8107                         adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
8108                         return tween;
8109                 } ]
8110         },
8111
8112         tweener: function( props, callback ) {
8113                 if ( isFunction( props ) ) {
8114                         callback = props;
8115                         props = [ "*" ];
8116                 } else {
8117                         props = props.match( rnothtmlwhite );
8118                 }
8119
8120                 var prop,
8121                         index = 0,
8122                         length = props.length;
8123
8124                 for ( ; index < length; index++ ) {
8125                         prop = props[ index ];
8126                         Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
8127                         Animation.tweeners[ prop ].unshift( callback );
8128                 }
8129         },
8130
8131         prefilters: [ defaultPrefilter ],
8132
8133         prefilter: function( callback, prepend ) {
8134                 if ( prepend ) {
8135                         Animation.prefilters.unshift( callback );
8136                 } else {
8137                         Animation.prefilters.push( callback );
8138                 }
8139         }
8140     } );
8141
8142     jQuery.speed = function( speed, easing, fn ) {
8143         var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
8144                 complete: fn || !fn && easing ||
8145                         isFunction( speed ) && speed,
8146                 duration: speed,
8147                 easing: fn && easing || easing && !isFunction( easing ) && easing
8148         };
8149
8150         // Go to the end state if fx are off
8151         if ( jQuery.fx.off ) {
8152                 opt.duration = 0;
8153
8154         } else {
8155                 if ( typeof opt.duration !== "number" ) {
8156                         if ( opt.duration in jQuery.fx.speeds ) {
8157                                 opt.duration = jQuery.fx.speeds[ opt.duration ];
8158
8159                         } else {
8160                                 opt.duration = jQuery.fx.speeds._default;
8161                         }
8162                 }
8163         }
8164
8165         // Normalize opt.queue - true/undefined/null -> "fx"
8166         if ( opt.queue == null || opt.queue === true ) {
8167                 opt.queue = "fx";
8168         }
8169
8170         // Queueing
8171         opt.old = opt.complete;
8172
8173         opt.complete = function() {
8174                 if ( isFunction( opt.old ) ) {
8175                         opt.old.call( this );
8176                 }
8177
8178                 if ( opt.queue ) {
8179                         jQuery.dequeue( this, opt.queue );
8180                 }
8181         };
8182
8183         return opt;
8184     };
8185
8186     jQuery.fn.extend( {
8187         fadeTo: function( speed, to, easing, callback ) {
8188
8189                 // Show any hidden elements after setting opacity to 0
8190                 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
8191
8192                         // Animate to the value specified
8193                         .end().animate( { opacity: to }, speed, easing, callback );
8194         },
8195         animate: function( prop, speed, easing, callback ) {
8196                 var empty = jQuery.isEmptyObject( prop ),
8197                         optall = jQuery.speed( speed, easing, callback ),
8198                         doAnimation = function() {
8199
8200                                 // Operate on a copy of prop so per-property easing won't be lost
8201                                 var anim = Animation( this, jQuery.extend( {}, prop ), optall );
8202
8203                                 // Empty animations, or finishing resolves immediately
8204                                 if ( empty || dataPriv.get( this, "finish" ) ) {
8205                                         anim.stop( true );
8206                                 }
8207                         };
8208                         doAnimation.finish = doAnimation;
8209
8210                 return empty || optall.queue === false ?
8211                         this.each( doAnimation ) :
8212                         this.queue( optall.queue, doAnimation );
8213         },
8214         stop: function( type, clearQueue, gotoEnd ) {
8215                 var stopQueue = function( hooks ) {
8216                         var stop = hooks.stop;
8217                         delete hooks.stop;
8218                         stop( gotoEnd );
8219                 };
8220
8221                 if ( typeof type !== "string" ) {
8222                         gotoEnd = clearQueue;
8223                         clearQueue = type;
8224                         type = undefined;
8225                 }
8226                 if ( clearQueue ) {
8227                         this.queue( type || "fx", [] );
8228                 }
8229
8230                 return this.each( function() {
8231                         var dequeue = true,
8232                                 index = type != null && type + "queueHooks",
8233                                 timers = jQuery.timers,
8234                                 data = dataPriv.get( this );
8235
8236                         if ( index ) {
8237                                 if ( data[ index ] && data[ index ].stop ) {
8238                                         stopQueue( data[ index ] );
8239                                 }
8240                         } else {
8241                                 for ( index in data ) {
8242                                         if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
8243                                                 stopQueue( data[ index ] );
8244                                         }
8245                                 }
8246                         }
8247
8248                         for ( index = timers.length; index--; ) {
8249                                 if ( timers[ index ].elem === this &&
8250                                         ( type == null || timers[ index ].queue === type ) ) {
8251
8252                                         timers[ index ].anim.stop( gotoEnd );
8253                                         dequeue = false;
8254                                         timers.splice( index, 1 );
8255                                 }
8256                         }
8257
8258                         // Start the next in the queue if the last step wasn't forced.
8259                         // Timers currently will call their complete callbacks, which
8260                         // will dequeue but only if they were gotoEnd.
8261                         if ( dequeue || !gotoEnd ) {
8262                                 jQuery.dequeue( this, type );
8263                         }
8264                 } );
8265         },
8266         finish: function( type ) {
8267                 if ( type !== false ) {
8268                         type = type || "fx";
8269                 }
8270                 return this.each( function() {
8271                         var index,
8272                                 data = dataPriv.get( this ),
8273                                 queue = data[ type + "queue" ],
8274                                 hooks = data[ type + "queueHooks" ],
8275                                 timers = jQuery.timers,
8276                                 length = queue ? queue.length : 0;
8277
8278                         // Enable finishing flag on private data
8279                         data.finish = true;
8280
8281                         // Empty the queue first
8282                         jQuery.queue( this, type, [] );
8283
8284                         if ( hooks && hooks.stop ) {
8285                                 hooks.stop.call( this, true );
8286                         }
8287
8288                         // Look for any active animations, and finish them
8289                         for ( index = timers.length; index--; ) {
8290                                 if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
8291                                         timers[ index ].anim.stop( true );
8292                                         timers.splice( index, 1 );
8293                                 }
8294                         }
8295
8296                         // Look for any animations in the old queue and finish them
8297                         for ( index = 0; index < length; index++ ) {
8298                                 if ( queue[ index ] && queue[ index ].finish ) {
8299                                         queue[ index ].finish.call( this );
8300                                 }
8301                         }
8302
8303                         // Turn off finishing flag
8304                         delete data.finish;
8305                 } );
8306         }
8307     } );
8308
8309     jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) {
8310         var cssFn = jQuery.fn[ name ];
8311         jQuery.fn[ name ] = function( speed, easing, callback ) {
8312                 return speed == null || typeof speed === "boolean" ?
8313                         cssFn.apply( this, arguments ) :
8314                         this.animate( genFx( name, true ), speed, easing, callback );
8315         };
8316     } );
8317
8318     // Generate shortcuts for custom animations
8319     jQuery.each( {
8320         slideDown: genFx( "show" ),
8321         slideUp: genFx( "hide" ),
8322         slideToggle: genFx( "toggle" ),
8323         fadeIn: { opacity: "show" },
8324         fadeOut: { opacity: "hide" },
8325         fadeToggle: { opacity: "toggle" }
8326     }, function( name, props ) {
8327         jQuery.fn[ name ] = function( speed, easing, callback ) {
8328                 return this.animate( props, speed, easing, callback );
8329         };
8330     } );
8331
8332     jQuery.timers = [];
8333     jQuery.fx.tick = function() {
8334         var timer,
8335                 i = 0,
8336                 timers = jQuery.timers;
8337
8338         fxNow = Date.now();
8339
8340         for ( ; i < timers.length; i++ ) {
8341                 timer = timers[ i ];
8342
8343                 // Run the timer and safely remove it when done (allowing for external removal)
8344                 if ( !timer() && timers[ i ] === timer ) {
8345                         timers.splice( i--, 1 );
8346                 }
8347         }
8348
8349         if ( !timers.length ) {
8350                 jQuery.fx.stop();
8351         }
8352         fxNow = undefined;
8353     };
8354
8355     jQuery.fx.timer = function( timer ) {
8356         jQuery.timers.push( timer );
8357         jQuery.fx.start();
8358     };
8359
8360     jQuery.fx.interval = 13;
8361     jQuery.fx.start = function() {
8362         if ( inProgress ) {
8363                 return;
8364         }
8365
8366         inProgress = true;
8367         schedule();
8368     };
8369
8370     jQuery.fx.stop = function() {
8371         inProgress = null;
8372     };
8373
8374     jQuery.fx.speeds = {
8375         slow: 600,
8376         fast: 200,
8377
8378         // Default speed
8379         _default: 400
8380     };
8381
8382
8383     // Based off of the plugin by Clint Helfers, with permission.
8384     // https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
8385     jQuery.fn.delay = function( time, type ) {
8386         time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
8387         type = type || "fx";
8388
8389         return this.queue( type, function( next, hooks ) {
8390                 var timeout = window.setTimeout( next, time );
8391                 hooks.stop = function() {
8392                         window.clearTimeout( timeout );
8393                 };
8394         } );
8395     };
8396
8397
8398     ( function() {
8399         var input = document.createElement( "input" ),
8400                 select = document.createElement( "select" ),
8401                 opt = select.appendChild( document.createElement( "option" ) );
8402
8403         input.type = "checkbox";
8404
8405         // Support: Android <=4.3 only
8406         // Default value for a checkbox should be "on"
8407         support.checkOn = input.value !== "";
8408
8409         // Support: IE <=11 only
8410         // Must access selectedIndex to make default options select
8411         support.optSelected = opt.selected;
8412
8413         // Support: IE <=11 only
8414         // An input loses its value after becoming a radio
8415         input = document.createElement( "input" );
8416         input.value = "t";
8417         input.type = "radio";
8418         support.radioValue = input.value === "t";
8419     } )();
8420
8421
8422     var boolHook,
8423         attrHandle = jQuery.expr.attrHandle;
8424
8425     jQuery.fn.extend( {
8426         attr: function( name, value ) {
8427                 return access( this, jQuery.attr, name, value, arguments.length > 1 );
8428         },
8429
8430         removeAttr: function( name ) {
8431                 return this.each( function() {
8432                         jQuery.removeAttr( this, name );
8433                 } );
8434         }
8435     } );
8436
8437     jQuery.extend( {
8438         attr: function( elem, name, value ) {
8439                 var ret, hooks,
8440                         nType = elem.nodeType;
8441
8442                 // Don't get/set attributes on text, comment and attribute nodes
8443                 if ( nType === 3 || nType === 8 || nType === 2 ) {
8444                         return;
8445                 }
8446
8447                 // Fallback to prop when attributes are not supported
8448                 if ( typeof elem.getAttribute === "undefined" ) {
8449                         return jQuery.prop( elem, name, value );
8450                 }
8451
8452                 // Attribute hooks are determined by the lowercase version
8453                 // Grab necessary hook if one is defined
8454                 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8455                         hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
8456                                 ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
8457                 }
8458
8459                 if ( value !== undefined ) {
8460                         if ( value === null ) {
8461                                 jQuery.removeAttr( elem, name );
8462                                 return;
8463                         }
8464
8465                         if ( hooks && "set" in hooks &&
8466                                 ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8467                                 return ret;
8468                         }
8469
8470                         elem.setAttribute( name, value + "" );
8471                         return value;
8472                 }
8473
8474                 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8475                         return ret;
8476                 }
8477
8478                 ret = jQuery.find.attr( elem, name );
8479
8480                 // Non-existent attributes return null, we normalize to undefined
8481                 return ret == null ? undefined : ret;
8482         },
8483
8484         attrHooks: {
8485                 type: {
8486                         set: function( elem, value ) {
8487                                 if ( !support.radioValue && value === "radio" &&
8488                                         nodeName( elem, "input" ) ) {
8489                                         var val = elem.value;
8490                                         elem.setAttribute( "type", value );
8491                                         if ( val ) {
8492                                                 elem.value = val;
8493                                         }
8494                                         return value;
8495                                 }
8496                         }
8497                 }
8498         },
8499
8500         removeAttr: function( elem, value ) {
8501                 var name,
8502                         i = 0,
8503
8504                         // Attribute names can contain non-HTML whitespace characters
8505                         // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
8506                         attrNames = value && value.match( rnothtmlwhite );
8507
8508                 if ( attrNames && elem.nodeType === 1 ) {
8509                         while ( ( name = attrNames[ i++ ] ) ) {
8510                                 elem.removeAttribute( name );
8511                         }
8512                 }
8513         }
8514     } );
8515
8516     // Hooks for boolean attributes
8517     boolHook = {
8518         set: function( elem, value, name ) {
8519                 if ( value === false ) {
8520
8521                         // Remove boolean attributes when set to false
8522                         jQuery.removeAttr( elem, name );
8523                 } else {
8524                         elem.setAttribute( name, name );
8525                 }
8526                 return name;
8527         }
8528     };
8529
8530     jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) {
8531         var getter = attrHandle[ name ] || jQuery.find.attr;
8532
8533         attrHandle[ name ] = function( elem, name, isXML ) {
8534                 var ret, handle,
8535                         lowercaseName = name.toLowerCase();
8536
8537                 if ( !isXML ) {
8538
8539                         // Avoid an infinite loop by temporarily removing this function from the getter
8540                         handle = attrHandle[ lowercaseName ];
8541                         attrHandle[ lowercaseName ] = ret;
8542                         ret = getter( elem, name, isXML ) != null ?
8543                                 lowercaseName :
8544                                 null;
8545                         attrHandle[ lowercaseName ] = handle;
8546                 }
8547                 return ret;
8548         };
8549     } );
8550
8551
8552
8553
8554     var rfocusable = /^(?:input|select|textarea|button)$/i,
8555         rclickable = /^(?:a|area)$/i;
8556
8557     jQuery.fn.extend( {
8558         prop: function( name, value ) {
8559                 return access( this, jQuery.prop, name, value, arguments.length > 1 );
8560         },
8561
8562         removeProp: function( name ) {
8563                 return this.each( function() {
8564                         delete this[ jQuery.propFix[ name ] || name ];
8565                 } );
8566         }
8567     } );
8568
8569     jQuery.extend( {
8570         prop: function( elem, name, value ) {
8571                 var ret, hooks,
8572                         nType = elem.nodeType;
8573
8574                 // Don't get/set properties on text, comment and attribute nodes
8575                 if ( nType === 3 || nType === 8 || nType === 2 ) {
8576                         return;
8577                 }
8578
8579                 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
8580
8581                         // Fix name and attach hooks
8582                         name = jQuery.propFix[ name ] || name;
8583                         hooks = jQuery.propHooks[ name ];
8584                 }
8585
8586                 if ( value !== undefined ) {
8587                         if ( hooks && "set" in hooks &&
8588                                 ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
8589                                 return ret;
8590                         }
8591
8592                         return ( elem[ name ] = value );
8593                 }
8594
8595                 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
8596                         return ret;
8597                 }
8598
8599                 return elem[ name ];
8600         },
8601
8602         propHooks: {
8603                 tabIndex: {
8604                         get: function( elem ) {
8605
8606                                 // Support: IE <=9 - 11 only
8607                                 // elem.tabIndex doesn't always return the
8608                                 // correct value when it hasn't been explicitly set
8609                                 // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
8610                                 // Use proper attribute retrieval(#12072)
8611                                 var tabindex = jQuery.find.attr( elem, "tabindex" );
8612
8613                                 if ( tabindex ) {
8614                                         return parseInt( tabindex, 10 );
8615                                 }
8616
8617                                 if (
8618                                         rfocusable.test( elem.nodeName ) ||
8619                                         rclickable.test( elem.nodeName ) &&
8620                                         elem.href
8621                                 ) {
8622                                         return 0;
8623                                 }
8624
8625                                 return -1;
8626                         }
8627                 }
8628         },
8629
8630         propFix: {
8631                 "for": "htmlFor",
8632                 "class": "className"
8633         }
8634     } );
8635
8636     // Support: IE <=11 only
8637     // Accessing the selectedIndex property
8638     // forces the browser to respect setting selected
8639     // on the option
8640     // The getter ensures a default option is selected
8641     // when in an optgroup
8642     // eslint rule "no-unused-expressions" is disabled for this code
8643     // since it considers such accessions noop
8644     if ( !support.optSelected ) {
8645         jQuery.propHooks.selected = {
8646                 get: function( elem ) {
8647
8648                         /* eslint no-unused-expressions: "off" */
8649
8650                         var parent = elem.parentNode;
8651                         if ( parent && parent.parentNode ) {
8652                                 parent.parentNode.selectedIndex;
8653                         }
8654                         return null;
8655                 },
8656                 set: function( elem ) {
8657
8658                         /* eslint no-unused-expressions: "off" */
8659
8660                         var parent = elem.parentNode;
8661                         if ( parent ) {
8662                                 parent.selectedIndex;
8663
8664                                 if ( parent.parentNode ) {
8665                                         parent.parentNode.selectedIndex;
8666                                 }
8667                         }
8668                 }
8669         };
8670     }
8671
8672     jQuery.each( [
8673         "tabIndex",
8674         "readOnly",
8675         "maxLength",
8676         "cellSpacing",
8677         "cellPadding",
8678         "rowSpan",
8679         "colSpan",
8680         "useMap",
8681         "frameBorder",
8682         "contentEditable"
8683     ], function() {
8684         jQuery.propFix[ this.toLowerCase() ] = this;
8685     } );
8686
8687
8688
8689
8690         // Strip and collapse whitespace according to HTML spec
8691         // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace
8692         function stripAndCollapse( value ) {
8693                 var tokens = value.match( rnothtmlwhite ) || [];
8694                 return tokens.join( " " );
8695         }
8696
8697
8698     function getClass( elem ) {
8699         return elem.getAttribute && elem.getAttribute( "class" ) || "";
8700     }
8701
8702     function classesToArray( value ) {
8703         if ( Array.isArray( value ) ) {
8704                 return value;
8705         }
8706         if ( typeof value === "string" ) {
8707                 return value.match( rnothtmlwhite ) || [];
8708         }
8709         return [];
8710     }
8711
8712     jQuery.fn.extend( {
8713         addClass: function( value ) {
8714                 var classes, elem, cur, curValue, clazz, j, finalValue,
8715                         i = 0;
8716
8717                 if ( isFunction( value ) ) {
8718                         return this.each( function( j ) {
8719                                 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
8720                         } );
8721                 }
8722
8723                 classes = classesToArray( value );
8724
8725                 if ( classes.length ) {
8726                         while ( ( elem = this[ i++ ] ) ) {
8727                                 curValue = getClass( elem );
8728                                 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
8729
8730                                 if ( cur ) {
8731                                         j = 0;
8732                                         while ( ( clazz = classes[ j++ ] ) ) {
8733                                                 if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
8734                                                         cur += clazz + " ";
8735                                                 }
8736                                         }
8737
8738                                         // Only assign if different to avoid unneeded rendering.
8739                                         finalValue = stripAndCollapse( cur );
8740                                         if ( curValue !== finalValue ) {
8741                                                 elem.setAttribute( "class", finalValue );
8742                                         }
8743                                 }
8744                         }
8745                 }
8746
8747                 return this;
8748         },
8749
8750         removeClass: function( value ) {
8751                 var classes, elem, cur, curValue, clazz, j, finalValue,
8752                         i = 0;
8753
8754                 if ( isFunction( value ) ) {
8755                         return this.each( function( j ) {
8756                                 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
8757                         } );
8758                 }
8759
8760                 if ( !arguments.length ) {
8761                         return this.attr( "class", "" );
8762                 }
8763
8764                 classes = classesToArray( value );
8765
8766                 if ( classes.length ) {
8767                         while ( ( elem = this[ i++ ] ) ) {
8768                                 curValue = getClass( elem );
8769
8770                                 // This expression is here for better compressibility (see addClass)
8771                                 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
8772
8773                                 if ( cur ) {
8774                                         j = 0;
8775                                         while ( ( clazz = classes[ j++ ] ) ) {
8776
8777                                                 // Remove *all* instances
8778                                                 while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
8779                                                         cur = cur.replace( " " + clazz + " ", " " );
8780                                                 }
8781                                         }
8782
8783                                         // Only assign if different to avoid unneeded rendering.
8784                                         finalValue = stripAndCollapse( cur );
8785                                         if ( curValue !== finalValue ) {
8786                                                 elem.setAttribute( "class", finalValue );
8787                                         }
8788                                 }
8789                         }
8790                 }
8791
8792                 return this;
8793         },
8794
8795         toggleClass: function( value, stateVal ) {
8796                 var type = typeof value,
8797                         isValidValue = type === "string" || Array.isArray( value );
8798
8799                 if ( typeof stateVal === "boolean" && isValidValue ) {
8800                         return stateVal ? this.addClass( value ) : this.removeClass( value );
8801                 }
8802
8803                 if ( isFunction( value ) ) {
8804                         return this.each( function( i ) {
8805                                 jQuery( this ).toggleClass(
8806                                         value.call( this, i, getClass( this ), stateVal ),
8807                                         stateVal
8808                                 );
8809                         } );
8810                 }
8811
8812                 return this.each( function() {
8813                         var className, i, self, classNames;
8814
8815                         if ( isValidValue ) {
8816
8817                                 // Toggle individual class names
8818                                 i = 0;
8819                                 self = jQuery( this );
8820                                 classNames = classesToArray( value );
8821
8822                                 while ( ( className = classNames[ i++ ] ) ) {
8823
8824                                         // Check each className given, space separated list
8825                                         if ( self.hasClass( className ) ) {
8826                                                 self.removeClass( className );
8827                                         } else {
8828                                                 self.addClass( className );
8829                                         }
8830                                 }
8831
8832                         // Toggle whole class name
8833                         } else if ( value === undefined || type === "boolean" ) {
8834                                 className = getClass( this );
8835                                 if ( className ) {
8836
8837                                         // Store className if set
8838                                         dataPriv.set( this, "__className__", className );
8839                                 }
8840
8841                                 // If the element has a class name or if we're passed `false`,
8842                                 // then remove the whole classname (if there was one, the above saved it).
8843                                 // Otherwise bring back whatever was previously saved (if anything),
8844                                 // falling back to the empty string if nothing was stored.
8845                                 if ( this.setAttribute ) {
8846                                         this.setAttribute( "class",
8847                                                 className || value === false ?
8848                                                 "" :
8849                                                 dataPriv.get( this, "__className__" ) || ""
8850                                         );
8851                                 }
8852                         }
8853                 } );
8854         },
8855
8856         hasClass: function( selector ) {
8857                 var className, elem,
8858                         i = 0;
8859
8860                 className = " " + selector + " ";
8861                 while ( ( elem = this[ i++ ] ) ) {
8862                         if ( elem.nodeType === 1 &&
8863                                 ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) {
8864                                         return true;
8865                         }
8866                 }
8867
8868                 return false;
8869         }
8870     } );
8871
8872
8873
8874
8875     var rreturn = /\r/g;
8876
8877     jQuery.fn.extend( {
8878         val: function( value ) {
8879                 var hooks, ret, valueIsFunction,
8880                         elem = this[ 0 ];
8881
8882                 if ( !arguments.length ) {
8883                         if ( elem ) {
8884                                 hooks = jQuery.valHooks[ elem.type ] ||
8885                                         jQuery.valHooks[ elem.nodeName.toLowerCase() ];
8886
8887                                 if ( hooks &&
8888                                         "get" in hooks &&
8889                                         ( ret = hooks.get( elem, "value" ) ) !== undefined
8890                                 ) {
8891                                         return ret;
8892                                 }
8893
8894                                 ret = elem.value;
8895
8896                                 // Handle most common string cases
8897                                 if ( typeof ret === "string" ) {
8898                                         return ret.replace( rreturn, "" );
8899                                 }
8900
8901                                 // Handle cases where value is null/undef or number
8902                                 return ret == null ? "" : ret;
8903                         }
8904
8905                         return;
8906                 }
8907
8908                 valueIsFunction = isFunction( value );
8909
8910                 return this.each( function( i ) {
8911                         var val;
8912
8913                         if ( this.nodeType !== 1 ) {
8914                                 return;
8915                         }
8916
8917                         if ( valueIsFunction ) {
8918                                 val = value.call( this, i, jQuery( this ).val() );
8919                         } else {
8920                                 val = value;
8921                         }
8922
8923                         // Treat null/undefined as ""; convert numbers to string
8924                         if ( val == null ) {
8925                                 val = "";
8926
8927                         } else if ( typeof val === "number" ) {
8928                                 val += "";
8929
8930                         } else if ( Array.isArray( val ) ) {
8931                                 val = jQuery.map( val, function( value ) {
8932                                         return value == null ? "" : value + "";
8933                                 } );
8934                         }
8935
8936                         hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
8937
8938                         // If set returns undefined, fall back to normal setting
8939                         if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) {
8940                                 this.value = val;
8941                         }
8942                 } );
8943         }
8944     } );
8945
8946     jQuery.extend( {
8947         valHooks: {
8948                 option: {
8949                         get: function( elem ) {
8950
8951                                 var val = jQuery.find.attr( elem, "value" );
8952                                 return val != null ?
8953                                         val :
8954
8955                                         // Support: IE <=10 - 11 only
8956                                         // option.text throws exceptions (#14686, #14858)
8957                                         // Strip and collapse whitespace
8958                                         // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
8959                                         stripAndCollapse( jQuery.text( elem ) );
8960                         }
8961                 },
8962                 select: {
8963                         get: function( elem ) {
8964                                 var value, option, i,
8965                                         options = elem.options,
8966                                         index = elem.selectedIndex,
8967                                         one = elem.type === "select-one",
8968                                         values = one ? null : [],
8969                                         max = one ? index + 1 : options.length;
8970
8971                                 if ( index < 0 ) {
8972                                         i = max;
8973
8974                                 } else {
8975                                         i = one ? index : 0;
8976                                 }
8977
8978                                 // Loop through all the selected options
8979                                 for ( ; i < max; i++ ) {
8980                                         option = options[ i ];
8981
8982                                         // Support: IE <=9 only
8983                                         // IE8-9 doesn't update selected after form reset (#2551)
8984                                         if ( ( option.selected || i === index ) &&
8985
8986                                                         // Don't return options that are disabled or in a disabled optgroup
8987                                                         !option.disabled &&
8988                                                         ( !option.parentNode.disabled ||
8989                                                                 !nodeName( option.parentNode, "optgroup" ) ) ) {
8990
8991                                                 // Get the specific value for the option
8992                                                 value = jQuery( option ).val();
8993
8994                                                 // We don't need an array for one selects
8995                                                 if ( one ) {
8996                                                         return value;
8997                                                 }
8998
8999                                                 // Multi-Selects return an array
9000                                                 values.push( value );
9001                                         }
9002                                 }
9003
9004                                 return values;
9005                         },
9006
9007                         set: function( elem, value ) {
9008                                 var optionSet, option,
9009                                         options = elem.options,
9010                                         values = jQuery.makeArray( value ),
9011                                         i = options.length;
9012
9013                                 while ( i-- ) {
9014                                         option = options[ i ];
9015
9016                                         /* eslint-disable no-cond-assign */
9017
9018                                         if ( option.selected =
9019                                                 jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1
9020                                         ) {
9021                                                 optionSet = true;
9022                                         }
9023
9024                                         /* eslint-enable no-cond-assign */
9025                                 }
9026
9027                                 // Force browsers to behave consistently when non-matching value is set
9028                                 if ( !optionSet ) {
9029                                         elem.selectedIndex = -1;
9030                                 }
9031                                 return values;
9032                         }
9033                 }
9034         }
9035     } );
9036
9037     // Radios and checkboxes getter/setter
9038     jQuery.each( [ "radio", "checkbox" ], function() {
9039         jQuery.valHooks[ this ] = {
9040                 set: function( elem, value ) {
9041                         if ( Array.isArray( value ) ) {
9042                                 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
9043                         }
9044                 }
9045         };
9046         if ( !support.checkOn ) {
9047                 jQuery.valHooks[ this ].get = function( elem ) {
9048                         return elem.getAttribute( "value" ) === null ? "on" : elem.value;
9049                 };
9050         }
9051     } );
9052
9053
9054
9055
9056     // Return jQuery for attributes-only inclusion
9057
9058
9059     support.focusin = "onfocusin" in window;
9060
9061
9062     var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
9063         stopPropagationCallback = function( e ) {
9064                 e.stopPropagation();
9065         };
9066
9067     jQuery.extend( jQuery.event, {
9068
9069         trigger: function( event, data, elem, onlyHandlers ) {
9070
9071                 var i, cur, tmp, bubbleType, ontype, handle, special, lastElement,
9072                         eventPath = [ elem || document ],
9073                         type = hasOwn.call( event, "type" ) ? event.type : event,
9074                         namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
9075
9076                 cur = lastElement = tmp = elem = elem || document;
9077
9078                 // Don't do events on text and comment nodes
9079                 if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
9080                         return;
9081                 }
9082
9083                 // focus/blur morphs to focusin/out; ensure we're not firing them right now
9084                 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
9085                         return;
9086                 }
9087
9088                 if ( type.indexOf( "." ) > -1 ) {
9089
9090                         // Namespaced trigger; create a regexp to match event type in handle()
9091                         namespaces = type.split( "." );
9092                         type = namespaces.shift();
9093                         namespaces.sort();
9094                 }
9095                 ontype = type.indexOf( ":" ) < 0 && "on" + type;
9096
9097                 // Caller can pass in a jQuery.Event object, Object, or just an event type string
9098                 event = event[ jQuery.expando ] ?
9099                         event :
9100                         new jQuery.Event( type, typeof event === "object" && event );
9101
9102                 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
9103                 event.isTrigger = onlyHandlers ? 2 : 3;
9104                 event.namespace = namespaces.join( "." );
9105                 event.rnamespace = event.namespace ?
9106                         new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
9107                         null;
9108
9109                 // Clean up the event in case it is being reused
9110                 event.result = undefined;
9111                 if ( !event.target ) {
9112                         event.target = elem;
9113                 }
9114
9115                 // Clone any incoming data and prepend the event, creating the handler arg list
9116                 data = data == null ?
9117                         [ event ] :
9118                         jQuery.makeArray( data, [ event ] );
9119
9120                 // Allow special events to draw outside the lines
9121                 special = jQuery.event.special[ type ] || {};
9122                 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
9123                         return;
9124                 }
9125
9126                 // Determine event propagation path in advance, per W3C events spec (#9951)
9127                 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
9128                 if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) {
9129
9130                         bubbleType = special.delegateType || type;
9131                         if ( !rfocusMorph.test( bubbleType + type ) ) {
9132                                 cur = cur.parentNode;
9133                         }
9134                         for ( ; cur; cur = cur.parentNode ) {
9135                                 eventPath.push( cur );
9136                                 tmp = cur;
9137                         }
9138
9139                         // Only add window if we got to document (e.g., not plain obj or detached DOM)
9140                         if ( tmp === ( elem.ownerDocument || document ) ) {
9141                                 eventPath.push( tmp.defaultView || tmp.parentWindow || window );
9142                         }
9143                 }
9144
9145                 // Fire handlers on the event path
9146                 i = 0;
9147                 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
9148                         lastElement = cur;
9149                         event.type = i > 1 ?
9150                                 bubbleType :
9151                                 special.bindType || type;
9152
9153                         // jQuery handler
9154                         handle = (
9155                                         dataPriv.get( cur, "events" ) || Object.create( null )
9156                                 )[ event.type ] &&
9157                                 dataPriv.get( cur, "handle" );
9158                         if ( handle ) {
9159                                 handle.apply( cur, data );
9160                         }
9161
9162                         // Native handler
9163                         handle = ontype && cur[ ontype ];
9164                         if ( handle && handle.apply && acceptData( cur ) ) {
9165                                 event.result = handle.apply( cur, data );
9166                                 if ( event.result === false ) {
9167                                         event.preventDefault();
9168                                 }
9169                         }
9170                 }
9171                 event.type = type;
9172
9173                 // If nobody prevented the default action, do it now
9174                 if ( !onlyHandlers && !event.isDefaultPrevented() ) {
9175
9176                         if ( ( !special._default ||
9177                                 special._default.apply( eventPath.pop(), data ) === false ) &&
9178                                 acceptData( elem ) ) {
9179
9180                                 // Call a native DOM method on the target with the same name as the event.
9181                                 // Don't do default actions on window, that's where global variables be (#6170)
9182                                 if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) {
9183
9184                                         // Don't re-trigger an onFOO event when we call its FOO() method
9185                                         tmp = elem[ ontype ];
9186
9187                                         if ( tmp ) {
9188                                                 elem[ ontype ] = null;
9189                                         }
9190
9191                                         // Prevent re-triggering of the same event, since we already bubbled it above
9192                                         jQuery.event.triggered = type;
9193
9194                                         if ( event.isPropagationStopped() ) {
9195                                                 lastElement.addEventListener( type, stopPropagationCallback );
9196                                         }
9197
9198                                         elem[ type ]();
9199
9200                                         if ( event.isPropagationStopped() ) {
9201                                                 lastElement.removeEventListener( type, stopPropagationCallback );
9202                                         }
9203
9204                                         jQuery.event.triggered = undefined;
9205
9206                                         if ( tmp ) {
9207                                                 elem[ ontype ] = tmp;
9208                                         }
9209                                 }
9210                         }
9211                 }
9212
9213                 return event.result;
9214         },
9215
9216         // Piggyback on a donor event to simulate a different one
9217         // Used only for `focus(in | out)` events
9218         simulate: function( type, elem, event ) {
9219                 var e = jQuery.extend(
9220                         new jQuery.Event(),
9221                         event,
9222                         {
9223                                 type: type,
9224                                 isSimulated: true
9225                         }
9226                 );
9227
9228                 jQuery.event.trigger( e, null, elem );
9229         }
9230
9231     } );
9232
9233     jQuery.fn.extend( {
9234
9235         trigger: function( type, data ) {
9236                 return this.each( function() {
9237                         jQuery.event.trigger( type, data, this );
9238                 } );
9239         },
9240         triggerHandler: function( type, data ) {
9241                 var elem = this[ 0 ];
9242                 if ( elem ) {
9243                         return jQuery.event.trigger( type, data, elem, true );
9244                 }
9245         }
9246     } );
9247
9248
9249     // Support: Firefox <=44
9250     // Firefox doesn't have focus(in | out) events
9251     // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
9252     //
9253     // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
9254     // focus(in | out) events fire after focus & blur events,
9255     // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
9256     // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
9257     if ( !support.focusin ) {
9258         jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
9259
9260                 // Attach a single capturing handler on the document while someone wants focusin/focusout
9261                 var handler = function( event ) {
9262                         jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
9263                 };
9264
9265                 jQuery.event.special[ fix ] = {
9266                         setup: function() {
9267
9268                                 // Handle: regular nodes (via `this.ownerDocument`), window
9269                                 // (via `this.document`) & document (via `this`).
9270                                 var doc = this.ownerDocument || this.document || this,
9271                                         attaches = dataPriv.access( doc, fix );
9272
9273                                 if ( !attaches ) {
9274                                         doc.addEventListener( orig, handler, true );
9275                                 }
9276                                 dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
9277                         },
9278                         teardown: function() {
9279                                 var doc = this.ownerDocument || this.document || this,
9280                                         attaches = dataPriv.access( doc, fix ) - 1;
9281
9282                                 if ( !attaches ) {
9283                                         doc.removeEventListener( orig, handler, true );
9284                                         dataPriv.remove( doc, fix );
9285
9286                                 } else {
9287                                         dataPriv.access( doc, fix, attaches );
9288                                 }
9289                         }
9290                 };
9291         } );
9292     }
9293     var location = window.location;
9294
9295     var nonce = { guid: Date.now() };
9296
9297     var rquery = ( /\?/ );
9298
9299
9300
9301     // Cross-browser xml parsing
9302     jQuery.parseXML = function( data ) {
9303         var xml;
9304         if ( !data || typeof data !== "string" ) {
9305                 return null;
9306         }
9307
9308         // Support: IE 9 - 11 only
9309         // IE throws on parseFromString with invalid input.
9310         try {
9311                 xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
9312         } catch ( e ) {
9313                 xml = undefined;
9314         }
9315
9316         if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
9317                 jQuery.error( "Invalid XML: " + data );
9318         }
9319         return xml;
9320     };
9321
9322
9323     var
9324         rbracket = /\[\]$/,
9325         rCRLF = /\r?\n/g,
9326         rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
9327         rsubmittable = /^(?:input|select|textarea|keygen)/i;
9328
9329     function buildParams( prefix, obj, traditional, add ) {
9330         var name;
9331
9332         if ( Array.isArray( obj ) ) {
9333
9334                 // Serialize array item.
9335                 jQuery.each( obj, function( i, v ) {
9336                         if ( traditional || rbracket.test( prefix ) ) {
9337
9338                                 // Treat each array item as a scalar.
9339                                 add( prefix, v );
9340
9341                         } else {
9342
9343                                 // Item is non-scalar (array or object), encode its numeric index.
9344                                 buildParams(
9345                                         prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
9346                                         v,
9347                                         traditional,
9348                                         add
9349                                 );
9350                         }
9351                 } );
9352
9353         } else if ( !traditional && toType( obj ) === "object" ) {
9354
9355                 // Serialize object item.
9356                 for ( name in obj ) {
9357                         buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
9358                 }
9359
9360         } else {
9361
9362                 // Serialize scalar item.
9363                 add( prefix, obj );
9364         }
9365     }
9366
9367     // Serialize an array of form elements or a set of
9368     // key/values into a query string
9369     jQuery.param = function( a, traditional ) {
9370         var prefix,
9371                 s = [],
9372                 add = function( key, valueOrFunction ) {
9373
9374                         // If value is a function, invoke it and use its return value
9375                         var value = isFunction( valueOrFunction ) ?
9376                                 valueOrFunction() :
9377                                 valueOrFunction;
9378
9379                         s[ s.length ] = encodeURIComponent( key ) + "=" +
9380                                 encodeURIComponent( value == null ? "" : value );
9381                 };
9382
9383         if ( a == null ) {
9384                 return "";
9385         }
9386
9387         // If an array was passed in, assume that it is an array of form elements.
9388         if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
9389
9390                 // Serialize the form elements
9391                 jQuery.each( a, function() {
9392                         add( this.name, this.value );
9393                 } );
9394
9395         } else {
9396
9397                 // If traditional, encode the "old" way (the way 1.3.2 or older
9398                 // did it), otherwise encode params recursively.
9399                 for ( prefix in a ) {
9400                         buildParams( prefix, a[ prefix ], traditional, add );
9401                 }
9402         }
9403
9404         // Return the resulting serialization
9405         return s.join( "&" );
9406     };
9407
9408     jQuery.fn.extend( {
9409         serialize: function() {
9410                 return jQuery.param( this.serializeArray() );
9411         },
9412         serializeArray: function() {
9413                 return this.map( function() {
9414
9415                         // Can add propHook for "elements" to filter or add form elements
9416                         var elements = jQuery.prop( this, "elements" );
9417                         return elements ? jQuery.makeArray( elements ) : this;
9418                 } )
9419                 .filter( function() {
9420                         var type = this.type;
9421
9422                         // Use .is( ":disabled" ) so that fieldset[disabled] works
9423                         return this.name && !jQuery( this ).is( ":disabled" ) &&
9424                                 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
9425                                 ( this.checked || !rcheckableType.test( type ) );
9426                 } )
9427                 .map( function( _i, elem ) {
9428                         var val = jQuery( this ).val();
9429
9430                         if ( val == null ) {
9431                                 return null;
9432                         }
9433
9434                         if ( Array.isArray( val ) ) {
9435                                 return jQuery.map( val, function( val ) {
9436                                         return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9437                                 } );
9438                         }
9439
9440                         return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
9441                 } ).get();
9442         }
9443     } );
9444
9445
9446     var
9447         r20 = /%20/g,
9448         rhash = /#.*$/,
9449         rantiCache = /([?&])_=[^&]*/,
9450         rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
9451
9452         // #7653, #8125, #8152: local protocol detection
9453         rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
9454         rnoContent = /^(?:GET|HEAD)$/,
9455         rprotocol = /^\/\//,
9456
9457         /* Prefilters
9458          * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
9459          * 2) These are called:
9460          *    - BEFORE asking for a transport
9461          *    - AFTER param serialization (s.data is a string if s.processData is true)
9462          * 3) key is the dataType
9463          * 4) the catchall symbol "*" can be used
9464          * 5) execution will start with transport dataType and THEN continue down to "*" if needed
9465          */
9466         prefilters = {},
9467
9468         /* Transports bindings
9469          * 1) key is the dataType
9470          * 2) the catchall symbol "*" can be used
9471          * 3) selection will start with transport dataType and THEN go to "*" if needed
9472          */
9473         transports = {},
9474
9475         // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
9476         allTypes = "*/".concat( "*" ),
9477
9478         // Anchor tag for parsing the document origin
9479         originAnchor = document.createElement( "a" );
9480         originAnchor.href = location.href;
9481
9482     // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
9483     function addToPrefiltersOrTransports( structure ) {
9484
9485         // dataTypeExpression is optional and defaults to "*"
9486         return function( dataTypeExpression, func ) {
9487
9488                 if ( typeof dataTypeExpression !== "string" ) {
9489                         func = dataTypeExpression;
9490                         dataTypeExpression = "*";
9491                 }
9492
9493                 var dataType,
9494                         i = 0,
9495                         dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
9496
9497                 if ( isFunction( func ) ) {
9498
9499                         // For each dataType in the dataTypeExpression
9500                         while ( ( dataType = dataTypes[ i++ ] ) ) {
9501
9502                                 // Prepend if requested
9503                                 if ( dataType[ 0 ] === "+" ) {
9504                                         dataType = dataType.slice( 1 ) || "*";
9505                                         ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );
9506
9507                                 // Otherwise append
9508                                 } else {
9509                                         ( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
9510                                 }
9511                         }
9512                 }
9513         };
9514     }
9515
9516     // Base inspection function for prefilters and transports
9517     function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
9518
9519         var inspected = {},
9520                 seekingTransport = ( structure === transports );
9521
9522         function inspect( dataType ) {
9523                 var selected;
9524                 inspected[ dataType ] = true;
9525                 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
9526                         var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
9527                         if ( typeof dataTypeOrTransport === "string" &&
9528                                 !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
9529
9530                                 options.dataTypes.unshift( dataTypeOrTransport );
9531                                 inspect( dataTypeOrTransport );
9532                                 return false;
9533                         } else if ( seekingTransport ) {
9534                                 return !( selected = dataTypeOrTransport );
9535                         }
9536                 } );
9537                 return selected;
9538         }
9539
9540         return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
9541     }
9542
9543     // A special extend for ajax options
9544     // that takes "flat" options (not to be deep extended)
9545     // Fixes #9887
9546     function ajaxExtend( target, src ) {
9547         var key, deep,
9548                 flatOptions = jQuery.ajaxSettings.flatOptions || {};
9549
9550         for ( key in src ) {
9551                 if ( src[ key ] !== undefined ) {
9552                         ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
9553                 }
9554         }
9555         if ( deep ) {
9556                 jQuery.extend( true, target, deep );
9557         }
9558
9559         return target;
9560     }
9561
9562     /* Handles responses to an ajax request:
9563      * - finds the right dataType (mediates between content-type and expected dataType)
9564      * - returns the corresponding response
9565      */
9566     function ajaxHandleResponses( s, jqXHR, responses ) {
9567
9568         var ct, type, finalDataType, firstDataType,
9569                 contents = s.contents,
9570                 dataTypes = s.dataTypes;
9571
9572         // Remove auto dataType and get content-type in the process
9573         while ( dataTypes[ 0 ] === "*" ) {
9574                 dataTypes.shift();
9575                 if ( ct === undefined ) {
9576                         ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
9577                 }
9578         }
9579
9580         // Check if we're dealing with a known content-type
9581         if ( ct ) {
9582                 for ( type in contents ) {
9583                         if ( contents[ type ] && contents[ type ].test( ct ) ) {
9584                                 dataTypes.unshift( type );
9585                                 break;
9586                         }
9587                 }
9588         }
9589
9590         // Check to see if we have a response for the expected dataType
9591         if ( dataTypes[ 0 ] in responses ) {
9592                 finalDataType = dataTypes[ 0 ];
9593         } else {
9594
9595                 // Try convertible dataTypes
9596                 for ( type in responses ) {
9597                         if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
9598                                 finalDataType = type;
9599                                 break;
9600                         }
9601                         if ( !firstDataType ) {
9602                                 firstDataType = type;
9603                         }
9604                 }
9605
9606                 // Or just use first one
9607                 finalDataType = finalDataType || firstDataType;
9608         }
9609
9610         // If we found a dataType
9611         // We add the dataType to the list if needed
9612         // and return the corresponding response
9613         if ( finalDataType ) {
9614                 if ( finalDataType !== dataTypes[ 0 ] ) {
9615                         dataTypes.unshift( finalDataType );
9616                 }
9617                 return responses[ finalDataType ];
9618         }
9619     }
9620
9621     /* Chain conversions given the request and the original response
9622      * Also sets the responseXXX fields on the jqXHR instance
9623      */
9624     function ajaxConvert( s, response, jqXHR, isSuccess ) {
9625         var conv2, current, conv, tmp, prev,
9626                 converters = {},
9627
9628                 // Work with a copy of dataTypes in case we need to modify it for conversion
9629                 dataTypes = s.dataTypes.slice();
9630
9631         // Create converters map with lowercased keys
9632         if ( dataTypes[ 1 ] ) {
9633                 for ( conv in s.converters ) {
9634                         converters[ conv.toLowerCase() ] = s.converters[ conv ];
9635                 }
9636         }
9637
9638         current = dataTypes.shift();
9639
9640         // Convert to each sequential dataType
9641         while ( current ) {
9642
9643                 if ( s.responseFields[ current ] ) {
9644                         jqXHR[ s.responseFields[ current ] ] = response;
9645                 }
9646
9647                 // Apply the dataFilter if provided
9648                 if ( !prev && isSuccess && s.dataFilter ) {
9649                         response = s.dataFilter( response, s.dataType );
9650                 }
9651
9652                 prev = current;
9653                 current = dataTypes.shift();
9654
9655                 if ( current ) {
9656
9657                         // There's only work to do if current dataType is non-auto
9658                         if ( current === "*" ) {
9659
9660                                 current = prev;
9661
9662                         // Convert response if prev dataType is non-auto and differs from current
9663                         } else if ( prev !== "*" && prev !== current ) {
9664
9665                                 // Seek a direct converter
9666                                 conv = converters[ prev + " " + current ] || converters[ "* " + current ];
9667
9668                                 // If none found, seek a pair
9669                                 if ( !conv ) {
9670                                         for ( conv2 in converters ) {
9671
9672                                                 // If conv2 outputs current
9673                                                 tmp = conv2.split( " " );
9674                                                 if ( tmp[ 1 ] === current ) {
9675
9676                                                         // If prev can be converted to accepted input
9677                                                         conv = converters[ prev + " " + tmp[ 0 ] ] ||
9678                                                                 converters[ "* " + tmp[ 0 ] ];
9679                                                         if ( conv ) {
9680
9681                                                                 // Condense equivalence converters
9682                                                                 if ( conv === true ) {
9683                                                                         conv = converters[ conv2 ];
9684
9685                                                                 // Otherwise, insert the intermediate dataType
9686                                                                 } else if ( converters[ conv2 ] !== true ) {
9687                                                                         current = tmp[ 0 ];
9688                                                                         dataTypes.unshift( tmp[ 1 ] );
9689                                                                 }
9690                                                                 break;
9691                                                         }
9692                                                 }
9693                                         }
9694                                 }
9695
9696                                 // Apply converter (if not an equivalence)
9697                                 if ( conv !== true ) {
9698
9699                                         // Unless errors are allowed to bubble, catch and return them
9700                                         if ( conv && s.throws ) {
9701                                                 response = conv( response );
9702                                         } else {
9703                                                 try {
9704                                                         response = conv( response );
9705                                                 } catch ( e ) {
9706                                                         return {
9707                                                                 state: "parsererror",
9708                                                                 error: conv ? e : "No conversion from " + prev + " to " + current
9709                                                         };
9710                                                 }
9711                                         }
9712                                 }
9713                         }
9714                 }
9715         }
9716
9717         return { state: "success", data: response };
9718     }
9719
9720     jQuery.extend( {
9721
9722         // Counter for holding the number of active queries
9723         active: 0,
9724
9725         // Last-Modified header cache for next request
9726         lastModified: {},
9727         etag: {},
9728
9729         ajaxSettings: {
9730                 url: location.href,
9731                 type: "GET",
9732                 isLocal: rlocalProtocol.test( location.protocol ),
9733                 global: true,
9734                 processData: true,
9735                 async: true,
9736                 contentType: "application/x-www-form-urlencoded; charset=UTF-8",
9737
9738                 /*
9739                 timeout: 0,
9740                 data: null,
9741                 dataType: null,
9742                 username: null,
9743                 password: null,
9744                 cache: null,
9745                 throws: false,
9746                 traditional: false,
9747                 headers: {},
9748                 */
9749
9750                 accepts: {
9751                         "*": allTypes,
9752                         text: "text/plain",
9753                         html: "text/html",
9754                         xml: "application/xml, text/xml",
9755                         json: "application/json, text/javascript"
9756                 },
9757
9758                 contents: {
9759                         xml: /\bxml\b/,
9760                         html: /\bhtml/,
9761                         json: /\bjson\b/
9762                 },
9763
9764                 responseFields: {
9765                         xml: "responseXML",
9766                         text: "responseText",
9767                         json: "responseJSON"
9768                 },
9769
9770                 // Data converters
9771                 // Keys separate source (or catchall "*") and destination types with a single space
9772                 converters: {
9773
9774                         // Convert anything to text
9775                         "* text": String,
9776
9777                         // Text to html (true = no transformation)
9778                         "text html": true,
9779
9780                         // Evaluate text as a json expression
9781                         "text json": JSON.parse,
9782
9783                         // Parse text as xml
9784                         "text xml": jQuery.parseXML
9785                 },
9786
9787                 // For options that shouldn't be deep extended:
9788                 // you can add your own custom options here if
9789                 // and when you create one that shouldn't be
9790                 // deep extended (see ajaxExtend)
9791                 flatOptions: {
9792                         url: true,
9793                         context: true
9794                 }
9795         },
9796
9797         // Creates a full fledged settings object into target
9798         // with both ajaxSettings and settings fields.
9799         // If target is omitted, writes into ajaxSettings.
9800         ajaxSetup: function( target, settings ) {
9801                 return settings ?
9802
9803                         // Building a settings object
9804                         ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
9805
9806                         // Extending ajaxSettings
9807                         ajaxExtend( jQuery.ajaxSettings, target );
9808         },
9809
9810         ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
9811         ajaxTransport: addToPrefiltersOrTransports( transports ),
9812
9813         // Main method
9814         ajax: function( url, options ) {
9815
9816                 // If url is an object, simulate pre-1.5 signature
9817                 if ( typeof url === "object" ) {
9818                         options = url;
9819                         url = undefined;
9820                 }
9821
9822                 // Force options to be an object
9823                 options = options || {};
9824
9825                 var transport,
9826
9827                         // URL without anti-cache param
9828                         cacheURL,
9829
9830                         // Response headers
9831                         responseHeadersString,
9832                         responseHeaders,
9833
9834                         // timeout handle
9835                         timeoutTimer,
9836
9837                         // Url cleanup var
9838                         urlAnchor,
9839
9840                         // Request state (becomes false upon send and true upon completion)
9841                         completed,
9842
9843                         // To know if global events are to be dispatched
9844                         fireGlobals,
9845
9846                         // Loop variable
9847                         i,
9848
9849                         // uncached part of the url
9850                         uncached,
9851
9852                         // Create the final options object
9853                         s = jQuery.ajaxSetup( {}, options ),
9854
9855                         // Callbacks context
9856                         callbackContext = s.context || s,
9857
9858                         // Context for global events is callbackContext if it is a DOM node or jQuery collection
9859                         globalEventContext = s.context &&
9860                                 ( callbackContext.nodeType || callbackContext.jquery ) ?
9861                                         jQuery( callbackContext ) :
9862                                         jQuery.event,
9863
9864                         // Deferreds
9865                         deferred = jQuery.Deferred(),
9866                         completeDeferred = jQuery.Callbacks( "once memory" ),
9867
9868                         // Status-dependent callbacks
9869                         statusCode = s.statusCode || {},
9870
9871                         // Headers (they are sent all at once)
9872                         requestHeaders = {},
9873                         requestHeadersNames = {},
9874
9875                         // Default abort message
9876                         strAbort = "canceled",
9877
9878                         // Fake xhr
9879                         jqXHR = {
9880                                 readyState: 0,
9881
9882                                 // Builds headers hashtable if needed
9883                                 getResponseHeader: function( key ) {
9884                                         var match;
9885                                         if ( completed ) {
9886                                                 if ( !responseHeaders ) {
9887                                                         responseHeaders = {};
9888                                                         while ( ( match = rheaders.exec( responseHeadersString ) ) ) {
9889                                                                 responseHeaders[ match[ 1 ].toLowerCase() + " " ] =
9890                                                                         ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] )
9891                                                                                 .concat( match[ 2 ] );
9892                                                         }
9893                                                 }
9894                                                 match = responseHeaders[ key.toLowerCase() + " " ];
9895                                         }
9896                                         return match == null ? null : match.join( ", " );
9897                                 },
9898
9899                                 // Raw string
9900                                 getAllResponseHeaders: function() {
9901                                         return completed ? responseHeadersString : null;
9902                                 },
9903
9904                                 // Caches the header
9905                                 setRequestHeader: function( name, value ) {
9906                                         if ( completed == null ) {
9907                                                 name = requestHeadersNames[ name.toLowerCase() ] =
9908                                                         requestHeadersNames[ name.toLowerCase() ] || name;
9909                                                 requestHeaders[ name ] = value;
9910                                         }
9911                                         return this;
9912                                 },
9913
9914                                 // Overrides response content-type header
9915                                 overrideMimeType: function( type ) {
9916                                         if ( completed == null ) {
9917                                                 s.mimeType = type;
9918                                         }
9919                                         return this;
9920                                 },
9921
9922                                 // Status-dependent callbacks
9923                                 statusCode: function( map ) {
9924                                         var code;
9925                                         if ( map ) {
9926                                                 if ( completed ) {
9927
9928                                                         // Execute the appropriate callbacks
9929                                                         jqXHR.always( map[ jqXHR.status ] );
9930                                                 } else {
9931
9932                                                         // Lazy-add the new callbacks in a way that preserves old ones
9933                                                         for ( code in map ) {
9934                                                                 statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
9935                                                         }
9936                                                 }
9937                                         }
9938                                         return this;
9939                                 },
9940
9941                                 // Cancel the request
9942                                 abort: function( statusText ) {
9943                                         var finalText = statusText || strAbort;
9944                                         if ( transport ) {
9945                                                 transport.abort( finalText );
9946                                         }
9947                                         done( 0, finalText );
9948                                         return this;
9949                                 }
9950                         };
9951
9952                 // Attach deferreds
9953                 deferred.promise( jqXHR );
9954
9955                 // Add protocol if not provided (prefilters might expect it)
9956                 // Handle falsy url in the settings object (#10093: consistency with old signature)
9957                 // We also use the url parameter if available
9958                 s.url = ( ( url || s.url || location.href ) + "" )
9959                         .replace( rprotocol, location.protocol + "//" );
9960
9961                 // Alias method option to type as per ticket #12004
9962                 s.type = options.method || options.type || s.method || s.type;
9963
9964                 // Extract dataTypes list
9965                 s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
9966
9967                 // A cross-domain request is in order when the origin doesn't match the current origin.
9968                 if ( s.crossDomain == null ) {
9969                         urlAnchor = document.createElement( "a" );
9970
9971                         // Support: IE <=8 - 11, Edge 12 - 15
9972                         // IE throws exception on accessing the href property if url is malformed,
9973                         // e.g. http://example.com:80x/
9974                         try {
9975                                 urlAnchor.href = s.url;
9976
9977                                 // Support: IE <=8 - 11 only
9978                                 // Anchor's host property isn't correctly set when s.url is relative
9979                                 urlAnchor.href = urlAnchor.href;
9980                                 s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
9981                                         urlAnchor.protocol + "//" + urlAnchor.host;
9982                         } catch ( e ) {
9983
9984                                 // If there is an error parsing the URL, assume it is crossDomain,
9985                                 // it can be rejected by the transport if it is invalid
9986                                 s.crossDomain = true;
9987                         }
9988                 }
9989
9990                 // Convert data if not already a string
9991                 if ( s.data && s.processData && typeof s.data !== "string" ) {
9992                         s.data = jQuery.param( s.data, s.traditional );
9993                 }
9994
9995                 // Apply prefilters
9996                 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
9997
9998                 // If request was aborted inside a prefilter, stop there
9999                 if ( completed ) {
10000                         return jqXHR;
10001                 }
10002
10003                 // We can fire global events as of now if asked to
10004                 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
10005                 fireGlobals = jQuery.event && s.global;
10006
10007                 // Watch for a new set of requests
10008                 if ( fireGlobals && jQuery.active++ === 0 ) {
10009                         jQuery.event.trigger( "ajaxStart" );
10010                 }
10011
10012                 // Uppercase the type
10013                 s.type = s.type.toUpperCase();
10014
10015                 // Determine if request has content
10016                 s.hasContent = !rnoContent.test( s.type );
10017
10018                 // Save the URL in case we're toying with the If-Modified-Since
10019                 // and/or If-None-Match header later on
10020                 // Remove hash to simplify url manipulation
10021                 cacheURL = s.url.replace( rhash, "" );
10022
10023                 // More options handling for requests with no content
10024                 if ( !s.hasContent ) {
10025
10026                         // Remember the hash so we can put it back
10027                         uncached = s.url.slice( cacheURL.length );
10028
10029                         // If data is available and should be processed, append data to url
10030                         if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
10031                                 cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
10032
10033                                 // #9682: remove data so that it's not used in an eventual retry
10034                                 delete s.data;
10035                         }
10036
10037                         // Add or update anti-cache param if needed
10038                         if ( s.cache === false ) {
10039                                 cacheURL = cacheURL.replace( rantiCache, "$1" );
10040                                 uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) +
10041                                         uncached;
10042                         }
10043
10044                         // Put hash and anti-cache on the URL that will be requested (gh-1732)
10045                         s.url = cacheURL + uncached;
10046
10047                 // Change '%20' to '+' if this is encoded form body content (gh-2658)
10048                 } else if ( s.data && s.processData &&
10049                         ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
10050                         s.data = s.data.replace( r20, "+" );
10051                 }
10052
10053                 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
10054                 if ( s.ifModified ) {
10055                         if ( jQuery.lastModified[ cacheURL ] ) {
10056                                 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
10057                         }
10058                         if ( jQuery.etag[ cacheURL ] ) {
10059                                 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
10060                         }
10061                 }
10062
10063                 // Set the correct header, if data is being sent
10064                 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
10065                         jqXHR.setRequestHeader( "Content-Type", s.contentType );
10066                 }
10067
10068                 // Set the Accepts header for the server, depending on the dataType
10069                 jqXHR.setRequestHeader(
10070                         "Accept",
10071                         s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
10072                                 s.accepts[ s.dataTypes[ 0 ] ] +
10073                                         ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
10074                                 s.accepts[ "*" ]
10075                 );
10076
10077                 // Check for headers option
10078                 for ( i in s.headers ) {
10079                         jqXHR.setRequestHeader( i, s.headers[ i ] );
10080                 }
10081
10082                 // Allow custom headers/mimetypes and early abort
10083                 if ( s.beforeSend &&
10084                         ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
10085
10086                         // Abort if not done already and return
10087                         return jqXHR.abort();
10088                 }
10089
10090                 // Aborting is no longer a cancellation
10091                 strAbort = "abort";
10092
10093                 // Install callbacks on deferreds
10094                 completeDeferred.add( s.complete );
10095                 jqXHR.done( s.success );
10096                 jqXHR.fail( s.error );
10097
10098                 // Get transport
10099                 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
10100
10101                 // If no transport, we auto-abort
10102                 if ( !transport ) {
10103                         done( -1, "No Transport" );
10104                 } else {
10105                         jqXHR.readyState = 1;
10106
10107                         // Send global event
10108                         if ( fireGlobals ) {
10109                                 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
10110                         }
10111
10112                         // If request was aborted inside ajaxSend, stop there
10113                         if ( completed ) {
10114                                 return jqXHR;
10115                         }
10116
10117                         // Timeout
10118                         if ( s.async && s.timeout > 0 ) {
10119                                 timeoutTimer = window.setTimeout( function() {
10120                                         jqXHR.abort( "timeout" );
10121                                 }, s.timeout );
10122                         }
10123
10124                         try {
10125                                 completed = false;
10126                                 transport.send( requestHeaders, done );
10127                         } catch ( e ) {
10128
10129                                 // Rethrow post-completion exceptions
10130                                 if ( completed ) {
10131                                         throw e;
10132                                 }
10133
10134                                 // Propagate others as results
10135                                 done( -1, e );
10136                         }
10137                 }
10138
10139                 // Callback for when everything is done
10140                 function done( status, nativeStatusText, responses, headers ) {
10141                         var isSuccess, success, error, response, modified,
10142                                 statusText = nativeStatusText;
10143
10144                         // Ignore repeat invocations
10145                         if ( completed ) {
10146                                 return;
10147                         }
10148
10149                         completed = true;
10150
10151                         // Clear timeout if it exists
10152                         if ( timeoutTimer ) {
10153                                 window.clearTimeout( timeoutTimer );
10154                         }
10155
10156                         // Dereference transport for early garbage collection
10157                         // (no matter how long the jqXHR object will be used)
10158                         transport = undefined;
10159
10160                         // Cache response headers
10161                         responseHeadersString = headers || "";
10162
10163                         // Set readyState
10164                         jqXHR.readyState = status > 0 ? 4 : 0;
10165
10166                         // Determine if successful
10167                         isSuccess = status >= 200 && status < 300 || status === 304;
10168
10169                         // Get response data
10170                         if ( responses ) {
10171                                 response = ajaxHandleResponses( s, jqXHR, responses );
10172                         }
10173
10174                         // Use a noop converter for missing script
10175                         if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) {
10176                                 s.converters[ "text script" ] = function() {};
10177                         }
10178
10179                         // Convert no matter what (that way responseXXX fields are always set)
10180                         response = ajaxConvert( s, response, jqXHR, isSuccess );
10181
10182                         // If successful, handle type chaining
10183                         if ( isSuccess ) {
10184
10185                                 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
10186                                 if ( s.ifModified ) {
10187                                         modified = jqXHR.getResponseHeader( "Last-Modified" );
10188                                         if ( modified ) {
10189                                                 jQuery.lastModified[ cacheURL ] = modified;
10190                                         }
10191                                         modified = jqXHR.getResponseHeader( "etag" );
10192                                         if ( modified ) {
10193                                                 jQuery.etag[ cacheURL ] = modified;
10194                                         }
10195                                 }
10196
10197                                 // if no content
10198                                 if ( status === 204 || s.type === "HEAD" ) {
10199                                         statusText = "nocontent";
10200
10201                                 // if not modified
10202                                 } else if ( status === 304 ) {
10203                                         statusText = "notmodified";
10204
10205                                 // If we have data, let's convert it
10206                                 } else {
10207                                         statusText = response.state;
10208                                         success = response.data;
10209                                         error = response.error;
10210                                         isSuccess = !error;
10211                                 }
10212                         } else {
10213
10214                                 // Extract error from statusText and normalize for non-aborts
10215                                 error = statusText;
10216                                 if ( status || !statusText ) {
10217                                         statusText = "error";
10218                                         if ( status < 0 ) {
10219                                                 status = 0;
10220                                         }
10221                                 }
10222                         }
10223
10224                         // Set data for the fake xhr object
10225                         jqXHR.status = status;
10226                         jqXHR.statusText = ( nativeStatusText || statusText ) + "";
10227
10228                         // Success/Error
10229                         if ( isSuccess ) {
10230                                 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
10231                         } else {
10232                                 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
10233                         }
10234
10235                         // Status-dependent callbacks
10236                         jqXHR.statusCode( statusCode );
10237                         statusCode = undefined;
10238
10239                         if ( fireGlobals ) {
10240                                 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
10241                                         [ jqXHR, s, isSuccess ? success : error ] );
10242                         }
10243
10244                         // Complete
10245                         completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
10246
10247                         if ( fireGlobals ) {
10248                                 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
10249
10250                                 // Handle the global AJAX counter
10251                                 if ( !( --jQuery.active ) ) {
10252                                         jQuery.event.trigger( "ajaxStop" );
10253                                 }
10254                         }
10255                 }
10256
10257                 return jqXHR;
10258         },
10259
10260         getJSON: function( url, data, callback ) {
10261                 return jQuery.get( url, data, callback, "json" );
10262         },
10263
10264         getScript: function( url, callback ) {
10265                 return jQuery.get( url, undefined, callback, "script" );
10266         }
10267     } );
10268
10269     jQuery.each( [ "get", "post" ], function( _i, method ) {
10270         jQuery[ method ] = function( url, data, callback, type ) {
10271
10272                 // Shift arguments if data argument was omitted
10273                 if ( isFunction( data ) ) {
10274                         type = type || callback;
10275                         callback = data;
10276                         data = undefined;
10277                 }
10278
10279                 // The url can be an options object (which then must have .url)
10280                 return jQuery.ajax( jQuery.extend( {
10281                         url: url,
10282                         type: method,
10283                         dataType: type,
10284                         data: data,
10285                         success: callback
10286                 }, jQuery.isPlainObject( url ) && url ) );
10287         };
10288     } );
10289
10290     jQuery.ajaxPrefilter( function( s ) {
10291         var i;
10292         for ( i in s.headers ) {
10293                 if ( i.toLowerCase() === "content-type" ) {
10294                         s.contentType = s.headers[ i ] || "";
10295                 }
10296         }
10297     } );
10298
10299
10300     jQuery._evalUrl = function( url, options, doc ) {
10301         return jQuery.ajax( {
10302                 url: url,
10303
10304                 // Make this explicit, since user can override this through ajaxSetup (#11264)
10305                 type: "GET",
10306                 dataType: "script",
10307                 cache: true,
10308                 async: false,
10309                 global: false,
10310
10311                 // Only evaluate the response if it is successful (gh-4126)
10312                 // dataFilter is not invoked for failure responses, so using it instead
10313                 // of the default converter is kludgy but it works.
10314                 converters: {
10315                         "text script": function() {}
10316                 },
10317                 dataFilter: function( response ) {
10318                         jQuery.globalEval( response, options, doc );
10319                 }
10320         } );
10321     };
10322
10323
10324     jQuery.fn.extend( {
10325         wrapAll: function( html ) {
10326                 var wrap;
10327
10328                 if ( this[ 0 ] ) {
10329                         if ( isFunction( html ) ) {
10330                                 html = html.call( this[ 0 ] );
10331                         }
10332
10333                         // The elements to wrap the target around
10334                         wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
10335
10336                         if ( this[ 0 ].parentNode ) {
10337                                 wrap.insertBefore( this[ 0 ] );
10338                         }
10339
10340                         wrap.map( function() {
10341                                 var elem = this;
10342
10343                                 while ( elem.firstElementChild ) {
10344                                         elem = elem.firstElementChild;
10345                                 }
10346
10347                                 return elem;
10348                         } ).append( this );
10349                 }
10350
10351                 return this;
10352         },
10353
10354         wrapInner: function( html ) {
10355                 if ( isFunction( html ) ) {
10356                         return this.each( function( i ) {
10357                                 jQuery( this ).wrapInner( html.call( this, i ) );
10358                         } );
10359                 }
10360
10361                 return this.each( function() {
10362                         var self = jQuery( this ),
10363                                 contents = self.contents();
10364
10365                         if ( contents.length ) {
10366                                 contents.wrapAll( html );
10367
10368                         } else {
10369                                 self.append( html );
10370                         }
10371                 } );
10372         },
10373
10374         wrap: function( html ) {
10375                 var htmlIsFunction = isFunction( html );
10376
10377                 return this.each( function( i ) {
10378                         jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html );
10379                 } );
10380         },
10381
10382         unwrap: function( selector ) {
10383                 this.parent( selector ).not( "body" ).each( function() {
10384                         jQuery( this ).replaceWith( this.childNodes );
10385                 } );
10386                 return this;
10387         }
10388     } );
10389
10390
10391     jQuery.expr.pseudos.hidden = function( elem ) {
10392         return !jQuery.expr.pseudos.visible( elem );
10393     };
10394     jQuery.expr.pseudos.visible = function( elem ) {
10395         return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
10396     };
10397
10398
10399
10400
10401     jQuery.ajaxSettings.xhr = function() {
10402         try {
10403                 return new window.XMLHttpRequest();
10404         } catch ( e ) {}
10405     };
10406
10407     var xhrSuccessStatus = {
10408
10409                 // File protocol always yields status code 0, assume 200
10410                 0: 200,
10411
10412                 // Support: IE <=9 only
10413                 // #1450: sometimes IE returns 1223 when it should be 204
10414                 1223: 204
10415         },
10416         xhrSupported = jQuery.ajaxSettings.xhr();
10417
10418     support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
10419     support.ajax = xhrSupported = !!xhrSupported;
10420
10421     jQuery.ajaxTransport( function( options ) {
10422         var callback, errorCallback;
10423
10424         // Cross domain only allowed if supported through XMLHttpRequest
10425         if ( support.cors || xhrSupported && !options.crossDomain ) {
10426                 return {
10427                         send: function( headers, complete ) {
10428                                 var i,
10429                                         xhr = options.xhr();
10430
10431                                 xhr.open(
10432                                         options.type,
10433                                         options.url,
10434                                         options.async,
10435                                         options.username,
10436                                         options.password
10437                                 );
10438
10439                                 // Apply custom fields if provided
10440                                 if ( options.xhrFields ) {
10441                                         for ( i in options.xhrFields ) {
10442                                                 xhr[ i ] = options.xhrFields[ i ];
10443                                         }
10444                                 }
10445
10446                                 // Override mime type if needed
10447                                 if ( options.mimeType && xhr.overrideMimeType ) {
10448                                         xhr.overrideMimeType( options.mimeType );
10449                                 }
10450
10451                                 // X-Requested-With header
10452                                 // For cross-domain requests, seeing as conditions for a preflight are
10453                                 // akin to a jigsaw puzzle, we simply never set it to be sure.
10454                                 // (it can always be set on a per-request basis or even using ajaxSetup)
10455                                 // For same-domain requests, won't change header if already provided.
10456                                 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
10457                                         headers[ "X-Requested-With" ] = "XMLHttpRequest";
10458                                 }
10459
10460                                 // Set headers
10461                                 for ( i in headers ) {
10462                                         xhr.setRequestHeader( i, headers[ i ] );
10463                                 }
10464
10465                                 // Callback
10466                                 callback = function( type ) {
10467                                         return function() {
10468                                                 if ( callback ) {
10469                                                         callback = errorCallback = xhr.onload =
10470                                                                 xhr.onerror = xhr.onabort = xhr.ontimeout =
10471                                                                         xhr.onreadystatechange = null;
10472
10473                                                         if ( type === "abort" ) {
10474                                                                 xhr.abort();
10475                                                         } else if ( type === "error" ) {
10476
10477                                                                 // Support: IE <=9 only
10478                                                                 // On a manual native abort, IE9 throws
10479                                                                 // errors on any property access that is not readyState
10480                                                                 if ( typeof xhr.status !== "number" ) {
10481                                                                         complete( 0, "error" );
10482                                                                 } else {
10483                                                                         complete(
10484
10485                                                                                 // File: protocol always yields status 0; see #8605, #14207
10486                                                                                 xhr.status,
10487                                                                                 xhr.statusText
10488                                                                         );
10489                                                                 }
10490                                                         } else {
10491                                                                 complete(
10492                                                                         xhrSuccessStatus[ xhr.status ] || xhr.status,
10493                                                                         xhr.statusText,
10494
10495                                                                         // Support: IE <=9 only
10496                                                                         // IE9 has no XHR2 but throws on binary (trac-11426)
10497                                                                         // For XHR2 non-text, let the caller handle it (gh-2498)
10498                                                                         ( xhr.responseType || "text" ) !== "text"  ||
10499                                                                         typeof xhr.responseText !== "string" ?
10500                                                                                 { binary: xhr.response } :
10501                                                                                 { text: xhr.responseText },
10502                                                                         xhr.getAllResponseHeaders()
10503                                                                 );
10504                                                         }
10505                                                 }
10506                                         };
10507                                 };
10508
10509                                 // Listen to events
10510                                 xhr.onload = callback();
10511                                 errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" );
10512
10513                                 // Support: IE 9 only
10514                                 // Use onreadystatechange to replace onabort
10515                                 // to handle uncaught aborts
10516                                 if ( xhr.onabort !== undefined ) {
10517                                         xhr.onabort = errorCallback;
10518                                 } else {
10519                                         xhr.onreadystatechange = function() {
10520
10521                                                 // Check readyState before timeout as it changes
10522                                                 if ( xhr.readyState === 4 ) {
10523
10524                                                         // Allow onerror to be called first,
10525                                                         // but that will not handle a native abort
10526                                                         // Also, save errorCallback to a variable
10527                                                         // as xhr.onerror cannot be accessed
10528                                                         window.setTimeout( function() {
10529                                                                 if ( callback ) {
10530                                                                         errorCallback();
10531                                                                 }
10532                                                         } );
10533                                                 }
10534                                         };
10535                                 }
10536
10537                                 // Create the abort callback
10538                                 callback = callback( "abort" );
10539
10540                                 try {
10541
10542                                         // Do send the request (this may raise an exception)
10543                                         xhr.send( options.hasContent && options.data || null );
10544                                 } catch ( e ) {
10545
10546                                         // #14683: Only rethrow if this hasn't been notified as an error yet
10547                                         if ( callback ) {
10548                                                 throw e;
10549                                         }
10550                                 }
10551                         },
10552
10553                         abort: function() {
10554                                 if ( callback ) {
10555                                         callback();
10556                                 }
10557                         }
10558                 };
10559         }
10560     } );
10561
10562
10563
10564
10565     // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
10566     jQuery.ajaxPrefilter( function( s ) {
10567         if ( s.crossDomain ) {
10568                 s.contents.script = false;
10569         }
10570     } );
10571
10572     // Install script dataType
10573     jQuery.ajaxSetup( {
10574         accepts: {
10575                 script: "text/javascript, application/javascript, " +
10576                         "application/ecmascript, application/x-ecmascript"
10577         },
10578         contents: {
10579                 script: /\b(?:java|ecma)script\b/
10580         },
10581         converters: {
10582                 "text script": function( text ) {
10583                         jQuery.globalEval( text );
10584                         return text;
10585                 }
10586         }
10587     } );
10588
10589     // Handle cache's special case and crossDomain
10590     jQuery.ajaxPrefilter( "script", function( s ) {
10591         if ( s.cache === undefined ) {
10592                 s.cache = false;
10593         }
10594         if ( s.crossDomain ) {
10595                 s.type = "GET";
10596         }
10597     } );
10598
10599     // Bind script tag hack transport
10600     jQuery.ajaxTransport( "script", function( s ) {
10601
10602         // This transport only deals with cross domain or forced-by-attrs requests
10603         if ( s.crossDomain || s.scriptAttrs ) {
10604                 var script, callback;
10605                 return {
10606                         send: function( _, complete ) {
10607                                 script = jQuery( "<script>" )
10608                                         .attr( s.scriptAttrs || {} )
10609                                         .prop( { charset: s.scriptCharset, src: s.url } )
10610                                         .on( "load error", callback = function( evt ) {
10611                                                 script.remove();
10612                                                 callback = null;
10613                                                 if ( evt ) {
10614                                                         complete( evt.type === "error" ? 404 : 200, evt.type );
10615                                                 }
10616                                         } );
10617
10618                                 // Use native DOM manipulation to avoid our domManip AJAX trickery
10619                                 document.head.appendChild( script[ 0 ] );
10620                         },
10621                         abort: function() {
10622                                 if ( callback ) {
10623                                         callback();
10624                                 }
10625                         }
10626                 };
10627         }
10628     } );
10629
10630
10631
10632
10633     var oldCallbacks = [],
10634         rjsonp = /(=)\?(?=&|$)|\?\?/;
10635
10636     // Default jsonp settings
10637     jQuery.ajaxSetup( {
10638         jsonp: "callback",
10639         jsonpCallback: function() {
10640                 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) );
10641                 this[ callback ] = true;
10642                 return callback;
10643         }
10644     } );
10645
10646     // Detect, normalize options and install callbacks for jsonp requests
10647     jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
10648
10649         var callbackName, overwritten, responseContainer,
10650                 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
10651                         "url" :
10652                         typeof s.data === "string" &&
10653                                 ( s.contentType || "" )
10654                                         .indexOf( "application/x-www-form-urlencoded" ) === 0 &&
10655                                 rjsonp.test( s.data ) && "data"
10656                 );
10657
10658         // Handle iff the expected data type is "jsonp" or we have a parameter to set
10659         if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
10660
10661                 // Get callback name, remembering preexisting value associated with it
10662                 callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ?
10663                         s.jsonpCallback() :
10664                         s.jsonpCallback;
10665
10666                 // Insert callback into url or form data
10667                 if ( jsonProp ) {
10668                         s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
10669                 } else if ( s.jsonp !== false ) {
10670                         s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
10671                 }
10672
10673                 // Use data converter to retrieve json after script execution
10674                 s.converters[ "script json" ] = function() {
10675                         if ( !responseContainer ) {
10676                                 jQuery.error( callbackName + " was not called" );
10677                         }
10678                         return responseContainer[ 0 ];
10679                 };
10680
10681                 // Force json dataType
10682                 s.dataTypes[ 0 ] = "json";
10683
10684                 // Install callback
10685                 overwritten = window[ callbackName ];
10686                 window[ callbackName ] = function() {
10687                         responseContainer = arguments;
10688                 };
10689
10690                 // Clean-up function (fires after converters)
10691                 jqXHR.always( function() {
10692
10693                         // If previous value didn't exist - remove it
10694                         if ( overwritten === undefined ) {
10695                                 jQuery( window ).removeProp( callbackName );
10696
10697                         // Otherwise restore preexisting value
10698                         } else {
10699                                 window[ callbackName ] = overwritten;
10700                         }
10701
10702                         // Save back as free
10703                         if ( s[ callbackName ] ) {
10704
10705                                 // Make sure that re-using the options doesn't screw things around
10706                                 s.jsonpCallback = originalSettings.jsonpCallback;
10707
10708                                 // Save the callback name for future use
10709                                 oldCallbacks.push( callbackName );
10710                         }
10711
10712                         // Call if it was a function and we have a response
10713                         if ( responseContainer && isFunction( overwritten ) ) {
10714                                 overwritten( responseContainer[ 0 ] );
10715                         }
10716
10717                         responseContainer = overwritten = undefined;
10718                 } );
10719
10720                 // Delegate to script
10721                 return "script";
10722         }
10723     } );
10724
10725
10726
10727
10728     // Support: Safari 8 only
10729     // In Safari 8 documents created via document.implementation.createHTMLDocument
10730     // collapse sibling forms: the second one becomes a child of the first one.
10731     // Because of that, this security measure has to be disabled in Safari 8.
10732     // https://bugs.webkit.org/show_bug.cgi?id=137337
10733     support.createHTMLDocument = ( function() {
10734         var body = document.implementation.createHTMLDocument( "" ).body;
10735         body.innerHTML = "<form></form><form></form>";
10736         return body.childNodes.length === 2;
10737     } )();
10738
10739
10740     // Argument "data" should be string of html
10741     // context (optional): If specified, the fragment will be created in this context,
10742     // defaults to document
10743     // keepScripts (optional): If true, will include scripts passed in the html string
10744     jQuery.parseHTML = function( data, context, keepScripts ) {
10745         if ( typeof data !== "string" ) {
10746                 return [];
10747         }
10748         if ( typeof context === "boolean" ) {
10749                 keepScripts = context;
10750                 context = false;
10751         }
10752
10753         var base, parsed, scripts;
10754
10755         if ( !context ) {
10756
10757                 // Stop scripts or inline event handlers from being executed immediately
10758                 // by using document.implementation
10759                 if ( support.createHTMLDocument ) {
10760                         context = document.implementation.createHTMLDocument( "" );
10761
10762                         // Set the base href for the created document
10763                         // so any parsed elements with URLs
10764                         // are based on the document's URL (gh-2965)
10765                         base = context.createElement( "base" );
10766                         base.href = document.location.href;
10767                         context.head.appendChild( base );
10768                 } else {
10769                         context = document;
10770                 }
10771         }
10772
10773         parsed = rsingleTag.exec( data );
10774         scripts = !keepScripts && [];
10775
10776         // Single tag
10777         if ( parsed ) {
10778                 return [ context.createElement( parsed[ 1 ] ) ];
10779         }
10780
10781         parsed = buildFragment( [ data ], context, scripts );
10782
10783         if ( scripts && scripts.length ) {
10784                 jQuery( scripts ).remove();
10785         }
10786
10787         return jQuery.merge( [], parsed.childNodes );
10788     };
10789
10790
10791     /**
10792      * Load a url into a page
10793      */
10794     jQuery.fn.load = function( url, params, callback ) {
10795         var selector, type, response,
10796                 self = this,
10797                 off = url.indexOf( " " );
10798
10799         if ( off > -1 ) {
10800                 selector = stripAndCollapse( url.slice( off ) );
10801                 url = url.slice( 0, off );
10802         }
10803
10804         // If it's a function
10805         if ( isFunction( params ) ) {
10806
10807                 // We assume that it's the callback
10808                 callback = params;
10809                 params = undefined;
10810
10811         // Otherwise, build a param string
10812         } else if ( params && typeof params === "object" ) {
10813                 type = "POST";
10814         }
10815
10816         // If we have elements to modify, make the request
10817         if ( self.length > 0 ) {
10818                 jQuery.ajax( {
10819                         url: url,
10820
10821                         // If "type" variable is undefined, then "GET" method will be used.
10822                         // Make value of this field explicit since
10823                         // user can override it through ajaxSetup method
10824                         type: type || "GET",
10825                         dataType: "html",
10826                         data: params
10827                 } ).done( function( responseText ) {
10828
10829                         // Save response for use in complete callback
10830                         response = arguments;
10831
10832                         self.html( selector ?
10833
10834                                 // If a selector was specified, locate the right elements in a dummy div
10835                                 // Exclude scripts to avoid IE 'Permission Denied' errors
10836                                 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :
10837
10838                                 // Otherwise use the full result
10839                                 responseText );
10840
10841                 // If the request succeeds, this function gets "data", "status", "jqXHR"
10842                 // but they are ignored because response was set above.
10843                 // If it fails, this function gets "jqXHR", "status", "error"
10844                 } ).always( callback && function( jqXHR, status ) {
10845                         self.each( function() {
10846                                 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
10847                         } );
10848                 } );
10849         }
10850
10851         return this;
10852     };
10853
10854
10855
10856
10857     jQuery.expr.pseudos.animated = function( elem ) {
10858         return jQuery.grep( jQuery.timers, function( fn ) {
10859                 return elem === fn.elem;
10860         } ).length;
10861     };
10862
10863
10864
10865
10866     jQuery.offset = {
10867         setOffset: function( elem, options, i ) {
10868                 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
10869                         position = jQuery.css( elem, "position" ),
10870                         curElem = jQuery( elem ),
10871                         props = {};
10872
10873                 // Set position first, in-case top/left are set even on static elem
10874                 if ( position === "static" ) {
10875                         elem.style.position = "relative";
10876                 }
10877
10878                 curOffset = curElem.offset();
10879                 curCSSTop = jQuery.css( elem, "top" );
10880                 curCSSLeft = jQuery.css( elem, "left" );
10881                 calculatePosition = ( position === "absolute" || position === "fixed" ) &&
10882                         ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
10883
10884                 // Need to be able to calculate position if either
10885                 // top or left is auto and position is either absolute or fixed
10886                 if ( calculatePosition ) {
10887                         curPosition = curElem.position();
10888                         curTop = curPosition.top;
10889                         curLeft = curPosition.left;
10890
10891                 } else {
10892                         curTop = parseFloat( curCSSTop ) || 0;
10893                         curLeft = parseFloat( curCSSLeft ) || 0;
10894                 }
10895
10896                 if ( isFunction( options ) ) {
10897
10898                         // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
10899                         options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
10900                 }
10901
10902                 if ( options.top != null ) {
10903                         props.top = ( options.top - curOffset.top ) + curTop;
10904                 }
10905                 if ( options.left != null ) {
10906                         props.left = ( options.left - curOffset.left ) + curLeft;
10907                 }
10908
10909                 if ( "using" in options ) {
10910                         options.using.call( elem, props );
10911
10912                 } else {
10913                         if ( typeof props.top === "number" ) {
10914                                 props.top += "px";
10915                         }
10916                         if ( typeof props.left === "number" ) {
10917                                 props.left += "px";
10918                         }
10919                         curElem.css( props );
10920                 }
10921         }
10922     };
10923
10924     jQuery.fn.extend( {
10925
10926         // offset() relates an element's border box to the document origin
10927         offset: function( options ) {
10928
10929                 // Preserve chaining for setter
10930                 if ( arguments.length ) {
10931                         return options === undefined ?
10932                                 this :
10933                                 this.each( function( i ) {
10934                                         jQuery.offset.setOffset( this, options, i );
10935                                 } );
10936                 }
10937
10938                 var rect, win,
10939                         elem = this[ 0 ];
10940
10941                 if ( !elem ) {
10942                         return;
10943                 }
10944
10945                 // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
10946                 // Support: IE <=11 only
10947                 // Running getBoundingClientRect on a
10948                 // disconnected node in IE throws an error
10949                 if ( !elem.getClientRects().length ) {
10950                         return { top: 0, left: 0 };
10951                 }
10952
10953                 // Get document-relative position by adding viewport scroll to viewport-relative gBCR
10954                 rect = elem.getBoundingClientRect();
10955                 win = elem.ownerDocument.defaultView;
10956                 return {
10957                         top: rect.top + win.pageYOffset,
10958                         left: rect.left + win.pageXOffset
10959                 };
10960         },
10961
10962         // position() relates an element's margin box to its offset parent's padding box
10963         // This corresponds to the behavior of CSS absolute positioning
10964         position: function() {
10965                 if ( !this[ 0 ] ) {
10966                         return;
10967                 }
10968
10969                 var offsetParent, offset, doc,
10970                         elem = this[ 0 ],
10971                         parentOffset = { top: 0, left: 0 };
10972
10973                 // position:fixed elements are offset from the viewport, which itself always has zero offset
10974                 if ( jQuery.css( elem, "position" ) === "fixed" ) {
10975
10976                         // Assume position:fixed implies availability of getBoundingClientRect
10977                         offset = elem.getBoundingClientRect();
10978
10979                 } else {
10980                         offset = this.offset();
10981
10982                         // Account for the *real* offset parent, which can be the document or its root element
10983                         // when a statically positioned element is identified
10984                         doc = elem.ownerDocument;
10985                         offsetParent = elem.offsetParent || doc.documentElement;
10986                         while ( offsetParent &&
10987                                 ( offsetParent === doc.body || offsetParent === doc.documentElement ) &&
10988                                 jQuery.css( offsetParent, "position" ) === "static" ) {
10989
10990                                 offsetParent = offsetParent.parentNode;
10991                         }
10992                         if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) {
10993
10994                                 // Incorporate borders into its offset, since they are outside its content origin
10995                                 parentOffset = jQuery( offsetParent ).offset();
10996                                 parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true );
10997                                 parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true );
10998                         }
10999                 }
11000
11001                 // Subtract parent offsets and element margins
11002                 return {
11003                         top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
11004                         left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
11005                 };
11006         },
11007
11008         // This method will return documentElement in the following cases:
11009         // 1) For the element inside the iframe without offsetParent, this method will return
11010         //    documentElement of the parent window
11011         // 2) For the hidden or detached element
11012         // 3) For body or html element, i.e. in case of the html node - it will return itself
11013         //
11014         // but those exceptions were never presented as a real life use-cases
11015         // and might be considered as more preferable results.
11016         //
11017         // This logic, however, is not guaranteed and can change at any point in the future
11018         offsetParent: function() {
11019                 return this.map( function() {
11020                         var offsetParent = this.offsetParent;
11021
11022                         while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
11023                                 offsetParent = offsetParent.offsetParent;
11024                         }
11025
11026                         return offsetParent || documentElement;
11027                 } );
11028         }
11029     } );
11030
11031     // Create scrollLeft and scrollTop methods
11032     jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
11033         var top = "pageYOffset" === prop;
11034
11035         jQuery.fn[ method ] = function( val ) {
11036                 return access( this, function( elem, method, val ) {
11037
11038                         // Coalesce documents and windows
11039                         var win;
11040                         if ( isWindow( elem ) ) {
11041                                 win = elem;
11042                         } else if ( elem.nodeType === 9 ) {
11043                                 win = elem.defaultView;
11044                         }
11045
11046                         if ( val === undefined ) {
11047                                 return win ? win[ prop ] : elem[ method ];
11048                         }
11049
11050                         if ( win ) {
11051                                 win.scrollTo(
11052                                         !top ? val : win.pageXOffset,
11053                                         top ? val : win.pageYOffset
11054                                 );
11055
11056                         } else {
11057                                 elem[ method ] = val;
11058                         }
11059                 }, method, val, arguments.length );
11060         };
11061     } );
11062
11063     // Support: Safari <=7 - 9.1, Chrome <=37 - 49
11064     // Add the top/left cssHooks using jQuery.fn.position
11065     // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
11066     // Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
11067     // getComputedStyle returns percent when specified for top/left/bottom/right;
11068     // rather than make the css module depend on the offset module, just check for it here
11069     jQuery.each( [ "top", "left" ], function( _i, prop ) {
11070         jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
11071                 function( elem, computed ) {
11072                         if ( computed ) {
11073                                 computed = curCSS( elem, prop );
11074
11075                                 // If curCSS returns percentage, fallback to offset
11076                                 return rnumnonpx.test( computed ) ?
11077                                         jQuery( elem ).position()[ prop ] + "px" :
11078                                         computed;
11079                         }
11080                 }
11081         );
11082     } );
11083
11084
11085     // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
11086     jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
11087         jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
11088                 function( defaultExtra, funcName ) {
11089
11090                 // Margin is only for outerHeight, outerWidth
11091                 jQuery.fn[ funcName ] = function( margin, value ) {
11092                         var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
11093                                 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
11094
11095                         return access( this, function( elem, type, value ) {
11096                                 var doc;
11097
11098                                 if ( isWindow( elem ) ) {
11099
11100                                         // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729)
11101                                         return funcName.indexOf( "outer" ) === 0 ?
11102                                                 elem[ "inner" + name ] :
11103                                                 elem.document.documentElement[ "client" + name ];
11104                                 }
11105
11106                                 // Get document width or height
11107                                 if ( elem.nodeType === 9 ) {
11108                                         doc = elem.documentElement;
11109
11110                                         // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
11111                                         // whichever is greatest
11112                                         return Math.max(
11113                                                 elem.body[ "scroll" + name ], doc[ "scroll" + name ],
11114                                                 elem.body[ "offset" + name ], doc[ "offset" + name ],
11115                                                 doc[ "client" + name ]
11116                                         );
11117                                 }
11118
11119                                 return value === undefined ?
11120
11121                                         // Get width or height on the element, requesting but not forcing parseFloat
11122                                         jQuery.css( elem, type, extra ) :
11123
11124                                         // Set width or height on the element
11125                                         jQuery.style( elem, type, value, extra );
11126                         }, type, chainable ? margin : undefined, chainable );
11127                 };
11128         } );
11129     } );
11130
11131
11132     jQuery.each( [
11133         "ajaxStart",
11134         "ajaxStop",
11135         "ajaxComplete",
11136         "ajaxError",
11137         "ajaxSuccess",
11138         "ajaxSend"
11139     ], function( _i, type ) {
11140         jQuery.fn[ type ] = function( fn ) {
11141                 return this.on( type, fn );
11142         };
11143     } );
11144
11145
11146
11147
11148     jQuery.fn.extend( {
11149
11150         bind: function( types, data, fn ) {
11151                 return this.on( types, null, data, fn );
11152         },
11153         unbind: function( types, fn ) {
11154                 return this.off( types, null, fn );
11155         },
11156
11157         delegate: function( selector, types, data, fn ) {
11158                 return this.on( types, selector, data, fn );
11159         },
11160         undelegate: function( selector, types, fn ) {
11161
11162                 // ( namespace ) or ( selector, types [, fn] )
11163                 return arguments.length === 1 ?
11164                         this.off( selector, "**" ) :
11165                         this.off( types, selector || "**", fn );
11166         },
11167
11168         hover: function( fnOver, fnOut ) {
11169                 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
11170         }
11171     } );
11172
11173     jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
11174         "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
11175         "change select submit keydown keypress keyup contextmenu" ).split( " " ),
11176         function( _i, name ) {
11177
11178                 // Handle event binding
11179                 jQuery.fn[ name ] = function( data, fn ) {
11180                         return arguments.length > 0 ?
11181                                 this.on( name, null, data, fn ) :
11182                                 this.trigger( name );
11183                 };
11184         } );
11185
11186
11187
11188
11189     // Support: Android <=4.0 only
11190     // Make sure we trim BOM and NBSP
11191     var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
11192
11193     // Bind a function to a context, optionally partially applying any
11194     // arguments.
11195     // jQuery.proxy is deprecated to promote standards (specifically Function#bind)
11196     // However, it is not slated for removal any time soon
11197     jQuery.proxy = function( fn, context ) {
11198         var tmp, args, proxy;
11199
11200         if ( typeof context === "string" ) {
11201                 tmp = fn[ context ];
11202                 context = fn;
11203                 fn = tmp;
11204         }
11205
11206         // Quick check to determine if target is callable, in the spec
11207         // this throws a TypeError, but we will just return undefined.
11208         if ( !isFunction( fn ) ) {
11209                 return undefined;
11210         }
11211
11212         // Simulated bind
11213         args = slice.call( arguments, 2 );
11214         proxy = function() {
11215                 return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
11216         };
11217
11218         // Set the guid of unique handler to the same of original handler, so it can be removed
11219         proxy.guid = fn.guid = fn.guid || jQuery.guid++;
11220
11221         return proxy;
11222     };
11223
11224     jQuery.holdReady = function( hold ) {
11225         if ( hold ) {
11226                 jQuery.readyWait++;
11227         } else {
11228                 jQuery.ready( true );
11229         }
11230     };
11231     jQuery.isArray = Array.isArray;
11232     jQuery.parseJSON = JSON.parse;
11233     jQuery.nodeName = nodeName;
11234     jQuery.isFunction = isFunction;
11235     jQuery.isWindow = isWindow;
11236     jQuery.camelCase = camelCase;
11237     jQuery.type = toType;
11238
11239     jQuery.now = Date.now;
11240
11241     jQuery.isNumeric = function( obj ) {
11242
11243         // As of jQuery 3.0, isNumeric is limited to
11244         // strings and numbers (primitives or objects)
11245         // that can be coerced to finite numbers (gh-2662)
11246         var type = jQuery.type( obj );
11247         return ( type === "number" || type === "string" ) &&
11248
11249                 // parseFloat NaNs numeric-cast false positives ("")
11250                 // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
11251                 // subtraction forces infinities to NaN
11252                 !isNaN( obj - parseFloat( obj ) );
11253     };
11254
11255     jQuery.trim = function( text ) {
11256         return text == null ?
11257                 "" :
11258                 ( text + "" ).replace( rtrim, "" );
11259     };
11260
11261
11262
11263
11264     var
11265
11266         // Map over jQuery in case of overwrite
11267         _jQuery = window.jQuery,
11268
11269         // Map over the $ in case of overwrite
11270         _$ = window.$;
11271
11272     jQuery.noConflict = function( deep ) {
11273         if ( window.$ === jQuery ) {
11274                 window.$ = _$;
11275         }
11276
11277         if ( deep && window.jQuery === jQuery ) {
11278                 window.jQuery = _jQuery;
11279         }
11280
11281         return jQuery;
11282     };
11283
11284     // Expose jQuery and $ identifiers, even in AMD
11285     // (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
11286     // and CommonJS for browser emulators (#13566)
11287     if ( typeof noGlobal === "undefined" ) {
11288         window.jQuery = window.$ = jQuery;
11289     }
11290
11291
11292
11293
11294     return jQuery;
11295     } );
11296     });
11297
11298     var jquery$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.assign(/*#__PURE__*/Object.create(null), jquery, {
11299         'default': jquery
11300     }));
11301
11302     /*!
11303       * Bootstrap v4.6.0 (https://getbootstrap.com/)
11304       * Copyright 2011-2021 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
11305       * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
11306       */
11307
11308     createCommonjsModule(function (module, exports) {
11309     (function (global, factory) {
11310        factory(exports, jquery) ;
11311     }(commonjsGlobal, (function (exports, $) {
11312       function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
11313
11314       var $__default = /*#__PURE__*/_interopDefaultLegacy($);
11315
11316       function _defineProperties(target, props) {
11317         for (var i = 0; i < props.length; i++) {
11318           var descriptor = props[i];
11319           descriptor.enumerable = descriptor.enumerable || false;
11320           descriptor.configurable = true;
11321           if ("value" in descriptor) descriptor.writable = true;
11322           Object.defineProperty(target, descriptor.key, descriptor);
11323         }
11324       }
11325
11326       function _createClass(Constructor, protoProps, staticProps) {
11327         if (protoProps) _defineProperties(Constructor.prototype, protoProps);
11328         if (staticProps) _defineProperties(Constructor, staticProps);
11329         return Constructor;
11330       }
11331
11332       function _extends() {
11333         _extends = Object.assign || function (target) {
11334           for (var i = 1; i < arguments.length; i++) {
11335             var source = arguments[i];
11336
11337             for (var key in source) {
11338               if (Object.prototype.hasOwnProperty.call(source, key)) {
11339                 target[key] = source[key];
11340               }
11341             }
11342           }
11343
11344           return target;
11345         };
11346
11347         return _extends.apply(this, arguments);
11348       }
11349
11350       function _inheritsLoose(subClass, superClass) {
11351         subClass.prototype = Object.create(superClass.prototype);
11352         subClass.prototype.constructor = subClass;
11353         subClass.__proto__ = superClass;
11354       }
11355
11356       /**
11357        * --------------------------------------------------------------------------
11358        * Bootstrap (v4.6.0): util.js
11359        * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
11360        * --------------------------------------------------------------------------
11361        */
11362       /**
11363        * ------------------------------------------------------------------------
11364        * Private TransitionEnd Helpers
11365        * ------------------------------------------------------------------------
11366        */
11367
11368       var TRANSITION_END = 'transitionend';
11369       var MAX_UID = 1000000;
11370       var MILLISECONDS_MULTIPLIER = 1000; // Shoutout AngusCroll (https://goo.gl/pxwQGp)
11371
11372       function toType(obj) {
11373         if (obj === null || typeof obj === 'undefined') {
11374           return "" + obj;
11375         }
11376
11377         return {}.toString.call(obj).match(/\s([a-z]+)/i)[1].toLowerCase();
11378       }
11379
11380       function getSpecialTransitionEndEvent() {
11381         return {
11382           bindType: TRANSITION_END,
11383           delegateType: TRANSITION_END,
11384           handle: function handle(event) {
11385             if ($__default['default'](event.target).is(this)) {
11386               return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params
11387             }
11388
11389             return undefined;
11390           }
11391         };
11392       }
11393
11394       function transitionEndEmulator(duration) {
11395         var _this = this;
11396
11397         var called = false;
11398         $__default['default'](this).one(Util.TRANSITION_END, function () {
11399           called = true;
11400         });
11401         setTimeout(function () {
11402           if (!called) {
11403             Util.triggerTransitionEnd(_this);
11404           }
11405         }, duration);
11406         return this;
11407       }
11408
11409       function setTransitionEndSupport() {
11410         $__default['default'].fn.emulateTransitionEnd = transitionEndEmulator;
11411         $__default['default'].event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent();
11412       }
11413       /**
11414        * --------------------------------------------------------------------------
11415        * Public Util Api
11416        * --------------------------------------------------------------------------
11417        */
11418
11419
11420       var Util = {
11421         TRANSITION_END: 'bsTransitionEnd',
11422         getUID: function getUID(prefix) {
11423           do {
11424             prefix += ~~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here
11425           } while (document.getElementById(prefix));
11426
11427           return prefix;
11428         },
11429         getSelectorFromElement: function getSelectorFromElement(element) {
11430           var selector = element.getAttribute('data-target');
11431
11432           if (!selector || selector === '#') {
11433             var hrefAttr = element.getAttribute('href');
11434             selector = hrefAttr && hrefAttr !== '#' ? hrefAttr.trim() : '';
11435           }
11436
11437           try {
11438             return document.querySelector(selector) ? selector : null;
11439           } catch (_) {
11440             return null;
11441           }
11442         },
11443         getTransitionDurationFromElement: function getTransitionDurationFromElement(element) {
11444           if (!element) {
11445             return 0;
11446           } // Get transition-duration of the element
11447
11448
11449           var transitionDuration = $__default['default'](element).css('transition-duration');
11450           var transitionDelay = $__default['default'](element).css('transition-delay');
11451           var floatTransitionDuration = parseFloat(transitionDuration);
11452           var floatTransitionDelay = parseFloat(transitionDelay); // Return 0 if element or transition duration is not found
11453
11454           if (!floatTransitionDuration && !floatTransitionDelay) {
11455             return 0;
11456           } // If multiple durations are defined, take the first
11457
11458
11459           transitionDuration = transitionDuration.split(',')[0];
11460           transitionDelay = transitionDelay.split(',')[0];
11461           return (parseFloat(transitionDuration) + parseFloat(transitionDelay)) * MILLISECONDS_MULTIPLIER;
11462         },
11463         reflow: function reflow(element) {
11464           return element.offsetHeight;
11465         },
11466         triggerTransitionEnd: function triggerTransitionEnd(element) {
11467           $__default['default'](element).trigger(TRANSITION_END);
11468         },
11469         supportsTransitionEnd: function supportsTransitionEnd() {
11470           return Boolean(TRANSITION_END);
11471         },
11472         isElement: function isElement(obj) {
11473           return (obj[0] || obj).nodeType;
11474         },
11475         typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) {
11476           for (var property in configTypes) {
11477             if (Object.prototype.hasOwnProperty.call(configTypes, property)) {
11478               var expectedTypes = configTypes[property];
11479               var value = config[property];
11480               var valueType = value && Util.isElement(value) ? 'element' : toType(value);
11481
11482               if (!new RegExp(expectedTypes).test(valueType)) {
11483                 throw new Error(componentName.toUpperCase() + ": " + ("Option \"" + property + "\" provided type \"" + valueType + "\" ") + ("but expected type \"" + expectedTypes + "\"."));
11484               }
11485             }
11486           }
11487         },
11488         findShadowRoot: function findShadowRoot(element) {
11489           if (!document.documentElement.attachShadow) {
11490             return null;
11491           } // Can find the shadow root otherwise it'll return the document
11492
11493
11494           if (typeof element.getRootNode === 'function') {
11495             var root = element.getRootNode();
11496             return root instanceof ShadowRoot ? root : null;
11497           }
11498
11499           if (element instanceof ShadowRoot) {
11500             return element;
11501           } // when we don't find a shadow root
11502
11503
11504           if (!element.parentNode) {
11505             return null;
11506           }
11507
11508           return Util.findShadowRoot(element.parentNode);
11509         },
11510         jQueryDetection: function jQueryDetection() {
11511           if (typeof $__default['default'] === 'undefined') {
11512             throw new TypeError('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s JavaScript.');
11513           }
11514
11515           var version = $__default['default'].fn.jquery.split(' ')[0].split('.');
11516           var minMajor = 1;
11517           var ltMajor = 2;
11518           var minMinor = 9;
11519           var minPatch = 1;
11520           var maxMajor = 4;
11521
11522           if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && version[2] < minPatch || version[0] >= maxMajor) {
11523             throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0');
11524           }
11525         }
11526       };
11527       Util.jQueryDetection();
11528       setTransitionEndSupport();
11529
11530       /**
11531        * ------------------------------------------------------------------------
11532        * Constants
11533        * ------------------------------------------------------------------------
11534        */
11535
11536       var NAME = 'alert';
11537       var VERSION = '4.6.0';
11538       var DATA_KEY = 'bs.alert';
11539       var EVENT_KEY = "." + DATA_KEY;
11540       var DATA_API_KEY = '.data-api';
11541       var JQUERY_NO_CONFLICT = $__default['default'].fn[NAME];
11542       var SELECTOR_DISMISS = '[data-dismiss="alert"]';
11543       var EVENT_CLOSE = "close" + EVENT_KEY;
11544       var EVENT_CLOSED = "closed" + EVENT_KEY;
11545       var EVENT_CLICK_DATA_API = "click" + EVENT_KEY + DATA_API_KEY;
11546       var CLASS_NAME_ALERT = 'alert';
11547       var CLASS_NAME_FADE = 'fade';
11548       var CLASS_NAME_SHOW = 'show';
11549       /**
11550        * ------------------------------------------------------------------------
11551        * Class Definition
11552        * ------------------------------------------------------------------------
11553        */
11554
11555       var Alert = /*#__PURE__*/function () {
11556         function Alert(element) {
11557           this._element = element;
11558         } // Getters
11559
11560
11561         var _proto = Alert.prototype;
11562
11563         // Public
11564         _proto.close = function close(element) {
11565           var rootElement = this._element;
11566
11567           if (element) {
11568             rootElement = this._getRootElement(element);
11569           }
11570
11571           var customEvent = this._triggerCloseEvent(rootElement);
11572
11573           if (customEvent.isDefaultPrevented()) {
11574             return;
11575           }
11576
11577           this._removeElement(rootElement);
11578         };
11579
11580         _proto.dispose = function dispose() {
11581           $__default['default'].removeData(this._element, DATA_KEY);
11582           this._element = null;
11583         } // Private
11584         ;
11585
11586         _proto._getRootElement = function _getRootElement(element) {
11587           var selector = Util.getSelectorFromElement(element);
11588           var parent = false;
11589
11590           if (selector) {
11591             parent = document.querySelector(selector);
11592           }
11593
11594           if (!parent) {
11595             parent = $__default['default'](element).closest("." + CLASS_NAME_ALERT)[0];
11596           }
11597
11598           return parent;
11599         };
11600
11601         _proto._triggerCloseEvent = function _triggerCloseEvent(element) {
11602           var closeEvent = $__default['default'].Event(EVENT_CLOSE);
11603           $__default['default'](element).trigger(closeEvent);
11604           return closeEvent;
11605         };
11606
11607         _proto._removeElement = function _removeElement(element) {
11608           var _this = this;
11609
11610           $__default['default'](element).removeClass(CLASS_NAME_SHOW);
11611
11612           if (!$__default['default'](element).hasClass(CLASS_NAME_FADE)) {
11613             this._destroyElement(element);
11614
11615             return;
11616           }
11617
11618           var transitionDuration = Util.getTransitionDurationFromElement(element);
11619           $__default['default'](element).one(Util.TRANSITION_END, function (event) {
11620             return _this._destroyElement(element, event);
11621           }).emulateTransitionEnd(transitionDuration);
11622         };
11623
11624         _proto._destroyElement = function _destroyElement(element) {
11625           $__default['default'](element).detach().trigger(EVENT_CLOSED).remove();
11626         } // Static
11627         ;
11628
11629         Alert._jQueryInterface = function _jQueryInterface(config) {
11630           return this.each(function () {
11631             var $element = $__default['default'](this);
11632             var data = $element.data(DATA_KEY);
11633
11634             if (!data) {
11635               data = new Alert(this);
11636               $element.data(DATA_KEY, data);
11637             }
11638
11639             if (config === 'close') {
11640               data[config](this);
11641             }
11642           });
11643         };
11644
11645         Alert._handleDismiss = function _handleDismiss(alertInstance) {
11646           return function (event) {
11647             if (event) {
11648               event.preventDefault();
11649             }
11650
11651             alertInstance.close(this);
11652           };
11653         };
11654
11655         _createClass(Alert, null, [{
11656           key: "VERSION",
11657           get: function get() {
11658             return VERSION;
11659           }
11660         }]);
11661
11662         return Alert;
11663       }();
11664       /**
11665        * ------------------------------------------------------------------------
11666        * Data Api implementation
11667        * ------------------------------------------------------------------------
11668        */
11669
11670
11671       $__default['default'](document).on(EVENT_CLICK_DATA_API, SELECTOR_DISMISS, Alert._handleDismiss(new Alert()));
11672       /**
11673        * ------------------------------------------------------------------------
11674        * jQuery
11675        * ------------------------------------------------------------------------
11676        */
11677
11678       $__default['default'].fn[NAME] = Alert._jQueryInterface;
11679       $__default['default'].fn[NAME].Constructor = Alert;
11680
11681       $__default['default'].fn[NAME].noConflict = function () {
11682         $__default['default'].fn[NAME] = JQUERY_NO_CONFLICT;
11683         return Alert._jQueryInterface;
11684       };
11685
11686       /**
11687        * ------------------------------------------------------------------------
11688        * Constants
11689        * ------------------------------------------------------------------------
11690        */
11691
11692       var NAME$1 = 'button';
11693       var VERSION$1 = '4.6.0';
11694       var DATA_KEY$1 = 'bs.button';
11695       var EVENT_KEY$1 = "." + DATA_KEY$1;
11696       var DATA_API_KEY$1 = '.data-api';
11697       var JQUERY_NO_CONFLICT$1 = $__default['default'].fn[NAME$1];
11698       var CLASS_NAME_ACTIVE = 'active';
11699       var CLASS_NAME_BUTTON = 'btn';
11700       var CLASS_NAME_FOCUS = 'focus';
11701       var SELECTOR_DATA_TOGGLE_CARROT = '[data-toggle^="button"]';
11702       var SELECTOR_DATA_TOGGLES = '[data-toggle="buttons"]';
11703       var SELECTOR_DATA_TOGGLE = '[data-toggle="button"]';
11704       var SELECTOR_DATA_TOGGLES_BUTTONS = '[data-toggle="buttons"] .btn';
11705       var SELECTOR_INPUT = 'input:not([type="hidden"])';
11706       var SELECTOR_ACTIVE = '.active';
11707       var SELECTOR_BUTTON = '.btn';
11708       var EVENT_CLICK_DATA_API$1 = "click" + EVENT_KEY$1 + DATA_API_KEY$1;
11709       var EVENT_FOCUS_BLUR_DATA_API = "focus" + EVENT_KEY$1 + DATA_API_KEY$1 + " " + ("blur" + EVENT_KEY$1 + DATA_API_KEY$1);
11710       var EVENT_LOAD_DATA_API = "load" + EVENT_KEY$1 + DATA_API_KEY$1;
11711       /**
11712        * ------------------------------------------------------------------------
11713        * Class Definition
11714        * ------------------------------------------------------------------------
11715        */
11716
11717       var Button = /*#__PURE__*/function () {
11718         function Button(element) {
11719           this._element = element;
11720           this.shouldAvoidTriggerChange = false;
11721         } // Getters
11722
11723
11724         var _proto = Button.prototype;
11725
11726         // Public
11727         _proto.toggle = function toggle() {
11728           var triggerChangeEvent = true;
11729           var addAriaPressed = true;
11730           var rootElement = $__default['default'](this._element).closest(SELECTOR_DATA_TOGGLES)[0];
11731
11732           if (rootElement) {
11733             var input = this._element.querySelector(SELECTOR_INPUT);
11734
11735             if (input) {
11736               if (input.type === 'radio') {
11737                 if (input.checked && this._element.classList.contains(CLASS_NAME_ACTIVE)) {
11738                   triggerChangeEvent = false;
11739                 } else {
11740                   var activeElement = rootElement.querySelector(SELECTOR_ACTIVE);
11741
11742                   if (activeElement) {
11743                     $__default['default'](activeElement).removeClass(CLASS_NAME_ACTIVE);
11744                   }
11745                 }
11746               }
11747
11748               if (triggerChangeEvent) {
11749                 // if it's not a radio button or checkbox don't add a pointless/invalid checked property to the input
11750                 if (input.type === 'checkbox' || input.type === 'radio') {
11751                   input.checked = !this._element.classList.contains(CLASS_NAME_ACTIVE);
11752                 }
11753
11754                 if (!this.shouldAvoidTriggerChange) {
11755                   $__default['default'](input).trigger('change');
11756                 }
11757               }
11758
11759               input.focus();
11760               addAriaPressed = false;
11761             }
11762           }
11763
11764           if (!(this._element.hasAttribute('disabled') || this._element.classList.contains('disabled'))) {
11765             if (addAriaPressed) {
11766               this._element.setAttribute('aria-pressed', !this._element.classList.contains(CLASS_NAME_ACTIVE));
11767             }
11768
11769             if (triggerChangeEvent) {
11770               $__default['default'](this._element).toggleClass(CLASS_NAME_ACTIVE);
11771             }
11772           }
11773         };
11774
11775         _proto.dispose = function dispose() {
11776           $__default['default'].removeData(this._element, DATA_KEY$1);
11777           this._element = null;
11778         } // Static
11779         ;
11780
11781         Button._jQueryInterface = function _jQueryInterface(config, avoidTriggerChange) {
11782           return this.each(function () {
11783             var $element = $__default['default'](this);
11784             var data = $element.data(DATA_KEY$1);
11785
11786             if (!data) {
11787               data = new Button(this);
11788               $element.data(DATA_KEY$1, data);
11789             }
11790
11791             data.shouldAvoidTriggerChange = avoidTriggerChange;
11792
11793             if (config === 'toggle') {
11794               data[config]();
11795             }
11796           });
11797         };
11798
11799         _createClass(Button, null, [{
11800           key: "VERSION",
11801           get: function get() {
11802             return VERSION$1;
11803           }
11804         }]);
11805
11806         return Button;
11807       }();
11808       /**
11809        * ------------------------------------------------------------------------
11810        * Data Api implementation
11811        * ------------------------------------------------------------------------
11812        */
11813
11814
11815       $__default['default'](document).on(EVENT_CLICK_DATA_API$1, SELECTOR_DATA_TOGGLE_CARROT, function (event) {
11816         var button = event.target;
11817         var initialButton = button;
11818
11819         if (!$__default['default'](button).hasClass(CLASS_NAME_BUTTON)) {
11820           button = $__default['default'](button).closest(SELECTOR_BUTTON)[0];
11821         }
11822
11823         if (!button || button.hasAttribute('disabled') || button.classList.contains('disabled')) {
11824           event.preventDefault(); // work around Firefox bug #1540995
11825         } else {
11826           var inputBtn = button.querySelector(SELECTOR_INPUT);
11827
11828           if (inputBtn && (inputBtn.hasAttribute('disabled') || inputBtn.classList.contains('disabled'))) {
11829             event.preventDefault(); // work around Firefox bug #1540995
11830
11831             return;
11832           }
11833
11834           if (initialButton.tagName === 'INPUT' || button.tagName !== 'LABEL') {
11835             Button._jQueryInterface.call($__default['default'](button), 'toggle', initialButton.tagName === 'INPUT');
11836           }
11837         }
11838       }).on(EVENT_FOCUS_BLUR_DATA_API, SELECTOR_DATA_TOGGLE_CARROT, function (event) {
11839         var button = $__default['default'](event.target).closest(SELECTOR_BUTTON)[0];
11840         $__default['default'](button).toggleClass(CLASS_NAME_FOCUS, /^focus(in)?$/.test(event.type));
11841       });
11842       $__default['default'](window).on(EVENT_LOAD_DATA_API, function () {
11843         // ensure correct active class is set to match the controls' actual values/states
11844         // find all checkboxes/readio buttons inside data-toggle groups
11845         var buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLES_BUTTONS));
11846
11847         for (var i = 0, len = buttons.length; i < len; i++) {
11848           var button = buttons[i];
11849           var input = button.querySelector(SELECTOR_INPUT);
11850
11851           if (input.checked || input.hasAttribute('checked')) {
11852             button.classList.add(CLASS_NAME_ACTIVE);
11853           } else {
11854             button.classList.remove(CLASS_NAME_ACTIVE);
11855           }
11856         } // find all button toggles
11857
11858
11859         buttons = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE));
11860
11861         for (var _i = 0, _len = buttons.length; _i < _len; _i++) {
11862           var _button = buttons[_i];
11863
11864           if (_button.getAttribute('aria-pressed') === 'true') {
11865             _button.classList.add(CLASS_NAME_ACTIVE);
11866           } else {
11867             _button.classList.remove(CLASS_NAME_ACTIVE);
11868           }
11869         }
11870       });
11871       /**
11872        * ------------------------------------------------------------------------
11873        * jQuery
11874        * ------------------------------------------------------------------------
11875        */
11876
11877       $__default['default'].fn[NAME$1] = Button._jQueryInterface;
11878       $__default['default'].fn[NAME$1].Constructor = Button;
11879
11880       $__default['default'].fn[NAME$1].noConflict = function () {
11881         $__default['default'].fn[NAME$1] = JQUERY_NO_CONFLICT$1;
11882         return Button._jQueryInterface;
11883       };
11884
11885       /**
11886        * ------------------------------------------------------------------------
11887        * Constants
11888        * ------------------------------------------------------------------------
11889        */
11890
11891       var NAME$2 = 'carousel';
11892       var VERSION$2 = '4.6.0';
11893       var DATA_KEY$2 = 'bs.carousel';
11894       var EVENT_KEY$2 = "." + DATA_KEY$2;
11895       var DATA_API_KEY$2 = '.data-api';
11896       var JQUERY_NO_CONFLICT$2 = $__default['default'].fn[NAME$2];
11897       var ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key
11898
11899       var ARROW_RIGHT_KEYCODE = 39; // KeyboardEvent.which value for right arrow key
11900
11901       var TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch
11902
11903       var SWIPE_THRESHOLD = 40;
11904       var Default = {
11905         interval: 5000,
11906         keyboard: true,
11907         slide: false,
11908         pause: 'hover',
11909         wrap: true,
11910         touch: true
11911       };
11912       var DefaultType = {
11913         interval: '(number|boolean)',
11914         keyboard: 'boolean',
11915         slide: '(boolean|string)',
11916         pause: '(string|boolean)',
11917         wrap: 'boolean',
11918         touch: 'boolean'
11919       };
11920       var DIRECTION_NEXT = 'next';
11921       var DIRECTION_PREV = 'prev';
11922       var DIRECTION_LEFT = 'left';
11923       var DIRECTION_RIGHT = 'right';
11924       var EVENT_SLIDE = "slide" + EVENT_KEY$2;
11925       var EVENT_SLID = "slid" + EVENT_KEY$2;
11926       var EVENT_KEYDOWN = "keydown" + EVENT_KEY$2;
11927       var EVENT_MOUSEENTER = "mouseenter" + EVENT_KEY$2;
11928       var EVENT_MOUSELEAVE = "mouseleave" + EVENT_KEY$2;
11929       var EVENT_TOUCHSTART = "touchstart" + EVENT_KEY$2;
11930       var EVENT_TOUCHMOVE = "touchmove" + EVENT_KEY$2;
11931       var EVENT_TOUCHEND = "touchend" + EVENT_KEY$2;
11932       var EVENT_POINTERDOWN = "pointerdown" + EVENT_KEY$2;
11933       var EVENT_POINTERUP = "pointerup" + EVENT_KEY$2;
11934       var EVENT_DRAG_START = "dragstart" + EVENT_KEY$2;
11935       var EVENT_LOAD_DATA_API$1 = "load" + EVENT_KEY$2 + DATA_API_KEY$2;
11936       var EVENT_CLICK_DATA_API$2 = "click" + EVENT_KEY$2 + DATA_API_KEY$2;
11937       var CLASS_NAME_CAROUSEL = 'carousel';
11938       var CLASS_NAME_ACTIVE$1 = 'active';
11939       var CLASS_NAME_SLIDE = 'slide';
11940       var CLASS_NAME_RIGHT = 'carousel-item-right';
11941       var CLASS_NAME_LEFT = 'carousel-item-left';
11942       var CLASS_NAME_NEXT = 'carousel-item-next';
11943       var CLASS_NAME_PREV = 'carousel-item-prev';
11944       var CLASS_NAME_POINTER_EVENT = 'pointer-event';
11945       var SELECTOR_ACTIVE$1 = '.active';
11946       var SELECTOR_ACTIVE_ITEM = '.active.carousel-item';
11947       var SELECTOR_ITEM = '.carousel-item';
11948       var SELECTOR_ITEM_IMG = '.carousel-item img';
11949       var SELECTOR_NEXT_PREV = '.carousel-item-next, .carousel-item-prev';
11950       var SELECTOR_INDICATORS = '.carousel-indicators';
11951       var SELECTOR_DATA_SLIDE = '[data-slide], [data-slide-to]';
11952       var SELECTOR_DATA_RIDE = '[data-ride="carousel"]';
11953       var PointerType = {
11954         TOUCH: 'touch',
11955         PEN: 'pen'
11956       };
11957       /**
11958        * ------------------------------------------------------------------------
11959        * Class Definition
11960        * ------------------------------------------------------------------------
11961        */
11962
11963       var Carousel = /*#__PURE__*/function () {
11964         function Carousel(element, config) {
11965           this._items = null;
11966           this._interval = null;
11967           this._activeElement = null;
11968           this._isPaused = false;
11969           this._isSliding = false;
11970           this.touchTimeout = null;
11971           this.touchStartX = 0;
11972           this.touchDeltaX = 0;
11973           this._config = this._getConfig(config);
11974           this._element = element;
11975           this._indicatorsElement = this._element.querySelector(SELECTOR_INDICATORS);
11976           this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0;
11977           this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent);
11978
11979           this._addEventListeners();
11980         } // Getters
11981
11982
11983         var _proto = Carousel.prototype;
11984
11985         // Public
11986         _proto.next = function next() {
11987           if (!this._isSliding) {
11988             this._slide(DIRECTION_NEXT);
11989           }
11990         };
11991
11992         _proto.nextWhenVisible = function nextWhenVisible() {
11993           var $element = $__default['default'](this._element); // Don't call next when the page isn't visible
11994           // or the carousel or its parent isn't visible
11995
11996           if (!document.hidden && $element.is(':visible') && $element.css('visibility') !== 'hidden') {
11997             this.next();
11998           }
11999         };
12000
12001         _proto.prev = function prev() {
12002           if (!this._isSliding) {
12003             this._slide(DIRECTION_PREV);
12004           }
12005         };
12006
12007         _proto.pause = function pause(event) {
12008           if (!event) {
12009             this._isPaused = true;
12010           }
12011
12012           if (this._element.querySelector(SELECTOR_NEXT_PREV)) {
12013             Util.triggerTransitionEnd(this._element);
12014             this.cycle(true);
12015           }
12016
12017           clearInterval(this._interval);
12018           this._interval = null;
12019         };
12020
12021         _proto.cycle = function cycle(event) {
12022           if (!event) {
12023             this._isPaused = false;
12024           }
12025
12026           if (this._interval) {
12027             clearInterval(this._interval);
12028             this._interval = null;
12029           }
12030
12031           if (this._config.interval && !this._isPaused) {
12032             this._updateInterval();
12033
12034             this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : this.next).bind(this), this._config.interval);
12035           }
12036         };
12037
12038         _proto.to = function to(index) {
12039           var _this = this;
12040
12041           this._activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM);
12042
12043           var activeIndex = this._getItemIndex(this._activeElement);
12044
12045           if (index > this._items.length - 1 || index < 0) {
12046             return;
12047           }
12048
12049           if (this._isSliding) {
12050             $__default['default'](this._element).one(EVENT_SLID, function () {
12051               return _this.to(index);
12052             });
12053             return;
12054           }
12055
12056           if (activeIndex === index) {
12057             this.pause();
12058             this.cycle();
12059             return;
12060           }
12061
12062           var direction = index > activeIndex ? DIRECTION_NEXT : DIRECTION_PREV;
12063
12064           this._slide(direction, this._items[index]);
12065         };
12066
12067         _proto.dispose = function dispose() {
12068           $__default['default'](this._element).off(EVENT_KEY$2);
12069           $__default['default'].removeData(this._element, DATA_KEY$2);
12070           this._items = null;
12071           this._config = null;
12072           this._element = null;
12073           this._interval = null;
12074           this._isPaused = null;
12075           this._isSliding = null;
12076           this._activeElement = null;
12077           this._indicatorsElement = null;
12078         } // Private
12079         ;
12080
12081         _proto._getConfig = function _getConfig(config) {
12082           config = _extends({}, Default, config);
12083           Util.typeCheckConfig(NAME$2, config, DefaultType);
12084           return config;
12085         };
12086
12087         _proto._handleSwipe = function _handleSwipe() {
12088           var absDeltax = Math.abs(this.touchDeltaX);
12089
12090           if (absDeltax <= SWIPE_THRESHOLD) {
12091             return;
12092           }
12093
12094           var direction = absDeltax / this.touchDeltaX;
12095           this.touchDeltaX = 0; // swipe left
12096
12097           if (direction > 0) {
12098             this.prev();
12099           } // swipe right
12100
12101
12102           if (direction < 0) {
12103             this.next();
12104           }
12105         };
12106
12107         _proto._addEventListeners = function _addEventListeners() {
12108           var _this2 = this;
12109
12110           if (this._config.keyboard) {
12111             $__default['default'](this._element).on(EVENT_KEYDOWN, function (event) {
12112               return _this2._keydown(event);
12113             });
12114           }
12115
12116           if (this._config.pause === 'hover') {
12117             $__default['default'](this._element).on(EVENT_MOUSEENTER, function (event) {
12118               return _this2.pause(event);
12119             }).on(EVENT_MOUSELEAVE, function (event) {
12120               return _this2.cycle(event);
12121             });
12122           }
12123
12124           if (this._config.touch) {
12125             this._addTouchEventListeners();
12126           }
12127         };
12128
12129         _proto._addTouchEventListeners = function _addTouchEventListeners() {
12130           var _this3 = this;
12131
12132           if (!this._touchSupported) {
12133             return;
12134           }
12135
12136           var start = function start(event) {
12137             if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {
12138               _this3.touchStartX = event.originalEvent.clientX;
12139             } else if (!_this3._pointerEvent) {
12140               _this3.touchStartX = event.originalEvent.touches[0].clientX;
12141             }
12142           };
12143
12144           var move = function move(event) {
12145             // ensure swiping with one touch and not pinching
12146             if (event.originalEvent.touches && event.originalEvent.touches.length > 1) {
12147               _this3.touchDeltaX = 0;
12148             } else {
12149               _this3.touchDeltaX = event.originalEvent.touches[0].clientX - _this3.touchStartX;
12150             }
12151           };
12152
12153           var end = function end(event) {
12154             if (_this3._pointerEvent && PointerType[event.originalEvent.pointerType.toUpperCase()]) {
12155               _this3.touchDeltaX = event.originalEvent.clientX - _this3.touchStartX;
12156             }
12157
12158             _this3._handleSwipe();
12159
12160             if (_this3._config.pause === 'hover') {
12161               // If it's a touch-enabled device, mouseenter/leave are fired as
12162               // part of the mouse compatibility events on first tap - the carousel
12163               // would stop cycling until user tapped out of it;
12164               // here, we listen for touchend, explicitly pause the carousel
12165               // (as if it's the second time we tap on it, mouseenter compat event
12166               // is NOT fired) and after a timeout (to allow for mouse compatibility
12167               // events to fire) we explicitly restart cycling
12168               _this3.pause();
12169
12170               if (_this3.touchTimeout) {
12171                 clearTimeout(_this3.touchTimeout);
12172               }
12173
12174               _this3.touchTimeout = setTimeout(function (event) {
12175                 return _this3.cycle(event);
12176               }, TOUCHEVENT_COMPAT_WAIT + _this3._config.interval);
12177             }
12178           };
12179
12180           $__default['default'](this._element.querySelectorAll(SELECTOR_ITEM_IMG)).on(EVENT_DRAG_START, function (e) {
12181             return e.preventDefault();
12182           });
12183
12184           if (this._pointerEvent) {
12185             $__default['default'](this._element).on(EVENT_POINTERDOWN, function (event) {
12186               return start(event);
12187             });
12188             $__default['default'](this._element).on(EVENT_POINTERUP, function (event) {
12189               return end(event);
12190             });
12191
12192             this._element.classList.add(CLASS_NAME_POINTER_EVENT);
12193           } else {
12194             $__default['default'](this._element).on(EVENT_TOUCHSTART, function (event) {
12195               return start(event);
12196             });
12197             $__default['default'](this._element).on(EVENT_TOUCHMOVE, function (event) {
12198               return move(event);
12199             });
12200             $__default['default'](this._element).on(EVENT_TOUCHEND, function (event) {
12201               return end(event);
12202             });
12203           }
12204         };
12205
12206         _proto._keydown = function _keydown(event) {
12207           if (/input|textarea/i.test(event.target.tagName)) {
12208             return;
12209           }
12210
12211           switch (event.which) {
12212             case ARROW_LEFT_KEYCODE:
12213               event.preventDefault();
12214               this.prev();
12215               break;
12216
12217             case ARROW_RIGHT_KEYCODE:
12218               event.preventDefault();
12219               this.next();
12220               break;
12221           }
12222         };
12223
12224         _proto._getItemIndex = function _getItemIndex(element) {
12225           this._items = element && element.parentNode ? [].slice.call(element.parentNode.querySelectorAll(SELECTOR_ITEM)) : [];
12226           return this._items.indexOf(element);
12227         };
12228
12229         _proto._getItemByDirection = function _getItemByDirection(direction, activeElement) {
12230           var isNextDirection = direction === DIRECTION_NEXT;
12231           var isPrevDirection = direction === DIRECTION_PREV;
12232
12233           var activeIndex = this._getItemIndex(activeElement);
12234
12235           var lastItemIndex = this._items.length - 1;
12236           var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === lastItemIndex;
12237
12238           if (isGoingToWrap && !this._config.wrap) {
12239             return activeElement;
12240           }
12241
12242           var delta = direction === DIRECTION_PREV ? -1 : 1;
12243           var itemIndex = (activeIndex + delta) % this._items.length;
12244           return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex];
12245         };
12246
12247         _proto._triggerSlideEvent = function _triggerSlideEvent(relatedTarget, eventDirectionName) {
12248           var targetIndex = this._getItemIndex(relatedTarget);
12249
12250           var fromIndex = this._getItemIndex(this._element.querySelector(SELECTOR_ACTIVE_ITEM));
12251
12252           var slideEvent = $__default['default'].Event(EVENT_SLIDE, {
12253             relatedTarget: relatedTarget,
12254             direction: eventDirectionName,
12255             from: fromIndex,
12256             to: targetIndex
12257           });
12258           $__default['default'](this._element).trigger(slideEvent);
12259           return slideEvent;
12260         };
12261
12262         _proto._setActiveIndicatorElement = function _setActiveIndicatorElement(element) {
12263           if (this._indicatorsElement) {
12264             var indicators = [].slice.call(this._indicatorsElement.querySelectorAll(SELECTOR_ACTIVE$1));
12265             $__default['default'](indicators).removeClass(CLASS_NAME_ACTIVE$1);
12266
12267             var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)];
12268
12269             if (nextIndicator) {
12270               $__default['default'](nextIndicator).addClass(CLASS_NAME_ACTIVE$1);
12271             }
12272           }
12273         };
12274
12275         _proto._updateInterval = function _updateInterval() {
12276           var element = this._activeElement || this._element.querySelector(SELECTOR_ACTIVE_ITEM);
12277
12278           if (!element) {
12279             return;
12280           }
12281
12282           var elementInterval = parseInt(element.getAttribute('data-interval'), 10);
12283
12284           if (elementInterval) {
12285             this._config.defaultInterval = this._config.defaultInterval || this._config.interval;
12286             this._config.interval = elementInterval;
12287           } else {
12288             this._config.interval = this._config.defaultInterval || this._config.interval;
12289           }
12290         };
12291
12292         _proto._slide = function _slide(direction, element) {
12293           var _this4 = this;
12294
12295           var activeElement = this._element.querySelector(SELECTOR_ACTIVE_ITEM);
12296
12297           var activeElementIndex = this._getItemIndex(activeElement);
12298
12299           var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement);
12300
12301           var nextElementIndex = this._getItemIndex(nextElement);
12302
12303           var isCycling = Boolean(this._interval);
12304           var directionalClassName;
12305           var orderClassName;
12306           var eventDirectionName;
12307
12308           if (direction === DIRECTION_NEXT) {
12309             directionalClassName = CLASS_NAME_LEFT;
12310             orderClassName = CLASS_NAME_NEXT;
12311             eventDirectionName = DIRECTION_LEFT;
12312           } else {
12313             directionalClassName = CLASS_NAME_RIGHT;
12314             orderClassName = CLASS_NAME_PREV;
12315             eventDirectionName = DIRECTION_RIGHT;
12316           }
12317
12318           if (nextElement && $__default['default'](nextElement).hasClass(CLASS_NAME_ACTIVE$1)) {
12319             this._isSliding = false;
12320             return;
12321           }
12322
12323           var slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);
12324
12325           if (slideEvent.isDefaultPrevented()) {
12326             return;
12327           }
12328
12329           if (!activeElement || !nextElement) {
12330             // Some weirdness is happening, so we bail
12331             return;
12332           }
12333
12334           this._isSliding = true;
12335
12336           if (isCycling) {
12337             this.pause();
12338           }
12339
12340           this._setActiveIndicatorElement(nextElement);
12341
12342           this._activeElement = nextElement;
12343           var slidEvent = $__default['default'].Event(EVENT_SLID, {
12344             relatedTarget: nextElement,
12345             direction: eventDirectionName,
12346             from: activeElementIndex,
12347             to: nextElementIndex
12348           });
12349
12350           if ($__default['default'](this._element).hasClass(CLASS_NAME_SLIDE)) {
12351             $__default['default'](nextElement).addClass(orderClassName);
12352             Util.reflow(nextElement);
12353             $__default['default'](activeElement).addClass(directionalClassName);
12354             $__default['default'](nextElement).addClass(directionalClassName);
12355             var transitionDuration = Util.getTransitionDurationFromElement(activeElement);
12356             $__default['default'](activeElement).one(Util.TRANSITION_END, function () {
12357               $__default['default'](nextElement).removeClass(directionalClassName + " " + orderClassName).addClass(CLASS_NAME_ACTIVE$1);
12358               $__default['default'](activeElement).removeClass(CLASS_NAME_ACTIVE$1 + " " + orderClassName + " " + directionalClassName);
12359               _this4._isSliding = false;
12360               setTimeout(function () {
12361                 return $__default['default'](_this4._element).trigger(slidEvent);
12362               }, 0);
12363             }).emulateTransitionEnd(transitionDuration);
12364           } else {
12365             $__default['default'](activeElement).removeClass(CLASS_NAME_ACTIVE$1);
12366             $__default['default'](nextElement).addClass(CLASS_NAME_ACTIVE$1);
12367             this._isSliding = false;
12368             $__default['default'](this._element).trigger(slidEvent);
12369           }
12370
12371           if (isCycling) {
12372             this.cycle();
12373           }
12374         } // Static
12375         ;
12376
12377         Carousel._jQueryInterface = function _jQueryInterface(config) {
12378           return this.each(function () {
12379             var data = $__default['default'](this).data(DATA_KEY$2);
12380
12381             var _config = _extends({}, Default, $__default['default'](this).data());
12382
12383             if (typeof config === 'object') {
12384               _config = _extends({}, _config, config);
12385             }
12386
12387             var action = typeof config === 'string' ? config : _config.slide;
12388
12389             if (!data) {
12390               data = new Carousel(this, _config);
12391               $__default['default'](this).data(DATA_KEY$2, data);
12392             }
12393
12394             if (typeof config === 'number') {
12395               data.to(config);
12396             } else if (typeof action === 'string') {
12397               if (typeof data[action] === 'undefined') {
12398                 throw new TypeError("No method named \"" + action + "\"");
12399               }
12400
12401               data[action]();
12402             } else if (_config.interval && _config.ride) {
12403               data.pause();
12404               data.cycle();
12405             }
12406           });
12407         };
12408
12409         Carousel._dataApiClickHandler = function _dataApiClickHandler(event) {
12410           var selector = Util.getSelectorFromElement(this);
12411
12412           if (!selector) {
12413             return;
12414           }
12415
12416           var target = $__default['default'](selector)[0];
12417
12418           if (!target || !$__default['default'](target).hasClass(CLASS_NAME_CAROUSEL)) {
12419             return;
12420           }
12421
12422           var config = _extends({}, $__default['default'](target).data(), $__default['default'](this).data());
12423
12424           var slideIndex = this.getAttribute('data-slide-to');
12425
12426           if (slideIndex) {
12427             config.interval = false;
12428           }
12429
12430           Carousel._jQueryInterface.call($__default['default'](target), config);
12431
12432           if (slideIndex) {
12433             $__default['default'](target).data(DATA_KEY$2).to(slideIndex);
12434           }
12435
12436           event.preventDefault();
12437         };
12438
12439         _createClass(Carousel, null, [{
12440           key: "VERSION",
12441           get: function get() {
12442             return VERSION$2;
12443           }
12444         }, {
12445           key: "Default",
12446           get: function get() {
12447             return Default;
12448           }
12449         }]);
12450
12451         return Carousel;
12452       }();
12453       /**
12454        * ------------------------------------------------------------------------
12455        * Data Api implementation
12456        * ------------------------------------------------------------------------
12457        */
12458
12459
12460       $__default['default'](document).on(EVENT_CLICK_DATA_API$2, SELECTOR_DATA_SLIDE, Carousel._dataApiClickHandler);
12461       $__default['default'](window).on(EVENT_LOAD_DATA_API$1, function () {
12462         var carousels = [].slice.call(document.querySelectorAll(SELECTOR_DATA_RIDE));
12463
12464         for (var i = 0, len = carousels.length; i < len; i++) {
12465           var $carousel = $__default['default'](carousels[i]);
12466
12467           Carousel._jQueryInterface.call($carousel, $carousel.data());
12468         }
12469       });
12470       /**
12471        * ------------------------------------------------------------------------
12472        * jQuery
12473        * ------------------------------------------------------------------------
12474        */
12475
12476       $__default['default'].fn[NAME$2] = Carousel._jQueryInterface;
12477       $__default['default'].fn[NAME$2].Constructor = Carousel;
12478
12479       $__default['default'].fn[NAME$2].noConflict = function () {
12480         $__default['default'].fn[NAME$2] = JQUERY_NO_CONFLICT$2;
12481         return Carousel._jQueryInterface;
12482       };
12483
12484       /**
12485        * ------------------------------------------------------------------------
12486        * Constants
12487        * ------------------------------------------------------------------------
12488        */
12489
12490       var NAME$3 = 'collapse';
12491       var VERSION$3 = '4.6.0';
12492       var DATA_KEY$3 = 'bs.collapse';
12493       var EVENT_KEY$3 = "." + DATA_KEY$3;
12494       var DATA_API_KEY$3 = '.data-api';
12495       var JQUERY_NO_CONFLICT$3 = $__default['default'].fn[NAME$3];
12496       var Default$1 = {
12497         toggle: true,
12498         parent: ''
12499       };
12500       var DefaultType$1 = {
12501         toggle: 'boolean',
12502         parent: '(string|element)'
12503       };
12504       var EVENT_SHOW = "show" + EVENT_KEY$3;
12505       var EVENT_SHOWN = "shown" + EVENT_KEY$3;
12506       var EVENT_HIDE = "hide" + EVENT_KEY$3;
12507       var EVENT_HIDDEN = "hidden" + EVENT_KEY$3;
12508       var EVENT_CLICK_DATA_API$3 = "click" + EVENT_KEY$3 + DATA_API_KEY$3;
12509       var CLASS_NAME_SHOW$1 = 'show';
12510       var CLASS_NAME_COLLAPSE = 'collapse';
12511       var CLASS_NAME_COLLAPSING = 'collapsing';
12512       var CLASS_NAME_COLLAPSED = 'collapsed';
12513       var DIMENSION_WIDTH = 'width';
12514       var DIMENSION_HEIGHT = 'height';
12515       var SELECTOR_ACTIVES = '.show, .collapsing';
12516       var SELECTOR_DATA_TOGGLE$1 = '[data-toggle="collapse"]';
12517       /**
12518        * ------------------------------------------------------------------------
12519        * Class Definition
12520        * ------------------------------------------------------------------------
12521        */
12522
12523       var Collapse = /*#__PURE__*/function () {
12524         function Collapse(element, config) {
12525           this._isTransitioning = false;
12526           this._element = element;
12527           this._config = this._getConfig(config);
12528           this._triggerArray = [].slice.call(document.querySelectorAll("[data-toggle=\"collapse\"][href=\"#" + element.id + "\"]," + ("[data-toggle=\"collapse\"][data-target=\"#" + element.id + "\"]")));
12529           var toggleList = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE$1));
12530
12531           for (var i = 0, len = toggleList.length; i < len; i++) {
12532             var elem = toggleList[i];
12533             var selector = Util.getSelectorFromElement(elem);
12534             var filterElement = [].slice.call(document.querySelectorAll(selector)).filter(function (foundElem) {
12535               return foundElem === element;
12536             });
12537
12538             if (selector !== null && filterElement.length > 0) {
12539               this._selector = selector;
12540
12541               this._triggerArray.push(elem);
12542             }
12543           }
12544
12545           this._parent = this._config.parent ? this._getParent() : null;
12546
12547           if (!this._config.parent) {
12548             this._addAriaAndCollapsedClass(this._element, this._triggerArray);
12549           }
12550
12551           if (this._config.toggle) {
12552             this.toggle();
12553           }
12554         } // Getters
12555
12556
12557         var _proto = Collapse.prototype;
12558
12559         // Public
12560         _proto.toggle = function toggle() {
12561           if ($__default['default'](this._element).hasClass(CLASS_NAME_SHOW$1)) {
12562             this.hide();
12563           } else {
12564             this.show();
12565           }
12566         };
12567
12568         _proto.show = function show() {
12569           var _this = this;
12570
12571           if (this._isTransitioning || $__default['default'](this._element).hasClass(CLASS_NAME_SHOW$1)) {
12572             return;
12573           }
12574
12575           var actives;
12576           var activesData;
12577
12578           if (this._parent) {
12579             actives = [].slice.call(this._parent.querySelectorAll(SELECTOR_ACTIVES)).filter(function (elem) {
12580               if (typeof _this._config.parent === 'string') {
12581                 return elem.getAttribute('data-parent') === _this._config.parent;
12582               }
12583
12584               return elem.classList.contains(CLASS_NAME_COLLAPSE);
12585             });
12586
12587             if (actives.length === 0) {
12588               actives = null;
12589             }
12590           }
12591
12592           if (actives) {
12593             activesData = $__default['default'](actives).not(this._selector).data(DATA_KEY$3);
12594
12595             if (activesData && activesData._isTransitioning) {
12596               return;
12597             }
12598           }
12599
12600           var startEvent = $__default['default'].Event(EVENT_SHOW);
12601           $__default['default'](this._element).trigger(startEvent);
12602
12603           if (startEvent.isDefaultPrevented()) {
12604             return;
12605           }
12606
12607           if (actives) {
12608             Collapse._jQueryInterface.call($__default['default'](actives).not(this._selector), 'hide');
12609
12610             if (!activesData) {
12611               $__default['default'](actives).data(DATA_KEY$3, null);
12612             }
12613           }
12614
12615           var dimension = this._getDimension();
12616
12617           $__default['default'](this._element).removeClass(CLASS_NAME_COLLAPSE).addClass(CLASS_NAME_COLLAPSING);
12618           this._element.style[dimension] = 0;
12619
12620           if (this._triggerArray.length) {
12621             $__default['default'](this._triggerArray).removeClass(CLASS_NAME_COLLAPSED).attr('aria-expanded', true);
12622           }
12623
12624           this.setTransitioning(true);
12625
12626           var complete = function complete() {
12627             $__default['default'](_this._element).removeClass(CLASS_NAME_COLLAPSING).addClass(CLASS_NAME_COLLAPSE + " " + CLASS_NAME_SHOW$1);
12628             _this._element.style[dimension] = '';
12629
12630             _this.setTransitioning(false);
12631
12632             $__default['default'](_this._element).trigger(EVENT_SHOWN);
12633           };
12634
12635           var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
12636           var scrollSize = "scroll" + capitalizedDimension;
12637           var transitionDuration = Util.getTransitionDurationFromElement(this._element);
12638           $__default['default'](this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
12639           this._element.style[dimension] = this._element[scrollSize] + "px";
12640         };
12641
12642         _proto.hide = function hide() {
12643           var _this2 = this;
12644
12645           if (this._isTransitioning || !$__default['default'](this._element).hasClass(CLASS_NAME_SHOW$1)) {
12646             return;
12647           }
12648
12649           var startEvent = $__default['default'].Event(EVENT_HIDE);
12650           $__default['default'](this._element).trigger(startEvent);
12651
12652           if (startEvent.isDefaultPrevented()) {
12653             return;
12654           }
12655
12656           var dimension = this._getDimension();
12657
12658           this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + "px";
12659           Util.reflow(this._element);
12660           $__default['default'](this._element).addClass(CLASS_NAME_COLLAPSING).removeClass(CLASS_NAME_COLLAPSE + " " + CLASS_NAME_SHOW$1);
12661           var triggerArrayLength = this._triggerArray.length;
12662
12663           if (triggerArrayLength > 0) {
12664             for (var i = 0; i < triggerArrayLength; i++) {
12665               var trigger = this._triggerArray[i];
12666               var selector = Util.getSelectorFromElement(trigger);
12667
12668               if (selector !== null) {
12669                 var $elem = $__default['default']([].slice.call(document.querySelectorAll(selector)));
12670
12671                 if (!$elem.hasClass(CLASS_NAME_SHOW$1)) {
12672                   $__default['default'](trigger).addClass(CLASS_NAME_COLLAPSED).attr('aria-expanded', false);
12673                 }
12674               }
12675             }
12676           }
12677
12678           this.setTransitioning(true);
12679
12680           var complete = function complete() {
12681             _this2.setTransitioning(false);
12682
12683             $__default['default'](_this2._element).removeClass(CLASS_NAME_COLLAPSING).addClass(CLASS_NAME_COLLAPSE).trigger(EVENT_HIDDEN);
12684           };
12685
12686           this._element.style[dimension] = '';
12687           var transitionDuration = Util.getTransitionDurationFromElement(this._element);
12688           $__default['default'](this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
12689         };
12690
12691         _proto.setTransitioning = function setTransitioning(isTransitioning) {
12692           this._isTransitioning = isTransitioning;
12693         };
12694
12695         _proto.dispose = function dispose() {
12696           $__default['default'].removeData(this._element, DATA_KEY$3);
12697           this._config = null;
12698           this._parent = null;
12699           this._element = null;
12700           this._triggerArray = null;
12701           this._isTransitioning = null;
12702         } // Private
12703         ;
12704
12705         _proto._getConfig = function _getConfig(config) {
12706           config = _extends({}, Default$1, config);
12707           config.toggle = Boolean(config.toggle); // Coerce string values
12708
12709           Util.typeCheckConfig(NAME$3, config, DefaultType$1);
12710           return config;
12711         };
12712
12713         _proto._getDimension = function _getDimension() {
12714           var hasWidth = $__default['default'](this._element).hasClass(DIMENSION_WIDTH);
12715           return hasWidth ? DIMENSION_WIDTH : DIMENSION_HEIGHT;
12716         };
12717
12718         _proto._getParent = function _getParent() {
12719           var _this3 = this;
12720
12721           var parent;
12722
12723           if (Util.isElement(this._config.parent)) {
12724             parent = this._config.parent; // It's a jQuery object
12725
12726             if (typeof this._config.parent.jquery !== 'undefined') {
12727               parent = this._config.parent[0];
12728             }
12729           } else {
12730             parent = document.querySelector(this._config.parent);
12731           }
12732
12733           var selector = "[data-toggle=\"collapse\"][data-parent=\"" + this._config.parent + "\"]";
12734           var children = [].slice.call(parent.querySelectorAll(selector));
12735           $__default['default'](children).each(function (i, element) {
12736             _this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]);
12737           });
12738           return parent;
12739         };
12740
12741         _proto._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) {
12742           var isOpen = $__default['default'](element).hasClass(CLASS_NAME_SHOW$1);
12743
12744           if (triggerArray.length) {
12745             $__default['default'](triggerArray).toggleClass(CLASS_NAME_COLLAPSED, !isOpen).attr('aria-expanded', isOpen);
12746           }
12747         } // Static
12748         ;
12749
12750         Collapse._getTargetFromElement = function _getTargetFromElement(element) {
12751           var selector = Util.getSelectorFromElement(element);
12752           return selector ? document.querySelector(selector) : null;
12753         };
12754
12755         Collapse._jQueryInterface = function _jQueryInterface(config) {
12756           return this.each(function () {
12757             var $element = $__default['default'](this);
12758             var data = $element.data(DATA_KEY$3);
12759
12760             var _config = _extends({}, Default$1, $element.data(), typeof config === 'object' && config ? config : {});
12761
12762             if (!data && _config.toggle && typeof config === 'string' && /show|hide/.test(config)) {
12763               _config.toggle = false;
12764             }
12765
12766             if (!data) {
12767               data = new Collapse(this, _config);
12768               $element.data(DATA_KEY$3, data);
12769             }
12770
12771             if (typeof config === 'string') {
12772               if (typeof data[config] === 'undefined') {
12773                 throw new TypeError("No method named \"" + config + "\"");
12774               }
12775
12776               data[config]();
12777             }
12778           });
12779         };
12780
12781         _createClass(Collapse, null, [{
12782           key: "VERSION",
12783           get: function get() {
12784             return VERSION$3;
12785           }
12786         }, {
12787           key: "Default",
12788           get: function get() {
12789             return Default$1;
12790           }
12791         }]);
12792
12793         return Collapse;
12794       }();
12795       /**
12796        * ------------------------------------------------------------------------
12797        * Data Api implementation
12798        * ------------------------------------------------------------------------
12799        */
12800
12801
12802       $__default['default'](document).on(EVENT_CLICK_DATA_API$3, SELECTOR_DATA_TOGGLE$1, function (event) {
12803         // preventDefault only for <a> elements (which change the URL) not inside the collapsible element
12804         if (event.currentTarget.tagName === 'A') {
12805           event.preventDefault();
12806         }
12807
12808         var $trigger = $__default['default'](this);
12809         var selector = Util.getSelectorFromElement(this);
12810         var selectors = [].slice.call(document.querySelectorAll(selector));
12811         $__default['default'](selectors).each(function () {
12812           var $target = $__default['default'](this);
12813           var data = $target.data(DATA_KEY$3);
12814           var config = data ? 'toggle' : $trigger.data();
12815
12816           Collapse._jQueryInterface.call($target, config);
12817         });
12818       });
12819       /**
12820        * ------------------------------------------------------------------------
12821        * jQuery
12822        * ------------------------------------------------------------------------
12823        */
12824
12825       $__default['default'].fn[NAME$3] = Collapse._jQueryInterface;
12826       $__default['default'].fn[NAME$3].Constructor = Collapse;
12827
12828       $__default['default'].fn[NAME$3].noConflict = function () {
12829         $__default['default'].fn[NAME$3] = JQUERY_NO_CONFLICT$3;
12830         return Collapse._jQueryInterface;
12831       };
12832
12833       /**!
12834        * @fileOverview Kickass library to create and place poppers near their reference elements.
12835        * @version 1.16.1
12836        * @license
12837        * Copyright (c) 2016 Federico Zivolo and contributors
12838        *
12839        * Permission is hereby granted, free of charge, to any person obtaining a copy
12840        * of this software and associated documentation files (the "Software"), to deal
12841        * in the Software without restriction, including without limitation the rights
12842        * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12843        * copies of the Software, and to permit persons to whom the Software is
12844        * furnished to do so, subject to the following conditions:
12845        *
12846        * The above copyright notice and this permission notice shall be included in all
12847        * copies or substantial portions of the Software.
12848        *
12849        * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12850        * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12851        * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
12852        * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
12853        * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12854        * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
12855        * SOFTWARE.
12856        */
12857       var isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof navigator !== 'undefined';
12858
12859       var timeoutDuration = function () {
12860         var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox'];
12861         for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) {
12862           if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) {
12863             return 1;
12864           }
12865         }
12866         return 0;
12867       }();
12868
12869       function microtaskDebounce(fn) {
12870         var called = false;
12871         return function () {
12872           if (called) {
12873             return;
12874           }
12875           called = true;
12876           window.Promise.resolve().then(function () {
12877             called = false;
12878             fn();
12879           });
12880         };
12881       }
12882
12883       function taskDebounce(fn) {
12884         var scheduled = false;
12885         return function () {
12886           if (!scheduled) {
12887             scheduled = true;
12888             setTimeout(function () {
12889               scheduled = false;
12890               fn();
12891             }, timeoutDuration);
12892           }
12893         };
12894       }
12895
12896       var supportsMicroTasks = isBrowser && window.Promise;
12897
12898       /**
12899       * Create a debounced version of a method, that's asynchronously deferred
12900       * but called in the minimum time possible.
12901       *
12902       * @method
12903       * @memberof Popper.Utils
12904       * @argument {Function} fn
12905       * @returns {Function}
12906       */
12907       var debounce = supportsMicroTasks ? microtaskDebounce : taskDebounce;
12908
12909       /**
12910        * Check if the given variable is a function
12911        * @method
12912        * @memberof Popper.Utils
12913        * @argument {Any} functionToCheck - variable to check
12914        * @returns {Boolean} answer to: is a function?
12915        */
12916       function isFunction(functionToCheck) {
12917         var getType = {};
12918         return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
12919       }
12920
12921       /**
12922        * Get CSS computed property of the given element
12923        * @method
12924        * @memberof Popper.Utils
12925        * @argument {Eement} element
12926        * @argument {String} property
12927        */
12928       function getStyleComputedProperty(element, property) {
12929         if (element.nodeType !== 1) {
12930           return [];
12931         }
12932         // NOTE: 1 DOM access here
12933         var window = element.ownerDocument.defaultView;
12934         var css = window.getComputedStyle(element, null);
12935         return property ? css[property] : css;
12936       }
12937
12938       /**
12939        * Returns the parentNode or the host of the element
12940        * @method
12941        * @memberof Popper.Utils
12942        * @argument {Element} element
12943        * @returns {Element} parent
12944        */
12945       function getParentNode(element) {
12946         if (element.nodeName === 'HTML') {
12947           return element;
12948         }
12949         return element.parentNode || element.host;
12950       }
12951
12952       /**
12953        * Returns the scrolling parent of the given element
12954        * @method
12955        * @memberof Popper.Utils
12956        * @argument {Element} element
12957        * @returns {Element} scroll parent
12958        */
12959       function getScrollParent(element) {
12960         // Return body, `getScroll` will take care to get the correct `scrollTop` from it
12961         if (!element) {
12962           return document.body;
12963         }
12964
12965         switch (element.nodeName) {
12966           case 'HTML':
12967           case 'BODY':
12968             return element.ownerDocument.body;
12969           case '#document':
12970             return element.body;
12971         }
12972
12973         // Firefox want us to check `-x` and `-y` variations as well
12974
12975         var _getStyleComputedProp = getStyleComputedProperty(element),
12976             overflow = _getStyleComputedProp.overflow,
12977             overflowX = _getStyleComputedProp.overflowX,
12978             overflowY = _getStyleComputedProp.overflowY;
12979
12980         if (/(auto|scroll|overlay)/.test(overflow + overflowY + overflowX)) {
12981           return element;
12982         }
12983
12984         return getScrollParent(getParentNode(element));
12985       }
12986
12987       /**
12988        * Returns the reference node of the reference object, or the reference object itself.
12989        * @method
12990        * @memberof Popper.Utils
12991        * @param {Element|Object} reference - the reference element (the popper will be relative to this)
12992        * @returns {Element} parent
12993        */
12994       function getReferenceNode(reference) {
12995         return reference && reference.referenceNode ? reference.referenceNode : reference;
12996       }
12997
12998       var isIE11 = isBrowser && !!(window.MSInputMethodContext && document.documentMode);
12999       var isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent);
13000
13001       /**
13002        * Determines if the browser is Internet Explorer
13003        * @method
13004        * @memberof Popper.Utils
13005        * @param {Number} version to check
13006        * @returns {Boolean} isIE
13007        */
13008       function isIE(version) {
13009         if (version === 11) {
13010           return isIE11;
13011         }
13012         if (version === 10) {
13013           return isIE10;
13014         }
13015         return isIE11 || isIE10;
13016       }
13017
13018       /**
13019        * Returns the offset parent of the given element
13020        * @method
13021        * @memberof Popper.Utils
13022        * @argument {Element} element
13023        * @returns {Element} offset parent
13024        */
13025       function getOffsetParent(element) {
13026         if (!element) {
13027           return document.documentElement;
13028         }
13029
13030         var noOffsetParent = isIE(10) ? document.body : null;
13031
13032         // NOTE: 1 DOM access here
13033         var offsetParent = element.offsetParent || null;
13034         // Skip hidden elements which don't have an offsetParent
13035         while (offsetParent === noOffsetParent && element.nextElementSibling) {
13036           offsetParent = (element = element.nextElementSibling).offsetParent;
13037         }
13038
13039         var nodeName = offsetParent && offsetParent.nodeName;
13040
13041         if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {
13042           return element ? element.ownerDocument.documentElement : document.documentElement;
13043         }
13044
13045         // .offsetParent will return the closest TH, TD or TABLE in case
13046         // no offsetParent is present, I hate this job...
13047         if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 'position') === 'static') {
13048           return getOffsetParent(offsetParent);
13049         }
13050
13051         return offsetParent;
13052       }
13053
13054       function isOffsetContainer(element) {
13055         var nodeName = element.nodeName;
13056
13057         if (nodeName === 'BODY') {
13058           return false;
13059         }
13060         return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element;
13061       }
13062
13063       /**
13064        * Finds the root node (document, shadowDOM root) of the given element
13065        * @method
13066        * @memberof Popper.Utils
13067        * @argument {Element} node
13068        * @returns {Element} root node
13069        */
13070       function getRoot(node) {
13071         if (node.parentNode !== null) {
13072           return getRoot(node.parentNode);
13073         }
13074
13075         return node;
13076       }
13077
13078       /**
13079        * Finds the offset parent common to the two provided nodes
13080        * @method
13081        * @memberof Popper.Utils
13082        * @argument {Element} element1
13083        * @argument {Element} element2
13084        * @returns {Element} common offset parent
13085        */
13086       function findCommonOffsetParent(element1, element2) {
13087         // This check is needed to avoid errors in case one of the elements isn't defined for any reason
13088         if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) {
13089           return document.documentElement;
13090         }
13091
13092         // Here we make sure to give as "start" the element that comes first in the DOM
13093         var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING;
13094         var start = order ? element1 : element2;
13095         var end = order ? element2 : element1;
13096
13097         // Get common ancestor container
13098         var range = document.createRange();
13099         range.setStart(start, 0);
13100         range.setEnd(end, 0);
13101         var commonAncestorContainer = range.commonAncestorContainer;
13102
13103         // Both nodes are inside #document
13104
13105         if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) {
13106           if (isOffsetContainer(commonAncestorContainer)) {
13107             return commonAncestorContainer;
13108           }
13109
13110           return getOffsetParent(commonAncestorContainer);
13111         }
13112
13113         // one of the nodes is inside shadowDOM, find which one
13114         var element1root = getRoot(element1);
13115         if (element1root.host) {
13116           return findCommonOffsetParent(element1root.host, element2);
13117         } else {
13118           return findCommonOffsetParent(element1, getRoot(element2).host);
13119         }
13120       }
13121
13122       /**
13123        * Gets the scroll value of the given element in the given side (top and left)
13124        * @method
13125        * @memberof Popper.Utils
13126        * @argument {Element} element
13127        * @argument {String} side `top` or `left`
13128        * @returns {number} amount of scrolled pixels
13129        */
13130       function getScroll(element) {
13131         var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top';
13132
13133         var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';
13134         var nodeName = element.nodeName;
13135
13136         if (nodeName === 'BODY' || nodeName === 'HTML') {
13137           var html = element.ownerDocument.documentElement;
13138           var scrollingElement = element.ownerDocument.scrollingElement || html;
13139           return scrollingElement[upperSide];
13140         }
13141
13142         return element[upperSide];
13143       }
13144
13145       /*
13146        * Sum or subtract the element scroll values (left and top) from a given rect object
13147        * @method
13148        * @memberof Popper.Utils
13149        * @param {Object} rect - Rect object you want to change
13150        * @param {HTMLElement} element - The element from the function reads the scroll values
13151        * @param {Boolean} subtract - set to true if you want to subtract the scroll values
13152        * @return {Object} rect - The modifier rect object
13153        */
13154       function includeScroll(rect, element) {
13155         var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
13156
13157         var scrollTop = getScroll(element, 'top');
13158         var scrollLeft = getScroll(element, 'left');
13159         var modifier = subtract ? -1 : 1;
13160         rect.top += scrollTop * modifier;
13161         rect.bottom += scrollTop * modifier;
13162         rect.left += scrollLeft * modifier;
13163         rect.right += scrollLeft * modifier;
13164         return rect;
13165       }
13166
13167       /*
13168        * Helper to detect borders of a given element
13169        * @method
13170        * @memberof Popper.Utils
13171        * @param {CSSStyleDeclaration} styles
13172        * Result of `getStyleComputedProperty` on the given element
13173        * @param {String} axis - `x` or `y`
13174        * @return {number} borders - The borders size of the given axis
13175        */
13176
13177       function getBordersSize(styles, axis) {
13178         var sideA = axis === 'x' ? 'Left' : 'Top';
13179         var sideB = sideA === 'Left' ? 'Right' : 'Bottom';
13180
13181         return parseFloat(styles['border' + sideA + 'Width']) + parseFloat(styles['border' + sideB + 'Width']);
13182       }
13183
13184       function getSize(axis, body, html, computedStyle) {
13185         return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + axis], html['scroll' + axis], isIE(10) ? parseInt(html['offset' + axis]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Top' : 'Left')]) + parseInt(computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')]) : 0);
13186       }
13187
13188       function getWindowSizes(document) {
13189         var body = document.body;
13190         var html = document.documentElement;
13191         var computedStyle = isIE(10) && getComputedStyle(html);
13192
13193         return {
13194           height: getSize('Height', body, html, computedStyle),
13195           width: getSize('Width', body, html, computedStyle)
13196         };
13197       }
13198
13199       var classCallCheck = function (instance, Constructor) {
13200         if (!(instance instanceof Constructor)) {
13201           throw new TypeError("Cannot call a class as a function");
13202         }
13203       };
13204
13205       var createClass = function () {
13206         function defineProperties(target, props) {
13207           for (var i = 0; i < props.length; i++) {
13208             var descriptor = props[i];
13209             descriptor.enumerable = descriptor.enumerable || false;
13210             descriptor.configurable = true;
13211             if ("value" in descriptor) descriptor.writable = true;
13212             Object.defineProperty(target, descriptor.key, descriptor);
13213           }
13214         }
13215
13216         return function (Constructor, protoProps, staticProps) {
13217           if (protoProps) defineProperties(Constructor.prototype, protoProps);
13218           if (staticProps) defineProperties(Constructor, staticProps);
13219           return Constructor;
13220         };
13221       }();
13222
13223
13224
13225
13226
13227       var defineProperty = function (obj, key, value) {
13228         if (key in obj) {
13229           Object.defineProperty(obj, key, {
13230             value: value,
13231             enumerable: true,
13232             configurable: true,
13233             writable: true
13234           });
13235         } else {
13236           obj[key] = value;
13237         }
13238
13239         return obj;
13240       };
13241
13242       var _extends$1 = Object.assign || function (target) {
13243         for (var i = 1; i < arguments.length; i++) {
13244           var source = arguments[i];
13245
13246           for (var key in source) {
13247             if (Object.prototype.hasOwnProperty.call(source, key)) {
13248               target[key] = source[key];
13249             }
13250           }
13251         }
13252
13253         return target;
13254       };
13255
13256       /**
13257        * Given element offsets, generate an output similar to getBoundingClientRect
13258        * @method
13259        * @memberof Popper.Utils
13260        * @argument {Object} offsets
13261        * @returns {Object} ClientRect like output
13262        */
13263       function getClientRect(offsets) {
13264         return _extends$1({}, offsets, {
13265           right: offsets.left + offsets.width,
13266           bottom: offsets.top + offsets.height
13267         });
13268       }
13269
13270       /**
13271        * Get bounding client rect of given element
13272        * @method
13273        * @memberof Popper.Utils
13274        * @param {HTMLElement} element
13275        * @return {Object} client rect
13276        */
13277       function getBoundingClientRect(element) {
13278         var rect = {};
13279
13280         // IE10 10 FIX: Please, don't ask, the element isn't
13281         // considered in DOM in some circumstances...
13282         // This isn't reproducible in IE10 compatibility mode of IE11
13283         try {
13284           if (isIE(10)) {
13285             rect = element.getBoundingClientRect();
13286             var scrollTop = getScroll(element, 'top');
13287             var scrollLeft = getScroll(element, 'left');
13288             rect.top += scrollTop;
13289             rect.left += scrollLeft;
13290             rect.bottom += scrollTop;
13291             rect.right += scrollLeft;
13292           } else {
13293             rect = element.getBoundingClientRect();
13294           }
13295         } catch (e) {}
13296
13297         var result = {
13298           left: rect.left,
13299           top: rect.top,
13300           width: rect.right - rect.left,
13301           height: rect.bottom - rect.top
13302         };
13303
13304         // subtract scrollbar size from sizes
13305         var sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {};
13306         var width = sizes.width || element.clientWidth || result.width;
13307         var height = sizes.height || element.clientHeight || result.height;
13308
13309         var horizScrollbar = element.offsetWidth - width;
13310         var vertScrollbar = element.offsetHeight - height;
13311
13312         // if an hypothetical scrollbar is detected, we must be sure it's not a `border`
13313         // we make this check conditional for performance reasons
13314         if (horizScrollbar || vertScrollbar) {
13315           var styles = getStyleComputedProperty(element);
13316           horizScrollbar -= getBordersSize(styles, 'x');
13317           vertScrollbar -= getBordersSize(styles, 'y');
13318
13319           result.width -= horizScrollbar;
13320           result.height -= vertScrollbar;
13321         }
13322
13323         return getClientRect(result);
13324       }
13325
13326       function getOffsetRectRelativeToArbitraryNode(children, parent) {
13327         var fixedPosition = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
13328
13329         var isIE10 = isIE(10);
13330         var isHTML = parent.nodeName === 'HTML';
13331         var childrenRect = getBoundingClientRect(children);
13332         var parentRect = getBoundingClientRect(parent);
13333         var scrollParent = getScrollParent(children);
13334
13335         var styles = getStyleComputedProperty(parent);
13336         var borderTopWidth = parseFloat(styles.borderTopWidth);
13337         var borderLeftWidth = parseFloat(styles.borderLeftWidth);
13338
13339         // In cases where the parent is fixed, we must ignore negative scroll in offset calc
13340         if (fixedPosition && isHTML) {
13341           parentRect.top = Math.max(parentRect.top, 0);
13342           parentRect.left = Math.max(parentRect.left, 0);
13343         }
13344         var offsets = getClientRect({
13345           top: childrenRect.top - parentRect.top - borderTopWidth,
13346           left: childrenRect.left - parentRect.left - borderLeftWidth,
13347           width: childrenRect.width,
13348           height: childrenRect.height
13349         });
13350         offsets.marginTop = 0;
13351         offsets.marginLeft = 0;
13352
13353         // Subtract margins of documentElement in case it's being used as parent
13354         // we do this only on HTML because it's the only element that behaves
13355         // differently when margins are applied to it. The margins are included in
13356         // the box of the documentElement, in the other cases not.
13357         if (!isIE10 && isHTML) {
13358           var marginTop = parseFloat(styles.marginTop);
13359           var marginLeft = parseFloat(styles.marginLeft);
13360
13361           offsets.top -= borderTopWidth - marginTop;
13362           offsets.bottom -= borderTopWidth - marginTop;
13363           offsets.left -= borderLeftWidth - marginLeft;
13364           offsets.right -= borderLeftWidth - marginLeft;
13365
13366           // Attach marginTop and marginLeft because in some circumstances we may need them
13367           offsets.marginTop = marginTop;
13368           offsets.marginLeft = marginLeft;
13369         }
13370
13371         if (isIE10 && !fixedPosition ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') {
13372           offsets = includeScroll(offsets, parent);
13373         }
13374
13375         return offsets;
13376       }
13377
13378       function getViewportOffsetRectRelativeToArtbitraryNode(element) {
13379         var excludeScroll = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
13380
13381         var html = element.ownerDocument.documentElement;
13382         var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html);
13383         var width = Math.max(html.clientWidth, window.innerWidth || 0);
13384         var height = Math.max(html.clientHeight, window.innerHeight || 0);
13385
13386         var scrollTop = !excludeScroll ? getScroll(html) : 0;
13387         var scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0;
13388
13389         var offset = {
13390           top: scrollTop - relativeOffset.top + relativeOffset.marginTop,
13391           left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft,
13392           width: width,
13393           height: height
13394         };
13395
13396         return getClientRect(offset);
13397       }
13398
13399       /**
13400        * Check if the given element is fixed or is inside a fixed parent
13401        * @method
13402        * @memberof Popper.Utils
13403        * @argument {Element} element
13404        * @argument {Element} customContainer
13405        * @returns {Boolean} answer to "isFixed?"
13406        */
13407       function isFixed(element) {
13408         var nodeName = element.nodeName;
13409         if (nodeName === 'BODY' || nodeName === 'HTML') {
13410           return false;
13411         }
13412         if (getStyleComputedProperty(element, 'position') === 'fixed') {
13413           return true;
13414         }
13415         var parentNode = getParentNode(element);
13416         if (!parentNode) {
13417           return false;
13418         }
13419         return isFixed(parentNode);
13420       }
13421
13422       /**
13423        * Finds the first parent of an element that has a transformed property defined
13424        * @method
13425        * @memberof Popper.Utils
13426        * @argument {Element} element
13427        * @returns {Element} first transformed parent or documentElement
13428        */
13429
13430       function getFixedPositionOffsetParent(element) {
13431         // This check is needed to avoid errors in case one of the elements isn't defined for any reason
13432         if (!element || !element.parentElement || isIE()) {
13433           return document.documentElement;
13434         }
13435         var el = element.parentElement;
13436         while (el && getStyleComputedProperty(el, 'transform') === 'none') {
13437           el = el.parentElement;
13438         }
13439         return el || document.documentElement;
13440       }
13441
13442       /**
13443        * Computed the boundaries limits and return them
13444        * @method
13445        * @memberof Popper.Utils
13446        * @param {HTMLElement} popper
13447        * @param {HTMLElement} reference
13448        * @param {number} padding
13449        * @param {HTMLElement} boundariesElement - Element used to define the boundaries
13450        * @param {Boolean} fixedPosition - Is in fixed position mode
13451        * @returns {Object} Coordinates of the boundaries
13452        */
13453       function getBoundaries(popper, reference, padding, boundariesElement) {
13454         var fixedPosition = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
13455
13456         // NOTE: 1 DOM access here
13457
13458         var boundaries = { top: 0, left: 0 };
13459         var offsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));
13460
13461         // Handle viewport case
13462         if (boundariesElement === 'viewport') {
13463           boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition);
13464         } else {
13465           // Handle other cases based on DOM element used as boundaries
13466           var boundariesNode = void 0;
13467           if (boundariesElement === 'scrollParent') {
13468             boundariesNode = getScrollParent(getParentNode(reference));
13469             if (boundariesNode.nodeName === 'BODY') {
13470               boundariesNode = popper.ownerDocument.documentElement;
13471             }
13472           } else if (boundariesElement === 'window') {
13473             boundariesNode = popper.ownerDocument.documentElement;
13474           } else {
13475             boundariesNode = boundariesElement;
13476           }
13477
13478           var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition);
13479
13480           // In case of HTML, we need a different computation
13481           if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) {
13482             var _getWindowSizes = getWindowSizes(popper.ownerDocument),
13483                 height = _getWindowSizes.height,
13484                 width = _getWindowSizes.width;
13485
13486             boundaries.top += offsets.top - offsets.marginTop;
13487             boundaries.bottom = height + offsets.top;
13488             boundaries.left += offsets.left - offsets.marginLeft;
13489             boundaries.right = width + offsets.left;
13490           } else {
13491             // for all the other DOM elements, this one is good
13492             boundaries = offsets;
13493           }
13494         }
13495
13496         // Add paddings
13497         padding = padding || 0;
13498         var isPaddingNumber = typeof padding === 'number';
13499         boundaries.left += isPaddingNumber ? padding : padding.left || 0;
13500         boundaries.top += isPaddingNumber ? padding : padding.top || 0;
13501         boundaries.right -= isPaddingNumber ? padding : padding.right || 0;
13502         boundaries.bottom -= isPaddingNumber ? padding : padding.bottom || 0;
13503
13504         return boundaries;
13505       }
13506
13507       function getArea(_ref) {
13508         var width = _ref.width,
13509             height = _ref.height;
13510
13511         return width * height;
13512       }
13513
13514       /**
13515        * Utility used to transform the `auto` placement to the placement with more
13516        * available space.
13517        * @method
13518        * @memberof Popper.Utils
13519        * @argument {Object} data - The data object generated by update method
13520        * @argument {Object} options - Modifiers configuration and options
13521        * @returns {Object} The data object, properly modified
13522        */
13523       function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) {
13524         var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
13525
13526         if (placement.indexOf('auto') === -1) {
13527           return placement;
13528         }
13529
13530         var boundaries = getBoundaries(popper, reference, padding, boundariesElement);
13531
13532         var rects = {
13533           top: {
13534             width: boundaries.width,
13535             height: refRect.top - boundaries.top
13536           },
13537           right: {
13538             width: boundaries.right - refRect.right,
13539             height: boundaries.height
13540           },
13541           bottom: {
13542             width: boundaries.width,
13543             height: boundaries.bottom - refRect.bottom
13544           },
13545           left: {
13546             width: refRect.left - boundaries.left,
13547             height: boundaries.height
13548           }
13549         };
13550
13551         var sortedAreas = Object.keys(rects).map(function (key) {
13552           return _extends$1({
13553             key: key
13554           }, rects[key], {
13555             area: getArea(rects[key])
13556           });
13557         }).sort(function (a, b) {
13558           return b.area - a.area;
13559         });
13560
13561         var filteredAreas = sortedAreas.filter(function (_ref2) {
13562           var width = _ref2.width,
13563               height = _ref2.height;
13564           return width >= popper.clientWidth && height >= popper.clientHeight;
13565         });
13566
13567         var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key;
13568
13569         var variation = placement.split('-')[1];
13570
13571         return computedPlacement + (variation ? '-' + variation : '');
13572       }
13573
13574       /**
13575        * Get offsets to the reference element
13576        * @method
13577        * @memberof Popper.Utils
13578        * @param {Object} state
13579        * @param {Element} popper - the popper element
13580        * @param {Element} reference - the reference element (the popper will be relative to this)
13581        * @param {Element} fixedPosition - is in fixed position mode
13582        * @returns {Object} An object containing the offsets which will be applied to the popper
13583        */
13584       function getReferenceOffsets(state, popper, reference) {
13585         var fixedPosition = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
13586
13587         var commonOffsetParent = fixedPosition ? getFixedPositionOffsetParent(popper) : findCommonOffsetParent(popper, getReferenceNode(reference));
13588         return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent, fixedPosition);
13589       }
13590
13591       /**
13592        * Get the outer sizes of the given element (offset size + margins)
13593        * @method
13594        * @memberof Popper.Utils
13595        * @argument {Element} element
13596        * @returns {Object} object containing width and height properties
13597        */
13598       function getOuterSizes(element) {
13599         var window = element.ownerDocument.defaultView;
13600         var styles = window.getComputedStyle(element);
13601         var x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0);
13602         var y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0);
13603         var result = {
13604           width: element.offsetWidth + y,
13605           height: element.offsetHeight + x
13606         };
13607         return result;
13608       }
13609
13610       /**
13611        * Get the opposite placement of the given one
13612        * @method
13613        * @memberof Popper.Utils
13614        * @argument {String} placement
13615        * @returns {String} flipped placement
13616        */
13617       function getOppositePlacement(placement) {
13618         var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };
13619         return placement.replace(/left|right|bottom|top/g, function (matched) {
13620           return hash[matched];
13621         });
13622       }
13623
13624       /**
13625        * Get offsets to the popper
13626        * @method
13627        * @memberof Popper.Utils
13628        * @param {Object} position - CSS position the Popper will get applied
13629        * @param {HTMLElement} popper - the popper element
13630        * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this)
13631        * @param {String} placement - one of the valid placement options
13632        * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper
13633        */
13634       function getPopperOffsets(popper, referenceOffsets, placement) {
13635         placement = placement.split('-')[0];
13636
13637         // Get popper node sizes
13638         var popperRect = getOuterSizes(popper);
13639
13640         // Add position, width and height to our offsets object
13641         var popperOffsets = {
13642           width: popperRect.width,
13643           height: popperRect.height
13644         };
13645
13646         // depending by the popper placement we have to compute its offsets slightly differently
13647         var isHoriz = ['right', 'left'].indexOf(placement) !== -1;
13648         var mainSide = isHoriz ? 'top' : 'left';
13649         var secondarySide = isHoriz ? 'left' : 'top';
13650         var measurement = isHoriz ? 'height' : 'width';
13651         var secondaryMeasurement = !isHoriz ? 'height' : 'width';
13652
13653         popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - popperRect[measurement] / 2;
13654         if (placement === secondarySide) {
13655           popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement];
13656         } else {
13657           popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)];
13658         }
13659
13660         return popperOffsets;
13661       }
13662
13663       /**
13664        * Mimics the `find` method of Array
13665        * @method
13666        * @memberof Popper.Utils
13667        * @argument {Array} arr
13668        * @argument prop
13669        * @argument value
13670        * @returns index or -1
13671        */
13672       function find(arr, check) {
13673         // use native find if supported
13674         if (Array.prototype.find) {
13675           return arr.find(check);
13676         }
13677
13678         // use `filter` to obtain the same behavior of `find`
13679         return arr.filter(check)[0];
13680       }
13681
13682       /**
13683        * Return the index of the matching object
13684        * @method
13685        * @memberof Popper.Utils
13686        * @argument {Array} arr
13687        * @argument prop
13688        * @argument value
13689        * @returns index or -1
13690        */
13691       function findIndex(arr, prop, value) {
13692         // use native findIndex if supported
13693         if (Array.prototype.findIndex) {
13694           return arr.findIndex(function (cur) {
13695             return cur[prop] === value;
13696           });
13697         }
13698
13699         // use `find` + `indexOf` if `findIndex` isn't supported
13700         var match = find(arr, function (obj) {
13701           return obj[prop] === value;
13702         });
13703         return arr.indexOf(match);
13704       }
13705
13706       /**
13707        * Loop trough the list of modifiers and run them in order,
13708        * each of them will then edit the data object.
13709        * @method
13710        * @memberof Popper.Utils
13711        * @param {dataObject} data
13712        * @param {Array} modifiers
13713        * @param {String} ends - Optional modifier name used as stopper
13714        * @returns {dataObject}
13715        */
13716       function runModifiers(modifiers, data, ends) {
13717         var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', ends));
13718
13719         modifiersToRun.forEach(function (modifier) {
13720           if (modifier['function']) {
13721             // eslint-disable-line dot-notation
13722             console.warn('`modifier.function` is deprecated, use `modifier.fn`!');
13723           }
13724           var fn = modifier['function'] || modifier.fn; // eslint-disable-line dot-notation
13725           if (modifier.enabled && isFunction(fn)) {
13726             // Add properties to offsets to make them a complete clientRect object
13727             // we do this before each modifier to make sure the previous one doesn't
13728             // mess with these values
13729             data.offsets.popper = getClientRect(data.offsets.popper);
13730             data.offsets.reference = getClientRect(data.offsets.reference);
13731
13732             data = fn(data, modifier);
13733           }
13734         });
13735
13736         return data;
13737       }
13738
13739       /**
13740        * Updates the position of the popper, computing the new offsets and applying
13741        * the new style.<br />
13742        * Prefer `scheduleUpdate` over `update` because of performance reasons.
13743        * @method
13744        * @memberof Popper
13745        */
13746       function update() {
13747         // if popper is destroyed, don't perform any further update
13748         if (this.state.isDestroyed) {
13749           return;
13750         }
13751
13752         var data = {
13753           instance: this,
13754           styles: {},
13755           arrowStyles: {},
13756           attributes: {},
13757           flipped: false,
13758           offsets: {}
13759         };
13760
13761         // compute reference element offsets
13762         data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference, this.options.positionFixed);
13763
13764         // compute auto placement, store placement inside the data object,
13765         // modifiers will be able to edit `placement` if needed
13766         // and refer to originalPlacement to know the original value
13767         data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding);
13768
13769         // store the computed placement inside `originalPlacement`
13770         data.originalPlacement = data.placement;
13771
13772         data.positionFixed = this.options.positionFixed;
13773
13774         // compute the popper offsets
13775         data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement);
13776
13777         data.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute';
13778
13779         // run the modifiers
13780         data = runModifiers(this.modifiers, data);
13781
13782         // the first `update` will call `onCreate` callback
13783         // the other ones will call `onUpdate` callback
13784         if (!this.state.isCreated) {
13785           this.state.isCreated = true;
13786           this.options.onCreate(data);
13787         } else {
13788           this.options.onUpdate(data);
13789         }
13790       }
13791
13792       /**
13793        * Helper used to know if the given modifier is enabled.
13794        * @method
13795        * @memberof Popper.Utils
13796        * @returns {Boolean}
13797        */
13798       function isModifierEnabled(modifiers, modifierName) {
13799         return modifiers.some(function (_ref) {
13800           var name = _ref.name,
13801               enabled = _ref.enabled;
13802           return enabled && name === modifierName;
13803         });
13804       }
13805
13806       /**
13807        * Get the prefixed supported property name
13808        * @method
13809        * @memberof Popper.Utils
13810        * @argument {String} property (camelCase)
13811        * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix)
13812        */
13813       function getSupportedPropertyName(property) {
13814         var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O'];
13815         var upperProp = property.charAt(0).toUpperCase() + property.slice(1);
13816
13817         for (var i = 0; i < prefixes.length; i++) {
13818           var prefix = prefixes[i];
13819           var toCheck = prefix ? '' + prefix + upperProp : property;
13820           if (typeof document.body.style[toCheck] !== 'undefined') {
13821             return toCheck;
13822           }
13823         }
13824         return null;
13825       }
13826
13827       /**
13828        * Destroys the popper.
13829        * @method
13830        * @memberof Popper
13831        */
13832       function destroy() {
13833         this.state.isDestroyed = true;
13834
13835         // touch DOM only if `applyStyle` modifier is enabled
13836         if (isModifierEnabled(this.modifiers, 'applyStyle')) {
13837           this.popper.removeAttribute('x-placement');
13838           this.popper.style.position = '';
13839           this.popper.style.top = '';
13840           this.popper.style.left = '';
13841           this.popper.style.right = '';
13842           this.popper.style.bottom = '';
13843           this.popper.style.willChange = '';
13844           this.popper.style[getSupportedPropertyName('transform')] = '';
13845         }
13846
13847         this.disableEventListeners();
13848
13849         // remove the popper if user explicitly asked for the deletion on destroy
13850         // do not use `remove` because IE11 doesn't support it
13851         if (this.options.removeOnDestroy) {
13852           this.popper.parentNode.removeChild(this.popper);
13853         }
13854         return this;
13855       }
13856
13857       /**
13858        * Get the window associated with the element
13859        * @argument {Element} element
13860        * @returns {Window}
13861        */
13862       function getWindow(element) {
13863         var ownerDocument = element.ownerDocument;
13864         return ownerDocument ? ownerDocument.defaultView : window;
13865       }
13866
13867       function attachToScrollParents(scrollParent, event, callback, scrollParents) {
13868         var isBody = scrollParent.nodeName === 'BODY';
13869         var target = isBody ? scrollParent.ownerDocument.defaultView : scrollParent;
13870         target.addEventListener(event, callback, { passive: true });
13871
13872         if (!isBody) {
13873           attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents);
13874         }
13875         scrollParents.push(target);
13876       }
13877
13878       /**
13879        * Setup needed event listeners used to update the popper position
13880        * @method
13881        * @memberof Popper.Utils
13882        * @private
13883        */
13884       function setupEventListeners(reference, options, state, updateBound) {
13885         // Resize event listener on window
13886         state.updateBound = updateBound;
13887         getWindow(reference).addEventListener('resize', state.updateBound, { passive: true });
13888
13889         // Scroll event listener on scroll parents
13890         var scrollElement = getScrollParent(reference);
13891         attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents);
13892         state.scrollElement = scrollElement;
13893         state.eventsEnabled = true;
13894
13895         return state;
13896       }
13897
13898       /**
13899        * It will add resize/scroll events and start recalculating
13900        * position of the popper element when they are triggered.
13901        * @method
13902        * @memberof Popper
13903        */
13904       function enableEventListeners() {
13905         if (!this.state.eventsEnabled) {
13906           this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate);
13907         }
13908       }
13909
13910       /**
13911        * Remove event listeners used to update the popper position
13912        * @method
13913        * @memberof Popper.Utils
13914        * @private
13915        */
13916       function removeEventListeners(reference, state) {
13917         // Remove resize event listener on window
13918         getWindow(reference).removeEventListener('resize', state.updateBound);
13919
13920         // Remove scroll event listener on scroll parents
13921         state.scrollParents.forEach(function (target) {
13922           target.removeEventListener('scroll', state.updateBound);
13923         });
13924
13925         // Reset state
13926         state.updateBound = null;
13927         state.scrollParents = [];
13928         state.scrollElement = null;
13929         state.eventsEnabled = false;
13930         return state;
13931       }
13932
13933       /**
13934        * It will remove resize/scroll events and won't recalculate popper position
13935        * when they are triggered. It also won't trigger `onUpdate` callback anymore,
13936        * unless you call `update` method manually.
13937        * @method
13938        * @memberof Popper
13939        */
13940       function disableEventListeners() {
13941         if (this.state.eventsEnabled) {
13942           cancelAnimationFrame(this.scheduleUpdate);
13943           this.state = removeEventListeners(this.reference, this.state);
13944         }
13945       }
13946
13947       /**
13948        * Tells if a given input is a number
13949        * @method
13950        * @memberof Popper.Utils
13951        * @param {*} input to check
13952        * @return {Boolean}
13953        */
13954       function isNumeric(n) {
13955         return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);
13956       }
13957
13958       /**
13959        * Set the style to the given popper
13960        * @method
13961        * @memberof Popper.Utils
13962        * @argument {Element} element - Element to apply the style to
13963        * @argument {Object} styles
13964        * Object with a list of properties and values which will be applied to the element
13965        */
13966       function setStyles(element, styles) {
13967         Object.keys(styles).forEach(function (prop) {
13968           var unit = '';
13969           // add unit if the value is numeric and is one of the following
13970           if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && isNumeric(styles[prop])) {
13971             unit = 'px';
13972           }
13973           element.style[prop] = styles[prop] + unit;
13974         });
13975       }
13976
13977       /**
13978        * Set the attributes to the given popper
13979        * @method
13980        * @memberof Popper.Utils
13981        * @argument {Element} element - Element to apply the attributes to
13982        * @argument {Object} styles
13983        * Object with a list of properties and values which will be applied to the element
13984        */
13985       function setAttributes(element, attributes) {
13986         Object.keys(attributes).forEach(function (prop) {
13987           var value = attributes[prop];
13988           if (value !== false) {
13989             element.setAttribute(prop, attributes[prop]);
13990           } else {
13991             element.removeAttribute(prop);
13992           }
13993         });
13994       }
13995
13996       /**
13997        * @function
13998        * @memberof Modifiers
13999        * @argument {Object} data - The data object generated by `update` method
14000        * @argument {Object} data.styles - List of style properties - values to apply to popper element
14001        * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element
14002        * @argument {Object} options - Modifiers configuration and options
14003        * @returns {Object} The same data object
14004        */
14005       function applyStyle(data) {
14006         // any property present in `data.styles` will be applied to the popper,
14007         // in this way we can make the 3rd party modifiers add custom styles to it
14008         // Be aware, modifiers could override the properties defined in the previous
14009         // lines of this modifier!
14010         setStyles(data.instance.popper, data.styles);
14011
14012         // any property present in `data.attributes` will be applied to the popper,
14013         // they will be set as HTML attributes of the element
14014         setAttributes(data.instance.popper, data.attributes);
14015
14016         // if arrowElement is defined and arrowStyles has some properties
14017         if (data.arrowElement && Object.keys(data.arrowStyles).length) {
14018           setStyles(data.arrowElement, data.arrowStyles);
14019         }
14020
14021         return data;
14022       }
14023
14024       /**
14025        * Set the x-placement attribute before everything else because it could be used
14026        * to add margins to the popper margins needs to be calculated to get the
14027        * correct popper offsets.
14028        * @method
14029        * @memberof Popper.modifiers
14030        * @param {HTMLElement} reference - The reference element used to position the popper
14031        * @param {HTMLElement} popper - The HTML element used as popper
14032        * @param {Object} options - Popper.js options
14033        */
14034       function applyStyleOnLoad(reference, popper, options, modifierOptions, state) {
14035         // compute reference element offsets
14036         var referenceOffsets = getReferenceOffsets(state, popper, reference, options.positionFixed);
14037
14038         // compute auto placement, store placement inside the data object,
14039         // modifiers will be able to edit `placement` if needed
14040         // and refer to originalPlacement to know the original value
14041         var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, options.modifiers.flip.boundariesElement, options.modifiers.flip.padding);
14042
14043         popper.setAttribute('x-placement', placement);
14044
14045         // Apply `position` to popper before anything else because
14046         // without the position applied we can't guarantee correct computations
14047         setStyles(popper, { position: options.positionFixed ? 'fixed' : 'absolute' });
14048
14049         return options;
14050       }
14051
14052       /**
14053        * @function
14054        * @memberof Popper.Utils
14055        * @argument {Object} data - The data object generated by `update` method
14056        * @argument {Boolean} shouldRound - If the offsets should be rounded at all
14057        * @returns {Object} The popper's position offsets rounded
14058        *
14059        * The tale of pixel-perfect positioning. It's still not 100% perfect, but as
14060        * good as it can be within reason.
14061        * Discussion here: https://github.com/FezVrasta/popper.js/pull/715
14062        *
14063        * Low DPI screens cause a popper to be blurry if not using full pixels (Safari
14064        * as well on High DPI screens).
14065        *
14066        * Firefox prefers no rounding for positioning and does not have blurriness on
14067        * high DPI screens.
14068        *
14069        * Only horizontal placement and left/right values need to be considered.
14070        */
14071       function getRoundedOffsets(data, shouldRound) {
14072         var _data$offsets = data.offsets,
14073             popper = _data$offsets.popper,
14074             reference = _data$offsets.reference;
14075         var round = Math.round,
14076             floor = Math.floor;
14077
14078         var noRound = function noRound(v) {
14079           return v;
14080         };
14081
14082         var referenceWidth = round(reference.width);
14083         var popperWidth = round(popper.width);
14084
14085         var isVertical = ['left', 'right'].indexOf(data.placement) !== -1;
14086         var isVariation = data.placement.indexOf('-') !== -1;
14087         var sameWidthParity = referenceWidth % 2 === popperWidth % 2;
14088         var bothOddWidth = referenceWidth % 2 === 1 && popperWidth % 2 === 1;
14089
14090         var horizontalToInteger = !shouldRound ? noRound : isVertical || isVariation || sameWidthParity ? round : floor;
14091         var verticalToInteger = !shouldRound ? noRound : round;
14092
14093         return {
14094           left: horizontalToInteger(bothOddWidth && !isVariation && shouldRound ? popper.left - 1 : popper.left),
14095           top: verticalToInteger(popper.top),
14096           bottom: verticalToInteger(popper.bottom),
14097           right: horizontalToInteger(popper.right)
14098         };
14099       }
14100
14101       var isFirefox = isBrowser && /Firefox/i.test(navigator.userAgent);
14102
14103       /**
14104        * @function
14105        * @memberof Modifiers
14106        * @argument {Object} data - The data object generated by `update` method
14107        * @argument {Object} options - Modifiers configuration and options
14108        * @returns {Object} The data object, properly modified
14109        */
14110       function computeStyle(data, options) {
14111         var x = options.x,
14112             y = options.y;
14113         var popper = data.offsets.popper;
14114
14115         // Remove this legacy support in Popper.js v2
14116
14117         var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) {
14118           return modifier.name === 'applyStyle';
14119         }).gpuAcceleration;
14120         if (legacyGpuAccelerationOption !== undefined) {
14121           console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');
14122         }
14123         var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : options.gpuAcceleration;
14124
14125         var offsetParent = getOffsetParent(data.instance.popper);
14126         var offsetParentRect = getBoundingClientRect(offsetParent);
14127
14128         // Styles
14129         var styles = {
14130           position: popper.position
14131         };
14132
14133         var offsets = getRoundedOffsets(data, window.devicePixelRatio < 2 || !isFirefox);
14134
14135         var sideA = x === 'bottom' ? 'top' : 'bottom';
14136         var sideB = y === 'right' ? 'left' : 'right';
14137
14138         // if gpuAcceleration is set to `true` and transform is supported,
14139         //  we use `translate3d` to apply the position to the popper we
14140         // automatically use the supported prefixed version if needed
14141         var prefixedProperty = getSupportedPropertyName('transform');
14142
14143         // now, let's make a step back and look at this code closely (wtf?)
14144         // If the content of the popper grows once it's been positioned, it
14145         // may happen that the popper gets misplaced because of the new content
14146         // overflowing its reference element
14147         // To avoid this problem, we provide two options (x and y), which allow
14148         // the consumer to define the offset origin.
14149         // If we position a popper on top of a reference element, we can set
14150         // `x` to `top` to make the popper grow towards its top instead of
14151         // its bottom.
14152         var left = void 0,
14153             top = void 0;
14154         if (sideA === 'bottom') {
14155           // when offsetParent is <html> the positioning is relative to the bottom of the screen (excluding the scrollbar)
14156           // and not the bottom of the html element
14157           if (offsetParent.nodeName === 'HTML') {
14158             top = -offsetParent.clientHeight + offsets.bottom;
14159           } else {
14160             top = -offsetParentRect.height + offsets.bottom;
14161           }
14162         } else {
14163           top = offsets.top;
14164         }
14165         if (sideB === 'right') {
14166           if (offsetParent.nodeName === 'HTML') {
14167             left = -offsetParent.clientWidth + offsets.right;
14168           } else {
14169             left = -offsetParentRect.width + offsets.right;
14170           }
14171         } else {
14172           left = offsets.left;
14173         }
14174         if (gpuAcceleration && prefixedProperty) {
14175           styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)';
14176           styles[sideA] = 0;
14177           styles[sideB] = 0;
14178           styles.willChange = 'transform';
14179         } else {
14180           // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties
14181           var invertTop = sideA === 'bottom' ? -1 : 1;
14182           var invertLeft = sideB === 'right' ? -1 : 1;
14183           styles[sideA] = top * invertTop;
14184           styles[sideB] = left * invertLeft;
14185           styles.willChange = sideA + ', ' + sideB;
14186         }
14187
14188         // Attributes
14189         var attributes = {
14190           'x-placement': data.placement
14191         };
14192
14193         // Update `data` attributes, styles and arrowStyles
14194         data.attributes = _extends$1({}, attributes, data.attributes);
14195         data.styles = _extends$1({}, styles, data.styles);
14196         data.arrowStyles = _extends$1({}, data.offsets.arrow, data.arrowStyles);
14197
14198         return data;
14199       }
14200
14201       /**
14202        * Helper used to know if the given modifier depends from another one.<br />
14203        * It checks if the needed modifier is listed and enabled.
14204        * @method
14205        * @memberof Popper.Utils
14206        * @param {Array} modifiers - list of modifiers
14207        * @param {String} requestingName - name of requesting modifier
14208        * @param {String} requestedName - name of requested modifier
14209        * @returns {Boolean}
14210        */
14211       function isModifierRequired(modifiers, requestingName, requestedName) {
14212         var requesting = find(modifiers, function (_ref) {
14213           var name = _ref.name;
14214           return name === requestingName;
14215         });
14216
14217         var isRequired = !!requesting && modifiers.some(function (modifier) {
14218           return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order;
14219         });
14220
14221         if (!isRequired) {
14222           var _requesting = '`' + requestingName + '`';
14223           var requested = '`' + requestedName + '`';
14224           console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be sure to include it before ' + _requesting + '!');
14225         }
14226         return isRequired;
14227       }
14228
14229       /**
14230        * @function
14231        * @memberof Modifiers
14232        * @argument {Object} data - The data object generated by update method
14233        * @argument {Object} options - Modifiers configuration and options
14234        * @returns {Object} The data object, properly modified
14235        */
14236       function arrow(data, options) {
14237         var _data$offsets$arrow;
14238
14239         // arrow depends on keepTogether in order to work
14240         if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {
14241           return data;
14242         }
14243
14244         var arrowElement = options.element;
14245
14246         // if arrowElement is a string, suppose it's a CSS selector
14247         if (typeof arrowElement === 'string') {
14248           arrowElement = data.instance.popper.querySelector(arrowElement);
14249
14250           // if arrowElement is not found, don't run the modifier
14251           if (!arrowElement) {
14252             return data;
14253           }
14254         } else {
14255           // if the arrowElement isn't a query selector we must check that the
14256           // provided DOM node is child of its popper node
14257           if (!data.instance.popper.contains(arrowElement)) {
14258             console.warn('WARNING: `arrow.element` must be child of its popper element!');
14259             return data;
14260           }
14261         }
14262
14263         var placement = data.placement.split('-')[0];
14264         var _data$offsets = data.offsets,
14265             popper = _data$offsets.popper,
14266             reference = _data$offsets.reference;
14267
14268         var isVertical = ['left', 'right'].indexOf(placement) !== -1;
14269
14270         var len = isVertical ? 'height' : 'width';
14271         var sideCapitalized = isVertical ? 'Top' : 'Left';
14272         var side = sideCapitalized.toLowerCase();
14273         var altSide = isVertical ? 'left' : 'top';
14274         var opSide = isVertical ? 'bottom' : 'right';
14275         var arrowElementSize = getOuterSizes(arrowElement)[len];
14276
14277         //
14278         // extends keepTogether behavior making sure the popper and its
14279         // reference have enough pixels in conjunction
14280         //
14281
14282         // top/left side
14283         if (reference[opSide] - arrowElementSize < popper[side]) {
14284           data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize);
14285         }
14286         // bottom/right side
14287         if (reference[side] + arrowElementSize > popper[opSide]) {
14288           data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide];
14289         }
14290         data.offsets.popper = getClientRect(data.offsets.popper);
14291
14292         // compute center of the popper
14293         var center = reference[side] + reference[len] / 2 - arrowElementSize / 2;
14294
14295         // Compute the sideValue using the updated popper offsets
14296         // take popper margin in account because we don't have this info available
14297         var css = getStyleComputedProperty(data.instance.popper);
14298         var popperMarginSide = parseFloat(css['margin' + sideCapitalized]);
14299         var popperBorderSide = parseFloat(css['border' + sideCapitalized + 'Width']);
14300         var sideValue = center - data.offsets.popper[side] - popperMarginSide - popperBorderSide;
14301
14302         // prevent arrowElement from being placed not contiguously to its popper
14303         sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0);
14304
14305         data.arrowElement = arrowElement;
14306         data.offsets.arrow = (_data$offsets$arrow = {}, defineProperty(_data$offsets$arrow, side, Math.round(sideValue)), defineProperty(_data$offsets$arrow, altSide, ''), _data$offsets$arrow);
14307
14308         return data;
14309       }
14310
14311       /**
14312        * Get the opposite placement variation of the given one
14313        * @method
14314        * @memberof Popper.Utils
14315        * @argument {String} placement variation
14316        * @returns {String} flipped placement variation
14317        */
14318       function getOppositeVariation(variation) {
14319         if (variation === 'end') {
14320           return 'start';
14321         } else if (variation === 'start') {
14322           return 'end';
14323         }
14324         return variation;
14325       }
14326
14327       /**
14328        * List of accepted placements to use as values of the `placement` option.<br />
14329        * Valid placements are:
14330        * - `auto`
14331        * - `top`
14332        * - `right`
14333        * - `bottom`
14334        * - `left`
14335        *
14336        * Each placement can have a variation from this list:
14337        * - `-start`
14338        * - `-end`
14339        *
14340        * Variations are interpreted easily if you think of them as the left to right
14341        * written languages. Horizontally (`top` and `bottom`), `start` is left and `end`
14342        * is right.<br />
14343        * Vertically (`left` and `right`), `start` is top and `end` is bottom.
14344        *
14345        * Some valid examples are:
14346        * - `top-end` (on top of reference, right aligned)
14347        * - `right-start` (on right of reference, top aligned)
14348        * - `bottom` (on bottom, centered)
14349        * - `auto-end` (on the side with more space available, alignment depends by placement)
14350        *
14351        * @static
14352        * @type {Array}
14353        * @enum {String}
14354        * @readonly
14355        * @method placements
14356        * @memberof Popper
14357        */
14358       var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start'];
14359
14360       // Get rid of `auto` `auto-start` and `auto-end`
14361       var validPlacements = placements.slice(3);
14362
14363       /**
14364        * Given an initial placement, returns all the subsequent placements
14365        * clockwise (or counter-clockwise).
14366        *
14367        * @method
14368        * @memberof Popper.Utils
14369        * @argument {String} placement - A valid placement (it accepts variations)
14370        * @argument {Boolean} counter - Set to true to walk the placements counterclockwise
14371        * @returns {Array} placements including their variations
14372        */
14373       function clockwise(placement) {
14374         var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
14375
14376         var index = validPlacements.indexOf(placement);
14377         var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index));
14378         return counter ? arr.reverse() : arr;
14379       }
14380
14381       var BEHAVIORS = {
14382         FLIP: 'flip',
14383         CLOCKWISE: 'clockwise',
14384         COUNTERCLOCKWISE: 'counterclockwise'
14385       };
14386
14387       /**
14388        * @function
14389        * @memberof Modifiers
14390        * @argument {Object} data - The data object generated by update method
14391        * @argument {Object} options - Modifiers configuration and options
14392        * @returns {Object} The data object, properly modified
14393        */
14394       function flip(data, options) {
14395         // if `inner` modifier is enabled, we can't use the `flip` modifier
14396         if (isModifierEnabled(data.instance.modifiers, 'inner')) {
14397           return data;
14398         }
14399
14400         if (data.flipped && data.placement === data.originalPlacement) {
14401           // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides
14402           return data;
14403         }
14404
14405         var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, options.boundariesElement, data.positionFixed);
14406
14407         var placement = data.placement.split('-')[0];
14408         var placementOpposite = getOppositePlacement(placement);
14409         var variation = data.placement.split('-')[1] || '';
14410
14411         var flipOrder = [];
14412
14413         switch (options.behavior) {
14414           case BEHAVIORS.FLIP:
14415             flipOrder = [placement, placementOpposite];
14416             break;
14417           case BEHAVIORS.CLOCKWISE:
14418             flipOrder = clockwise(placement);
14419             break;
14420           case BEHAVIORS.COUNTERCLOCKWISE:
14421             flipOrder = clockwise(placement, true);
14422             break;
14423           default:
14424             flipOrder = options.behavior;
14425         }
14426
14427         flipOrder.forEach(function (step, index) {
14428           if (placement !== step || flipOrder.length === index + 1) {
14429             return data;
14430           }
14431
14432           placement = data.placement.split('-')[0];
14433           placementOpposite = getOppositePlacement(placement);
14434
14435           var popperOffsets = data.offsets.popper;
14436           var refOffsets = data.offsets.reference;
14437
14438           // using floor because the reference offsets may contain decimals we are not going to consider here
14439           var floor = Math.floor;
14440           var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < floor(refOffsets.bottom);
14441
14442           var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left);
14443           var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right);
14444           var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top);
14445           var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom);
14446
14447           var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom;
14448
14449           // flip the variation if required
14450           var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
14451
14452           // flips variation if reference element overflows boundaries
14453           var flippedVariationByRef = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft || isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && overflowsTop || !isVertical && variation === 'end' && overflowsBottom);
14454
14455           // flips variation if popper content overflows boundaries
14456           var flippedVariationByContent = !!options.flipVariationsByContent && (isVertical && variation === 'start' && overflowsRight || isVertical && variation === 'end' && overflowsLeft || !isVertical && variation === 'start' && overflowsBottom || !isVertical && variation === 'end' && overflowsTop);
14457
14458           var flippedVariation = flippedVariationByRef || flippedVariationByContent;
14459
14460           if (overlapsRef || overflowsBoundaries || flippedVariation) {
14461             // this boolean to detect any flip loop
14462             data.flipped = true;
14463
14464             if (overlapsRef || overflowsBoundaries) {
14465               placement = flipOrder[index + 1];
14466             }
14467
14468             if (flippedVariation) {
14469               variation = getOppositeVariation(variation);
14470             }
14471
14472             data.placement = placement + (variation ? '-' + variation : '');
14473
14474             // this object contains `position`, we want to preserve it along with
14475             // any additional property we may add in the future
14476             data.offsets.popper = _extends$1({}, data.offsets.popper, getPopperOffsets(data.instance.popper, data.offsets.reference, data.placement));
14477
14478             data = runModifiers(data.instance.modifiers, data, 'flip');
14479           }
14480         });
14481         return data;
14482       }
14483
14484       /**
14485        * @function
14486        * @memberof Modifiers
14487        * @argument {Object} data - The data object generated by update method
14488        * @argument {Object} options - Modifiers configuration and options
14489        * @returns {Object} The data object, properly modified
14490        */
14491       function keepTogether(data) {
14492         var _data$offsets = data.offsets,
14493             popper = _data$offsets.popper,
14494             reference = _data$offsets.reference;
14495
14496         var placement = data.placement.split('-')[0];
14497         var floor = Math.floor;
14498         var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
14499         var side = isVertical ? 'right' : 'bottom';
14500         var opSide = isVertical ? 'left' : 'top';
14501         var measurement = isVertical ? 'width' : 'height';
14502
14503         if (popper[side] < floor(reference[opSide])) {
14504           data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement];
14505         }
14506         if (popper[opSide] > floor(reference[side])) {
14507           data.offsets.popper[opSide] = floor(reference[side]);
14508         }
14509
14510         return data;
14511       }
14512
14513       /**
14514        * Converts a string containing value + unit into a px value number
14515        * @function
14516        * @memberof {modifiers~offset}
14517        * @private
14518        * @argument {String} str - Value + unit string
14519        * @argument {String} measurement - `height` or `width`
14520        * @argument {Object} popperOffsets
14521        * @argument {Object} referenceOffsets
14522        * @returns {Number|String}
14523        * Value in pixels, or original string if no values were extracted
14524        */
14525       function toValue(str, measurement, popperOffsets, referenceOffsets) {
14526         // separate value from unit
14527         var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/);
14528         var value = +split[1];
14529         var unit = split[2];
14530
14531         // If it's not a number it's an operator, I guess
14532         if (!value) {
14533           return str;
14534         }
14535
14536         if (unit.indexOf('%') === 0) {
14537           var element = void 0;
14538           switch (unit) {
14539             case '%p':
14540               element = popperOffsets;
14541               break;
14542             case '%':
14543             case '%r':
14544             default:
14545               element = referenceOffsets;
14546           }
14547
14548           var rect = getClientRect(element);
14549           return rect[measurement] / 100 * value;
14550         } else if (unit === 'vh' || unit === 'vw') {
14551           // if is a vh or vw, we calculate the size based on the viewport
14552           var size = void 0;
14553           if (unit === 'vh') {
14554             size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
14555           } else {
14556             size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
14557           }
14558           return size / 100 * value;
14559         } else {
14560           // if is an explicit pixel unit, we get rid of the unit and keep the value
14561           // if is an implicit unit, it's px, and we return just the value
14562           return value;
14563         }
14564       }
14565
14566       /**
14567        * Parse an `offset` string to extrapolate `x` and `y` numeric offsets.
14568        * @function
14569        * @memberof {modifiers~offset}
14570        * @private
14571        * @argument {String} offset
14572        * @argument {Object} popperOffsets
14573        * @argument {Object} referenceOffsets
14574        * @argument {String} basePlacement
14575        * @returns {Array} a two cells array with x and y offsets in numbers
14576        */
14577       function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) {
14578         var offsets = [0, 0];
14579
14580         // Use height if placement is left or right and index is 0 otherwise use width
14581         // in this way the first offset will use an axis and the second one
14582         // will use the other one
14583         var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1;
14584
14585         // Split the offset string to obtain a list of values and operands
14586         // The regex addresses values with the plus or minus sign in front (+10, -20, etc)
14587         var fragments = offset.split(/(\+|\-)/).map(function (frag) {
14588           return frag.trim();
14589         });
14590
14591         // Detect if the offset string contains a pair of values or a single one
14592         // they could be separated by comma or space
14593         var divider = fragments.indexOf(find(fragments, function (frag) {
14594           return frag.search(/,|\s/) !== -1;
14595         }));
14596
14597         if (fragments[divider] && fragments[divider].indexOf(',') === -1) {
14598           console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');
14599         }
14600
14601         // If divider is found, we divide the list of values and operands to divide
14602         // them by ofset X and Y.
14603         var splitRegex = /\s*,\s*|\s+/;
14604         var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), [fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments];
14605
14606         // Convert the values with units to absolute pixels to allow our computations
14607         ops = ops.map(function (op, index) {
14608           // Most of the units rely on the orientation of the popper
14609           var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width';
14610           var mergeWithPrevious = false;
14611           return op
14612           // This aggregates any `+` or `-` sign that aren't considered operators
14613           // e.g.: 10 + +5 => [10, +, +5]
14614           .reduce(function (a, b) {
14615             if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) {
14616               a[a.length - 1] = b;
14617               mergeWithPrevious = true;
14618               return a;
14619             } else if (mergeWithPrevious) {
14620               a[a.length - 1] += b;
14621               mergeWithPrevious = false;
14622               return a;
14623             } else {
14624               return a.concat(b);
14625             }
14626           }, [])
14627           // Here we convert the string values into number values (in px)
14628           .map(function (str) {
14629             return toValue(str, measurement, popperOffsets, referenceOffsets);
14630           });
14631         });
14632
14633         // Loop trough the offsets arrays and execute the operations
14634         ops.forEach(function (op, index) {
14635           op.forEach(function (frag, index2) {
14636             if (isNumeric(frag)) {
14637               offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1);
14638             }
14639           });
14640         });
14641         return offsets;
14642       }
14643
14644       /**
14645        * @function
14646        * @memberof Modifiers
14647        * @argument {Object} data - The data object generated by update method
14648        * @argument {Object} options - Modifiers configuration and options
14649        * @argument {Number|String} options.offset=0
14650        * The offset value as described in the modifier description
14651        * @returns {Object} The data object, properly modified
14652        */
14653       function offset(data, _ref) {
14654         var offset = _ref.offset;
14655         var placement = data.placement,
14656             _data$offsets = data.offsets,
14657             popper = _data$offsets.popper,
14658             reference = _data$offsets.reference;
14659
14660         var basePlacement = placement.split('-')[0];
14661
14662         var offsets = void 0;
14663         if (isNumeric(+offset)) {
14664           offsets = [+offset, 0];
14665         } else {
14666           offsets = parseOffset(offset, popper, reference, basePlacement);
14667         }
14668
14669         if (basePlacement === 'left') {
14670           popper.top += offsets[0];
14671           popper.left -= offsets[1];
14672         } else if (basePlacement === 'right') {
14673           popper.top += offsets[0];
14674           popper.left += offsets[1];
14675         } else if (basePlacement === 'top') {
14676           popper.left += offsets[0];
14677           popper.top -= offsets[1];
14678         } else if (basePlacement === 'bottom') {
14679           popper.left += offsets[0];
14680           popper.top += offsets[1];
14681         }
14682
14683         data.popper = popper;
14684         return data;
14685       }
14686
14687       /**
14688        * @function
14689        * @memberof Modifiers
14690        * @argument {Object} data - The data object generated by `update` method
14691        * @argument {Object} options - Modifiers configuration and options
14692        * @returns {Object} The data object, properly modified
14693        */
14694       function preventOverflow(data, options) {
14695         var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper);
14696
14697         // If offsetParent is the reference element, we really want to
14698         // go one step up and use the next offsetParent as reference to
14699         // avoid to make this modifier completely useless and look like broken
14700         if (data.instance.reference === boundariesElement) {
14701           boundariesElement = getOffsetParent(boundariesElement);
14702         }
14703
14704         // NOTE: DOM access here
14705         // resets the popper's position so that the document size can be calculated excluding
14706         // the size of the popper element itself
14707         var transformProp = getSupportedPropertyName('transform');
14708         var popperStyles = data.instance.popper.style; // assignment to help minification
14709         var top = popperStyles.top,
14710             left = popperStyles.left,
14711             transform = popperStyles[transformProp];
14712
14713         popperStyles.top = '';
14714         popperStyles.left = '';
14715         popperStyles[transformProp] = '';
14716
14717         var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, boundariesElement, data.positionFixed);
14718
14719         // NOTE: DOM access here
14720         // restores the original style properties after the offsets have been computed
14721         popperStyles.top = top;
14722         popperStyles.left = left;
14723         popperStyles[transformProp] = transform;
14724
14725         options.boundaries = boundaries;
14726
14727         var order = options.priority;
14728         var popper = data.offsets.popper;
14729
14730         var check = {
14731           primary: function primary(placement) {
14732             var value = popper[placement];
14733             if (popper[placement] < boundaries[placement] && !options.escapeWithReference) {
14734               value = Math.max(popper[placement], boundaries[placement]);
14735             }
14736             return defineProperty({}, placement, value);
14737           },
14738           secondary: function secondary(placement) {
14739             var mainSide = placement === 'right' ? 'left' : 'top';
14740             var value = popper[mainSide];
14741             if (popper[placement] > boundaries[placement] && !options.escapeWithReference) {
14742               value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : popper.height));
14743             }
14744             return defineProperty({}, mainSide, value);
14745           }
14746         };
14747
14748         order.forEach(function (placement) {
14749           var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';
14750           popper = _extends$1({}, popper, check[side](placement));
14751         });
14752
14753         data.offsets.popper = popper;
14754
14755         return data;
14756       }
14757
14758       /**
14759        * @function
14760        * @memberof Modifiers
14761        * @argument {Object} data - The data object generated by `update` method
14762        * @argument {Object} options - Modifiers configuration and options
14763        * @returns {Object} The data object, properly modified
14764        */
14765       function shift(data) {
14766         var placement = data.placement;
14767         var basePlacement = placement.split('-')[0];
14768         var shiftvariation = placement.split('-')[1];
14769
14770         // if shift shiftvariation is specified, run the modifier
14771         if (shiftvariation) {
14772           var _data$offsets = data.offsets,
14773               reference = _data$offsets.reference,
14774               popper = _data$offsets.popper;
14775
14776           var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;
14777           var side = isVertical ? 'left' : 'top';
14778           var measurement = isVertical ? 'width' : 'height';
14779
14780           var shiftOffsets = {
14781             start: defineProperty({}, side, reference[side]),
14782             end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement])
14783           };
14784
14785           data.offsets.popper = _extends$1({}, popper, shiftOffsets[shiftvariation]);
14786         }
14787
14788         return data;
14789       }
14790
14791       /**
14792        * @function
14793        * @memberof Modifiers
14794        * @argument {Object} data - The data object generated by update method
14795        * @argument {Object} options - Modifiers configuration and options
14796        * @returns {Object} The data object, properly modified
14797        */
14798       function hide(data) {
14799         if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) {
14800           return data;
14801         }
14802
14803         var refRect = data.offsets.reference;
14804         var bound = find(data.instance.modifiers, function (modifier) {
14805           return modifier.name === 'preventOverflow';
14806         }).boundaries;
14807
14808         if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || refRect.right < bound.left) {
14809           // Avoid unnecessary DOM access if visibility hasn't changed
14810           if (data.hide === true) {
14811             return data;
14812           }
14813
14814           data.hide = true;
14815           data.attributes['x-out-of-boundaries'] = '';
14816         } else {
14817           // Avoid unnecessary DOM access if visibility hasn't changed
14818           if (data.hide === false) {
14819             return data;
14820           }
14821
14822           data.hide = false;
14823           data.attributes['x-out-of-boundaries'] = false;
14824         }
14825
14826         return data;
14827       }
14828
14829       /**
14830        * @function
14831        * @memberof Modifiers
14832        * @argument {Object} data - The data object generated by `update` method
14833        * @argument {Object} options - Modifiers configuration and options
14834        * @returns {Object} The data object, properly modified
14835        */
14836       function inner(data) {
14837         var placement = data.placement;
14838         var basePlacement = placement.split('-')[0];
14839         var _data$offsets = data.offsets,
14840             popper = _data$offsets.popper,
14841             reference = _data$offsets.reference;
14842
14843         var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1;
14844
14845         var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1;
14846
14847         popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 'height'] : 0);
14848
14849         data.placement = getOppositePlacement(placement);
14850         data.offsets.popper = getClientRect(popper);
14851
14852         return data;
14853       }
14854
14855       /**
14856        * Modifier function, each modifier can have a function of this type assigned
14857        * to its `fn` property.<br />
14858        * These functions will be called on each update, this means that you must
14859        * make sure they are performant enough to avoid performance bottlenecks.
14860        *
14861        * @function ModifierFn
14862        * @argument {dataObject} data - The data object generated by `update` method
14863        * @argument {Object} options - Modifiers configuration and options
14864        * @returns {dataObject} The data object, properly modified
14865        */
14866
14867       /**
14868        * Modifiers are plugins used to alter the behavior of your poppers.<br />
14869        * Popper.js uses a set of 9 modifiers to provide all the basic functionalities
14870        * needed by the library.
14871        *
14872        * Usually you don't want to override the `order`, `fn` and `onLoad` props.
14873        * All the other properties are configurations that could be tweaked.
14874        * @namespace modifiers
14875        */
14876       var modifiers = {
14877         /**
14878          * Modifier used to shift the popper on the start or end of its reference
14879          * element.<br />
14880          * It will read the variation of the `placement` property.<br />
14881          * It can be one either `-end` or `-start`.
14882          * @memberof modifiers
14883          * @inner
14884          */
14885         shift: {
14886           /** @prop {number} order=100 - Index used to define the order of execution */
14887           order: 100,
14888           /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
14889           enabled: true,
14890           /** @prop {ModifierFn} */
14891           fn: shift
14892         },
14893
14894         /**
14895          * The `offset` modifier can shift your popper on both its axis.
14896          *
14897          * It accepts the following units:
14898          * - `px` or unit-less, interpreted as pixels
14899          * - `%` or `%r`, percentage relative to the length of the reference element
14900          * - `%p`, percentage relative to the length of the popper element
14901          * - `vw`, CSS viewport width unit
14902          * - `vh`, CSS viewport height unit
14903          *
14904          * For length is intended the main axis relative to the placement of the popper.<br />
14905          * This means that if the placement is `top` or `bottom`, the length will be the
14906          * `width`. In case of `left` or `right`, it will be the `height`.
14907          *
14908          * You can provide a single value (as `Number` or `String`), or a pair of values
14909          * as `String` divided by a comma or one (or more) white spaces.<br />
14910          * The latter is a deprecated method because it leads to confusion and will be
14911          * removed in v2.<br />
14912          * Additionally, it accepts additions and subtractions between different units.
14913          * Note that multiplications and divisions aren't supported.
14914          *
14915          * Valid examples are:
14916          * ```
14917          * 10
14918          * '10%'
14919          * '10, 10'
14920          * '10%, 10'
14921          * '10 + 10%'
14922          * '10 - 5vh + 3%'
14923          * '-10px + 5vh, 5px - 6%'
14924          * ```
14925          * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap
14926          * > with their reference element, unfortunately, you will have to disable the `flip` modifier.
14927          * > You can read more on this at this [issue](https://github.com/FezVrasta/popper.js/issues/373).
14928          *
14929          * @memberof modifiers
14930          * @inner
14931          */
14932         offset: {
14933           /** @prop {number} order=200 - Index used to define the order of execution */
14934           order: 200,
14935           /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
14936           enabled: true,
14937           /** @prop {ModifierFn} */
14938           fn: offset,
14939           /** @prop {Number|String} offset=0
14940            * The offset value as described in the modifier description
14941            */
14942           offset: 0
14943         },
14944
14945         /**
14946          * Modifier used to prevent the popper from being positioned outside the boundary.
14947          *
14948          * A scenario exists where the reference itself is not within the boundaries.<br />
14949          * We can say it has "escaped the boundaries" â€” or just "escaped".<br />
14950          * In this case we need to decide whether the popper should either:
14951          *
14952          * - detach from the reference and remain "trapped" in the boundaries, or
14953          * - if it should ignore the boundary and "escape with its reference"
14954          *
14955          * When `escapeWithReference` is set to`true` and reference is completely
14956          * outside its boundaries, the popper will overflow (or completely leave)
14957          * the boundaries in order to remain attached to the edge of the reference.
14958          *
14959          * @memberof modifiers
14960          * @inner
14961          */
14962         preventOverflow: {
14963           /** @prop {number} order=300 - Index used to define the order of execution */
14964           order: 300,
14965           /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
14966           enabled: true,
14967           /** @prop {ModifierFn} */
14968           fn: preventOverflow,
14969           /**
14970            * @prop {Array} [priority=['left','right','top','bottom']]
14971            * Popper will try to prevent overflow following these priorities by default,
14972            * then, it could overflow on the left and on top of the `boundariesElement`
14973            */
14974           priority: ['left', 'right', 'top', 'bottom'],
14975           /**
14976            * @prop {number} padding=5
14977            * Amount of pixel used to define a minimum distance between the boundaries
14978            * and the popper. This makes sure the popper always has a little padding
14979            * between the edges of its container
14980            */
14981           padding: 5,
14982           /**
14983            * @prop {String|HTMLElement} boundariesElement='scrollParent'
14984            * Boundaries used by the modifier. Can be `scrollParent`, `window`,
14985            * `viewport` or any DOM element.
14986            */
14987           boundariesElement: 'scrollParent'
14988         },
14989
14990         /**
14991          * Modifier used to make sure the reference and its popper stay near each other
14992          * without leaving any gap between the two. Especially useful when the arrow is
14993          * enabled and you want to ensure that it points to its reference element.
14994          * It cares only about the first axis. You can still have poppers with margin
14995          * between the popper and its reference element.
14996          * @memberof modifiers
14997          * @inner
14998          */
14999         keepTogether: {
15000           /** @prop {number} order=400 - Index used to define the order of execution */
15001           order: 400,
15002           /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
15003           enabled: true,
15004           /** @prop {ModifierFn} */
15005           fn: keepTogether
15006         },
15007
15008         /**
15009          * This modifier is used to move the `arrowElement` of the popper to make
15010          * sure it is positioned between the reference element and its popper element.
15011          * It will read the outer size of the `arrowElement` node to detect how many
15012          * pixels of conjunction are needed.
15013          *
15014          * It has no effect if no `arrowElement` is provided.
15015          * @memberof modifiers
15016          * @inner
15017          */
15018         arrow: {
15019           /** @prop {number} order=500 - Index used to define the order of execution */
15020           order: 500,
15021           /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
15022           enabled: true,
15023           /** @prop {ModifierFn} */
15024           fn: arrow,
15025           /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */
15026           element: '[x-arrow]'
15027         },
15028
15029         /**
15030          * Modifier used to flip the popper's placement when it starts to overlap its
15031          * reference element.
15032          *
15033          * Requires the `preventOverflow` modifier before it in order to work.
15034          *
15035          * **NOTE:** this modifier will interrupt the current update cycle and will
15036          * restart it if it detects the need to flip the placement.
15037          * @memberof modifiers
15038          * @inner
15039          */
15040         flip: {
15041           /** @prop {number} order=600 - Index used to define the order of execution */
15042           order: 600,
15043           /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
15044           enabled: true,
15045           /** @prop {ModifierFn} */
15046           fn: flip,
15047           /**
15048            * @prop {String|Array} behavior='flip'
15049            * The behavior used to change the popper's placement. It can be one of
15050            * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid
15051            * placements (with optional variations)
15052            */
15053           behavior: 'flip',
15054           /**
15055            * @prop {number} padding=5
15056            * The popper will flip if it hits the edges of the `boundariesElement`
15057            */
15058           padding: 5,
15059           /**
15060            * @prop {String|HTMLElement} boundariesElement='viewport'
15061            * The element which will define the boundaries of the popper position.
15062            * The popper will never be placed outside of the defined boundaries
15063            * (except if `keepTogether` is enabled)
15064            */
15065           boundariesElement: 'viewport',
15066           /**
15067            * @prop {Boolean} flipVariations=false
15068            * The popper will switch placement variation between `-start` and `-end` when
15069            * the reference element overlaps its boundaries.
15070            *
15071            * The original placement should have a set variation.
15072            */
15073           flipVariations: false,
15074           /**
15075            * @prop {Boolean} flipVariationsByContent=false
15076            * The popper will switch placement variation between `-start` and `-end` when
15077            * the popper element overlaps its reference boundaries.
15078            *
15079            * The original placement should have a set variation.
15080            */
15081           flipVariationsByContent: false
15082         },
15083
15084         /**
15085          * Modifier used to make the popper flow toward the inner of the reference element.
15086          * By default, when this modifier is disabled, the popper will be placed outside
15087          * the reference element.
15088          * @memberof modifiers
15089          * @inner
15090          */
15091         inner: {
15092           /** @prop {number} order=700 - Index used to define the order of execution */
15093           order: 700,
15094           /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */
15095           enabled: false,
15096           /** @prop {ModifierFn} */
15097           fn: inner
15098         },
15099
15100         /**
15101          * Modifier used to hide the popper when its reference element is outside of the
15102          * popper boundaries. It will set a `x-out-of-boundaries` attribute which can
15103          * be used to hide with a CSS selector the popper when its reference is
15104          * out of boundaries.
15105          *
15106          * Requires the `preventOverflow` modifier before it in order to work.
15107          * @memberof modifiers
15108          * @inner
15109          */
15110         hide: {
15111           /** @prop {number} order=800 - Index used to define the order of execution */
15112           order: 800,
15113           /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
15114           enabled: true,
15115           /** @prop {ModifierFn} */
15116           fn: hide
15117         },
15118
15119         /**
15120          * Computes the style that will be applied to the popper element to gets
15121          * properly positioned.
15122          *
15123          * Note that this modifier will not touch the DOM, it just prepares the styles
15124          * so that `applyStyle` modifier can apply it. This separation is useful
15125          * in case you need to replace `applyStyle` with a custom implementation.
15126          *
15127          * This modifier has `850` as `order` value to maintain backward compatibility
15128          * with previous versions of Popper.js. Expect the modifiers ordering method
15129          * to change in future major versions of the library.
15130          *
15131          * @memberof modifiers
15132          * @inner
15133          */
15134         computeStyle: {
15135           /** @prop {number} order=850 - Index used to define the order of execution */
15136           order: 850,
15137           /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
15138           enabled: true,
15139           /** @prop {ModifierFn} */
15140           fn: computeStyle,
15141           /**
15142            * @prop {Boolean} gpuAcceleration=true
15143            * If true, it uses the CSS 3D transformation to position the popper.
15144            * Otherwise, it will use the `top` and `left` properties
15145            */
15146           gpuAcceleration: true,
15147           /**
15148            * @prop {string} [x='bottom']
15149            * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin.
15150            * Change this if your popper should grow in a direction different from `bottom`
15151            */
15152           x: 'bottom',
15153           /**
15154            * @prop {string} [x='left']
15155            * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin.
15156            * Change this if your popper should grow in a direction different from `right`
15157            */
15158           y: 'right'
15159         },
15160
15161         /**
15162          * Applies the computed styles to the popper element.
15163          *
15164          * All the DOM manipulations are limited to this modifier. This is useful in case
15165          * you want to integrate Popper.js inside a framework or view library and you
15166          * want to delegate all the DOM manipulations to it.
15167          *
15168          * Note that if you disable this modifier, you must make sure the popper element
15169          * has its position set to `absolute` before Popper.js can do its work!
15170          *
15171          * Just disable this modifier and define your own to achieve the desired effect.
15172          *
15173          * @memberof modifiers
15174          * @inner
15175          */
15176         applyStyle: {
15177           /** @prop {number} order=900 - Index used to define the order of execution */
15178           order: 900,
15179           /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
15180           enabled: true,
15181           /** @prop {ModifierFn} */
15182           fn: applyStyle,
15183           /** @prop {Function} */
15184           onLoad: applyStyleOnLoad,
15185           /**
15186            * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier
15187            * @prop {Boolean} gpuAcceleration=true
15188            * If true, it uses the CSS 3D transformation to position the popper.
15189            * Otherwise, it will use the `top` and `left` properties
15190            */
15191           gpuAcceleration: undefined
15192         }
15193       };
15194
15195       /**
15196        * The `dataObject` is an object containing all the information used by Popper.js.
15197        * This object is passed to modifiers and to the `onCreate` and `onUpdate` callbacks.
15198        * @name dataObject
15199        * @property {Object} data.instance The Popper.js instance
15200        * @property {String} data.placement Placement applied to popper
15201        * @property {String} data.originalPlacement Placement originally defined on init
15202        * @property {Boolean} data.flipped True if popper has been flipped by flip modifier
15203        * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to hide the popper
15204        * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier
15205        * @property {Object} data.styles Any CSS property defined here will be applied to the popper. It expects the JavaScript nomenclature (eg. `marginBottom`)
15206        * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow. It expects the JavaScript nomenclature (eg. `marginBottom`)
15207        * @property {Object} data.boundaries Offsets of the popper boundaries
15208        * @property {Object} data.offsets The measurements of popper, reference and arrow elements
15209        * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values
15210        * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values
15211        * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0
15212        */
15213
15214       /**
15215        * Default options provided to Popper.js constructor.<br />
15216        * These can be overridden using the `options` argument of Popper.js.<br />
15217        * To override an option, simply pass an object with the same
15218        * structure of the `options` object, as the 3rd argument. For example:
15219        * ```
15220        * new Popper(ref, pop, {
15221        *   modifiers: {
15222        *     preventOverflow: { enabled: false }
15223        *   }
15224        * })
15225        * ```
15226        * @type {Object}
15227        * @static
15228        * @memberof Popper
15229        */
15230       var Defaults = {
15231         /**
15232          * Popper's placement.
15233          * @prop {Popper.placements} placement='bottom'
15234          */
15235         placement: 'bottom',
15236
15237         /**
15238          * Set this to true if you want popper to position it self in 'fixed' mode
15239          * @prop {Boolean} positionFixed=false
15240          */
15241         positionFixed: false,
15242
15243         /**
15244          * Whether events (resize, scroll) are initially enabled.
15245          * @prop {Boolean} eventsEnabled=true
15246          */
15247         eventsEnabled: true,
15248
15249         /**
15250          * Set to true if you want to automatically remove the popper when
15251          * you call the `destroy` method.
15252          * @prop {Boolean} removeOnDestroy=false
15253          */
15254         removeOnDestroy: false,
15255
15256         /**
15257          * Callback called when the popper is created.<br />
15258          * By default, it is set to no-op.<br />
15259          * Access Popper.js instance with `data.instance`.
15260          * @prop {onCreate}
15261          */
15262         onCreate: function onCreate() {},
15263
15264         /**
15265          * Callback called when the popper is updated. This callback is not called
15266          * on the initialization/creation of the popper, but only on subsequent
15267          * updates.<br />
15268          * By default, it is set to no-op.<br />
15269          * Access Popper.js instance with `data.instance`.
15270          * @prop {onUpdate}
15271          */
15272         onUpdate: function onUpdate() {},
15273
15274         /**
15275          * List of modifiers used to modify the offsets before they are applied to the popper.
15276          * They provide most of the functionalities of Popper.js.
15277          * @prop {modifiers}
15278          */
15279         modifiers: modifiers
15280       };
15281
15282       /**
15283        * @callback onCreate
15284        * @param {dataObject} data
15285        */
15286
15287       /**
15288        * @callback onUpdate
15289        * @param {dataObject} data
15290        */
15291
15292       // Utils
15293       // Methods
15294       var Popper = function () {
15295         /**
15296          * Creates a new Popper.js instance.
15297          * @class Popper
15298          * @param {Element|referenceObject} reference - The reference element used to position the popper
15299          * @param {Element} popper - The HTML / XML element used as the popper
15300          * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults)
15301          * @return {Object} instance - The generated Popper.js instance
15302          */
15303         function Popper(reference, popper) {
15304           var _this = this;
15305
15306           var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
15307           classCallCheck(this, Popper);
15308
15309           this.scheduleUpdate = function () {
15310             return requestAnimationFrame(_this.update);
15311           };
15312
15313           // make update() debounced, so that it only runs at most once-per-tick
15314           this.update = debounce(this.update.bind(this));
15315
15316           // with {} we create a new object with the options inside it
15317           this.options = _extends$1({}, Popper.Defaults, options);
15318
15319           // init state
15320           this.state = {
15321             isDestroyed: false,
15322             isCreated: false,
15323             scrollParents: []
15324           };
15325
15326           // get reference and popper elements (allow jQuery wrappers)
15327           this.reference = reference && reference.jquery ? reference[0] : reference;
15328           this.popper = popper && popper.jquery ? popper[0] : popper;
15329
15330           // Deep merge modifiers options
15331           this.options.modifiers = {};
15332           Object.keys(_extends$1({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) {
15333             _this.options.modifiers[name] = _extends$1({}, Popper.Defaults.modifiers[name] || {}, options.modifiers ? options.modifiers[name] : {});
15334           });
15335
15336           // Refactoring modifiers' list (Object => Array)
15337           this.modifiers = Object.keys(this.options.modifiers).map(function (name) {
15338             return _extends$1({
15339               name: name
15340             }, _this.options.modifiers[name]);
15341           })
15342           // sort the modifiers by order
15343           .sort(function (a, b) {
15344             return a.order - b.order;
15345           });
15346
15347           // modifiers have the ability to execute arbitrary code when Popper.js get inited
15348           // such code is executed in the same order of its modifier
15349           // they could add new properties to their options configuration
15350           // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`!
15351           this.modifiers.forEach(function (modifierOptions) {
15352             if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) {
15353               modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state);
15354             }
15355           });
15356
15357           // fire the first update to position the popper in the right place
15358           this.update();
15359
15360           var eventsEnabled = this.options.eventsEnabled;
15361           if (eventsEnabled) {
15362             // setup event listeners, they will take care of update the position in specific situations
15363             this.enableEventListeners();
15364           }
15365
15366           this.state.eventsEnabled = eventsEnabled;
15367         }
15368
15369         // We can't use class properties because they don't get listed in the
15370         // class prototype and break stuff like Sinon stubs
15371
15372
15373         createClass(Popper, [{
15374           key: 'update',
15375           value: function update$$1() {
15376             return update.call(this);
15377           }
15378         }, {
15379           key: 'destroy',
15380           value: function destroy$$1() {
15381             return destroy.call(this);
15382           }
15383         }, {
15384           key: 'enableEventListeners',
15385           value: function enableEventListeners$$1() {
15386             return enableEventListeners.call(this);
15387           }
15388         }, {
15389           key: 'disableEventListeners',
15390           value: function disableEventListeners$$1() {
15391             return disableEventListeners.call(this);
15392           }
15393
15394           /**
15395            * Schedules an update. It will run on the next UI update available.
15396            * @method scheduleUpdate
15397            * @memberof Popper
15398            */
15399
15400
15401           /**
15402            * Collection of utilities useful when writing custom modifiers.
15403            * Starting from version 1.7, this method is available only if you
15404            * include `popper-utils.js` before `popper.js`.
15405            *
15406            * **DEPRECATION**: This way to access PopperUtils is deprecated
15407            * and will be removed in v2! Use the PopperUtils module directly instead.
15408            * Due to the high instability of the methods contained in Utils, we can't
15409            * guarantee them to follow semver. Use them at your own risk!
15410            * @static
15411            * @private
15412            * @type {Object}
15413            * @deprecated since version 1.8
15414            * @member Utils
15415            * @memberof Popper
15416            */
15417
15418         }]);
15419         return Popper;
15420       }();
15421
15422       /**
15423        * The `referenceObject` is an object that provides an interface compatible with Popper.js
15424        * and lets you use it as replacement of a real DOM node.<br />
15425        * You can use this method to position a popper relatively to a set of coordinates
15426        * in case you don't have a DOM node to use as reference.
15427        *
15428        * ```
15429        * new Popper(referenceObject, popperNode);
15430        * ```
15431        *
15432        * NB: This feature isn't supported in Internet Explorer 10.
15433        * @name referenceObject
15434        * @property {Function} data.getBoundingClientRect
15435        * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method.
15436        * @property {number} data.clientWidth
15437        * An ES6 getter that will return the width of the virtual reference element.
15438        * @property {number} data.clientHeight
15439        * An ES6 getter that will return the height of the virtual reference element.
15440        */
15441
15442
15443       Popper.Utils = (typeof window !== 'undefined' ? window : commonjsGlobal).PopperUtils;
15444       Popper.placements = placements;
15445       Popper.Defaults = Defaults;
15446
15447       /**
15448        * ------------------------------------------------------------------------
15449        * Constants
15450        * ------------------------------------------------------------------------
15451        */
15452
15453       var NAME$4 = 'dropdown';
15454       var VERSION$4 = '4.6.0';
15455       var DATA_KEY$4 = 'bs.dropdown';
15456       var EVENT_KEY$4 = "." + DATA_KEY$4;
15457       var DATA_API_KEY$4 = '.data-api';
15458       var JQUERY_NO_CONFLICT$4 = $__default['default'].fn[NAME$4];
15459       var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
15460
15461       var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key
15462
15463       var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key
15464
15465       var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key
15466
15467       var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key
15468
15469       var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed mouse)
15470
15471       var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE);
15472       var EVENT_HIDE$1 = "hide" + EVENT_KEY$4;
15473       var EVENT_HIDDEN$1 = "hidden" + EVENT_KEY$4;
15474       var EVENT_SHOW$1 = "show" + EVENT_KEY$4;
15475       var EVENT_SHOWN$1 = "shown" + EVENT_KEY$4;
15476       var EVENT_CLICK = "click" + EVENT_KEY$4;
15477       var EVENT_CLICK_DATA_API$4 = "click" + EVENT_KEY$4 + DATA_API_KEY$4;
15478       var EVENT_KEYDOWN_DATA_API = "keydown" + EVENT_KEY$4 + DATA_API_KEY$4;
15479       var EVENT_KEYUP_DATA_API = "keyup" + EVENT_KEY$4 + DATA_API_KEY$4;
15480       var CLASS_NAME_DISABLED = 'disabled';
15481       var CLASS_NAME_SHOW$2 = 'show';
15482       var CLASS_NAME_DROPUP = 'dropup';
15483       var CLASS_NAME_DROPRIGHT = 'dropright';
15484       var CLASS_NAME_DROPLEFT = 'dropleft';
15485       var CLASS_NAME_MENURIGHT = 'dropdown-menu-right';
15486       var CLASS_NAME_POSITION_STATIC = 'position-static';
15487       var SELECTOR_DATA_TOGGLE$2 = '[data-toggle="dropdown"]';
15488       var SELECTOR_FORM_CHILD = '.dropdown form';
15489       var SELECTOR_MENU = '.dropdown-menu';
15490       var SELECTOR_NAVBAR_NAV = '.navbar-nav';
15491       var SELECTOR_VISIBLE_ITEMS = '.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)';
15492       var PLACEMENT_TOP = 'top-start';
15493       var PLACEMENT_TOPEND = 'top-end';
15494       var PLACEMENT_BOTTOM = 'bottom-start';
15495       var PLACEMENT_BOTTOMEND = 'bottom-end';
15496       var PLACEMENT_RIGHT = 'right-start';
15497       var PLACEMENT_LEFT = 'left-start';
15498       var Default$2 = {
15499         offset: 0,
15500         flip: true,
15501         boundary: 'scrollParent',
15502         reference: 'toggle',
15503         display: 'dynamic',
15504         popperConfig: null
15505       };
15506       var DefaultType$2 = {
15507         offset: '(number|string|function)',
15508         flip: 'boolean',
15509         boundary: '(string|element)',
15510         reference: '(string|element)',
15511         display: 'string',
15512         popperConfig: '(null|object)'
15513       };
15514       /**
15515        * ------------------------------------------------------------------------
15516        * Class Definition
15517        * ------------------------------------------------------------------------
15518        */
15519
15520       var Dropdown = /*#__PURE__*/function () {
15521         function Dropdown(element, config) {
15522           this._element = element;
15523           this._popper = null;
15524           this._config = this._getConfig(config);
15525           this._menu = this._getMenuElement();
15526           this._inNavbar = this._detectNavbar();
15527
15528           this._addEventListeners();
15529         } // Getters
15530
15531
15532         var _proto = Dropdown.prototype;
15533
15534         // Public
15535         _proto.toggle = function toggle() {
15536           if (this._element.disabled || $__default['default'](this._element).hasClass(CLASS_NAME_DISABLED)) {
15537             return;
15538           }
15539
15540           var isActive = $__default['default'](this._menu).hasClass(CLASS_NAME_SHOW$2);
15541
15542           Dropdown._clearMenus();
15543
15544           if (isActive) {
15545             return;
15546           }
15547
15548           this.show(true);
15549         };
15550
15551         _proto.show = function show(usePopper) {
15552           if (usePopper === void 0) {
15553             usePopper = false;
15554           }
15555
15556           if (this._element.disabled || $__default['default'](this._element).hasClass(CLASS_NAME_DISABLED) || $__default['default'](this._menu).hasClass(CLASS_NAME_SHOW$2)) {
15557             return;
15558           }
15559
15560           var relatedTarget = {
15561             relatedTarget: this._element
15562           };
15563           var showEvent = $__default['default'].Event(EVENT_SHOW$1, relatedTarget);
15564
15565           var parent = Dropdown._getParentFromElement(this._element);
15566
15567           $__default['default'](parent).trigger(showEvent);
15568
15569           if (showEvent.isDefaultPrevented()) {
15570             return;
15571           } // Totally disable Popper for Dropdowns in Navbar
15572
15573
15574           if (!this._inNavbar && usePopper) {
15575             /**
15576              * Check for Popper dependency
15577              * Popper - https://popper.js.org
15578              */
15579             if (typeof Popper === 'undefined') {
15580               throw new TypeError('Bootstrap\'s dropdowns require Popper (https://popper.js.org)');
15581             }
15582
15583             var referenceElement = this._element;
15584
15585             if (this._config.reference === 'parent') {
15586               referenceElement = parent;
15587             } else if (Util.isElement(this._config.reference)) {
15588               referenceElement = this._config.reference; // Check if it's jQuery element
15589
15590               if (typeof this._config.reference.jquery !== 'undefined') {
15591                 referenceElement = this._config.reference[0];
15592               }
15593             } // If boundary is not `scrollParent`, then set position to `static`
15594             // to allow the menu to "escape" the scroll parent's boundaries
15595             // https://github.com/twbs/bootstrap/issues/24251
15596
15597
15598             if (this._config.boundary !== 'scrollParent') {
15599               $__default['default'](parent).addClass(CLASS_NAME_POSITION_STATIC);
15600             }
15601
15602             this._popper = new Popper(referenceElement, this._menu, this._getPopperConfig());
15603           } // If this is a touch-enabled device we add extra
15604           // empty mouseover listeners to the body's immediate children;
15605           // only needed because of broken event delegation on iOS
15606           // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
15607
15608
15609           if ('ontouchstart' in document.documentElement && $__default['default'](parent).closest(SELECTOR_NAVBAR_NAV).length === 0) {
15610             $__default['default'](document.body).children().on('mouseover', null, $__default['default'].noop);
15611           }
15612
15613           this._element.focus();
15614
15615           this._element.setAttribute('aria-expanded', true);
15616
15617           $__default['default'](this._menu).toggleClass(CLASS_NAME_SHOW$2);
15618           $__default['default'](parent).toggleClass(CLASS_NAME_SHOW$2).trigger($__default['default'].Event(EVENT_SHOWN$1, relatedTarget));
15619         };
15620
15621         _proto.hide = function hide() {
15622           if (this._element.disabled || $__default['default'](this._element).hasClass(CLASS_NAME_DISABLED) || !$__default['default'](this._menu).hasClass(CLASS_NAME_SHOW$2)) {
15623             return;
15624           }
15625
15626           var relatedTarget = {
15627             relatedTarget: this._element
15628           };
15629           var hideEvent = $__default['default'].Event(EVENT_HIDE$1, relatedTarget);
15630
15631           var parent = Dropdown._getParentFromElement(this._element);
15632
15633           $__default['default'](parent).trigger(hideEvent);
15634
15635           if (hideEvent.isDefaultPrevented()) {
15636             return;
15637           }
15638
15639           if (this._popper) {
15640             this._popper.destroy();
15641           }
15642
15643           $__default['default'](this._menu).toggleClass(CLASS_NAME_SHOW$2);
15644           $__default['default'](parent).toggleClass(CLASS_NAME_SHOW$2).trigger($__default['default'].Event(EVENT_HIDDEN$1, relatedTarget));
15645         };
15646
15647         _proto.dispose = function dispose() {
15648           $__default['default'].removeData(this._element, DATA_KEY$4);
15649           $__default['default'](this._element).off(EVENT_KEY$4);
15650           this._element = null;
15651           this._menu = null;
15652
15653           if (this._popper !== null) {
15654             this._popper.destroy();
15655
15656             this._popper = null;
15657           }
15658         };
15659
15660         _proto.update = function update() {
15661           this._inNavbar = this._detectNavbar();
15662
15663           if (this._popper !== null) {
15664             this._popper.scheduleUpdate();
15665           }
15666         } // Private
15667         ;
15668
15669         _proto._addEventListeners = function _addEventListeners() {
15670           var _this = this;
15671
15672           $__default['default'](this._element).on(EVENT_CLICK, function (event) {
15673             event.preventDefault();
15674             event.stopPropagation();
15675
15676             _this.toggle();
15677           });
15678         };
15679
15680         _proto._getConfig = function _getConfig(config) {
15681           config = _extends({}, this.constructor.Default, $__default['default'](this._element).data(), config);
15682           Util.typeCheckConfig(NAME$4, config, this.constructor.DefaultType);
15683           return config;
15684         };
15685
15686         _proto._getMenuElement = function _getMenuElement() {
15687           if (!this._menu) {
15688             var parent = Dropdown._getParentFromElement(this._element);
15689
15690             if (parent) {
15691               this._menu = parent.querySelector(SELECTOR_MENU);
15692             }
15693           }
15694
15695           return this._menu;
15696         };
15697
15698         _proto._getPlacement = function _getPlacement() {
15699           var $parentDropdown = $__default['default'](this._element.parentNode);
15700           var placement = PLACEMENT_BOTTOM; // Handle dropup
15701
15702           if ($parentDropdown.hasClass(CLASS_NAME_DROPUP)) {
15703             placement = $__default['default'](this._menu).hasClass(CLASS_NAME_MENURIGHT) ? PLACEMENT_TOPEND : PLACEMENT_TOP;
15704           } else if ($parentDropdown.hasClass(CLASS_NAME_DROPRIGHT)) {
15705             placement = PLACEMENT_RIGHT;
15706           } else if ($parentDropdown.hasClass(CLASS_NAME_DROPLEFT)) {
15707             placement = PLACEMENT_LEFT;
15708           } else if ($__default['default'](this._menu).hasClass(CLASS_NAME_MENURIGHT)) {
15709             placement = PLACEMENT_BOTTOMEND;
15710           }
15711
15712           return placement;
15713         };
15714
15715         _proto._detectNavbar = function _detectNavbar() {
15716           return $__default['default'](this._element).closest('.navbar').length > 0;
15717         };
15718
15719         _proto._getOffset = function _getOffset() {
15720           var _this2 = this;
15721
15722           var offset = {};
15723
15724           if (typeof this._config.offset === 'function') {
15725             offset.fn = function (data) {
15726               data.offsets = _extends({}, data.offsets, _this2._config.offset(data.offsets, _this2._element) || {});
15727               return data;
15728             };
15729           } else {
15730             offset.offset = this._config.offset;
15731           }
15732
15733           return offset;
15734         };
15735
15736         _proto._getPopperConfig = function _getPopperConfig() {
15737           var popperConfig = {
15738             placement: this._getPlacement(),
15739             modifiers: {
15740               offset: this._getOffset(),
15741               flip: {
15742                 enabled: this._config.flip
15743               },
15744               preventOverflow: {
15745                 boundariesElement: this._config.boundary
15746               }
15747             }
15748           }; // Disable Popper if we have a static display
15749
15750           if (this._config.display === 'static') {
15751             popperConfig.modifiers.applyStyle = {
15752               enabled: false
15753             };
15754           }
15755
15756           return _extends({}, popperConfig, this._config.popperConfig);
15757         } // Static
15758         ;
15759
15760         Dropdown._jQueryInterface = function _jQueryInterface(config) {
15761           return this.each(function () {
15762             var data = $__default['default'](this).data(DATA_KEY$4);
15763
15764             var _config = typeof config === 'object' ? config : null;
15765
15766             if (!data) {
15767               data = new Dropdown(this, _config);
15768               $__default['default'](this).data(DATA_KEY$4, data);
15769             }
15770
15771             if (typeof config === 'string') {
15772               if (typeof data[config] === 'undefined') {
15773                 throw new TypeError("No method named \"" + config + "\"");
15774               }
15775
15776               data[config]();
15777             }
15778           });
15779         };
15780
15781         Dropdown._clearMenus = function _clearMenus(event) {
15782           if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== TAB_KEYCODE)) {
15783             return;
15784           }
15785
15786           var toggles = [].slice.call(document.querySelectorAll(SELECTOR_DATA_TOGGLE$2));
15787
15788           for (var i = 0, len = toggles.length; i < len; i++) {
15789             var parent = Dropdown._getParentFromElement(toggles[i]);
15790
15791             var context = $__default['default'](toggles[i]).data(DATA_KEY$4);
15792             var relatedTarget = {
15793               relatedTarget: toggles[i]
15794             };
15795
15796             if (event && event.type === 'click') {
15797               relatedTarget.clickEvent = event;
15798             }
15799
15800             if (!context) {
15801               continue;
15802             }
15803
15804             var dropdownMenu = context._menu;
15805
15806             if (!$__default['default'](parent).hasClass(CLASS_NAME_SHOW$2)) {
15807               continue;
15808             }
15809
15810             if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type === 'keyup' && event.which === TAB_KEYCODE) && $__default['default'].contains(parent, event.target)) {
15811               continue;
15812             }
15813
15814             var hideEvent = $__default['default'].Event(EVENT_HIDE$1, relatedTarget);
15815             $__default['default'](parent).trigger(hideEvent);
15816
15817             if (hideEvent.isDefaultPrevented()) {
15818               continue;
15819             } // If this is a touch-enabled device we remove the extra
15820             // empty mouseover listeners we added for iOS support
15821
15822
15823             if ('ontouchstart' in document.documentElement) {
15824               $__default['default'](document.body).children().off('mouseover', null, $__default['default'].noop);
15825             }
15826
15827             toggles[i].setAttribute('aria-expanded', 'false');
15828
15829             if (context._popper) {
15830               context._popper.destroy();
15831             }
15832
15833             $__default['default'](dropdownMenu).removeClass(CLASS_NAME_SHOW$2);
15834             $__default['default'](parent).removeClass(CLASS_NAME_SHOW$2).trigger($__default['default'].Event(EVENT_HIDDEN$1, relatedTarget));
15835           }
15836         };
15837
15838         Dropdown._getParentFromElement = function _getParentFromElement(element) {
15839           var parent;
15840           var selector = Util.getSelectorFromElement(element);
15841
15842           if (selector) {
15843             parent = document.querySelector(selector);
15844           }
15845
15846           return parent || element.parentNode;
15847         } // eslint-disable-next-line complexity
15848         ;
15849
15850         Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) {
15851           // If not input/textarea:
15852           //  - And not a key in REGEXP_KEYDOWN => not a dropdown command
15853           // If input/textarea:
15854           //  - If space key => not a dropdown command
15855           //  - If key is other than escape
15856           //    - If key is not up or down => not a dropdown command
15857           //    - If trigger inside the menu => not a dropdown command
15858           if (/input|textarea/i.test(event.target.tagName) ? event.which === SPACE_KEYCODE || event.which !== ESCAPE_KEYCODE && (event.which !== ARROW_DOWN_KEYCODE && event.which !== ARROW_UP_KEYCODE || $__default['default'](event.target).closest(SELECTOR_MENU).length) : !REGEXP_KEYDOWN.test(event.which)) {
15859             return;
15860           }
15861
15862           if (this.disabled || $__default['default'](this).hasClass(CLASS_NAME_DISABLED)) {
15863             return;
15864           }
15865
15866           var parent = Dropdown._getParentFromElement(this);
15867
15868           var isActive = $__default['default'](parent).hasClass(CLASS_NAME_SHOW$2);
15869
15870           if (!isActive && event.which === ESCAPE_KEYCODE) {
15871             return;
15872           }
15873
15874           event.preventDefault();
15875           event.stopPropagation();
15876
15877           if (!isActive || event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE) {
15878             if (event.which === ESCAPE_KEYCODE) {
15879               $__default['default'](parent.querySelector(SELECTOR_DATA_TOGGLE$2)).trigger('focus');
15880             }
15881
15882             $__default['default'](this).trigger('click');
15883             return;
15884           }
15885
15886           var items = [].slice.call(parent.querySelectorAll(SELECTOR_VISIBLE_ITEMS)).filter(function (item) {
15887             return $__default['default'](item).is(':visible');
15888           });
15889
15890           if (items.length === 0) {
15891             return;
15892           }
15893
15894           var index = items.indexOf(event.target);
15895
15896           if (event.which === ARROW_UP_KEYCODE && index > 0) {
15897             // Up
15898             index--;
15899           }
15900
15901           if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) {
15902             // Down
15903             index++;
15904           }
15905
15906           if (index < 0) {
15907             index = 0;
15908           }
15909
15910           items[index].focus();
15911         };
15912
15913         _createClass(Dropdown, null, [{
15914           key: "VERSION",
15915           get: function get() {
15916             return VERSION$4;
15917           }
15918         }, {
15919           key: "Default",
15920           get: function get() {
15921             return Default$2;
15922           }
15923         }, {
15924           key: "DefaultType",
15925           get: function get() {
15926             return DefaultType$2;
15927           }
15928         }]);
15929
15930         return Dropdown;
15931       }();
15932       /**
15933        * ------------------------------------------------------------------------
15934        * Data Api implementation
15935        * ------------------------------------------------------------------------
15936        */
15937
15938
15939       $__default['default'](document).on(EVENT_KEYDOWN_DATA_API, SELECTOR_DATA_TOGGLE$2, Dropdown._dataApiKeydownHandler).on(EVENT_KEYDOWN_DATA_API, SELECTOR_MENU, Dropdown._dataApiKeydownHandler).on(EVENT_CLICK_DATA_API$4 + " " + EVENT_KEYUP_DATA_API, Dropdown._clearMenus).on(EVENT_CLICK_DATA_API$4, SELECTOR_DATA_TOGGLE$2, function (event) {
15940         event.preventDefault();
15941         event.stopPropagation();
15942
15943         Dropdown._jQueryInterface.call($__default['default'](this), 'toggle');
15944       }).on(EVENT_CLICK_DATA_API$4, SELECTOR_FORM_CHILD, function (e) {
15945         e.stopPropagation();
15946       });
15947       /**
15948        * ------------------------------------------------------------------------
15949        * jQuery
15950        * ------------------------------------------------------------------------
15951        */
15952
15953       $__default['default'].fn[NAME$4] = Dropdown._jQueryInterface;
15954       $__default['default'].fn[NAME$4].Constructor = Dropdown;
15955
15956       $__default['default'].fn[NAME$4].noConflict = function () {
15957         $__default['default'].fn[NAME$4] = JQUERY_NO_CONFLICT$4;
15958         return Dropdown._jQueryInterface;
15959       };
15960
15961       /**
15962        * ------------------------------------------------------------------------
15963        * Constants
15964        * ------------------------------------------------------------------------
15965        */
15966
15967       var NAME$5 = 'modal';
15968       var VERSION$5 = '4.6.0';
15969       var DATA_KEY$5 = 'bs.modal';
15970       var EVENT_KEY$5 = "." + DATA_KEY$5;
15971       var DATA_API_KEY$5 = '.data-api';
15972       var JQUERY_NO_CONFLICT$5 = $__default['default'].fn[NAME$5];
15973       var ESCAPE_KEYCODE$1 = 27; // KeyboardEvent.which value for Escape (Esc) key
15974
15975       var Default$3 = {
15976         backdrop: true,
15977         keyboard: true,
15978         focus: true,
15979         show: true
15980       };
15981       var DefaultType$3 = {
15982         backdrop: '(boolean|string)',
15983         keyboard: 'boolean',
15984         focus: 'boolean',
15985         show: 'boolean'
15986       };
15987       var EVENT_HIDE$2 = "hide" + EVENT_KEY$5;
15988       var EVENT_HIDE_PREVENTED = "hidePrevented" + EVENT_KEY$5;
15989       var EVENT_HIDDEN$2 = "hidden" + EVENT_KEY$5;
15990       var EVENT_SHOW$2 = "show" + EVENT_KEY$5;
15991       var EVENT_SHOWN$2 = "shown" + EVENT_KEY$5;
15992       var EVENT_FOCUSIN = "focusin" + EVENT_KEY$5;
15993       var EVENT_RESIZE = "resize" + EVENT_KEY$5;
15994       var EVENT_CLICK_DISMISS = "click.dismiss" + EVENT_KEY$5;
15995       var EVENT_KEYDOWN_DISMISS = "keydown.dismiss" + EVENT_KEY$5;
15996       var EVENT_MOUSEUP_DISMISS = "mouseup.dismiss" + EVENT_KEY$5;
15997       var EVENT_MOUSEDOWN_DISMISS = "mousedown.dismiss" + EVENT_KEY$5;
15998       var EVENT_CLICK_DATA_API$5 = "click" + EVENT_KEY$5 + DATA_API_KEY$5;
15999       var CLASS_NAME_SCROLLABLE = 'modal-dialog-scrollable';
16000       var CLASS_NAME_SCROLLBAR_MEASURER = 'modal-scrollbar-measure';
16001       var CLASS_NAME_BACKDROP = 'modal-backdrop';
16002       var CLASS_NAME_OPEN = 'modal-open';
16003       var CLASS_NAME_FADE$1 = 'fade';
16004       var CLASS_NAME_SHOW$3 = 'show';
16005       var CLASS_NAME_STATIC = 'modal-static';
16006       var SELECTOR_DIALOG = '.modal-dialog';
16007       var SELECTOR_MODAL_BODY = '.modal-body';
16008       var SELECTOR_DATA_TOGGLE$3 = '[data-toggle="modal"]';
16009       var SELECTOR_DATA_DISMISS = '[data-dismiss="modal"]';
16010       var SELECTOR_FIXED_CONTENT = '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top';
16011       var SELECTOR_STICKY_CONTENT = '.sticky-top';
16012       /**
16013        * ------------------------------------------------------------------------
16014        * Class Definition
16015        * ------------------------------------------------------------------------
16016        */
16017
16018       var Modal = /*#__PURE__*/function () {
16019         function Modal(element, config) {
16020           this._config = this._getConfig(config);
16021           this._element = element;
16022           this._dialog = element.querySelector(SELECTOR_DIALOG);
16023           this._backdrop = null;
16024           this._isShown = false;
16025           this._isBodyOverflowing = false;
16026           this._ignoreBackdropClick = false;
16027           this._isTransitioning = false;
16028           this._scrollbarWidth = 0;
16029         } // Getters
16030
16031
16032         var _proto = Modal.prototype;
16033
16034         // Public
16035         _proto.toggle = function toggle(relatedTarget) {
16036           return this._isShown ? this.hide() : this.show(relatedTarget);
16037         };
16038
16039         _proto.show = function show(relatedTarget) {
16040           var _this = this;
16041
16042           if (this._isShown || this._isTransitioning) {
16043             return;
16044           }
16045
16046           if ($__default['default'](this._element).hasClass(CLASS_NAME_FADE$1)) {
16047             this._isTransitioning = true;
16048           }
16049
16050           var showEvent = $__default['default'].Event(EVENT_SHOW$2, {
16051             relatedTarget: relatedTarget
16052           });
16053           $__default['default'](this._element).trigger(showEvent);
16054
16055           if (this._isShown || showEvent.isDefaultPrevented()) {
16056             return;
16057           }
16058
16059           this._isShown = true;
16060
16061           this._checkScrollbar();
16062
16063           this._setScrollbar();
16064
16065           this._adjustDialog();
16066
16067           this._setEscapeEvent();
16068
16069           this._setResizeEvent();
16070
16071           $__default['default'](this._element).on(EVENT_CLICK_DISMISS, SELECTOR_DATA_DISMISS, function (event) {
16072             return _this.hide(event);
16073           });
16074           $__default['default'](this._dialog).on(EVENT_MOUSEDOWN_DISMISS, function () {
16075             $__default['default'](_this._element).one(EVENT_MOUSEUP_DISMISS, function (event) {
16076               if ($__default['default'](event.target).is(_this._element)) {
16077                 _this._ignoreBackdropClick = true;
16078               }
16079             });
16080           });
16081
16082           this._showBackdrop(function () {
16083             return _this._showElement(relatedTarget);
16084           });
16085         };
16086
16087         _proto.hide = function hide(event) {
16088           var _this2 = this;
16089
16090           if (event) {
16091             event.preventDefault();
16092           }
16093
16094           if (!this._isShown || this._isTransitioning) {
16095             return;
16096           }
16097
16098           var hideEvent = $__default['default'].Event(EVENT_HIDE$2);
16099           $__default['default'](this._element).trigger(hideEvent);
16100
16101           if (!this._isShown || hideEvent.isDefaultPrevented()) {
16102             return;
16103           }
16104
16105           this._isShown = false;
16106           var transition = $__default['default'](this._element).hasClass(CLASS_NAME_FADE$1);
16107
16108           if (transition) {
16109             this._isTransitioning = true;
16110           }
16111
16112           this._setEscapeEvent();
16113
16114           this._setResizeEvent();
16115
16116           $__default['default'](document).off(EVENT_FOCUSIN);
16117           $__default['default'](this._element).removeClass(CLASS_NAME_SHOW$3);
16118           $__default['default'](this._element).off(EVENT_CLICK_DISMISS);
16119           $__default['default'](this._dialog).off(EVENT_MOUSEDOWN_DISMISS);
16120
16121           if (transition) {
16122             var transitionDuration = Util.getTransitionDurationFromElement(this._element);
16123             $__default['default'](this._element).one(Util.TRANSITION_END, function (event) {
16124               return _this2._hideModal(event);
16125             }).emulateTransitionEnd(transitionDuration);
16126           } else {
16127             this._hideModal();
16128           }
16129         };
16130
16131         _proto.dispose = function dispose() {
16132           [window, this._element, this._dialog].forEach(function (htmlElement) {
16133             return $__default['default'](htmlElement).off(EVENT_KEY$5);
16134           });
16135           /**
16136            * `document` has 2 events `EVENT_FOCUSIN` and `EVENT_CLICK_DATA_API`
16137            * Do not move `document` in `htmlElements` array
16138            * It will remove `EVENT_CLICK_DATA_API` event that should remain
16139            */
16140
16141           $__default['default'](document).off(EVENT_FOCUSIN);
16142           $__default['default'].removeData(this._element, DATA_KEY$5);
16143           this._config = null;
16144           this._element = null;
16145           this._dialog = null;
16146           this._backdrop = null;
16147           this._isShown = null;
16148           this._isBodyOverflowing = null;
16149           this._ignoreBackdropClick = null;
16150           this._isTransitioning = null;
16151           this._scrollbarWidth = null;
16152         };
16153
16154         _proto.handleUpdate = function handleUpdate() {
16155           this._adjustDialog();
16156         } // Private
16157         ;
16158
16159         _proto._getConfig = function _getConfig(config) {
16160           config = _extends({}, Default$3, config);
16161           Util.typeCheckConfig(NAME$5, config, DefaultType$3);
16162           return config;
16163         };
16164
16165         _proto._triggerBackdropTransition = function _triggerBackdropTransition() {
16166           var _this3 = this;
16167
16168           var hideEventPrevented = $__default['default'].Event(EVENT_HIDE_PREVENTED);
16169           $__default['default'](this._element).trigger(hideEventPrevented);
16170
16171           if (hideEventPrevented.isDefaultPrevented()) {
16172             return;
16173           }
16174
16175           var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
16176
16177           if (!isModalOverflowing) {
16178             this._element.style.overflowY = 'hidden';
16179           }
16180
16181           this._element.classList.add(CLASS_NAME_STATIC);
16182
16183           var modalTransitionDuration = Util.getTransitionDurationFromElement(this._dialog);
16184           $__default['default'](this._element).off(Util.TRANSITION_END);
16185           $__default['default'](this._element).one(Util.TRANSITION_END, function () {
16186             _this3._element.classList.remove(CLASS_NAME_STATIC);
16187
16188             if (!isModalOverflowing) {
16189               $__default['default'](_this3._element).one(Util.TRANSITION_END, function () {
16190                 _this3._element.style.overflowY = '';
16191               }).emulateTransitionEnd(_this3._element, modalTransitionDuration);
16192             }
16193           }).emulateTransitionEnd(modalTransitionDuration);
16194
16195           this._element.focus();
16196         };
16197
16198         _proto._showElement = function _showElement(relatedTarget) {
16199           var _this4 = this;
16200
16201           var transition = $__default['default'](this._element).hasClass(CLASS_NAME_FADE$1);
16202           var modalBody = this._dialog ? this._dialog.querySelector(SELECTOR_MODAL_BODY) : null;
16203
16204           if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
16205             // Don't move modal's DOM position
16206             document.body.appendChild(this._element);
16207           }
16208
16209           this._element.style.display = 'block';
16210
16211           this._element.removeAttribute('aria-hidden');
16212
16213           this._element.setAttribute('aria-modal', true);
16214
16215           this._element.setAttribute('role', 'dialog');
16216
16217           if ($__default['default'](this._dialog).hasClass(CLASS_NAME_SCROLLABLE) && modalBody) {
16218             modalBody.scrollTop = 0;
16219           } else {
16220             this._element.scrollTop = 0;
16221           }
16222
16223           if (transition) {
16224             Util.reflow(this._element);
16225           }
16226
16227           $__default['default'](this._element).addClass(CLASS_NAME_SHOW$3);
16228
16229           if (this._config.focus) {
16230             this._enforceFocus();
16231           }
16232
16233           var shownEvent = $__default['default'].Event(EVENT_SHOWN$2, {
16234             relatedTarget: relatedTarget
16235           });
16236
16237           var transitionComplete = function transitionComplete() {
16238             if (_this4._config.focus) {
16239               _this4._element.focus();
16240             }
16241
16242             _this4._isTransitioning = false;
16243             $__default['default'](_this4._element).trigger(shownEvent);
16244           };
16245
16246           if (transition) {
16247             var transitionDuration = Util.getTransitionDurationFromElement(this._dialog);
16248             $__default['default'](this._dialog).one(Util.TRANSITION_END, transitionComplete).emulateTransitionEnd(transitionDuration);
16249           } else {
16250             transitionComplete();
16251           }
16252         };
16253
16254         _proto._enforceFocus = function _enforceFocus() {
16255           var _this5 = this;
16256
16257           $__default['default'](document).off(EVENT_FOCUSIN) // Guard against infinite focus loop
16258           .on(EVENT_FOCUSIN, function (event) {
16259             if (document !== event.target && _this5._element !== event.target && $__default['default'](_this5._element).has(event.target).length === 0) {
16260               _this5._element.focus();
16261             }
16262           });
16263         };
16264
16265         _proto._setEscapeEvent = function _setEscapeEvent() {
16266           var _this6 = this;
16267
16268           if (this._isShown) {
16269             $__default['default'](this._element).on(EVENT_KEYDOWN_DISMISS, function (event) {
16270               if (_this6._config.keyboard && event.which === ESCAPE_KEYCODE$1) {
16271                 event.preventDefault();
16272
16273                 _this6.hide();
16274               } else if (!_this6._config.keyboard && event.which === ESCAPE_KEYCODE$1) {
16275                 _this6._triggerBackdropTransition();
16276               }
16277             });
16278           } else if (!this._isShown) {
16279             $__default['default'](this._element).off(EVENT_KEYDOWN_DISMISS);
16280           }
16281         };
16282
16283         _proto._setResizeEvent = function _setResizeEvent() {
16284           var _this7 = this;
16285
16286           if (this._isShown) {
16287             $__default['default'](window).on(EVENT_RESIZE, function (event) {
16288               return _this7.handleUpdate(event);
16289             });
16290           } else {
16291             $__default['default'](window).off(EVENT_RESIZE);
16292           }
16293         };
16294
16295         _proto._hideModal = function _hideModal() {
16296           var _this8 = this;
16297
16298           this._element.style.display = 'none';
16299
16300           this._element.setAttribute('aria-hidden', true);
16301
16302           this._element.removeAttribute('aria-modal');
16303
16304           this._element.removeAttribute('role');
16305
16306           this._isTransitioning = false;
16307
16308           this._showBackdrop(function () {
16309             $__default['default'](document.body).removeClass(CLASS_NAME_OPEN);
16310
16311             _this8._resetAdjustments();
16312
16313             _this8._resetScrollbar();
16314
16315             $__default['default'](_this8._element).trigger(EVENT_HIDDEN$2);
16316           });
16317         };
16318
16319         _proto._removeBackdrop = function _removeBackdrop() {
16320           if (this._backdrop) {
16321             $__default['default'](this._backdrop).remove();
16322             this._backdrop = null;
16323           }
16324         };
16325
16326         _proto._showBackdrop = function _showBackdrop(callback) {
16327           var _this9 = this;
16328
16329           var animate = $__default['default'](this._element).hasClass(CLASS_NAME_FADE$1) ? CLASS_NAME_FADE$1 : '';
16330
16331           if (this._isShown && this._config.backdrop) {
16332             this._backdrop = document.createElement('div');
16333             this._backdrop.className = CLASS_NAME_BACKDROP;
16334
16335             if (animate) {
16336               this._backdrop.classList.add(animate);
16337             }
16338
16339             $__default['default'](this._backdrop).appendTo(document.body);
16340             $__default['default'](this._element).on(EVENT_CLICK_DISMISS, function (event) {
16341               if (_this9._ignoreBackdropClick) {
16342                 _this9._ignoreBackdropClick = false;
16343                 return;
16344               }
16345
16346               if (event.target !== event.currentTarget) {
16347                 return;
16348               }
16349
16350               if (_this9._config.backdrop === 'static') {
16351                 _this9._triggerBackdropTransition();
16352               } else {
16353                 _this9.hide();
16354               }
16355             });
16356
16357             if (animate) {
16358               Util.reflow(this._backdrop);
16359             }
16360
16361             $__default['default'](this._backdrop).addClass(CLASS_NAME_SHOW$3);
16362
16363             if (!callback) {
16364               return;
16365             }
16366
16367             if (!animate) {
16368               callback();
16369               return;
16370             }
16371
16372             var backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop);
16373             $__default['default'](this._backdrop).one(Util.TRANSITION_END, callback).emulateTransitionEnd(backdropTransitionDuration);
16374           } else if (!this._isShown && this._backdrop) {
16375             $__default['default'](this._backdrop).removeClass(CLASS_NAME_SHOW$3);
16376
16377             var callbackRemove = function callbackRemove() {
16378               _this9._removeBackdrop();
16379
16380               if (callback) {
16381                 callback();
16382               }
16383             };
16384
16385             if ($__default['default'](this._element).hasClass(CLASS_NAME_FADE$1)) {
16386               var _backdropTransitionDuration = Util.getTransitionDurationFromElement(this._backdrop);
16387
16388               $__default['default'](this._backdrop).one(Util.TRANSITION_END, callbackRemove).emulateTransitionEnd(_backdropTransitionDuration);
16389             } else {
16390               callbackRemove();
16391             }
16392           } else if (callback) {
16393             callback();
16394           }
16395         } // ----------------------------------------------------------------------
16396         // the following methods are used to handle overflowing modals
16397         // todo (fat): these should probably be refactored out of modal.js
16398         // ----------------------------------------------------------------------
16399         ;
16400
16401         _proto._adjustDialog = function _adjustDialog() {
16402           var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
16403
16404           if (!this._isBodyOverflowing && isModalOverflowing) {
16405             this._element.style.paddingLeft = this._scrollbarWidth + "px";
16406           }
16407
16408           if (this._isBodyOverflowing && !isModalOverflowing) {
16409             this._element.style.paddingRight = this._scrollbarWidth + "px";
16410           }
16411         };
16412
16413         _proto._resetAdjustments = function _resetAdjustments() {
16414           this._element.style.paddingLeft = '';
16415           this._element.style.paddingRight = '';
16416         };
16417
16418         _proto._checkScrollbar = function _checkScrollbar() {
16419           var rect = document.body.getBoundingClientRect();
16420           this._isBodyOverflowing = Math.round(rect.left + rect.right) < window.innerWidth;
16421           this._scrollbarWidth = this._getScrollbarWidth();
16422         };
16423
16424         _proto._setScrollbar = function _setScrollbar() {
16425           var _this10 = this;
16426
16427           if (this._isBodyOverflowing) {
16428             // Note: DOMNode.style.paddingRight returns the actual value or '' if not set
16429             //   while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set
16430             var fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT));
16431             var stickyContent = [].slice.call(document.querySelectorAll(SELECTOR_STICKY_CONTENT)); // Adjust fixed content padding
16432
16433             $__default['default'](fixedContent).each(function (index, element) {
16434               var actualPadding = element.style.paddingRight;
16435               var calculatedPadding = $__default['default'](element).css('padding-right');
16436               $__default['default'](element).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + _this10._scrollbarWidth + "px");
16437             }); // Adjust sticky content margin
16438
16439             $__default['default'](stickyContent).each(function (index, element) {
16440               var actualMargin = element.style.marginRight;
16441               var calculatedMargin = $__default['default'](element).css('margin-right');
16442               $__default['default'](element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) - _this10._scrollbarWidth + "px");
16443             }); // Adjust body padding
16444
16445             var actualPadding = document.body.style.paddingRight;
16446             var calculatedPadding = $__default['default'](document.body).css('padding-right');
16447             $__default['default'](document.body).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + this._scrollbarWidth + "px");
16448           }
16449
16450           $__default['default'](document.body).addClass(CLASS_NAME_OPEN);
16451         };
16452
16453         _proto._resetScrollbar = function _resetScrollbar() {
16454           // Restore fixed content padding
16455           var fixedContent = [].slice.call(document.querySelectorAll(SELECTOR_FIXED_CONTENT));
16456           $__default['default'](fixedContent).each(function (index, element) {
16457             var padding = $__default['default'](element).data('padding-right');
16458             $__default['default'](element).removeData('padding-right');
16459             element.style.paddingRight = padding ? padding : '';
16460           }); // Restore sticky content
16461
16462           var elements = [].slice.call(document.querySelectorAll("" + SELECTOR_STICKY_CONTENT));
16463           $__default['default'](elements).each(function (index, element) {
16464             var margin = $__default['default'](element).data('margin-right');
16465
16466             if (typeof margin !== 'undefined') {
16467               $__default['default'](element).css('margin-right', margin).removeData('margin-right');
16468             }
16469           }); // Restore body padding
16470
16471           var padding = $__default['default'](document.body).data('padding-right');
16472           $__default['default'](document.body).removeData('padding-right');
16473           document.body.style.paddingRight = padding ? padding : '';
16474         };
16475
16476         _proto._getScrollbarWidth = function _getScrollbarWidth() {
16477           // thx d.walsh
16478           var scrollDiv = document.createElement('div');
16479           scrollDiv.className = CLASS_NAME_SCROLLBAR_MEASURER;
16480           document.body.appendChild(scrollDiv);
16481           var scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
16482           document.body.removeChild(scrollDiv);
16483           return scrollbarWidth;
16484         } // Static
16485         ;
16486
16487         Modal._jQueryInterface = function _jQueryInterface(config, relatedTarget) {
16488           return this.each(function () {
16489             var data = $__default['default'](this).data(DATA_KEY$5);
16490
16491             var _config = _extends({}, Default$3, $__default['default'](this).data(), typeof config === 'object' && config ? config : {});
16492
16493             if (!data) {
16494               data = new Modal(this, _config);
16495               $__default['default'](this).data(DATA_KEY$5, data);
16496             }
16497
16498             if (typeof config === 'string') {
16499               if (typeof data[config] === 'undefined') {
16500                 throw new TypeError("No method named \"" + config + "\"");
16501               }
16502
16503               data[config](relatedTarget);
16504             } else if (_config.show) {
16505               data.show(relatedTarget);
16506             }
16507           });
16508         };
16509
16510         _createClass(Modal, null, [{
16511           key: "VERSION",
16512           get: function get() {
16513             return VERSION$5;
16514           }
16515         }, {
16516           key: "Default",
16517           get: function get() {
16518             return Default$3;
16519           }
16520         }]);
16521
16522         return Modal;
16523       }();
16524       /**
16525        * ------------------------------------------------------------------------
16526        * Data Api implementation
16527        * ------------------------------------------------------------------------
16528        */
16529
16530
16531       $__default['default'](document).on(EVENT_CLICK_DATA_API$5, SELECTOR_DATA_TOGGLE$3, function (event) {
16532         var _this11 = this;
16533
16534         var target;
16535         var selector = Util.getSelectorFromElement(this);
16536
16537         if (selector) {
16538           target = document.querySelector(selector);
16539         }
16540
16541         var config = $__default['default'](target).data(DATA_KEY$5) ? 'toggle' : _extends({}, $__default['default'](target).data(), $__default['default'](this).data());
16542
16543         if (this.tagName === 'A' || this.tagName === 'AREA') {
16544           event.preventDefault();
16545         }
16546
16547         var $target = $__default['default'](target).one(EVENT_SHOW$2, function (showEvent) {
16548           if (showEvent.isDefaultPrevented()) {
16549             // Only register focus restorer if modal will actually get shown
16550             return;
16551           }
16552
16553           $target.one(EVENT_HIDDEN$2, function () {
16554             if ($__default['default'](_this11).is(':visible')) {
16555               _this11.focus();
16556             }
16557           });
16558         });
16559
16560         Modal._jQueryInterface.call($__default['default'](target), config, this);
16561       });
16562       /**
16563        * ------------------------------------------------------------------------
16564        * jQuery
16565        * ------------------------------------------------------------------------
16566        */
16567
16568       $__default['default'].fn[NAME$5] = Modal._jQueryInterface;
16569       $__default['default'].fn[NAME$5].Constructor = Modal;
16570
16571       $__default['default'].fn[NAME$5].noConflict = function () {
16572         $__default['default'].fn[NAME$5] = JQUERY_NO_CONFLICT$5;
16573         return Modal._jQueryInterface;
16574       };
16575
16576       /**
16577        * --------------------------------------------------------------------------
16578        * Bootstrap (v4.6.0): tools/sanitizer.js
16579        * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
16580        * --------------------------------------------------------------------------
16581        */
16582       var uriAttrs = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href'];
16583       var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i;
16584       var DefaultWhitelist = {
16585         // Global attributes allowed on any supplied element below.
16586         '*': ['class', 'dir', 'id', 'lang', 'role', ARIA_ATTRIBUTE_PATTERN],
16587         a: ['target', 'href', 'title', 'rel'],
16588         area: [],
16589         b: [],
16590         br: [],
16591         col: [],
16592         code: [],
16593         div: [],
16594         em: [],
16595         hr: [],
16596         h1: [],
16597         h2: [],
16598         h3: [],
16599         h4: [],
16600         h5: [],
16601         h6: [],
16602         i: [],
16603         img: ['src', 'srcset', 'alt', 'title', 'width', 'height'],
16604         li: [],
16605         ol: [],
16606         p: [],
16607         pre: [],
16608         s: [],
16609         small: [],
16610         span: [],
16611         sub: [],
16612         sup: [],
16613         strong: [],
16614         u: [],
16615         ul: []
16616       };
16617       /**
16618        * A pattern that recognizes a commonly useful subset of URLs that are safe.
16619        *
16620        * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
16621        */
16622
16623       var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi;
16624       /**
16625        * A pattern that matches safe data URLs. Only matches image, video and audio types.
16626        *
16627        * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts
16628        */
16629
16630       var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;
16631
16632       function allowedAttribute(attr, allowedAttributeList) {
16633         var attrName = attr.nodeName.toLowerCase();
16634
16635         if (allowedAttributeList.indexOf(attrName) !== -1) {
16636           if (uriAttrs.indexOf(attrName) !== -1) {
16637             return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN));
16638           }
16639
16640           return true;
16641         }
16642
16643         var regExp = allowedAttributeList.filter(function (attrRegex) {
16644           return attrRegex instanceof RegExp;
16645         }); // Check if a regular expression validates the attribute.
16646
16647         for (var i = 0, len = regExp.length; i < len; i++) {
16648           if (attrName.match(regExp[i])) {
16649             return true;
16650           }
16651         }
16652
16653         return false;
16654       }
16655
16656       function sanitizeHtml(unsafeHtml, whiteList, sanitizeFn) {
16657         if (unsafeHtml.length === 0) {
16658           return unsafeHtml;
16659         }
16660
16661         if (sanitizeFn && typeof sanitizeFn === 'function') {
16662           return sanitizeFn(unsafeHtml);
16663         }
16664
16665         var domParser = new window.DOMParser();
16666         var createdDocument = domParser.parseFromString(unsafeHtml, 'text/html');
16667         var whitelistKeys = Object.keys(whiteList);
16668         var elements = [].slice.call(createdDocument.body.querySelectorAll('*'));
16669
16670         var _loop = function _loop(i, len) {
16671           var el = elements[i];
16672           var elName = el.nodeName.toLowerCase();
16673
16674           if (whitelistKeys.indexOf(el.nodeName.toLowerCase()) === -1) {
16675             el.parentNode.removeChild(el);
16676             return "continue";
16677           }
16678
16679           var attributeList = [].slice.call(el.attributes);
16680           var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []);
16681           attributeList.forEach(function (attr) {
16682             if (!allowedAttribute(attr, whitelistedAttributes)) {
16683               el.removeAttribute(attr.nodeName);
16684             }
16685           });
16686         };
16687
16688         for (var i = 0, len = elements.length; i < len; i++) {
16689           var _ret = _loop(i);
16690
16691           if (_ret === "continue") continue;
16692         }
16693
16694         return createdDocument.body.innerHTML;
16695       }
16696
16697       /**
16698        * ------------------------------------------------------------------------
16699        * Constants
16700        * ------------------------------------------------------------------------
16701        */
16702
16703       var NAME$6 = 'tooltip';
16704       var VERSION$6 = '4.6.0';
16705       var DATA_KEY$6 = 'bs.tooltip';
16706       var EVENT_KEY$6 = "." + DATA_KEY$6;
16707       var JQUERY_NO_CONFLICT$6 = $__default['default'].fn[NAME$6];
16708       var CLASS_PREFIX = 'bs-tooltip';
16709       var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g');
16710       var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn'];
16711       var DefaultType$4 = {
16712         animation: 'boolean',
16713         template: 'string',
16714         title: '(string|element|function)',
16715         trigger: 'string',
16716         delay: '(number|object)',
16717         html: 'boolean',
16718         selector: '(string|boolean)',
16719         placement: '(string|function)',
16720         offset: '(number|string|function)',
16721         container: '(string|element|boolean)',
16722         fallbackPlacement: '(string|array)',
16723         boundary: '(string|element)',
16724         customClass: '(string|function)',
16725         sanitize: 'boolean',
16726         sanitizeFn: '(null|function)',
16727         whiteList: 'object',
16728         popperConfig: '(null|object)'
16729       };
16730       var AttachmentMap = {
16731         AUTO: 'auto',
16732         TOP: 'top',
16733         RIGHT: 'right',
16734         BOTTOM: 'bottom',
16735         LEFT: 'left'
16736       };
16737       var Default$4 = {
16738         animation: true,
16739         template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div class="tooltip-inner"></div></div>',
16740         trigger: 'hover focus',
16741         title: '',
16742         delay: 0,
16743         html: false,
16744         selector: false,
16745         placement: 'top',
16746         offset: 0,
16747         container: false,
16748         fallbackPlacement: 'flip',
16749         boundary: 'scrollParent',
16750         customClass: '',
16751         sanitize: true,
16752         sanitizeFn: null,
16753         whiteList: DefaultWhitelist,
16754         popperConfig: null
16755       };
16756       var HOVER_STATE_SHOW = 'show';
16757       var HOVER_STATE_OUT = 'out';
16758       var Event = {
16759         HIDE: "hide" + EVENT_KEY$6,
16760         HIDDEN: "hidden" + EVENT_KEY$6,
16761         SHOW: "show" + EVENT_KEY$6,
16762         SHOWN: "shown" + EVENT_KEY$6,
16763         INSERTED: "inserted" + EVENT_KEY$6,
16764         CLICK: "click" + EVENT_KEY$6,
16765         FOCUSIN: "focusin" + EVENT_KEY$6,
16766         FOCUSOUT: "focusout" + EVENT_KEY$6,
16767         MOUSEENTER: "mouseenter" + EVENT_KEY$6,
16768         MOUSELEAVE: "mouseleave" + EVENT_KEY$6
16769       };
16770       var CLASS_NAME_FADE$2 = 'fade';
16771       var CLASS_NAME_SHOW$4 = 'show';
16772       var SELECTOR_TOOLTIP_INNER = '.tooltip-inner';
16773       var SELECTOR_ARROW = '.arrow';
16774       var TRIGGER_HOVER = 'hover';
16775       var TRIGGER_FOCUS = 'focus';
16776       var TRIGGER_CLICK = 'click';
16777       var TRIGGER_MANUAL = 'manual';
16778       /**
16779        * ------------------------------------------------------------------------
16780        * Class Definition
16781        * ------------------------------------------------------------------------
16782        */
16783
16784       var Tooltip = /*#__PURE__*/function () {
16785         function Tooltip(element, config) {
16786           if (typeof Popper === 'undefined') {
16787             throw new TypeError('Bootstrap\'s tooltips require Popper (https://popper.js.org)');
16788           } // private
16789
16790
16791           this._isEnabled = true;
16792           this._timeout = 0;
16793           this._hoverState = '';
16794           this._activeTrigger = {};
16795           this._popper = null; // Protected
16796
16797           this.element = element;
16798           this.config = this._getConfig(config);
16799           this.tip = null;
16800
16801           this._setListeners();
16802         } // Getters
16803
16804
16805         var _proto = Tooltip.prototype;
16806
16807         // Public
16808         _proto.enable = function enable() {
16809           this._isEnabled = true;
16810         };
16811
16812         _proto.disable = function disable() {
16813           this._isEnabled = false;
16814         };
16815
16816         _proto.toggleEnabled = function toggleEnabled() {
16817           this._isEnabled = !this._isEnabled;
16818         };
16819
16820         _proto.toggle = function toggle(event) {
16821           if (!this._isEnabled) {
16822             return;
16823           }
16824
16825           if (event) {
16826             var dataKey = this.constructor.DATA_KEY;
16827             var context = $__default['default'](event.currentTarget).data(dataKey);
16828
16829             if (!context) {
16830               context = new this.constructor(event.currentTarget, this._getDelegateConfig());
16831               $__default['default'](event.currentTarget).data(dataKey, context);
16832             }
16833
16834             context._activeTrigger.click = !context._activeTrigger.click;
16835
16836             if (context._isWithActiveTrigger()) {
16837               context._enter(null, context);
16838             } else {
16839               context._leave(null, context);
16840             }
16841           } else {
16842             if ($__default['default'](this.getTipElement()).hasClass(CLASS_NAME_SHOW$4)) {
16843               this._leave(null, this);
16844
16845               return;
16846             }
16847
16848             this._enter(null, this);
16849           }
16850         };
16851
16852         _proto.dispose = function dispose() {
16853           clearTimeout(this._timeout);
16854           $__default['default'].removeData(this.element, this.constructor.DATA_KEY);
16855           $__default['default'](this.element).off(this.constructor.EVENT_KEY);
16856           $__default['default'](this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler);
16857
16858           if (this.tip) {
16859             $__default['default'](this.tip).remove();
16860           }
16861
16862           this._isEnabled = null;
16863           this._timeout = null;
16864           this._hoverState = null;
16865           this._activeTrigger = null;
16866
16867           if (this._popper) {
16868             this._popper.destroy();
16869           }
16870
16871           this._popper = null;
16872           this.element = null;
16873           this.config = null;
16874           this.tip = null;
16875         };
16876
16877         _proto.show = function show() {
16878           var _this = this;
16879
16880           if ($__default['default'](this.element).css('display') === 'none') {
16881             throw new Error('Please use show on visible elements');
16882           }
16883
16884           var showEvent = $__default['default'].Event(this.constructor.Event.SHOW);
16885
16886           if (this.isWithContent() && this._isEnabled) {
16887             $__default['default'](this.element).trigger(showEvent);
16888             var shadowRoot = Util.findShadowRoot(this.element);
16889             var isInTheDom = $__default['default'].contains(shadowRoot !== null ? shadowRoot : this.element.ownerDocument.documentElement, this.element);
16890
16891             if (showEvent.isDefaultPrevented() || !isInTheDom) {
16892               return;
16893             }
16894
16895             var tip = this.getTipElement();
16896             var tipId = Util.getUID(this.constructor.NAME);
16897             tip.setAttribute('id', tipId);
16898             this.element.setAttribute('aria-describedby', tipId);
16899             this.setContent();
16900
16901             if (this.config.animation) {
16902               $__default['default'](tip).addClass(CLASS_NAME_FADE$2);
16903             }
16904
16905             var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, this.element) : this.config.placement;
16906
16907             var attachment = this._getAttachment(placement);
16908
16909             this.addAttachmentClass(attachment);
16910
16911             var container = this._getContainer();
16912
16913             $__default['default'](tip).data(this.constructor.DATA_KEY, this);
16914
16915             if (!$__default['default'].contains(this.element.ownerDocument.documentElement, this.tip)) {
16916               $__default['default'](tip).appendTo(container);
16917             }
16918
16919             $__default['default'](this.element).trigger(this.constructor.Event.INSERTED);
16920             this._popper = new Popper(this.element, tip, this._getPopperConfig(attachment));
16921             $__default['default'](tip).addClass(CLASS_NAME_SHOW$4);
16922             $__default['default'](tip).addClass(this.config.customClass); // If this is a touch-enabled device we add extra
16923             // empty mouseover listeners to the body's immediate children;
16924             // only needed because of broken event delegation on iOS
16925             // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
16926
16927             if ('ontouchstart' in document.documentElement) {
16928               $__default['default'](document.body).children().on('mouseover', null, $__default['default'].noop);
16929             }
16930
16931             var complete = function complete() {
16932               if (_this.config.animation) {
16933                 _this._fixTransition();
16934               }
16935
16936               var prevHoverState = _this._hoverState;
16937               _this._hoverState = null;
16938               $__default['default'](_this.element).trigger(_this.constructor.Event.SHOWN);
16939
16940               if (prevHoverState === HOVER_STATE_OUT) {
16941                 _this._leave(null, _this);
16942               }
16943             };
16944
16945             if ($__default['default'](this.tip).hasClass(CLASS_NAME_FADE$2)) {
16946               var transitionDuration = Util.getTransitionDurationFromElement(this.tip);
16947               $__default['default'](this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
16948             } else {
16949               complete();
16950             }
16951           }
16952         };
16953
16954         _proto.hide = function hide(callback) {
16955           var _this2 = this;
16956
16957           var tip = this.getTipElement();
16958           var hideEvent = $__default['default'].Event(this.constructor.Event.HIDE);
16959
16960           var complete = function complete() {
16961             if (_this2._hoverState !== HOVER_STATE_SHOW && tip.parentNode) {
16962               tip.parentNode.removeChild(tip);
16963             }
16964
16965             _this2._cleanTipClass();
16966
16967             _this2.element.removeAttribute('aria-describedby');
16968
16969             $__default['default'](_this2.element).trigger(_this2.constructor.Event.HIDDEN);
16970
16971             if (_this2._popper !== null) {
16972               _this2._popper.destroy();
16973             }
16974
16975             if (callback) {
16976               callback();
16977             }
16978           };
16979
16980           $__default['default'](this.element).trigger(hideEvent);
16981
16982           if (hideEvent.isDefaultPrevented()) {
16983             return;
16984           }
16985
16986           $__default['default'](tip).removeClass(CLASS_NAME_SHOW$4); // If this is a touch-enabled device we remove the extra
16987           // empty mouseover listeners we added for iOS support
16988
16989           if ('ontouchstart' in document.documentElement) {
16990             $__default['default'](document.body).children().off('mouseover', null, $__default['default'].noop);
16991           }
16992
16993           this._activeTrigger[TRIGGER_CLICK] = false;
16994           this._activeTrigger[TRIGGER_FOCUS] = false;
16995           this._activeTrigger[TRIGGER_HOVER] = false;
16996
16997           if ($__default['default'](this.tip).hasClass(CLASS_NAME_FADE$2)) {
16998             var transitionDuration = Util.getTransitionDurationFromElement(tip);
16999             $__default['default'](tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
17000           } else {
17001             complete();
17002           }
17003
17004           this._hoverState = '';
17005         };
17006
17007         _proto.update = function update() {
17008           if (this._popper !== null) {
17009             this._popper.scheduleUpdate();
17010           }
17011         } // Protected
17012         ;
17013
17014         _proto.isWithContent = function isWithContent() {
17015           return Boolean(this.getTitle());
17016         };
17017
17018         _proto.addAttachmentClass = function addAttachmentClass(attachment) {
17019           $__default['default'](this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment);
17020         };
17021
17022         _proto.getTipElement = function getTipElement() {
17023           this.tip = this.tip || $__default['default'](this.config.template)[0];
17024           return this.tip;
17025         };
17026
17027         _proto.setContent = function setContent() {
17028           var tip = this.getTipElement();
17029           this.setElementContent($__default['default'](tip.querySelectorAll(SELECTOR_TOOLTIP_INNER)), this.getTitle());
17030           $__default['default'](tip).removeClass(CLASS_NAME_FADE$2 + " " + CLASS_NAME_SHOW$4);
17031         };
17032
17033         _proto.setElementContent = function setElementContent($element, content) {
17034           if (typeof content === 'object' && (content.nodeType || content.jquery)) {
17035             // Content is a DOM node or a jQuery
17036             if (this.config.html) {
17037               if (!$__default['default'](content).parent().is($element)) {
17038                 $element.empty().append(content);
17039               }
17040             } else {
17041               $element.text($__default['default'](content).text());
17042             }
17043
17044             return;
17045           }
17046
17047           if (this.config.html) {
17048             if (this.config.sanitize) {
17049               content = sanitizeHtml(content, this.config.whiteList, this.config.sanitizeFn);
17050             }
17051
17052             $element.html(content);
17053           } else {
17054             $element.text(content);
17055           }
17056         };
17057
17058         _proto.getTitle = function getTitle() {
17059           var title = this.element.getAttribute('data-original-title');
17060
17061           if (!title) {
17062             title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : this.config.title;
17063           }
17064
17065           return title;
17066         } // Private
17067         ;
17068
17069         _proto._getPopperConfig = function _getPopperConfig(attachment) {
17070           var _this3 = this;
17071
17072           var defaultBsConfig = {
17073             placement: attachment,
17074             modifiers: {
17075               offset: this._getOffset(),
17076               flip: {
17077                 behavior: this.config.fallbackPlacement
17078               },
17079               arrow: {
17080                 element: SELECTOR_ARROW
17081               },
17082               preventOverflow: {
17083                 boundariesElement: this.config.boundary
17084               }
17085             },
17086             onCreate: function onCreate(data) {
17087               if (data.originalPlacement !== data.placement) {
17088                 _this3._handlePopperPlacementChange(data);
17089               }
17090             },
17091             onUpdate: function onUpdate(data) {
17092               return _this3._handlePopperPlacementChange(data);
17093             }
17094           };
17095           return _extends({}, defaultBsConfig, this.config.popperConfig);
17096         };
17097
17098         _proto._getOffset = function _getOffset() {
17099           var _this4 = this;
17100
17101           var offset = {};
17102
17103           if (typeof this.config.offset === 'function') {
17104             offset.fn = function (data) {
17105               data.offsets = _extends({}, data.offsets, _this4.config.offset(data.offsets, _this4.element) || {});
17106               return data;
17107             };
17108           } else {
17109             offset.offset = this.config.offset;
17110           }
17111
17112           return offset;
17113         };
17114
17115         _proto._getContainer = function _getContainer() {
17116           if (this.config.container === false) {
17117             return document.body;
17118           }
17119
17120           if (Util.isElement(this.config.container)) {
17121             return $__default['default'](this.config.container);
17122           }
17123
17124           return $__default['default'](document).find(this.config.container);
17125         };
17126
17127         _proto._getAttachment = function _getAttachment(placement) {
17128           return AttachmentMap[placement.toUpperCase()];
17129         };
17130
17131         _proto._setListeners = function _setListeners() {
17132           var _this5 = this;
17133
17134           var triggers = this.config.trigger.split(' ');
17135           triggers.forEach(function (trigger) {
17136             if (trigger === 'click') {
17137               $__default['default'](_this5.element).on(_this5.constructor.Event.CLICK, _this5.config.selector, function (event) {
17138                 return _this5.toggle(event);
17139               });
17140             } else if (trigger !== TRIGGER_MANUAL) {
17141               var eventIn = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSEENTER : _this5.constructor.Event.FOCUSIN;
17142               var eventOut = trigger === TRIGGER_HOVER ? _this5.constructor.Event.MOUSELEAVE : _this5.constructor.Event.FOCUSOUT;
17143               $__default['default'](_this5.element).on(eventIn, _this5.config.selector, function (event) {
17144                 return _this5._enter(event);
17145               }).on(eventOut, _this5.config.selector, function (event) {
17146                 return _this5._leave(event);
17147               });
17148             }
17149           });
17150
17151           this._hideModalHandler = function () {
17152             if (_this5.element) {
17153               _this5.hide();
17154             }
17155           };
17156
17157           $__default['default'](this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler);
17158
17159           if (this.config.selector) {
17160             this.config = _extends({}, this.config, {
17161               trigger: 'manual',
17162               selector: ''
17163             });
17164           } else {
17165             this._fixTitle();
17166           }
17167         };
17168
17169         _proto._fixTitle = function _fixTitle() {
17170           var titleType = typeof this.element.getAttribute('data-original-title');
17171
17172           if (this.element.getAttribute('title') || titleType !== 'string') {
17173             this.element.setAttribute('data-original-title', this.element.getAttribute('title') || '');
17174             this.element.setAttribute('title', '');
17175           }
17176         };
17177
17178         _proto._enter = function _enter(event, context) {
17179           var dataKey = this.constructor.DATA_KEY;
17180           context = context || $__default['default'](event.currentTarget).data(dataKey);
17181
17182           if (!context) {
17183             context = new this.constructor(event.currentTarget, this._getDelegateConfig());
17184             $__default['default'](event.currentTarget).data(dataKey, context);
17185           }
17186
17187           if (event) {
17188             context._activeTrigger[event.type === 'focusin' ? TRIGGER_FOCUS : TRIGGER_HOVER] = true;
17189           }
17190
17191           if ($__default['default'](context.getTipElement()).hasClass(CLASS_NAME_SHOW$4) || context._hoverState === HOVER_STATE_SHOW) {
17192             context._hoverState = HOVER_STATE_SHOW;
17193             return;
17194           }
17195
17196           clearTimeout(context._timeout);
17197           context._hoverState = HOVER_STATE_SHOW;
17198
17199           if (!context.config.delay || !context.config.delay.show) {
17200             context.show();
17201             return;
17202           }
17203
17204           context._timeout = setTimeout(function () {
17205             if (context._hoverState === HOVER_STATE_SHOW) {
17206               context.show();
17207             }
17208           }, context.config.delay.show);
17209         };
17210
17211         _proto._leave = function _leave(event, context) {
17212           var dataKey = this.constructor.DATA_KEY;
17213           context = context || $__default['default'](event.currentTarget).data(dataKey);
17214
17215           if (!context) {
17216             context = new this.constructor(event.currentTarget, this._getDelegateConfig());
17217             $__default['default'](event.currentTarget).data(dataKey, context);
17218           }
17219
17220           if (event) {
17221             context._activeTrigger[event.type === 'focusout' ? TRIGGER_FOCUS : TRIGGER_HOVER] = false;
17222           }
17223
17224           if (context._isWithActiveTrigger()) {
17225             return;
17226           }
17227
17228           clearTimeout(context._timeout);
17229           context._hoverState = HOVER_STATE_OUT;
17230
17231           if (!context.config.delay || !context.config.delay.hide) {
17232             context.hide();
17233             return;
17234           }
17235
17236           context._timeout = setTimeout(function () {
17237             if (context._hoverState === HOVER_STATE_OUT) {
17238               context.hide();
17239             }
17240           }, context.config.delay.hide);
17241         };
17242
17243         _proto._isWithActiveTrigger = function _isWithActiveTrigger() {
17244           for (var trigger in this._activeTrigger) {
17245             if (this._activeTrigger[trigger]) {
17246               return true;
17247             }
17248           }
17249
17250           return false;
17251         };
17252
17253         _proto._getConfig = function _getConfig(config) {
17254           var dataAttributes = $__default['default'](this.element).data();
17255           Object.keys(dataAttributes).forEach(function (dataAttr) {
17256             if (DISALLOWED_ATTRIBUTES.indexOf(dataAttr) !== -1) {
17257               delete dataAttributes[dataAttr];
17258             }
17259           });
17260           config = _extends({}, this.constructor.Default, dataAttributes, typeof config === 'object' && config ? config : {});
17261
17262           if (typeof config.delay === 'number') {
17263             config.delay = {
17264               show: config.delay,
17265               hide: config.delay
17266             };
17267           }
17268
17269           if (typeof config.title === 'number') {
17270             config.title = config.title.toString();
17271           }
17272
17273           if (typeof config.content === 'number') {
17274             config.content = config.content.toString();
17275           }
17276
17277           Util.typeCheckConfig(NAME$6, config, this.constructor.DefaultType);
17278
17279           if (config.sanitize) {
17280             config.template = sanitizeHtml(config.template, config.whiteList, config.sanitizeFn);
17281           }
17282
17283           return config;
17284         };
17285
17286         _proto._getDelegateConfig = function _getDelegateConfig() {
17287           var config = {};
17288
17289           if (this.config) {
17290             for (var key in this.config) {
17291               if (this.constructor.Default[key] !== this.config[key]) {
17292                 config[key] = this.config[key];
17293               }
17294             }
17295           }
17296
17297           return config;
17298         };
17299
17300         _proto._cleanTipClass = function _cleanTipClass() {
17301           var $tip = $__default['default'](this.getTipElement());
17302           var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX);
17303
17304           if (tabClass !== null && tabClass.length) {
17305             $tip.removeClass(tabClass.join(''));
17306           }
17307         };
17308
17309         _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(popperData) {
17310           this.tip = popperData.instance.popper;
17311
17312           this._cleanTipClass();
17313
17314           this.addAttachmentClass(this._getAttachment(popperData.placement));
17315         };
17316
17317         _proto._fixTransition = function _fixTransition() {
17318           var tip = this.getTipElement();
17319           var initConfigAnimation = this.config.animation;
17320
17321           if (tip.getAttribute('x-placement') !== null) {
17322             return;
17323           }
17324
17325           $__default['default'](tip).removeClass(CLASS_NAME_FADE$2);
17326           this.config.animation = false;
17327           this.hide();
17328           this.show();
17329           this.config.animation = initConfigAnimation;
17330         } // Static
17331         ;
17332
17333         Tooltip._jQueryInterface = function _jQueryInterface(config) {
17334           return this.each(function () {
17335             var $element = $__default['default'](this);
17336             var data = $element.data(DATA_KEY$6);
17337
17338             var _config = typeof config === 'object' && config;
17339
17340             if (!data && /dispose|hide/.test(config)) {
17341               return;
17342             }
17343
17344             if (!data) {
17345               data = new Tooltip(this, _config);
17346               $element.data(DATA_KEY$6, data);
17347             }
17348
17349             if (typeof config === 'string') {
17350               if (typeof data[config] === 'undefined') {
17351                 throw new TypeError("No method named \"" + config + "\"");
17352               }
17353
17354               data[config]();
17355             }
17356           });
17357         };
17358
17359         _createClass(Tooltip, null, [{
17360           key: "VERSION",
17361           get: function get() {
17362             return VERSION$6;
17363           }
17364         }, {
17365           key: "Default",
17366           get: function get() {
17367             return Default$4;
17368           }
17369         }, {
17370           key: "NAME",
17371           get: function get() {
17372             return NAME$6;
17373           }
17374         }, {
17375           key: "DATA_KEY",
17376           get: function get() {
17377             return DATA_KEY$6;
17378           }
17379         }, {
17380           key: "Event",
17381           get: function get() {
17382             return Event;
17383           }
17384         }, {
17385           key: "EVENT_KEY",
17386           get: function get() {
17387             return EVENT_KEY$6;
17388           }
17389         }, {
17390           key: "DefaultType",
17391           get: function get() {
17392             return DefaultType$4;
17393           }
17394         }]);
17395
17396         return Tooltip;
17397       }();
17398       /**
17399        * ------------------------------------------------------------------------
17400        * jQuery
17401        * ------------------------------------------------------------------------
17402        */
17403
17404
17405       $__default['default'].fn[NAME$6] = Tooltip._jQueryInterface;
17406       $__default['default'].fn[NAME$6].Constructor = Tooltip;
17407
17408       $__default['default'].fn[NAME$6].noConflict = function () {
17409         $__default['default'].fn[NAME$6] = JQUERY_NO_CONFLICT$6;
17410         return Tooltip._jQueryInterface;
17411       };
17412
17413       /**
17414        * ------------------------------------------------------------------------
17415        * Constants
17416        * ------------------------------------------------------------------------
17417        */
17418
17419       var NAME$7 = 'popover';
17420       var VERSION$7 = '4.6.0';
17421       var DATA_KEY$7 = 'bs.popover';
17422       var EVENT_KEY$7 = "." + DATA_KEY$7;
17423       var JQUERY_NO_CONFLICT$7 = $__default['default'].fn[NAME$7];
17424       var CLASS_PREFIX$1 = 'bs-popover';
17425       var BSCLS_PREFIX_REGEX$1 = new RegExp("(^|\\s)" + CLASS_PREFIX$1 + "\\S+", 'g');
17426
17427       var Default$5 = _extends({}, Tooltip.Default, {
17428         placement: 'right',
17429         trigger: 'click',
17430         content: '',
17431         template: '<div class="popover" role="tooltip">' + '<div class="arrow"></div>' + '<h3 class="popover-header"></h3>' + '<div class="popover-body"></div></div>'
17432       });
17433
17434       var DefaultType$5 = _extends({}, Tooltip.DefaultType, {
17435         content: '(string|element|function)'
17436       });
17437
17438       var CLASS_NAME_FADE$3 = 'fade';
17439       var CLASS_NAME_SHOW$5 = 'show';
17440       var SELECTOR_TITLE = '.popover-header';
17441       var SELECTOR_CONTENT = '.popover-body';
17442       var Event$1 = {
17443         HIDE: "hide" + EVENT_KEY$7,
17444         HIDDEN: "hidden" + EVENT_KEY$7,
17445         SHOW: "show" + EVENT_KEY$7,
17446         SHOWN: "shown" + EVENT_KEY$7,
17447         INSERTED: "inserted" + EVENT_KEY$7,
17448         CLICK: "click" + EVENT_KEY$7,
17449         FOCUSIN: "focusin" + EVENT_KEY$7,
17450         FOCUSOUT: "focusout" + EVENT_KEY$7,
17451         MOUSEENTER: "mouseenter" + EVENT_KEY$7,
17452         MOUSELEAVE: "mouseleave" + EVENT_KEY$7
17453       };
17454       /**
17455        * ------------------------------------------------------------------------
17456        * Class Definition
17457        * ------------------------------------------------------------------------
17458        */
17459
17460       var Popover = /*#__PURE__*/function (_Tooltip) {
17461         _inheritsLoose(Popover, _Tooltip);
17462
17463         function Popover() {
17464           return _Tooltip.apply(this, arguments) || this;
17465         }
17466
17467         var _proto = Popover.prototype;
17468
17469         // Overrides
17470         _proto.isWithContent = function isWithContent() {
17471           return this.getTitle() || this._getContent();
17472         };
17473
17474         _proto.addAttachmentClass = function addAttachmentClass(attachment) {
17475           $__default['default'](this.getTipElement()).addClass(CLASS_PREFIX$1 + "-" + attachment);
17476         };
17477
17478         _proto.getTipElement = function getTipElement() {
17479           this.tip = this.tip || $__default['default'](this.config.template)[0];
17480           return this.tip;
17481         };
17482
17483         _proto.setContent = function setContent() {
17484           var $tip = $__default['default'](this.getTipElement()); // We use append for html objects to maintain js events
17485
17486           this.setElementContent($tip.find(SELECTOR_TITLE), this.getTitle());
17487
17488           var content = this._getContent();
17489
17490           if (typeof content === 'function') {
17491             content = content.call(this.element);
17492           }
17493
17494           this.setElementContent($tip.find(SELECTOR_CONTENT), content);
17495           $tip.removeClass(CLASS_NAME_FADE$3 + " " + CLASS_NAME_SHOW$5);
17496         } // Private
17497         ;
17498
17499         _proto._getContent = function _getContent() {
17500           return this.element.getAttribute('data-content') || this.config.content;
17501         };
17502
17503         _proto._cleanTipClass = function _cleanTipClass() {
17504           var $tip = $__default['default'](this.getTipElement());
17505           var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX$1);
17506
17507           if (tabClass !== null && tabClass.length > 0) {
17508             $tip.removeClass(tabClass.join(''));
17509           }
17510         } // Static
17511         ;
17512
17513         Popover._jQueryInterface = function _jQueryInterface(config) {
17514           return this.each(function () {
17515             var data = $__default['default'](this).data(DATA_KEY$7);
17516
17517             var _config = typeof config === 'object' ? config : null;
17518
17519             if (!data && /dispose|hide/.test(config)) {
17520               return;
17521             }
17522
17523             if (!data) {
17524               data = new Popover(this, _config);
17525               $__default['default'](this).data(DATA_KEY$7, data);
17526             }
17527
17528             if (typeof config === 'string') {
17529               if (typeof data[config] === 'undefined') {
17530                 throw new TypeError("No method named \"" + config + "\"");
17531               }
17532
17533               data[config]();
17534             }
17535           });
17536         };
17537
17538         _createClass(Popover, null, [{
17539           key: "VERSION",
17540           // Getters
17541           get: function get() {
17542             return VERSION$7;
17543           }
17544         }, {
17545           key: "Default",
17546           get: function get() {
17547             return Default$5;
17548           }
17549         }, {
17550           key: "NAME",
17551           get: function get() {
17552             return NAME$7;
17553           }
17554         }, {
17555           key: "DATA_KEY",
17556           get: function get() {
17557             return DATA_KEY$7;
17558           }
17559         }, {
17560           key: "Event",
17561           get: function get() {
17562             return Event$1;
17563           }
17564         }, {
17565           key: "EVENT_KEY",
17566           get: function get() {
17567             return EVENT_KEY$7;
17568           }
17569         }, {
17570           key: "DefaultType",
17571           get: function get() {
17572             return DefaultType$5;
17573           }
17574         }]);
17575
17576         return Popover;
17577       }(Tooltip);
17578       /**
17579        * ------------------------------------------------------------------------
17580        * jQuery
17581        * ------------------------------------------------------------------------
17582        */
17583
17584
17585       $__default['default'].fn[NAME$7] = Popover._jQueryInterface;
17586       $__default['default'].fn[NAME$7].Constructor = Popover;
17587
17588       $__default['default'].fn[NAME$7].noConflict = function () {
17589         $__default['default'].fn[NAME$7] = JQUERY_NO_CONFLICT$7;
17590         return Popover._jQueryInterface;
17591       };
17592
17593       /**
17594        * ------------------------------------------------------------------------
17595        * Constants
17596        * ------------------------------------------------------------------------
17597        */
17598
17599       var NAME$8 = 'scrollspy';
17600       var VERSION$8 = '4.6.0';
17601       var DATA_KEY$8 = 'bs.scrollspy';
17602       var EVENT_KEY$8 = "." + DATA_KEY$8;
17603       var DATA_API_KEY$6 = '.data-api';
17604       var JQUERY_NO_CONFLICT$8 = $__default['default'].fn[NAME$8];
17605       var Default$6 = {
17606         offset: 10,
17607         method: 'auto',
17608         target: ''
17609       };
17610       var DefaultType$6 = {
17611         offset: 'number',
17612         method: 'string',
17613         target: '(string|element)'
17614       };
17615       var EVENT_ACTIVATE = "activate" + EVENT_KEY$8;
17616       var EVENT_SCROLL = "scroll" + EVENT_KEY$8;
17617       var EVENT_LOAD_DATA_API$2 = "load" + EVENT_KEY$8 + DATA_API_KEY$6;
17618       var CLASS_NAME_DROPDOWN_ITEM = 'dropdown-item';
17619       var CLASS_NAME_ACTIVE$2 = 'active';
17620       var SELECTOR_DATA_SPY = '[data-spy="scroll"]';
17621       var SELECTOR_NAV_LIST_GROUP = '.nav, .list-group';
17622       var SELECTOR_NAV_LINKS = '.nav-link';
17623       var SELECTOR_NAV_ITEMS = '.nav-item';
17624       var SELECTOR_LIST_ITEMS = '.list-group-item';
17625       var SELECTOR_DROPDOWN = '.dropdown';
17626       var SELECTOR_DROPDOWN_ITEMS = '.dropdown-item';
17627       var SELECTOR_DROPDOWN_TOGGLE = '.dropdown-toggle';
17628       var METHOD_OFFSET = 'offset';
17629       var METHOD_POSITION = 'position';
17630       /**
17631        * ------------------------------------------------------------------------
17632        * Class Definition
17633        * ------------------------------------------------------------------------
17634        */
17635
17636       var ScrollSpy = /*#__PURE__*/function () {
17637         function ScrollSpy(element, config) {
17638           var _this = this;
17639
17640           this._element = element;
17641           this._scrollElement = element.tagName === 'BODY' ? window : element;
17642           this._config = this._getConfig(config);
17643           this._selector = this._config.target + " " + SELECTOR_NAV_LINKS + "," + (this._config.target + " " + SELECTOR_LIST_ITEMS + ",") + (this._config.target + " " + SELECTOR_DROPDOWN_ITEMS);
17644           this._offsets = [];
17645           this._targets = [];
17646           this._activeTarget = null;
17647           this._scrollHeight = 0;
17648           $__default['default'](this._scrollElement).on(EVENT_SCROLL, function (event) {
17649             return _this._process(event);
17650           });
17651           this.refresh();
17652
17653           this._process();
17654         } // Getters
17655
17656
17657         var _proto = ScrollSpy.prototype;
17658
17659         // Public
17660         _proto.refresh = function refresh() {
17661           var _this2 = this;
17662
17663           var autoMethod = this._scrollElement === this._scrollElement.window ? METHOD_OFFSET : METHOD_POSITION;
17664           var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
17665           var offsetBase = offsetMethod === METHOD_POSITION ? this._getScrollTop() : 0;
17666           this._offsets = [];
17667           this._targets = [];
17668           this._scrollHeight = this._getScrollHeight();
17669           var targets = [].slice.call(document.querySelectorAll(this._selector));
17670           targets.map(function (element) {
17671             var target;
17672             var targetSelector = Util.getSelectorFromElement(element);
17673
17674             if (targetSelector) {
17675               target = document.querySelector(targetSelector);
17676             }
17677
17678             if (target) {
17679               var targetBCR = target.getBoundingClientRect();
17680
17681               if (targetBCR.width || targetBCR.height) {
17682                 // TODO (fat): remove sketch reliance on jQuery position/offset
17683                 return [$__default['default'](target)[offsetMethod]().top + offsetBase, targetSelector];
17684               }
17685             }
17686
17687             return null;
17688           }).filter(function (item) {
17689             return item;
17690           }).sort(function (a, b) {
17691             return a[0] - b[0];
17692           }).forEach(function (item) {
17693             _this2._offsets.push(item[0]);
17694
17695             _this2._targets.push(item[1]);
17696           });
17697         };
17698
17699         _proto.dispose = function dispose() {
17700           $__default['default'].removeData(this._element, DATA_KEY$8);
17701           $__default['default'](this._scrollElement).off(EVENT_KEY$8);
17702           this._element = null;
17703           this._scrollElement = null;
17704           this._config = null;
17705           this._selector = null;
17706           this._offsets = null;
17707           this._targets = null;
17708           this._activeTarget = null;
17709           this._scrollHeight = null;
17710         } // Private
17711         ;
17712
17713         _proto._getConfig = function _getConfig(config) {
17714           config = _extends({}, Default$6, typeof config === 'object' && config ? config : {});
17715
17716           if (typeof config.target !== 'string' && Util.isElement(config.target)) {
17717             var id = $__default['default'](config.target).attr('id');
17718
17719             if (!id) {
17720               id = Util.getUID(NAME$8);
17721               $__default['default'](config.target).attr('id', id);
17722             }
17723
17724             config.target = "#" + id;
17725           }
17726
17727           Util.typeCheckConfig(NAME$8, config, DefaultType$6);
17728           return config;
17729         };
17730
17731         _proto._getScrollTop = function _getScrollTop() {
17732           return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop;
17733         };
17734
17735         _proto._getScrollHeight = function _getScrollHeight() {
17736           return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight);
17737         };
17738
17739         _proto._getOffsetHeight = function _getOffsetHeight() {
17740           return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height;
17741         };
17742
17743         _proto._process = function _process() {
17744           var scrollTop = this._getScrollTop() + this._config.offset;
17745
17746           var scrollHeight = this._getScrollHeight();
17747
17748           var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();
17749
17750           if (this._scrollHeight !== scrollHeight) {
17751             this.refresh();
17752           }
17753
17754           if (scrollTop >= maxScroll) {
17755             var target = this._targets[this._targets.length - 1];
17756
17757             if (this._activeTarget !== target) {
17758               this._activate(target);
17759             }
17760
17761             return;
17762           }
17763
17764           if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
17765             this._activeTarget = null;
17766
17767             this._clear();
17768
17769             return;
17770           }
17771
17772           for (var i = this._offsets.length; i--;) {
17773             var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && (typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);
17774
17775             if (isActiveTarget) {
17776               this._activate(this._targets[i]);
17777             }
17778           }
17779         };
17780
17781         _proto._activate = function _activate(target) {
17782           this._activeTarget = target;
17783
17784           this._clear();
17785
17786           var queries = this._selector.split(',').map(function (selector) {
17787             return selector + "[data-target=\"" + target + "\"]," + selector + "[href=\"" + target + "\"]";
17788           });
17789
17790           var $link = $__default['default']([].slice.call(document.querySelectorAll(queries.join(','))));
17791
17792           if ($link.hasClass(CLASS_NAME_DROPDOWN_ITEM)) {
17793             $link.closest(SELECTOR_DROPDOWN).find(SELECTOR_DROPDOWN_TOGGLE).addClass(CLASS_NAME_ACTIVE$2);
17794             $link.addClass(CLASS_NAME_ACTIVE$2);
17795           } else {
17796             // Set triggered link as active
17797             $link.addClass(CLASS_NAME_ACTIVE$2); // Set triggered links parents as active
17798             // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
17799
17800             $link.parents(SELECTOR_NAV_LIST_GROUP).prev(SELECTOR_NAV_LINKS + ", " + SELECTOR_LIST_ITEMS).addClass(CLASS_NAME_ACTIVE$2); // Handle special case when .nav-link is inside .nav-item
17801
17802             $link.parents(SELECTOR_NAV_LIST_GROUP).prev(SELECTOR_NAV_ITEMS).children(SELECTOR_NAV_LINKS).addClass(CLASS_NAME_ACTIVE$2);
17803           }
17804
17805           $__default['default'](this._scrollElement).trigger(EVENT_ACTIVATE, {
17806             relatedTarget: target
17807           });
17808         };
17809
17810         _proto._clear = function _clear() {
17811           [].slice.call(document.querySelectorAll(this._selector)).filter(function (node) {
17812             return node.classList.contains(CLASS_NAME_ACTIVE$2);
17813           }).forEach(function (node) {
17814             return node.classList.remove(CLASS_NAME_ACTIVE$2);
17815           });
17816         } // Static
17817         ;
17818
17819         ScrollSpy._jQueryInterface = function _jQueryInterface(config) {
17820           return this.each(function () {
17821             var data = $__default['default'](this).data(DATA_KEY$8);
17822
17823             var _config = typeof config === 'object' && config;
17824
17825             if (!data) {
17826               data = new ScrollSpy(this, _config);
17827               $__default['default'](this).data(DATA_KEY$8, data);
17828             }
17829
17830             if (typeof config === 'string') {
17831               if (typeof data[config] === 'undefined') {
17832                 throw new TypeError("No method named \"" + config + "\"");
17833               }
17834
17835               data[config]();
17836             }
17837           });
17838         };
17839
17840         _createClass(ScrollSpy, null, [{
17841           key: "VERSION",
17842           get: function get() {
17843             return VERSION$8;
17844           }
17845         }, {
17846           key: "Default",
17847           get: function get() {
17848             return Default$6;
17849           }
17850         }]);
17851
17852         return ScrollSpy;
17853       }();
17854       /**
17855        * ------------------------------------------------------------------------
17856        * Data Api implementation
17857        * ------------------------------------------------------------------------
17858        */
17859
17860
17861       $__default['default'](window).on(EVENT_LOAD_DATA_API$2, function () {
17862         var scrollSpys = [].slice.call(document.querySelectorAll(SELECTOR_DATA_SPY));
17863         var scrollSpysLength = scrollSpys.length;
17864
17865         for (var i = scrollSpysLength; i--;) {
17866           var $spy = $__default['default'](scrollSpys[i]);
17867
17868           ScrollSpy._jQueryInterface.call($spy, $spy.data());
17869         }
17870       });
17871       /**
17872        * ------------------------------------------------------------------------
17873        * jQuery
17874        * ------------------------------------------------------------------------
17875        */
17876
17877       $__default['default'].fn[NAME$8] = ScrollSpy._jQueryInterface;
17878       $__default['default'].fn[NAME$8].Constructor = ScrollSpy;
17879
17880       $__default['default'].fn[NAME$8].noConflict = function () {
17881         $__default['default'].fn[NAME$8] = JQUERY_NO_CONFLICT$8;
17882         return ScrollSpy._jQueryInterface;
17883       };
17884
17885       /**
17886        * ------------------------------------------------------------------------
17887        * Constants
17888        * ------------------------------------------------------------------------
17889        */
17890
17891       var NAME$9 = 'tab';
17892       var VERSION$9 = '4.6.0';
17893       var DATA_KEY$9 = 'bs.tab';
17894       var EVENT_KEY$9 = "." + DATA_KEY$9;
17895       var DATA_API_KEY$7 = '.data-api';
17896       var JQUERY_NO_CONFLICT$9 = $__default['default'].fn[NAME$9];
17897       var EVENT_HIDE$3 = "hide" + EVENT_KEY$9;
17898       var EVENT_HIDDEN$3 = "hidden" + EVENT_KEY$9;
17899       var EVENT_SHOW$3 = "show" + EVENT_KEY$9;
17900       var EVENT_SHOWN$3 = "shown" + EVENT_KEY$9;
17901       var EVENT_CLICK_DATA_API$6 = "click" + EVENT_KEY$9 + DATA_API_KEY$7;
17902       var CLASS_NAME_DROPDOWN_MENU = 'dropdown-menu';
17903       var CLASS_NAME_ACTIVE$3 = 'active';
17904       var CLASS_NAME_DISABLED$1 = 'disabled';
17905       var CLASS_NAME_FADE$4 = 'fade';
17906       var CLASS_NAME_SHOW$6 = 'show';
17907       var SELECTOR_DROPDOWN$1 = '.dropdown';
17908       var SELECTOR_NAV_LIST_GROUP$1 = '.nav, .list-group';
17909       var SELECTOR_ACTIVE$2 = '.active';
17910       var SELECTOR_ACTIVE_UL = '> li > .active';
17911       var SELECTOR_DATA_TOGGLE$4 = '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]';
17912       var SELECTOR_DROPDOWN_TOGGLE$1 = '.dropdown-toggle';
17913       var SELECTOR_DROPDOWN_ACTIVE_CHILD = '> .dropdown-menu .active';
17914       /**
17915        * ------------------------------------------------------------------------
17916        * Class Definition
17917        * ------------------------------------------------------------------------
17918        */
17919
17920       var Tab = /*#__PURE__*/function () {
17921         function Tab(element) {
17922           this._element = element;
17923         } // Getters
17924
17925
17926         var _proto = Tab.prototype;
17927
17928         // Public
17929         _proto.show = function show() {
17930           var _this = this;
17931
17932           if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && $__default['default'](this._element).hasClass(CLASS_NAME_ACTIVE$3) || $__default['default'](this._element).hasClass(CLASS_NAME_DISABLED$1)) {
17933             return;
17934           }
17935
17936           var target;
17937           var previous;
17938           var listElement = $__default['default'](this._element).closest(SELECTOR_NAV_LIST_GROUP$1)[0];
17939           var selector = Util.getSelectorFromElement(this._element);
17940
17941           if (listElement) {
17942             var itemSelector = listElement.nodeName === 'UL' || listElement.nodeName === 'OL' ? SELECTOR_ACTIVE_UL : SELECTOR_ACTIVE$2;
17943             previous = $__default['default'].makeArray($__default['default'](listElement).find(itemSelector));
17944             previous = previous[previous.length - 1];
17945           }
17946
17947           var hideEvent = $__default['default'].Event(EVENT_HIDE$3, {
17948             relatedTarget: this._element
17949           });
17950           var showEvent = $__default['default'].Event(EVENT_SHOW$3, {
17951             relatedTarget: previous
17952           });
17953
17954           if (previous) {
17955             $__default['default'](previous).trigger(hideEvent);
17956           }
17957
17958           $__default['default'](this._element).trigger(showEvent);
17959
17960           if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) {
17961             return;
17962           }
17963
17964           if (selector) {
17965             target = document.querySelector(selector);
17966           }
17967
17968           this._activate(this._element, listElement);
17969
17970           var complete = function complete() {
17971             var hiddenEvent = $__default['default'].Event(EVENT_HIDDEN$3, {
17972               relatedTarget: _this._element
17973             });
17974             var shownEvent = $__default['default'].Event(EVENT_SHOWN$3, {
17975               relatedTarget: previous
17976             });
17977             $__default['default'](previous).trigger(hiddenEvent);
17978             $__default['default'](_this._element).trigger(shownEvent);
17979           };
17980
17981           if (target) {
17982             this._activate(target, target.parentNode, complete);
17983           } else {
17984             complete();
17985           }
17986         };
17987
17988         _proto.dispose = function dispose() {
17989           $__default['default'].removeData(this._element, DATA_KEY$9);
17990           this._element = null;
17991         } // Private
17992         ;
17993
17994         _proto._activate = function _activate(element, container, callback) {
17995           var _this2 = this;
17996
17997           var activeElements = container && (container.nodeName === 'UL' || container.nodeName === 'OL') ? $__default['default'](container).find(SELECTOR_ACTIVE_UL) : $__default['default'](container).children(SELECTOR_ACTIVE$2);
17998           var active = activeElements[0];
17999           var isTransitioning = callback && active && $__default['default'](active).hasClass(CLASS_NAME_FADE$4);
18000
18001           var complete = function complete() {
18002             return _this2._transitionComplete(element, active, callback);
18003           };
18004
18005           if (active && isTransitioning) {
18006             var transitionDuration = Util.getTransitionDurationFromElement(active);
18007             $__default['default'](active).removeClass(CLASS_NAME_SHOW$6).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
18008           } else {
18009             complete();
18010           }
18011         };
18012
18013         _proto._transitionComplete = function _transitionComplete(element, active, callback) {
18014           if (active) {
18015             $__default['default'](active).removeClass(CLASS_NAME_ACTIVE$3);
18016             var dropdownChild = $__default['default'](active.parentNode).find(SELECTOR_DROPDOWN_ACTIVE_CHILD)[0];
18017
18018             if (dropdownChild) {
18019               $__default['default'](dropdownChild).removeClass(CLASS_NAME_ACTIVE$3);
18020             }
18021
18022             if (active.getAttribute('role') === 'tab') {
18023               active.setAttribute('aria-selected', false);
18024             }
18025           }
18026
18027           $__default['default'](element).addClass(CLASS_NAME_ACTIVE$3);
18028
18029           if (element.getAttribute('role') === 'tab') {
18030             element.setAttribute('aria-selected', true);
18031           }
18032
18033           Util.reflow(element);
18034
18035           if (element.classList.contains(CLASS_NAME_FADE$4)) {
18036             element.classList.add(CLASS_NAME_SHOW$6);
18037           }
18038
18039           if (element.parentNode && $__default['default'](element.parentNode).hasClass(CLASS_NAME_DROPDOWN_MENU)) {
18040             var dropdownElement = $__default['default'](element).closest(SELECTOR_DROPDOWN$1)[0];
18041
18042             if (dropdownElement) {
18043               var dropdownToggleList = [].slice.call(dropdownElement.querySelectorAll(SELECTOR_DROPDOWN_TOGGLE$1));
18044               $__default['default'](dropdownToggleList).addClass(CLASS_NAME_ACTIVE$3);
18045             }
18046
18047             element.setAttribute('aria-expanded', true);
18048           }
18049
18050           if (callback) {
18051             callback();
18052           }
18053         } // Static
18054         ;
18055
18056         Tab._jQueryInterface = function _jQueryInterface(config) {
18057           return this.each(function () {
18058             var $this = $__default['default'](this);
18059             var data = $this.data(DATA_KEY$9);
18060
18061             if (!data) {
18062               data = new Tab(this);
18063               $this.data(DATA_KEY$9, data);
18064             }
18065
18066             if (typeof config === 'string') {
18067               if (typeof data[config] === 'undefined') {
18068                 throw new TypeError("No method named \"" + config + "\"");
18069               }
18070
18071               data[config]();
18072             }
18073           });
18074         };
18075
18076         _createClass(Tab, null, [{
18077           key: "VERSION",
18078           get: function get() {
18079             return VERSION$9;
18080           }
18081         }]);
18082
18083         return Tab;
18084       }();
18085       /**
18086        * ------------------------------------------------------------------------
18087        * Data Api implementation
18088        * ------------------------------------------------------------------------
18089        */
18090
18091
18092       $__default['default'](document).on(EVENT_CLICK_DATA_API$6, SELECTOR_DATA_TOGGLE$4, function (event) {
18093         event.preventDefault();
18094
18095         Tab._jQueryInterface.call($__default['default'](this), 'show');
18096       });
18097       /**
18098        * ------------------------------------------------------------------------
18099        * jQuery
18100        * ------------------------------------------------------------------------
18101        */
18102
18103       $__default['default'].fn[NAME$9] = Tab._jQueryInterface;
18104       $__default['default'].fn[NAME$9].Constructor = Tab;
18105
18106       $__default['default'].fn[NAME$9].noConflict = function () {
18107         $__default['default'].fn[NAME$9] = JQUERY_NO_CONFLICT$9;
18108         return Tab._jQueryInterface;
18109       };
18110
18111       /**
18112        * ------------------------------------------------------------------------
18113        * Constants
18114        * ------------------------------------------------------------------------
18115        */
18116
18117       var NAME$a = 'toast';
18118       var VERSION$a = '4.6.0';
18119       var DATA_KEY$a = 'bs.toast';
18120       var EVENT_KEY$a = "." + DATA_KEY$a;
18121       var JQUERY_NO_CONFLICT$a = $__default['default'].fn[NAME$a];
18122       var EVENT_CLICK_DISMISS$1 = "click.dismiss" + EVENT_KEY$a;
18123       var EVENT_HIDE$4 = "hide" + EVENT_KEY$a;
18124       var EVENT_HIDDEN$4 = "hidden" + EVENT_KEY$a;
18125       var EVENT_SHOW$4 = "show" + EVENT_KEY$a;
18126       var EVENT_SHOWN$4 = "shown" + EVENT_KEY$a;
18127       var CLASS_NAME_FADE$5 = 'fade';
18128       var CLASS_NAME_HIDE = 'hide';
18129       var CLASS_NAME_SHOW$7 = 'show';
18130       var CLASS_NAME_SHOWING = 'showing';
18131       var DefaultType$7 = {
18132         animation: 'boolean',
18133         autohide: 'boolean',
18134         delay: 'number'
18135       };
18136       var Default$7 = {
18137         animation: true,
18138         autohide: true,
18139         delay: 500
18140       };
18141       var SELECTOR_DATA_DISMISS$1 = '[data-dismiss="toast"]';
18142       /**
18143        * ------------------------------------------------------------------------
18144        * Class Definition
18145        * ------------------------------------------------------------------------
18146        */
18147
18148       var Toast = /*#__PURE__*/function () {
18149         function Toast(element, config) {
18150           this._element = element;
18151           this._config = this._getConfig(config);
18152           this._timeout = null;
18153
18154           this._setListeners();
18155         } // Getters
18156
18157
18158         var _proto = Toast.prototype;
18159
18160         // Public
18161         _proto.show = function show() {
18162           var _this = this;
18163
18164           var showEvent = $__default['default'].Event(EVENT_SHOW$4);
18165           $__default['default'](this._element).trigger(showEvent);
18166
18167           if (showEvent.isDefaultPrevented()) {
18168             return;
18169           }
18170
18171           this._clearTimeout();
18172
18173           if (this._config.animation) {
18174             this._element.classList.add(CLASS_NAME_FADE$5);
18175           }
18176
18177           var complete = function complete() {
18178             _this._element.classList.remove(CLASS_NAME_SHOWING);
18179
18180             _this._element.classList.add(CLASS_NAME_SHOW$7);
18181
18182             $__default['default'](_this._element).trigger(EVENT_SHOWN$4);
18183
18184             if (_this._config.autohide) {
18185               _this._timeout = setTimeout(function () {
18186                 _this.hide();
18187               }, _this._config.delay);
18188             }
18189           };
18190
18191           this._element.classList.remove(CLASS_NAME_HIDE);
18192
18193           Util.reflow(this._element);
18194
18195           this._element.classList.add(CLASS_NAME_SHOWING);
18196
18197           if (this._config.animation) {
18198             var transitionDuration = Util.getTransitionDurationFromElement(this._element);
18199             $__default['default'](this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
18200           } else {
18201             complete();
18202           }
18203         };
18204
18205         _proto.hide = function hide() {
18206           if (!this._element.classList.contains(CLASS_NAME_SHOW$7)) {
18207             return;
18208           }
18209
18210           var hideEvent = $__default['default'].Event(EVENT_HIDE$4);
18211           $__default['default'](this._element).trigger(hideEvent);
18212
18213           if (hideEvent.isDefaultPrevented()) {
18214             return;
18215           }
18216
18217           this._close();
18218         };
18219
18220         _proto.dispose = function dispose() {
18221           this._clearTimeout();
18222
18223           if (this._element.classList.contains(CLASS_NAME_SHOW$7)) {
18224             this._element.classList.remove(CLASS_NAME_SHOW$7);
18225           }
18226
18227           $__default['default'](this._element).off(EVENT_CLICK_DISMISS$1);
18228           $__default['default'].removeData(this._element, DATA_KEY$a);
18229           this._element = null;
18230           this._config = null;
18231         } // Private
18232         ;
18233
18234         _proto._getConfig = function _getConfig(config) {
18235           config = _extends({}, Default$7, $__default['default'](this._element).data(), typeof config === 'object' && config ? config : {});
18236           Util.typeCheckConfig(NAME$a, config, this.constructor.DefaultType);
18237           return config;
18238         };
18239
18240         _proto._setListeners = function _setListeners() {
18241           var _this2 = this;
18242
18243           $__default['default'](this._element).on(EVENT_CLICK_DISMISS$1, SELECTOR_DATA_DISMISS$1, function () {
18244             return _this2.hide();
18245           });
18246         };
18247
18248         _proto._close = function _close() {
18249           var _this3 = this;
18250
18251           var complete = function complete() {
18252             _this3._element.classList.add(CLASS_NAME_HIDE);
18253
18254             $__default['default'](_this3._element).trigger(EVENT_HIDDEN$4);
18255           };
18256
18257           this._element.classList.remove(CLASS_NAME_SHOW$7);
18258
18259           if (this._config.animation) {
18260             var transitionDuration = Util.getTransitionDurationFromElement(this._element);
18261             $__default['default'](this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(transitionDuration);
18262           } else {
18263             complete();
18264           }
18265         };
18266
18267         _proto._clearTimeout = function _clearTimeout() {
18268           clearTimeout(this._timeout);
18269           this._timeout = null;
18270         } // Static
18271         ;
18272
18273         Toast._jQueryInterface = function _jQueryInterface(config) {
18274           return this.each(function () {
18275             var $element = $__default['default'](this);
18276             var data = $element.data(DATA_KEY$a);
18277
18278             var _config = typeof config === 'object' && config;
18279
18280             if (!data) {
18281               data = new Toast(this, _config);
18282               $element.data(DATA_KEY$a, data);
18283             }
18284
18285             if (typeof config === 'string') {
18286               if (typeof data[config] === 'undefined') {
18287                 throw new TypeError("No method named \"" + config + "\"");
18288               }
18289
18290               data[config](this);
18291             }
18292           });
18293         };
18294
18295         _createClass(Toast, null, [{
18296           key: "VERSION",
18297           get: function get() {
18298             return VERSION$a;
18299           }
18300         }, {
18301           key: "DefaultType",
18302           get: function get() {
18303             return DefaultType$7;
18304           }
18305         }, {
18306           key: "Default",
18307           get: function get() {
18308             return Default$7;
18309           }
18310         }]);
18311
18312         return Toast;
18313       }();
18314       /**
18315        * ------------------------------------------------------------------------
18316        * jQuery
18317        * ------------------------------------------------------------------------
18318        */
18319
18320
18321       $__default['default'].fn[NAME$a] = Toast._jQueryInterface;
18322       $__default['default'].fn[NAME$a].Constructor = Toast;
18323
18324       $__default['default'].fn[NAME$a].noConflict = function () {
18325         $__default['default'].fn[NAME$a] = JQUERY_NO_CONFLICT$a;
18326         return Toast._jQueryInterface;
18327       };
18328
18329       exports.Alert = Alert;
18330       exports.Button = Button;
18331       exports.Carousel = Carousel;
18332       exports.Collapse = Collapse;
18333       exports.Dropdown = Dropdown;
18334       exports.Modal = Modal;
18335       exports.Popover = Popover;
18336       exports.Scrollspy = ScrollSpy;
18337       exports.Tab = Tab;
18338       exports.Toast = Toast;
18339       exports.Tooltip = Tooltip;
18340       exports.Util = Util;
18341
18342       Object.defineProperty(exports, '__esModule', { value: true });
18343
18344     })));
18345
18346     });
18347
18348     const subscriber_queue = [];
18349     /**
18350      * Create a `Writable` store that allows both updating and reading by subscription.
18351      * @param {*=}value initial value
18352      * @param {StartStopNotifier=}start start and stop notifications for subscriptions
18353      */
18354     function writable(value, start = noop) {
18355         let stop;
18356         const subscribers = [];
18357         function set(new_value) {
18358             if (safe_not_equal(value, new_value)) {
18359                 value = new_value;
18360                 if (stop) { // store is ready
18361                     const run_queue = !subscriber_queue.length;
18362                     for (let i = 0; i < subscribers.length; i += 1) {
18363                         const s = subscribers[i];
18364                         s[1]();
18365                         subscriber_queue.push(s, value);
18366                     }
18367                     if (run_queue) {
18368                         for (let i = 0; i < subscriber_queue.length; i += 2) {
18369                             subscriber_queue[i][0](subscriber_queue[i + 1]);
18370                         }
18371                         subscriber_queue.length = 0;
18372                     }
18373                 }
18374             }
18375         }
18376         function update(fn) {
18377             set(fn(value));
18378         }
18379         function subscribe(run, invalidate = noop) {
18380             const subscriber = [run, invalidate];
18381             subscribers.push(subscriber);
18382             if (subscribers.length === 1) {
18383                 stop = start(set) || noop;
18384             }
18385             run(value);
18386             return () => {
18387                 const index = subscribers.indexOf(subscriber);
18388                 if (index !== -1) {
18389                     subscribers.splice(index, 1);
18390                 }
18391                 if (subscribers.length === 0) {
18392                     stop();
18393                     stop = null;
18394                 }
18395             };
18396         }
18397         return { set, update, subscribe };
18398     }
18399
18400     const map_store = writable();
18401     const results_store = writable();
18402     const current_result_store = writable();
18403     const current_request_latlon = writable();
18404     const last_updated_store = writable();
18405
18406     /* src/components/Header.svelte generated by Svelte v3.31.2 */
18407     const file = "src/components/Header.svelte";
18408
18409     // (76:8) {#if last_updated}
18410     function create_if_block(ctx) {
18411         let div;
18412         let t0;
18413         let a0;
18414         let t1;
18415         let a0_href_value;
18416         let t2;
18417         let span0;
18418         let t3;
18419         let a1;
18420         let t4;
18421         let a1_href_value;
18422         let t5;
18423         let t6;
18424         let span1;
18425         let t7_value = /*last_updated*/ ctx[0].date + "";
18426         let t7;
18427
18428         const block = {
18429                 c: function create() {
18430                         div = element("div");
18431                         t0 = text("Data from ");
18432                         a0 = element("a");
18433                         t1 = text("API request");
18434                         t2 = space();
18435                         span0 = element("span");
18436                         t3 = text("(");
18437                         a1 = element("a");
18438                         t4 = text("debug output");
18439                         t5 = text(")");
18440                         t6 = text("\n          Data last updated: ");
18441                         span1 = element("span");
18442                         t7 = text(t7_value);
18443                         attr_dev(a0, "href", a0_href_value = /*last_updated*/ ctx[0].api_request_url);
18444                         attr_dev(a0, "class", "svelte-1hjkg8o");
18445                         add_location(a0, file, 77, 22, 1413);
18446                         attr_dev(a1, "href", a1_href_value = /*last_updated*/ ctx[0].api_request_url_debug);
18447                         attr_dev(a1, "class", "svelte-1hjkg8o");
18448                         add_location(a1, file, 78, 42, 1512);
18449                         attr_dev(span0, "id", "api-request-debug");
18450                         add_location(span0, file, 78, 12, 1482);
18451                         attr_dev(div, "id", "api-request");
18452                         add_location(div, file, 76, 10, 1368);
18453                         attr_dev(span1, "id", "data-date");
18454                         add_location(span1, file, 80, 29, 1630);
18455                 },
18456                 m: function mount(target, anchor) {
18457                         insert_dev(target, div, anchor);
18458                         append_dev(div, t0);
18459                         append_dev(div, a0);
18460                         append_dev(a0, t1);
18461                         append_dev(div, t2);
18462                         append_dev(div, span0);
18463                         append_dev(span0, t3);
18464                         append_dev(span0, a1);
18465                         append_dev(a1, t4);
18466                         append_dev(span0, t5);
18467                         insert_dev(target, t6, anchor);
18468                         insert_dev(target, span1, anchor);
18469                         append_dev(span1, t7);
18470                 },
18471                 p: function update(ctx, dirty) {
18472                         if (dirty & /*last_updated*/ 1 && a0_href_value !== (a0_href_value = /*last_updated*/ ctx[0].api_request_url)) {
18473                                 attr_dev(a0, "href", a0_href_value);
18474                         }
18475
18476                         if (dirty & /*last_updated*/ 1 && a1_href_value !== (a1_href_value = /*last_updated*/ ctx[0].api_request_url_debug)) {
18477                                 attr_dev(a1, "href", a1_href_value);
18478                         }
18479
18480                         if (dirty & /*last_updated*/ 1 && t7_value !== (t7_value = /*last_updated*/ ctx[0].date + "")) set_data_dev(t7, t7_value);
18481                 },
18482                 d: function destroy(detaching) {
18483                         if (detaching) detach_dev(div);
18484                         if (detaching) detach_dev(t6);
18485                         if (detaching) detach_dev(span1);
18486                 }
18487         };
18488
18489         dispatch_dev("SvelteRegisterBlock", {
18490                 block,
18491                 id: create_if_block.name,
18492                 type: "if",
18493                 source: "(76:8) {#if last_updated}",
18494                 ctx
18495         });
18496
18497         return block;
18498     }
18499
18500     function create_fragment(ctx) {
18501         let header;
18502         let div9;
18503         let div1;
18504         let div0;
18505         let a0;
18506         let img;
18507         let img_src_value;
18508         let t0;
18509         let h1;
18510         let t2;
18511         let div4;
18512         let div3;
18513         let div2;
18514         let t4;
18515         let t5;
18516         let div8;
18517         let div7;
18518         let button;
18519         let t7;
18520         let div6;
18521         let a1;
18522         let t9;
18523         let a2;
18524         let t11;
18525         let a3;
18526         let t13;
18527         let a4;
18528         let t15;
18529         let a5;
18530         let t17;
18531         let div5;
18532         let t18;
18533         let a6;
18534         let if_block = /*last_updated*/ ctx[0] && create_if_block(ctx);
18535
18536         const block = {
18537                 c: function create() {
18538                         header = element("header");
18539                         div9 = element("div");
18540                         div1 = element("div");
18541                         div0 = element("div");
18542                         a0 = element("a");
18543                         img = element("img");
18544                         t0 = space();
18545                         h1 = element("h1");
18546                         h1.textContent = "Nominatim";
18547                         t2 = space();
18548                         div4 = element("div");
18549                         div3 = element("div");
18550                         div2 = element("div");
18551                         div2.textContent = "loading...";
18552                         t4 = space();
18553                         if (if_block) if_block.c();
18554                         t5 = space();
18555                         div8 = element("div");
18556                         div7 = element("div");
18557                         button = element("button");
18558                         button.textContent = "About & Help";
18559                         t7 = space();
18560                         div6 = element("div");
18561                         a1 = element("a");
18562                         a1.textContent = "API Reference";
18563                         t9 = space();
18564                         a2 = element("a");
18565                         a2.textContent = "FAQ";
18566                         t11 = space();
18567                         a3 = element("a");
18568                         a3.textContent = "OpenStreetMap Help";
18569                         t13 = space();
18570                         a4 = element("a");
18571                         a4.textContent = "Nominatim on Github";
18572                         t15 = space();
18573                         a5 = element("a");
18574                         a5.textContent = "This frontend on Github";
18575                         t17 = space();
18576                         div5 = element("div");
18577                         t18 = space();
18578                         a6 = element("a");
18579                         a6.textContent = "Report problem with results";
18580                         attr_dev(img, "alt", "logo");
18581                         if (img.src !== (img_src_value = "images/osm_logo.120px.png")) attr_dev(img, "src", img_src_value);
18582                         attr_dev(img, "width", "30");
18583                         attr_dev(img, "height", "30");
18584                         attr_dev(img, "class", "svelte-1hjkg8o");
18585                         add_location(img, file, 67, 10, 1075);
18586                         attr_dev(h1, "class", "svelte-1hjkg8o");
18587                         add_location(h1, file, 68, 10, 1158);
18588                         attr_dev(a0, "href", "search.html");
18589                         attr_dev(a0, "class", "svelte-1hjkg8o");
18590                         add_location(a0, file, 66, 8, 1042);
18591                         attr_dev(div0, "class", "brand svelte-1hjkg8o");
18592                         add_location(div0, file, 65, 6, 1014);
18593                         attr_dev(div1, "class", "col-4");
18594                         add_location(div1, file, 64, 4, 988);
18595                         attr_dev(div2, "id", "loading");
18596                         attr_dev(div2, "class", "svelte-1hjkg8o");
18597                         add_location(div2, file, 74, 8, 1296);
18598                         attr_dev(div3, "id", "last-updated");
18599                         attr_dev(div3, "class", "text-center svelte-1hjkg8o");
18600                         add_location(div3, file, 73, 6, 1244);
18601                         attr_dev(div4, "class", "col-4");
18602                         add_location(div4, file, 72, 4, 1218);
18603                         attr_dev(button, "class", "dropdown-toggle btn btn-sm btn-outline-secondary");
18604                         attr_dev(button, "data-toggle", "dropdown");
18605                         attr_dev(button, "role", "button");
18606                         attr_dev(button, "aria-haspopup", "true");
18607                         attr_dev(button, "aria-expanded", "false");
18608                         add_location(button, file, 86, 8, 1788);
18609                         attr_dev(a1, "class", "dropdown-item svelte-1hjkg8o");
18610                         attr_dev(a1, "href", "https://nominatim.org/release-docs/develop/api/Overview/");
18611                         attr_dev(a1, "target", "_blank");
18612                         add_location(a1, file, 90, 10, 2045);
18613                         attr_dev(a2, "class", "dropdown-item svelte-1hjkg8o");
18614                         attr_dev(a2, "href", "https://nominatim.org/release-docs/develop/api/Faq/");
18615                         attr_dev(a2, "target", "_blank");
18616                         add_location(a2, file, 91, 10, 2178);
18617                         attr_dev(a3, "class", "dropdown-item svelte-1hjkg8o");
18618                         attr_dev(a3, "href", "https://help.openstreetmap.org/tags/nominatim/");
18619                         add_location(a3, file, 92, 10, 2296);
18620                         attr_dev(a4, "class", "dropdown-item svelte-1hjkg8o");
18621                         attr_dev(a4, "href", "https://github.com/osm-search/Nominatim");
18622                         add_location(a4, file, 93, 10, 2408);
18623                         attr_dev(a5, "class", "dropdown-item svelte-1hjkg8o");
18624                         attr_dev(a5, "href", "https://github.com/osm-search/nominatim-ui");
18625                         add_location(a5, file, 94, 10, 2514);
18626                         attr_dev(div5, "class", "dropdown-divider");
18627                         add_location(div5, file, 95, 10, 2627);
18628                         attr_dev(a6, "class", "dropdown-item svelte-1hjkg8o");
18629                         attr_dev(a6, "href", "#");
18630                         attr_dev(a6, "data-toggle", "modal");
18631                         attr_dev(a6, "data-target", "#report-modal");
18632                         add_location(a6, file, 96, 10, 2674);
18633                         attr_dev(div6, "class", "dropdown-menu dropdown-menu-right svelte-1hjkg8o");
18634                         add_location(div6, file, 89, 8, 1987);
18635                         attr_dev(div7, "class", "dropdown");
18636                         add_location(div7, file, 85, 6, 1757);
18637                         attr_dev(div8, "class", "col-4 text-right");
18638                         add_location(div8, file, 84, 4, 1720);
18639                         attr_dev(div9, "class", "row");
18640                         add_location(div9, file, 63, 2, 966);
18641                         attr_dev(header, "class", "container-fluid svelte-1hjkg8o");
18642                         add_location(header, file, 62, 0, 931);
18643                 },
18644                 l: function claim(nodes) {
18645                         throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
18646                 },
18647                 m: function mount(target, anchor) {
18648                         insert_dev(target, header, anchor);
18649                         append_dev(header, div9);
18650                         append_dev(div9, div1);
18651                         append_dev(div1, div0);
18652                         append_dev(div0, a0);
18653                         append_dev(a0, img);
18654                         append_dev(a0, t0);
18655                         append_dev(a0, h1);
18656                         append_dev(div9, t2);
18657                         append_dev(div9, div4);
18658                         append_dev(div4, div3);
18659                         append_dev(div3, div2);
18660                         append_dev(div3, t4);
18661                         if (if_block) if_block.m(div3, null);
18662                         append_dev(div9, t5);
18663                         append_dev(div9, div8);
18664                         append_dev(div8, div7);
18665                         append_dev(div7, button);
18666                         append_dev(div7, t7);
18667                         append_dev(div7, div6);
18668                         append_dev(div6, a1);
18669                         append_dev(div6, t9);
18670                         append_dev(div6, a2);
18671                         append_dev(div6, t11);
18672                         append_dev(div6, a3);
18673                         append_dev(div6, t13);
18674                         append_dev(div6, a4);
18675                         append_dev(div6, t15);
18676                         append_dev(div6, a5);
18677                         append_dev(div6, t17);
18678                         append_dev(div6, div5);
18679                         append_dev(div6, t18);
18680                         append_dev(div6, a6);
18681                 },
18682                 p: function update(ctx, [dirty]) {
18683                         if (/*last_updated*/ ctx[0]) {
18684                                 if (if_block) {
18685                                         if_block.p(ctx, dirty);
18686                                 } else {
18687                                         if_block = create_if_block(ctx);
18688                                         if_block.c();
18689                                         if_block.m(div3, null);
18690                                 }
18691                         } else if (if_block) {
18692                                 if_block.d(1);
18693                                 if_block = null;
18694                         }
18695                 },
18696                 i: noop,
18697                 o: noop,
18698                 d: function destroy(detaching) {
18699                         if (detaching) detach_dev(header);
18700                         if (if_block) if_block.d();
18701                 }
18702         };
18703
18704         dispatch_dev("SvelteRegisterBlock", {
18705                 block,
18706                 id: create_fragment.name,
18707                 type: "component",
18708                 source: "",
18709                 ctx
18710         });
18711
18712         return block;
18713     }
18714
18715     function instance($$self, $$props, $$invalidate) {
18716         let { $$slots: slots = {}, $$scope } = $$props;
18717         validate_slots("Header", slots, []);
18718         let last_updated;
18719
18720         last_updated_store.subscribe(data => {
18721                 if (!data) {
18722                         return;
18723                 }
18724
18725                 $$invalidate(0, last_updated = data);
18726         });
18727
18728         const writable_props = [];
18729
18730         Object.keys($$props).forEach(key => {
18731                 if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<Header> was created with unknown prop '${key}'`);
18732         });
18733
18734         $$self.$capture_state = () => ({ last_updated_store, last_updated });
18735
18736         $$self.$inject_state = $$props => {
18737                 if ("last_updated" in $$props) $$invalidate(0, last_updated = $$props.last_updated);
18738         };
18739
18740         if ($$props && "$$inject" in $$props) {
18741                 $$self.$inject_state($$props.$$inject);
18742         }
18743
18744         return [last_updated];
18745     }
18746
18747     class Header extends SvelteComponentDev {
18748         constructor(options) {
18749                 super(options);
18750                 init(this, options, instance, create_fragment, safe_not_equal, {});
18751
18752                 dispatch_dev("SvelteRegisterComponent", {
18753                         component: this,
18754                         tagName: "Header",
18755                         options,
18756                         id: create_fragment.name
18757                 });
18758         }
18759     }
18760
18761     /* src/components/Footer.svelte generated by Svelte v3.31.2 */
18762
18763     const file$1 = "src/components/Footer.svelte";
18764
18765     function create_fragment$1(ctx) {
18766         let footer;
18767         let p0;
18768         let t1;
18769         let p1;
18770         let t2;
18771         let a;
18772         let t4;
18773
18774         const block = {
18775                 c: function create() {
18776                         footer = element("footer");
18777                         p0 = element("p");
18778                         p0.textContent = "Addresses and postcodes are approximate";
18779                         t1 = space();
18780                         p1 = element("p");
18781                         t2 = text("© ");
18782                         a = element("a");
18783                         a.textContent = "OpenStreetMap";
18784                         t4 = text(" contributors");
18785                         attr_dev(p0, "class", "disclaimer svelte-1f2bd8l");
18786                         add_location(p0, file$1, 12, 2, 141);
18787                         attr_dev(a, "href", "https://osm.org/copyright");
18788                         add_location(a, file$1, 16, 11, 250);
18789                         attr_dev(p1, "class", "copyright svelte-1f2bd8l");
18790                         add_location(p1, file$1, 15, 2, 217);
18791                         attr_dev(footer, "class", "svelte-1f2bd8l");
18792                         add_location(footer, file$1, 11, 0, 130);
18793                 },
18794                 l: function claim(nodes) {
18795                         throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
18796                 },
18797                 m: function mount(target, anchor) {
18798                         insert_dev(target, footer, anchor);
18799                         append_dev(footer, p0);
18800                         append_dev(footer, t1);
18801                         append_dev(footer, p1);
18802                         append_dev(p1, t2);
18803                         append_dev(p1, a);
18804                         append_dev(p1, t4);
18805                 },
18806                 p: noop,
18807                 i: noop,
18808                 o: noop,
18809                 d: function destroy(detaching) {
18810                         if (detaching) detach_dev(footer);
18811                 }
18812         };
18813
18814         dispatch_dev("SvelteRegisterBlock", {
18815                 block,
18816                 id: create_fragment$1.name,
18817                 type: "component",
18818                 source: "",
18819                 ctx
18820         });
18821
18822         return block;
18823     }
18824
18825     function instance$1($$self, $$props) {
18826         let { $$slots: slots = {}, $$scope } = $$props;
18827         validate_slots("Footer", slots, []);
18828         const writable_props = [];
18829
18830         Object.keys($$props).forEach(key => {
18831                 if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<Footer> was created with unknown prop '${key}'`);
18832         });
18833
18834         return [];
18835     }
18836
18837     class Footer extends SvelteComponentDev {
18838         constructor(options) {
18839                 super(options);
18840                 init(this, options, instance$1, create_fragment$1, safe_not_equal, {});
18841
18842                 dispatch_dev("SvelteRegisterComponent", {
18843                         component: this,
18844                         tagName: "Footer",
18845                         options,
18846                         id: create_fragment$1.name
18847                 });
18848         }
18849     }
18850
18851     /* src/App.svelte generated by Svelte v3.31.2 */
18852     const file$2 = "src/App.svelte";
18853
18854     function create_fragment$2(ctx) {
18855         let header;
18856         let t0;
18857         let div;
18858         let t1;
18859         let footer;
18860         let current;
18861         header = new Header({ $$inline: true });
18862         footer = new Footer({ $$inline: true });
18863
18864         const block = {
18865                 c: function create() {
18866                         create_component(header.$$.fragment);
18867                         t0 = space();
18868                         div = element("div");
18869                         t1 = space();
18870                         create_component(footer.$$.fragment);
18871                         attr_dev(div, "id", "main");
18872                         add_location(div, file$2, 10, 0, 297);
18873                 },
18874                 l: function claim(nodes) {
18875                         throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
18876                 },
18877                 m: function mount(target, anchor) {
18878                         mount_component(header, target, anchor);
18879                         insert_dev(target, t0, anchor);
18880                         insert_dev(target, div, anchor);
18881                         insert_dev(target, t1, anchor);
18882                         mount_component(footer, target, anchor);
18883                         current = true;
18884                 },
18885                 p: noop,
18886                 i: function intro(local) {
18887                         if (current) return;
18888                         transition_in(header.$$.fragment, local);
18889                         transition_in(footer.$$.fragment, local);
18890                         current = true;
18891                 },
18892                 o: function outro(local) {
18893                         transition_out(header.$$.fragment, local);
18894                         transition_out(footer.$$.fragment, local);
18895                         current = false;
18896                 },
18897                 d: function destroy(detaching) {
18898                         destroy_component(header, detaching);
18899                         if (detaching) detach_dev(t0);
18900                         if (detaching) detach_dev(div);
18901                         if (detaching) detach_dev(t1);
18902                         destroy_component(footer, detaching);
18903                 }
18904         };
18905
18906         dispatch_dev("SvelteRegisterBlock", {
18907                 block,
18908                 id: create_fragment$2.name,
18909                 type: "component",
18910                 source: "",
18911                 ctx
18912         });
18913
18914         return block;
18915     }
18916
18917     function instance$2($$self, $$props, $$invalidate) {
18918         let { $$slots: slots = {}, $$scope } = $$props;
18919         validate_slots("App", slots, []);
18920         const writable_props = [];
18921
18922         Object.keys($$props).forEach(key => {
18923                 if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<App> was created with unknown prop '${key}'`);
18924         });
18925
18926         $$self.$capture_state = () => ({ jquery: jquery$1, Header, Footer });
18927         return [];
18928     }
18929
18930     class App extends SvelteComponentDev {
18931         constructor(options) {
18932                 super(options);
18933                 init(this, options, instance$2, create_fragment$2, safe_not_equal, {});
18934
18935                 dispatch_dev("SvelteRegisterComponent", {
18936                         component: this,
18937                         tagName: "App",
18938                         options,
18939                         id: create_fragment$2.name
18940                 });
18941         }
18942     }
18943
18944     var get_config_value_1 = get_config_value;
18945
18946
18947     const Nominatim_Config_Defaults = {
18948       Nominatim_API_Endpoint: 'http://localhost/nominatim/',
18949       Images_Base_Url: 'mapicons/',
18950       Search_AreaPolygons: 1,
18951       Reverse_Default_Search_Zoom: 18,
18952       Map_Default_Lat: 20.0,
18953       Map_Default_Lon: 0.0,
18954       Map_Default_Zoom: 2,
18955       Map_Tile_URL: 'https://{s}.tile.osm.org/{z}/{x}/{y}.png',
18956       Map_Tile_Attribution: '<a href="https://osm.org/copyright">OpenStreetMap contributors</a>'
18957     };
18958
18959     function get_config_value(str, default_val) {
18960       var value = ((typeof Nominatim_Config !== 'undefined')
18961                    && (typeof Nominatim_Config[str] !== 'undefined'))
18962         ? Nominatim_Config[str]
18963         : Nominatim_Config_Defaults[str];
18964       return (typeof value !== 'undefined' ? value : default_val);
18965     }
18966
18967     async function fetch_from_api(endpoint_name, params, callback) {
18968       var api_url = generate_nominatim_api_url(endpoint_name, params);
18969
18970       document.getElementById('loading').style.display = 'block';
18971       await fetch(api_url)
18972         .then(response => response.json())
18973         .then(data => {
18974           callback(data);
18975           document.getElementById('loading').style.display = 'none';
18976         });
18977
18978
18979       fetch(generate_nominatim_api_url('status', {format: 'json'}))
18980         .then(response => response.json())
18981         .then(data => {
18982           let last_updated = {
18983             api_request_url: api_url,
18984             api_request_url_debug: api_url + '&debug=1',
18985             date: data.data_updated
18986           };
18987           last_updated_store.set(last_updated);
18988         });
18989     }
18990
18991     function generate_nominatim_api_url(endpoint_name, params) {
18992       return get_config_value_1('Nominatim_API_Endpoint') + endpoint_name + '.php?'
18993              + Object.keys(clean_up_parameters(params)).map( (k) => {
18994                return encodeURIComponent(k) + '=' + encodeURIComponent(params[k])
18995              }).join('&');
18996     }
18997
18998     /*!
18999      * Serialize all form data into a SearchParams string
19000      * (c) 2020 Chris Ferdinandi, MIT License, https://gomakethings.com
19001      * @param  {Node}   form The form to serialize
19002      * @return {String}      The serialized form data
19003      */
19004     function serialize_form(form) {
19005       var arr = [];
19006       Array.prototype.slice.call(form.elements).forEach(function (field) {
19007         if (!field.name || field.disabled || ['file', 'reset', 'submit', 'button'].indexOf(field.type) > -1) return;
19008         // if (field.type === 'select-multiple') {
19009         //   Array.prototype.slice.call(field.options).forEach(function (option) {
19010         //     if (!option.selected) return;
19011         //     arr.push(encodeURIComponent(field.name) + '=' + encodeURIComponent(option.value));
19012         //   });
19013         //   return;
19014         // }
19015         if (['checkbox', 'radio'].indexOf(field.type) >-1 && !field.checked) return;
19016         if (typeof(field.value) === 'undefined') return;
19017         arr.push(encodeURIComponent(field.name) + '=' + encodeURIComponent(field.value));
19018       });
19019       return arr.join('&');
19020     }
19021
19022     // remove any URL paramters with empty values
19023     // '&empty=&filled=value' => 'filled=value'
19024     function clean_up_url_parameters(url) {
19025       var url_params = new URLSearchParams(url);
19026       var to_delete = []; // deleting inside loop would skip iterations
19027       url_params.forEach(function (value, key) {
19028         if (value === '') to_delete.push(key);
19029       });
19030       for (var i = 0; i < to_delete.length; i += 1) {
19031         url_params.delete(to_delete[i]);
19032       }
19033       return url_params.toString();
19034     }
19035
19036     function clean_up_parameters(params) {
19037       // `&a=&b=&c=1` => '&c=1'
19038       var param_names = Object.keys(params);
19039       for (var i = 0; i < param_names.length; i += 1) {
19040         var val = params[param_names[i]];
19041         if (typeof (val) === 'undefined' || val === '' || val === null) {
19042           delete params[param_names[i]];
19043         }
19044       }
19045       return params;
19046     }
19047
19048     function update_html_title(title) {
19049       document.title = [title, 'OpenStreetMap Nominatim']
19050                          .filter( (val) => val && val.length > 1 )
19051                          .join(' | ');
19052     }
19053
19054     /*!
19055      * escape-html
19056      * Copyright(c) 2012-2013 TJ Holowaychuk
19057      * Copyright(c) 2015 Andreas Lubbe
19058      * Copyright(c) 2015 Tiancheng "Timothy" Gu
19059      * MIT Licensed
19060      */
19061
19062     /**
19063      * Module variables.
19064      * @private
19065      */
19066
19067     var matchHtmlRegExp = /["'&<>]/;
19068
19069     /**
19070      * Module exports.
19071      * @public
19072      */
19073
19074     var escapeHtml_1 = escapeHtml;
19075
19076     /**
19077      * Escape special characters in the given string of html.
19078      *
19079      * @param  {string} string The string to escape for inserting into HTML
19080      * @return {string}
19081      * @public
19082      */
19083
19084     function escapeHtml(string) {
19085       var str = '' + string;
19086       var match = matchHtmlRegExp.exec(str);
19087
19088       if (!match) {
19089         return str;
19090       }
19091
19092       var escape;
19093       var html = '';
19094       var index = 0;
19095       var lastIndex = 0;
19096
19097       for (index = match.index; index < str.length; index++) {
19098         switch (str.charCodeAt(index)) {
19099           case 34: // "
19100             escape = '&quot;';
19101             break;
19102           case 38: // &
19103             escape = '&amp;';
19104             break;
19105           case 39: // '
19106             escape = '&#39;';
19107             break;
19108           case 60: // <
19109             escape = '&lt;';
19110             break;
19111           case 62: // >
19112             escape = '&gt;';
19113             break;
19114           default:
19115             continue;
19116         }
19117
19118         if (lastIndex !== index) {
19119           html += str.substring(lastIndex, index);
19120         }
19121
19122         lastIndex = index + 1;
19123         html += escape;
19124       }
19125
19126       return lastIndex !== index
19127         ? html + str.substring(lastIndex, index)
19128         : html;
19129     }
19130
19131     var formatOSMType_1 = formatOSMType;
19132     var osmLink_1 = osmLink;
19133     var formatLabel_1 = formatLabel;
19134     var detailsURL_1 = detailsURL;
19135     var wikipediaLink_1 = wikipediaLink;
19136     var coverageType_1 = coverageType;
19137     var isAdminBoundary_1 = isAdminBoundary;
19138     var formatAddressRank_1 = formatAddressRank;
19139     var formatPlaceType_1 = formatPlaceType;
19140     var formatAdminLevel_1 = formatAdminLevel;
19141     var formatDistance_1 = formatDistance;
19142     var formatKeywordToken_1 = formatKeywordToken;
19143     var zoomLevels_1 = zoomLevels;
19144
19145
19146
19147     function formatOSMType(sType, bExcludeExternal) {
19148       if (sType === 'N') return 'node';
19149       if (sType === 'W') return 'way';
19150       if (sType === 'R') return 'relation';
19151
19152       if (!bExcludeExternal) return '';
19153
19154       if (sType === 'T') return 'way';
19155       if (sType === 'I') return 'way';
19156
19157       return '';
19158     }
19159
19160     function formatShortOSMType(sType) {
19161       if (sType === 'node') return 'N';
19162       if (sType === 'way') return 'W';
19163       if (sType === 'relation') return 'R';
19164       return '';
19165     }
19166
19167     function osmLink(aPlace) {
19168       if (!aPlace.osm_type) return '';
19169       var sOSMType = formatOSMType(aPlace.osm_type, false);
19170       if (!sOSMType) return '';
19171
19172       return '<a href="https://www.openstreetmap.org/' + sOSMType + '/' + aPlace.osm_id + '">' + sOSMType + ' ' + aPlace.osm_id + '</a>'
19173     }
19174
19175     function formatLabel(aPlace) {
19176       if (aPlace.label) return aPlace.label;
19177
19178       function capitalize(s) {
19179         return s && s[0].toUpperCase() + s.slice(1);
19180       }
19181
19182       if (aPlace.type && aPlace.type === 'yes' && aPlace.class) {
19183         return capitalize(aPlace.class.replace(/_/g, ' '));
19184       }
19185       if (aPlace.type) {
19186         return capitalize(aPlace.type.replace(/_/g, ' '));
19187       }
19188       return '';
19189     }
19190
19191     // 'details.html?osmtype=R&osmid=2181874&class=boundary'
19192     function detailsURL(aFeature) {
19193       if (!aFeature) return '';
19194
19195       var sOSMType = aFeature.osm_type;
19196       if (sOSMType && sOSMType.length !== 1) {
19197         sOSMType = formatShortOSMType(aFeature.osm_type); // node => N
19198       }
19199       if (!sOSMType) return '';
19200
19201       var sURL = 'details.html?osmtype=' + sOSMType + '&osmid=' + aFeature.osm_id;
19202       if (aFeature.class) {
19203         sURL = sURL + '&class=' + encodeURIComponent(aFeature.class);
19204       } else if (aFeature.category) {
19205         sURL = sURL + '&class=' +encodeURIComponent(aFeature.category);
19206       }
19207       return sURL;
19208     }
19209
19210       /* en:London_Borough_of_Redbridge => https://en.wikipedia.org/wiki/London_Borough_of_Redbridge */
19211     function wikipediaLink(aPlace) {
19212       if (!aPlace.calculated_wikipedia) return '';
19213
19214       var parts = aPlace.calculated_wikipedia.split(':', 2);
19215
19216       var sTitle = escapeHtml_1(aPlace.calculated_wikipedia);
19217       var sLanguage = escapeHtml_1(parts[0]);
19218       var sArticle = escapeHtml_1(parts[1]);
19219
19220       return '<a href="https://' + sLanguage + '.wikipedia.org/wiki/' + sArticle + '" target="_blank">' + sTitle + '</a>';
19221     }
19222
19223     function coverageType(aPlace) {
19224       return (aPlace.isarea ? 'Polygon' : 'Point');
19225     }
19226
19227     function isAdminBoundary(aPlace) {
19228       return aPlace.category === 'boundary' && aPlace.type === 'administrative';
19229     }
19230
19231     function formatAddressRank(iRank) {
19232       if (iRank < 4) return 'other';
19233       if (iRank < 6) return 'country';
19234       if (iRank < 8) return 'region';
19235       if (iRank < 10) return 'state';
19236       if (iRank < 12) return 'state district';
19237       if (iRank < 14) return 'county';
19238       if (iRank < 16) return 'municipality';
19239       if (iRank < 18) return 'city / town / village';
19240       if (iRank < 20) return 'city / village district';
19241       if (iRank < 22) return 'suburb / hamlet';
19242       if (iRank < 24) return 'neighbourhood';
19243       if (iRank < 26) return 'city block / square';
19244       if (iRank === 26) return 'major street';
19245       if (iRank === 27) return 'minory street / path';
19246       if (iRank <= 30) return 'house / building';
19247       return 'other';
19248     }
19249
19250     function formatPlaceType(aPlace) {
19251       var sOut = aPlace.class + ':' + aPlace.type;
19252       if (aPlace.type && aPlace.type === 'administrative' && aPlace.place_type) {
19253         sOut = sOut + ' (' + aPlace.place_type + ')';
19254       }
19255       return escapeHtml_1(sOut);
19256     }
19257
19258     // Any over 15 are invalid data in OSM anyway
19259     function formatAdminLevel(iLevel) {
19260       return (iLevel < 15 ? iLevel : '');
19261     }
19262
19263     function formatDistance(fDistance, bInMeters) {
19264       if (bInMeters) {
19265         if (fDistance < 1) return '0';
19266         var sFormatted = (fDistance >= 1000)
19267           ? Math.round(fDistance / 1000, 1) + ' km'
19268           : Math.round(fDistance, 0) + ' m';
19269
19270         return '<abbr class="distance" title="' + fDistance + ' meters">~' + sFormatted + '</abbr>';
19271       }
19272
19273       // spheric distance, http://postgis.net/docs/ST_Distance_Spheroid.html
19274       if (fDistance === 0) return '0';
19275
19276       return '<abbr class="distance" title="spheric distance ' + fDistance + '">~'
19277           + (Math.round(fDistance * 1000, 4) / 1000)
19278           + '</abbr>';
19279     }
19280
19281     // mark partial tokens (those starting with a space) with a star for readability
19282     function formatKeywordToken(sToken) {
19283       return (sToken[0] === ' ' ? '*' : '') + escapeHtml_1(sToken);
19284     }
19285
19286     function zoomLevels() {
19287       const aZoomLevels = [
19288         /*  0 */ 'Continent / Sea',
19289         /*  1 */ '',
19290         /*  2 */ '',
19291         /*  3 */ 'Country',
19292         /*  4 */ '',
19293         /*  5 */ 'State',
19294         /*  6 */ 'Region',
19295         /*  7 */ '',
19296         /*  8 */ 'County',
19297         /*  9 */ '',
19298         /* 10 */ 'City',
19299         /* 11 */ '',
19300         /* 12 */ 'Town / Village',
19301         /* 13 */ '',
19302         /* 14 */ 'Suburb',
19303         /* 15 */ '',
19304         /* 16 */ 'Street',
19305         /* 17 */ '',
19306         /* 18 */ 'Building',
19307         /* 19 */ '',
19308         /* 20 */ '',
19309         /* 21 */ ''
19310       ];
19311       return aZoomLevels;
19312
19313     }
19314
19315     /* src/components/SearchBar.svelte generated by Svelte v3.31.2 */
19316
19317     const { console: console_1 } = globals;
19318     const file$3 = "src/components/SearchBar.svelte";
19319
19320     function get_each_context(ctx, list, i) {
19321         const child_ctx = ctx.slice();
19322         child_ctx[6] = list[i];
19323         child_ctx[8] = i;
19324         return child_ctx;
19325     }
19326
19327     // (129:0) {:else}
19328     function create_else_block(ctx) {
19329         let div11;
19330         let ul;
19331         let li0;
19332         let a0;
19333         let t1;
19334         let li1;
19335         let a1;
19336         let t3;
19337         let div0;
19338         let a2;
19339         let t5;
19340         let a3;
19341         let t7;
19342         let div10;
19343         let div2;
19344         let form0;
19345         let input0;
19346         let input0_value_value;
19347         let t8;
19348         let div1;
19349         let button0;
19350         let t10;
19351         let input1;
19352         let input1_value_value;
19353         let t11;
19354         let input2;
19355         let input2_value_value;
19356         let t12;
19357         let input3;
19358         let input3_value_value;
19359         let t13;
19360         let input4;
19361         let input4_value_value;
19362         let t14;
19363         let input5;
19364         let input5_value_value;
19365         let t15;
19366         let input6;
19367         let input6_value_value;
19368         let t16;
19369         let input7;
19370         let input7_value_value;
19371         let t17;
19372         let div4;
19373         let form1;
19374         let input8;
19375         let input8_value_value;
19376         let t18;
19377         let input9;
19378         let input9_value_value;
19379         let t19;
19380         let input10;
19381         let input10_value_value;
19382         let t20;
19383         let input11;
19384         let input11_value_value;
19385         let t21;
19386         let input12;
19387         let input12_value_value;
19388         let t22;
19389         let input13;
19390         let input13_value_value;
19391         let t23;
19392         let div3;
19393         let button1;
19394         let t25;
19395         let input14;
19396         let input14_value_value;
19397         let t26;
19398         let input15;
19399         let input15_value_value;
19400         let t27;
19401         let input16;
19402         let input16_value_value;
19403         let t28;
19404         let input17;
19405         let input17_value_value;
19406         let t29;
19407         let input18;
19408         let input18_value_value;
19409         let t30;
19410         let input19;
19411         let input19_value_value;
19412         let t31;
19413         let input20;
19414         let input20_value_value;
19415         let t32;
19416         let a4;
19417         let t34;
19418         let div9;
19419         let div8;
19420         let div5;
19421         let span0;
19422         let input21;
19423         let input21_checked_value;
19424         let t35;
19425         let label0;
19426         let t37;
19427         let span1;
19428         let input22;
19429         let input22_checked_value;
19430         let t38;
19431         let label1;
19432         let t40;
19433         let span2;
19434         let input23;
19435         let input23_checked_value;
19436         let t41;
19437         let label2;
19438         let t43;
19439         let div6;
19440         let span3;
19441         let label3;
19442         let t45;
19443         let input24;
19444         let input24_value_value;
19445         let t46;
19446         let span4;
19447         let label4;
19448         let t48;
19449         let input25;
19450         let input25_value_value;
19451         let t49;
19452         let div7;
19453         let span5;
19454         let label5;
19455         let t51;
19456         let input26;
19457         let input26_value_value;
19458         let t52;
19459         let span6;
19460         let label6;
19461         let t54;
19462         let input27;
19463         let input27_value_value;
19464         let mounted;
19465         let dispose;
19466
19467         const block = {
19468                 c: function create() {
19469                         div11 = element("div");
19470                         ul = element("ul");
19471                         li0 = element("li");
19472                         a0 = element("a");
19473                         a0.textContent = "simple";
19474                         t1 = space();
19475                         li1 = element("li");
19476                         a1 = element("a");
19477                         a1.textContent = "structured";
19478                         t3 = space();
19479                         div0 = element("div");
19480                         a2 = element("a");
19481                         a2.textContent = "search by id";
19482                         t5 = space();
19483                         a3 = element("a");
19484                         a3.textContent = "reverse search";
19485                         t7 = space();
19486                         div10 = element("div");
19487                         div2 = element("div");
19488                         form0 = element("form");
19489                         input0 = element("input");
19490                         t8 = space();
19491                         div1 = element("div");
19492                         button0 = element("button");
19493                         button0.textContent = "Search";
19494                         t10 = space();
19495                         input1 = element("input");
19496                         t11 = space();
19497                         input2 = element("input");
19498                         t12 = space();
19499                         input3 = element("input");
19500                         t13 = space();
19501                         input4 = element("input");
19502                         t14 = space();
19503                         input5 = element("input");
19504                         t15 = space();
19505                         input6 = element("input");
19506                         t16 = space();
19507                         input7 = element("input");
19508                         t17 = space();
19509                         div4 = element("div");
19510                         form1 = element("form");
19511                         input8 = element("input");
19512                         t18 = space();
19513                         input9 = element("input");
19514                         t19 = space();
19515                         input10 = element("input");
19516                         t20 = space();
19517                         input11 = element("input");
19518                         t21 = space();
19519                         input12 = element("input");
19520                         t22 = space();
19521                         input13 = element("input");
19522                         t23 = space();
19523                         div3 = element("div");
19524                         button1 = element("button");
19525                         button1.textContent = "Search";
19526                         t25 = space();
19527                         input14 = element("input");
19528                         t26 = space();
19529                         input15 = element("input");
19530                         t27 = space();
19531                         input16 = element("input");
19532                         t28 = space();
19533                         input17 = element("input");
19534                         t29 = space();
19535                         input18 = element("input");
19536                         t30 = space();
19537                         input19 = element("input");
19538                         t31 = space();
19539                         input20 = element("input");
19540                         t32 = space();
19541                         a4 = element("a");
19542                         a4.textContent = "Advanced options";
19543                         t34 = space();
19544                         div9 = element("div");
19545                         div8 = element("div");
19546                         div5 = element("div");
19547                         span0 = element("span");
19548                         input21 = element("input");
19549                         t35 = space();
19550                         label0 = element("label");
19551                         label0.textContent = "apply viewbox";
19552                         t37 = space();
19553                         span1 = element("span");
19554                         input22 = element("input");
19555                         t38 = space();
19556                         label1 = element("label");
19557                         label1.textContent = "bounded to viewbox";
19558                         t40 = space();
19559                         span2 = element("span");
19560                         input23 = element("input");
19561                         t41 = space();
19562                         label2 = element("label");
19563                         label2.textContent = "deduplicate results";
19564                         t43 = space();
19565                         div6 = element("div");
19566                         span3 = element("span");
19567                         label3 = element("label");
19568                         label3.textContent = "Maximum number of results:";
19569                         t45 = space();
19570                         input24 = element("input");
19571                         t46 = space();
19572                         span4 = element("span");
19573                         label4 = element("label");
19574                         label4.textContent = "Polygon simplification:";
19575                         t48 = space();
19576                         input25 = element("input");
19577                         t49 = space();
19578                         div7 = element("div");
19579                         span5 = element("span");
19580                         label5 = element("label");
19581                         label5.textContent = "Languages:";
19582                         t51 = space();
19583                         input26 = element("input");
19584                         t52 = space();
19585                         span6 = element("span");
19586                         label6 = element("label");
19587                         label6.textContent = "Countries:";
19588                         t54 = space();
19589                         input27 = element("input");
19590                         attr_dev(a0, "class", "nav-link");
19591                         attr_dev(a0, "data-toggle", "tab");
19592                         attr_dev(a0, "href", "#simple");
19593                         toggle_class(a0, "active", !/*bStructuredSearch*/ ctx[0]);
19594                         add_location(a0, file$3, 133, 8, 4140);
19595                         attr_dev(li0, "class", "nav-item");
19596                         add_location(li0, file$3, 132, 6, 4110);
19597                         attr_dev(a1, "class", "nav-link");
19598                         attr_dev(a1, "data-toggle", "tab");
19599                         attr_dev(a1, "href", "#structured");
19600                         toggle_class(a1, "active", /*bStructuredSearch*/ ctx[0]);
19601                         add_location(a1, file$3, 136, 8, 4286);
19602                         attr_dev(li1, "class", "nav-item");
19603                         add_location(li1, file$3, 135, 6, 4256);
19604                         attr_dev(a2, "href", "details.html");
19605                         attr_dev(a2, "class", "mr-2");
19606                         add_location(a2, file$3, 139, 8, 4448);
19607                         attr_dev(a3, "id", "switch-to-reverse");
19608                         attr_dev(a3, "href", "reverse.html");
19609                         add_location(a3, file$3, 140, 8, 4509);
19610                         attr_dev(div0, "class", "search-type-link svelte-i44z6l");
19611                         add_location(div0, file$3, 138, 6, 4409);
19612                         attr_dev(ul, "class", "nav nav-tabs");
19613                         add_location(ul, file$3, 131, 4, 4078);
19614                         attr_dev(input0, "id", "q");
19615                         attr_dev(input0, "name", "q");
19616                         attr_dev(input0, "type", "text");
19617                         attr_dev(input0, "class", "form-control form-control-sm svelte-i44z6l");
19618                         attr_dev(input0, "placeholder", "Search");
19619                         input0.value = input0_value_value = /*api_request_params*/ ctx[2].q || "";
19620                         add_location(input0, file$3, 146, 10, 4814);
19621                         attr_dev(button0, "type", "submit");
19622                         attr_dev(button0, "class", "btn btn-primary btn-sm mx-1");
19623                         add_location(button0, file$3, 154, 12, 5100);
19624                         attr_dev(input1, "type", "hidden");
19625                         attr_dev(input1, "name", "viewbox");
19626                         input1.value = input1_value_value = /*sViewBox*/ ctx[3] || "";
19627                         add_location(input1, file$3, 155, 12, 5186);
19628                         attr_dev(input2, "type", "hidden");
19629                         attr_dev(input2, "name", "dedupe");
19630                         input2.value = input2_value_value = !/*api_request_params*/ ctx[2].dedupe ? "" : 1;
19631                         add_location(input2, file$3, 156, 12, 5262);
19632                         attr_dev(input3, "type", "hidden");
19633                         attr_dev(input3, "name", "bounded");
19634                         input3.value = input3_value_value = /*api_request_params*/ ctx[2].bounded ? 1 : "";
19635                         add_location(input3, file$3, 157, 12, 5358);
19636                         attr_dev(input4, "type", "hidden");
19637                         attr_dev(input4, "name", "accept-language");
19638                         input4.value = input4_value_value = /*api_request_params*/ ctx[2]["accept-language"] || "";
19639                         add_location(input4, file$3, 158, 12, 5455);
19640                         attr_dev(input5, "type", "hidden");
19641                         attr_dev(input5, "name", "countrycodes");
19642                         input5.value = input5_value_value = /*api_request_params*/ ctx[2].countrycodes || "";
19643                         add_location(input5, file$3, 159, 12, 5568);
19644                         attr_dev(input6, "type", "hidden");
19645                         attr_dev(input6, "name", "limit");
19646                         input6.value = input6_value_value = /*api_request_params*/ ctx[2].limit || "";
19647                         add_location(input6, file$3, 160, 12, 5672);
19648                         attr_dev(input7, "type", "hidden");
19649                         attr_dev(input7, "name", "polygon_threshold");
19650                         input7.value = input7_value_value = /*api_request_params*/ ctx[2].polygon_threshold || "";
19651                         add_location(input7, file$3, 161, 12, 5762);
19652                         attr_dev(div1, "class", "form-group search-button-group svelte-i44z6l");
19653                         add_location(div1, file$3, 153, 10, 5043);
19654                         attr_dev(form0, "class", "form-inline svelte-i44z6l");
19655                         attr_dev(form0, "role", "search");
19656                         attr_dev(form0, "accept-charset", "UTF-8");
19657                         attr_dev(form0, "action", "");
19658                         add_location(form0, file$3, 145, 8, 4730);
19659                         attr_dev(div2, "class", "tab-pane");
19660                         attr_dev(div2, "id", "simple");
19661                         attr_dev(div2, "role", "tabpanel");
19662                         toggle_class(div2, "active", !/*bStructuredSearch*/ ctx[0]);
19663                         add_location(div2, file$3, 144, 6, 4637);
19664                         attr_dev(input8, "name", "street");
19665                         attr_dev(input8, "type", "text");
19666                         attr_dev(input8, "class", "form-control form-control-sm mr-1");
19667                         attr_dev(input8, "placeholder", "House number/Street");
19668                         input8.value = input8_value_value = /*api_request_params*/ ctx[2].street || "";
19669                         add_location(input8, file$3, 167, 10, 6096);
19670                         attr_dev(input9, "name", "city");
19671                         attr_dev(input9, "type", "text");
19672                         attr_dev(input9, "class", "form-control form-control-sm mr-1");
19673                         attr_dev(input9, "placeholder", "City");
19674                         input9.value = input9_value_value = /*api_request_params*/ ctx[2].city || "";
19675                         add_location(input9, file$3, 170, 10, 6294);
19676                         attr_dev(input10, "id", "county");
19677                         attr_dev(input10, "name", "county");
19678                         attr_dev(input10, "type", "text");
19679                         attr_dev(input10, "class", "form-control form-control-sm mr-1");
19680                         attr_dev(input10, "placeholder", "County");
19681                         input10.value = input10_value_value = /*api_request_params*/ ctx[2].county || "";
19682                         add_location(input10, file$3, 173, 10, 6473);
19683                         attr_dev(input11, "name", "state");
19684                         attr_dev(input11, "type", "text");
19685                         attr_dev(input11, "class", "form-control form-control-sm mr-1");
19686                         attr_dev(input11, "placeholder", "State");
19687                         input11.value = input11_value_value = /*api_request_params*/ ctx[2].state || "";
19688                         add_location(input11, file$3, 176, 10, 6670);
19689                         attr_dev(input12, "name", "country");
19690                         attr_dev(input12, "type", "text");
19691                         attr_dev(input12, "class", "form-control form-control-sm mr-1");
19692                         attr_dev(input12, "placeholder", "Country");
19693                         input12.value = input12_value_value = /*api_request_params*/ ctx[2].country || "";
19694                         add_location(input12, file$3, 179, 10, 6852);
19695                         attr_dev(input13, "name", "postalcode");
19696                         attr_dev(input13, "type", "text");
19697                         attr_dev(input13, "class", "form-control form-control-sm mr-1");
19698                         attr_dev(input13, "placeholder", "Postal Code");
19699                         input13.value = input13_value_value = /*api_request_params*/ ctx[2].postalcode || "";
19700                         add_location(input13, file$3, 182, 10, 7040);
19701                         attr_dev(button1, "type", "submit");
19702                         attr_dev(button1, "class", "btn btn-primary btn-sm mx-1");
19703                         add_location(button1, file$3, 187, 12, 7296);
19704                         attr_dev(input14, "type", "hidden");
19705                         attr_dev(input14, "name", "viewbox");
19706                         input14.value = input14_value_value = /*sViewBox*/ ctx[3] || "";
19707                         add_location(input14, file$3, 188, 12, 7382);
19708                         attr_dev(input15, "type", "hidden");
19709                         attr_dev(input15, "name", "dedupe");
19710                         input15.value = input15_value_value = !/*api_request_params*/ ctx[2].dedupe ? "" : 1;
19711                         add_location(input15, file$3, 189, 12, 7458);
19712                         attr_dev(input16, "type", "hidden");
19713                         attr_dev(input16, "name", "bounded");
19714                         input16.value = input16_value_value = /*api_request_params*/ ctx[2].bounded ? 1 : "";
19715                         add_location(input16, file$3, 190, 12, 7554);
19716                         attr_dev(input17, "type", "hidden");
19717                         attr_dev(input17, "name", "accept-language");
19718                         input17.value = input17_value_value = /*api_request_params*/ ctx[2]["accept-language"] || "";
19719                         add_location(input17, file$3, 191, 12, 7651);
19720                         attr_dev(input18, "type", "hidden");
19721                         attr_dev(input18, "name", "countrycodes");
19722                         input18.value = input18_value_value = /*api_request_params*/ ctx[2].countrycodes || "";
19723                         add_location(input18, file$3, 192, 12, 7764);
19724                         attr_dev(input19, "type", "hidden");
19725                         attr_dev(input19, "name", "limit");
19726                         input19.value = input19_value_value = /*api_request_params*/ ctx[2].limit || "";
19727                         add_location(input19, file$3, 193, 12, 7868);
19728                         attr_dev(input20, "type", "hidden");
19729                         attr_dev(input20, "name", "polygon_threshold");
19730                         input20.value = input20_value_value = /*api_request_params*/ ctx[2].polygon_threshold || "";
19731                         add_location(input20, file$3, 194, 12, 7958);
19732                         attr_dev(div3, "class", "form-group search-button-group svelte-i44z6l");
19733                         add_location(div3, file$3, 186, 10, 7239);
19734                         attr_dev(form1, "class", "form-inline");
19735                         attr_dev(form1, "role", "search");
19736                         attr_dev(form1, "accept-charset", "UTF-8");
19737                         attr_dev(form1, "action", "");
19738                         add_location(form1, file$3, 166, 8, 6012);
19739                         attr_dev(div4, "class", "tab-pane");
19740                         attr_dev(div4, "id", "structured");
19741                         attr_dev(div4, "role", "tabpanel");
19742                         toggle_class(div4, "active", /*bStructuredSearch*/ ctx[0]);
19743                         add_location(div4, file$3, 165, 6, 5916);
19744                         attr_dev(a4, "href", "#advanced");
19745                         attr_dev(a4, "class", "btn btn-outline-secondary btn-sm");
19746                         attr_dev(a4, "data-toggle", "collapse");
19747                         attr_dev(a4, "data-target", "#searchAdvancedOptions");
19748                         attr_dev(a4, "role", "button");
19749                         attr_dev(a4, "aria-expanded", "false");
19750                         attr_dev(a4, "aria-controls", "collapseAdvancedOptions");
19751                         add_location(a4, file$3, 199, 6, 8146);
19752                         attr_dev(input21, "type", "checkbox");
19753                         attr_dev(input21, "class", "form-check-input api-param-setting");
19754                         attr_dev(input21, "id", "use_viewbox");
19755                         input21.checked = input21_checked_value = /*api_request_params*/ ctx[2].viewbox;
19756                         add_location(input21, file$3, 205, 20, 8559);
19757                         attr_dev(label0, "class", "form-check-label svelte-i44z6l");
19758                         attr_dev(label0, "for", "use_viewbox");
19759                         add_location(label0, file$3, 207, 14, 8741);
19760                         attr_dev(span0, "class", "svelte-i44z6l");
19761                         add_location(span0, file$3, 205, 14, 8553);
19762                         attr_dev(input22, "type", "checkbox");
19763                         attr_dev(input22, "class", "form-check-input api-param-setting");
19764                         attr_dev(input22, "id", "option_bounded");
19765                         input22.checked = input22_checked_value = !!/*api_request_params*/ ctx[2].bounded;
19766                         add_location(input22, file$3, 208, 20, 8840);
19767                         attr_dev(label1, "class", "form-check-label svelte-i44z6l");
19768                         attr_dev(label1, "for", "option_bounded");
19769                         add_location(label1, file$3, 210, 14, 9025);
19770                         attr_dev(span1, "class", "svelte-i44z6l");
19771                         add_location(span1, file$3, 208, 14, 8834);
19772                         attr_dev(input23, "type", "checkbox");
19773                         attr_dev(input23, "class", "form-check-input api-param-setting");
19774                         attr_dev(input23, "id", "option_dedupe");
19775                         input23.checked = input23_checked_value = !!/*api_request_params*/ ctx[2].dedupe;
19776                         add_location(input23, file$3, 211, 20, 9132);
19777                         attr_dev(label2, "class", "form-check-label svelte-i44z6l");
19778                         attr_dev(label2, "for", "option_dedupe");
19779                         add_location(label2, file$3, 213, 14, 9314);
19780                         attr_dev(span2, "class", "svelte-i44z6l");
19781                         add_location(span2, file$3, 211, 14, 9126);
19782                         attr_dev(div5, "class", "form-check form-check-inline");
19783                         add_location(div5, file$3, 204, 12, 8496);
19784                         attr_dev(label3, "class", "form-check-label svelte-i44z6l");
19785                         attr_dev(label3, "for", "option_limit");
19786                         add_location(label3, file$3, 216, 20, 9495);
19787                         attr_dev(input24, "type", "number");
19788                         attr_dev(input24, "class", "form-check-input api-param-setting");
19789                         attr_dev(input24, "data-api-param", "limit");
19790                         attr_dev(input24, "id", "option_limit");
19791                         attr_dev(input24, "size", "5");
19792                         attr_dev(input24, "min", "1");
19793                         attr_dev(input24, "max", "50");
19794                         input24.value = input24_value_value = /*api_request_params*/ ctx[2].limit || "";
19795                         add_location(input24, file$3, 217, 14, 9596);
19796                         attr_dev(span3, "class", "svelte-i44z6l");
19797                         add_location(span3, file$3, 216, 14, 9489);
19798                         attr_dev(label4, "class", "form-check-label svelte-i44z6l");
19799                         attr_dev(label4, "for", "option_polygon_threashold");
19800                         add_location(label4, file$3, 218, 20, 9822);
19801                         attr_dev(input25, "type", "number");
19802                         attr_dev(input25, "class", "form-check-input api-param-setting");
19803                         attr_dev(input25, "data-api-param", "polygon_threshold");
19804                         attr_dev(input25, "id", "option_polygon_threshold");
19805                         attr_dev(input25, "size", "5");
19806                         attr_dev(input25, "min", "0.0");
19807                         attr_dev(input25, "step", "0.01");
19808                         input25.value = input25_value_value = /*api_request_params*/ ctx[2].polygon_threshold || "";
19809                         add_location(input25, file$3, 219, 14, 9933);
19810                         attr_dev(span4, "class", "svelte-i44z6l");
19811                         add_location(span4, file$3, 218, 14, 9816);
19812                         attr_dev(div6, "class", "form-check form-check-inline");
19813                         add_location(div6, file$3, 215, 12, 9432);
19814                         attr_dev(label5, "class", "form-check-label svelte-i44z6l");
19815                         attr_dev(label5, "for", "accept_lang");
19816                         add_location(label5, file$3, 222, 20, 10274);
19817                         attr_dev(input26, "type", "text");
19818                         attr_dev(input26, "placeholder", "e.g. en,zh-Hant");
19819                         attr_dev(input26, "class", "form-check-input api-param-setting");
19820                         attr_dev(input26, "data-api-param", "accept-language");
19821                         attr_dev(input26, "id", "accept_lang");
19822                         attr_dev(input26, "size", "15");
19823                         input26.value = input26_value_value = /*api_request_params*/ ctx[2]["accept-language"] || "";
19824                         add_location(input26, file$3, 223, 14, 10358);
19825                         attr_dev(span5, "class", "svelte-i44z6l");
19826                         add_location(span5, file$3, 222, 14, 10268);
19827                         attr_dev(label6, "class", "form-check-label svelte-i44z6l");
19828                         attr_dev(label6, "for", "option_ccode");
19829                         add_location(label6, file$3, 224, 20, 10618);
19830                         attr_dev(input27, "type", "text");
19831                         attr_dev(input27, "placeholder", "e.g. de,gb");
19832                         attr_dev(input27, "class", "form-check-input api-param-setting");
19833                         attr_dev(input27, "data-api-param", "countrycodes");
19834                         attr_dev(input27, "id", "option_ccode");
19835                         attr_dev(input27, "size", "15");
19836                         input27.value = input27_value_value = /*api_request_params*/ ctx[2].countrycodes || "";
19837                         add_location(input27, file$3, 225, 14, 10703);
19838                         attr_dev(span6, "class", "svelte-i44z6l");
19839                         add_location(span6, file$3, 224, 14, 10612);
19840                         attr_dev(div7, "class", "form-check form-check-inline");
19841                         add_location(div7, file$3, 221, 12, 10211);
19842                         attr_dev(div8, "id", "searchAdvancedOptionsContent");
19843                         attr_dev(div8, "class", "svelte-i44z6l");
19844                         add_location(div8, file$3, 203, 8, 8444);
19845                         attr_dev(div9, "class", "collapse");
19846                         attr_dev(div9, "id", "searchAdvancedOptions");
19847                         add_location(div9, file$3, 202, 6, 8386);
19848                         attr_dev(div10, "class", "tab-content p-2 svelte-i44z6l");
19849                         add_location(div10, file$3, 143, 4, 4601);
19850                         attr_dev(div11, "class", "top-bar svelte-i44z6l");
19851                         add_location(div11, file$3, 130, 2, 4052);
19852                 },
19853                 m: function mount(target, anchor) {
19854                         insert_dev(target, div11, anchor);
19855                         append_dev(div11, ul);
19856                         append_dev(ul, li0);
19857                         append_dev(li0, a0);
19858                         append_dev(ul, t1);
19859                         append_dev(ul, li1);
19860                         append_dev(li1, a1);
19861                         append_dev(ul, t3);
19862                         append_dev(ul, div0);
19863                         append_dev(div0, a2);
19864                         append_dev(div0, t5);
19865                         append_dev(div0, a3);
19866                         append_dev(div11, t7);
19867                         append_dev(div11, div10);
19868                         append_dev(div10, div2);
19869                         append_dev(div2, form0);
19870                         append_dev(form0, input0);
19871                         append_dev(form0, t8);
19872                         append_dev(form0, div1);
19873                         append_dev(div1, button0);
19874                         append_dev(div1, t10);
19875                         append_dev(div1, input1);
19876                         append_dev(div1, t11);
19877                         append_dev(div1, input2);
19878                         append_dev(div1, t12);
19879                         append_dev(div1, input3);
19880                         append_dev(div1, t13);
19881                         append_dev(div1, input4);
19882                         append_dev(div1, t14);
19883                         append_dev(div1, input5);
19884                         append_dev(div1, t15);
19885                         append_dev(div1, input6);
19886                         append_dev(div1, t16);
19887                         append_dev(div1, input7);
19888                         append_dev(div10, t17);
19889                         append_dev(div10, div4);
19890                         append_dev(div4, form1);
19891                         append_dev(form1, input8);
19892                         append_dev(form1, t18);
19893                         append_dev(form1, input9);
19894                         append_dev(form1, t19);
19895                         append_dev(form1, input10);
19896                         append_dev(form1, t20);
19897                         append_dev(form1, input11);
19898                         append_dev(form1, t21);
19899                         append_dev(form1, input12);
19900                         append_dev(form1, t22);
19901                         append_dev(form1, input13);
19902                         append_dev(form1, t23);
19903                         append_dev(form1, div3);
19904                         append_dev(div3, button1);
19905                         append_dev(div3, t25);
19906                         append_dev(div3, input14);
19907                         append_dev(div3, t26);
19908                         append_dev(div3, input15);
19909                         append_dev(div3, t27);
19910                         append_dev(div3, input16);
19911                         append_dev(div3, t28);
19912                         append_dev(div3, input17);
19913                         append_dev(div3, t29);
19914                         append_dev(div3, input18);
19915                         append_dev(div3, t30);
19916                         append_dev(div3, input19);
19917                         append_dev(div3, t31);
19918                         append_dev(div3, input20);
19919                         append_dev(div10, t32);
19920                         append_dev(div10, a4);
19921                         append_dev(div10, t34);
19922                         append_dev(div10, div9);
19923                         append_dev(div9, div8);
19924                         append_dev(div8, div5);
19925                         append_dev(div5, span0);
19926                         append_dev(span0, input21);
19927                         append_dev(span0, t35);
19928                         append_dev(span0, label0);
19929                         append_dev(div5, t37);
19930                         append_dev(div5, span1);
19931                         append_dev(span1, input22);
19932                         append_dev(span1, t38);
19933                         append_dev(span1, label1);
19934                         append_dev(div5, t40);
19935                         append_dev(div5, span2);
19936                         append_dev(span2, input23);
19937                         append_dev(span2, t41);
19938                         append_dev(span2, label2);
19939                         append_dev(div8, t43);
19940                         append_dev(div8, div6);
19941                         append_dev(div6, span3);
19942                         append_dev(span3, label3);
19943                         append_dev(span3, t45);
19944                         append_dev(span3, input24);
19945                         append_dev(div6, t46);
19946                         append_dev(div6, span4);
19947                         append_dev(span4, label4);
19948                         append_dev(span4, t48);
19949                         append_dev(span4, input25);
19950                         append_dev(div8, t49);
19951                         append_dev(div8, div7);
19952                         append_dev(div7, span5);
19953                         append_dev(span5, label5);
19954                         append_dev(span5, t51);
19955                         append_dev(span5, input26);
19956                         append_dev(div7, t52);
19957                         append_dev(div7, span6);
19958                         append_dev(span6, label6);
19959                         append_dev(span6, t54);
19960                         append_dev(span6, input27);
19961
19962                         if (!mounted) {
19963                                 dispose = [
19964                                         listen_dev(input21, "change", /*reset_viewbox*/ ctx[4], false, false, false),
19965                                         listen_dev(input22, "change", set_bounded, false, false, false),
19966                                         listen_dev(input23, "change", set_dedupe, false, false, false),
19967                                         listen_dev(input24, "change", set_api_param, false, false, false),
19968                                         listen_dev(input25, "change", set_api_param, false, false, false),
19969                                         listen_dev(input26, "change", set_api_param, false, false, false),
19970                                         listen_dev(input27, "change", set_api_param, false, false, false)
19971                                 ];
19972
19973                                 mounted = true;
19974                         }
19975                 },
19976                 p: function update(ctx, dirty) {
19977                         if (dirty & /*bStructuredSearch*/ 1) {
19978                                 toggle_class(a0, "active", !/*bStructuredSearch*/ ctx[0]);
19979                         }
19980
19981                         if (dirty & /*bStructuredSearch*/ 1) {
19982                                 toggle_class(a1, "active", /*bStructuredSearch*/ ctx[0]);
19983                         }
19984
19985                         if (dirty & /*api_request_params*/ 4 && input0_value_value !== (input0_value_value = /*api_request_params*/ ctx[2].q || "") && input0.value !== input0_value_value) {
19986                                 prop_dev(input0, "value", input0_value_value);
19987                         }
19988
19989                         if (dirty & /*sViewBox*/ 8 && input1_value_value !== (input1_value_value = /*sViewBox*/ ctx[3] || "")) {
19990                                 prop_dev(input1, "value", input1_value_value);
19991                         }
19992
19993                         if (dirty & /*api_request_params*/ 4 && input2_value_value !== (input2_value_value = !/*api_request_params*/ ctx[2].dedupe ? "" : 1)) {
19994                                 prop_dev(input2, "value", input2_value_value);
19995                         }
19996
19997                         if (dirty & /*api_request_params*/ 4 && input3_value_value !== (input3_value_value = /*api_request_params*/ ctx[2].bounded ? 1 : "")) {
19998                                 prop_dev(input3, "value", input3_value_value);
19999                         }
20000
20001                         if (dirty & /*api_request_params*/ 4 && input4_value_value !== (input4_value_value = /*api_request_params*/ ctx[2]["accept-language"] || "")) {
20002                                 prop_dev(input4, "value", input4_value_value);
20003                         }
20004
20005                         if (dirty & /*api_request_params*/ 4 && input5_value_value !== (input5_value_value = /*api_request_params*/ ctx[2].countrycodes || "")) {
20006                                 prop_dev(input5, "value", input5_value_value);
20007                         }
20008
20009                         if (dirty & /*api_request_params*/ 4 && input6_value_value !== (input6_value_value = /*api_request_params*/ ctx[2].limit || "")) {
20010                                 prop_dev(input6, "value", input6_value_value);
20011                         }
20012
20013                         if (dirty & /*api_request_params*/ 4 && input7_value_value !== (input7_value_value = /*api_request_params*/ ctx[2].polygon_threshold || "")) {
20014                                 prop_dev(input7, "value", input7_value_value);
20015                         }
20016
20017                         if (dirty & /*bStructuredSearch*/ 1) {
20018                                 toggle_class(div2, "active", !/*bStructuredSearch*/ ctx[0]);
20019                         }
20020
20021                         if (dirty & /*api_request_params*/ 4 && input8_value_value !== (input8_value_value = /*api_request_params*/ ctx[2].street || "") && input8.value !== input8_value_value) {
20022                                 prop_dev(input8, "value", input8_value_value);
20023                         }
20024
20025                         if (dirty & /*api_request_params*/ 4 && input9_value_value !== (input9_value_value = /*api_request_params*/ ctx[2].city || "") && input9.value !== input9_value_value) {
20026                                 prop_dev(input9, "value", input9_value_value);
20027                         }
20028
20029                         if (dirty & /*api_request_params*/ 4 && input10_value_value !== (input10_value_value = /*api_request_params*/ ctx[2].county || "") && input10.value !== input10_value_value) {
20030                                 prop_dev(input10, "value", input10_value_value);
20031                         }
20032
20033                         if (dirty & /*api_request_params*/ 4 && input11_value_value !== (input11_value_value = /*api_request_params*/ ctx[2].state || "") && input11.value !== input11_value_value) {
20034                                 prop_dev(input11, "value", input11_value_value);
20035                         }
20036
20037                         if (dirty & /*api_request_params*/ 4 && input12_value_value !== (input12_value_value = /*api_request_params*/ ctx[2].country || "") && input12.value !== input12_value_value) {
20038                                 prop_dev(input12, "value", input12_value_value);
20039                         }
20040
20041                         if (dirty & /*api_request_params*/ 4 && input13_value_value !== (input13_value_value = /*api_request_params*/ ctx[2].postalcode || "") && input13.value !== input13_value_value) {
20042                                 prop_dev(input13, "value", input13_value_value);
20043                         }
20044
20045                         if (dirty & /*sViewBox*/ 8 && input14_value_value !== (input14_value_value = /*sViewBox*/ ctx[3] || "")) {
20046                                 prop_dev(input14, "value", input14_value_value);
20047                         }
20048
20049                         if (dirty & /*api_request_params*/ 4 && input15_value_value !== (input15_value_value = !/*api_request_params*/ ctx[2].dedupe ? "" : 1)) {
20050                                 prop_dev(input15, "value", input15_value_value);
20051                         }
20052
20053                         if (dirty & /*api_request_params*/ 4 && input16_value_value !== (input16_value_value = /*api_request_params*/ ctx[2].bounded ? 1 : "")) {
20054                                 prop_dev(input16, "value", input16_value_value);
20055                         }
20056
20057                         if (dirty & /*api_request_params*/ 4 && input17_value_value !== (input17_value_value = /*api_request_params*/ ctx[2]["accept-language"] || "")) {
20058                                 prop_dev(input17, "value", input17_value_value);
20059                         }
20060
20061                         if (dirty & /*api_request_params*/ 4 && input18_value_value !== (input18_value_value = /*api_request_params*/ ctx[2].countrycodes || "")) {
20062                                 prop_dev(input18, "value", input18_value_value);
20063                         }
20064
20065                         if (dirty & /*api_request_params*/ 4 && input19_value_value !== (input19_value_value = /*api_request_params*/ ctx[2].limit || "")) {
20066                                 prop_dev(input19, "value", input19_value_value);
20067                         }
20068
20069                         if (dirty & /*api_request_params*/ 4 && input20_value_value !== (input20_value_value = /*api_request_params*/ ctx[2].polygon_threshold || "")) {
20070                                 prop_dev(input20, "value", input20_value_value);
20071                         }
20072
20073                         if (dirty & /*bStructuredSearch*/ 1) {
20074                                 toggle_class(div4, "active", /*bStructuredSearch*/ ctx[0]);
20075                         }
20076
20077                         if (dirty & /*api_request_params*/ 4 && input21_checked_value !== (input21_checked_value = /*api_request_params*/ ctx[2].viewbox)) {
20078                                 prop_dev(input21, "checked", input21_checked_value);
20079                         }
20080
20081                         if (dirty & /*api_request_params*/ 4 && input22_checked_value !== (input22_checked_value = !!/*api_request_params*/ ctx[2].bounded)) {
20082                                 prop_dev(input22, "checked", input22_checked_value);
20083                         }
20084
20085                         if (dirty & /*api_request_params*/ 4 && input23_checked_value !== (input23_checked_value = !!/*api_request_params*/ ctx[2].dedupe)) {
20086                                 prop_dev(input23, "checked", input23_checked_value);
20087                         }
20088
20089                         if (dirty & /*api_request_params*/ 4 && input24_value_value !== (input24_value_value = /*api_request_params*/ ctx[2].limit || "")) {
20090                                 prop_dev(input24, "value", input24_value_value);
20091                         }
20092
20093                         if (dirty & /*api_request_params*/ 4 && input25_value_value !== (input25_value_value = /*api_request_params*/ ctx[2].polygon_threshold || "")) {
20094                                 prop_dev(input25, "value", input25_value_value);
20095                         }
20096
20097                         if (dirty & /*api_request_params*/ 4 && input26_value_value !== (input26_value_value = /*api_request_params*/ ctx[2]["accept-language"] || "") && input26.value !== input26_value_value) {
20098                                 prop_dev(input26, "value", input26_value_value);
20099                         }
20100
20101                         if (dirty & /*api_request_params*/ 4 && input27_value_value !== (input27_value_value = /*api_request_params*/ ctx[2].countrycodes || "") && input27.value !== input27_value_value) {
20102                                 prop_dev(input27, "value", input27_value_value);
20103                         }
20104                 },
20105                 d: function destroy(detaching) {
20106                         if (detaching) detach_dev(div11);
20107                         mounted = false;
20108                         run_all(dispose);
20109                 }
20110         };
20111
20112         dispatch_dev("SvelteRegisterBlock", {
20113                 block,
20114                 id: create_else_block.name,
20115                 type: "else",
20116                 source: "(129:0) {:else}",
20117                 ctx
20118         });
20119
20120         return block;
20121     }
20122
20123     // (90:0) {#if reverse_search}
20124     function create_if_block$1(ctx) {
20125         let div2;
20126         let form;
20127         let div0;
20128         let input0;
20129         let t0;
20130         let label0;
20131         let t2;
20132         let input1;
20133         let input1_value_value;
20134         let t3;
20135         let a0;
20136         let t5;
20137         let label1;
20138         let t7;
20139         let input2;
20140         let input2_value_value;
20141         let t8;
20142         let label2;
20143         let t10;
20144         let select;
20145         let option;
20146         let t11;
20147         let option_selected_value;
20148         let select_value_value;
20149         let t12;
20150         let button;
20151         let t14;
20152         let div1;
20153         let a1;
20154         let t16;
20155         let a2;
20156         let mounted;
20157         let dispose;
20158         let each_value = zoomLevels_1();
20159         validate_each_argument(each_value);
20160         let each_blocks = [];
20161
20162         for (let i = 0; i < each_value.length; i += 1) {
20163                 each_blocks[i] = create_each_block(get_each_context(ctx, each_value, i));
20164         }
20165
20166         const block = {
20167                 c: function create() {
20168                         div2 = element("div");
20169                         form = element("form");
20170                         div0 = element("div");
20171                         input0 = element("input");
20172                         t0 = space();
20173                         label0 = element("label");
20174                         label0.textContent = "lat";
20175                         t2 = space();
20176                         input1 = element("input");
20177                         t3 = space();
20178                         a0 = element("a");
20179                         a0.textContent = "<>";
20180                         t5 = space();
20181                         label1 = element("label");
20182                         label1.textContent = "lon";
20183                         t7 = space();
20184                         input2 = element("input");
20185                         t8 = space();
20186                         label2 = element("label");
20187                         label2.textContent = "max zoom";
20188                         t10 = space();
20189                         select = element("select");
20190                         option = element("option");
20191                         t11 = text("---");
20192
20193                         for (let i = 0; i < each_blocks.length; i += 1) {
20194                                 each_blocks[i].c();
20195                         }
20196
20197                         t12 = space();
20198                         button = element("button");
20199                         button.textContent = "Search";
20200                         t14 = space();
20201                         div1 = element("div");
20202                         a1 = element("a");
20203                         a1.textContent = "search by id";
20204                         t16 = space();
20205                         a2 = element("a");
20206                         a2.textContent = "forward search";
20207                         attr_dev(input0, "name", "format");
20208                         attr_dev(input0, "type", "hidden");
20209                         input0.value = "html";
20210                         add_location(input0, file$3, 93, 8, 2644);
20211                         attr_dev(label0, "class", "svelte-i44z6l");
20212                         add_location(label0, file$3, 94, 8, 2701);
20213                         attr_dev(input1, "name", "lat");
20214                         attr_dev(input1, "type", "text");
20215                         attr_dev(input1, "class", "form-control form-control-sm");
20216                         attr_dev(input1, "placeholder", "latitude");
20217                         input1.value = input1_value_value = /*api_request_params*/ ctx[2].lat || "";
20218                         add_location(input1, file$3, 95, 8, 2728);
20219                         attr_dev(a0, "id", "switch-coords");
20220                         attr_dev(a0, "class", "btn btn-outline-secondary btn-sm svelte-i44z6l");
20221                         attr_dev(a0, "title", "switch lat and lon");
20222                         add_location(a0, file$3, 100, 8, 2928);
20223                         attr_dev(label1, "class", "svelte-i44z6l");
20224                         add_location(label1, file$3, 104, 8, 3133);
20225                         attr_dev(input2, "name", "lon");
20226                         attr_dev(input2, "type", "text");
20227                         attr_dev(input2, "class", "form-control form-control-sm");
20228                         attr_dev(input2, "placeholder", "longitude");
20229                         input2.value = input2_value_value = /*api_request_params*/ ctx[2].lon || "";
20230                         add_location(input2, file$3, 105, 8, 3160);
20231                         attr_dev(label2, "class", "svelte-i44z6l");
20232                         add_location(label2, file$3, 110, 8, 3361);
20233                         option.__value = "";
20234                         option.value = option.__value;
20235                         option.selected = option_selected_value = !/*api_request_params*/ ctx[2].zoom;
20236                         add_location(option, file$3, 112, 10, 3495);
20237                         attr_dev(select, "name", "zoom");
20238                         attr_dev(select, "class", "form-control form-control-sm");
20239                         add_location(select, file$3, 111, 8, 3393);
20240                         attr_dev(button, "type", "submit");
20241                         attr_dev(button, "class", "btn btn-primary btn-sm mx-1");
20242                         add_location(button, file$3, 117, 8, 3752);
20243                         attr_dev(div0, "class", "form-group");
20244                         add_location(div0, file$3, 92, 6, 2611);
20245                         attr_dev(a1, "href", "details.html");
20246                         attr_dev(a1, "class", "mr-2");
20247                         add_location(a1, file$3, 122, 8, 3904);
20248                         attr_dev(a2, "href", "search.html");
20249                         add_location(a2, file$3, 123, 8, 3965);
20250                         attr_dev(div1, "class", "search-type-link svelte-i44z6l");
20251                         add_location(div1, file$3, 121, 6, 3865);
20252                         attr_dev(form, "class", "form-inline svelte-i44z6l");
20253                         attr_dev(form, "role", "search");
20254                         attr_dev(form, "accept-charset", "UTF-8");
20255                         attr_dev(form, "action", "");
20256                         add_location(form, file$3, 91, 4, 2531);
20257                         attr_dev(div2, "class", "top-bar svelte-i44z6l");
20258                         add_location(div2, file$3, 90, 2, 2505);
20259                 },
20260                 m: function mount(target, anchor) {
20261                         insert_dev(target, div2, anchor);
20262                         append_dev(div2, form);
20263                         append_dev(form, div0);
20264                         append_dev(div0, input0);
20265                         append_dev(div0, t0);
20266                         append_dev(div0, label0);
20267                         append_dev(div0, t2);
20268                         append_dev(div0, input1);
20269                         append_dev(div0, t3);
20270                         append_dev(div0, a0);
20271                         append_dev(div0, t5);
20272                         append_dev(div0, label1);
20273                         append_dev(div0, t7);
20274                         append_dev(div0, input2);
20275                         append_dev(div0, t8);
20276                         append_dev(div0, label2);
20277                         append_dev(div0, t10);
20278                         append_dev(div0, select);
20279                         append_dev(select, option);
20280                         append_dev(option, t11);
20281
20282                         for (let i = 0; i < each_blocks.length; i += 1) {
20283                                 each_blocks[i].m(select, null);
20284                         }
20285
20286                         select_option(select, /*api_request_params*/ ctx[2].zoom);
20287                         append_dev(div0, t12);
20288                         append_dev(div0, button);
20289                         append_dev(form, t14);
20290                         append_dev(form, div1);
20291                         append_dev(div1, a1);
20292                         append_dev(div1, t16);
20293                         append_dev(div1, a2);
20294
20295                         if (!mounted) {
20296                                 dispose = listen_dev(a0, "click", stop_propagation(prevent_default(handleSwitchCoords)), false, true, true);
20297                                 mounted = true;
20298                         }
20299                 },
20300                 p: function update(ctx, dirty) {
20301                         if (dirty & /*api_request_params*/ 4 && input1_value_value !== (input1_value_value = /*api_request_params*/ ctx[2].lat || "") && input1.value !== input1_value_value) {
20302                                 prop_dev(input1, "value", input1_value_value);
20303                         }
20304
20305                         if (dirty & /*api_request_params*/ 4 && input2_value_value !== (input2_value_value = /*api_request_params*/ ctx[2].lon || "") && input2.value !== input2_value_value) {
20306                                 prop_dev(input2, "value", input2_value_value);
20307                         }
20308
20309                         if (dirty & /*api_request_params*/ 4 && option_selected_value !== (option_selected_value = !/*api_request_params*/ ctx[2].zoom)) {
20310                                 prop_dev(option, "selected", option_selected_value);
20311                         }
20312
20313                         if (dirty & /*api_request_params, zoomLevels*/ 4) {
20314                                 each_value = zoomLevels_1();
20315                                 validate_each_argument(each_value);
20316                                 let i;
20317
20318                                 for (i = 0; i < each_value.length; i += 1) {
20319                                         const child_ctx = get_each_context(ctx, each_value, i);
20320
20321                                         if (each_blocks[i]) {
20322                                                 each_blocks[i].p(child_ctx, dirty);
20323                                         } else {
20324                                                 each_blocks[i] = create_each_block(child_ctx);
20325                                                 each_blocks[i].c();
20326                                                 each_blocks[i].m(select, null);
20327                                         }
20328                                 }
20329
20330                                 for (; i < each_blocks.length; i += 1) {
20331                                         each_blocks[i].d(1);
20332                                 }
20333
20334                                 each_blocks.length = each_value.length;
20335                         }
20336
20337                         if (dirty & /*api_request_params*/ 4 && select_value_value !== (select_value_value = /*api_request_params*/ ctx[2].zoom)) {
20338                                 select_option(select, /*api_request_params*/ ctx[2].zoom);
20339                         }
20340                 },
20341                 d: function destroy(detaching) {
20342                         if (detaching) detach_dev(div2);
20343                         destroy_each(each_blocks, detaching);
20344                         mounted = false;
20345                         dispose();
20346                 }
20347         };
20348
20349         dispatch_dev("SvelteRegisterBlock", {
20350                 block,
20351                 id: create_if_block$1.name,
20352                 type: "if",
20353                 source: "(90:0) {#if reverse_search}",
20354                 ctx
20355         });
20356
20357         return block;
20358     }
20359
20360     // (114:10) {#each zoomLevels() as zoomTitle, i}
20361     function create_each_block(ctx) {
20362         let option;
20363         let t0;
20364         let t1;
20365         let t2_value = /*zoomTitle*/ ctx[6] + "";
20366         let t2;
20367         let option_selected_value;
20368
20369         const block = {
20370                 c: function create() {
20371                         option = element("option");
20372                         t0 = text(/*i*/ ctx[8]);
20373                         t1 = text(" - ");
20374                         t2 = text(t2_value);
20375                         option.__value = /*i*/ ctx[8];
20376                         option.value = option.__value;
20377                         option.selected = option_selected_value = /*i*/ ctx[8] === /*api_request_params*/ ctx[2].zoom;
20378                         add_location(option, file$3, 114, 12, 3620);
20379                 },
20380                 m: function mount(target, anchor) {
20381                         insert_dev(target, option, anchor);
20382                         append_dev(option, t0);
20383                         append_dev(option, t1);
20384                         append_dev(option, t2);
20385                 },
20386                 p: function update(ctx, dirty) {
20387                         if (dirty & /*api_request_params*/ 4 && option_selected_value !== (option_selected_value = /*i*/ ctx[8] === /*api_request_params*/ ctx[2].zoom)) {
20388                                 prop_dev(option, "selected", option_selected_value);
20389                         }
20390                 },
20391                 d: function destroy(detaching) {
20392                         if (detaching) detach_dev(option);
20393                 }
20394         };
20395
20396         dispatch_dev("SvelteRegisterBlock", {
20397                 block,
20398                 id: create_each_block.name,
20399                 type: "each",
20400                 source: "(114:10) {#each zoomLevels() as zoomTitle, i}",
20401                 ctx
20402         });
20403
20404         return block;
20405     }
20406
20407     function create_fragment$3(ctx) {
20408         let if_block_anchor;
20409
20410         function select_block_type(ctx, dirty) {
20411                 if (/*reverse_search*/ ctx[1]) return create_if_block$1;
20412                 return create_else_block;
20413         }
20414
20415         let current_block_type = select_block_type(ctx);
20416         let if_block = current_block_type(ctx);
20417
20418         const block = {
20419                 c: function create() {
20420                         if_block.c();
20421                         if_block_anchor = empty();
20422                 },
20423                 l: function claim(nodes) {
20424                         throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
20425                 },
20426                 m: function mount(target, anchor) {
20427                         if_block.m(target, anchor);
20428                         insert_dev(target, if_block_anchor, anchor);
20429                 },
20430                 p: function update(ctx, [dirty]) {
20431                         if (current_block_type === (current_block_type = select_block_type(ctx)) && if_block) {
20432                                 if_block.p(ctx, dirty);
20433                         } else {
20434                                 if_block.d(1);
20435                                 if_block = current_block_type(ctx);
20436
20437                                 if (if_block) {
20438                                         if_block.c();
20439                                         if_block.m(if_block_anchor.parentNode, if_block_anchor);
20440                                 }
20441                         }
20442                 },
20443                 i: noop,
20444                 o: noop,
20445                 d: function destroy(detaching) {
20446                         if_block.d(detaching);
20447                         if (detaching) detach_dev(if_block_anchor);
20448                 }
20449         };
20450
20451         dispatch_dev("SvelteRegisterBlock", {
20452                 block,
20453                 id: create_fragment$3.name,
20454                 type: "component",
20455                 source: "",
20456                 ctx
20457         });
20458
20459         return block;
20460     }
20461
20462     function map_viewbox_as_string(map) {
20463         var bounds = map.getBounds();
20464         var west = bounds.getWest();
20465         var east = bounds.getEast();
20466
20467         if (east - west >= 360) {
20468                 // covers more than whole planet
20469                 west = map.getCenter().lng - 179.999;
20470
20471                 east = map.getCenter().lng + 179.999;
20472         }
20473
20474         east = L.latLng(77, east).wrap().lng;
20475         west = L.latLng(77, west).wrap().lng;
20476
20477         return [
20478                 west.toFixed(5),
20479                 bounds.getNorth().toFixed(5),
20480                 east.toFixed(5),
20481                 bounds.getSouth().toFixed(5)
20482         ].join(","); // left
20483         // top
20484         // right
20485         // bottom
20486     }
20487
20488     function update_reverse_link(map) {
20489         let link = document.getElementById("switch-to-reverse");
20490
20491         if (link) {
20492                 let center_lat_lng = map.wrapLatLng(map.getCenter());
20493                 link.href = "reverse.html?lat=" + center_lat_lng.lat.toFixed(5) + "&lon=" + center_lat_lng.lng.toFixed(5);
20494         }
20495     }
20496
20497     function set_bounded(e) {
20498         console.log("setting", e.target);
20499         document.querySelector("input[name=bounded]").value = e.target.checked ? 1 : "";
20500     }
20501
20502     function set_dedupe(e) {
20503         document.querySelector("input[name=dedupe]").value = e.target.checked ? 1 : "";
20504     }
20505
20506     function set_api_param(e) {
20507         document.querySelector("input[name=" + e.target.dataset["apiParam"] + "]").value = e.target.value;
20508     }
20509
20510     function handleSwitchCoords() {
20511         let lat = document.querySelector("input[name=lat]").value;
20512         let lon = document.querySelector("input[name=lon]").value;
20513         document.querySelector("input[name=lat]").value = lon;
20514         document.querySelector("input[name=lon]").value = lat;
20515         document.querySelector("form").submit();
20516     }
20517
20518     function instance$3($$self, $$props, $$invalidate) {
20519         let { $$slots: slots = {}, $$scope } = $$props;
20520         validate_slots("SearchBar", slots, []);
20521         let { bStructuredSearch = false } = $$props;
20522         let { reverse_search = false } = $$props;
20523         let { api_request_params = {} } = $$props;
20524         let sViewBox;
20525
20526         function set_viewbox(map) {
20527                 let set_viewbox = document.getElementById("use_viewbox");
20528
20529                 if (set_viewbox && set_viewbox.checked) {
20530                         $$invalidate(3, sViewBox = map_viewbox_as_string(map));
20531                 } else {
20532                         $$invalidate(3, sViewBox = "");
20533                 }
20534         }
20535
20536         map_store.subscribe(map => {
20537                 if (!map) {
20538                         return;
20539                 }
20540
20541                 map.on("move", function () {
20542                         set_viewbox(map);
20543                         update_reverse_link(map);
20544                 });
20545
20546                 map.on("load", function () {
20547                         set_viewbox(map);
20548                         update_reverse_link(map);
20549                 });
20550         });
20551
20552         function reset_viewbox() {
20553                 let map = get_store_value(map_store);
20554
20555                 if (map) {
20556                         set_viewbox(map);
20557                 }
20558
20559                 
20560         }
20561
20562         const writable_props = ["bStructuredSearch", "reverse_search", "api_request_params"];
20563
20564         Object.keys($$props).forEach(key => {
20565                 if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console_1.warn(`<SearchBar> was created with unknown prop '${key}'`);
20566         });
20567
20568         $$self.$$set = $$props => {
20569                 if ("bStructuredSearch" in $$props) $$invalidate(0, bStructuredSearch = $$props.bStructuredSearch);
20570                 if ("reverse_search" in $$props) $$invalidate(1, reverse_search = $$props.reverse_search);
20571                 if ("api_request_params" in $$props) $$invalidate(2, api_request_params = $$props.api_request_params);
20572         };
20573
20574         $$self.$capture_state = () => ({
20575                 zoomLevels: zoomLevels_1,
20576                 map_store,
20577                 get: get_store_value,
20578                 bStructuredSearch,
20579                 reverse_search,
20580                 api_request_params,
20581                 sViewBox,
20582                 map_viewbox_as_string,
20583                 set_viewbox,
20584                 update_reverse_link,
20585                 reset_viewbox,
20586                 set_bounded,
20587                 set_dedupe,
20588                 set_api_param,
20589                 handleSwitchCoords
20590         });
20591
20592         $$self.$inject_state = $$props => {
20593                 if ("bStructuredSearch" in $$props) $$invalidate(0, bStructuredSearch = $$props.bStructuredSearch);
20594                 if ("reverse_search" in $$props) $$invalidate(1, reverse_search = $$props.reverse_search);
20595                 if ("api_request_params" in $$props) $$invalidate(2, api_request_params = $$props.api_request_params);
20596                 if ("sViewBox" in $$props) $$invalidate(3, sViewBox = $$props.sViewBox);
20597         };
20598
20599         if ($$props && "$$inject" in $$props) {
20600                 $$self.$inject_state($$props.$$inject);
20601         }
20602
20603         return [bStructuredSearch, reverse_search, api_request_params, sViewBox, reset_viewbox];
20604     }
20605
20606     class SearchBar extends SvelteComponentDev {
20607         constructor(options) {
20608                 super(options);
20609
20610                 init(this, options, instance$3, create_fragment$3, safe_not_equal, {
20611                         bStructuredSearch: 0,
20612                         reverse_search: 1,
20613                         api_request_params: 2
20614                 });
20615
20616                 dispatch_dev("SvelteRegisterComponent", {
20617                         component: this,
20618                         tagName: "SearchBar",
20619                         options,
20620                         id: create_fragment$3.name
20621                 });
20622         }
20623
20624         get bStructuredSearch() {
20625                 throw new Error("<SearchBar>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
20626         }
20627
20628         set bStructuredSearch(value) {
20629                 throw new Error("<SearchBar>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
20630         }
20631
20632         get reverse_search() {
20633                 throw new Error("<SearchBar>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
20634         }
20635
20636         set reverse_search(value) {
20637                 throw new Error("<SearchBar>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
20638         }
20639
20640         get api_request_params() {
20641                 throw new Error("<SearchBar>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
20642         }
20643
20644         set api_request_params(value) {
20645                 throw new Error("<SearchBar>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
20646         }
20647     }
20648
20649     /* src/components/Welcome.svelte generated by Svelte v3.31.2 */
20650
20651     const file$4 = "src/components/Welcome.svelte";
20652
20653     function create_fragment$4(ctx) {
20654         let div;
20655         let h2;
20656         let t1;
20657         let p;
20658         let t2;
20659         let a0;
20660         let t4;
20661         let t5;
20662         let a1;
20663         let t7;
20664
20665         const block = {
20666                 c: function create() {
20667                         div = element("div");
20668                         h2 = element("h2");
20669                         h2.textContent = "Welcome to Nominatim";
20670                         t1 = space();
20671                         p = element("p");
20672                         t2 = text("Nominatim is a search engine for\n    ");
20673                         a0 = element("a");
20674                         a0.textContent = "OpenStreetMap";
20675                         t4 = text(" data. This\n    is the debugging interface. You may search for a name or address\n    (forward search) or look up data by its geographic coordinate (reverse\n    search). Each result comes with a link to a details page where you\n    can inspect what data about the object is saved in the database and\n    investigate how the address of the object has been computed.");
20676                         t5 = text("\n\n  For more information visit the\n  ");
20677                         a1 = element("a");
20678                         a1.textContent = "Nominatim home page";
20679                         t7 = text(".");
20680                         add_location(h2, file$4, 1, 2, 21);
20681                         attr_dev(a0, "href", "https://www.openstreetmap.org");
20682                         add_location(a0, file$4, 5, 4, 99);
20683                         add_location(p, file$4, 3, 2, 54);
20684                         attr_dev(a1, "href", "https://nominatim.org");
20685                         add_location(a1, file$4, 14, 2, 563);
20686                         attr_dev(div, "id", "welcome");
20687                         add_location(div, file$4, 0, 0, 0);
20688                 },
20689                 l: function claim(nodes) {
20690                         throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
20691                 },
20692                 m: function mount(target, anchor) {
20693                         insert_dev(target, div, anchor);
20694                         append_dev(div, h2);
20695                         append_dev(div, t1);
20696                         append_dev(div, p);
20697                         append_dev(p, t2);
20698                         append_dev(p, a0);
20699                         append_dev(p, t4);
20700                         append_dev(div, t5);
20701                         append_dev(div, a1);
20702                         append_dev(div, t7);
20703                 },
20704                 p: noop,
20705                 i: noop,
20706                 o: noop,
20707                 d: function destroy(detaching) {
20708                         if (detaching) detach_dev(div);
20709                 }
20710         };
20711
20712         dispatch_dev("SvelteRegisterBlock", {
20713                 block,
20714                 id: create_fragment$4.name,
20715                 type: "component",
20716                 source: "",
20717                 ctx
20718         });
20719
20720         return block;
20721     }
20722
20723     function instance$4($$self, $$props) {
20724         let { $$slots: slots = {}, $$scope } = $$props;
20725         validate_slots("Welcome", slots, []);
20726         const writable_props = [];
20727
20728         Object.keys($$props).forEach(key => {
20729                 if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<Welcome> was created with unknown prop '${key}'`);
20730         });
20731
20732         return [];
20733     }
20734
20735     class Welcome extends SvelteComponentDev {
20736         constructor(options) {
20737                 super(options);
20738                 init(this, options, instance$4, create_fragment$4, safe_not_equal, {});
20739
20740                 dispatch_dev("SvelteRegisterComponent", {
20741                         component: this,
20742                         tagName: "Welcome",
20743                         options,
20744                         id: create_fragment$4.name
20745                 });
20746         }
20747     }
20748
20749     /* src/components/MapIcon.svelte generated by Svelte v3.31.2 */
20750     const file$5 = "src/components/MapIcon.svelte";
20751
20752     // (109:0) {#if sIcon}
20753     function create_if_block$2(ctx) {
20754         let img;
20755         let img_src_value;
20756
20757         const block = {
20758                 c: function create() {
20759                         img = element("img");
20760                         attr_dev(img, "class", "mapicon svelte-180cawe");
20761                         if (img.src !== (img_src_value = /*url*/ ctx[2])) attr_dev(img, "src", img_src_value);
20762                         attr_dev(img, "alt", /*title*/ ctx[1]);
20763                         add_location(img, file$5, 109, 2, 4543);
20764                 },
20765                 m: function mount(target, anchor) {
20766                         insert_dev(target, img, anchor);
20767                 },
20768                 p: noop,
20769                 d: function destroy(detaching) {
20770                         if (detaching) detach_dev(img);
20771                 }
20772         };
20773
20774         dispatch_dev("SvelteRegisterBlock", {
20775                 block,
20776                 id: create_if_block$2.name,
20777                 type: "if",
20778                 source: "(109:0) {#if sIcon}",
20779                 ctx
20780         });
20781
20782         return block;
20783     }
20784
20785     function create_fragment$5(ctx) {
20786         let if_block_anchor;
20787         let if_block = /*sIcon*/ ctx[0] && create_if_block$2(ctx);
20788
20789         const block = {
20790                 c: function create() {
20791                         if (if_block) if_block.c();
20792                         if_block_anchor = empty();
20793                 },
20794                 l: function claim(nodes) {
20795                         throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
20796                 },
20797                 m: function mount(target, anchor) {
20798                         if (if_block) if_block.m(target, anchor);
20799                         insert_dev(target, if_block_anchor, anchor);
20800                 },
20801                 p: function update(ctx, [dirty]) {
20802                         if (/*sIcon*/ ctx[0]) if_block.p(ctx, dirty);
20803                 },
20804                 i: noop,
20805                 o: noop,
20806                 d: function destroy(detaching) {
20807                         if (if_block) if_block.d(detaching);
20808                         if (detaching) detach_dev(if_block_anchor);
20809                 }
20810         };
20811
20812         dispatch_dev("SvelteRegisterBlock", {
20813                 block,
20814                 id: create_fragment$5.name,
20815                 type: "component",
20816                 source: "",
20817                 ctx
20818         });
20819
20820         return block;
20821     }
20822
20823     function getIcon(aPlace) {
20824         // equivalent to PHP Nominatim::ClassTypes::getIcon
20825         // covers 83 of 214 available icon filenames, e.g. transport_roundabout_anticlockwise
20826         // transport_rental_bicycle or place_of_worship_christian would need more data from
20827         // the place.
20828         var aIcons = {
20829                 "boundary:administrative": "poi_boundary_administrative",
20830                 "place:city": "poi_place_city",
20831                 "place:town": "poi_place_town",
20832                 "place:village": "poi_place_village",
20833                 "place:hamlet": "poi_place_village",
20834                 "place:suburb": "poi_place_village",
20835                 "place:locality": "poi_place_village",
20836                 "place:airport": "transport_airport2",
20837                 "aeroway:aerodrome": "transport_airport2",
20838                 "railway:station": "transport_train_station2",
20839                 "amenity:place_of_worship": "place_of_worship_unknown3",
20840                 "amenity:pub": "food_pub",
20841                 "amenity:bar": "food_bar",
20842                 "amenity:university": "education_university",
20843                 "tourism:museum": "tourist_museum",
20844                 "amenity:arts_centre": "tourist_art_gallery2",
20845                 "tourism:zoo": "tourist_zoo",
20846                 "tourism:theme_park": "poi_point_of_interest",
20847                 "tourism:attraction": "poi_point_of_interest",
20848                 "leisure:golf_course": "sport_golf",
20849                 "historic:castle": "tourist_castle",
20850                 "amenity:hospital": "health_hospital",
20851                 "amenity:school": "education_school",
20852                 "amenity:theatre": "tourist_theatre",
20853                 "amenity:library": "amenity_library",
20854                 "amenity:fire_station": "amenity_firestation3",
20855                 "amenity:police": "amenity_police2",
20856                 "amenity:bank": "money_bank2",
20857                 "amenity:post_office": "amenity_post_office",
20858                 "tourism:hotel": "accommodation_hotel2",
20859                 "amenity:cinema": "tourist_cinema",
20860                 "tourism:artwork": "tourist_art_gallery2",
20861                 "historic:archaeological_site": "tourist_archaeological2",
20862                 "amenity:doctors": "health_doctors",
20863                 "leisure:sports_centre": "sport_leisure_centre",
20864                 "leisure:swimming_pool": "sport_swimming_outdoor",
20865                 "shop:supermarket": "shopping_supermarket",
20866                 "shop:convenience": "shopping_convenience",
20867                 "amenity:restaurant": "food_restaurant",
20868                 "amenity:fast_food": "food_fastfood",
20869                 "amenity:cafe": "food_cafe",
20870                 "tourism:guest_house": "accommodation_bed_and_breakfast",
20871                 "amenity:pharmacy": "health_pharmacy_dispensing",
20872                 "amenity:fuel": "transport_fuel",
20873                 "natural:peak": "poi_peak",
20874                 "natural:wood": "landuse_coniferous_and_deciduous",
20875                 "shop:bicycle": "shopping_bicycle",
20876                 "shop:clothes": "shopping_clothes",
20877                 "shop:hairdresser": "shopping_hairdresser",
20878                 "shop:doityourself": "shopping_diy",
20879                 "shop:estate_agent": "shopping_estateagent2",
20880                 "shop:car": "shopping_car",
20881                 "shop:garden_centre": "shopping_garden_centre",
20882                 "shop:car_repair": "shopping_car_repair",
20883                 "shop:bakery": "shopping_bakery",
20884                 "shop:butcher": "shopping_butcher",
20885                 "shop:apparel": "shopping_clothes",
20886                 "shop:laundry": "shopping_laundrette",
20887                 "shop:beverages": "shopping_alcohol",
20888                 "shop:alcohol": "shopping_alcohol",
20889                 "shop:optician": "health_opticians",
20890                 "shop:chemist": "health_pharmacy",
20891                 "shop:gallery": "tourist_art_gallery2",
20892                 "shop:jewelry": "shopping_jewelry",
20893                 "tourism:information": "amenity_information",
20894                 "historic:ruins": "tourist_ruin",
20895                 "amenity:college": "education_school",
20896                 "historic:monument": "tourist_monument",
20897                 "historic:memorial": "tourist_monument",
20898                 "historic:mine": "poi_mine",
20899                 "tourism:caravan_site": "accommodation_caravan_park",
20900                 "amenity:bus_station": "transport_bus_station",
20901                 "amenity:atm": "money_atm2",
20902                 "tourism:viewpoint": "tourist_view_point",
20903                 "tourism:guesthouse": "accommodation_bed_and_breakfast",
20904                 "railway:tram": "transport_tram_stop",
20905                 "amenity:courthouse": "amenity_court",
20906                 "amenity:recycling": "amenity_recycling",
20907                 "amenity:dentist": "health_dentist",
20908                 "natural:beach": "tourist_beach",
20909                 "railway:tram_stop": "transport_tram_stop",
20910                 "amenity:prison": "amenity_prison",
20911                 "highway:bus_stop": "transport_bus_stop2"
20912         };
20913
20914         var sCategoryPlace = aPlace.category + ":" + aPlace.type;
20915         return aIcons[sCategoryPlace];
20916     }
20917
20918     function instance$5($$self, $$props, $$invalidate) {
20919         let { $$slots: slots = {}, $$scope } = $$props;
20920         validate_slots("MapIcon", slots, []);
20921         let { aPlace } = $$props;
20922         let sIcon = getIcon(aPlace);
20923         let title = "icon for " + aPlace.category + " " + aPlace.type;
20924         let url = get_config_value_1("Images_Base_Url") + sIcon + ".p.20.png";
20925         const writable_props = ["aPlace"];
20926
20927         Object.keys($$props).forEach(key => {
20928                 if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<MapIcon> was created with unknown prop '${key}'`);
20929         });
20930
20931         $$self.$$set = $$props => {
20932                 if ("aPlace" in $$props) $$invalidate(3, aPlace = $$props.aPlace);
20933         };
20934
20935         $$self.$capture_state = () => ({
20936                 aPlace,
20937                 get_config_value: get_config_value_1,
20938                 sIcon,
20939                 title,
20940                 url,
20941                 getIcon
20942         });
20943
20944         $$self.$inject_state = $$props => {
20945                 if ("aPlace" in $$props) $$invalidate(3, aPlace = $$props.aPlace);
20946                 if ("sIcon" in $$props) $$invalidate(0, sIcon = $$props.sIcon);
20947                 if ("title" in $$props) $$invalidate(1, title = $$props.title);
20948                 if ("url" in $$props) $$invalidate(2, url = $$props.url);
20949         };
20950
20951         if ($$props && "$$inject" in $$props) {
20952                 $$self.$inject_state($$props.$$inject);
20953         }
20954
20955         return [sIcon, title, url, aPlace];
20956     }
20957
20958     class MapIcon extends SvelteComponentDev {
20959         constructor(options) {
20960                 super(options);
20961                 init(this, options, instance$5, create_fragment$5, safe_not_equal, { aPlace: 3 });
20962
20963                 dispatch_dev("SvelteRegisterComponent", {
20964                         component: this,
20965                         tagName: "MapIcon",
20966                         options,
20967                         id: create_fragment$5.name
20968                 });
20969
20970                 const { ctx } = this.$$;
20971                 const props = options.props || {};
20972
20973                 if (/*aPlace*/ ctx[3] === undefined && !("aPlace" in props)) {
20974                         console.warn("<MapIcon> was created without expected prop 'aPlace'");
20975                 }
20976         }
20977
20978         get aPlace() {
20979                 throw new Error("<MapIcon>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
20980         }
20981
20982         set aPlace(value) {
20983                 throw new Error("<MapIcon>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
20984         }
20985     }
20986
20987     /* src/components/ResultsList.svelte generated by Svelte v3.31.2 */
20988     const file$6 = "src/components/ResultsList.svelte";
20989
20990     function get_each_context$1(ctx, list, i) {
20991         const child_ctx = ctx.slice();
20992         child_ctx[5] = list[i];
20993         child_ctx[7] = i;
20994         return child_ctx;
20995     }
20996
20997     // (83:0) {:else}
20998     function create_else_block_1(ctx) {
20999         let welcome;
21000         let current;
21001         welcome = new Welcome({ $$inline: true });
21002
21003         const block = {
21004                 c: function create() {
21005                         create_component(welcome.$$.fragment);
21006                 },
21007                 m: function mount(target, anchor) {
21008                         mount_component(welcome, target, anchor);
21009                         current = true;
21010                 },
21011                 p: noop,
21012                 i: function intro(local) {
21013                         if (current) return;
21014                         transition_in(welcome.$$.fragment, local);
21015                         current = true;
21016                 },
21017                 o: function outro(local) {
21018                         transition_out(welcome.$$.fragment, local);
21019                         current = false;
21020                 },
21021                 d: function destroy(detaching) {
21022                         destroy_component(welcome, detaching);
21023                 }
21024         };
21025
21026         dispatch_dev("SvelteRegisterBlock", {
21027                 block,
21028                 id: create_else_block_1.name,
21029                 type: "else",
21030                 source: "(83:0) {:else}",
21031                 ctx
21032         });
21033
21034         return block;
21035     }
21036
21037     // (77:25) 
21038     function create_if_block_2(ctx) {
21039         let if_block_anchor;
21040
21041         function select_block_type_1(ctx, dirty) {
21042                 if (/*reverse_search*/ ctx[0]) return create_if_block_3;
21043                 return create_else_block$1;
21044         }
21045
21046         let current_block_type = select_block_type_1(ctx);
21047         let if_block = current_block_type(ctx);
21048
21049         const block = {
21050                 c: function create() {
21051                         if_block.c();
21052                         if_block_anchor = empty();
21053                 },
21054                 m: function mount(target, anchor) {
21055                         if_block.m(target, anchor);
21056                         insert_dev(target, if_block_anchor, anchor);
21057                 },
21058                 p: function update(ctx, dirty) {
21059                         if (current_block_type !== (current_block_type = select_block_type_1(ctx))) {
21060                                 if_block.d(1);
21061                                 if_block = current_block_type(ctx);
21062
21063                                 if (if_block) {
21064                                         if_block.c();
21065                                         if_block.m(if_block_anchor.parentNode, if_block_anchor);
21066                                 }
21067                         }
21068                 },
21069                 i: noop,
21070                 o: noop,
21071                 d: function destroy(detaching) {
21072                         if_block.d(detaching);
21073                         if (detaching) detach_dev(if_block_anchor);
21074                 }
21075         };
21076
21077         dispatch_dev("SvelteRegisterBlock", {
21078                 block,
21079                 id: create_if_block_2.name,
21080                 type: "if",
21081                 source: "(77:25) ",
21082                 ctx
21083         });
21084
21085         return block;
21086     }
21087
21088     // (53:0) {#if aSearchResults && aSearchResults.length > 0}
21089     function create_if_block$3(ctx) {
21090         let div;
21091         let t;
21092         let current;
21093         let each_value = /*aSearchResults*/ ctx[1];
21094         validate_each_argument(each_value);
21095         let each_blocks = [];
21096
21097         for (let i = 0; i < each_value.length; i += 1) {
21098                 each_blocks[i] = create_each_block$1(get_each_context$1(ctx, each_value, i));
21099         }
21100
21101         const out = i => transition_out(each_blocks[i], 1, 1, () => {
21102                 each_blocks[i] = null;
21103         });
21104
21105         let if_block = /*sMoreURL*/ ctx[3] && !/*reverse_search*/ ctx[0] && create_if_block_1(ctx);
21106
21107         const block = {
21108                 c: function create() {
21109                         div = element("div");
21110
21111                         for (let i = 0; i < each_blocks.length; i += 1) {
21112                                 each_blocks[i].c();
21113                         }
21114
21115                         t = space();
21116                         if (if_block) if_block.c();
21117                         attr_dev(div, "id", "searchresults");
21118                         add_location(div, file$6, 53, 2, 1681);
21119                 },
21120                 m: function mount(target, anchor) {
21121                         insert_dev(target, div, anchor);
21122
21123                         for (let i = 0; i < each_blocks.length; i += 1) {
21124                                 each_blocks[i].m(div, null);
21125                         }
21126
21127                         append_dev(div, t);
21128                         if (if_block) if_block.m(div, null);
21129                         current = true;
21130                 },
21131                 p: function update(ctx, dirty) {
21132                         if (dirty & /*iHighlightNum, handleClick, detailsURL, aSearchResults, formatLabel*/ 22) {
21133                                 each_value = /*aSearchResults*/ ctx[1];
21134                                 validate_each_argument(each_value);
21135                                 let i;
21136
21137                                 for (i = 0; i < each_value.length; i += 1) {
21138                                         const child_ctx = get_each_context$1(ctx, each_value, i);
21139
21140                                         if (each_blocks[i]) {
21141                                                 each_blocks[i].p(child_ctx, dirty);
21142                                                 transition_in(each_blocks[i], 1);
21143                                         } else {
21144                                                 each_blocks[i] = create_each_block$1(child_ctx);
21145                                                 each_blocks[i].c();
21146                                                 transition_in(each_blocks[i], 1);
21147                                                 each_blocks[i].m(div, t);
21148                                         }
21149                                 }
21150
21151                                 group_outros();
21152
21153                                 for (i = each_value.length; i < each_blocks.length; i += 1) {
21154                                         out(i);
21155                                 }
21156
21157                                 check_outros();
21158                         }
21159
21160                         if (/*sMoreURL*/ ctx[3] && !/*reverse_search*/ ctx[0]) {
21161                                 if (if_block) {
21162                                         if_block.p(ctx, dirty);
21163                                 } else {
21164                                         if_block = create_if_block_1(ctx);
21165                                         if_block.c();
21166                                         if_block.m(div, null);
21167                                 }
21168                         } else if (if_block) {
21169                                 if_block.d(1);
21170                                 if_block = null;
21171                         }
21172                 },
21173                 i: function intro(local) {
21174                         if (current) return;
21175
21176                         for (let i = 0; i < each_value.length; i += 1) {
21177                                 transition_in(each_blocks[i]);
21178                         }
21179
21180                         current = true;
21181                 },
21182                 o: function outro(local) {
21183                         each_blocks = each_blocks.filter(Boolean);
21184
21185                         for (let i = 0; i < each_blocks.length; i += 1) {
21186                                 transition_out(each_blocks[i]);
21187                         }
21188
21189                         current = false;
21190                 },
21191                 d: function destroy(detaching) {
21192                         if (detaching) detach_dev(div);
21193                         destroy_each(each_blocks, detaching);
21194                         if (if_block) if_block.d();
21195                 }
21196         };
21197
21198         dispatch_dev("SvelteRegisterBlock", {
21199                 block,
21200                 id: create_if_block$3.name,
21201                 type: "if",
21202                 source: "(53:0) {#if aSearchResults && aSearchResults.length > 0}",
21203                 ctx
21204         });
21205
21206         return block;
21207     }
21208
21209     // (80:2) {:else}
21210     function create_else_block$1(ctx) {
21211         let div;
21212
21213         const block = {
21214                 c: function create() {
21215                         div = element("div");
21216                         div.textContent = "No search results found";
21217                         attr_dev(div, "class", "noresults svelte-d36c6n");
21218                         add_location(div, file$6, 80, 4, 2634);
21219                 },
21220                 m: function mount(target, anchor) {
21221                         insert_dev(target, div, anchor);
21222                 },
21223                 d: function destroy(detaching) {
21224                         if (detaching) detach_dev(div);
21225                 }
21226         };
21227
21228         dispatch_dev("SvelteRegisterBlock", {
21229                 block,
21230                 id: create_else_block$1.name,
21231                 type: "else",
21232                 source: "(80:2) {:else}",
21233                 ctx
21234         });
21235
21236         return block;
21237     }
21238
21239     // (78:2) {#if reverse_search}
21240     function create_if_block_3(ctx) {
21241         let div;
21242
21243         const block = {
21244                 c: function create() {
21245                         div = element("div");
21246                         div.textContent = "Search for coordinates or click anywhere on the map.";
21247                         attr_dev(div, "id", "intro");
21248                         attr_dev(div, "class", "sidebar");
21249                         add_location(div, file$6, 78, 4, 2529);
21250                 },
21251                 m: function mount(target, anchor) {
21252                         insert_dev(target, div, anchor);
21253                 },
21254                 d: function destroy(detaching) {
21255                         if (detaching) detach_dev(div);
21256                 }
21257         };
21258
21259         dispatch_dev("SvelteRegisterBlock", {
21260                 block,
21261                 id: create_if_block_3.name,
21262                 type: "if",
21263                 source: "(78:2) {#if reverse_search}",
21264                 ctx
21265         });
21266
21267         return block;
21268     }
21269
21270     // (56:4) {#each aSearchResults as aResult, iResNum}
21271     function create_each_block$1(ctx) {
21272         let div1;
21273         let div0;
21274         let mapicon;
21275         let t0;
21276         let span0;
21277         let t1_value = /*aResult*/ ctx[5].display_name + "";
21278         let t1;
21279         let t2;
21280         let span1;
21281         let t3_value = formatLabel_1(/*aResult*/ ctx[5]) + "";
21282         let t3;
21283         let t4;
21284         let p;
21285         let t5_value = /*aResult*/ ctx[5].lat + "";
21286         let t5;
21287         let t6;
21288         let t7_value = /*aResult*/ ctx[5].lon + "";
21289         let t7;
21290         let t8;
21291         let a;
21292         let t9;
21293         let a_href_value;
21294         let current;
21295         let mounted;
21296         let dispose;
21297
21298         mapicon = new MapIcon({
21299                         props: { aPlace: /*aResult*/ ctx[5] },
21300                         $$inline: true
21301                 });
21302
21303         const block = {
21304                 c: function create() {
21305                         div1 = element("div");
21306                         div0 = element("div");
21307                         create_component(mapicon.$$.fragment);
21308                         t0 = space();
21309                         span0 = element("span");
21310                         t1 = text(t1_value);
21311                         t2 = space();
21312                         span1 = element("span");
21313                         t3 = text(t3_value);
21314                         t4 = space();
21315                         p = element("p");
21316                         t5 = text(t5_value);
21317                         t6 = text(",");
21318                         t7 = text(t7_value);
21319                         t8 = space();
21320                         a = element("a");
21321                         t9 = text("details");
21322                         set_style(div0, "float", "right");
21323                         add_location(div0, file$6, 57, 8, 1898);
21324                         attr_dev(span0, "class", "name");
21325                         add_location(span0, file$6, 60, 8, 1986);
21326                         attr_dev(span1, "class", "type svelte-d36c6n");
21327                         add_location(span1, file$6, 61, 8, 2043);
21328                         attr_dev(p, "class", "coords svelte-d36c6n");
21329                         add_location(p, file$6, 62, 8, 2100);
21330                         attr_dev(a, "class", "details btn btn-outline-secondary btn-sm svelte-d36c6n");
21331                         attr_dev(a, "href", a_href_value = detailsURL_1(/*aResult*/ ctx[5]));
21332                         add_location(a, file$6, 64, 8, 2161);
21333                         attr_dev(div1, "class", "result svelte-d36c6n");
21334                         attr_dev(div1, "data-position", /*iResNum*/ ctx[7]);
21335                         toggle_class(div1, "highlight", /*iResNum*/ ctx[7] === /*iHighlightNum*/ ctx[2]);
21336                         add_location(div1, file$6, 56, 6, 1760);
21337                 },
21338                 m: function mount(target, anchor) {
21339                         insert_dev(target, div1, anchor);
21340                         append_dev(div1, div0);
21341                         mount_component(mapicon, div0, null);
21342                         append_dev(div1, t0);
21343                         append_dev(div1, span0);
21344                         append_dev(span0, t1);
21345                         append_dev(div1, t2);
21346                         append_dev(div1, span1);
21347                         append_dev(span1, t3);
21348                         append_dev(div1, t4);
21349                         append_dev(div1, p);
21350                         append_dev(p, t5);
21351                         append_dev(p, t6);
21352                         append_dev(p, t7);
21353                         append_dev(div1, t8);
21354                         append_dev(div1, a);
21355                         append_dev(a, t9);
21356                         current = true;
21357
21358                         if (!mounted) {
21359                                 dispose = listen_dev(div1, "click", stop_propagation(/*handleClick*/ ctx[4]), false, false, true);
21360                                 mounted = true;
21361                         }
21362                 },
21363                 p: function update(ctx, dirty) {
21364                         const mapicon_changes = {};
21365                         if (dirty & /*aSearchResults*/ 2) mapicon_changes.aPlace = /*aResult*/ ctx[5];
21366                         mapicon.$set(mapicon_changes);
21367                         if ((!current || dirty & /*aSearchResults*/ 2) && t1_value !== (t1_value = /*aResult*/ ctx[5].display_name + "")) set_data_dev(t1, t1_value);
21368                         if ((!current || dirty & /*aSearchResults*/ 2) && t3_value !== (t3_value = formatLabel_1(/*aResult*/ ctx[5]) + "")) set_data_dev(t3, t3_value);
21369                         if ((!current || dirty & /*aSearchResults*/ 2) && t5_value !== (t5_value = /*aResult*/ ctx[5].lat + "")) set_data_dev(t5, t5_value);
21370                         if ((!current || dirty & /*aSearchResults*/ 2) && t7_value !== (t7_value = /*aResult*/ ctx[5].lon + "")) set_data_dev(t7, t7_value);
21371
21372                         if (!current || dirty & /*aSearchResults*/ 2 && a_href_value !== (a_href_value = detailsURL_1(/*aResult*/ ctx[5]))) {
21373                                 attr_dev(a, "href", a_href_value);
21374                         }
21375
21376                         if (dirty & /*iHighlightNum*/ 4) {
21377                                 toggle_class(div1, "highlight", /*iResNum*/ ctx[7] === /*iHighlightNum*/ ctx[2]);
21378                         }
21379                 },
21380                 i: function intro(local) {
21381                         if (current) return;
21382                         transition_in(mapicon.$$.fragment, local);
21383                         current = true;
21384                 },
21385                 o: function outro(local) {
21386                         transition_out(mapicon.$$.fragment, local);
21387                         current = false;
21388                 },
21389                 d: function destroy(detaching) {
21390                         if (detaching) detach_dev(div1);
21391                         destroy_component(mapicon);
21392                         mounted = false;
21393                         dispose();
21394                 }
21395         };
21396
21397         dispatch_dev("SvelteRegisterBlock", {
21398                 block,
21399                 id: create_each_block$1.name,
21400                 type: "each",
21401                 source: "(56:4) {#each aSearchResults as aResult, iResNum}",
21402                 ctx
21403         });
21404
21405         return block;
21406     }
21407
21408     // (69:4) {#if sMoreURL && !reverse_search}
21409     function create_if_block_1(ctx) {
21410         let div;
21411         let a;
21412         let t;
21413
21414         const block = {
21415                 c: function create() {
21416                         div = element("div");
21417                         a = element("a");
21418                         t = text("Search for more results");
21419                         attr_dev(a, "class", "btn btn-primary");
21420                         attr_dev(a, "href", /*sMoreURL*/ ctx[3]);
21421                         add_location(a, file$6, 70, 8, 2351);
21422                         attr_dev(div, "class", "more svelte-d36c6n");
21423                         add_location(div, file$6, 69, 6, 2324);
21424                 },
21425                 m: function mount(target, anchor) {
21426                         insert_dev(target, div, anchor);
21427                         append_dev(div, a);
21428                         append_dev(a, t);
21429                 },
21430                 p: function update(ctx, dirty) {
21431                         if (dirty & /*sMoreURL*/ 8) {
21432                                 attr_dev(a, "href", /*sMoreURL*/ ctx[3]);
21433                         }
21434                 },
21435                 d: function destroy(detaching) {
21436                         if (detaching) detach_dev(div);
21437                 }
21438         };
21439
21440         dispatch_dev("SvelteRegisterBlock", {
21441                 block,
21442                 id: create_if_block_1.name,
21443                 type: "if",
21444                 source: "(69:4) {#if sMoreURL && !reverse_search}",
21445                 ctx
21446         });
21447
21448         return block;
21449     }
21450
21451     function create_fragment$6(ctx) {
21452         let current_block_type_index;
21453         let if_block;
21454         let if_block_anchor;
21455         let current;
21456         const if_block_creators = [create_if_block$3, create_if_block_2, create_else_block_1];
21457         const if_blocks = [];
21458
21459         function select_block_type(ctx, dirty) {
21460                 if (/*aSearchResults*/ ctx[1] && /*aSearchResults*/ ctx[1].length > 0) return 0;
21461                 if (/*aSearchResults*/ ctx[1]) return 1;
21462                 return 2;
21463         }
21464
21465         current_block_type_index = select_block_type(ctx);
21466         if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
21467
21468         const block = {
21469                 c: function create() {
21470                         if_block.c();
21471                         if_block_anchor = empty();
21472                 },
21473                 l: function claim(nodes) {
21474                         throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
21475                 },
21476                 m: function mount(target, anchor) {
21477                         if_blocks[current_block_type_index].m(target, anchor);
21478                         insert_dev(target, if_block_anchor, anchor);
21479                         current = true;
21480                 },
21481                 p: function update(ctx, [dirty]) {
21482                         let previous_block_index = current_block_type_index;
21483                         current_block_type_index = select_block_type(ctx);
21484
21485                         if (current_block_type_index === previous_block_index) {
21486                                 if_blocks[current_block_type_index].p(ctx, dirty);
21487                         } else {
21488                                 group_outros();
21489
21490                                 transition_out(if_blocks[previous_block_index], 1, 1, () => {
21491                                         if_blocks[previous_block_index] = null;
21492                                 });
21493
21494                                 check_outros();
21495                                 if_block = if_blocks[current_block_type_index];
21496
21497                                 if (!if_block) {
21498                                         if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
21499                                         if_block.c();
21500                                 } else {
21501                                         if_block.p(ctx, dirty);
21502                                 }
21503
21504                                 transition_in(if_block, 1);
21505                                 if_block.m(if_block_anchor.parentNode, if_block_anchor);
21506                         }
21507                 },
21508                 i: function intro(local) {
21509                         if (current) return;
21510                         transition_in(if_block);
21511                         current = true;
21512                 },
21513                 o: function outro(local) {
21514                         transition_out(if_block);
21515                         current = false;
21516                 },
21517                 d: function destroy(detaching) {
21518                         if_blocks[current_block_type_index].d(detaching);
21519                         if (detaching) detach_dev(if_block_anchor);
21520                 }
21521         };
21522
21523         dispatch_dev("SvelteRegisterBlock", {
21524                 block,
21525                 id: create_fragment$6.name,
21526                 type: "component",
21527                 source: "",
21528                 ctx
21529         });
21530
21531         return block;
21532     }
21533
21534     function instance$6($$self, $$props, $$invalidate) {
21535         let { $$slots: slots = {}, $$scope } = $$props;
21536         validate_slots("ResultsList", slots, []);
21537         let { reverse_search = false } = $$props;
21538         let aSearchResults;
21539         let iHighlightNum;
21540         let sMoreURL;
21541
21542         results_store.subscribe(data => {
21543                 if (!data) {
21544                         return;
21545                 }
21546
21547                 $$invalidate(1, aSearchResults = data);
21548                 $$invalidate(2, iHighlightNum = 0);
21549                 current_result_store.set(aSearchResults[0]);
21550                 let search_params = new URLSearchParams(window.location.search);
21551                 let aResults = data;
21552
21553                 // lonvia wrote: https://github.com/osm-search/nominatim-ui/issues/24
21554                 // I would suggest to remove the guessing and always show the link. Nominatim only returns
21555                 // one or two results when it believes the result to be a good enough match.
21556                 // if (aResults.length >= 10) {
21557                 var aExcludePlaceIds = [];
21558
21559                 if (search_params.has("exclude_place_ids")) {
21560                         aExcludePlaceIds = search_params.get("exclude_place_ids").split(",");
21561                 }
21562
21563                 for (var i = 0; i < aResults.length; i += 1) {
21564                         aExcludePlaceIds.push(aResults[i].place_id);
21565                 }
21566
21567                 var parsed_url = new URLSearchParams(window.location.search);
21568                 parsed_url.set("exclude_place_ids", aExcludePlaceIds.join(","));
21569                 $$invalidate(3, sMoreURL = "?" + parsed_url.toString());
21570         });
21571
21572         function handleClick(e) {
21573                 let result_el = e.target;
21574
21575                 if (!result_el.className.match("result")) {
21576                         result_el = result_el.parentElement;
21577                 }
21578
21579                 let pos = Number(result_el.dataset.position);
21580                 current_result_store.set(aSearchResults[pos]);
21581                 $$invalidate(2, iHighlightNum = pos);
21582         }
21583
21584         const writable_props = ["reverse_search"];
21585
21586         Object.keys($$props).forEach(key => {
21587                 if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<ResultsList> was created with unknown prop '${key}'`);
21588         });
21589
21590         $$self.$$set = $$props => {
21591                 if ("reverse_search" in $$props) $$invalidate(0, reverse_search = $$props.reverse_search);
21592         };
21593
21594         $$self.$capture_state = () => ({
21595                 results_store,
21596                 current_result_store,
21597                 formatLabel: formatLabel_1,
21598                 detailsURL: detailsURL_1,
21599                 Welcome,
21600                 MapIcon,
21601                 reverse_search,
21602                 aSearchResults,
21603                 iHighlightNum,
21604                 sMoreURL,
21605                 handleClick
21606         });
21607
21608         $$self.$inject_state = $$props => {
21609                 if ("reverse_search" in $$props) $$invalidate(0, reverse_search = $$props.reverse_search);
21610                 if ("aSearchResults" in $$props) $$invalidate(1, aSearchResults = $$props.aSearchResults);
21611                 if ("iHighlightNum" in $$props) $$invalidate(2, iHighlightNum = $$props.iHighlightNum);
21612                 if ("sMoreURL" in $$props) $$invalidate(3, sMoreURL = $$props.sMoreURL);
21613         };
21614
21615         if ($$props && "$$inject" in $$props) {
21616                 $$self.$inject_state($$props.$$inject);
21617         }
21618
21619         return [reverse_search, aSearchResults, iHighlightNum, sMoreURL, handleClick];
21620     }
21621
21622     class ResultsList extends SvelteComponentDev {
21623         constructor(options) {
21624                 super(options);
21625                 init(this, options, instance$6, create_fragment$6, safe_not_equal, { reverse_search: 0 });
21626
21627                 dispatch_dev("SvelteRegisterComponent", {
21628                         component: this,
21629                         tagName: "ResultsList",
21630                         options,
21631                         id: create_fragment$6.name
21632                 });
21633         }
21634
21635         get reverse_search() {
21636                 throw new Error("<ResultsList>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
21637         }
21638
21639         set reverse_search(value) {
21640                 throw new Error("<ResultsList>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
21641         }
21642     }
21643
21644     /* @preserve
21645      * Leaflet 1.7.1, a JS library for interactive maps. http://leafletjs.com
21646      * (c) 2010-2019 Vladimir Agafonkin, (c) 2010-2011 CloudMade
21647      */
21648
21649     var leafletSrc = createCommonjsModule(function (module, exports) {
21650     (function (global, factory) {
21651        factory(exports) ;
21652     }(commonjsGlobal, (function (exports) {
21653       var version = "1.7.1";
21654
21655       /*\r
21656        * @namespace Util\r
21657        *\r
21658        * Various utility functions, used by Leaflet internally.\r
21659        */\r
21660 \r
21661       // @function extend(dest: Object, src?: Object): Object\r
21662       // Merges the properties of the `src` object (or multiple objects) into `dest` object and returns the latter. Has an `L.extend` shortcut.\r
21663       function extend(dest) {\r
21664         var i, j, len, src;\r
21665 \r
21666         for (j = 1, len = arguments.length; j < len; j++) {\r
21667                 src = arguments[j];\r
21668                 for (i in src) {\r
21669                         dest[i] = src[i];\r
21670                 }\r
21671         }\r
21672         return dest;\r
21673       }\r
21674 \r
21675       // @function create(proto: Object, properties?: Object): Object\r
21676       // Compatibility polyfill for [Object.create](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/create)\r
21677       var create = Object.create || (function () {\r
21678         function F() {}\r
21679         return function (proto) {\r
21680                 F.prototype = proto;\r
21681                 return new F();\r
21682         };\r
21683       })();\r
21684 \r
21685       // @function bind(fn: Function, â€¦): Function\r
21686       // Returns a new function bound to the arguments passed, like [Function.prototype.bind](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Function/bind).\r
21687       // Has a `L.bind()` shortcut.\r
21688       function bind(fn, obj) {\r
21689         var slice = Array.prototype.slice;\r
21690 \r
21691         if (fn.bind) {\r
21692                 return fn.bind.apply(fn, slice.call(arguments, 1));\r
21693         }\r
21694 \r
21695         var args = slice.call(arguments, 2);\r
21696 \r
21697         return function () {\r
21698                 return fn.apply(obj, args.length ? args.concat(slice.call(arguments)) : arguments);\r
21699         };\r
21700       }\r
21701 \r
21702       // @property lastId: Number\r
21703       // Last unique ID used by [`stamp()`](#util-stamp)\r
21704       var lastId = 0;\r
21705 \r
21706       // @function stamp(obj: Object): Number\r
21707       // Returns the unique ID of an object, assigning it one if it doesn't have it.\r
21708       function stamp(obj) {\r
21709         /*eslint-disable */\r
21710         obj._leaflet_id = obj._leaflet_id || ++lastId;\r
21711         return obj._leaflet_id;\r
21712         /* eslint-enable */\r
21713       }\r
21714 \r
21715       // @function throttle(fn: Function, time: Number, context: Object): Function\r
21716       // Returns a function which executes function `fn` with the given scope `context`\r
21717       // (so that the `this` keyword refers to `context` inside `fn`'s code). The function\r
21718       // `fn` will be called no more than one time per given amount of `time`. The arguments\r
21719       // received by the bound function will be any arguments passed when binding the\r
21720       // function, followed by any arguments passed when invoking the bound function.\r
21721       // Has an `L.throttle` shortcut.\r
21722       function throttle(fn, time, context) {\r
21723         var lock, args, wrapperFn, later;\r
21724 \r
21725         later = function () {\r
21726                 // reset lock and call if queued\r
21727                 lock = false;\r
21728                 if (args) {\r
21729                         wrapperFn.apply(context, args);\r
21730                         args = false;\r
21731                 }\r
21732         };\r
21733 \r
21734         wrapperFn = function () {\r
21735                 if (lock) {\r
21736                         // called too soon, queue to call later\r
21737                         args = arguments;\r
21738 \r
21739                 } else {\r
21740                         // call and lock until later\r
21741                         fn.apply(context, arguments);\r
21742                         setTimeout(later, time);\r
21743                         lock = true;\r
21744                 }\r
21745         };\r
21746 \r
21747         return wrapperFn;\r
21748       }\r
21749 \r
21750       // @function wrapNum(num: Number, range: Number[], includeMax?: Boolean): Number\r
21751       // Returns the number `num` modulo `range` in such a way so it lies within\r
21752       // `range[0]` and `range[1]`. The returned value will be always smaller than\r
21753       // `range[1]` unless `includeMax` is set to `true`.\r
21754       function wrapNum(x, range, includeMax) {\r
21755         var max = range[1],\r
21756             min = range[0],\r
21757             d = max - min;\r
21758         return x === max && includeMax ? x : ((x - min) % d + d) % d + min;\r
21759       }\r
21760 \r
21761       // @function falseFn(): Function\r
21762       // Returns a function which always returns `false`.\r
21763       function falseFn() { return false; }\r
21764 \r
21765       // @function formatNum(num: Number, digits?: Number): Number\r
21766       // Returns the number `num` rounded to `digits` decimals, or to 6 decimals by default.\r
21767       function formatNum(num, digits) {\r
21768         var pow = Math.pow(10, (digits === undefined ? 6 : digits));\r
21769         return Math.round(num * pow) / pow;\r
21770       }\r
21771 \r
21772       // @function trim(str: String): String\r
21773       // Compatibility polyfill for [String.prototype.trim](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/Trim)\r
21774       function trim(str) {\r
21775         return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, '');\r
21776       }\r
21777 \r
21778       // @function splitWords(str: String): String[]\r
21779       // Trims and splits the string on whitespace and returns the array of parts.\r
21780       function splitWords(str) {\r
21781         return trim(str).split(/\s+/);\r
21782       }\r
21783 \r
21784       // @function setOptions(obj: Object, options: Object): Object\r
21785       // Merges the given properties to the `options` of the `obj` object, returning the resulting options. See `Class options`. Has an `L.setOptions` shortcut.\r
21786       function setOptions(obj, options) {\r
21787         if (!Object.prototype.hasOwnProperty.call(obj, 'options')) {\r
21788                 obj.options = obj.options ? create(obj.options) : {};\r
21789         }\r
21790         for (var i in options) {\r
21791                 obj.options[i] = options[i];\r
21792         }\r
21793         return obj.options;\r
21794       }\r
21795 \r
21796       // @function getParamString(obj: Object, existingUrl?: String, uppercase?: Boolean): String\r
21797       // Converts an object into a parameter URL string, e.g. `{a: "foo", b: "bar"}`\r
21798       // translates to `'?a=foo&b=bar'`. If `existingUrl` is set, the parameters will\r
21799       // be appended at the end. If `uppercase` is `true`, the parameter names will\r
21800       // be uppercased (e.g. `'?A=foo&B=bar'`)\r
21801       function getParamString(obj, existingUrl, uppercase) {\r
21802         var params = [];\r
21803         for (var i in obj) {\r
21804                 params.push(encodeURIComponent(uppercase ? i.toUpperCase() : i) + '=' + encodeURIComponent(obj[i]));\r
21805         }\r
21806         return ((!existingUrl || existingUrl.indexOf('?') === -1) ? '?' : '&') + params.join('&');\r
21807       }\r
21808 \r
21809       var templateRe = /\{ *([\w_-]+) *\}/g;\r
21810 \r
21811       // @function template(str: String, data: Object): String\r
21812       // Simple templating facility, accepts a template string of the form `'Hello {a}, {b}'`\r
21813       // and a data object like `{a: 'foo', b: 'bar'}`, returns evaluated string\r
21814       // `('Hello foo, bar')`. You can also specify functions instead of strings for\r
21815       // data values â€” they will be evaluated passing `data` as an argument.\r
21816       function template(str, data) {\r
21817         return str.replace(templateRe, function (str, key) {\r
21818                 var value = data[key];\r
21819 \r
21820                 if (value === undefined) {\r
21821                         throw new Error('No value provided for variable ' + str);\r
21822 \r
21823                 } else if (typeof value === 'function') {\r
21824                         value = value(data);\r
21825                 }\r
21826                 return value;\r
21827         });\r
21828       }\r
21829 \r
21830       // @function isArray(obj): Boolean\r
21831       // Compatibility polyfill for [Array.isArray](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray)\r
21832       var isArray = Array.isArray || function (obj) {\r
21833         return (Object.prototype.toString.call(obj) === '[object Array]');\r
21834       };\r
21835 \r
21836       // @function indexOf(array: Array, el: Object): Number\r
21837       // Compatibility polyfill for [Array.prototype.indexOf](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)\r
21838       function indexOf(array, el) {\r
21839         for (var i = 0; i < array.length; i++) {\r
21840                 if (array[i] === el) { return i; }\r
21841         }\r
21842         return -1;\r
21843       }\r
21844 \r
21845       // @property emptyImageUrl: String\r
21846       // Data URI string containing a base64-encoded empty GIF image.\r
21847       // Used as a hack to free memory from unused images on WebKit-powered\r
21848       // mobile devices (by setting image `src` to this string).\r
21849       var emptyImageUrl = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';\r
21850 \r
21851       // inspired by http://paulirish.com/2011/requestanimationframe-for-smart-animating/\r
21852 \r
21853       function getPrefixed(name) {\r
21854         return window['webkit' + name] || window['moz' + name] || window['ms' + name];\r
21855       }\r
21856 \r
21857       var lastTime = 0;\r
21858 \r
21859       // fallback for IE 7-8\r
21860       function timeoutDefer(fn) {\r
21861         var time = +new Date(),\r
21862             timeToCall = Math.max(0, 16 - (time - lastTime));\r
21863 \r
21864         lastTime = time + timeToCall;\r
21865         return window.setTimeout(fn, timeToCall);\r
21866       }\r
21867 \r
21868       var requestFn = window.requestAnimationFrame || getPrefixed('RequestAnimationFrame') || timeoutDefer;\r
21869       var cancelFn = window.cancelAnimationFrame || getPrefixed('CancelAnimationFrame') ||\r
21870                 getPrefixed('CancelRequestAnimationFrame') || function (id) { window.clearTimeout(id); };\r
21871 \r
21872       // @function requestAnimFrame(fn: Function, context?: Object, immediate?: Boolean): Number\r
21873       // Schedules `fn` to be executed when the browser repaints. `fn` is bound to\r
21874       // `context` if given. When `immediate` is set, `fn` is called immediately if\r
21875       // the browser doesn't have native support for\r
21876       // [`window.requestAnimationFrame`](https://developer.mozilla.org/docs/Web/API/window/requestAnimationFrame),\r
21877       // otherwise it's delayed. Returns a request ID that can be used to cancel the request.\r
21878       function requestAnimFrame(fn, context, immediate) {\r
21879         if (immediate && requestFn === timeoutDefer) {\r
21880                 fn.call(context);\r
21881         } else {\r
21882                 return requestFn.call(window, bind(fn, context));\r
21883         }\r
21884       }\r
21885 \r
21886       // @function cancelAnimFrame(id: Number): undefined\r
21887       // Cancels a previous `requestAnimFrame`. See also [window.cancelAnimationFrame](https://developer.mozilla.org/docs/Web/API/window/cancelAnimationFrame).\r
21888       function cancelAnimFrame(id) {\r
21889         if (id) {\r
21890                 cancelFn.call(window, id);\r
21891         }\r
21892       }
21893
21894       var Util = ({
21895         extend: extend,
21896         create: create,
21897         bind: bind,
21898         lastId: lastId,
21899         stamp: stamp,
21900         throttle: throttle,
21901         wrapNum: wrapNum,
21902         falseFn: falseFn,
21903         formatNum: formatNum,
21904         trim: trim,
21905         splitWords: splitWords,
21906         setOptions: setOptions,
21907         getParamString: getParamString,
21908         template: template,
21909         isArray: isArray,
21910         indexOf: indexOf,
21911         emptyImageUrl: emptyImageUrl,
21912         requestFn: requestFn,
21913         cancelFn: cancelFn,
21914         requestAnimFrame: requestAnimFrame,
21915         cancelAnimFrame: cancelAnimFrame
21916       });
21917
21918       // @class Class\r
21919       // @aka L.Class\r
21920 \r
21921       // @section\r
21922       // @uninheritable\r
21923 \r
21924       // Thanks to John Resig and Dean Edwards for inspiration!\r
21925 \r
21926       function Class() {}\r
21927 \r
21928       Class.extend = function (props) {\r
21929 \r
21930         // @function extend(props: Object): Function\r
21931         // [Extends the current class](#class-inheritance) given the properties to be included.\r
21932         // Returns a Javascript function that is a class constructor (to be called with `new`).\r
21933         var NewClass = function () {\r
21934 \r
21935                 // call the constructor\r
21936                 if (this.initialize) {\r
21937                         this.initialize.apply(this, arguments);\r
21938                 }\r
21939 \r
21940                 // call all constructor hooks\r
21941                 this.callInitHooks();\r
21942         };\r
21943 \r
21944         var parentProto = NewClass.__super__ = this.prototype;\r
21945 \r
21946         var proto = create(parentProto);\r
21947         proto.constructor = NewClass;\r
21948 \r
21949         NewClass.prototype = proto;\r
21950 \r
21951         // inherit parent's statics\r
21952         for (var i in this) {\r
21953                 if (Object.prototype.hasOwnProperty.call(this, i) && i !== 'prototype' && i !== '__super__') {\r
21954                         NewClass[i] = this[i];\r
21955                 }\r
21956         }\r
21957 \r
21958         // mix static properties into the class\r
21959         if (props.statics) {\r
21960                 extend(NewClass, props.statics);\r
21961                 delete props.statics;\r
21962         }\r
21963 \r
21964         // mix includes into the prototype\r
21965         if (props.includes) {\r
21966                 checkDeprecatedMixinEvents(props.includes);\r
21967                 extend.apply(null, [proto].concat(props.includes));\r
21968                 delete props.includes;\r
21969         }\r
21970 \r
21971         // merge options\r
21972         if (proto.options) {\r
21973                 props.options = extend(create(proto.options), props.options);\r
21974         }\r
21975 \r
21976         // mix given properties into the prototype\r
21977         extend(proto, props);\r
21978 \r
21979         proto._initHooks = [];\r
21980 \r
21981         // add method for calling all hooks\r
21982         proto.callInitHooks = function () {\r
21983 \r
21984                 if (this._initHooksCalled) { return; }\r
21985 \r
21986                 if (parentProto.callInitHooks) {\r
21987                         parentProto.callInitHooks.call(this);\r
21988                 }\r
21989 \r
21990                 this._initHooksCalled = true;\r
21991 \r
21992                 for (var i = 0, len = proto._initHooks.length; i < len; i++) {\r
21993                         proto._initHooks[i].call(this);\r
21994                 }\r
21995         };\r
21996 \r
21997         return NewClass;\r
21998       };\r
21999 \r
22000 \r
22001       // @function include(properties: Object): this\r
22002       // [Includes a mixin](#class-includes) into the current class.\r
22003       Class.include = function (props) {\r
22004         extend(this.prototype, props);\r
22005         return this;\r
22006       };\r
22007 \r
22008       // @function mergeOptions(options: Object): this\r
22009       // [Merges `options`](#class-options) into the defaults of the class.\r
22010       Class.mergeOptions = function (options) {\r
22011         extend(this.prototype.options, options);\r
22012         return this;\r
22013       };\r
22014 \r
22015       // @function addInitHook(fn: Function): this\r
22016       // Adds a [constructor hook](#class-constructor-hooks) to the class.\r
22017       Class.addInitHook = function (fn) { // (Function) || (String, args...)\r
22018         var args = Array.prototype.slice.call(arguments, 1);\r
22019 \r
22020         var init = typeof fn === 'function' ? fn : function () {\r
22021                 this[fn].apply(this, args);\r
22022         };\r
22023 \r
22024         this.prototype._initHooks = this.prototype._initHooks || [];\r
22025         this.prototype._initHooks.push(init);\r
22026         return this;\r
22027       };\r
22028 \r
22029       function checkDeprecatedMixinEvents(includes) {\r
22030         if (typeof L === 'undefined' || !L || !L.Mixin) { return; }\r
22031 \r
22032         includes = isArray(includes) ? includes : [includes];\r
22033 \r
22034         for (var i = 0; i < includes.length; i++) {\r
22035                 if (includes[i] === L.Mixin.Events) {\r
22036                         console.warn('Deprecated include of L.Mixin.Events: ' +\r
22037                                 'this property will be removed in future releases, ' +\r
22038                                 'please inherit from L.Evented instead.', new Error().stack);\r
22039                 }\r
22040         }\r
22041       }
22042
22043       /*\r
22044        * @class Evented\r
22045        * @aka L.Evented\r
22046        * @inherits Class\r
22047        *\r
22048        * A set of methods shared between event-powered classes (like `Map` and `Marker`). Generally, events allow you to execute some function when something happens with an object (e.g. the user clicks on the map, causing the map to fire `'click'` event).\r
22049        *\r
22050        * @example\r
22051        *\r
22052        * ```js\r
22053        * map.on('click', function(e) {\r
22054        *        alert(e.latlng);\r
22055        * } );\r
22056        * ```\r
22057        *\r
22058        * Leaflet deals with event listeners by reference, so if you want to add a listener and then remove it, define it as a function:\r
22059        *\r
22060        * ```js\r
22061        * function onClick(e) { ... }\r
22062        *\r
22063        * map.on('click', onClick);\r
22064        * map.off('click', onClick);\r
22065        * ```\r
22066        */\r
22067 \r
22068       var Events = {\r
22069         /* @method on(type: String, fn: Function, context?: Object): this\r
22070          * Adds a listener function (`fn`) to a particular event type of the object. You can optionally specify the context of the listener (object the this keyword will point to). You can also pass several space-separated types (e.g. `'click dblclick'`).\r
22071          *\r
22072          * @alternative\r
22073          * @method on(eventMap: Object): this\r
22074          * Adds a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}`\r
22075          */\r
22076         on: function (types, fn, context) {\r
22077 \r
22078                 // types can be a map of types/handlers\r
22079                 if (typeof types === 'object') {\r
22080                         for (var type in types) {\r
22081                                 // we don't process space-separated events here for performance;\r
22082                                 // it's a hot path since Layer uses the on(obj) syntax\r
22083                                 this._on(type, types[type], fn);\r
22084                         }\r
22085 \r
22086                 } else {\r
22087                         // types can be a string of space-separated words\r
22088                         types = splitWords(types);\r
22089 \r
22090                         for (var i = 0, len = types.length; i < len; i++) {\r
22091                                 this._on(types[i], fn, context);\r
22092                         }\r
22093                 }\r
22094 \r
22095                 return this;\r
22096         },\r
22097 \r
22098         /* @method off(type: String, fn?: Function, context?: Object): this\r
22099          * Removes a previously added listener function. If no function is specified, it will remove all the listeners of that particular event from the object. Note that if you passed a custom context to `on`, you must pass the same context to `off` in order to remove the listener.\r
22100          *\r
22101          * @alternative\r
22102          * @method off(eventMap: Object): this\r
22103          * Removes a set of type/listener pairs.\r
22104          *\r
22105          * @alternative\r
22106          * @method off: this\r
22107          * Removes all listeners to all events on the object. This includes implicitly attached events.\r
22108          */\r
22109         off: function (types, fn, context) {\r
22110 \r
22111                 if (!types) {\r
22112                         // clear all listeners if called without arguments\r
22113                         delete this._events;\r
22114 \r
22115                 } else if (typeof types === 'object') {\r
22116                         for (var type in types) {\r
22117                                 this._off(type, types[type], fn);\r
22118                         }\r
22119 \r
22120                 } else {\r
22121                         types = splitWords(types);\r
22122 \r
22123                         for (var i = 0, len = types.length; i < len; i++) {\r
22124                                 this._off(types[i], fn, context);\r
22125                         }\r
22126                 }\r
22127 \r
22128                 return this;\r
22129         },\r
22130 \r
22131         // attach listener (without syntactic sugar now)\r
22132         _on: function (type, fn, context) {\r
22133                 this._events = this._events || {};\r
22134 \r
22135                 /* get/init listeners for type */\r
22136                 var typeListeners = this._events[type];\r
22137                 if (!typeListeners) {\r
22138                         typeListeners = [];\r
22139                         this._events[type] = typeListeners;\r
22140                 }\r
22141 \r
22142                 if (context === this) {\r
22143                         // Less memory footprint.\r
22144                         context = undefined;\r
22145                 }\r
22146                 var newListener = {fn: fn, ctx: context},\r
22147                     listeners = typeListeners;\r
22148 \r
22149                 // check if fn already there\r
22150                 for (var i = 0, len = listeners.length; i < len; i++) {\r
22151                         if (listeners[i].fn === fn && listeners[i].ctx === context) {\r
22152                                 return;\r
22153                         }\r
22154                 }\r
22155 \r
22156                 listeners.push(newListener);\r
22157         },\r
22158 \r
22159         _off: function (type, fn, context) {\r
22160                 var listeners,\r
22161                     i,\r
22162                     len;\r
22163 \r
22164                 if (!this._events) { return; }\r
22165 \r
22166                 listeners = this._events[type];\r
22167 \r
22168                 if (!listeners) {\r
22169                         return;\r
22170                 }\r
22171 \r
22172                 if (!fn) {\r
22173                         // Set all removed listeners to noop so they are not called if remove happens in fire\r
22174                         for (i = 0, len = listeners.length; i < len; i++) {\r
22175                                 listeners[i].fn = falseFn;\r
22176                         }\r
22177                         // clear all listeners for a type if function isn't specified\r
22178                         delete this._events[type];\r
22179                         return;\r
22180                 }\r
22181 \r
22182                 if (context === this) {\r
22183                         context = undefined;\r
22184                 }\r
22185 \r
22186                 if (listeners) {\r
22187 \r
22188                         // find fn and remove it\r
22189                         for (i = 0, len = listeners.length; i < len; i++) {\r
22190                                 var l = listeners[i];\r
22191                                 if (l.ctx !== context) { continue; }\r
22192                                 if (l.fn === fn) {\r
22193 \r
22194                                         // set the removed listener to noop so that's not called if remove happens in fire\r
22195                                         l.fn = falseFn;\r
22196 \r
22197                                         if (this._firingCount) {\r
22198                                                 /* copy array in case events are being fired */\r
22199                                                 this._events[type] = listeners = listeners.slice();\r
22200                                         }\r
22201                                         listeners.splice(i, 1);\r
22202 \r
22203                                         return;\r
22204                                 }\r
22205                         }\r
22206                 }\r
22207         },\r
22208 \r
22209         // @method fire(type: String, data?: Object, propagate?: Boolean): this\r
22210         // Fires an event of the specified type. You can optionally provide an data\r
22211         // object â€” the first argument of the listener function will contain its\r
22212         // properties. The event can optionally be propagated to event parents.\r
22213         fire: function (type, data, propagate) {\r
22214                 if (!this.listens(type, propagate)) { return this; }\r
22215 \r
22216                 var event = extend({}, data, {\r
22217                         type: type,\r
22218                         target: this,\r
22219                         sourceTarget: data && data.sourceTarget || this\r
22220                 });\r
22221 \r
22222                 if (this._events) {\r
22223                         var listeners = this._events[type];\r
22224 \r
22225                         if (listeners) {\r
22226                                 this._firingCount = (this._firingCount + 1) || 1;\r
22227                                 for (var i = 0, len = listeners.length; i < len; i++) {\r
22228                                         var l = listeners[i];\r
22229                                         l.fn.call(l.ctx || this, event);\r
22230                                 }\r
22231 \r
22232                                 this._firingCount--;\r
22233                         }\r
22234                 }\r
22235 \r
22236                 if (propagate) {\r
22237                         // propagate the event to parents (set with addEventParent)\r
22238                         this._propagateEvent(event);\r
22239                 }\r
22240 \r
22241                 return this;\r
22242         },\r
22243 \r
22244         // @method listens(type: String): Boolean\r
22245         // Returns `true` if a particular event type has any listeners attached to it.\r
22246         listens: function (type, propagate) {\r
22247                 var listeners = this._events && this._events[type];\r
22248                 if (listeners && listeners.length) { return true; }\r
22249 \r
22250                 if (propagate) {\r
22251                         // also check parents for listeners if event propagates\r
22252                         for (var id in this._eventParents) {\r
22253                                 if (this._eventParents[id].listens(type, propagate)) { return true; }\r
22254                         }\r
22255                 }\r
22256                 return false;\r
22257         },\r
22258 \r
22259         // @method once(…): this\r
22260         // Behaves as [`on(…)`](#evented-on), except the listener will only get fired once and then removed.\r
22261         once: function (types, fn, context) {\r
22262 \r
22263                 if (typeof types === 'object') {\r
22264                         for (var type in types) {\r
22265                                 this.once(type, types[type], fn);\r
22266                         }\r
22267                         return this;\r
22268                 }\r
22269 \r
22270                 var handler = bind(function () {\r
22271                         this\r
22272                             .off(types, fn, context)\r
22273                             .off(types, handler, context);\r
22274                 }, this);\r
22275 \r
22276                 // add a listener that's executed once and removed after that\r
22277                 return this\r
22278                     .on(types, fn, context)\r
22279                     .on(types, handler, context);\r
22280         },\r
22281 \r
22282         // @method addEventParent(obj: Evented): this\r
22283         // Adds an event parent - an `Evented` that will receive propagated events\r
22284         addEventParent: function (obj) {\r
22285                 this._eventParents = this._eventParents || {};\r
22286                 this._eventParents[stamp(obj)] = obj;\r
22287                 return this;\r
22288         },\r
22289 \r
22290         // @method removeEventParent(obj: Evented): this\r
22291         // Removes an event parent, so it will stop receiving propagated events\r
22292         removeEventParent: function (obj) {\r
22293                 if (this._eventParents) {\r
22294                         delete this._eventParents[stamp(obj)];\r
22295                 }\r
22296                 return this;\r
22297         },\r
22298 \r
22299         _propagateEvent: function (e) {\r
22300                 for (var id in this._eventParents) {\r
22301                         this._eventParents[id].fire(e.type, extend({\r
22302                                 layer: e.target,\r
22303                                 propagatedFrom: e.target\r
22304                         }, e), true);\r
22305                 }\r
22306         }\r
22307       };\r
22308 \r
22309       // aliases; we should ditch those eventually\r
22310 \r
22311       // @method addEventListener(…): this\r
22312       // Alias to [`on(…)`](#evented-on)\r
22313       Events.addEventListener = Events.on;\r
22314 \r
22315       // @method removeEventListener(…): this\r
22316       // Alias to [`off(…)`](#evented-off)\r
22317 \r
22318       // @method clearAllEventListeners(…): this\r
22319       // Alias to [`off()`](#evented-off)\r
22320       Events.removeEventListener = Events.clearAllEventListeners = Events.off;\r
22321 \r
22322       // @method addOneTimeEventListener(…): this\r
22323       // Alias to [`once(…)`](#evented-once)\r
22324       Events.addOneTimeEventListener = Events.once;\r
22325 \r
22326       // @method fireEvent(…): this\r
22327       // Alias to [`fire(…)`](#evented-fire)\r
22328       Events.fireEvent = Events.fire;\r
22329 \r
22330       // @method hasEventListeners(…): Boolean\r
22331       // Alias to [`listens(…)`](#evented-listens)\r
22332       Events.hasEventListeners = Events.listens;\r
22333 \r
22334       var Evented = Class.extend(Events);
22335
22336       /*\r
22337        * @class Point\r
22338        * @aka L.Point\r
22339        *\r
22340        * Represents a point with `x` and `y` coordinates in pixels.\r
22341        *\r
22342        * @example\r
22343        *\r
22344        * ```js\r
22345        * var point = L.point(200, 300);\r
22346        * ```\r
22347        *\r
22348        * All Leaflet methods and options that accept `Point` objects also accept them in a simple Array form (unless noted otherwise), so these lines are equivalent:\r
22349        *\r
22350        * ```js\r
22351        * map.panBy([200, 300]);\r
22352        * map.panBy(L.point(200, 300));\r
22353        * ```\r
22354        *\r
22355        * Note that `Point` does not inherit from Leaflet's `Class` object,\r
22356        * which means new classes can't inherit from it, and new methods\r
22357        * can't be added to it with the `include` function.\r
22358        */\r
22359 \r
22360       function Point(x, y, round) {\r
22361         // @property x: Number; The `x` coordinate of the point\r
22362         this.x = (round ? Math.round(x) : x);\r
22363         // @property y: Number; The `y` coordinate of the point\r
22364         this.y = (round ? Math.round(y) : y);\r
22365       }\r
22366 \r
22367       var trunc = Math.trunc || function (v) {\r
22368         return v > 0 ? Math.floor(v) : Math.ceil(v);\r
22369       };\r
22370 \r
22371       Point.prototype = {\r
22372 \r
22373         // @method clone(): Point\r
22374         // Returns a copy of the current point.\r
22375         clone: function () {\r
22376                 return new Point(this.x, this.y);\r
22377         },\r
22378 \r
22379         // @method add(otherPoint: Point): Point\r
22380         // Returns the result of addition of the current and the given points.\r
22381         add: function (point) {\r
22382                 // non-destructive, returns a new point\r
22383                 return this.clone()._add(toPoint(point));\r
22384         },\r
22385 \r
22386         _add: function (point) {\r
22387                 // destructive, used directly for performance in situations where it's safe to modify existing point\r
22388                 this.x += point.x;\r
22389                 this.y += point.y;\r
22390                 return this;\r
22391         },\r
22392 \r
22393         // @method subtract(otherPoint: Point): Point\r
22394         // Returns the result of subtraction of the given point from the current.\r
22395         subtract: function (point) {\r
22396                 return this.clone()._subtract(toPoint(point));\r
22397         },\r
22398 \r
22399         _subtract: function (point) {\r
22400                 this.x -= point.x;\r
22401                 this.y -= point.y;\r
22402                 return this;\r
22403         },\r
22404 \r
22405         // @method divideBy(num: Number): Point\r
22406         // Returns the result of division of the current point by the given number.\r
22407         divideBy: function (num) {\r
22408                 return this.clone()._divideBy(num);\r
22409         },\r
22410 \r
22411         _divideBy: function (num) {\r
22412                 this.x /= num;\r
22413                 this.y /= num;\r
22414                 return this;\r
22415         },\r
22416 \r
22417         // @method multiplyBy(num: Number): Point\r
22418         // Returns the result of multiplication of the current point by the given number.\r
22419         multiplyBy: function (num) {\r
22420                 return this.clone()._multiplyBy(num);\r
22421         },\r
22422 \r
22423         _multiplyBy: function (num) {\r
22424                 this.x *= num;\r
22425                 this.y *= num;\r
22426                 return this;\r
22427         },\r
22428 \r
22429         // @method scaleBy(scale: Point): Point\r
22430         // Multiply each coordinate of the current point by each coordinate of\r
22431         // `scale`. In linear algebra terms, multiply the point by the\r
22432         // [scaling matrix](https://en.wikipedia.org/wiki/Scaling_%28geometry%29#Matrix_representation)\r
22433         // defined by `scale`.\r
22434         scaleBy: function (point) {\r
22435                 return new Point(this.x * point.x, this.y * point.y);\r
22436         },\r
22437 \r
22438         // @method unscaleBy(scale: Point): Point\r
22439         // Inverse of `scaleBy`. Divide each coordinate of the current point by\r
22440         // each coordinate of `scale`.\r
22441         unscaleBy: function (point) {\r
22442                 return new Point(this.x / point.x, this.y / point.y);\r
22443         },\r
22444 \r
22445         // @method round(): Point\r
22446         // Returns a copy of the current point with rounded coordinates.\r
22447         round: function () {\r
22448                 return this.clone()._round();\r
22449         },\r
22450 \r
22451         _round: function () {\r
22452                 this.x = Math.round(this.x);\r
22453                 this.y = Math.round(this.y);\r
22454                 return this;\r
22455         },\r
22456 \r
22457         // @method floor(): Point\r
22458         // Returns a copy of the current point with floored coordinates (rounded down).\r
22459         floor: function () {\r
22460                 return this.clone()._floor();\r
22461         },\r
22462 \r
22463         _floor: function () {\r
22464                 this.x = Math.floor(this.x);\r
22465                 this.y = Math.floor(this.y);\r
22466                 return this;\r
22467         },\r
22468 \r
22469         // @method ceil(): Point\r
22470         // Returns a copy of the current point with ceiled coordinates (rounded up).\r
22471         ceil: function () {\r
22472                 return this.clone()._ceil();\r
22473         },\r
22474 \r
22475         _ceil: function () {\r
22476                 this.x = Math.ceil(this.x);\r
22477                 this.y = Math.ceil(this.y);\r
22478                 return this;\r
22479         },\r
22480 \r
22481         // @method trunc(): Point\r
22482         // Returns a copy of the current point with truncated coordinates (rounded towards zero).\r
22483         trunc: function () {\r
22484                 return this.clone()._trunc();\r
22485         },\r
22486 \r
22487         _trunc: function () {\r
22488                 this.x = trunc(this.x);\r
22489                 this.y = trunc(this.y);\r
22490                 return this;\r
22491         },\r
22492 \r
22493         // @method distanceTo(otherPoint: Point): Number\r
22494         // Returns the cartesian distance between the current and the given points.\r
22495         distanceTo: function (point) {\r
22496                 point = toPoint(point);\r
22497 \r
22498                 var x = point.x - this.x,\r
22499                     y = point.y - this.y;\r
22500 \r
22501                 return Math.sqrt(x * x + y * y);\r
22502         },\r
22503 \r
22504         // @method equals(otherPoint: Point): Boolean\r
22505         // Returns `true` if the given point has the same coordinates.\r
22506         equals: function (point) {\r
22507                 point = toPoint(point);\r
22508 \r
22509                 return point.x === this.x &&\r
22510                        point.y === this.y;\r
22511         },\r
22512 \r
22513         // @method contains(otherPoint: Point): Boolean\r
22514         // Returns `true` if both coordinates of the given point are less than the corresponding current point coordinates (in absolute values).\r
22515         contains: function (point) {\r
22516                 point = toPoint(point);\r
22517 \r
22518                 return Math.abs(point.x) <= Math.abs(this.x) &&\r
22519                        Math.abs(point.y) <= Math.abs(this.y);\r
22520         },\r
22521 \r
22522         // @method toString(): String\r
22523         // Returns a string representation of the point for debugging purposes.\r
22524         toString: function () {\r
22525                 return 'Point(' +\r
22526                         formatNum(this.x) + ', ' +\r
22527                         formatNum(this.y) + ')';\r
22528         }\r
22529       };\r
22530 \r
22531       // @factory L.point(x: Number, y: Number, round?: Boolean)\r
22532       // Creates a Point object with the given `x` and `y` coordinates. If optional `round` is set to true, rounds the `x` and `y` values.\r
22533 \r
22534       // @alternative\r
22535       // @factory L.point(coords: Number[])\r
22536       // Expects an array of the form `[x, y]` instead.\r
22537 \r
22538       // @alternative\r
22539       // @factory L.point(coords: Object)\r
22540       // Expects a plain object of the form `{x: Number, y: Number}` instead.\r
22541       function toPoint(x, y, round) {\r
22542         if (x instanceof Point) {\r
22543                 return x;\r
22544         }\r
22545         if (isArray(x)) {\r
22546                 return new Point(x[0], x[1]);\r
22547         }\r
22548         if (x === undefined || x === null) {\r
22549                 return x;\r
22550         }\r
22551         if (typeof x === 'object' && 'x' in x && 'y' in x) {\r
22552                 return new Point(x.x, x.y);\r
22553         }\r
22554         return new Point(x, y, round);\r
22555       }
22556
22557       /*\r
22558        * @class Bounds\r
22559        * @aka L.Bounds\r
22560        *\r
22561        * Represents a rectangular area in pixel coordinates.\r
22562        *\r
22563        * @example\r
22564        *\r
22565        * ```js\r
22566        * var p1 = L.point(10, 10),\r
22567        * p2 = L.point(40, 60),\r
22568        * bounds = L.bounds(p1, p2);\r
22569        * ```\r
22570        *\r
22571        * All Leaflet methods that accept `Bounds` objects also accept them in a simple Array form (unless noted otherwise), so the bounds example above can be passed like this:\r
22572        *\r
22573        * ```js\r
22574        * otherBounds.intersects([[10, 10], [40, 60]]);\r
22575        * ```\r
22576        *\r
22577        * Note that `Bounds` does not inherit from Leaflet's `Class` object,\r
22578        * which means new classes can't inherit from it, and new methods\r
22579        * can't be added to it with the `include` function.\r
22580        */\r
22581 \r
22582       function Bounds(a, b) {\r
22583         if (!a) { return; }\r
22584 \r
22585         var points = b ? [a, b] : a;\r
22586 \r
22587         for (var i = 0, len = points.length; i < len; i++) {\r
22588                 this.extend(points[i]);\r
22589         }\r
22590       }\r
22591 \r
22592       Bounds.prototype = {\r
22593         // @method extend(point: Point): this\r
22594         // Extends the bounds to contain the given point.\r
22595         extend: function (point) { // (Point)\r
22596                 point = toPoint(point);\r
22597 \r
22598                 // @property min: Point\r
22599                 // The top left corner of the rectangle.\r
22600                 // @property max: Point\r
22601                 // The bottom right corner of the rectangle.\r
22602                 if (!this.min && !this.max) {\r
22603                         this.min = point.clone();\r
22604                         this.max = point.clone();\r
22605                 } else {\r
22606                         this.min.x = Math.min(point.x, this.min.x);\r
22607                         this.max.x = Math.max(point.x, this.max.x);\r
22608                         this.min.y = Math.min(point.y, this.min.y);\r
22609                         this.max.y = Math.max(point.y, this.max.y);\r
22610                 }\r
22611                 return this;\r
22612         },\r
22613 \r
22614         // @method getCenter(round?: Boolean): Point\r
22615         // Returns the center point of the bounds.\r
22616         getCenter: function (round) {\r
22617                 return new Point(\r
22618                         (this.min.x + this.max.x) / 2,\r
22619                         (this.min.y + this.max.y) / 2, round);\r
22620         },\r
22621 \r
22622         // @method getBottomLeft(): Point\r
22623         // Returns the bottom-left point of the bounds.\r
22624         getBottomLeft: function () {\r
22625                 return new Point(this.min.x, this.max.y);\r
22626         },\r
22627 \r
22628         // @method getTopRight(): Point\r
22629         // Returns the top-right point of the bounds.\r
22630         getTopRight: function () { // -> Point\r
22631                 return new Point(this.max.x, this.min.y);\r
22632         },\r
22633 \r
22634         // @method getTopLeft(): Point\r
22635         // Returns the top-left point of the bounds (i.e. [`this.min`](#bounds-min)).\r
22636         getTopLeft: function () {\r
22637                 return this.min; // left, top\r
22638         },\r
22639 \r
22640         // @method getBottomRight(): Point\r
22641         // Returns the bottom-right point of the bounds (i.e. [`this.max`](#bounds-max)).\r
22642         getBottomRight: function () {\r
22643                 return this.max; // right, bottom\r
22644         },\r
22645 \r
22646         // @method getSize(): Point\r
22647         // Returns the size of the given bounds\r
22648         getSize: function () {\r
22649                 return this.max.subtract(this.min);\r
22650         },\r
22651 \r
22652         // @method contains(otherBounds: Bounds): Boolean\r
22653         // Returns `true` if the rectangle contains the given one.\r
22654         // @alternative\r
22655         // @method contains(point: Point): Boolean\r
22656         // Returns `true` if the rectangle contains the given point.\r
22657         contains: function (obj) {\r
22658                 var min, max;\r
22659 \r
22660                 if (typeof obj[0] === 'number' || obj instanceof Point) {\r
22661                         obj = toPoint(obj);\r
22662                 } else {\r
22663                         obj = toBounds(obj);\r
22664                 }\r
22665 \r
22666                 if (obj instanceof Bounds) {\r
22667                         min = obj.min;\r
22668                         max = obj.max;\r
22669                 } else {\r
22670                         min = max = obj;\r
22671                 }\r
22672 \r
22673                 return (min.x >= this.min.x) &&\r
22674                        (max.x <= this.max.x) &&\r
22675                        (min.y >= this.min.y) &&\r
22676                        (max.y <= this.max.y);\r
22677         },\r
22678 \r
22679         // @method intersects(otherBounds: Bounds): Boolean\r
22680         // Returns `true` if the rectangle intersects the given bounds. Two bounds\r
22681         // intersect if they have at least one point in common.\r
22682         intersects: function (bounds) { // (Bounds) -> Boolean\r
22683                 bounds = toBounds(bounds);\r
22684 \r
22685                 var min = this.min,\r
22686                     max = this.max,\r
22687                     min2 = bounds.min,\r
22688                     max2 = bounds.max,\r
22689                     xIntersects = (max2.x >= min.x) && (min2.x <= max.x),\r
22690                     yIntersects = (max2.y >= min.y) && (min2.y <= max.y);\r
22691 \r
22692                 return xIntersects && yIntersects;\r
22693         },\r
22694 \r
22695         // @method overlaps(otherBounds: Bounds): Boolean\r
22696         // Returns `true` if the rectangle overlaps the given bounds. Two bounds\r
22697         // overlap if their intersection is an area.\r
22698         overlaps: function (bounds) { // (Bounds) -> Boolean\r
22699                 bounds = toBounds(bounds);\r
22700 \r
22701                 var min = this.min,\r
22702                     max = this.max,\r
22703                     min2 = bounds.min,\r
22704                     max2 = bounds.max,\r
22705                     xOverlaps = (max2.x > min.x) && (min2.x < max.x),\r
22706                     yOverlaps = (max2.y > min.y) && (min2.y < max.y);\r
22707 \r
22708                 return xOverlaps && yOverlaps;\r
22709         },\r
22710 \r
22711         isValid: function () {\r
22712                 return !!(this.min && this.max);\r
22713         }\r
22714       };\r
22715 \r
22716 \r
22717       // @factory L.bounds(corner1: Point, corner2: Point)\r
22718       // Creates a Bounds object from two corners coordinate pairs.\r
22719       // @alternative\r
22720       // @factory L.bounds(points: Point[])\r
22721       // Creates a Bounds object from the given array of points.\r
22722       function toBounds(a, b) {\r
22723         if (!a || a instanceof Bounds) {\r
22724                 return a;\r
22725         }\r
22726         return new Bounds(a, b);\r
22727       }
22728
22729       /*\r
22730        * @class LatLngBounds\r
22731        * @aka L.LatLngBounds\r
22732        *\r
22733        * Represents a rectangular geographical area on a map.\r
22734        *\r
22735        * @example\r
22736        *\r
22737        * ```js\r
22738        * var corner1 = L.latLng(40.712, -74.227),\r
22739        * corner2 = L.latLng(40.774, -74.125),\r
22740        * bounds = L.latLngBounds(corner1, corner2);\r
22741        * ```\r
22742        *\r
22743        * All Leaflet methods that accept LatLngBounds objects also accept them in a simple Array form (unless noted otherwise), so the bounds example above can be passed like this:\r
22744        *\r
22745        * ```js\r
22746        * map.fitBounds([\r
22747        *        [40.712, -74.227],\r
22748        *        [40.774, -74.125]\r
22749        * ]);\r
22750        * ```\r
22751        *\r
22752        * Caution: if the area crosses the antimeridian (often confused with the International Date Line), you must specify corners _outside_ the [-180, 180] degrees longitude range.\r
22753        *\r
22754        * Note that `LatLngBounds` does not inherit from Leaflet's `Class` object,\r
22755        * which means new classes can't inherit from it, and new methods\r
22756        * can't be added to it with the `include` function.\r
22757        */\r
22758 \r
22759       function LatLngBounds(corner1, corner2) { // (LatLng, LatLng) or (LatLng[])\r
22760         if (!corner1) { return; }\r
22761 \r
22762         var latlngs = corner2 ? [corner1, corner2] : corner1;\r
22763 \r
22764         for (var i = 0, len = latlngs.length; i < len; i++) {\r
22765                 this.extend(latlngs[i]);\r
22766         }\r
22767       }\r
22768 \r
22769       LatLngBounds.prototype = {\r
22770 \r
22771         // @method extend(latlng: LatLng): this\r
22772         // Extend the bounds to contain the given point\r
22773 \r
22774         // @alternative\r
22775         // @method extend(otherBounds: LatLngBounds): this\r
22776         // Extend the bounds to contain the given bounds\r
22777         extend: function (obj) {\r
22778                 var sw = this._southWest,\r
22779                     ne = this._northEast,\r
22780                     sw2, ne2;\r
22781 \r
22782                 if (obj instanceof LatLng) {\r
22783                         sw2 = obj;\r
22784                         ne2 = obj;\r
22785 \r
22786                 } else if (obj instanceof LatLngBounds) {\r
22787                         sw2 = obj._southWest;\r
22788                         ne2 = obj._northEast;\r
22789 \r
22790                         if (!sw2 || !ne2) { return this; }\r
22791 \r
22792                 } else {\r
22793                         return obj ? this.extend(toLatLng(obj) || toLatLngBounds(obj)) : this;\r
22794                 }\r
22795 \r
22796                 if (!sw && !ne) {\r
22797                         this._southWest = new LatLng(sw2.lat, sw2.lng);\r
22798                         this._northEast = new LatLng(ne2.lat, ne2.lng);\r
22799                 } else {\r
22800                         sw.lat = Math.min(sw2.lat, sw.lat);\r
22801                         sw.lng = Math.min(sw2.lng, sw.lng);\r
22802                         ne.lat = Math.max(ne2.lat, ne.lat);\r
22803                         ne.lng = Math.max(ne2.lng, ne.lng);\r
22804                 }\r
22805 \r
22806                 return this;\r
22807         },\r
22808 \r
22809         // @method pad(bufferRatio: Number): LatLngBounds\r
22810         // Returns bounds created by extending or retracting the current bounds by a given ratio in each direction.\r
22811         // For example, a ratio of 0.5 extends the bounds by 50% in each direction.\r
22812         // Negative values will retract the bounds.\r
22813         pad: function (bufferRatio) {\r
22814                 var sw = this._southWest,\r
22815                     ne = this._northEast,\r
22816                     heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio,\r
22817                     widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio;\r
22818 \r
22819                 return new LatLngBounds(\r
22820                         new LatLng(sw.lat - heightBuffer, sw.lng - widthBuffer),\r
22821                         new LatLng(ne.lat + heightBuffer, ne.lng + widthBuffer));\r
22822         },\r
22823 \r
22824         // @method getCenter(): LatLng\r
22825         // Returns the center point of the bounds.\r
22826         getCenter: function () {\r
22827                 return new LatLng(\r
22828                         (this._southWest.lat + this._northEast.lat) / 2,\r
22829                         (this._southWest.lng + this._northEast.lng) / 2);\r
22830         },\r
22831 \r
22832         // @method getSouthWest(): LatLng\r
22833         // Returns the south-west point of the bounds.\r
22834         getSouthWest: function () {\r
22835                 return this._southWest;\r
22836         },\r
22837 \r
22838         // @method getNorthEast(): LatLng\r
22839         // Returns the north-east point of the bounds.\r
22840         getNorthEast: function () {\r
22841                 return this._northEast;\r
22842         },\r
22843 \r
22844         // @method getNorthWest(): LatLng\r
22845         // Returns the north-west point of the bounds.\r
22846         getNorthWest: function () {\r
22847                 return new LatLng(this.getNorth(), this.getWest());\r
22848         },\r
22849 \r
22850         // @method getSouthEast(): LatLng\r
22851         // Returns the south-east point of the bounds.\r
22852         getSouthEast: function () {\r
22853                 return new LatLng(this.getSouth(), this.getEast());\r
22854         },\r
22855 \r
22856         // @method getWest(): Number\r
22857         // Returns the west longitude of the bounds\r
22858         getWest: function () {\r
22859                 return this._southWest.lng;\r
22860         },\r
22861 \r
22862         // @method getSouth(): Number\r
22863         // Returns the south latitude of the bounds\r
22864         getSouth: function () {\r
22865                 return this._southWest.lat;\r
22866         },\r
22867 \r
22868         // @method getEast(): Number\r
22869         // Returns the east longitude of the bounds\r
22870         getEast: function () {\r
22871                 return this._northEast.lng;\r
22872         },\r
22873 \r
22874         // @method getNorth(): Number\r
22875         // Returns the north latitude of the bounds\r
22876         getNorth: function () {\r
22877                 return this._northEast.lat;\r
22878         },\r
22879 \r
22880         // @method contains(otherBounds: LatLngBounds): Boolean\r
22881         // Returns `true` if the rectangle contains the given one.\r
22882 \r
22883         // @alternative\r
22884         // @method contains (latlng: LatLng): Boolean\r
22885         // Returns `true` if the rectangle contains the given point.\r
22886         contains: function (obj) { // (LatLngBounds) or (LatLng) -> Boolean\r
22887                 if (typeof obj[0] === 'number' || obj instanceof LatLng || 'lat' in obj) {\r
22888                         obj = toLatLng(obj);\r
22889                 } else {\r
22890                         obj = toLatLngBounds(obj);\r
22891                 }\r
22892 \r
22893                 var sw = this._southWest,\r
22894                     ne = this._northEast,\r
22895                     sw2, ne2;\r
22896 \r
22897                 if (obj instanceof LatLngBounds) {\r
22898                         sw2 = obj.getSouthWest();\r
22899                         ne2 = obj.getNorthEast();\r
22900                 } else {\r
22901                         sw2 = ne2 = obj;\r
22902                 }\r
22903 \r
22904                 return (sw2.lat >= sw.lat) && (ne2.lat <= ne.lat) &&\r
22905                        (sw2.lng >= sw.lng) && (ne2.lng <= ne.lng);\r
22906         },\r
22907 \r
22908         // @method intersects(otherBounds: LatLngBounds): Boolean\r
22909         // Returns `true` if the rectangle intersects the given bounds. Two bounds intersect if they have at least one point in common.\r
22910         intersects: function (bounds) {\r
22911                 bounds = toLatLngBounds(bounds);\r
22912 \r
22913                 var sw = this._southWest,\r
22914                     ne = this._northEast,\r
22915                     sw2 = bounds.getSouthWest(),\r
22916                     ne2 = bounds.getNorthEast(),\r
22917 \r
22918                     latIntersects = (ne2.lat >= sw.lat) && (sw2.lat <= ne.lat),\r
22919                     lngIntersects = (ne2.lng >= sw.lng) && (sw2.lng <= ne.lng);\r
22920 \r
22921                 return latIntersects && lngIntersects;\r
22922         },\r
22923 \r
22924         // @method overlaps(otherBounds: LatLngBounds): Boolean\r
22925         // Returns `true` if the rectangle overlaps the given bounds. Two bounds overlap if their intersection is an area.\r
22926         overlaps: function (bounds) {\r
22927                 bounds = toLatLngBounds(bounds);\r
22928 \r
22929                 var sw = this._southWest,\r
22930                     ne = this._northEast,\r
22931                     sw2 = bounds.getSouthWest(),\r
22932                     ne2 = bounds.getNorthEast(),\r
22933 \r
22934                     latOverlaps = (ne2.lat > sw.lat) && (sw2.lat < ne.lat),\r
22935                     lngOverlaps = (ne2.lng > sw.lng) && (sw2.lng < ne.lng);\r
22936 \r
22937                 return latOverlaps && lngOverlaps;\r
22938         },\r
22939 \r
22940         // @method toBBoxString(): String\r
22941         // Returns a string with bounding box coordinates in a 'southwest_lng,southwest_lat,northeast_lng,northeast_lat' format. Useful for sending requests to web services that return geo data.\r
22942         toBBoxString: function () {\r
22943                 return [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()].join(',');\r
22944         },\r
22945 \r
22946         // @method equals(otherBounds: LatLngBounds, maxMargin?: Number): Boolean\r
22947         // Returns `true` if the rectangle is equivalent (within a small margin of error) to the given bounds. The margin of error can be overridden by setting `maxMargin` to a small number.\r
22948         equals: function (bounds, maxMargin) {\r
22949                 if (!bounds) { return false; }\r
22950 \r
22951                 bounds = toLatLngBounds(bounds);\r
22952 \r
22953                 return this._southWest.equals(bounds.getSouthWest(), maxMargin) &&\r
22954                        this._northEast.equals(bounds.getNorthEast(), maxMargin);\r
22955         },\r
22956 \r
22957         // @method isValid(): Boolean\r
22958         // Returns `true` if the bounds are properly initialized.\r
22959         isValid: function () {\r
22960                 return !!(this._southWest && this._northEast);\r
22961         }\r
22962       };\r
22963 \r
22964       // TODO International date line?\r
22965 \r
22966       // @factory L.latLngBounds(corner1: LatLng, corner2: LatLng)\r
22967       // Creates a `LatLngBounds` object by defining two diagonally opposite corners of the rectangle.\r
22968 \r
22969       // @alternative\r
22970       // @factory L.latLngBounds(latlngs: LatLng[])\r
22971       // Creates a `LatLngBounds` object defined by the geographical points it contains. Very useful for zooming the map to fit a particular set of locations with [`fitBounds`](#map-fitbounds).\r
22972       function toLatLngBounds(a, b) {\r
22973         if (a instanceof LatLngBounds) {\r
22974                 return a;\r
22975         }\r
22976         return new LatLngBounds(a, b);\r
22977       }
22978
22979       /* @class LatLng\r
22980        * @aka L.LatLng\r
22981        *\r
22982        * Represents a geographical point with a certain latitude and longitude.\r
22983        *\r
22984        * @example\r
22985        *\r
22986        * ```\r
22987        * var latlng = L.latLng(50.5, 30.5);\r
22988        * ```\r
22989        *\r
22990        * All Leaflet methods that accept LatLng objects also accept them in a simple Array form and simple object form (unless noted otherwise), so these lines are equivalent:\r
22991        *\r
22992        * ```\r
22993        * map.panTo([50, 30]);\r
22994        * map.panTo({lon: 30, lat: 50});\r
22995        * map.panTo({lat: 50, lng: 30});\r
22996        * map.panTo(L.latLng(50, 30));\r
22997        * ```\r
22998        *\r
22999        * Note that `LatLng` does not inherit from Leaflet's `Class` object,\r
23000        * which means new classes can't inherit from it, and new methods\r
23001        * can't be added to it with the `include` function.\r
23002        */\r
23003 \r
23004       function LatLng(lat, lng, alt) {\r
23005         if (isNaN(lat) || isNaN(lng)) {\r
23006                 throw new Error('Invalid LatLng object: (' + lat + ', ' + lng + ')');\r
23007         }\r
23008 \r
23009         // @property lat: Number\r
23010         // Latitude in degrees\r
23011         this.lat = +lat;\r
23012 \r
23013         // @property lng: Number\r
23014         // Longitude in degrees\r
23015         this.lng = +lng;\r
23016 \r
23017         // @property alt: Number\r
23018         // Altitude in meters (optional)\r
23019         if (alt !== undefined) {\r
23020                 this.alt = +alt;\r
23021         }\r
23022       }\r
23023 \r
23024       LatLng.prototype = {\r
23025         // @method equals(otherLatLng: LatLng, maxMargin?: Number): Boolean\r
23026         // Returns `true` if the given `LatLng` point is at the same position (within a small margin of error). The margin of error can be overridden by setting `maxMargin` to a small number.\r
23027         equals: function (obj, maxMargin) {\r
23028                 if (!obj) { return false; }\r
23029 \r
23030                 obj = toLatLng(obj);\r
23031 \r
23032                 var margin = Math.max(\r
23033                         Math.abs(this.lat - obj.lat),\r
23034                         Math.abs(this.lng - obj.lng));\r
23035 \r
23036                 return margin <= (maxMargin === undefined ? 1.0E-9 : maxMargin);\r
23037         },\r
23038 \r
23039         // @method toString(): String\r
23040         // Returns a string representation of the point (for debugging purposes).\r
23041         toString: function (precision) {\r
23042                 return 'LatLng(' +\r
23043                         formatNum(this.lat, precision) + ', ' +\r
23044                         formatNum(this.lng, precision) + ')';\r
23045         },\r
23046 \r
23047         // @method distanceTo(otherLatLng: LatLng): Number\r
23048         // Returns the distance (in meters) to the given `LatLng` calculated using the [Spherical Law of Cosines](https://en.wikipedia.org/wiki/Spherical_law_of_cosines).\r
23049         distanceTo: function (other) {\r
23050                 return Earth.distance(this, toLatLng(other));\r
23051         },\r
23052 \r
23053         // @method wrap(): LatLng\r
23054         // Returns a new `LatLng` object with the longitude wrapped so it's always between -180 and +180 degrees.\r
23055         wrap: function () {\r
23056                 return Earth.wrapLatLng(this);\r
23057         },\r
23058 \r
23059         // @method toBounds(sizeInMeters: Number): LatLngBounds\r
23060         // Returns a new `LatLngBounds` object in which each boundary is `sizeInMeters/2` meters apart from the `LatLng`.\r
23061         toBounds: function (sizeInMeters) {\r
23062                 var latAccuracy = 180 * sizeInMeters / 40075017,\r
23063                     lngAccuracy = latAccuracy / Math.cos((Math.PI / 180) * this.lat);\r
23064 \r
23065                 return toLatLngBounds(\r
23066                         [this.lat - latAccuracy, this.lng - lngAccuracy],\r
23067                         [this.lat + latAccuracy, this.lng + lngAccuracy]);\r
23068         },\r
23069 \r
23070         clone: function () {\r
23071                 return new LatLng(this.lat, this.lng, this.alt);\r
23072         }\r
23073       };\r
23074 \r
23075 \r
23076 \r
23077       // @factory L.latLng(latitude: Number, longitude: Number, altitude?: Number): LatLng\r
23078       // Creates an object representing a geographical point with the given latitude and longitude (and optionally altitude).\r
23079 \r
23080       // @alternative\r
23081       // @factory L.latLng(coords: Array): LatLng\r
23082       // Expects an array of the form `[Number, Number]` or `[Number, Number, Number]` instead.\r
23083 \r
23084       // @alternative\r
23085       // @factory L.latLng(coords: Object): LatLng\r
23086       // Expects an plain object of the form `{lat: Number, lng: Number}` or `{lat: Number, lng: Number, alt: Number}` instead.\r
23087 \r
23088       function toLatLng(a, b, c) {\r
23089         if (a instanceof LatLng) {\r
23090                 return a;\r
23091         }\r
23092         if (isArray(a) && typeof a[0] !== 'object') {\r
23093                 if (a.length === 3) {\r
23094                         return new LatLng(a[0], a[1], a[2]);\r
23095                 }\r
23096                 if (a.length === 2) {\r
23097                         return new LatLng(a[0], a[1]);\r
23098                 }\r
23099                 return null;\r
23100         }\r
23101         if (a === undefined || a === null) {\r
23102                 return a;\r
23103         }\r
23104         if (typeof a === 'object' && 'lat' in a) {\r
23105                 return new LatLng(a.lat, 'lng' in a ? a.lng : a.lon, a.alt);\r
23106         }\r
23107         if (b === undefined) {\r
23108                 return null;\r
23109         }\r
23110         return new LatLng(a, b, c);\r
23111       }
23112
23113       /*\r
23114        * @namespace CRS\r
23115        * @crs L.CRS.Base\r
23116        * Object that defines coordinate reference systems for projecting\r
23117        * geographical points into pixel (screen) coordinates and back (and to\r
23118        * coordinates in other units for [WMS](https://en.wikipedia.org/wiki/Web_Map_Service) services). See\r
23119        * [spatial reference system](http://en.wikipedia.org/wiki/Coordinate_reference_system).\r
23120        *\r
23121        * Leaflet defines the most usual CRSs by default. If you want to use a\r
23122        * CRS not defined by default, take a look at the\r
23123        * [Proj4Leaflet](https://github.com/kartena/Proj4Leaflet) plugin.\r
23124        *\r
23125        * Note that the CRS instances do not inherit from Leaflet's `Class` object,\r
23126        * and can't be instantiated. Also, new classes can't inherit from them,\r
23127        * and methods can't be added to them with the `include` function.\r
23128        */\r
23129 \r
23130       var CRS = {\r
23131         // @method latLngToPoint(latlng: LatLng, zoom: Number): Point\r
23132         // Projects geographical coordinates into pixel coordinates for a given zoom.\r
23133         latLngToPoint: function (latlng, zoom) {\r
23134                 var projectedPoint = this.projection.project(latlng),\r
23135                     scale = this.scale(zoom);\r
23136 \r
23137                 return this.transformation._transform(projectedPoint, scale);\r
23138         },\r
23139 \r
23140         // @method pointToLatLng(point: Point, zoom: Number): LatLng\r
23141         // The inverse of `latLngToPoint`. Projects pixel coordinates on a given\r
23142         // zoom into geographical coordinates.\r
23143         pointToLatLng: function (point, zoom) {\r
23144                 var scale = this.scale(zoom),\r
23145                     untransformedPoint = this.transformation.untransform(point, scale);\r
23146 \r
23147                 return this.projection.unproject(untransformedPoint);\r
23148         },\r
23149 \r
23150         // @method project(latlng: LatLng): Point\r
23151         // Projects geographical coordinates into coordinates in units accepted for\r
23152         // this CRS (e.g. meters for EPSG:3857, for passing it to WMS services).\r
23153         project: function (latlng) {\r
23154                 return this.projection.project(latlng);\r
23155         },\r
23156 \r
23157         // @method unproject(point: Point): LatLng\r
23158         // Given a projected coordinate returns the corresponding LatLng.\r
23159         // The inverse of `project`.\r
23160         unproject: function (point) {\r
23161                 return this.projection.unproject(point);\r
23162         },\r
23163 \r
23164         // @method scale(zoom: Number): Number\r
23165         // Returns the scale used when transforming projected coordinates into\r
23166         // pixel coordinates for a particular zoom. For example, it returns\r
23167         // `256 * 2^zoom` for Mercator-based CRS.\r
23168         scale: function (zoom) {\r
23169                 return 256 * Math.pow(2, zoom);\r
23170         },\r
23171 \r
23172         // @method zoom(scale: Number): Number\r
23173         // Inverse of `scale()`, returns the zoom level corresponding to a scale\r
23174         // factor of `scale`.\r
23175         zoom: function (scale) {\r
23176                 return Math.log(scale / 256) / Math.LN2;\r
23177         },\r
23178 \r
23179         // @method getProjectedBounds(zoom: Number): Bounds\r
23180         // Returns the projection's bounds scaled and transformed for the provided `zoom`.\r
23181         getProjectedBounds: function (zoom) {\r
23182                 if (this.infinite) { return null; }\r
23183 \r
23184                 var b = this.projection.bounds,\r
23185                     s = this.scale(zoom),\r
23186                     min = this.transformation.transform(b.min, s),\r
23187                     max = this.transformation.transform(b.max, s);\r
23188 \r
23189                 return new Bounds(min, max);\r
23190         },\r
23191 \r
23192         // @method distance(latlng1: LatLng, latlng2: LatLng): Number\r
23193         // Returns the distance between two geographical coordinates.\r
23194 \r
23195         // @property code: String\r
23196         // Standard code name of the CRS passed into WMS services (e.g. `'EPSG:3857'`)\r
23197         //\r
23198         // @property wrapLng: Number[]\r
23199         // An array of two numbers defining whether the longitude (horizontal) coordinate\r
23200         // axis wraps around a given range and how. Defaults to `[-180, 180]` in most\r
23201         // geographical CRSs. If `undefined`, the longitude axis does not wrap around.\r
23202         //\r
23203         // @property wrapLat: Number[]\r
23204         // Like `wrapLng`, but for the latitude (vertical) axis.\r
23205 \r
23206         // wrapLng: [min, max],\r
23207         // wrapLat: [min, max],\r
23208 \r
23209         // @property infinite: Boolean\r
23210         // If true, the coordinate space will be unbounded (infinite in both axes)\r
23211         infinite: false,\r
23212 \r
23213         // @method wrapLatLng(latlng: LatLng): LatLng\r
23214         // Returns a `LatLng` where lat and lng has been wrapped according to the\r
23215         // CRS's `wrapLat` and `wrapLng` properties, if they are outside the CRS's bounds.\r
23216         wrapLatLng: function (latlng) {\r
23217                 var lng = this.wrapLng ? wrapNum(latlng.lng, this.wrapLng, true) : latlng.lng,\r
23218                     lat = this.wrapLat ? wrapNum(latlng.lat, this.wrapLat, true) : latlng.lat,\r
23219                     alt = latlng.alt;\r
23220 \r
23221                 return new LatLng(lat, lng, alt);\r
23222         },\r
23223 \r
23224         // @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds\r
23225         // Returns a `LatLngBounds` with the same size as the given one, ensuring\r
23226         // that its center is within the CRS's bounds.\r
23227         // Only accepts actual `L.LatLngBounds` instances, not arrays.\r
23228         wrapLatLngBounds: function (bounds) {\r
23229                 var center = bounds.getCenter(),\r
23230                     newCenter = this.wrapLatLng(center),\r
23231                     latShift = center.lat - newCenter.lat,\r
23232                     lngShift = center.lng - newCenter.lng;\r
23233 \r
23234                 if (latShift === 0 && lngShift === 0) {\r
23235                         return bounds;\r
23236                 }\r
23237 \r
23238                 var sw = bounds.getSouthWest(),\r
23239                     ne = bounds.getNorthEast(),\r
23240                     newSw = new LatLng(sw.lat - latShift, sw.lng - lngShift),\r
23241                     newNe = new LatLng(ne.lat - latShift, ne.lng - lngShift);\r
23242 \r
23243                 return new LatLngBounds(newSw, newNe);\r
23244         }\r
23245       };
23246
23247       /*
23248        * @namespace CRS
23249        * @crs L.CRS.Earth
23250        *
23251        * Serves as the base for CRS that are global such that they cover the earth.
23252        * Can only be used as the base for other CRS and cannot be used directly,
23253        * since it does not have a `code`, `projection` or `transformation`. `distance()` returns
23254        * meters.
23255        */
23256
23257       var Earth = extend({}, CRS, {
23258         wrapLng: [-180, 180],
23259
23260         // Mean Earth Radius, as recommended for use by
23261         // the International Union of Geodesy and Geophysics,
23262         // see http://rosettacode.org/wiki/Haversine_formula
23263         R: 6371000,
23264
23265         // distance between two geographical points using spherical law of cosines approximation
23266         distance: function (latlng1, latlng2) {
23267                 var rad = Math.PI / 180,
23268                     lat1 = latlng1.lat * rad,
23269                     lat2 = latlng2.lat * rad,
23270                     sinDLat = Math.sin((latlng2.lat - latlng1.lat) * rad / 2),
23271                     sinDLon = Math.sin((latlng2.lng - latlng1.lng) * rad / 2),
23272                     a = sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon,
23273                     c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
23274                 return this.R * c;
23275         }
23276       });
23277
23278       /*\r
23279        * @namespace Projection\r
23280        * @projection L.Projection.SphericalMercator\r
23281        *\r
23282        * Spherical Mercator projection â€” the most common projection for online maps,\r
23283        * used by almost all free and commercial tile providers. Assumes that Earth is\r
23284        * a sphere. Used by the `EPSG:3857` CRS.\r
23285        */\r
23286 \r
23287       var earthRadius = 6378137;\r
23288 \r
23289       var SphericalMercator = {\r
23290 \r
23291         R: earthRadius,\r
23292         MAX_LATITUDE: 85.0511287798,\r
23293 \r
23294         project: function (latlng) {\r
23295                 var d = Math.PI / 180,\r
23296                     max = this.MAX_LATITUDE,\r
23297                     lat = Math.max(Math.min(max, latlng.lat), -max),\r
23298                     sin = Math.sin(lat * d);\r
23299 \r
23300                 return new Point(\r
23301                         this.R * latlng.lng * d,\r
23302                         this.R * Math.log((1 + sin) / (1 - sin)) / 2);\r
23303         },\r
23304 \r
23305         unproject: function (point) {\r
23306                 var d = 180 / Math.PI;\r
23307 \r
23308                 return new LatLng(\r
23309                         (2 * Math.atan(Math.exp(point.y / this.R)) - (Math.PI / 2)) * d,\r
23310                         point.x * d / this.R);\r
23311         },\r
23312 \r
23313         bounds: (function () {\r
23314                 var d = earthRadius * Math.PI;\r
23315                 return new Bounds([-d, -d], [d, d]);\r
23316         })()\r
23317       };
23318
23319       /*\r
23320        * @class Transformation\r
23321        * @aka L.Transformation\r
23322        *\r
23323        * Represents an affine transformation: a set of coefficients `a`, `b`, `c`, `d`\r
23324        * for transforming a point of a form `(x, y)` into `(a*x + b, c*y + d)` and doing\r
23325        * the reverse. Used by Leaflet in its projections code.\r
23326        *\r
23327        * @example\r
23328        *\r
23329        * ```js\r
23330        * var transformation = L.transformation(2, 5, -1, 10),\r
23331        *        p = L.point(1, 2),\r
23332        *        p2 = transformation.transform(p), //  L.point(7, 8)\r
23333        *        p3 = transformation.untransform(p2); //  L.point(1, 2)\r
23334        * ```\r
23335        */\r
23336 \r
23337 \r
23338       // factory new L.Transformation(a: Number, b: Number, c: Number, d: Number)\r
23339       // Creates a `Transformation` object with the given coefficients.\r
23340       function Transformation(a, b, c, d) {\r
23341         if (isArray(a)) {\r
23342                 // use array properties\r
23343                 this._a = a[0];\r
23344                 this._b = a[1];\r
23345                 this._c = a[2];\r
23346                 this._d = a[3];\r
23347                 return;\r
23348         }\r
23349         this._a = a;\r
23350         this._b = b;\r
23351         this._c = c;\r
23352         this._d = d;\r
23353       }\r
23354 \r
23355       Transformation.prototype = {\r
23356         // @method transform(point: Point, scale?: Number): Point\r
23357         // Returns a transformed point, optionally multiplied by the given scale.\r
23358         // Only accepts actual `L.Point` instances, not arrays.\r
23359         transform: function (point, scale) { // (Point, Number) -> Point\r
23360                 return this._transform(point.clone(), scale);\r
23361         },\r
23362 \r
23363         // destructive transform (faster)\r
23364         _transform: function (point, scale) {\r
23365                 scale = scale || 1;\r
23366                 point.x = scale * (this._a * point.x + this._b);\r
23367                 point.y = scale * (this._c * point.y + this._d);\r
23368                 return point;\r
23369         },\r
23370 \r
23371         // @method untransform(point: Point, scale?: Number): Point\r
23372         // Returns the reverse transformation of the given point, optionally divided\r
23373         // by the given scale. Only accepts actual `L.Point` instances, not arrays.\r
23374         untransform: function (point, scale) {\r
23375                 scale = scale || 1;\r
23376                 return new Point(\r
23377                         (point.x / scale - this._b) / this._a,\r
23378                         (point.y / scale - this._d) / this._c);\r
23379         }\r
23380       };\r
23381 \r
23382       // factory L.transformation(a: Number, b: Number, c: Number, d: Number)\r
23383 \r
23384       // @factory L.transformation(a: Number, b: Number, c: Number, d: Number)\r
23385       // Instantiates a Transformation object with the given coefficients.\r
23386 \r
23387       // @alternative\r
23388       // @factory L.transformation(coefficients: Array): Transformation\r
23389       // Expects an coefficients array of the form\r
23390       // `[a: Number, b: Number, c: Number, d: Number]`.\r
23391 \r
23392       function toTransformation(a, b, c, d) {\r
23393         return new Transformation(a, b, c, d);\r
23394       }
23395
23396       /*\r
23397        * @namespace CRS\r
23398        * @crs L.CRS.EPSG3857\r
23399        *\r
23400        * The most common CRS for online maps, used by almost all free and commercial\r
23401        * tile providers. Uses Spherical Mercator projection. Set in by default in\r
23402        * Map's `crs` option.\r
23403        */\r
23404 \r
23405       var EPSG3857 = extend({}, Earth, {\r
23406         code: 'EPSG:3857',\r
23407         projection: SphericalMercator,\r
23408 \r
23409         transformation: (function () {\r
23410                 var scale = 0.5 / (Math.PI * SphericalMercator.R);\r
23411                 return toTransformation(scale, 0.5, -scale, 0.5);\r
23412         }())\r
23413       });\r
23414 \r
23415       var EPSG900913 = extend({}, EPSG3857, {\r
23416         code: 'EPSG:900913'\r
23417       });
23418
23419       // @namespace SVG; @section
23420       // There are several static functions which can be called without instantiating L.SVG:
23421
23422       // @function create(name: String): SVGElement
23423       // Returns a instance of [SVGElement](https://developer.mozilla.org/docs/Web/API/SVGElement),
23424       // corresponding to the class name passed. For example, using 'line' will return
23425       // an instance of [SVGLineElement](https://developer.mozilla.org/docs/Web/API/SVGLineElement).
23426       function svgCreate(name) {
23427         return document.createElementNS('http://www.w3.org/2000/svg', name);
23428       }
23429
23430       // @function pointsToPath(rings: Point[], closed: Boolean): String
23431       // Generates a SVG path string for multiple rings, with each ring turning
23432       // into "M..L..L.." instructions
23433       function pointsToPath(rings, closed) {
23434         var str = '',
23435         i, j, len, len2, points, p;
23436
23437         for (i = 0, len = rings.length; i < len; i++) {
23438                 points = rings[i];
23439
23440                 for (j = 0, len2 = points.length; j < len2; j++) {
23441                         p = points[j];
23442                         str += (j ? 'L' : 'M') + p.x + ' ' + p.y;
23443                 }
23444
23445                 // closes the ring for polygons; "x" is VML syntax
23446                 str += closed ? (svg ? 'z' : 'x') : '';
23447         }
23448
23449         // SVG complains about empty path strings
23450         return str || 'M0 0';
23451       }
23452
23453       /*\r
23454        * @namespace Browser\r
23455        * @aka L.Browser\r
23456        *\r
23457        * A namespace with static properties for browser/feature detection used by Leaflet internally.\r
23458        *\r
23459        * @example\r
23460        *\r
23461        * ```js\r
23462        * if (L.Browser.ielt9) {\r
23463        *   alert('Upgrade your browser, dude!');\r
23464        * }\r
23465        * ```\r
23466        */\r
23467 \r
23468       var style$1 = document.documentElement.style;\r
23469 \r
23470       // @property ie: Boolean; `true` for all Internet Explorer versions (not Edge).\r
23471       var ie = 'ActiveXObject' in window;\r
23472 \r
23473       // @property ielt9: Boolean; `true` for Internet Explorer versions less than 9.\r
23474       var ielt9 = ie && !document.addEventListener;\r
23475 \r
23476       // @property edge: Boolean; `true` for the Edge web browser.\r
23477       var edge = 'msLaunchUri' in navigator && !('documentMode' in document);\r
23478 \r
23479       // @property webkit: Boolean;\r
23480       // `true` for webkit-based browsers like Chrome and Safari (including mobile versions).\r
23481       var webkit = userAgentContains('webkit');\r
23482 \r
23483       // @property android: Boolean\r
23484       // `true` for any browser running on an Android platform.\r
23485       var android = userAgentContains('android');\r
23486 \r
23487       // @property android23: Boolean; `true` for browsers running on Android 2 or Android 3.\r
23488       var android23 = userAgentContains('android 2') || userAgentContains('android 3');\r
23489 \r
23490       /* See https://stackoverflow.com/a/17961266 for details on detecting stock Android */\r
23491       var webkitVer = parseInt(/WebKit\/([0-9]+)|$/.exec(navigator.userAgent)[1], 10); // also matches AppleWebKit\r
23492       // @property androidStock: Boolean; `true` for the Android stock browser (i.e. not Chrome)\r
23493       var androidStock = android && userAgentContains('Google') && webkitVer < 537 && !('AudioNode' in window);\r
23494 \r
23495       // @property opera: Boolean; `true` for the Opera browser\r
23496       var opera = !!window.opera;\r
23497 \r
23498       // @property chrome: Boolean; `true` for the Chrome browser.\r
23499       var chrome = !edge && userAgentContains('chrome');\r
23500 \r
23501       // @property gecko: Boolean; `true` for gecko-based browsers like Firefox.\r
23502       var gecko = userAgentContains('gecko') && !webkit && !opera && !ie;\r
23503 \r
23504       // @property safari: Boolean; `true` for the Safari browser.\r
23505       var safari = !chrome && userAgentContains('safari');\r
23506 \r
23507       var phantom = userAgentContains('phantom');\r
23508 \r
23509       // @property opera12: Boolean\r
23510       // `true` for the Opera browser supporting CSS transforms (version 12 or later).\r
23511       var opera12 = 'OTransition' in style$1;\r
23512 \r
23513       // @property win: Boolean; `true` when the browser is running in a Windows platform\r
23514       var win = navigator.platform.indexOf('Win') === 0;\r
23515 \r
23516       // @property ie3d: Boolean; `true` for all Internet Explorer versions supporting CSS transforms.\r
23517       var ie3d = ie && ('transition' in style$1);\r
23518 \r
23519       // @property webkit3d: Boolean; `true` for webkit-based browsers supporting CSS transforms.\r
23520       var webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()) && !android23;\r
23521 \r
23522       // @property gecko3d: Boolean; `true` for gecko-based browsers supporting CSS transforms.\r
23523       var gecko3d = 'MozPerspective' in style$1;\r
23524 \r
23525       // @property any3d: Boolean\r
23526       // `true` for all browsers supporting CSS transforms.\r
23527       var any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d) && !opera12 && !phantom;\r
23528 \r
23529       // @property mobile: Boolean; `true` for all browsers running in a mobile device.\r
23530       var mobile = typeof orientation !== 'undefined' || userAgentContains('mobile');\r
23531 \r
23532       // @property mobileWebkit: Boolean; `true` for all webkit-based browsers in a mobile device.\r
23533       var mobileWebkit = mobile && webkit;\r
23534 \r
23535       // @property mobileWebkit3d: Boolean\r
23536       // `true` for all webkit-based browsers in a mobile device supporting CSS transforms.\r
23537       var mobileWebkit3d = mobile && webkit3d;\r
23538 \r
23539       // @property msPointer: Boolean\r
23540       // `true` for browsers implementing the Microsoft touch events model (notably IE10).\r
23541       var msPointer = !window.PointerEvent && window.MSPointerEvent;\r
23542 \r
23543       // @property pointer: Boolean\r
23544       // `true` for all browsers supporting [pointer events](https://msdn.microsoft.com/en-us/library/dn433244%28v=vs.85%29.aspx).\r
23545       var pointer = !!(window.PointerEvent || msPointer);\r
23546 \r
23547       // @property touch: Boolean\r
23548       // `true` for all browsers supporting [touch events](https://developer.mozilla.org/docs/Web/API/Touch_events).\r
23549       // This does not necessarily mean that the browser is running in a computer with\r
23550       // a touchscreen, it only means that the browser is capable of understanding\r
23551       // touch events.\r
23552       var touch = !window.L_NO_TOUCH && (pointer || 'ontouchstart' in window ||\r
23553                 (window.DocumentTouch && document instanceof window.DocumentTouch));\r
23554 \r
23555       // @property mobileOpera: Boolean; `true` for the Opera browser in a mobile device.\r
23556       var mobileOpera = mobile && opera;\r
23557 \r
23558       // @property mobileGecko: Boolean\r
23559       // `true` for gecko-based browsers running in a mobile device.\r
23560       var mobileGecko = mobile && gecko;\r
23561 \r
23562       // @property retina: Boolean\r
23563       // `true` for browsers on a high-resolution "retina" screen or on any screen when browser's display zoom is more than 100%.\r
23564       var retina = (window.devicePixelRatio || (window.screen.deviceXDPI / window.screen.logicalXDPI)) > 1;\r
23565 \r
23566       // @property passiveEvents: Boolean\r
23567       // `true` for browsers that support passive events.\r
23568       var passiveEvents = (function () {\r
23569         var supportsPassiveOption = false;\r
23570         try {\r
23571                 var opts = Object.defineProperty({}, 'passive', {\r
23572                         get: function () { // eslint-disable-line getter-return\r
23573                                 supportsPassiveOption = true;\r
23574                         }\r
23575                 });\r
23576                 window.addEventListener('testPassiveEventSupport', falseFn, opts);\r
23577                 window.removeEventListener('testPassiveEventSupport', falseFn, opts);\r
23578         } catch (e) {\r
23579                 // Errors can safely be ignored since this is only a browser support test.\r
23580         }\r
23581         return supportsPassiveOption;\r
23582       }());\r
23583 \r
23584       // @property canvas: Boolean\r
23585       // `true` when the browser supports [`<canvas>`](https://developer.mozilla.org/docs/Web/API/Canvas_API).\r
23586       var canvas = (function () {\r
23587         return !!document.createElement('canvas').getContext;\r
23588       }());\r
23589 \r
23590       // @property svg: Boolean\r
23591       // `true` when the browser supports [SVG](https://developer.mozilla.org/docs/Web/SVG).\r
23592       var svg = !!(document.createElementNS && svgCreate('svg').createSVGRect);\r
23593 \r
23594       // @property vml: Boolean\r
23595       // `true` if the browser supports [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language).\r
23596       var vml = !svg && (function () {\r
23597         try {\r
23598                 var div = document.createElement('div');\r
23599                 div.innerHTML = '<v:shape adj="1"/>';\r
23600 \r
23601                 var shape = div.firstChild;\r
23602                 shape.style.behavior = 'url(#default#VML)';\r
23603 \r
23604                 return shape && (typeof shape.adj === 'object');\r
23605 \r
23606         } catch (e) {\r
23607                 return false;\r
23608         }\r
23609       }());\r
23610 \r
23611 \r
23612       function userAgentContains(str) {\r
23613         return navigator.userAgent.toLowerCase().indexOf(str) >= 0;\r
23614       }
23615
23616       var Browser = ({
23617         ie: ie,
23618         ielt9: ielt9,
23619         edge: edge,
23620         webkit: webkit,
23621         android: android,
23622         android23: android23,
23623         androidStock: androidStock,
23624         opera: opera,
23625         chrome: chrome,
23626         gecko: gecko,
23627         safari: safari,
23628         phantom: phantom,
23629         opera12: opera12,
23630         win: win,
23631         ie3d: ie3d,
23632         webkit3d: webkit3d,
23633         gecko3d: gecko3d,
23634         any3d: any3d,
23635         mobile: mobile,
23636         mobileWebkit: mobileWebkit,
23637         mobileWebkit3d: mobileWebkit3d,
23638         msPointer: msPointer,
23639         pointer: pointer,
23640         touch: touch,
23641         mobileOpera: mobileOpera,
23642         mobileGecko: mobileGecko,
23643         retina: retina,
23644         passiveEvents: passiveEvents,
23645         canvas: canvas,
23646         svg: svg,
23647         vml: vml
23648       });
23649
23650       /*
23651        * Extends L.DomEvent to provide touch support for Internet Explorer and Windows-based devices.
23652        */
23653
23654
23655       var POINTER_DOWN =   msPointer ? 'MSPointerDown'   : 'pointerdown';
23656       var POINTER_MOVE =   msPointer ? 'MSPointerMove'   : 'pointermove';
23657       var POINTER_UP =     msPointer ? 'MSPointerUp'     : 'pointerup';
23658       var POINTER_CANCEL = msPointer ? 'MSPointerCancel' : 'pointercancel';
23659
23660       var _pointers = {};
23661       var _pointerDocListener = false;
23662
23663       // Provides a touch events wrapper for (ms)pointer events.
23664       // ref http://www.w3.org/TR/pointerevents/ https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890
23665
23666       function addPointerListener(obj, type, handler, id) {
23667         if (type === 'touchstart') {
23668                 _addPointerStart(obj, handler, id);
23669
23670         } else if (type === 'touchmove') {
23671                 _addPointerMove(obj, handler, id);
23672
23673         } else if (type === 'touchend') {
23674                 _addPointerEnd(obj, handler, id);
23675         }
23676
23677         return this;
23678       }
23679
23680       function removePointerListener(obj, type, id) {
23681         var handler = obj['_leaflet_' + type + id];
23682
23683         if (type === 'touchstart') {
23684                 obj.removeEventListener(POINTER_DOWN, handler, false);
23685
23686         } else if (type === 'touchmove') {
23687                 obj.removeEventListener(POINTER_MOVE, handler, false);
23688
23689         } else if (type === 'touchend') {
23690                 obj.removeEventListener(POINTER_UP, handler, false);
23691                 obj.removeEventListener(POINTER_CANCEL, handler, false);
23692         }
23693
23694         return this;
23695       }
23696
23697       function _addPointerStart(obj, handler, id) {
23698         var onDown = bind(function (e) {
23699                 // IE10 specific: MsTouch needs preventDefault. See #2000
23700                 if (e.MSPOINTER_TYPE_TOUCH && e.pointerType === e.MSPOINTER_TYPE_TOUCH) {
23701                         preventDefault(e);
23702                 }
23703
23704                 _handlePointer(e, handler);
23705         });
23706
23707         obj['_leaflet_touchstart' + id] = onDown;
23708         obj.addEventListener(POINTER_DOWN, onDown, false);
23709
23710         // need to keep track of what pointers and how many are active to provide e.touches emulation
23711         if (!_pointerDocListener) {
23712                 // we listen document as any drags that end by moving the touch off the screen get fired there
23713                 document.addEventListener(POINTER_DOWN, _globalPointerDown, true);
23714                 document.addEventListener(POINTER_MOVE, _globalPointerMove, true);
23715                 document.addEventListener(POINTER_UP, _globalPointerUp, true);
23716                 document.addEventListener(POINTER_CANCEL, _globalPointerUp, true);
23717
23718                 _pointerDocListener = true;
23719         }
23720       }
23721
23722       function _globalPointerDown(e) {
23723         _pointers[e.pointerId] = e;
23724       }
23725
23726       function _globalPointerMove(e) {
23727         if (_pointers[e.pointerId]) {
23728                 _pointers[e.pointerId] = e;
23729         }
23730       }
23731
23732       function _globalPointerUp(e) {
23733         delete _pointers[e.pointerId];
23734       }
23735
23736       function _handlePointer(e, handler) {
23737         e.touches = [];
23738         for (var i in _pointers) {
23739                 e.touches.push(_pointers[i]);
23740         }
23741         e.changedTouches = [e];
23742
23743         handler(e);
23744       }
23745
23746       function _addPointerMove(obj, handler, id) {
23747         var onMove = function (e) {
23748                 // don't fire touch moves when mouse isn't down
23749                 if ((e.pointerType === (e.MSPOINTER_TYPE_MOUSE || 'mouse')) && e.buttons === 0) {
23750                         return;
23751                 }
23752
23753                 _handlePointer(e, handler);
23754         };
23755
23756         obj['_leaflet_touchmove' + id] = onMove;
23757         obj.addEventListener(POINTER_MOVE, onMove, false);
23758       }
23759
23760       function _addPointerEnd(obj, handler, id) {
23761         var onUp = function (e) {
23762                 _handlePointer(e, handler);
23763         };
23764
23765         obj['_leaflet_touchend' + id] = onUp;
23766         obj.addEventListener(POINTER_UP, onUp, false);
23767         obj.addEventListener(POINTER_CANCEL, onUp, false);
23768       }
23769
23770       /*\r
23771        * Extends the event handling code with double tap support for mobile browsers.\r
23772        */\r
23773 \r
23774       var _touchstart = msPointer ? 'MSPointerDown' : pointer ? 'pointerdown' : 'touchstart';\r
23775       var _touchend = msPointer ? 'MSPointerUp' : pointer ? 'pointerup' : 'touchend';\r
23776       var _pre = '_leaflet_';\r
23777 \r
23778       // inspired by Zepto touch code by Thomas Fuchs\r
23779       function addDoubleTapListener(obj, handler, id) {\r
23780         var last, touch$$1,\r
23781             doubleTap = false,\r
23782             delay = 250;\r
23783 \r
23784         function onTouchStart(e) {\r
23785 \r
23786                 if (pointer) {\r
23787                         if (!e.isPrimary) { return; }\r
23788                         if (e.pointerType === 'mouse') { return; } // mouse fires native dblclick\r
23789                 } else if (e.touches.length > 1) {\r
23790                         return;\r
23791                 }\r
23792 \r
23793                 var now = Date.now(),\r
23794                     delta = now - (last || now);\r
23795 \r
23796                 touch$$1 = e.touches ? e.touches[0] : e;\r
23797                 doubleTap = (delta > 0 && delta <= delay);\r
23798                 last = now;\r
23799         }\r
23800 \r
23801         function onTouchEnd(e) {\r
23802                 if (doubleTap && !touch$$1.cancelBubble) {\r
23803                         if (pointer) {\r
23804                                 if (e.pointerType === 'mouse') { return; }\r
23805                                 // work around .type being readonly with MSPointer* events\r
23806                                 var newTouch = {},\r
23807                                     prop, i;\r
23808 \r
23809                                 for (i in touch$$1) {\r
23810                                         prop = touch$$1[i];\r
23811                                         newTouch[i] = prop && prop.bind ? prop.bind(touch$$1) : prop;\r
23812                                 }\r
23813                                 touch$$1 = newTouch;\r
23814                         }\r
23815                         touch$$1.type = 'dblclick';\r
23816                         touch$$1.button = 0;\r
23817                         handler(touch$$1);\r
23818                         last = null;\r
23819                 }\r
23820         }\r
23821 \r
23822         obj[_pre + _touchstart + id] = onTouchStart;\r
23823         obj[_pre + _touchend + id] = onTouchEnd;\r
23824         obj[_pre + 'dblclick' + id] = handler;\r
23825 \r
23826         obj.addEventListener(_touchstart, onTouchStart, passiveEvents ? {passive: false} : false);\r
23827         obj.addEventListener(_touchend, onTouchEnd, passiveEvents ? {passive: false} : false);\r
23828 \r
23829         // On some platforms (notably, chrome<55 on win10 + touchscreen + mouse),\r
23830         // the browser doesn't fire touchend/pointerup events but does fire\r
23831         // native dblclicks. See #4127.\r
23832         // Edge 14 also fires native dblclicks, but only for pointerType mouse, see #5180.\r
23833         obj.addEventListener('dblclick', handler, false);\r
23834 \r
23835         return this;\r
23836       }\r
23837 \r
23838       function removeDoubleTapListener(obj, id) {\r
23839         var touchstart = obj[_pre + _touchstart + id],\r
23840             touchend = obj[_pre + _touchend + id],\r
23841             dblclick = obj[_pre + 'dblclick' + id];\r
23842 \r
23843         obj.removeEventListener(_touchstart, touchstart, passiveEvents ? {passive: false} : false);\r
23844         obj.removeEventListener(_touchend, touchend, passiveEvents ? {passive: false} : false);\r
23845         obj.removeEventListener('dblclick', dblclick, false);\r
23846 \r
23847         return this;\r
23848       }
23849
23850       /*\r
23851        * @namespace DomUtil\r
23852        *\r
23853        * Utility functions to work with the [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model)\r
23854        * tree, used by Leaflet internally.\r
23855        *\r
23856        * Most functions expecting or returning a `HTMLElement` also work for\r
23857        * SVG elements. The only difference is that classes refer to CSS classes\r
23858        * in HTML and SVG classes in SVG.\r
23859        */\r
23860 \r
23861 \r
23862       // @property TRANSFORM: String\r
23863       // Vendor-prefixed transform style name (e.g. `'webkitTransform'` for WebKit).\r
23864       var TRANSFORM = testProp(\r
23865         ['transform', 'webkitTransform', 'OTransform', 'MozTransform', 'msTransform']);\r
23866 \r
23867       // webkitTransition comes first because some browser versions that drop vendor prefix don't do\r
23868       // the same for the transitionend event, in particular the Android 4.1 stock browser\r
23869 \r
23870       // @property TRANSITION: String\r
23871       // Vendor-prefixed transition style name.\r
23872       var TRANSITION = testProp(\r
23873         ['webkitTransition', 'transition', 'OTransition', 'MozTransition', 'msTransition']);\r
23874 \r
23875       // @property TRANSITION_END: String\r
23876       // Vendor-prefixed transitionend event name.\r
23877       var TRANSITION_END =\r
23878         TRANSITION === 'webkitTransition' || TRANSITION === 'OTransition' ? TRANSITION + 'End' : 'transitionend';\r
23879 \r
23880 \r
23881       // @function get(id: String|HTMLElement): HTMLElement\r
23882       // Returns an element given its DOM id, or returns the element itself\r
23883       // if it was passed directly.\r
23884       function get(id) {\r
23885         return typeof id === 'string' ? document.getElementById(id) : id;\r
23886       }\r
23887 \r
23888       // @function getStyle(el: HTMLElement, styleAttrib: String): String\r
23889       // Returns the value for a certain style attribute on an element,\r
23890       // including computed values or values set through CSS.\r
23891       function getStyle(el, style) {\r
23892         var value = el.style[style] || (el.currentStyle && el.currentStyle[style]);\r
23893 \r
23894         if ((!value || value === 'auto') && document.defaultView) {\r
23895                 var css = document.defaultView.getComputedStyle(el, null);\r
23896                 value = css ? css[style] : null;\r
23897         }\r
23898         return value === 'auto' ? null : value;\r
23899       }\r
23900 \r
23901       // @function create(tagName: String, className?: String, container?: HTMLElement): HTMLElement\r
23902       // Creates an HTML element with `tagName`, sets its class to `className`, and optionally appends it to `container` element.\r
23903       function create$1(tagName, className, container) {\r
23904         var el = document.createElement(tagName);\r
23905         el.className = className || '';\r
23906 \r
23907         if (container) {\r
23908                 container.appendChild(el);\r
23909         }\r
23910         return el;\r
23911       }\r
23912 \r
23913       // @function remove(el: HTMLElement)\r
23914       // Removes `el` from its parent element\r
23915       function remove(el) {\r
23916         var parent = el.parentNode;\r
23917         if (parent) {\r
23918                 parent.removeChild(el);\r
23919         }\r
23920       }\r
23921 \r
23922       // @function empty(el: HTMLElement)\r
23923       // Removes all of `el`'s children elements from `el`\r
23924       function empty(el) {\r
23925         while (el.firstChild) {\r
23926                 el.removeChild(el.firstChild);\r
23927         }\r
23928       }\r
23929 \r
23930       // @function toFront(el: HTMLElement)\r
23931       // Makes `el` the last child of its parent, so it renders in front of the other children.\r
23932       function toFront(el) {\r
23933         var parent = el.parentNode;\r
23934         if (parent && parent.lastChild !== el) {\r
23935                 parent.appendChild(el);\r
23936         }\r
23937       }\r
23938 \r
23939       // @function toBack(el: HTMLElement)\r
23940       // Makes `el` the first child of its parent, so it renders behind the other children.\r
23941       function toBack(el) {\r
23942         var parent = el.parentNode;\r
23943         if (parent && parent.firstChild !== el) {\r
23944                 parent.insertBefore(el, parent.firstChild);\r
23945         }\r
23946       }\r
23947 \r
23948       // @function hasClass(el: HTMLElement, name: String): Boolean\r
23949       // Returns `true` if the element's class attribute contains `name`.\r
23950       function hasClass(el, name) {\r
23951         if (el.classList !== undefined) {\r
23952                 return el.classList.contains(name);\r
23953         }\r
23954         var className = getClass(el);\r
23955         return className.length > 0 && new RegExp('(^|\\s)' + name + '(\\s|$)').test(className);\r
23956       }\r
23957 \r
23958       // @function addClass(el: HTMLElement, name: String)\r
23959       // Adds `name` to the element's class attribute.\r
23960       function addClass(el, name) {\r
23961         if (el.classList !== undefined) {\r
23962                 var classes = splitWords(name);\r
23963                 for (var i = 0, len = classes.length; i < len; i++) {\r
23964                         el.classList.add(classes[i]);\r
23965                 }\r
23966         } else if (!hasClass(el, name)) {\r
23967                 var className = getClass(el);\r
23968                 setClass(el, (className ? className + ' ' : '') + name);\r
23969         }\r
23970       }\r
23971 \r
23972       // @function removeClass(el: HTMLElement, name: String)\r
23973       // Removes `name` from the element's class attribute.\r
23974       function removeClass(el, name) {\r
23975         if (el.classList !== undefined) {\r
23976                 el.classList.remove(name);\r
23977         } else {\r
23978                 setClass(el, trim((' ' + getClass(el) + ' ').replace(' ' + name + ' ', ' ')));\r
23979         }\r
23980       }\r
23981 \r
23982       // @function setClass(el: HTMLElement, name: String)\r
23983       // Sets the element's class.\r
23984       function setClass(el, name) {\r
23985         if (el.className.baseVal === undefined) {\r
23986                 el.className = name;\r
23987         } else {\r
23988                 // in case of SVG element\r
23989                 el.className.baseVal = name;\r
23990         }\r
23991       }\r
23992 \r
23993       // @function getClass(el: HTMLElement): String\r
23994       // Returns the element's class.\r
23995       function getClass(el) {\r
23996         // Check if the element is an SVGElementInstance and use the correspondingElement instead\r
23997         // (Required for linked SVG elements in IE11.)\r
23998         if (el.correspondingElement) {\r
23999                 el = el.correspondingElement;\r
24000         }\r
24001         return el.className.baseVal === undefined ? el.className : el.className.baseVal;\r
24002       }\r
24003 \r
24004       // @function setOpacity(el: HTMLElement, opacity: Number)\r
24005       // Set the opacity of an element (including old IE support).\r
24006       // `opacity` must be a number from `0` to `1`.\r
24007       function setOpacity(el, value) {\r
24008         if ('opacity' in el.style) {\r
24009                 el.style.opacity = value;\r
24010         } else if ('filter' in el.style) {\r
24011                 _setOpacityIE(el, value);\r
24012         }\r
24013       }\r
24014 \r
24015       function _setOpacityIE(el, value) {\r
24016         var filter = false,\r
24017             filterName = 'DXImageTransform.Microsoft.Alpha';\r
24018 \r
24019         // filters collection throws an error if we try to retrieve a filter that doesn't exist\r
24020         try {\r
24021                 filter = el.filters.item(filterName);\r
24022         } catch (e) {\r
24023                 // don't set opacity to 1 if we haven't already set an opacity,\r
24024                 // it isn't needed and breaks transparent pngs.\r
24025                 if (value === 1) { return; }\r
24026         }\r
24027 \r
24028         value = Math.round(value * 100);\r
24029 \r
24030         if (filter) {\r
24031                 filter.Enabled = (value !== 100);\r
24032                 filter.Opacity = value;\r
24033         } else {\r
24034                 el.style.filter += ' progid:' + filterName + '(opacity=' + value + ')';\r
24035         }\r
24036       }\r
24037 \r
24038       // @function testProp(props: String[]): String|false\r
24039       // Goes through the array of style names and returns the first name\r
24040       // that is a valid style name for an element. If no such name is found,\r
24041       // it returns false. Useful for vendor-prefixed styles like `transform`.\r
24042       function testProp(props) {\r
24043         var style = document.documentElement.style;\r
24044 \r
24045         for (var i = 0; i < props.length; i++) {\r
24046                 if (props[i] in style) {\r
24047                         return props[i];\r
24048                 }\r
24049         }\r
24050         return false;\r
24051       }\r
24052 \r
24053       // @function setTransform(el: HTMLElement, offset: Point, scale?: Number)\r
24054       // Resets the 3D CSS transform of `el` so it is translated by `offset` pixels\r
24055       // and optionally scaled by `scale`. Does not have an effect if the\r
24056       // browser doesn't support 3D CSS transforms.\r
24057       function setTransform(el, offset, scale) {\r
24058         var pos = offset || new Point(0, 0);\r
24059 \r
24060         el.style[TRANSFORM] =\r
24061                 (ie3d ?\r
24062                         'translate(' + pos.x + 'px,' + pos.y + 'px)' :\r
24063                         'translate3d(' + pos.x + 'px,' + pos.y + 'px,0)') +\r
24064                 (scale ? ' scale(' + scale + ')' : '');\r
24065       }\r
24066 \r
24067       // @function setPosition(el: HTMLElement, position: Point)\r
24068       // Sets the position of `el` to coordinates specified by `position`,\r
24069       // using CSS translate or top/left positioning depending on the browser\r
24070       // (used by Leaflet internally to position its layers).\r
24071       function setPosition(el, point) {\r
24072 \r
24073         /*eslint-disable */\r
24074         el._leaflet_pos = point;\r
24075         /* eslint-enable */\r
24076 \r
24077         if (any3d) {\r
24078                 setTransform(el, point);\r
24079         } else {\r
24080                 el.style.left = point.x + 'px';\r
24081                 el.style.top = point.y + 'px';\r
24082         }\r
24083       }\r
24084 \r
24085       // @function getPosition(el: HTMLElement): Point\r
24086       // Returns the coordinates of an element previously positioned with setPosition.\r
24087       function getPosition(el) {\r
24088         // this method is only used for elements previously positioned using setPosition,\r
24089         // so it's safe to cache the position for performance\r
24090 \r
24091         return el._leaflet_pos || new Point(0, 0);\r
24092       }\r
24093 \r
24094       // @function disableTextSelection()\r
24095       // Prevents the user from generating `selectstart` DOM events, usually generated\r
24096       // when the user drags the mouse through a page with text. Used internally\r
24097       // by Leaflet to override the behaviour of any click-and-drag interaction on\r
24098       // the map. Affects drag interactions on the whole document.\r
24099 \r
24100       // @function enableTextSelection()\r
24101       // Cancels the effects of a previous [`L.DomUtil.disableTextSelection`](#domutil-disabletextselection).\r
24102       var disableTextSelection;\r
24103       var enableTextSelection;\r
24104       var _userSelect;\r
24105       if ('onselectstart' in document) {\r
24106         disableTextSelection = function () {\r
24107                 on(window, 'selectstart', preventDefault);\r
24108         };\r
24109         enableTextSelection = function () {\r
24110                 off(window, 'selectstart', preventDefault);\r
24111         };\r
24112       } else {\r
24113         var userSelectProperty = testProp(\r
24114                 ['userSelect', 'WebkitUserSelect', 'OUserSelect', 'MozUserSelect', 'msUserSelect']);\r
24115 \r
24116         disableTextSelection = function () {\r
24117                 if (userSelectProperty) {\r
24118                         var style = document.documentElement.style;\r
24119                         _userSelect = style[userSelectProperty];\r
24120                         style[userSelectProperty] = 'none';\r
24121                 }\r
24122         };\r
24123         enableTextSelection = function () {\r
24124                 if (userSelectProperty) {\r
24125                         document.documentElement.style[userSelectProperty] = _userSelect;\r
24126                         _userSelect = undefined;\r
24127                 }\r
24128         };\r
24129       }\r
24130 \r
24131       // @function disableImageDrag()\r
24132       // As [`L.DomUtil.disableTextSelection`](#domutil-disabletextselection), but\r
24133       // for `dragstart` DOM events, usually generated when the user drags an image.\r
24134       function disableImageDrag() {\r
24135         on(window, 'dragstart', preventDefault);\r
24136       }\r
24137 \r
24138       // @function enableImageDrag()\r
24139       // Cancels the effects of a previous [`L.DomUtil.disableImageDrag`](#domutil-disabletextselection).\r
24140       function enableImageDrag() {\r
24141         off(window, 'dragstart', preventDefault);\r
24142       }\r
24143 \r
24144       var _outlineElement, _outlineStyle;\r
24145       // @function preventOutline(el: HTMLElement)\r
24146       // Makes the [outline](https://developer.mozilla.org/docs/Web/CSS/outline)\r
24147       // of the element `el` invisible. Used internally by Leaflet to prevent\r
24148       // focusable elements from displaying an outline when the user performs a\r
24149       // drag interaction on them.\r
24150       function preventOutline(element) {\r
24151         while (element.tabIndex === -1) {\r
24152                 element = element.parentNode;\r
24153         }\r
24154         if (!element.style) { return; }\r
24155         restoreOutline();\r
24156         _outlineElement = element;\r
24157         _outlineStyle = element.style.outline;\r
24158         element.style.outline = 'none';\r
24159         on(window, 'keydown', restoreOutline);\r
24160       }\r
24161 \r
24162       // @function restoreOutline()\r
24163       // Cancels the effects of a previous [`L.DomUtil.preventOutline`]().\r
24164       function restoreOutline() {\r
24165         if (!_outlineElement) { return; }\r
24166         _outlineElement.style.outline = _outlineStyle;\r
24167         _outlineElement = undefined;\r
24168         _outlineStyle = undefined;\r
24169         off(window, 'keydown', restoreOutline);\r
24170       }\r
24171 \r
24172       // @function getSizedParentNode(el: HTMLElement): HTMLElement\r
24173       // Finds the closest parent node which size (width and height) is not null.\r
24174       function getSizedParentNode(element) {\r
24175         do {\r
24176                 element = element.parentNode;\r
24177         } while ((!element.offsetWidth || !element.offsetHeight) && element !== document.body);\r
24178         return element;\r
24179       }\r
24180 \r
24181       // @function getScale(el: HTMLElement): Object\r
24182       // Computes the CSS scale currently applied on the element.\r
24183       // Returns an object with `x` and `y` members as horizontal and vertical scales respectively,\r
24184       // and `boundingClientRect` as the result of [`getBoundingClientRect()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect).\r
24185       function getScale(element) {\r
24186         var rect = element.getBoundingClientRect(); // Read-only in old browsers.\r
24187 \r
24188         return {\r
24189                 x: rect.width / element.offsetWidth || 1,\r
24190                 y: rect.height / element.offsetHeight || 1,\r
24191                 boundingClientRect: rect\r
24192         };\r
24193       }
24194
24195       var DomUtil = ({
24196         TRANSFORM: TRANSFORM,
24197         TRANSITION: TRANSITION,
24198         TRANSITION_END: TRANSITION_END,
24199         get: get,
24200         getStyle: getStyle,
24201         create: create$1,
24202         remove: remove,
24203         empty: empty,
24204         toFront: toFront,
24205         toBack: toBack,
24206         hasClass: hasClass,
24207         addClass: addClass,
24208         removeClass: removeClass,
24209         setClass: setClass,
24210         getClass: getClass,
24211         setOpacity: setOpacity,
24212         testProp: testProp,
24213         setTransform: setTransform,
24214         setPosition: setPosition,
24215         getPosition: getPosition,
24216         disableTextSelection: disableTextSelection,
24217         enableTextSelection: enableTextSelection,
24218         disableImageDrag: disableImageDrag,
24219         enableImageDrag: enableImageDrag,
24220         preventOutline: preventOutline,
24221         restoreOutline: restoreOutline,
24222         getSizedParentNode: getSizedParentNode,
24223         getScale: getScale
24224       });
24225
24226       /*\r
24227        * @namespace DomEvent\r
24228        * Utility functions to work with the [DOM events](https://developer.mozilla.org/docs/Web/API/Event), used by Leaflet internally.\r
24229        */\r
24230 \r
24231       // Inspired by John Resig, Dean Edwards and YUI addEvent implementations.\r
24232 \r
24233       // @function on(el: HTMLElement, types: String, fn: Function, context?: Object): this\r
24234       // Adds a listener function (`fn`) to a particular DOM event type of the\r
24235       // element `el`. You can optionally specify the context of the listener\r
24236       // (object the `this` keyword will point to). You can also pass several\r
24237       // space-separated types (e.g. `'click dblclick'`).\r
24238 \r
24239       // @alternative\r
24240       // @function on(el: HTMLElement, eventMap: Object, context?: Object): this\r
24241       // Adds a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}`\r
24242       function on(obj, types, fn, context) {\r
24243 \r
24244         if (typeof types === 'object') {\r
24245                 for (var type in types) {\r
24246                         addOne(obj, type, types[type], fn);\r
24247                 }\r
24248         } else {\r
24249                 types = splitWords(types);\r
24250 \r
24251                 for (var i = 0, len = types.length; i < len; i++) {\r
24252                         addOne(obj, types[i], fn, context);\r
24253                 }\r
24254         }\r
24255 \r
24256         return this;\r
24257       }\r
24258 \r
24259       var eventsKey = '_leaflet_events';\r
24260 \r
24261       // @function off(el: HTMLElement, types: String, fn: Function, context?: Object): this\r
24262       // Removes a previously added listener function.\r
24263       // Note that if you passed a custom context to on, you must pass the same\r
24264       // context to `off` in order to remove the listener.\r
24265 \r
24266       // @alternative\r
24267       // @function off(el: HTMLElement, eventMap: Object, context?: Object): this\r
24268       // Removes a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}`\r
24269       function off(obj, types, fn, context) {\r
24270 \r
24271         if (typeof types === 'object') {\r
24272                 for (var type in types) {\r
24273                         removeOne(obj, type, types[type], fn);\r
24274                 }\r
24275         } else if (types) {\r
24276                 types = splitWords(types);\r
24277 \r
24278                 for (var i = 0, len = types.length; i < len; i++) {\r
24279                         removeOne(obj, types[i], fn, context);\r
24280                 }\r
24281         } else {\r
24282                 for (var j in obj[eventsKey]) {\r
24283                         removeOne(obj, j, obj[eventsKey][j]);\r
24284                 }\r
24285                 delete obj[eventsKey];\r
24286         }\r
24287 \r
24288         return this;\r
24289       }\r
24290 \r
24291       function browserFiresNativeDblClick() {\r
24292         // See https://github.com/w3c/pointerevents/issues/171\r
24293         if (pointer) {\r
24294                 return !(edge || safari);\r
24295         }\r
24296       }\r
24297 \r
24298       var mouseSubst = {\r
24299         mouseenter: 'mouseover',\r
24300         mouseleave: 'mouseout',\r
24301         wheel: !('onwheel' in window) && 'mousewheel'\r
24302       };\r
24303 \r
24304       function addOne(obj, type, fn, context) {\r
24305         var id = type + stamp(fn) + (context ? '_' + stamp(context) : '');\r
24306 \r
24307         if (obj[eventsKey] && obj[eventsKey][id]) { return this; }\r
24308 \r
24309         var handler = function (e) {\r
24310                 return fn.call(context || obj, e || window.event);\r
24311         };\r
24312 \r
24313         var originalHandler = handler;\r
24314 \r
24315         if (pointer && type.indexOf('touch') === 0) {\r
24316                 // Needs DomEvent.Pointer.js\r
24317                 addPointerListener(obj, type, handler, id);\r
24318 \r
24319         } else if (touch && (type === 'dblclick') && !browserFiresNativeDblClick()) {\r
24320                 addDoubleTapListener(obj, handler, id);\r
24321 \r
24322         } else if ('addEventListener' in obj) {\r
24323 \r
24324                 if (type === 'touchstart' || type === 'touchmove' || type === 'wheel' ||  type === 'mousewheel') {\r
24325                         obj.addEventListener(mouseSubst[type] || type, handler, passiveEvents ? {passive: false} : false);\r
24326 \r
24327                 } else if (type === 'mouseenter' || type === 'mouseleave') {\r
24328                         handler = function (e) {\r
24329                                 e = e || window.event;\r
24330                                 if (isExternalTarget(obj, e)) {\r
24331                                         originalHandler(e);\r
24332                                 }\r
24333                         };\r
24334                         obj.addEventListener(mouseSubst[type], handler, false);\r
24335 \r
24336                 } else {\r
24337                         obj.addEventListener(type, originalHandler, false);\r
24338                 }\r
24339 \r
24340         } else if ('attachEvent' in obj) {\r
24341                 obj.attachEvent('on' + type, handler);\r
24342         }\r
24343 \r
24344         obj[eventsKey] = obj[eventsKey] || {};\r
24345         obj[eventsKey][id] = handler;\r
24346       }\r
24347 \r
24348       function removeOne(obj, type, fn, context) {\r
24349 \r
24350         var id = type + stamp(fn) + (context ? '_' + stamp(context) : ''),\r
24351             handler = obj[eventsKey] && obj[eventsKey][id];\r
24352 \r
24353         if (!handler) { return this; }\r
24354 \r
24355         if (pointer && type.indexOf('touch') === 0) {\r
24356                 removePointerListener(obj, type, id);\r
24357 \r
24358         } else if (touch && (type === 'dblclick') && !browserFiresNativeDblClick()) {\r
24359                 removeDoubleTapListener(obj, id);\r
24360 \r
24361         } else if ('removeEventListener' in obj) {\r
24362 \r
24363                 obj.removeEventListener(mouseSubst[type] || type, handler, false);\r
24364 \r
24365         } else if ('detachEvent' in obj) {\r
24366                 obj.detachEvent('on' + type, handler);\r
24367         }\r
24368 \r
24369         obj[eventsKey][id] = null;\r
24370       }\r
24371 \r
24372       // @function stopPropagation(ev: DOMEvent): this\r
24373       // Stop the given event from propagation to parent elements. Used inside the listener functions:\r
24374       // ```js\r
24375       // L.DomEvent.on(div, 'click', function (ev) {\r
24376       //        L.DomEvent.stopPropagation(ev);\r
24377       // });\r
24378       // ```\r
24379       function stopPropagation(e) {\r
24380 \r
24381         if (e.stopPropagation) {\r
24382                 e.stopPropagation();\r
24383         } else if (e.originalEvent) {  // In case of Leaflet event.\r
24384                 e.originalEvent._stopped = true;\r
24385         } else {\r
24386                 e.cancelBubble = true;\r
24387         }\r
24388         skipped(e);\r
24389 \r
24390         return this;\r
24391       }\r
24392 \r
24393       // @function disableScrollPropagation(el: HTMLElement): this\r
24394       // Adds `stopPropagation` to the element's `'wheel'` events (plus browser variants).\r
24395       function disableScrollPropagation(el) {\r
24396         addOne(el, 'wheel', stopPropagation);\r
24397         return this;\r
24398       }\r
24399 \r
24400       // @function disableClickPropagation(el: HTMLElement): this\r
24401       // Adds `stopPropagation` to the element's `'click'`, `'doubleclick'`,\r
24402       // `'mousedown'` and `'touchstart'` events (plus browser variants).\r
24403       function disableClickPropagation(el) {\r
24404         on(el, 'mousedown touchstart dblclick', stopPropagation);\r
24405         addOne(el, 'click', fakeStop);\r
24406         return this;\r
24407       }\r
24408 \r
24409       // @function preventDefault(ev: DOMEvent): this\r
24410       // Prevents the default action of the DOM Event `ev` from happening (such as\r
24411       // following a link in the href of the a element, or doing a POST request\r
24412       // with page reload when a `<form>` is submitted).\r
24413       // Use it inside listener functions.\r
24414       function preventDefault(e) {\r
24415         if (e.preventDefault) {\r
24416                 e.preventDefault();\r
24417         } else {\r
24418                 e.returnValue = false;\r
24419         }\r
24420         return this;\r
24421       }\r
24422 \r
24423       // @function stop(ev: DOMEvent): this\r
24424       // Does `stopPropagation` and `preventDefault` at the same time.\r
24425       function stop(e) {\r
24426         preventDefault(e);\r
24427         stopPropagation(e);\r
24428         return this;\r
24429       }\r
24430 \r
24431       // @function getMousePosition(ev: DOMEvent, container?: HTMLElement): Point\r
24432       // Gets normalized mouse position from a DOM event relative to the\r
24433       // `container` (border excluded) or to the whole page if not specified.\r
24434       function getMousePosition(e, container) {\r
24435         if (!container) {\r
24436                 return new Point(e.clientX, e.clientY);\r
24437         }\r
24438 \r
24439         var scale = getScale(container),\r
24440             offset = scale.boundingClientRect; // left and top  values are in page scale (like the event clientX/Y)\r
24441 \r
24442         return new Point(\r
24443                 // offset.left/top values are in page scale (like clientX/Y),\r
24444                 // whereas clientLeft/Top (border width) values are the original values (before CSS scale applies).\r
24445                 (e.clientX - offset.left) / scale.x - container.clientLeft,\r
24446                 (e.clientY - offset.top) / scale.y - container.clientTop\r
24447         );\r
24448       }\r
24449 \r
24450       // Chrome on Win scrolls double the pixels as in other platforms (see #4538),\r
24451       // and Firefox scrolls device pixels, not CSS pixels\r
24452       var wheelPxFactor =\r
24453         (win && chrome) ? 2 * window.devicePixelRatio :\r
24454         gecko ? window.devicePixelRatio : 1;\r
24455 \r
24456       // @function getWheelDelta(ev: DOMEvent): Number\r
24457       // Gets normalized wheel delta from a wheel DOM event, in vertical\r
24458       // pixels scrolled (negative if scrolling down).\r
24459       // Events from pointing devices without precise scrolling are mapped to\r
24460       // a best guess of 60 pixels.\r
24461       function getWheelDelta(e) {\r
24462         return (edge) ? e.wheelDeltaY / 2 : // Don't trust window-geometry-based delta\r
24463                (e.deltaY && e.deltaMode === 0) ? -e.deltaY / wheelPxFactor : // Pixels\r
24464                (e.deltaY && e.deltaMode === 1) ? -e.deltaY * 20 : // Lines\r
24465                (e.deltaY && e.deltaMode === 2) ? -e.deltaY * 60 : // Pages\r
24466                (e.deltaX || e.deltaZ) ? 0 :     // Skip horizontal/depth wheel events\r
24467                e.wheelDelta ? (e.wheelDeltaY || e.wheelDelta) / 2 : // Legacy IE pixels\r
24468                (e.detail && Math.abs(e.detail) < 32765) ? -e.detail * 20 : // Legacy Moz lines\r
24469                e.detail ? e.detail / -32765 * 60 : // Legacy Moz pages\r
24470                0;\r
24471       }\r
24472 \r
24473       var skipEvents = {};\r
24474 \r
24475       function fakeStop(e) {\r
24476         // fakes stopPropagation by setting a special event flag, checked/reset with skipped(e)\r
24477         skipEvents[e.type] = true;\r
24478       }\r
24479 \r
24480       function skipped(e) {\r
24481         var events = skipEvents[e.type];\r
24482         // reset when checking, as it's only used in map container and propagates outside of the map\r
24483         skipEvents[e.type] = false;\r
24484         return events;\r
24485       }\r
24486 \r
24487       // check if element really left/entered the event target (for mouseenter/mouseleave)\r
24488       function isExternalTarget(el, e) {\r
24489 \r
24490         var related = e.relatedTarget;\r
24491 \r
24492         if (!related) { return true; }\r
24493 \r
24494         try {\r
24495                 while (related && (related !== el)) {\r
24496                         related = related.parentNode;\r
24497                 }\r
24498         } catch (err) {\r
24499                 return false;\r
24500         }\r
24501         return (related !== el);\r
24502       }
24503
24504       var DomEvent = ({
24505         on: on,
24506         off: off,
24507         stopPropagation: stopPropagation,
24508         disableScrollPropagation: disableScrollPropagation,
24509         disableClickPropagation: disableClickPropagation,
24510         preventDefault: preventDefault,
24511         stop: stop,
24512         getMousePosition: getMousePosition,
24513         getWheelDelta: getWheelDelta,
24514         fakeStop: fakeStop,
24515         skipped: skipped,
24516         isExternalTarget: isExternalTarget,
24517         addListener: on,
24518         removeListener: off
24519       });
24520
24521       /*
24522        * @class PosAnimation
24523        * @aka L.PosAnimation
24524        * @inherits Evented
24525        * Used internally for panning animations, utilizing CSS3 Transitions for modern browsers and a timer fallback for IE6-9.
24526        *
24527        * @example
24528        * ```js
24529        * var fx = new L.PosAnimation();
24530        * fx.run(el, [300, 500], 0.5);
24531        * ```
24532        *
24533        * @constructor L.PosAnimation()
24534        * Creates a `PosAnimation` object.
24535        *
24536        */
24537
24538       var PosAnimation = Evented.extend({
24539
24540         // @method run(el: HTMLElement, newPos: Point, duration?: Number, easeLinearity?: Number)
24541         // Run an animation of a given element to a new position, optionally setting
24542         // duration in seconds (`0.25` by default) and easing linearity factor (3rd
24543         // argument of the [cubic bezier curve](http://cubic-bezier.com/#0,0,.5,1),
24544         // `0.5` by default).
24545         run: function (el, newPos, duration, easeLinearity) {
24546                 this.stop();
24547
24548                 this._el = el;
24549                 this._inProgress = true;
24550                 this._duration = duration || 0.25;
24551                 this._easeOutPower = 1 / Math.max(easeLinearity || 0.5, 0.2);
24552
24553                 this._startPos = getPosition(el);
24554                 this._offset = newPos.subtract(this._startPos);
24555                 this._startTime = +new Date();
24556
24557                 // @event start: Event
24558                 // Fired when the animation starts
24559                 this.fire('start');
24560
24561                 this._animate();
24562         },
24563
24564         // @method stop()
24565         // Stops the animation (if currently running).
24566         stop: function () {
24567                 if (!this._inProgress) { return; }
24568
24569                 this._step(true);
24570                 this._complete();
24571         },
24572
24573         _animate: function () {
24574                 // animation loop
24575                 this._animId = requestAnimFrame(this._animate, this);
24576                 this._step();
24577         },
24578
24579         _step: function (round) {
24580                 var elapsed = (+new Date()) - this._startTime,
24581                     duration = this._duration * 1000;
24582
24583                 if (elapsed < duration) {
24584                         this._runFrame(this._easeOut(elapsed / duration), round);
24585                 } else {
24586                         this._runFrame(1);
24587                         this._complete();
24588                 }
24589         },
24590
24591         _runFrame: function (progress, round) {
24592                 var pos = this._startPos.add(this._offset.multiplyBy(progress));
24593                 if (round) {
24594                         pos._round();
24595                 }
24596                 setPosition(this._el, pos);
24597
24598                 // @event step: Event
24599                 // Fired continuously during the animation.
24600                 this.fire('step');
24601         },
24602
24603         _complete: function () {
24604                 cancelAnimFrame(this._animId);
24605
24606                 this._inProgress = false;
24607                 // @event end: Event
24608                 // Fired when the animation ends.
24609                 this.fire('end');
24610         },
24611
24612         _easeOut: function (t) {
24613                 return 1 - Math.pow(1 - t, this._easeOutPower);
24614         }
24615       });
24616
24617       /*\r
24618        * @class Map\r
24619        * @aka L.Map\r
24620        * @inherits Evented\r
24621        *\r
24622        * The central class of the API â€” it is used to create a map on a page and manipulate it.\r
24623        *\r
24624        * @example\r
24625        *\r
24626        * ```js\r
24627        * // initialize the map on the "map" div with a given center and zoom\r
24628        * var map = L.map('map', {\r
24629        *        center: [51.505, -0.09],\r
24630        *        zoom: 13\r
24631        * });\r
24632        * ```\r
24633        *\r
24634        */\r
24635 \r
24636       var Map = Evented.extend({\r
24637 \r
24638         options: {\r
24639                 // @section Map State Options\r
24640                 // @option crs: CRS = L.CRS.EPSG3857\r
24641                 // The [Coordinate Reference System](#crs) to use. Don't change this if you're not\r
24642                 // sure what it means.\r
24643                 crs: EPSG3857,\r
24644 \r
24645                 // @option center: LatLng = undefined\r
24646                 // Initial geographic center of the map\r
24647                 center: undefined,\r
24648 \r
24649                 // @option zoom: Number = undefined\r
24650                 // Initial map zoom level\r
24651                 zoom: undefined,\r
24652 \r
24653                 // @option minZoom: Number = *\r
24654                 // Minimum zoom level of the map.\r
24655                 // If not specified and at least one `GridLayer` or `TileLayer` is in the map,\r
24656                 // the lowest of their `minZoom` options will be used instead.\r
24657                 minZoom: undefined,\r
24658 \r
24659                 // @option maxZoom: Number = *\r
24660                 // Maximum zoom level of the map.\r
24661                 // If not specified and at least one `GridLayer` or `TileLayer` is in the map,\r
24662                 // the highest of their `maxZoom` options will be used instead.\r
24663                 maxZoom: undefined,\r
24664 \r
24665                 // @option layers: Layer[] = []\r
24666                 // Array of layers that will be added to the map initially\r
24667                 layers: [],\r
24668 \r
24669                 // @option maxBounds: LatLngBounds = null\r
24670                 // When this option is set, the map restricts the view to the given\r
24671                 // geographical bounds, bouncing the user back if the user tries to pan\r
24672                 // outside the view. To set the restriction dynamically, use\r
24673                 // [`setMaxBounds`](#map-setmaxbounds) method.\r
24674                 maxBounds: undefined,\r
24675 \r
24676                 // @option renderer: Renderer = *\r
24677                 // The default method for drawing vector layers on the map. `L.SVG`\r
24678                 // or `L.Canvas` by default depending on browser support.\r
24679                 renderer: undefined,\r
24680 \r
24681 \r
24682                 // @section Animation Options\r
24683                 // @option zoomAnimation: Boolean = true\r
24684                 // Whether the map zoom animation is enabled. By default it's enabled\r
24685                 // in all browsers that support CSS3 Transitions except Android.\r
24686                 zoomAnimation: true,\r
24687 \r
24688                 // @option zoomAnimationThreshold: Number = 4\r
24689                 // Won't animate zoom if the zoom difference exceeds this value.\r
24690                 zoomAnimationThreshold: 4,\r
24691 \r
24692                 // @option fadeAnimation: Boolean = true\r
24693                 // Whether the tile fade animation is enabled. By default it's enabled\r
24694                 // in all browsers that support CSS3 Transitions except Android.\r
24695                 fadeAnimation: true,\r
24696 \r
24697                 // @option markerZoomAnimation: Boolean = true\r
24698                 // Whether markers animate their zoom with the zoom animation, if disabled\r
24699                 // they will disappear for the length of the animation. By default it's\r
24700                 // enabled in all browsers that support CSS3 Transitions except Android.\r
24701                 markerZoomAnimation: true,\r
24702 \r
24703                 // @option transform3DLimit: Number = 2^23\r
24704                 // Defines the maximum size of a CSS translation transform. The default\r
24705                 // value should not be changed unless a web browser positions layers in\r
24706                 // the wrong place after doing a large `panBy`.\r
24707                 transform3DLimit: 8388608, // Precision limit of a 32-bit float\r
24708 \r
24709                 // @section Interaction Options\r
24710                 // @option zoomSnap: Number = 1\r
24711                 // Forces the map's zoom level to always be a multiple of this, particularly\r
24712                 // right after a [`fitBounds()`](#map-fitbounds) or a pinch-zoom.\r
24713                 // By default, the zoom level snaps to the nearest integer; lower values\r
24714                 // (e.g. `0.5` or `0.1`) allow for greater granularity. A value of `0`\r
24715                 // means the zoom level will not be snapped after `fitBounds` or a pinch-zoom.\r
24716                 zoomSnap: 1,\r
24717 \r
24718                 // @option zoomDelta: Number = 1\r
24719                 // Controls how much the map's zoom level will change after a\r
24720                 // [`zoomIn()`](#map-zoomin), [`zoomOut()`](#map-zoomout), pressing `+`\r
24721                 // or `-` on the keyboard, or using the [zoom controls](#control-zoom).\r
24722                 // Values smaller than `1` (e.g. `0.5`) allow for greater granularity.\r
24723                 zoomDelta: 1,\r
24724 \r
24725                 // @option trackResize: Boolean = true\r
24726                 // Whether the map automatically handles browser window resize to update itself.\r
24727                 trackResize: true\r
24728         },\r
24729 \r
24730         initialize: function (id, options) { // (HTMLElement or String, Object)\r
24731                 options = setOptions(this, options);\r
24732 \r
24733                 // Make sure to assign internal flags at the beginning,\r
24734                 // to avoid inconsistent state in some edge cases.\r
24735                 this._handlers = [];\r
24736                 this._layers = {};\r
24737                 this._zoomBoundLayers = {};\r
24738                 this._sizeChanged = true;\r
24739 \r
24740                 this._initContainer(id);\r
24741                 this._initLayout();\r
24742 \r
24743                 // hack for https://github.com/Leaflet/Leaflet/issues/1980\r
24744                 this._onResize = bind(this._onResize, this);\r
24745 \r
24746                 this._initEvents();\r
24747 \r
24748                 if (options.maxBounds) {\r
24749                         this.setMaxBounds(options.maxBounds);\r
24750                 }\r
24751 \r
24752                 if (options.zoom !== undefined) {\r
24753                         this._zoom = this._limitZoom(options.zoom);\r
24754                 }\r
24755 \r
24756                 if (options.center && options.zoom !== undefined) {\r
24757                         this.setView(toLatLng(options.center), options.zoom, {reset: true});\r
24758                 }\r
24759 \r
24760                 this.callInitHooks();\r
24761 \r
24762                 // don't animate on browsers without hardware-accelerated transitions or old Android/Opera\r
24763                 this._zoomAnimated = TRANSITION && any3d && !mobileOpera &&\r
24764                                 this.options.zoomAnimation;\r
24765 \r
24766                 // zoom transitions run with the same duration for all layers, so if one of transitionend events\r
24767                 // happens after starting zoom animation (propagating to the map pane), we know that it ended globally\r
24768                 if (this._zoomAnimated) {\r
24769                         this._createAnimProxy();\r
24770                         on(this._proxy, TRANSITION_END, this._catchTransitionEnd, this);\r
24771                 }\r
24772 \r
24773                 this._addLayers(this.options.layers);\r
24774         },\r
24775 \r
24776 \r
24777         // @section Methods for modifying map state\r
24778 \r
24779         // @method setView(center: LatLng, zoom: Number, options?: Zoom/pan options): this\r
24780         // Sets the view of the map (geographical center and zoom) with the given\r
24781         // animation options.\r
24782         setView: function (center, zoom, options) {\r
24783 \r
24784                 zoom = zoom === undefined ? this._zoom : this._limitZoom(zoom);\r
24785                 center = this._limitCenter(toLatLng(center), zoom, this.options.maxBounds);\r
24786                 options = options || {};\r
24787 \r
24788                 this._stop();\r
24789 \r
24790                 if (this._loaded && !options.reset && options !== true) {\r
24791 \r
24792                         if (options.animate !== undefined) {\r
24793                                 options.zoom = extend({animate: options.animate}, options.zoom);\r
24794                                 options.pan = extend({animate: options.animate, duration: options.duration}, options.pan);\r
24795                         }\r
24796 \r
24797                         // try animating pan or zoom\r
24798                         var moved = (this._zoom !== zoom) ?\r
24799                                 this._tryAnimatedZoom && this._tryAnimatedZoom(center, zoom, options.zoom) :\r
24800                                 this._tryAnimatedPan(center, options.pan);\r
24801 \r
24802                         if (moved) {\r
24803                                 // prevent resize handler call, the view will refresh after animation anyway\r
24804                                 clearTimeout(this._sizeTimer);\r
24805                                 return this;\r
24806                         }\r
24807                 }\r
24808 \r
24809                 // animation didn't start, just reset the map view\r
24810                 this._resetView(center, zoom);\r
24811 \r
24812                 return this;\r
24813         },\r
24814 \r
24815         // @method setZoom(zoom: Number, options?: Zoom/pan options): this\r
24816         // Sets the zoom of the map.\r
24817         setZoom: function (zoom, options) {\r
24818                 if (!this._loaded) {\r
24819                         this._zoom = zoom;\r
24820                         return this;\r
24821                 }\r
24822                 return this.setView(this.getCenter(), zoom, {zoom: options});\r
24823         },\r
24824 \r
24825         // @method zoomIn(delta?: Number, options?: Zoom options): this\r
24826         // Increases the zoom of the map by `delta` ([`zoomDelta`](#map-zoomdelta) by default).\r
24827         zoomIn: function (delta, options) {\r
24828                 delta = delta || (any3d ? this.options.zoomDelta : 1);\r
24829                 return this.setZoom(this._zoom + delta, options);\r
24830         },\r
24831 \r
24832         // @method zoomOut(delta?: Number, options?: Zoom options): this\r
24833         // Decreases the zoom of the map by `delta` ([`zoomDelta`](#map-zoomdelta) by default).\r
24834         zoomOut: function (delta, options) {\r
24835                 delta = delta || (any3d ? this.options.zoomDelta : 1);\r
24836                 return this.setZoom(this._zoom - delta, options);\r
24837         },\r
24838 \r
24839         // @method setZoomAround(latlng: LatLng, zoom: Number, options: Zoom options): this\r
24840         // Zooms the map while keeping a specified geographical point on the map\r
24841         // stationary (e.g. used internally for scroll zoom and double-click zoom).\r
24842         // @alternative\r
24843         // @method setZoomAround(offset: Point, zoom: Number, options: Zoom options): this\r
24844         // Zooms the map while keeping a specified pixel on the map (relative to the top-left corner) stationary.\r
24845         setZoomAround: function (latlng, zoom, options) {\r
24846                 var scale = this.getZoomScale(zoom),\r
24847                     viewHalf = this.getSize().divideBy(2),\r
24848                     containerPoint = latlng instanceof Point ? latlng : this.latLngToContainerPoint(latlng),\r
24849 \r
24850                     centerOffset = containerPoint.subtract(viewHalf).multiplyBy(1 - 1 / scale),\r
24851                     newCenter = this.containerPointToLatLng(viewHalf.add(centerOffset));\r
24852 \r
24853                 return this.setView(newCenter, zoom, {zoom: options});\r
24854         },\r
24855 \r
24856         _getBoundsCenterZoom: function (bounds, options) {\r
24857 \r
24858                 options = options || {};\r
24859                 bounds = bounds.getBounds ? bounds.getBounds() : toLatLngBounds(bounds);\r
24860 \r
24861                 var paddingTL = toPoint(options.paddingTopLeft || options.padding || [0, 0]),\r
24862                     paddingBR = toPoint(options.paddingBottomRight || options.padding || [0, 0]),\r
24863 \r
24864                     zoom = this.getBoundsZoom(bounds, false, paddingTL.add(paddingBR));\r
24865 \r
24866                 zoom = (typeof options.maxZoom === 'number') ? Math.min(options.maxZoom, zoom) : zoom;\r
24867 \r
24868                 if (zoom === Infinity) {\r
24869                         return {\r
24870                                 center: bounds.getCenter(),\r
24871                                 zoom: zoom\r
24872                         };\r
24873                 }\r
24874 \r
24875                 var paddingOffset = paddingBR.subtract(paddingTL).divideBy(2),\r
24876 \r
24877                     swPoint = this.project(bounds.getSouthWest(), zoom),\r
24878                     nePoint = this.project(bounds.getNorthEast(), zoom),\r
24879                     center = this.unproject(swPoint.add(nePoint).divideBy(2).add(paddingOffset), zoom);\r
24880 \r
24881                 return {\r
24882                         center: center,\r
24883                         zoom: zoom\r
24884                 };\r
24885         },\r
24886 \r
24887         // @method fitBounds(bounds: LatLngBounds, options?: fitBounds options): this\r
24888         // Sets a map view that contains the given geographical bounds with the\r
24889         // maximum zoom level possible.\r
24890         fitBounds: function (bounds, options) {\r
24891 \r
24892                 bounds = toLatLngBounds(bounds);\r
24893 \r
24894                 if (!bounds.isValid()) {\r
24895                         throw new Error('Bounds are not valid.');\r
24896                 }\r
24897 \r
24898                 var target = this._getBoundsCenterZoom(bounds, options);\r
24899                 return this.setView(target.center, target.zoom, options);\r
24900         },\r
24901 \r
24902         // @method fitWorld(options?: fitBounds options): this\r
24903         // Sets a map view that mostly contains the whole world with the maximum\r
24904         // zoom level possible.\r
24905         fitWorld: function (options) {\r
24906                 return this.fitBounds([[-90, -180], [90, 180]], options);\r
24907         },\r
24908 \r
24909         // @method panTo(latlng: LatLng, options?: Pan options): this\r
24910         // Pans the map to a given center.\r
24911         panTo: function (center, options) { // (LatLng)\r
24912                 return this.setView(center, this._zoom, {pan: options});\r
24913         },\r
24914 \r
24915         // @method panBy(offset: Point, options?: Pan options): this\r
24916         // Pans the map by a given number of pixels (animated).\r
24917         panBy: function (offset, options) {\r
24918                 offset = toPoint(offset).round();\r
24919                 options = options || {};\r
24920 \r
24921                 if (!offset.x && !offset.y) {\r
24922                         return this.fire('moveend');\r
24923                 }\r
24924                 // If we pan too far, Chrome gets issues with tiles\r
24925                 // and makes them disappear or appear in the wrong place (slightly offset) #2602\r
24926                 if (options.animate !== true && !this.getSize().contains(offset)) {\r
24927                         this._resetView(this.unproject(this.project(this.getCenter()).add(offset)), this.getZoom());\r
24928                         return this;\r
24929                 }\r
24930 \r
24931                 if (!this._panAnim) {\r
24932                         this._panAnim = new PosAnimation();\r
24933 \r
24934                         this._panAnim.on({\r
24935                                 'step': this._onPanTransitionStep,\r
24936                                 'end': this._onPanTransitionEnd\r
24937                         }, this);\r
24938                 }\r
24939 \r
24940                 // don't fire movestart if animating inertia\r
24941                 if (!options.noMoveStart) {\r
24942                         this.fire('movestart');\r
24943                 }\r
24944 \r
24945                 // animate pan unless animate: false specified\r
24946                 if (options.animate !== false) {\r
24947                         addClass(this._mapPane, 'leaflet-pan-anim');\r
24948 \r
24949                         var newPos = this._getMapPanePos().subtract(offset).round();\r
24950                         this._panAnim.run(this._mapPane, newPos, options.duration || 0.25, options.easeLinearity);\r
24951                 } else {\r
24952                         this._rawPanBy(offset);\r
24953                         this.fire('move').fire('moveend');\r
24954                 }\r
24955 \r
24956                 return this;\r
24957         },\r
24958 \r
24959         // @method flyTo(latlng: LatLng, zoom?: Number, options?: Zoom/pan options): this\r
24960         // Sets the view of the map (geographical center and zoom) performing a smooth\r
24961         // pan-zoom animation.\r
24962         flyTo: function (targetCenter, targetZoom, options) {\r
24963 \r
24964                 options = options || {};\r
24965                 if (options.animate === false || !any3d) {\r
24966                         return this.setView(targetCenter, targetZoom, options);\r
24967                 }\r
24968 \r
24969                 this._stop();\r
24970 \r
24971                 var from = this.project(this.getCenter()),\r
24972                     to = this.project(targetCenter),\r
24973                     size = this.getSize(),\r
24974                     startZoom = this._zoom;\r
24975 \r
24976                 targetCenter = toLatLng(targetCenter);\r
24977                 targetZoom = targetZoom === undefined ? startZoom : targetZoom;\r
24978 \r
24979                 var w0 = Math.max(size.x, size.y),\r
24980                     w1 = w0 * this.getZoomScale(startZoom, targetZoom),\r
24981                     u1 = (to.distanceTo(from)) || 1,\r
24982                     rho = 1.42,\r
24983                     rho2 = rho * rho;\r
24984 \r
24985                 function r(i) {\r
24986                         var s1 = i ? -1 : 1,\r
24987                             s2 = i ? w1 : w0,\r
24988                             t1 = w1 * w1 - w0 * w0 + s1 * rho2 * rho2 * u1 * u1,\r
24989                             b1 = 2 * s2 * rho2 * u1,\r
24990                             b = t1 / b1,\r
24991                             sq = Math.sqrt(b * b + 1) - b;\r
24992 \r
24993                             // workaround for floating point precision bug when sq = 0, log = -Infinite,\r
24994                             // thus triggering an infinite loop in flyTo\r
24995                             var log = sq < 0.000000001 ? -18 : Math.log(sq);\r
24996 \r
24997                         return log;\r
24998                 }\r
24999 \r
25000                 function sinh(n) { return (Math.exp(n) - Math.exp(-n)) / 2; }\r
25001                 function cosh(n) { return (Math.exp(n) + Math.exp(-n)) / 2; }\r
25002                 function tanh(n) { return sinh(n) / cosh(n); }\r
25003 \r
25004                 var r0 = r(0);\r
25005 \r
25006                 function w(s) { return w0 * (cosh(r0) / cosh(r0 + rho * s)); }\r
25007                 function u(s) { return w0 * (cosh(r0) * tanh(r0 + rho * s) - sinh(r0)) / rho2; }\r
25008 \r
25009                 function easeOut(t) { return 1 - Math.pow(1 - t, 1.5); }\r
25010 \r
25011                 var start = Date.now(),\r
25012                     S = (r(1) - r0) / rho,\r
25013                     duration = options.duration ? 1000 * options.duration : 1000 * S * 0.8;\r
25014 \r
25015                 function frame() {\r
25016                         var t = (Date.now() - start) / duration,\r
25017                             s = easeOut(t) * S;\r
25018 \r
25019                         if (t <= 1) {\r
25020                                 this._flyToFrame = requestAnimFrame(frame, this);\r
25021 \r
25022                                 this._move(\r
25023                                         this.unproject(from.add(to.subtract(from).multiplyBy(u(s) / u1)), startZoom),\r
25024                                         this.getScaleZoom(w0 / w(s), startZoom),\r
25025                                         {flyTo: true});\r
25026 \r
25027                         } else {\r
25028                                 this\r
25029                                         ._move(targetCenter, targetZoom)\r
25030                                         ._moveEnd(true);\r
25031                         }\r
25032                 }\r
25033 \r
25034                 this._moveStart(true, options.noMoveStart);\r
25035 \r
25036                 frame.call(this);\r
25037                 return this;\r
25038         },\r
25039 \r
25040         // @method flyToBounds(bounds: LatLngBounds, options?: fitBounds options): this\r
25041         // Sets the view of the map with a smooth animation like [`flyTo`](#map-flyto),\r
25042         // but takes a bounds parameter like [`fitBounds`](#map-fitbounds).\r
25043         flyToBounds: function (bounds, options) {\r
25044                 var target = this._getBoundsCenterZoom(bounds, options);\r
25045                 return this.flyTo(target.center, target.zoom, options);\r
25046         },\r
25047 \r
25048         // @method setMaxBounds(bounds: LatLngBounds): this\r
25049         // Restricts the map view to the given bounds (see the [maxBounds](#map-maxbounds) option).\r
25050         setMaxBounds: function (bounds) {\r
25051                 bounds = toLatLngBounds(bounds);\r
25052 \r
25053                 if (!bounds.isValid()) {\r
25054                         this.options.maxBounds = null;\r
25055                         return this.off('moveend', this._panInsideMaxBounds);\r
25056                 } else if (this.options.maxBounds) {\r
25057                         this.off('moveend', this._panInsideMaxBounds);\r
25058                 }\r
25059 \r
25060                 this.options.maxBounds = bounds;\r
25061 \r
25062                 if (this._loaded) {\r
25063                         this._panInsideMaxBounds();\r
25064                 }\r
25065 \r
25066                 return this.on('moveend', this._panInsideMaxBounds);\r
25067         },\r
25068 \r
25069         // @method setMinZoom(zoom: Number): this\r
25070         // Sets the lower limit for the available zoom levels (see the [minZoom](#map-minzoom) option).\r
25071         setMinZoom: function (zoom) {\r
25072                 var oldZoom = this.options.minZoom;\r
25073                 this.options.minZoom = zoom;\r
25074 \r
25075                 if (this._loaded && oldZoom !== zoom) {\r
25076                         this.fire('zoomlevelschange');\r
25077 \r
25078                         if (this.getZoom() < this.options.minZoom) {\r
25079                                 return this.setZoom(zoom);\r
25080                         }\r
25081                 }\r
25082 \r
25083                 return this;\r
25084         },\r
25085 \r
25086         // @method setMaxZoom(zoom: Number): this\r
25087         // Sets the upper limit for the available zoom levels (see the [maxZoom](#map-maxzoom) option).\r
25088         setMaxZoom: function (zoom) {\r
25089                 var oldZoom = this.options.maxZoom;\r
25090                 this.options.maxZoom = zoom;\r
25091 \r
25092                 if (this._loaded && oldZoom !== zoom) {\r
25093                         this.fire('zoomlevelschange');\r
25094 \r
25095                         if (this.getZoom() > this.options.maxZoom) {\r
25096                                 return this.setZoom(zoom);\r
25097                         }\r
25098                 }\r
25099 \r
25100                 return this;\r
25101         },\r
25102 \r
25103         // @method panInsideBounds(bounds: LatLngBounds, options?: Pan options): this\r
25104         // Pans the map to the closest view that would lie inside the given bounds (if it's not already), controlling the animation using the options specific, if any.\r
25105         panInsideBounds: function (bounds, options) {\r
25106                 this._enforcingBounds = true;\r
25107                 var center = this.getCenter(),\r
25108                     newCenter = this._limitCenter(center, this._zoom, toLatLngBounds(bounds));\r
25109 \r
25110                 if (!center.equals(newCenter)) {\r
25111                         this.panTo(newCenter, options);\r
25112                 }\r
25113 \r
25114                 this._enforcingBounds = false;\r
25115                 return this;\r
25116         },\r
25117 \r
25118         // @method panInside(latlng: LatLng, options?: options): this\r
25119         // Pans the map the minimum amount to make the `latlng` visible. Use\r
25120         // `padding`, `paddingTopLeft` and `paddingTopRight` options to fit\r
25121         // the display to more restricted bounds, like [`fitBounds`](#map-fitbounds).\r
25122         // If `latlng` is already within the (optionally padded) display bounds,\r
25123         // the map will not be panned.\r
25124         panInside: function (latlng, options) {\r
25125                 options = options || {};\r
25126 \r
25127                 var paddingTL = toPoint(options.paddingTopLeft || options.padding || [0, 0]),\r
25128                     paddingBR = toPoint(options.paddingBottomRight || options.padding || [0, 0]),\r
25129                     center = this.getCenter(),\r
25130                     pixelCenter = this.project(center),\r
25131                     pixelPoint = this.project(latlng),\r
25132                     pixelBounds = this.getPixelBounds(),\r
25133                     halfPixelBounds = pixelBounds.getSize().divideBy(2),\r
25134                     paddedBounds = toBounds([pixelBounds.min.add(paddingTL), pixelBounds.max.subtract(paddingBR)]);\r
25135 \r
25136                 if (!paddedBounds.contains(pixelPoint)) {\r
25137                         this._enforcingBounds = true;\r
25138                         var diff = pixelCenter.subtract(pixelPoint),\r
25139                             newCenter = toPoint(pixelPoint.x + diff.x, pixelPoint.y + diff.y);\r
25140 \r
25141                         if (pixelPoint.x < paddedBounds.min.x || pixelPoint.x > paddedBounds.max.x) {\r
25142                                 newCenter.x = pixelCenter.x - diff.x;\r
25143                                 if (diff.x > 0) {\r
25144                                         newCenter.x += halfPixelBounds.x - paddingTL.x;\r
25145                                 } else {\r
25146                                         newCenter.x -= halfPixelBounds.x - paddingBR.x;\r
25147                                 }\r
25148                         }\r
25149                         if (pixelPoint.y < paddedBounds.min.y || pixelPoint.y > paddedBounds.max.y) {\r
25150                                 newCenter.y = pixelCenter.y - diff.y;\r
25151                                 if (diff.y > 0) {\r
25152                                         newCenter.y += halfPixelBounds.y - paddingTL.y;\r
25153                                 } else {\r
25154                                         newCenter.y -= halfPixelBounds.y - paddingBR.y;\r
25155                                 }\r
25156                         }\r
25157                         this.panTo(this.unproject(newCenter), options);\r
25158                         this._enforcingBounds = false;\r
25159                 }\r
25160                 return this;\r
25161         },\r
25162 \r
25163         // @method invalidateSize(options: Zoom/pan options): this\r
25164         // Checks if the map container size changed and updates the map if so â€”\r
25165         // call it after you've changed the map size dynamically, also animating\r
25166         // pan by default. If `options.pan` is `false`, panning will not occur.\r
25167         // If `options.debounceMoveend` is `true`, it will delay `moveend` event so\r
25168         // that it doesn't happen often even if the method is called many\r
25169         // times in a row.\r
25170 \r
25171         // @alternative\r
25172         // @method invalidateSize(animate: Boolean): this\r
25173         // Checks if the map container size changed and updates the map if so â€”\r
25174         // call it after you've changed the map size dynamically, also animating\r
25175         // pan by default.\r
25176         invalidateSize: function (options) {\r
25177                 if (!this._loaded) { return this; }\r
25178 \r
25179                 options = extend({\r
25180                         animate: false,\r
25181                         pan: true\r
25182                 }, options === true ? {animate: true} : options);\r
25183 \r
25184                 var oldSize = this.getSize();\r
25185                 this._sizeChanged = true;\r
25186                 this._lastCenter = null;\r
25187 \r
25188                 var newSize = this.getSize(),\r
25189                     oldCenter = oldSize.divideBy(2).round(),\r
25190                     newCenter = newSize.divideBy(2).round(),\r
25191                     offset = oldCenter.subtract(newCenter);\r
25192 \r
25193                 if (!offset.x && !offset.y) { return this; }\r
25194 \r
25195                 if (options.animate && options.pan) {\r
25196                         this.panBy(offset);\r
25197 \r
25198                 } else {\r
25199                         if (options.pan) {\r
25200                                 this._rawPanBy(offset);\r
25201                         }\r
25202 \r
25203                         this.fire('move');\r
25204 \r
25205                         if (options.debounceMoveend) {\r
25206                                 clearTimeout(this._sizeTimer);\r
25207                                 this._sizeTimer = setTimeout(bind(this.fire, this, 'moveend'), 200);\r
25208                         } else {\r
25209                                 this.fire('moveend');\r
25210                         }\r
25211                 }\r
25212 \r
25213                 // @section Map state change events\r
25214                 // @event resize: ResizeEvent\r
25215                 // Fired when the map is resized.\r
25216                 return this.fire('resize', {\r
25217                         oldSize: oldSize,\r
25218                         newSize: newSize\r
25219                 });\r
25220         },\r
25221 \r
25222         // @section Methods for modifying map state\r
25223         // @method stop(): this\r
25224         // Stops the currently running `panTo` or `flyTo` animation, if any.\r
25225         stop: function () {\r
25226                 this.setZoom(this._limitZoom(this._zoom));\r
25227                 if (!this.options.zoomSnap) {\r
25228                         this.fire('viewreset');\r
25229                 }\r
25230                 return this._stop();\r
25231         },\r
25232 \r
25233         // @section Geolocation methods\r
25234         // @method locate(options?: Locate options): this\r
25235         // Tries to locate the user using the Geolocation API, firing a [`locationfound`](#map-locationfound)\r
25236         // event with location data on success or a [`locationerror`](#map-locationerror) event on failure,\r
25237         // and optionally sets the map view to the user's location with respect to\r
25238         // detection accuracy (or to the world view if geolocation failed).\r
25239         // Note that, if your page doesn't use HTTPS, this method will fail in\r
25240         // modern browsers ([Chrome 50 and newer](https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-powerful-features-on-insecure-origins))\r
25241         // See `Locate options` for more details.\r
25242         locate: function (options) {\r
25243 \r
25244                 options = this._locateOptions = extend({\r
25245                         timeout: 10000,\r
25246                         watch: false\r
25247                         // setView: false\r
25248                         // maxZoom: <Number>\r
25249                         // maximumAge: 0\r
25250                         // enableHighAccuracy: false\r
25251                 }, options);\r
25252 \r
25253                 if (!('geolocation' in navigator)) {\r
25254                         this._handleGeolocationError({\r
25255                                 code: 0,\r
25256                                 message: 'Geolocation not supported.'\r
25257                         });\r
25258                         return this;\r
25259                 }\r
25260 \r
25261                 var onResponse = bind(this._handleGeolocationResponse, this),\r
25262                     onError = bind(this._handleGeolocationError, this);\r
25263 \r
25264                 if (options.watch) {\r
25265                         this._locationWatchId =\r
25266                                 navigator.geolocation.watchPosition(onResponse, onError, options);\r
25267                 } else {\r
25268                         navigator.geolocation.getCurrentPosition(onResponse, onError, options);\r
25269                 }\r
25270                 return this;\r
25271         },\r
25272 \r
25273         // @method stopLocate(): this\r
25274         // Stops watching location previously initiated by `map.locate({watch: true})`\r
25275         // and aborts resetting the map view if map.locate was called with\r
25276         // `{setView: true}`.\r
25277         stopLocate: function () {\r
25278                 if (navigator.geolocation && navigator.geolocation.clearWatch) {\r
25279                         navigator.geolocation.clearWatch(this._locationWatchId);\r
25280                 }\r
25281                 if (this._locateOptions) {\r
25282                         this._locateOptions.setView = false;\r
25283                 }\r
25284                 return this;\r
25285         },\r
25286 \r
25287         _handleGeolocationError: function (error) {\r
25288                 var c = error.code,\r
25289                     message = error.message ||\r
25290                             (c === 1 ? 'permission denied' :\r
25291                             (c === 2 ? 'position unavailable' : 'timeout'));\r
25292 \r
25293                 if (this._locateOptions.setView && !this._loaded) {\r
25294                         this.fitWorld();\r
25295                 }\r
25296 \r
25297                 // @section Location events\r
25298                 // @event locationerror: ErrorEvent\r
25299                 // Fired when geolocation (using the [`locate`](#map-locate) method) failed.\r
25300                 this.fire('locationerror', {\r
25301                         code: c,\r
25302                         message: 'Geolocation error: ' + message + '.'\r
25303                 });\r
25304         },\r
25305 \r
25306         _handleGeolocationResponse: function (pos) {\r
25307                 var lat = pos.coords.latitude,\r
25308                     lng = pos.coords.longitude,\r
25309                     latlng = new LatLng(lat, lng),\r
25310                     bounds = latlng.toBounds(pos.coords.accuracy * 2),\r
25311                     options = this._locateOptions;\r
25312 \r
25313                 if (options.setView) {\r
25314                         var zoom = this.getBoundsZoom(bounds);\r
25315                         this.setView(latlng, options.maxZoom ? Math.min(zoom, options.maxZoom) : zoom);\r
25316                 }\r
25317 \r
25318                 var data = {\r
25319                         latlng: latlng,\r
25320                         bounds: bounds,\r
25321                         timestamp: pos.timestamp\r
25322                 };\r
25323 \r
25324                 for (var i in pos.coords) {\r
25325                         if (typeof pos.coords[i] === 'number') {\r
25326                                 data[i] = pos.coords[i];\r
25327                         }\r
25328                 }\r
25329 \r
25330                 // @event locationfound: LocationEvent\r
25331                 // Fired when geolocation (using the [`locate`](#map-locate) method)\r
25332                 // went successfully.\r
25333                 this.fire('locationfound', data);\r
25334         },\r
25335 \r
25336         // TODO Appropriate docs section?\r
25337         // @section Other Methods\r
25338         // @method addHandler(name: String, HandlerClass: Function): this\r
25339         // Adds a new `Handler` to the map, given its name and constructor function.\r
25340         addHandler: function (name, HandlerClass) {\r
25341                 if (!HandlerClass) { return this; }\r
25342 \r
25343                 var handler = this[name] = new HandlerClass(this);\r
25344 \r
25345                 this._handlers.push(handler);\r
25346 \r
25347                 if (this.options[name]) {\r
25348                         handler.enable();\r
25349                 }\r
25350 \r
25351                 return this;\r
25352         },\r
25353 \r
25354         // @method remove(): this\r
25355         // Destroys the map and clears all related event listeners.\r
25356         remove: function () {\r
25357 \r
25358                 this._initEvents(true);\r
25359                 this.off('moveend', this._panInsideMaxBounds);\r
25360 \r
25361                 if (this._containerId !== this._container._leaflet_id) {\r
25362                         throw new Error('Map container is being reused by another instance');\r
25363                 }\r
25364 \r
25365                 try {\r
25366                         // throws error in IE6-8\r
25367                         delete this._container._leaflet_id;\r
25368                         delete this._containerId;\r
25369                 } catch (e) {\r
25370                         /*eslint-disable */\r
25371                         this._container._leaflet_id = undefined;\r
25372                         /* eslint-enable */\r
25373                         this._containerId = undefined;\r
25374                 }\r
25375 \r
25376                 if (this._locationWatchId !== undefined) {\r
25377                         this.stopLocate();\r
25378                 }\r
25379 \r
25380                 this._stop();\r
25381 \r
25382                 remove(this._mapPane);\r
25383 \r
25384                 if (this._clearControlPos) {\r
25385                         this._clearControlPos();\r
25386                 }\r
25387                 if (this._resizeRequest) {\r
25388                         cancelAnimFrame(this._resizeRequest);\r
25389                         this._resizeRequest = null;\r
25390                 }\r
25391 \r
25392                 this._clearHandlers();\r
25393 \r
25394                 if (this._loaded) {\r
25395                         // @section Map state change events\r
25396                         // @event unload: Event\r
25397                         // Fired when the map is destroyed with [remove](#map-remove) method.\r
25398                         this.fire('unload');\r
25399                 }\r
25400 \r
25401                 var i;\r
25402                 for (i in this._layers) {\r
25403                         this._layers[i].remove();\r
25404                 }\r
25405                 for (i in this._panes) {\r
25406                         remove(this._panes[i]);\r
25407                 }\r
25408 \r
25409                 this._layers = [];\r
25410                 this._panes = [];\r
25411                 delete this._mapPane;\r
25412                 delete this._renderer;\r
25413 \r
25414                 return this;\r
25415         },\r
25416 \r
25417         // @section Other Methods\r
25418         // @method createPane(name: String, container?: HTMLElement): HTMLElement\r
25419         // Creates a new [map pane](#map-pane) with the given name if it doesn't exist already,\r
25420         // then returns it. The pane is created as a child of `container`, or\r
25421         // as a child of the main map pane if not set.\r
25422         createPane: function (name, container) {\r
25423                 var className = 'leaflet-pane' + (name ? ' leaflet-' + name.replace('Pane', '') + '-pane' : ''),\r
25424                     pane = create$1('div', className, container || this._mapPane);\r
25425 \r
25426                 if (name) {\r
25427                         this._panes[name] = pane;\r
25428                 }\r
25429                 return pane;\r
25430         },\r
25431 \r
25432         // @section Methods for Getting Map State\r
25433 \r
25434         // @method getCenter(): LatLng\r
25435         // Returns the geographical center of the map view\r
25436         getCenter: function () {\r
25437                 this._checkIfLoaded();\r
25438 \r
25439                 if (this._lastCenter && !this._moved()) {\r
25440                         return this._lastCenter;\r
25441                 }\r
25442                 return this.layerPointToLatLng(this._getCenterLayerPoint());\r
25443         },\r
25444 \r
25445         // @method getZoom(): Number\r
25446         // Returns the current zoom level of the map view\r
25447         getZoom: function () {\r
25448                 return this._zoom;\r
25449         },\r
25450 \r
25451         // @method getBounds(): LatLngBounds\r
25452         // Returns the geographical bounds visible in the current map view\r
25453         getBounds: function () {\r
25454                 var bounds = this.getPixelBounds(),\r
25455                     sw = this.unproject(bounds.getBottomLeft()),\r
25456                     ne = this.unproject(bounds.getTopRight());\r
25457 \r
25458                 return new LatLngBounds(sw, ne);\r
25459         },\r
25460 \r
25461         // @method getMinZoom(): Number\r
25462         // Returns the minimum zoom level of the map (if set in the `minZoom` option of the map or of any layers), or `0` by default.\r
25463         getMinZoom: function () {\r
25464                 return this.options.minZoom === undefined ? this._layersMinZoom || 0 : this.options.minZoom;\r
25465         },\r
25466 \r
25467         // @method getMaxZoom(): Number\r
25468         // Returns the maximum zoom level of the map (if set in the `maxZoom` option of the map or of any layers).\r
25469         getMaxZoom: function () {\r
25470                 return this.options.maxZoom === undefined ?\r
25471                         (this._layersMaxZoom === undefined ? Infinity : this._layersMaxZoom) :\r
25472                         this.options.maxZoom;\r
25473         },\r
25474 \r
25475         // @method getBoundsZoom(bounds: LatLngBounds, inside?: Boolean, padding?: Point): Number\r
25476         // Returns the maximum zoom level on which the given bounds fit to the map\r
25477         // view in its entirety. If `inside` (optional) is set to `true`, the method\r
25478         // instead returns the minimum zoom level on which the map view fits into\r
25479         // the given bounds in its entirety.\r
25480         getBoundsZoom: function (bounds, inside, padding) { // (LatLngBounds[, Boolean, Point]) -> Number\r
25481                 bounds = toLatLngBounds(bounds);\r
25482                 padding = toPoint(padding || [0, 0]);\r
25483 \r
25484                 var zoom = this.getZoom() || 0,\r
25485                     min = this.getMinZoom(),\r
25486                     max = this.getMaxZoom(),\r
25487                     nw = bounds.getNorthWest(),\r
25488                     se = bounds.getSouthEast(),\r
25489                     size = this.getSize().subtract(padding),\r
25490                     boundsSize = toBounds(this.project(se, zoom), this.project(nw, zoom)).getSize(),\r
25491                     snap = any3d ? this.options.zoomSnap : 1,\r
25492                     scalex = size.x / boundsSize.x,\r
25493                     scaley = size.y / boundsSize.y,\r
25494                     scale = inside ? Math.max(scalex, scaley) : Math.min(scalex, scaley);\r
25495 \r
25496                 zoom = this.getScaleZoom(scale, zoom);\r
25497 \r
25498                 if (snap) {\r
25499                         zoom = Math.round(zoom / (snap / 100)) * (snap / 100); // don't jump if within 1% of a snap level\r
25500                         zoom = inside ? Math.ceil(zoom / snap) * snap : Math.floor(zoom / snap) * snap;\r
25501                 }\r
25502 \r
25503                 return Math.max(min, Math.min(max, zoom));\r
25504         },\r
25505 \r
25506         // @method getSize(): Point\r
25507         // Returns the current size of the map container (in pixels).\r
25508         getSize: function () {\r
25509                 if (!this._size || this._sizeChanged) {\r
25510                         this._size = new Point(\r
25511                                 this._container.clientWidth || 0,\r
25512                                 this._container.clientHeight || 0);\r
25513 \r
25514                         this._sizeChanged = false;\r
25515                 }\r
25516                 return this._size.clone();\r
25517         },\r
25518 \r
25519         // @method getPixelBounds(): Bounds\r
25520         // Returns the bounds of the current map view in projected pixel\r
25521         // coordinates (sometimes useful in layer and overlay implementations).\r
25522         getPixelBounds: function (center, zoom) {\r
25523                 var topLeftPoint = this._getTopLeftPoint(center, zoom);\r
25524                 return new Bounds(topLeftPoint, topLeftPoint.add(this.getSize()));\r
25525         },\r
25526 \r
25527         // TODO: Check semantics - isn't the pixel origin the 0,0 coord relative to\r
25528         // the map pane? "left point of the map layer" can be confusing, specially\r
25529         // since there can be negative offsets.\r
25530         // @method getPixelOrigin(): Point\r
25531         // Returns the projected pixel coordinates of the top left point of\r
25532         // the map layer (useful in custom layer and overlay implementations).\r
25533         getPixelOrigin: function () {\r
25534                 this._checkIfLoaded();\r
25535                 return this._pixelOrigin;\r
25536         },\r
25537 \r
25538         // @method getPixelWorldBounds(zoom?: Number): Bounds\r
25539         // Returns the world's bounds in pixel coordinates for zoom level `zoom`.\r
25540         // If `zoom` is omitted, the map's current zoom level is used.\r
25541         getPixelWorldBounds: function (zoom) {\r
25542                 return this.options.crs.getProjectedBounds(zoom === undefined ? this.getZoom() : zoom);\r
25543         },\r
25544 \r
25545         // @section Other Methods\r
25546 \r
25547         // @method getPane(pane: String|HTMLElement): HTMLElement\r
25548         // Returns a [map pane](#map-pane), given its name or its HTML element (its identity).\r
25549         getPane: function (pane) {\r
25550                 return typeof pane === 'string' ? this._panes[pane] : pane;\r
25551         },\r
25552 \r
25553         // @method getPanes(): Object\r
25554         // Returns a plain object containing the names of all [panes](#map-pane) as keys and\r
25555         // the panes as values.\r
25556         getPanes: function () {\r
25557                 return this._panes;\r
25558         },\r
25559 \r
25560         // @method getContainer: HTMLElement\r
25561         // Returns the HTML element that contains the map.\r
25562         getContainer: function () {\r
25563                 return this._container;\r
25564         },\r
25565 \r
25566 \r
25567         // @section Conversion Methods\r
25568 \r
25569         // @method getZoomScale(toZoom: Number, fromZoom: Number): Number\r
25570         // Returns the scale factor to be applied to a map transition from zoom level\r
25571         // `fromZoom` to `toZoom`. Used internally to help with zoom animations.\r
25572         getZoomScale: function (toZoom, fromZoom) {\r
25573                 // TODO replace with universal implementation after refactoring projections\r
25574                 var crs = this.options.crs;\r
25575                 fromZoom = fromZoom === undefined ? this._zoom : fromZoom;\r
25576                 return crs.scale(toZoom) / crs.scale(fromZoom);\r
25577         },\r
25578 \r
25579         // @method getScaleZoom(scale: Number, fromZoom: Number): Number\r
25580         // Returns the zoom level that the map would end up at, if it is at `fromZoom`\r
25581         // level and everything is scaled by a factor of `scale`. Inverse of\r
25582         // [`getZoomScale`](#map-getZoomScale).\r
25583         getScaleZoom: function (scale, fromZoom) {\r
25584                 var crs = this.options.crs;\r
25585                 fromZoom = fromZoom === undefined ? this._zoom : fromZoom;\r
25586                 var zoom = crs.zoom(scale * crs.scale(fromZoom));\r
25587                 return isNaN(zoom) ? Infinity : zoom;\r
25588         },\r
25589 \r
25590         // @method project(latlng: LatLng, zoom: Number): Point\r
25591         // Projects a geographical coordinate `LatLng` according to the projection\r
25592         // of the map's CRS, then scales it according to `zoom` and the CRS's\r
25593         // `Transformation`. The result is pixel coordinate relative to\r
25594         // the CRS origin.\r
25595         project: function (latlng, zoom) {\r
25596                 zoom = zoom === undefined ? this._zoom : zoom;\r
25597                 return this.options.crs.latLngToPoint(toLatLng(latlng), zoom);\r
25598         },\r
25599 \r
25600         // @method unproject(point: Point, zoom: Number): LatLng\r
25601         // Inverse of [`project`](#map-project).\r
25602         unproject: function (point, zoom) {\r
25603                 zoom = zoom === undefined ? this._zoom : zoom;\r
25604                 return this.options.crs.pointToLatLng(toPoint(point), zoom);\r
25605         },\r
25606 \r
25607         // @method layerPointToLatLng(point: Point): LatLng\r
25608         // Given a pixel coordinate relative to the [origin pixel](#map-getpixelorigin),\r
25609         // returns the corresponding geographical coordinate (for the current zoom level).\r
25610         layerPointToLatLng: function (point) {\r
25611                 var projectedPoint = toPoint(point).add(this.getPixelOrigin());\r
25612                 return this.unproject(projectedPoint);\r
25613         },\r
25614 \r
25615         // @method latLngToLayerPoint(latlng: LatLng): Point\r
25616         // Given a geographical coordinate, returns the corresponding pixel coordinate\r
25617         // relative to the [origin pixel](#map-getpixelorigin).\r
25618         latLngToLayerPoint: function (latlng) {\r
25619                 var projectedPoint = this.project(toLatLng(latlng))._round();\r
25620                 return projectedPoint._subtract(this.getPixelOrigin());\r
25621         },\r
25622 \r
25623         // @method wrapLatLng(latlng: LatLng): LatLng\r
25624         // Returns a `LatLng` where `lat` and `lng` has been wrapped according to the\r
25625         // map's CRS's `wrapLat` and `wrapLng` properties, if they are outside the\r
25626         // CRS's bounds.\r
25627         // By default this means longitude is wrapped around the dateline so its\r
25628         // value is between -180 and +180 degrees.\r
25629         wrapLatLng: function (latlng) {\r
25630                 return this.options.crs.wrapLatLng(toLatLng(latlng));\r
25631         },\r
25632 \r
25633         // @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds\r
25634         // Returns a `LatLngBounds` with the same size as the given one, ensuring that\r
25635         // its center is within the CRS's bounds.\r
25636         // By default this means the center longitude is wrapped around the dateline so its\r
25637         // value is between -180 and +180 degrees, and the majority of the bounds\r
25638         // overlaps the CRS's bounds.\r
25639         wrapLatLngBounds: function (latlng) {\r
25640                 return this.options.crs.wrapLatLngBounds(toLatLngBounds(latlng));\r
25641         },\r
25642 \r
25643         // @method distance(latlng1: LatLng, latlng2: LatLng): Number\r
25644         // Returns the distance between two geographical coordinates according to\r
25645         // the map's CRS. By default this measures distance in meters.\r
25646         distance: function (latlng1, latlng2) {\r
25647                 return this.options.crs.distance(toLatLng(latlng1), toLatLng(latlng2));\r
25648         },\r
25649 \r
25650         // @method containerPointToLayerPoint(point: Point): Point\r
25651         // Given a pixel coordinate relative to the map container, returns the corresponding\r
25652         // pixel coordinate relative to the [origin pixel](#map-getpixelorigin).\r
25653         containerPointToLayerPoint: function (point) { // (Point)\r
25654                 return toPoint(point).subtract(this._getMapPanePos());\r
25655         },\r
25656 \r
25657         // @method layerPointToContainerPoint(point: Point): Point\r
25658         // Given a pixel coordinate relative to the [origin pixel](#map-getpixelorigin),\r
25659         // returns the corresponding pixel coordinate relative to the map container.\r
25660         layerPointToContainerPoint: function (point) { // (Point)\r
25661                 return toPoint(point).add(this._getMapPanePos());\r
25662         },\r
25663 \r
25664         // @method containerPointToLatLng(point: Point): LatLng\r
25665         // Given a pixel coordinate relative to the map container, returns\r
25666         // the corresponding geographical coordinate (for the current zoom level).\r
25667         containerPointToLatLng: function (point) {\r
25668                 var layerPoint = this.containerPointToLayerPoint(toPoint(point));\r
25669                 return this.layerPointToLatLng(layerPoint);\r
25670         },\r
25671 \r
25672         // @method latLngToContainerPoint(latlng: LatLng): Point\r
25673         // Given a geographical coordinate, returns the corresponding pixel coordinate\r
25674         // relative to the map container.\r
25675         latLngToContainerPoint: function (latlng) {\r
25676                 return this.layerPointToContainerPoint(this.latLngToLayerPoint(toLatLng(latlng)));\r
25677         },\r
25678 \r
25679         // @method mouseEventToContainerPoint(ev: MouseEvent): Point\r
25680         // Given a MouseEvent object, returns the pixel coordinate relative to the\r
25681         // map container where the event took place.\r
25682         mouseEventToContainerPoint: function (e) {\r
25683                 return getMousePosition(e, this._container);\r
25684         },\r
25685 \r
25686         // @method mouseEventToLayerPoint(ev: MouseEvent): Point\r
25687         // Given a MouseEvent object, returns the pixel coordinate relative to\r
25688         // the [origin pixel](#map-getpixelorigin) where the event took place.\r
25689         mouseEventToLayerPoint: function (e) {\r
25690                 return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(e));\r
25691         },\r
25692 \r
25693         // @method mouseEventToLatLng(ev: MouseEvent): LatLng\r
25694         // Given a MouseEvent object, returns geographical coordinate where the\r
25695         // event took place.\r
25696         mouseEventToLatLng: function (e) { // (MouseEvent)\r
25697                 return this.layerPointToLatLng(this.mouseEventToLayerPoint(e));\r
25698         },\r
25699 \r
25700 \r
25701         // map initialization methods\r
25702 \r
25703         _initContainer: function (id) {\r
25704                 var container = this._container = get(id);\r
25705 \r
25706                 if (!container) {\r
25707                         throw new Error('Map container not found.');\r
25708                 } else if (container._leaflet_id) {\r
25709                         throw new Error('Map container is already initialized.');\r
25710                 }\r
25711 \r
25712                 on(container, 'scroll', this._onScroll, this);\r
25713                 this._containerId = stamp(container);\r
25714         },\r
25715 \r
25716         _initLayout: function () {\r
25717                 var container = this._container;\r
25718 \r
25719                 this._fadeAnimated = this.options.fadeAnimation && any3d;\r
25720 \r
25721                 addClass(container, 'leaflet-container' +\r
25722                         (touch ? ' leaflet-touch' : '') +\r
25723                         (retina ? ' leaflet-retina' : '') +\r
25724                         (ielt9 ? ' leaflet-oldie' : '') +\r
25725                         (safari ? ' leaflet-safari' : '') +\r
25726                         (this._fadeAnimated ? ' leaflet-fade-anim' : ''));\r
25727 \r
25728                 var position = getStyle(container, 'position');\r
25729 \r
25730                 if (position !== 'absolute' && position !== 'relative' && position !== 'fixed') {\r
25731                         container.style.position = 'relative';\r
25732                 }\r
25733 \r
25734                 this._initPanes();\r
25735 \r
25736                 if (this._initControlPos) {\r
25737                         this._initControlPos();\r
25738                 }\r
25739         },\r
25740 \r
25741         _initPanes: function () {\r
25742                 var panes = this._panes = {};\r
25743                 this._paneRenderers = {};\r
25744 \r
25745                 // @section\r
25746                 //\r
25747                 // Panes are DOM elements used to control the ordering of layers on the map. You\r
25748                 // can access panes with [`map.getPane`](#map-getpane) or\r
25749                 // [`map.getPanes`](#map-getpanes) methods. New panes can be created with the\r
25750                 // [`map.createPane`](#map-createpane) method.\r
25751                 //\r
25752                 // Every map has the following default panes that differ only in zIndex.\r
25753                 //\r
25754                 // @pane mapPane: HTMLElement = 'auto'\r
25755                 // Pane that contains all other map panes\r
25756 \r
25757                 this._mapPane = this.createPane('mapPane', this._container);\r
25758                 setPosition(this._mapPane, new Point(0, 0));\r
25759 \r
25760                 // @pane tilePane: HTMLElement = 200\r
25761                 // Pane for `GridLayer`s and `TileLayer`s\r
25762                 this.createPane('tilePane');\r
25763                 // @pane overlayPane: HTMLElement = 400\r
25764                 // Pane for overlay shadows (e.g. `Marker` shadows)\r
25765                 this.createPane('shadowPane');\r
25766                 // @pane shadowPane: HTMLElement = 500\r
25767                 // Pane for vectors (`Path`s, like `Polyline`s and `Polygon`s), `ImageOverlay`s and `VideoOverlay`s\r
25768                 this.createPane('overlayPane');\r
25769                 // @pane markerPane: HTMLElement = 600\r
25770                 // Pane for `Icon`s of `Marker`s\r
25771                 this.createPane('markerPane');\r
25772                 // @pane tooltipPane: HTMLElement = 650\r
25773                 // Pane for `Tooltip`s.\r
25774                 this.createPane('tooltipPane');\r
25775                 // @pane popupPane: HTMLElement = 700\r
25776                 // Pane for `Popup`s.\r
25777                 this.createPane('popupPane');\r
25778 \r
25779                 if (!this.options.markerZoomAnimation) {\r
25780                         addClass(panes.markerPane, 'leaflet-zoom-hide');\r
25781                         addClass(panes.shadowPane, 'leaflet-zoom-hide');\r
25782                 }\r
25783         },\r
25784 \r
25785 \r
25786         // private methods that modify map state\r
25787 \r
25788         // @section Map state change events\r
25789         _resetView: function (center, zoom) {\r
25790                 setPosition(this._mapPane, new Point(0, 0));\r
25791 \r
25792                 var loading = !this._loaded;\r
25793                 this._loaded = true;\r
25794                 zoom = this._limitZoom(zoom);\r
25795 \r
25796                 this.fire('viewprereset');\r
25797 \r
25798                 var zoomChanged = this._zoom !== zoom;\r
25799                 this\r
25800                         ._moveStart(zoomChanged, false)\r
25801                         ._move(center, zoom)\r
25802                         ._moveEnd(zoomChanged);\r
25803 \r
25804                 // @event viewreset: Event\r
25805                 // Fired when the map needs to redraw its content (this usually happens\r
25806                 // on map zoom or load). Very useful for creating custom overlays.\r
25807                 this.fire('viewreset');\r
25808 \r
25809                 // @event load: Event\r
25810                 // Fired when the map is initialized (when its center and zoom are set\r
25811                 // for the first time).\r
25812                 if (loading) {\r
25813                         this.fire('load');\r
25814                 }\r
25815         },\r
25816 \r
25817         _moveStart: function (zoomChanged, noMoveStart) {\r
25818                 // @event zoomstart: Event\r
25819                 // Fired when the map zoom is about to change (e.g. before zoom animation).\r
25820                 // @event movestart: Event\r
25821                 // Fired when the view of the map starts changing (e.g. user starts dragging the map).\r
25822                 if (zoomChanged) {\r
25823                         this.fire('zoomstart');\r
25824                 }\r
25825                 if (!noMoveStart) {\r
25826                         this.fire('movestart');\r
25827                 }\r
25828                 return this;\r
25829         },\r
25830 \r
25831         _move: function (center, zoom, data) {\r
25832                 if (zoom === undefined) {\r
25833                         zoom = this._zoom;\r
25834                 }\r
25835                 var zoomChanged = this._zoom !== zoom;\r
25836 \r
25837                 this._zoom = zoom;\r
25838                 this._lastCenter = center;\r
25839                 this._pixelOrigin = this._getNewPixelOrigin(center);\r
25840 \r
25841                 // @event zoom: Event\r
25842                 // Fired repeatedly during any change in zoom level, including zoom\r
25843                 // and fly animations.\r
25844                 if (zoomChanged || (data && data.pinch)) {      // Always fire 'zoom' if pinching because #3530\r
25845                         this.fire('zoom', data);\r
25846                 }\r
25847 \r
25848                 // @event move: Event\r
25849                 // Fired repeatedly during any movement of the map, including pan and\r
25850                 // fly animations.\r
25851                 return this.fire('move', data);\r
25852         },\r
25853 \r
25854         _moveEnd: function (zoomChanged) {\r
25855                 // @event zoomend: Event\r
25856                 // Fired when the map has changed, after any animations.\r
25857                 if (zoomChanged) {\r
25858                         this.fire('zoomend');\r
25859                 }\r
25860 \r
25861                 // @event moveend: Event\r
25862                 // Fired when the center of the map stops changing (e.g. user stopped\r
25863                 // dragging the map).\r
25864                 return this.fire('moveend');\r
25865         },\r
25866 \r
25867         _stop: function () {\r
25868                 cancelAnimFrame(this._flyToFrame);\r
25869                 if (this._panAnim) {\r
25870                         this._panAnim.stop();\r
25871                 }\r
25872                 return this;\r
25873         },\r
25874 \r
25875         _rawPanBy: function (offset) {\r
25876                 setPosition(this._mapPane, this._getMapPanePos().subtract(offset));\r
25877         },\r
25878 \r
25879         _getZoomSpan: function () {\r
25880                 return this.getMaxZoom() - this.getMinZoom();\r
25881         },\r
25882 \r
25883         _panInsideMaxBounds: function () {\r
25884                 if (!this._enforcingBounds) {\r
25885                         this.panInsideBounds(this.options.maxBounds);\r
25886                 }\r
25887         },\r
25888 \r
25889         _checkIfLoaded: function () {\r
25890                 if (!this._loaded) {\r
25891                         throw new Error('Set map center and zoom first.');\r
25892                 }\r
25893         },\r
25894 \r
25895         // DOM event handling\r
25896 \r
25897         // @section Interaction events\r
25898         _initEvents: function (remove$$1) {\r
25899                 this._targets = {};\r
25900                 this._targets[stamp(this._container)] = this;\r
25901 \r
25902                 var onOff = remove$$1 ? off : on;\r
25903 \r
25904                 // @event click: MouseEvent\r
25905                 // Fired when the user clicks (or taps) the map.\r
25906                 // @event dblclick: MouseEvent\r
25907                 // Fired when the user double-clicks (or double-taps) the map.\r
25908                 // @event mousedown: MouseEvent\r
25909                 // Fired when the user pushes the mouse button on the map.\r
25910                 // @event mouseup: MouseEvent\r
25911                 // Fired when the user releases the mouse button on the map.\r
25912                 // @event mouseover: MouseEvent\r
25913                 // Fired when the mouse enters the map.\r
25914                 // @event mouseout: MouseEvent\r
25915                 // Fired when the mouse leaves the map.\r
25916                 // @event mousemove: MouseEvent\r
25917                 // Fired while the mouse moves over the map.\r
25918                 // @event contextmenu: MouseEvent\r
25919                 // Fired when the user pushes the right mouse button on the map, prevents\r
25920                 // default browser context menu from showing if there are listeners on\r
25921                 // this event. Also fired on mobile when the user holds a single touch\r
25922                 // for a second (also called long press).\r
25923                 // @event keypress: KeyboardEvent\r
25924                 // Fired when the user presses a key from the keyboard that produces a character value while the map is focused.\r
25925                 // @event keydown: KeyboardEvent\r
25926                 // Fired when the user presses a key from the keyboard while the map is focused. Unlike the `keypress` event,\r
25927                 // the `keydown` event is fired for keys that produce a character value and for keys\r
25928                 // that do not produce a character value.\r
25929                 // @event keyup: KeyboardEvent\r
25930                 // Fired when the user releases a key from the keyboard while the map is focused.\r
25931                 onOff(this._container, 'click dblclick mousedown mouseup ' +\r
25932                         'mouseover mouseout mousemove contextmenu keypress keydown keyup', this._handleDOMEvent, this);\r
25933 \r
25934                 if (this.options.trackResize) {\r
25935                         onOff(window, 'resize', this._onResize, this);\r
25936                 }\r
25937 \r
25938                 if (any3d && this.options.transform3DLimit) {\r
25939                         (remove$$1 ? this.off : this.on).call(this, 'moveend', this._onMoveEnd);\r
25940                 }\r
25941         },\r
25942 \r
25943         _onResize: function () {\r
25944                 cancelAnimFrame(this._resizeRequest);\r
25945                 this._resizeRequest = requestAnimFrame(\r
25946                         function () { this.invalidateSize({debounceMoveend: true}); }, this);\r
25947         },\r
25948 \r
25949         _onScroll: function () {\r
25950                 this._container.scrollTop  = 0;\r
25951                 this._container.scrollLeft = 0;\r
25952         },\r
25953 \r
25954         _onMoveEnd: function () {\r
25955                 var pos = this._getMapPanePos();\r
25956                 if (Math.max(Math.abs(pos.x), Math.abs(pos.y)) >= this.options.transform3DLimit) {\r
25957                         // https://bugzilla.mozilla.org/show_bug.cgi?id=1203873 but Webkit also have\r
25958                         // a pixel offset on very high values, see: http://jsfiddle.net/dg6r5hhb/\r
25959                         this._resetView(this.getCenter(), this.getZoom());\r
25960                 }\r
25961         },\r
25962 \r
25963         _findEventTargets: function (e, type) {\r
25964                 var targets = [],\r
25965                     target,\r
25966                     isHover = type === 'mouseout' || type === 'mouseover',\r
25967                     src = e.target || e.srcElement,\r
25968                     dragging = false;\r
25969 \r
25970                 while (src) {\r
25971                         target = this._targets[stamp(src)];\r
25972                         if (target && (type === 'click' || type === 'preclick') && !e._simulated && this._draggableMoved(target)) {\r
25973                                 // Prevent firing click after you just dragged an object.\r
25974                                 dragging = true;\r
25975                                 break;\r
25976                         }\r
25977                         if (target && target.listens(type, true)) {\r
25978                                 if (isHover && !isExternalTarget(src, e)) { break; }\r
25979                                 targets.push(target);\r
25980                                 if (isHover) { break; }\r
25981                         }\r
25982                         if (src === this._container) { break; }\r
25983                         src = src.parentNode;\r
25984                 }\r
25985                 if (!targets.length && !dragging && !isHover && isExternalTarget(src, e)) {\r
25986                         targets = [this];\r
25987                 }\r
25988                 return targets;\r
25989         },\r
25990 \r
25991         _handleDOMEvent: function (e) {\r
25992                 if (!this._loaded || skipped(e)) { return; }\r
25993 \r
25994                 var type = e.type;\r
25995 \r
25996                 if (type === 'mousedown' || type === 'keypress' || type === 'keyup' || type === 'keydown') {\r
25997                         // prevents outline when clicking on keyboard-focusable element\r
25998                         preventOutline(e.target || e.srcElement);\r
25999                 }\r
26000 \r
26001                 this._fireDOMEvent(e, type);\r
26002         },\r
26003 \r
26004         _mouseEvents: ['click', 'dblclick', 'mouseover', 'mouseout', 'contextmenu'],\r
26005 \r
26006         _fireDOMEvent: function (e, type, targets) {\r
26007 \r
26008                 if (e.type === 'click') {\r
26009                         // Fire a synthetic 'preclick' event which propagates up (mainly for closing popups).\r
26010                         // @event preclick: MouseEvent\r
26011                         // Fired before mouse click on the map (sometimes useful when you\r
26012                         // want something to happen on click before any existing click\r
26013                         // handlers start running).\r
26014                         var synth = extend({}, e);\r
26015                         synth.type = 'preclick';\r
26016                         this._fireDOMEvent(synth, synth.type, targets);\r
26017                 }\r
26018 \r
26019                 if (e._stopped) { return; }\r
26020 \r
26021                 // Find the layer the event is propagating from and its parents.\r
26022                 targets = (targets || []).concat(this._findEventTargets(e, type));\r
26023 \r
26024                 if (!targets.length) { return; }\r
26025 \r
26026                 var target = targets[0];\r
26027                 if (type === 'contextmenu' && target.listens(type, true)) {\r
26028                         preventDefault(e);\r
26029                 }\r
26030 \r
26031                 var data = {\r
26032                         originalEvent: e\r
26033                 };\r
26034 \r
26035                 if (e.type !== 'keypress' && e.type !== 'keydown' && e.type !== 'keyup') {\r
26036                         var isMarker = target.getLatLng && (!target._radius || target._radius <= 10);\r
26037                         data.containerPoint = isMarker ?\r
26038                                 this.latLngToContainerPoint(target.getLatLng()) : this.mouseEventToContainerPoint(e);\r
26039                         data.layerPoint = this.containerPointToLayerPoint(data.containerPoint);\r
26040                         data.latlng = isMarker ? target.getLatLng() : this.layerPointToLatLng(data.layerPoint);\r
26041                 }\r
26042 \r
26043                 for (var i = 0; i < targets.length; i++) {\r
26044                         targets[i].fire(type, data, true);\r
26045                         if (data.originalEvent._stopped ||\r
26046                                 (targets[i].options.bubblingMouseEvents === false && indexOf(this._mouseEvents, type) !== -1)) { return; }\r
26047                 }\r
26048         },\r
26049 \r
26050         _draggableMoved: function (obj) {\r
26051                 obj = obj.dragging && obj.dragging.enabled() ? obj : this;\r
26052                 return (obj.dragging && obj.dragging.moved()) || (this.boxZoom && this.boxZoom.moved());\r
26053         },\r
26054 \r
26055         _clearHandlers: function () {\r
26056                 for (var i = 0, len = this._handlers.length; i < len; i++) {\r
26057                         this._handlers[i].disable();\r
26058                 }\r
26059         },\r
26060 \r
26061         // @section Other Methods\r
26062 \r
26063         // @method whenReady(fn: Function, context?: Object): this\r
26064         // Runs the given function `fn` when the map gets initialized with\r
26065         // a view (center and zoom) and at least one layer, or immediately\r
26066         // if it's already initialized, optionally passing a function context.\r
26067         whenReady: function (callback, context) {\r
26068                 if (this._loaded) {\r
26069                         callback.call(context || this, {target: this});\r
26070                 } else {\r
26071                         this.on('load', callback, context);\r
26072                 }\r
26073                 return this;\r
26074         },\r
26075 \r
26076 \r
26077         // private methods for getting map state\r
26078 \r
26079         _getMapPanePos: function () {\r
26080                 return getPosition(this._mapPane) || new Point(0, 0);\r
26081         },\r
26082 \r
26083         _moved: function () {\r
26084                 var pos = this._getMapPanePos();\r
26085                 return pos && !pos.equals([0, 0]);\r
26086         },\r
26087 \r
26088         _getTopLeftPoint: function (center, zoom) {\r
26089                 var pixelOrigin = center && zoom !== undefined ?\r
26090                         this._getNewPixelOrigin(center, zoom) :\r
26091                         this.getPixelOrigin();\r
26092                 return pixelOrigin.subtract(this._getMapPanePos());\r
26093         },\r
26094 \r
26095         _getNewPixelOrigin: function (center, zoom) {\r
26096                 var viewHalf = this.getSize()._divideBy(2);\r
26097                 return this.project(center, zoom)._subtract(viewHalf)._add(this._getMapPanePos())._round();\r
26098         },\r
26099 \r
26100         _latLngToNewLayerPoint: function (latlng, zoom, center) {\r
26101                 var topLeft = this._getNewPixelOrigin(center, zoom);\r
26102                 return this.project(latlng, zoom)._subtract(topLeft);\r
26103         },\r
26104 \r
26105         _latLngBoundsToNewLayerBounds: function (latLngBounds, zoom, center) {\r
26106                 var topLeft = this._getNewPixelOrigin(center, zoom);\r
26107                 return toBounds([\r
26108                         this.project(latLngBounds.getSouthWest(), zoom)._subtract(topLeft),\r
26109                         this.project(latLngBounds.getNorthWest(), zoom)._subtract(topLeft),\r
26110                         this.project(latLngBounds.getSouthEast(), zoom)._subtract(topLeft),\r
26111                         this.project(latLngBounds.getNorthEast(), zoom)._subtract(topLeft)\r
26112                 ]);\r
26113         },\r
26114 \r
26115         // layer point of the current center\r
26116         _getCenterLayerPoint: function () {\r
26117                 return this.containerPointToLayerPoint(this.getSize()._divideBy(2));\r
26118         },\r
26119 \r
26120         // offset of the specified place to the current center in pixels\r
26121         _getCenterOffset: function (latlng) {\r
26122                 return this.latLngToLayerPoint(latlng).subtract(this._getCenterLayerPoint());\r
26123         },\r
26124 \r
26125         // adjust center for view to get inside bounds\r
26126         _limitCenter: function (center, zoom, bounds) {\r
26127 \r
26128                 if (!bounds) { return center; }\r
26129 \r
26130                 var centerPoint = this.project(center, zoom),\r
26131                     viewHalf = this.getSize().divideBy(2),\r
26132                     viewBounds = new Bounds(centerPoint.subtract(viewHalf), centerPoint.add(viewHalf)),\r
26133                     offset = this._getBoundsOffset(viewBounds, bounds, zoom);\r
26134 \r
26135                 // If offset is less than a pixel, ignore.\r
26136                 // This prevents unstable projections from getting into\r
26137                 // an infinite loop of tiny offsets.\r
26138                 if (offset.round().equals([0, 0])) {\r
26139                         return center;\r
26140                 }\r
26141 \r
26142                 return this.unproject(centerPoint.add(offset), zoom);\r
26143         },\r
26144 \r
26145         // adjust offset for view to get inside bounds\r
26146         _limitOffset: function (offset, bounds) {\r
26147                 if (!bounds) { return offset; }\r
26148 \r
26149                 var viewBounds = this.getPixelBounds(),\r
26150                     newBounds = new Bounds(viewBounds.min.add(offset), viewBounds.max.add(offset));\r
26151 \r
26152                 return offset.add(this._getBoundsOffset(newBounds, bounds));\r
26153         },\r
26154 \r
26155         // returns offset needed for pxBounds to get inside maxBounds at a specified zoom\r
26156         _getBoundsOffset: function (pxBounds, maxBounds, zoom) {\r
26157                 var projectedMaxBounds = toBounds(\r
26158                         this.project(maxBounds.getNorthEast(), zoom),\r
26159                         this.project(maxBounds.getSouthWest(), zoom)\r
26160                     ),\r
26161                     minOffset = projectedMaxBounds.min.subtract(pxBounds.min),\r
26162                     maxOffset = projectedMaxBounds.max.subtract(pxBounds.max),\r
26163 \r
26164                     dx = this._rebound(minOffset.x, -maxOffset.x),\r
26165                     dy = this._rebound(minOffset.y, -maxOffset.y);\r
26166 \r
26167                 return new Point(dx, dy);\r
26168         },\r
26169 \r
26170         _rebound: function (left, right) {\r
26171                 return left + right > 0 ?\r
26172                         Math.round(left - right) / 2 :\r
26173                         Math.max(0, Math.ceil(left)) - Math.max(0, Math.floor(right));\r
26174         },\r
26175 \r
26176         _limitZoom: function (zoom) {\r
26177                 var min = this.getMinZoom(),\r
26178                     max = this.getMaxZoom(),\r
26179                     snap = any3d ? this.options.zoomSnap : 1;\r
26180                 if (snap) {\r
26181                         zoom = Math.round(zoom / snap) * snap;\r
26182                 }\r
26183                 return Math.max(min, Math.min(max, zoom));\r
26184         },\r
26185 \r
26186         _onPanTransitionStep: function () {\r
26187                 this.fire('move');\r
26188         },\r
26189 \r
26190         _onPanTransitionEnd: function () {\r
26191                 removeClass(this._mapPane, 'leaflet-pan-anim');\r
26192                 this.fire('moveend');\r
26193         },\r
26194 \r
26195         _tryAnimatedPan: function (center, options) {\r
26196                 // difference between the new and current centers in pixels\r
26197                 var offset = this._getCenterOffset(center)._trunc();\r
26198 \r
26199                 // don't animate too far unless animate: true specified in options\r
26200                 if ((options && options.animate) !== true && !this.getSize().contains(offset)) { return false; }\r
26201 \r
26202                 this.panBy(offset, options);\r
26203 \r
26204                 return true;\r
26205         },\r
26206 \r
26207         _createAnimProxy: function () {\r
26208 \r
26209                 var proxy = this._proxy = create$1('div', 'leaflet-proxy leaflet-zoom-animated');\r
26210                 this._panes.mapPane.appendChild(proxy);\r
26211 \r
26212                 this.on('zoomanim', function (e) {\r
26213                         var prop = TRANSFORM,\r
26214                             transform = this._proxy.style[prop];\r
26215 \r
26216                         setTransform(this._proxy, this.project(e.center, e.zoom), this.getZoomScale(e.zoom, 1));\r
26217 \r
26218                         // workaround for case when transform is the same and so transitionend event is not fired\r
26219                         if (transform === this._proxy.style[prop] && this._animatingZoom) {\r
26220                                 this._onZoomTransitionEnd();\r
26221                         }\r
26222                 }, this);\r
26223 \r
26224                 this.on('load moveend', this._animMoveEnd, this);\r
26225 \r
26226                 this._on('unload', this._destroyAnimProxy, this);\r
26227         },\r
26228 \r
26229         _destroyAnimProxy: function () {\r
26230                 remove(this._proxy);\r
26231                 this.off('load moveend', this._animMoveEnd, this);\r
26232                 delete this._proxy;\r
26233         },\r
26234 \r
26235         _animMoveEnd: function () {\r
26236                 var c = this.getCenter(),\r
26237                     z = this.getZoom();\r
26238                 setTransform(this._proxy, this.project(c, z), this.getZoomScale(z, 1));\r
26239         },\r
26240 \r
26241         _catchTransitionEnd: function (e) {\r
26242                 if (this._animatingZoom && e.propertyName.indexOf('transform') >= 0) {\r
26243                         this._onZoomTransitionEnd();\r
26244                 }\r
26245         },\r
26246 \r
26247         _nothingToAnimate: function () {\r
26248                 return !this._container.getElementsByClassName('leaflet-zoom-animated').length;\r
26249         },\r
26250 \r
26251         _tryAnimatedZoom: function (center, zoom, options) {\r
26252 \r
26253                 if (this._animatingZoom) { return true; }\r
26254 \r
26255                 options = options || {};\r
26256 \r
26257                 // don't animate if disabled, not supported or zoom difference is too large\r
26258                 if (!this._zoomAnimated || options.animate === false || this._nothingToAnimate() ||\r
26259                         Math.abs(zoom - this._zoom) > this.options.zoomAnimationThreshold) { return false; }\r
26260 \r
26261                 // offset is the pixel coords of the zoom origin relative to the current center\r
26262                 var scale = this.getZoomScale(zoom),\r
26263                     offset = this._getCenterOffset(center)._divideBy(1 - 1 / scale);\r
26264 \r
26265                 // don't animate if the zoom origin isn't within one screen from the current center, unless forced\r
26266                 if (options.animate !== true && !this.getSize().contains(offset)) { return false; }\r
26267 \r
26268                 requestAnimFrame(function () {\r
26269                         this\r
26270                             ._moveStart(true, false)\r
26271                             ._animateZoom(center, zoom, true);\r
26272                 }, this);\r
26273 \r
26274                 return true;\r
26275         },\r
26276 \r
26277         _animateZoom: function (center, zoom, startAnim, noUpdate) {\r
26278                 if (!this._mapPane) { return; }\r
26279 \r
26280                 if (startAnim) {\r
26281                         this._animatingZoom = true;\r
26282 \r
26283                         // remember what center/zoom to set after animation\r
26284                         this._animateToCenter = center;\r
26285                         this._animateToZoom = zoom;\r
26286 \r
26287                         addClass(this._mapPane, 'leaflet-zoom-anim');\r
26288                 }\r
26289 \r
26290                 // @section Other Events\r
26291                 // @event zoomanim: ZoomAnimEvent\r
26292                 // Fired at least once per zoom animation. For continuous zoom, like pinch zooming, fired once per frame during zoom.\r
26293                 this.fire('zoomanim', {\r
26294                         center: center,\r
26295                         zoom: zoom,\r
26296                         noUpdate: noUpdate\r
26297                 });\r
26298 \r
26299                 // Work around webkit not firing 'transitionend', see https://github.com/Leaflet/Leaflet/issues/3689, 2693\r
26300                 setTimeout(bind(this._onZoomTransitionEnd, this), 250);\r
26301         },\r
26302 \r
26303         _onZoomTransitionEnd: function () {\r
26304                 if (!this._animatingZoom) { return; }\r
26305 \r
26306                 if (this._mapPane) {\r
26307                         removeClass(this._mapPane, 'leaflet-zoom-anim');\r
26308                 }\r
26309 \r
26310                 this._animatingZoom = false;\r
26311 \r
26312                 this._move(this._animateToCenter, this._animateToZoom);\r
26313 \r
26314                 // This anim frame should prevent an obscure iOS webkit tile loading race condition.\r
26315                 requestAnimFrame(function () {\r
26316                         this._moveEnd(true);\r
26317                 }, this);\r
26318         }\r
26319       });\r
26320 \r
26321       // @section\r
26322 \r
26323       // @factory L.map(id: String, options?: Map options)\r
26324       // Instantiates a map object given the DOM ID of a `<div>` element\r
26325       // and optionally an object literal with `Map options`.\r
26326       //\r
26327       // @alternative\r
26328       // @factory L.map(el: HTMLElement, options?: Map options)\r
26329       // Instantiates a map object given an instance of a `<div>` HTML element\r
26330       // and optionally an object literal with `Map options`.\r
26331       function createMap(id, options) {\r
26332         return new Map(id, options);\r
26333       }
26334
26335       /*\r
26336        * @class Control\r
26337        * @aka L.Control\r
26338        * @inherits Class\r
26339        *\r
26340        * L.Control is a base class for implementing map controls. Handles positioning.\r
26341        * All other controls extend from this class.\r
26342        */\r
26343 \r
26344       var Control = Class.extend({\r
26345         // @section\r
26346         // @aka Control options\r
26347         options: {\r
26348                 // @option position: String = 'topright'\r
26349                 // The position of the control (one of the map corners). Possible values are `'topleft'`,\r
26350                 // `'topright'`, `'bottomleft'` or `'bottomright'`\r
26351                 position: 'topright'\r
26352         },\r
26353 \r
26354         initialize: function (options) {\r
26355                 setOptions(this, options);\r
26356         },\r
26357 \r
26358         /* @section\r
26359          * Classes extending L.Control will inherit the following methods:\r
26360          *\r
26361          * @method getPosition: string\r
26362          * Returns the position of the control.\r
26363          */\r
26364         getPosition: function () {\r
26365                 return this.options.position;\r
26366         },\r
26367 \r
26368         // @method setPosition(position: string): this\r
26369         // Sets the position of the control.\r
26370         setPosition: function (position) {\r
26371                 var map = this._map;\r
26372 \r
26373                 if (map) {\r
26374                         map.removeControl(this);\r
26375                 }\r
26376 \r
26377                 this.options.position = position;\r
26378 \r
26379                 if (map) {\r
26380                         map.addControl(this);\r
26381                 }\r
26382 \r
26383                 return this;\r
26384         },\r
26385 \r
26386         // @method getContainer: HTMLElement\r
26387         // Returns the HTMLElement that contains the control.\r
26388         getContainer: function () {\r
26389                 return this._container;\r
26390         },\r
26391 \r
26392         // @method addTo(map: Map): this\r
26393         // Adds the control to the given map.\r
26394         addTo: function (map) {\r
26395                 this.remove();\r
26396                 this._map = map;\r
26397 \r
26398                 var container = this._container = this.onAdd(map),\r
26399                     pos = this.getPosition(),\r
26400                     corner = map._controlCorners[pos];\r
26401 \r
26402                 addClass(container, 'leaflet-control');\r
26403 \r
26404                 if (pos.indexOf('bottom') !== -1) {\r
26405                         corner.insertBefore(container, corner.firstChild);\r
26406                 } else {\r
26407                         corner.appendChild(container);\r
26408                 }\r
26409 \r
26410                 this._map.on('unload', this.remove, this);\r
26411 \r
26412                 return this;\r
26413         },\r
26414 \r
26415         // @method remove: this\r
26416         // Removes the control from the map it is currently active on.\r
26417         remove: function () {\r
26418                 if (!this._map) {\r
26419                         return this;\r
26420                 }\r
26421 \r
26422                 remove(this._container);\r
26423 \r
26424                 if (this.onRemove) {\r
26425                         this.onRemove(this._map);\r
26426                 }\r
26427 \r
26428                 this._map.off('unload', this.remove, this);\r
26429                 this._map = null;\r
26430 \r
26431                 return this;\r
26432         },\r
26433 \r
26434         _refocusOnMap: function (e) {\r
26435                 // if map exists and event is not a keyboard event\r
26436                 if (this._map && e && e.screenX > 0 && e.screenY > 0) {\r
26437                         this._map.getContainer().focus();\r
26438                 }\r
26439         }\r
26440       });\r
26441 \r
26442       var control = function (options) {\r
26443         return new Control(options);\r
26444       };\r
26445 \r
26446       /* @section Extension methods\r
26447        * @uninheritable\r
26448        *\r
26449        * Every control should extend from `L.Control` and (re-)implement the following methods.\r
26450        *\r
26451        * @method onAdd(map: Map): HTMLElement\r
26452        * Should return the container DOM element for the control and add listeners on relevant map events. Called on [`control.addTo(map)`](#control-addTo).\r
26453        *\r
26454        * @method onRemove(map: Map)\r
26455        * Optional method. Should contain all clean up code that removes the listeners previously added in [`onAdd`](#control-onadd). Called on [`control.remove()`](#control-remove).\r
26456        */\r
26457 \r
26458       /* @namespace Map\r
26459        * @section Methods for Layers and Controls\r
26460        */\r
26461       Map.include({\r
26462         // @method addControl(control: Control): this\r
26463         // Adds the given control to the map\r
26464         addControl: function (control) {\r
26465                 control.addTo(this);\r
26466                 return this;\r
26467         },\r
26468 \r
26469         // @method removeControl(control: Control): this\r
26470         // Removes the given control from the map\r
26471         removeControl: function (control) {\r
26472                 control.remove();\r
26473                 return this;\r
26474         },\r
26475 \r
26476         _initControlPos: function () {\r
26477                 var corners = this._controlCorners = {},\r
26478                     l = 'leaflet-',\r
26479                     container = this._controlContainer =\r
26480                             create$1('div', l + 'control-container', this._container);\r
26481 \r
26482                 function createCorner(vSide, hSide) {\r
26483                         var className = l + vSide + ' ' + l + hSide;\r
26484 \r
26485                         corners[vSide + hSide] = create$1('div', className, container);\r
26486                 }\r
26487 \r
26488                 createCorner('top', 'left');\r
26489                 createCorner('top', 'right');\r
26490                 createCorner('bottom', 'left');\r
26491                 createCorner('bottom', 'right');\r
26492         },\r
26493 \r
26494         _clearControlPos: function () {\r
26495                 for (var i in this._controlCorners) {\r
26496                         remove(this._controlCorners[i]);\r
26497                 }\r
26498                 remove(this._controlContainer);\r
26499                 delete this._controlCorners;\r
26500                 delete this._controlContainer;\r
26501         }\r
26502       });
26503
26504       /*\r
26505        * @class Control.Layers\r
26506        * @aka L.Control.Layers\r
26507        * @inherits Control\r
26508        *\r
26509        * The layers control gives users the ability to switch between different base layers and switch overlays on/off (check out the [detailed example](http://leafletjs.com/examples/layers-control/)). Extends `Control`.\r
26510        *\r
26511        * @example\r
26512        *\r
26513        * ```js\r
26514        * var baseLayers = {\r
26515        *        "Mapbox": mapbox,\r
26516        *        "OpenStreetMap": osm\r
26517        * };\r
26518        *\r
26519        * var overlays = {\r
26520        *        "Marker": marker,\r
26521        *        "Roads": roadsLayer\r
26522        * };\r
26523        *\r
26524        * L.control.layers(baseLayers, overlays).addTo(map);\r
26525        * ```\r
26526        *\r
26527        * The `baseLayers` and `overlays` parameters are object literals with layer names as keys and `Layer` objects as values:\r
26528        *\r
26529        * ```js\r
26530        * {\r
26531        *     "<someName1>": layer1,\r
26532        *     "<someName2>": layer2\r
26533        * }\r
26534        * ```\r
26535        *\r
26536        * The layer names can contain HTML, which allows you to add additional styling to the items:\r
26537        *\r
26538        * ```js\r
26539        * {"<img src='my-layer-icon' /> <span class='my-layer-item'>My Layer</span>": myLayer}\r
26540        * ```\r
26541        */\r
26542 \r
26543       var Layers = Control.extend({\r
26544         // @section\r
26545         // @aka Control.Layers options\r
26546         options: {\r
26547                 // @option collapsed: Boolean = true\r
26548                 // If `true`, the control will be collapsed into an icon and expanded on mouse hover or touch.\r
26549                 collapsed: true,\r
26550                 position: 'topright',\r
26551 \r
26552                 // @option autoZIndex: Boolean = true\r
26553                 // If `true`, the control will assign zIndexes in increasing order to all of its layers so that the order is preserved when switching them on/off.\r
26554                 autoZIndex: true,\r
26555 \r
26556                 // @option hideSingleBase: Boolean = false\r
26557                 // If `true`, the base layers in the control will be hidden when there is only one.\r
26558                 hideSingleBase: false,\r
26559 \r
26560                 // @option sortLayers: Boolean = false\r
26561                 // Whether to sort the layers. When `false`, layers will keep the order\r
26562                 // in which they were added to the control.\r
26563                 sortLayers: false,\r
26564 \r
26565                 // @option sortFunction: Function = *\r
26566                 // A [compare function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)\r
26567                 // that will be used for sorting the layers, when `sortLayers` is `true`.\r
26568                 // The function receives both the `L.Layer` instances and their names, as in\r
26569                 // `sortFunction(layerA, layerB, nameA, nameB)`.\r
26570                 // By default, it sorts layers alphabetically by their name.\r
26571                 sortFunction: function (layerA, layerB, nameA, nameB) {\r
26572                         return nameA < nameB ? -1 : (nameB < nameA ? 1 : 0);\r
26573                 }\r
26574         },\r
26575 \r
26576         initialize: function (baseLayers, overlays, options) {\r
26577                 setOptions(this, options);\r
26578 \r
26579                 this._layerControlInputs = [];\r
26580                 this._layers = [];\r
26581                 this._lastZIndex = 0;\r
26582                 this._handlingClick = false;\r
26583 \r
26584                 for (var i in baseLayers) {\r
26585                         this._addLayer(baseLayers[i], i);\r
26586                 }\r
26587 \r
26588                 for (i in overlays) {\r
26589                         this._addLayer(overlays[i], i, true);\r
26590                 }\r
26591         },\r
26592 \r
26593         onAdd: function (map) {\r
26594                 this._initLayout();\r
26595                 this._update();\r
26596 \r
26597                 this._map = map;\r
26598                 map.on('zoomend', this._checkDisabledLayers, this);\r
26599 \r
26600                 for (var i = 0; i < this._layers.length; i++) {\r
26601                         this._layers[i].layer.on('add remove', this._onLayerChange, this);\r
26602                 }\r
26603 \r
26604                 return this._container;\r
26605         },\r
26606 \r
26607         addTo: function (map) {\r
26608                 Control.prototype.addTo.call(this, map);\r
26609                 // Trigger expand after Layers Control has been inserted into DOM so that is now has an actual height.\r
26610                 return this._expandIfNotCollapsed();\r
26611         },\r
26612 \r
26613         onRemove: function () {\r
26614                 this._map.off('zoomend', this._checkDisabledLayers, this);\r
26615 \r
26616                 for (var i = 0; i < this._layers.length; i++) {\r
26617                         this._layers[i].layer.off('add remove', this._onLayerChange, this);\r
26618                 }\r
26619         },\r
26620 \r
26621         // @method addBaseLayer(layer: Layer, name: String): this\r
26622         // Adds a base layer (radio button entry) with the given name to the control.\r
26623         addBaseLayer: function (layer, name) {\r
26624                 this._addLayer(layer, name);\r
26625                 return (this._map) ? this._update() : this;\r
26626         },\r
26627 \r
26628         // @method addOverlay(layer: Layer, name: String): this\r
26629         // Adds an overlay (checkbox entry) with the given name to the control.\r
26630         addOverlay: function (layer, name) {\r
26631                 this._addLayer(layer, name, true);\r
26632                 return (this._map) ? this._update() : this;\r
26633         },\r
26634 \r
26635         // @method removeLayer(layer: Layer): this\r
26636         // Remove the given layer from the control.\r
26637         removeLayer: function (layer) {\r
26638                 layer.off('add remove', this._onLayerChange, this);\r
26639 \r
26640                 var obj = this._getLayer(stamp(layer));\r
26641                 if (obj) {\r
26642                         this._layers.splice(this._layers.indexOf(obj), 1);\r
26643                 }\r
26644                 return (this._map) ? this._update() : this;\r
26645         },\r
26646 \r
26647         // @method expand(): this\r
26648         // Expand the control container if collapsed.\r
26649         expand: function () {\r
26650                 addClass(this._container, 'leaflet-control-layers-expanded');\r
26651                 this._section.style.height = null;\r
26652                 var acceptableHeight = this._map.getSize().y - (this._container.offsetTop + 50);\r
26653                 if (acceptableHeight < this._section.clientHeight) {\r
26654                         addClass(this._section, 'leaflet-control-layers-scrollbar');\r
26655                         this._section.style.height = acceptableHeight + 'px';\r
26656                 } else {\r
26657                         removeClass(this._section, 'leaflet-control-layers-scrollbar');\r
26658                 }\r
26659                 this._checkDisabledLayers();\r
26660                 return this;\r
26661         },\r
26662 \r
26663         // @method collapse(): this\r
26664         // Collapse the control container if expanded.\r
26665         collapse: function () {\r
26666                 removeClass(this._container, 'leaflet-control-layers-expanded');\r
26667                 return this;\r
26668         },\r
26669 \r
26670         _initLayout: function () {\r
26671                 var className = 'leaflet-control-layers',\r
26672                     container = this._container = create$1('div', className),\r
26673                     collapsed = this.options.collapsed;\r
26674 \r
26675                 // makes this work on IE touch devices by stopping it from firing a mouseout event when the touch is released\r
26676                 container.setAttribute('aria-haspopup', true);\r
26677 \r
26678                 disableClickPropagation(container);\r
26679                 disableScrollPropagation(container);\r
26680 \r
26681                 var section = this._section = create$1('section', className + '-list');\r
26682 \r
26683                 if (collapsed) {\r
26684                         this._map.on('click', this.collapse, this);\r
26685 \r
26686                         if (!android) {\r
26687                                 on(container, {\r
26688                                         mouseenter: this.expand,\r
26689                                         mouseleave: this.collapse\r
26690                                 }, this);\r
26691                         }\r
26692                 }\r
26693 \r
26694                 var link = this._layersLink = create$1('a', className + '-toggle', container);\r
26695                 link.href = '#';\r
26696                 link.title = 'Layers';\r
26697 \r
26698                 if (touch) {\r
26699                         on(link, 'click', stop);\r
26700                         on(link, 'click', this.expand, this);\r
26701                 } else {\r
26702                         on(link, 'focus', this.expand, this);\r
26703                 }\r
26704 \r
26705                 if (!collapsed) {\r
26706                         this.expand();\r
26707                 }\r
26708 \r
26709                 this._baseLayersList = create$1('div', className + '-base', section);\r
26710                 this._separator = create$1('div', className + '-separator', section);\r
26711                 this._overlaysList = create$1('div', className + '-overlays', section);\r
26712 \r
26713                 container.appendChild(section);\r
26714         },\r
26715 \r
26716         _getLayer: function (id) {\r
26717                 for (var i = 0; i < this._layers.length; i++) {\r
26718 \r
26719                         if (this._layers[i] && stamp(this._layers[i].layer) === id) {\r
26720                                 return this._layers[i];\r
26721                         }\r
26722                 }\r
26723         },\r
26724 \r
26725         _addLayer: function (layer, name, overlay) {\r
26726                 if (this._map) {\r
26727                         layer.on('add remove', this._onLayerChange, this);\r
26728                 }\r
26729 \r
26730                 this._layers.push({\r
26731                         layer: layer,\r
26732                         name: name,\r
26733                         overlay: overlay\r
26734                 });\r
26735 \r
26736                 if (this.options.sortLayers) {\r
26737                         this._layers.sort(bind(function (a, b) {\r
26738                                 return this.options.sortFunction(a.layer, b.layer, a.name, b.name);\r
26739                         }, this));\r
26740                 }\r
26741 \r
26742                 if (this.options.autoZIndex && layer.setZIndex) {\r
26743                         this._lastZIndex++;\r
26744                         layer.setZIndex(this._lastZIndex);\r
26745                 }\r
26746 \r
26747                 this._expandIfNotCollapsed();\r
26748         },\r
26749 \r
26750         _update: function () {\r
26751                 if (!this._container) { return this; }\r
26752 \r
26753                 empty(this._baseLayersList);\r
26754                 empty(this._overlaysList);\r
26755 \r
26756                 this._layerControlInputs = [];\r
26757                 var baseLayersPresent, overlaysPresent, i, obj, baseLayersCount = 0;\r
26758 \r
26759                 for (i = 0; i < this._layers.length; i++) {\r
26760                         obj = this._layers[i];\r
26761                         this._addItem(obj);\r
26762                         overlaysPresent = overlaysPresent || obj.overlay;\r
26763                         baseLayersPresent = baseLayersPresent || !obj.overlay;\r
26764                         baseLayersCount += !obj.overlay ? 1 : 0;\r
26765                 }\r
26766 \r
26767                 // Hide base layers section if there's only one layer.\r
26768                 if (this.options.hideSingleBase) {\r
26769                         baseLayersPresent = baseLayersPresent && baseLayersCount > 1;\r
26770                         this._baseLayersList.style.display = baseLayersPresent ? '' : 'none';\r
26771                 }\r
26772 \r
26773                 this._separator.style.display = overlaysPresent && baseLayersPresent ? '' : 'none';\r
26774 \r
26775                 return this;\r
26776         },\r
26777 \r
26778         _onLayerChange: function (e) {\r
26779                 if (!this._handlingClick) {\r
26780                         this._update();\r
26781                 }\r
26782 \r
26783                 var obj = this._getLayer(stamp(e.target));\r
26784 \r
26785                 // @namespace Map\r
26786                 // @section Layer events\r
26787                 // @event baselayerchange: LayersControlEvent\r
26788                 // Fired when the base layer is changed through the [layers control](#control-layers).\r
26789                 // @event overlayadd: LayersControlEvent\r
26790                 // Fired when an overlay is selected through the [layers control](#control-layers).\r
26791                 // @event overlayremove: LayersControlEvent\r
26792                 // Fired when an overlay is deselected through the [layers control](#control-layers).\r
26793                 // @namespace Control.Layers\r
26794                 var type = obj.overlay ?\r
26795                         (e.type === 'add' ? 'overlayadd' : 'overlayremove') :\r
26796                         (e.type === 'add' ? 'baselayerchange' : null);\r
26797 \r
26798                 if (type) {\r
26799                         this._map.fire(type, obj);\r
26800                 }\r
26801         },\r
26802 \r
26803         // IE7 bugs out if you create a radio dynamically, so you have to do it this hacky way (see http://bit.ly/PqYLBe)\r
26804         _createRadioElement: function (name, checked) {\r
26805 \r
26806                 var radioHtml = '<input type="radio" class="leaflet-control-layers-selector" name="' +\r
26807                                 name + '"' + (checked ? ' checked="checked"' : '') + '/>';\r
26808 \r
26809                 var radioFragment = document.createElement('div');\r
26810                 radioFragment.innerHTML = radioHtml;\r
26811 \r
26812                 return radioFragment.firstChild;\r
26813         },\r
26814 \r
26815         _addItem: function (obj) {\r
26816                 var label = document.createElement('label'),\r
26817                     checked = this._map.hasLayer(obj.layer),\r
26818                     input;\r
26819 \r
26820                 if (obj.overlay) {\r
26821                         input = document.createElement('input');\r
26822                         input.type = 'checkbox';\r
26823                         input.className = 'leaflet-control-layers-selector';\r
26824                         input.defaultChecked = checked;\r
26825                 } else {\r
26826                         input = this._createRadioElement('leaflet-base-layers_' + stamp(this), checked);\r
26827                 }\r
26828 \r
26829                 this._layerControlInputs.push(input);\r
26830                 input.layerId = stamp(obj.layer);\r
26831 \r
26832                 on(input, 'click', this._onInputClick, this);\r
26833 \r
26834                 var name = document.createElement('span');\r
26835                 name.innerHTML = ' ' + obj.name;\r
26836 \r
26837                 // Helps from preventing layer control flicker when checkboxes are disabled\r
26838                 // https://github.com/Leaflet/Leaflet/issues/2771\r
26839                 var holder = document.createElement('div');\r
26840 \r
26841                 label.appendChild(holder);\r
26842                 holder.appendChild(input);\r
26843                 holder.appendChild(name);\r
26844 \r
26845                 var container = obj.overlay ? this._overlaysList : this._baseLayersList;\r
26846                 container.appendChild(label);\r
26847 \r
26848                 this._checkDisabledLayers();\r
26849                 return label;\r
26850         },\r
26851 \r
26852         _onInputClick: function () {\r
26853                 var inputs = this._layerControlInputs,\r
26854                     input, layer;\r
26855                 var addedLayers = [],\r
26856                     removedLayers = [];\r
26857 \r
26858                 this._handlingClick = true;\r
26859 \r
26860                 for (var i = inputs.length - 1; i >= 0; i--) {\r
26861                         input = inputs[i];\r
26862                         layer = this._getLayer(input.layerId).layer;\r
26863 \r
26864                         if (input.checked) {\r
26865                                 addedLayers.push(layer);\r
26866                         } else if (!input.checked) {\r
26867                                 removedLayers.push(layer);\r
26868                         }\r
26869                 }\r
26870 \r
26871                 // Bugfix issue 2318: Should remove all old layers before readding new ones\r
26872                 for (i = 0; i < removedLayers.length; i++) {\r
26873                         if (this._map.hasLayer(removedLayers[i])) {\r
26874                                 this._map.removeLayer(removedLayers[i]);\r
26875                         }\r
26876                 }\r
26877                 for (i = 0; i < addedLayers.length; i++) {\r
26878                         if (!this._map.hasLayer(addedLayers[i])) {\r
26879                                 this._map.addLayer(addedLayers[i]);\r
26880                         }\r
26881                 }\r
26882 \r
26883                 this._handlingClick = false;\r
26884 \r
26885                 this._refocusOnMap();\r
26886         },\r
26887 \r
26888         _checkDisabledLayers: function () {\r
26889                 var inputs = this._layerControlInputs,\r
26890                     input,\r
26891                     layer,\r
26892                     zoom = this._map.getZoom();\r
26893 \r
26894                 for (var i = inputs.length - 1; i >= 0; i--) {\r
26895                         input = inputs[i];\r
26896                         layer = this._getLayer(input.layerId).layer;\r
26897                         input.disabled = (layer.options.minZoom !== undefined && zoom < layer.options.minZoom) ||\r
26898                                          (layer.options.maxZoom !== undefined && zoom > layer.options.maxZoom);\r
26899 \r
26900                 }\r
26901         },\r
26902 \r
26903         _expandIfNotCollapsed: function () {\r
26904                 if (this._map && !this.options.collapsed) {\r
26905                         this.expand();\r
26906                 }\r
26907                 return this;\r
26908         },\r
26909 \r
26910         _expand: function () {\r
26911                 // Backward compatibility, remove me in 1.1.\r
26912                 return this.expand();\r
26913         },\r
26914 \r
26915         _collapse: function () {\r
26916                 // Backward compatibility, remove me in 1.1.\r
26917                 return this.collapse();\r
26918         }\r
26919 \r
26920       });\r
26921 \r
26922 \r
26923       // @factory L.control.layers(baselayers?: Object, overlays?: Object, options?: Control.Layers options)\r
26924       // Creates a layers control with the given layers. Base layers will be switched with radio buttons, while overlays will be switched with checkboxes. Note that all base layers should be passed in the base layers object, but only one should be added to the map during map instantiation.\r
26925       var layers = function (baseLayers, overlays, options) {\r
26926         return new Layers(baseLayers, overlays, options);\r
26927       };
26928
26929       /*\r
26930        * @class Control.Zoom\r
26931        * @aka L.Control.Zoom\r
26932        * @inherits Control\r
26933        *\r
26934        * A basic zoom control with two buttons (zoom in and zoom out). It is put on the map by default unless you set its [`zoomControl` option](#map-zoomcontrol) to `false`. Extends `Control`.\r
26935        */\r
26936 \r
26937       var Zoom = Control.extend({\r
26938         // @section\r
26939         // @aka Control.Zoom options\r
26940         options: {\r
26941                 position: 'topleft',\r
26942 \r
26943                 // @option zoomInText: String = '+'\r
26944                 // The text set on the 'zoom in' button.\r
26945                 zoomInText: '+',\r
26946 \r
26947                 // @option zoomInTitle: String = 'Zoom in'\r
26948                 // The title set on the 'zoom in' button.\r
26949                 zoomInTitle: 'Zoom in',\r
26950 \r
26951                 // @option zoomOutText: String = '&#x2212;'\r
26952                 // The text set on the 'zoom out' button.\r
26953                 zoomOutText: '&#x2212;',\r
26954 \r
26955                 // @option zoomOutTitle: String = 'Zoom out'\r
26956                 // The title set on the 'zoom out' button.\r
26957                 zoomOutTitle: 'Zoom out'\r
26958         },\r
26959 \r
26960         onAdd: function (map) {\r
26961                 var zoomName = 'leaflet-control-zoom',\r
26962                     container = create$1('div', zoomName + ' leaflet-bar'),\r
26963                     options = this.options;\r
26964 \r
26965                 this._zoomInButton  = this._createButton(options.zoomInText, options.zoomInTitle,\r
26966                         zoomName + '-in',  container, this._zoomIn);\r
26967                 this._zoomOutButton = this._createButton(options.zoomOutText, options.zoomOutTitle,\r
26968                         zoomName + '-out', container, this._zoomOut);\r
26969 \r
26970                 this._updateDisabled();\r
26971                 map.on('zoomend zoomlevelschange', this._updateDisabled, this);\r
26972 \r
26973                 return container;\r
26974         },\r
26975 \r
26976         onRemove: function (map) {\r
26977                 map.off('zoomend zoomlevelschange', this._updateDisabled, this);\r
26978         },\r
26979 \r
26980         disable: function () {\r
26981                 this._disabled = true;\r
26982                 this._updateDisabled();\r
26983                 return this;\r
26984         },\r
26985 \r
26986         enable: function () {\r
26987                 this._disabled = false;\r
26988                 this._updateDisabled();\r
26989                 return this;\r
26990         },\r
26991 \r
26992         _zoomIn: function (e) {\r
26993                 if (!this._disabled && this._map._zoom < this._map.getMaxZoom()) {\r
26994                         this._map.zoomIn(this._map.options.zoomDelta * (e.shiftKey ? 3 : 1));\r
26995                 }\r
26996         },\r
26997 \r
26998         _zoomOut: function (e) {\r
26999                 if (!this._disabled && this._map._zoom > this._map.getMinZoom()) {\r
27000                         this._map.zoomOut(this._map.options.zoomDelta * (e.shiftKey ? 3 : 1));\r
27001                 }\r
27002         },\r
27003 \r
27004         _createButton: function (html, title, className, container, fn) {\r
27005                 var link = create$1('a', className, container);\r
27006                 link.innerHTML = html;\r
27007                 link.href = '#';\r
27008                 link.title = title;\r
27009 \r
27010                 /*\r
27011                  * Will force screen readers like VoiceOver to read this as "Zoom in - button"\r
27012                  */\r
27013                 link.setAttribute('role', 'button');\r
27014                 link.setAttribute('aria-label', title);\r
27015 \r
27016                 disableClickPropagation(link);\r
27017                 on(link, 'click', stop);\r
27018                 on(link, 'click', fn, this);\r
27019                 on(link, 'click', this._refocusOnMap, this);\r
27020 \r
27021                 return link;\r
27022         },\r
27023 \r
27024         _updateDisabled: function () {\r
27025                 var map = this._map,\r
27026                     className = 'leaflet-disabled';\r
27027 \r
27028                 removeClass(this._zoomInButton, className);\r
27029                 removeClass(this._zoomOutButton, className);\r
27030 \r
27031                 if (this._disabled || map._zoom === map.getMinZoom()) {\r
27032                         addClass(this._zoomOutButton, className);\r
27033                 }\r
27034                 if (this._disabled || map._zoom === map.getMaxZoom()) {\r
27035                         addClass(this._zoomInButton, className);\r
27036                 }\r
27037         }\r
27038       });\r
27039 \r
27040       // @namespace Map\r
27041       // @section Control options\r
27042       // @option zoomControl: Boolean = true\r
27043       // Whether a [zoom control](#control-zoom) is added to the map by default.\r
27044       Map.mergeOptions({\r
27045         zoomControl: true\r
27046       });\r
27047 \r
27048       Map.addInitHook(function () {\r
27049         if (this.options.zoomControl) {\r
27050                 // @section Controls\r
27051                 // @property zoomControl: Control.Zoom\r
27052                 // The default zoom control (only available if the\r
27053                 // [`zoomControl` option](#map-zoomcontrol) was `true` when creating the map).\r
27054                 this.zoomControl = new Zoom();\r
27055                 this.addControl(this.zoomControl);\r
27056         }\r
27057       });\r
27058 \r
27059       // @namespace Control.Zoom\r
27060       // @factory L.control.zoom(options: Control.Zoom options)\r
27061       // Creates a zoom control\r
27062       var zoom = function (options) {\r
27063         return new Zoom(options);\r
27064       };
27065
27066       /*
27067        * @class Control.Scale
27068        * @aka L.Control.Scale
27069        * @inherits Control
27070        *
27071        * A simple scale control that shows the scale of the current center of screen in metric (m/km) and imperial (mi/ft) systems. Extends `Control`.
27072        *
27073        * @example
27074        *
27075        * ```js
27076        * L.control.scale().addTo(map);
27077        * ```
27078        */
27079
27080       var Scale = Control.extend({
27081         // @section
27082         // @aka Control.Scale options
27083         options: {
27084                 position: 'bottomleft',
27085
27086                 // @option maxWidth: Number = 100
27087                 // Maximum width of the control in pixels. The width is set dynamically to show round values (e.g. 100, 200, 500).
27088                 maxWidth: 100,
27089
27090                 // @option metric: Boolean = True
27091                 // Whether to show the metric scale line (m/km).
27092                 metric: true,
27093
27094                 // @option imperial: Boolean = True
27095                 // Whether to show the imperial scale line (mi/ft).
27096                 imperial: true
27097
27098                 // @option updateWhenIdle: Boolean = false
27099                 // If `true`, the control is updated on [`moveend`](#map-moveend), otherwise it's always up-to-date (updated on [`move`](#map-move)).
27100         },
27101
27102         onAdd: function (map) {
27103                 var className = 'leaflet-control-scale',
27104                     container = create$1('div', className),
27105                     options = this.options;
27106
27107                 this._addScales(options, className + '-line', container);
27108
27109                 map.on(options.updateWhenIdle ? 'moveend' : 'move', this._update, this);
27110                 map.whenReady(this._update, this);
27111
27112                 return container;
27113         },
27114
27115         onRemove: function (map) {
27116                 map.off(this.options.updateWhenIdle ? 'moveend' : 'move', this._update, this);
27117         },
27118
27119         _addScales: function (options, className, container) {
27120                 if (options.metric) {
27121                         this._mScale = create$1('div', className, container);
27122                 }
27123                 if (options.imperial) {
27124                         this._iScale = create$1('div', className, container);
27125                 }
27126         },
27127
27128         _update: function () {
27129                 var map = this._map,
27130                     y = map.getSize().y / 2;
27131
27132                 var maxMeters = map.distance(
27133                         map.containerPointToLatLng([0, y]),
27134                         map.containerPointToLatLng([this.options.maxWidth, y]));
27135
27136                 this._updateScales(maxMeters);
27137         },
27138
27139         _updateScales: function (maxMeters) {
27140                 if (this.options.metric && maxMeters) {
27141                         this._updateMetric(maxMeters);
27142                 }
27143                 if (this.options.imperial && maxMeters) {
27144                         this._updateImperial(maxMeters);
27145                 }
27146         },
27147
27148         _updateMetric: function (maxMeters) {
27149                 var meters = this._getRoundNum(maxMeters),
27150                     label = meters < 1000 ? meters + ' m' : (meters / 1000) + ' km';
27151
27152                 this._updateScale(this._mScale, label, meters / maxMeters);
27153         },
27154
27155         _updateImperial: function (maxMeters) {
27156                 var maxFeet = maxMeters * 3.2808399,
27157                     maxMiles, miles, feet;
27158
27159                 if (maxFeet > 5280) {
27160                         maxMiles = maxFeet / 5280;
27161                         miles = this._getRoundNum(maxMiles);
27162                         this._updateScale(this._iScale, miles + ' mi', miles / maxMiles);
27163
27164                 } else {
27165                         feet = this._getRoundNum(maxFeet);
27166                         this._updateScale(this._iScale, feet + ' ft', feet / maxFeet);
27167                 }
27168         },
27169
27170         _updateScale: function (scale, text, ratio) {
27171                 scale.style.width = Math.round(this.options.maxWidth * ratio) + 'px';
27172                 scale.innerHTML = text;
27173         },
27174
27175         _getRoundNum: function (num) {
27176                 var pow10 = Math.pow(10, (Math.floor(num) + '').length - 1),
27177                     d = num / pow10;
27178
27179                 d = d >= 10 ? 10 :
27180                     d >= 5 ? 5 :
27181                     d >= 3 ? 3 :
27182                     d >= 2 ? 2 : 1;
27183
27184                 return pow10 * d;
27185         }
27186       });
27187
27188
27189       // @factory L.control.scale(options?: Control.Scale options)
27190       // Creates an scale control with the given options.
27191       var scale = function (options) {
27192         return new Scale(options);
27193       };
27194
27195       /*\r
27196        * @class Control.Attribution\r
27197        * @aka L.Control.Attribution\r
27198        * @inherits Control\r
27199        *\r
27200        * The attribution control allows you to display attribution data in a small text box on a map. It is put on the map by default unless you set its [`attributionControl` option](#map-attributioncontrol) to `false`, and it fetches attribution texts from layers with the [`getAttribution` method](#layer-getattribution) automatically. Extends Control.\r
27201        */\r
27202 \r
27203       var Attribution = Control.extend({\r
27204         // @section\r
27205         // @aka Control.Attribution options\r
27206         options: {\r
27207                 position: 'bottomright',\r
27208 \r
27209                 // @option prefix: String = 'Leaflet'\r
27210                 // The HTML text shown before the attributions. Pass `false` to disable.\r
27211                 prefix: '<a href="https://leafletjs.com" title="A JS library for interactive maps">Leaflet</a>'\r
27212         },\r
27213 \r
27214         initialize: function (options) {\r
27215                 setOptions(this, options);\r
27216 \r
27217                 this._attributions = {};\r
27218         },\r
27219 \r
27220         onAdd: function (map) {\r
27221                 map.attributionControl = this;\r
27222                 this._container = create$1('div', 'leaflet-control-attribution');\r
27223                 disableClickPropagation(this._container);\r
27224 \r
27225                 // TODO ugly, refactor\r
27226                 for (var i in map._layers) {\r
27227                         if (map._layers[i].getAttribution) {\r
27228                                 this.addAttribution(map._layers[i].getAttribution());\r
27229                         }\r
27230                 }\r
27231 \r
27232                 this._update();\r
27233 \r
27234                 return this._container;\r
27235         },\r
27236 \r
27237         // @method setPrefix(prefix: String): this\r
27238         // Sets the text before the attributions.\r
27239         setPrefix: function (prefix) {\r
27240                 this.options.prefix = prefix;\r
27241                 this._update();\r
27242                 return this;\r
27243         },\r
27244 \r
27245         // @method addAttribution(text: String): this\r
27246         // Adds an attribution text (e.g. `'Vector data &copy; Mapbox'`).\r
27247         addAttribution: function (text) {\r
27248                 if (!text) { return this; }\r
27249 \r
27250                 if (!this._attributions[text]) {\r
27251                         this._attributions[text] = 0;\r
27252                 }\r
27253                 this._attributions[text]++;\r
27254 \r
27255                 this._update();\r
27256 \r
27257                 return this;\r
27258         },\r
27259 \r
27260         // @method removeAttribution(text: String): this\r
27261         // Removes an attribution text.\r
27262         removeAttribution: function (text) {\r
27263                 if (!text) { return this; }\r
27264 \r
27265                 if (this._attributions[text]) {\r
27266                         this._attributions[text]--;\r
27267                         this._update();\r
27268                 }\r
27269 \r
27270                 return this;\r
27271         },\r
27272 \r
27273         _update: function () {\r
27274                 if (!this._map) { return; }\r
27275 \r
27276                 var attribs = [];\r
27277 \r
27278                 for (var i in this._attributions) {\r
27279                         if (this._attributions[i]) {\r
27280                                 attribs.push(i);\r
27281                         }\r
27282                 }\r
27283 \r
27284                 var prefixAndAttribs = [];\r
27285 \r
27286                 if (this.options.prefix) {\r
27287                         prefixAndAttribs.push(this.options.prefix);\r
27288                 }\r
27289                 if (attribs.length) {\r
27290                         prefixAndAttribs.push(attribs.join(', '));\r
27291                 }\r
27292 \r
27293                 this._container.innerHTML = prefixAndAttribs.join(' | ');\r
27294         }\r
27295       });\r
27296 \r
27297       // @namespace Map\r
27298       // @section Control options\r
27299       // @option attributionControl: Boolean = true\r
27300       // Whether a [attribution control](#control-attribution) is added to the map by default.\r
27301       Map.mergeOptions({\r
27302         attributionControl: true\r
27303       });\r
27304 \r
27305       Map.addInitHook(function () {\r
27306         if (this.options.attributionControl) {\r
27307                 new Attribution().addTo(this);\r
27308         }\r
27309       });\r
27310 \r
27311       // @namespace Control.Attribution\r
27312       // @factory L.control.attribution(options: Control.Attribution options)\r
27313       // Creates an attribution control.\r
27314       var attribution = function (options) {\r
27315         return new Attribution(options);\r
27316       };
27317
27318       Control.Layers = Layers;
27319       Control.Zoom = Zoom;
27320       Control.Scale = Scale;
27321       Control.Attribution = Attribution;
27322
27323       control.layers = layers;
27324       control.zoom = zoom;
27325       control.scale = scale;
27326       control.attribution = attribution;
27327
27328       /*
27329         L.Handler is a base class for handler classes that are used internally to inject
27330         interaction features like dragging to classes like Map and Marker.
27331       */
27332
27333       // @class Handler
27334       // @aka L.Handler
27335       // Abstract class for map interaction handlers
27336
27337       var Handler = Class.extend({
27338         initialize: function (map) {
27339                 this._map = map;
27340         },
27341
27342         // @method enable(): this
27343         // Enables the handler
27344         enable: function () {
27345                 if (this._enabled) { return this; }
27346
27347                 this._enabled = true;
27348                 this.addHooks();
27349                 return this;
27350         },
27351
27352         // @method disable(): this
27353         // Disables the handler
27354         disable: function () {
27355                 if (!this._enabled) { return this; }
27356
27357                 this._enabled = false;
27358                 this.removeHooks();
27359                 return this;
27360         },
27361
27362         // @method enabled(): Boolean
27363         // Returns `true` if the handler is enabled
27364         enabled: function () {
27365                 return !!this._enabled;
27366         }
27367
27368         // @section Extension methods
27369         // Classes inheriting from `Handler` must implement the two following methods:
27370         // @method addHooks()
27371         // Called when the handler is enabled, should add event hooks.
27372         // @method removeHooks()
27373         // Called when the handler is disabled, should remove the event hooks added previously.
27374       });
27375
27376       // @section There is static function which can be called without instantiating L.Handler:
27377       // @function addTo(map: Map, name: String): this
27378       // Adds a new Handler to the given map with the given name.
27379       Handler.addTo = function (map, name) {
27380         map.addHandler(name, this);
27381         return this;
27382       };
27383
27384       var Mixin = {Events: Events};
27385
27386       /*\r
27387        * @class Draggable\r
27388        * @aka L.Draggable\r
27389        * @inherits Evented\r
27390        *\r
27391        * A class for making DOM elements draggable (including touch support).\r
27392        * Used internally for map and marker dragging. Only works for elements\r
27393        * that were positioned with [`L.DomUtil.setPosition`](#domutil-setposition).\r
27394        *\r
27395        * @example\r
27396        * ```js\r
27397        * var draggable = new L.Draggable(elementToDrag);\r
27398        * draggable.enable();\r
27399        * ```\r
27400        */\r
27401 \r
27402       var START = touch ? 'touchstart mousedown' : 'mousedown';\r
27403       var END = {\r
27404         mousedown: 'mouseup',\r
27405         touchstart: 'touchend',\r
27406         pointerdown: 'touchend',\r
27407         MSPointerDown: 'touchend'\r
27408       };\r
27409       var MOVE = {\r
27410         mousedown: 'mousemove',\r
27411         touchstart: 'touchmove',\r
27412         pointerdown: 'touchmove',\r
27413         MSPointerDown: 'touchmove'\r
27414       };\r
27415 \r
27416 \r
27417       var Draggable = Evented.extend({\r
27418 \r
27419         options: {\r
27420                 // @section\r
27421                 // @aka Draggable options\r
27422                 // @option clickTolerance: Number = 3\r
27423                 // The max number of pixels a user can shift the mouse pointer during a click\r
27424                 // for it to be considered a valid click (as opposed to a mouse drag).\r
27425                 clickTolerance: 3\r
27426         },\r
27427 \r
27428         // @constructor L.Draggable(el: HTMLElement, dragHandle?: HTMLElement, preventOutline?: Boolean, options?: Draggable options)\r
27429         // Creates a `Draggable` object for moving `el` when you start dragging the `dragHandle` element (equals `el` itself by default).\r
27430         initialize: function (element, dragStartTarget, preventOutline$$1, options) {\r
27431                 setOptions(this, options);\r
27432 \r
27433                 this._element = element;\r
27434                 this._dragStartTarget = dragStartTarget || element;\r
27435                 this._preventOutline = preventOutline$$1;\r
27436         },\r
27437 \r
27438         // @method enable()\r
27439         // Enables the dragging ability\r
27440         enable: function () {\r
27441                 if (this._enabled) { return; }\r
27442 \r
27443                 on(this._dragStartTarget, START, this._onDown, this);\r
27444 \r
27445                 this._enabled = true;\r
27446         },\r
27447 \r
27448         // @method disable()\r
27449         // Disables the dragging ability\r
27450         disable: function () {\r
27451                 if (!this._enabled) { return; }\r
27452 \r
27453                 // If we're currently dragging this draggable,\r
27454                 // disabling it counts as first ending the drag.\r
27455                 if (Draggable._dragging === this) {\r
27456                         this.finishDrag();\r
27457                 }\r
27458 \r
27459                 off(this._dragStartTarget, START, this._onDown, this);\r
27460 \r
27461                 this._enabled = false;\r
27462                 this._moved = false;\r
27463         },\r
27464 \r
27465         _onDown: function (e) {\r
27466                 // Ignore simulated events, since we handle both touch and\r
27467                 // mouse explicitly; otherwise we risk getting duplicates of\r
27468                 // touch events, see #4315.\r
27469                 // Also ignore the event if disabled; this happens in IE11\r
27470                 // under some circumstances, see #3666.\r
27471                 if (e._simulated || !this._enabled) { return; }\r
27472 \r
27473                 this._moved = false;\r
27474 \r
27475                 if (hasClass(this._element, 'leaflet-zoom-anim')) { return; }\r
27476 \r
27477                 if (Draggable._dragging || e.shiftKey || ((e.which !== 1) && (e.button !== 1) && !e.touches)) { return; }\r
27478                 Draggable._dragging = this;  // Prevent dragging multiple objects at once.\r
27479 \r
27480                 if (this._preventOutline) {\r
27481                         preventOutline(this._element);\r
27482                 }\r
27483 \r
27484                 disableImageDrag();\r
27485                 disableTextSelection();\r
27486 \r
27487                 if (this._moving) { return; }\r
27488 \r
27489                 // @event down: Event\r
27490                 // Fired when a drag is about to start.\r
27491                 this.fire('down');\r
27492 \r
27493                 var first = e.touches ? e.touches[0] : e,\r
27494                     sizedParent = getSizedParentNode(this._element);\r
27495 \r
27496                 this._startPoint = new Point(first.clientX, first.clientY);\r
27497 \r
27498                 // Cache the scale, so that we can continuously compensate for it during drag (_onMove).\r
27499                 this._parentScale = getScale(sizedParent);\r
27500 \r
27501                 on(document, MOVE[e.type], this._onMove, this);\r
27502                 on(document, END[e.type], this._onUp, this);\r
27503         },\r
27504 \r
27505         _onMove: function (e) {\r
27506                 // Ignore simulated events, since we handle both touch and\r
27507                 // mouse explicitly; otherwise we risk getting duplicates of\r
27508                 // touch events, see #4315.\r
27509                 // Also ignore the event if disabled; this happens in IE11\r
27510                 // under some circumstances, see #3666.\r
27511                 if (e._simulated || !this._enabled) { return; }\r
27512 \r
27513                 if (e.touches && e.touches.length > 1) {\r
27514                         this._moved = true;\r
27515                         return;\r
27516                 }\r
27517 \r
27518                 var first = (e.touches && e.touches.length === 1 ? e.touches[0] : e),\r
27519                     offset = new Point(first.clientX, first.clientY)._subtract(this._startPoint);\r
27520 \r
27521                 if (!offset.x && !offset.y) { return; }\r
27522                 if (Math.abs(offset.x) + Math.abs(offset.y) < this.options.clickTolerance) { return; }\r
27523 \r
27524                 // We assume that the parent container's position, border and scale do not change for the duration of the drag.\r
27525                 // Therefore there is no need to account for the position and border (they are eliminated by the subtraction)\r
27526                 // and we can use the cached value for the scale.\r
27527                 offset.x /= this._parentScale.x;\r
27528                 offset.y /= this._parentScale.y;\r
27529 \r
27530                 preventDefault(e);\r
27531 \r
27532                 if (!this._moved) {\r
27533                         // @event dragstart: Event\r
27534                         // Fired when a drag starts\r
27535                         this.fire('dragstart');\r
27536 \r
27537                         this._moved = true;\r
27538                         this._startPos = getPosition(this._element).subtract(offset);\r
27539 \r
27540                         addClass(document.body, 'leaflet-dragging');\r
27541 \r
27542                         this._lastTarget = e.target || e.srcElement;\r
27543                         // IE and Edge do not give the <use> element, so fetch it\r
27544                         // if necessary\r
27545                         if (window.SVGElementInstance && this._lastTarget instanceof window.SVGElementInstance) {\r
27546                                 this._lastTarget = this._lastTarget.correspondingUseElement;\r
27547                         }\r
27548                         addClass(this._lastTarget, 'leaflet-drag-target');\r
27549                 }\r
27550 \r
27551                 this._newPos = this._startPos.add(offset);\r
27552                 this._moving = true;\r
27553 \r
27554                 cancelAnimFrame(this._animRequest);\r
27555                 this._lastEvent = e;\r
27556                 this._animRequest = requestAnimFrame(this._updatePosition, this, true);\r
27557         },\r
27558 \r
27559         _updatePosition: function () {\r
27560                 var e = {originalEvent: this._lastEvent};\r
27561 \r
27562                 // @event predrag: Event\r
27563                 // Fired continuously during dragging *before* each corresponding\r
27564                 // update of the element's position.\r
27565                 this.fire('predrag', e);\r
27566                 setPosition(this._element, this._newPos);\r
27567 \r
27568                 // @event drag: Event\r
27569                 // Fired continuously during dragging.\r
27570                 this.fire('drag', e);\r
27571         },\r
27572 \r
27573         _onUp: function (e) {\r
27574                 // Ignore simulated events, since we handle both touch and\r
27575                 // mouse explicitly; otherwise we risk getting duplicates of\r
27576                 // touch events, see #4315.\r
27577                 // Also ignore the event if disabled; this happens in IE11\r
27578                 // under some circumstances, see #3666.\r
27579                 if (e._simulated || !this._enabled) { return; }\r
27580                 this.finishDrag();\r
27581         },\r
27582 \r
27583         finishDrag: function () {\r
27584                 removeClass(document.body, 'leaflet-dragging');\r
27585 \r
27586                 if (this._lastTarget) {\r
27587                         removeClass(this._lastTarget, 'leaflet-drag-target');\r
27588                         this._lastTarget = null;\r
27589                 }\r
27590 \r
27591                 for (var i in MOVE) {\r
27592                         off(document, MOVE[i], this._onMove, this);\r
27593                         off(document, END[i], this._onUp, this);\r
27594                 }\r
27595 \r
27596                 enableImageDrag();\r
27597                 enableTextSelection();\r
27598 \r
27599                 if (this._moved && this._moving) {\r
27600                         // ensure drag is not fired after dragend\r
27601                         cancelAnimFrame(this._animRequest);\r
27602 \r
27603                         // @event dragend: DragEndEvent\r
27604                         // Fired when the drag ends.\r
27605                         this.fire('dragend', {\r
27606                                 distance: this._newPos.distanceTo(this._startPos)\r
27607                         });\r
27608                 }\r
27609 \r
27610                 this._moving = false;\r
27611                 Draggable._dragging = false;\r
27612         }\r
27613 \r
27614       });
27615
27616       /*\r
27617        * @namespace LineUtil\r
27618        *\r
27619        * Various utility functions for polyline points processing, used by Leaflet internally to make polylines lightning-fast.\r
27620        */\r
27621 \r
27622       // Simplify polyline with vertex reduction and Douglas-Peucker simplification.\r
27623       // Improves rendering performance dramatically by lessening the number of points to draw.\r
27624 \r
27625       // @function simplify(points: Point[], tolerance: Number): Point[]\r
27626       // Dramatically reduces the number of points in a polyline while retaining\r
27627       // its shape and returns a new array of simplified points, using the\r
27628       // [Douglas-Peucker algorithm](http://en.wikipedia.org/wiki/Douglas-Peucker_algorithm).\r
27629       // Used for a huge performance boost when processing/displaying Leaflet polylines for\r
27630       // each zoom level and also reducing visual noise. tolerance affects the amount of\r
27631       // simplification (lesser value means higher quality but slower and with more points).\r
27632       // Also released as a separated micro-library [Simplify.js](http://mourner.github.com/simplify-js/).\r
27633       function simplify(points, tolerance) {\r
27634         if (!tolerance || !points.length) {\r
27635                 return points.slice();\r
27636         }\r
27637 \r
27638         var sqTolerance = tolerance * tolerance;\r
27639 \r
27640             // stage 1: vertex reduction\r
27641             points = _reducePoints(points, sqTolerance);\r
27642 \r
27643             // stage 2: Douglas-Peucker simplification\r
27644             points = _simplifyDP(points, sqTolerance);\r
27645 \r
27646         return points;\r
27647       }\r
27648 \r
27649       // @function pointToSegmentDistance(p: Point, p1: Point, p2: Point): Number\r
27650       // Returns the distance between point `p` and segment `p1` to `p2`.\r
27651       function pointToSegmentDistance(p, p1, p2) {\r
27652         return Math.sqrt(_sqClosestPointOnSegment(p, p1, p2, true));\r
27653       }\r
27654 \r
27655       // @function closestPointOnSegment(p: Point, p1: Point, p2: Point): Number\r
27656       // Returns the closest point from a point `p` on a segment `p1` to `p2`.\r
27657       function closestPointOnSegment(p, p1, p2) {\r
27658         return _sqClosestPointOnSegment(p, p1, p2);\r
27659       }\r
27660 \r
27661       // Douglas-Peucker simplification, see http://en.wikipedia.org/wiki/Douglas-Peucker_algorithm\r
27662       function _simplifyDP(points, sqTolerance) {\r
27663 \r
27664         var len = points.length,\r
27665             ArrayConstructor = typeof Uint8Array !== undefined + '' ? Uint8Array : Array,\r
27666             markers = new ArrayConstructor(len);\r
27667 \r
27668             markers[0] = markers[len - 1] = 1;\r
27669 \r
27670         _simplifyDPStep(points, markers, sqTolerance, 0, len - 1);\r
27671 \r
27672         var i,\r
27673             newPoints = [];\r
27674 \r
27675         for (i = 0; i < len; i++) {\r
27676                 if (markers[i]) {\r
27677                         newPoints.push(points[i]);\r
27678                 }\r
27679         }\r
27680 \r
27681         return newPoints;\r
27682       }\r
27683 \r
27684       function _simplifyDPStep(points, markers, sqTolerance, first, last) {\r
27685 \r
27686         var maxSqDist = 0,\r
27687         index, i, sqDist;\r
27688 \r
27689         for (i = first + 1; i <= last - 1; i++) {\r
27690                 sqDist = _sqClosestPointOnSegment(points[i], points[first], points[last], true);\r
27691 \r
27692                 if (sqDist > maxSqDist) {\r
27693                         index = i;\r
27694                         maxSqDist = sqDist;\r
27695                 }\r
27696         }\r
27697 \r
27698         if (maxSqDist > sqTolerance) {\r
27699                 markers[index] = 1;\r
27700 \r
27701                 _simplifyDPStep(points, markers, sqTolerance, first, index);\r
27702                 _simplifyDPStep(points, markers, sqTolerance, index, last);\r
27703         }\r
27704       }\r
27705 \r
27706       // reduce points that are too close to each other to a single point\r
27707       function _reducePoints(points, sqTolerance) {\r
27708         var reducedPoints = [points[0]];\r
27709 \r
27710         for (var i = 1, prev = 0, len = points.length; i < len; i++) {\r
27711                 if (_sqDist(points[i], points[prev]) > sqTolerance) {\r
27712                         reducedPoints.push(points[i]);\r
27713                         prev = i;\r
27714                 }\r
27715         }\r
27716         if (prev < len - 1) {\r
27717                 reducedPoints.push(points[len - 1]);\r
27718         }\r
27719         return reducedPoints;\r
27720       }\r
27721 \r
27722       var _lastCode;\r
27723 \r
27724       // @function clipSegment(a: Point, b: Point, bounds: Bounds, useLastCode?: Boolean, round?: Boolean): Point[]|Boolean\r
27725       // Clips the segment a to b by rectangular bounds with the\r
27726       // [Cohen-Sutherland algorithm](https://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm)\r
27727       // (modifying the segment points directly!). Used by Leaflet to only show polyline\r
27728       // points that are on the screen or near, increasing performance.\r
27729       function clipSegment(a, b, bounds, useLastCode, round) {\r
27730         var codeA = useLastCode ? _lastCode : _getBitCode(a, bounds),\r
27731             codeB = _getBitCode(b, bounds),\r
27732 \r
27733             codeOut, p, newCode;\r
27734 \r
27735             // save 2nd code to avoid calculating it on the next segment\r
27736             _lastCode = codeB;\r
27737 \r
27738         while (true) {\r
27739                 // if a,b is inside the clip window (trivial accept)\r
27740                 if (!(codeA | codeB)) {\r
27741                         return [a, b];\r
27742                 }\r
27743 \r
27744                 // if a,b is outside the clip window (trivial reject)\r
27745                 if (codeA & codeB) {\r
27746                         return false;\r
27747                 }\r
27748 \r
27749                 // other cases\r
27750                 codeOut = codeA || codeB;\r
27751                 p = _getEdgeIntersection(a, b, codeOut, bounds, round);\r
27752                 newCode = _getBitCode(p, bounds);\r
27753 \r
27754                 if (codeOut === codeA) {\r
27755                         a = p;\r
27756                         codeA = newCode;\r
27757                 } else {\r
27758                         b = p;\r
27759                         codeB = newCode;\r
27760                 }\r
27761         }\r
27762       }\r
27763 \r
27764       function _getEdgeIntersection(a, b, code, bounds, round) {\r
27765         var dx = b.x - a.x,\r
27766             dy = b.y - a.y,\r
27767             min = bounds.min,\r
27768             max = bounds.max,\r
27769             x, y;\r
27770 \r
27771         if (code & 8) { // top\r
27772                 x = a.x + dx * (max.y - a.y) / dy;\r
27773                 y = max.y;\r
27774 \r
27775         } else if (code & 4) { // bottom\r
27776                 x = a.x + dx * (min.y - a.y) / dy;\r
27777                 y = min.y;\r
27778 \r
27779         } else if (code & 2) { // right\r
27780                 x = max.x;\r
27781                 y = a.y + dy * (max.x - a.x) / dx;\r
27782 \r
27783         } else if (code & 1) { // left\r
27784                 x = min.x;\r
27785                 y = a.y + dy * (min.x - a.x) / dx;\r
27786         }\r
27787 \r
27788         return new Point(x, y, round);\r
27789       }\r
27790 \r
27791       function _getBitCode(p, bounds) {\r
27792         var code = 0;\r
27793 \r
27794         if (p.x < bounds.min.x) { // left\r
27795                 code |= 1;\r
27796         } else if (p.x > bounds.max.x) { // right\r
27797                 code |= 2;\r
27798         }\r
27799 \r
27800         if (p.y < bounds.min.y) { // bottom\r
27801                 code |= 4;\r
27802         } else if (p.y > bounds.max.y) { // top\r
27803                 code |= 8;\r
27804         }\r
27805 \r
27806         return code;\r
27807       }\r
27808 \r
27809       // square distance (to avoid unnecessary Math.sqrt calls)\r
27810       function _sqDist(p1, p2) {\r
27811         var dx = p2.x - p1.x,\r
27812             dy = p2.y - p1.y;\r
27813         return dx * dx + dy * dy;\r
27814       }\r
27815 \r
27816       // return closest point on segment or distance to that point\r
27817       function _sqClosestPointOnSegment(p, p1, p2, sqDist) {\r
27818         var x = p1.x,\r
27819             y = p1.y,\r
27820             dx = p2.x - x,\r
27821             dy = p2.y - y,\r
27822             dot = dx * dx + dy * dy,\r
27823             t;\r
27824 \r
27825         if (dot > 0) {\r
27826                 t = ((p.x - x) * dx + (p.y - y) * dy) / dot;\r
27827 \r
27828                 if (t > 1) {\r
27829                         x = p2.x;\r
27830                         y = p2.y;\r
27831                 } else if (t > 0) {\r
27832                         x += dx * t;\r
27833                         y += dy * t;\r
27834                 }\r
27835         }\r
27836 \r
27837         dx = p.x - x;\r
27838         dy = p.y - y;\r
27839 \r
27840         return sqDist ? dx * dx + dy * dy : new Point(x, y);\r
27841       }\r
27842 \r
27843 \r
27844       // @function isFlat(latlngs: LatLng[]): Boolean\r
27845       // Returns true if `latlngs` is a flat array, false is nested.\r
27846       function isFlat(latlngs) {\r
27847         return !isArray(latlngs[0]) || (typeof latlngs[0][0] !== 'object' && typeof latlngs[0][0] !== 'undefined');\r
27848       }\r
27849 \r
27850       function _flat(latlngs) {\r
27851         console.warn('Deprecated use of _flat, please use L.LineUtil.isFlat instead.');\r
27852         return isFlat(latlngs);\r
27853       }
27854
27855       var LineUtil = ({
27856         simplify: simplify,
27857         pointToSegmentDistance: pointToSegmentDistance,
27858         closestPointOnSegment: closestPointOnSegment,
27859         clipSegment: clipSegment,
27860         _getEdgeIntersection: _getEdgeIntersection,
27861         _getBitCode: _getBitCode,
27862         _sqClosestPointOnSegment: _sqClosestPointOnSegment,
27863         isFlat: isFlat,
27864         _flat: _flat
27865       });
27866
27867       /*\r
27868        * @namespace PolyUtil\r
27869        * Various utility functions for polygon geometries.\r
27870        */\r
27871 \r
27872       /* @function clipPolygon(points: Point[], bounds: Bounds, round?: Boolean): Point[]\r
27873        * Clips the polygon geometry defined by the given `points` by the given bounds (using the [Sutherland-Hodgman algorithm](https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm)).\r
27874        * Used by Leaflet to only show polygon points that are on the screen or near, increasing\r
27875        * performance. Note that polygon points needs different algorithm for clipping\r
27876        * than polyline, so there's a separate method for it.\r
27877        */\r
27878       function clipPolygon(points, bounds, round) {\r
27879         var clippedPoints,\r
27880             edges = [1, 4, 2, 8],\r
27881             i, j, k,\r
27882             a, b,\r
27883             len, edge, p;\r
27884 \r
27885         for (i = 0, len = points.length; i < len; i++) {\r
27886                 points[i]._code = _getBitCode(points[i], bounds);\r
27887         }\r
27888 \r
27889         // for each edge (left, bottom, right, top)\r
27890         for (k = 0; k < 4; k++) {\r
27891                 edge = edges[k];\r
27892                 clippedPoints = [];\r
27893 \r
27894                 for (i = 0, len = points.length, j = len - 1; i < len; j = i++) {\r
27895                         a = points[i];\r
27896                         b = points[j];\r
27897 \r
27898                         // if a is inside the clip window\r
27899                         if (!(a._code & edge)) {\r
27900                                 // if b is outside the clip window (a->b goes out of screen)\r
27901                                 if (b._code & edge) {\r
27902                                         p = _getEdgeIntersection(b, a, edge, bounds, round);\r
27903                                         p._code = _getBitCode(p, bounds);\r
27904                                         clippedPoints.push(p);\r
27905                                 }\r
27906                                 clippedPoints.push(a);\r
27907 \r
27908                         // else if b is inside the clip window (a->b enters the screen)\r
27909                         } else if (!(b._code & edge)) {\r
27910                                 p = _getEdgeIntersection(b, a, edge, bounds, round);\r
27911                                 p._code = _getBitCode(p, bounds);\r
27912                                 clippedPoints.push(p);\r
27913                         }\r
27914                 }\r
27915                 points = clippedPoints;\r
27916         }\r
27917 \r
27918         return points;\r
27919       }
27920
27921       var PolyUtil = ({
27922         clipPolygon: clipPolygon
27923       });
27924
27925       /*\r
27926        * @namespace Projection\r
27927        * @section\r
27928        * Leaflet comes with a set of already defined Projections out of the box:\r
27929        *\r
27930        * @projection L.Projection.LonLat\r
27931        *\r
27932        * Equirectangular, or Plate Carree projection â€” the most simple projection,\r
27933        * mostly used by GIS enthusiasts. Directly maps `x` as longitude, and `y` as\r
27934        * latitude. Also suitable for flat worlds, e.g. game maps. Used by the\r
27935        * `EPSG:4326` and `Simple` CRS.\r
27936        */\r
27937 \r
27938       var LonLat = {\r
27939         project: function (latlng) {\r
27940                 return new Point(latlng.lng, latlng.lat);\r
27941         },\r
27942 \r
27943         unproject: function (point) {\r
27944                 return new LatLng(point.y, point.x);\r
27945         },\r
27946 \r
27947         bounds: new Bounds([-180, -90], [180, 90])\r
27948       };
27949
27950       /*\r
27951        * @namespace Projection\r
27952        * @projection L.Projection.Mercator\r
27953        *\r
27954        * Elliptical Mercator projection â€” more complex than Spherical Mercator. Assumes that Earth is an ellipsoid. Used by the EPSG:3395 CRS.\r
27955        */\r
27956 \r
27957       var Mercator = {\r
27958         R: 6378137,\r
27959         R_MINOR: 6356752.314245179,\r
27960 \r
27961         bounds: new Bounds([-20037508.34279, -15496570.73972], [20037508.34279, 18764656.23138]),\r
27962 \r
27963         project: function (latlng) {\r
27964                 var d = Math.PI / 180,\r
27965                     r = this.R,\r
27966                     y = latlng.lat * d,\r
27967                     tmp = this.R_MINOR / r,\r
27968                     e = Math.sqrt(1 - tmp * tmp),\r
27969                     con = e * Math.sin(y);\r
27970 \r
27971                 var ts = Math.tan(Math.PI / 4 - y / 2) / Math.pow((1 - con) / (1 + con), e / 2);\r
27972                 y = -r * Math.log(Math.max(ts, 1E-10));\r
27973 \r
27974                 return new Point(latlng.lng * d * r, y);\r
27975         },\r
27976 \r
27977         unproject: function (point) {\r
27978                 var d = 180 / Math.PI,\r
27979                     r = this.R,\r
27980                     tmp = this.R_MINOR / r,\r
27981                     e = Math.sqrt(1 - tmp * tmp),\r
27982                     ts = Math.exp(-point.y / r),\r
27983                     phi = Math.PI / 2 - 2 * Math.atan(ts);\r
27984 \r
27985                 for (var i = 0, dphi = 0.1, con; i < 15 && Math.abs(dphi) > 1e-7; i++) {\r
27986                         con = e * Math.sin(phi);\r
27987                         con = Math.pow((1 - con) / (1 + con), e / 2);\r
27988                         dphi = Math.PI / 2 - 2 * Math.atan(ts * con) - phi;\r
27989                         phi += dphi;\r
27990                 }\r
27991 \r
27992                 return new LatLng(phi * d, point.x * d / r);\r
27993         }\r
27994       };
27995
27996       /*
27997        * @class Projection
27998
27999        * An object with methods for projecting geographical coordinates of the world onto
28000        * a flat surface (and back). See [Map projection](http://en.wikipedia.org/wiki/Map_projection).
28001
28002        * @property bounds: Bounds
28003        * The bounds (specified in CRS units) where the projection is valid
28004
28005        * @method project(latlng: LatLng): Point
28006        * Projects geographical coordinates into a 2D point.
28007        * Only accepts actual `L.LatLng` instances, not arrays.
28008
28009        * @method unproject(point: Point): LatLng
28010        * The inverse of `project`. Projects a 2D point into a geographical location.
28011        * Only accepts actual `L.Point` instances, not arrays.
28012
28013        * Note that the projection instances do not inherit from Leaflet's `Class` object,
28014        * and can't be instantiated. Also, new classes can't inherit from them,
28015        * and methods can't be added to them with the `include` function.
28016
28017        */
28018
28019       var index = ({
28020         LonLat: LonLat,
28021         Mercator: Mercator,
28022         SphericalMercator: SphericalMercator
28023       });
28024
28025       /*\r
28026        * @namespace CRS\r
28027        * @crs L.CRS.EPSG3395\r
28028        *\r
28029        * Rarely used by some commercial tile providers. Uses Elliptical Mercator projection.\r
28030        */\r
28031       var EPSG3395 = extend({}, Earth, {\r
28032         code: 'EPSG:3395',\r
28033         projection: Mercator,\r
28034 \r
28035         transformation: (function () {\r
28036                 var scale = 0.5 / (Math.PI * Mercator.R);\r
28037                 return toTransformation(scale, 0.5, -scale, 0.5);\r
28038         }())\r
28039       });
28040
28041       /*\r
28042        * @namespace CRS\r
28043        * @crs L.CRS.EPSG4326\r
28044        *\r
28045        * A common CRS among GIS enthusiasts. Uses simple Equirectangular projection.\r
28046        *\r
28047        * Leaflet 1.0.x complies with the [TMS coordinate scheme for EPSG:4326](https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification#global-geodetic),\r
28048        * which is a breaking change from 0.7.x behaviour.  If you are using a `TileLayer`\r
28049        * with this CRS, ensure that there are two 256x256 pixel tiles covering the\r
28050        * whole earth at zoom level zero, and that the tile coordinate origin is (-180,+90),\r
28051        * or (-180,-90) for `TileLayer`s with [the `tms` option](#tilelayer-tms) set.\r
28052        */\r
28053 \r
28054       var EPSG4326 = extend({}, Earth, {\r
28055         code: 'EPSG:4326',\r
28056         projection: LonLat,\r
28057         transformation: toTransformation(1 / 180, 1, -1 / 180, 0.5)\r
28058       });
28059
28060       /*
28061        * @namespace CRS
28062        * @crs L.CRS.Simple
28063        *
28064        * A simple CRS that maps longitude and latitude into `x` and `y` directly.
28065        * May be used for maps of flat surfaces (e.g. game maps). Note that the `y`
28066        * axis should still be inverted (going from bottom to top). `distance()` returns
28067        * simple euclidean distance.
28068        */
28069
28070       var Simple = extend({}, CRS, {
28071         projection: LonLat,
28072         transformation: toTransformation(1, 0, -1, 0),
28073
28074         scale: function (zoom) {
28075                 return Math.pow(2, zoom);
28076         },
28077
28078         zoom: function (scale) {
28079                 return Math.log(scale) / Math.LN2;
28080         },
28081
28082         distance: function (latlng1, latlng2) {
28083                 var dx = latlng2.lng - latlng1.lng,
28084                     dy = latlng2.lat - latlng1.lat;
28085
28086                 return Math.sqrt(dx * dx + dy * dy);
28087         },
28088
28089         infinite: true
28090       });
28091
28092       CRS.Earth = Earth;
28093       CRS.EPSG3395 = EPSG3395;
28094       CRS.EPSG3857 = EPSG3857;
28095       CRS.EPSG900913 = EPSG900913;
28096       CRS.EPSG4326 = EPSG4326;
28097       CRS.Simple = Simple;
28098
28099       /*
28100        * @class Layer
28101        * @inherits Evented
28102        * @aka L.Layer
28103        * @aka ILayer
28104        *
28105        * A set of methods from the Layer base class that all Leaflet layers use.
28106        * Inherits all methods, options and events from `L.Evented`.
28107        *
28108        * @example
28109        *
28110        * ```js
28111        * var layer = L.marker(latlng).addTo(map);
28112        * layer.addTo(map);
28113        * layer.remove();
28114        * ```
28115        *
28116        * @event add: Event
28117        * Fired after the layer is added to a map
28118        *
28119        * @event remove: Event
28120        * Fired after the layer is removed from a map
28121        */
28122
28123
28124       var Layer = Evented.extend({
28125
28126         // Classes extending `L.Layer` will inherit the following options:
28127         options: {
28128                 // @option pane: String = 'overlayPane'
28129                 // By default the layer will be added to the map's [overlay pane](#map-overlaypane). Overriding this option will cause the layer to be placed on another pane by default.
28130                 pane: 'overlayPane',
28131
28132                 // @option attribution: String = null
28133                 // String to be shown in the attribution control, e.g. "© OpenStreetMap contributors". It describes the layer data and is often a legal obligation towards copyright holders and tile providers.
28134                 attribution: null,
28135
28136                 bubblingMouseEvents: true
28137         },
28138
28139         /* @section
28140          * Classes extending `L.Layer` will inherit the following methods:
28141          *
28142          * @method addTo(map: Map|LayerGroup): this
28143          * Adds the layer to the given map or layer group.
28144          */
28145         addTo: function (map) {
28146                 map.addLayer(this);
28147                 return this;
28148         },
28149
28150         // @method remove: this
28151         // Removes the layer from the map it is currently active on.
28152         remove: function () {
28153                 return this.removeFrom(this._map || this._mapToAdd);
28154         },
28155
28156         // @method removeFrom(map: Map): this
28157         // Removes the layer from the given map
28158         //
28159         // @alternative
28160         // @method removeFrom(group: LayerGroup): this
28161         // Removes the layer from the given `LayerGroup`
28162         removeFrom: function (obj) {
28163                 if (obj) {
28164                         obj.removeLayer(this);
28165                 }
28166                 return this;
28167         },
28168
28169         // @method getPane(name? : String): HTMLElement
28170         // Returns the `HTMLElement` representing the named pane on the map. If `name` is omitted, returns the pane for this layer.
28171         getPane: function (name) {
28172                 return this._map.getPane(name ? (this.options[name] || name) : this.options.pane);
28173         },
28174
28175         addInteractiveTarget: function (targetEl) {
28176                 this._map._targets[stamp(targetEl)] = this;
28177                 return this;
28178         },
28179
28180         removeInteractiveTarget: function (targetEl) {
28181                 delete this._map._targets[stamp(targetEl)];
28182                 return this;
28183         },
28184
28185         // @method getAttribution: String
28186         // Used by the `attribution control`, returns the [attribution option](#gridlayer-attribution).
28187         getAttribution: function () {
28188                 return this.options.attribution;
28189         },
28190
28191         _layerAdd: function (e) {
28192                 var map = e.target;
28193
28194                 // check in case layer gets added and then removed before the map is ready
28195                 if (!map.hasLayer(this)) { return; }
28196
28197                 this._map = map;
28198                 this._zoomAnimated = map._zoomAnimated;
28199
28200                 if (this.getEvents) {
28201                         var events = this.getEvents();
28202                         map.on(events, this);
28203                         this.once('remove', function () {
28204                                 map.off(events, this);
28205                         }, this);
28206                 }
28207
28208                 this.onAdd(map);
28209
28210                 if (this.getAttribution && map.attributionControl) {
28211                         map.attributionControl.addAttribution(this.getAttribution());
28212                 }
28213
28214                 this.fire('add');
28215                 map.fire('layeradd', {layer: this});
28216         }
28217       });
28218
28219       /* @section Extension methods
28220        * @uninheritable
28221        *
28222        * Every layer should extend from `L.Layer` and (re-)implement the following methods.
28223        *
28224        * @method onAdd(map: Map): this
28225        * Should contain code that creates DOM elements for the layer, adds them to `map panes` where they should belong and puts listeners on relevant map events. Called on [`map.addLayer(layer)`](#map-addlayer).
28226        *
28227        * @method onRemove(map: Map): this
28228        * Should contain all clean up code that removes the layer's elements from the DOM and removes listeners previously added in [`onAdd`](#layer-onadd). Called on [`map.removeLayer(layer)`](#map-removelayer).
28229        *
28230        * @method getEvents(): Object
28231        * This optional method should return an object like `{ viewreset: this._reset }` for [`addEventListener`](#evented-addeventlistener). The event handlers in this object will be automatically added and removed from the map with your layer.
28232        *
28233        * @method getAttribution(): String
28234        * This optional method should return a string containing HTML to be shown on the `Attribution control` whenever the layer is visible.
28235        *
28236        * @method beforeAdd(map: Map): this
28237        * Optional method. Called on [`map.addLayer(layer)`](#map-addlayer), before the layer is added to the map, before events are initialized, without waiting until the map is in a usable state. Use for early initialization only.
28238        */
28239
28240
28241       /* @namespace Map
28242        * @section Layer events
28243        *
28244        * @event layeradd: LayerEvent
28245        * Fired when a new layer is added to the map.
28246        *
28247        * @event layerremove: LayerEvent
28248        * Fired when some layer is removed from the map
28249        *
28250        * @section Methods for Layers and Controls
28251        */
28252       Map.include({
28253         // @method addLayer(layer: Layer): this
28254         // Adds the given layer to the map
28255         addLayer: function (layer) {
28256                 if (!layer._layerAdd) {
28257                         throw new Error('The provided object is not a Layer.');
28258                 }
28259
28260                 var id = stamp(layer);
28261                 if (this._layers[id]) { return this; }
28262                 this._layers[id] = layer;
28263
28264                 layer._mapToAdd = this;
28265
28266                 if (layer.beforeAdd) {
28267                         layer.beforeAdd(this);
28268                 }
28269
28270                 this.whenReady(layer._layerAdd, layer);
28271
28272                 return this;
28273         },
28274
28275         // @method removeLayer(layer: Layer): this
28276         // Removes the given layer from the map.
28277         removeLayer: function (layer) {
28278                 var id = stamp(layer);
28279
28280                 if (!this._layers[id]) { return this; }
28281
28282                 if (this._loaded) {
28283                         layer.onRemove(this);
28284                 }
28285
28286                 if (layer.getAttribution && this.attributionControl) {
28287                         this.attributionControl.removeAttribution(layer.getAttribution());
28288                 }
28289
28290                 delete this._layers[id];
28291
28292                 if (this._loaded) {
28293                         this.fire('layerremove', {layer: layer});
28294                         layer.fire('remove');
28295                 }
28296
28297                 layer._map = layer._mapToAdd = null;
28298
28299                 return this;
28300         },
28301
28302         // @method hasLayer(layer: Layer): Boolean
28303         // Returns `true` if the given layer is currently added to the map
28304         hasLayer: function (layer) {
28305                 return !!layer && (stamp(layer) in this._layers);
28306         },
28307
28308         /* @method eachLayer(fn: Function, context?: Object): this
28309          * Iterates over the layers of the map, optionally specifying context of the iterator function.
28310          * ```
28311          * map.eachLayer(function(layer){
28312          *     layer.bindPopup('Hello');
28313          * });
28314          * ```
28315          */
28316         eachLayer: function (method, context) {
28317                 for (var i in this._layers) {
28318                         method.call(context, this._layers[i]);
28319                 }
28320                 return this;
28321         },
28322
28323         _addLayers: function (layers) {
28324                 layers = layers ? (isArray(layers) ? layers : [layers]) : [];
28325
28326                 for (var i = 0, len = layers.length; i < len; i++) {
28327                         this.addLayer(layers[i]);
28328                 }
28329         },
28330
28331         _addZoomLimit: function (layer) {
28332                 if (isNaN(layer.options.maxZoom) || !isNaN(layer.options.minZoom)) {
28333                         this._zoomBoundLayers[stamp(layer)] = layer;
28334                         this._updateZoomLevels();
28335                 }
28336         },
28337
28338         _removeZoomLimit: function (layer) {
28339                 var id = stamp(layer);
28340
28341                 if (this._zoomBoundLayers[id]) {
28342                         delete this._zoomBoundLayers[id];
28343                         this._updateZoomLevels();
28344                 }
28345         },
28346
28347         _updateZoomLevels: function () {
28348                 var minZoom = Infinity,
28349                     maxZoom = -Infinity,
28350                     oldZoomSpan = this._getZoomSpan();
28351
28352                 for (var i in this._zoomBoundLayers) {
28353                         var options = this._zoomBoundLayers[i].options;
28354
28355                         minZoom = options.minZoom === undefined ? minZoom : Math.min(minZoom, options.minZoom);
28356                         maxZoom = options.maxZoom === undefined ? maxZoom : Math.max(maxZoom, options.maxZoom);
28357                 }
28358
28359                 this._layersMaxZoom = maxZoom === -Infinity ? undefined : maxZoom;
28360                 this._layersMinZoom = minZoom === Infinity ? undefined : minZoom;
28361
28362                 // @section Map state change events
28363                 // @event zoomlevelschange: Event
28364                 // Fired when the number of zoomlevels on the map is changed due
28365                 // to adding or removing a layer.
28366                 if (oldZoomSpan !== this._getZoomSpan()) {
28367                         this.fire('zoomlevelschange');
28368                 }
28369
28370                 if (this.options.maxZoom === undefined && this._layersMaxZoom && this.getZoom() > this._layersMaxZoom) {
28371                         this.setZoom(this._layersMaxZoom);
28372                 }
28373                 if (this.options.minZoom === undefined && this._layersMinZoom && this.getZoom() < this._layersMinZoom) {
28374                         this.setZoom(this._layersMinZoom);
28375                 }
28376         }
28377       });
28378
28379       /*\r
28380        * @class LayerGroup\r
28381        * @aka L.LayerGroup\r
28382        * @inherits Layer\r
28383        *\r
28384        * Used to group several layers and handle them as one. If you add it to the map,\r
28385        * any layers added or removed from the group will be added/removed on the map as\r
28386        * well. Extends `Layer`.\r
28387        *\r
28388        * @example\r
28389        *\r
28390        * ```js\r
28391        * L.layerGroup([marker1, marker2])\r
28392        *        .addLayer(polyline)\r
28393        *        .addTo(map);\r
28394        * ```\r
28395        */\r
28396 \r
28397       var LayerGroup = Layer.extend({\r
28398 \r
28399         initialize: function (layers, options) {\r
28400                 setOptions(this, options);\r
28401 \r
28402                 this._layers = {};\r
28403 \r
28404                 var i, len;\r
28405 \r
28406                 if (layers) {\r
28407                         for (i = 0, len = layers.length; i < len; i++) {\r
28408                                 this.addLayer(layers[i]);\r
28409                         }\r
28410                 }\r
28411         },\r
28412 \r
28413         // @method addLayer(layer: Layer): this\r
28414         // Adds the given layer to the group.\r
28415         addLayer: function (layer) {\r
28416                 var id = this.getLayerId(layer);\r
28417 \r
28418                 this._layers[id] = layer;\r
28419 \r
28420                 if (this._map) {\r
28421                         this._map.addLayer(layer);\r
28422                 }\r
28423 \r
28424                 return this;\r
28425         },\r
28426 \r
28427         // @method removeLayer(layer: Layer): this\r
28428         // Removes the given layer from the group.\r
28429         // @alternative\r
28430         // @method removeLayer(id: Number): this\r
28431         // Removes the layer with the given internal ID from the group.\r
28432         removeLayer: function (layer) {\r
28433                 var id = layer in this._layers ? layer : this.getLayerId(layer);\r
28434 \r
28435                 if (this._map && this._layers[id]) {\r
28436                         this._map.removeLayer(this._layers[id]);\r
28437                 }\r
28438 \r
28439                 delete this._layers[id];\r
28440 \r
28441                 return this;\r
28442         },\r
28443 \r
28444         // @method hasLayer(layer: Layer): Boolean\r
28445         // Returns `true` if the given layer is currently added to the group.\r
28446         // @alternative\r
28447         // @method hasLayer(id: Number): Boolean\r
28448         // Returns `true` if the given internal ID is currently added to the group.\r
28449         hasLayer: function (layer) {\r
28450                 if (!layer) { return false; }\r
28451                 var layerId = typeof layer === 'number' ? layer : this.getLayerId(layer);\r
28452                 return layerId in this._layers;\r
28453         },\r
28454 \r
28455         // @method clearLayers(): this\r
28456         // Removes all the layers from the group.\r
28457         clearLayers: function () {\r
28458                 return this.eachLayer(this.removeLayer, this);\r
28459         },\r
28460 \r
28461         // @method invoke(methodName: String, â€¦): this\r
28462         // Calls `methodName` on every layer contained in this group, passing any\r
28463         // additional parameters. Has no effect if the layers contained do not\r
28464         // implement `methodName`.\r
28465         invoke: function (methodName) {\r
28466                 var args = Array.prototype.slice.call(arguments, 1),\r
28467                     i, layer;\r
28468 \r
28469                 for (i in this._layers) {\r
28470                         layer = this._layers[i];\r
28471 \r
28472                         if (layer[methodName]) {\r
28473                                 layer[methodName].apply(layer, args);\r
28474                         }\r
28475                 }\r
28476 \r
28477                 return this;\r
28478         },\r
28479 \r
28480         onAdd: function (map) {\r
28481                 this.eachLayer(map.addLayer, map);\r
28482         },\r
28483 \r
28484         onRemove: function (map) {\r
28485                 this.eachLayer(map.removeLayer, map);\r
28486         },\r
28487 \r
28488         // @method eachLayer(fn: Function, context?: Object): this\r
28489         // Iterates over the layers of the group, optionally specifying context of the iterator function.\r
28490         // ```js\r
28491         // group.eachLayer(function (layer) {\r
28492         //      layer.bindPopup('Hello');\r
28493         // });\r
28494         // ```\r
28495         eachLayer: function (method, context) {\r
28496                 for (var i in this._layers) {\r
28497                         method.call(context, this._layers[i]);\r
28498                 }\r
28499                 return this;\r
28500         },\r
28501 \r
28502         // @method getLayer(id: Number): Layer\r
28503         // Returns the layer with the given internal ID.\r
28504         getLayer: function (id) {\r
28505                 return this._layers[id];\r
28506         },\r
28507 \r
28508         // @method getLayers(): Layer[]\r
28509         // Returns an array of all the layers added to the group.\r
28510         getLayers: function () {\r
28511                 var layers = [];\r
28512                 this.eachLayer(layers.push, layers);\r
28513                 return layers;\r
28514         },\r
28515 \r
28516         // @method setZIndex(zIndex: Number): this\r
28517         // Calls `setZIndex` on every layer contained in this group, passing the z-index.\r
28518         setZIndex: function (zIndex) {\r
28519                 return this.invoke('setZIndex', zIndex);\r
28520         },\r
28521 \r
28522         // @method getLayerId(layer: Layer): Number\r
28523         // Returns the internal ID for a layer\r
28524         getLayerId: function (layer) {\r
28525                 return stamp(layer);\r
28526         }\r
28527       });\r
28528 \r
28529 \r
28530       // @factory L.layerGroup(layers?: Layer[], options?: Object)\r
28531       // Create a layer group, optionally given an initial set of layers and an `options` object.\r
28532       var layerGroup = function (layers, options) {\r
28533         return new LayerGroup(layers, options);\r
28534       };
28535
28536       /*\r
28537        * @class FeatureGroup\r
28538        * @aka L.FeatureGroup\r
28539        * @inherits LayerGroup\r
28540        *\r
28541        * Extended `LayerGroup` that makes it easier to do the same thing to all its member layers:\r
28542        *  * [`bindPopup`](#layer-bindpopup) binds a popup to all of the layers at once (likewise with [`bindTooltip`](#layer-bindtooltip))\r
28543        *  * Events are propagated to the `FeatureGroup`, so if the group has an event\r
28544        * handler, it will handle events from any of the layers. This includes mouse events\r
28545        * and custom events.\r
28546        *  * Has `layeradd` and `layerremove` events\r
28547        *\r
28548        * @example\r
28549        *\r
28550        * ```js\r
28551        * L.featureGroup([marker1, marker2, polyline])\r
28552        *        .bindPopup('Hello world!')\r
28553        *        .on('click', function() { alert('Clicked on a member of the group!'); })\r
28554        *        .addTo(map);\r
28555        * ```\r
28556        */\r
28557 \r
28558       var FeatureGroup = LayerGroup.extend({\r
28559 \r
28560         addLayer: function (layer) {\r
28561                 if (this.hasLayer(layer)) {\r
28562                         return this;\r
28563                 }\r
28564 \r
28565                 layer.addEventParent(this);\r
28566 \r
28567                 LayerGroup.prototype.addLayer.call(this, layer);\r
28568 \r
28569                 // @event layeradd: LayerEvent\r
28570                 // Fired when a layer is added to this `FeatureGroup`\r
28571                 return this.fire('layeradd', {layer: layer});\r
28572         },\r
28573 \r
28574         removeLayer: function (layer) {\r
28575                 if (!this.hasLayer(layer)) {\r
28576                         return this;\r
28577                 }\r
28578                 if (layer in this._layers) {\r
28579                         layer = this._layers[layer];\r
28580                 }\r
28581 \r
28582                 layer.removeEventParent(this);\r
28583 \r
28584                 LayerGroup.prototype.removeLayer.call(this, layer);\r
28585 \r
28586                 // @event layerremove: LayerEvent\r
28587                 // Fired when a layer is removed from this `FeatureGroup`\r
28588                 return this.fire('layerremove', {layer: layer});\r
28589         },\r
28590 \r
28591         // @method setStyle(style: Path options): this\r
28592         // Sets the given path options to each layer of the group that has a `setStyle` method.\r
28593         setStyle: function (style) {\r
28594                 return this.invoke('setStyle', style);\r
28595         },\r
28596 \r
28597         // @method bringToFront(): this\r
28598         // Brings the layer group to the top of all other layers\r
28599         bringToFront: function () {\r
28600                 return this.invoke('bringToFront');\r
28601         },\r
28602 \r
28603         // @method bringToBack(): this\r
28604         // Brings the layer group to the back of all other layers\r
28605         bringToBack: function () {\r
28606                 return this.invoke('bringToBack');\r
28607         },\r
28608 \r
28609         // @method getBounds(): LatLngBounds\r
28610         // Returns the LatLngBounds of the Feature Group (created from bounds and coordinates of its children).\r
28611         getBounds: function () {\r
28612                 var bounds = new LatLngBounds();\r
28613 \r
28614                 for (var id in this._layers) {\r
28615                         var layer = this._layers[id];\r
28616                         bounds.extend(layer.getBounds ? layer.getBounds() : layer.getLatLng());\r
28617                 }\r
28618                 return bounds;\r
28619         }\r
28620       });\r
28621 \r
28622       // @factory L.featureGroup(layers?: Layer[], options?: Object)\r
28623       // Create a feature group, optionally given an initial set of layers and an `options` object.\r
28624       var featureGroup = function (layers, options) {\r
28625         return new FeatureGroup(layers, options);\r
28626       };
28627
28628       /*\r
28629        * @class Icon\r
28630        * @aka L.Icon\r
28631        *\r
28632        * Represents an icon to provide when creating a marker.\r
28633        *\r
28634        * @example\r
28635        *\r
28636        * ```js\r
28637        * var myIcon = L.icon({\r
28638        *     iconUrl: 'my-icon.png',\r
28639        *     iconRetinaUrl: 'my-icon@2x.png',\r
28640        *     iconSize: [38, 95],\r
28641        *     iconAnchor: [22, 94],\r
28642        *     popupAnchor: [-3, -76],\r
28643        *     shadowUrl: 'my-icon-shadow.png',\r
28644        *     shadowRetinaUrl: 'my-icon-shadow@2x.png',\r
28645        *     shadowSize: [68, 95],\r
28646        *     shadowAnchor: [22, 94]\r
28647        * });\r
28648        *\r
28649        * L.marker([50.505, 30.57], {icon: myIcon}).addTo(map);\r
28650        * ```\r
28651        *\r
28652        * `L.Icon.Default` extends `L.Icon` and is the blue icon Leaflet uses for markers by default.\r
28653        *\r
28654        */\r
28655 \r
28656       var Icon = Class.extend({\r
28657 \r
28658         /* @section\r
28659          * @aka Icon options\r
28660          *\r
28661          * @option iconUrl: String = null\r
28662          * **(required)** The URL to the icon image (absolute or relative to your script path).\r
28663          *\r
28664          * @option iconRetinaUrl: String = null\r
28665          * The URL to a retina sized version of the icon image (absolute or relative to your\r
28666          * script path). Used for Retina screen devices.\r
28667          *\r
28668          * @option iconSize: Point = null\r
28669          * Size of the icon image in pixels.\r
28670          *\r
28671          * @option iconAnchor: Point = null\r
28672          * The coordinates of the "tip" of the icon (relative to its top left corner). The icon\r
28673          * will be aligned so that this point is at the marker's geographical location. Centered\r
28674          * by default if size is specified, also can be set in CSS with negative margins.\r
28675          *\r
28676          * @option popupAnchor: Point = [0, 0]\r
28677          * The coordinates of the point from which popups will "open", relative to the icon anchor.\r
28678          *\r
28679          * @option tooltipAnchor: Point = [0, 0]\r
28680          * The coordinates of the point from which tooltips will "open", relative to the icon anchor.\r
28681          *\r
28682          * @option shadowUrl: String = null\r
28683          * The URL to the icon shadow image. If not specified, no shadow image will be created.\r
28684          *\r
28685          * @option shadowRetinaUrl: String = null\r
28686          *\r
28687          * @option shadowSize: Point = null\r
28688          * Size of the shadow image in pixels.\r
28689          *\r
28690          * @option shadowAnchor: Point = null\r
28691          * The coordinates of the "tip" of the shadow (relative to its top left corner) (the same\r
28692          * as iconAnchor if not specified).\r
28693          *\r
28694          * @option className: String = ''\r
28695          * A custom class name to assign to both icon and shadow images. Empty by default.\r
28696          */\r
28697 \r
28698         options: {\r
28699                 popupAnchor: [0, 0],\r
28700                 tooltipAnchor: [0, 0]\r
28701         },\r
28702 \r
28703         initialize: function (options) {\r
28704                 setOptions(this, options);\r
28705         },\r
28706 \r
28707         // @method createIcon(oldIcon?: HTMLElement): HTMLElement\r
28708         // Called internally when the icon has to be shown, returns a `<img>` HTML element\r
28709         // styled according to the options.\r
28710         createIcon: function (oldIcon) {\r
28711                 return this._createIcon('icon', oldIcon);\r
28712         },\r
28713 \r
28714         // @method createShadow(oldIcon?: HTMLElement): HTMLElement\r
28715         // As `createIcon`, but for the shadow beneath it.\r
28716         createShadow: function (oldIcon) {\r
28717                 return this._createIcon('shadow', oldIcon);\r
28718         },\r
28719 \r
28720         _createIcon: function (name, oldIcon) {\r
28721                 var src = this._getIconUrl(name);\r
28722 \r
28723                 if (!src) {\r
28724                         if (name === 'icon') {\r
28725                                 throw new Error('iconUrl not set in Icon options (see the docs).');\r
28726                         }\r
28727                         return null;\r
28728                 }\r
28729 \r
28730                 var img = this._createImg(src, oldIcon && oldIcon.tagName === 'IMG' ? oldIcon : null);\r
28731                 this._setIconStyles(img, name);\r
28732 \r
28733                 return img;\r
28734         },\r
28735 \r
28736         _setIconStyles: function (img, name) {\r
28737                 var options = this.options;\r
28738                 var sizeOption = options[name + 'Size'];\r
28739 \r
28740                 if (typeof sizeOption === 'number') {\r
28741                         sizeOption = [sizeOption, sizeOption];\r
28742                 }\r
28743 \r
28744                 var size = toPoint(sizeOption),\r
28745                     anchor = toPoint(name === 'shadow' && options.shadowAnchor || options.iconAnchor ||\r
28746                             size && size.divideBy(2, true));\r
28747 \r
28748                 img.className = 'leaflet-marker-' + name + ' ' + (options.className || '');\r
28749 \r
28750                 if (anchor) {\r
28751                         img.style.marginLeft = (-anchor.x) + 'px';\r
28752                         img.style.marginTop  = (-anchor.y) + 'px';\r
28753                 }\r
28754 \r
28755                 if (size) {\r
28756                         img.style.width  = size.x + 'px';\r
28757                         img.style.height = size.y + 'px';\r
28758                 }\r
28759         },\r
28760 \r
28761         _createImg: function (src, el) {\r
28762                 el = el || document.createElement('img');\r
28763                 el.src = src;\r
28764                 return el;\r
28765         },\r
28766 \r
28767         _getIconUrl: function (name) {\r
28768                 return retina && this.options[name + 'RetinaUrl'] || this.options[name + 'Url'];\r
28769         }\r
28770       });\r
28771 \r
28772 \r
28773       // @factory L.icon(options: Icon options)\r
28774       // Creates an icon instance with the given options.\r
28775       function icon(options) {\r
28776         return new Icon(options);\r
28777       }
28778
28779       /*
28780        * @miniclass Icon.Default (Icon)
28781        * @aka L.Icon.Default
28782        * @section
28783        *
28784        * A trivial subclass of `Icon`, represents the icon to use in `Marker`s when
28785        * no icon is specified. Points to the blue marker image distributed with Leaflet
28786        * releases.
28787        *
28788        * In order to customize the default icon, just change the properties of `L.Icon.Default.prototype.options`
28789        * (which is a set of `Icon options`).
28790        *
28791        * If you want to _completely_ replace the default icon, override the
28792        * `L.Marker.prototype.options.icon` with your own icon instead.
28793        */
28794
28795       var IconDefault = Icon.extend({
28796
28797         options: {
28798                 iconUrl:       'marker-icon.png',
28799                 iconRetinaUrl: 'marker-icon-2x.png',
28800                 shadowUrl:     'marker-shadow.png',
28801                 iconSize:    [25, 41],
28802                 iconAnchor:  [12, 41],
28803                 popupAnchor: [1, -34],
28804                 tooltipAnchor: [16, -28],
28805                 shadowSize:  [41, 41]
28806         },
28807
28808         _getIconUrl: function (name) {
28809                 if (!IconDefault.imagePath) {   // Deprecated, backwards-compatibility only
28810                         IconDefault.imagePath = this._detectIconPath();
28811                 }
28812
28813                 // @option imagePath: String
28814                 // `Icon.Default` will try to auto-detect the location of the
28815                 // blue icon images. If you are placing these images in a non-standard
28816                 // way, set this option to point to the right path.
28817                 return (this.options.imagePath || IconDefault.imagePath) + Icon.prototype._getIconUrl.call(this, name);
28818         },
28819
28820         _detectIconPath: function () {
28821                 var el = create$1('div',  'leaflet-default-icon-path', document.body);
28822                 var path = getStyle(el, 'background-image') ||
28823                            getStyle(el, 'backgroundImage');     // IE8
28824
28825                 document.body.removeChild(el);
28826
28827                 if (path === null || path.indexOf('url') !== 0) {
28828                         path = '';
28829                 } else {
28830                         path = path.replace(/^url\(["']?/, '').replace(/marker-icon\.png["']?\)$/, '');
28831                 }
28832
28833                 return path;
28834         }
28835       });
28836
28837       /*
28838        * L.Handler.MarkerDrag is used internally by L.Marker to make the markers draggable.
28839        */
28840
28841
28842       /* @namespace Marker
28843        * @section Interaction handlers
28844        *
28845        * Interaction handlers are properties of a marker instance that allow you to control interaction behavior in runtime, enabling or disabling certain features such as dragging (see `Handler` methods). Example:
28846        *
28847        * ```js
28848        * marker.dragging.disable();
28849        * ```
28850        *
28851        * @property dragging: Handler
28852        * Marker dragging handler (by both mouse and touch). Only valid when the marker is on the map (Otherwise set [`marker.options.draggable`](#marker-draggable)).
28853        */
28854
28855       var MarkerDrag = Handler.extend({
28856         initialize: function (marker) {
28857                 this._marker = marker;
28858         },
28859
28860         addHooks: function () {
28861                 var icon = this._marker._icon;
28862
28863                 if (!this._draggable) {
28864                         this._draggable = new Draggable(icon, icon, true);
28865                 }
28866
28867                 this._draggable.on({
28868                         dragstart: this._onDragStart,
28869                         predrag: this._onPreDrag,
28870                         drag: this._onDrag,
28871                         dragend: this._onDragEnd
28872                 }, this).enable();
28873
28874                 addClass(icon, 'leaflet-marker-draggable');
28875         },
28876
28877         removeHooks: function () {
28878                 this._draggable.off({
28879                         dragstart: this._onDragStart,
28880                         predrag: this._onPreDrag,
28881                         drag: this._onDrag,
28882                         dragend: this._onDragEnd
28883                 }, this).disable();
28884
28885                 if (this._marker._icon) {
28886                         removeClass(this._marker._icon, 'leaflet-marker-draggable');
28887                 }
28888         },
28889
28890         moved: function () {
28891                 return this._draggable && this._draggable._moved;
28892         },
28893
28894         _adjustPan: function (e) {
28895                 var marker = this._marker,
28896                     map = marker._map,
28897                     speed = this._marker.options.autoPanSpeed,
28898                     padding = this._marker.options.autoPanPadding,
28899                     iconPos = getPosition(marker._icon),
28900                     bounds = map.getPixelBounds(),
28901                     origin = map.getPixelOrigin();
28902
28903                 var panBounds = toBounds(
28904                         bounds.min._subtract(origin).add(padding),
28905                         bounds.max._subtract(origin).subtract(padding)
28906                 );
28907
28908                 if (!panBounds.contains(iconPos)) {
28909                         // Compute incremental movement
28910                         var movement = toPoint(
28911                                 (Math.max(panBounds.max.x, iconPos.x) - panBounds.max.x) / (bounds.max.x - panBounds.max.x) -
28912                                 (Math.min(panBounds.min.x, iconPos.x) - panBounds.min.x) / (bounds.min.x - panBounds.min.x),
28913
28914                                 (Math.max(panBounds.max.y, iconPos.y) - panBounds.max.y) / (bounds.max.y - panBounds.max.y) -
28915                                 (Math.min(panBounds.min.y, iconPos.y) - panBounds.min.y) / (bounds.min.y - panBounds.min.y)
28916                         ).multiplyBy(speed);
28917
28918                         map.panBy(movement, {animate: false});
28919
28920                         this._draggable._newPos._add(movement);
28921                         this._draggable._startPos._add(movement);
28922
28923                         setPosition(marker._icon, this._draggable._newPos);
28924                         this._onDrag(e);
28925
28926                         this._panRequest = requestAnimFrame(this._adjustPan.bind(this, e));
28927                 }
28928         },
28929
28930         _onDragStart: function () {
28931                 // @section Dragging events
28932                 // @event dragstart: Event
28933                 // Fired when the user starts dragging the marker.
28934
28935                 // @event movestart: Event
28936                 // Fired when the marker starts moving (because of dragging).
28937
28938                 this._oldLatLng = this._marker.getLatLng();
28939
28940                 // When using ES6 imports it could not be set when `Popup` was not imported as well
28941                 this._marker.closePopup && this._marker.closePopup();
28942
28943                 this._marker
28944                         .fire('movestart')
28945                         .fire('dragstart');
28946         },
28947
28948         _onPreDrag: function (e) {
28949                 if (this._marker.options.autoPan) {
28950                         cancelAnimFrame(this._panRequest);
28951                         this._panRequest = requestAnimFrame(this._adjustPan.bind(this, e));
28952                 }
28953         },
28954
28955         _onDrag: function (e) {
28956                 var marker = this._marker,
28957                     shadow = marker._shadow,
28958                     iconPos = getPosition(marker._icon),
28959                     latlng = marker._map.layerPointToLatLng(iconPos);
28960
28961                 // update shadow position
28962                 if (shadow) {
28963                         setPosition(shadow, iconPos);
28964                 }
28965
28966                 marker._latlng = latlng;
28967                 e.latlng = latlng;
28968                 e.oldLatLng = this._oldLatLng;
28969
28970                 // @event drag: Event
28971                 // Fired repeatedly while the user drags the marker.
28972                 marker
28973                     .fire('move', e)
28974                     .fire('drag', e);
28975         },
28976
28977         _onDragEnd: function (e) {
28978                 // @event dragend: DragEndEvent
28979                 // Fired when the user stops dragging the marker.
28980
28981                  cancelAnimFrame(this._panRequest);
28982
28983                 // @event moveend: Event
28984                 // Fired when the marker stops moving (because of dragging).
28985                 delete this._oldLatLng;
28986                 this._marker
28987                     .fire('moveend')
28988                     .fire('dragend', e);
28989         }
28990       });
28991
28992       /*\r
28993        * @class Marker\r
28994        * @inherits Interactive layer\r
28995        * @aka L.Marker\r
28996        * L.Marker is used to display clickable/draggable icons on the map. Extends `Layer`.\r
28997        *\r
28998        * @example\r
28999        *\r
29000        * ```js\r
29001        * L.marker([50.5, 30.5]).addTo(map);\r
29002        * ```\r
29003        */\r
29004 \r
29005       var Marker = Layer.extend({\r
29006 \r
29007         // @section\r
29008         // @aka Marker options\r
29009         options: {\r
29010                 // @option icon: Icon = *\r
29011                 // Icon instance to use for rendering the marker.\r
29012                 // See [Icon documentation](#L.Icon) for details on how to customize the marker icon.\r
29013                 // If not specified, a common instance of `L.Icon.Default` is used.\r
29014                 icon: new IconDefault(),\r
29015 \r
29016                 // Option inherited from "Interactive layer" abstract class\r
29017                 interactive: true,\r
29018 \r
29019                 // @option keyboard: Boolean = true\r
29020                 // Whether the marker can be tabbed to with a keyboard and clicked by pressing enter.\r
29021                 keyboard: true,\r
29022 \r
29023                 // @option title: String = ''\r
29024                 // Text for the browser tooltip that appear on marker hover (no tooltip by default).\r
29025                 title: '',\r
29026 \r
29027                 // @option alt: String = ''\r
29028                 // Text for the `alt` attribute of the icon image (useful for accessibility).\r
29029                 alt: '',\r
29030 \r
29031                 // @option zIndexOffset: Number = 0\r
29032                 // By default, marker images zIndex is set automatically based on its latitude. Use this option if you want to put the marker on top of all others (or below), specifying a high value like `1000` (or high negative value, respectively).\r
29033                 zIndexOffset: 0,\r
29034 \r
29035                 // @option opacity: Number = 1.0\r
29036                 // The opacity of the marker.\r
29037                 opacity: 1,\r
29038 \r
29039                 // @option riseOnHover: Boolean = false\r
29040                 // If `true`, the marker will get on top of others when you hover the mouse over it.\r
29041                 riseOnHover: false,\r
29042 \r
29043                 // @option riseOffset: Number = 250\r
29044                 // The z-index offset used for the `riseOnHover` feature.\r
29045                 riseOffset: 250,\r
29046 \r
29047                 // @option pane: String = 'markerPane'\r
29048                 // `Map pane` where the markers icon will be added.\r
29049                 pane: 'markerPane',\r
29050 \r
29051                 // @option shadowPane: String = 'shadowPane'\r
29052                 // `Map pane` where the markers shadow will be added.\r
29053                 shadowPane: 'shadowPane',\r
29054 \r
29055                 // @option bubblingMouseEvents: Boolean = false\r
29056                 // When `true`, a mouse event on this marker will trigger the same event on the map\r
29057                 // (unless [`L.DomEvent.stopPropagation`](#domevent-stoppropagation) is used).\r
29058                 bubblingMouseEvents: false,\r
29059 \r
29060                 // @section Draggable marker options\r
29061                 // @option draggable: Boolean = false\r
29062                 // Whether the marker is draggable with mouse/touch or not.\r
29063                 draggable: false,\r
29064 \r
29065                 // @option autoPan: Boolean = false\r
29066                 // Whether to pan the map when dragging this marker near its edge or not.\r
29067                 autoPan: false,\r
29068 \r
29069                 // @option autoPanPadding: Point = Point(50, 50)\r
29070                 // Distance (in pixels to the left/right and to the top/bottom) of the\r
29071                 // map edge to start panning the map.\r
29072                 autoPanPadding: [50, 50],\r
29073 \r
29074                 // @option autoPanSpeed: Number = 10\r
29075                 // Number of pixels the map should pan by.\r
29076                 autoPanSpeed: 10\r
29077         },\r
29078 \r
29079         /* @section\r
29080          *\r
29081          * In addition to [shared layer methods](#Layer) like `addTo()` and `remove()` and [popup methods](#Popup) like bindPopup() you can also use the following methods:\r
29082          */\r
29083 \r
29084         initialize: function (latlng, options) {\r
29085                 setOptions(this, options);\r
29086                 this._latlng = toLatLng(latlng);\r
29087         },\r
29088 \r
29089         onAdd: function (map) {\r
29090                 this._zoomAnimated = this._zoomAnimated && map.options.markerZoomAnimation;\r
29091 \r
29092                 if (this._zoomAnimated) {\r
29093                         map.on('zoomanim', this._animateZoom, this);\r
29094                 }\r
29095 \r
29096                 this._initIcon();\r
29097                 this.update();\r
29098         },\r
29099 \r
29100         onRemove: function (map) {\r
29101                 if (this.dragging && this.dragging.enabled()) {\r
29102                         this.options.draggable = true;\r
29103                         this.dragging.removeHooks();\r
29104                 }\r
29105                 delete this.dragging;\r
29106 \r
29107                 if (this._zoomAnimated) {\r
29108                         map.off('zoomanim', this._animateZoom, this);\r
29109                 }\r
29110 \r
29111                 this._removeIcon();\r
29112                 this._removeShadow();\r
29113         },\r
29114 \r
29115         getEvents: function () {\r
29116                 return {\r
29117                         zoom: this.update,\r
29118                         viewreset: this.update\r
29119                 };\r
29120         },\r
29121 \r
29122         // @method getLatLng: LatLng\r
29123         // Returns the current geographical position of the marker.\r
29124         getLatLng: function () {\r
29125                 return this._latlng;\r
29126         },\r
29127 \r
29128         // @method setLatLng(latlng: LatLng): this\r
29129         // Changes the marker position to the given point.\r
29130         setLatLng: function (latlng) {\r
29131                 var oldLatLng = this._latlng;\r
29132                 this._latlng = toLatLng(latlng);\r
29133                 this.update();\r
29134 \r
29135                 // @event move: Event\r
29136                 // Fired when the marker is moved via [`setLatLng`](#marker-setlatlng) or by [dragging](#marker-dragging). Old and new coordinates are included in event arguments as `oldLatLng`, `latlng`.\r
29137                 return this.fire('move', {oldLatLng: oldLatLng, latlng: this._latlng});\r
29138         },\r
29139 \r
29140         // @method setZIndexOffset(offset: Number): this\r
29141         // Changes the [zIndex offset](#marker-zindexoffset) of the marker.\r
29142         setZIndexOffset: function (offset) {\r
29143                 this.options.zIndexOffset = offset;\r
29144                 return this.update();\r
29145         },\r
29146 \r
29147         // @method getIcon: Icon\r
29148         // Returns the current icon used by the marker\r
29149         getIcon: function () {\r
29150                 return this.options.icon;\r
29151         },\r
29152 \r
29153         // @method setIcon(icon: Icon): this\r
29154         // Changes the marker icon.\r
29155         setIcon: function (icon) {\r
29156 \r
29157                 this.options.icon = icon;\r
29158 \r
29159                 if (this._map) {\r
29160                         this._initIcon();\r
29161                         this.update();\r
29162                 }\r
29163 \r
29164                 if (this._popup) {\r
29165                         this.bindPopup(this._popup, this._popup.options);\r
29166                 }\r
29167 \r
29168                 return this;\r
29169         },\r
29170 \r
29171         getElement: function () {\r
29172                 return this._icon;\r
29173         },\r
29174 \r
29175         update: function () {\r
29176 \r
29177                 if (this._icon && this._map) {\r
29178                         var pos = this._map.latLngToLayerPoint(this._latlng).round();\r
29179                         this._setPos(pos);\r
29180                 }\r
29181 \r
29182                 return this;\r
29183         },\r
29184 \r
29185         _initIcon: function () {\r
29186                 var options = this.options,\r
29187                     classToAdd = 'leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide');\r
29188 \r
29189                 var icon = options.icon.createIcon(this._icon),\r
29190                     addIcon = false;\r
29191 \r
29192                 // if we're not reusing the icon, remove the old one and init new one\r
29193                 if (icon !== this._icon) {\r
29194                         if (this._icon) {\r
29195                                 this._removeIcon();\r
29196                         }\r
29197                         addIcon = true;\r
29198 \r
29199                         if (options.title) {\r
29200                                 icon.title = options.title;\r
29201                         }\r
29202 \r
29203                         if (icon.tagName === 'IMG') {\r
29204                                 icon.alt = options.alt || '';\r
29205                         }\r
29206                 }\r
29207 \r
29208                 addClass(icon, classToAdd);\r
29209 \r
29210                 if (options.keyboard) {\r
29211                         icon.tabIndex = '0';\r
29212                 }\r
29213 \r
29214                 this._icon = icon;\r
29215 \r
29216                 if (options.riseOnHover) {\r
29217                         this.on({\r
29218                                 mouseover: this._bringToFront,\r
29219                                 mouseout: this._resetZIndex\r
29220                         });\r
29221                 }\r
29222 \r
29223                 var newShadow = options.icon.createShadow(this._shadow),\r
29224                     addShadow = false;\r
29225 \r
29226                 if (newShadow !== this._shadow) {\r
29227                         this._removeShadow();\r
29228                         addShadow = true;\r
29229                 }\r
29230 \r
29231                 if (newShadow) {\r
29232                         addClass(newShadow, classToAdd);\r
29233                         newShadow.alt = '';\r
29234                 }\r
29235                 this._shadow = newShadow;\r
29236 \r
29237 \r
29238                 if (options.opacity < 1) {\r
29239                         this._updateOpacity();\r
29240                 }\r
29241 \r
29242 \r
29243                 if (addIcon) {\r
29244                         this.getPane().appendChild(this._icon);\r
29245                 }\r
29246                 this._initInteraction();\r
29247                 if (newShadow && addShadow) {\r
29248                         this.getPane(options.shadowPane).appendChild(this._shadow);\r
29249                 }\r
29250         },\r
29251 \r
29252         _removeIcon: function () {\r
29253                 if (this.options.riseOnHover) {\r
29254                         this.off({\r
29255                                 mouseover: this._bringToFront,\r
29256                                 mouseout: this._resetZIndex\r
29257                         });\r
29258                 }\r
29259 \r
29260                 remove(this._icon);\r
29261                 this.removeInteractiveTarget(this._icon);\r
29262 \r
29263                 this._icon = null;\r
29264         },\r
29265 \r
29266         _removeShadow: function () {\r
29267                 if (this._shadow) {\r
29268                         remove(this._shadow);\r
29269                 }\r
29270                 this._shadow = null;\r
29271         },\r
29272 \r
29273         _setPos: function (pos) {\r
29274 \r
29275                 if (this._icon) {\r
29276                         setPosition(this._icon, pos);\r
29277                 }\r
29278 \r
29279                 if (this._shadow) {\r
29280                         setPosition(this._shadow, pos);\r
29281                 }\r
29282 \r
29283                 this._zIndex = pos.y + this.options.zIndexOffset;\r
29284 \r
29285                 this._resetZIndex();\r
29286         },\r
29287 \r
29288         _updateZIndex: function (offset) {\r
29289                 if (this._icon) {\r
29290                         this._icon.style.zIndex = this._zIndex + offset;\r
29291                 }\r
29292         },\r
29293 \r
29294         _animateZoom: function (opt) {\r
29295                 var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round();\r
29296 \r
29297                 this._setPos(pos);\r
29298         },\r
29299 \r
29300         _initInteraction: function () {\r
29301 \r
29302                 if (!this.options.interactive) { return; }\r
29303 \r
29304                 addClass(this._icon, 'leaflet-interactive');\r
29305 \r
29306                 this.addInteractiveTarget(this._icon);\r
29307 \r
29308                 if (MarkerDrag) {\r
29309                         var draggable = this.options.draggable;\r
29310                         if (this.dragging) {\r
29311                                 draggable = this.dragging.enabled();\r
29312                                 this.dragging.disable();\r
29313                         }\r
29314 \r
29315                         this.dragging = new MarkerDrag(this);\r
29316 \r
29317                         if (draggable) {\r
29318                                 this.dragging.enable();\r
29319                         }\r
29320                 }\r
29321         },\r
29322 \r
29323         // @method setOpacity(opacity: Number): this\r
29324         // Changes the opacity of the marker.\r
29325         setOpacity: function (opacity) {\r
29326                 this.options.opacity = opacity;\r
29327                 if (this._map) {\r
29328                         this._updateOpacity();\r
29329                 }\r
29330 \r
29331                 return this;\r
29332         },\r
29333 \r
29334         _updateOpacity: function () {\r
29335                 var opacity = this.options.opacity;\r
29336 \r
29337                 if (this._icon) {\r
29338                         setOpacity(this._icon, opacity);\r
29339                 }\r
29340 \r
29341                 if (this._shadow) {\r
29342                         setOpacity(this._shadow, opacity);\r
29343                 }\r
29344         },\r
29345 \r
29346         _bringToFront: function () {\r
29347                 this._updateZIndex(this.options.riseOffset);\r
29348         },\r
29349 \r
29350         _resetZIndex: function () {\r
29351                 this._updateZIndex(0);\r
29352         },\r
29353 \r
29354         _getPopupAnchor: function () {\r
29355                 return this.options.icon.options.popupAnchor;\r
29356         },\r
29357 \r
29358         _getTooltipAnchor: function () {\r
29359                 return this.options.icon.options.tooltipAnchor;\r
29360         }\r
29361       });\r
29362 \r
29363 \r
29364       // factory L.marker(latlng: LatLng, options? : Marker options)\r
29365 \r
29366       // @factory L.marker(latlng: LatLng, options? : Marker options)\r
29367       // Instantiates a Marker object given a geographical point and optionally an options object.\r
29368       function marker(latlng, options) {\r
29369         return new Marker(latlng, options);\r
29370       }
29371
29372       /*
29373        * @class Path
29374        * @aka L.Path
29375        * @inherits Interactive layer
29376        *
29377        * An abstract class that contains options and constants shared between vector
29378        * overlays (Polygon, Polyline, Circle). Do not use it directly. Extends `Layer`.
29379        */
29380
29381       var Path = Layer.extend({
29382
29383         // @section
29384         // @aka Path options
29385         options: {
29386                 // @option stroke: Boolean = true
29387                 // Whether to draw stroke along the path. Set it to `false` to disable borders on polygons or circles.
29388                 stroke: true,
29389
29390                 // @option color: String = '#3388ff'
29391                 // Stroke color
29392                 color: '#3388ff',
29393
29394                 // @option weight: Number = 3
29395                 // Stroke width in pixels
29396                 weight: 3,
29397
29398                 // @option opacity: Number = 1.0
29399                 // Stroke opacity
29400                 opacity: 1,
29401
29402                 // @option lineCap: String= 'round'
29403                 // A string that defines [shape to be used at the end](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-linecap) of the stroke.
29404                 lineCap: 'round',
29405
29406                 // @option lineJoin: String = 'round'
29407                 // A string that defines [shape to be used at the corners](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-linejoin) of the stroke.
29408                 lineJoin: 'round',
29409
29410                 // @option dashArray: String = null
29411                 // A string that defines the stroke [dash pattern](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-dasharray). Doesn't work on `Canvas`-powered layers in [some old browsers](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/setLineDash#Browser_compatibility).
29412                 dashArray: null,
29413
29414                 // @option dashOffset: String = null
29415                 // A string that defines the [distance into the dash pattern to start the dash](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-dashoffset). Doesn't work on `Canvas`-powered layers in [some old browsers](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/setLineDash#Browser_compatibility).
29416                 dashOffset: null,
29417
29418                 // @option fill: Boolean = depends
29419                 // Whether to fill the path with color. Set it to `false` to disable filling on polygons or circles.
29420                 fill: false,
29421
29422                 // @option fillColor: String = *
29423                 // Fill color. Defaults to the value of the [`color`](#path-color) option
29424                 fillColor: null,
29425
29426                 // @option fillOpacity: Number = 0.2
29427                 // Fill opacity.
29428                 fillOpacity: 0.2,
29429
29430                 // @option fillRule: String = 'evenodd'
29431                 // A string that defines [how the inside of a shape](https://developer.mozilla.org/docs/Web/SVG/Attribute/fill-rule) is determined.
29432                 fillRule: 'evenodd',
29433
29434                 // className: '',
29435
29436                 // Option inherited from "Interactive layer" abstract class
29437                 interactive: true,
29438
29439                 // @option bubblingMouseEvents: Boolean = true
29440                 // When `true`, a mouse event on this path will trigger the same event on the map
29441                 // (unless [`L.DomEvent.stopPropagation`](#domevent-stoppropagation) is used).
29442                 bubblingMouseEvents: true
29443         },
29444
29445         beforeAdd: function (map) {
29446                 // Renderer is set here because we need to call renderer.getEvents
29447                 // before this.getEvents.
29448                 this._renderer = map.getRenderer(this);
29449         },
29450
29451         onAdd: function () {
29452                 this._renderer._initPath(this);
29453                 this._reset();
29454                 this._renderer._addPath(this);
29455         },
29456
29457         onRemove: function () {
29458                 this._renderer._removePath(this);
29459         },
29460
29461         // @method redraw(): this
29462         // Redraws the layer. Sometimes useful after you changed the coordinates that the path uses.
29463         redraw: function () {
29464                 if (this._map) {
29465                         this._renderer._updatePath(this);
29466                 }
29467                 return this;
29468         },
29469
29470         // @method setStyle(style: Path options): this
29471         // Changes the appearance of a Path based on the options in the `Path options` object.
29472         setStyle: function (style) {
29473                 setOptions(this, style);
29474                 if (this._renderer) {
29475                         this._renderer._updateStyle(this);
29476                         if (this.options.stroke && style && Object.prototype.hasOwnProperty.call(style, 'weight')) {
29477                                 this._updateBounds();
29478                         }
29479                 }
29480                 return this;
29481         },
29482
29483         // @method bringToFront(): this
29484         // Brings the layer to the top of all path layers.
29485         bringToFront: function () {
29486                 if (this._renderer) {
29487                         this._renderer._bringToFront(this);
29488                 }
29489                 return this;
29490         },
29491
29492         // @method bringToBack(): this
29493         // Brings the layer to the bottom of all path layers.
29494         bringToBack: function () {
29495                 if (this._renderer) {
29496                         this._renderer._bringToBack(this);
29497                 }
29498                 return this;
29499         },
29500
29501         getElement: function () {
29502                 return this._path;
29503         },
29504
29505         _reset: function () {
29506                 // defined in child classes
29507                 this._project();
29508                 this._update();
29509         },
29510
29511         _clickTolerance: function () {
29512                 // used when doing hit detection for Canvas layers
29513                 return (this.options.stroke ? this.options.weight / 2 : 0) + this._renderer.options.tolerance;
29514         }
29515       });
29516
29517       /*
29518        * @class CircleMarker
29519        * @aka L.CircleMarker
29520        * @inherits Path
29521        *
29522        * A circle of a fixed size with radius specified in pixels. Extends `Path`.
29523        */
29524
29525       var CircleMarker = Path.extend({
29526
29527         // @section
29528         // @aka CircleMarker options
29529         options: {
29530                 fill: true,
29531
29532                 // @option radius: Number = 10
29533                 // Radius of the circle marker, in pixels
29534                 radius: 10
29535         },
29536
29537         initialize: function (latlng, options) {
29538                 setOptions(this, options);
29539                 this._latlng = toLatLng(latlng);
29540                 this._radius = this.options.radius;
29541         },
29542
29543         // @method setLatLng(latLng: LatLng): this
29544         // Sets the position of a circle marker to a new location.
29545         setLatLng: function (latlng) {
29546                 var oldLatLng = this._latlng;
29547                 this._latlng = toLatLng(latlng);
29548                 this.redraw();
29549
29550                 // @event move: Event
29551                 // Fired when the marker is moved via [`setLatLng`](#circlemarker-setlatlng). Old and new coordinates are included in event arguments as `oldLatLng`, `latlng`.
29552                 return this.fire('move', {oldLatLng: oldLatLng, latlng: this._latlng});
29553         },
29554
29555         // @method getLatLng(): LatLng
29556         // Returns the current geographical position of the circle marker
29557         getLatLng: function () {
29558                 return this._latlng;
29559         },
29560
29561         // @method setRadius(radius: Number): this
29562         // Sets the radius of a circle marker. Units are in pixels.
29563         setRadius: function (radius) {
29564                 this.options.radius = this._radius = radius;
29565                 return this.redraw();
29566         },
29567
29568         // @method getRadius(): Number
29569         // Returns the current radius of the circle
29570         getRadius: function () {
29571                 return this._radius;
29572         },
29573
29574         setStyle : function (options) {
29575                 var radius = options && options.radius || this._radius;
29576                 Path.prototype.setStyle.call(this, options);
29577                 this.setRadius(radius);
29578                 return this;
29579         },
29580
29581         _project: function () {
29582                 this._point = this._map.latLngToLayerPoint(this._latlng);
29583                 this._updateBounds();
29584         },
29585
29586         _updateBounds: function () {
29587                 var r = this._radius,
29588                     r2 = this._radiusY || r,
29589                     w = this._clickTolerance(),
29590                     p = [r + w, r2 + w];
29591                 this._pxBounds = new Bounds(this._point.subtract(p), this._point.add(p));
29592         },
29593
29594         _update: function () {
29595                 if (this._map) {
29596                         this._updatePath();
29597                 }
29598         },
29599
29600         _updatePath: function () {
29601                 this._renderer._updateCircle(this);
29602         },
29603
29604         _empty: function () {
29605                 return this._radius && !this._renderer._bounds.intersects(this._pxBounds);
29606         },
29607
29608         // Needed by the `Canvas` renderer for interactivity
29609         _containsPoint: function (p) {
29610                 return p.distanceTo(this._point) <= this._radius + this._clickTolerance();
29611         }
29612       });
29613
29614
29615       // @factory L.circleMarker(latlng: LatLng, options?: CircleMarker options)
29616       // Instantiates a circle marker object given a geographical point, and an optional options object.
29617       function circleMarker(latlng, options) {
29618         return new CircleMarker(latlng, options);
29619       }
29620
29621       /*
29622        * @class Circle
29623        * @aka L.Circle
29624        * @inherits CircleMarker
29625        *
29626        * A class for drawing circle overlays on a map. Extends `CircleMarker`.
29627        *
29628        * It's an approximation and starts to diverge from a real circle closer to poles (due to projection distortion).
29629        *
29630        * @example
29631        *
29632        * ```js
29633        * L.circle([50.5, 30.5], {radius: 200}).addTo(map);
29634        * ```
29635        */
29636
29637       var Circle = CircleMarker.extend({
29638
29639         initialize: function (latlng, options, legacyOptions) {
29640                 if (typeof options === 'number') {
29641                         // Backwards compatibility with 0.7.x factory (latlng, radius, options?)
29642                         options = extend({}, legacyOptions, {radius: options});
29643                 }
29644                 setOptions(this, options);
29645                 this._latlng = toLatLng(latlng);
29646
29647                 if (isNaN(this.options.radius)) { throw new Error('Circle radius cannot be NaN'); }
29648
29649                 // @section
29650                 // @aka Circle options
29651                 // @option radius: Number; Radius of the circle, in meters.
29652                 this._mRadius = this.options.radius;
29653         },
29654
29655         // @method setRadius(radius: Number): this
29656         // Sets the radius of a circle. Units are in meters.
29657         setRadius: function (radius) {
29658                 this._mRadius = radius;
29659                 return this.redraw();
29660         },
29661
29662         // @method getRadius(): Number
29663         // Returns the current radius of a circle. Units are in meters.
29664         getRadius: function () {
29665                 return this._mRadius;
29666         },
29667
29668         // @method getBounds(): LatLngBounds
29669         // Returns the `LatLngBounds` of the path.
29670         getBounds: function () {
29671                 var half = [this._radius, this._radiusY || this._radius];
29672
29673                 return new LatLngBounds(
29674                         this._map.layerPointToLatLng(this._point.subtract(half)),
29675                         this._map.layerPointToLatLng(this._point.add(half)));
29676         },
29677
29678         setStyle: Path.prototype.setStyle,
29679
29680         _project: function () {
29681
29682                 var lng = this._latlng.lng,
29683                     lat = this._latlng.lat,
29684                     map = this._map,
29685                     crs = map.options.crs;
29686
29687                 if (crs.distance === Earth.distance) {
29688                         var d = Math.PI / 180,
29689                             latR = (this._mRadius / Earth.R) / d,
29690                             top = map.project([lat + latR, lng]),
29691                             bottom = map.project([lat - latR, lng]),
29692                             p = top.add(bottom).divideBy(2),
29693                             lat2 = map.unproject(p).lat,
29694                             lngR = Math.acos((Math.cos(latR * d) - Math.sin(lat * d) * Math.sin(lat2 * d)) /
29695                                     (Math.cos(lat * d) * Math.cos(lat2 * d))) / d;
29696
29697                         if (isNaN(lngR) || lngR === 0) {
29698                                 lngR = latR / Math.cos(Math.PI / 180 * lat); // Fallback for edge case, #2425
29699                         }
29700
29701                         this._point = p.subtract(map.getPixelOrigin());
29702                         this._radius = isNaN(lngR) ? 0 : p.x - map.project([lat2, lng - lngR]).x;
29703                         this._radiusY = p.y - top.y;
29704
29705                 } else {
29706                         var latlng2 = crs.unproject(crs.project(this._latlng).subtract([this._mRadius, 0]));
29707
29708                         this._point = map.latLngToLayerPoint(this._latlng);
29709                         this._radius = this._point.x - map.latLngToLayerPoint(latlng2).x;
29710                 }
29711
29712                 this._updateBounds();
29713         }
29714       });
29715
29716       // @factory L.circle(latlng: LatLng, options?: Circle options)
29717       // Instantiates a circle object given a geographical point, and an options object
29718       // which contains the circle radius.
29719       // @alternative
29720       // @factory L.circle(latlng: LatLng, radius: Number, options?: Circle options)
29721       // Obsolete way of instantiating a circle, for compatibility with 0.7.x code.
29722       // Do not use in new applications or plugins.
29723       function circle(latlng, options, legacyOptions) {
29724         return new Circle(latlng, options, legacyOptions);
29725       }
29726
29727       /*
29728        * @class Polyline
29729        * @aka L.Polyline
29730        * @inherits Path
29731        *
29732        * A class for drawing polyline overlays on a map. Extends `Path`.
29733        *
29734        * @example
29735        *
29736        * ```js
29737        * // create a red polyline from an array of LatLng points
29738        * var latlngs = [
29739        *        [45.51, -122.68],
29740        *        [37.77, -122.43],
29741        *        [34.04, -118.2]
29742        * ];
29743        *
29744        * var polyline = L.polyline(latlngs, {color: 'red'}).addTo(map);
29745        *
29746        * // zoom the map to the polyline
29747        * map.fitBounds(polyline.getBounds());
29748        * ```
29749        *
29750        * You can also pass a multi-dimensional array to represent a `MultiPolyline` shape:
29751        *
29752        * ```js
29753        * // create a red polyline from an array of arrays of LatLng points
29754        * var latlngs = [
29755        *        [[45.51, -122.68],
29756        *         [37.77, -122.43],
29757        *         [34.04, -118.2]],
29758        *        [[40.78, -73.91],
29759        *         [41.83, -87.62],
29760        *         [32.76, -96.72]]
29761        * ];
29762        * ```
29763        */
29764
29765
29766       var Polyline = Path.extend({
29767
29768         // @section
29769         // @aka Polyline options
29770         options: {
29771                 // @option smoothFactor: Number = 1.0
29772                 // How much to simplify the polyline on each zoom level. More means
29773                 // better performance and smoother look, and less means more accurate representation.
29774                 smoothFactor: 1.0,
29775
29776                 // @option noClip: Boolean = false
29777                 // Disable polyline clipping.
29778                 noClip: false
29779         },
29780
29781         initialize: function (latlngs, options) {
29782                 setOptions(this, options);
29783                 this._setLatLngs(latlngs);
29784         },
29785
29786         // @method getLatLngs(): LatLng[]
29787         // Returns an array of the points in the path, or nested arrays of points in case of multi-polyline.
29788         getLatLngs: function () {
29789                 return this._latlngs;
29790         },
29791
29792         // @method setLatLngs(latlngs: LatLng[]): this
29793         // Replaces all the points in the polyline with the given array of geographical points.
29794         setLatLngs: function (latlngs) {
29795                 this._setLatLngs(latlngs);
29796                 return this.redraw();
29797         },
29798
29799         // @method isEmpty(): Boolean
29800         // Returns `true` if the Polyline has no LatLngs.
29801         isEmpty: function () {
29802                 return !this._latlngs.length;
29803         },
29804
29805         // @method closestLayerPoint(p: Point): Point
29806         // Returns the point closest to `p` on the Polyline.
29807         closestLayerPoint: function (p) {
29808                 var minDistance = Infinity,
29809                     minPoint = null,
29810                     closest = _sqClosestPointOnSegment,
29811                     p1, p2;
29812
29813                 for (var j = 0, jLen = this._parts.length; j < jLen; j++) {
29814                         var points = this._parts[j];
29815
29816                         for (var i = 1, len = points.length; i < len; i++) {
29817                                 p1 = points[i - 1];
29818                                 p2 = points[i];
29819
29820                                 var sqDist = closest(p, p1, p2, true);
29821
29822                                 if (sqDist < minDistance) {
29823                                         minDistance = sqDist;
29824                                         minPoint = closest(p, p1, p2);
29825                                 }
29826                         }
29827                 }
29828                 if (minPoint) {
29829                         minPoint.distance = Math.sqrt(minDistance);
29830                 }
29831                 return minPoint;
29832         },
29833
29834         // @method getCenter(): LatLng
29835         // Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the polyline.
29836         getCenter: function () {
29837                 // throws error when not yet added to map as this center calculation requires projected coordinates
29838                 if (!this._map) {
29839                         throw new Error('Must add layer to map before using getCenter()');
29840                 }
29841
29842                 var i, halfDist, segDist, dist, p1, p2, ratio,
29843                     points = this._rings[0],
29844                     len = points.length;
29845
29846                 if (!len) { return null; }
29847
29848                 // polyline centroid algorithm; only uses the first ring if there are multiple
29849
29850                 for (i = 0, halfDist = 0; i < len - 1; i++) {
29851                         halfDist += points[i].distanceTo(points[i + 1]) / 2;
29852                 }
29853
29854                 // The line is so small in the current view that all points are on the same pixel.
29855                 if (halfDist === 0) {
29856                         return this._map.layerPointToLatLng(points[0]);
29857                 }
29858
29859                 for (i = 0, dist = 0; i < len - 1; i++) {
29860                         p1 = points[i];
29861                         p2 = points[i + 1];
29862                         segDist = p1.distanceTo(p2);
29863                         dist += segDist;
29864
29865                         if (dist > halfDist) {
29866                                 ratio = (dist - halfDist) / segDist;
29867                                 return this._map.layerPointToLatLng([
29868                                         p2.x - ratio * (p2.x - p1.x),
29869                                         p2.y - ratio * (p2.y - p1.y)
29870                                 ]);
29871                         }
29872                 }
29873         },
29874
29875         // @method getBounds(): LatLngBounds
29876         // Returns the `LatLngBounds` of the path.
29877         getBounds: function () {
29878                 return this._bounds;
29879         },
29880
29881         // @method addLatLng(latlng: LatLng, latlngs?: LatLng[]): this
29882         // Adds a given point to the polyline. By default, adds to the first ring of
29883         // the polyline in case of a multi-polyline, but can be overridden by passing
29884         // a specific ring as a LatLng array (that you can earlier access with [`getLatLngs`](#polyline-getlatlngs)).
29885         addLatLng: function (latlng, latlngs) {
29886                 latlngs = latlngs || this._defaultShape();
29887                 latlng = toLatLng(latlng);
29888                 latlngs.push(latlng);
29889                 this._bounds.extend(latlng);
29890                 return this.redraw();
29891         },
29892
29893         _setLatLngs: function (latlngs) {
29894                 this._bounds = new LatLngBounds();
29895                 this._latlngs = this._convertLatLngs(latlngs);
29896         },
29897
29898         _defaultShape: function () {
29899                 return isFlat(this._latlngs) ? this._latlngs : this._latlngs[0];
29900         },
29901
29902         // recursively convert latlngs input into actual LatLng instances; calculate bounds along the way
29903         _convertLatLngs: function (latlngs) {
29904                 var result = [],
29905                     flat = isFlat(latlngs);
29906
29907                 for (var i = 0, len = latlngs.length; i < len; i++) {
29908                         if (flat) {
29909                                 result[i] = toLatLng(latlngs[i]);
29910                                 this._bounds.extend(result[i]);
29911                         } else {
29912                                 result[i] = this._convertLatLngs(latlngs[i]);
29913                         }
29914                 }
29915
29916                 return result;
29917         },
29918
29919         _project: function () {
29920                 var pxBounds = new Bounds();
29921                 this._rings = [];
29922                 this._projectLatlngs(this._latlngs, this._rings, pxBounds);
29923
29924                 if (this._bounds.isValid() && pxBounds.isValid()) {
29925                         this._rawPxBounds = pxBounds;
29926                         this._updateBounds();
29927                 }
29928         },
29929
29930         _updateBounds: function () {
29931                 var w = this._clickTolerance(),
29932                     p = new Point(w, w);
29933                 this._pxBounds = new Bounds([
29934                         this._rawPxBounds.min.subtract(p),
29935                         this._rawPxBounds.max.add(p)
29936                 ]);
29937         },
29938
29939         // recursively turns latlngs into a set of rings with projected coordinates
29940         _projectLatlngs: function (latlngs, result, projectedBounds) {
29941                 var flat = latlngs[0] instanceof LatLng,
29942                     len = latlngs.length,
29943                     i, ring;
29944
29945                 if (flat) {
29946                         ring = [];
29947                         for (i = 0; i < len; i++) {
29948                                 ring[i] = this._map.latLngToLayerPoint(latlngs[i]);
29949                                 projectedBounds.extend(ring[i]);
29950                         }
29951                         result.push(ring);
29952                 } else {
29953                         for (i = 0; i < len; i++) {
29954                                 this._projectLatlngs(latlngs[i], result, projectedBounds);
29955                         }
29956                 }
29957         },
29958
29959         // clip polyline by renderer bounds so that we have less to render for performance
29960         _clipPoints: function () {
29961                 var bounds = this._renderer._bounds;
29962
29963                 this._parts = [];
29964                 if (!this._pxBounds || !this._pxBounds.intersects(bounds)) {
29965                         return;
29966                 }
29967
29968                 if (this.options.noClip) {
29969                         this._parts = this._rings;
29970                         return;
29971                 }
29972
29973                 var parts = this._parts,
29974                     i, j, k, len, len2, segment, points;
29975
29976                 for (i = 0, k = 0, len = this._rings.length; i < len; i++) {
29977                         points = this._rings[i];
29978
29979                         for (j = 0, len2 = points.length; j < len2 - 1; j++) {
29980                                 segment = clipSegment(points[j], points[j + 1], bounds, j, true);
29981
29982                                 if (!segment) { continue; }
29983
29984                                 parts[k] = parts[k] || [];
29985                                 parts[k].push(segment[0]);
29986
29987                                 // if segment goes out of screen, or it's the last one, it's the end of the line part
29988                                 if ((segment[1] !== points[j + 1]) || (j === len2 - 2)) {
29989                                         parts[k].push(segment[1]);
29990                                         k++;
29991                                 }
29992                         }
29993                 }
29994         },
29995
29996         // simplify each clipped part of the polyline for performance
29997         _simplifyPoints: function () {
29998                 var parts = this._parts,
29999                     tolerance = this.options.smoothFactor;
30000
30001                 for (var i = 0, len = parts.length; i < len; i++) {
30002                         parts[i] = simplify(parts[i], tolerance);
30003                 }
30004         },
30005
30006         _update: function () {
30007                 if (!this._map) { return; }
30008
30009                 this._clipPoints();
30010                 this._simplifyPoints();
30011                 this._updatePath();
30012         },
30013
30014         _updatePath: function () {
30015                 this._renderer._updatePoly(this);
30016         },
30017
30018         // Needed by the `Canvas` renderer for interactivity
30019         _containsPoint: function (p, closed) {
30020                 var i, j, k, len, len2, part,
30021                     w = this._clickTolerance();
30022
30023                 if (!this._pxBounds || !this._pxBounds.contains(p)) { return false; }
30024
30025                 // hit detection for polylines
30026                 for (i = 0, len = this._parts.length; i < len; i++) {
30027                         part = this._parts[i];
30028
30029                         for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) {
30030                                 if (!closed && (j === 0)) { continue; }
30031
30032                                 if (pointToSegmentDistance(p, part[k], part[j]) <= w) {
30033                                         return true;
30034                                 }
30035                         }
30036                 }
30037                 return false;
30038         }
30039       });
30040
30041       // @factory L.polyline(latlngs: LatLng[], options?: Polyline options)
30042       // Instantiates a polyline object given an array of geographical points and
30043       // optionally an options object. You can create a `Polyline` object with
30044       // multiple separate lines (`MultiPolyline`) by passing an array of arrays
30045       // of geographic points.
30046       function polyline(latlngs, options) {
30047         return new Polyline(latlngs, options);
30048       }
30049
30050       // Retrocompat. Allow plugins to support Leaflet versions before and after 1.1.
30051       Polyline._flat = _flat;
30052
30053       /*
30054        * @class Polygon
30055        * @aka L.Polygon
30056        * @inherits Polyline
30057        *
30058        * A class for drawing polygon overlays on a map. Extends `Polyline`.
30059        *
30060        * Note that points you pass when creating a polygon shouldn't have an additional last point equal to the first one â€” it's better to filter out such points.
30061        *
30062        *
30063        * @example
30064        *
30065        * ```js
30066        * // create a red polygon from an array of LatLng points
30067        * var latlngs = [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]];
30068        *
30069        * var polygon = L.polygon(latlngs, {color: 'red'}).addTo(map);
30070        *
30071        * // zoom the map to the polygon
30072        * map.fitBounds(polygon.getBounds());
30073        * ```
30074        *
30075        * You can also pass an array of arrays of latlngs, with the first array representing the outer shape and the other arrays representing holes in the outer shape:
30076        *
30077        * ```js
30078        * var latlngs = [
30079        *   [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]], // outer ring
30080        *   [[37.29, -108.58],[40.71, -108.58],[40.71, -102.50],[37.29, -102.50]] // hole
30081        * ];
30082        * ```
30083        *
30084        * Additionally, you can pass a multi-dimensional array to represent a MultiPolygon shape.
30085        *
30086        * ```js
30087        * var latlngs = [
30088        *   [ // first polygon
30089        *     [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]], // outer ring
30090        *     [[37.29, -108.58],[40.71, -108.58],[40.71, -102.50],[37.29, -102.50]] // hole
30091        *   ],
30092        *   [ // second polygon
30093        *     [[41, -111.03],[45, -111.04],[45, -104.05],[41, -104.05]]
30094        *   ]
30095        * ];
30096        * ```
30097        */
30098
30099       var Polygon = Polyline.extend({
30100
30101         options: {
30102                 fill: true
30103         },
30104
30105         isEmpty: function () {
30106                 return !this._latlngs.length || !this._latlngs[0].length;
30107         },
30108
30109         getCenter: function () {
30110                 // throws error when not yet added to map as this center calculation requires projected coordinates
30111                 if (!this._map) {
30112                         throw new Error('Must add layer to map before using getCenter()');
30113                 }
30114
30115                 var i, j, p1, p2, f, area, x, y, center,
30116                     points = this._rings[0],
30117                     len = points.length;
30118
30119                 if (!len) { return null; }
30120
30121                 // polygon centroid algorithm; only uses the first ring if there are multiple
30122
30123                 area = x = y = 0;
30124
30125                 for (i = 0, j = len - 1; i < len; j = i++) {
30126                         p1 = points[i];
30127                         p2 = points[j];
30128
30129                         f = p1.y * p2.x - p2.y * p1.x;
30130                         x += (p1.x + p2.x) * f;
30131                         y += (p1.y + p2.y) * f;
30132                         area += f * 3;
30133                 }
30134
30135                 if (area === 0) {
30136                         // Polygon is so small that all points are on same pixel.
30137                         center = points[0];
30138                 } else {
30139                         center = [x / area, y / area];
30140                 }
30141                 return this._map.layerPointToLatLng(center);
30142         },
30143
30144         _convertLatLngs: function (latlngs) {
30145                 var result = Polyline.prototype._convertLatLngs.call(this, latlngs),
30146                     len = result.length;
30147
30148                 // remove last point if it equals first one
30149                 if (len >= 2 && result[0] instanceof LatLng && result[0].equals(result[len - 1])) {
30150                         result.pop();
30151                 }
30152                 return result;
30153         },
30154
30155         _setLatLngs: function (latlngs) {
30156                 Polyline.prototype._setLatLngs.call(this, latlngs);
30157                 if (isFlat(this._latlngs)) {
30158                         this._latlngs = [this._latlngs];
30159                 }
30160         },
30161
30162         _defaultShape: function () {
30163                 return isFlat(this._latlngs[0]) ? this._latlngs[0] : this._latlngs[0][0];
30164         },
30165
30166         _clipPoints: function () {
30167                 // polygons need a different clipping algorithm so we redefine that
30168
30169                 var bounds = this._renderer._bounds,
30170                     w = this.options.weight,
30171                     p = new Point(w, w);
30172
30173                 // increase clip padding by stroke width to avoid stroke on clip edges
30174                 bounds = new Bounds(bounds.min.subtract(p), bounds.max.add(p));
30175
30176                 this._parts = [];
30177                 if (!this._pxBounds || !this._pxBounds.intersects(bounds)) {
30178                         return;
30179                 }
30180
30181                 if (this.options.noClip) {
30182                         this._parts = this._rings;
30183                         return;
30184                 }
30185
30186                 for (var i = 0, len = this._rings.length, clipped; i < len; i++) {
30187                         clipped = clipPolygon(this._rings[i], bounds, true);
30188                         if (clipped.length) {
30189                                 this._parts.push(clipped);
30190                         }
30191                 }
30192         },
30193
30194         _updatePath: function () {
30195                 this._renderer._updatePoly(this, true);
30196         },
30197
30198         // Needed by the `Canvas` renderer for interactivity
30199         _containsPoint: function (p) {
30200                 var inside = false,
30201                     part, p1, p2, i, j, k, len, len2;
30202
30203                 if (!this._pxBounds || !this._pxBounds.contains(p)) { return false; }
30204
30205                 // ray casting algorithm for detecting if point is in polygon
30206                 for (i = 0, len = this._parts.length; i < len; i++) {
30207                         part = this._parts[i];
30208
30209                         for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) {
30210                                 p1 = part[j];
30211                                 p2 = part[k];
30212
30213                                 if (((p1.y > p.y) !== (p2.y > p.y)) && (p.x < (p2.x - p1.x) * (p.y - p1.y) / (p2.y - p1.y) + p1.x)) {
30214                                         inside = !inside;
30215                                 }
30216                         }
30217                 }
30218
30219                 // also check if it's on polygon stroke
30220                 return inside || Polyline.prototype._containsPoint.call(this, p, true);
30221         }
30222
30223       });
30224
30225
30226       // @factory L.polygon(latlngs: LatLng[], options?: Polyline options)
30227       function polygon(latlngs, options) {
30228         return new Polygon(latlngs, options);
30229       }
30230
30231       /*\r
30232        * @class GeoJSON\r
30233        * @aka L.GeoJSON\r
30234        * @inherits FeatureGroup\r
30235        *\r
30236        * Represents a GeoJSON object or an array of GeoJSON objects. Allows you to parse\r
30237        * GeoJSON data and display it on the map. Extends `FeatureGroup`.\r
30238        *\r
30239        * @example\r
30240        *\r
30241        * ```js\r
30242        * L.geoJSON(data, {\r
30243        *        style: function (feature) {\r
30244        *                return {color: feature.properties.color};\r
30245        *        }\r
30246        * }).bindPopup(function (layer) {\r
30247        *        return layer.feature.properties.description;\r
30248        * }).addTo(map);\r
30249        * ```\r
30250        */\r
30251 \r
30252       var GeoJSON = FeatureGroup.extend({\r
30253 \r
30254         /* @section\r
30255          * @aka GeoJSON options\r
30256          *\r
30257          * @option pointToLayer: Function = *\r
30258          * A `Function` defining how GeoJSON points spawn Leaflet layers. It is internally\r
30259          * called when data is added, passing the GeoJSON point feature and its `LatLng`.\r
30260          * The default is to spawn a default `Marker`:\r
30261          * ```js\r
30262          * function(geoJsonPoint, latlng) {\r
30263          *      return L.marker(latlng);\r
30264          * }\r
30265          * ```\r
30266          *\r
30267          * @option style: Function = *\r
30268          * A `Function` defining the `Path options` for styling GeoJSON lines and polygons,\r
30269          * called internally when data is added.\r
30270          * The default value is to not override any defaults:\r
30271          * ```js\r
30272          * function (geoJsonFeature) {\r
30273          *      return {}\r
30274          * }\r
30275          * ```\r
30276          *\r
30277          * @option onEachFeature: Function = *\r
30278          * A `Function` that will be called once for each created `Feature`, after it has\r
30279          * been created and styled. Useful for attaching events and popups to features.\r
30280          * The default is to do nothing with the newly created layers:\r
30281          * ```js\r
30282          * function (feature, layer) {}\r
30283          * ```\r
30284          *\r
30285          * @option filter: Function = *\r
30286          * A `Function` that will be used to decide whether to include a feature or not.\r
30287          * The default is to include all features:\r
30288          * ```js\r
30289          * function (geoJsonFeature) {\r
30290          *      return true;\r
30291          * }\r
30292          * ```\r
30293          * Note: dynamically changing the `filter` option will have effect only on newly\r
30294          * added data. It will _not_ re-evaluate already included features.\r
30295          *\r
30296          * @option coordsToLatLng: Function = *\r
30297          * A `Function` that will be used for converting GeoJSON coordinates to `LatLng`s.\r
30298          * The default is the `coordsToLatLng` static method.\r
30299          *\r
30300          * @option markersInheritOptions: Boolean = false\r
30301          * Whether default Markers for "Point" type Features inherit from group options.\r
30302          */\r
30303 \r
30304         initialize: function (geojson, options) {\r
30305                 setOptions(this, options);\r
30306 \r
30307                 this._layers = {};\r
30308 \r
30309                 if (geojson) {\r
30310                         this.addData(geojson);\r
30311                 }\r
30312         },\r
30313 \r
30314         // @method addData( <GeoJSON> data ): this\r
30315         // Adds a GeoJSON object to the layer.\r
30316         addData: function (geojson) {\r
30317                 var features = isArray(geojson) ? geojson : geojson.features,\r
30318                     i, len, feature;\r
30319 \r
30320                 if (features) {\r
30321                         for (i = 0, len = features.length; i < len; i++) {\r
30322                                 // only add this if geometry or geometries are set and not null\r
30323                                 feature = features[i];\r
30324                                 if (feature.geometries || feature.geometry || feature.features || feature.coordinates) {\r
30325                                         this.addData(feature);\r
30326                                 }\r
30327                         }\r
30328                         return this;\r
30329                 }\r
30330 \r
30331                 var options = this.options;\r
30332 \r
30333                 if (options.filter && !options.filter(geojson)) { return this; }\r
30334 \r
30335                 var layer = geometryToLayer(geojson, options);\r
30336                 if (!layer) {\r
30337                         return this;\r
30338                 }\r
30339                 layer.feature = asFeature(geojson);\r
30340 \r
30341                 layer.defaultOptions = layer.options;\r
30342                 this.resetStyle(layer);\r
30343 \r
30344                 if (options.onEachFeature) {\r
30345                         options.onEachFeature(geojson, layer);\r
30346                 }\r
30347 \r
30348                 return this.addLayer(layer);\r
30349         },\r
30350 \r
30351         // @method resetStyle( <Path> layer? ): this\r
30352         // Resets the given vector layer's style to the original GeoJSON style, useful for resetting style after hover events.\r
30353         // If `layer` is omitted, the style of all features in the current layer is reset.\r
30354         resetStyle: function (layer) {\r
30355                 if (layer === undefined) {\r
30356                         return this.eachLayer(this.resetStyle, this);\r
30357                 }\r
30358                 // reset any custom styles\r
30359                 layer.options = extend({}, layer.defaultOptions);\r
30360                 this._setLayerStyle(layer, this.options.style);\r
30361                 return this;\r
30362         },\r
30363 \r
30364         // @method setStyle( <Function> style ): this\r
30365         // Changes styles of GeoJSON vector layers with the given style function.\r
30366         setStyle: function (style) {\r
30367                 return this.eachLayer(function (layer) {\r
30368                         this._setLayerStyle(layer, style);\r
30369                 }, this);\r
30370         },\r
30371 \r
30372         _setLayerStyle: function (layer, style) {\r
30373                 if (layer.setStyle) {\r
30374                         if (typeof style === 'function') {\r
30375                                 style = style(layer.feature);\r
30376                         }\r
30377                         layer.setStyle(style);\r
30378                 }\r
30379         }\r
30380       });\r
30381 \r
30382       // @section\r
30383       // There are several static functions which can be called without instantiating L.GeoJSON:\r
30384 \r
30385       // @function geometryToLayer(featureData: Object, options?: GeoJSON options): Layer\r
30386       // Creates a `Layer` from a given GeoJSON feature. Can use a custom\r
30387       // [`pointToLayer`](#geojson-pointtolayer) and/or [`coordsToLatLng`](#geojson-coordstolatlng)\r
30388       // functions if provided as options.\r
30389       function geometryToLayer(geojson, options) {\r
30390 \r
30391         var geometry = geojson.type === 'Feature' ? geojson.geometry : geojson,\r
30392             coords = geometry ? geometry.coordinates : null,\r
30393             layers = [],\r
30394             pointToLayer = options && options.pointToLayer,\r
30395             _coordsToLatLng = options && options.coordsToLatLng || coordsToLatLng,\r
30396             latlng, latlngs, i, len;\r
30397 \r
30398         if (!coords && !geometry) {\r
30399                 return null;\r
30400         }\r
30401 \r
30402         switch (geometry.type) {\r
30403         case 'Point':\r
30404                 latlng = _coordsToLatLng(coords);\r
30405                 return _pointToLayer(pointToLayer, geojson, latlng, options);\r
30406 \r
30407         case 'MultiPoint':\r
30408                 for (i = 0, len = coords.length; i < len; i++) {\r
30409                         latlng = _coordsToLatLng(coords[i]);\r
30410                         layers.push(_pointToLayer(pointToLayer, geojson, latlng, options));\r
30411                 }\r
30412                 return new FeatureGroup(layers);\r
30413 \r
30414         case 'LineString':\r
30415         case 'MultiLineString':\r
30416                 latlngs = coordsToLatLngs(coords, geometry.type === 'LineString' ? 0 : 1, _coordsToLatLng);\r
30417                 return new Polyline(latlngs, options);\r
30418 \r
30419         case 'Polygon':\r
30420         case 'MultiPolygon':\r
30421                 latlngs = coordsToLatLngs(coords, geometry.type === 'Polygon' ? 1 : 2, _coordsToLatLng);\r
30422                 return new Polygon(latlngs, options);\r
30423 \r
30424         case 'GeometryCollection':\r
30425                 for (i = 0, len = geometry.geometries.length; i < len; i++) {\r
30426                         var layer = geometryToLayer({\r
30427                                 geometry: geometry.geometries[i],\r
30428                                 type: 'Feature',\r
30429                                 properties: geojson.properties\r
30430                         }, options);\r
30431 \r
30432                         if (layer) {\r
30433                                 layers.push(layer);\r
30434                         }\r
30435                 }\r
30436                 return new FeatureGroup(layers);\r
30437 \r
30438         default:\r
30439                 throw new Error('Invalid GeoJSON object.');\r
30440         }\r
30441       }\r
30442 \r
30443       function _pointToLayer(pointToLayerFn, geojson, latlng, options) {\r
30444         return pointToLayerFn ?\r
30445                 pointToLayerFn(geojson, latlng) :\r
30446                 new Marker(latlng, options && options.markersInheritOptions && options);\r
30447       }\r
30448 \r
30449       // @function coordsToLatLng(coords: Array): LatLng\r
30450       // Creates a `LatLng` object from an array of 2 numbers (longitude, latitude)\r
30451       // or 3 numbers (longitude, latitude, altitude) used in GeoJSON for points.\r
30452       function coordsToLatLng(coords) {\r
30453         return new LatLng(coords[1], coords[0], coords[2]);\r
30454       }\r
30455 \r
30456       // @function coordsToLatLngs(coords: Array, levelsDeep?: Number, coordsToLatLng?: Function): Array\r
30457       // Creates a multidimensional array of `LatLng`s from a GeoJSON coordinates array.\r
30458       // `levelsDeep` specifies the nesting level (0 is for an array of points, 1 for an array of arrays of points, etc., 0 by default).\r
30459       // Can use a custom [`coordsToLatLng`](#geojson-coordstolatlng) function.\r
30460       function coordsToLatLngs(coords, levelsDeep, _coordsToLatLng) {\r
30461         var latlngs = [];\r
30462 \r
30463         for (var i = 0, len = coords.length, latlng; i < len; i++) {\r
30464                 latlng = levelsDeep ?\r
30465                         coordsToLatLngs(coords[i], levelsDeep - 1, _coordsToLatLng) :\r
30466                         (_coordsToLatLng || coordsToLatLng)(coords[i]);\r
30467 \r
30468                 latlngs.push(latlng);\r
30469         }\r
30470 \r
30471         return latlngs;\r
30472       }\r
30473 \r
30474       // @function latLngToCoords(latlng: LatLng, precision?: Number): Array\r
30475       // Reverse of [`coordsToLatLng`](#geojson-coordstolatlng)\r
30476       function latLngToCoords(latlng, precision) {\r
30477         precision = typeof precision === 'number' ? precision : 6;\r
30478         return latlng.alt !== undefined ?\r
30479                 [formatNum(latlng.lng, precision), formatNum(latlng.lat, precision), formatNum(latlng.alt, precision)] :\r
30480                 [formatNum(latlng.lng, precision), formatNum(latlng.lat, precision)];\r
30481       }\r
30482 \r
30483       // @function latLngsToCoords(latlngs: Array, levelsDeep?: Number, closed?: Boolean): Array\r
30484       // Reverse of [`coordsToLatLngs`](#geojson-coordstolatlngs)\r
30485       // `closed` determines whether the first point should be appended to the end of the array to close the feature, only used when `levelsDeep` is 0. False by default.\r
30486       function latLngsToCoords(latlngs, levelsDeep, closed, precision) {\r
30487         var coords = [];\r
30488 \r
30489         for (var i = 0, len = latlngs.length; i < len; i++) {\r
30490                 coords.push(levelsDeep ?\r
30491                         latLngsToCoords(latlngs[i], levelsDeep - 1, closed, precision) :\r
30492                         latLngToCoords(latlngs[i], precision));\r
30493         }\r
30494 \r
30495         if (!levelsDeep && closed) {\r
30496                 coords.push(coords[0]);\r
30497         }\r
30498 \r
30499         return coords;\r
30500       }\r
30501 \r
30502       function getFeature(layer, newGeometry) {\r
30503         return layer.feature ?\r
30504                 extend({}, layer.feature, {geometry: newGeometry}) :\r
30505                 asFeature(newGeometry);\r
30506       }\r
30507 \r
30508       // @function asFeature(geojson: Object): Object\r
30509       // Normalize GeoJSON geometries/features into GeoJSON features.\r
30510       function asFeature(geojson) {\r
30511         if (geojson.type === 'Feature' || geojson.type === 'FeatureCollection') {\r
30512                 return geojson;\r
30513         }\r
30514 \r
30515         return {\r
30516                 type: 'Feature',\r
30517                 properties: {},\r
30518                 geometry: geojson\r
30519         };\r
30520       }\r
30521 \r
30522       var PointToGeoJSON = {\r
30523         toGeoJSON: function (precision) {\r
30524                 return getFeature(this, {\r
30525                         type: 'Point',\r
30526                         coordinates: latLngToCoords(this.getLatLng(), precision)\r
30527                 });\r
30528         }\r
30529       };\r
30530 \r
30531       // @namespace Marker\r
30532       // @section Other methods\r
30533       // @method toGeoJSON(precision?: Number): Object\r
30534       // `precision` is the number of decimal places for coordinates.\r
30535       // The default value is 6 places.\r
30536       // Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the marker (as a GeoJSON `Point` Feature).\r
30537       Marker.include(PointToGeoJSON);\r
30538 \r
30539       // @namespace CircleMarker\r
30540       // @method toGeoJSON(precision?: Number): Object\r
30541       // `precision` is the number of decimal places for coordinates.\r
30542       // The default value is 6 places.\r
30543       // Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the circle marker (as a GeoJSON `Point` Feature).\r
30544       Circle.include(PointToGeoJSON);\r
30545       CircleMarker.include(PointToGeoJSON);\r
30546 \r
30547 \r
30548       // @namespace Polyline\r
30549       // @method toGeoJSON(precision?: Number): Object\r
30550       // `precision` is the number of decimal places for coordinates.\r
30551       // The default value is 6 places.\r
30552       // Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the polyline (as a GeoJSON `LineString` or `MultiLineString` Feature).\r
30553       Polyline.include({\r
30554         toGeoJSON: function (precision) {\r
30555                 var multi = !isFlat(this._latlngs);\r
30556 \r
30557                 var coords = latLngsToCoords(this._latlngs, multi ? 1 : 0, false, precision);\r
30558 \r
30559                 return getFeature(this, {\r
30560                         type: (multi ? 'Multi' : '') + 'LineString',\r
30561                         coordinates: coords\r
30562                 });\r
30563         }\r
30564       });\r
30565 \r
30566       // @namespace Polygon\r
30567       // @method toGeoJSON(precision?: Number): Object\r
30568       // `precision` is the number of decimal places for coordinates.\r
30569       // The default value is 6 places.\r
30570       // Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the polygon (as a GeoJSON `Polygon` or `MultiPolygon` Feature).\r
30571       Polygon.include({\r
30572         toGeoJSON: function (precision) {\r
30573                 var holes = !isFlat(this._latlngs),\r
30574                     multi = holes && !isFlat(this._latlngs[0]);\r
30575 \r
30576                 var coords = latLngsToCoords(this._latlngs, multi ? 2 : holes ? 1 : 0, true, precision);\r
30577 \r
30578                 if (!holes) {\r
30579                         coords = [coords];\r
30580                 }\r
30581 \r
30582                 return getFeature(this, {\r
30583                         type: (multi ? 'Multi' : '') + 'Polygon',\r
30584                         coordinates: coords\r
30585                 });\r
30586         }\r
30587       });\r
30588 \r
30589 \r
30590       // @namespace LayerGroup\r
30591       LayerGroup.include({\r
30592         toMultiPoint: function (precision) {\r
30593                 var coords = [];\r
30594 \r
30595                 this.eachLayer(function (layer) {\r
30596                         coords.push(layer.toGeoJSON(precision).geometry.coordinates);\r
30597                 });\r
30598 \r
30599                 return getFeature(this, {\r
30600                         type: 'MultiPoint',\r
30601                         coordinates: coords\r
30602                 });\r
30603         },\r
30604 \r
30605         // @method toGeoJSON(precision?: Number): Object\r
30606         // `precision` is the number of decimal places for coordinates.\r
30607         // The default value is 6 places.\r
30608         // Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the layer group (as a GeoJSON `FeatureCollection`, `GeometryCollection`, or `MultiPoint`).\r
30609         toGeoJSON: function (precision) {\r
30610 \r
30611                 var type = this.feature && this.feature.geometry && this.feature.geometry.type;\r
30612 \r
30613                 if (type === 'MultiPoint') {\r
30614                         return this.toMultiPoint(precision);\r
30615                 }\r
30616 \r
30617                 var isGeometryCollection = type === 'GeometryCollection',\r
30618                     jsons = [];\r
30619 \r
30620                 this.eachLayer(function (layer) {\r
30621                         if (layer.toGeoJSON) {\r
30622                                 var json = layer.toGeoJSON(precision);\r
30623                                 if (isGeometryCollection) {\r
30624                                         jsons.push(json.geometry);\r
30625                                 } else {\r
30626                                         var feature = asFeature(json);\r
30627                                         // Squash nested feature collections\r
30628                                         if (feature.type === 'FeatureCollection') {\r
30629                                                 jsons.push.apply(jsons, feature.features);\r
30630                                         } else {\r
30631                                                 jsons.push(feature);\r
30632                                         }\r
30633                                 }\r
30634                         }\r
30635                 });\r
30636 \r
30637                 if (isGeometryCollection) {\r
30638                         return getFeature(this, {\r
30639                                 geometries: jsons,\r
30640                                 type: 'GeometryCollection'\r
30641                         });\r
30642                 }\r
30643 \r
30644                 return {\r
30645                         type: 'FeatureCollection',\r
30646                         features: jsons\r
30647                 };\r
30648         }\r
30649       });\r
30650 \r
30651       // @namespace GeoJSON\r
30652       // @factory L.geoJSON(geojson?: Object, options?: GeoJSON options)\r
30653       // Creates a GeoJSON layer. Optionally accepts an object in\r
30654       // [GeoJSON format](https://tools.ietf.org/html/rfc7946) to display on the map\r
30655       // (you can alternatively add it later with `addData` method) and an `options` object.\r
30656       function geoJSON(geojson, options) {\r
30657         return new GeoJSON(geojson, options);\r
30658       }\r
30659 \r
30660       // Backward compatibility.\r
30661       var geoJson = geoJSON;
30662
30663       /*\r
30664        * @class ImageOverlay\r
30665        * @aka L.ImageOverlay\r
30666        * @inherits Interactive layer\r
30667        *\r
30668        * Used to load and display a single image over specific bounds of the map. Extends `Layer`.\r
30669        *\r
30670        * @example\r
30671        *\r
30672        * ```js\r
30673        * var imageUrl = 'http://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg',\r
30674        *        imageBounds = [[40.712216, -74.22655], [40.773941, -74.12544]];\r
30675        * L.imageOverlay(imageUrl, imageBounds).addTo(map);\r
30676        * ```\r
30677        */\r
30678 \r
30679       var ImageOverlay = Layer.extend({\r
30680 \r
30681         // @section\r
30682         // @aka ImageOverlay options\r
30683         options: {\r
30684                 // @option opacity: Number = 1.0\r
30685                 // The opacity of the image overlay.\r
30686                 opacity: 1,\r
30687 \r
30688                 // @option alt: String = ''\r
30689                 // Text for the `alt` attribute of the image (useful for accessibility).\r
30690                 alt: '',\r
30691 \r
30692                 // @option interactive: Boolean = false\r
30693                 // If `true`, the image overlay will emit [mouse events](#interactive-layer) when clicked or hovered.\r
30694                 interactive: false,\r
30695 \r
30696                 // @option crossOrigin: Boolean|String = false\r
30697                 // Whether the crossOrigin attribute will be added to the image.\r
30698                 // If a String is provided, the image will have its crossOrigin attribute set to the String provided. This is needed if you want to access image pixel data.\r
30699                 // Refer to [CORS Settings](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) for valid String values.\r
30700                 crossOrigin: false,\r
30701 \r
30702                 // @option errorOverlayUrl: String = ''\r
30703                 // URL to the overlay image to show in place of the overlay that failed to load.\r
30704                 errorOverlayUrl: '',\r
30705 \r
30706                 // @option zIndex: Number = 1\r
30707                 // The explicit [zIndex](https://developer.mozilla.org/docs/Web/CSS/CSS_Positioning/Understanding_z_index) of the overlay layer.\r
30708                 zIndex: 1,\r
30709 \r
30710                 // @option className: String = ''\r
30711                 // A custom class name to assign to the image. Empty by default.\r
30712                 className: ''\r
30713         },\r
30714 \r
30715         initialize: function (url, bounds, options) { // (String, LatLngBounds, Object)\r
30716                 this._url = url;\r
30717                 this._bounds = toLatLngBounds(bounds);\r
30718 \r
30719                 setOptions(this, options);\r
30720         },\r
30721 \r
30722         onAdd: function () {\r
30723                 if (!this._image) {\r
30724                         this._initImage();\r
30725 \r
30726                         if (this.options.opacity < 1) {\r
30727                                 this._updateOpacity();\r
30728                         }\r
30729                 }\r
30730 \r
30731                 if (this.options.interactive) {\r
30732                         addClass(this._image, 'leaflet-interactive');\r
30733                         this.addInteractiveTarget(this._image);\r
30734                 }\r
30735 \r
30736                 this.getPane().appendChild(this._image);\r
30737                 this._reset();\r
30738         },\r
30739 \r
30740         onRemove: function () {\r
30741                 remove(this._image);\r
30742                 if (this.options.interactive) {\r
30743                         this.removeInteractiveTarget(this._image);\r
30744                 }\r
30745         },\r
30746 \r
30747         // @method setOpacity(opacity: Number): this\r
30748         // Sets the opacity of the overlay.\r
30749         setOpacity: function (opacity) {\r
30750                 this.options.opacity = opacity;\r
30751 \r
30752                 if (this._image) {\r
30753                         this._updateOpacity();\r
30754                 }\r
30755                 return this;\r
30756         },\r
30757 \r
30758         setStyle: function (styleOpts) {\r
30759                 if (styleOpts.opacity) {\r
30760                         this.setOpacity(styleOpts.opacity);\r
30761                 }\r
30762                 return this;\r
30763         },\r
30764 \r
30765         // @method bringToFront(): this\r
30766         // Brings the layer to the top of all overlays.\r
30767         bringToFront: function () {\r
30768                 if (this._map) {\r
30769                         toFront(this._image);\r
30770                 }\r
30771                 return this;\r
30772         },\r
30773 \r
30774         // @method bringToBack(): this\r
30775         // Brings the layer to the bottom of all overlays.\r
30776         bringToBack: function () {\r
30777                 if (this._map) {\r
30778                         toBack(this._image);\r
30779                 }\r
30780                 return this;\r
30781         },\r
30782 \r
30783         // @method setUrl(url: String): this\r
30784         // Changes the URL of the image.\r
30785         setUrl: function (url) {\r
30786                 this._url = url;\r
30787 \r
30788                 if (this._image) {\r
30789                         this._image.src = url;\r
30790                 }\r
30791                 return this;\r
30792         },\r
30793 \r
30794         // @method setBounds(bounds: LatLngBounds): this\r
30795         // Update the bounds that this ImageOverlay covers\r
30796         setBounds: function (bounds) {\r
30797                 this._bounds = toLatLngBounds(bounds);\r
30798 \r
30799                 if (this._map) {\r
30800                         this._reset();\r
30801                 }\r
30802                 return this;\r
30803         },\r
30804 \r
30805         getEvents: function () {\r
30806                 var events = {\r
30807                         zoom: this._reset,\r
30808                         viewreset: this._reset\r
30809                 };\r
30810 \r
30811                 if (this._zoomAnimated) {\r
30812                         events.zoomanim = this._animateZoom;\r
30813                 }\r
30814 \r
30815                 return events;\r
30816         },\r
30817 \r
30818         // @method setZIndex(value: Number): this\r
30819         // Changes the [zIndex](#imageoverlay-zindex) of the image overlay.\r
30820         setZIndex: function (value) {\r
30821                 this.options.zIndex = value;\r
30822                 this._updateZIndex();\r
30823                 return this;\r
30824         },\r
30825 \r
30826         // @method getBounds(): LatLngBounds\r
30827         // Get the bounds that this ImageOverlay covers\r
30828         getBounds: function () {\r
30829                 return this._bounds;\r
30830         },\r
30831 \r
30832         // @method getElement(): HTMLElement\r
30833         // Returns the instance of [`HTMLImageElement`](https://developer.mozilla.org/docs/Web/API/HTMLImageElement)\r
30834         // used by this overlay.\r
30835         getElement: function () {\r
30836                 return this._image;\r
30837         },\r
30838 \r
30839         _initImage: function () {\r
30840                 var wasElementSupplied = this._url.tagName === 'IMG';\r
30841                 var img = this._image = wasElementSupplied ? this._url : create$1('img');\r
30842 \r
30843                 addClass(img, 'leaflet-image-layer');\r
30844                 if (this._zoomAnimated) { addClass(img, 'leaflet-zoom-animated'); }\r
30845                 if (this.options.className) { addClass(img, this.options.className); }\r
30846 \r
30847                 img.onselectstart = falseFn;\r
30848                 img.onmousemove = falseFn;\r
30849 \r
30850                 // @event load: Event\r
30851                 // Fired when the ImageOverlay layer has loaded its image\r
30852                 img.onload = bind(this.fire, this, 'load');\r
30853                 img.onerror = bind(this._overlayOnError, this, 'error');\r
30854 \r
30855                 if (this.options.crossOrigin || this.options.crossOrigin === '') {\r
30856                         img.crossOrigin = this.options.crossOrigin === true ? '' : this.options.crossOrigin;\r
30857                 }\r
30858 \r
30859                 if (this.options.zIndex) {\r
30860                         this._updateZIndex();\r
30861                 }\r
30862 \r
30863                 if (wasElementSupplied) {\r
30864                         this._url = img.src;\r
30865                         return;\r
30866                 }\r
30867 \r
30868                 img.src = this._url;\r
30869                 img.alt = this.options.alt;\r
30870         },\r
30871 \r
30872         _animateZoom: function (e) {\r
30873                 var scale = this._map.getZoomScale(e.zoom),\r
30874                     offset = this._map._latLngBoundsToNewLayerBounds(this._bounds, e.zoom, e.center).min;\r
30875 \r
30876                 setTransform(this._image, offset, scale);\r
30877         },\r
30878 \r
30879         _reset: function () {\r
30880                 var image = this._image,\r
30881                     bounds = new Bounds(\r
30882                         this._map.latLngToLayerPoint(this._bounds.getNorthWest()),\r
30883                         this._map.latLngToLayerPoint(this._bounds.getSouthEast())),\r
30884                     size = bounds.getSize();\r
30885 \r
30886                 setPosition(image, bounds.min);\r
30887 \r
30888                 image.style.width  = size.x + 'px';\r
30889                 image.style.height = size.y + 'px';\r
30890         },\r
30891 \r
30892         _updateOpacity: function () {\r
30893                 setOpacity(this._image, this.options.opacity);\r
30894         },\r
30895 \r
30896         _updateZIndex: function () {\r
30897                 if (this._image && this.options.zIndex !== undefined && this.options.zIndex !== null) {\r
30898                         this._image.style.zIndex = this.options.zIndex;\r
30899                 }\r
30900         },\r
30901 \r
30902         _overlayOnError: function () {\r
30903                 // @event error: Event\r
30904                 // Fired when the ImageOverlay layer fails to load its image\r
30905                 this.fire('error');\r
30906 \r
30907                 var errorUrl = this.options.errorOverlayUrl;\r
30908                 if (errorUrl && this._url !== errorUrl) {\r
30909                         this._url = errorUrl;\r
30910                         this._image.src = errorUrl;\r
30911                 }\r
30912         }\r
30913       });\r
30914 \r
30915       // @factory L.imageOverlay(imageUrl: String, bounds: LatLngBounds, options?: ImageOverlay options)\r
30916       // Instantiates an image overlay object given the URL of the image and the\r
30917       // geographical bounds it is tied to.\r
30918       var imageOverlay = function (url, bounds, options) {\r
30919         return new ImageOverlay(url, bounds, options);\r
30920       };
30921
30922       /*\r
30923        * @class VideoOverlay\r
30924        * @aka L.VideoOverlay\r
30925        * @inherits ImageOverlay\r
30926        *\r
30927        * Used to load and display a video player over specific bounds of the map. Extends `ImageOverlay`.\r
30928        *\r
30929        * A video overlay uses the [`<video>`](https://developer.mozilla.org/docs/Web/HTML/Element/video)\r
30930        * HTML5 element.\r
30931        *\r
30932        * @example\r
30933        *\r
30934        * ```js\r
30935        * var videoUrl = 'https://www.mapbox.com/bites/00188/patricia_nasa.webm',\r
30936        *        videoBounds = [[ 32, -130], [ 13, -100]];\r
30937        * L.videoOverlay(videoUrl, videoBounds ).addTo(map);\r
30938        * ```\r
30939        */\r
30940 \r
30941       var VideoOverlay = ImageOverlay.extend({\r
30942 \r
30943         // @section\r
30944         // @aka VideoOverlay options\r
30945         options: {\r
30946                 // @option autoplay: Boolean = true\r
30947                 // Whether the video starts playing automatically when loaded.\r
30948                 autoplay: true,\r
30949 \r
30950                 // @option loop: Boolean = true\r
30951                 // Whether the video will loop back to the beginning when played.\r
30952                 loop: true,\r
30953 \r
30954                 // @option keepAspectRatio: Boolean = true\r
30955                 // Whether the video will save aspect ratio after the projection.\r
30956                 // Relevant for supported browsers. Browser compatibility- https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit\r
30957                 keepAspectRatio: true,\r
30958 \r
30959                 // @option muted: Boolean = false\r
30960                 // Whether the video starts on mute when loaded.\r
30961                 muted: false\r
30962         },\r
30963 \r
30964         _initImage: function () {\r
30965                 var wasElementSupplied = this._url.tagName === 'VIDEO';\r
30966                 var vid = this._image = wasElementSupplied ? this._url : create$1('video');\r
30967 \r
30968                 addClass(vid, 'leaflet-image-layer');\r
30969                 if (this._zoomAnimated) { addClass(vid, 'leaflet-zoom-animated'); }\r
30970                 if (this.options.className) { addClass(vid, this.options.className); }\r
30971 \r
30972                 vid.onselectstart = falseFn;\r
30973                 vid.onmousemove = falseFn;\r
30974 \r
30975                 // @event load: Event\r
30976                 // Fired when the video has finished loading the first frame\r
30977                 vid.onloadeddata = bind(this.fire, this, 'load');\r
30978 \r
30979                 if (wasElementSupplied) {\r
30980                         var sourceElements = vid.getElementsByTagName('source');\r
30981                         var sources = [];\r
30982                         for (var j = 0; j < sourceElements.length; j++) {\r
30983                                 sources.push(sourceElements[j].src);\r
30984                         }\r
30985 \r
30986                         this._url = (sourceElements.length > 0) ? sources : [vid.src];\r
30987                         return;\r
30988                 }\r
30989 \r
30990                 if (!isArray(this._url)) { this._url = [this._url]; }\r
30991 \r
30992                 if (!this.options.keepAspectRatio && Object.prototype.hasOwnProperty.call(vid.style, 'objectFit')) {\r
30993                         vid.style['objectFit'] = 'fill';\r
30994                 }\r
30995                 vid.autoplay = !!this.options.autoplay;\r
30996                 vid.loop = !!this.options.loop;\r
30997                 vid.muted = !!this.options.muted;\r
30998                 for (var i = 0; i < this._url.length; i++) {\r
30999                         var source = create$1('source');\r
31000                         source.src = this._url[i];\r
31001                         vid.appendChild(source);\r
31002                 }\r
31003         }\r
31004 \r
31005         // @method getElement(): HTMLVideoElement\r
31006         // Returns the instance of [`HTMLVideoElement`](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement)\r
31007         // used by this overlay.\r
31008       });\r
31009 \r
31010 \r
31011       // @factory L.videoOverlay(video: String|Array|HTMLVideoElement, bounds: LatLngBounds, options?: VideoOverlay options)\r
31012       // Instantiates an image overlay object given the URL of the video (or array of URLs, or even a video element) and the\r
31013       // geographical bounds it is tied to.\r
31014 \r
31015       function videoOverlay(video, bounds, options) {\r
31016         return new VideoOverlay(video, bounds, options);\r
31017       }
31018
31019       /*
31020        * @class SVGOverlay
31021        * @aka L.SVGOverlay
31022        * @inherits ImageOverlay
31023        *
31024        * Used to load, display and provide DOM access to an SVG file over specific bounds of the map. Extends `ImageOverlay`.
31025        *
31026        * An SVG overlay uses the [`<svg>`](https://developer.mozilla.org/docs/Web/SVG/Element/svg) element.
31027        *
31028        * @example
31029        *
31030        * ```js
31031        * var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
31032        * svgElement.setAttribute('xmlns', "http://www.w3.org/2000/svg");
31033        * svgElement.setAttribute('viewBox', "0 0 200 200");
31034        * svgElement.innerHTML = '<rect width="200" height="200"/><rect x="75" y="23" width="50" height="50" style="fill:red"/><rect x="75" y="123" width="50" height="50" style="fill:#0013ff"/>';
31035        * var svgElementBounds = [ [ 32, -130 ], [ 13, -100 ] ];
31036        * L.svgOverlay(svgElement, svgElementBounds).addTo(map);
31037        * ```
31038        */
31039
31040       var SVGOverlay = ImageOverlay.extend({
31041         _initImage: function () {
31042                 var el = this._image = this._url;
31043
31044                 addClass(el, 'leaflet-image-layer');
31045                 if (this._zoomAnimated) { addClass(el, 'leaflet-zoom-animated'); }
31046                 if (this.options.className) { addClass(el, this.options.className); }
31047
31048                 el.onselectstart = falseFn;
31049                 el.onmousemove = falseFn;
31050         }
31051
31052         // @method getElement(): SVGElement
31053         // Returns the instance of [`SVGElement`](https://developer.mozilla.org/docs/Web/API/SVGElement)
31054         // used by this overlay.
31055       });
31056
31057
31058       // @factory L.svgOverlay(svg: String|SVGElement, bounds: LatLngBounds, options?: SVGOverlay options)
31059       // Instantiates an image overlay object given an SVG element and the geographical bounds it is tied to.
31060       // A viewBox attribute is required on the SVG element to zoom in and out properly.
31061
31062       function svgOverlay(el, bounds, options) {
31063         return new SVGOverlay(el, bounds, options);
31064       }
31065
31066       /*\r
31067        * @class DivOverlay\r
31068        * @inherits Layer\r
31069        * @aka L.DivOverlay\r
31070        * Base model for L.Popup and L.Tooltip. Inherit from it for custom popup like plugins.\r
31071        */\r
31072 \r
31073       // @namespace DivOverlay\r
31074       var DivOverlay = Layer.extend({\r
31075 \r
31076         // @section\r
31077         // @aka DivOverlay options\r
31078         options: {\r
31079                 // @option offset: Point = Point(0, 7)\r
31080                 // The offset of the popup position. Useful to control the anchor\r
31081                 // of the popup when opening it on some overlays.\r
31082                 offset: [0, 7],\r
31083 \r
31084                 // @option className: String = ''\r
31085                 // A custom CSS class name to assign to the popup.\r
31086                 className: '',\r
31087 \r
31088                 // @option pane: String = 'popupPane'\r
31089                 // `Map pane` where the popup will be added.\r
31090                 pane: 'popupPane'\r
31091         },\r
31092 \r
31093         initialize: function (options, source) {\r
31094                 setOptions(this, options);\r
31095 \r
31096                 this._source = source;\r
31097         },\r
31098 \r
31099         onAdd: function (map) {\r
31100                 this._zoomAnimated = map._zoomAnimated;\r
31101 \r
31102                 if (!this._container) {\r
31103                         this._initLayout();\r
31104                 }\r
31105 \r
31106                 if (map._fadeAnimated) {\r
31107                         setOpacity(this._container, 0);\r
31108                 }\r
31109 \r
31110                 clearTimeout(this._removeTimeout);\r
31111                 this.getPane().appendChild(this._container);\r
31112                 this.update();\r
31113 \r
31114                 if (map._fadeAnimated) {\r
31115                         setOpacity(this._container, 1);\r
31116                 }\r
31117 \r
31118                 this.bringToFront();\r
31119         },\r
31120 \r
31121         onRemove: function (map) {\r
31122                 if (map._fadeAnimated) {\r
31123                         setOpacity(this._container, 0);\r
31124                         this._removeTimeout = setTimeout(bind(remove, undefined, this._container), 200);\r
31125                 } else {\r
31126                         remove(this._container);\r
31127                 }\r
31128         },\r
31129 \r
31130         // @namespace Popup\r
31131         // @method getLatLng: LatLng\r
31132         // Returns the geographical point of popup.\r
31133         getLatLng: function () {\r
31134                 return this._latlng;\r
31135         },\r
31136 \r
31137         // @method setLatLng(latlng: LatLng): this\r
31138         // Sets the geographical point where the popup will open.\r
31139         setLatLng: function (latlng) {\r
31140                 this._latlng = toLatLng(latlng);\r
31141                 if (this._map) {\r
31142                         this._updatePosition();\r
31143                         this._adjustPan();\r
31144                 }\r
31145                 return this;\r
31146         },\r
31147 \r
31148         // @method getContent: String|HTMLElement\r
31149         // Returns the content of the popup.\r
31150         getContent: function () {\r
31151                 return this._content;\r
31152         },\r
31153 \r
31154         // @method setContent(htmlContent: String|HTMLElement|Function): this\r
31155         // Sets the HTML content of the popup. If a function is passed the source layer will be passed to the function. The function should return a `String` or `HTMLElement` to be used in the popup.\r
31156         setContent: function (content) {\r
31157                 this._content = content;\r
31158                 this.update();\r
31159                 return this;\r
31160         },\r
31161 \r
31162         // @method getElement: String|HTMLElement\r
31163         // Returns the HTML container of the popup.\r
31164         getElement: function () {\r
31165                 return this._container;\r
31166         },\r
31167 \r
31168         // @method update: null\r
31169         // Updates the popup content, layout and position. Useful for updating the popup after something inside changed, e.g. image loaded.\r
31170         update: function () {\r
31171                 if (!this._map) { return; }\r
31172 \r
31173                 this._container.style.visibility = 'hidden';\r
31174 \r
31175                 this._updateContent();\r
31176                 this._updateLayout();\r
31177                 this._updatePosition();\r
31178 \r
31179                 this._container.style.visibility = '';\r
31180 \r
31181                 this._adjustPan();\r
31182         },\r
31183 \r
31184         getEvents: function () {\r
31185                 var events = {\r
31186                         zoom: this._updatePosition,\r
31187                         viewreset: this._updatePosition\r
31188                 };\r
31189 \r
31190                 if (this._zoomAnimated) {\r
31191                         events.zoomanim = this._animateZoom;\r
31192                 }\r
31193                 return events;\r
31194         },\r
31195 \r
31196         // @method isOpen: Boolean\r
31197         // Returns `true` when the popup is visible on the map.\r
31198         isOpen: function () {\r
31199                 return !!this._map && this._map.hasLayer(this);\r
31200         },\r
31201 \r
31202         // @method bringToFront: this\r
31203         // Brings this popup in front of other popups (in the same map pane).\r
31204         bringToFront: function () {\r
31205                 if (this._map) {\r
31206                         toFront(this._container);\r
31207                 }\r
31208                 return this;\r
31209         },\r
31210 \r
31211         // @method bringToBack: this\r
31212         // Brings this popup to the back of other popups (in the same map pane).\r
31213         bringToBack: function () {\r
31214                 if (this._map) {\r
31215                         toBack(this._container);\r
31216                 }\r
31217                 return this;\r
31218         },\r
31219 \r
31220         _prepareOpen: function (parent, layer, latlng) {\r
31221                 if (!(layer instanceof Layer)) {\r
31222                         latlng = layer;\r
31223                         layer = parent;\r
31224                 }\r
31225 \r
31226                 if (layer instanceof FeatureGroup) {\r
31227                         for (var id in parent._layers) {\r
31228                                 layer = parent._layers[id];\r
31229                                 break;\r
31230                         }\r
31231                 }\r
31232 \r
31233                 if (!latlng) {\r
31234                         if (layer.getCenter) {\r
31235                                 latlng = layer.getCenter();\r
31236                         } else if (layer.getLatLng) {\r
31237                                 latlng = layer.getLatLng();\r
31238                         } else {\r
31239                                 throw new Error('Unable to get source layer LatLng.');\r
31240                         }\r
31241                 }\r
31242 \r
31243                 // set overlay source to this layer\r
31244                 this._source = layer;\r
31245 \r
31246                 // update the overlay (content, layout, ect...)\r
31247                 this.update();\r
31248 \r
31249                 return latlng;\r
31250         },\r
31251 \r
31252         _updateContent: function () {\r
31253                 if (!this._content) { return; }\r
31254 \r
31255                 var node = this._contentNode;\r
31256                 var content = (typeof this._content === 'function') ? this._content(this._source || this) : this._content;\r
31257 \r
31258                 if (typeof content === 'string') {\r
31259                         node.innerHTML = content;\r
31260                 } else {\r
31261                         while (node.hasChildNodes()) {\r
31262                                 node.removeChild(node.firstChild);\r
31263                         }\r
31264                         node.appendChild(content);\r
31265                 }\r
31266                 this.fire('contentupdate');\r
31267         },\r
31268 \r
31269         _updatePosition: function () {\r
31270                 if (!this._map) { return; }\r
31271 \r
31272                 var pos = this._map.latLngToLayerPoint(this._latlng),\r
31273                     offset = toPoint(this.options.offset),\r
31274                     anchor = this._getAnchor();\r
31275 \r
31276                 if (this._zoomAnimated) {\r
31277                         setPosition(this._container, pos.add(anchor));\r
31278                 } else {\r
31279                         offset = offset.add(pos).add(anchor);\r
31280                 }\r
31281 \r
31282                 var bottom = this._containerBottom = -offset.y,\r
31283                     left = this._containerLeft = -Math.round(this._containerWidth / 2) + offset.x;\r
31284 \r
31285                 // bottom position the popup in case the height of the popup changes (images loading etc)\r
31286                 this._container.style.bottom = bottom + 'px';\r
31287                 this._container.style.left = left + 'px';\r
31288         },\r
31289 \r
31290         _getAnchor: function () {\r
31291                 return [0, 0];\r
31292         }\r
31293 \r
31294       });
31295
31296       /*\r
31297        * @class Popup\r
31298        * @inherits DivOverlay\r
31299        * @aka L.Popup\r
31300        * Used to open popups in certain places of the map. Use [Map.openPopup](#map-openpopup) to\r
31301        * open popups while making sure that only one popup is open at one time\r
31302        * (recommended for usability), or use [Map.addLayer](#map-addlayer) to open as many as you want.\r
31303        *\r
31304        * @example\r
31305        *\r
31306        * If you want to just bind a popup to marker click and then open it, it's really easy:\r
31307        *\r
31308        * ```js\r
31309        * marker.bindPopup(popupContent).openPopup();\r
31310        * ```\r
31311        * Path overlays like polylines also have a `bindPopup` method.\r
31312        * Here's a more complicated way to open a popup on a map:\r
31313        *\r
31314        * ```js\r
31315        * var popup = L.popup()\r
31316        *        .setLatLng(latlng)\r
31317        *        .setContent('<p>Hello world!<br />This is a nice popup.</p>')\r
31318        *        .openOn(map);\r
31319        * ```\r
31320        */\r
31321 \r
31322 \r
31323       // @namespace Popup\r
31324       var Popup = DivOverlay.extend({\r
31325 \r
31326         // @section\r
31327         // @aka Popup options\r
31328         options: {\r
31329                 // @option maxWidth: Number = 300\r
31330                 // Max width of the popup, in pixels.\r
31331                 maxWidth: 300,\r
31332 \r
31333                 // @option minWidth: Number = 50\r
31334                 // Min width of the popup, in pixels.\r
31335                 minWidth: 50,\r
31336 \r
31337                 // @option maxHeight: Number = null\r
31338                 // If set, creates a scrollable container of the given height\r
31339                 // inside a popup if its content exceeds it.\r
31340                 maxHeight: null,\r
31341 \r
31342                 // @option autoPan: Boolean = true\r
31343                 // Set it to `false` if you don't want the map to do panning animation\r
31344                 // to fit the opened popup.\r
31345                 autoPan: true,\r
31346 \r
31347                 // @option autoPanPaddingTopLeft: Point = null\r
31348                 // The margin between the popup and the top left corner of the map\r
31349                 // view after autopanning was performed.\r
31350                 autoPanPaddingTopLeft: null,\r
31351 \r
31352                 // @option autoPanPaddingBottomRight: Point = null\r
31353                 // The margin between the popup and the bottom right corner of the map\r
31354                 // view after autopanning was performed.\r
31355                 autoPanPaddingBottomRight: null,\r
31356 \r
31357                 // @option autoPanPadding: Point = Point(5, 5)\r
31358                 // Equivalent of setting both top left and bottom right autopan padding to the same value.\r
31359                 autoPanPadding: [5, 5],\r
31360 \r
31361                 // @option keepInView: Boolean = false\r
31362                 // Set it to `true` if you want to prevent users from panning the popup\r
31363                 // off of the screen while it is open.\r
31364                 keepInView: false,\r
31365 \r
31366                 // @option closeButton: Boolean = true\r
31367                 // Controls the presence of a close button in the popup.\r
31368                 closeButton: true,\r
31369 \r
31370                 // @option autoClose: Boolean = true\r
31371                 // Set it to `false` if you want to override the default behavior of\r
31372                 // the popup closing when another popup is opened.\r
31373                 autoClose: true,\r
31374 \r
31375                 // @option closeOnEscapeKey: Boolean = true\r
31376                 // Set it to `false` if you want to override the default behavior of\r
31377                 // the ESC key for closing of the popup.\r
31378                 closeOnEscapeKey: true,\r
31379 \r
31380                 // @option closeOnClick: Boolean = *\r
31381                 // Set it if you want to override the default behavior of the popup closing when user clicks\r
31382                 // on the map. Defaults to the map's [`closePopupOnClick`](#map-closepopuponclick) option.\r
31383 \r
31384                 // @option className: String = ''\r
31385                 // A custom CSS class name to assign to the popup.\r
31386                 className: ''\r
31387         },\r
31388 \r
31389         // @namespace Popup\r
31390         // @method openOn(map: Map): this\r
31391         // Adds the popup to the map and closes the previous one. The same as `map.openPopup(popup)`.\r
31392         openOn: function (map) {\r
31393                 map.openPopup(this);\r
31394                 return this;\r
31395         },\r
31396 \r
31397         onAdd: function (map) {\r
31398                 DivOverlay.prototype.onAdd.call(this, map);\r
31399 \r
31400                 // @namespace Map\r
31401                 // @section Popup events\r
31402                 // @event popupopen: PopupEvent\r
31403                 // Fired when a popup is opened in the map\r
31404                 map.fire('popupopen', {popup: this});\r
31405 \r
31406                 if (this._source) {\r
31407                         // @namespace Layer\r
31408                         // @section Popup events\r
31409                         // @event popupopen: PopupEvent\r
31410                         // Fired when a popup bound to this layer is opened\r
31411                         this._source.fire('popupopen', {popup: this}, true);\r
31412                         // For non-path layers, we toggle the popup when clicking\r
31413                         // again the layer, so prevent the map to reopen it.\r
31414                         if (!(this._source instanceof Path)) {\r
31415                                 this._source.on('preclick', stopPropagation);\r
31416                         }\r
31417                 }\r
31418         },\r
31419 \r
31420         onRemove: function (map) {\r
31421                 DivOverlay.prototype.onRemove.call(this, map);\r
31422 \r
31423                 // @namespace Map\r
31424                 // @section Popup events\r
31425                 // @event popupclose: PopupEvent\r
31426                 // Fired when a popup in the map is closed\r
31427                 map.fire('popupclose', {popup: this});\r
31428 \r
31429                 if (this._source) {\r
31430                         // @namespace Layer\r
31431                         // @section Popup events\r
31432                         // @event popupclose: PopupEvent\r
31433                         // Fired when a popup bound to this layer is closed\r
31434                         this._source.fire('popupclose', {popup: this}, true);\r
31435                         if (!(this._source instanceof Path)) {\r
31436                                 this._source.off('preclick', stopPropagation);\r
31437                         }\r
31438                 }\r
31439         },\r
31440 \r
31441         getEvents: function () {\r
31442                 var events = DivOverlay.prototype.getEvents.call(this);\r
31443 \r
31444                 if (this.options.closeOnClick !== undefined ? this.options.closeOnClick : this._map.options.closePopupOnClick) {\r
31445                         events.preclick = this._close;\r
31446                 }\r
31447 \r
31448                 if (this.options.keepInView) {\r
31449                         events.moveend = this._adjustPan;\r
31450                 }\r
31451 \r
31452                 return events;\r
31453         },\r
31454 \r
31455         _close: function () {\r
31456                 if (this._map) {\r
31457                         this._map.closePopup(this);\r
31458                 }\r
31459         },\r
31460 \r
31461         _initLayout: function () {\r
31462                 var prefix = 'leaflet-popup',\r
31463                     container = this._container = create$1('div',\r
31464                         prefix + ' ' + (this.options.className || '') +\r
31465                         ' leaflet-zoom-animated');\r
31466 \r
31467                 var wrapper = this._wrapper = create$1('div', prefix + '-content-wrapper', container);\r
31468                 this._contentNode = create$1('div', prefix + '-content', wrapper);\r
31469 \r
31470                 disableClickPropagation(container);\r
31471                 disableScrollPropagation(this._contentNode);\r
31472                 on(container, 'contextmenu', stopPropagation);\r
31473 \r
31474                 this._tipContainer = create$1('div', prefix + '-tip-container', container);\r
31475                 this._tip = create$1('div', prefix + '-tip', this._tipContainer);\r
31476 \r
31477                 if (this.options.closeButton) {\r
31478                         var closeButton = this._closeButton = create$1('a', prefix + '-close-button', container);\r
31479                         closeButton.href = '#close';\r
31480                         closeButton.innerHTML = '&#215;';\r
31481 \r
31482                         on(closeButton, 'click', this._onCloseButtonClick, this);\r
31483                 }\r
31484         },\r
31485 \r
31486         _updateLayout: function () {\r
31487                 var container = this._contentNode,\r
31488                     style = container.style;\r
31489 \r
31490                 style.width = '';\r
31491                 style.whiteSpace = 'nowrap';\r
31492 \r
31493                 var width = container.offsetWidth;\r
31494                 width = Math.min(width, this.options.maxWidth);\r
31495                 width = Math.max(width, this.options.minWidth);\r
31496 \r
31497                 style.width = (width + 1) + 'px';\r
31498                 style.whiteSpace = '';\r
31499 \r
31500                 style.height = '';\r
31501 \r
31502                 var height = container.offsetHeight,\r
31503                     maxHeight = this.options.maxHeight,\r
31504                     scrolledClass = 'leaflet-popup-scrolled';\r
31505 \r
31506                 if (maxHeight && height > maxHeight) {\r
31507                         style.height = maxHeight + 'px';\r
31508                         addClass(container, scrolledClass);\r
31509                 } else {\r
31510                         removeClass(container, scrolledClass);\r
31511                 }\r
31512 \r
31513                 this._containerWidth = this._container.offsetWidth;\r
31514         },\r
31515 \r
31516         _animateZoom: function (e) {\r
31517                 var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center),\r
31518                     anchor = this._getAnchor();\r
31519                 setPosition(this._container, pos.add(anchor));\r
31520         },\r
31521 \r
31522         _adjustPan: function () {\r
31523                 if (!this.options.autoPan) { return; }\r
31524                 if (this._map._panAnim) { this._map._panAnim.stop(); }\r
31525 \r
31526                 var map = this._map,\r
31527                     marginBottom = parseInt(getStyle(this._container, 'marginBottom'), 10) || 0,\r
31528                     containerHeight = this._container.offsetHeight + marginBottom,\r
31529                     containerWidth = this._containerWidth,\r
31530                     layerPos = new Point(this._containerLeft, -containerHeight - this._containerBottom);\r
31531 \r
31532                 layerPos._add(getPosition(this._container));\r
31533 \r
31534                 var containerPos = map.layerPointToContainerPoint(layerPos),\r
31535                     padding = toPoint(this.options.autoPanPadding),\r
31536                     paddingTL = toPoint(this.options.autoPanPaddingTopLeft || padding),\r
31537                     paddingBR = toPoint(this.options.autoPanPaddingBottomRight || padding),\r
31538                     size = map.getSize(),\r
31539                     dx = 0,\r
31540                     dy = 0;\r
31541 \r
31542                 if (containerPos.x + containerWidth + paddingBR.x > size.x) { // right\r
31543                         dx = containerPos.x + containerWidth - size.x + paddingBR.x;\r
31544                 }\r
31545                 if (containerPos.x - dx - paddingTL.x < 0) { // left\r
31546                         dx = containerPos.x - paddingTL.x;\r
31547                 }\r
31548                 if (containerPos.y + containerHeight + paddingBR.y > size.y) { // bottom\r
31549                         dy = containerPos.y + containerHeight - size.y + paddingBR.y;\r
31550                 }\r
31551                 if (containerPos.y - dy - paddingTL.y < 0) { // top\r
31552                         dy = containerPos.y - paddingTL.y;\r
31553                 }\r
31554 \r
31555                 // @namespace Map\r
31556                 // @section Popup events\r
31557                 // @event autopanstart: Event\r
31558                 // Fired when the map starts autopanning when opening a popup.\r
31559                 if (dx || dy) {\r
31560                         map\r
31561                             .fire('autopanstart')\r
31562                             .panBy([dx, dy]);\r
31563                 }\r
31564         },\r
31565 \r
31566         _onCloseButtonClick: function (e) {\r
31567                 this._close();\r
31568                 stop(e);\r
31569         },\r
31570 \r
31571         _getAnchor: function () {\r
31572                 // Where should we anchor the popup on the source layer?\r
31573                 return toPoint(this._source && this._source._getPopupAnchor ? this._source._getPopupAnchor() : [0, 0]);\r
31574         }\r
31575 \r
31576       });\r
31577 \r
31578       // @namespace Popup\r
31579       // @factory L.popup(options?: Popup options, source?: Layer)\r
31580       // Instantiates a `Popup` object given an optional `options` object that describes its appearance and location and an optional `source` object that is used to tag the popup with a reference to the Layer to which it refers.\r
31581       var popup = function (options, source) {\r
31582         return new Popup(options, source);\r
31583       };\r
31584 \r
31585 \r
31586       /* @namespace Map\r
31587        * @section Interaction Options\r
31588        * @option closePopupOnClick: Boolean = true\r
31589        * Set it to `false` if you don't want popups to close when user clicks the map.\r
31590        */\r
31591       Map.mergeOptions({\r
31592         closePopupOnClick: true\r
31593       });\r
31594 \r
31595 \r
31596       // @namespace Map\r
31597       // @section Methods for Layers and Controls\r
31598       Map.include({\r
31599         // @method openPopup(popup: Popup): this\r
31600         // Opens the specified popup while closing the previously opened (to make sure only one is opened at one time for usability).\r
31601         // @alternative\r
31602         // @method openPopup(content: String|HTMLElement, latlng: LatLng, options?: Popup options): this\r
31603         // Creates a popup with the specified content and options and opens it in the given point on a map.\r
31604         openPopup: function (popup, latlng, options) {\r
31605                 if (!(popup instanceof Popup)) {\r
31606                         popup = new Popup(options).setContent(popup);\r
31607                 }\r
31608 \r
31609                 if (latlng) {\r
31610                         popup.setLatLng(latlng);\r
31611                 }\r
31612 \r
31613                 if (this.hasLayer(popup)) {\r
31614                         return this;\r
31615                 }\r
31616 \r
31617                 if (this._popup && this._popup.options.autoClose) {\r
31618                         this.closePopup();\r
31619                 }\r
31620 \r
31621                 this._popup = popup;\r
31622                 return this.addLayer(popup);\r
31623         },\r
31624 \r
31625         // @method closePopup(popup?: Popup): this\r
31626         // Closes the popup previously opened with [openPopup](#map-openpopup) (or the given one).\r
31627         closePopup: function (popup) {\r
31628                 if (!popup || popup === this._popup) {\r
31629                         popup = this._popup;\r
31630                         this._popup = null;\r
31631                 }\r
31632                 if (popup) {\r
31633                         this.removeLayer(popup);\r
31634                 }\r
31635                 return this;\r
31636         }\r
31637       });\r
31638 \r
31639       /*\r
31640        * @namespace Layer\r
31641        * @section Popup methods example\r
31642        *\r
31643        * All layers share a set of methods convenient for binding popups to it.\r
31644        *\r
31645        * ```js\r
31646        * var layer = L.Polygon(latlngs).bindPopup('Hi There!').addTo(map);\r
31647        * layer.openPopup();\r
31648        * layer.closePopup();\r
31649        * ```\r
31650        *\r
31651        * Popups will also be automatically opened when the layer is clicked on and closed when the layer is removed from the map or another popup is opened.\r
31652        */\r
31653 \r
31654       // @section Popup methods\r
31655       Layer.include({\r
31656 \r
31657         // @method bindPopup(content: String|HTMLElement|Function|Popup, options?: Popup options): this\r
31658         // Binds a popup to the layer with the passed `content` and sets up the\r
31659         // necessary event listeners. If a `Function` is passed it will receive\r
31660         // the layer as the first argument and should return a `String` or `HTMLElement`.\r
31661         bindPopup: function (content, options) {\r
31662 \r
31663                 if (content instanceof Popup) {\r
31664                         setOptions(content, options);\r
31665                         this._popup = content;\r
31666                         content._source = this;\r
31667                 } else {\r
31668                         if (!this._popup || options) {\r
31669                                 this._popup = new Popup(options, this);\r
31670                         }\r
31671                         this._popup.setContent(content);\r
31672                 }\r
31673 \r
31674                 if (!this._popupHandlersAdded) {\r
31675                         this.on({\r
31676                                 click: this._openPopup,\r
31677                                 keypress: this._onKeyPress,\r
31678                                 remove: this.closePopup,\r
31679                                 move: this._movePopup\r
31680                         });\r
31681                         this._popupHandlersAdded = true;\r
31682                 }\r
31683 \r
31684                 return this;\r
31685         },\r
31686 \r
31687         // @method unbindPopup(): this\r
31688         // Removes the popup previously bound with `bindPopup`.\r
31689         unbindPopup: function () {\r
31690                 if (this._popup) {\r
31691                         this.off({\r
31692                                 click: this._openPopup,\r
31693                                 keypress: this._onKeyPress,\r
31694                                 remove: this.closePopup,\r
31695                                 move: this._movePopup\r
31696                         });\r
31697                         this._popupHandlersAdded = false;\r
31698                         this._popup = null;\r
31699                 }\r
31700                 return this;\r
31701         },\r
31702 \r
31703         // @method openPopup(latlng?: LatLng): this\r
31704         // Opens the bound popup at the specified `latlng` or at the default popup anchor if no `latlng` is passed.\r
31705         openPopup: function (layer, latlng) {\r
31706                 if (this._popup && this._map) {\r
31707                         latlng = this._popup._prepareOpen(this, layer, latlng);\r
31708 \r
31709                         // open the popup on the map\r
31710                         this._map.openPopup(this._popup, latlng);\r
31711                 }\r
31712 \r
31713                 return this;\r
31714         },\r
31715 \r
31716         // @method closePopup(): this\r
31717         // Closes the popup bound to this layer if it is open.\r
31718         closePopup: function () {\r
31719                 if (this._popup) {\r
31720                         this._popup._close();\r
31721                 }\r
31722                 return this;\r
31723         },\r
31724 \r
31725         // @method togglePopup(): this\r
31726         // Opens or closes the popup bound to this layer depending on its current state.\r
31727         togglePopup: function (target) {\r
31728                 if (this._popup) {\r
31729                         if (this._popup._map) {\r
31730                                 this.closePopup();\r
31731                         } else {\r
31732                                 this.openPopup(target);\r
31733                         }\r
31734                 }\r
31735                 return this;\r
31736         },\r
31737 \r
31738         // @method isPopupOpen(): boolean\r
31739         // Returns `true` if the popup bound to this layer is currently open.\r
31740         isPopupOpen: function () {\r
31741                 return (this._popup ? this._popup.isOpen() : false);\r
31742         },\r
31743 \r
31744         // @method setPopupContent(content: String|HTMLElement|Popup): this\r
31745         // Sets the content of the popup bound to this layer.\r
31746         setPopupContent: function (content) {\r
31747                 if (this._popup) {\r
31748                         this._popup.setContent(content);\r
31749                 }\r
31750                 return this;\r
31751         },\r
31752 \r
31753         // @method getPopup(): Popup\r
31754         // Returns the popup bound to this layer.\r
31755         getPopup: function () {\r
31756                 return this._popup;\r
31757         },\r
31758 \r
31759         _openPopup: function (e) {\r
31760                 var layer = e.layer || e.target;\r
31761 \r
31762                 if (!this._popup) {\r
31763                         return;\r
31764                 }\r
31765 \r
31766                 if (!this._map) {\r
31767                         return;\r
31768                 }\r
31769 \r
31770                 // prevent map click\r
31771                 stop(e);\r
31772 \r
31773                 // if this inherits from Path its a vector and we can just\r
31774                 // open the popup at the new location\r
31775                 if (layer instanceof Path) {\r
31776                         this.openPopup(e.layer || e.target, e.latlng);\r
31777                         return;\r
31778                 }\r
31779 \r
31780                 // otherwise treat it like a marker and figure out\r
31781                 // if we should toggle it open/closed\r
31782                 if (this._map.hasLayer(this._popup) && this._popup._source === layer) {\r
31783                         this.closePopup();\r
31784                 } else {\r
31785                         this.openPopup(layer, e.latlng);\r
31786                 }\r
31787         },\r
31788 \r
31789         _movePopup: function (e) {\r
31790                 this._popup.setLatLng(e.latlng);\r
31791         },\r
31792 \r
31793         _onKeyPress: function (e) {\r
31794                 if (e.originalEvent.keyCode === 13) {\r
31795                         this._openPopup(e);\r
31796                 }\r
31797         }\r
31798       });
31799
31800       /*
31801        * @class Tooltip
31802        * @inherits DivOverlay
31803        * @aka L.Tooltip
31804        * Used to display small texts on top of map layers.
31805        *
31806        * @example
31807        *
31808        * ```js
31809        * marker.bindTooltip("my tooltip text").openTooltip();
31810        * ```
31811        * Note about tooltip offset. Leaflet takes two options in consideration
31812        * for computing tooltip offsetting:
31813        * - the `offset` Tooltip option: it defaults to [0, 0], and it's specific to one tooltip.
31814        *   Add a positive x offset to move the tooltip to the right, and a positive y offset to
31815        *   move it to the bottom. Negatives will move to the left and top.
31816        * - the `tooltipAnchor` Icon option: this will only be considered for Marker. You
31817        *   should adapt this value if you use a custom icon.
31818        */
31819
31820
31821       // @namespace Tooltip
31822       var Tooltip = DivOverlay.extend({
31823
31824         // @section
31825         // @aka Tooltip options
31826         options: {
31827                 // @option pane: String = 'tooltipPane'
31828                 // `Map pane` where the tooltip will be added.
31829                 pane: 'tooltipPane',
31830
31831                 // @option offset: Point = Point(0, 0)
31832                 // Optional offset of the tooltip position.
31833                 offset: [0, 0],
31834
31835                 // @option direction: String = 'auto'
31836                 // Direction where to open the tooltip. Possible values are: `right`, `left`,
31837                 // `top`, `bottom`, `center`, `auto`.
31838                 // `auto` will dynamically switch between `right` and `left` according to the tooltip
31839                 // position on the map.
31840                 direction: 'auto',
31841
31842                 // @option permanent: Boolean = false
31843                 // Whether to open the tooltip permanently or only on mouseover.
31844                 permanent: false,
31845
31846                 // @option sticky: Boolean = false
31847                 // If true, the tooltip will follow the mouse instead of being fixed at the feature center.
31848                 sticky: false,
31849
31850                 // @option interactive: Boolean = false
31851                 // If true, the tooltip will listen to the feature events.
31852                 interactive: false,
31853
31854                 // @option opacity: Number = 0.9
31855                 // Tooltip container opacity.
31856                 opacity: 0.9
31857         },
31858
31859         onAdd: function (map) {
31860                 DivOverlay.prototype.onAdd.call(this, map);
31861                 this.setOpacity(this.options.opacity);
31862
31863                 // @namespace Map
31864                 // @section Tooltip events
31865                 // @event tooltipopen: TooltipEvent
31866                 // Fired when a tooltip is opened in the map.
31867                 map.fire('tooltipopen', {tooltip: this});
31868
31869                 if (this._source) {
31870                         // @namespace Layer
31871                         // @section Tooltip events
31872                         // @event tooltipopen: TooltipEvent
31873                         // Fired when a tooltip bound to this layer is opened.
31874                         this._source.fire('tooltipopen', {tooltip: this}, true);
31875                 }
31876         },
31877
31878         onRemove: function (map) {
31879                 DivOverlay.prototype.onRemove.call(this, map);
31880
31881                 // @namespace Map
31882                 // @section Tooltip events
31883                 // @event tooltipclose: TooltipEvent
31884                 // Fired when a tooltip in the map is closed.
31885                 map.fire('tooltipclose', {tooltip: this});
31886
31887                 if (this._source) {
31888                         // @namespace Layer
31889                         // @section Tooltip events
31890                         // @event tooltipclose: TooltipEvent
31891                         // Fired when a tooltip bound to this layer is closed.
31892                         this._source.fire('tooltipclose', {tooltip: this}, true);
31893                 }
31894         },
31895
31896         getEvents: function () {
31897                 var events = DivOverlay.prototype.getEvents.call(this);
31898
31899                 if (touch && !this.options.permanent) {
31900                         events.preclick = this._close;
31901                 }
31902
31903                 return events;
31904         },
31905
31906         _close: function () {
31907                 if (this._map) {
31908                         this._map.closeTooltip(this);
31909                 }
31910         },
31911
31912         _initLayout: function () {
31913                 var prefix = 'leaflet-tooltip',
31914                     className = prefix + ' ' + (this.options.className || '') + ' leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide');
31915
31916                 this._contentNode = this._container = create$1('div', className);
31917         },
31918
31919         _updateLayout: function () {},
31920
31921         _adjustPan: function () {},
31922
31923         _setPosition: function (pos) {
31924                 var subX, subY,
31925                     map = this._map,
31926                     container = this._container,
31927                     centerPoint = map.latLngToContainerPoint(map.getCenter()),
31928                     tooltipPoint = map.layerPointToContainerPoint(pos),
31929                     direction = this.options.direction,
31930                     tooltipWidth = container.offsetWidth,
31931                     tooltipHeight = container.offsetHeight,
31932                     offset = toPoint(this.options.offset),
31933                     anchor = this._getAnchor();
31934
31935                 if (direction === 'top') {
31936                         subX = tooltipWidth / 2;
31937                         subY = tooltipHeight;
31938                 } else if (direction === 'bottom') {
31939                         subX = tooltipWidth / 2;
31940                         subY = 0;
31941                 } else if (direction === 'center') {
31942                         subX = tooltipWidth / 2;
31943                         subY = tooltipHeight / 2;
31944                 } else if (direction === 'right') {
31945                         subX = 0;
31946                         subY = tooltipHeight / 2;
31947                 } else if (direction === 'left') {
31948                         subX = tooltipWidth;
31949                         subY = tooltipHeight / 2;
31950                 } else if (tooltipPoint.x < centerPoint.x) {
31951                         direction = 'right';
31952                         subX = 0;
31953                         subY = tooltipHeight / 2;
31954                 } else {
31955                         direction = 'left';
31956                         subX = tooltipWidth + (offset.x + anchor.x) * 2;
31957                         subY = tooltipHeight / 2;
31958                 }
31959
31960                 pos = pos.subtract(toPoint(subX, subY, true)).add(offset).add(anchor);
31961
31962                 removeClass(container, 'leaflet-tooltip-right');
31963                 removeClass(container, 'leaflet-tooltip-left');
31964                 removeClass(container, 'leaflet-tooltip-top');
31965                 removeClass(container, 'leaflet-tooltip-bottom');
31966                 addClass(container, 'leaflet-tooltip-' + direction);
31967                 setPosition(container, pos);
31968         },
31969
31970         _updatePosition: function () {
31971                 var pos = this._map.latLngToLayerPoint(this._latlng);
31972                 this._setPosition(pos);
31973         },
31974
31975         setOpacity: function (opacity) {
31976                 this.options.opacity = opacity;
31977
31978                 if (this._container) {
31979                         setOpacity(this._container, opacity);
31980                 }
31981         },
31982
31983         _animateZoom: function (e) {
31984                 var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center);
31985                 this._setPosition(pos);
31986         },
31987
31988         _getAnchor: function () {
31989                 // Where should we anchor the tooltip on the source layer?
31990                 return toPoint(this._source && this._source._getTooltipAnchor && !this.options.sticky ? this._source._getTooltipAnchor() : [0, 0]);
31991         }
31992
31993       });
31994
31995       // @namespace Tooltip
31996       // @factory L.tooltip(options?: Tooltip options, source?: Layer)
31997       // Instantiates a Tooltip object given an optional `options` object that describes its appearance and location and an optional `source` object that is used to tag the tooltip with a reference to the Layer to which it refers.
31998       var tooltip = function (options, source) {
31999         return new Tooltip(options, source);
32000       };
32001
32002       // @namespace Map
32003       // @section Methods for Layers and Controls
32004       Map.include({
32005
32006         // @method openTooltip(tooltip: Tooltip): this
32007         // Opens the specified tooltip.
32008         // @alternative
32009         // @method openTooltip(content: String|HTMLElement, latlng: LatLng, options?: Tooltip options): this
32010         // Creates a tooltip with the specified content and options and open it.
32011         openTooltip: function (tooltip, latlng, options) {
32012                 if (!(tooltip instanceof Tooltip)) {
32013                         tooltip = new Tooltip(options).setContent(tooltip);
32014                 }
32015
32016                 if (latlng) {
32017                         tooltip.setLatLng(latlng);
32018                 }
32019
32020                 if (this.hasLayer(tooltip)) {
32021                         return this;
32022                 }
32023
32024                 return this.addLayer(tooltip);
32025         },
32026
32027         // @method closeTooltip(tooltip?: Tooltip): this
32028         // Closes the tooltip given as parameter.
32029         closeTooltip: function (tooltip) {
32030                 if (tooltip) {
32031                         this.removeLayer(tooltip);
32032                 }
32033                 return this;
32034         }
32035
32036       });
32037
32038       /*
32039        * @namespace Layer
32040        * @section Tooltip methods example
32041        *
32042        * All layers share a set of methods convenient for binding tooltips to it.
32043        *
32044        * ```js
32045        * var layer = L.Polygon(latlngs).bindTooltip('Hi There!').addTo(map);
32046        * layer.openTooltip();
32047        * layer.closeTooltip();
32048        * ```
32049        */
32050
32051       // @section Tooltip methods
32052       Layer.include({
32053
32054         // @method bindTooltip(content: String|HTMLElement|Function|Tooltip, options?: Tooltip options): this
32055         // Binds a tooltip to the layer with the passed `content` and sets up the
32056         // necessary event listeners. If a `Function` is passed it will receive
32057         // the layer as the first argument and should return a `String` or `HTMLElement`.
32058         bindTooltip: function (content, options) {
32059
32060                 if (content instanceof Tooltip) {
32061                         setOptions(content, options);
32062                         this._tooltip = content;
32063                         content._source = this;
32064                 } else {
32065                         if (!this._tooltip || options) {
32066                                 this._tooltip = new Tooltip(options, this);
32067                         }
32068                         this._tooltip.setContent(content);
32069
32070                 }
32071
32072                 this._initTooltipInteractions();
32073
32074                 if (this._tooltip.options.permanent && this._map && this._map.hasLayer(this)) {
32075                         this.openTooltip();
32076                 }
32077
32078                 return this;
32079         },
32080
32081         // @method unbindTooltip(): this
32082         // Removes the tooltip previously bound with `bindTooltip`.
32083         unbindTooltip: function () {
32084                 if (this._tooltip) {
32085                         this._initTooltipInteractions(true);
32086                         this.closeTooltip();
32087                         this._tooltip = null;
32088                 }
32089                 return this;
32090         },
32091
32092         _initTooltipInteractions: function (remove$$1) {
32093                 if (!remove$$1 && this._tooltipHandlersAdded) { return; }
32094                 var onOff = remove$$1 ? 'off' : 'on',
32095                     events = {
32096                         remove: this.closeTooltip,
32097                         move: this._moveTooltip
32098                     };
32099                 if (!this._tooltip.options.permanent) {
32100                         events.mouseover = this._openTooltip;
32101                         events.mouseout = this.closeTooltip;
32102                         if (this._tooltip.options.sticky) {
32103                                 events.mousemove = this._moveTooltip;
32104                         }
32105                         if (touch) {
32106                                 events.click = this._openTooltip;
32107                         }
32108                 } else {
32109                         events.add = this._openTooltip;
32110                 }
32111                 this[onOff](events);
32112                 this._tooltipHandlersAdded = !remove$$1;
32113         },
32114
32115         // @method openTooltip(latlng?: LatLng): this
32116         // Opens the bound tooltip at the specified `latlng` or at the default tooltip anchor if no `latlng` is passed.
32117         openTooltip: function (layer, latlng) {
32118                 if (this._tooltip && this._map) {
32119                         latlng = this._tooltip._prepareOpen(this, layer, latlng);
32120
32121                         // open the tooltip on the map
32122                         this._map.openTooltip(this._tooltip, latlng);
32123
32124                         // Tooltip container may not be defined if not permanent and never
32125                         // opened.
32126                         if (this._tooltip.options.interactive && this._tooltip._container) {
32127                                 addClass(this._tooltip._container, 'leaflet-clickable');
32128                                 this.addInteractiveTarget(this._tooltip._container);
32129                         }
32130                 }
32131
32132                 return this;
32133         },
32134
32135         // @method closeTooltip(): this
32136         // Closes the tooltip bound to this layer if it is open.
32137         closeTooltip: function () {
32138                 if (this._tooltip) {
32139                         this._tooltip._close();
32140                         if (this._tooltip.options.interactive && this._tooltip._container) {
32141                                 removeClass(this._tooltip._container, 'leaflet-clickable');
32142                                 this.removeInteractiveTarget(this._tooltip._container);
32143                         }
32144                 }
32145                 return this;
32146         },
32147
32148         // @method toggleTooltip(): this
32149         // Opens or closes the tooltip bound to this layer depending on its current state.
32150         toggleTooltip: function (target) {
32151                 if (this._tooltip) {
32152                         if (this._tooltip._map) {
32153                                 this.closeTooltip();
32154                         } else {
32155                                 this.openTooltip(target);
32156                         }
32157                 }
32158                 return this;
32159         },
32160
32161         // @method isTooltipOpen(): boolean
32162         // Returns `true` if the tooltip bound to this layer is currently open.
32163         isTooltipOpen: function () {
32164                 return this._tooltip.isOpen();
32165         },
32166
32167         // @method setTooltipContent(content: String|HTMLElement|Tooltip): this
32168         // Sets the content of the tooltip bound to this layer.
32169         setTooltipContent: function (content) {
32170                 if (this._tooltip) {
32171                         this._tooltip.setContent(content);
32172                 }
32173                 return this;
32174         },
32175
32176         // @method getTooltip(): Tooltip
32177         // Returns the tooltip bound to this layer.
32178         getTooltip: function () {
32179                 return this._tooltip;
32180         },
32181
32182         _openTooltip: function (e) {
32183                 var layer = e.layer || e.target;
32184
32185                 if (!this._tooltip || !this._map) {
32186                         return;
32187                 }
32188                 this.openTooltip(layer, this._tooltip.options.sticky ? e.latlng : undefined);
32189         },
32190
32191         _moveTooltip: function (e) {
32192                 var latlng = e.latlng, containerPoint, layerPoint;
32193                 if (this._tooltip.options.sticky && e.originalEvent) {
32194                         containerPoint = this._map.mouseEventToContainerPoint(e.originalEvent);
32195                         layerPoint = this._map.containerPointToLayerPoint(containerPoint);
32196                         latlng = this._map.layerPointToLatLng(layerPoint);
32197                 }
32198                 this._tooltip.setLatLng(latlng);
32199         }
32200       });
32201
32202       /*
32203        * @class DivIcon
32204        * @aka L.DivIcon
32205        * @inherits Icon
32206        *
32207        * Represents a lightweight icon for markers that uses a simple `<div>`
32208        * element instead of an image. Inherits from `Icon` but ignores the `iconUrl` and shadow options.
32209        *
32210        * @example
32211        * ```js
32212        * var myIcon = L.divIcon({className: 'my-div-icon'});
32213        * // you can set .my-div-icon styles in CSS
32214        *
32215        * L.marker([50.505, 30.57], {icon: myIcon}).addTo(map);
32216        * ```
32217        *
32218        * By default, it has a 'leaflet-div-icon' CSS class and is styled as a little white square with a shadow.
32219        */
32220
32221       var DivIcon = Icon.extend({
32222         options: {
32223                 // @section
32224                 // @aka DivIcon options
32225                 iconSize: [12, 12], // also can be set through CSS
32226
32227                 // iconAnchor: (Point),
32228                 // popupAnchor: (Point),
32229
32230                 // @option html: String|HTMLElement = ''
32231                 // Custom HTML code to put inside the div element, empty by default. Alternatively,
32232                 // an instance of `HTMLElement`.
32233                 html: false,
32234
32235                 // @option bgPos: Point = [0, 0]
32236                 // Optional relative position of the background, in pixels
32237                 bgPos: null,
32238
32239                 className: 'leaflet-div-icon'
32240         },
32241
32242         createIcon: function (oldIcon) {
32243                 var div = (oldIcon && oldIcon.tagName === 'DIV') ? oldIcon : document.createElement('div'),
32244                     options = this.options;
32245
32246                 if (options.html instanceof Element) {
32247                         empty(div);
32248                         div.appendChild(options.html);
32249                 } else {
32250                         div.innerHTML = options.html !== false ? options.html : '';
32251                 }
32252
32253                 if (options.bgPos) {
32254                         var bgPos = toPoint(options.bgPos);
32255                         div.style.backgroundPosition = (-bgPos.x) + 'px ' + (-bgPos.y) + 'px';
32256                 }
32257                 this._setIconStyles(div, 'icon');
32258
32259                 return div;
32260         },
32261
32262         createShadow: function () {
32263                 return null;
32264         }
32265       });
32266
32267       // @factory L.divIcon(options: DivIcon options)
32268       // Creates a `DivIcon` instance with the given options.
32269       function divIcon(options) {
32270         return new DivIcon(options);
32271       }
32272
32273       Icon.Default = IconDefault;
32274
32275       /*
32276        * @class GridLayer
32277        * @inherits Layer
32278        * @aka L.GridLayer
32279        *
32280        * Generic class for handling a tiled grid of HTML elements. This is the base class for all tile layers and replaces `TileLayer.Canvas`.
32281        * GridLayer can be extended to create a tiled grid of HTML elements like `<canvas>`, `<img>` or `<div>`. GridLayer will handle creating and animating these DOM elements for you.
32282        *
32283        *
32284        * @section Synchronous usage
32285        * @example
32286        *
32287        * To create a custom layer, extend GridLayer and implement the `createTile()` method, which will be passed a `Point` object with the `x`, `y`, and `z` (zoom level) coordinates to draw your tile.
32288        *
32289        * ```js
32290        * var CanvasLayer = L.GridLayer.extend({
32291        *     createTile: function(coords){
32292        *         // create a <canvas> element for drawing
32293        *         var tile = L.DomUtil.create('canvas', 'leaflet-tile');
32294        *
32295        *         // setup tile width and height according to the options
32296        *         var size = this.getTileSize();
32297        *         tile.width = size.x;
32298        *         tile.height = size.y;
32299        *
32300        *         // get a canvas context and draw something on it using coords.x, coords.y and coords.z
32301        *         var ctx = tile.getContext('2d');
32302        *
32303        *         // return the tile so it can be rendered on screen
32304        *         return tile;
32305        *     }
32306        * });
32307        * ```
32308        *
32309        * @section Asynchronous usage
32310        * @example
32311        *
32312        * Tile creation can also be asynchronous, this is useful when using a third-party drawing library. Once the tile is finished drawing it can be passed to the `done()` callback.
32313        *
32314        * ```js
32315        * var CanvasLayer = L.GridLayer.extend({
32316        *     createTile: function(coords, done){
32317        *         var error;
32318        *
32319        *         // create a <canvas> element for drawing
32320        *         var tile = L.DomUtil.create('canvas', 'leaflet-tile');
32321        *
32322        *         // setup tile width and height according to the options
32323        *         var size = this.getTileSize();
32324        *         tile.width = size.x;
32325        *         tile.height = size.y;
32326        *
32327        *         // draw something asynchronously and pass the tile to the done() callback
32328        *         setTimeout(function() {
32329        *             done(error, tile);
32330        *         }, 1000);
32331        *
32332        *         return tile;
32333        *     }
32334        * });
32335        * ```
32336        *
32337        * @section
32338        */
32339
32340
32341       var GridLayer = Layer.extend({
32342
32343         // @section
32344         // @aka GridLayer options
32345         options: {
32346                 // @option tileSize: Number|Point = 256
32347                 // Width and height of tiles in the grid. Use a number if width and height are equal, or `L.point(width, height)` otherwise.
32348                 tileSize: 256,
32349
32350                 // @option opacity: Number = 1.0
32351                 // Opacity of the tiles. Can be used in the `createTile()` function.
32352                 opacity: 1,
32353
32354                 // @option updateWhenIdle: Boolean = (depends)
32355                 // Load new tiles only when panning ends.
32356                 // `true` by default on mobile browsers, in order to avoid too many requests and keep smooth navigation.
32357                 // `false` otherwise in order to display new tiles _during_ panning, since it is easy to pan outside the
32358                 // [`keepBuffer`](#gridlayer-keepbuffer) option in desktop browsers.
32359                 updateWhenIdle: mobile,
32360
32361                 // @option updateWhenZooming: Boolean = true
32362                 // By default, a smooth zoom animation (during a [touch zoom](#map-touchzoom) or a [`flyTo()`](#map-flyto)) will update grid layers every integer zoom level. Setting this option to `false` will update the grid layer only when the smooth animation ends.
32363                 updateWhenZooming: true,
32364
32365                 // @option updateInterval: Number = 200
32366                 // Tiles will not update more than once every `updateInterval` milliseconds when panning.
32367                 updateInterval: 200,
32368
32369                 // @option zIndex: Number = 1
32370                 // The explicit zIndex of the tile layer.
32371                 zIndex: 1,
32372
32373                 // @option bounds: LatLngBounds = undefined
32374                 // If set, tiles will only be loaded inside the set `LatLngBounds`.
32375                 bounds: null,
32376
32377                 // @option minZoom: Number = 0
32378                 // The minimum zoom level down to which this layer will be displayed (inclusive).
32379                 minZoom: 0,
32380
32381                 // @option maxZoom: Number = undefined
32382                 // The maximum zoom level up to which this layer will be displayed (inclusive).
32383                 maxZoom: undefined,
32384
32385                 // @option maxNativeZoom: Number = undefined
32386                 // Maximum zoom number the tile source has available. If it is specified,
32387                 // the tiles on all zoom levels higher than `maxNativeZoom` will be loaded
32388                 // from `maxNativeZoom` level and auto-scaled.
32389                 maxNativeZoom: undefined,
32390
32391                 // @option minNativeZoom: Number = undefined
32392                 // Minimum zoom number the tile source has available. If it is specified,
32393                 // the tiles on all zoom levels lower than `minNativeZoom` will be loaded
32394                 // from `minNativeZoom` level and auto-scaled.
32395                 minNativeZoom: undefined,
32396
32397                 // @option noWrap: Boolean = false
32398                 // Whether the layer is wrapped around the antimeridian. If `true`, the
32399                 // GridLayer will only be displayed once at low zoom levels. Has no
32400                 // effect when the [map CRS](#map-crs) doesn't wrap around. Can be used
32401                 // in combination with [`bounds`](#gridlayer-bounds) to prevent requesting
32402                 // tiles outside the CRS limits.
32403                 noWrap: false,
32404
32405                 // @option pane: String = 'tilePane'
32406                 // `Map pane` where the grid layer will be added.
32407                 pane: 'tilePane',
32408
32409                 // @option className: String = ''
32410                 // A custom class name to assign to the tile layer. Empty by default.
32411                 className: '',
32412
32413                 // @option keepBuffer: Number = 2
32414                 // When panning the map, keep this many rows and columns of tiles before unloading them.
32415                 keepBuffer: 2
32416         },
32417
32418         initialize: function (options) {
32419                 setOptions(this, options);
32420         },
32421
32422         onAdd: function () {
32423                 this._initContainer();
32424
32425                 this._levels = {};
32426                 this._tiles = {};
32427
32428                 this._resetView();
32429                 this._update();
32430         },
32431
32432         beforeAdd: function (map) {
32433                 map._addZoomLimit(this);
32434         },
32435
32436         onRemove: function (map) {
32437                 this._removeAllTiles();
32438                 remove(this._container);
32439                 map._removeZoomLimit(this);
32440                 this._container = null;
32441                 this._tileZoom = undefined;
32442         },
32443
32444         // @method bringToFront: this
32445         // Brings the tile layer to the top of all tile layers.
32446         bringToFront: function () {
32447                 if (this._map) {
32448                         toFront(this._container);
32449                         this._setAutoZIndex(Math.max);
32450                 }
32451                 return this;
32452         },
32453
32454         // @method bringToBack: this
32455         // Brings the tile layer to the bottom of all tile layers.
32456         bringToBack: function () {
32457                 if (this._map) {
32458                         toBack(this._container);
32459                         this._setAutoZIndex(Math.min);
32460                 }
32461                 return this;
32462         },
32463
32464         // @method getContainer: HTMLElement
32465         // Returns the HTML element that contains the tiles for this layer.
32466         getContainer: function () {
32467                 return this._container;
32468         },
32469
32470         // @method setOpacity(opacity: Number): this
32471         // Changes the [opacity](#gridlayer-opacity) of the grid layer.
32472         setOpacity: function (opacity) {
32473                 this.options.opacity = opacity;
32474                 this._updateOpacity();
32475                 return this;
32476         },
32477
32478         // @method setZIndex(zIndex: Number): this
32479         // Changes the [zIndex](#gridlayer-zindex) of the grid layer.
32480         setZIndex: function (zIndex) {
32481                 this.options.zIndex = zIndex;
32482                 this._updateZIndex();
32483
32484                 return this;
32485         },
32486
32487         // @method isLoading: Boolean
32488         // Returns `true` if any tile in the grid layer has not finished loading.
32489         isLoading: function () {
32490                 return this._loading;
32491         },
32492
32493         // @method redraw: this
32494         // Causes the layer to clear all the tiles and request them again.
32495         redraw: function () {
32496                 if (this._map) {
32497                         this._removeAllTiles();
32498                         this._update();
32499                 }
32500                 return this;
32501         },
32502
32503         getEvents: function () {
32504                 var events = {
32505                         viewprereset: this._invalidateAll,
32506                         viewreset: this._resetView,
32507                         zoom: this._resetView,
32508                         moveend: this._onMoveEnd
32509                 };
32510
32511                 if (!this.options.updateWhenIdle) {
32512                         // update tiles on move, but not more often than once per given interval
32513                         if (!this._onMove) {
32514                                 this._onMove = throttle(this._onMoveEnd, this.options.updateInterval, this);
32515                         }
32516
32517                         events.move = this._onMove;
32518                 }
32519
32520                 if (this._zoomAnimated) {
32521                         events.zoomanim = this._animateZoom;
32522                 }
32523
32524                 return events;
32525         },
32526
32527         // @section Extension methods
32528         // Layers extending `GridLayer` shall reimplement the following method.
32529         // @method createTile(coords: Object, done?: Function): HTMLElement
32530         // Called only internally, must be overridden by classes extending `GridLayer`.
32531         // Returns the `HTMLElement` corresponding to the given `coords`. If the `done` callback
32532         // is specified, it must be called when the tile has finished loading and drawing.
32533         createTile: function () {
32534                 return document.createElement('div');
32535         },
32536
32537         // @section
32538         // @method getTileSize: Point
32539         // Normalizes the [tileSize option](#gridlayer-tilesize) into a point. Used by the `createTile()` method.
32540         getTileSize: function () {
32541                 var s = this.options.tileSize;
32542                 return s instanceof Point ? s : new Point(s, s);
32543         },
32544
32545         _updateZIndex: function () {
32546                 if (this._container && this.options.zIndex !== undefined && this.options.zIndex !== null) {
32547                         this._container.style.zIndex = this.options.zIndex;
32548                 }
32549         },
32550
32551         _setAutoZIndex: function (compare) {
32552                 // go through all other layers of the same pane, set zIndex to max + 1 (front) or min - 1 (back)
32553
32554                 var layers = this.getPane().children,
32555                     edgeZIndex = -compare(-Infinity, Infinity); // -Infinity for max, Infinity for min
32556
32557                 for (var i = 0, len = layers.length, zIndex; i < len; i++) {
32558
32559                         zIndex = layers[i].style.zIndex;
32560
32561                         if (layers[i] !== this._container && zIndex) {
32562                                 edgeZIndex = compare(edgeZIndex, +zIndex);
32563                         }
32564                 }
32565
32566                 if (isFinite(edgeZIndex)) {
32567                         this.options.zIndex = edgeZIndex + compare(-1, 1);
32568                         this._updateZIndex();
32569                 }
32570         },
32571
32572         _updateOpacity: function () {
32573                 if (!this._map) { return; }
32574
32575                 // IE doesn't inherit filter opacity properly, so we're forced to set it on tiles
32576                 if (ielt9) { return; }
32577
32578                 setOpacity(this._container, this.options.opacity);
32579
32580                 var now = +new Date(),
32581                     nextFrame = false,
32582                     willPrune = false;
32583
32584                 for (var key in this._tiles) {
32585                         var tile = this._tiles[key];
32586                         if (!tile.current || !tile.loaded) { continue; }
32587
32588                         var fade = Math.min(1, (now - tile.loaded) / 200);
32589
32590                         setOpacity(tile.el, fade);
32591                         if (fade < 1) {
32592                                 nextFrame = true;
32593                         } else {
32594                                 if (tile.active) {
32595                                         willPrune = true;
32596                                 } else {
32597                                         this._onOpaqueTile(tile);
32598                                 }
32599                                 tile.active = true;
32600                         }
32601                 }
32602
32603                 if (willPrune && !this._noPrune) { this._pruneTiles(); }
32604
32605                 if (nextFrame) {
32606                         cancelAnimFrame(this._fadeFrame);
32607                         this._fadeFrame = requestAnimFrame(this._updateOpacity, this);
32608                 }
32609         },
32610
32611         _onOpaqueTile: falseFn,
32612
32613         _initContainer: function () {
32614                 if (this._container) { return; }
32615
32616                 this._container = create$1('div', 'leaflet-layer ' + (this.options.className || ''));
32617                 this._updateZIndex();
32618
32619                 if (this.options.opacity < 1) {
32620                         this._updateOpacity();
32621                 }
32622
32623                 this.getPane().appendChild(this._container);
32624         },
32625
32626         _updateLevels: function () {
32627
32628                 var zoom = this._tileZoom,
32629                     maxZoom = this.options.maxZoom;
32630
32631                 if (zoom === undefined) { return undefined; }
32632
32633                 for (var z in this._levels) {
32634                         z = Number(z);
32635                         if (this._levels[z].el.children.length || z === zoom) {
32636                                 this._levels[z].el.style.zIndex = maxZoom - Math.abs(zoom - z);
32637                                 this._onUpdateLevel(z);
32638                         } else {
32639                                 remove(this._levels[z].el);
32640                                 this._removeTilesAtZoom(z);
32641                                 this._onRemoveLevel(z);
32642                                 delete this._levels[z];
32643                         }
32644                 }
32645
32646                 var level = this._levels[zoom],
32647                     map = this._map;
32648
32649                 if (!level) {
32650                         level = this._levels[zoom] = {};
32651
32652                         level.el = create$1('div', 'leaflet-tile-container leaflet-zoom-animated', this._container);
32653                         level.el.style.zIndex = maxZoom;
32654
32655                         level.origin = map.project(map.unproject(map.getPixelOrigin()), zoom).round();
32656                         level.zoom = zoom;
32657
32658                         this._setZoomTransform(level, map.getCenter(), map.getZoom());
32659
32660                         // force the browser to consider the newly added element for transition
32661                         falseFn(level.el.offsetWidth);
32662
32663                         this._onCreateLevel(level);
32664                 }
32665
32666                 this._level = level;
32667
32668                 return level;
32669         },
32670
32671         _onUpdateLevel: falseFn,
32672
32673         _onRemoveLevel: falseFn,
32674
32675         _onCreateLevel: falseFn,
32676
32677         _pruneTiles: function () {
32678                 if (!this._map) {
32679                         return;
32680                 }
32681
32682                 var key, tile;
32683
32684                 var zoom = this._map.getZoom();
32685                 if (zoom > this.options.maxZoom ||
32686                         zoom < this.options.minZoom) {
32687                         this._removeAllTiles();
32688                         return;
32689                 }
32690
32691                 for (key in this._tiles) {
32692                         tile = this._tiles[key];
32693                         tile.retain = tile.current;
32694                 }
32695
32696                 for (key in this._tiles) {
32697                         tile = this._tiles[key];
32698                         if (tile.current && !tile.active) {
32699                                 var coords = tile.coords;
32700                                 if (!this._retainParent(coords.x, coords.y, coords.z, coords.z - 5)) {
32701                                         this._retainChildren(coords.x, coords.y, coords.z, coords.z + 2);
32702                                 }
32703                         }
32704                 }
32705
32706                 for (key in this._tiles) {
32707                         if (!this._tiles[key].retain) {
32708                                 this._removeTile(key);
32709                         }
32710                 }
32711         },
32712
32713         _removeTilesAtZoom: function (zoom) {
32714                 for (var key in this._tiles) {
32715                         if (this._tiles[key].coords.z !== zoom) {
32716                                 continue;
32717                         }
32718                         this._removeTile(key);
32719                 }
32720         },
32721
32722         _removeAllTiles: function () {
32723                 for (var key in this._tiles) {
32724                         this._removeTile(key);
32725                 }
32726         },
32727
32728         _invalidateAll: function () {
32729                 for (var z in this._levels) {
32730                         remove(this._levels[z].el);
32731                         this._onRemoveLevel(Number(z));
32732                         delete this._levels[z];
32733                 }
32734                 this._removeAllTiles();
32735
32736                 this._tileZoom = undefined;
32737         },
32738
32739         _retainParent: function (x, y, z, minZoom) {
32740                 var x2 = Math.floor(x / 2),
32741                     y2 = Math.floor(y / 2),
32742                     z2 = z - 1,
32743                     coords2 = new Point(+x2, +y2);
32744                 coords2.z = +z2;
32745
32746                 var key = this._tileCoordsToKey(coords2),
32747                     tile = this._tiles[key];
32748
32749                 if (tile && tile.active) {
32750                         tile.retain = true;
32751                         return true;
32752
32753                 } else if (tile && tile.loaded) {
32754                         tile.retain = true;
32755                 }
32756
32757                 if (z2 > minZoom) {
32758                         return this._retainParent(x2, y2, z2, minZoom);
32759                 }
32760
32761                 return false;
32762         },
32763
32764         _retainChildren: function (x, y, z, maxZoom) {
32765
32766                 for (var i = 2 * x; i < 2 * x + 2; i++) {
32767                         for (var j = 2 * y; j < 2 * y + 2; j++) {
32768
32769                                 var coords = new Point(i, j);
32770                                 coords.z = z + 1;
32771
32772                                 var key = this._tileCoordsToKey(coords),
32773                                     tile = this._tiles[key];
32774
32775                                 if (tile && tile.active) {
32776                                         tile.retain = true;
32777                                         continue;
32778
32779                                 } else if (tile && tile.loaded) {
32780                                         tile.retain = true;
32781                                 }
32782
32783                                 if (z + 1 < maxZoom) {
32784                                         this._retainChildren(i, j, z + 1, maxZoom);
32785                                 }
32786                         }
32787                 }
32788         },
32789
32790         _resetView: function (e) {
32791                 var animating = e && (e.pinch || e.flyTo);
32792                 this._setView(this._map.getCenter(), this._map.getZoom(), animating, animating);
32793         },
32794
32795         _animateZoom: function (e) {
32796                 this._setView(e.center, e.zoom, true, e.noUpdate);
32797         },
32798
32799         _clampZoom: function (zoom) {
32800                 var options = this.options;
32801
32802                 if (undefined !== options.minNativeZoom && zoom < options.minNativeZoom) {
32803                         return options.minNativeZoom;
32804                 }
32805
32806                 if (undefined !== options.maxNativeZoom && options.maxNativeZoom < zoom) {
32807                         return options.maxNativeZoom;
32808                 }
32809
32810                 return zoom;
32811         },
32812
32813         _setView: function (center, zoom, noPrune, noUpdate) {
32814                 var tileZoom = Math.round(zoom);
32815                 if ((this.options.maxZoom !== undefined && tileZoom > this.options.maxZoom) ||
32816                     (this.options.minZoom !== undefined && tileZoom < this.options.minZoom)) {
32817                         tileZoom = undefined;
32818                 } else {
32819                         tileZoom = this._clampZoom(tileZoom);
32820                 }
32821
32822                 var tileZoomChanged = this.options.updateWhenZooming && (tileZoom !== this._tileZoom);
32823
32824                 if (!noUpdate || tileZoomChanged) {
32825
32826                         this._tileZoom = tileZoom;
32827
32828                         if (this._abortLoading) {
32829                                 this._abortLoading();
32830                         }
32831
32832                         this._updateLevels();
32833                         this._resetGrid();
32834
32835                         if (tileZoom !== undefined) {
32836                                 this._update(center);
32837                         }
32838
32839                         if (!noPrune) {
32840                                 this._pruneTiles();
32841                         }
32842
32843                         // Flag to prevent _updateOpacity from pruning tiles during
32844                         // a zoom anim or a pinch gesture
32845                         this._noPrune = !!noPrune;
32846                 }
32847
32848                 this._setZoomTransforms(center, zoom);
32849         },
32850
32851         _setZoomTransforms: function (center, zoom) {
32852                 for (var i in this._levels) {
32853                         this._setZoomTransform(this._levels[i], center, zoom);
32854                 }
32855         },
32856
32857         _setZoomTransform: function (level, center, zoom) {
32858                 var scale = this._map.getZoomScale(zoom, level.zoom),
32859                     translate = level.origin.multiplyBy(scale)
32860                         .subtract(this._map._getNewPixelOrigin(center, zoom)).round();
32861
32862                 if (any3d) {
32863                         setTransform(level.el, translate, scale);
32864                 } else {
32865                         setPosition(level.el, translate);
32866                 }
32867         },
32868
32869         _resetGrid: function () {
32870                 var map = this._map,
32871                     crs = map.options.crs,
32872                     tileSize = this._tileSize = this.getTileSize(),
32873                     tileZoom = this._tileZoom;
32874
32875                 var bounds = this._map.getPixelWorldBounds(this._tileZoom);
32876                 if (bounds) {
32877                         this._globalTileRange = this._pxBoundsToTileRange(bounds);
32878                 }
32879
32880                 this._wrapX = crs.wrapLng && !this.options.noWrap && [
32881                         Math.floor(map.project([0, crs.wrapLng[0]], tileZoom).x / tileSize.x),
32882                         Math.ceil(map.project([0, crs.wrapLng[1]], tileZoom).x / tileSize.y)
32883                 ];
32884                 this._wrapY = crs.wrapLat && !this.options.noWrap && [
32885                         Math.floor(map.project([crs.wrapLat[0], 0], tileZoom).y / tileSize.x),
32886                         Math.ceil(map.project([crs.wrapLat[1], 0], tileZoom).y / tileSize.y)
32887                 ];
32888         },
32889
32890         _onMoveEnd: function () {
32891                 if (!this._map || this._map._animatingZoom) { return; }
32892
32893                 this._update();
32894         },
32895
32896         _getTiledPixelBounds: function (center) {
32897                 var map = this._map,
32898                     mapZoom = map._animatingZoom ? Math.max(map._animateToZoom, map.getZoom()) : map.getZoom(),
32899                     scale = map.getZoomScale(mapZoom, this._tileZoom),
32900                     pixelCenter = map.project(center, this._tileZoom).floor(),
32901                     halfSize = map.getSize().divideBy(scale * 2);
32902
32903                 return new Bounds(pixelCenter.subtract(halfSize), pixelCenter.add(halfSize));
32904         },
32905
32906         // Private method to load tiles in the grid's active zoom level according to map bounds
32907         _update: function (center) {
32908                 var map = this._map;
32909                 if (!map) { return; }
32910                 var zoom = this._clampZoom(map.getZoom());
32911
32912                 if (center === undefined) { center = map.getCenter(); }
32913                 if (this._tileZoom === undefined) { return; }   // if out of minzoom/maxzoom
32914
32915                 var pixelBounds = this._getTiledPixelBounds(center),
32916                     tileRange = this._pxBoundsToTileRange(pixelBounds),
32917                     tileCenter = tileRange.getCenter(),
32918                     queue = [],
32919                     margin = this.options.keepBuffer,
32920                     noPruneRange = new Bounds(tileRange.getBottomLeft().subtract([margin, -margin]),
32921                                               tileRange.getTopRight().add([margin, -margin]));
32922
32923                 // Sanity check: panic if the tile range contains Infinity somewhere.
32924                 if (!(isFinite(tileRange.min.x) &&
32925                       isFinite(tileRange.min.y) &&
32926                       isFinite(tileRange.max.x) &&
32927                       isFinite(tileRange.max.y))) { throw new Error('Attempted to load an infinite number of tiles'); }
32928
32929                 for (var key in this._tiles) {
32930                         var c = this._tiles[key].coords;
32931                         if (c.z !== this._tileZoom || !noPruneRange.contains(new Point(c.x, c.y))) {
32932                                 this._tiles[key].current = false;
32933                         }
32934                 }
32935
32936                 // _update just loads more tiles. If the tile zoom level differs too much
32937                 // from the map's, let _setView reset levels and prune old tiles.
32938                 if (Math.abs(zoom - this._tileZoom) > 1) { this._setView(center, zoom); return; }
32939
32940                 // create a queue of coordinates to load tiles from
32941                 for (var j = tileRange.min.y; j <= tileRange.max.y; j++) {
32942                         for (var i = tileRange.min.x; i <= tileRange.max.x; i++) {
32943                                 var coords = new Point(i, j);
32944                                 coords.z = this._tileZoom;
32945
32946                                 if (!this._isValidTile(coords)) { continue; }
32947
32948                                 var tile = this._tiles[this._tileCoordsToKey(coords)];
32949                                 if (tile) {
32950                                         tile.current = true;
32951                                 } else {
32952                                         queue.push(coords);
32953                                 }
32954                         }
32955                 }
32956
32957                 // sort tile queue to load tiles in order of their distance to center
32958                 queue.sort(function (a, b) {
32959                         return a.distanceTo(tileCenter) - b.distanceTo(tileCenter);
32960                 });
32961
32962                 if (queue.length !== 0) {
32963                         // if it's the first batch of tiles to load
32964                         if (!this._loading) {
32965                                 this._loading = true;
32966                                 // @event loading: Event
32967                                 // Fired when the grid layer starts loading tiles.
32968                                 this.fire('loading');
32969                         }
32970
32971                         // create DOM fragment to append tiles in one batch
32972                         var fragment = document.createDocumentFragment();
32973
32974                         for (i = 0; i < queue.length; i++) {
32975                                 this._addTile(queue[i], fragment);
32976                         }
32977
32978                         this._level.el.appendChild(fragment);
32979                 }
32980         },
32981
32982         _isValidTile: function (coords) {
32983                 var crs = this._map.options.crs;
32984
32985                 if (!crs.infinite) {
32986                         // don't load tile if it's out of bounds and not wrapped
32987                         var bounds = this._globalTileRange;
32988                         if ((!crs.wrapLng && (coords.x < bounds.min.x || coords.x > bounds.max.x)) ||
32989                             (!crs.wrapLat && (coords.y < bounds.min.y || coords.y > bounds.max.y))) { return false; }
32990                 }
32991
32992                 if (!this.options.bounds) { return true; }
32993
32994                 // don't load tile if it doesn't intersect the bounds in options
32995                 var tileBounds = this._tileCoordsToBounds(coords);
32996                 return toLatLngBounds(this.options.bounds).overlaps(tileBounds);
32997         },
32998
32999         _keyToBounds: function (key) {
33000                 return this._tileCoordsToBounds(this._keyToTileCoords(key));
33001         },
33002
33003         _tileCoordsToNwSe: function (coords) {
33004                 var map = this._map,
33005                     tileSize = this.getTileSize(),
33006                     nwPoint = coords.scaleBy(tileSize),
33007                     sePoint = nwPoint.add(tileSize),
33008                     nw = map.unproject(nwPoint, coords.z),
33009                     se = map.unproject(sePoint, coords.z);
33010                 return [nw, se];
33011         },
33012
33013         // converts tile coordinates to its geographical bounds
33014         _tileCoordsToBounds: function (coords) {
33015                 var bp = this._tileCoordsToNwSe(coords),
33016                     bounds = new LatLngBounds(bp[0], bp[1]);
33017
33018                 if (!this.options.noWrap) {
33019                         bounds = this._map.wrapLatLngBounds(bounds);
33020                 }
33021                 return bounds;
33022         },
33023         // converts tile coordinates to key for the tile cache
33024         _tileCoordsToKey: function (coords) {
33025                 return coords.x + ':' + coords.y + ':' + coords.z;
33026         },
33027
33028         // converts tile cache key to coordinates
33029         _keyToTileCoords: function (key) {
33030                 var k = key.split(':'),
33031                     coords = new Point(+k[0], +k[1]);
33032                 coords.z = +k[2];
33033                 return coords;
33034         },
33035
33036         _removeTile: function (key) {
33037                 var tile = this._tiles[key];
33038                 if (!tile) { return; }
33039
33040                 remove(tile.el);
33041
33042                 delete this._tiles[key];
33043
33044                 // @event tileunload: TileEvent
33045                 // Fired when a tile is removed (e.g. when a tile goes off the screen).
33046                 this.fire('tileunload', {
33047                         tile: tile.el,
33048                         coords: this._keyToTileCoords(key)
33049                 });
33050         },
33051
33052         _initTile: function (tile) {
33053                 addClass(tile, 'leaflet-tile');
33054
33055                 var tileSize = this.getTileSize();
33056                 tile.style.width = tileSize.x + 'px';
33057                 tile.style.height = tileSize.y + 'px';
33058
33059                 tile.onselectstart = falseFn;
33060                 tile.onmousemove = falseFn;
33061
33062                 // update opacity on tiles in IE7-8 because of filter inheritance problems
33063                 if (ielt9 && this.options.opacity < 1) {
33064                         setOpacity(tile, this.options.opacity);
33065                 }
33066
33067                 // without this hack, tiles disappear after zoom on Chrome for Android
33068                 // https://github.com/Leaflet/Leaflet/issues/2078
33069                 if (android && !android23) {
33070                         tile.style.WebkitBackfaceVisibility = 'hidden';
33071                 }
33072         },
33073
33074         _addTile: function (coords, container) {
33075                 var tilePos = this._getTilePos(coords),
33076                     key = this._tileCoordsToKey(coords);
33077
33078                 var tile = this.createTile(this._wrapCoords(coords), bind(this._tileReady, this, coords));
33079
33080                 this._initTile(tile);
33081
33082                 // if createTile is defined with a second argument ("done" callback),
33083                 // we know that tile is async and will be ready later; otherwise
33084                 if (this.createTile.length < 2) {
33085                         // mark tile as ready, but delay one frame for opacity animation to happen
33086                         requestAnimFrame(bind(this._tileReady, this, coords, null, tile));
33087                 }
33088
33089                 setPosition(tile, tilePos);
33090
33091                 // save tile in cache
33092                 this._tiles[key] = {
33093                         el: tile,
33094                         coords: coords,
33095                         current: true
33096                 };
33097
33098                 container.appendChild(tile);
33099                 // @event tileloadstart: TileEvent
33100                 // Fired when a tile is requested and starts loading.
33101                 this.fire('tileloadstart', {
33102                         tile: tile,
33103                         coords: coords
33104                 });
33105         },
33106
33107         _tileReady: function (coords, err, tile) {
33108                 if (err) {
33109                         // @event tileerror: TileErrorEvent
33110                         // Fired when there is an error loading a tile.
33111                         this.fire('tileerror', {
33112                                 error: err,
33113                                 tile: tile,
33114                                 coords: coords
33115                         });
33116                 }
33117
33118                 var key = this._tileCoordsToKey(coords);
33119
33120                 tile = this._tiles[key];
33121                 if (!tile) { return; }
33122
33123                 tile.loaded = +new Date();
33124                 if (this._map._fadeAnimated) {
33125                         setOpacity(tile.el, 0);
33126                         cancelAnimFrame(this._fadeFrame);
33127                         this._fadeFrame = requestAnimFrame(this._updateOpacity, this);
33128                 } else {
33129                         tile.active = true;
33130                         this._pruneTiles();
33131                 }
33132
33133                 if (!err) {
33134                         addClass(tile.el, 'leaflet-tile-loaded');
33135
33136                         // @event tileload: TileEvent
33137                         // Fired when a tile loads.
33138                         this.fire('tileload', {
33139                                 tile: tile.el,
33140                                 coords: coords
33141                         });
33142                 }
33143
33144                 if (this._noTilesToLoad()) {
33145                         this._loading = false;
33146                         // @event load: Event
33147                         // Fired when the grid layer loaded all visible tiles.
33148                         this.fire('load');
33149
33150                         if (ielt9 || !this._map._fadeAnimated) {
33151                                 requestAnimFrame(this._pruneTiles, this);
33152                         } else {
33153                                 // Wait a bit more than 0.2 secs (the duration of the tile fade-in)
33154                                 // to trigger a pruning.
33155                                 setTimeout(bind(this._pruneTiles, this), 250);
33156                         }
33157                 }
33158         },
33159
33160         _getTilePos: function (coords) {
33161                 return coords.scaleBy(this.getTileSize()).subtract(this._level.origin);
33162         },
33163
33164         _wrapCoords: function (coords) {
33165                 var newCoords = new Point(
33166                         this._wrapX ? wrapNum(coords.x, this._wrapX) : coords.x,
33167                         this._wrapY ? wrapNum(coords.y, this._wrapY) : coords.y);
33168                 newCoords.z = coords.z;
33169                 return newCoords;
33170         },
33171
33172         _pxBoundsToTileRange: function (bounds) {
33173                 var tileSize = this.getTileSize();
33174                 return new Bounds(
33175                         bounds.min.unscaleBy(tileSize).floor(),
33176                         bounds.max.unscaleBy(tileSize).ceil().subtract([1, 1]));
33177         },
33178
33179         _noTilesToLoad: function () {
33180                 for (var key in this._tiles) {
33181                         if (!this._tiles[key].loaded) { return false; }
33182                 }
33183                 return true;
33184         }
33185       });
33186
33187       // @factory L.gridLayer(options?: GridLayer options)
33188       // Creates a new instance of GridLayer with the supplied options.
33189       function gridLayer(options) {
33190         return new GridLayer(options);
33191       }
33192
33193       /*\r
33194        * @class TileLayer\r
33195        * @inherits GridLayer\r
33196        * @aka L.TileLayer\r
33197        * Used to load and display tile layers on the map. Note that most tile servers require attribution, which you can set under `Layer`. Extends `GridLayer`.\r
33198        *\r
33199        * @example\r
33200        *\r
33201        * ```js\r
33202        * L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?{foo}', {foo: 'bar', attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'}).addTo(map);\r
33203        * ```\r
33204        *\r
33205        * @section URL template\r
33206        * @example\r
33207        *\r
33208        * A string of the following form:\r
33209        *\r
33210        * ```\r
33211        * 'http://{s}.somedomain.com/blabla/{z}/{x}/{y}{r}.png'\r
33212        * ```\r
33213        *\r
33214        * `{s}` means one of the available subdomains (used sequentially to help with browser parallel requests per domain limitation; subdomain values are specified in options; `a`, `b` or `c` by default, can be omitted), `{z}` â€” zoom level, `{x}` and `{y}` â€” tile coordinates. `{r}` can be used to add "&commat;2x" to the URL to load retina tiles.\r
33215        *\r
33216        * You can use custom keys in the template, which will be [evaluated](#util-template) from TileLayer options, like this:\r
33217        *\r
33218        * ```\r
33219        * L.tileLayer('http://{s}.somedomain.com/{foo}/{z}/{x}/{y}.png', {foo: 'bar'});\r
33220        * ```\r
33221        */\r
33222 \r
33223 \r
33224       var TileLayer = GridLayer.extend({\r
33225 \r
33226         // @section\r
33227         // @aka TileLayer options\r
33228         options: {\r
33229                 // @option minZoom: Number = 0\r
33230                 // The minimum zoom level down to which this layer will be displayed (inclusive).\r
33231                 minZoom: 0,\r
33232 \r
33233                 // @option maxZoom: Number = 18\r
33234                 // The maximum zoom level up to which this layer will be displayed (inclusive).\r
33235                 maxZoom: 18,\r
33236 \r
33237                 // @option subdomains: String|String[] = 'abc'\r
33238                 // Subdomains of the tile service. Can be passed in the form of one string (where each letter is a subdomain name) or an array of strings.\r
33239                 subdomains: 'abc',\r
33240 \r
33241                 // @option errorTileUrl: String = ''\r
33242                 // URL to the tile image to show in place of the tile that failed to load.\r
33243                 errorTileUrl: '',\r
33244 \r
33245                 // @option zoomOffset: Number = 0\r
33246                 // The zoom number used in tile URLs will be offset with this value.\r
33247                 zoomOffset: 0,\r
33248 \r
33249                 // @option tms: Boolean = false\r
33250                 // If `true`, inverses Y axis numbering for tiles (turn this on for [TMS](https://en.wikipedia.org/wiki/Tile_Map_Service) services).\r
33251                 tms: false,\r
33252 \r
33253                 // @option zoomReverse: Boolean = false\r
33254                 // If set to true, the zoom number used in tile URLs will be reversed (`maxZoom - zoom` instead of `zoom`)\r
33255                 zoomReverse: false,\r
33256 \r
33257                 // @option detectRetina: Boolean = false\r
33258                 // If `true` and user is on a retina display, it will request four tiles of half the specified size and a bigger zoom level in place of one to utilize the high resolution.\r
33259                 detectRetina: false,\r
33260 \r
33261                 // @option crossOrigin: Boolean|String = false\r
33262                 // Whether the crossOrigin attribute will be added to the tiles.\r
33263                 // If a String is provided, all tiles will have their crossOrigin attribute set to the String provided. This is needed if you want to access tile pixel data.\r
33264                 // Refer to [CORS Settings](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) for valid String values.\r
33265                 crossOrigin: false\r
33266         },\r
33267 \r
33268         initialize: function (url, options) {\r
33269 \r
33270                 this._url = url;\r
33271 \r
33272                 options = setOptions(this, options);\r
33273 \r
33274                 // detecting retina displays, adjusting tileSize and zoom levels\r
33275                 if (options.detectRetina && retina && options.maxZoom > 0) {\r
33276 \r
33277                         options.tileSize = Math.floor(options.tileSize / 2);\r
33278 \r
33279                         if (!options.zoomReverse) {\r
33280                                 options.zoomOffset++;\r
33281                                 options.maxZoom--;\r
33282                         } else {\r
33283                                 options.zoomOffset--;\r
33284                                 options.minZoom++;\r
33285                         }\r
33286 \r
33287                         options.minZoom = Math.max(0, options.minZoom);\r
33288                 }\r
33289 \r
33290                 if (typeof options.subdomains === 'string') {\r
33291                         options.subdomains = options.subdomains.split('');\r
33292                 }\r
33293 \r
33294                 // for https://github.com/Leaflet/Leaflet/issues/137\r
33295                 if (!android) {\r
33296                         this.on('tileunload', this._onTileRemove);\r
33297                 }\r
33298         },\r
33299 \r
33300         // @method setUrl(url: String, noRedraw?: Boolean): this\r
33301         // Updates the layer's URL template and redraws it (unless `noRedraw` is set to `true`).\r
33302         // If the URL does not change, the layer will not be redrawn unless\r
33303         // the noRedraw parameter is set to false.\r
33304         setUrl: function (url, noRedraw) {\r
33305                 if (this._url === url && noRedraw === undefined) {\r
33306                         noRedraw = true;\r
33307                 }\r
33308 \r
33309                 this._url = url;\r
33310 \r
33311                 if (!noRedraw) {\r
33312                         this.redraw();\r
33313                 }\r
33314                 return this;\r
33315         },\r
33316 \r
33317         // @method createTile(coords: Object, done?: Function): HTMLElement\r
33318         // Called only internally, overrides GridLayer's [`createTile()`](#gridlayer-createtile)\r
33319         // to return an `<img>` HTML element with the appropriate image URL given `coords`. The `done`\r
33320         // callback is called when the tile has been loaded.\r
33321         createTile: function (coords, done) {\r
33322                 var tile = document.createElement('img');\r
33323 \r
33324                 on(tile, 'load', bind(this._tileOnLoad, this, done, tile));\r
33325                 on(tile, 'error', bind(this._tileOnError, this, done, tile));\r
33326 \r
33327                 if (this.options.crossOrigin || this.options.crossOrigin === '') {\r
33328                         tile.crossOrigin = this.options.crossOrigin === true ? '' : this.options.crossOrigin;\r
33329                 }\r
33330 \r
33331                 /*\r
33332                  Alt tag is set to empty string to keep screen readers from reading URL and for compliance reasons\r
33333                  http://www.w3.org/TR/WCAG20-TECHS/H67\r
33334                 */\r
33335                 tile.alt = '';\r
33336 \r
33337                 /*\r
33338                  Set role="presentation" to force screen readers to ignore this\r
33339                  https://www.w3.org/TR/wai-aria/roles#textalternativecomputation\r
33340                 */\r
33341                 tile.setAttribute('role', 'presentation');\r
33342 \r
33343                 tile.src = this.getTileUrl(coords);\r
33344 \r
33345                 return tile;\r
33346         },\r
33347 \r
33348         // @section Extension methods\r
33349         // @uninheritable\r
33350         // Layers extending `TileLayer` might reimplement the following method.\r
33351         // @method getTileUrl(coords: Object): String\r
33352         // Called only internally, returns the URL for a tile given its coordinates.\r
33353         // Classes extending `TileLayer` can override this function to provide custom tile URL naming schemes.\r
33354         getTileUrl: function (coords) {\r
33355                 var data = {\r
33356                         r: retina ? '@2x' : '',\r
33357                         s: this._getSubdomain(coords),\r
33358                         x: coords.x,\r
33359                         y: coords.y,\r
33360                         z: this._getZoomForUrl()\r
33361                 };\r
33362                 if (this._map && !this._map.options.crs.infinite) {\r
33363                         var invertedY = this._globalTileRange.max.y - coords.y;\r
33364                         if (this.options.tms) {\r
33365                                 data['y'] = invertedY;\r
33366                         }\r
33367                         data['-y'] = invertedY;\r
33368                 }\r
33369 \r
33370                 return template(this._url, extend(data, this.options));\r
33371         },\r
33372 \r
33373         _tileOnLoad: function (done, tile) {\r
33374                 // For https://github.com/Leaflet/Leaflet/issues/3332\r
33375                 if (ielt9) {\r
33376                         setTimeout(bind(done, this, null, tile), 0);\r
33377                 } else {\r
33378                         done(null, tile);\r
33379                 }\r
33380         },\r
33381 \r
33382         _tileOnError: function (done, tile, e) {\r
33383                 var errorUrl = this.options.errorTileUrl;\r
33384                 if (errorUrl && tile.getAttribute('src') !== errorUrl) {\r
33385                         tile.src = errorUrl;\r
33386                 }\r
33387                 done(e, tile);\r
33388         },\r
33389 \r
33390         _onTileRemove: function (e) {\r
33391                 e.tile.onload = null;\r
33392         },\r
33393 \r
33394         _getZoomForUrl: function () {\r
33395                 var zoom = this._tileZoom,\r
33396                 maxZoom = this.options.maxZoom,\r
33397                 zoomReverse = this.options.zoomReverse,\r
33398                 zoomOffset = this.options.zoomOffset;\r
33399 \r
33400                 if (zoomReverse) {\r
33401                         zoom = maxZoom - zoom;\r
33402                 }\r
33403 \r
33404                 return zoom + zoomOffset;\r
33405         },\r
33406 \r
33407         _getSubdomain: function (tilePoint) {\r
33408                 var index = Math.abs(tilePoint.x + tilePoint.y) % this.options.subdomains.length;\r
33409                 return this.options.subdomains[index];\r
33410         },\r
33411 \r
33412         // stops loading all tiles in the background layer\r
33413         _abortLoading: function () {\r
33414                 var i, tile;\r
33415                 for (i in this._tiles) {\r
33416                         if (this._tiles[i].coords.z !== this._tileZoom) {\r
33417                                 tile = this._tiles[i].el;\r
33418 \r
33419                                 tile.onload = falseFn;\r
33420                                 tile.onerror = falseFn;\r
33421 \r
33422                                 if (!tile.complete) {\r
33423                                         tile.src = emptyImageUrl;\r
33424                                         remove(tile);\r
33425                                         delete this._tiles[i];\r
33426                                 }\r
33427                         }\r
33428                 }\r
33429         },\r
33430 \r
33431         _removeTile: function (key) {\r
33432                 var tile = this._tiles[key];\r
33433                 if (!tile) { return; }\r
33434 \r
33435                 // Cancels any pending http requests associated with the tile\r
33436                 // unless we're on Android's stock browser,\r
33437                 // see https://github.com/Leaflet/Leaflet/issues/137\r
33438                 if (!androidStock) {\r
33439                         tile.el.setAttribute('src', emptyImageUrl);\r
33440                 }\r
33441 \r
33442                 return GridLayer.prototype._removeTile.call(this, key);\r
33443         },\r
33444 \r
33445         _tileReady: function (coords, err, tile) {\r
33446                 if (!this._map || (tile && tile.getAttribute('src') === emptyImageUrl)) {\r
33447                         return;\r
33448                 }\r
33449 \r
33450                 return GridLayer.prototype._tileReady.call(this, coords, err, tile);\r
33451         }\r
33452       });\r
33453 \r
33454 \r
33455       // @factory L.tilelayer(urlTemplate: String, options?: TileLayer options)\r
33456       // Instantiates a tile layer object given a `URL template` and optionally an options object.\r
33457 \r
33458       function tileLayer(url, options) {\r
33459         return new TileLayer(url, options);\r
33460       }
33461
33462       /*\r
33463        * @class TileLayer.WMS\r
33464        * @inherits TileLayer\r
33465        * @aka L.TileLayer.WMS\r
33466        * Used to display [WMS](https://en.wikipedia.org/wiki/Web_Map_Service) services as tile layers on the map. Extends `TileLayer`.\r
33467        *\r
33468        * @example\r
33469        *\r
33470        * ```js\r
33471        * var nexrad = L.tileLayer.wms("http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi", {\r
33472        *        layers: 'nexrad-n0r-900913',\r
33473        *        format: 'image/png',\r
33474        *        transparent: true,\r
33475        *        attribution: "Weather data Â© 2012 IEM Nexrad"\r
33476        * });\r
33477        * ```\r
33478        */\r
33479 \r
33480       var TileLayerWMS = TileLayer.extend({\r
33481 \r
33482         // @section\r
33483         // @aka TileLayer.WMS options\r
33484         // If any custom options not documented here are used, they will be sent to the\r
33485         // WMS server as extra parameters in each request URL. This can be useful for\r
33486         // [non-standard vendor WMS parameters](http://docs.geoserver.org/stable/en/user/services/wms/vendor.html).\r
33487         defaultWmsParams: {\r
33488                 service: 'WMS',\r
33489                 request: 'GetMap',\r
33490 \r
33491                 // @option layers: String = ''\r
33492                 // **(required)** Comma-separated list of WMS layers to show.\r
33493                 layers: '',\r
33494 \r
33495                 // @option styles: String = ''\r
33496                 // Comma-separated list of WMS styles.\r
33497                 styles: '',\r
33498 \r
33499                 // @option format: String = 'image/jpeg'\r
33500                 // WMS image format (use `'image/png'` for layers with transparency).\r
33501                 format: 'image/jpeg',\r
33502 \r
33503                 // @option transparent: Boolean = false\r
33504                 // If `true`, the WMS service will return images with transparency.\r
33505                 transparent: false,\r
33506 \r
33507                 // @option version: String = '1.1.1'\r
33508                 // Version of the WMS service to use\r
33509                 version: '1.1.1'\r
33510         },\r
33511 \r
33512         options: {\r
33513                 // @option crs: CRS = null\r
33514                 // Coordinate Reference System to use for the WMS requests, defaults to\r
33515                 // map CRS. Don't change this if you're not sure what it means.\r
33516                 crs: null,\r
33517 \r
33518                 // @option uppercase: Boolean = false\r
33519                 // If `true`, WMS request parameter keys will be uppercase.\r
33520                 uppercase: false\r
33521         },\r
33522 \r
33523         initialize: function (url, options) {\r
33524 \r
33525                 this._url = url;\r
33526 \r
33527                 var wmsParams = extend({}, this.defaultWmsParams);\r
33528 \r
33529                 // all keys that are not TileLayer options go to WMS params\r
33530                 for (var i in options) {\r
33531                         if (!(i in this.options)) {\r
33532                                 wmsParams[i] = options[i];\r
33533                         }\r
33534                 }\r
33535 \r
33536                 options = setOptions(this, options);\r
33537 \r
33538                 var realRetina = options.detectRetina && retina ? 2 : 1;\r
33539                 var tileSize = this.getTileSize();\r
33540                 wmsParams.width = tileSize.x * realRetina;\r
33541                 wmsParams.height = tileSize.y * realRetina;\r
33542 \r
33543                 this.wmsParams = wmsParams;\r
33544         },\r
33545 \r
33546         onAdd: function (map) {\r
33547 \r
33548                 this._crs = this.options.crs || map.options.crs;\r
33549                 this._wmsVersion = parseFloat(this.wmsParams.version);\r
33550 \r
33551                 var projectionKey = this._wmsVersion >= 1.3 ? 'crs' : 'srs';\r
33552                 this.wmsParams[projectionKey] = this._crs.code;\r
33553 \r
33554                 TileLayer.prototype.onAdd.call(this, map);\r
33555         },\r
33556 \r
33557         getTileUrl: function (coords) {\r
33558 \r
33559                 var tileBounds = this._tileCoordsToNwSe(coords),\r
33560                     crs = this._crs,\r
33561                     bounds = toBounds(crs.project(tileBounds[0]), crs.project(tileBounds[1])),\r
33562                     min = bounds.min,\r
33563                     max = bounds.max,\r
33564                     bbox = (this._wmsVersion >= 1.3 && this._crs === EPSG4326 ?\r
33565                     [min.y, min.x, max.y, max.x] :\r
33566                     [min.x, min.y, max.x, max.y]).join(','),\r
33567                     url = TileLayer.prototype.getTileUrl.call(this, coords);\r
33568                 return url +\r
33569                         getParamString(this.wmsParams, url, this.options.uppercase) +\r
33570                         (this.options.uppercase ? '&BBOX=' : '&bbox=') + bbox;\r
33571         },\r
33572 \r
33573         // @method setParams(params: Object, noRedraw?: Boolean): this\r
33574         // Merges an object with the new parameters and re-requests tiles on the current screen (unless `noRedraw` was set to true).\r
33575         setParams: function (params, noRedraw) {\r
33576 \r
33577                 extend(this.wmsParams, params);\r
33578 \r
33579                 if (!noRedraw) {\r
33580                         this.redraw();\r
33581                 }\r
33582 \r
33583                 return this;\r
33584         }\r
33585       });\r
33586 \r
33587 \r
33588       // @factory L.tileLayer.wms(baseUrl: String, options: TileLayer.WMS options)\r
33589       // Instantiates a WMS tile layer object given a base URL of the WMS service and a WMS parameters/options object.\r
33590       function tileLayerWMS(url, options) {\r
33591         return new TileLayerWMS(url, options);\r
33592       }
33593
33594       TileLayer.WMS = TileLayerWMS;
33595       tileLayer.wms = tileLayerWMS;
33596
33597       /*
33598        * @class Renderer
33599        * @inherits Layer
33600        * @aka L.Renderer
33601        *
33602        * Base class for vector renderer implementations (`SVG`, `Canvas`). Handles the
33603        * DOM container of the renderer, its bounds, and its zoom animation.
33604        *
33605        * A `Renderer` works as an implicit layer group for all `Path`s - the renderer
33606        * itself can be added or removed to the map. All paths use a renderer, which can
33607        * be implicit (the map will decide the type of renderer and use it automatically)
33608        * or explicit (using the [`renderer`](#path-renderer) option of the path).
33609        *
33610        * Do not use this class directly, use `SVG` and `Canvas` instead.
33611        *
33612        * @event update: Event
33613        * Fired when the renderer updates its bounds, center and zoom, for example when
33614        * its map has moved
33615        */
33616
33617       var Renderer = Layer.extend({
33618
33619         // @section
33620         // @aka Renderer options
33621         options: {
33622                 // @option padding: Number = 0.1
33623                 // How much to extend the clip area around the map view (relative to its size)
33624                 // e.g. 0.1 would be 10% of map view in each direction
33625                 padding: 0.1,
33626
33627                 // @option tolerance: Number = 0
33628                 // How much to extend click tolerance round a path/object on the map
33629                 tolerance : 0
33630         },
33631
33632         initialize: function (options) {
33633                 setOptions(this, options);
33634                 stamp(this);
33635                 this._layers = this._layers || {};
33636         },
33637
33638         onAdd: function () {
33639                 if (!this._container) {
33640                         this._initContainer(); // defined by renderer implementations
33641
33642                         if (this._zoomAnimated) {
33643                                 addClass(this._container, 'leaflet-zoom-animated');
33644                         }
33645                 }
33646
33647                 this.getPane().appendChild(this._container);
33648                 this._update();
33649                 this.on('update', this._updatePaths, this);
33650         },
33651
33652         onRemove: function () {
33653                 this.off('update', this._updatePaths, this);
33654                 this._destroyContainer();
33655         },
33656
33657         getEvents: function () {
33658                 var events = {
33659                         viewreset: this._reset,
33660                         zoom: this._onZoom,
33661                         moveend: this._update,
33662                         zoomend: this._onZoomEnd
33663                 };
33664                 if (this._zoomAnimated) {
33665                         events.zoomanim = this._onAnimZoom;
33666                 }
33667                 return events;
33668         },
33669
33670         _onAnimZoom: function (ev) {
33671                 this._updateTransform(ev.center, ev.zoom);
33672         },
33673
33674         _onZoom: function () {
33675                 this._updateTransform(this._map.getCenter(), this._map.getZoom());
33676         },
33677
33678         _updateTransform: function (center, zoom) {
33679                 var scale = this._map.getZoomScale(zoom, this._zoom),
33680                     position = getPosition(this._container),
33681                     viewHalf = this._map.getSize().multiplyBy(0.5 + this.options.padding),
33682                     currentCenterPoint = this._map.project(this._center, zoom),
33683                     destCenterPoint = this._map.project(center, zoom),
33684                     centerOffset = destCenterPoint.subtract(currentCenterPoint),
33685
33686                     topLeftOffset = viewHalf.multiplyBy(-scale).add(position).add(viewHalf).subtract(centerOffset);
33687
33688                 if (any3d) {
33689                         setTransform(this._container, topLeftOffset, scale);
33690                 } else {
33691                         setPosition(this._container, topLeftOffset);
33692                 }
33693         },
33694
33695         _reset: function () {
33696                 this._update();
33697                 this._updateTransform(this._center, this._zoom);
33698
33699                 for (var id in this._layers) {
33700                         this._layers[id]._reset();
33701                 }
33702         },
33703
33704         _onZoomEnd: function () {
33705                 for (var id in this._layers) {
33706                         this._layers[id]._project();
33707                 }
33708         },
33709
33710         _updatePaths: function () {
33711                 for (var id in this._layers) {
33712                         this._layers[id]._update();
33713                 }
33714         },
33715
33716         _update: function () {
33717                 // Update pixel bounds of renderer container (for positioning/sizing/clipping later)
33718                 // Subclasses are responsible of firing the 'update' event.
33719                 var p = this.options.padding,
33720                     size = this._map.getSize(),
33721                     min = this._map.containerPointToLayerPoint(size.multiplyBy(-p)).round();
33722
33723                 this._bounds = new Bounds(min, min.add(size.multiplyBy(1 + p * 2)).round());
33724
33725                 this._center = this._map.getCenter();
33726                 this._zoom = this._map.getZoom();
33727         }
33728       });
33729
33730       /*
33731        * @class Canvas
33732        * @inherits Renderer
33733        * @aka L.Canvas
33734        *
33735        * Allows vector layers to be displayed with [`<canvas>`](https://developer.mozilla.org/docs/Web/API/Canvas_API).
33736        * Inherits `Renderer`.
33737        *
33738        * Due to [technical limitations](http://caniuse.com/#search=canvas), Canvas is not
33739        * available in all web browsers, notably IE8, and overlapping geometries might
33740        * not display properly in some edge cases.
33741        *
33742        * @example
33743        *
33744        * Use Canvas by default for all paths in the map:
33745        *
33746        * ```js
33747        * var map = L.map('map', {
33748        *        renderer: L.canvas()
33749        * });
33750        * ```
33751        *
33752        * Use a Canvas renderer with extra padding for specific vector geometries:
33753        *
33754        * ```js
33755        * var map = L.map('map');
33756        * var myRenderer = L.canvas({ padding: 0.5 });
33757        * var line = L.polyline( coordinates, { renderer: myRenderer } );
33758        * var circle = L.circle( center, { renderer: myRenderer } );
33759        * ```
33760        */
33761
33762       var Canvas = Renderer.extend({
33763         getEvents: function () {
33764                 var events = Renderer.prototype.getEvents.call(this);
33765                 events.viewprereset = this._onViewPreReset;
33766                 return events;
33767         },
33768
33769         _onViewPreReset: function () {
33770                 // Set a flag so that a viewprereset+moveend+viewreset only updates&redraws once
33771                 this._postponeUpdatePaths = true;
33772         },
33773
33774         onAdd: function () {
33775                 Renderer.prototype.onAdd.call(this);
33776
33777                 // Redraw vectors since canvas is cleared upon removal,
33778                 // in case of removing the renderer itself from the map.
33779                 this._draw();
33780         },
33781
33782         _initContainer: function () {
33783                 var container = this._container = document.createElement('canvas');
33784
33785                 on(container, 'mousemove', this._onMouseMove, this);
33786                 on(container, 'click dblclick mousedown mouseup contextmenu', this._onClick, this);
33787                 on(container, 'mouseout', this._handleMouseOut, this);
33788
33789                 this._ctx = container.getContext('2d');
33790         },
33791
33792         _destroyContainer: function () {
33793                 cancelAnimFrame(this._redrawRequest);
33794                 delete this._ctx;
33795                 remove(this._container);
33796                 off(this._container);
33797                 delete this._container;
33798         },
33799
33800         _updatePaths: function () {
33801                 if (this._postponeUpdatePaths) { return; }
33802
33803                 var layer;
33804                 this._redrawBounds = null;
33805                 for (var id in this._layers) {
33806                         layer = this._layers[id];
33807                         layer._update();
33808                 }
33809                 this._redraw();
33810         },
33811
33812         _update: function () {
33813                 if (this._map._animatingZoom && this._bounds) { return; }
33814
33815                 Renderer.prototype._update.call(this);
33816
33817                 var b = this._bounds,
33818                     container = this._container,
33819                     size = b.getSize(),
33820                     m = retina ? 2 : 1;
33821
33822                 setPosition(container, b.min);
33823
33824                 // set canvas size (also clearing it); use double size on retina
33825                 container.width = m * size.x;
33826                 container.height = m * size.y;
33827                 container.style.width = size.x + 'px';
33828                 container.style.height = size.y + 'px';
33829
33830                 if (retina) {
33831                         this._ctx.scale(2, 2);
33832                 }
33833
33834                 // translate so we use the same path coordinates after canvas element moves
33835                 this._ctx.translate(-b.min.x, -b.min.y);
33836
33837                 // Tell paths to redraw themselves
33838                 this.fire('update');
33839         },
33840
33841         _reset: function () {
33842                 Renderer.prototype._reset.call(this);
33843
33844                 if (this._postponeUpdatePaths) {
33845                         this._postponeUpdatePaths = false;
33846                         this._updatePaths();
33847                 }
33848         },
33849
33850         _initPath: function (layer) {
33851                 this._updateDashArray(layer);
33852                 this._layers[stamp(layer)] = layer;
33853
33854                 var order = layer._order = {
33855                         layer: layer,
33856                         prev: this._drawLast,
33857                         next: null
33858                 };
33859                 if (this._drawLast) { this._drawLast.next = order; }
33860                 this._drawLast = order;
33861                 this._drawFirst = this._drawFirst || this._drawLast;
33862         },
33863
33864         _addPath: function (layer) {
33865                 this._requestRedraw(layer);
33866         },
33867
33868         _removePath: function (layer) {
33869                 var order = layer._order;
33870                 var next = order.next;
33871                 var prev = order.prev;
33872
33873                 if (next) {
33874                         next.prev = prev;
33875                 } else {
33876                         this._drawLast = prev;
33877                 }
33878                 if (prev) {
33879                         prev.next = next;
33880                 } else {
33881                         this._drawFirst = next;
33882                 }
33883
33884                 delete layer._order;
33885
33886                 delete this._layers[stamp(layer)];
33887
33888                 this._requestRedraw(layer);
33889         },
33890
33891         _updatePath: function (layer) {
33892                 // Redraw the union of the layer's old pixel
33893                 // bounds and the new pixel bounds.
33894                 this._extendRedrawBounds(layer);
33895                 layer._project();
33896                 layer._update();
33897                 // The redraw will extend the redraw bounds
33898                 // with the new pixel bounds.
33899                 this._requestRedraw(layer);
33900         },
33901
33902         _updateStyle: function (layer) {
33903                 this._updateDashArray(layer);
33904                 this._requestRedraw(layer);
33905         },
33906
33907         _updateDashArray: function (layer) {
33908                 if (typeof layer.options.dashArray === 'string') {
33909                         var parts = layer.options.dashArray.split(/[, ]+/),
33910                             dashArray = [],
33911                             dashValue,
33912                             i;
33913                         for (i = 0; i < parts.length; i++) {
33914                                 dashValue = Number(parts[i]);
33915                                 // Ignore dash array containing invalid lengths
33916                                 if (isNaN(dashValue)) { return; }
33917                                 dashArray.push(dashValue);
33918                         }
33919                         layer.options._dashArray = dashArray;
33920                 } else {
33921                         layer.options._dashArray = layer.options.dashArray;
33922                 }
33923         },
33924
33925         _requestRedraw: function (layer) {
33926                 if (!this._map) { return; }
33927
33928                 this._extendRedrawBounds(layer);
33929                 this._redrawRequest = this._redrawRequest || requestAnimFrame(this._redraw, this);
33930         },
33931
33932         _extendRedrawBounds: function (layer) {
33933                 if (layer._pxBounds) {
33934                         var padding = (layer.options.weight || 0) + 1;
33935                         this._redrawBounds = this._redrawBounds || new Bounds();
33936                         this._redrawBounds.extend(layer._pxBounds.min.subtract([padding, padding]));
33937                         this._redrawBounds.extend(layer._pxBounds.max.add([padding, padding]));
33938                 }
33939         },
33940
33941         _redraw: function () {
33942                 this._redrawRequest = null;
33943
33944                 if (this._redrawBounds) {
33945                         this._redrawBounds.min._floor();
33946                         this._redrawBounds.max._ceil();
33947                 }
33948
33949                 this._clear(); // clear layers in redraw bounds
33950                 this._draw(); // draw layers
33951
33952                 this._redrawBounds = null;
33953         },
33954
33955         _clear: function () {
33956                 var bounds = this._redrawBounds;
33957                 if (bounds) {
33958                         var size = bounds.getSize();
33959                         this._ctx.clearRect(bounds.min.x, bounds.min.y, size.x, size.y);
33960                 } else {
33961                         this._ctx.save();
33962                         this._ctx.setTransform(1, 0, 0, 1, 0, 0);
33963                         this._ctx.clearRect(0, 0, this._container.width, this._container.height);
33964                         this._ctx.restore();
33965                 }
33966         },
33967
33968         _draw: function () {
33969                 var layer, bounds = this._redrawBounds;
33970                 this._ctx.save();
33971                 if (bounds) {
33972                         var size = bounds.getSize();
33973                         this._ctx.beginPath();
33974                         this._ctx.rect(bounds.min.x, bounds.min.y, size.x, size.y);
33975                         this._ctx.clip();
33976                 }
33977
33978                 this._drawing = true;
33979
33980                 for (var order = this._drawFirst; order; order = order.next) {
33981                         layer = order.layer;
33982                         if (!bounds || (layer._pxBounds && layer._pxBounds.intersects(bounds))) {
33983                                 layer._updatePath();
33984                         }
33985                 }
33986
33987                 this._drawing = false;
33988
33989                 this._ctx.restore();  // Restore state before clipping.
33990         },
33991
33992         _updatePoly: function (layer, closed) {
33993                 if (!this._drawing) { return; }
33994
33995                 var i, j, len2, p,
33996                     parts = layer._parts,
33997                     len = parts.length,
33998                     ctx = this._ctx;
33999
34000                 if (!len) { return; }
34001
34002                 ctx.beginPath();
34003
34004                 for (i = 0; i < len; i++) {
34005                         for (j = 0, len2 = parts[i].length; j < len2; j++) {
34006                                 p = parts[i][j];
34007                                 ctx[j ? 'lineTo' : 'moveTo'](p.x, p.y);
34008                         }
34009                         if (closed) {
34010                                 ctx.closePath();
34011                         }
34012                 }
34013
34014                 this._fillStroke(ctx, layer);
34015
34016                 // TODO optimization: 1 fill/stroke for all features with equal style instead of 1 for each feature
34017         },
34018
34019         _updateCircle: function (layer) {
34020
34021                 if (!this._drawing || layer._empty()) { return; }
34022
34023                 var p = layer._point,
34024                     ctx = this._ctx,
34025                     r = Math.max(Math.round(layer._radius), 1),
34026                     s = (Math.max(Math.round(layer._radiusY), 1) || r) / r;
34027
34028                 if (s !== 1) {
34029                         ctx.save();
34030                         ctx.scale(1, s);
34031                 }
34032
34033                 ctx.beginPath();
34034                 ctx.arc(p.x, p.y / s, r, 0, Math.PI * 2, false);
34035
34036                 if (s !== 1) {
34037                         ctx.restore();
34038                 }
34039
34040                 this._fillStroke(ctx, layer);
34041         },
34042
34043         _fillStroke: function (ctx, layer) {
34044                 var options = layer.options;
34045
34046                 if (options.fill) {
34047                         ctx.globalAlpha = options.fillOpacity;
34048                         ctx.fillStyle = options.fillColor || options.color;
34049                         ctx.fill(options.fillRule || 'evenodd');
34050                 }
34051
34052                 if (options.stroke && options.weight !== 0) {
34053                         if (ctx.setLineDash) {
34054                                 ctx.setLineDash(layer.options && layer.options._dashArray || []);
34055                         }
34056                         ctx.globalAlpha = options.opacity;
34057                         ctx.lineWidth = options.weight;
34058                         ctx.strokeStyle = options.color;
34059                         ctx.lineCap = options.lineCap;
34060                         ctx.lineJoin = options.lineJoin;
34061                         ctx.stroke();
34062                 }
34063         },
34064
34065         // Canvas obviously doesn't have mouse events for individual drawn objects,
34066         // so we emulate that by calculating what's under the mouse on mousemove/click manually
34067
34068         _onClick: function (e) {
34069                 var point = this._map.mouseEventToLayerPoint(e), layer, clickedLayer;
34070
34071                 for (var order = this._drawFirst; order; order = order.next) {
34072                         layer = order.layer;
34073                         if (layer.options.interactive && layer._containsPoint(point)) {
34074                                 if (!(e.type === 'click' || e.type !== 'preclick') || !this._map._draggableMoved(layer)) {
34075                                         clickedLayer = layer;
34076                                 }
34077                         }
34078                 }
34079                 if (clickedLayer)  {
34080                         fakeStop(e);
34081                         this._fireEvent([clickedLayer], e);
34082                 }
34083         },
34084
34085         _onMouseMove: function (e) {
34086                 if (!this._map || this._map.dragging.moving() || this._map._animatingZoom) { return; }
34087
34088                 var point = this._map.mouseEventToLayerPoint(e);
34089                 this._handleMouseHover(e, point);
34090         },
34091
34092
34093         _handleMouseOut: function (e) {
34094                 var layer = this._hoveredLayer;
34095                 if (layer) {
34096                         // if we're leaving the layer, fire mouseout
34097                         removeClass(this._container, 'leaflet-interactive');
34098                         this._fireEvent([layer], e, 'mouseout');
34099                         this._hoveredLayer = null;
34100                         this._mouseHoverThrottled = false;
34101                 }
34102         },
34103
34104         _handleMouseHover: function (e, point) {
34105                 if (this._mouseHoverThrottled) {
34106                         return;
34107                 }
34108
34109                 var layer, candidateHoveredLayer;
34110
34111                 for (var order = this._drawFirst; order; order = order.next) {
34112                         layer = order.layer;
34113                         if (layer.options.interactive && layer._containsPoint(point)) {
34114                                 candidateHoveredLayer = layer;
34115                         }
34116                 }
34117
34118                 if (candidateHoveredLayer !== this._hoveredLayer) {
34119                         this._handleMouseOut(e);
34120
34121                         if (candidateHoveredLayer) {
34122                                 addClass(this._container, 'leaflet-interactive'); // change cursor
34123                                 this._fireEvent([candidateHoveredLayer], e, 'mouseover');
34124                                 this._hoveredLayer = candidateHoveredLayer;
34125                         }
34126                 }
34127
34128                 if (this._hoveredLayer) {
34129                         this._fireEvent([this._hoveredLayer], e);
34130                 }
34131
34132                 this._mouseHoverThrottled = true;
34133                 setTimeout(bind(function () {
34134                         this._mouseHoverThrottled = false;
34135                 }, this), 32);
34136         },
34137
34138         _fireEvent: function (layers, e, type) {
34139                 this._map._fireDOMEvent(e, type || e.type, layers);
34140         },
34141
34142         _bringToFront: function (layer) {
34143                 var order = layer._order;
34144
34145                 if (!order) { return; }
34146
34147                 var next = order.next;
34148                 var prev = order.prev;
34149
34150                 if (next) {
34151                         next.prev = prev;
34152                 } else {
34153                         // Already last
34154                         return;
34155                 }
34156                 if (prev) {
34157                         prev.next = next;
34158                 } else if (next) {
34159                         // Update first entry unless this is the
34160                         // single entry
34161                         this._drawFirst = next;
34162                 }
34163
34164                 order.prev = this._drawLast;
34165                 this._drawLast.next = order;
34166
34167                 order.next = null;
34168                 this._drawLast = order;
34169
34170                 this._requestRedraw(layer);
34171         },
34172
34173         _bringToBack: function (layer) {
34174                 var order = layer._order;
34175
34176                 if (!order) { return; }
34177
34178                 var next = order.next;
34179                 var prev = order.prev;
34180
34181                 if (prev) {
34182                         prev.next = next;
34183                 } else {
34184                         // Already first
34185                         return;
34186                 }
34187                 if (next) {
34188                         next.prev = prev;
34189                 } else if (prev) {
34190                         // Update last entry unless this is the
34191                         // single entry
34192                         this._drawLast = prev;
34193                 }
34194
34195                 order.prev = null;
34196
34197                 order.next = this._drawFirst;
34198                 this._drawFirst.prev = order;
34199                 this._drawFirst = order;
34200
34201                 this._requestRedraw(layer);
34202         }
34203       });
34204
34205       // @factory L.canvas(options?: Renderer options)
34206       // Creates a Canvas renderer with the given options.
34207       function canvas$1(options) {
34208         return canvas ? new Canvas(options) : null;
34209       }
34210
34211       /*
34212        * Thanks to Dmitry Baranovsky and his Raphael library for inspiration!
34213        */
34214
34215
34216       var vmlCreate = (function () {
34217         try {
34218                 document.namespaces.add('lvml', 'urn:schemas-microsoft-com:vml');
34219                 return function (name) {
34220                         return document.createElement('<lvml:' + name + ' class="lvml">');
34221                 };
34222         } catch (e) {
34223                 return function (name) {
34224                         return document.createElement('<' + name + ' xmlns="urn:schemas-microsoft.com:vml" class="lvml">');
34225                 };
34226         }
34227       })();
34228
34229
34230       /*
34231        * @class SVG
34232        *
34233        *
34234        * VML was deprecated in 2012, which means VML functionality exists only for backwards compatibility
34235        * with old versions of Internet Explorer.
34236        */
34237
34238       // mixin to redefine some SVG methods to handle VML syntax which is similar but with some differences
34239       var vmlMixin = {
34240
34241         _initContainer: function () {
34242                 this._container = create$1('div', 'leaflet-vml-container');
34243         },
34244
34245         _update: function () {
34246                 if (this._map._animatingZoom) { return; }
34247                 Renderer.prototype._update.call(this);
34248                 this.fire('update');
34249         },
34250
34251         _initPath: function (layer) {
34252                 var container = layer._container = vmlCreate('shape');
34253
34254                 addClass(container, 'leaflet-vml-shape ' + (this.options.className || ''));
34255
34256                 container.coordsize = '1 1';
34257
34258                 layer._path = vmlCreate('path');
34259                 container.appendChild(layer._path);
34260
34261                 this._updateStyle(layer);
34262                 this._layers[stamp(layer)] = layer;
34263         },
34264
34265         _addPath: function (layer) {
34266                 var container = layer._container;
34267                 this._container.appendChild(container);
34268
34269                 if (layer.options.interactive) {
34270                         layer.addInteractiveTarget(container);
34271                 }
34272         },
34273
34274         _removePath: function (layer) {
34275                 var container = layer._container;
34276                 remove(container);
34277                 layer.removeInteractiveTarget(container);
34278                 delete this._layers[stamp(layer)];
34279         },
34280
34281         _updateStyle: function (layer) {
34282                 var stroke = layer._stroke,
34283                     fill = layer._fill,
34284                     options = layer.options,
34285                     container = layer._container;
34286
34287                 container.stroked = !!options.stroke;
34288                 container.filled = !!options.fill;
34289
34290                 if (options.stroke) {
34291                         if (!stroke) {
34292                                 stroke = layer._stroke = vmlCreate('stroke');
34293                         }
34294                         container.appendChild(stroke);
34295                         stroke.weight = options.weight + 'px';
34296                         stroke.color = options.color;
34297                         stroke.opacity = options.opacity;
34298
34299                         if (options.dashArray) {
34300                                 stroke.dashStyle = isArray(options.dashArray) ?
34301                                     options.dashArray.join(' ') :
34302                                     options.dashArray.replace(/( *, *)/g, ' ');
34303                         } else {
34304                                 stroke.dashStyle = '';
34305                         }
34306                         stroke.endcap = options.lineCap.replace('butt', 'flat');
34307                         stroke.joinstyle = options.lineJoin;
34308
34309                 } else if (stroke) {
34310                         container.removeChild(stroke);
34311                         layer._stroke = null;
34312                 }
34313
34314                 if (options.fill) {
34315                         if (!fill) {
34316                                 fill = layer._fill = vmlCreate('fill');
34317                         }
34318                         container.appendChild(fill);
34319                         fill.color = options.fillColor || options.color;
34320                         fill.opacity = options.fillOpacity;
34321
34322                 } else if (fill) {
34323                         container.removeChild(fill);
34324                         layer._fill = null;
34325                 }
34326         },
34327
34328         _updateCircle: function (layer) {
34329                 var p = layer._point.round(),
34330                     r = Math.round(layer._radius),
34331                     r2 = Math.round(layer._radiusY || r);
34332
34333                 this._setPath(layer, layer._empty() ? 'M0 0' :
34334                         'AL ' + p.x + ',' + p.y + ' ' + r + ',' + r2 + ' 0,' + (65535 * 360));
34335         },
34336
34337         _setPath: function (layer, path) {
34338                 layer._path.v = path;
34339         },
34340
34341         _bringToFront: function (layer) {
34342                 toFront(layer._container);
34343         },
34344
34345         _bringToBack: function (layer) {
34346                 toBack(layer._container);
34347         }
34348       };
34349
34350       var create$2 = vml ? vmlCreate : svgCreate;
34351
34352       /*
34353        * @class SVG
34354        * @inherits Renderer
34355        * @aka L.SVG
34356        *
34357        * Allows vector layers to be displayed with [SVG](https://developer.mozilla.org/docs/Web/SVG).
34358        * Inherits `Renderer`.
34359        *
34360        * Due to [technical limitations](http://caniuse.com/#search=svg), SVG is not
34361        * available in all web browsers, notably Android 2.x and 3.x.
34362        *
34363        * Although SVG is not available on IE7 and IE8, these browsers support
34364        * [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language)
34365        * (a now deprecated technology), and the SVG renderer will fall back to VML in
34366        * this case.
34367        *
34368        * @example
34369        *
34370        * Use SVG by default for all paths in the map:
34371        *
34372        * ```js
34373        * var map = L.map('map', {
34374        *        renderer: L.svg()
34375        * });
34376        * ```
34377        *
34378        * Use a SVG renderer with extra padding for specific vector geometries:
34379        *
34380        * ```js
34381        * var map = L.map('map');
34382        * var myRenderer = L.svg({ padding: 0.5 });
34383        * var line = L.polyline( coordinates, { renderer: myRenderer } );
34384        * var circle = L.circle( center, { renderer: myRenderer } );
34385        * ```
34386        */
34387
34388       var SVG = Renderer.extend({
34389
34390         getEvents: function () {
34391                 var events = Renderer.prototype.getEvents.call(this);
34392                 events.zoomstart = this._onZoomStart;
34393                 return events;
34394         },
34395
34396         _initContainer: function () {
34397                 this._container = create$2('svg');
34398
34399                 // makes it possible to click through svg root; we'll reset it back in individual paths
34400                 this._container.setAttribute('pointer-events', 'none');
34401
34402                 this._rootGroup = create$2('g');
34403                 this._container.appendChild(this._rootGroup);
34404         },
34405
34406         _destroyContainer: function () {
34407                 remove(this._container);
34408                 off(this._container);
34409                 delete this._container;
34410                 delete this._rootGroup;
34411                 delete this._svgSize;
34412         },
34413
34414         _onZoomStart: function () {
34415                 // Drag-then-pinch interactions might mess up the center and zoom.
34416                 // In this case, the easiest way to prevent this is re-do the renderer
34417                 //   bounds and padding when the zooming starts.
34418                 this._update();
34419         },
34420
34421         _update: function () {
34422                 if (this._map._animatingZoom && this._bounds) { return; }
34423
34424                 Renderer.prototype._update.call(this);
34425
34426                 var b = this._bounds,
34427                     size = b.getSize(),
34428                     container = this._container;
34429
34430                 // set size of svg-container if changed
34431                 if (!this._svgSize || !this._svgSize.equals(size)) {
34432                         this._svgSize = size;
34433                         container.setAttribute('width', size.x);
34434                         container.setAttribute('height', size.y);
34435                 }
34436
34437                 // movement: update container viewBox so that we don't have to change coordinates of individual layers
34438                 setPosition(container, b.min);
34439                 container.setAttribute('viewBox', [b.min.x, b.min.y, size.x, size.y].join(' '));
34440
34441                 this.fire('update');
34442         },
34443
34444         // methods below are called by vector layers implementations
34445
34446         _initPath: function (layer) {
34447                 var path = layer._path = create$2('path');
34448
34449                 // @namespace Path
34450                 // @option className: String = null
34451                 // Custom class name set on an element. Only for SVG renderer.
34452                 if (layer.options.className) {
34453                         addClass(path, layer.options.className);
34454                 }
34455
34456                 if (layer.options.interactive) {
34457                         addClass(path, 'leaflet-interactive');
34458                 }
34459
34460                 this._updateStyle(layer);
34461                 this._layers[stamp(layer)] = layer;
34462         },
34463
34464         _addPath: function (layer) {
34465                 if (!this._rootGroup) { this._initContainer(); }
34466                 this._rootGroup.appendChild(layer._path);
34467                 layer.addInteractiveTarget(layer._path);
34468         },
34469
34470         _removePath: function (layer) {
34471                 remove(layer._path);
34472                 layer.removeInteractiveTarget(layer._path);
34473                 delete this._layers[stamp(layer)];
34474         },
34475
34476         _updatePath: function (layer) {
34477                 layer._project();
34478                 layer._update();
34479         },
34480
34481         _updateStyle: function (layer) {
34482                 var path = layer._path,
34483                     options = layer.options;
34484
34485                 if (!path) { return; }
34486
34487                 if (options.stroke) {
34488                         path.setAttribute('stroke', options.color);
34489                         path.setAttribute('stroke-opacity', options.opacity);
34490                         path.setAttribute('stroke-width', options.weight);
34491                         path.setAttribute('stroke-linecap', options.lineCap);
34492                         path.setAttribute('stroke-linejoin', options.lineJoin);
34493
34494                         if (options.dashArray) {
34495                                 path.setAttribute('stroke-dasharray', options.dashArray);
34496                         } else {
34497                                 path.removeAttribute('stroke-dasharray');
34498                         }
34499
34500                         if (options.dashOffset) {
34501                                 path.setAttribute('stroke-dashoffset', options.dashOffset);
34502                         } else {
34503                                 path.removeAttribute('stroke-dashoffset');
34504                         }
34505                 } else {
34506                         path.setAttribute('stroke', 'none');
34507                 }
34508
34509                 if (options.fill) {
34510                         path.setAttribute('fill', options.fillColor || options.color);
34511                         path.setAttribute('fill-opacity', options.fillOpacity);
34512                         path.setAttribute('fill-rule', options.fillRule || 'evenodd');
34513                 } else {
34514                         path.setAttribute('fill', 'none');
34515                 }
34516         },
34517
34518         _updatePoly: function (layer, closed) {
34519                 this._setPath(layer, pointsToPath(layer._parts, closed));
34520         },
34521
34522         _updateCircle: function (layer) {
34523                 var p = layer._point,
34524                     r = Math.max(Math.round(layer._radius), 1),
34525                     r2 = Math.max(Math.round(layer._radiusY), 1) || r,
34526                     arc = 'a' + r + ',' + r2 + ' 0 1,0 ';
34527
34528                 // drawing a circle with two half-arcs
34529                 var d = layer._empty() ? 'M0 0' :
34530                         'M' + (p.x - r) + ',' + p.y +
34531                         arc + (r * 2) + ',0 ' +
34532                         arc + (-r * 2) + ',0 ';
34533
34534                 this._setPath(layer, d);
34535         },
34536
34537         _setPath: function (layer, path) {
34538                 layer._path.setAttribute('d', path);
34539         },
34540
34541         // SVG does not have the concept of zIndex so we resort to changing the DOM order of elements
34542         _bringToFront: function (layer) {
34543                 toFront(layer._path);
34544         },
34545
34546         _bringToBack: function (layer) {
34547                 toBack(layer._path);
34548         }
34549       });
34550
34551       if (vml) {
34552         SVG.include(vmlMixin);
34553       }
34554
34555       // @namespace SVG
34556       // @factory L.svg(options?: Renderer options)
34557       // Creates a SVG renderer with the given options.
34558       function svg$1(options) {
34559         return svg || vml ? new SVG(options) : null;
34560       }
34561
34562       Map.include({
34563         // @namespace Map; @method getRenderer(layer: Path): Renderer
34564         // Returns the instance of `Renderer` that should be used to render the given
34565         // `Path`. It will ensure that the `renderer` options of the map and paths
34566         // are respected, and that the renderers do exist on the map.
34567         getRenderer: function (layer) {
34568                 // @namespace Path; @option renderer: Renderer
34569                 // Use this specific instance of `Renderer` for this path. Takes
34570                 // precedence over the map's [default renderer](#map-renderer).
34571                 var renderer = layer.options.renderer || this._getPaneRenderer(layer.options.pane) || this.options.renderer || this._renderer;
34572
34573                 if (!renderer) {
34574                         renderer = this._renderer = this._createRenderer();
34575                 }
34576
34577                 if (!this.hasLayer(renderer)) {
34578                         this.addLayer(renderer);
34579                 }
34580                 return renderer;
34581         },
34582
34583         _getPaneRenderer: function (name) {
34584                 if (name === 'overlayPane' || name === undefined) {
34585                         return false;
34586                 }
34587
34588                 var renderer = this._paneRenderers[name];
34589                 if (renderer === undefined) {
34590                         renderer = this._createRenderer({pane: name});
34591                         this._paneRenderers[name] = renderer;
34592                 }
34593                 return renderer;
34594         },
34595
34596         _createRenderer: function (options) {
34597                 // @namespace Map; @option preferCanvas: Boolean = false
34598                 // Whether `Path`s should be rendered on a `Canvas` renderer.
34599                 // By default, all `Path`s are rendered in a `SVG` renderer.
34600                 return (this.options.preferCanvas && canvas$1(options)) || svg$1(options);
34601         }
34602       });
34603
34604       /*
34605        * L.Rectangle extends Polygon and creates a rectangle when passed a LatLngBounds object.
34606        */
34607
34608       /*
34609        * @class Rectangle
34610        * @aka L.Rectangle
34611        * @inherits Polygon
34612        *
34613        * A class for drawing rectangle overlays on a map. Extends `Polygon`.
34614        *
34615        * @example
34616        *
34617        * ```js
34618        * // define rectangle geographical bounds
34619        * var bounds = [[54.559322, -5.767822], [56.1210604, -3.021240]];
34620        *
34621        * // create an orange rectangle
34622        * L.rectangle(bounds, {color: "#ff7800", weight: 1}).addTo(map);
34623        *
34624        * // zoom the map to the rectangle bounds
34625        * map.fitBounds(bounds);
34626        * ```
34627        *
34628        */
34629
34630
34631       var Rectangle = Polygon.extend({
34632         initialize: function (latLngBounds, options) {
34633                 Polygon.prototype.initialize.call(this, this._boundsToLatLngs(latLngBounds), options);
34634         },
34635
34636         // @method setBounds(latLngBounds: LatLngBounds): this
34637         // Redraws the rectangle with the passed bounds.
34638         setBounds: function (latLngBounds) {
34639                 return this.setLatLngs(this._boundsToLatLngs(latLngBounds));
34640         },
34641
34642         _boundsToLatLngs: function (latLngBounds) {
34643                 latLngBounds = toLatLngBounds(latLngBounds);
34644                 return [
34645                         latLngBounds.getSouthWest(),
34646                         latLngBounds.getNorthWest(),
34647                         latLngBounds.getNorthEast(),
34648                         latLngBounds.getSouthEast()
34649                 ];
34650         }
34651       });
34652
34653
34654       // @factory L.rectangle(latLngBounds: LatLngBounds, options?: Polyline options)
34655       function rectangle(latLngBounds, options) {
34656         return new Rectangle(latLngBounds, options);
34657       }
34658
34659       SVG.create = create$2;
34660       SVG.pointsToPath = pointsToPath;
34661
34662       GeoJSON.geometryToLayer = geometryToLayer;
34663       GeoJSON.coordsToLatLng = coordsToLatLng;
34664       GeoJSON.coordsToLatLngs = coordsToLatLngs;
34665       GeoJSON.latLngToCoords = latLngToCoords;
34666       GeoJSON.latLngsToCoords = latLngsToCoords;
34667       GeoJSON.getFeature = getFeature;
34668       GeoJSON.asFeature = asFeature;
34669
34670       /*
34671        * L.Handler.BoxZoom is used to add shift-drag zoom interaction to the map
34672        * (zoom to a selected bounding box), enabled by default.
34673        */
34674
34675       // @namespace Map
34676       // @section Interaction Options
34677       Map.mergeOptions({
34678         // @option boxZoom: Boolean = true
34679         // Whether the map can be zoomed to a rectangular area specified by
34680         // dragging the mouse while pressing the shift key.
34681         boxZoom: true
34682       });
34683
34684       var BoxZoom = Handler.extend({
34685         initialize: function (map) {
34686                 this._map = map;
34687                 this._container = map._container;
34688                 this._pane = map._panes.overlayPane;
34689                 this._resetStateTimeout = 0;
34690                 map.on('unload', this._destroy, this);
34691         },
34692
34693         addHooks: function () {
34694                 on(this._container, 'mousedown', this._onMouseDown, this);
34695         },
34696
34697         removeHooks: function () {
34698                 off(this._container, 'mousedown', this._onMouseDown, this);
34699         },
34700
34701         moved: function () {
34702                 return this._moved;
34703         },
34704
34705         _destroy: function () {
34706                 remove(this._pane);
34707                 delete this._pane;
34708         },
34709
34710         _resetState: function () {
34711                 this._resetStateTimeout = 0;
34712                 this._moved = false;
34713         },
34714
34715         _clearDeferredResetState: function () {
34716                 if (this._resetStateTimeout !== 0) {
34717                         clearTimeout(this._resetStateTimeout);
34718                         this._resetStateTimeout = 0;
34719                 }
34720         },
34721
34722         _onMouseDown: function (e) {
34723                 if (!e.shiftKey || ((e.which !== 1) && (e.button !== 1))) { return false; }
34724
34725                 // Clear the deferred resetState if it hasn't executed yet, otherwise it
34726                 // will interrupt the interaction and orphan a box element in the container.
34727                 this._clearDeferredResetState();
34728                 this._resetState();
34729
34730                 disableTextSelection();
34731                 disableImageDrag();
34732
34733                 this._startPoint = this._map.mouseEventToContainerPoint(e);
34734
34735                 on(document, {
34736                         contextmenu: stop,
34737                         mousemove: this._onMouseMove,
34738                         mouseup: this._onMouseUp,
34739                         keydown: this._onKeyDown
34740                 }, this);
34741         },
34742
34743         _onMouseMove: function (e) {
34744                 if (!this._moved) {
34745                         this._moved = true;
34746
34747                         this._box = create$1('div', 'leaflet-zoom-box', this._container);
34748                         addClass(this._container, 'leaflet-crosshair');
34749
34750                         this._map.fire('boxzoomstart');
34751                 }
34752
34753                 this._point = this._map.mouseEventToContainerPoint(e);
34754
34755                 var bounds = new Bounds(this._point, this._startPoint),
34756                     size = bounds.getSize();
34757
34758                 setPosition(this._box, bounds.min);
34759
34760                 this._box.style.width  = size.x + 'px';
34761                 this._box.style.height = size.y + 'px';
34762         },
34763
34764         _finish: function () {
34765                 if (this._moved) {
34766                         remove(this._box);
34767                         removeClass(this._container, 'leaflet-crosshair');
34768                 }
34769
34770                 enableTextSelection();
34771                 enableImageDrag();
34772
34773                 off(document, {
34774                         contextmenu: stop,
34775                         mousemove: this._onMouseMove,
34776                         mouseup: this._onMouseUp,
34777                         keydown: this._onKeyDown
34778                 }, this);
34779         },
34780
34781         _onMouseUp: function (e) {
34782                 if ((e.which !== 1) && (e.button !== 1)) { return; }
34783
34784                 this._finish();
34785
34786                 if (!this._moved) { return; }
34787                 // Postpone to next JS tick so internal click event handling
34788                 // still see it as "moved".
34789                 this._clearDeferredResetState();
34790                 this._resetStateTimeout = setTimeout(bind(this._resetState, this), 0);
34791
34792                 var bounds = new LatLngBounds(
34793                         this._map.containerPointToLatLng(this._startPoint),
34794                         this._map.containerPointToLatLng(this._point));
34795
34796                 this._map
34797                         .fitBounds(bounds)
34798                         .fire('boxzoomend', {boxZoomBounds: bounds});
34799         },
34800
34801         _onKeyDown: function (e) {
34802                 if (e.keyCode === 27) {
34803                         this._finish();
34804                 }
34805         }
34806       });
34807
34808       // @section Handlers
34809       // @property boxZoom: Handler
34810       // Box (shift-drag with mouse) zoom handler.
34811       Map.addInitHook('addHandler', 'boxZoom', BoxZoom);
34812
34813       /*
34814        * L.Handler.DoubleClickZoom is used to handle double-click zoom on the map, enabled by default.
34815        */
34816
34817       // @namespace Map
34818       // @section Interaction Options
34819
34820       Map.mergeOptions({
34821         // @option doubleClickZoom: Boolean|String = true
34822         // Whether the map can be zoomed in by double clicking on it and
34823         // zoomed out by double clicking while holding shift. If passed
34824         // `'center'`, double-click zoom will zoom to the center of the
34825         //  view regardless of where the mouse was.
34826         doubleClickZoom: true
34827       });
34828
34829       var DoubleClickZoom = Handler.extend({
34830         addHooks: function () {
34831                 this._map.on('dblclick', this._onDoubleClick, this);
34832         },
34833
34834         removeHooks: function () {
34835                 this._map.off('dblclick', this._onDoubleClick, this);
34836         },
34837
34838         _onDoubleClick: function (e) {
34839                 var map = this._map,
34840                     oldZoom = map.getZoom(),
34841                     delta = map.options.zoomDelta,
34842                     zoom = e.originalEvent.shiftKey ? oldZoom - delta : oldZoom + delta;
34843
34844                 if (map.options.doubleClickZoom === 'center') {
34845                         map.setZoom(zoom);
34846                 } else {
34847                         map.setZoomAround(e.containerPoint, zoom);
34848                 }
34849         }
34850       });
34851
34852       // @section Handlers
34853       //
34854       // Map properties include interaction handlers that allow you to control
34855       // interaction behavior in runtime, enabling or disabling certain features such
34856       // as dragging or touch zoom (see `Handler` methods). For example:
34857       //
34858       // ```js
34859       // map.doubleClickZoom.disable();
34860       // ```
34861       //
34862       // @property doubleClickZoom: Handler
34863       // Double click zoom handler.
34864       Map.addInitHook('addHandler', 'doubleClickZoom', DoubleClickZoom);
34865
34866       /*
34867        * L.Handler.MapDrag is used to make the map draggable (with panning inertia), enabled by default.
34868        */
34869
34870       // @namespace Map
34871       // @section Interaction Options
34872       Map.mergeOptions({
34873         // @option dragging: Boolean = true
34874         // Whether the map be draggable with mouse/touch or not.
34875         dragging: true,
34876
34877         // @section Panning Inertia Options
34878         // @option inertia: Boolean = *
34879         // If enabled, panning of the map will have an inertia effect where
34880         // the map builds momentum while dragging and continues moving in
34881         // the same direction for some time. Feels especially nice on touch
34882         // devices. Enabled by default unless running on old Android devices.
34883         inertia: !android23,
34884
34885         // @option inertiaDeceleration: Number = 3000
34886         // The rate with which the inertial movement slows down, in pixels/second².
34887         inertiaDeceleration: 3400, // px/s^2
34888
34889         // @option inertiaMaxSpeed: Number = Infinity
34890         // Max speed of the inertial movement, in pixels/second.
34891         inertiaMaxSpeed: Infinity, // px/s
34892
34893         // @option easeLinearity: Number = 0.2
34894         easeLinearity: 0.2,
34895
34896         // TODO refactor, move to CRS
34897         // @option worldCopyJump: Boolean = false
34898         // With this option enabled, the map tracks when you pan to another "copy"
34899         // of the world and seamlessly jumps to the original one so that all overlays
34900         // like markers and vector layers are still visible.
34901         worldCopyJump: false,
34902
34903         // @option maxBoundsViscosity: Number = 0.0
34904         // If `maxBounds` is set, this option will control how solid the bounds
34905         // are when dragging the map around. The default value of `0.0` allows the
34906         // user to drag outside the bounds at normal speed, higher values will
34907         // slow down map dragging outside bounds, and `1.0` makes the bounds fully
34908         // solid, preventing the user from dragging outside the bounds.
34909         maxBoundsViscosity: 0.0
34910       });
34911
34912       var Drag = Handler.extend({
34913         addHooks: function () {
34914                 if (!this._draggable) {
34915                         var map = this._map;
34916
34917                         this._draggable = new Draggable(map._mapPane, map._container);
34918
34919                         this._draggable.on({
34920                                 dragstart: this._onDragStart,
34921                                 drag: this._onDrag,
34922                                 dragend: this._onDragEnd
34923                         }, this);
34924
34925                         this._draggable.on('predrag', this._onPreDragLimit, this);
34926                         if (map.options.worldCopyJump) {
34927                                 this._draggable.on('predrag', this._onPreDragWrap, this);
34928                                 map.on('zoomend', this._onZoomEnd, this);
34929
34930                                 map.whenReady(this._onZoomEnd, this);
34931                         }
34932                 }
34933                 addClass(this._map._container, 'leaflet-grab leaflet-touch-drag');
34934                 this._draggable.enable();
34935                 this._positions = [];
34936                 this._times = [];
34937         },
34938
34939         removeHooks: function () {
34940                 removeClass(this._map._container, 'leaflet-grab');
34941                 removeClass(this._map._container, 'leaflet-touch-drag');
34942                 this._draggable.disable();
34943         },
34944
34945         moved: function () {
34946                 return this._draggable && this._draggable._moved;
34947         },
34948
34949         moving: function () {
34950                 return this._draggable && this._draggable._moving;
34951         },
34952
34953         _onDragStart: function () {
34954                 var map = this._map;
34955
34956                 map._stop();
34957                 if (this._map.options.maxBounds && this._map.options.maxBoundsViscosity) {
34958                         var bounds = toLatLngBounds(this._map.options.maxBounds);
34959
34960                         this._offsetLimit = toBounds(
34961                                 this._map.latLngToContainerPoint(bounds.getNorthWest()).multiplyBy(-1),
34962                                 this._map.latLngToContainerPoint(bounds.getSouthEast()).multiplyBy(-1)
34963                                         .add(this._map.getSize()));
34964
34965                         this._viscosity = Math.min(1.0, Math.max(0.0, this._map.options.maxBoundsViscosity));
34966                 } else {
34967                         this._offsetLimit = null;
34968                 }
34969
34970                 map
34971                     .fire('movestart')
34972                     .fire('dragstart');
34973
34974                 if (map.options.inertia) {
34975                         this._positions = [];
34976                         this._times = [];
34977                 }
34978         },
34979
34980         _onDrag: function (e) {
34981                 if (this._map.options.inertia) {
34982                         var time = this._lastTime = +new Date(),
34983                             pos = this._lastPos = this._draggable._absPos || this._draggable._newPos;
34984
34985                         this._positions.push(pos);
34986                         this._times.push(time);
34987
34988                         this._prunePositions(time);
34989                 }
34990
34991                 this._map
34992                     .fire('move', e)
34993                     .fire('drag', e);
34994         },
34995
34996         _prunePositions: function (time) {
34997                 while (this._positions.length > 1 && time - this._times[0] > 50) {
34998                         this._positions.shift();
34999                         this._times.shift();
35000                 }
35001         },
35002
35003         _onZoomEnd: function () {
35004                 var pxCenter = this._map.getSize().divideBy(2),
35005                     pxWorldCenter = this._map.latLngToLayerPoint([0, 0]);
35006
35007                 this._initialWorldOffset = pxWorldCenter.subtract(pxCenter).x;
35008                 this._worldWidth = this._map.getPixelWorldBounds().getSize().x;
35009         },
35010
35011         _viscousLimit: function (value, threshold) {
35012                 return value - (value - threshold) * this._viscosity;
35013         },
35014
35015         _onPreDragLimit: function () {
35016                 if (!this._viscosity || !this._offsetLimit) { return; }
35017
35018                 var offset = this._draggable._newPos.subtract(this._draggable._startPos);
35019
35020                 var limit = this._offsetLimit;
35021                 if (offset.x < limit.min.x) { offset.x = this._viscousLimit(offset.x, limit.min.x); }
35022                 if (offset.y < limit.min.y) { offset.y = this._viscousLimit(offset.y, limit.min.y); }
35023                 if (offset.x > limit.max.x) { offset.x = this._viscousLimit(offset.x, limit.max.x); }
35024                 if (offset.y > limit.max.y) { offset.y = this._viscousLimit(offset.y, limit.max.y); }
35025
35026                 this._draggable._newPos = this._draggable._startPos.add(offset);
35027         },
35028
35029         _onPreDragWrap: function () {
35030                 // TODO refactor to be able to adjust map pane position after zoom
35031                 var worldWidth = this._worldWidth,
35032                     halfWidth = Math.round(worldWidth / 2),
35033                     dx = this._initialWorldOffset,
35034                     x = this._draggable._newPos.x,
35035                     newX1 = (x - halfWidth + dx) % worldWidth + halfWidth - dx,
35036                     newX2 = (x + halfWidth + dx) % worldWidth - halfWidth - dx,
35037                     newX = Math.abs(newX1 + dx) < Math.abs(newX2 + dx) ? newX1 : newX2;
35038
35039                 this._draggable._absPos = this._draggable._newPos.clone();
35040                 this._draggable._newPos.x = newX;
35041         },
35042
35043         _onDragEnd: function (e) {
35044                 var map = this._map,
35045                     options = map.options,
35046
35047                     noInertia = !options.inertia || this._times.length < 2;
35048
35049                 map.fire('dragend', e);
35050
35051                 if (noInertia) {
35052                         map.fire('moveend');
35053
35054                 } else {
35055                         this._prunePositions(+new Date());
35056
35057                         var direction = this._lastPos.subtract(this._positions[0]),
35058                             duration = (this._lastTime - this._times[0]) / 1000,
35059                             ease = options.easeLinearity,
35060
35061                             speedVector = direction.multiplyBy(ease / duration),
35062                             speed = speedVector.distanceTo([0, 0]),
35063
35064                             limitedSpeed = Math.min(options.inertiaMaxSpeed, speed),
35065                             limitedSpeedVector = speedVector.multiplyBy(limitedSpeed / speed),
35066
35067                             decelerationDuration = limitedSpeed / (options.inertiaDeceleration * ease),
35068                             offset = limitedSpeedVector.multiplyBy(-decelerationDuration / 2).round();
35069
35070                         if (!offset.x && !offset.y) {
35071                                 map.fire('moveend');
35072
35073                         } else {
35074                                 offset = map._limitOffset(offset, map.options.maxBounds);
35075
35076                                 requestAnimFrame(function () {
35077                                         map.panBy(offset, {
35078                                                 duration: decelerationDuration,
35079                                                 easeLinearity: ease,
35080                                                 noMoveStart: true,
35081                                                 animate: true
35082                                         });
35083                                 });
35084                         }
35085                 }
35086         }
35087       });
35088
35089       // @section Handlers
35090       // @property dragging: Handler
35091       // Map dragging handler (by both mouse and touch).
35092       Map.addInitHook('addHandler', 'dragging', Drag);
35093
35094       /*
35095        * L.Map.Keyboard is handling keyboard interaction with the map, enabled by default.
35096        */
35097
35098       // @namespace Map
35099       // @section Keyboard Navigation Options
35100       Map.mergeOptions({
35101         // @option keyboard: Boolean = true
35102         // Makes the map focusable and allows users to navigate the map with keyboard
35103         // arrows and `+`/`-` keys.
35104         keyboard: true,
35105
35106         // @option keyboardPanDelta: Number = 80
35107         // Amount of pixels to pan when pressing an arrow key.
35108         keyboardPanDelta: 80
35109       });
35110
35111       var Keyboard = Handler.extend({
35112
35113         keyCodes: {
35114                 left:    [37],
35115                 right:   [39],
35116                 down:    [40],
35117                 up:      [38],
35118                 zoomIn:  [187, 107, 61, 171],
35119                 zoomOut: [189, 109, 54, 173]
35120         },
35121
35122         initialize: function (map) {
35123                 this._map = map;
35124
35125                 this._setPanDelta(map.options.keyboardPanDelta);
35126                 this._setZoomDelta(map.options.zoomDelta);
35127         },
35128
35129         addHooks: function () {
35130                 var container = this._map._container;
35131
35132                 // make the container focusable by tabbing
35133                 if (container.tabIndex <= 0) {
35134                         container.tabIndex = '0';
35135                 }
35136
35137                 on(container, {
35138                         focus: this._onFocus,
35139                         blur: this._onBlur,
35140                         mousedown: this._onMouseDown
35141                 }, this);
35142
35143                 this._map.on({
35144                         focus: this._addHooks,
35145                         blur: this._removeHooks
35146                 }, this);
35147         },
35148
35149         removeHooks: function () {
35150                 this._removeHooks();
35151
35152                 off(this._map._container, {
35153                         focus: this._onFocus,
35154                         blur: this._onBlur,
35155                         mousedown: this._onMouseDown
35156                 }, this);
35157
35158                 this._map.off({
35159                         focus: this._addHooks,
35160                         blur: this._removeHooks
35161                 }, this);
35162         },
35163
35164         _onMouseDown: function () {
35165                 if (this._focused) { return; }
35166
35167                 var body = document.body,
35168                     docEl = document.documentElement,
35169                     top = body.scrollTop || docEl.scrollTop,
35170                     left = body.scrollLeft || docEl.scrollLeft;
35171
35172                 this._map._container.focus();
35173
35174                 window.scrollTo(left, top);
35175         },
35176
35177         _onFocus: function () {
35178                 this._focused = true;
35179                 this._map.fire('focus');
35180         },
35181
35182         _onBlur: function () {
35183                 this._focused = false;
35184                 this._map.fire('blur');
35185         },
35186
35187         _setPanDelta: function (panDelta) {
35188                 var keys = this._panKeys = {},
35189                     codes = this.keyCodes,
35190                     i, len;
35191
35192                 for (i = 0, len = codes.left.length; i < len; i++) {
35193                         keys[codes.left[i]] = [-1 * panDelta, 0];
35194                 }
35195                 for (i = 0, len = codes.right.length; i < len; i++) {
35196                         keys[codes.right[i]] = [panDelta, 0];
35197                 }
35198                 for (i = 0, len = codes.down.length; i < len; i++) {
35199                         keys[codes.down[i]] = [0, panDelta];
35200                 }
35201                 for (i = 0, len = codes.up.length; i < len; i++) {
35202                         keys[codes.up[i]] = [0, -1 * panDelta];
35203                 }
35204         },
35205
35206         _setZoomDelta: function (zoomDelta) {
35207                 var keys = this._zoomKeys = {},
35208                     codes = this.keyCodes,
35209                     i, len;
35210
35211                 for (i = 0, len = codes.zoomIn.length; i < len; i++) {
35212                         keys[codes.zoomIn[i]] = zoomDelta;
35213                 }
35214                 for (i = 0, len = codes.zoomOut.length; i < len; i++) {
35215                         keys[codes.zoomOut[i]] = -zoomDelta;
35216                 }
35217         },
35218
35219         _addHooks: function () {
35220                 on(document, 'keydown', this._onKeyDown, this);
35221         },
35222
35223         _removeHooks: function () {
35224                 off(document, 'keydown', this._onKeyDown, this);
35225         },
35226
35227         _onKeyDown: function (e) {
35228                 if (e.altKey || e.ctrlKey || e.metaKey) { return; }
35229
35230                 var key = e.keyCode,
35231                     map = this._map,
35232                     offset;
35233
35234                 if (key in this._panKeys) {
35235                         if (!map._panAnim || !map._panAnim._inProgress) {
35236                                 offset = this._panKeys[key];
35237                                 if (e.shiftKey) {
35238                                         offset = toPoint(offset).multiplyBy(3);
35239                                 }
35240
35241                                 map.panBy(offset);
35242
35243                                 if (map.options.maxBounds) {
35244                                         map.panInsideBounds(map.options.maxBounds);
35245                                 }
35246                         }
35247                 } else if (key in this._zoomKeys) {
35248                         map.setZoom(map.getZoom() + (e.shiftKey ? 3 : 1) * this._zoomKeys[key]);
35249
35250                 } else if (key === 27 && map._popup && map._popup.options.closeOnEscapeKey) {
35251                         map.closePopup();
35252
35253                 } else {
35254                         return;
35255                 }
35256
35257                 stop(e);
35258         }
35259       });
35260
35261       // @section Handlers
35262       // @section Handlers
35263       // @property keyboard: Handler
35264       // Keyboard navigation handler.
35265       Map.addInitHook('addHandler', 'keyboard', Keyboard);
35266
35267       /*
35268        * L.Handler.ScrollWheelZoom is used by L.Map to enable mouse scroll wheel zoom on the map.
35269        */
35270
35271       // @namespace Map
35272       // @section Interaction Options
35273       Map.mergeOptions({
35274         // @section Mouse wheel options
35275         // @option scrollWheelZoom: Boolean|String = true
35276         // Whether the map can be zoomed by using the mouse wheel. If passed `'center'`,
35277         // it will zoom to the center of the view regardless of where the mouse was.
35278         scrollWheelZoom: true,
35279
35280         // @option wheelDebounceTime: Number = 40
35281         // Limits the rate at which a wheel can fire (in milliseconds). By default
35282         // user can't zoom via wheel more often than once per 40 ms.
35283         wheelDebounceTime: 40,
35284
35285         // @option wheelPxPerZoomLevel: Number = 60
35286         // How many scroll pixels (as reported by [L.DomEvent.getWheelDelta](#domevent-getwheeldelta))
35287         // mean a change of one full zoom level. Smaller values will make wheel-zooming
35288         // faster (and vice versa).
35289         wheelPxPerZoomLevel: 60
35290       });
35291
35292       var ScrollWheelZoom = Handler.extend({
35293         addHooks: function () {
35294                 on(this._map._container, 'wheel', this._onWheelScroll, this);
35295
35296                 this._delta = 0;
35297         },
35298
35299         removeHooks: function () {
35300                 off(this._map._container, 'wheel', this._onWheelScroll, this);
35301         },
35302
35303         _onWheelScroll: function (e) {
35304                 var delta = getWheelDelta(e);
35305
35306                 var debounce = this._map.options.wheelDebounceTime;
35307
35308                 this._delta += delta;
35309                 this._lastMousePos = this._map.mouseEventToContainerPoint(e);
35310
35311                 if (!this._startTime) {
35312                         this._startTime = +new Date();
35313                 }
35314
35315                 var left = Math.max(debounce - (+new Date() - this._startTime), 0);
35316
35317                 clearTimeout(this._timer);
35318                 this._timer = setTimeout(bind(this._performZoom, this), left);
35319
35320                 stop(e);
35321         },
35322
35323         _performZoom: function () {
35324                 var map = this._map,
35325                     zoom = map.getZoom(),
35326                     snap = this._map.options.zoomSnap || 0;
35327
35328                 map._stop(); // stop panning and fly animations if any
35329
35330                 // map the delta with a sigmoid function to -4..4 range leaning on -1..1
35331                 var d2 = this._delta / (this._map.options.wheelPxPerZoomLevel * 4),
35332                     d3 = 4 * Math.log(2 / (1 + Math.exp(-Math.abs(d2)))) / Math.LN2,
35333                     d4 = snap ? Math.ceil(d3 / snap) * snap : d3,
35334                     delta = map._limitZoom(zoom + (this._delta > 0 ? d4 : -d4)) - zoom;
35335
35336                 this._delta = 0;
35337                 this._startTime = null;
35338
35339                 if (!delta) { return; }
35340
35341                 if (map.options.scrollWheelZoom === 'center') {
35342                         map.setZoom(zoom + delta);
35343                 } else {
35344                         map.setZoomAround(this._lastMousePos, zoom + delta);
35345                 }
35346         }
35347       });
35348
35349       // @section Handlers
35350       // @property scrollWheelZoom: Handler
35351       // Scroll wheel zoom handler.
35352       Map.addInitHook('addHandler', 'scrollWheelZoom', ScrollWheelZoom);
35353
35354       /*
35355        * L.Map.Tap is used to enable mobile hacks like quick taps and long hold.
35356        */
35357
35358       // @namespace Map
35359       // @section Interaction Options
35360       Map.mergeOptions({
35361         // @section Touch interaction options
35362         // @option tap: Boolean = true
35363         // Enables mobile hacks for supporting instant taps (fixing 200ms click
35364         // delay on iOS/Android) and touch holds (fired as `contextmenu` events).
35365         tap: true,
35366
35367         // @option tapTolerance: Number = 15
35368         // The max number of pixels a user can shift his finger during touch
35369         // for it to be considered a valid tap.
35370         tapTolerance: 15
35371       });
35372
35373       var Tap = Handler.extend({
35374         addHooks: function () {
35375                 on(this._map._container, 'touchstart', this._onDown, this);
35376         },
35377
35378         removeHooks: function () {
35379                 off(this._map._container, 'touchstart', this._onDown, this);
35380         },
35381
35382         _onDown: function (e) {
35383                 if (!e.touches) { return; }
35384
35385                 preventDefault(e);
35386
35387                 this._fireClick = true;
35388
35389                 // don't simulate click or track longpress if more than 1 touch
35390                 if (e.touches.length > 1) {
35391                         this._fireClick = false;
35392                         clearTimeout(this._holdTimeout);
35393                         return;
35394                 }
35395
35396                 var first = e.touches[0],
35397                     el = first.target;
35398
35399                 this._startPos = this._newPos = new Point(first.clientX, first.clientY);
35400
35401                 // if touching a link, highlight it
35402                 if (el.tagName && el.tagName.toLowerCase() === 'a') {
35403                         addClass(el, 'leaflet-active');
35404                 }
35405
35406                 // simulate long hold but setting a timeout
35407                 this._holdTimeout = setTimeout(bind(function () {
35408                         if (this._isTapValid()) {
35409                                 this._fireClick = false;
35410                                 this._onUp();
35411                                 this._simulateEvent('contextmenu', first);
35412                         }
35413                 }, this), 1000);
35414
35415                 this._simulateEvent('mousedown', first);
35416
35417                 on(document, {
35418                         touchmove: this._onMove,
35419                         touchend: this._onUp
35420                 }, this);
35421         },
35422
35423         _onUp: function (e) {
35424                 clearTimeout(this._holdTimeout);
35425
35426                 off(document, {
35427                         touchmove: this._onMove,
35428                         touchend: this._onUp
35429                 }, this);
35430
35431                 if (this._fireClick && e && e.changedTouches) {
35432
35433                         var first = e.changedTouches[0],
35434                             el = first.target;
35435
35436                         if (el && el.tagName && el.tagName.toLowerCase() === 'a') {
35437                                 removeClass(el, 'leaflet-active');
35438                         }
35439
35440                         this._simulateEvent('mouseup', first);
35441
35442                         // simulate click if the touch didn't move too much
35443                         if (this._isTapValid()) {
35444                                 this._simulateEvent('click', first);
35445                         }
35446                 }
35447         },
35448
35449         _isTapValid: function () {
35450                 return this._newPos.distanceTo(this._startPos) <= this._map.options.tapTolerance;
35451         },
35452
35453         _onMove: function (e) {
35454                 var first = e.touches[0];
35455                 this._newPos = new Point(first.clientX, first.clientY);
35456                 this._simulateEvent('mousemove', first);
35457         },
35458
35459         _simulateEvent: function (type, e) {
35460                 var simulatedEvent = document.createEvent('MouseEvents');
35461
35462                 simulatedEvent._simulated = true;
35463                 e.target._simulatedClick = true;
35464
35465                 simulatedEvent.initMouseEvent(
35466                         type, true, true, window, 1,
35467                         e.screenX, e.screenY,
35468                         e.clientX, e.clientY,
35469                         false, false, false, false, 0, null);
35470
35471                 e.target.dispatchEvent(simulatedEvent);
35472         }
35473       });
35474
35475       // @section Handlers
35476       // @property tap: Handler
35477       // Mobile touch hacks (quick tap and touch hold) handler.
35478       if (touch && (!pointer || safari)) {
35479         Map.addInitHook('addHandler', 'tap', Tap);
35480       }
35481
35482       /*
35483        * L.Handler.TouchZoom is used by L.Map to add pinch zoom on supported mobile browsers.
35484        */
35485
35486       // @namespace Map
35487       // @section Interaction Options
35488       Map.mergeOptions({
35489         // @section Touch interaction options
35490         // @option touchZoom: Boolean|String = *
35491         // Whether the map can be zoomed by touch-dragging with two fingers. If
35492         // passed `'center'`, it will zoom to the center of the view regardless of
35493         // where the touch events (fingers) were. Enabled for touch-capable web
35494         // browsers except for old Androids.
35495         touchZoom: touch && !android23,
35496
35497         // @option bounceAtZoomLimits: Boolean = true
35498         // Set it to false if you don't want the map to zoom beyond min/max zoom
35499         // and then bounce back when pinch-zooming.
35500         bounceAtZoomLimits: true
35501       });
35502
35503       var TouchZoom = Handler.extend({
35504         addHooks: function () {
35505                 addClass(this._map._container, 'leaflet-touch-zoom');
35506                 on(this._map._container, 'touchstart', this._onTouchStart, this);
35507         },
35508
35509         removeHooks: function () {
35510                 removeClass(this._map._container, 'leaflet-touch-zoom');
35511                 off(this._map._container, 'touchstart', this._onTouchStart, this);
35512         },
35513
35514         _onTouchStart: function (e) {
35515                 var map = this._map;
35516                 if (!e.touches || e.touches.length !== 2 || map._animatingZoom || this._zooming) { return; }
35517
35518                 var p1 = map.mouseEventToContainerPoint(e.touches[0]),
35519                     p2 = map.mouseEventToContainerPoint(e.touches[1]);
35520
35521                 this._centerPoint = map.getSize()._divideBy(2);
35522                 this._startLatLng = map.containerPointToLatLng(this._centerPoint);
35523                 if (map.options.touchZoom !== 'center') {
35524                         this._pinchStartLatLng = map.containerPointToLatLng(p1.add(p2)._divideBy(2));
35525                 }
35526
35527                 this._startDist = p1.distanceTo(p2);
35528                 this._startZoom = map.getZoom();
35529
35530                 this._moved = false;
35531                 this._zooming = true;
35532
35533                 map._stop();
35534
35535                 on(document, 'touchmove', this._onTouchMove, this);
35536                 on(document, 'touchend', this._onTouchEnd, this);
35537
35538                 preventDefault(e);
35539         },
35540
35541         _onTouchMove: function (e) {
35542                 if (!e.touches || e.touches.length !== 2 || !this._zooming) { return; }
35543
35544                 var map = this._map,
35545                     p1 = map.mouseEventToContainerPoint(e.touches[0]),
35546                     p2 = map.mouseEventToContainerPoint(e.touches[1]),
35547                     scale = p1.distanceTo(p2) / this._startDist;
35548
35549                 this._zoom = map.getScaleZoom(scale, this._startZoom);
35550
35551                 if (!map.options.bounceAtZoomLimits && (
35552                         (this._zoom < map.getMinZoom() && scale < 1) ||
35553                         (this._zoom > map.getMaxZoom() && scale > 1))) {
35554                         this._zoom = map._limitZoom(this._zoom);
35555                 }
35556
35557                 if (map.options.touchZoom === 'center') {
35558                         this._center = this._startLatLng;
35559                         if (scale === 1) { return; }
35560                 } else {
35561                         // Get delta from pinch to center, so centerLatLng is delta applied to initial pinchLatLng
35562                         var delta = p1._add(p2)._divideBy(2)._subtract(this._centerPoint);
35563                         if (scale === 1 && delta.x === 0 && delta.y === 0) { return; }
35564                         this._center = map.unproject(map.project(this._pinchStartLatLng, this._zoom).subtract(delta), this._zoom);
35565                 }
35566
35567                 if (!this._moved) {
35568                         map._moveStart(true, false);
35569                         this._moved = true;
35570                 }
35571
35572                 cancelAnimFrame(this._animRequest);
35573
35574                 var moveFn = bind(map._move, map, this._center, this._zoom, {pinch: true, round: false});
35575                 this._animRequest = requestAnimFrame(moveFn, this, true);
35576
35577                 preventDefault(e);
35578         },
35579
35580         _onTouchEnd: function () {
35581                 if (!this._moved || !this._zooming) {
35582                         this._zooming = false;
35583                         return;
35584                 }
35585
35586                 this._zooming = false;
35587                 cancelAnimFrame(this._animRequest);
35588
35589                 off(document, 'touchmove', this._onTouchMove, this);
35590                 off(document, 'touchend', this._onTouchEnd, this);
35591
35592                 // Pinch updates GridLayers' levels only when zoomSnap is off, so zoomSnap becomes noUpdate.
35593                 if (this._map.options.zoomAnimation) {
35594                         this._map._animateZoom(this._center, this._map._limitZoom(this._zoom), true, this._map.options.zoomSnap);
35595                 } else {
35596                         this._map._resetView(this._center, this._map._limitZoom(this._zoom));
35597                 }
35598         }
35599       });
35600
35601       // @section Handlers
35602       // @property touchZoom: Handler
35603       // Touch zoom handler.
35604       Map.addInitHook('addHandler', 'touchZoom', TouchZoom);
35605
35606       Map.BoxZoom = BoxZoom;
35607       Map.DoubleClickZoom = DoubleClickZoom;
35608       Map.Drag = Drag;
35609       Map.Keyboard = Keyboard;
35610       Map.ScrollWheelZoom = ScrollWheelZoom;
35611       Map.Tap = Tap;
35612       Map.TouchZoom = TouchZoom;
35613
35614       exports.version = version;
35615       exports.Control = Control;
35616       exports.control = control;
35617       exports.Browser = Browser;
35618       exports.Evented = Evented;
35619       exports.Mixin = Mixin;
35620       exports.Util = Util;
35621       exports.Class = Class;
35622       exports.Handler = Handler;
35623       exports.extend = extend;
35624       exports.bind = bind;
35625       exports.stamp = stamp;
35626       exports.setOptions = setOptions;
35627       exports.DomEvent = DomEvent;
35628       exports.DomUtil = DomUtil;
35629       exports.PosAnimation = PosAnimation;
35630       exports.Draggable = Draggable;
35631       exports.LineUtil = LineUtil;
35632       exports.PolyUtil = PolyUtil;
35633       exports.Point = Point;
35634       exports.point = toPoint;
35635       exports.Bounds = Bounds;
35636       exports.bounds = toBounds;
35637       exports.Transformation = Transformation;
35638       exports.transformation = toTransformation;
35639       exports.Projection = index;
35640       exports.LatLng = LatLng;
35641       exports.latLng = toLatLng;
35642       exports.LatLngBounds = LatLngBounds;
35643       exports.latLngBounds = toLatLngBounds;
35644       exports.CRS = CRS;
35645       exports.GeoJSON = GeoJSON;
35646       exports.geoJSON = geoJSON;
35647       exports.geoJson = geoJson;
35648       exports.Layer = Layer;
35649       exports.LayerGroup = LayerGroup;
35650       exports.layerGroup = layerGroup;
35651       exports.FeatureGroup = FeatureGroup;
35652       exports.featureGroup = featureGroup;
35653       exports.ImageOverlay = ImageOverlay;
35654       exports.imageOverlay = imageOverlay;
35655       exports.VideoOverlay = VideoOverlay;
35656       exports.videoOverlay = videoOverlay;
35657       exports.SVGOverlay = SVGOverlay;
35658       exports.svgOverlay = svgOverlay;
35659       exports.DivOverlay = DivOverlay;
35660       exports.Popup = Popup;
35661       exports.popup = popup;
35662       exports.Tooltip = Tooltip;
35663       exports.tooltip = tooltip;
35664       exports.Icon = Icon;
35665       exports.icon = icon;
35666       exports.DivIcon = DivIcon;
35667       exports.divIcon = divIcon;
35668       exports.Marker = Marker;
35669       exports.marker = marker;
35670       exports.TileLayer = TileLayer;
35671       exports.tileLayer = tileLayer;
35672       exports.GridLayer = GridLayer;
35673       exports.gridLayer = gridLayer;
35674       exports.SVG = SVG;
35675       exports.svg = svg$1;
35676       exports.Renderer = Renderer;
35677       exports.Canvas = Canvas;
35678       exports.canvas = canvas$1;
35679       exports.Path = Path;
35680       exports.CircleMarker = CircleMarker;
35681       exports.circleMarker = circleMarker;
35682       exports.Circle = Circle;
35683       exports.circle = circle;
35684       exports.Polyline = Polyline;
35685       exports.polyline = polyline;
35686       exports.Polygon = Polygon;
35687       exports.polygon = polygon;
35688       exports.Rectangle = Rectangle;
35689       exports.rectangle = rectangle;
35690       exports.Map = Map;
35691       exports.map = createMap;
35692
35693       var oldL = window.L;
35694       exports.noConflict = function() {
35695         window.L = oldL;
35696         return this;
35697       };
35698
35699       // Always export us to window global (see #2364)
35700       window.L = exports;
35701
35702     })));
35703
35704     });
35705
35706     var L$1 = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.assign(/*#__PURE__*/Object.create(null), leafletSrc, {
35707         'default': leafletSrc
35708     }));
35709
35710     var Control_MiniMap_min = createCommonjsModule(function (module, exports) {
35711     (function(factory,window){{module.exports=factory(leafletSrc);}if(typeof window!=="undefined"&&window.L){window.L.Control.MiniMap=factory(L);window.L.control.minimap=function(layer,options){return new window.L.Control.MiniMap(layer,options)};}})(function(L){var MiniMap=L.Control.extend({includes:L.Evented?L.Evented.prototype:L.Mixin.Events,options:{position:"bottomright",toggleDisplay:false,zoomLevelOffset:-5,zoomLevelFixed:false,centerFixed:false,zoomAnimation:false,autoToggleDisplay:false,minimized:false,width:150,height:150,collapsedWidth:19,collapsedHeight:19,aimingRectOptions:{color:"#ff7800",weight:1,clickable:false},shadowRectOptions:{color:"#000000",weight:1,clickable:false,opacity:0,fillOpacity:0},strings:{hideText:"Hide MiniMap",showText:"Show MiniMap"},mapOptions:{}},initialize:function(layer,options){L.Util.setOptions(this,options);this.options.aimingRectOptions.clickable=false;this.options.shadowRectOptions.clickable=false;this._layer=layer;},onAdd:function(map){this._mainMap=map;this._container=L.DomUtil.create("div","leaflet-control-minimap");this._container.style.width=this.options.width+"px";this._container.style.height=this.options.height+"px";L.DomEvent.disableClickPropagation(this._container);L.DomEvent.on(this._container,"mousewheel",L.DomEvent.stopPropagation);var mapOptions={attributionControl:false,dragging:!this.options.centerFixed,zoomControl:false,zoomAnimation:this.options.zoomAnimation,autoToggleDisplay:this.options.autoToggleDisplay,touchZoom:this.options.centerFixed?"center":!this._isZoomLevelFixed(),scrollWheelZoom:this.options.centerFixed?"center":!this._isZoomLevelFixed(),doubleClickZoom:this.options.centerFixed?"center":!this._isZoomLevelFixed(),boxZoom:!this._isZoomLevelFixed(),crs:map.options.crs};mapOptions=L.Util.extend(this.options.mapOptions,mapOptions);this._miniMap=new L.Map(this._container,mapOptions);this._miniMap.addLayer(this._layer);this._mainMapMoving=false;this._miniMapMoving=false;this._userToggledDisplay=false;this._minimized=false;if(this.options.toggleDisplay){this._addToggleButton();}this._miniMap.whenReady(L.Util.bind(function(){this._aimingRect=L.rectangle(this._mainMap.getBounds(),this.options.aimingRectOptions).addTo(this._miniMap);this._shadowRect=L.rectangle(this._mainMap.getBounds(),this.options.shadowRectOptions).addTo(this._miniMap);this._mainMap.on("moveend",this._onMainMapMoved,this);this._mainMap.on("move",this._onMainMapMoving,this);this._miniMap.on("movestart",this._onMiniMapMoveStarted,this);this._miniMap.on("move",this._onMiniMapMoving,this);this._miniMap.on("moveend",this._onMiniMapMoved,this);},this));return this._container},addTo:function(map){L.Control.prototype.addTo.call(this,map);var center=this.options.centerFixed||this._mainMap.getCenter();this._miniMap.setView(center,this._decideZoom(true));this._setDisplay(this.options.minimized);return this},onRemove:function(map){this._mainMap.off("moveend",this._onMainMapMoved,this);this._mainMap.off("move",this._onMainMapMoving,this);this._miniMap.off("moveend",this._onMiniMapMoved,this);this._miniMap.removeLayer(this._layer);},changeLayer:function(layer){this._miniMap.removeLayer(this._layer);this._layer=layer;this._miniMap.addLayer(this._layer);},_addToggleButton:function(){this._toggleDisplayButton=this.options.toggleDisplay?this._createButton("",this._toggleButtonInitialTitleText(),"leaflet-control-minimap-toggle-display leaflet-control-minimap-toggle-display-"+this.options.position,this._container,this._toggleDisplayButtonClicked,this):undefined;this._toggleDisplayButton.style.width=this.options.collapsedWidth+"px";this._toggleDisplayButton.style.height=this.options.collapsedHeight+"px";},_toggleButtonInitialTitleText:function(){if(this.options.minimized){return this.options.strings.showText}else {return this.options.strings.hideText}},_createButton:function(html,title,className,container,fn,context){var link=L.DomUtil.create("a",className,container);link.innerHTML=html;link.href="#";link.title=title;var stop=L.DomEvent.stopPropagation;L.DomEvent.on(link,"click",stop).on(link,"mousedown",stop).on(link,"dblclick",stop).on(link,"click",L.DomEvent.preventDefault).on(link,"click",fn,context);return link},_toggleDisplayButtonClicked:function(){this._userToggledDisplay=true;if(!this._minimized){this._minimize();}else {this._restore();}},_setDisplay:function(minimize){if(minimize!==this._minimized){if(!this._minimized){this._minimize();}else {this._restore();}}},_minimize:function(){if(this.options.toggleDisplay){this._container.style.width=this.options.collapsedWidth+"px";this._container.style.height=this.options.collapsedHeight+"px";this._toggleDisplayButton.className+=" minimized-"+this.options.position;this._toggleDisplayButton.title=this.options.strings.showText;}else {this._container.style.display="none";}this._minimized=true;this._onToggle();},_restore:function(){if(this.options.toggleDisplay){this._container.style.width=this.options.width+"px";this._container.style.height=this.options.height+"px";this._toggleDisplayButton.className=this._toggleDisplayButton.className.replace("minimized-"+this.options.position,"");this._toggleDisplayButton.title=this.options.strings.hideText;}else {this._container.style.display="block";}this._minimized=false;this._onToggle();},_onMainMapMoved:function(e){if(!this._miniMapMoving){var center=this.options.centerFixed||this._mainMap.getCenter();this._mainMapMoving=true;this._miniMap.setView(center,this._decideZoom(true));this._setDisplay(this._decideMinimized());}else {this._miniMapMoving=false;}this._aimingRect.setBounds(this._mainMap.getBounds());},_onMainMapMoving:function(e){this._aimingRect.setBounds(this._mainMap.getBounds());},_onMiniMapMoveStarted:function(e){if(!this.options.centerFixed){var lastAimingRect=this._aimingRect.getBounds();var sw=this._miniMap.latLngToContainerPoint(lastAimingRect.getSouthWest());var ne=this._miniMap.latLngToContainerPoint(lastAimingRect.getNorthEast());this._lastAimingRectPosition={sw:sw,ne:ne};}},_onMiniMapMoving:function(e){if(!this.options.centerFixed){if(!this._mainMapMoving&&this._lastAimingRectPosition){this._shadowRect.setBounds(new L.LatLngBounds(this._miniMap.containerPointToLatLng(this._lastAimingRectPosition.sw),this._miniMap.containerPointToLatLng(this._lastAimingRectPosition.ne)));this._shadowRect.setStyle({opacity:1,fillOpacity:.3});}}},_onMiniMapMoved:function(e){if(!this._mainMapMoving){this._miniMapMoving=true;this._mainMap.setView(this._miniMap.getCenter(),this._decideZoom(false));this._shadowRect.setStyle({opacity:0,fillOpacity:0});}else {this._mainMapMoving=false;}},_isZoomLevelFixed:function(){var zoomLevelFixed=this.options.zoomLevelFixed;return this._isDefined(zoomLevelFixed)&&this._isInteger(zoomLevelFixed)},_decideZoom:function(fromMaintoMini){if(!this._isZoomLevelFixed()){if(fromMaintoMini){return this._mainMap.getZoom()+this.options.zoomLevelOffset}else {var currentDiff=this._miniMap.getZoom()-this._mainMap.getZoom();var proposedZoom=this._miniMap.getZoom()-this.options.zoomLevelOffset;var toRet;if(currentDiff>this.options.zoomLevelOffset&&this._mainMap.getZoom()<this._miniMap.getMinZoom()-this.options.zoomLevelOffset){if(this._miniMap.getZoom()>this._lastMiniMapZoom){toRet=this._mainMap.getZoom()+1;this._miniMap.setZoom(this._miniMap.getZoom()-1);}else {toRet=this._mainMap.getZoom();}}else {toRet=proposedZoom;}this._lastMiniMapZoom=this._miniMap.getZoom();return toRet}}else {if(fromMaintoMini){return this.options.zoomLevelFixed}else {return this._mainMap.getZoom()}}},_decideMinimized:function(){if(this._userToggledDisplay){return this._minimized}if(this.options.autoToggleDisplay){if(this._mainMap.getBounds().contains(this._miniMap.getBounds())){return true}return false}return this._minimized},_isInteger:function(value){return typeof value==="number"},_isDefined:function(value){return typeof value!=="undefined"},_onToggle:function(){L.Util.requestAnimFrame(function(){L.DomEvent.on(this._container,"transitionend",this._fireToggleEvents,this);if(!L.Browser.any3d){L.Util.requestAnimFrame(this._fireToggleEvents,this);}},this);},_fireToggleEvents:function(){L.DomEvent.off(this._container,"transitionend",this._fireToggleEvents,this);var data={minimized:this._minimized};this.fire(this._minimized?"minimize":"restore",data);this.fire("toggle",data);}});L.Map.mergeOptions({miniMapControl:false});L.Map.addInitHook(function(){if(this.options.miniMapControl){this.miniMapControl=(new MiniMap).addTo(this);}});return MiniMap},window);
35712     });
35713
35714     var LMM = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.assign(/*#__PURE__*/Object.create(null), Control_MiniMap_min, {
35715         'default': Control_MiniMap_min
35716     }));
35717
35718     /* src/components/MapPosition.svelte generated by Svelte v3.31.2 */
35719     const file$7 = "src/components/MapPosition.svelte";
35720
35721     function create_fragment$7(ctx) {
35722         let div2;
35723         let div0;
35724         let t0;
35725         let t1;
35726         let t2;
35727         let a0;
35728         let t3;
35729         let t4;
35730         let br0;
35731         let t5;
35732         let t6;
35733         let t7;
35734         let br1;
35735         let t8;
35736         let t9;
35737         let t10;
35738         let br2;
35739         let t11;
35740         let t12;
35741         let t13;
35742         let br3;
35743         let t14;
35744         let t15;
35745         let t16;
35746         let div1;
35747         let a1;
35748         let mounted;
35749         let dispose;
35750
35751         const block = {
35752                 c: function create() {
35753                         div2 = element("div");
35754                         div0 = element("div");
35755                         t0 = text("map center: ");
35756                         t1 = text(/*map_center*/ ctx[0]);
35757                         t2 = space();
35758                         a0 = element("a");
35759                         t3 = text("view on osm.org");
35760                         t4 = space();
35761                         br0 = element("br");
35762                         t5 = text("\n    map zoom: ");
35763                         t6 = text(/*map_zoom*/ ctx[1]);
35764                         t7 = space();
35765                         br1 = element("br");
35766                         t8 = text("\n    viewbox: ");
35767                         t9 = text(/*map_viewbox*/ ctx[2]);
35768                         t10 = space();
35769                         br2 = element("br");
35770                         t11 = text("\n    last click: ");
35771                         t12 = text(/*last_click*/ ctx[4]);
35772                         t13 = space();
35773                         br3 = element("br");
35774                         t14 = text("\n    mouse position: ");
35775                         t15 = text(/*mouse_position*/ ctx[5]);
35776                         t16 = space();
35777                         div1 = element("div");
35778                         a1 = element("a");
35779                         a1.textContent = "hide";
35780                         attr_dev(a0, "target", "_blank");
35781                         attr_dev(a0, "href", /*view_on_osm_link*/ ctx[3]);
35782                         add_location(a0, file$7, 86, 4, 2297);
35783                         add_location(br0, file$7, 87, 4, 2366);
35784                         add_location(br1, file$7, 89, 4, 2400);
35785                         add_location(br2, file$7, 91, 4, 2436);
35786                         add_location(br3, file$7, 93, 4, 2474);
35787                         attr_dev(div0, "id", "map-position-inner");
35788                         add_location(div0, file$7, 84, 2, 2234);
35789                         attr_dev(a1, "href", "#");
35790                         add_location(a1, file$7, 96, 31, 2556);
35791                         attr_dev(div1, "id", "map-position-close");
35792                         attr_dev(div1, "class", "svelte-1b30dq3");
35793                         add_location(div1, file$7, 96, 2, 2527);
35794                         attr_dev(div2, "id", "map-position");
35795                         attr_dev(div2, "class", "svelte-1b30dq3");
35796                         add_location(div2, file$7, 83, 0, 2208);
35797                 },
35798                 l: function claim(nodes) {
35799                         throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
35800                 },
35801                 m: function mount(target, anchor) {
35802                         insert_dev(target, div2, anchor);
35803                         append_dev(div2, div0);
35804                         append_dev(div0, t0);
35805                         append_dev(div0, t1);
35806                         append_dev(div0, t2);
35807                         append_dev(div0, a0);
35808                         append_dev(a0, t3);
35809                         append_dev(div0, t4);
35810                         append_dev(div0, br0);
35811                         append_dev(div0, t5);
35812                         append_dev(div0, t6);
35813                         append_dev(div0, t7);
35814                         append_dev(div0, br1);
35815                         append_dev(div0, t8);
35816                         append_dev(div0, t9);
35817                         append_dev(div0, t10);
35818                         append_dev(div0, br2);
35819                         append_dev(div0, t11);
35820                         append_dev(div0, t12);
35821                         append_dev(div0, t13);
35822                         append_dev(div0, br3);
35823                         append_dev(div0, t14);
35824                         append_dev(div0, t15);
35825                         append_dev(div2, t16);
35826                         append_dev(div2, div1);
35827                         append_dev(div1, a1);
35828
35829                         if (!mounted) {
35830                                 dispose = listen_dev(a1, "click", handleHideClick, false, false, false);
35831                                 mounted = true;
35832                         }
35833                 },
35834                 p: function update(ctx, [dirty]) {
35835                         if (dirty & /*map_center*/ 1) set_data_dev(t1, /*map_center*/ ctx[0]);
35836
35837                         if (dirty & /*view_on_osm_link*/ 8) {
35838                                 attr_dev(a0, "href", /*view_on_osm_link*/ ctx[3]);
35839                         }
35840
35841                         if (dirty & /*map_zoom*/ 2) set_data_dev(t6, /*map_zoom*/ ctx[1]);
35842                         if (dirty & /*map_viewbox*/ 4) set_data_dev(t9, /*map_viewbox*/ ctx[2]);
35843                         if (dirty & /*last_click*/ 16) set_data_dev(t12, /*last_click*/ ctx[4]);
35844                         if (dirty & /*mouse_position*/ 32) set_data_dev(t15, /*mouse_position*/ ctx[5]);
35845                 },
35846                 i: noop,
35847                 o: noop,
35848                 d: function destroy(detaching) {
35849                         if (detaching) detach_dev(div2);
35850                         mounted = false;
35851                         dispose();
35852                 }
35853         };
35854
35855         dispatch_dev("SvelteRegisterBlock", {
35856                 block,
35857                 id: create_fragment$7.name,
35858                 type: "component",
35859                 source: "",
35860                 ctx
35861         });
35862
35863         return block;
35864     }
35865
35866     function map_link_to_osm(map) {
35867         var zoom = map.getZoom();
35868         var lat = map.getCenter().lat.toFixed(5);
35869         var lng = map.getCenter().lng.toFixed(5);
35870         return "https://openstreetmap.org/#map=" + zoom + "/" + lat + "/" + lng;
35871     }
35872
35873     function map_viewbox_as_string$1(map) {
35874         var bounds = map.getBounds();
35875         var west = bounds.getWest();
35876         var east = bounds.getEast();
35877
35878         if (east - west >= 360) {
35879                 // covers more than whole planet
35880                 west = map.getCenter().lng - 179.999;
35881
35882                 east = map.getCenter().lng + 179.999;
35883         }
35884
35885         east = L.latLng(77, east).wrap().lng;
35886         west = L.latLng(77, west).wrap().lng;
35887
35888         return [
35889                 west.toFixed(5),
35890                 bounds.getNorth().toFixed(5),
35891                 east.toFixed(5),
35892                 bounds.getSouth().toFixed(5)
35893         ].join(","); // left
35894         // top
35895         // right
35896         // bottom
35897     }
35898
35899     function handleHideClick(e) {
35900         document.getElementById("map-position").style.display = "none";
35901         document.getElementById("show-map-position").style.display = "block";
35902     }
35903
35904     function instance$7($$self, $$props, $$invalidate) {
35905         let { $$slots: slots = {}, $$scope } = $$props;
35906         validate_slots("MapPosition", slots, []);
35907         let last_click_latlng;
35908         let map_center;
35909         let map_zoom;
35910         let map_viewbox;
35911         let view_on_osm_link;
35912         let last_click;
35913         let mouse_position;
35914
35915         function display_map_position(map, mouse_lat_lng) {
35916                 $$invalidate(0, map_center = map.getCenter().lat.toFixed(5) + "," + map.getCenter().lng.toFixed(5));
35917                 $$invalidate(3, view_on_osm_link = map_link_to_osm(map));
35918                 $$invalidate(1, map_zoom = map.getZoom());
35919                 $$invalidate(2, map_viewbox = map_viewbox_as_string$1(map));
35920                 $$invalidate(5, mouse_position = "-");
35921
35922                 if (mouse_lat_lng) {
35923                         $$invalidate(5, mouse_position = [mouse_lat_lng.lat.toFixed(5), mouse_lat_lng.lng.toFixed(5)].join(","));
35924                 }
35925
35926                 if (last_click_latlng) {
35927                         $$invalidate(4, last_click = [last_click_latlng.lat.toFixed(5), last_click_latlng.lng.toFixed(5)].join(","));
35928                 }
35929         }
35930
35931         map_store.subscribe(map => {
35932                 if (!map) {
35933                         return;
35934                 }
35935
35936                 map.on("move", function () {
35937                         display_map_position(map);
35938                 }); // update_viewbox_field();
35939
35940                 map.on("mousemove", function (e) {
35941                         display_map_position(map, e.latlng);
35942                 });
35943
35944                 map.on("click", function (e) {
35945                         last_click_latlng = e.latlng;
35946                         display_map_position(map);
35947                 });
35948
35949                 map.on("load", function () {
35950                         display_map_position(map);
35951                 });
35952         });
35953
35954         const writable_props = [];
35955
35956         Object.keys($$props).forEach(key => {
35957                 if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<MapPosition> was created with unknown prop '${key}'`);
35958         });
35959
35960         $$self.$capture_state = () => ({
35961                 map_store,
35962                 last_click_latlng,
35963                 map_center,
35964                 map_zoom,
35965                 map_viewbox,
35966                 view_on_osm_link,
35967                 last_click,
35968                 mouse_position,
35969                 map_link_to_osm,
35970                 map_viewbox_as_string: map_viewbox_as_string$1,
35971                 display_map_position,
35972                 handleHideClick
35973         });
35974
35975         $$self.$inject_state = $$props => {
35976                 if ("last_click_latlng" in $$props) last_click_latlng = $$props.last_click_latlng;
35977                 if ("map_center" in $$props) $$invalidate(0, map_center = $$props.map_center);
35978                 if ("map_zoom" in $$props) $$invalidate(1, map_zoom = $$props.map_zoom);
35979                 if ("map_viewbox" in $$props) $$invalidate(2, map_viewbox = $$props.map_viewbox);
35980                 if ("view_on_osm_link" in $$props) $$invalidate(3, view_on_osm_link = $$props.view_on_osm_link);
35981                 if ("last_click" in $$props) $$invalidate(4, last_click = $$props.last_click);
35982                 if ("mouse_position" in $$props) $$invalidate(5, mouse_position = $$props.mouse_position);
35983         };
35984
35985         if ($$props && "$$inject" in $$props) {
35986                 $$self.$inject_state($$props.$$inject);
35987         }
35988
35989         return [
35990                 map_center,
35991                 map_zoom,
35992                 map_viewbox,
35993                 view_on_osm_link,
35994                 last_click,
35995                 mouse_position
35996         ];
35997     }
35998
35999     class MapPosition extends SvelteComponentDev {
36000         constructor(options) {
36001                 super(options);
36002                 init(this, options, instance$7, create_fragment$7, safe_not_equal, {});
36003
36004                 dispatch_dev("SvelteRegisterComponent", {
36005                         component: this,
36006                         tagName: "MapPosition",
36007                         options,
36008                         id: create_fragment$7.name
36009                 });
36010         }
36011     }
36012
36013     /* src/components/Map.svelte generated by Svelte v3.31.2 */
36014     const file$8 = "src/components/Map.svelte";
36015
36016     function create_fragment$8(ctx) {
36017         let mapposition;
36018         let t0;
36019         let div0;
36020         let t1;
36021         let div1;
36022         let current;
36023         let mounted;
36024         let dispose;
36025         mapposition = new MapPosition({ $$inline: true });
36026
36027         const block = {
36028                 c: function create() {
36029                         create_component(mapposition.$$.fragment);
36030                         t0 = space();
36031                         div0 = element("div");
36032                         t1 = space();
36033                         div1 = element("div");
36034                         div1.textContent = "show map bounds";
36035                         attr_dev(div0, "id", "map");
36036                         attr_dev(div0, "class", "svelte-1vbvdrk");
36037                         add_location(div0, file$8, 173, 0, 4682);
36038                         attr_dev(div1, "id", "show-map-position");
36039                         attr_dev(div1, "class", "leaflet-bar btn btn-sm btn-outline-secondary svelte-1vbvdrk");
36040                         add_location(div1, file$8, 174, 0, 4713);
36041                 },
36042                 l: function claim(nodes) {
36043                         throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
36044                 },
36045                 m: function mount(target, anchor) {
36046                         mount_component(mapposition, target, anchor);
36047                         insert_dev(target, t0, anchor);
36048                         insert_dev(target, div0, anchor);
36049                         insert_dev(target, t1, anchor);
36050                         insert_dev(target, div1, anchor);
36051                         current = true;
36052
36053                         if (!mounted) {
36054                                 dispose = [
36055                                         action_destroyer(/*mapAction*/ ctx[0].call(null, div0)),
36056                                         listen_dev(div1, "click", stop_propagation(show_map_position_click), false, false, true)
36057                                 ];
36058
36059                                 mounted = true;
36060                         }
36061                 },
36062                 p: noop,
36063                 i: function intro(local) {
36064                         if (current) return;
36065                         transition_in(mapposition.$$.fragment, local);
36066                         current = true;
36067                 },
36068                 o: function outro(local) {
36069                         transition_out(mapposition.$$.fragment, local);
36070                         current = false;
36071                 },
36072                 d: function destroy(detaching) {
36073                         destroy_component(mapposition, detaching);
36074                         if (detaching) detach_dev(t0);
36075                         if (detaching) detach_dev(div0);
36076                         if (detaching) detach_dev(t1);
36077                         if (detaching) detach_dev(div1);
36078                         mounted = false;
36079                         run_all(dispose);
36080                 }
36081         };
36082
36083         dispatch_dev("SvelteRegisterBlock", {
36084                 block,
36085                 id: create_fragment$8.name,
36086                 type: "component",
36087                 source: "",
36088                 ctx
36089         });
36090
36091         return block;
36092     }
36093
36094     function parse_and_normalize_geojson_string(part) {
36095         // normalize places the geometry into a featurecollection, similar to
36096         // https://github.com/mapbox/geojson-normalize
36097         var parsed_geojson = {
36098                 type: "FeatureCollection",
36099                 features: [
36100                         {
36101                                 type: "Feature",
36102                                 geometry: part,
36103                                 properties: {}
36104                         }
36105                 ]
36106         };
36107
36108         return parsed_geojson;
36109     }
36110
36111     function show_map_position_click(e) {
36112         e.target.style.display = "none";
36113         document.getElementById("map-position").style.display = "block";
36114     }
36115
36116     function instance$8($$self, $$props, $$invalidate) {
36117         let { $$slots: slots = {}, $$scope } = $$props;
36118         validate_slots("Map", slots, []);
36119         let { display_minimap = false } = $$props;
36120         let dataLayers = [];
36121
36122         function createMap(container) {
36123                 const attribution = get_config_value_1("Map_Tile_Attribution") || null;
36124
36125                 let map = new leafletSrc.map(container,
36126                 {
36127                                 attributionControl: attribution && attribution.length,
36128                                 scrollWheelZoom: true, // !L.Browser.touch,
36129                                 touchZoom: false,
36130                                 center: [get_config_value_1("Map_Default_Lat"), get_config_value_1("Map_Default_Lon")],
36131                                 zoom: get_config_value_1("Map_Default_Zoom")
36132                         });
36133
36134                 leafletSrc.tileLayer(get_config_value_1("Map_Tile_URL"), { attribution }).addTo(map);
36135
36136                 if (display_minimap) {
36137                         let osm2 = new leafletSrc.TileLayer(get_config_value_1("Map_Tile_URL"), { minZoom: 0, maxZoom: 13, attribution });
36138                         new leafletSrc.Control.MiniMap(osm2, { toggleDisplay: true }).addTo(map);
36139                 }
36140
36141                 const MapPositionControl = leafletSrc.Control.extend({
36142                         options: { position: "topright" },
36143                         onAdd: () => {
36144                                 return document.getElementById("show-map-position");
36145                         }
36146                 });
36147
36148                 map.addControl(new MapPositionControl());
36149                 return map;
36150         }
36151
36152         function mapAction(container) {
36153                 let map = createMap(container);
36154                 map_store.set(map);
36155                 setMapData(get_store_value(current_result_store));
36156
36157                 return {
36158                         destroy: () => {
36159                                 map.remove();
36160                         }
36161                 };
36162         }
36163
36164         function resetMapData() {
36165                 let map = get_store_value(map_store);
36166
36167                 if (!map) {
36168                         return;
36169                 }
36170
36171                 dataLayers.forEach(function (layer) {
36172                         map.removeLayer(layer);
36173                 });
36174         }
36175
36176         function setMapData(aFeature) {
36177                 let map = get_store_value(map_store);
36178
36179                 if (!map) {
36180                         return;
36181                 }
36182
36183                 resetMapData();
36184                 let request_latlon = get_store_value(current_request_latlon);
36185
36186                 if (request_latlon) {
36187                         // We don't need a marker, but an L.circle instance changes radius once you zoom in/out
36188                         let cm = leafletSrc.circleMarker(request_latlon, {
36189                                 radius: 5,
36190                                 weight: 2,
36191                                 fillColor: "#ff7800",
36192                                 color: "red",
36193                                 opacity: 0.75,
36194                                 zIndexOffset: 100,
36195                                 clickable: false
36196                         });
36197
36198                         cm.addTo(map);
36199                         dataLayers.push(cm);
36200                 }
36201
36202                 var search_params = new URLSearchParams(window.location.search);
36203                 var viewbox = search_params.get("viewbox");
36204
36205                 if (viewbox) {
36206                         let coords = viewbox.split(","); // <x1>,<y1>,<x2>,<y2>
36207                         let bounds = leafletSrc.latLngBounds([coords[1], coords[0]], [coords[3], coords[2]]);
36208
36209                         leafletSrc.rectangle(bounds, {
36210                                 color: "#69d53e",
36211                                 weight: 3,
36212                                 dashArray: "5 5",
36213                                 opacity: 0.8,
36214                                 fill: false
36215                         }).addTo(map);
36216                 }
36217
36218                 // nothing to do
36219                 if (!aFeature) {
36220                         return;
36221                 }
36222
36223                 let lat = aFeature.centroid
36224                 ? aFeature.centroid.coordinates[1]
36225                 : aFeature.lat;
36226
36227                 let lon = aFeature.centroid
36228                 ? aFeature.centroid.coordinates[0]
36229                 : aFeature.lon;
36230
36231                 let geojson = aFeature.geometry || aFeature.geojson;
36232
36233                 if (lat && lon) {
36234                         let circle = leafletSrc.circleMarker([lat, lon], {
36235                                 radius: 10,
36236                                 weight: 2,
36237                                 fillColor: "#ff7800",
36238                                 color: "blue",
36239                                 opacity: 0.75
36240                         });
36241
36242                         map.addLayer(circle);
36243                         dataLayers.push(circle);
36244                 }
36245
36246                 if (geojson) {
36247                         var geojson_layer = leafletSrc.geoJson(
36248                                 // https://leafletjs.com/reference-1.0.3.html#path-option
36249                                 parse_and_normalize_geojson_string(geojson),
36250                                 {
36251                                         style() {
36252                                                 return { interactive: false, color: "blue" };
36253                                         }
36254                                 }
36255                         );
36256
36257                         map.addLayer(geojson_layer);
36258                         dataLayers.push(geojson_layer);
36259                         map.fitBounds(geojson_layer.getBounds());
36260                 } else if (lat && lon) {
36261                         map.setView([lat, lon], 10);
36262                 } else {
36263                         map.fitWorld();
36264                 }
36265         }
36266
36267         current_result_store.subscribe(aFeature => {
36268                 setMapData(aFeature);
36269         });
36270
36271         const writable_props = ["display_minimap"];
36272
36273         Object.keys($$props).forEach(key => {
36274                 if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<Map> was created with unknown prop '${key}'`);
36275         });
36276
36277         $$self.$$set = $$props => {
36278                 if ("display_minimap" in $$props) $$invalidate(1, display_minimap = $$props.display_minimap);
36279         };
36280
36281         $$self.$capture_state = () => ({
36282                 L: L$1,
36283                 LMM,
36284                 get: get_store_value,
36285                 get_config_value: get_config_value_1,
36286                 map_store,
36287                 current_result_store,
36288                 current_request_latlon,
36289                 MapPosition,
36290                 display_minimap,
36291                 dataLayers,
36292                 createMap,
36293                 mapAction,
36294                 parse_and_normalize_geojson_string,
36295                 resetMapData,
36296                 setMapData,
36297                 show_map_position_click
36298         });
36299
36300         $$self.$inject_state = $$props => {
36301                 if ("display_minimap" in $$props) $$invalidate(1, display_minimap = $$props.display_minimap);
36302                 if ("dataLayers" in $$props) dataLayers = $$props.dataLayers;
36303         };
36304
36305         if ($$props && "$$inject" in $$props) {
36306                 $$self.$inject_state($$props.$$inject);
36307         }
36308
36309         return [mapAction, display_minimap];
36310     }
36311
36312     class Map$1 extends SvelteComponentDev {
36313         constructor(options) {
36314                 super(options);
36315                 init(this, options, instance$8, create_fragment$8, safe_not_equal, { display_minimap: 1 });
36316
36317                 dispatch_dev("SvelteRegisterComponent", {
36318                         component: this,
36319                         tagName: "Map",
36320                         options,
36321                         id: create_fragment$8.name
36322                 });
36323         }
36324
36325         get display_minimap() {
36326                 throw new Error("<Map>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
36327         }
36328
36329         set display_minimap(value) {
36330                 throw new Error("<Map>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
36331         }
36332     }
36333
36334     /* src/pages/SearchPage.svelte generated by Svelte v3.31.2 */
36335     const file$9 = "src/pages/SearchPage.svelte";
36336
36337     function create_fragment$9(ctx) {
36338         let searchbar;
36339         let t0;
36340         let div2;
36341         let div0;
36342         let resultslist;
36343         let t1;
36344         let div1;
36345         let map;
36346         let current;
36347
36348         searchbar = new SearchBar({
36349                         props: {
36350                                 reverse_search: /*reverse_search*/ ctx[0],
36351                                 api_request_params: /*api_request_params*/ ctx[1],
36352                                 bStructuredSearch: /*bStructuredSearch*/ ctx[2]
36353                         },
36354                         $$inline: true
36355                 });
36356
36357         resultslist = new ResultsList({
36358                         props: {
36359                                 reverse_search: /*reverse_search*/ ctx[0]
36360                         },
36361                         $$inline: true
36362                 });
36363
36364         map = new Map$1({
36365                         props: { display_minimap: true },
36366                         $$inline: true
36367                 });
36368
36369         const block = {
36370                 c: function create() {
36371                         create_component(searchbar.$$.fragment);
36372                         t0 = space();
36373                         div2 = element("div");
36374                         div0 = element("div");
36375                         create_component(resultslist.$$.fragment);
36376                         t1 = space();
36377                         div1 = element("div");
36378                         create_component(map.$$.fragment);
36379                         attr_dev(div0, "class", "sidebar svelte-1wb4w3");
36380                         add_location(div0, file$9, 93, 2, 3393);
36381                         attr_dev(div1, "id", "map-wrapper");
36382                         attr_dev(div1, "class", "svelte-1wb4w3");
36383                         add_location(div1, file$9, 96, 2, 3478);
36384                         attr_dev(div2, "id", "content");
36385                         attr_dev(div2, "class", "svelte-1wb4w3");
36386                         add_location(div2, file$9, 92, 0, 3372);
36387                 },
36388                 l: function claim(nodes) {
36389                         throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
36390                 },
36391                 m: function mount(target, anchor) {
36392                         mount_component(searchbar, target, anchor);
36393                         insert_dev(target, t0, anchor);
36394                         insert_dev(target, div2, anchor);
36395                         append_dev(div2, div0);
36396                         mount_component(resultslist, div0, null);
36397                         append_dev(div2, t1);
36398                         append_dev(div2, div1);
36399                         mount_component(map, div1, null);
36400                         current = true;
36401                 },
36402                 p: function update(ctx, [dirty]) {
36403                         const searchbar_changes = {};
36404                         if (dirty & /*reverse_search*/ 1) searchbar_changes.reverse_search = /*reverse_search*/ ctx[0];
36405                         if (dirty & /*api_request_params*/ 2) searchbar_changes.api_request_params = /*api_request_params*/ ctx[1];
36406                         searchbar.$set(searchbar_changes);
36407                         const resultslist_changes = {};
36408                         if (dirty & /*reverse_search*/ 1) resultslist_changes.reverse_search = /*reverse_search*/ ctx[0];
36409                         resultslist.$set(resultslist_changes);
36410                 },
36411                 i: function intro(local) {
36412                         if (current) return;
36413                         transition_in(searchbar.$$.fragment, local);
36414                         transition_in(resultslist.$$.fragment, local);
36415                         transition_in(map.$$.fragment, local);
36416                         current = true;
36417                 },
36418                 o: function outro(local) {
36419                         transition_out(searchbar.$$.fragment, local);
36420                         transition_out(resultslist.$$.fragment, local);
36421                         transition_out(map.$$.fragment, local);
36422                         current = false;
36423                 },
36424                 d: function destroy(detaching) {
36425                         destroy_component(searchbar, detaching);
36426                         if (detaching) detach_dev(t0);
36427                         if (detaching) detach_dev(div2);
36428                         destroy_component(resultslist);
36429                         destroy_component(map);
36430                 }
36431         };
36432
36433         dispatch_dev("SvelteRegisterBlock", {
36434                 block,
36435                 id: create_fragment$9.name,
36436                 type: "component",
36437                 source: "",
36438                 ctx
36439         });
36440
36441         return block;
36442     }
36443
36444     function instance$9($$self, $$props, $$invalidate) {
36445         let { $$slots: slots = {}, $$scope } = $$props;
36446         validate_slots("SearchPage", slots, []);
36447         let { reverse_search = false } = $$props;
36448         let api_request_params;
36449         let bStructuredSearch;
36450
36451         function loaddata() {
36452                 let search_params = new URLSearchParams(window.location.search);
36453                 update_html_title();
36454
36455                 if (reverse_search) {
36456                         $$invalidate(1, api_request_params = {
36457                                 lat: search_params.get("lat"),
36458                                 lon: search_params.get("lon"),
36459                                 zoom: search_params.get("zoom") > 1
36460                                 ? Number(search_params.get("zoom"))
36461                                 : Number(get_config_value_1("Reverse_Default_Search_Zoom")),
36462                                 format: "jsonv2"
36463                         });
36464
36465                         if (api_request_params.lat || api_request_params.lat) {
36466                                 fetch_from_api("reverse", api_request_params, function (data) {
36467                                         if (data && !data.error) {
36468                                                 current_request_latlon.set([api_request_params.lat, api_request_params.lon]);
36469                                                 results_store.set([data]);
36470                                         } else {
36471                                                 results_store.set([]);
36472                                         }
36473
36474                                         update_html_title("Reverse result for " + api_request_params.lat + "," + api_request_params.lon);
36475                                         document.querySelector("input[name=lat]").focus();
36476                                 });
36477                         }
36478                 } else {
36479                         $$invalidate(1, api_request_params = {
36480                                 q: search_params.get("q"),
36481                                 street: search_params.get("street"),
36482                                 city: search_params.get("city"),
36483                                 county: search_params.get("county"),
36484                                 state: search_params.get("state"),
36485                                 country: search_params.get("country"),
36486                                 postalcode: search_params.get("postalcode"),
36487                                 polygon_geojson: get_config_value_1("Search_AreaPolygons", false) ? 1 : 0,
36488                                 viewbox: search_params.get("viewbox"),
36489                                 bounded: search_params.get("bounded"),
36490                                 dedupe: search_params.get("dedupe"),
36491                                 "accept-language": search_params.get("accept-language"),
36492                                 countrycodes: search_params.get("countrycodes"),
36493                                 limit: search_params.get("limit"),
36494                                 polygon_threshold: search_params.get("polygon_threshold"),
36495                                 exclude_place_ids: search_params.get("exclude_place_ids"),
36496                                 format: "jsonv2"
36497                         });
36498
36499                         let bStructuredSearch = api_request_params.street || api_request_params.city || api_request_params.county || api_request_params.state || api_request_params.country || api_request_params.postalcode;
36500
36501                         if (api_request_params.q || bStructuredSearch) {
36502                                 fetch_from_api("search", api_request_params, function (data) {
36503                                         results_store.set(data);
36504                                         update_html_title("Result for " + api_request_params.q);
36505                                         document.querySelector("input[name=q]").focus();
36506                                 });
36507                         }
36508                 }
36509         }
36510
36511         onMount(loaddata);
36512         const writable_props = ["reverse_search"];
36513
36514         Object.keys($$props).forEach(key => {
36515                 if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<SearchPage> was created with unknown prop '${key}'`);
36516         });
36517
36518         $$self.$$set = $$props => {
36519                 if ("reverse_search" in $$props) $$invalidate(0, reverse_search = $$props.reverse_search);
36520         };
36521
36522         $$self.$capture_state = () => ({
36523                 onMount,
36524                 results_store,
36525                 current_result_store,
36526                 current_request_latlon,
36527                 get_config_value: get_config_value_1,
36528                 fetch_from_api,
36529                 update_html_title,
36530                 SearchBar,
36531                 ResultsList,
36532                 Map: Map$1,
36533                 reverse_search,
36534                 api_request_params,
36535                 bStructuredSearch,
36536                 loaddata
36537         });
36538
36539         $$self.$inject_state = $$props => {
36540                 if ("reverse_search" in $$props) $$invalidate(0, reverse_search = $$props.reverse_search);
36541                 if ("api_request_params" in $$props) $$invalidate(1, api_request_params = $$props.api_request_params);
36542                 if ("bStructuredSearch" in $$props) $$invalidate(2, bStructuredSearch = $$props.bStructuredSearch);
36543         };
36544
36545         if ($$props && "$$inject" in $$props) {
36546                 $$self.$inject_state($$props.$$inject);
36547         }
36548
36549         return [reverse_search, api_request_params, bStructuredSearch];
36550     }
36551
36552     class SearchPage extends SvelteComponentDev {
36553         constructor(options) {
36554                 super(options);
36555                 init(this, options, instance$9, create_fragment$9, safe_not_equal, { reverse_search: 0 });
36556
36557                 dispatch_dev("SvelteRegisterComponent", {
36558                         component: this,
36559                         tagName: "SearchPage",
36560                         options,
36561                         id: create_fragment$9.name
36562                 });
36563         }
36564
36565         get reverse_search() {
36566                 throw new Error("<SearchPage>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
36567         }
36568
36569         set reverse_search(value) {
36570                 throw new Error("<SearchPage>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
36571         }
36572     }
36573
36574     /* src/components/DetailsIndex.svelte generated by Svelte v3.31.2 */
36575
36576     const file$a = "src/components/DetailsIndex.svelte";
36577
36578     function create_fragment$a(ctx) {
36579         let div5;
36580         let div4;
36581         let div3;
36582         let h1;
36583         let t1;
36584         let div0;
36585         let h40;
36586         let t3;
36587         let form0;
36588         let input0;
36589         let t4;
36590         let input1;
36591         let t5;
36592         let div1;
36593         let h41;
36594         let t7;
36595         let form1;
36596         let input2;
36597         let t8;
36598         let input3;
36599         let t9;
36600         let input4;
36601         let t10;
36602         let input5;
36603         let t11;
36604         let div2;
36605         let h42;
36606         let t13;
36607         let form2;
36608         let input6;
36609         let t14;
36610         let input7;
36611         let t15;
36612         let input8;
36613         let t16;
36614         let input9;
36615         let mounted;
36616         let dispose;
36617
36618         const block = {
36619                 c: function create() {
36620                         div5 = element("div");
36621                         div4 = element("div");
36622                         div3 = element("div");
36623                         h1 = element("h1");
36624                         h1.textContent = "Show details for place";
36625                         t1 = space();
36626                         div0 = element("div");
36627                         h40 = element("h4");
36628                         h40.textContent = "Search by place id";
36629                         t3 = space();
36630                         form0 = element("form");
36631                         input0 = element("input");
36632                         t4 = space();
36633                         input1 = element("input");
36634                         t5 = space();
36635                         div1 = element("div");
36636                         h41 = element("h4");
36637                         h41.textContent = "Search by OSM type and OSM id";
36638                         t7 = space();
36639                         form1 = element("form");
36640                         input2 = element("input");
36641                         t8 = space();
36642                         input3 = element("input");
36643                         t9 = space();
36644                         input4 = element("input");
36645                         t10 = space();
36646                         input5 = element("input");
36647                         t11 = space();
36648                         div2 = element("div");
36649                         h42 = element("h4");
36650                         h42.textContent = "Search by openstreetmap.org URL";
36651                         t13 = space();
36652                         form2 = element("form");
36653                         input6 = element("input");
36654                         t14 = space();
36655                         input7 = element("input");
36656                         t15 = space();
36657                         input8 = element("input");
36658                         t16 = space();
36659                         input9 = element("input");
36660                         add_location(h1, file$a, 25, 6, 687);
36661                         attr_dev(h40, "class", "svelte-k5v90i");
36662                         add_location(h40, file$a, 28, 8, 760);
36663                         attr_dev(input0, "type", "edit");
36664                         attr_dev(input0, "class", "form-control form-control-sm svelte-k5v90i");
36665                         attr_dev(input0, "pattern", "^[0-9]+$");
36666                         attr_dev(input0, "name", "place_id");
36667                         attr_dev(input0, "placeholder", "12345");
36668                         add_location(input0, file$a, 31, 10, 856);
36669                         attr_dev(input1, "type", "submit");
36670                         attr_dev(input1, "class", "btn btn-primary btn-sm");
36671                         input1.value = "Show";
36672                         add_location(input1, file$a, 36, 10, 1048);
36673                         attr_dev(form0, "class", "form-inline");
36674                         attr_dev(form0, "action", "details.html");
36675                         add_location(form0, file$a, 30, 8, 797);
36676                         attr_dev(div0, "class", "search-form svelte-k5v90i");
36677                         add_location(div0, file$a, 27, 6, 726);
36678                         attr_dev(h41, "class", "svelte-k5v90i");
36679                         add_location(h41, file$a, 43, 8, 1220);
36680                         attr_dev(input2, "type", "edit");
36681                         attr_dev(input2, "class", "form-control form-control-sm svelte-k5v90i");
36682                         attr_dev(input2, "pattern", "^[NWR][0-9]+$");
36683                         attr_dev(input2, "placeholder", "N123 or W123 or R123");
36684                         add_location(input2, file$a, 49, 10, 1438);
36685                         attr_dev(input3, "type", "hidden");
36686                         attr_dev(input3, "name", "osmtype");
36687                         add_location(input3, file$a, 53, 10, 1617);
36688                         attr_dev(input4, "type", "hidden");
36689                         attr_dev(input4, "name", "osmid");
36690                         add_location(input4, file$a, 54, 10, 1666);
36691                         attr_dev(input5, "type", "submit");
36692                         attr_dev(input5, "class", "btn btn-primary btn-sm");
36693                         input5.value = "Show";
36694                         add_location(input5, file$a, 55, 10, 1713);
36695                         attr_dev(form1, "id", "form-by-type-and-id");
36696                         attr_dev(form1, "class", "form-inline");
36697                         attr_dev(form1, "action", "details.html");
36698                         add_location(form1, file$a, 45, 8, 1268);
36699                         attr_dev(div1, "class", "search-form svelte-k5v90i");
36700                         add_location(div1, file$a, 42, 6, 1186);
36701                         attr_dev(h42, "class", "svelte-k5v90i");
36702                         add_location(h42, file$a, 60, 8, 1851);
36703                         attr_dev(input6, "type", "edit");
36704                         attr_dev(input6, "class", "form-control form-control-sm svelte-k5v90i");
36705                         attr_dev(input6, "pattern", ".*openstreetmap.*");
36706                         attr_dev(input6, "placeholder", "https://www.openstreetmap.org/relation/123");
36707                         add_location(input6, file$a, 66, 10, 2067);
36708                         attr_dev(input7, "type", "hidden");
36709                         attr_dev(input7, "name", "osmtype");
36710                         add_location(input7, file$a, 70, 10, 2272);
36711                         attr_dev(input8, "type", "hidden");
36712                         attr_dev(input8, "name", "osmid");
36713                         add_location(input8, file$a, 71, 10, 2321);
36714                         attr_dev(input9, "type", "submit");
36715                         attr_dev(input9, "class", "btn btn-primary btn-sm");
36716                         input9.value = "Show";
36717                         add_location(input9, file$a, 72, 10, 2368);
36718                         attr_dev(form2, "id", "form-by-osm-url");
36719                         attr_dev(form2, "class", "form-inline");
36720                         attr_dev(form2, "action", "details.html");
36721                         add_location(form2, file$a, 62, 8, 1901);
36722                         attr_dev(div2, "class", "search-form svelte-k5v90i");
36723                         add_location(div2, file$a, 59, 6, 1817);
36724                         attr_dev(div3, "class", "col-md-12");
36725                         add_location(div3, file$a, 23, 4, 656);
36726                         attr_dev(div4, "class", "row");
36727                         add_location(div4, file$a, 22, 2, 634);
36728                         attr_dev(div5, "class", "container");
36729                         attr_dev(div5, "id", "details-index-page");
36730                         add_location(div5, file$a, 21, 0, 584);
36731                 },
36732                 l: function claim(nodes) {
36733                         throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
36734                 },
36735                 m: function mount(target, anchor) {
36736                         insert_dev(target, div5, anchor);
36737                         append_dev(div5, div4);
36738                         append_dev(div4, div3);
36739                         append_dev(div3, h1);
36740                         append_dev(div3, t1);
36741                         append_dev(div3, div0);
36742                         append_dev(div0, h40);
36743                         append_dev(div0, t3);
36744                         append_dev(div0, form0);
36745                         append_dev(form0, input0);
36746                         append_dev(form0, t4);
36747                         append_dev(form0, input1);
36748                         append_dev(div3, t5);
36749                         append_dev(div3, div1);
36750                         append_dev(div1, h41);
36751                         append_dev(div1, t7);
36752                         append_dev(div1, form1);
36753                         append_dev(form1, input2);
36754                         append_dev(form1, t8);
36755                         append_dev(form1, input3);
36756                         append_dev(form1, t9);
36757                         append_dev(form1, input4);
36758                         append_dev(form1, t10);
36759                         append_dev(form1, input5);
36760                         append_dev(div3, t11);
36761                         append_dev(div3, div2);
36762                         append_dev(div2, h42);
36763                         append_dev(div2, t13);
36764                         append_dev(div2, form2);
36765                         append_dev(form2, input6);
36766                         append_dev(form2, t14);
36767                         append_dev(form2, input7);
36768                         append_dev(form2, t15);
36769                         append_dev(form2, input8);
36770                         append_dev(form2, t16);
36771                         append_dev(form2, input9);
36772
36773                         if (!mounted) {
36774                                 dispose = [
36775                                         listen_dev(form1, "submit", prevent_default(handleFormSubmit), false, true, false),
36776                                         listen_dev(form2, "submit", prevent_default(handleFormSubmit), false, true, false)
36777                                 ];
36778
36779                                 mounted = true;
36780                         }
36781                 },
36782                 p: noop,
36783                 i: noop,
36784                 o: noop,
36785                 d: function destroy(detaching) {
36786                         if (detaching) detach_dev(div5);
36787                         mounted = false;
36788                         run_all(dispose);
36789                 }
36790         };
36791
36792         dispatch_dev("SvelteRegisterBlock", {
36793                 block,
36794                 id: create_fragment$a.name,
36795                 type: "component",
36796                 source: "",
36797                 ctx
36798         });
36799
36800         return block;
36801     }
36802
36803     function handleFormSubmit(event) {
36804         let form_el = event.target;
36805         let val = form_el.querySelector("input[type=edit]").value;
36806         let matches = val.match(/^\s*([NWR])(\d+)\s*$/i);
36807
36808         if (!matches) {
36809                 matches = val.match(/\/(relation|way|node)\/(\d+)\s*$/);
36810         }
36811
36812         if (!matches) {
36813                 alert("invalid input");
36814                 return;
36815         }
36816
36817         form_el.querySelector("input[name=osmtype]").setAttribute("value", matches[1].charAt(0).toUpperCase());
36818         form_el.querySelector("input[name=osmid]").setAttribute("value", matches[2]);
36819         form_el.submit();
36820     }
36821
36822     function instance$a($$self, $$props, $$invalidate) {
36823         let { $$slots: slots = {}, $$scope } = $$props;
36824         validate_slots("DetailsIndex", slots, []);
36825         const writable_props = [];
36826
36827         Object.keys($$props).forEach(key => {
36828                 if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<DetailsIndex> was created with unknown prop '${key}'`);
36829         });
36830
36831         $$self.$capture_state = () => ({ handleFormSubmit });
36832         return [];
36833     }
36834
36835     class DetailsIndex extends SvelteComponentDev {
36836         constructor(options) {
36837                 super(options);
36838                 init(this, options, instance$a, create_fragment$a, safe_not_equal, {});
36839
36840                 dispatch_dev("SvelteRegisterComponent", {
36841                         component: this,
36842                         tagName: "DetailsIndex",
36843                         options,
36844                         id: create_fragment$a.name
36845                 });
36846         }
36847     }
36848
36849     /* src/components/DetailsOneRow.svelte generated by Svelte v3.31.2 */
36850
36851     const file$b = "src/components/DetailsOneRow.svelte";
36852
36853     // (16:4) {:else}
36854     function create_else_block$2(ctx) {
36855         let span;
36856
36857         const block = {
36858                 c: function create() {
36859                         span = element("span");
36860                         span.textContent = "No Name";
36861                         attr_dev(span, "class", "noname svelte-rtfpp8");
36862                         add_location(span, file$b, 16, 6, 377);
36863                 },
36864                 m: function mount(target, anchor) {
36865                         insert_dev(target, span, anchor);
36866                 },
36867                 p: noop,
36868                 d: function destroy(detaching) {
36869                         if (detaching) detach_dev(span);
36870                 }
36871         };
36872
36873         dispatch_dev("SvelteRegisterBlock", {
36874                 block,
36875                 id: create_else_block$2.name,
36876                 type: "else",
36877                 source: "(16:4) {:else}",
36878                 ctx
36879         });
36880
36881         return block;
36882     }
36883
36884     // (14:4) {#if addressLine.localname}
36885     function create_if_block_1$1(ctx) {
36886         let t_value = /*addressLine*/ ctx[0].localname + "";
36887         let t;
36888
36889         const block = {
36890                 c: function create() {
36891                         t = text(t_value);
36892                 },
36893                 m: function mount(target, anchor) {
36894                         insert_dev(target, t, anchor);
36895                 },
36896                 p: function update(ctx, dirty) {
36897                         if (dirty & /*addressLine*/ 1 && t_value !== (t_value = /*addressLine*/ ctx[0].localname + "")) set_data_dev(t, t_value);
36898                 },
36899                 d: function destroy(detaching) {
36900                         if (detaching) detach_dev(t);
36901                 }
36902         };
36903
36904         dispatch_dev("SvelteRegisterBlock", {
36905                 block,
36906                 id: create_if_block_1$1.name,
36907                 type: "if",
36908                 source: "(14:4) {#if addressLine.localname}",
36909                 ctx
36910         });
36911
36912         return block;
36913     }
36914
36915     // (25:6) {#if addressLine.osm_id}
36916     function create_if_block$4(ctx) {
36917         let a;
36918         let t;
36919         let a_href_value;
36920
36921         const block = {
36922                 c: function create() {
36923                         a = element("a");
36924                         t = text("details");
36925                         attr_dev(a, "href", a_href_value = detailsURL_1(/*addressLine*/ ctx[0]));
36926                         add_location(a, file$b, 24, 30, 711);
36927                 },
36928                 m: function mount(target, anchor) {
36929                         insert_dev(target, a, anchor);
36930                         append_dev(a, t);
36931                 },
36932                 p: function update(ctx, dirty) {
36933                         if (dirty & /*addressLine*/ 1 && a_href_value !== (a_href_value = detailsURL_1(/*addressLine*/ ctx[0]))) {
36934                                 attr_dev(a, "href", a_href_value);
36935                         }
36936                 },
36937                 d: function destroy(detaching) {
36938                         if (detaching) detach_dev(a);
36939                 }
36940         };
36941
36942         dispatch_dev("SvelteRegisterBlock", {
36943                 block,
36944                 id: create_if_block$4.name,
36945                 type: "if",
36946                 source: "(25:6) {#if addressLine.osm_id}",
36947                 ctx
36948         });
36949
36950         return block;
36951     }
36952
36953     function create_fragment$b(ctx) {
36954         let tr;
36955         let td0;
36956         let t0;
36957         let td1;
36958         let t1_value = formatPlaceType_1(/*addressLine*/ ctx[0]) + "";
36959         let t1;
36960         let t2;
36961         let td2;
36962         let raw0_value = osmLink_1(/*addressLine*/ ctx[0]) + "";
36963         let t3;
36964         let td3;
36965         let t4_value = /*addressLine*/ ctx[0].rank_address + "";
36966         let t4;
36967         let t5;
36968         let td4;
36969         let t6_value = formatAdminLevel_1(/*addressLine*/ ctx[0].admin_level) + "";
36970         let t6;
36971         let t7;
36972         let td5;
36973         let raw1_value = formatDistance_1(/*addressLine*/ ctx[0].distance, /*bDistanceInMeters*/ ctx[1]) + "";
36974         let t8;
36975         let td6;
36976
36977         function select_block_type(ctx, dirty) {
36978                 if (/*addressLine*/ ctx[0].localname) return create_if_block_1$1;
36979                 return create_else_block$2;
36980         }
36981
36982         let current_block_type = select_block_type(ctx);
36983         let if_block0 = current_block_type(ctx);
36984         let if_block1 = /*addressLine*/ ctx[0].osm_id && create_if_block$4(ctx);
36985
36986         const block = {
36987                 c: function create() {
36988                         tr = element("tr");
36989                         td0 = element("td");
36990                         if_block0.c();
36991                         t0 = space();
36992                         td1 = element("td");
36993                         t1 = text(t1_value);
36994                         t2 = space();
36995                         td2 = element("td");
36996                         t3 = space();
36997                         td3 = element("td");
36998                         t4 = text(t4_value);
36999                         t5 = space();
37000                         td4 = element("td");
37001                         t6 = text(t6_value);
37002                         t7 = space();
37003                         td5 = element("td");
37004                         t8 = space();
37005                         td6 = element("td");
37006                         if (if_block1) if_block1.c();
37007                         attr_dev(td0, "class", "name svelte-rtfpp8");
37008                         add_location(td0, file$b, 12, 2, 279);
37009                         add_location(td1, file$b, 19, 2, 433);
37010                         add_location(td2, file$b, 20, 2, 475);
37011                         add_location(td3, file$b, 21, 2, 515);
37012                         add_location(td4, file$b, 22, 2, 553);
37013                         add_location(td5, file$b, 23, 2, 608);
37014                         add_location(td6, file$b, 24, 2, 683);
37015                         attr_dev(tr, "class", "svelte-rtfpp8");
37016                         toggle_class(tr, "notused", !/*bAddressLineUsed*/ ctx[2]);
37017                         add_location(tr, file$b, 11, 0, 238);
37018                 },
37019                 l: function claim(nodes) {
37020                         throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
37021                 },
37022                 m: function mount(target, anchor) {
37023                         insert_dev(target, tr, anchor);
37024                         append_dev(tr, td0);
37025                         if_block0.m(td0, null);
37026                         append_dev(tr, t0);
37027                         append_dev(tr, td1);
37028                         append_dev(td1, t1);
37029                         append_dev(tr, t2);
37030                         append_dev(tr, td2);
37031                         td2.innerHTML = raw0_value;
37032                         append_dev(tr, t3);
37033                         append_dev(tr, td3);
37034                         append_dev(td3, t4);
37035                         append_dev(tr, t5);
37036                         append_dev(tr, td4);
37037                         append_dev(td4, t6);
37038                         append_dev(tr, t7);
37039                         append_dev(tr, td5);
37040                         td5.innerHTML = raw1_value;
37041                         append_dev(tr, t8);
37042                         append_dev(tr, td6);
37043                         if (if_block1) if_block1.m(td6, null);
37044                 },
37045                 p: function update(ctx, [dirty]) {
37046                         if (current_block_type === (current_block_type = select_block_type(ctx)) && if_block0) {
37047                                 if_block0.p(ctx, dirty);
37048                         } else {
37049                                 if_block0.d(1);
37050                                 if_block0 = current_block_type(ctx);
37051
37052                                 if (if_block0) {
37053                                         if_block0.c();
37054                                         if_block0.m(td0, null);
37055                                 }
37056                         }
37057
37058                         if (dirty & /*addressLine*/ 1 && t1_value !== (t1_value = formatPlaceType_1(/*addressLine*/ ctx[0]) + "")) set_data_dev(t1, t1_value);
37059                         if (dirty & /*addressLine*/ 1 && raw0_value !== (raw0_value = osmLink_1(/*addressLine*/ ctx[0]) + "")) td2.innerHTML = raw0_value;                      if (dirty & /*addressLine*/ 1 && t4_value !== (t4_value = /*addressLine*/ ctx[0].rank_address + "")) set_data_dev(t4, t4_value);
37060                         if (dirty & /*addressLine*/ 1 && t6_value !== (t6_value = formatAdminLevel_1(/*addressLine*/ ctx[0].admin_level) + "")) set_data_dev(t6, t6_value);
37061                         if (dirty & /*addressLine, bDistanceInMeters*/ 3 && raw1_value !== (raw1_value = formatDistance_1(/*addressLine*/ ctx[0].distance, /*bDistanceInMeters*/ ctx[1]) + "")) td5.innerHTML = raw1_value;
37062                         if (/*addressLine*/ ctx[0].osm_id) {
37063                                 if (if_block1) {
37064                                         if_block1.p(ctx, dirty);
37065                                 } else {
37066                                         if_block1 = create_if_block$4(ctx);
37067                                         if_block1.c();
37068                                         if_block1.m(td6, null);
37069                                 }
37070                         } else if (if_block1) {
37071                                 if_block1.d(1);
37072                                 if_block1 = null;
37073                         }
37074
37075                         if (dirty & /*bAddressLineUsed*/ 4) {
37076                                 toggle_class(tr, "notused", !/*bAddressLineUsed*/ ctx[2]);
37077                         }
37078                 },
37079                 i: noop,
37080                 o: noop,
37081                 d: function destroy(detaching) {
37082                         if (detaching) detach_dev(tr);
37083                         if_block0.d();
37084                         if (if_block1) if_block1.d();
37085                 }
37086         };
37087
37088         dispatch_dev("SvelteRegisterBlock", {
37089                 block,
37090                 id: create_fragment$b.name,
37091                 type: "component",
37092                 source: "",
37093                 ctx
37094         });
37095
37096         return block;
37097     }
37098
37099     function instance$b($$self, $$props, $$invalidate) {
37100         let bAddressLineUsed;
37101         let { $$slots: slots = {}, $$scope } = $$props;
37102         validate_slots("DetailsOneRow", slots, []);
37103         let { addressLine } = $$props;
37104         let { bDistanceInMeters } = $$props;
37105         const writable_props = ["addressLine", "bDistanceInMeters"];
37106
37107         Object.keys($$props).forEach(key => {
37108                 if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<DetailsOneRow> was created with unknown prop '${key}'`);
37109         });
37110
37111         $$self.$$set = $$props => {
37112                 if ("addressLine" in $$props) $$invalidate(0, addressLine = $$props.addressLine);
37113                 if ("bDistanceInMeters" in $$props) $$invalidate(1, bDistanceInMeters = $$props.bDistanceInMeters);
37114         };
37115
37116         $$self.$capture_state = () => ({
37117                 addressLine,
37118                 bDistanceInMeters,
37119                 formatPlaceType: formatPlaceType_1,
37120                 osmLink: osmLink_1,
37121                 formatAdminLevel: formatAdminLevel_1,
37122                 formatDistance: formatDistance_1,
37123                 detailsURL: detailsURL_1,
37124                 bAddressLineUsed
37125         });
37126
37127         $$self.$inject_state = $$props => {
37128                 if ("addressLine" in $$props) $$invalidate(0, addressLine = $$props.addressLine);
37129                 if ("bDistanceInMeters" in $$props) $$invalidate(1, bDistanceInMeters = $$props.bDistanceInMeters);
37130                 if ("bAddressLineUsed" in $$props) $$invalidate(2, bAddressLineUsed = $$props.bAddressLineUsed);
37131         };
37132
37133         if ($$props && "$$inject" in $$props) {
37134                 $$self.$inject_state($$props.$$inject);
37135         }
37136
37137         $$self.$$.update = () => {
37138                 if ($$self.$$.dirty & /*addressLine*/ 1) {
37139                          $$invalidate(2, bAddressLineUsed = addressLine.isaddress);
37140                 }
37141         };
37142
37143         return [addressLine, bDistanceInMeters, bAddressLineUsed];
37144     }
37145
37146     class DetailsOneRow extends SvelteComponentDev {
37147         constructor(options) {
37148                 super(options);
37149                 init(this, options, instance$b, create_fragment$b, safe_not_equal, { addressLine: 0, bDistanceInMeters: 1 });
37150
37151                 dispatch_dev("SvelteRegisterComponent", {
37152                         component: this,
37153                         tagName: "DetailsOneRow",
37154                         options,
37155                         id: create_fragment$b.name
37156                 });
37157
37158                 const { ctx } = this.$$;
37159                 const props = options.props || {};
37160
37161                 if (/*addressLine*/ ctx[0] === undefined && !("addressLine" in props)) {
37162                         console.warn("<DetailsOneRow> was created without expected prop 'addressLine'");
37163                 }
37164
37165                 if (/*bDistanceInMeters*/ ctx[1] === undefined && !("bDistanceInMeters" in props)) {
37166                         console.warn("<DetailsOneRow> was created without expected prop 'bDistanceInMeters'");
37167                 }
37168         }
37169
37170         get addressLine() {
37171                 throw new Error("<DetailsOneRow>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
37172         }
37173
37174         set addressLine(value) {
37175                 throw new Error("<DetailsOneRow>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
37176         }
37177
37178         get bDistanceInMeters() {
37179                 throw new Error("<DetailsOneRow>: Props cannot be read directly from the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
37180         }
37181
37182         set bDistanceInMeters(value) {
37183                 throw new Error("<DetailsOneRow>: Props cannot be set directly on the component instance unless compiling with 'accessors: true' or '<svelte:options accessors/>'");
37184         }
37185     }
37186
37187     /* src/pages/DetailsPage.svelte generated by Svelte v3.31.2 */
37188
37189     const { Object: Object_1 } = globals;
37190     const file$c = "src/pages/DetailsPage.svelte";
37191
37192     function get_each_context$2(ctx, list, i) {
37193         const child_ctx = ctx.slice();
37194         child_ctx[3] = list[i];
37195         return child_ctx;
37196     }
37197
37198     function get_each_context_1(ctx, list, i) {
37199         const child_ctx = ctx.slice();
37200         child_ctx[6] = list[i];
37201         return child_ctx;
37202     }
37203
37204     function get_each_context_2(ctx, list, i) {
37205         const child_ctx = ctx.slice();
37206         child_ctx[9] = list[i];
37207         return child_ctx;
37208     }
37209
37210     function get_each_context_3(ctx, list, i) {
37211         const child_ctx = ctx.slice();
37212         child_ctx[9] = list[i];
37213         return child_ctx;
37214     }
37215
37216     function get_each_context_4(ctx, list, i) {
37217         const child_ctx = ctx.slice();
37218         child_ctx[14] = list[i];
37219         return child_ctx;
37220     }
37221
37222     function get_each_context_5(ctx, list, i) {
37223         const child_ctx = ctx.slice();
37224         child_ctx[14] = list[i];
37225         return child_ctx;
37226     }
37227
37228     function get_each_context_6(ctx, list, i) {
37229         const child_ctx = ctx.slice();
37230         child_ctx[19] = list[i];
37231         return child_ctx;
37232     }
37233
37234     function get_each_context_7(ctx, list, i) {
37235         const child_ctx = ctx.slice();
37236         child_ctx[19] = list[i];
37237         return child_ctx;
37238     }
37239
37240     function get_each_context_8(ctx, list, i) {
37241         const child_ctx = ctx.slice();
37242         child_ctx[19] = list[i];
37243         return child_ctx;
37244     }
37245
37246     // (258:0) {:else}
37247     function create_else_block_2(ctx) {
37248         let t;
37249
37250         const block = {
37251                 c: function create() {
37252                         t = text("No such place found.");
37253                 },
37254                 m: function mount(target, anchor) {
37255                         insert_dev(target, t, anchor);
37256                 },
37257                 p: noop,
37258                 i: noop,
37259                 o: noop,
37260                 d: function destroy(detaching) {
37261                         if (detaching) detach_dev(t);
37262                 }
37263         };
37264
37265         dispatch_dev("SvelteRegisterBlock", {
37266                 block,
37267                 id: create_else_block_2.name,
37268                 type: "else",
37269                 source: "(258:0) {:else}",
37270                 ctx
37271         });
37272
37273         return block;
37274     }
37275
37276     // (256:35) 
37277     function create_if_block_12(ctx) {
37278         let detailsindex;
37279         let current;
37280         detailsindex = new DetailsIndex({ $$inline: true });
37281
37282         const block = {
37283                 c: function create() {
37284                         create_component(detailsindex.$$.fragment);
37285                 },
37286                 m: function mount(target, anchor) {
37287                         mount_component(detailsindex, target, anchor);
37288                         current = true;
37289                 },
37290                 p: noop,
37291                 i: function intro(local) {
37292                         if (current) return;
37293                         transition_in(detailsindex.$$.fragment, local);
37294                         current = true;
37295                 },
37296                 o: function outro(local) {
37297                         transition_out(detailsindex.$$.fragment, local);
37298                         current = false;
37299                 },
37300                 d: function destroy(detaching) {
37301                         destroy_component(detailsindex, detaching);
37302                 }
37303         };
37304
37305         dispatch_dev("SvelteRegisterBlock", {
37306                 block,
37307                 id: create_if_block_12.name,
37308                 type: "if",
37309                 source: "(256:35) ",
37310                 ctx
37311         });
37312
37313         return block;
37314     }
37315
37316     // (53:0) {#if aPlace}
37317     function create_if_block$5(ctx) {
37318         let div9;
37319         let div2;
37320         let div0;
37321         let h1;
37322         let t0_value = /*aPlace*/ ctx[0].localname + "";
37323         let t0;
37324         let t1;
37325         let small;
37326         let a0;
37327         let t2;
37328         let a0_href_value;
37329         let t3;
37330         let div1;
37331         let mapicon;
37332         let t4;
37333         let div6;
37334         let div3;
37335         let table0;
37336         let tbody0;
37337         let tr0;
37338         let td0;
37339         let t6;
37340         let td1;
37341         let t7;
37342         let tr1;
37343         let td2;
37344         let t9;
37345         let td3;
37346         let t10_value = /*aPlace*/ ctx[0].category + "";
37347         let t10;
37348         let t11;
37349         let t12_value = /*aPlace*/ ctx[0].type + "";
37350         let t12;
37351         let t13;
37352         let tr2;
37353         let td4;
37354         let t15;
37355         let td5;
37356         let t16_value = /*aPlace*/ ctx[0].indexed_date + "";
37357         let t16;
37358         let t17;
37359         let show_if = isAdminBoundary_1(/*aPlace*/ ctx[0]);
37360         let t18;
37361         let tr3;
37362         let td6;
37363         let t20;
37364         let td7;
37365         let t21_value = /*aPlace*/ ctx[0].rank_search + "";
37366         let t21;
37367         let t22;
37368         let tr4;
37369         let td8;
37370         let t24;
37371         let td9;
37372         let t25_value = /*aPlace*/ ctx[0].rank_address + "";
37373         let t25;
37374         let t26;
37375         let t27_value = formatAddressRank_1(/*aPlace*/ ctx[0].rank_address) + "";
37376         let t27;
37377         let t28;
37378         let t29;
37379         let t30;
37380         let tr5;
37381         let td10;
37382         let t32;
37383         let td11;
37384         let t33_value = coverageType_1(/*aPlace*/ ctx[0]) + "";
37385         let t33;
37386         let t34;
37387         let tr6;
37388         let td12;
37389         let t36;
37390         let td13;
37391         let t37_value = /*aPlace*/ ctx[0].centroid.coordinates[1] + "";
37392         let t37;
37393         let t38;
37394         let t39_value = /*aPlace*/ ctx[0].centroid.coordinates[0] + "";
37395         let t39;
37396         let t40;
37397         let tr7;
37398         let td14;
37399         let t42;
37400         let td15;
37401         let raw_value = osmLink_1(/*aPlace*/ ctx[0]) + "";
37402         let t43;
37403         let tr8;
37404         let td16;
37405         let t44;
37406         let a1;
37407         let t46;
37408         let t47;
37409         let td17;
37410         let t48_value = /*aPlace*/ ctx[0].place_id + "";
37411         let t48;
37412         let t49;
37413         let t50;
37414         let tr9;
37415         let td18;
37416         let t52;
37417         let td19;
37418         let t53_value = /*aPlace*/ ctx[0].calculated_postcode + "";
37419         let t53;
37420         let t54;
37421         let tr10;
37422         let td20;
37423         let t56;
37424         let td21;
37425         let t57;
37426         let tr11;
37427         let td22;
37428         let t59;
37429         let td23;
37430         let t60;
37431         let div5;
37432         let div4;
37433         let map;
37434         let t61;
37435         let div8;
37436         let div7;
37437         let h20;
37438         let t63;
37439         let table1;
37440         let thead;
37441         let tr12;
37442         let th0;
37443         let t65;
37444         let th1;
37445         let t67;
37446         let th2;
37447         let t69;
37448         let th3;
37449         let t71;
37450         let th4;
37451         let t73;
37452         let th5;
37453         let t75;
37454         let th6;
37455         let t76;
37456         let tbody1;
37457         let t77;
37458         let t78;
37459         let tr13;
37460         let td24;
37461         let h21;
37462         let t80;
37463         let t81;
37464         let tr14;
37465         let td25;
37466         let h22;
37467         let t83;
37468         let current_block_type_index;
37469         let if_block6;
37470         let current;
37471
37472         mapicon = new MapIcon({
37473                         props: { aPlace: /*aPlace*/ ctx[0] },
37474                         $$inline: true
37475                 });
37476
37477         let each_value_8 = Object.keys(/*aPlace*/ ctx[0].names);
37478         validate_each_argument(each_value_8);
37479         let each_blocks_2 = [];
37480
37481         for (let i = 0; i < each_value_8.length; i += 1) {
37482                 each_blocks_2[i] = create_each_block_8(get_each_context_8(ctx, each_value_8, i));
37483         }
37484
37485         let if_block0 = show_if && create_if_block_11(ctx);
37486         let if_block1 = /*aPlace*/ ctx[0].calculated_importance && create_if_block_9(ctx);
37487         let if_block2 = /*aPlace*/ ctx[0].calculated_wikipedia && create_if_block_8(ctx);
37488         let each_value_7 = Object.keys(/*aPlace*/ ctx[0].addresstags);
37489         validate_each_argument(each_value_7);
37490         let each_blocks_1 = [];
37491
37492         for (let i = 0; i < each_value_7.length; i += 1) {
37493                 each_blocks_1[i] = create_each_block_7(get_each_context_7(ctx, each_value_7, i));
37494         }
37495
37496         let each_value_6 = Object.keys(/*aPlace*/ ctx[0].extratags);
37497         validate_each_argument(each_value_6);
37498         let each_blocks = [];
37499
37500         for (let i = 0; i < each_value_6.length; i += 1) {
37501                 each_blocks[i] = create_each_block_6(get_each_context_6(ctx, each_value_6, i));
37502         }
37503
37504         map = new Map$1({ $$inline: true });
37505         let if_block3 = /*aPlace*/ ctx[0].address && create_if_block_7(ctx);
37506         let if_block4 = /*aPlace*/ ctx[0].linked_places && create_if_block_6(ctx);
37507
37508         function select_block_type_1(ctx, dirty) {
37509                 if (/*aPlace*/ ctx[0].keywords) return create_if_block_3$1;
37510                 return create_else_block_1$1;
37511         }
37512
37513         let current_block_type = select_block_type_1(ctx);
37514         let if_block5 = current_block_type(ctx);
37515         const if_block_creators = [create_if_block_1$2, create_else_block$3];
37516         const if_blocks = [];
37517
37518         function select_block_type_2(ctx, dirty) {
37519                 if (/*aPlace*/ ctx[0].hierarchy) return 0;
37520                 return 1;
37521         }
37522
37523         current_block_type_index = select_block_type_2(ctx);
37524         if_block6 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
37525
37526         const block = {
37527                 c: function create() {
37528                         div9 = element("div");
37529                         div2 = element("div");
37530                         div0 = element("div");
37531                         h1 = element("h1");
37532                         t0 = text(t0_value);
37533                         t1 = space();
37534                         small = element("small");
37535                         a0 = element("a");
37536                         t2 = text("link to this page");
37537                         t3 = space();
37538                         div1 = element("div");
37539                         create_component(mapicon.$$.fragment);
37540                         t4 = space();
37541                         div6 = element("div");
37542                         div3 = element("div");
37543                         table0 = element("table");
37544                         tbody0 = element("tbody");
37545                         tr0 = element("tr");
37546                         td0 = element("td");
37547                         td0.textContent = "Name";
37548                         t6 = space();
37549                         td1 = element("td");
37550
37551                         for (let i = 0; i < each_blocks_2.length; i += 1) {
37552                                 each_blocks_2[i].c();
37553                         }
37554
37555                         t7 = space();
37556                         tr1 = element("tr");
37557                         td2 = element("td");
37558                         td2.textContent = "Type";
37559                         t9 = space();
37560                         td3 = element("td");
37561                         t10 = text(t10_value);
37562                         t11 = text(":");
37563                         t12 = text(t12_value);
37564                         t13 = space();
37565                         tr2 = element("tr");
37566                         td4 = element("td");
37567                         td4.textContent = "Last Updated";
37568                         t15 = space();
37569                         td5 = element("td");
37570                         t16 = text(t16_value);
37571                         t17 = space();
37572                         if (if_block0) if_block0.c();
37573                         t18 = space();
37574                         tr3 = element("tr");
37575                         td6 = element("td");
37576                         td6.textContent = "Search Rank";
37577                         t20 = space();
37578                         td7 = element("td");
37579                         t21 = text(t21_value);
37580                         t22 = space();
37581                         tr4 = element("tr");
37582                         td8 = element("td");
37583                         td8.textContent = "Address Rank";
37584                         t24 = space();
37585                         td9 = element("td");
37586                         t25 = text(t25_value);
37587                         t26 = text(" (");
37588                         t27 = text(t27_value);
37589                         t28 = text(")");
37590                         t29 = space();
37591                         if (if_block1) if_block1.c();
37592                         t30 = space();
37593                         tr5 = element("tr");
37594                         td10 = element("td");
37595                         td10.textContent = "Coverage";
37596                         t32 = space();
37597                         td11 = element("td");
37598                         t33 = text(t33_value);
37599                         t34 = space();
37600                         tr6 = element("tr");
37601                         td12 = element("td");
37602                         td12.textContent = "Centre Point (lat,lon)";
37603                         t36 = space();
37604                         td13 = element("td");
37605                         t37 = text(t37_value);
37606                         t38 = text(",");
37607                         t39 = text(t39_value);
37608                         t40 = space();
37609                         tr7 = element("tr");
37610                         td14 = element("td");
37611                         td14.textContent = "OSM";
37612                         t42 = space();
37613                         td15 = element("td");
37614                         t43 = space();
37615                         tr8 = element("tr");
37616                         td16 = element("td");
37617                         t44 = text("Place Id\n                (");
37618                         a1 = element("a");
37619                         a1.textContent = "on this server";
37620                         t46 = text(")");
37621                         t47 = space();
37622                         td17 = element("td");
37623                         t48 = text(t48_value);
37624                         t49 = space();
37625                         if (if_block2) if_block2.c();
37626                         t50 = space();
37627                         tr9 = element("tr");
37628                         td18 = element("td");
37629                         td18.textContent = "Computed Postcode";
37630                         t52 = space();
37631                         td19 = element("td");
37632                         t53 = text(t53_value);
37633                         t54 = space();
37634                         tr10 = element("tr");
37635                         td20 = element("td");
37636                         td20.textContent = "Address Tags";
37637                         t56 = space();
37638                         td21 = element("td");
37639
37640                         for (let i = 0; i < each_blocks_1.length; i += 1) {
37641                                 each_blocks_1[i].c();
37642                         }
37643
37644                         t57 = space();
37645                         tr11 = element("tr");
37646                         td22 = element("td");
37647                         td22.textContent = "Extra Tags";
37648                         t59 = space();
37649                         td23 = element("td");
37650
37651                         for (let i = 0; i < each_blocks.length; i += 1) {
37652                                 each_blocks[i].c();
37653                         }
37654
37655                         t60 = space();
37656                         div5 = element("div");
37657                         div4 = element("div");
37658                         create_component(map.$$.fragment);
37659                         t61 = space();
37660                         div8 = element("div");
37661                         div7 = element("div");
37662                         h20 = element("h2");
37663                         h20.textContent = "Address";
37664                         t63 = space();
37665                         table1 = element("table");
37666                         thead = element("thead");
37667                         tr12 = element("tr");
37668                         th0 = element("th");
37669                         th0.textContent = "Local name";
37670                         t65 = space();
37671                         th1 = element("th");
37672                         th1.textContent = "Type";
37673                         t67 = space();
37674                         th2 = element("th");
37675                         th2.textContent = "OSM";
37676                         t69 = space();
37677                         th3 = element("th");
37678                         th3.textContent = "Address rank";
37679                         t71 = space();
37680                         th4 = element("th");
37681                         th4.textContent = "Admin level";
37682                         t73 = space();
37683                         th5 = element("th");
37684                         th5.textContent = "Distance";
37685                         t75 = space();
37686                         th6 = element("th");
37687                         t76 = space();
37688                         tbody1 = element("tbody");
37689                         if (if_block3) if_block3.c();
37690                         t77 = space();
37691                         if (if_block4) if_block4.c();
37692                         t78 = space();
37693                         tr13 = element("tr");
37694                         td24 = element("td");
37695                         h21 = element("h2");
37696                         h21.textContent = "Keywords";
37697                         t80 = space();
37698                         if_block5.c();
37699                         t81 = space();
37700                         tr14 = element("tr");
37701                         td25 = element("td");
37702                         h22 = element("h2");
37703                         h22.textContent = "Parent Of";
37704                         t83 = space();
37705                         if_block6.c();
37706                         attr_dev(a0, "href", a0_href_value = detailsURL_1(/*aPlace*/ ctx[0]));
37707                         attr_dev(a0, "class", "svelte-j6zgmy");
37708                         add_location(a0, file$c, 58, 17, 1869);
37709                         add_location(small, file$c, 58, 10, 1862);
37710                         attr_dev(h1, "class", "svelte-j6zgmy");
37711                         add_location(h1, file$c, 56, 8, 1818);
37712                         attr_dev(div0, "class", "col-sm-10");
37713                         add_location(div0, file$c, 55, 6, 1786);
37714                         attr_dev(div1, "class", "col-sm-2 text-right");
37715                         add_location(div1, file$c, 61, 6, 1963);
37716                         attr_dev(div2, "class", "row");
37717                         add_location(div2, file$c, 54, 4, 1762);
37718                         attr_dev(td0, "class", "svelte-j6zgmy");
37719                         add_location(td0, file$c, 70, 14, 2222);
37720                         attr_dev(td1, "class", "svelte-j6zgmy");
37721                         add_location(td1, file$c, 71, 14, 2250);
37722                         attr_dev(tr0, "class", "svelte-j6zgmy");
37723                         add_location(tr0, file$c, 69, 12, 2203);
37724                         attr_dev(td2, "class", "svelte-j6zgmy");
37725                         add_location(td2, file$c, 80, 14, 2544);
37726                         attr_dev(td3, "class", "svelte-j6zgmy");
37727                         add_location(td3, file$c, 81, 14, 2572);
37728                         attr_dev(tr1, "class", "svelte-j6zgmy");
37729                         add_location(tr1, file$c, 79, 12, 2525);
37730                         attr_dev(td4, "class", "svelte-j6zgmy");
37731                         add_location(td4, file$c, 84, 14, 2662);
37732                         attr_dev(td5, "class", "svelte-j6zgmy");
37733                         add_location(td5, file$c, 85, 14, 2698);
37734                         attr_dev(tr2, "class", "svelte-j6zgmy");
37735                         add_location(tr2, file$c, 83, 12, 2643);
37736                         attr_dev(td6, "class", "svelte-j6zgmy");
37737                         add_location(td6, file$c, 94, 14, 2955);
37738                         attr_dev(td7, "class", "svelte-j6zgmy");
37739                         add_location(td7, file$c, 95, 14, 2990);
37740                         attr_dev(tr3, "class", "svelte-j6zgmy");
37741                         add_location(tr3, file$c, 93, 12, 2936);
37742                         attr_dev(td8, "class", "svelte-j6zgmy");
37743                         add_location(td8, file$c, 98, 14, 3069);
37744                         attr_dev(td9, "class", "svelte-j6zgmy");
37745                         add_location(td9, file$c, 99, 14, 3105);
37746                         attr_dev(tr4, "class", "svelte-j6zgmy");
37747                         add_location(tr4, file$c, 97, 12, 3050);
37748                         attr_dev(td10, "class", "svelte-j6zgmy");
37749                         add_location(td10, file$c, 111, 14, 3520);
37750                         attr_dev(td11, "class", "svelte-j6zgmy");
37751                         add_location(td11, file$c, 112, 14, 3552);
37752                         attr_dev(tr5, "class", "svelte-j6zgmy");
37753                         add_location(tr5, file$c, 110, 12, 3501);
37754                         attr_dev(td12, "class", "svelte-j6zgmy");
37755                         add_location(td12, file$c, 115, 14, 3633);
37756                         attr_dev(td13, "class", "svelte-j6zgmy");
37757                         add_location(td13, file$c, 116, 14, 3679);
37758                         attr_dev(tr6, "class", "svelte-j6zgmy");
37759                         add_location(tr6, file$c, 114, 12, 3614);
37760                         attr_dev(td14, "class", "svelte-j6zgmy");
37761                         add_location(td14, file$c, 121, 14, 3835);
37762                         attr_dev(td15, "class", "svelte-j6zgmy");
37763                         add_location(td15, file$c, 122, 14, 3862);
37764                         attr_dev(tr7, "class", "svelte-j6zgmy");
37765                         add_location(tr7, file$c, 120, 12, 3816);
37766                         attr_dev(a1, "href", "https://nominatim.org/release-docs/develop/api/Output/#place_id-is-not-a-persistent-id");
37767                         add_location(a1, file$c, 127, 17, 3986);
37768                         attr_dev(td16, "class", "svelte-j6zgmy");
37769                         add_location(td16, file$c, 125, 14, 3939);
37770                         attr_dev(td17, "class", "svelte-j6zgmy");
37771                         add_location(td17, file$c, 129, 14, 4137);
37772                         attr_dev(tr8, "class", "svelte-j6zgmy");
37773                         add_location(tr8, file$c, 124, 12, 3920);
37774                         attr_dev(td18, "class", "svelte-j6zgmy");
37775                         add_location(td18, file$c, 138, 14, 4417);
37776                         attr_dev(td19, "class", "svelte-j6zgmy");
37777                         add_location(td19, file$c, 139, 14, 4458);
37778                         attr_dev(tr9, "class", "svelte-j6zgmy");
37779                         add_location(tr9, file$c, 137, 12, 4398);
37780                         attr_dev(td20, "class", "svelte-j6zgmy");
37781                         add_location(td20, file$c, 142, 14, 4545);
37782                         attr_dev(td21, "class", "svelte-j6zgmy");
37783                         add_location(td21, file$c, 143, 14, 4581);
37784                         attr_dev(tr10, "class", "svelte-j6zgmy");
37785                         add_location(tr10, file$c, 141, 12, 4526);
37786                         attr_dev(td22, "class", "svelte-j6zgmy");
37787                         add_location(td22, file$c, 152, 14, 4887);
37788                         attr_dev(td23, "class", "svelte-j6zgmy");
37789                         add_location(td23, file$c, 153, 14, 4921);
37790                         attr_dev(tr11, "class", "svelte-j6zgmy");
37791                         add_location(tr11, file$c, 151, 12, 4868);
37792                         attr_dev(tbody0, "class", "svelte-j6zgmy");
37793                         add_location(tbody0, file$c, 68, 10, 2183);
37794                         attr_dev(table0, "id", "locationdetails");
37795                         attr_dev(table0, "class", "table table-striped svelte-j6zgmy");
37796                         add_location(table0, file$c, 67, 8, 2116);
37797                         attr_dev(div3, "class", "col-md-6");
37798                         add_location(div3, file$c, 66, 6, 2085);
37799                         attr_dev(div4, "id", "map-wrapper");
37800                         attr_dev(div4, "class", "svelte-j6zgmy");
37801                         add_location(div4, file$c, 165, 8, 5278);
37802                         attr_dev(div5, "class", "col-md-6");
37803                         add_location(div5, file$c, 164, 6, 5247);
37804                         attr_dev(div6, "class", "row");
37805                         add_location(div6, file$c, 65, 4, 2061);
37806                         attr_dev(h20, "class", "svelte-j6zgmy");
37807                         add_location(h20, file$c, 172, 8, 5417);
37808                         attr_dev(th0, "class", "svelte-j6zgmy");
37809                         add_location(th0, file$c, 176, 14, 5553);
37810                         attr_dev(th1, "class", "svelte-j6zgmy");
37811                         add_location(th1, file$c, 177, 14, 5587);
37812                         attr_dev(th2, "class", "svelte-j6zgmy");
37813                         add_location(th2, file$c, 178, 14, 5615);
37814                         attr_dev(th3, "class", "svelte-j6zgmy");
37815                         add_location(th3, file$c, 179, 14, 5642);
37816                         attr_dev(th4, "class", "svelte-j6zgmy");
37817                         add_location(th4, file$c, 180, 14, 5678);
37818                         attr_dev(th5, "class", "svelte-j6zgmy");
37819                         add_location(th5, file$c, 181, 14, 5713);
37820                         attr_dev(th6, "class", "svelte-j6zgmy");
37821                         add_location(th6, file$c, 182, 14, 5745);
37822                         attr_dev(tr12, "class", "svelte-j6zgmy");
37823                         add_location(tr12, file$c, 175, 12, 5534);
37824                         attr_dev(thead, "class", "svelte-j6zgmy");
37825                         add_location(thead, file$c, 174, 10, 5514);
37826                         attr_dev(h21, "class", "svelte-j6zgmy");
37827                         add_location(h21, file$c, 199, 52, 6380);
37828                         attr_dev(td24, "colspan", "6");
37829                         attr_dev(td24, "class", "svelte-j6zgmy");
37830                         add_location(td24, file$c, 199, 36, 6364);
37831                         attr_dev(tr13, "class", "all-columns svelte-j6zgmy");
37832                         add_location(tr13, file$c, 199, 12, 6340);
37833                         attr_dev(h22, "class", "svelte-j6zgmy");
37834                         add_location(h22, file$c, 229, 52, 7511);
37835                         attr_dev(td25, "colspan", "6");
37836                         attr_dev(td25, "class", "svelte-j6zgmy");
37837                         add_location(td25, file$c, 229, 36, 7495);
37838                         attr_dev(tr14, "class", "all-columns svelte-j6zgmy");
37839                         add_location(tr14, file$c, 229, 12, 7471);
37840                         attr_dev(tbody1, "class", "svelte-j6zgmy");
37841                         add_location(tbody1, file$c, 185, 10, 5802);
37842                         attr_dev(table1, "id", "address");
37843                         attr_dev(table1, "class", "table table-striped table-small svelte-j6zgmy");
37844                         add_location(table1, file$c, 173, 9, 5443);
37845                         attr_dev(div7, "class", "col-md-12");
37846                         add_location(div7, file$c, 171, 6, 5385);
37847                         attr_dev(div8, "class", "row");
37848                         add_location(div8, file$c, 170, 4, 5361);
37849                         attr_dev(div9, "class", "container");
37850                         add_location(div9, file$c, 53, 2, 1734);
37851                 },
37852                 m: function mount(target, anchor) {
37853                         insert_dev(target, div9, anchor);
37854                         append_dev(div9, div2);
37855                         append_dev(div2, div0);
37856                         append_dev(div0, h1);
37857                         append_dev(h1, t0);
37858                         append_dev(h1, t1);
37859                         append_dev(h1, small);
37860                         append_dev(small, a0);
37861                         append_dev(a0, t2);
37862                         append_dev(div2, t3);
37863                         append_dev(div2, div1);
37864                         mount_component(mapicon, div1, null);
37865                         append_dev(div9, t4);
37866                         append_dev(div9, div6);
37867                         append_dev(div6, div3);
37868                         append_dev(div3, table0);
37869                         append_dev(table0, tbody0);
37870                         append_dev(tbody0, tr0);
37871                         append_dev(tr0, td0);
37872                         append_dev(tr0, t6);
37873                         append_dev(tr0, td1);
37874
37875                         for (let i = 0; i < each_blocks_2.length; i += 1) {
37876                                 each_blocks_2[i].m(td1, null);
37877                         }
37878
37879                         append_dev(tbody0, t7);
37880                         append_dev(tbody0, tr1);
37881                         append_dev(tr1, td2);
37882                         append_dev(tr1, t9);
37883                         append_dev(tr1, td3);
37884                         append_dev(td3, t10);
37885                         append_dev(td3, t11);
37886                         append_dev(td3, t12);
37887                         append_dev(tbody0, t13);
37888                         append_dev(tbody0, tr2);
37889                         append_dev(tr2, td4);
37890                         append_dev(tr2, t15);
37891                         append_dev(tr2, td5);
37892                         append_dev(td5, t16);
37893                         append_dev(tbody0, t17);
37894                         if (if_block0) if_block0.m(tbody0, null);
37895                         append_dev(tbody0, t18);
37896                         append_dev(tbody0, tr3);
37897                         append_dev(tr3, td6);
37898                         append_dev(tr3, t20);
37899                         append_dev(tr3, td7);
37900                         append_dev(td7, t21);
37901                         append_dev(tbody0, t22);
37902                         append_dev(tbody0, tr4);
37903                         append_dev(tr4, td8);
37904                         append_dev(tr4, t24);
37905                         append_dev(tr4, td9);
37906                         append_dev(td9, t25);
37907                         append_dev(td9, t26);
37908                         append_dev(td9, t27);
37909                         append_dev(td9, t28);
37910                         append_dev(tbody0, t29);
37911                         if (if_block1) if_block1.m(tbody0, null);
37912                         append_dev(tbody0, t30);
37913                         append_dev(tbody0, tr5);
37914                         append_dev(tr5, td10);
37915                         append_dev(tr5, t32);
37916                         append_dev(tr5, td11);
37917                         append_dev(td11, t33);
37918                         append_dev(tbody0, t34);
37919                         append_dev(tbody0, tr6);
37920                         append_dev(tr6, td12);
37921                         append_dev(tr6, t36);
37922                         append_dev(tr6, td13);
37923                         append_dev(td13, t37);
37924                         append_dev(td13, t38);
37925                         append_dev(td13, t39);
37926                         append_dev(tbody0, t40);
37927                         append_dev(tbody0, tr7);
37928                         append_dev(tr7, td14);
37929                         append_dev(tr7, t42);
37930                         append_dev(tr7, td15);
37931                         td15.innerHTML = raw_value;
37932                         append_dev(tbody0, t43);
37933                         append_dev(tbody0, tr8);
37934                         append_dev(tr8, td16);
37935                         append_dev(td16, t44);
37936                         append_dev(td16, a1);
37937                         append_dev(td16, t46);
37938                         append_dev(tr8, t47);
37939                         append_dev(tr8, td17);
37940                         append_dev(td17, t48);
37941                         append_dev(tbody0, t49);
37942                         if (if_block2) if_block2.m(tbody0, null);
37943                         append_dev(tbody0, t50);
37944                         append_dev(tbody0, tr9);
37945                         append_dev(tr9, td18);
37946                         append_dev(tr9, t52);
37947                         append_dev(tr9, td19);
37948                         append_dev(td19, t53);
37949                         append_dev(tbody0, t54);
37950                         append_dev(tbody0, tr10);
37951                         append_dev(tr10, td20);
37952                         append_dev(tr10, t56);
37953                         append_dev(tr10, td21);
37954
37955                         for (let i = 0; i < each_blocks_1.length; i += 1) {
37956                                 each_blocks_1[i].m(td21, null);
37957                         }
37958
37959                         append_dev(tbody0, t57);
37960                         append_dev(tbody0, tr11);
37961                         append_dev(tr11, td22);
37962                         append_dev(tr11, t59);
37963                         append_dev(tr11, td23);
37964
37965                         for (let i = 0; i < each_blocks.length; i += 1) {
37966                                 each_blocks[i].m(td23, null);
37967                         }
37968
37969                         append_dev(div6, t60);
37970                         append_dev(div6, div5);
37971                         append_dev(div5, div4);
37972                         mount_component(map, div4, null);
37973                         append_dev(div9, t61);
37974                         append_dev(div9, div8);
37975                         append_dev(div8, div7);
37976                         append_dev(div7, h20);
37977                         append_dev(div7, t63);
37978                         append_dev(div7, table1);
37979                         append_dev(table1, thead);
37980                         append_dev(thead, tr12);
37981                         append_dev(tr12, th0);
37982                         append_dev(tr12, t65);
37983                         append_dev(tr12, th1);
37984                         append_dev(tr12, t67);
37985                         append_dev(tr12, th2);
37986                         append_dev(tr12, t69);
37987                         append_dev(tr12, th3);
37988                         append_dev(tr12, t71);
37989                         append_dev(tr12, th4);
37990                         append_dev(tr12, t73);
37991                         append_dev(tr12, th5);
37992                         append_dev(tr12, t75);
37993                         append_dev(tr12, th6);
37994                         append_dev(table1, t76);
37995                         append_dev(table1, tbody1);
37996                         if (if_block3) if_block3.m(tbody1, null);
37997                         append_dev(tbody1, t77);
37998                         if (if_block4) if_block4.m(tbody1, null);
37999                         append_dev(tbody1, t78);
38000                         append_dev(tbody1, tr13);
38001                         append_dev(tr13, td24);
38002                         append_dev(td24, h21);
38003                         append_dev(tbody1, t80);
38004                         if_block5.m(tbody1, null);
38005                         append_dev(tbody1, t81);
38006                         append_dev(tbody1, tr14);
38007                         append_dev(tr14, td25);
38008                         append_dev(td25, h22);
38009                         append_dev(tbody1, t83);
38010                         if_blocks[current_block_type_index].m(tbody1, null);
38011                         current = true;
38012                 },
38013                 p: function update(ctx, dirty) {
38014                         if ((!current || dirty & /*aPlace*/ 1) && t0_value !== (t0_value = /*aPlace*/ ctx[0].localname + "")) set_data_dev(t0, t0_value);
38015
38016                         if (!current || dirty & /*aPlace*/ 1 && a0_href_value !== (a0_href_value = detailsURL_1(/*aPlace*/ ctx[0]))) {
38017                                 attr_dev(a0, "href", a0_href_value);
38018                         }
38019
38020                         const mapicon_changes = {};
38021                         if (dirty & /*aPlace*/ 1) mapicon_changes.aPlace = /*aPlace*/ ctx[0];
38022                         mapicon.$set(mapicon_changes);
38023
38024                         if (dirty & /*Object, aPlace*/ 1) {
38025                                 each_value_8 = Object.keys(/*aPlace*/ ctx[0].names);
38026                                 validate_each_argument(each_value_8);
38027                                 let i;
38028
38029                                 for (i = 0; i < each_value_8.length; i += 1) {
38030                                         const child_ctx = get_each_context_8(ctx, each_value_8, i);
38031
38032                                         if (each_blocks_2[i]) {
38033                                                 each_blocks_2[i].p(child_ctx, dirty);
38034                                         } else {
38035                                                 each_blocks_2[i] = create_each_block_8(child_ctx);
38036                                                 each_blocks_2[i].c();
38037                                                 each_blocks_2[i].m(td1, null);
38038                                         }
38039                                 }
38040
38041                                 for (; i < each_blocks_2.length; i += 1) {
38042                                         each_blocks_2[i].d(1);
38043                                 }
38044
38045                                 each_blocks_2.length = each_value_8.length;
38046                         }
38047
38048                         if ((!current || dirty & /*aPlace*/ 1) && t10_value !== (t10_value = /*aPlace*/ ctx[0].category + "")) set_data_dev(t10, t10_value);
38049                         if ((!current || dirty & /*aPlace*/ 1) && t12_value !== (t12_value = /*aPlace*/ ctx[0].type + "")) set_data_dev(t12, t12_value);
38050                         if ((!current || dirty & /*aPlace*/ 1) && t16_value !== (t16_value = /*aPlace*/ ctx[0].indexed_date + "")) set_data_dev(t16, t16_value);
38051                         if (dirty & /*aPlace*/ 1) show_if = isAdminBoundary_1(/*aPlace*/ ctx[0]);
38052
38053                         if (show_if) {
38054                                 if (if_block0) {
38055                                         if_block0.p(ctx, dirty);
38056                                 } else {
38057                                         if_block0 = create_if_block_11(ctx);
38058                                         if_block0.c();
38059                                         if_block0.m(tbody0, t18);
38060                                 }
38061                         } else if (if_block0) {
38062                                 if_block0.d(1);
38063                                 if_block0 = null;
38064                         }
38065
38066                         if ((!current || dirty & /*aPlace*/ 1) && t21_value !== (t21_value = /*aPlace*/ ctx[0].rank_search + "")) set_data_dev(t21, t21_value);
38067                         if ((!current || dirty & /*aPlace*/ 1) && t25_value !== (t25_value = /*aPlace*/ ctx[0].rank_address + "")) set_data_dev(t25, t25_value);
38068                         if ((!current || dirty & /*aPlace*/ 1) && t27_value !== (t27_value = formatAddressRank_1(/*aPlace*/ ctx[0].rank_address) + "")) set_data_dev(t27, t27_value);
38069
38070                         if (/*aPlace*/ ctx[0].calculated_importance) {
38071                                 if (if_block1) {
38072                                         if_block1.p(ctx, dirty);
38073                                 } else {
38074                                         if_block1 = create_if_block_9(ctx);
38075                                         if_block1.c();
38076                                         if_block1.m(tbody0, t30);
38077                                 }
38078                         } else if (if_block1) {
38079                                 if_block1.d(1);
38080                                 if_block1 = null;
38081                         }
38082
38083                         if ((!current || dirty & /*aPlace*/ 1) && t33_value !== (t33_value = coverageType_1(/*aPlace*/ ctx[0]) + "")) set_data_dev(t33, t33_value);
38084                         if ((!current || dirty & /*aPlace*/ 1) && t37_value !== (t37_value = /*aPlace*/ ctx[0].centroid.coordinates[1] + "")) set_data_dev(t37, t37_value);
38085                         if ((!current || dirty & /*aPlace*/ 1) && t39_value !== (t39_value = /*aPlace*/ ctx[0].centroid.coordinates[0] + "")) set_data_dev(t39, t39_value);
38086                         if ((!current || dirty & /*aPlace*/ 1) && raw_value !== (raw_value = osmLink_1(/*aPlace*/ ctx[0]) + "")) td15.innerHTML = raw_value;                    if ((!current || dirty & /*aPlace*/ 1) && t48_value !== (t48_value = /*aPlace*/ ctx[0].place_id + "")) set_data_dev(t48, t48_value);
38087
38088                         if (/*aPlace*/ ctx[0].calculated_wikipedia) {
38089                                 if (if_block2) {
38090                                         if_block2.p(ctx, dirty);
38091                                 } else {
38092                                         if_block2 = create_if_block_8(ctx);
38093                                         if_block2.c();
38094                                         if_block2.m(tbody0, t50);
38095                                 }
38096                         } else if (if_block2) {
38097                                 if_block2.d(1);
38098                                 if_block2 = null;
38099                         }
38100
38101                         if ((!current || dirty & /*aPlace*/ 1) && t53_value !== (t53_value = /*aPlace*/ ctx[0].calculated_postcode + "")) set_data_dev(t53, t53_value);
38102
38103                         if (dirty & /*Object, aPlace*/ 1) {
38104                                 each_value_7 = Object.keys(/*aPlace*/ ctx[0].addresstags);
38105                                 validate_each_argument(each_value_7);
38106                                 let i;
38107
38108                                 for (i = 0; i < each_value_7.length; i += 1) {
38109                                         const child_ctx = get_each_context_7(ctx, each_value_7, i);
38110
38111                                         if (each_blocks_1[i]) {
38112                                                 each_blocks_1[i].p(child_ctx, dirty);
38113                                         } else {
38114                                                 each_blocks_1[i] = create_each_block_7(child_ctx);
38115                                                 each_blocks_1[i].c();
38116                                                 each_blocks_1[i].m(td21, null);
38117                                         }
38118                                 }
38119
38120                                 for (; i < each_blocks_1.length; i += 1) {
38121                                         each_blocks_1[i].d(1);
38122                                 }
38123
38124                                 each_blocks_1.length = each_value_7.length;
38125                         }
38126
38127                         if (dirty & /*Object, aPlace*/ 1) {
38128                                 each_value_6 = Object.keys(/*aPlace*/ ctx[0].extratags);
38129                                 validate_each_argument(each_value_6);
38130                                 let i;
38131
38132                                 for (i = 0; i < each_value_6.length; i += 1) {
38133                                         const child_ctx = get_each_context_6(ctx, each_value_6, i);
38134
38135                                         if (each_blocks[i]) {
38136                                                 each_blocks[i].p(child_ctx, dirty);
38137                                         } else {
38138                                                 each_blocks[i] = create_each_block_6(child_ctx);
38139                                                 each_blocks[i].c();
38140                                                 each_blocks[i].m(td23, null);
38141                                         }
38142                                 }
38143
38144                                 for (; i < each_blocks.length; i += 1) {
38145                                         each_blocks[i].d(1);
38146                                 }
38147
38148                                 each_blocks.length = each_value_6.length;
38149                         }
38150
38151                         if (/*aPlace*/ ctx[0].address) {
38152                                 if (if_block3) {
38153                                         if_block3.p(ctx, dirty);
38154
38155                                         if (dirty & /*aPlace*/ 1) {
38156                                                 transition_in(if_block3, 1);
38157                                         }
38158                                 } else {
38159                                         if_block3 = create_if_block_7(ctx);
38160                                         if_block3.c();
38161                                         transition_in(if_block3, 1);
38162                                         if_block3.m(tbody1, t77);
38163                                 }
38164                         } else if (if_block3) {
38165                                 group_outros();
38166
38167                                 transition_out(if_block3, 1, 1, () => {
38168                                         if_block3 = null;
38169                                 });
38170
38171                                 check_outros();
38172                         }
38173
38174                         if (/*aPlace*/ ctx[0].linked_places) {
38175                                 if (if_block4) {
38176                                         if_block4.p(ctx, dirty);
38177
38178                                         if (dirty & /*aPlace*/ 1) {
38179                                                 transition_in(if_block4, 1);
38180                                         }
38181                                 } else {
38182                                         if_block4 = create_if_block_6(ctx);
38183                                         if_block4.c();
38184                                         transition_in(if_block4, 1);
38185                                         if_block4.m(tbody1, t78);
38186                                 }
38187                         } else if (if_block4) {
38188                                 group_outros();
38189
38190                                 transition_out(if_block4, 1, 1, () => {
38191                                         if_block4 = null;
38192                                 });
38193
38194                                 check_outros();
38195                         }
38196
38197                         if (current_block_type === (current_block_type = select_block_type_1(ctx)) && if_block5) {
38198                                 if_block5.p(ctx, dirty);
38199                         } else {
38200                                 if_block5.d(1);
38201                                 if_block5 = current_block_type(ctx);
38202
38203                                 if (if_block5) {
38204                                         if_block5.c();
38205                                         if_block5.m(tbody1, t81);
38206                                 }
38207                         }
38208
38209                         let previous_block_index = current_block_type_index;
38210                         current_block_type_index = select_block_type_2(ctx);
38211
38212                         if (current_block_type_index === previous_block_index) {
38213                                 if_blocks[current_block_type_index].p(ctx, dirty);
38214                         } else {
38215                                 group_outros();
38216
38217                                 transition_out(if_blocks[previous_block_index], 1, 1, () => {
38218                                         if_blocks[previous_block_index] = null;
38219                                 });
38220
38221                                 check_outros();
38222                                 if_block6 = if_blocks[current_block_type_index];
38223
38224                                 if (!if_block6) {
38225                                         if_block6 = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
38226                                         if_block6.c();
38227                                 } else {
38228                                         if_block6.p(ctx, dirty);
38229                                 }
38230
38231                                 transition_in(if_block6, 1);
38232                                 if_block6.m(tbody1, null);
38233                         }
38234                 },
38235                 i: function intro(local) {
38236                         if (current) return;
38237                         transition_in(mapicon.$$.fragment, local);
38238                         transition_in(map.$$.fragment, local);
38239                         transition_in(if_block3);
38240                         transition_in(if_block4);
38241                         transition_in(if_block6);
38242                         current = true;
38243                 },
38244                 o: function outro(local) {
38245                         transition_out(mapicon.$$.fragment, local);
38246                         transition_out(map.$$.fragment, local);
38247                         transition_out(if_block3);
38248                         transition_out(if_block4);
38249                         transition_out(if_block6);
38250                         current = false;
38251                 },
38252                 d: function destroy(detaching) {
38253                         if (detaching) detach_dev(div9);
38254                         destroy_component(mapicon);
38255                         destroy_each(each_blocks_2, detaching);
38256                         if (if_block0) if_block0.d();
38257                         if (if_block1) if_block1.d();
38258                         if (if_block2) if_block2.d();
38259                         destroy_each(each_blocks_1, detaching);
38260                         destroy_each(each_blocks, detaching);
38261                         destroy_component(map);
38262                         if (if_block3) if_block3.d();
38263                         if (if_block4) if_block4.d();
38264                         if_block5.d();
38265                         if_blocks[current_block_type_index].d();
38266                 }
38267         };
38268
38269         dispatch_dev("SvelteRegisterBlock", {
38270                 block,
38271                 id: create_if_block$5.name,
38272                 type: "if",
38273                 source: "(53:0) {#if aPlace}",
38274                 ctx
38275         });
38276
38277         return block;
38278     }
38279
38280     // (73:16) {#each Object.keys(aPlace.names) as name}
38281     function create_each_block_8(ctx) {
38282         let div;
38283         let span;
38284         let t0_value = /*aPlace*/ ctx[0].names[/*name*/ ctx[19]] + "";
38285         let t0;
38286         let t1;
38287         let t2_value = /*name*/ ctx[19] + "";
38288         let t2;
38289         let t3;
38290
38291         const block = {
38292                 c: function create() {
38293                         div = element("div");
38294                         span = element("span");
38295                         t0 = text(t0_value);
38296                         t1 = text(" (");
38297                         t2 = text(t2_value);
38298                         t3 = text(")\n                  ");
38299                         attr_dev(span, "class", "name svelte-j6zgmy");
38300                         add_location(span, file$c, 74, 20, 2370);
38301                         attr_dev(div, "class", "line");
38302                         add_location(div, file$c, 73, 18, 2331);
38303                 },
38304                 m: function mount(target, anchor) {
38305                         insert_dev(target, div, anchor);
38306                         append_dev(div, span);
38307                         append_dev(span, t0);
38308                         append_dev(div, t1);
38309                         append_dev(div, t2);
38310                         append_dev(div, t3);
38311                 },
38312                 p: function update(ctx, dirty) {
38313                         if (dirty & /*aPlace*/ 1 && t0_value !== (t0_value = /*aPlace*/ ctx[0].names[/*name*/ ctx[19]] + "")) set_data_dev(t0, t0_value);
38314                         if (dirty & /*aPlace*/ 1 && t2_value !== (t2_value = /*name*/ ctx[19] + "")) set_data_dev(t2, t2_value);
38315                 },
38316                 d: function destroy(detaching) {
38317                         if (detaching) detach_dev(div);
38318                 }
38319         };
38320
38321         dispatch_dev("SvelteRegisterBlock", {
38322                 block,
38323                 id: create_each_block_8.name,
38324                 type: "each",
38325                 source: "(73:16) {#each Object.keys(aPlace.names) as name}",
38326                 ctx
38327         });
38328
38329         return block;
38330     }
38331
38332     // (88:12) {#if (isAdminBoundary(aPlace)) }
38333     function create_if_block_11(ctx) {
38334         let tr;
38335         let td0;
38336         let t1;
38337         let td1;
38338         let t2_value = /*aPlace*/ ctx[0].admin_level + "";
38339         let t2;
38340
38341         const block = {
38342                 c: function create() {
38343                         tr = element("tr");
38344                         td0 = element("td");
38345                         td0.textContent = "Admin Level";
38346                         t1 = space();
38347                         td1 = element("td");
38348                         t2 = text(t2_value);
38349                         attr_dev(td0, "class", "svelte-j6zgmy");
38350                         add_location(td0, file$c, 89, 14, 2823);
38351                         attr_dev(td1, "class", "svelte-j6zgmy");
38352                         add_location(td1, file$c, 90, 14, 2858);
38353                         attr_dev(tr, "class", "svelte-j6zgmy");
38354                         add_location(tr, file$c, 88, 12, 2804);
38355                 },
38356                 m: function mount(target, anchor) {
38357                         insert_dev(target, tr, anchor);
38358                         append_dev(tr, td0);
38359                         append_dev(tr, t1);
38360                         append_dev(tr, td1);
38361                         append_dev(td1, t2);
38362                 },
38363                 p: function update(ctx, dirty) {
38364                         if (dirty & /*aPlace*/ 1 && t2_value !== (t2_value = /*aPlace*/ ctx[0].admin_level + "")) set_data_dev(t2, t2_value);
38365                 },
38366                 d: function destroy(detaching) {
38367                         if (detaching) detach_dev(tr);
38368                 }
38369         };
38370
38371         dispatch_dev("SvelteRegisterBlock", {
38372                 block,
38373                 id: create_if_block_11.name,
38374                 type: "if",
38375                 source: "(88:12) {#if (isAdminBoundary(aPlace)) }",
38376                 ctx
38377         });
38378
38379         return block;
38380     }
38381
38382     // (102:12) {#if aPlace.calculated_importance}
38383     function create_if_block_9(ctx) {
38384         let tr;
38385         let td0;
38386         let t1;
38387         let td1;
38388         let t2_value = /*aPlace*/ ctx[0].calculated_importance + "";
38389         let t2;
38390         let t3;
38391         let if_block = !/*aPlace*/ ctx[0].importance && create_if_block_10(ctx);
38392
38393         const block = {
38394                 c: function create() {
38395                         tr = element("tr");
38396                         td0 = element("td");
38397                         td0.textContent = "Importance";
38398                         t1 = space();
38399                         td1 = element("td");
38400                         t2 = text(t2_value);
38401                         t3 = space();
38402                         if (if_block) if_block.c();
38403                         attr_dev(td0, "class", "svelte-j6zgmy");
38404                         add_location(td0, file$c, 103, 16, 3279);
38405                         attr_dev(td1, "class", "svelte-j6zgmy");
38406                         add_location(td1, file$c, 104, 16, 3315);
38407                         attr_dev(tr, "class", "svelte-j6zgmy");
38408                         add_location(tr, file$c, 102, 14, 3258);
38409                 },
38410                 m: function mount(target, anchor) {
38411                         insert_dev(target, tr, anchor);
38412                         append_dev(tr, td0);
38413                         append_dev(tr, t1);
38414                         append_dev(tr, td1);
38415                         append_dev(td1, t2);
38416                         append_dev(td1, t3);
38417                         if (if_block) if_block.m(td1, null);
38418                 },
38419                 p: function update(ctx, dirty) {
38420                         if (dirty & /*aPlace*/ 1 && t2_value !== (t2_value = /*aPlace*/ ctx[0].calculated_importance + "")) set_data_dev(t2, t2_value);
38421
38422                         if (!/*aPlace*/ ctx[0].importance) {
38423                                 if (if_block) ; else {
38424                                         if_block = create_if_block_10(ctx);
38425                                         if_block.c();
38426                                         if_block.m(td1, null);
38427                                 }
38428                         } else if (if_block) {
38429                                 if_block.d(1);
38430                                 if_block = null;
38431                         }
38432                 },
38433                 d: function destroy(detaching) {
38434                         if (detaching) detach_dev(tr);
38435                         if (if_block) if_block.d();
38436                 }
38437         };
38438
38439         dispatch_dev("SvelteRegisterBlock", {
38440                 block,
38441                 id: create_if_block_9.name,
38442                 type: "if",
38443                 source: "(102:12) {#if aPlace.calculated_importance}",
38444                 ctx
38445         });
38446
38447         return block;
38448     }
38449
38450     // (107:18) {#if !aPlace.importance}
38451     function create_if_block_10(ctx) {
38452         let t;
38453
38454         const block = {
38455                 c: function create() {
38456                         t = text("(estimated)");
38457                 },
38458                 m: function mount(target, anchor) {
38459                         insert_dev(target, t, anchor);
38460                 },
38461                 d: function destroy(detaching) {
38462                         if (detaching) detach_dev(t);
38463                 }
38464         };
38465
38466         dispatch_dev("SvelteRegisterBlock", {
38467                 block,
38468                 id: create_if_block_10.name,
38469                 type: "if",
38470                 source: "(107:18) {#if !aPlace.importance}",
38471                 ctx
38472         });
38473
38474         return block;
38475     }
38476
38477     // (132:12) {#if aPlace.calculated_wikipedia}
38478     function create_if_block_8(ctx) {
38479         let tr;
38480         let td0;
38481         let t1;
38482         let td1;
38483         let raw_value = wikipediaLink_1(/*aPlace*/ ctx[0]) + "";
38484
38485         const block = {
38486                 c: function create() {
38487                         tr = element("tr");
38488                         td0 = element("td");
38489                         td0.textContent = "Wikipedia Calculated";
38490                         t1 = space();
38491                         td1 = element("td");
38492                         attr_dev(td0, "class", "svelte-j6zgmy");
38493                         add_location(td0, file$c, 133, 16, 4263);
38494                         attr_dev(td1, "class", "svelte-j6zgmy");
38495                         add_location(td1, file$c, 134, 16, 4309);
38496                         attr_dev(tr, "class", "svelte-j6zgmy");
38497                         add_location(tr, file$c, 132, 14, 4242);
38498                 },
38499                 m: function mount(target, anchor) {
38500                         insert_dev(target, tr, anchor);
38501                         append_dev(tr, td0);
38502                         append_dev(tr, t1);
38503                         append_dev(tr, td1);
38504                         td1.innerHTML = raw_value;
38505                 },
38506                 p: function update(ctx, dirty) {
38507                         if (dirty & /*aPlace*/ 1 && raw_value !== (raw_value = wikipediaLink_1(/*aPlace*/ ctx[0]) + "")) td1.innerHTML = raw_value;             },
38508                 d: function destroy(detaching) {
38509                         if (detaching) detach_dev(tr);
38510                 }
38511         };
38512
38513         dispatch_dev("SvelteRegisterBlock", {
38514                 block,
38515                 id: create_if_block_8.name,
38516                 type: "if",
38517                 source: "(132:12) {#if aPlace.calculated_wikipedia}",
38518                 ctx
38519         });
38520
38521         return block;
38522     }
38523
38524     // (145:16) {#each Object.keys(aPlace.addresstags) as name}
38525     function create_each_block_7(ctx) {
38526         let div;
38527         let span;
38528         let t0_value = /*aPlace*/ ctx[0].addresstags[/*name*/ ctx[19]] + "";
38529         let t0;
38530         let t1;
38531         let t2_value = /*name*/ ctx[19] + "";
38532         let t2;
38533         let t3;
38534
38535         const block = {
38536                 c: function create() {
38537                         div = element("div");
38538                         span = element("span");
38539                         t0 = text(t0_value);
38540                         t1 = text(" (");
38541                         t2 = text(t2_value);
38542                         t3 = text(")\n                  ");
38543                         attr_dev(span, "class", "name svelte-j6zgmy");
38544                         add_location(span, file$c, 146, 20, 4707);
38545                         attr_dev(div, "class", "line");
38546                         add_location(div, file$c, 145, 18, 4668);
38547                 },
38548                 m: function mount(target, anchor) {
38549                         insert_dev(target, div, anchor);
38550                         append_dev(div, span);
38551                         append_dev(span, t0);
38552                         append_dev(div, t1);
38553                         append_dev(div, t2);
38554                         append_dev(div, t3);
38555                 },
38556                 p: function update(ctx, dirty) {
38557                         if (dirty & /*aPlace*/ 1 && t0_value !== (t0_value = /*aPlace*/ ctx[0].addresstags[/*name*/ ctx[19]] + "")) set_data_dev(t0, t0_value);
38558                         if (dirty & /*aPlace*/ 1 && t2_value !== (t2_value = /*name*/ ctx[19] + "")) set_data_dev(t2, t2_value);
38559                 },
38560                 d: function destroy(detaching) {
38561                         if (detaching) detach_dev(div);
38562                 }
38563         };
38564
38565         dispatch_dev("SvelteRegisterBlock", {
38566                 block,
38567                 id: create_each_block_7.name,
38568                 type: "each",
38569                 source: "(145:16) {#each Object.keys(aPlace.addresstags) as name}",
38570                 ctx
38571         });
38572
38573         return block;
38574     }
38575
38576     // (155:16) {#each Object.keys(aPlace.extratags) as name}
38577     function create_each_block_6(ctx) {
38578         let div;
38579         let span;
38580         let t0_value = /*aPlace*/ ctx[0].extratags[/*name*/ ctx[19]] + "";
38581         let t0;
38582         let t1;
38583         let t2_value = /*name*/ ctx[19] + "";
38584         let t2;
38585         let t3;
38586
38587         const block = {
38588                 c: function create() {
38589                         div = element("div");
38590                         span = element("span");
38591                         t0 = text(t0_value);
38592                         t1 = text(" (");
38593                         t2 = text(t2_value);
38594                         t3 = text(")\n                  ");
38595                         attr_dev(span, "class", "name svelte-j6zgmy");
38596                         add_location(span, file$c, 156, 20, 5045);
38597                         attr_dev(div, "class", "line");
38598                         add_location(div, file$c, 155, 18, 5006);
38599                 },
38600                 m: function mount(target, anchor) {
38601                         insert_dev(target, div, anchor);
38602                         append_dev(div, span);
38603                         append_dev(span, t0);
38604                         append_dev(div, t1);
38605                         append_dev(div, t2);
38606                         append_dev(div, t3);
38607                 },
38608                 p: function update(ctx, dirty) {
38609                         if (dirty & /*aPlace*/ 1 && t0_value !== (t0_value = /*aPlace*/ ctx[0].extratags[/*name*/ ctx[19]] + "")) set_data_dev(t0, t0_value);
38610                         if (dirty & /*aPlace*/ 1 && t2_value !== (t2_value = /*name*/ ctx[19] + "")) set_data_dev(t2, t2_value);
38611                 },
38612                 d: function destroy(detaching) {
38613                         if (detaching) detach_dev(div);
38614                 }
38615         };
38616
38617         dispatch_dev("SvelteRegisterBlock", {
38618                 block,
38619                 id: create_each_block_6.name,
38620                 type: "each",
38621                 source: "(155:16) {#each Object.keys(aPlace.extratags) as name}",
38622                 ctx
38623         });
38624
38625         return block;
38626     }
38627
38628     // (187:12) {#if aPlace.address}
38629     function create_if_block_7(ctx) {
38630         let each_1_anchor;
38631         let current;
38632         let each_value_5 = /*aPlace*/ ctx[0].address;
38633         validate_each_argument(each_value_5);
38634         let each_blocks = [];
38635
38636         for (let i = 0; i < each_value_5.length; i += 1) {
38637                 each_blocks[i] = create_each_block_5(get_each_context_5(ctx, each_value_5, i));
38638         }
38639
38640         const out = i => transition_out(each_blocks[i], 1, 1, () => {
38641                 each_blocks[i] = null;
38642         });
38643
38644         const block = {
38645                 c: function create() {
38646                         for (let i = 0; i < each_blocks.length; i += 1) {
38647                                 each_blocks[i].c();
38648                         }
38649
38650                         each_1_anchor = empty();
38651                 },
38652                 m: function mount(target, anchor) {
38653                         for (let i = 0; i < each_blocks.length; i += 1) {
38654                                 each_blocks[i].m(target, anchor);
38655                         }
38656
38657                         insert_dev(target, each_1_anchor, anchor);
38658                         current = true;
38659                 },
38660                 p: function update(ctx, dirty) {
38661                         if (dirty & /*aPlace*/ 1) {
38662                                 each_value_5 = /*aPlace*/ ctx[0].address;
38663                                 validate_each_argument(each_value_5);
38664                                 let i;
38665
38666                                 for (i = 0; i < each_value_5.length; i += 1) {
38667                                         const child_ctx = get_each_context_5(ctx, each_value_5, i);
38668
38669                                         if (each_blocks[i]) {
38670                                                 each_blocks[i].p(child_ctx, dirty);
38671                                                 transition_in(each_blocks[i], 1);
38672                                         } else {
38673                                                 each_blocks[i] = create_each_block_5(child_ctx);
38674                                                 each_blocks[i].c();
38675                                                 transition_in(each_blocks[i], 1);
38676                                                 each_blocks[i].m(each_1_anchor.parentNode, each_1_anchor);
38677                                         }
38678                                 }
38679
38680                                 group_outros();
38681
38682                                 for (i = each_value_5.length; i < each_blocks.length; i += 1) {
38683                                         out(i);
38684                                 }
38685
38686                                 check_outros();
38687                         }
38688                 },
38689                 i: function intro(local) {
38690                         if (current) return;
38691
38692                         for (let i = 0; i < each_value_5.length; i += 1) {
38693                                 transition_in(each_blocks[i]);
38694                         }
38695
38696                         current = true;
38697                 },
38698                 o: function outro(local) {
38699                         each_blocks = each_blocks.filter(Boolean);
38700
38701                         for (let i = 0; i < each_blocks.length; i += 1) {
38702                                 transition_out(each_blocks[i]);
38703                         }
38704
38705                         current = false;
38706                 },
38707                 d: function destroy(detaching) {
38708                         destroy_each(each_blocks, detaching);
38709                         if (detaching) detach_dev(each_1_anchor);
38710                 }
38711         };
38712
38713         dispatch_dev("SvelteRegisterBlock", {
38714                 block,
38715                 id: create_if_block_7.name,
38716                 type: "if",
38717                 source: "(187:12) {#if aPlace.address}",
38718                 ctx
38719         });
38720
38721         return block;
38722     }
38723
38724     // (188:14) {#each aPlace.address as addressLine}
38725     function create_each_block_5(ctx) {
38726         let detailsonerow;
38727         let current;
38728
38729         detailsonerow = new DetailsOneRow({
38730                         props: {
38731                                 addressLine: /*addressLine*/ ctx[14],
38732                                 bDistanceInMeters: "false"
38733                         },
38734                         $$inline: true
38735                 });
38736
38737         const block = {
38738                 c: function create() {
38739                         create_component(detailsonerow.$$.fragment);
38740                 },
38741                 m: function mount(target, anchor) {
38742                         mount_component(detailsonerow, target, anchor);
38743                         current = true;
38744                 },
38745                 p: function update(ctx, dirty) {
38746                         const detailsonerow_changes = {};
38747                         if (dirty & /*aPlace*/ 1) detailsonerow_changes.addressLine = /*addressLine*/ ctx[14];
38748                         detailsonerow.$set(detailsonerow_changes);
38749                 },
38750                 i: function intro(local) {
38751                         if (current) return;
38752                         transition_in(detailsonerow.$$.fragment, local);
38753                         current = true;
38754                 },
38755                 o: function outro(local) {
38756                         transition_out(detailsonerow.$$.fragment, local);
38757                         current = false;
38758                 },
38759                 d: function destroy(detaching) {
38760                         destroy_component(detailsonerow, detaching);
38761                 }
38762         };
38763
38764         dispatch_dev("SvelteRegisterBlock", {
38765                 block,
38766                 id: create_each_block_5.name,
38767                 type: "each",
38768                 source: "(188:14) {#each aPlace.address as addressLine}",
38769                 ctx
38770         });
38771
38772         return block;
38773     }
38774
38775     // (193:12) {#if aPlace.linked_places}
38776     function create_if_block_6(ctx) {
38777         let tr;
38778         let td;
38779         let h2;
38780         let t1;
38781         let each_1_anchor;
38782         let current;
38783         let each_value_4 = /*aPlace*/ ctx[0].linked_places;
38784         validate_each_argument(each_value_4);
38785         let each_blocks = [];
38786
38787         for (let i = 0; i < each_value_4.length; i += 1) {
38788                 each_blocks[i] = create_each_block_4(get_each_context_4(ctx, each_value_4, i));
38789         }
38790
38791         const out = i => transition_out(each_blocks[i], 1, 1, () => {
38792                 each_blocks[i] = null;
38793         });
38794
38795         const block = {
38796                 c: function create() {
38797                         tr = element("tr");
38798                         td = element("td");
38799                         h2 = element("h2");
38800                         h2.textContent = "Linked Places";
38801                         t1 = space();
38802
38803                         for (let i = 0; i < each_blocks.length; i += 1) {
38804                                 each_blocks[i].c();
38805                         }
38806
38807                         each_1_anchor = empty();
38808                         attr_dev(h2, "class", "svelte-j6zgmy");
38809                         add_location(h2, file$c, 193, 54, 6113);
38810                         attr_dev(td, "colspan", "6");
38811                         attr_dev(td, "class", "svelte-j6zgmy");
38812                         add_location(td, file$c, 193, 38, 6097);
38813                         attr_dev(tr, "class", "all-columns svelte-j6zgmy");
38814                         add_location(tr, file$c, 193, 14, 6073);
38815                 },
38816                 m: function mount(target, anchor) {
38817                         insert_dev(target, tr, anchor);
38818                         append_dev(tr, td);
38819                         append_dev(td, h2);
38820                         insert_dev(target, t1, anchor);
38821
38822                         for (let i = 0; i < each_blocks.length; i += 1) {
38823                                 each_blocks[i].m(target, anchor);
38824                         }
38825
38826                         insert_dev(target, each_1_anchor, anchor);
38827                         current = true;
38828                 },
38829                 p: function update(ctx, dirty) {
38830                         if (dirty & /*aPlace*/ 1) {
38831                                 each_value_4 = /*aPlace*/ ctx[0].linked_places;
38832                                 validate_each_argument(each_value_4);
38833                                 let i;
38834
38835                                 for (i = 0; i < each_value_4.length; i += 1) {
38836                                         const child_ctx = get_each_context_4(ctx, each_value_4, i);
38837
38838                                         if (each_blocks[i]) {
38839                                                 each_blocks[i].p(child_ctx, dirty);
38840                                                 transition_in(each_blocks[i], 1);
38841                                         } else {
38842                                                 each_blocks[i] = create_each_block_4(child_ctx);
38843                                                 each_blocks[i].c();
38844                                                 transition_in(each_blocks[i], 1);
38845                                                 each_blocks[i].m(each_1_anchor.parentNode, each_1_anchor);
38846                                         }
38847                                 }
38848
38849                                 group_outros();
38850
38851                                 for (i = each_value_4.length; i < each_blocks.length; i += 1) {
38852                                         out(i);
38853                                 }
38854
38855                                 check_outros();
38856                         }
38857                 },
38858                 i: function intro(local) {
38859                         if (current) return;
38860
38861                         for (let i = 0; i < each_value_4.length; i += 1) {
38862                                 transition_in(each_blocks[i]);
38863                         }
38864
38865                         current = true;
38866                 },
38867                 o: function outro(local) {
38868                         each_blocks = each_blocks.filter(Boolean);
38869
38870                         for (let i = 0; i < each_blocks.length; i += 1) {
38871                                 transition_out(each_blocks[i]);
38872                         }
38873
38874                         current = false;
38875                 },
38876                 d: function destroy(detaching) {
38877                         if (detaching) detach_dev(tr);
38878                         if (detaching) detach_dev(t1);
38879                         destroy_each(each_blocks, detaching);
38880                         if (detaching) detach_dev(each_1_anchor);
38881                 }
38882         };
38883
38884         dispatch_dev("SvelteRegisterBlock", {
38885                 block,
38886                 id: create_if_block_6.name,
38887                 type: "if",
38888                 source: "(193:12) {#if aPlace.linked_places}",
38889                 ctx
38890         });
38891
38892         return block;
38893     }
38894
38895     // (195:14) {#each aPlace.linked_places as addressLine}
38896     function create_each_block_4(ctx) {
38897         let detailsonerow;
38898         let current;
38899
38900         detailsonerow = new DetailsOneRow({
38901                         props: {
38902                                 addressLine: /*addressLine*/ ctx[14],
38903                                 bDistanceInMeters: "true"
38904                         },
38905                         $$inline: true
38906                 });
38907
38908         const block = {
38909                 c: function create() {
38910                         create_component(detailsonerow.$$.fragment);
38911                 },
38912                 m: function mount(target, anchor) {
38913                         mount_component(detailsonerow, target, anchor);
38914                         current = true;
38915                 },
38916                 p: function update(ctx, dirty) {
38917                         const detailsonerow_changes = {};
38918                         if (dirty & /*aPlace*/ 1) detailsonerow_changes.addressLine = /*addressLine*/ ctx[14];
38919                         detailsonerow.$set(detailsonerow_changes);
38920                 },
38921                 i: function intro(local) {
38922                         if (current) return;
38923                         transition_in(detailsonerow.$$.fragment, local);
38924                         current = true;
38925                 },
38926                 o: function outro(local) {
38927                         transition_out(detailsonerow.$$.fragment, local);
38928                         current = false;
38929                 },
38930                 d: function destroy(detaching) {
38931                         destroy_component(detailsonerow, detaching);
38932                 }
38933         };
38934
38935         dispatch_dev("SvelteRegisterBlock", {
38936                 block,
38937                 id: create_each_block_4.name,
38938                 type: "each",
38939                 source: "(195:14) {#each aPlace.linked_places as addressLine}",
38940                 ctx
38941         });
38942
38943         return block;
38944     }
38945
38946     // (221:12) {:else}
38947     function create_else_block_1$1(ctx) {
38948         let tr;
38949         let td;
38950         let a;
38951         let t;
38952
38953         const block = {
38954                 c: function create() {
38955                         tr = element("tr");
38956                         td = element("td");
38957                         a = element("a");
38958                         t = text("display keywords");
38959                         attr_dev(a, "class", "btn btn-outline-secondary btn-sm");
38960                         attr_dev(a, "href", "" + (/*base_url*/ ctx[1] + "&keywords=1"));
38961                         add_location(a, file$c, 223, 19, 7284);
38962                         attr_dev(td, "class", "svelte-j6zgmy");
38963                         add_location(td, file$c, 222, 16, 7260);
38964                         attr_dev(tr, "class", "svelte-j6zgmy");
38965                         add_location(tr, file$c, 221, 14, 7239);
38966                 },
38967                 m: function mount(target, anchor) {
38968                         insert_dev(target, tr, anchor);
38969                         append_dev(tr, td);
38970                         append_dev(td, a);
38971                         append_dev(a, t);
38972                 },
38973                 p: noop,
38974                 d: function destroy(detaching) {
38975                         if (detaching) detach_dev(tr);
38976                 }
38977         };
38978
38979         dispatch_dev("SvelteRegisterBlock", {
38980                 block,
38981                 id: create_else_block_1$1.name,
38982                 type: "else",
38983                 source: "(221:12) {:else}",
38984                 ctx
38985         });
38986
38987         return block;
38988     }
38989
38990     // (201:12) {#if aPlace.keywords}
38991     function create_if_block_3$1(ctx) {
38992         let tr0;
38993         let td0;
38994         let h30;
38995         let t1;
38996         let t2;
38997         let tr1;
38998         let td1;
38999         let h31;
39000         let t4;
39001         let each1_anchor;
39002         let each_value_3 = /*aPlace*/ ctx[0].keywords.name;
39003         validate_each_argument(each_value_3);
39004         let each_blocks_1 = [];
39005
39006         for (let i = 0; i < each_value_3.length; i += 1) {
39007                 each_blocks_1[i] = create_each_block_3(get_each_context_3(ctx, each_value_3, i));
39008         }
39009
39010         let each_value_2 = /*aPlace*/ ctx[0].keywords.address;
39011         validate_each_argument(each_value_2);
39012         let each_blocks = [];
39013
39014         for (let i = 0; i < each_value_2.length; i += 1) {
39015                 each_blocks[i] = create_each_block_2(get_each_context_2(ctx, each_value_2, i));
39016         }
39017
39018         const block = {
39019                 c: function create() {
39020                         tr0 = element("tr");
39021                         td0 = element("td");
39022                         h30 = element("h3");
39023                         h30.textContent = "Name Keywords";
39024                         t1 = space();
39025
39026                         for (let i = 0; i < each_blocks_1.length; i += 1) {
39027                                 each_blocks_1[i].c();
39028                         }
39029
39030                         t2 = space();
39031                         tr1 = element("tr");
39032                         td1 = element("td");
39033                         h31 = element("h3");
39034                         h31.textContent = "Address Keywords";
39035                         t4 = space();
39036
39037                         for (let i = 0; i < each_blocks.length; i += 1) {
39038                                 each_blocks[i].c();
39039                         }
39040
39041                         each1_anchor = empty();
39042                         attr_dev(h30, "class", "svelte-j6zgmy");
39043                         add_location(h30, file$c, 201, 54, 6496);
39044                         attr_dev(td0, "colspan", "6");
39045                         attr_dev(td0, "class", "svelte-j6zgmy");
39046                         add_location(td0, file$c, 201, 38, 6480);
39047                         attr_dev(tr0, "class", "all-columns svelte-j6zgmy");
39048                         add_location(tr0, file$c, 201, 14, 6456);
39049                         attr_dev(h31, "class", "svelte-j6zgmy");
39050                         add_location(h31, file$c, 211, 54, 6876);
39051                         attr_dev(td1, "colspan", "6");
39052                         attr_dev(td1, "class", "svelte-j6zgmy");
39053                         add_location(td1, file$c, 211, 38, 6860);
39054                         attr_dev(tr1, "class", "all-columns svelte-j6zgmy");
39055                         add_location(tr1, file$c, 211, 14, 6836);
39056                 },
39057                 m: function mount(target, anchor) {
39058                         insert_dev(target, tr0, anchor);
39059                         append_dev(tr0, td0);
39060                         append_dev(td0, h30);
39061                         insert_dev(target, t1, anchor);
39062
39063                         for (let i = 0; i < each_blocks_1.length; i += 1) {
39064                                 each_blocks_1[i].m(target, anchor);
39065                         }
39066
39067                         insert_dev(target, t2, anchor);
39068                         insert_dev(target, tr1, anchor);
39069                         append_dev(tr1, td1);
39070                         append_dev(td1, h31);
39071                         insert_dev(target, t4, anchor);
39072
39073                         for (let i = 0; i < each_blocks.length; i += 1) {
39074                                 each_blocks[i].m(target, anchor);
39075                         }
39076
39077                         insert_dev(target, each1_anchor, anchor);
39078                 },
39079                 p: function update(ctx, dirty) {
39080                         if (dirty & /*aPlace, formatKeywordToken*/ 1) {
39081                                 each_value_3 = /*aPlace*/ ctx[0].keywords.name;
39082                                 validate_each_argument(each_value_3);
39083                                 let i;
39084
39085                                 for (i = 0; i < each_value_3.length; i += 1) {
39086                                         const child_ctx = get_each_context_3(ctx, each_value_3, i);
39087
39088                                         if (each_blocks_1[i]) {
39089                                                 each_blocks_1[i].p(child_ctx, dirty);
39090                                         } else {
39091                                                 each_blocks_1[i] = create_each_block_3(child_ctx);
39092                                                 each_blocks_1[i].c();
39093                                                 each_blocks_1[i].m(t2.parentNode, t2);
39094                                         }
39095                                 }
39096
39097                                 for (; i < each_blocks_1.length; i += 1) {
39098                                         each_blocks_1[i].d(1);
39099                                 }
39100
39101                                 each_blocks_1.length = each_value_3.length;
39102                         }
39103
39104                         if (dirty & /*aPlace, formatKeywordToken*/ 1) {
39105                                 each_value_2 = /*aPlace*/ ctx[0].keywords.address;
39106                                 validate_each_argument(each_value_2);
39107                                 let i;
39108
39109                                 for (i = 0; i < each_value_2.length; i += 1) {
39110                                         const child_ctx = get_each_context_2(ctx, each_value_2, i);
39111
39112                                         if (each_blocks[i]) {
39113                                                 each_blocks[i].p(child_ctx, dirty);
39114                                         } else {
39115                                                 each_blocks[i] = create_each_block_2(child_ctx);
39116                                                 each_blocks[i].c();
39117                                                 each_blocks[i].m(each1_anchor.parentNode, each1_anchor);
39118                                         }
39119                                 }
39120
39121                                 for (; i < each_blocks.length; i += 1) {
39122                                         each_blocks[i].d(1);
39123                                 }
39124
39125                                 each_blocks.length = each_value_2.length;
39126                         }
39127                 },
39128                 d: function destroy(detaching) {
39129                         if (detaching) detach_dev(tr0);
39130                         if (detaching) detach_dev(t1);
39131                         destroy_each(each_blocks_1, detaching);
39132                         if (detaching) detach_dev(t2);
39133                         if (detaching) detach_dev(tr1);
39134                         if (detaching) detach_dev(t4);
39135                         destroy_each(each_blocks, detaching);
39136                         if (detaching) detach_dev(each1_anchor);
39137                 }
39138         };
39139
39140         dispatch_dev("SvelteRegisterBlock", {
39141                 block,
39142                 id: create_if_block_3$1.name,
39143                 type: "if",
39144                 source: "(201:12) {#if aPlace.keywords}",
39145                 ctx
39146         });
39147
39148         return block;
39149     }
39150
39151     // (206:18) {#if keyword.id}
39152     function create_if_block_5(ctx) {
39153         let td;
39154         let t0;
39155         let t1_value = /*keyword*/ ctx[9].id + "";
39156         let t1;
39157
39158         const block = {
39159                 c: function create() {
39160                         td = element("td");
39161                         t0 = text("word id: ");
39162                         t1 = text(t1_value);
39163                         attr_dev(td, "class", "svelte-j6zgmy");
39164                         add_location(td, file$c, 206, 20, 6722);
39165                 },
39166                 m: function mount(target, anchor) {
39167                         insert_dev(target, td, anchor);
39168                         append_dev(td, t0);
39169                         append_dev(td, t1);
39170                 },
39171                 p: function update(ctx, dirty) {
39172                         if (dirty & /*aPlace*/ 1 && t1_value !== (t1_value = /*keyword*/ ctx[9].id + "")) set_data_dev(t1, t1_value);
39173                 },
39174                 d: function destroy(detaching) {
39175                         if (detaching) detach_dev(td);
39176                 }
39177         };
39178
39179         dispatch_dev("SvelteRegisterBlock", {
39180                 block,
39181                 id: create_if_block_5.name,
39182                 type: "if",
39183                 source: "(206:18) {#if keyword.id}",
39184                 ctx
39185         });
39186
39187         return block;
39188     }
39189
39190     // (203:14) {#each aPlace.keywords.name as keyword}
39191     function create_each_block_3(ctx) {
39192         let tr;
39193         let td;
39194         let t0_value = formatKeywordToken_1(/*keyword*/ ctx[9].token) + "";
39195         let t0;
39196         let t1;
39197         let if_block = /*keyword*/ ctx[9].id && create_if_block_5(ctx);
39198
39199         const block = {
39200                 c: function create() {
39201                         tr = element("tr");
39202                         td = element("td");
39203                         t0 = text(t0_value);
39204                         t1 = space();
39205                         if (if_block) if_block.c();
39206                         attr_dev(td, "class", "svelte-j6zgmy");
39207                         add_location(td, file$c, 204, 18, 6622);
39208                         attr_dev(tr, "class", "svelte-j6zgmy");
39209                         add_location(tr, file$c, 203, 16, 6599);
39210                 },
39211                 m: function mount(target, anchor) {
39212                         insert_dev(target, tr, anchor);
39213                         append_dev(tr, td);
39214                         append_dev(td, t0);
39215                         append_dev(tr, t1);
39216                         if (if_block) if_block.m(tr, null);
39217                 },
39218                 p: function update(ctx, dirty) {
39219                         if (dirty & /*aPlace*/ 1 && t0_value !== (t0_value = formatKeywordToken_1(/*keyword*/ ctx[9].token) + "")) set_data_dev(t0, t0_value);
39220
39221                         if (/*keyword*/ ctx[9].id) {
39222                                 if (if_block) {
39223                                         if_block.p(ctx, dirty);
39224                                 } else {
39225                                         if_block = create_if_block_5(ctx);
39226                                         if_block.c();
39227                                         if_block.m(tr, null);
39228                                 }
39229                         } else if (if_block) {
39230                                 if_block.d(1);
39231                                 if_block = null;
39232                         }
39233                 },
39234                 d: function destroy(detaching) {
39235                         if (detaching) detach_dev(tr);
39236                         if (if_block) if_block.d();
39237                 }
39238         };
39239
39240         dispatch_dev("SvelteRegisterBlock", {
39241                 block,
39242                 id: create_each_block_3.name,
39243                 type: "each",
39244                 source: "(203:14) {#each aPlace.keywords.name as keyword}",
39245                 ctx
39246         });
39247
39248         return block;
39249     }
39250
39251     // (216:18) {#if keyword.id}
39252     function create_if_block_4(ctx) {
39253         let td;
39254         let t0;
39255         let t1_value = /*keyword*/ ctx[9].id + "";
39256         let t1;
39257
39258         const block = {
39259                 c: function create() {
39260                         td = element("td");
39261                         t0 = text("word id: ");
39262                         t1 = text(t1_value);
39263                         attr_dev(td, "class", "svelte-j6zgmy");
39264                         add_location(td, file$c, 216, 20, 7108);
39265                 },
39266                 m: function mount(target, anchor) {
39267                         insert_dev(target, td, anchor);
39268                         append_dev(td, t0);
39269                         append_dev(td, t1);
39270                 },
39271                 p: function update(ctx, dirty) {
39272                         if (dirty & /*aPlace*/ 1 && t1_value !== (t1_value = /*keyword*/ ctx[9].id + "")) set_data_dev(t1, t1_value);
39273                 },
39274                 d: function destroy(detaching) {
39275                         if (detaching) detach_dev(td);
39276                 }
39277         };
39278
39279         dispatch_dev("SvelteRegisterBlock", {
39280                 block,
39281                 id: create_if_block_4.name,
39282                 type: "if",
39283                 source: "(216:18) {#if keyword.id}",
39284                 ctx
39285         });
39286
39287         return block;
39288     }
39289
39290     // (213:14) {#each aPlace.keywords.address as keyword}
39291     function create_each_block_2(ctx) {
39292         let tr;
39293         let td;
39294         let t0_value = formatKeywordToken_1(/*keyword*/ ctx[9].token) + "";
39295         let t0;
39296         let t1;
39297         let t2;
39298         let if_block = /*keyword*/ ctx[9].id && create_if_block_4(ctx);
39299
39300         const block = {
39301                 c: function create() {
39302                         tr = element("tr");
39303                         td = element("td");
39304                         t0 = text(t0_value);
39305                         t1 = space();
39306                         if (if_block) if_block.c();
39307                         t2 = space();
39308                         attr_dev(td, "class", "svelte-j6zgmy");
39309                         add_location(td, file$c, 214, 18, 7008);
39310                         attr_dev(tr, "class", "svelte-j6zgmy");
39311                         add_location(tr, file$c, 213, 16, 6985);
39312                 },
39313                 m: function mount(target, anchor) {
39314                         insert_dev(target, tr, anchor);
39315                         append_dev(tr, td);
39316                         append_dev(td, t0);
39317                         append_dev(tr, t1);
39318                         if (if_block) if_block.m(tr, null);
39319                         append_dev(tr, t2);
39320                 },
39321                 p: function update(ctx, dirty) {
39322                         if (dirty & /*aPlace*/ 1 && t0_value !== (t0_value = formatKeywordToken_1(/*keyword*/ ctx[9].token) + "")) set_data_dev(t0, t0_value);
39323
39324                         if (/*keyword*/ ctx[9].id) {
39325                                 if (if_block) {
39326                                         if_block.p(ctx, dirty);
39327                                 } else {
39328                                         if_block = create_if_block_4(ctx);
39329                                         if_block.c();
39330                                         if_block.m(tr, t2);
39331                                 }
39332                         } else if (if_block) {
39333                                 if_block.d(1);
39334                                 if_block = null;
39335                         }
39336                 },
39337                 d: function destroy(detaching) {
39338                         if (detaching) detach_dev(tr);
39339                         if (if_block) if_block.d();
39340                 }
39341         };
39342
39343         dispatch_dev("SvelteRegisterBlock", {
39344                 block,
39345                 id: create_each_block_2.name,
39346                 type: "each",
39347                 source: "(213:14) {#each aPlace.keywords.address as keyword}",
39348                 ctx
39349         });
39350
39351         return block;
39352     }
39353
39354     // (243:12) {:else}
39355     function create_else_block$3(ctx) {
39356         let tr;
39357         let td;
39358         let a;
39359         let t;
39360
39361         const block = {
39362                 c: function create() {
39363                         tr = element("tr");
39364                         td = element("td");
39365                         a = element("a");
39366                         t = text("display child places");
39367                         attr_dev(a, "class", "btn btn-outline-secondary btn-sm");
39368                         attr_dev(a, "href", "" + (/*base_url*/ ctx[1] + "&hierarchy=1"));
39369                         add_location(a, file$c, 245, 19, 8125);
39370                         attr_dev(td, "class", "svelte-j6zgmy");
39371                         add_location(td, file$c, 244, 16, 8101);
39372                         attr_dev(tr, "class", "svelte-j6zgmy");
39373                         add_location(tr, file$c, 243, 14, 8080);
39374                 },
39375                 m: function mount(target, anchor) {
39376                         insert_dev(target, tr, anchor);
39377                         append_dev(tr, td);
39378                         append_dev(td, a);
39379                         append_dev(a, t);
39380                 },
39381                 p: noop,
39382                 i: noop,
39383                 o: noop,
39384                 d: function destroy(detaching) {
39385                         if (detaching) detach_dev(tr);
39386                 }
39387         };
39388
39389         dispatch_dev("SvelteRegisterBlock", {
39390                 block,
39391                 id: create_else_block$3.name,
39392                 type: "else",
39393                 source: "(243:12) {:else}",
39394                 ctx
39395         });
39396
39397         return block;
39398     }
39399
39400     // (231:12) {#if aPlace.hierarchy}
39401     function create_if_block_1$2(ctx) {
39402         let t;
39403         let show_if = Object.keys(/*aPlace*/ ctx[0].hierarchy) > 500;
39404         let if_block_anchor;
39405         let current;
39406         let each_value = Object.keys(/*aPlace*/ ctx[0].hierarchy);
39407         validate_each_argument(each_value);
39408         let each_blocks = [];
39409
39410         for (let i = 0; i < each_value.length; i += 1) {
39411                 each_blocks[i] = create_each_block$2(get_each_context$2(ctx, each_value, i));
39412         }
39413
39414         const out = i => transition_out(each_blocks[i], 1, 1, () => {
39415                 each_blocks[i] = null;
39416         });
39417
39418         let if_block = show_if && create_if_block_2$1(ctx);
39419
39420         const block = {
39421                 c: function create() {
39422                         for (let i = 0; i < each_blocks.length; i += 1) {
39423                                 each_blocks[i].c();
39424                         }
39425
39426                         t = space();
39427                         if (if_block) if_block.c();
39428                         if_block_anchor = empty();
39429                 },
39430                 m: function mount(target, anchor) {
39431                         for (let i = 0; i < each_blocks.length; i += 1) {
39432                                 each_blocks[i].m(target, anchor);
39433                         }
39434
39435                         insert_dev(target, t, anchor);
39436                         if (if_block) if_block.m(target, anchor);
39437                         insert_dev(target, if_block_anchor, anchor);
39438                         current = true;
39439                 },
39440                 p: function update(ctx, dirty) {
39441                         if (dirty & /*aPlace, Object*/ 1) {
39442                                 each_value = Object.keys(/*aPlace*/ ctx[0].hierarchy);
39443                                 validate_each_argument(each_value);
39444                                 let i;
39445
39446                                 for (i = 0; i < each_value.length; i += 1) {
39447                                         const child_ctx = get_each_context$2(ctx, each_value, i);
39448
39449                                         if (each_blocks[i]) {
39450                                                 each_blocks[i].p(child_ctx, dirty);
39451                                                 transition_in(each_blocks[i], 1);
39452                                         } else {
39453                                                 each_blocks[i] = create_each_block$2(child_ctx);
39454                                                 each_blocks[i].c();
39455                                                 transition_in(each_blocks[i], 1);
39456                                                 each_blocks[i].m(t.parentNode, t);
39457                                         }
39458                                 }
39459
39460                                 group_outros();
39461
39462                                 for (i = each_value.length; i < each_blocks.length; i += 1) {
39463                                         out(i);
39464                                 }
39465
39466                                 check_outros();
39467                         }
39468
39469                         if (dirty & /*aPlace*/ 1) show_if = Object.keys(/*aPlace*/ ctx[0].hierarchy) > 500;
39470
39471                         if (show_if) {
39472                                 if (if_block) ; else {
39473                                         if_block = create_if_block_2$1(ctx);
39474                                         if_block.c();
39475                                         if_block.m(if_block_anchor.parentNode, if_block_anchor);
39476                                 }
39477                         } else if (if_block) {
39478                                 if_block.d(1);
39479                                 if_block = null;
39480                         }
39481                 },
39482                 i: function intro(local) {
39483                         if (current) return;
39484
39485                         for (let i = 0; i < each_value.length; i += 1) {
39486                                 transition_in(each_blocks[i]);
39487                         }
39488
39489                         current = true;
39490                 },
39491                 o: function outro(local) {
39492                         each_blocks = each_blocks.filter(Boolean);
39493
39494                         for (let i = 0; i < each_blocks.length; i += 1) {
39495                                 transition_out(each_blocks[i]);
39496                         }
39497
39498                         current = false;
39499                 },
39500                 d: function destroy(detaching) {
39501                         destroy_each(each_blocks, detaching);
39502                         if (detaching) detach_dev(t);
39503                         if (if_block) if_block.d(detaching);
39504                         if (detaching) detach_dev(if_block_anchor);
39505                 }
39506         };
39507
39508         dispatch_dev("SvelteRegisterBlock", {
39509                 block,
39510                 id: create_if_block_1$2.name,
39511                 type: "if",
39512                 source: "(231:12) {#if aPlace.hierarchy}",
39513                 ctx
39514         });
39515
39516         return block;
39517     }
39518
39519     // (235:16) {#each aPlace.hierarchy[type] as line}
39520     function create_each_block_1(ctx) {
39521         let detailsonerow;
39522         let current;
39523
39524         detailsonerow = new DetailsOneRow({
39525                         props: {
39526                                 addressLine: /*line*/ ctx[6],
39527                                 bDistanceInMeters: "true"
39528                         },
39529                         $$inline: true
39530                 });
39531
39532         const block = {
39533                 c: function create() {
39534                         create_component(detailsonerow.$$.fragment);
39535                 },
39536                 m: function mount(target, anchor) {
39537                         mount_component(detailsonerow, target, anchor);
39538                         current = true;
39539                 },
39540                 p: function update(ctx, dirty) {
39541                         const detailsonerow_changes = {};
39542                         if (dirty & /*aPlace*/ 1) detailsonerow_changes.addressLine = /*line*/ ctx[6];
39543                         detailsonerow.$set(detailsonerow_changes);
39544                 },
39545                 i: function intro(local) {
39546                         if (current) return;
39547                         transition_in(detailsonerow.$$.fragment, local);
39548                         current = true;
39549                 },
39550                 o: function outro(local) {
39551                         transition_out(detailsonerow.$$.fragment, local);
39552                         current = false;
39553                 },
39554                 d: function destroy(detaching) {
39555                         destroy_component(detailsonerow, detaching);
39556                 }
39557         };
39558
39559         dispatch_dev("SvelteRegisterBlock", {
39560                 block,
39561                 id: create_each_block_1.name,
39562                 type: "each",
39563                 source: "(235:16) {#each aPlace.hierarchy[type] as line}",
39564                 ctx
39565         });
39566
39567         return block;
39568     }
39569
39570     // (233:14) {#each Object.keys(aPlace.hierarchy) as type}
39571     function create_each_block$2(ctx) {
39572         let tr;
39573         let td;
39574         let h3;
39575         let t0_value = /*type*/ ctx[3] + "";
39576         let t0;
39577         let t1;
39578         let each_1_anchor;
39579         let current;
39580         let each_value_1 = /*aPlace*/ ctx[0].hierarchy[/*type*/ ctx[3]];
39581         validate_each_argument(each_value_1);
39582         let each_blocks = [];
39583
39584         for (let i = 0; i < each_value_1.length; i += 1) {
39585                 each_blocks[i] = create_each_block_1(get_each_context_1(ctx, each_value_1, i));
39586         }
39587
39588         const out = i => transition_out(each_blocks[i], 1, 1, () => {
39589                 each_blocks[i] = null;
39590         });
39591
39592         const block = {
39593                 c: function create() {
39594                         tr = element("tr");
39595                         td = element("td");
39596                         h3 = element("h3");
39597                         t0 = text(t0_value);
39598                         t1 = space();
39599
39600                         for (let i = 0; i < each_blocks.length; i += 1) {
39601                                 each_blocks[i].c();
39602                         }
39603
39604                         each_1_anchor = empty();
39605                         attr_dev(h3, "class", "svelte-j6zgmy");
39606                         add_location(h3, file$c, 233, 56, 7692);
39607                         attr_dev(td, "colspan", "6");
39608                         attr_dev(td, "class", "svelte-j6zgmy");
39609                         add_location(td, file$c, 233, 40, 7676);
39610                         attr_dev(tr, "class", "all-columns svelte-j6zgmy");
39611                         add_location(tr, file$c, 233, 16, 7652);
39612                 },
39613                 m: function mount(target, anchor) {
39614                         insert_dev(target, tr, anchor);
39615                         append_dev(tr, td);
39616                         append_dev(td, h3);
39617                         append_dev(h3, t0);
39618                         insert_dev(target, t1, anchor);
39619
39620                         for (let i = 0; i < each_blocks.length; i += 1) {
39621                                 each_blocks[i].m(target, anchor);
39622                         }
39623
39624                         insert_dev(target, each_1_anchor, anchor);
39625                         current = true;
39626                 },
39627                 p: function update(ctx, dirty) {
39628                         if ((!current || dirty & /*aPlace*/ 1) && t0_value !== (t0_value = /*type*/ ctx[3] + "")) set_data_dev(t0, t0_value);
39629
39630                         if (dirty & /*aPlace, Object*/ 1) {
39631                                 each_value_1 = /*aPlace*/ ctx[0].hierarchy[/*type*/ ctx[3]];
39632                                 validate_each_argument(each_value_1);
39633                                 let i;
39634
39635                                 for (i = 0; i < each_value_1.length; i += 1) {
39636                                         const child_ctx = get_each_context_1(ctx, each_value_1, i);
39637
39638                                         if (each_blocks[i]) {
39639                                                 each_blocks[i].p(child_ctx, dirty);
39640                                                 transition_in(each_blocks[i], 1);
39641                                         } else {
39642                                                 each_blocks[i] = create_each_block_1(child_ctx);
39643                                                 each_blocks[i].c();
39644                                                 transition_in(each_blocks[i], 1);
39645                                                 each_blocks[i].m(each_1_anchor.parentNode, each_1_anchor);
39646                                         }
39647                                 }
39648
39649                                 group_outros();
39650
39651                                 for (i = each_value_1.length; i < each_blocks.length; i += 1) {
39652                                         out(i);
39653                                 }
39654
39655                                 check_outros();
39656                         }
39657                 },
39658                 i: function intro(local) {
39659                         if (current) return;
39660
39661                         for (let i = 0; i < each_value_1.length; i += 1) {
39662                                 transition_in(each_blocks[i]);
39663                         }
39664
39665                         current = true;
39666                 },
39667                 o: function outro(local) {
39668                         each_blocks = each_blocks.filter(Boolean);
39669
39670                         for (let i = 0; i < each_blocks.length; i += 1) {
39671                                 transition_out(each_blocks[i]);
39672                         }
39673
39674                         current = false;
39675                 },
39676                 d: function destroy(detaching) {
39677                         if (detaching) detach_dev(tr);
39678                         if (detaching) detach_dev(t1);
39679                         destroy_each(each_blocks, detaching);
39680                         if (detaching) detach_dev(each_1_anchor);
39681                 }
39682         };
39683
39684         dispatch_dev("SvelteRegisterBlock", {
39685                 block,
39686                 id: create_each_block$2.name,
39687                 type: "each",
39688                 source: "(233:14) {#each Object.keys(aPlace.hierarchy) as type}",
39689                 ctx
39690         });
39691
39692         return block;
39693     }
39694
39695     // (240:14) {#if Object.keys(aPlace.hierarchy) > 500}
39696     function create_if_block_2$1(ctx) {
39697         let p;
39698
39699         const block = {
39700                 c: function create() {
39701                         p = element("p");
39702                         p.textContent = "There are more child objects which are not shown.";
39703                         add_location(p, file$c, 240, 16, 7969);
39704                 },
39705                 m: function mount(target, anchor) {
39706                         insert_dev(target, p, anchor);
39707                 },
39708                 d: function destroy(detaching) {
39709                         if (detaching) detach_dev(p);
39710                 }
39711         };
39712
39713         dispatch_dev("SvelteRegisterBlock", {
39714                 block,
39715                 id: create_if_block_2$1.name,
39716                 type: "if",
39717                 source: "(240:14) {#if Object.keys(aPlace.hierarchy) > 500}",
39718                 ctx
39719         });
39720
39721         return block;
39722     }
39723
39724     function create_fragment$c(ctx) {
39725         let current_block_type_index;
39726         let if_block;
39727         let if_block_anchor;
39728         let current;
39729         const if_block_creators = [create_if_block$5, create_if_block_12, create_else_block_2];
39730         const if_blocks = [];
39731
39732         function select_block_type(ctx, dirty) {
39733                 if (/*aPlace*/ ctx[0]) return 0;
39734                 if (location.search === "") return 1;
39735                 return 2;
39736         }
39737
39738         current_block_type_index = select_block_type(ctx);
39739         if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
39740
39741         const block = {
39742                 c: function create() {
39743                         if_block.c();
39744                         if_block_anchor = empty();
39745                 },
39746                 l: function claim(nodes) {
39747                         throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
39748                 },
39749                 m: function mount(target, anchor) {
39750                         if_blocks[current_block_type_index].m(target, anchor);
39751                         insert_dev(target, if_block_anchor, anchor);
39752                         current = true;
39753                 },
39754                 p: function update(ctx, [dirty]) {
39755                         let previous_block_index = current_block_type_index;
39756                         current_block_type_index = select_block_type(ctx);
39757
39758                         if (current_block_type_index === previous_block_index) {
39759                                 if_blocks[current_block_type_index].p(ctx, dirty);
39760                         } else {
39761                                 group_outros();
39762
39763                                 transition_out(if_blocks[previous_block_index], 1, 1, () => {
39764                                         if_blocks[previous_block_index] = null;
39765                                 });
39766
39767                                 check_outros();
39768                                 if_block = if_blocks[current_block_type_index];
39769
39770                                 if (!if_block) {
39771                                         if_block = if_blocks[current_block_type_index] = if_block_creators[current_block_type_index](ctx);
39772                                         if_block.c();
39773                                 } else {
39774                                         if_block.p(ctx, dirty);
39775                                 }
39776
39777                                 transition_in(if_block, 1);
39778                                 if_block.m(if_block_anchor.parentNode, if_block_anchor);
39779                         }
39780                 },
39781                 i: function intro(local) {
39782                         if (current) return;
39783                         transition_in(if_block);
39784                         current = true;
39785                 },
39786                 o: function outro(local) {
39787                         transition_out(if_block);
39788                         current = false;
39789                 },
39790                 d: function destroy(detaching) {
39791                         if_blocks[current_block_type_index].d(detaching);
39792                         if (detaching) detach_dev(if_block_anchor);
39793                 }
39794         };
39795
39796         dispatch_dev("SvelteRegisterBlock", {
39797                 block,
39798                 id: create_fragment$c.name,
39799                 type: "component",
39800                 source: "",
39801                 ctx
39802         });
39803
39804         return block;
39805     }
39806
39807     function instance$c($$self, $$props, $$invalidate) {
39808         let { $$slots: slots = {}, $$scope } = $$props;
39809         validate_slots("DetailsPage", slots, []);
39810         let aPlace;
39811         let base_url = window.location.search;
39812
39813         function loaddata() {
39814                 var search_params = new URLSearchParams(window.location.search);
39815
39816                 var api_request_params = {
39817                         place_id: search_params.get("place_id"),
39818                         osmtype: search_params.get("osmtype"),
39819                         osmid: search_params.get("osmid"),
39820                         class: search_params.get("class"),
39821                         keywords: search_params.get("keywords"),
39822                         addressdetails: 1,
39823                         hierarchy: search_params.get("hierarchy") === "1" ? 1 : 0,
39824                         group_hierarchy: 1,
39825                         polygon_geojson: 1,
39826                         format: "json"
39827                 };
39828
39829                 if (api_request_params.place_id || api_request_params.osmtype && api_request_params.osmid) {
39830                         if (api_request_params.place_id) {
39831                                 update_html_title("Details for " + api_request_params.place_id);
39832                         } else {
39833                                 update_html_title("Details for " + api_request_params.osmtype + api_request_params.osmid);
39834                         }
39835
39836                         fetch_from_api("details", api_request_params, function (data) {
39837                                 $$invalidate(0, aPlace = data);
39838                                 current_result_store.set(data);
39839                         });
39840                 } else {
39841                         $$invalidate(0, aPlace = undefined);
39842                 }
39843         }
39844
39845         onMount(loaddata);
39846         const writable_props = [];
39847
39848         Object_1.keys($$props).forEach(key => {
39849                 if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<DetailsPage> was created with unknown prop '${key}'`);
39850         });
39851
39852         $$self.$capture_state = () => ({
39853                 onMount,
39854                 fetch_from_api,
39855                 update_html_title,
39856                 current_result_store,
39857                 osmLink: osmLink_1,
39858                 detailsURL: detailsURL_1,
39859                 wikipediaLink: wikipediaLink_1,
39860                 coverageType: coverageType_1,
39861                 isAdminBoundary: isAdminBoundary_1,
39862                 formatAddressRank: formatAddressRank_1,
39863                 formatKeywordToken: formatKeywordToken_1,
39864                 MapIcon,
39865                 DetailsIndex,
39866                 DetailsOneRow,
39867                 Map: Map$1,
39868                 aPlace,
39869                 base_url,
39870                 loaddata
39871         });
39872
39873         $$self.$inject_state = $$props => {
39874                 if ("aPlace" in $$props) $$invalidate(0, aPlace = $$props.aPlace);
39875                 if ("base_url" in $$props) $$invalidate(1, base_url = $$props.base_url);
39876         };
39877
39878         if ($$props && "$$inject" in $$props) {
39879                 $$self.$inject_state($$props.$$inject);
39880         }
39881
39882         return [aPlace, base_url];
39883     }
39884
39885     class DetailsPage extends SvelteComponentDev {
39886         constructor(options) {
39887                 super(options);
39888                 init(this, options, instance$c, create_fragment$c, safe_not_equal, {});
39889
39890                 dispatch_dev("SvelteRegisterComponent", {
39891                         component: this,
39892                         tagName: "DetailsPage",
39893                         options,
39894                         id: create_fragment$c.name
39895                 });
39896         }
39897     }
39898
39899     /* src/pages/PolygonsPage.svelte generated by Svelte v3.31.2 */
39900     const file$d = "src/pages/PolygonsPage.svelte";
39901
39902     function get_each_context$3(ctx, list, i) {
39903         const child_ctx = ctx.slice();
39904         child_ctx[2] = list[i];
39905         return child_ctx;
39906     }
39907
39908     // (40:10) {#each aPolygons as polygon}
39909     function create_each_block$3(ctx) {
39910         let tr;
39911         let td0;
39912         let t0_value = /*polygon*/ ctx[2].osm_type + "";
39913         let t0;
39914         let t1;
39915         let td1;
39916         let raw_value = osmLink_1(/*polygon*/ ctx[2]) + "";
39917         let t2;
39918         let td2;
39919         let t3_value = /*polygon*/ ctx[2].class + "";
39920         let t3;
39921         let t4;
39922         let td3;
39923         let t5_value = /*polygon*/ ctx[2].type + "";
39924         let t5;
39925         let t6;
39926         let td4;
39927         let t7_value = /*polygon*/ ctx[2].name + "";
39928         let t7;
39929         let t8;
39930         let td5;
39931         let t9_value = (/*polygon*/ ctx[2].country_code || "") + "";
39932         let t9;
39933         let t10;
39934         let td6;
39935         let t11_value = /*polygon*/ ctx[2].errormessage + "";
39936         let t11;
39937         let t12;
39938         let td7;
39939         let t13_value = /*polygon*/ ctx[2].updated + "";
39940         let t13;
39941         let t14;
39942         let td8;
39943         let a;
39944         let t15;
39945         let a_href_value;
39946         let t16;
39947
39948         const block = {
39949                 c: function create() {
39950                         tr = element("tr");
39951                         td0 = element("td");
39952                         t0 = text(t0_value);
39953                         t1 = space();
39954                         td1 = element("td");
39955                         t2 = space();
39956                         td2 = element("td");
39957                         t3 = text(t3_value);
39958                         t4 = space();
39959                         td3 = element("td");
39960                         t5 = text(t5_value);
39961                         t6 = space();
39962                         td4 = element("td");
39963                         t7 = text(t7_value);
39964                         t8 = space();
39965                         td5 = element("td");
39966                         t9 = text(t9_value);
39967                         t10 = space();
39968                         td6 = element("td");
39969                         t11 = text(t11_value);
39970                         t12 = space();
39971                         td7 = element("td");
39972                         t13 = text(t13_value);
39973                         t14 = space();
39974                         td8 = element("td");
39975                         a = element("a");
39976                         t15 = text("josm");
39977                         t16 = space();
39978                         add_location(td0, file$d, 41, 14, 1005);
39979                         add_location(td1, file$d, 42, 14, 1047);
39980                         add_location(td2, file$d, 43, 14, 1095);
39981                         add_location(td3, file$d, 44, 14, 1134);
39982                         add_location(td4, file$d, 45, 14, 1172);
39983                         add_location(td5, file$d, 46, 14, 1210);
39984                         add_location(td6, file$d, 47, 14, 1262);
39985                         add_location(td7, file$d, 48, 14, 1308);
39986                         attr_dev(a, "href", a_href_value = "http://localhost:8111/import?url=https://www.openstreetmap.org/api/0.6/" + formatOSMType_1(/*polygon*/ ctx[2].osm_type) + "/" + /*polygon*/ ctx[2].osm_id + "/full");
39987                         attr_dev(a, "target", "josm");
39988                         add_location(a, file$d, 50, 16, 1370);
39989                         add_location(td8, file$d, 49, 14, 1349);
39990                         add_location(tr, file$d, 40, 12, 986);
39991                 },
39992                 m: function mount(target, anchor) {
39993                         insert_dev(target, tr, anchor);
39994                         append_dev(tr, td0);
39995                         append_dev(td0, t0);
39996                         append_dev(tr, t1);
39997                         append_dev(tr, td1);
39998                         td1.innerHTML = raw_value;
39999                         append_dev(tr, t2);
40000                         append_dev(tr, td2);
40001                         append_dev(td2, t3);
40002                         append_dev(tr, t4);
40003                         append_dev(tr, td3);
40004                         append_dev(td3, t5);
40005                         append_dev(tr, t6);
40006                         append_dev(tr, td4);
40007                         append_dev(td4, t7);
40008                         append_dev(tr, t8);
40009                         append_dev(tr, td5);
40010                         append_dev(td5, t9);
40011                         append_dev(tr, t10);
40012                         append_dev(tr, td6);
40013                         append_dev(td6, t11);
40014                         append_dev(tr, t12);
40015                         append_dev(tr, td7);
40016                         append_dev(td7, t13);
40017                         append_dev(tr, t14);
40018                         append_dev(tr, td8);
40019                         append_dev(td8, a);
40020                         append_dev(a, t15);
40021                         append_dev(tr, t16);
40022                 },
40023                 p: function update(ctx, dirty) {
40024                         if (dirty & /*aPolygons*/ 1 && t0_value !== (t0_value = /*polygon*/ ctx[2].osm_type + "")) set_data_dev(t0, t0_value);
40025                         if (dirty & /*aPolygons*/ 1 && raw_value !== (raw_value = osmLink_1(/*polygon*/ ctx[2]) + "")) td1.innerHTML = raw_value;                       if (dirty & /*aPolygons*/ 1 && t3_value !== (t3_value = /*polygon*/ ctx[2].class + "")) set_data_dev(t3, t3_value);
40026                         if (dirty & /*aPolygons*/ 1 && t5_value !== (t5_value = /*polygon*/ ctx[2].type + "")) set_data_dev(t5, t5_value);
40027                         if (dirty & /*aPolygons*/ 1 && t7_value !== (t7_value = /*polygon*/ ctx[2].name + "")) set_data_dev(t7, t7_value);
40028                         if (dirty & /*aPolygons*/ 1 && t9_value !== (t9_value = (/*polygon*/ ctx[2].country_code || "") + "")) set_data_dev(t9, t9_value);
40029                         if (dirty & /*aPolygons*/ 1 && t11_value !== (t11_value = /*polygon*/ ctx[2].errormessage + "")) set_data_dev(t11, t11_value);
40030                         if (dirty & /*aPolygons*/ 1 && t13_value !== (t13_value = /*polygon*/ ctx[2].updated + "")) set_data_dev(t13, t13_value);
40031
40032                         if (dirty & /*aPolygons*/ 1 && a_href_value !== (a_href_value = "http://localhost:8111/import?url=https://www.openstreetmap.org/api/0.6/" + formatOSMType_1(/*polygon*/ ctx[2].osm_type) + "/" + /*polygon*/ ctx[2].osm_id + "/full")) {
40033                                 attr_dev(a, "href", a_href_value);
40034                         }
40035                 },
40036                 d: function destroy(detaching) {
40037                         if (detaching) detach_dev(tr);
40038                 }
40039         };
40040
40041         dispatch_dev("SvelteRegisterBlock", {
40042                 block,
40043                 id: create_each_block$3.name,
40044                 type: "each",
40045                 source: "(40:10) {#each aPolygons as polygon}",
40046                 ctx
40047         });
40048
40049         return block;
40050     }
40051
40052     function create_fragment$d(ctx) {
40053         let div2;
40054         let div1;
40055         let div0;
40056         let h1;
40057         let t1;
40058         let p;
40059         let t2;
40060         let t3_value = /*aPolygons*/ ctx[0].length + "";
40061         let t3;
40062         let t4;
40063         let t5;
40064         let table;
40065         let thead;
40066         let th0;
40067         let t7;
40068         let th1;
40069         let t9;
40070         let th2;
40071         let t11;
40072         let th3;
40073         let t13;
40074         let th4;
40075         let t15;
40076         let th5;
40077         let t17;
40078         let th6;
40079         let t19;
40080         let th7;
40081         let t21;
40082         let th8;
40083         let t22;
40084         let tbody;
40085         let each_value = /*aPolygons*/ ctx[0];
40086         validate_each_argument(each_value);
40087         let each_blocks = [];
40088
40089         for (let i = 0; i < each_value.length; i += 1) {
40090                 each_blocks[i] = create_each_block$3(get_each_context$3(ctx, each_value, i));
40091         }
40092
40093         const block = {
40094                 c: function create() {
40095                         div2 = element("div");
40096                         div1 = element("div");
40097                         div0 = element("div");
40098                         h1 = element("h1");
40099                         h1.textContent = "Broken polygons";
40100                         t1 = space();
40101                         p = element("p");
40102                         t2 = text("Total number of broken polygons: ");
40103                         t3 = text(t3_value);
40104                         t4 = text(".");
40105                         t5 = space();
40106                         table = element("table");
40107                         thead = element("thead");
40108                         th0 = element("th");
40109                         th0.textContent = "OSM type";
40110                         t7 = space();
40111                         th1 = element("th");
40112                         th1.textContent = "OSM id";
40113                         t9 = space();
40114                         th2 = element("th");
40115                         th2.textContent = "Class";
40116                         t11 = space();
40117                         th3 = element("th");
40118                         th3.textContent = "Type";
40119                         t13 = space();
40120                         th4 = element("th");
40121                         th4.textContent = "Name";
40122                         t15 = space();
40123                         th5 = element("th");
40124                         th5.textContent = "Country Code";
40125                         t17 = space();
40126                         th6 = element("th");
40127                         th6.textContent = "Error message";
40128                         t19 = space();
40129                         th7 = element("th");
40130                         th7.textContent = "Updated";
40131                         t21 = space();
40132                         th8 = element("th");
40133                         t22 = space();
40134                         tbody = element("tbody");
40135
40136                         for (let i = 0; i < each_blocks.length; i += 1) {
40137                                 each_blocks[i].c();
40138                         }
40139
40140                         add_location(h1, file$d, 20, 6, 484);
40141                         add_location(p, file$d, 22, 6, 516);
40142                         add_location(th0, file$d, 28, 10, 673);
40143                         add_location(th1, file$d, 29, 10, 701);
40144                         add_location(th2, file$d, 30, 10, 727);
40145                         add_location(th3, file$d, 31, 10, 752);
40146                         add_location(th4, file$d, 32, 10, 776);
40147                         add_location(th5, file$d, 33, 10, 800);
40148                         add_location(th6, file$d, 34, 10, 832);
40149                         add_location(th7, file$d, 35, 10, 865);
40150                         add_location(th8, file$d, 36, 10, 892);
40151                         add_location(thead, file$d, 27, 8, 655);
40152                         add_location(tbody, file$d, 38, 8, 927);
40153                         attr_dev(table, "class", "table table-striped table-hover");
40154                         add_location(table, file$d, 26, 6, 599);
40155                         attr_dev(div0, "class", "col-sm-12");
40156                         add_location(div0, file$d, 19, 4, 454);
40157                         attr_dev(div1, "class", "row");
40158                         add_location(div1, file$d, 18, 2, 432);
40159                         attr_dev(div2, "class", "container");
40160                         add_location(div2, file$d, 17, 0, 406);
40161                 },
40162                 l: function claim(nodes) {
40163                         throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
40164                 },
40165                 m: function mount(target, anchor) {
40166                         insert_dev(target, div2, anchor);
40167                         append_dev(div2, div1);
40168                         append_dev(div1, div0);
40169                         append_dev(div0, h1);
40170                         append_dev(div0, t1);
40171                         append_dev(div0, p);
40172                         append_dev(p, t2);
40173                         append_dev(p, t3);
40174                         append_dev(p, t4);
40175                         append_dev(div0, t5);
40176                         append_dev(div0, table);
40177                         append_dev(table, thead);
40178                         append_dev(thead, th0);
40179                         append_dev(thead, t7);
40180                         append_dev(thead, th1);
40181                         append_dev(thead, t9);
40182                         append_dev(thead, th2);
40183                         append_dev(thead, t11);
40184                         append_dev(thead, th3);
40185                         append_dev(thead, t13);
40186                         append_dev(thead, th4);
40187                         append_dev(thead, t15);
40188                         append_dev(thead, th5);
40189                         append_dev(thead, t17);
40190                         append_dev(thead, th6);
40191                         append_dev(thead, t19);
40192                         append_dev(thead, th7);
40193                         append_dev(thead, t21);
40194                         append_dev(thead, th8);
40195                         append_dev(table, t22);
40196                         append_dev(table, tbody);
40197
40198                         for (let i = 0; i < each_blocks.length; i += 1) {
40199                                 each_blocks[i].m(tbody, null);
40200                         }
40201                 },
40202                 p: function update(ctx, [dirty]) {
40203                         if (dirty & /*aPolygons*/ 1 && t3_value !== (t3_value = /*aPolygons*/ ctx[0].length + "")) set_data_dev(t3, t3_value);
40204
40205                         if (dirty & /*formatOSMType, aPolygons, osmLink*/ 1) {
40206                                 each_value = /*aPolygons*/ ctx[0];
40207                                 validate_each_argument(each_value);
40208                                 let i;
40209
40210                                 for (i = 0; i < each_value.length; i += 1) {
40211                                         const child_ctx = get_each_context$3(ctx, each_value, i);
40212
40213                                         if (each_blocks[i]) {
40214                                                 each_blocks[i].p(child_ctx, dirty);
40215                                         } else {
40216                                                 each_blocks[i] = create_each_block$3(child_ctx);
40217                                                 each_blocks[i].c();
40218                                                 each_blocks[i].m(tbody, null);
40219                                         }
40220                                 }
40221
40222                                 for (; i < each_blocks.length; i += 1) {
40223                                         each_blocks[i].d(1);
40224                                 }
40225
40226                                 each_blocks.length = each_value.length;
40227                         }
40228                 },
40229                 i: noop,
40230                 o: noop,
40231                 d: function destroy(detaching) {
40232                         if (detaching) detach_dev(div2);
40233                         destroy_each(each_blocks, detaching);
40234                 }
40235         };
40236
40237         dispatch_dev("SvelteRegisterBlock", {
40238                 block,
40239                 id: create_fragment$d.name,
40240                 type: "component",
40241                 source: "",
40242                 ctx
40243         });
40244
40245         return block;
40246     }
40247
40248     function instance$d($$self, $$props, $$invalidate) {
40249         let { $$slots: slots = {}, $$scope } = $$props;
40250         validate_slots("PolygonsPage", slots, []);
40251         let aPolygons = [];
40252
40253         function loaddata() {
40254                 fetch_from_api("polygons", { format: "json" }, function (data) {
40255                         $$invalidate(0, aPolygons = data);
40256                 });
40257
40258                 update_html_title("Broken polygons");
40259         }
40260
40261         onMount(loaddata);
40262         const writable_props = [];
40263
40264         Object.keys($$props).forEach(key => {
40265                 if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<PolygonsPage> was created with unknown prop '${key}'`);
40266         });
40267
40268         $$self.$capture_state = () => ({
40269                 onMount,
40270                 fetch_from_api,
40271                 update_html_title,
40272                 formatOSMType: formatOSMType_1,
40273                 osmLink: osmLink_1,
40274                 aPolygons,
40275                 loaddata
40276         });
40277
40278         $$self.$inject_state = $$props => {
40279                 if ("aPolygons" in $$props) $$invalidate(0, aPolygons = $$props.aPolygons);
40280         };
40281
40282         if ($$props && "$$inject" in $$props) {
40283                 $$self.$inject_state($$props.$$inject);
40284         }
40285
40286         return [aPolygons];
40287     }
40288
40289     class PolygonsPage extends SvelteComponentDev {
40290         constructor(options) {
40291                 super(options);
40292                 init(this, options, instance$d, create_fragment$d, safe_not_equal, {});
40293
40294                 dispatch_dev("SvelteRegisterComponent", {
40295                         component: this,
40296                         tagName: "PolygonsPage",
40297                         options,
40298                         id: create_fragment$d.name
40299                 });
40300         }
40301     }
40302
40303     /* src/pages/DeletablePage.svelte generated by Svelte v3.31.2 */
40304     const file$e = "src/pages/DeletablePage.svelte";
40305
40306     function get_each_context$4(ctx, list, i) {
40307         const child_ctx = ctx.slice();
40308         child_ctx[2] = list[i];
40309         return child_ctx;
40310     }
40311
40312     // (37:10) {#each aPolygons as polygon}
40313     function create_each_block$4(ctx) {
40314         let tr;
40315         let td0;
40316         let a;
40317         let t0_value = /*polygon*/ ctx[2].place_id + "";
40318         let t0;
40319         let a_href_value;
40320         let t1;
40321         let td1;
40322         let t2_value = /*polygon*/ ctx[2].country_code + "";
40323         let t2;
40324         let t3;
40325         let td2;
40326         let t4_value = /*polygon*/ ctx[2].name + "";
40327         let t4;
40328         let t5;
40329         let td3;
40330         let raw_value = osmLink_1(/*polygon*/ ctx[2]) + "";
40331         let t6;
40332         let td4;
40333         let t7_value = /*polygon*/ ctx[2].osm_type + "";
40334         let t7;
40335         let t8;
40336         let td5;
40337         let t9_value = /*polygon*/ ctx[2].class + "";
40338         let t9;
40339         let t10;
40340         let td6;
40341         let t11_value = /*polygon*/ ctx[2].type + "";
40342         let t11;
40343         let t12;
40344
40345         const block = {
40346                 c: function create() {
40347                         tr = element("tr");
40348                         td0 = element("td");
40349                         a = element("a");
40350                         t0 = text(t0_value);
40351                         t1 = space();
40352                         td1 = element("td");
40353                         t2 = text(t2_value);
40354                         t3 = space();
40355                         td2 = element("td");
40356                         t4 = text(t4_value);
40357                         t5 = space();
40358                         td3 = element("td");
40359                         t6 = space();
40360                         td4 = element("td");
40361                         t7 = text(t7_value);
40362                         t8 = space();
40363                         td5 = element("td");
40364                         t9 = text(t9_value);
40365                         t10 = space();
40366                         td6 = element("td");
40367                         t11 = text(t11_value);
40368                         t12 = space();
40369                         attr_dev(a, "href", a_href_value = detailsURL_1(/*polygon*/ ctx[2]));
40370                         add_location(a, file$e, 38, 16, 988);
40371                         add_location(td0, file$e, 38, 12, 984);
40372                         add_location(td1, file$e, 39, 12, 1060);
40373                         add_location(td2, file$e, 40, 12, 1104);
40374                         add_location(td3, file$e, 41, 12, 1140);
40375                         add_location(td4, file$e, 42, 12, 1186);
40376                         add_location(td5, file$e, 43, 12, 1226);
40377                         add_location(td6, file$e, 44, 12, 1263);
40378                         add_location(tr, file$e, 37, 10, 967);
40379                 },
40380                 m: function mount(target, anchor) {
40381                         insert_dev(target, tr, anchor);
40382                         append_dev(tr, td0);
40383                         append_dev(td0, a);
40384                         append_dev(a, t0);
40385                         append_dev(tr, t1);
40386                         append_dev(tr, td1);
40387                         append_dev(td1, t2);
40388                         append_dev(tr, t3);
40389                         append_dev(tr, td2);
40390                         append_dev(td2, t4);
40391                         append_dev(tr, t5);
40392                         append_dev(tr, td3);
40393                         td3.innerHTML = raw_value;
40394                         append_dev(tr, t6);
40395                         append_dev(tr, td4);
40396                         append_dev(td4, t7);
40397                         append_dev(tr, t8);
40398                         append_dev(tr, td5);
40399                         append_dev(td5, t9);
40400                         append_dev(tr, t10);
40401                         append_dev(tr, td6);
40402                         append_dev(td6, t11);
40403                         append_dev(tr, t12);
40404                 },
40405                 p: function update(ctx, dirty) {
40406                         if (dirty & /*aPolygons*/ 1 && t0_value !== (t0_value = /*polygon*/ ctx[2].place_id + "")) set_data_dev(t0, t0_value);
40407
40408                         if (dirty & /*aPolygons*/ 1 && a_href_value !== (a_href_value = detailsURL_1(/*polygon*/ ctx[2]))) {
40409                                 attr_dev(a, "href", a_href_value);
40410                         }
40411
40412                         if (dirty & /*aPolygons*/ 1 && t2_value !== (t2_value = /*polygon*/ ctx[2].country_code + "")) set_data_dev(t2, t2_value);
40413                         if (dirty & /*aPolygons*/ 1 && t4_value !== (t4_value = /*polygon*/ ctx[2].name + "")) set_data_dev(t4, t4_value);
40414                         if (dirty & /*aPolygons*/ 1 && raw_value !== (raw_value = osmLink_1(/*polygon*/ ctx[2]) + "")) td3.innerHTML = raw_value;                       if (dirty & /*aPolygons*/ 1 && t7_value !== (t7_value = /*polygon*/ ctx[2].osm_type + "")) set_data_dev(t7, t7_value);
40415                         if (dirty & /*aPolygons*/ 1 && t9_value !== (t9_value = /*polygon*/ ctx[2].class + "")) set_data_dev(t9, t9_value);
40416                         if (dirty & /*aPolygons*/ 1 && t11_value !== (t11_value = /*polygon*/ ctx[2].type + "")) set_data_dev(t11, t11_value);
40417                 },
40418                 d: function destroy(detaching) {
40419                         if (detaching) detach_dev(tr);
40420                 }
40421         };
40422
40423         dispatch_dev("SvelteRegisterBlock", {
40424                 block,
40425                 id: create_each_block$4.name,
40426                 type: "each",
40427                 source: "(37:10) {#each aPolygons as polygon}",
40428                 ctx
40429         });
40430
40431         return block;
40432     }
40433
40434     function create_fragment$e(ctx) {
40435         let div2;
40436         let div1;
40437         let div0;
40438         let h1;
40439         let t1;
40440         let p;
40441         let t2_value = /*aPolygons*/ ctx[0].length + "";
40442         let t2;
40443         let t3;
40444         let t4;
40445         let table;
40446         let thead;
40447         let th0;
40448         let t6;
40449         let th1;
40450         let t8;
40451         let th2;
40452         let t10;
40453         let th3;
40454         let t12;
40455         let th4;
40456         let t14;
40457         let th5;
40458         let t16;
40459         let th6;
40460         let t18;
40461         let tbody;
40462         let each_value = /*aPolygons*/ ctx[0];
40463         validate_each_argument(each_value);
40464         let each_blocks = [];
40465
40466         for (let i = 0; i < each_value.length; i += 1) {
40467                 each_blocks[i] = create_each_block$4(get_each_context$4(ctx, each_value, i));
40468         }
40469
40470         const block = {
40471                 c: function create() {
40472                         div2 = element("div");
40473                         div1 = element("div");
40474                         div0 = element("div");
40475                         h1 = element("h1");
40476                         h1.textContent = "Deletable";
40477                         t1 = space();
40478                         p = element("p");
40479                         t2 = text(t2_value);
40480                         t3 = text(" objects have been deleted in OSM but are still in the Nominatim database.");
40481                         t4 = space();
40482                         table = element("table");
40483                         thead = element("thead");
40484                         th0 = element("th");
40485                         th0.textContent = "Place id";
40486                         t6 = space();
40487                         th1 = element("th");
40488                         th1.textContent = "Country Code";
40489                         t8 = space();
40490                         th2 = element("th");
40491                         th2.textContent = "Name";
40492                         t10 = space();
40493                         th3 = element("th");
40494                         th3.textContent = "OSM id";
40495                         t12 = space();
40496                         th4 = element("th");
40497                         th4.textContent = "OSM type";
40498                         t14 = space();
40499                         th5 = element("th");
40500                         th5.textContent = "Class";
40501                         t16 = space();
40502                         th6 = element("th");
40503                         th6.textContent = "Type";
40504                         t18 = space();
40505                         tbody = element("tbody");
40506
40507                         for (let i = 0; i < each_blocks.length; i += 1) {
40508                                 each_blocks[i].c();
40509                         }
40510
40511                         add_location(h1, file$e, 19, 6, 483);
40512                         add_location(p, file$e, 21, 6, 509);
40513                         add_location(th0, file$e, 27, 10, 708);
40514                         add_location(th1, file$e, 28, 10, 736);
40515                         add_location(th2, file$e, 29, 10, 768);
40516                         add_location(th3, file$e, 30, 10, 792);
40517                         add_location(th4, file$e, 31, 10, 818);
40518                         add_location(th5, file$e, 32, 10, 846);
40519                         add_location(th6, file$e, 33, 10, 871);
40520                         add_location(thead, file$e, 26, 8, 690);
40521                         add_location(tbody, file$e, 35, 8, 910);
40522                         attr_dev(table, "class", "table table-striped table-hover");
40523                         add_location(table, file$e, 25, 6, 634);
40524                         attr_dev(div0, "class", "col-sm-12");
40525                         add_location(div0, file$e, 18, 4, 453);
40526                         attr_dev(div1, "class", "row");
40527                         add_location(div1, file$e, 17, 2, 431);
40528                         attr_dev(div2, "class", "container");
40529                         add_location(div2, file$e, 16, 0, 405);
40530                 },
40531                 l: function claim(nodes) {
40532                         throw new Error("options.hydrate only works if the component was compiled with the `hydratable: true` option");
40533                 },
40534                 m: function mount(target, anchor) {
40535                         insert_dev(target, div2, anchor);
40536                         append_dev(div2, div1);
40537                         append_dev(div1, div0);
40538                         append_dev(div0, h1);
40539                         append_dev(div0, t1);
40540                         append_dev(div0, p);
40541                         append_dev(p, t2);
40542                         append_dev(p, t3);
40543                         append_dev(div0, t4);
40544                         append_dev(div0, table);
40545                         append_dev(table, thead);
40546                         append_dev(thead, th0);
40547                         append_dev(thead, t6);
40548                         append_dev(thead, th1);
40549                         append_dev(thead, t8);
40550                         append_dev(thead, th2);
40551                         append_dev(thead, t10);
40552                         append_dev(thead, th3);
40553                         append_dev(thead, t12);
40554                         append_dev(thead, th4);
40555                         append_dev(thead, t14);
40556                         append_dev(thead, th5);
40557                         append_dev(thead, t16);
40558                         append_dev(thead, th6);
40559                         append_dev(table, t18);
40560                         append_dev(table, tbody);
40561
40562                         for (let i = 0; i < each_blocks.length; i += 1) {
40563                                 each_blocks[i].m(tbody, null);
40564                         }
40565                 },
40566                 p: function update(ctx, [dirty]) {
40567                         if (dirty & /*aPolygons*/ 1 && t2_value !== (t2_value = /*aPolygons*/ ctx[0].length + "")) set_data_dev(t2, t2_value);
40568
40569                         if (dirty & /*aPolygons, osmLink, detailsURL*/ 1) {
40570                                 each_value = /*aPolygons*/ ctx[0];
40571                                 validate_each_argument(each_value);
40572                                 let i;
40573
40574                                 for (i = 0; i < each_value.length; i += 1) {
40575                                         const child_ctx = get_each_context$4(ctx, each_value, i);
40576
40577                                         if (each_blocks[i]) {
40578                                                 each_blocks[i].p(child_ctx, dirty);
40579                                         } else {
40580                                                 each_blocks[i] = create_each_block$4(child_ctx);
40581                                                 each_blocks[i].c();
40582                                                 each_blocks[i].m(tbody, null);
40583                                         }
40584                                 }
40585
40586                                 for (; i < each_blocks.length; i += 1) {
40587                                         each_blocks[i].d(1);
40588                                 }
40589
40590                                 each_blocks.length = each_value.length;
40591                         }
40592                 },
40593                 i: noop,
40594                 o: noop,
40595                 d: function destroy(detaching) {
40596                         if (detaching) detach_dev(div2);
40597                         destroy_each(each_blocks, detaching);
40598                 }
40599         };
40600
40601         dispatch_dev("SvelteRegisterBlock", {
40602                 block,
40603                 id: create_fragment$e.name,
40604                 type: "component",
40605                 source: "",
40606                 ctx
40607         });
40608
40609         return block;
40610     }
40611
40612     function instance$e($$self, $$props, $$invalidate) {
40613         let { $$slots: slots = {}, $$scope } = $$props;
40614         validate_slots("DeletablePage", slots, []);
40615         let aPolygons = [];
40616
40617         function loaddata() {
40618                 fetch_from_api("deletable", { format: "json" }, function (data) {
40619                         $$invalidate(0, aPolygons = data);
40620                 });
40621
40622                 update_html_title("Deletable objects");
40623         }
40624
40625         onMount(loaddata);
40626         const writable_props = [];
40627
40628         Object.keys($$props).forEach(key => {
40629                 if (!~writable_props.indexOf(key) && key.slice(0, 2) !== "$$") console.warn(`<DeletablePage> was created with unknown prop '${key}'`);
40630         });
40631
40632         $$self.$capture_state = () => ({
40633                 onMount,
40634                 fetch_from_api,
40635                 update_html_title,
40636                 detailsURL: detailsURL_1,
40637                 osmLink: osmLink_1,
40638                 aPolygons,
40639                 loaddata
40640         });
40641
40642         $$self.$inject_state = $$props => {
40643                 if ("aPolygons" in $$props) $$invalidate(0, aPolygons = $$props.aPolygons);
40644         };
40645
40646         if ($$props && "$$inject" in $$props) {
40647                 $$self.$inject_state($$props.$$inject);
40648         }
40649
40650         return [aPolygons];
40651     }
40652
40653     class DeletablePage extends SvelteComponentDev {
40654         constructor(options) {
40655                 super(options);
40656                 init(this, options, instance$e, create_fragment$e, safe_not_equal, {});
40657
40658                 dispatch_dev("SvelteRegisterComponent", {
40659                         component: this,
40660                         tagName: "DeletablePage",
40661                         options,
40662                         id: create_fragment$e.name
40663                 });
40664         }
40665     }
40666
40667     let myhistory = [];
40668
40669     new App({
40670       target: document.body
40671     });
40672
40673
40674
40675
40676     // inspects window.location
40677     function identify_current_page() {
40678       var pagename = window.location.pathname.replace('.html', '').replace(/^.*\//, '');
40679
40680       if (pagename === '') { return 'search' }
40681
40682       if (['search', 'reverse', 'details', 'deletable', 'polygons'].indexOf(pagename) != '-1') {
40683         return pagename;
40684       }
40685     }
40686
40687
40688
40689     function parse_url_and_load_page() {
40690       let pagename = identify_current_page();
40691
40692       document.getElementById('main').replaceChildren();
40693
40694       if (pagename === 'search' || pagename === 'reverse') {
40695         new SearchPage({
40696           target: document.getElementById('main'),
40697           props: {
40698             reverse_search: (pagename === 'reverse')
40699           }
40700         });
40701       } else if (pagename === 'details') {
40702         new DetailsPage({
40703           target: document.getElementById('main')
40704         });
40705       } else if (pagename === 'deletable') {
40706         new DeletablePage({
40707           target: document.getElementById('main')
40708         });
40709       } else if (pagename === 'polygons') {
40710         new PolygonsPage({
40711           target: document.getElementById('main')
40712         });
40713       }
40714     }
40715
40716
40717
40718     function is_relative_url(url) {
40719       if (!url) return false;
40720       if (url.indexOf('?') === 0) return true;
40721       if (url.indexOf('/') === 0) return true;
40722       if (url.indexOf('#') === 0) return false;
40723       if (url.match(/^http/)) return false;
40724       if (!url.match(/\.html/)) return true;
40725
40726       return false;
40727     }
40728
40729
40730     parse_url_and_load_page();
40731
40732     // load page after form submit
40733     document.addEventListener('submit', function (e) {
40734
40735       // loop parent nodes from the target to the delegation node
40736       for (var target = e.target; target && target != this; target = target.parentNode) {
40737         if (target.matches('form')) {
40738           e.preventDefault();
40739
40740           var target_url = serialize_form(target);
40741           target_url = clean_up_url_parameters(target_url);
40742
40743           window.history.pushState(myhistory, '', '?' + target_url);
40744
40745           parse_url_and_load_page();
40746           break;
40747         }
40748       }
40749
40750     });
40751
40752     // load page after click on relative URL
40753     document.addEventListener('click', function (e) {
40754
40755       // loop parent nodes from the target to the delegation node
40756       for (var target = e.target; target && target != this; target = target.parentNode) {
40757         if (target.matches('a')) {
40758
40759           var target_url = target.href;
40760
40761           if (!is_relative_url(target_url)) return;
40762
40763           e.preventDefault();
40764           e.stopPropagation();
40765
40766           window.history.pushState(myhistory, '', target_url);
40767
40768           parse_url_and_load_page();
40769           break;
40770         }
40771       }
40772     });
40773
40774     // deal with back-button and other user action
40775     window.onpopstate = function () {
40776       parse_url_and_load_page();
40777     };
40778
40779 }());
40780 //# sourceMappingURL=bundle.js.map