1/* @license GPL-2.0-or-later https://www.drupal.org/licensing/faq */ 2(function mskDialog($,Drupal){'use strict';Drupal.behaviors.mskDialogClose={attach:function attach(context){$('[data-dismiss="modal"], .msk-modal__close',context).click(function click(){$('.ui-dialog-content').dialog('close');});const videoEl=document.querySelector('#drupal-modal .video-js');if(videoEl)window.bc(videoEl);}};})(jQuery,Drupal);; 3(function GotoBlock($,Drupal,once){'use strict';Drupal.behaviors.mskBlockGotoAutoSubmit={attach:function attach(context){$(once('msk-block-goto-auto-submit','.js-msk-block-goto-auto-submit select',context)).on('change',function change(){if(this.name==='url')window.location=$(this).val();else this.form.submit();});}};})(jQuery,Drupal,once);; 4(function mskMarkup($,Drupal){'use strict';Drupal.behaviors.mskMarkupMailToLink={attach:function attach(context){$('a[href^="mailto:"]',context).each(function each(){this.href=this.href.replace('-at-mskcc.org','@mskcc.org');});}};Drupal.behaviors.mskMarkupBlockHerbSearch={attach:function attach(context){$('#msk-markup-block-herb-search #edit-letter',context).change(function change(){window.location=this.form.action+'?letter='+$(this).val();}).val('');}};Drupal.behaviors.mskMarkupRecipeSearch={attach:function attach(context){var el=document.getElementById('views-exposed-form-msk-recipes-embed-teaser');if(!el)return;el.addEventListener('submit',function submit(event){window.dataLayer.push({event:'sectionSearch',section:'Find a Recipe',action:'Search',filter1:document.querySelector('#edit_diet_guide_chosen span').textContent,filter2:document.querySelector('#edit_diet_symptom_chosen span').textContent});},false);}};Drupal.behaviors.mskMarkupNodeTimeline={attach:function attach(context){$('.msk-timeline',context).each(function each(){var id=$(this).attr('id');var data=$(this).attr('data-msk-timeline-data');var timeline=new window.TL.Timeline(id,data,{skinny_size:800});var rightArrow='<svg width="22" height="32" viewBox="0 0 22 32" xmlns="http://www.w3.org/2000/svg"><title>Arrow right</title><desc>An icon showing an arrow pointing to the right.</desc><path d="M4.352 32c-1.094 0-2.188-.4-2.873-1.335-1.505-1.602-1.367-4.005.274-5.475l10.26-9.08-10.67-9.345C-.299 5.295-.435 2.892.933 1.29 2.438-.312 4.9-.445 6.542 1.023l14.09 12.417c.821.668 1.368 1.735 1.368 2.804 0 1.068-.41 2.136-1.368 2.804L7.09 30.932C6.268 31.732 5.31 32 4.352 32z" fill="#222" fill-rule="nonzero"/></svg>';var leftArrow='<svg width="21" height="32" viewBox="0 0 21 32" xmlns="http://www.w3.org/2000/svg"><title>Arrow left</title><desc>An icon showing an arrow pointing to the right.</desc><path d="M16.71 0c1.154 0 2.017.29 2.882 1.161 1.441 1.74 1.153 4.062-.288 5.513L9.22 15.668l10.66 9.575c1.441 1.452 1.441 3.773.288 5.513-1.44 1.451-3.745 1.74-5.474.29L1.153 18.86C.288 18.28 0 17.12 0 15.959c0-1.161.576-2.031 1.153-2.902L14.406 1.161C14.983.291 15.847 0 16.711 0z" fill="#000" fill-rule="nonzero"/></svg>';var backArrow='<svg width="16" height="19" viewBox="0 0 16 19" xmlns="http://www.w3.org/2000/svg"><title>back-arrow</title><path d="M12.938 18.963c2.108-3.815 2.464-9.636-5.819-9.441v4.7L0 7.112 7.12 0v4.6c9.917-.259 11.021 8.745 5.818 14.363z" fill="#222" fill-rule="nonzero"/></svg>';var magnifyingGlassPlus='<svg width="17" height="17" viewBox="0 0 17 17" xmlns="http://www.w3.org/2000/svg"><title>Shape</title>
4<path d="M16.473 14.466l-4.026-3.424c-.417-.374-.862-.547-1.222-.53a6.375 6.375 0 1 0-.713.713c-.017.36.155.805.53 1.222l3.424 4.027c.587.65 1.545.707 2.129.121.585-.584.53-1.541-.122-2.129zM6.376 10.625a4.25 4.25 0 1 1-.137-8.5 4.25 4.25 0 0 1 .137 8.5zm1.063-7.437H5.313v2.125H3.187v2.126h2.126v2.124h2.126V7.438h2.124V5.314H7.437V3.188h.002z" fill="#222" fill-rule="nonzero"/></svg>';var magnifyingGlassMinus='<svg width="17" height="17" viewBox="0 0 17 17" xmlns="http://www.w3.org/2000/svg"><title>Shape</title><path d="M16.473 14.467l-4.027-3.424c-.416-.375-.861-.547-1.221-.531a6.375 6.375 0 1 0-.713.713c-.016.36.155.805.53 1.221l3.425 4.027c.587.653 1.544.707 2.128.123.585-.584.53-1.542-.122-2.129zm-10.097-3.84a4.25 4.25 0 1 1 0-8.5 4.25 4.25 0 0 1 0 8.5zM3.188 5.312h6.375v2.125H3.188V5.313z" fill="#222" fill-rule="nonzero"/></svg>';var observer=new MutationObserver(function MutationObserver(mutations){mutations.forEach(function mutationEach(mutation){mutation.addedNodes.forEach(function addedNodesEach(node){if(node.classList){if(node.classList.contains('tl-slidenav-next'))node.querySelector('.tl-slidenav-icon').innerHTML=rightArrow;if(node.classList.contains('tl-slidenav-previous'))node.querySelector('.tl-slidenav-icon').innerHTML=leftArrow;if(node.classList.contains('tl-icon-goback'))node.innerHTML=backArrow;if(node.classList.contains('tl-icon-zoom-in'))node.innerHTML=magnifyingGlassPlus;if(node.classList.contains('tl-icon-zoom-out'))node.innerHTML=magnifyingGlassMinus;}});});});observer.observe(document.querySelector('.tl-timeline'),{subtree:true,childList:true});window.addEventListener('resize',function resize(e){timeline.updateDisplay();});});}};})(jQuery,Drupal);; 5Drupal.debounce=function(func,wait,immediate){let timeout;let result;return function(...args){const context=this;const later=function(){timeout=null;if(!immediate)result=func.apply(context,args);};const callNow=immediate&&!timeout;clearTimeout(timeout);timeout=setTimeout(later,wait);if(callNow)result=func.apply(context,args);return result;};};; 6(function($,Drupal,debounce){const cache={right:0,left:0,bottom:0,top:0};const cssVarPrefix='--drupal-displace-offset';const documentStyle=document.documentElement.style;const offsetKeys=Object.keys(cache);const offsetProps={};offsetKeys.forEach((edge)=>{offsetProps[edge]={enumerable:true,get(){return cache[edge];},set(value){if(value!==cache[edge])documentStyle.setProperty(`${cssVarPrefix}-${edge}`,`${value}px`);cache[edge]=value;}};});const offsets=Object.seal(Object.defineProperties({},offsetProps));function getRawOffset(el,edge){const $el=$(el);const documentElement=document.documentElement;let displacement=0;const horizontal=edge==='left'||edge==='right';let placement=$el.offset()[horizontal?'left':'top'];placement-=window[`scroll${horizontal?'X':'Y'}`]||document.documentElement[`scroll${horizontal?'Left':'Top'}`]||0;switch(edge){case 'top':displacement=placement+$el.outerHeight();break;case 'left':displacement=placement+$el.outerWidth();break;case 'bottom':displacement=documentElement.clientHeight-placement;break;case 'right':displacement=documentElement.clientWidth-placement;break;default:displacement=0;}return displacement;}function calculateOffset(edge){let edgeOffset=0;const displacingElements=document.querySelectorAll(`[data-offset-${edge}]`);const n=displacingElements.length;for(let i=0;i<n;i++){const el=displacingElements[i];if(el.style.display==='none')continue;let displacement=parseInt(el.getAttribute(`data-offset-${edge}`),10);if(isNaN(displacement))displacement=getRawOffset(el,edge);edgeOffset=Math.max(edgeOffset,displacement);}return edgeOffset;}function displace(broadcast=true){const newOffsets={};offsetKeys.forEach((edge)=>{newOffsets[edge]=calculateOffset(edge);});offsetKeys.forEach((edge)=>{offsets[edge]=newOffsets[edge];});if(broadcast)$(document).trigger('drupalViewportOffsetChange',offsets);return offsets;}Drupal.behaviors.drupalDisplace={attach(){if(this.displaceProcessed)return;this.displaceProcessed=true;$(window).on('resize.drupalDisplace',debounce(displace,200));}};Drupal.displace=displace;Object.defineProperty(Drupal.displace,'offsets',{value:offsets,writable:false});Drupal.displace.calculateOffset=calculateOffset;})(jQuery,Drupal,Drupal.debounce);; 7(($,Drupal,{isTabbable})=>{$.extend($.expr[':'],{tabbable(element){Drupal.deprecationError({message:'The :tabbable selector is deprecated
7in Drupal 9.2.0 and will be removed in Drupal 11.0.0. Use the core/tabbable library instead. See https://www.drupal.org/node/3183730'});return isTabbable(element);}});})(jQuery,Drupal,window.tabbable);; 8(($)=>{let cachedScrollbarWidth=null;const {max,abs}=Math;const regexHorizontal=/left|center|right/;const regexVertical=/top|center|bottom/;const regexOffset=/[+-]\d+(\.[\d]+)?%?/;const regexPosition=/^\w+/;const _position=$.fn.position;function getOffsets(offsets,width,height){return [parseFloat(offsets[0])*(typeof offsets[0]==='string'&&offsets[0].endsWith('%')?width/100:1),parseFloat(offsets[1])*(typeof offsets[1]==='string'&&offsets[1].endsWith('%')?height/100:1)];}function parseCss(element,property){return parseInt(window.getComputedStyle(element)[property],10)||0;}function getDimensions(elem){const raw=elem[0];if(raw.nodeType===9)return {width:elem.width(),height:elem.height(),offset:{top:0,left:0}};if(!!raw&&raw===raw.window)return {width:elem.width(),height:elem.height(),offset:{top:elem.scrollTop(),left:elem.scrollLeft()}};if(raw.preventDefault)return {width:0,height:0,offset:{top:raw.pageY,left:raw.pageX}};return {width:elem.outerWidth(),height:elem.outerHeight(),offset:elem.offset()};}const collisions={fit:{left(position,data){const {within}=data;const withinOffset=within.isWindow?within.scrollLeft:within.offset.left;const outerWidth=within.width;const collisionPosLeft=position.left-data.collisionPosition.marginLeft;const overLeft=withinOffset-collisionPosLeft;const overRight=collisionPosLeft+data.collisionWidth-outerWidth-withinOffset;let newOverRight;if(data.collisionWidth>outerWidth)if(overLeft>0&&overRight<=0){newOverRight=position.left+overLeft+data.collisionWidth-outerWidth-withinOffset;position.left+=overLeft-newOverRight;}else if(overRight>0&&overLeft<=0)position.left=withinOffset;else if(overLeft>overRight)position.left=withinOffset+outerWidth-data.collisionWidth;else position.left=withinOffset;else if(overLeft>0)position.left+=overLeft;else if(overRight>0)position.left-=overRight;else position.left=max(position.left-collisionPosLeft,position.left);},top(position,data){const {within}=data;const withinOffset=within.isWindow?within.scrollTop:within.offset.top;const outerHeight=data.within.height;const collisionPosTop=position.top-data.collisionPosition.marginTop;const overTop=withinOffset-collisionPosTop;const overBottom=collisionPosTop+data.collisionHeight-outerHeight-withinOffset;let newOverBottom;if(data.collisionHeight>outerHeight)if(overTop>0&&overBottom<=0){newOverBottom=position.top+overTop+data.collisionHeight-outerHeight-withinOffset;position.top+=overTop-newOverBottom;}else if(overBottom>0&&overTop<=0)position.top=withinOffset;else if(overTop>overBottom)position.top=withinOffset+outerHeight-data.collisionHeight;else position.top=withinOffset;else if(overTop>0)position.top+=overTop;else if(overBottom>0)position.top-=overBottom;else position.top=max(position.top-collisionPosTop,position.top);}},flip:{left(position,data){const {within}=data;const withinOffset=within.offset.left+within.scrollLeft;const outerWidth=within.width;const offsetLeft=within.isWindow?within.scrollLeft:within.offset.left;const collisionPosLeft=position.left-data.collisionPosition.marginLeft;const overLeft=collisionPosLeft-offsetLeft;const overRight=collisionPosLeft+data.collisionWidth-outerWidth-offsetLeft;const myOffset=data.my[0]==='left'?-data.elemWidth:data.my[0]==='right'?data.elemWidth:0;const atOffset=data.at[0]==='left'?data.targetWidth:data.at[0]==='right'?-data.targetWidth:0;const offset=-2*data.offset[0];let newOverRight;let newOverLeft;if(overLeft<0){newOverRight=position.left+myOffset+atOffset+offset+data.collisionWidth-outerWidth-withinOffset;if(newOverRight<0||newOverRight<abs(overLeft))position.left+=myOffset+atOffset+offset;}else{if(overRight>0){newOverLeft=position.left-data.collisionPosition.marginLeft+myOffset+atOffset+offset-offsetLeft;if(newOverLeft>0||abs(newOverLeft)<overRight)position.left+=myOffset+atOffset+offset;}}},top(position,data){const {within}=data;const withinOffset=within.offset.top+within.scrollTop;const outerHeight=within.height;const offsetTop=within.isWindow?within.scrollTop:within.offset.top;const collisionPosTop=position.top-data.collisionPosition.marginTop;const overTop=collisionPosTop-offsetTop;const overBottom=collisionPosTop+data.collisionHeight-outerHeight-offsetTop;const top=data.my[1]==='top';const myOffset=top?-data.elemHeight:data.my[1]==='bottom'?data.elemHeight:0;const atOffset=data.at[1]==='top'?data.targetHeight:data.at[1]==='bottom'?-data.targetHeight:0;const offset=-2*data.offset[1];let newOverTop;let newOverBottom;if(overTop<0){newOverBottom=position.top+myOffset+atOffset+offset+data.collisionHeight-outerHeight-withinOffset;if(newOverBottom<0||newOverBottom<abs(overTop))position.top+=myOffset+atOffset+offset;}else{if(overBottom>0){newOverTop=position.top-data.collisionPosition.marginTop+myOffset+atOffset+offset-offsetTop;if(newOverTop>0||abs(newOverTop)<overBottom)position.top+=myOffset+atOffset+offset;}}}},flipfit:{left(...args){collisions.flip.left.apply(this,args);collisions.fit.left.apply(this,args);},top(...args){collisions.flip.top.apply(this,args);collisions.fit.top.apply(this,args);}}};$.position={scrollbarWidth(){if(cachedScrollbarWidth!==undefined)return cachedScrollbarWidth;const div=$('<div '+"style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'>"+"<div style='height:100px;width:auto;'></div></div>");const innerDiv=div.children()[0];$('body').append(div);const w1=innerDiv.offsetWidth;div[0].style.overflow='scroll';let w2=innerDiv.offsetWidth;if(w1===w2)w2=div[0].clientWidth;div.remove();cachedScrollbarWidth=w1-w2;return cachedScrollbarWidth;},getScrollInfo(within){const overflowX=within.isWindow||within.isDocument?'':window.getComputedStyle(within.element[0])['overflow-x'];const overflowY=within.isWindow||within.isDocument?'':window.getComputedStyle(within.element[0])['overflow-y'];const hasOverflowX=overflowX==='scroll'||(overflowX==='auto'&&within.width<within.element[0].scrollWidth);const hasOverflowY=overflowY==='scroll'||(overflowY==='auto'&&within.height<within.element[0].scrollHeight);return {width:hasOverflowY?$.position.scrollbarWidth():0,height:hasOverflowX?$.position.scrollbarWidth():0};},getWithinInfo(element){const withinElement=$(element||window);const isWindow=!!withinElement[0]&&withinElement[0]===withinElement[0].window;const isDocument=!!withinElement[0]&&withinElement[0].nodeType===9;const hasOffset=!isWindow&&!isDocument;return {element:withinElement,isWindow,isDocument,offset:hasOffset?$(element).offset():{left:0,top:0},scrollLeft:withinElement.scrollLeft(),scrollTop:withinElement.scrollTop(),width:withinElement.outerWidth(),height:withinElement.outerHeight()};}};$.fn.position=function(options){if(!options||!options.of)return _position.apply(this,arguments);options=$.extend({},options);const within=$.position.getWithinInfo(options.within);const scrollInfo=$.position.getScrollInfo(within);const collision=(options.collision||'flip').split(' ');const offsets={};const target=typeof options.of==='string'?$(document).find(options.of):$(options.of);const dimensions=getDimensions(target);const targetWidth=dimensions.width;const targetHeight=dimensions.height;const targetOffset=dimensions.offset;if(target[0].preventDefault)options.at='left top';const basePosition=$.extend({},targetOffset);$.each(['my','at'],function(){let pos=(options[this]||'').split(' ');
8if(pos.length===1)pos=regexHorizontal.test(pos[0])?pos.concat(['center']):regexVertical.test(pos[0])?['center'].concat(pos):['center','center'];pos[0]=regexHorizontal.test(pos[0])?pos[0]:'center';pos[1]=regexVertical.test(pos[1])?pos[1]:'center';const horizontalOffset=regexOffset.exec(pos[0]);const verticalOffset=regexOffset.exec(pos[1]);offsets[this]=[horizontalOffset?horizontalOffset[0]:0,verticalOffset?verticalOffset[0]:0];options[this]=[regexPosition.exec(pos[0])[0],regexPosition.exec(pos[1])[0]];});if(collision.length===1)collision[1]=collision[0];if(options.at[0]==='right')basePosition.left+=targetWidth;else{if(options.at[0]==='center')basePosition.left+=targetWidth/2;}if(options.at[1]==='bottom')basePosition.top+=targetHeight;else{if(options.at[1]==='center')basePosition.top+=targetHeight/2;}const atOffset=getOffsets(offsets.at,targetWidth,targetHeight);basePosition.left+=atOffset[0];basePosition.top+=atOffset[1];return this.each(function(){let using;const elem=$(this);const elemWidth=elem.outerWidth();const elemHeight=elem.outerHeight();const marginLeft=parseCss(this,'marginLeft');const marginTop=parseCss(this,'marginTop');const collisionWidth=elemWidth+marginLeft+parseCss(this,'marginRight')+scrollInfo.width;const collisionHeight=elemHeight+marginTop+parseCss(this,'marginBottom')+scrollInfo.height;const position=$.extend({},basePosition);const myOffset=getOffsets(offsets.my,elem.outerWidth(),elem.outerHeight());if(options.my[0]==='right')position.left-=elemWidth;else{if(options.my[0]==='center')position.left-=elemWidth/2;}if(options.my[1]==='bottom')position.top-=elemHeight;else{if(options.my[1]==='center')position.top-=elemHeight/2;}position.left+=myOffset[0];position.top+=myOffset[1];const collisionPosition={marginLeft,marginTop};$.each(['left','top'],function(i,dir){if(collisions[collision[i]])collisions[collision[i]][dir](position,{targetWidth,targetHeight,elemWidth,elemHeight,collisionPosition,collisionWidth,collisionHeight,offset:[atOffset[0]+myOffset[0],atOffset[1]+myOffset[1]],my:options.my,at:options.at,within,elem});});if(options.using)using=function(props){const left=targetOffset.left-position.left;const right=left+targetWidth-elemWidth;const top=targetOffset.top-position.top;const bottom=top+targetHeight-elemHeight;const feedback={target:{element:target,left:targetOffset.left,top:targetOffset.top,width:targetWidth,height:targetHeight},element:{element:elem,left:position.left,top:position.top,width:elemWidth,height:elemHeight},horizontal:right<0?'left':left>0?'right':'center',vertical:bottom<0?'top':top>0?'bottom':'middle'};if(targetWidth<elemWidth&&abs(left+right)<targetWidth)feedback.horizontal='center';if(targetHeight<elemHeight&&abs(top+bottom)<targetHeight)feedback.vertical='middle';if(max(abs(left),abs(right))>max(abs(top),abs(bottom)))feedback.important='horizontal';else feedback.important='vertical';options.using.call(this,props,feedback);};elem.offset($.extend(position,{using}));});};if(!$.hasOwnProperty('ui'))$.ui={};$.ui.position=collisions;})(jQuery);; 9(function($,Drupal,once){if(once('drupal-dialog-deprecation-listener','html').length){const eventSpecial={handle($event){const $element=$($event.target);const event=$event.originalEvent;const dialog=event.dialog;const dialogArguments=[$event,dialog,$element,event?.settings];$event.handleObj.handler.apply(this,dialogArguments);}};$.event.special['dialog:beforecreate']=eventSpecial;$.event.special['dialog:aftercreate']=eventSpecial;$.event.special['dialog:beforeclose']=eventSpecial;$.event.special['dialog:afterclose']=eventSpecial;const listenDialogEvent=(event)=>{const windowEvents=$._data(window,'events');const isWindowHasDialogListener=windowEvents[event.type];if(isWindowHasDialogListener)Drupal.deprecationError({message:`jQuery event ${event.type} is deprecated in 10.3.0 and is removed from Drupal:12.0.0. See https://www.drupal.org/node/3422670`});};['dialog:beforecreate','dialog:aftercreate','dialog:beforeclose','dialog:afterclose'].forEach((e)=>window.addEventListener(e,listenDialogEvent));}})(jQuery,Drupal,once);;
10class DrupalDialogEvent extends Event{constructor(type,dialog,settings=null){super(`dialog:${type}`,{bubbles:true});this.dialog=dialog;this.settings=settings;}}(function($,Drupal,drupalSettings,bodyScrollLock){drupalSettings.dialog={autoOpen:true,dialogClass:'',buttonClass:'button',buttonPrimaryClass:'button--primary',close(event){Drupal.dialog(event.target).close();Drupal.detachBehaviors(event.target,null,'unload');}};Drupal.dialog=function(element,options){let undef;const $element=$(element);const domElement=$element.get(0);const dialog={open:false,returnValue:undef};function openDialog(settings){settings=$.extend({},drupalSettings.dialog,options,settings);const event=new DrupalDialogEvent('beforecreate',dialog,settings);domElement.dispatchEvent(event);$element.dialog(event.settings);dialog.open=true;if(event.settings.modal)bodyScrollLock.lock(domElement);domElement.dispatchEvent(new DrupalDialogEvent('aftercreate',dialog,event.settings));}function closeDialog(value){domElement.dispatchEvent(new DrupalDialogEvent('beforeclose',dialog));bodyScrollLock.clearBodyLocks();$element.dialog('close');dialog.returnValue=value;dialog.open=false;domElement.dispatchEvent(new DrupalDialogEvent('afterclose',dialog));}dialog.show=()=>{openDialog({modal:false});};dialog.showModal=()=>{openDialog({modal:true});};dialog.close=closeDialog;return dialog;};})(jQuery,Drupal,drupalSettings,bodyScrollLock);; 11(function($,Drupal,drupalSettings,debounce,displace){drupalSettings.dialog=$.extend({autoResize:true,maxHeight:'95%'},drupalSettings.dialog);function resetPosition(options){const offsets=displace.offsets;const left=offsets.left-offsets.right;const top=offsets.top-offsets.bottom;const leftString=`${(left>0?'+':'-')+Math.abs(Math.round(left/2))}px`;const topString=`${(top>0?'+':'-')+Math.abs(Math.round(top/2))}px`;options.position={my:`center${left!==0?leftString:''} center${top!==0?topString:''}`,of:window};return options;}function resetSize(event){const positionOptions=['width','height','minWidth','minHeight','maxHeight','maxWidth','position'];let adjustedOptions={};let windowHeight=$(window).height();let option;let optionValue;let adjustedValue;for(let n=0;n<positionOptions.length;n++){option=positionOptions[n];optionValue=event.data.settings[option];if(optionValue)if(typeof optionValue==='string'&&optionValue.endsWith('%')&&/height/i.test(option)){windowHeight-=displace.offsets.top+displace.offsets.bottom;adjustedValue=parseInt(0.01*parseInt(optionValue,10)*windowHeight,10);if(option==='height'&&Math.round(event.data.$element.parent().outerHeight())<adjustedValue)adjustedValue='auto';adjustedOptions[option]=adjustedValue;}}if(!event.data.settings.modal)adjustedOptions=resetPosition(adjustedOptions);event.data.$element.dialog('option',adjustedOptions);event.data.$element?.get(0)?.dispatchEvent(new CustomEvent('dialogContentResize',{bubbles:true}));}window.addEventListener('dialog:aftercreate',(e)=>{const autoResize=debounce(resetSize,20);const $element=$(e.target);const {settings}=e;const eventData={settings,$element};if(settings.autoResize===true||settings.autoResize==='true'){const uiDialog=$element.dialog('option',{resizable:false,draggable:false}).dialog('widget');uiDialog[0].style.position='fixed';$(window).on('resize.dialogResize scroll.dialogResize',eventData,autoResize).trigger('resize.dialogResize');$(document).on('drupalViewportOffsetChange.dialogResize',eventData,autoResize);}});window.addEventListener('dialog:beforeclose',()=>{$(window).off('.dialogResize');$(document).off('.dialogResize');});})(jQuery,Drupal,drupalSettings,Drupal.debounce,Drupal.displace);; 12(function($,{tabbable,isTabbable}){$.widget('ui.dialog',$.ui.dialog,{options:{buttonClass:'button',buttonPrimaryClass:'button--primary'},_createButtons(){const opts=this.options;let primaryIndex;let index;const il=opts.buttons.length;for(index=0;index<il;index++)if(opts.buttons[index].primary&&opts.buttons[index].primary===true){primaryIndex=index;delete opts.buttons[index].primary;break;}this._super();const $buttons=this.uiButtonSet.children().addClass(opts.buttonClass);if(typeof primaryIndex!=='undefined')$buttons.eq(index).addClass(opts.buttonPrimaryClass);},_focusTabbable(){let hasFocus=this._focusedElement?this._focusedElement.get(0):null;if(!hasFocus)hasFocus=this.element.find('[autofocus]').get(0);if(!hasFocus){const $elements=[this.element,this.uiDialogButtonPane];for(let i=0;i<$elements.length;i++){const element=$elements[i].get(0);if(element){const elementTabbable=tabbable(element);hasFocus=elementTabbable.length?elementTabbable[0]:null;}if(hasFocus)break;}}if(!hasFocus){const closeBtn=this.uiDialogTitlebarClose.get(0);hasFocus=closeBtn&&isTabbable(closeBtn)?closeBtn:null;}if(!hasFocus)hasFocus=this.uiDialog.get(0);$(hasFocus).eq(0).trigger('focus');}});})(jQuery,window.tabbable);; 13(($)=>{$.widget('ui.dialog',$.ui.dialog,{_allowInteraction(event){if(event.target.classList===undefined)return this._super(event);return event.target.classList.contains('ck')||this._super(event);}});})(jQuery);; 14(function($,Drupal){"use strict";Drupal.mskMediaYouTubeOnload=function(){if(window.dataLayer&&window.dataLayer.push)window.dataLayer.push({'event':'modalOpen','attributes':{'type':'YouTube'}});};})(jQuery,Drupal);; 15(function($,once){"use strict";Drupal.behaviors.mskViewsExposedFormLetter={attach:function(context){$('.views-exposed-form #edit-letter',context).change(function(){window.location=location.pathname+'?letter='+$(this).val();}).val('');}};Drupal.behaviors.mskViewsAutocompleteSubmit={attach:function(context){$(once('msk-views-autocomplete-submit','.views-exposed-form input.form-autocomplete',context)).bind('autocompleteselect',function(event,ui){if(ui.item){var form=this.form;setTimeout(function(){form.submit();},1);}});}};})(jQuery,once);; 16/* @license GPL-2.0-or-later https://raw.githubusercontent.com/jquery-form/form/master/LICENSE */ 17(function(factory){if(typeof define==='function'&&define.amd)define(['jquery'],factory);else if(typeof module==='object'&&module.exports)module.exports=function(root,jQuery){if(typeof jQuery==='undefined')if(typeof window!=='undefined')jQuery=require('jquery');else jQuery=require('jquery')(root);factory(jQuery);return jQuery;};else factory(jQuery);}(function($){'use strict';var rCRLF=/\r?\n/g;var feature={};feature.fileapi=$('<input type="file">').get(0).files!==undefined;feature.formdata=(typeof window.FormData!=='undefined');var hasProp=!!$.fn.prop;$.fn.attr2=function(){if(!hasProp)return this.attr.apply(this,arguments);var val=this.prop.apply(this,arguments);if((val&&val.jquery)||typeof val==='string')return val;return this.attr.apply(this,arguments);};$.fn.ajaxSubmit=function(options,data,dataType,onSuccess){if(!this.length){log('ajaxSubmit: ski
17pping submit process - no element selected');return this;}var method,action,url,isMsie,iframeSrc,$form=this;if(typeof options==='function')options={success:options};else if(typeof options==='string'||(options===false&&arguments.length>0)){options={'url':options,'data':data,'dataType':dataType};if(typeof onSuccess==='function')options.success=onSuccess;}else{if(typeof options==='undefined')options={};}method=options.method||options.type||this.attr2('method');action=options.url||this.attr2('action');url=(typeof action==='string')?action.trim():'';url=url||window.location.href||'';if(url)url=(url.match(/^([^#]+)/)||[])[1];isMsie=/(MSIE|Trident)/.test(navigator.userAgent||'');iframeSrc=(isMsie&&/^https/i.test(window.location.href||''))?'javascript:false':'about:blank';options=$.extend(true,{url,success:$.ajaxSettings.success,type:method||$.ajaxSettings.type,iframeSrc},options);var veto={};this.trigger('form-pre-serialize',[this,options,veto]);if(veto.veto){log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');return this;}if(options.beforeSerialize&&options.beforeSerialize(this,options)===false){log('ajaxSubmit: submit aborted via beforeSerialize callback');return this;}var traditional=options.traditional;if(typeof traditional==='undefined')traditional=$.ajaxSettings.traditional;var elements=[];var qx,a=this.formToArray(options.semantic,elements,options.filtering);if(options.data){var optionsData=typeof (options.data)==="function"?options.data(a):options.data;options.extraData=optionsData;qx=$.param(optionsData,traditional);}if(options.beforeSubmit&&options.beforeSubmit(a,this,options)===false){log('ajaxSubmit: submit aborted via beforeSubmit callback');return this;}this.trigger('form-submit-validate',[a,this,options,veto]);if(veto.veto){log('ajaxSubmit: submit vetoed via form-submit-validate trigger');return this;}var q=$.param(a,traditional);if(qx)q=(q?(q+'&'+qx):qx);if(options.type.toUpperCase()==='GET'){options.url+=(options.url.indexOf('?')>=0?'&':'?')+q;options.data=null;}else options.data=q;var callbacks=[];if(options.resetForm)callbacks.push(function(){$form.resetForm();});if(options.clearForm)callbacks.push(function(){$form.clearForm(options.includeHidden);});if(!options.dataType&&options.target){var oldSuccess=options.success||function(){};callbacks.push(function(data,textStatus,jqXHR){var successArguments=arguments,fn=options.replaceTarget?'replaceWith':'html';$(options.target)[fn](data).each(function(){oldSuccess.apply(this,successArguments);});});}else{if(options.success)if(Array.isArray(options.success))callbacks=callbacks.concat(options.success);else callbacks.push(options.success);}options.success=function(data,status,xhr){var context=options.context||this;for(var i=0,max=callbacks.length;i<max;i++)callbacks[i].apply(context,[data,status,xhr||$form,$form]);};if(options.error){var oldError=options.error;options.error=function(xhr,status,error){var context=options.context||this;oldError.apply(context,[xhr,status,error,$form]);};}if(options.complete){var oldComplete=options.complete;options.complete=function(xhr,status){var context=options.context||this;oldComplete.apply(context,[xhr,status,$form]);};}var fileInputs=$('input[type=file]:enabled',this).filter(function(){return $(this).val()!=='';});var hasFileInputs=fileInputs.length>0;var mp='multipart/form-data';var multipart=($form.attr('enctype')===mp||$form.attr('encoding')===mp);var fileAPI=feature.fileapi&&feature.formdata;log('fileAPI :'+fileAPI);var shouldUseFrame=(hasFileInputs||multipart)&&!fileAPI;var jqxhr;if(options.iframe!==false&&(options.iframe||shouldUseFrame))if(options.closeKeepAlive)$.get(options.closeKeepAlive,function(){jqxhr=fileUploadIframe(a);});else jqxhr=fileUploadIframe(a);else if((hasFileInputs||multipart)&&fileAPI)jqxhr=fileUploadXhr(a);else jqxhr=$.ajax(options);$form.removeData('jqxhr').data('jqxhr',jqxhr);for(var k=0;k<elements.length;k++)elements[k]=null;this.trigger('form-submit-notify',[this,options]);return this;function deepSerialize(extraData){var serialized=$.param(extraData,options.traditional).split('&');var len=serialized.length;var result=[];var i,part;for(i=0;i<len;i++){serialized[i]=serialized[i].replace(/\+/g,' ');part=serialized[i].split('=');result.push([decodeURIComponent(part[0]),decodeURIComponent(part[1])]);}return result;}function fileUploadXhr(a){var formdata=new FormData();for(var i=0;i<a.length;i++)formdata.append(a[i].name,a[i].value);if(options.extraData){var serializedData=deepSerialize(options.extraData);for(i=0;i<serializedData.length;i++)if(serializedData[i])formdata.append(serializedData[i][0],serializedData[i][1]);}options.data=null;var s=$.extend(true,{},$.ajaxSettings,options,{contentType:false,processData:false,cache:false,type:method||'POST'});if(options.uploadProgress)s.xhr=function(){var xhr=$.ajaxSettings.xhr();if(xhr.upload)xhr.upload.addEventListener('progress',function(event){var percent=0;var position=event.loaded||event.position;var total=event.total;if(event.lengthComputable)percent=Math.ceil(position/total*100);options.uploadProgress(event,position,total,percent);},false);return xhr;};s.data=null;var beforeSend=s.beforeSend;s.beforeSend=function(xhr,o){if(options.formData)o.data=options.formData;else o.data=formdata;
17if(beforeSend)beforeSend.call(this,xhr,o);};return $.ajax(s);}function fileUploadIframe(a){var form=$form[0],el,i,s,g,id,$io,io,xhr,sub,n,timedOut,timeoutHandle;var deferred=$.Deferred();deferred.abort=function(status){xhr.abort(status);};if(a)for(i=0;i<elements.length;i++){el=$(elements[i]);if(hasProp)el.prop('disabled',false);else el.removeAttr('disabled');}s=$.extend(true,{},$.ajaxSettings,options);s.context=s.context||s;id='jqFormIO'+new Date().getTime();var ownerDocument=form.ownerDocument;var $body=$form.closest('body');if(s.iframeTarget){$io=$(s.iframeTarget,ownerDocument);n=$io.attr2('name');if(!n)$io.attr2('name',id);else id=n;}else{$io=$('<iframe name="'+id+'" src="'+s.iframeSrc+'" />',ownerDocument);$io.css({position:'absolute',top:'-1000px',left:'-1000px'});}io=$io[0];xhr={aborted:0,responseText:null,responseXML:null,status:0,statusText:'n/a',getAllResponseHeaders:function(){},getResponseHeader:function(){},setRequestHeader:function(){},abort:function(status){var e=(status==='timeout'?'timeout':'aborted');log('aborting upload... '+e);this.aborted=1;try{if(io.contentWindow.document.execCommand)io.contentWindow.document.execCommand('Stop');}catch(ignore){}$io.attr('src',s.iframeSrc);xhr.error=e;if(s.error)s.error.call(s.context,xhr,e,status);if(g)$.event.trigger('ajaxError',[xhr,s,e]);if(s.complete)s.complete.call(s.context,xhr,e);}};g=s.global;if(g&&$.active++===0)$.event.trigger('ajaxStart');if(g)$.event.trigger('ajaxSend',[xhr,s]);if(s.beforeSend&&s.beforeSend.call(s.context,xhr,s)===false){if(s.global)$.active--;deferred.reject();return deferred;}if(xhr.aborted){deferred.reject();return deferred;}sub=form.clk;if(sub){n=sub.name;if(n&&!sub.disabled){s.extraData=s.extraData||{};s.extraData[n]=sub.value;if(sub.type==='image'){s.extraData[n+'.x']=form.clk_x;s.extraData[n+'.y']=form.clk_y;}}}var CLIENT_TIMEOUT_ABORT=1;var SERVER_ABORT=2;function getDoc(frame){var doc=null;try{if(frame.contentWindow)doc=frame.contentWindow.document;}catch(err){log('cannot get iframe.contentWindow document: '+err);}if(doc)return doc;try{doc=frame.contentDocument?frame.contentDocument:frame.document;}catch(err){log('cannot get iframe.contentDocument: '+err);doc=frame.document;}return doc;}var csrf_token=$('meta[name=csrf-token]').attr('content');var csrf_param=$('meta[name=csrf-param]').attr('content');if(csrf_param&&csrf_token){s.extraData=s.extraData||{};s.extraData[csrf_param]=csrf_token;}function doSubmit(){var t=$form.attr2('target'),a=$form.attr2('action'),mp='multipart/form-data',et=$form.attr('enctype')||$form.attr('encoding')||mp;form.setAttribute('target',id);if(!method||/post/i.test(method))form.setAttribute('method','POST');if(a!==s.url)form.setAttribute('action',s.url);if(!s.skipEncodingOverride&&(!method||/post/i.test(method)))$form.attr({encoding:'multipart/form-data',enctype:'multipart/form-data'});if(s.timeout)timeoutHandle=setTimeout(function(){timedOut=true;cb(CLIENT_TIMEOUT_ABORT);},s.timeout);function checkState(){try{var state=getDoc(io).readyState;log('state = '+state);if(state&&state.toLowerCase()==='uninitialized')setTimeout(checkState,50);}catch(e){log('Server abort: ',e,' (',e.name,')');cb(SERVER_ABORT);if(timeoutHandle)clearTimeout(timeoutHandle);timeoutHandle=undefined;}}var extraInputs=[];try{if(s.extraData)for(var n in s.extraData)if(s.extraData.hasOwnProperty(n))if($.isPlainObject(s.extraData[n])&&s.extraData[n].hasOwnProperty('name')&&s.extraData[n].hasOwnProperty('value'))extraInputs.push($('<input type="hidden" name="'+s.extraData[n].name+'">',ownerDocument).val(s.extraData[n].value).appendTo(form)[0]);else extraInputs.push($('<input type="hidden" name="'+n+'">',ownerDocument).val(s.extraData[n]).appendTo(form)[0]);if(!s.iframeTarget)$io.appendTo($body);if(io.attachEvent)io.attachEvent('onload',cb);else io.addEventListener('load',cb,false);setTimeout(checkState,15);try{form.submit();}catch(err){var submitFn=document.createElement('form').submit;submitFn.apply(form);}}finally{form.setAttribute('action',a);form.setAttribute('enctype',et);if(t)form.setAttribute('target',t);else $form.removeAttr('target');$(extraInputs).remove();}}if(s.forceSync)doSubmit();else setTimeout(doSubmit,10);var data,doc,domCheckCount=50,callbackProcessed;function cb(e){if(xhr.aborted||callbackProcessed)return;doc=getDoc(io);if(!doc){log('cannot access response document');e=SERVER_ABORT;}if(e===CLIENT_TIMEOUT_ABORT&&xhr){xhr.abort('timeout');deferred.reject(xhr,'timeout');return;}if(e===SERVER_ABORT&&xhr){xhr.abort('server abort');deferred.reject(xhr,'error','server abort');return;}if(!doc||doc.location.href===s.iframeSrc)if(!timedOut)return;if(io.detachEvent)io.detachEvent('onload',cb);else io.removeEventListener('load',cb,false);var status='success',errMsg;
17try{if(timedOut)throw 'timeout';var isXml=s.dataType==='xml'||doc.XMLDocument||$.isXMLDoc(doc);log('isXml='+isXml);if(!isXml&&window.opera&&(doc.body===null||!doc.body.innerHTML))if(--domCheckCount){log('requeing onLoad callback, DOM not available');setTimeout(cb,250);return;}var docRoot=doc.body?doc.body:doc.documentElement;xhr.responseText=docRoot?docRoot.innerHTML:null;xhr.responseXML=doc.XMLDocument?doc.XMLDocument:doc;if(isXml)s.dataType='xml';xhr.getResponseHeader=function(header){var headers={'content-type':s.dataType};return headers[header.toLowerCase()];};if(docRoot){xhr.status=Number(docRoot.getAttribute('status'))||xhr.status;xhr.statusText=docRoot.getAttribute('statusText')||xhr.statusText;}var dt=(s.dataType||'').toLowerCase();var scr=/(json|script|text)/.test(dt);if(scr||s.textarea){var ta=doc.getElementsByTagName('textarea')[0];if(ta){xhr.responseText=ta.value;xhr.status=Number(ta.getAttribute('status'))||xhr.status;xhr.statusText=ta.getAttribute('statusText')||xhr.statusText;}else{if(scr){var pre=doc.getElementsByTagName('pre')[0];var b=doc.getElementsByTagName('body')[0];if(pre)xhr.responseText=pre.textContent?pre.textContent:pre.innerText;else{if(b)xhr.responseText=b.textContent?b.textContent:b.innerText;}}}}else{if(dt==='xml'&&!xhr.responseXML&&xhr.responseText)xhr.responseXML=toXml(xhr.responseText);}try{data=httpData(xhr,dt,s);}catch(err){status='parsererror';xhr.error=errMsg=(err||status);}}catch(err){log('error caught: ',err);status='error';xhr.error=errMsg=(err||status);}if(xhr.aborted){log('upload aborted');status=null;}if(xhr.status)status=((xhr.status>=200&&xhr.status<300)||xhr.status===304)?'success':'error';if(status==='success'){if(s.success)s.success.call(s.context,data,'success',xhr);deferred.resolve(xhr.responseText,'success',xhr);if(g)$.event.trigger('ajaxSuccess',[xhr,s]);}else{if(status){if(typeof errMsg==='undefined')errMsg=xhr.statusText;if(s.error)s.error.call(s.context,xhr,status,errMsg);deferred.reject(xhr,'error',errMsg);if(g)$.event.trigger('ajaxError',[xhr,s,errMsg]);}}if(g)$.event.trigger('ajaxComplete',[xhr,s]);if(g&&!--$.active)$.event.trigger('ajaxStop');if(s.complete)s.complete.call(s.context,xhr,status);callbackProcessed=true;if(s.timeout)clearTimeout(timeoutHandle);setTimeout(function(){if(!s.iframeTarget)$io.remove();else $io.attr('src',s.iframeSrc);xhr.responseXML=null;},100);}var toXml=$.parseXML||function(s,doc){if(window.ActiveXObject){doc=new ActiveXObject('Microsoft.XMLDOM');doc.async='false';doc.loadXML(s);}else doc=(new DOMParser()).parseFromString(s,'text/xml');return (doc&&doc.documentElement&&doc.documentElement.nodeName!=='parsererror')?doc:null;};var parseJSON=$.parseJSON||function(s){return window['eval']('('+s+')');};var httpData=function(xhr,type,s){var ct=xhr.getResponseHeader('content-type')||'',xml=((type==='xml'||!type)&&ct.indexOf('xml')>=0),data=xml?xhr.responseXML:xhr.responseText;if(xml&&data.documentElement.nodeName==='parsererror')if($.error)$.error('parsererror');if(s&&s.dataFilter)data=s.dataFilter(data,type);if(typeof data==='string')if((type==='json'||!type)&&ct.indexOf('json')>=0)data=parseJSON(data);else{if((type==='script'||!type)&&ct.indexOf('javascript')>=0)$.globalEval(data);}return data;};return deferred;}};$.fn.ajaxForm=function(options,data,dataType,onSuccess){if(typeof options==='string'||(options===false&&arguments.length>0)){options={'url':options,'data':data,'dataType':dataType};if(typeof onSuccess==='function')options.success=onSuccess;}options=options||{};options.delegation=options.delegation&&typeof $.fn.on==='function';if(!options.delegation&&this.length===0){var o={s:this.selector,c:this.context};if(!$.isReady&&o.s){log('DOM not ready, queuing ajaxForm');$(function(){$(o.s,o.c).ajaxForm(options);});return this;}log('terminating; zero elements found by selector'+($.isReady?'':' (DOM not ready)'));return this;}if(options.delegation){$(document).off('submit.form-plugin',this.selector,doAjaxSubmit).off('click.form-plugin',this.selector,captureSubmittingElement).on('submit.form-plugin',this.selector,options,doAjaxSubmit).on('click.form-plugin',this.selector,options,captureSubmittingElement);return this;}if(options.beforeFormUnbind)options.beforeFormUnbind(this,options);return this.ajaxFormUnbind().on('submit.form-plugin',options,doAjaxSubmit).on('click.form-plugin',options,captureSubmittingElement);};function doAjaxSubmit(e){var options=e.data;if(!e.isDefaultPrevented()){e.preventDefault();$(e.target).closest('form').ajaxSubmit(options);}}function captureSubmittingElement(e){var target=e.target;var $el=$(target);if(!$el.is('[type=submit],[type=image]')){var t=$el.closest('[type=submit]');if(t.length===0)return;target=t[0];}var form=target.form;form.clk=target;if(target.type==='image')if(typeof e.offsetX!=='undefined'){form.clk_x=e.offsetX;form.clk_y=e.offsetY;}else if(typeof $.fn.offset==='function'){var offset=$el.offset();form.clk_x=e.pageX-offset.left;form.clk_y=e.pageY-offset.top;}else{form.clk_x=e.pageX-target.offsetLeft;form.clk_y=e.pageY-target.offsetTop;}setTimeout(function(){form.clk=form.clk_x=form.clk_y=null;},100);}$.fn.ajaxFormUnbind=function(){return this.off('submit.form-plugin click.form-plugin');};$.fn.formToArray=function(semantic,elements,filtering){var a=[];if(this.length===0)return a;var form=this[0];var formId=this.attr('id');var els=(semantic||typeof form.elements==='undefined')?form.getElementsByTagName('*'):form.elements;var els2;if(els)els=$.makeArray(els);if(formId&&(semantic||/(Edge|Trident)\//.test(navigator.userAgent))){els2=$(':input[form="'+formId+'"]').get();if(els2.length)els=(els||[]).concat(els2);}if(!els||!els.length)return a;
17if(typeof (filtering)==="function")els=$.map(els,filtering);var i,j,n,v,el,max,jmax;for(i=0,max=els.length;i<max;i++){el=els[i];n=el.name;if(!n||el.disabled)continue;if(semantic&&form.clk&&el.type==='image'){if(form.clk===el){a.push({name:n,value:$(el).val(),type:el.type});a.push({name:n+'.x',value:form.clk_x},{name:n+'.y',value:form.clk_y});}continue;}v=$.fieldValue(el,true);if(v&&v.constructor===Array){if(elements)elements.push(el);for(j=0,jmax=v.length;j<jmax;j++)a.push({name:n,value:v[j]});}else if(feature.fileapi&&el.type==='file'){if(elements)elements.push(el);var files=el.files;if(files.length)for(j=0;j<files.length;j++)a.push({name:n,value:files[j],type:el.type});else a.push({name:n,value:'',type:el.type});}else{if(v!==null&&typeof v!=='undefined'){if(elements)elements.push(el);a.push({name:n,value:v,type:el.type,required:el.required});}}}if(!semantic&&form.clk){var $input=$(form.clk),input=$input[0];n=input.name;if(n&&!input.disabled&&input.type==='image'){a.push({name:n,value:$input.val()});a.push({name:n+'.x',value:form.clk_x},{name:n+'.y',value:form.clk_y});}}return a;};$.fn.formSerialize=function(semantic){return $.param(this.formToArray(semantic));};$.fn.fieldSerialize=function(successful){var a=[];this.each(function(){var n=this.name;if(!n)return;var v=$.fieldValue(this,successful);if(v&&v.constructor===Array)for(var i=0,max=v.length;i<max;i++)a.push({name:n,value:v[i]});else{if(v!==null&&typeof v!=='undefined')a.push({name:this.name,value:v});}});return $.param(a);};$.fn.fieldValue=function(successful){for(var val=[],i=0,max=this.length;i<max;i++){var el=this[i];var v=$.fieldValue(el,successful);if(v===null||typeof v==='undefined'||(v.constructor===Array&&!v.length))continue;if(Array.isArray(v))val=val.concat(v);else val.push(v);}return val;};$.fieldValue=function(el,successful){var n=el.name,t=el.type,tag=el.tagName.toLowerCase();if(typeof successful==='undefined')successful=true;if(successful&&(!n||el.disabled||t==='reset'||t==='button'||(t==='checkbox'||t==='radio')&&!el.checked||(t==='submit'||t==='image')&&el.form&&el.form.clk!==el||tag==='select'&&el.selectedIndex===-1))return null;if(tag==='select'){var index=el.selectedIndex;if(index<0)return null;var a=[],ops=el.options;var one=(t==='select-one');var max=(one?index+1:ops.length);for(var i=(one?index:0);i<max;i++){var op=ops[i];if(op.selected&&!op.disabled){var v=op.value;if(!v)v=(op.attributes&&op.attributes.value&&!(op.attributes.value.specified))?op.text:op.value;if(one)return v;a.push(v);}}return a;}return $(el).val().replace(rCRLF,'\r\n');};$.fn.clearForm=function(includeHidden){return this.each(function(){$('input,select,textarea',this).clearFields(includeHidden);});};$.fn.clearFields=$.fn.clearInputs=function(includeHidden){var re=/^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i;return this.each(function(){var t=this.type,tag=this.tagName.toLowerCase();if(re.test(t)||tag==='textarea')this.value='';else if(t==='checkbox'||t==='radio')this.checked=false;else if(tag==='select')this.selectedIndex=-1;else if(t==='file')if(/MSIE/.test(navigator.userAgent))$(this).replaceWith($(this).clone(true));else $(this).val('');else{if(includeHidden)if((includeHidden===true&&/hidden/.test(t))||(typeof includeHidden==='string'&&$(this).is(includeHidden)))this.value='';}});};$.fn.resetForm=function(){return this.each(function(){var el=$(this);var tag=this.tagName.toLowerCase();switch(tag){case 'input':this.checked=this.defaultChecked;case 'textarea':this.value=this.defaultValue;return true;case 'option':case 'optgroup':var select=el.parents('select');if(select.length&&select[0].multiple)if(tag==='option')this.selected=this.defaultSelected;else el.find('option').resetForm();else select.resetForm();return true;case 'select':el.find('option').each(function(i){this.selected=this.defaultSelected;if(this.defaultSelected&&!el[0].multiple){el[0].selectedIndex=i;return false;}});return true;case 'label':var forEl=$(el.attr('for'));var list=el.find('input,select,textarea');if(forEl[0])list.unshift(forEl[0]);list.resetForm();return true;case 'form':if(typeof this.reset==='function'||(typeof this.reset==='object'&&!this.reset.nodeType))this.reset();return true;default:el.find('form,input,label,select,textarea').resetForm();return true;}}
17);};$.fn.enable=function(b){if(typeof b==='undefined')b=true;return this.each(function(){this.disabled=!b;});};$.fn.selected=function(select){if(typeof select==='undefined')select=true;return this.each(function(){var t=this.type;if(t==='checkbox'||t==='radio')this.checked=select;else{if(this.tagName.toLowerCase()==='option'){var $sel=$(this).parent('select');if(select&&$sel[0]&&$sel[0].type==='select-one')$sel.find('option').selected(false);this.selected=select;}}});};$.fn.ajaxSubmit.debug=false;function log(){if(!$.fn.ajaxSubmit.debug)return;var msg='[jquery.form] '+Array.prototype.join.call(arguments,'');if(window.console&&window.console.log)window.console.log(msg);else{if(window.opera&&window.opera.postError)window.opera.postError(msg);}}}));; 18/* @license GPL-2.0-or-later https://www.drupal.org/licensing/faq */ 19(function($,Drupal){Drupal.theme.progressBar=function(id){const escapedId=Drupal.checkPlain(id);return (`<div id="${escapedId}" class="progress" aria-live="polite">`+'<div class="progress__label"> </div>'+'<div class="progress__track"><div class="progress__bar"></div></div>'+'<div class="progress__percentage"></div>'+'<div class="progress__description"> </div>'+'</div>');};Drupal.ProgressBar=function(id,updateCallback,method,errorCallback){this.id=id;this.method=method||'GET';this.updateCallback=updateCallback;this.errorCallback=errorCallback;this.element=$(Drupal.theme('progressBar',id));};$.extend(Drupal.ProgressBar.prototype,{setProgress(percentage,message,label){if(percentage>=0&&percentage<=100){$(this.element).find('div.progress__bar').each(function(){this.style.width=`${percentage}%`;});$(this.element).find('div.progress__percentage').html(`${percentage}%`);}$('div.progress__description',this.element).html(message);$('div.progress__label',this.element).html(label);if(this.updateCallback)this.updateCallback(percentage,message,this);},startMonitoring(uri,delay){this.delay=delay;this.uri=uri;this.sendPing();},stopMonitoring(){clearTimeout(this.timer);this.uri=null;},sendPing(){if(this.timer)clearTimeout(this.timer);if(this.uri){const pb=this;let uri=this.uri;if(!uri.includes('?'))uri+='?';else uri+='&';uri+='_format=json';$.ajax({type:this.method,url:uri,data:'',dataType:'json',success(progress){if(progress.status===0){pb.displayError(progress.data);return;}pb.setProgress(progress.percentage,progress.message,progress.label);pb.timer=setTimeout(()=>{pb.sendPing();},pb.delay);},error(xmlhttp){const e=new Drupal.AjaxError(xmlhttp,pb.uri);pb.displayError(`<pre>${e.message}</pre>`);}});}},displayError(string){const error=$('<div class="messages messages--error"></div>').html(string);$(this.element).before(error).hide();if(this.errorCallback)this.errorCallback(this);}});})(jQuery,Drupal);; 20/* @license MIT https://raw.githubusercontent.com/muicss/loadjs/4.3.0/LICENSE.txt */ 21loadjs=function(){var h=function(){},o={},c={},f={};function u(e,n){if(e){var t=f[e];if(c[e]=n,t)for(;t.length;)t[0](e,n),t.splice(0,1)}}function l(e,n){e.call&&(e={success:e}),n.length?(e.error||h)(n):(e.success||h)(e)}function p(t,r,i,s){var o,e,u,n=document,c=i.async,f=(i.numRetries||0)+1,l=i.before||h,a=t.replace(/[\?|#].*$/,""),d=t.replace(/^(css|img|module|nomodule)!/,"");if(s=s||0,/(^css!|\.css$)/.test(a))(u=n.createElement("link")).rel="stylesheet",u.href=d,(o="hideFocus"in u)&&u.relList&&(o=0,u.rel="preload",u.as="style");else if(/(^img!|\.(png|gif|jpg|svg|webp)$)/.test(a))(u=n.createElement("img")).src=d;else if((u=n.createElement("script")).src=d,u.async=void 0===c||c,e="noModule"in u,/^module!/.test(a)){if(!e)return r(t,"l");u.type="module"}else if(/^nomodule!/.test(a)&&e)return r(t,"l");!(u.onload=u.onerror=u.onbeforeload=function(e){var n=e.type[0];if(o)try{u.sheet.cssText.length||(n="e")}catch(e){18!=e.code&&(n="e")}if("e"==n){if((s+=1)<f)return p(t,r,i,s)}else if("preload"==u.rel&&"style"==u.as)return u.rel="stylesheet";r(t,n,e.defaultPrevented)})!==l(t,u)&&n.head.appendChild(u)}function t(e,n,t){var r,i;if(n&&n.trim&&(r=n),i=(r?t:n)||{},r){if(r in o)throw"LoadJS";o[r]=!0}function s(n,t){!function(e,r,n){var t,i,s=(e=e.push?e:[e]).length,o=s,u=[];for(t=function(e,n,t){if("e"==n&&u.push(e),"b"==n){if(!t)return;u.push(e)}--s||r(u)},i=0;i<o;i++)p(e[i],t,n)}(e,function(e){l(i,e),n&&l({success:n,error:t},e),u(r,e)},i)}if(i.returnPromise)return new Promise(s);s()}return t.ready=function(e,n){return function(e,t){e=e.push?e:[e];var n,r,i,s=[],o=e.length,u=o;
21for(n=function(e,n){n.length&&s.push(e),--u||t(s)};o--;)r=e[o],(i=c[r])?n(r,i):(f[r]=f[r]||[]).push(n)}(e,function(e){l(n,e)}),t},t.done=function(e){u(e,[])},t.reset=function(){o={},c={},f={}},t.isDefined=function(e){return e in o},t}();; 22/* @license GPL-2.0-or-later https://www.drupal.org/licensing/faq */ 23(function(Drupal,debounce){let liveElement;const announcements=[];Drupal.behaviors.drupalAnnounce={attach(context){if(!liveElement){liveElement=document.createElement('div');liveElement.id='drupal-live-announce';liveElement.className='visually-hidden';liveElement.setAttribute('aria-live','polite');liveElement.setAttribute('aria-busy','false');document.body.appendChild(liveElement);}}};function announce(){const text=[];let priority='polite';let announcement;const il=announcements.length;for(let i=0;i<il;i++){announcement=announcements.pop();text.unshift(announcement.text);if(announcement.priority==='assertive')priority='assertive';}if(text.length){liveElement.innerHTML='';liveElement.setAttribute('aria-busy','true');liveElement.setAttribute('aria-live',priority);liveElement.innerHTML=text.join('\n');liveElement.setAttribute('aria-busy','false');}}Drupal.announce=function(text,priority){announcements.push({text,priority});return debounce(announce,200)();};})(Drupal,Drupal.debounce);; 24((Drupal)=>{Drupal.Message=class{constructor(messageWrapper=null){if(!messageWrapper)this.messageWrapper=Drupal.Message.defaultWrapper();else this.messageWrapper=messageWrapper;}static defaultWrapper(){let wrapper=document.querySelector('[data-drupal-messages]')||document.querySelector('[data-drupal-messages-fallback]');if(!wrapper){wrapper=document.createElement('div');document.body.appendChild(wrapper);}if(wrapper.hasAttribute('data-drupal-messages-fallback')){wrapper.removeAttribute('data-drupal-messages-fallback');wrapper.classList.remove('hidden');}wrapper.setAttribute('data-drupal-messages','');return wrapper.innerHTML===''?Drupal.Message.messageInternalWrapper(wrapper):wrapper.firstElementChild;}static getMessageTypeLabels(){return {status:Drupal.t('Status message'),error:Drupal.t('Error message'),warning:Drupal.t('Warning message')};}add(message,options={}){if(!options.hasOwnProperty('type'))options.type='status';if(typeof message!=='string')throw new Error('Message must be a string.');Drupal.Message.announce(message,options);options.id=options.id?String(options.id):`${options.type}-${Math.random().toFixed(15).replace('0.','')}`;if(!Drupal.Message.getMessageTypeLabels().hasOwnProperty(options.type)){const {type}=options;throw new Error(`The message type, ${type}, is not present in Drupal.Message.getMessageTypeLabels().`);}this.messageWrapper.appendChild(Drupal.theme('message',{text:message},options));return options.id;}select(id){return this.messageWrapper.querySelector(`[data-drupal-message-id^="${id}"]`);}remove(id){return this.messageWrapper.removeChild(this.select(id));}clear(){Array.prototype.forEach.call(this.messageWrapper.querySelectorAll('[data-drupal-message-id]'),(message)=>{this.messageWrapper.removeChild(message);});}static announce(message,options){if(!options.priority&&(options.type==='warning'||options.type==='error'))options.priority='assertive';if(options.announce!=='')Drupal.announce(options.announce||message,options.priority);}static messageInternalWrapper(messageWrapper){const innerWrapper=document.createElement('div');innerWrapper.setAttribute('class','messages__wrapper');messageWrapper.insertAdjacentElement('afterbegin',innerWrapper);return innerWrapper;}};Drupal.theme.message=({text},{type,id})=>{const messagesTypes=Drupal.Message.getMessageTypeLabels();const messageWrapper=document.createElement('div');messageWrapper.setAttribute('class',`messages messages--${type}`);messageWrapper.setAttribute('role',type==='error'||type==='warning'?'alert':'status');messageWrapper.setAttribute('data-drupal-message-id',id);messageWrapper.setAttribute('data-drupal-message-type',type);messageWrapper.setAttribute('aria-label',messagesTypes[type]);messageWrapper.innerHTML=`${text}`;return messageWrapper;};})(Drupal);; 25(function($,window,Drupal,drupalSettings,loadjs,{isFocusable,tabbable}){Drupal.behaviors.AJAX={attach(context,settings){function loadAjaxBehavior(base){const elementSettings=settings.ajax[base];if(typeof elementSettings.selector==='undefined')elementSettings.selector=`#${base}`;
25once('drupal-ajax',$(elementSettings.selector)).forEach((el)=>{elementSettings.element=el;elementSettings.base=base;Drupal.ajax(elementSettings);});}Object.keys(settings.ajax||{}).forEach(loadAjaxBehavior);Drupal.ajax.bindAjaxLinks(document.body);once('ajax','.use-ajax-submit').forEach((el)=>{const elementSettings={};elementSettings.url=$(el.form).attr('action');elementSettings.setClick=true;elementSettings.event='click';elementSettings.progress={type:'throbber'};elementSettings.base=el.id;elementSettings.element=el;Drupal.ajax(elementSettings);});},detach(context,settings,trigger){if(trigger==='unload')Drupal.ajax.expired().forEach((instance)=>{Drupal.ajax.instances[instance.instanceIndex]=null;});}};Drupal.AjaxError=function(xmlhttp,uri,customMessage){let statusCode;let statusText;let responseText;if(xmlhttp.status)statusCode=`\n${Drupal.t('An AJAX HTTP error occurred.')}\n${Drupal.t('HTTP Result Code: !status',{'!status':xmlhttp.status})}`;else statusCode=`\n${Drupal.t('An AJAX HTTP request terminated abnormally.')}`;statusCode+=`\n${Drupal.t('Debugging information follows.')}`;const pathText=`\n${Drupal.t('Path: !uri',{'!uri':uri})}`;statusText='';try{statusText=`\n${Drupal.t('StatusText: !statusText',{'!statusText':xmlhttp.statusText.trim()})}`;}catch(e){}responseText='';try{responseText=`\n${Drupal.t('ResponseText: !responseText',{'!responseText':xmlhttp.responseText.trim()})}`;}catch(e){}responseText=responseText.replace(/<("[^"]*"|'[^']*'|[^'">])*>/gi,'');responseText=responseText.replace(/[\n]+\s+/g,'\n');const readyStateText=xmlhttp.status===0?`\n${Drupal.t('ReadyState: !readyState',{'!readyState':xmlhttp.readyState})}`:'';customMessage=customMessage?`\n${Drupal.t('CustomMessage: !customMessage',{'!customMessage':customMessage})}`:'';this.message=statusCode+pathText+statusText+customMessage+responseText+readyStateText;this.name='AjaxError';if(!Drupal.AjaxError.messages)Drupal.AjaxError.messages=new Drupal.Message();Drupal.AjaxError.messages.add(Drupal.t("Oops, something went wrong. Check your browser's developer console for more details."),{type:'error'});};Drupal.AjaxError.prototype=new Error();Drupal.AjaxError.prototype.constructor=Drupal.AjaxError;Drupal.ajax=function(settings){if(arguments.length!==1)throw new Error('Drupal.ajax() function must be called with one configuration object only');const base=settings.base||false;const element=settings.element||false;delete settings.base;delete settings.element;if(!settings.progress&&!element)settings.progress=false;const ajax=new Drupal.Ajax(base,element,settings);ajax.instanceIndex=Drupal.ajax.instances.length;Drupal.ajax.instances.push(ajax);return ajax;};Drupal.ajax.instances=[];Drupal.ajax.expired=function(){return Drupal.ajax.instances.filter((instance)=>instance&&instance.element!==false&&!document.body.contains(instance.element));};Drupal.ajax.bindAjaxLinks=(element)=>{once('ajax','.use-ajax',element).forEach((ajaxLink)=>{const $linkElement=$(ajaxLink);const elementSettings={progress:{type:'throbber'},dialogType:$linkElement.data('dialog-type'),dialog:$linkElement.data('dialog-options'),dialogRenderer:$linkElement.data('dialog-renderer'),base:$linkElement.attr('id'),element:ajaxLink};const href=$linkElement.attr('href');if(href){elementSettings.url=href;elementSettings.event='click';}const httpMethod=$linkElement.data('ajax-http-method');if(httpMethod)elementSettings.httpMethod=httpMethod;Drupal.ajax(elementSettings);});};Drupal.Ajax=function(base,element,elementSettings){const defaults={httpMethod:'POST',event:element?'mousedown':null,keypress:true,selector:base?`#${base}`:null,effect:'none',speed:'none',method:'replaceWith',progress:{type:'throbber',message:Drupal.t('Processing...')},submit:{js:true}};$.extend(this,defaults,elementSettings);this.commands=new Drupal.AjaxCommands();this.instanceIndex=false;if(this.wrapper)this.wrapper=`#${this.wrapper}`;this.element=element;this.preCommandsFocusedElementSelector=null;this.elementSettings=elementSettings;if(this.element&&this.element.form)this.$form=$(this.element.form);if(!this.url){const $element=$(this.element);if(this.element.tagName==='A')this.url=$element.attr('href');else{if(this.element&&element.form)this.url=this.$form.attr('action');}}const originalUrl=this.url;this.url=this.url.replace(/\/nojs(\/|$|\?|#)/,'/ajax$1');if(drupalSettings.ajaxTrustedUrl[originalUrl])drupalSettings.ajaxTrustedUrl[this.url]=true;const ajax=this;ajax.options={url:ajax.url,data:ajax.submit,isInProgress(){return ajax.ajaxing;},beforeSerialize(elementSettings,options){return ajax.beforeSerialize(elementSettings,options);},beforeSubmit(formValues,elementSettings,options){ajax.ajaxing=true;ajax.preCommandsFocusedElementSelector=null;return ajax.beforeSubmit(formValues,elementSettings,options);},beforeSend(xmlhttprequest,options){ajax.ajaxing=true;return ajax.beforeSend(xmlhttprequest,options);},success(response,status,xmlhttprequest){ajax.preCommandsFocusedElementSelector=document.activeElement.getAttribute('data-drupal-selector');if(typeof response==='string')response=$.parseJSON(response);if(response!==null&&!drupalSettings.ajaxTrustedUrl[ajax.url])if(xmlhttprequest.getResponseHeader('X-Drupal-Ajax-Token')!=='1'){const customMessage=Drupal.t('The response failed verification so will not be processed.');return ajax.error(xmlhttprequest,ajax.url,customMessage);}return (Promise.resolve(ajax.success(response,status)).then(()=>{ajax.ajaxing=false;
25$(document).trigger('ajaxSuccess',[xmlhttprequest,this]);$(document).trigger('ajaxComplete',[xmlhttprequest,this]);if(--$.active===0)$(document).trigger('ajaxStop');}));},error(xmlhttprequest,status,error){ajax.ajaxing=false;},complete(xmlhttprequest,status){if(status==='error'||status==='parsererror')return ajax.error(xmlhttprequest,ajax.url);},dataType:'json',jsonp:false,method:ajax.httpMethod};if(elementSettings.dialog)ajax.options.data.dialogOptions=elementSettings.dialog;if(!ajax.options.url.includes('?'))ajax.options.url+='?';else ajax.options.url+='&';let wrapper=`drupal_${elementSettings.dialogType||'ajax'}`;if(elementSettings.dialogRenderer)wrapper+=`.${elementSettings.dialogRenderer}`;ajax.options.url+=`${Drupal.ajax.WRAPPER_FORMAT}=${wrapper}`;$(ajax.element).on(elementSettings.event,function(event){if(!drupalSettings.ajaxTrustedUrl[ajax.url]&&!Drupal.url.isLocal(ajax.url))throw new Error(Drupal.t('The callback URL is not local and not trusted: !url',{'!url':ajax.url}));return ajax.eventResponse(this,event);});if(elementSettings.keypress)$(ajax.element).on('keypress',function(event){return ajax.keypressResponse(this,event);});if(elementSettings.prevent)$(ajax.element).on(elementSettings.prevent,false);};Drupal.ajax.WRAPPER_FORMAT='_wrapper_format';Drupal.Ajax.AJAX_REQUEST_PARAMETER='_drupal_ajax';Drupal.Ajax.prototype.execute=function(){if(this.ajaxing)return;try{this.beforeSerialize(this.element,this.options);return $.ajax(this.options);}catch(e){this.ajaxing=false;window.alert(`An error occurred while attempting to process ${this.options.url}: ${e.message}`);return $.Deferred().reject();}};Drupal.Ajax.prototype.keypressResponse=function(element,event){const ajax=this;if(event.which===13||(event.which===32&&element.type!=='text'&&element.type!=='textarea'&&element.type!=='tel'&&element.type!=='number')){event.preventDefault();event.stopPropagation();$(element).trigger(ajax.elementSettings.event);}};Drupal.Ajax.prototype.eventResponse=function(element,event){event.preventDefault();event.stopPropagation();const ajax=this;if(ajax.ajaxing)return;try{if(ajax.$form){if(ajax.setClick)element.form.clk=element;ajax.$form.ajaxSubmit(ajax.options);}else{ajax.beforeSerialize(ajax.element,ajax.options);$.ajax(ajax.options);}}catch(e){ajax.ajaxing=false;window.alert(`An error occurred while attempting to process ${ajax.options.url}: ${e.message}`);}};Drupal.Ajax.prototype.beforeSerialize=function(element,options){if(this.$form&&document.body.contains(this.$form.get(0))){const settings=this.settings||drupalSettings;Drupal.detachBehaviors(this.$form.get(0),settings,'serialize');}options.data[Drupal.Ajax.AJAX_REQUEST_PARAMETER]=1;const pageState=drupalSettings.ajaxPageState;options.data['ajax_page_state[theme]']=pageState.theme;options.data['ajax_page_state[theme_token]']=pageState.theme_token;options.data['ajax_page_state[libraries]']=pageState.libraries;};Drupal.Ajax.prototype.beforeSubmit=function(formValues,element,options){};Drupal.Ajax.prototype.beforeSend=function(xmlhttprequest,options){if(this.$form){options.extraData=options.extraData||{};options.extraData.ajax_iframe_upload='1';const v=$.fieldValue(this.element);if(v!==null)options.extraData[this.element.name]=v;}$(this.element).prop('disabled',true);if(!this.progress||!this.progress.type)return;const progressIndicatorMethod=`setProgressIndicator${this.progress.type.slice(0,1).toUpperCase()}${this.progress.type.slice(1).toLowerCase()}`;if(progressIndicatorMethod in this&&typeof this[progressIndicatorMethod]==='function')this[progressIndicatorMethod].call(this);};Drupal.theme.ajaxProgressThrobber=(message)=>{const messageMarkup=typeof message==='string'?Drupal.theme('ajaxProgressMessage',message):'';const throbber='<div class="throbber"> </div>';return `<div class="ajax-progress ajax-progress-throbber">${throbber}${messageMarkup}</div>`;};Drupal.theme.ajaxProgressIndicatorFullscreen=()=>'<div class="ajax-progress ajax-progress-fullscreen"> </div>';Drupal.theme.ajaxProgressMessage=(message)=>`<div class="message">${message}</div>`;Drupal.theme.ajaxProgressBar=($element)=>$('<div class="ajax-progress ajax-progress-bar"></div>').append($element);Drupal.Ajax.prototype.setProgressIndicatorBar=function(){const progressBar=new Drupal.ProgressBar(`ajax-progress-${this.element.i
25d}`,$.noop,this.progress.method,$.noop);if(this.progress.message)progressBar.setProgress(-1,this.progress.message);if(this.progress.url)progressBar.startMonitoring(this.progress.url,this.progress.interval||1500);this.progress.element=$(Drupal.theme('ajaxProgressBar',progressBar.element));this.progress.object=progressBar;$(this.element).after(this.progress.element);};Drupal.Ajax.prototype.setProgressIndicatorThrobber=function(){this.progress.element=$(Drupal.theme('ajaxProgressThrobber',this.progress.message));if($(this.element).closest('[data-drupal-ajax-container]').length)$(this.element).closest('[data-drupal-ajax-container]').after(this.progress.element);else $(this.element).after(this.progress.element);};Drupal.Ajax.prototype.setProgressIndicatorFullscreen=function(){this.progress.element=$(Drupal.theme('ajaxProgressIndicatorFullscreen'));$('body').append(this.progress.element);};Drupal.Ajax.prototype.commandExecutionQueue=function(response,status){const ajaxCommands=this.commands;return Object.keys(response||{}).reduce((executionQueue,key)=>executionQueue.then(()=>{const {command}=response[key];if(command&&ajaxCommands[command])return ajaxCommands[command](this,response[key],status);}),Promise.resolve());};Drupal.Ajax.prototype.success=function(response,status){if(this.progress.element)$(this.progress.element).remove();if(this.progress.object)this.progress.object.stopMonitoring();$(this.element).prop('disabled',false);const elementParents=$(this.element).parents('[data-drupal-selector]').addBack().toArray();const focusChanged=Object.keys(response||{}).some((key)=>{const {command,method}=response[key];return (command==='focusFirst'||command==='openDialog'||(command==='invoke'&&method==='focus'));});return (this.commandExecutionQueue(response,status).then(()=>{if(!focusChanged){let target=false;if(this.element){if($(this.element).data('refocus-blur')&&this.preCommandsFocusedElementSelector)target=document.querySelector(`[data-drupal-selector="${this.preCommandsFocusedElementSelector}"]`);if(!target&&!$(this.element).data('disable-refocus')){for(let n=elementParents.length-1;!target&&n>=0;n--)target=document.querySelector(`[data-drupal-selector="${elementParents[n].getAttribute('data-drupal-selector')}"]`);}}if(target)$(target).trigger('focus');}if(this.$form&&document.body.contains(this.$form.get(0))){const settings=this.settings||drupalSettings;Drupal.attachBehaviors(this.$form.get(0),settings);}this.settings=null;}).catch((error)=>console.error(Drupal.t('An error occurred during the execution of the Ajax response: !error',{'!error':error}))));};Drupal.Ajax.prototype.getEffect=function(response){const type=response.effect||this.effect;const speed=response.speed||this.speed;const effect={};if(type==='none'){effect.showEffect='show';effect.hideEffect='hide';effect.showSpeed='';}else if(type==='fade'){effect.showEffect='fadeIn';effect.hideEffect='fadeOut';effect.showSpeed=speed;}else{effect.showEffect=`${type}Toggle`;effect.hideEffect=`${type}Toggle`;effect.showSpeed=speed;}return effect;};Drupal.Ajax.prototype.error=function(xmlhttprequest,uri,customMessage){if(this.progress.element)$(this.progress.element).remove();if(this.progress.object)this.progress.object.stopMonitoring();$(this.wrapper).show();$(this.element).prop('disabled',false);if(this.$form&&document.body.contains(this.$form.get(0))){const settings=this.settings||drupalSettings;Drupal.attachBehaviors(this.$form.get(0),settings);}throw new Drupal.AjaxError(xmlhttprequest,uri,customMessage);};Drupal.theme.ajaxWrapperNewContent=($newContent,ajax,response)=>(response.effect||ajax.effect)!=='none'&&$newContent.filter((i)=>!(($newContent[i].nodeName==='#comment'||($newContent[i].nodeName==='#text'&&/^(\s|\n|\r)*$/.test($newContent[i].textContent))))).length>1?Drupal.theme('ajaxWrapperMultipleRootElements',$newContent):$newContent;Drupal.theme.ajaxWrapperMultipleRootElements=($elements)=>$('<div></div>').append($elements);Drupal.AjaxCommands=function(){};Drupal.AjaxCommands.prototype={insert(ajax,response){const $wrapper=response.selector?$(response.selector):$(ajax.wrapper);const method=response.method||ajax.method;const effect=ajax.getEffect(response);const settings=response.settings||ajax.settings||drupalSettings;const parseHTML=(htmlString)=>{const fragment=document.createDocumentFragment();const template=fragment.appendChild(document.createElement('template'));template.innerHTML=htmlString;return template.content.childNodes;};let $newContent=$(parseHTML(response.data));
25$newContent=Drupal.theme('ajaxWrapperNewContent',$newContent,ajax,response);switch(method){case 'html':case 'replaceWith':case 'replaceAll':case 'empty':case 'remove':Drupal.detachBehaviors($wrapper.get(0),settings);break;default:break;}$wrapper[method]($newContent);if(effect.showEffect!=='show')$newContent.hide();const $ajaxNewContent=$newContent.find('.ajax-new-content');if($ajaxNewContent.length){$ajaxNewContent.hide();$newContent.show();$ajaxNewContent[effect.showEffect](effect.showSpeed);}else{if(effect.showEffect!=='show')$newContent[effect.showEffect](effect.showSpeed);}$newContent.each((index,element)=>{if(element.nodeType===Node.ELEMENT_NODE&&document.documentElement.contains(element))Drupal.attachBehaviors(element,settings);});},remove(ajax,response,status){const settings=response.settings||ajax.settings||drupalSettings;$(response.selector).each(function(){Drupal.detachBehaviors(this,settings);}).remove();},changed(ajax,response,status){const $element=$(response.selector);if(!$element.hasClass('ajax-changed')){$element.addClass('ajax-changed');if(response.asterisk)$element.find(response.asterisk).append(` <abbr class="ajax-changed" title="${Drupal.t('Changed')}">*</abbr> `);}},alert(ajax,response,status){window.alert(response.text);},announce(ajax,response){if(response.priority)Drupal.announce(response.text,response.priority);else Drupal.announce(response.text);},redirect(ajax,response,status){window.location=response.url;},css(ajax,response,status){$(response.selector).css(response.argument);},settings(ajax,response,status){const ajaxSettings=drupalSettings.ajax;if(ajaxSettings)Drupal.ajax.expired().forEach((instance)=>{if(instance.selector){const selector=instance.selector.replace('#','');if(selector in ajaxSettings)delete ajaxSettings[selector];}});if(response.merge)$.extend(true,drupalSettings,response.settings);else ajax.settings=response.settings;},data(ajax,response,status){$(response.selector).data(response.name,response.value);},focusFirst(ajax,response,status){let focusChanged=false;const container=document.querySelector(response.selector);if(container){const tabbableElements=tabbable(container);if(tabbableElements.length){tabbableElements[0].focus();focusChanged=true;}else{if(isFocusable(container)){container.focus();focusChanged=true;}}}if(ajax.hasOwnProperty('element')&&!focusChanged)ajax.element.focus();},invoke(ajax,response,status){const $element=$(response.selector);$element[response.method](...response.args);},restripe(ajax,response,status){$(response.selector).find('> tbody > tr:visible, > tr:visible').removeClass('odd even').filter(':even').addClass('odd').end().filter(':odd').addClass('even');},update_build_id(ajax,response,status){document.querySelectorAll(`input[name="form_build_id"][value="${response.old}"]`).forEach((item)=>{item.value=response.new;});},add_css(ajax,response,status){if(typeof response.data==='string'){Drupal.deprecationError({message:'Passing a string to the Drupal.ajax.add_css() method is deprecated in 10.1.0 and is removed from drupal:11.0.0. See https://www.drupal.org/node/3154948.'});$('head').prepend(response.data);return;}const allUniqueBundleIds=response.data.map(function(style){const uniqueBundleId=style.href;if(!loadjs.isDefined(uniqueBundleId))loadjs(`css!${style.href}`,uniqueBundleId,{before(path,styleEl){Object.keys(style).forEach((attributeKey)=>{styleEl.setAttribute(attributeKey,style[attributeKey]);});}});return uniqueBundleId;});return new Promise((resolve,reject)=>{loadjs.ready(allUniqueBundleIds,{success(){resolve();},error(depsNotFound){const message=Drupal.t(`The following files could not be loaded: @dependencies`,{'@dependencies':depsNotFound.join(', ')});reject(message);}});});},message(ajax,response){const messages=new Drupal.Message(document.querySelector(response.messageWrapperQuerySelector));if(response.clearPrevious)messages.clear();messages.add(response.message,response.messageOptions);},add_js(ajax,response,status){const parentEl=document.querySelector(response.selector||'body');const settings=ajax.settings||drupalSettings;const allUniqueBundleIds=response.data.map((script)=>{const uniqueBundleId=script.src;
25if(!loadjs.isDefined(uniqueBundleId))loadjs(script.src,uniqueBundleId,{async:false,before(path,scriptEl){Object.keys(script).forEach((attributeKey)=>{scriptEl.setAttribute(attributeKey,script[attributeKey]);});parentEl.appendChild(scriptEl);return false;}});return uniqueBundleId;});return new Promise((resolve,reject)=>{loadjs.ready(allUniqueBundleIds,{success(){Drupal.attachBehaviors(parentEl,settings);resolve();},error(depsNotFound){const message=Drupal.t(`The following files could not be loaded: @dependencies`,{'@dependencies':depsNotFound.join(', ')});reject(message);}});});},scrollTop(ajax,response){document.querySelector(response.selector)?.scrollIntoView();}};const stopEvent=(xhr,settings)=>{return (xhr.getResponseHeader('X-Drupal-Ajax-Token')==='1'&&settings.isInProgress&&settings.isInProgress());};$.extend(true,$.event.special,{ajaxSuccess:{trigger(event,xhr,settings){if(stopEvent(xhr,settings))return false;}},ajaxComplete:{trigger(event,xhr,settings){if(stopEvent(xhr,settings)){$.active++;return false;}}}});})(jQuery,window,Drupal,drupalSettings,loadjs,window.tabbable);; 26(function($,Drupal,drupalSettings){Drupal.Views={};Drupal.Views.parseQueryString=function(query){const args={};if(query.includes('?'))query=query.substring(query.indexOf('?')+1);let pair;const pairs=query.split('&');for(let i=0;i<pairs.length;i++){pair=pairs[i].split('=');if(pair[0]!=='q')if(pair[1])args[decodeURIComponent(pair[0].replace(/\+/g,' '))]=decodeURIComponent(pair[1].replace(/\+/g,' '));else args[decodeURIComponent(pair[0].replace(/\+/g,' '))]='';}return args;};Drupal.Views.parseViewArgs=function(href,viewPath){const returnObj={};const path=Drupal.Views.getPath(href);const viewHref=Drupal.url(viewPath).substring(drupalSettings.path.baseUrl.length);if(viewHref&&path.startsWith(`${viewHref}/`)){returnObj.view_args=decodeURIComponent(path.substring(viewHref.length+1,path.length));returnObj.view_path=path;}return returnObj;};Drupal.Views.pathPortion=function(href){const protocol=window.location.protocol;if(href.startsWith(protocol))href=href.substring(href.indexOf('/',protocol.length+2));return href;};Drupal.Views.getPath=function(href){href=Drupal.Views.pathPortion(href);href=href.substring(drupalSettings.path.baseUrl.length,href.length);if(href.startsWith('?q='))href=href.substring(3,href.length);const chars=['#','?','&'];for(let i=0;i<chars.length;i++)if(href.includes(chars[i]))href=href.substring(0,href.indexOf(chars[i]));return href;};})(jQuery,Drupal,drupalSettings);; 27(function($,Drupal,drupalSettings){Drupal.behaviors.ViewsAjaxView={};Drupal.behaviors.ViewsAjaxView.attach=function(context,settings){if(settings&&settings.views&&settings.views.ajaxViews){const {views:{ajaxViews}}=settings;Object.keys(ajaxViews||{}).forEach((i)=>{Drupal.views.instances[i]=new Drupal.views.ajaxView(ajaxViews[i]);});}};Drupal.behaviors.ViewsAjaxView.detach=(context,settings,trigger)=>{if(trigger==='unload')if(settings&&settings.views&&settings.views.ajaxViews){const {views:{ajaxViews}}=settings;Object.keys(ajaxViews||{}).forEach((i)=>{const selector=`.js-view-dom-id-${ajaxViews[i].view_dom_id}`;if($(selector,context).length){delete Drupal.views.instances[i];delete settings.views.ajaxViews[i];}});}};Drupal.views={};Drupal.views.instances={};Drupal.views.ajaxView=function(settings){const selector=`.js-view-dom-id-${settings.view_dom_id}`;this.$view=$(selector);let ajaxPath=drupalSettings.views.ajax_path;if(ajaxPath.constructor.toString().includes('Array'))ajaxPath=ajaxPath[0];let queryString=window.location.search||'';if(queryString!==''){queryString=queryString.slice(1).replace(/q=[^&]+&?|page=[^&]+&?|&?render=[^&]+/,'');if(queryString!=='')queryString=(/\?/.test(ajaxPath)?'&':'?')+queryString;}this.element_settings={url:ajaxPath+queryString,submit:settings,httpMethod:'GET',setClick:true,event:'click',selector,progress:{type:'fullscreen'}};this.settings=settings;this.$exposed_form=$(`form#views-exposed-form-${settings.view_name.replace(/_/g,'-')}-${settings.view_display_id.replace(/_/g,'-')}`);once('exposed-form',this.$exposed_form).forEach(this.attachExposedFormAjax.bind(this));
27once('ajax-pager',this.$view.filter(this.filterNestedViews.bind(this))).forEach(this.attachPagerAjax.bind(this));const selfSettings=$.extend({},this.element_settings,{event:'RefreshView',base:this.selector,httpMethod:'GET',element:this.$view.get(0)});this.refreshViewAjax=Drupal.ajax(selfSettings);};Drupal.views.ajaxView.prototype.attachExposedFormAjax=function(){const that=this;this.exposedFormAjax=[];$('input[type=submit], button[type=submit], input[type=image]',this.$exposed_form).not('[data-drupal-selector=edit-reset]').each(function(index){const selfSettings=$.extend({},that.element_settings,{base:$(this).attr('id'),element:this});that.exposedFormAjax[index]=Drupal.ajax(selfSettings);});};Drupal.views.ajaxView.prototype.filterNestedViews=function(){return !this.$view.parents('.view').length;};Drupal.views.ajaxView.prototype.attachPagerAjax=function(){this.$view.find('.js-pager__items a, th.views-field a, .attachment .views-summary a').each(this.attachPagerLinkAjax.bind(this));};Drupal.views.ajaxView.prototype.attachPagerLinkAjax=function(id,link){const $link=$(link);const viewData={};const href=$link.attr('href');$.extend(viewData,this.settings,Drupal.Views.parseQueryString(href),Drupal.Views.parseViewArgs(href,this.settings.view_base_path));const selfSettings=$.extend({},this.element_settings,{submit:viewData,base:false,element:link,httpMethod:'GET'});this.pagerAjax=Drupal.ajax(selfSettings);};Drupal.AjaxCommands.prototype.viewsScrollTop=function(ajax,response){Drupal.AjaxCommands.prototype.scrollTop(ajax,response);};})(jQuery,Drupal,drupalSettings);; 28var TL;(()=>{var t={838:function(t){t.exports=function(){"use strict";const {entries:t,setPrototypeOf:e,isFrozen:i,getPrototypeOf:a,getOwnPropertyDescriptor:s}=Object;let {freeze:n,seal:o,create:r}=Object,{apply:l,construct:h}="undefined"!=typeof Reflect&&Reflect;n||(n=function(t){return t;}),o||(o=function(t){return t;}),l||(l=function(t,e,i){return t.apply(e,i);}),h||(h=function(t,e){return new t(...e);});const d=x(Array.prototype.forEach),c=x(Array.prototype.pop),u=x(Array.prototype.push),m=x(String.prototype.toLowerCase),_=x(String.prototype.toString),p=x(String.prototype.match),f=x(String.prototype.replace),g=x(String.prototype.indexOf),v=x(String.prototype.trim),y=x(Object.prototype.hasOwnProperty),b=x(RegExp.prototype.test),w=(k=TypeError,function(){for(var t=arguments.length,e=new Array(t),i=0;i<t;i++)e[i]=arguments[i];return h(k,e);});var k;function x(t){return function(e){for(var i=arguments.length,a=new Array(i>1?i-1:0),s=1;s<i;s++)a[s-1]=arguments[s];return l(t,e,a);};}function T(t,a){let s=arguments.length>2&&void 0!==arguments[2]?arguments[2]:m;e&&e(t,null);let n=a.length;for(;n--;){let e=a[n];if("string"==typeof e){const t=s(e);t!==e&&(i(a)||(a[n]=t),e=t);}t[e]=!0;}return t;}function M(t){for(let e=0;e<t.length;e++)y(t,e)||(t[e]=null);return t;}function E(e){const i=r(null);for(const [a,s] of t(e))y(e,a)&&(Array.isArray(s)?i[a]=M(s):s&&"object"==typeof s&&s.constructor===Object?i[a]=E(s):i[a]=s);return i;}function L(t,e){for(;null!==t;){const i=s(t,e);if(i){if(i.get)return x(i.get);if("function"==typeof i.value)return x(i.value);}t=a(t);}return function(){return null;};}const D=n(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),S=n(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),N=n(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),A=n(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),C=n(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),I=n(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),O
28=n(["#text"]),R=n(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","popover","popovertarget","popovertargetaction","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","wrap","xmlns","slot"]),j=n(["accent-height","accumulate","additive","alignment-baseline","amplitude","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","exponent","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","intercept","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","slope","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","tablevalues","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),P=n(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),z=n(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),H=o(/\{\{[\w\W]*|[\w\W]*\}\}/gm),F=o(/<%[\w\W]*|[\w\W]*%>/gm),q=o(/\${[\w\W]*}/gm),$=o(/^data-[\-\w.\u00B7-\uFFFF]/),U=o(/^aria-[\-\w]+$/),B=o(/^(?:(?:(?
28:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),W=o(/^(?:\w+script|data):/i),G=o(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),Y=o(/^html$/i),Z=o(/^[a-z][.\w]*(-[.\w]+)+$/i);var V=Object.freeze({__proto__:null,MUSTACHE_EXPR:H,ERB_EXPR:F,TMPLIT_EXPR:q,DATA_ATTR:$,ARIA_ATTR:U,IS_ALLOWED_URI:B,IS_SCRIPT_OR_DATA:W,ATTR_WHITESPACE:G,DOCTYPE_NAME:Y,CUSTOM_ELEMENT:Z});const X=1,J=3,K=7,Q=8,tt=9,et=function(){return "undefined"==typeof window?null:window;};return function e(){let i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:et();const a=(t)=>e(t);if(a.version="3.1.7",a.removed=[],!i||!i.document||i.document.nodeType!==tt)return a.isSupported=!1,a;let {document:s}=i;const o=s,l=o.currentScript,{DocumentFragment:h,HTMLTemplateElement:k,Node:x,Element:M,NodeFilter:H,NamedNodeMap:F=i.NamedNodeMap||i.MozNamedAttrMap,HTMLFormElement:q,DOMParser:$,trustedTypes:U}=i,W=M.prototype,G=L(W,"cloneNode"),Z=L(W,"remove"),it=L(W,"nextSibling"),at=L(W,"childNodes"),st=L(W,"parentNode");if("function"==typeof k){const t=s.createElement("template");t.content&&t.content.ownerDocument&&(s=t.content.ownerDocument);}let nt,ot="";const {implementation:rt,createNodeIterator:lt,createDocumentFragment:ht,getElementsByTagName:dt}=s,{importNode:ct}=o;let ut={};a.isSupported="function"==typeof t&&"function"==typeof st&&rt&&void 0!==rt.createHTMLDocument;const {MUSTACHE_EXPR:mt,ERB_EXPR:_t,TMPLIT_EXPR:pt,DATA_ATTR:ft,ARIA_ATTR:gt,IS_SCRIPT_OR_DATA:vt,ATTR_WHITESPACE:yt,CUSTOM_ELEMENT:bt}=V;let {IS_ALLOWED_URI:wt}=V,kt=null;const xt=T({},[...D,...S,...N,...C,...O]);let Tt=null;const Mt=T({},[...R,...j,...P,...z]);let Et=Object.seal(r(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),Lt=null,Dt=null,St=!0,Nt=!0,At=!1,Ct=!0,It=!1,Ot=!0,Rt=!1,jt=!1,Pt=!1,zt=!1,Ht=!1,Ft=!1,qt=!0,$t=!1,Ut=!0,Bt=!1,Wt={},Gt=null;const Yt=T({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let Zt=null;const Vt=T({},["audio","video","img","source","image","track"]);let Xt=null;const Jt=T({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),Kt="http://www.w3.org/1998/Math/MathML",Qt="http://www.w3.org/2000/svg",te="http://www.w3.org/1999/xhtml";let ee=te,ie=!1,ae=null;const se=T({},[Kt,Qt,te],_);let ne=null;const oe=["application/xhtml+xml","text/html"];let re=null,le=null;const he=s.createElement("form"),de=function(t){return t instanceof RegExp||t instanceof Function;},ce=function(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(!le||le!==t){if(t&&"object"==typeof t||(t={}),t=E(t),ne=-1===oe.indexOf(t.PARSER_MEDIA_TYPE)?"text/html":t.PARSER_MEDIA_TYPE,re="application/xhtml+xml"===ne?_:m,kt=y(t,"ALLOWED_TAGS")?T({},t.ALLOWED_TAGS,re):xt,Tt=y(t,"ALLOWED_ATTR")?T({},t.ALLOWED_ATTR,re):Mt,ae=y(t,"ALLOWED_NAMESPACES")?T({},t.ALLOWED_NAMESPACES,_):se,Xt=y(t,"ADD_URI_SAFE_ATTR")?T(E(Jt),t.ADD_URI_SAFE_ATTR,re):Jt,Zt=y(t,"ADD_DATA_URI_TAGS")?T(E(Vt),t.ADD_DATA_URI_TAGS,re):Vt,Gt=y(t,"FORBID_CONTENTS")?T({},t.FORBID_CONTENTS,re):Yt,Lt=y(t,"FORBID_TAGS")?T({},t.FORBID_TAGS,re):{},Dt=y(t,"FORBID_ATTR")?T({},t.FORBID_ATTR,re):{},Wt=!!y(t,"USE_PROFILES")&&t.USE_PROFILES,St=!1!==t.ALLOW_ARIA_ATTR,Nt=!1!==t.ALLOW_DATA_ATTR,At=t.ALLOW_UNKNOWN_PROTOCOLS||!1,Ct=!1!==t.ALLOW_SELF_CLOSE_IN_ATTR,It=t.SAFE_FOR_TEMPLATES||!1,Ot=!1!==t.SAFE_FOR_XML,Rt=t.WHOLE_DOCUMENT||!1,zt=t.RETURN_DOM||!1,Ht=t.RETURN_DOM_FRAGMENT||!1,Ft=t.RETURN_TRUSTED_TYPE||!1,Pt=t.FORCE_BODY||!1,qt=!1!==t.SANITIZE_DOM,$t=t.SANITIZE_NAMED_PROPS||!1,Ut=!1!==t.KEEP_CONTENT,Bt=t.IN_PLACE||!1,wt=t.ALLOWED_URI_REGEXP||B,ee=t.NAMESPACE||te,Et=t.CUSTOM_ELEMENT_HANDLING||{},t.CUSTOM_ELEMENT_HANDLING&&de(t.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(Et.tagNameCheck=t.CUSTOM_ELEMENT_HANDLING.tagNameCheck),t.CUSTOM_ELEMENT_HANDLING&&de(t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(Et.attributeNameCheck=t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),t.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(Et.allowCustomizedBuiltInElements=t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),It&&(Nt=!1),Ht&&(zt=!0),Wt&&(kt=T({},O),Tt=[],!0===Wt.html&&(T(kt,D),T(Tt,R)),!0===Wt.svg&&(T(kt,S),T(Tt,j),T(Tt,z)),!0===Wt.svgFilters&&
28(T(kt,N),T(Tt,j),T(Tt,z)),!0===Wt.mathMl&&(T(kt,C),T(Tt,P),T(Tt,z))),t.ADD_TAGS&&(kt===xt&&(kt=E(kt)),T(kt,t.ADD_TAGS,re)),t.ADD_ATTR&&(Tt===Mt&&(Tt=E(Tt)),T(Tt,t.ADD_ATTR,re)),t.ADD_URI_SAFE_ATTR&&T(Xt,t.ADD_URI_SAFE_ATTR,re),t.FORBID_CONTENTS&&(Gt===Yt&&(Gt=E(Gt)),T(Gt,t.FORBID_CONTENTS,re)),Ut&&(kt["#text"]=!0),Rt&&T(kt,["html","head","body"]),kt.table&&(T(kt,["tbody"]),delete Lt.tbody),t.TRUSTED_TYPES_POLICY){if("function"!=typeof t.TRUSTED_TYPES_POLICY.createHTML)throw w('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if("function"!=typeof t.TRUSTED_TYPES_POLICY.createScriptURL)throw w('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');nt=t.TRUSTED_TYPES_POLICY,ot=nt.createHTML("");}else void 0===nt&&(nt=function(t,e){if("object"!=typeof t||"function"!=typeof t.createPolicy)return null;let i=null;const a="data-tt-policy-suffix";e&&e.hasAttribute(a)&&(i=e.getAttribute(a));const s="dompurify"+(i?"#"+i:"");try{return t.createPolicy(s,{createHTML:(t)=>t,createScriptURL:(t)=>t});}catch(t){return console.warn("TrustedTypes policy "+s+" could not be created."),null;}}(U,l)),null!==nt&&"string"==typeof ot&&(ot=nt.createHTML(""));n&&n(t),le=t;}},ue=T({},["mi","mo","mn","ms","mtext"]),me=T({},["annotation-xml"]),_e=T({},["title","style","font","a","script"]),pe=T({},[...S,...N,...A]),fe=T({},[...C,...I]),ge=function(t){u(a.removed,{element:t});try{st(t).removeChild(t);}catch(e){Z(t);}},ve=function(t,e){try{u(a.removed,{attribute:e.getAttributeNode(t),from:e});}catch(t){u(a.removed,{attribute:null,from:e});}if(e.removeAttribute(t),"is"===t&&!Tt[t])if(zt||Ht)try{ge(e);}catch(t){}else try{e.setAttribute(t,"");}catch(t){}},ye=function(t){let e=null,i=null;if(Pt)t="<remove></remove>"+t;else{const e=p(t,/^[\r\n\t ]+/);i=e&&e[0];}"application/xhtml+xml"===ne&&ee===te&&(t='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+t+"</body></html>");const a=nt?nt.createHTML(t):t;if(ee===te)try{e=(new $()).parseFromString(a,ne);}catch(t){}if(!e||!e.documentElement){e=rt.createDocument(ee,"template",null);try{e.documentElement.innerHTML=ie?ot:a;}catch(t){}}const n=e.body||e.documentElement;return t&&i&&n.insertBefore(s.createTextNode(i),n.childNodes[0]||null),ee===te?dt.call(e,Rt?"html":"body")[0]:Rt?e.documentElement:n;},be=function(t){return lt.call(t.ownerDocument||t,t,H.SHOW_ELEMENT|H.SHOW_COMMENT|H.SHOW_TEXT|H.SHOW_PROCESSING_INSTRUCTION|H.SHOW_CDATA_SECTION,null);},we=function(t){return t instanceof q&&("string"!=typeof t.nodeName||"string"!=typeof t.textContent||"function"!=typeof t.removeChild||!(t.attributes instanceof F)||"function"!=typeof t.removeAttribute||"function"!=typeof t.setAttribute||"string"!=typeof t.namespaceURI||"function"!=typeof t.insertBefore||"function"!=typeof t.hasChildNodes);},ke=function(t){return "function"==typeof x&&t instanceof x;},xe=function(t,e,i){ut[t]&&d(ut[t],((t)=>{t.call(a,e,i,le);}));},Te=function(t){let e=null;if(xe("beforeSanitizeElements",t,null),we(t))return ge(t),!0;const i=re(t.nodeName);if(xe("uponSanitizeElement",t,{tagName:i,allowedTags:kt}),t.hasChildNodes()&&!ke(t.firstElementChild)&&b(/<[/\w]/g,t.innerHTML)&&b(/<[/\w]/g,t.textContent))return ge(t),!0;if(t.nodeType===K)return ge(t),!0;if(Ot&&t.nodeType===Q&&b(/<[/\w]/g,t.data))return ge(t),!0;if(!kt[i]||Lt[i]){if(!Lt[i]&&Ee(i)){if(Et.tagNameCheck instanceof RegExp&&b(Et.tagNameCheck,i))return !1;if(Et.tagNameCheck instanceof Function&&Et.tagNameCheck(i))return !1;}if(Ut&&!Gt[i]){const e=st(t)||t.parentNode,i=at(t)||t.childNodes;if(i&&e){for(let a=i.length-1;a>=0;--a){const s=G(i[a],!0);s.__removalCount=(t.__removalCount||0)+1,e.insertBefore(s,it(t));}}}return ge(t),!0;}return t instanceof M&&!function(t){let e=st(t);e&&e.tagName||(e={namespaceURI:ee,tagName:"template"});const i=m(t.tagName),a=m(e.tagName);return !!ae[t.namespaceURI]&&(t.namespaceURI===Qt?e.namespaceURI===te?"svg"===i:e.namespaceURI===Kt?"svg"===i&&("annotation-xml"===a||ue[a]):Boolean(pe[i]):t.namespaceURI===Kt?e.namespaceURI===te?"math"===i:e.namespaceURI===Qt?"math"===i&&me[a]:Boolean(fe[i]):t.namespaceURI===te?!(e.namespaceURI===Qt&&!me[a])&&!(e.namespaceURI===Kt&&!ue[a])&&!fe[i]&&(_e[i]||!pe[i]):!("application/xhtml+xml"!==ne||!ae[t.namespaceURI]));}(t)?(ge(t),!0):"noscript"!==i&&"noembed"!==i&&"noframes"!==i||!b(/<\/no(script|embed|frames)/i,t.innerHTML)?(It&&t.nodeType===J&&(e=t.textContent,d([mt,_t,pt],((t)=>{e=f(e,t," ");})),t.textContent!==e&&(u(a.removed,{element:t.cloneNode()}),t.textContent=e)),xe("afterSanitizeElements",t,null),!1):(ge(t),!0);}
28,Me=function(t,e,i){if(qt&&("id"===e||"name"===e)&&(i in s||i in he))return !1;if(Nt&&!Dt[e]&&b(ft,e));else if(St&&b(gt,e));else if(!Tt[e]||Dt[e]){if(!(Ee(t)&&(Et.tagNameCheck instanceof RegExp&&b(Et.tagNameCheck,t)||Et.tagNameCheck instanceof Function&&Et.tagNameCheck(t))&&(Et.attributeNameCheck instanceof RegExp&&b(Et.attributeNameCheck,e)||Et.attributeNameCheck instanceof Function&&Et.attributeNameCheck(e))||"is"===e&&Et.allowCustomizedBuiltInElements&&(Et.tagNameCheck instanceof RegExp&&b(Et.tagNameCheck,i)||Et.tagNameCheck instanceof Function&&Et.tagNameCheck(i))))return !1;}else if(Xt[e]);else if(b(wt,f(i,yt,"")));else{if("src"!==e&&"xlink:href"!==e&&"href"!==e||"script"===t||0!==g(i,"data:")||!Zt[t])if(At&&!b(vt,f(i,yt,"")));else{if(i)return !1;}}return !0;},Ee=function(t){return "annotation-xml"!==t&&p(t,bt);},Le=function(t){xe("beforeSanitizeAttributes",t,null);const {attributes:e}=t;if(!e)return;const i={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:Tt};let s=e.length;for(;s--;){const n=e[s],{name:o,namespaceURI:r,value:l}=n,h=re(o);let u="value"===o?l:v(l);if(i.attrName=h,i.attrValue=u,i.keepAttr=!0,i.forceKeepAttr=void 0,xe("uponSanitizeAttribute",t,i),u=i.attrValue,i.forceKeepAttr)continue;if(ve(o,t),!i.keepAttr)continue;if(!Ct&&b(/\/>/i,u)){ve(o,t);continue;}It&&d([mt,_t,pt],((t)=>{u=f(u,t," ");}));const m=re(t.nodeName);if(Me(m,h,u))if(!$t||"id"!==h&&"name"!==h||(ve(o,t),u="user-content-"+u),Ot&&b(/((--!?|])>)|<\/(style|title)/i,u))ve(o,t);else{if(nt&&"object"==typeof U&&"function"==typeof U.getAttributeType)if(r);else switch(U.getAttributeType(m,h)){case "TrustedHTML":u=nt.createHTML(u);break;case "TrustedScriptURL":u=nt.createScriptURL(u);}try{r?t.setAttributeNS(r,o,u):t.setAttribute(o,u),we(t)?ge(t):c(a.removed);}catch(t){}}}xe("afterSanitizeAttributes",t,null);},De=function t(e){let i=null;const a=be(e);for(xe("beforeSanitizeShadowDOM",e,null);i=a.nextNode();)xe("uponSanitizeShadowNode",i,null),Te(i)||(i.content instanceof h&&t(i.content),Le(i));xe("afterSanitizeShadowDOM",e,null);};return a.sanitize=function(t){let e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=null,s=null,n=null,r=null;if(ie=!t,ie&&(t="\x3c!--\x3e"),"string"!=typeof t&&!ke(t)){if("function"!=typeof t.toString)throw w("toString is not a function");if("string"!=typeof (t=t.toString()))throw w("dirty is not a string, aborting");}if(!a.isSupported)return t;if(jt||ce(e),a.removed=[],"string"==typeof t&&(Bt=!1),Bt){if(t.nodeName){const e=re(t.nodeName);if(!kt[e]||Lt[e])throw w("root node is forbidden and cannot be sanitized in-place");}}else if(t instanceof x)i=ye("\x3c!----\x3e"),s=i.ownerDocument.importNode(t,!0),s.nodeType===X&&"BODY"===s.nodeName||"HTML"===s.nodeName?i=s:i.appendChild(s);else{if(!zt&&!It&&!Rt&&-1===t.indexOf("<"))return nt&&Ft?nt.createHTML(t):t;if(i=ye(t),!i)return zt?null:Ft?ot:"";}i&&Pt&&ge(i.firstChild);const l=be(Bt?t:i);for(;n=l.nextNode();)Te(n)||(n.content instanceof h&&De(n.content),Le(n));if(Bt)return t;if(zt){if(Ht)for(r=ht.call(i.ownerDocument);i.firstChild;)r.appendChild(i.firstChild);else r=i;return (Tt.shadowroot||Tt.shadowrootmode)&&(r=ct.call(o,r,!0)),r;}let c=Rt?i.outerHTML:i.innerHTML;return Rt&&kt["!doctype"]&&i.ownerDocument&&i.ownerDocument.doctype&&i.ownerDocument.doctype.name&&b(Y,i.ownerDocument.doctype.name)&&(c="<!DOCTYPE "+i.ownerDocument.doctype.name+">\n"+c),It&&d([mt,_t,pt],((t)=>{c=f(c,t," ");})),nt&&Ft?nt.createHTML(c):c;},a.setConfig=function(){ce(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}),jt=!0;},a.clearConfig=function(){le=null,jt=!1;},a.isValidAttribute=function(t,e,i){le||ce({});const a=re(t),s=re(e);return Me(a,s,i);},a.addHook=function(t,e){"function"==typeof e&&(ut[t]=ut[t]||[],u(ut[t],e));},a.removeHook=function(t){if(ut[t])return c(ut[t]);},a.removeHooks=function(t){ut[t]&&(ut[t]=[]);},a.removeAllHooks=function(){ut={};},a;}();}();},142:()=>{var t=function(){function t(t,e){for(var i=0;i<e.length;i++){var a=e[i];a.enumerable=a.enumerable||!1,a.configurable=!0,"value" in a&&(a.writable=!0),Object.defineProperty(t,a.key,a);}}
28return function(e,i,a){return i&&t(e.prototype,i),a&&t(e,a),e;};}();function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function");}!function(){if("undefined"!=typeof window){var i=Array.prototype.slice,a=Element.prototype.matches||Element.prototype.msMatchesSelector,s=["a[href]","area[href]","input:not([disabled])","select:not([disabled])","textarea:not([disabled])","button:not([disabled])","details","summary","iframe","object","embed","[contenteditable]"].join(","),n=function(){function n(t,i){e(this,n),this._inertManager=i,this._rootElement=t,this._managedNodes=new Set(),this._rootElement.hasAttribute("aria-hidden")?this._savedAriaHidden=this._rootElement.getAttribute("aria-hidden"):this._savedAriaHidden=null,this._rootElement.setAttribute("aria-hidden","true"),this._makeSubtreeUnfocusable(this._rootElement),this._observer=new MutationObserver(this._onMutation.bind(this)),this._observer.observe(this._rootElement,{attributes:!0,childList:!0,subtree:!0});}return t(n,[{key:"destructor",value:function(){this._observer.disconnect(),this._rootElement&&(null!==this._savedAriaHidden?this._rootElement.setAttribute("aria-hidden",this._savedAriaHidden):this._rootElement.removeAttribute("aria-hidden")),this._managedNodes.forEach((function(t){this._unmanageNode(t.node);}),this),this._observer=null,this._rootElement=null,this._managedNodes=null,this._inertManager=null;}},{key:"_makeSubtreeUnfocusable",value:function(t){var e=this;h(t,(function(t){return e._visitNode(t);}));var i=document.activeElement;if(!document.body.contains(t)){for(var a=t,s=void 0;a;){if(a.nodeType===Node.DOCUMENT_FRAGMENT_NODE){s=a;break;}a=a.parentNode;}s&&(i=s.activeElement);}t.contains(i)&&(i.blur(),i===document.activeElement&&document.body.focus());}},{key:"_visitNode",value:function(t){if(t.nodeType===Node.ELEMENT_NODE){var e=t;e!==this._rootElement&&e.hasAttribute("inert")&&this._adoptInertRoot(e),(a.call(e,s)||e.hasAttribute("tabindex"))&&this._manageNode(e);}}},{key:"_manageNode",value:function(t){var e=this._inertManager.register(t,this);this._managedNodes.add(e);}},{key:"_unmanageNode",value:function(t){var e=this._inertManager.deregister(t,this);e&&this._managedNodes.delete(e);}},{key:"_unmanageSubtree",value:function(t){var e=this;h(t,(function(t){return e._unmanageNode(t);}));}},{key:"_adoptInertRoot",value:function(t){var e=this._inertManager.getInertRoot(t);e||(this._inertManager.setInert(t,!0),e=this._inertManager.getInertRoot(t)),e.managedNodes.forEach((function(t){this._manageNode(t.node);}),this);}},{key:"_onMutation",value:function(t,e){t.forEach((function(t){var e=t.target;if("childList"===t.type)i.call(t.addedNodes).forEach((function(t){this._makeSubtreeUnfocusable(t);}),this),i.call(t.removedNodes).forEach((function(t){this._unmanageSubtree(t);}),this);else{if("attributes"===t.type)if("tabindex"===t.attributeName)this._manageNode(e);else{if(e!==this._rootElement&&"inert"===t.attributeName&&e.hasAttribute("inert")){this._adoptInertRoot(e);var a=this._inertManager.getInertRoot(e);this._managedNodes.forEach((function(t){e.contains(t.node)&&a._manageNode(t.node);}));}}}}),this);}},{key:"managedNodes",get:function(){return new Set(this._managedNodes);}},{key:"hasSavedAriaHidden",get:function(){return null!==this._savedAriaHidden;}},{key:"savedAriaHidden",set:function(t){this._savedAriaHidden=t;},get:function(){return this._savedAriaHidden;}}]),n;}(),o=function(){function i(t,a){e(this,i),this._node=t,this._overrodeFocusMethod=!1,this._inertRoots=new Set([a]),this._savedTabIndex=null,this._destroyed=!1,this.ensureUntabbable();}return t(i,[{key:"destructor",value:function(){if(this._throwIfDestroyed(),this._node&&this._node.nodeType===Node.ELEMENT_NODE){var t=this._node;null!==this._savedTabIndex?t.setAttribute("tabindex",this._savedTabIndex):t.removeAttribute("tabindex"),this._overrodeFocusMethod&&delete t.focus;}this._node=null,this._inertRoots=null,this._destroyed=!0;}},{key:"_throwIfDestroyed",value:function(){if(this.destroyed)throw new Error("Trying to access destroyed InertNode");}},{key:"ensureUntabbable",value:function(){if(this.node.nodeType===Node.ELEMENT_NODE){var t=this.node;if(a.call(t,s)){if(-1===t.tabIndex&&this.hasSavedTabIndex)return;t.hasAttribute("tabindex")&&(this._savedTabIndex=t.tabIndex),t.setAttribute("tabindex","-1"),t.nodeType===Node.ELEMENT_NODE&&(t.focus=function(){},this._overrodeFocusMethod=!0);}else t.hasAttribute("tabindex")&&(this._savedTabIndex=t.tabIndex,t.removeAttribute("tabindex"));}}},{key:"addInertRoot",value:function(t){this._throwIfDestroyed(),this._inertRoots.add(t);}},{key:"removeInertRoot",value:function(t){this._throwIfDestroyed(),this._inertRoots.delete(t),0===this._inertRoots.size&&this.destructor();}},{key:"destroyed",get:function(){return this._destroyed;}},{key:"hasSavedTabIndex",get:function(){return null!==this._savedTabIndex;}},{key:"node",get:function(){return this._throwIfDestroyed(),this._node;}},{key:"savedTabIndex",set:function(t){this._throwIfDestroyed(),this._savedTabIndex=t;},get:function(){return this._throwIfDestroyed(),this._savedTabIndex;}}]),i;}(),r=function(){function s(t){if(e(this,s),!t)throw new Error("Missing required argument; InertManager needs to wrap a document.");this._document=t,this._managedNodes=new Map(),this._inertRoots=new Map(),this._observer=new MutationObserver(this._watchForInert.bind(this)),d(t.head||t.body||t.documentElement),"loading"===t.readyState?t.addEventListener("DOMContentLoaded",this._onDocumentLoaded.bind(this)):this._onDocumentLoaded();}return t(s,[{key:"setInert",value:function(t,e){if(e){if(this._inertRoots.has(t))return;var i=new n(t,this);if(t.setAttribute("inert",""),this._inertRoots.set(t,i),!this._document.body.contains(t))for(var a=t.parentNode;a;)11===a.nodeType&&d(a),a=a.parentNode;}else{if(!this._inertRoots.has(t))return;this._inertRoots.get(t).destructor(),this._inertRoots.delete(t),t.removeAttribute("inert");}}},{key:"getInertRoot",value:function(t){return this._inertRoots.get(t);}},{key:"register",value:function(t,e){var i=this._managedNodes.get(t);return void 0!==i?i.addInertRoot(e):i=new o(t,e),this._managedNodes.set(t,i),i;}},{key:"deregister",value:function(t,e){var i=this._managedNodes.get(t);return i?(i.removeInertRoot(e),i.destroyed&&this._managedNodes.delete(t),i):null;}},{key:"_onDocumentLoaded",value:function(){i.call(this._document.querySelectorAll("[inert]")).forEac
28h((function(t){this.setInert(t,!0);}),this),this._observer.observe(this._document.body||this._document.documentElement,{attributes:!0,subtree:!0,childList:!0});}},{key:"_watchForInert",value:function(t,e){var s=this;t.forEach((function(t){switch(t.type){case "childList":i.call(t.addedNodes).forEach((function(t){if(t.nodeType===Node.ELEMENT_NODE){var e=i.call(t.querySelectorAll("[inert]"));a.call(t,"[inert]")&&e.unshift(t),e.forEach((function(t){this.setInert(t,!0);}),s);}}),s);break;case "attributes":if("inert"!==t.attributeName)return;var e=t.target,n=e.hasAttribute("inert");s.setInert(e,n);}}),this);}}]),s;}();if(!HTMLElement.prototype.hasOwnProperty("inert")){var l=new r(document);Object.defineProperty(HTMLElement.prototype,"inert",{enumerable:!0,get:function(){return this.hasAttribute("inert");},set:function(t){l.setInert(this,t);}});}}function h(t,e,i){if(t.nodeType==Node.ELEMENT_NODE){var a=t;e&&e(a);var s=a.shadowRoot;if(s)return void h(s,e,s);if("content"==a.localName){for(var n=a,o=n.getDistributedNodes?n.getDistributedNodes():[],r=0;r<o.length;r++)h(o[r],e,i);return;}if("slot"==a.localName){for(var l=a,d=l.assignedNodes?l.assignedNodes({flatten:!0}):[],c=0;c<d.length;c++)h(d[c],e,i);return;}}for(var u=t.firstChild;null!=u;)h(u,e,i),u=u.nextSibling;}function d(t){if(!t.querySelector("style#inert-style, link#inert-style")){var e=document.createElement("style");e.setAttribute("id","inert-style"),e.textContent="\n[inert] {\n pointer-events: none;\n cursor: default;\n}\n\n[inert], [inert] * {\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n",t.appendChild(e);}}}();}},e={};function i(a){var s=e[a];if(void 0!==s)return s.exports;var n=e[a]={exports:{}};return t[a].call(n.exports,n,n.exports,i),n.exports;}i.n=(t)=>{var e=t&&t.__esModule?()=>t.default:()=>t;return i.d(e,{a:e}),e;},i.d=(t,e)=>{for(var a in e)i.o(e,a)&&!i.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:e[a]});},i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),i.r=(t)=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0});};var a={};(()=>{"use strict";i.r(a),i.d(a,{Timeline:()=>Xe,exportJSON:()=>Je,lookupMediaType:()=>qe,parseGoogleSpreadsheetURL:()=>Kt});const t=navigator?navigator.userAgent.toLowerCase():"no-user-agent-specified",e=document?document.documentElement:null,s=!!t&&-1!==t.indexOf("phantom"),o=window&&"ActiveXObject" in window,r=(Boolean(o&&t.match(/MSIE 9/i)),o&&document&&document.addEventListener,-1!==t.indexOf("webkit")),l=(t.indexOf("android"),-1!==t.search("android [23]")),h=!!window&&void 0!==window.orientation,d=!(!navigator||!window)&&navigator.msPointerEnabled&&navigator.msMaxTouchPoints&&!window.PointerEvent,c=navigator&&window?window.PointerEvent&&navigator.pointerEnabled&&navigator.maxTouchPoints:d,u=!!window&&window.opera,m=(t.indexOf("gecko"),-1!==t.indexOf("gecko")&&!r&&!u&&!o),_=(t.indexOf("chrome"),-1!==t.indexOf("edge/"));!!e&&o&&e.style,!!window&&"WebKitCSSMatrix" in window&&new window.WebKitCSSMatrix(),!!e&&e.style,!!e&&e.style;window&&window.L_DISABLE_3D,h&&window.opera;let p=!!window&&"devicePixelRatio" in window&&window.devicePixelRatio>1;
28if(!p&&window&&"matchMedia" in window){let t=window.matchMedia("(min-resolution:144dpi)");p=t&&t.matches;}const f=window&&!window.L_NO_TOUCH&&!s&&(c||"ontouchstart" in window||window.DocumentTouch&&document instanceof window.DocumentTouch);function g(t){return "string"==typeof t?document.getElementById(t):t;}function v(t,e,i){var a=document.createElement(t);return a.className=e,i&&i.appendChild(a),a;}function y(t,e){var i=v("button",t,e);return i.type="button",i;}function b(t){for(var e={x:0,y:0};t&&!isNaN(t.offsetLeft)&&!isNaN(t.offsetTop);)e.x+=t.offsetLeft,e.y+=t.offsetTop,t=t.offsetParent;return e;}function w(t){for(var e=document.documentElement.style,i=0;i<t.length;i++)if(t[i] in e)return t[i];return !1;}w(["transition","webkitTransition","OTransition","MozTransition","msTransition"]),w(["transformProperty","WebkitTransform","OTransform","MozTransform","msTransform"]);class x extends Error{constructor(t,e){super(),this.name="TLError",this.message=t||"error",this.message_key=this.message,this.detail=e||"";}}const T={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};function M(t){T[t.toLowerCase()]&&(t=T[t.toLowerCase()]),t=t.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i,(function(t,e,i,a){return e+e+i+i+a+a;}));var e=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return e?{r:parseInt(e[1],16),g:parseInt(e[2],16),b:parseInt(e[3],16)}:null;}function E(t,e){var i;for(i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t;}
28function L(t){for(var e=Array.prototype.slice.call(arguments,1),i=0,a=e.length;i<a;i++)E(t,e[i]||{});return t;}const D=[];function S(t){D.forEach(((e)=>{try{e(t);}catch(t){console&&console.log&&console.log("Error handling trace",t);}}));}function N(t,e){for(t=String(t),e=e||2;t.length<e;)t="0"+t;return t;}const A=(C=0,I="_tl_id",function(t){return t[I]=t[I]||++C,t[I];});var C,I;function O(t){return t&&"function"==typeof t.replace?t.replace(/^\s+|\s+$/g,""):"";}function R(t,...e){for(let a of e)for(var i of Object.getOwnPropertyNames(a.prototype))t.prototype[i]=a.prototype[i];}function j(t){t=(t=O(t)).toLowerCase();for(var e=0;e<31;e++)t=t.replace(new RegExp("ãà áäâẽèéëêìÃïîõòóöôùúüûñç·/_,:;".charAt(e),"g"),"aaaaaeeeeeiiiiooooouuuunc------".charAt(e));return (t=t.replace(/[^a-z0-9 -]/g,"").replace(/\s+/g,"-").replace(/-+/g,"-")).replace(/^([0-9])/,"_$1");}function P(t,e){var i=function(t){for(var e="",i=0;i<t;i++)e+="abcdefghijklmnopqurstuvwxyz".substr(Math.floor(32*Math.random()),1);return e;};return e?e+"-"+i(t):"tl-"+i(t);}function z(t){return t==parseFloat(t)?!(t%2):void 0;}function H(t,e,i,a){for(var s=a||0,n=0;n<e.length;n++)e[n].data[i]==t&&(s=n);return s;}function F(t){return t?t=(t=t.replace(/<a\b[^>]*>/i,"")).replace(/<\/a>/i,""):t;}function q(t){return (t=t.replace(/(<[^>]*>)+/g,"")).replace('"',"'");}function $(t,e,i){var a=function(t,e,i){return i||(i=""),e&&e.length>30&&(e=e.substring(0,30)+"â¦"),i+"<a class='tl-makelink' href='"+t+"' onclick='void(0)'>"+e+"</a>";};return t.replace(/\b(?:https?|ftp):\/\/([a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|])/gim,(function(t,e,i,s){if(i>0){var n=s[i-1];if('"'==n||"'"==n||"="==n)return t;}return a(t,e);})).replace(/(^|[^\/>])(www\.[\S]+(\b|$))/gim,(function(t,e,i,s,n){return a("http://"+i,i,e);})).replace(/([a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+)/gim,(function(t,e,i,s){return a("mailto:"+e,e);}));}function U(t){return t.replace(/(.*)www.dropbox.com\/(.*)/,"$1dl.dropboxusercontent.com/$2");}const B=(t)=>{var e={w:0,h:0};return t.w>t.h&&t.h>0?(e.h=t.h,e.w=t.h):(e.w=t.w,e.h=t.w),e;},W=(t)=>null!==t.w&&""!==t.w?Math.round(t.w/16*9):null!==t.h&&""!==t.h?Math.round(t.h/9*16):0;let G=(Z=(Y="123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ").length,{encode:function(t){if("number"!=typeof t||t!==parseInt(t))throw '"encode" only accepts integers.';for(var e="";t;){var i=t%Z;t=Math.floor(t/Z),e=Y[i].toString()+e;}return e;},decode:function(t){if("string"!=typeof t)throw '"decode" only accepts strings.';for(var e=0;t;){var i=Y.indexOf(t[0]);if(i<0)throw '"decode" can\'t find "'+t[0]+'" in the alphabet: "'+Y+'"';var a=t.length-1;e+=i*Math.pow(Z,a),t=t.substring(1);}return e;}});var Y,Z;function V(t){if("string"==typeof t){let a=t.match(/^\s*(\d+h)?(\d+m)?(\d+s)?\s*/i);if(a){var e=parseInt(a[1])||0,i=parseInt(a[2])||0;return (parseInt(a[3])||0)+60*i+60*e*60;}}else{if("number"==typeof t)return t;}return 0;}function X(t){return (new DOMParser()).parseFromString(t,"text/html").body.textContent||"";}const J=[.42,0,1,1];function K(t){}function Q(t){return new K(J).get(t);}function tt(t){return 1==t?1:1-Math.pow(2,-10*t);}function et(t){return t<.5?16*t*t*t*t*t:1+16*--t*t*t*t*t;}let it=function(){};it.extend=function(t){var e=function(){this.initialize&&this.initialize.apply(this,arguments);},i=function(){};i.prototype=this.prototype;var a=new i();for(var s in a.constructor=e,e.prototype=a,e.superclass=this.prototype,this)this.hasOwnProperty(s)&&"prototype"!==s&&"superclass"!==s&&(e[s]=this[s]);return t.statics&&(L(e,t.statics),delete t.statics),t.includes&&(L.apply(null,[a].concat(t.includes)),delete t.includes),t.options&&a.options&&(t.options=L({},a.options,t.options)),L(a,t),e.extend=it.extend,e.include=function(t){L(this.prototype,t);},e;};class at{on(t,e,i){if(!e)throw new x("No callback function provided");var a=this._tl_events=this._tl_events||{};return a[t]=a[t]||[],a[t].push({action:e,context:i||this}),this;}addEventListener(t,e,i){return this.on(t,e,i);}hasEventListeners(t){var e="_tl_events";return e in this&&t in this[e]&&this[e][t].length>0;}removeEventListener(t,e,i){if(!this.hasEventListeners(t))return this;for(var a=0,s=this._tl_events,n=s[t].length;a<n;a++)if(s[t][a].action===e&&(!i||s[t][a].context===i))return s[t].splice(a,1),this;return this;}off(t,e,i){return this.removeEventListener(t,e,i);}fire(t,e){if(!this.hasEventListeners(t))return this;for(var i=E({type:t,target:this},e),a=this._tl_events[t].slice(),s=0,n=a.length;s<n;s++)a[s].action?a[s].action.call(a[s].context||this,i):S(`no action defined for ${t} listener`);return this;}}function st(t,e){return nt(t,e);}const nt=function(){var t=document,e=window,i=e.performance,a=i&&(i.now||i.webkitNow||i.msNow||i.mozNow),s=a?function(){return a.call(i);}:function(){return +new Date();},n=t.documentElement,o=!1,r=1e3,l=/^rgb\(|#/,h=/^([+\-])=([\d\.]+)/,d=/^(?:[\+\-]=?)?\d+(?:\.\d+)?(%|in|cm|mm|em|ex|pt|pc|px)$/,c=/rotate\(((?:[+\-]=)?([\-\d\.]+))deg\)/,u=/scale\(((?:[+\-]=)?([\d\.]+))\)/,m=/skew\(((?:[+\-]=)?([\-\d\.]+))deg, ?((?:[+\-]=)?([\-\d\.]+))deg\)/,_=/translate\(((?:[+\-]=)?([\-\d\.]+))px, ?((?:[+\-]=)?([\-\d\.]+))px\)/,p={lineHeight:1,zoom:1,zIndex:1,opacity:1,transform:1},f=function(){var e,i=t.createElement("a").style,a=["webkitTransform","MozTransform","OTransform","msTransform","Transform"];for(e=0;e<a.length;e++)if(a[e] in i)return a[e];}(),g=void 0!==t.createElement("a").style.opacity,v=t.defaultView&&t.defaultView.getComputedStyle?function(e,i){i=M(i="transform"==i?f
28:i);var a=null,s=t.defaultView.getComputedStyle(e,"");return s&&(a=s[i]),e.style[i]||a;}:n.currentStyle?function(t,e){if("opacity"==(e=M(e))){var i=100;try{i=t.filters["DXImageTransform.Microsoft.Alpha"].opacity;}catch(e){try{i=t.filters("alpha").opacity;}catch(t){}}return i/100;}var a=t.currentStyle?t.currentStyle[e]:null;return t.style[e]||a;}:function(t,e){return t.style[M(e)];},y=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.msRequestAnimationFrame||e.oRequestAnimationFrame||function(t){e.setTimeout((function(){t(+new Date());}),17);},b=[];function w(t){var e,i=b.length;for(a&&t>1e12&&(t=s()),o&&(t=s()),e=i;e--;)b[e](t);b.length&&y(w);}function k(t,e){var i,a={};return (i=t.match(c))&&(a.rotate=A(i[1],e?e.rotate:null)),(i=t.match(u))&&(a.scale=A(i[1],e?e.scale:null)),(i=t.match(m))&&(a.skewx=A(i[1],e?e.skewx:null),a.skewy=A(i[3],e?e.skewy:null)),(i=t.match(_))&&(a.translatex=A(i[1],e?e.translatex:null),a.translatey=A(i[3],e?e.translatey:null)),a;}function x(t){var e="";return "rotate" in t&&(e+="rotate("+t.rotate+"deg) "),"scale" in t&&(e+="scale("+t.scale+") "),"translatex" in t&&(e+="translate("+t.translatex+"px,"+t.translatey+"px) "),"skewx" in t&&(e+="skew("+t.skewx+"deg,"+t.skewy+"deg)"),e;}function T(t){var e,i,a,s=t.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);return (s?(e=s[1],i=s[2],a=s[3],"#"+(1<<24|e<<16|i<<8|a).toString(16).slice(1)):t).replace(/#(\w)(\w)(\w)$/,"#$1$1$2$2$3$3");}function M(t){return t.replace(/-(.)/g,(function(t,e){return e.toUpperCase();}));}function E(t){return "function"==typeof t;}function L(t){return Math.sin(t*Math.PI/2);}function D(t,e,i,a,n,o){a=E(a)?a:C.easings[a]||L;var l,h=t||r,d=this,c=o-n,u=s(),m=0,_=0;return l=function t(s){var r=s-u;if(r>h||m)return o=isFinite(o)?o:1,m?_&&e(o):e(o),function(t){var e,i=function(t,e,i){if(Array.prototype.indexOf)return t.indexOf(e);for(i=0;i<t.length;++i)if(t[i]===e)return i;}(b,t);i>=0&&(e=b.slice(i+1),b.length=i,b=b.concat(e));}(t),i&&i.apply(d);isFinite(o)?e(c*a(r/h)+n):e(a(r/h));},1===b.push(l)&&y(w),{stop:function(t){m=1,_=t,t||(i=null);}};}function S(t,e){var i,a,s=t.length,n=[];for(i=0;i<s;++i)n[i]=[t[i][0],t[i][1]];for(a=1;a<s;++a)for(i=0;i<s-a;++i)n[i][0]=(1-e)*n[i][0]+e*n[parseInt(i+1,10)][0],n[i][1]=(1-e)*n[i][1]+e*n[parseInt(i+1,10)][1];return [n[0][0],n[0][1]];}function N(t,e,i,a,s,n,o){if("transform"==s){for(var l in o={},i[n][s])o[l]=l in a[n][s]?Math.round(((a[n][s][l]-i[n][s][l])*t+i[n][s][l])*r)/r:i[n][s][l];return o;}return "string"==typeof i[n][s]?function(t,e,i){var a,s,n,o,r=[];for(a=0;a<6;a++)n=Math.min(15,parseInt(e.charAt(a),16)),o=Math.min(15,parseInt(i.charAt(a),16)),s=(s=Math.floor((o-n)*t+n))>15?15:s<0?0:s,r[a]=s.toString(16);return "#"+r.join("");}(t,i[n][s],a[n][s]):(o=Math.round(((a[n][s]-i[n][s])*t+i[n][s])*r)/r,s in p||(o+=e[n][s]||"px"),o);}function A(t,e,i,a,s){return (i=h.exec(t))?(s=parseFloat(i[2]))&&e+("+"==i[1]?1:-1)*s:parseFloat(t);}function C(t,e){var i,a,s,n=t?n=isFinite(t.length)?t:[t]:[],o=e.complete,r=e.duration,h=e.easing,c=e.bezier,u=[],m=[],_=[],p=[];for(c&&(a=e.left,s=e.top,delete e.right,delete e.bottom,delete e.left,delete e.top),i=n.length;i--;){if(u[i]={},m[i]={},_[i]={},c){var y=v(n[i],"left"),b=v(n[i],"top"),w=[A(E(a)?a(n[i]):a||0,parseFloat(y)),A(E(s)?s(n[i]):s||0,parseFloat(b))];p[i]=E(c)?c(n[i],w):c,p[i].push(w),p[i].unshift([parseInt(y,10),parseInt(b,10)]);}for(var L in e){switch(L){case "complete":case "duration":case "easing":case "bezier":continue;}var C,I=v(n[i],L),O=E(e[L])?e[L](n[i]):e[L];"string"!=typeof O||!l.test(O)||l.test(I)?(u[i][L]="transform"==L?k(I):"string"==typeof O&&l.test(O)?T(I).slice(1):parseFloat(I),m[i][L]="transform"==L?k(O,u[i][L]):"string"==typeof O&&"#"==O.charAt(0)?T(O).slice(1):A(O,parseFloat(I)),"string"==typeof O&&(C=O.match(d))&&(_[i][L]=C[1])):delete e[L];}}return D.apply(n,[r,function(t,a,s){for(i=n.length;i--;)for(var o in c&&(s=S(p[i],t),n[i].style.left=s[0]+"px",n[i].style.top=s[1]+"px"),e)a=N(t,_,u,m,o,i),"transform"==o?n[i].style[f]=x(a):"opacity"!=o||g?n[i].style[M(o)]=a:n[i].style.filter="alpha(opacity="+100*a+")";},o,h]);}return y((function(t){o=t>1e12!=s()>1e12;})),C.tween=D,C.getStyle=v,C.bezier=S,C.transform=f,C.parseTransform=k,C.formatTransform=x,C.easings={},C;}();class ot{show(t){t||(this._el.container.style.display="block");}hide(t){this._el.container.style.display="none";}addTo(t){t.appendChild(this._el.container),this.onAdd();}removeFrom(t){t.removeChild(this._el.container),this.onRemove();}animatePosition(t,e){var i={duration:this.options.duration,easing:this.options.ease};for(var a in t)t.hasOwnProperty(a)&&(i[a]=t[a]+"px");this.animator&&this.animator.stop(),this.animator=st(e,i);}onLoaded(){this.fire("loaded",this.data);}onAdd(){this.fire("added",this.data);}onRemove(){this.fire("removed",this.data);}setPosition(t,e){for(var i in t)t.hasOwnProperty(i)&&(e?e.style[i]=t[i]+"px":this._el.container.style[i]=t[i]+"px");}getPosition(){return b(this._el.container);}}class rt{constructor(t,e,i){this._el={drag:t,move:t}
28,this.mousedrag={down:"mousedown",up:"mouseup",leave:"mouseleave",move:"mousemove"},this.touchdrag={down:"touchstart",up:"touchend",leave:"mouseleave",move:"touchmove"},i&&(this._el.move=i),this.options={enable:{x:!0,y:!0},constraint:{top:!1,bottom:!1,left:!1,right:!1},momentum_multiplier:2e3,duration:1e3,ease:et},this.animator=null,this.dragevent=this.mousedrag,f&&(this.dragevent=this.touchdrag),this.data={sliding:!1,direction:"none",pagex:{start:0,end:0},pagey:{start:0,end:0},pos:{start:{x:0,y:0},end:{x:0,y:0}},new_pos:{x:0,y:0},new_pos_parent:{x:0,y:0},time:{start:0,end:0},touch:!1},E(this.options,e);}enable(t){this.data.pos.start=0,this._el.move.style.left=this.data.pos.start.x+"px",this._el.move.style.top=this.data.pos.start.y+"px",this._el.move.style.position="absolute";}disable(){ht.removeListener(this._el.drag,this.dragevent.down,this._onDragStart,this),ht.removeListener(this._el.drag,this.dragevent.up,this._onDragEnd,this);}stopMomentum(){this.animator&&this.animator.stop();}updateConstraint(t){this.options.constraint=t;}_onDragStart(t){f?t.originalEvent?(this.data.pagex.start=t.originalEvent.touches[0].screenX,this.data.pagey.start=t.originalEvent.touches[0].screenY):(this.data.pagex.start=t.targetTouches[0].screenX,this.data.pagey.start=t.targetTouches[0].screenY):(this.data.pagex.start=t.pageX,this.data.pagey.start=t.pageY),this.options.enable.x&&(this._el.move.style.left=this.data.pagex.start-this._el.move.offsetWidth/2+"px"),this.options.enable.y&&(this._el.move.style.top=this.data.pagey.start-this._el.move.offsetHeight/2+"px"),this.data.pos.start=b(this._el.drag),this.data.time.start=(new Date()).getTime(),this.fire("dragstart",this.data),ht.addListener(this._el.drag,this.dragevent.move,this._onDragMove,this),ht.addListener(this._el.drag,this.dragevent.leave,this._onDragEnd,this);}_onDragEnd(t){this.data.sliding=!1,ht.removeListener(this._el.drag,this.dragevent.move,this._onDragMove,this),ht.removeListener(this._el.drag,this.dragevent.leave,this._onDragEnd,this),this.fire("dragend",this.data),this._momentum();}_onDragMove(t){t.preventDefault(),this.data.sliding=!0,f?t.originalEvent?(this.data.pagex.end=t.originalEvent.touches[0].screenX,this.data.pagey.end=t.originalEvent.touches[0].screenY):(this.data.pagex.end=t.targetTouches[0].screenX,this.data.pagey.end=t.targetTouches[0].screenY):(this.data.pagex.end=t.pageX,this.data.pagey.end=t.pageY),this.data.pos.end=b(this._el.drag),this.data.new_pos.x=-(this.data.pagex.start-this.data.pagex.end-this.data.pos.start.x),this.data.new_pos.y=-(this.data.pagey.start-this.data.pagey.end-this.data.pos.start.y),this.options.enable.x&&(this._el.move.style.left=this.data.new_pos.x+"px"),this.options.enable.y&&(this._el.move.style.top=this.data.new_pos.y+"px"),this.fire("dragmove",this.data);}_momentum(){var t={x:0,y:0,time:0},e={x:0,y:0,time:0},i=!1;t.time=10*((new Date()).getTime()-this.data.time.start),e.time=10*((new Date()).getTime()-this.data.time.start),e.x=this.options.momentum_multiplier*(Math.abs(this.data.pagex.end)-Math.abs(this.data.pagex.start)),e.y=this.options.momentum_multiplier*(Math.abs(this.data.pagey.end)-Math.abs(this.data.pagey.start)),t.x=Math.round(e.x/e.time),t.y=Math.round(e.y/e.time),this.data.new_pos.x=Math.min(this.data.pos.end.x+t.x),this.data.new_pos.y=Math.min(this.data.pos.end.y+t.y),this.options.enable.x?this.data.new_pos.x<0&&(this.data.new_pos.x=0):this.data.new_pos.x=this.data.pos.start.x,this.options.enable.y?this.data.new_pos.y<0&&(this.data.new_pos.y=0):this.data.new_pos.y=this.data.pos.start.y,e.time<3e3&&(i=!0),Math.abs(e.x)>1e4&&(this.data.direction="left",e.x>0&&(this.data.direction="right")),Math.abs(e.y)>1e4&&(this.data.direction="up",e.y>0&&(this.data.direction="down")),this._animateMomentum(),i&&this.fire("swipe_"+this.data.direction,this.data);}_animateMomentum(){var t={x:this.data.new_pos.x,y:this.data.new_pos.y},e={duration:this.options.duration,easing:tt};this.options.enable.y&&((this.options.constraint.top||this.options.constraint.bottom)&&(t.y>this.options.constraint.bottom?t.y=this.options.constraint.bottom:t.y<this.options.constraint.top&&(t.y=this.options.constraint.top)),e.top=Math.floor(t.y)+"px"),this.options.enable.x&&((this.options.constraint.left||this.options.constraint.right)&&(t.x>this.options.constraint.left?t.x=this.options.constraint.left:t.x<this.options.constraint.right&&(t.x=this.options.constraint.right)),e.left=Math.floor(t.x)+"px"),this.animator=st(this._el.move,e),this.fire("momentum",this.data);}}R(at);
28var lt,ht={addListener:function(t,e,i,a){var s=A(i),n="_tl_"+e+s;if(!t[n]){var o=function(e){return i.call(a||t,e||ht._getEvent());};if(f&&"dblclick"===e&&this.addDoubleTapListener)this.addDoubleTapListener(t,o,s);else if("addEventListener" in t)if("mousewheel"===e)t.addEventListener("DOMMouseScroll",o,!1),t.addEventListener(e,o,!1);else if("mouseenter"===e||"mouseleave"===e){var r=o,l="mouseenter"===e?"mouseover":"mouseout";o=function(e){if(ht._checkMouse(t,e))return r(e);},t.addEventListener(l,o,!1);}else t.addEventListener(e,o,!1);else "attachEvent" in t&&t.attachEvent("on"+e,o);t[n]=o;}},removeListener:function(t,e,i){var a=A(i),s="_tl_"+e+a,n=t[s];n&&(f&&"dblclick"===e&&this.removeDoubleTapListener?this.removeDoubleTapListener(t,a):"removeEventListener" in t?"mousewheel"===e?(t.removeEventListener("DOMMouseScroll",n,!1),t.removeEventListener(e,n,!1)):"mouseenter"===e||"mouseleave"===e?t.removeEventListener("mouseenter"===e?"mouseover":"mouseout",n,!1):t.removeEventListener(e,n,!1):"detachEvent" in t&&t.detachEvent("on"+e,n),t[s]=null);},_checkMouse:function(t,e){var i=e.relatedTarget;if(!i)return !0;try{for(;i&&i!==t;)i=i.parentNode;}catch(t){return !1;}return i!==t;},_getEvent:function(){var t=window.event;if(!t)for(var e=arguments.callee.caller;e&&(!(t=e.arguments[0])||window.Event!==t.constructor);)e=e.caller;return t;},stopPropagation:function(t){t.stopPropagation?t.stopPropagation():t.cancelBubble=!0;},disableClickPropagation:function(t){ht.addListener(t,rt.START,ht.stopPropagation),ht.addListener(t,"click",ht.stopPropagation),ht.addListener(t,"dblclick",ht.stopPropagation);},preventDefault:function(t){t.preventDefault?t.preventDefault():t.returnValue=!1;},stop:function(t){ht.preventDefault(t),ht.stopPropagation(t);},getWheelDelta:function(t){var e=0;return t.wheelDelta&&(e=t.wheelDelta/120),t.detail&&(e=-t.detail/3),e;}},dt=function(){var t,e,i,a,s,n,o=[],r=o.slice,l=o.filter,h=window.document,d={},c={},u={"column-count":1,columns:1,"font-weight":1,"line-height":1,opacity:1,"z-index":1,zoom:1},m=/^\s*<(\w+|!)[^>]*>/,_=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,p=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,f=/^(?:body|html)$/i,g=/([A-Z])/g,v=["val","css","html","text","data","width","height","offset"],y=h.createElement("table"),b=h.createElement("tr"),w={tr:h.createElement("tbody"),tbody:y,thead:y,tfoot:y,td:b,th:b,"*":h.createElement("div")},k=/complete|loaded|interactive/,x=/^[\w-]*$/,T={},M=T.toString,E={},L=h.createElement("div"),D={tabindex:"tabIndex",readonly:"readOnly",for:"htmlFor",class:"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},S=Array.isArray||function(t){return t instanceof Array;};function N(t){return null==t?String(t):T[M.call(t)]||"object";}function A(t){return "function"==N(t);}function C(t){return null!=t&&t==t.window;}function I(t){return null!=t&&t.nodeType==t.DOCUMENT_NODE;}function O(t){return "object"==N(t);}function R(t){return O(t)&&!C(t)&&Object.getPrototypeOf(t)==Object.prototype;}function j(t){return "number"==typeof t.length;}function P(t){return t.replace(/::/g,"/").replace(/([A-Z]+)([A-Z][a-z])/g,"$1_$2").replace(/([a-z\d])([A-Z])/g,"$1_$2").replace(/_/g,"-").toLowerCase();}function z(t){return t in c?c[t]:c[t]=new RegExp("(^|\\s)"+t+"(\\s|$)");}function H(t,e){return "number"!=typeof e||u[P(t)]?e:e+"px";}function F(t){return "children" in t?r.call(t.children):i.map(t.childNodes,(function(t){if(1==t.nodeType)return t;}));}function q(i,a,s){for(e in a)s&&(R(a[e])||S(a[e]))?(R(a[e])&&!R(i[e])&&(i[e]={}),S(a[e])&&!S(i[e])&&(i[e]=[]),q(i[e],a[e],s)):a[e]!==t&&(i[e]=a[e]);}function $(t,e){return null==e?i(t):i(t).filter(e);}function U(t,e,i,a){return A(e)?e.call(t,i,a):e;}function B(t,e,i){null==i?t.removeAttribute(e):t.setAttribute(e,i);}function W(e,i){var a=e.className,s=a&&a.baseVal!==t;if(i===t)return s?a.baseVal:a;s?a.baseVal=i:e.className=i;}function G(t){var e;try{return t?"true"==t||"false"!=t&&("null"==t?null:/^0/.test(t)||isNaN(e=Number(t))?/^[\[\{]/.test(t)?i.parseJSON(t):t:e):t;}catch(e){return t;}}function Y(t,e){for(var i in e(t),t.childNodes)Y(t.childNodes[i],e);}return E.matches=function(t,e){if(!e||!t||1!==t.nodeType)return !1;var i=t.webkitMatchesSelector||t.mozMatchesSelector||t.oMatchesSelector||t.matchesSelector;if(i)return i.call(t,e);var a,s=t.parentNode,n=!s;return n&&(s=L).appendChild(t),a=~E.qsa(s,e).indexOf(t),n&&L.removeChild(t),a;},s=function(t){return t.replace(/-+(.)?/g,(function(t,e){return e?e.toUpperCase():"";}));},n=function(t){return l.call(t,(function(e,i){return t.indexOf(e)==i;}));},E.fragment=function(e,a,s){var n,o,l;return _.test(e)&&(n=i(h.createElement(RegExp.$1))),n||(e.replace&&(e=e.replace(p,"<$1></$2>
28")),a===t&&(a=m.test(e)&&RegExp.$1),a in w||(a="*"),(l=w[a]).innerHTML=""+e,n=i.each(r.call(l.childNodes),(function(){l.removeChild(this);}))),R(s)&&(o=i(n),i.each(s,(function(t,e){v.indexOf(t)>-1?o[t](e):o.attr(t,e);}))),n;},E.Z=function(t,e){return (t=t||[]).__proto__=i.fn,t.selector=e||"",t;},E.isZ=function(t){return t instanceof E.Z;},E.init=function(e,a){var s,n;if(!e)return E.Z();if("string"==typeof e)if("<"==(e=e.trim())[0]&&m.test(e))s=E.fragment(e,RegExp.$1,a),e=null;else{if(a!==t)return i(a).find(e);s=E.qsa(h,e);}else{if(A(e))return i(h).ready(e);if(E.isZ(e))return e;if(S(e))n=e,s=l.call(n,(function(t){return null!=t;}));else if(O(e))s=[e],e=null;else if(m.test(e))s=E.fragment(e.trim(),RegExp.$1,a),e=null;else{if(a!==t)return i(a).find(e);s=E.qsa(h,e);}}return E.Z(s,e);},(i=function(t,e){return E.init(t,e);}).extend=function(t){var e,i=r.call(arguments,1);return "boolean"==typeof t&&(e=t,t=i.shift()),i.forEach((function(i){q(t,i,e);})),t;},E.qsa=function(t,e){var i,a="#"==e[0],s=!a&&"."==e[0],n=a||s?e.slice(1):e,o=x.test(n);return I(t)&&o&&a?(i=t.getElementById(n))?[i]:[]:1!==t.nodeType&&9!==t.nodeType?[]:r.call(o&&!a?s?t.getElementsByClassName(n):t.getElementsByTagName(e):t.querySelectorAll(e));},i.contains=function(t,e){return t!==e&&t.contains(e);},i.type=N,i.isFunction=A,i.isWindow=C,i.isArray=S,i.isPlainObject=R,i.isEmptyObject=function(t){var e;for(e in t)return !1;return !0;},i.inArray=function(t,e,i){return o.indexOf.call(e,t,i);},i.camelCase=s,i.trim=function(t){return null==t?"":String.prototype.trim.call(t);},i.uuid=0,i.support={},i.expr={},i.map=function(t,e){var a,s,n,o,r=[];if(j(t))for(s=0;s<t.length;s++)null!=(a=e(t[s],s))&&r.push(a);else for(n in t)null!=(a=e(t[n],n))&&r.push(a);return (o=r).length>0?i.fn.concat.apply([],o):o;},i.each=function(t,e){var i,a;if(j(t)){for(i=0;i<t.length;i++)if(!1===e.call(t[i],i,t[i]))return t;}else{for(a in t)if(!1===e.call(t[a],a,t[a]))return t;}return t;},i.grep=function(t,e){return l.call(t,e);},window.JSON&&(i.parseJSON=JSON.parse),i.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),(function(t,e){T["[object "+e+"]"]=e.toLowerCase();})),i.fn={forEach:o.forEach,reduce:o.reduce,push:o.push,sort:o.sort,indexOf:o.indexOf,concat:o.concat,map:function(t){return i(i.map(this,(function(e,i){return t.call(e,i,e);})));},slice:function(){return i(r.apply(this,arguments));},ready:function(t){return k.test(h.readyState)&&h.body?t(i):h.addEventListener("DOMContentLoaded",(function(){t(i);}),!1),this;},get:function(e){return e===t?r.call(this):this[e>=0?e:e+this.length];},toArray:function(){return this.get();},size:function(){return this.length;},remove:function(){return this.each((function(){null!=this.parentNode&&this.parentNode.removeChild(this);}));},each:function(t){return o.every.call(this,(function(e,i){return !1!==t.call(e,i,e);})),this;},filter:function(t){return A(t)?this.not(this.not(t)):i(l.call(this,(function(e){return E.matches(e,t);})));},add:function(t,e){return i(n(this.concat(i(t,e))));},is:function(t){return this.length>0&&E.matches(this[0],t);},not:function(e){var a=[];if(A(e)&&e.call!==t)this.each((function(t){e.call(this,t)||a.push(this);}));else{var s="string"==typeof e?this.filter(e):j(e)&&A(e.item)?r.call(e):i(e);this.forEach((function(t){s.indexOf(t)<0&&a.push(t);}));}return i(a);},has:function(t){return this.filter((function(){return O(t)?i.contains(this,t):i(this).find(t).size();}));},eq:function(t){return -1===t?this.slice(t):this.slice(t,+t+1);},first:function(){var t=this[0];return t&&!O(t)?t:i(t);},last:function(){var t=this[this.length-1];return t&&!O(t)?t:i(t);},find:function(t){var e=this;return "object"==typeof t?i(t).filter((function(){var t=this;return o.some.call(e,(function(e){return i.contains(e,t);}));})):1==this.length?i(E.qsa(this[0],t)):this.map((function(){return E.qsa(this,t);}));},closest:function(t,e){var a=this[0],s=!1;for("object"==typeof t&&(s=i(t));a&&!(s?s.indexOf(a)>=0:E.matches(a,t));)a=a!==e&&!I(a)&&a.parentNode;return i(a);},parents:function(t){for(var e=[],a=this;a.length>0;)a=i.map(a,(function(t){if((t=t.parentNode)&&!I(t)&&e.indexOf(t)<0)return e.push(t),t;}));return $(e,t);},parent:function(t){return $(n(this.pluck("parentNode")),t);},children:function(t){return $(this.map((function(){return F(this);})),t);},contents:function(){return this.map((function(){return r.call(this.childNodes);}));},siblings:function(t){return $(this.map((function(t,e){return l.call(F(e.parentNode),(function(t){return t!==e;}));})),t);},empty:function(){return this.each((function(){this.innerHTML="";}));},pluck:function(t){return i.map(this,(function(e){return e[t];}));},show:function(){return this.each((function(){var t,e,i;"none"==this.style.display&&(this.style.display=""),"none"==getComputedStyle(this,"").getPropertyValue("display")&&(this.style.display=(t=this.nodeName,d[t]||(e=h.createElement(t),h.body.appendChild(e),i=getComputedStyle(e,"").getPropertyValue("display"),e.parentNode.removeChild(e),"none"==i&&(i="block"),d[t]=i),d[t]));}));},replaceWith:function(t){return this.before(t).remove();},wrap:function(t){var e=A(t);if(this[0]&&!e)var a=i(t).get(0),s=a.parentNode||this.length>1;return this.each((function(n){i(this).wrapAll(e?t.call(this,n):s?a.cloneNode(!0):a);}));},wrapAll:function(t){if(this[0]){var e;
28for(i(this[0]).before(t=i(t));(e=t.children()).length;)t=e.first();i(t).append(this);}return this;},wrapInner:function(t){var e=A(t);return this.each((function(a){var s=i(this),n=s.contents(),o=e?t.call(this,a):t;n.length?n.wrapAll(o):s.append(o);}));},unwrap:function(){return this.parent().each((function(){i(this).replaceWith(i(this).children());})),this;},clone:function(){return this.map((function(){return this.cloneNode(!0);}));},hide:function(){return this.css("display","none");},toggle:function(e){return this.each((function(){var a=i(this);(e===t?"none"==a.css("display"):e)?a.show():a.hide();}));},prev:function(t){return i(this.pluck("previousElementSibling")).filter(t||"*");},next:function(t){return i(this.pluck("nextElementSibling")).filter(t||"*");},html:function(t){return 0===arguments.length?this.length>0?this[0].innerHTML:null:this.each((function(e){var a=this.innerHTML;i(this).empty().append(U(this,t,e,a));}));},text:function(e){return 0===arguments.length?this.length>0?this[0].textContent:null:this.each((function(){this.textContent=e===t?"":""+e;}));},attr:function(i,a){var s;return "string"==typeof i&&a===t?0==this.length||1!==this[0].nodeType?t:"value"==i&&"INPUT"==this[0].nodeName?this.val():!(s=this[0].getAttribute(i))&&i in this[0]?this[0][i]:s:this.each((function(t){if(1===this.nodeType)if(O(i))for(e in i)B(this,e,i[e]);else B(this,i,U(this,a,t,this.getAttribute(i)));}));},removeAttr:function(t){return this.each((function(){1===this.nodeType&&B(this,t);}));},prop:function(e,i){return e=D[e]||e,i===t?this[0]&&this[0][e]:this.each((function(t){this[e]=U(this,i,t,this[e]);}));},data:function(e,i){var a=this.attr("data-"+e.replace(g,"-$1").toLowerCase(),i);return null!==a?G(a):t;},val:function(t){return 0===arguments.length?this[0]&&(this[0].multiple?i(this[0]).find("option").filter((function(){return this.selected;})).pluck("value"):this[0].value):this.each((function(e){this.value=U(this,t,e,this.value);}));},offset:function(t){if(t)return this.each((function(e){var a=i(this),s=U(this,t,e,a.offset()),n=a.offsetParent().offset(),o={top:s.top-n.top,left:s.left-n.left};"static"==a.css("position")&&(o.position="relative"),a.css(o);}));if(0==this.length)return null;var e=this[0].getBoundingClientRect();return {left:e.left+window.pageXOffset,top:e.top+window.pageYOffset,width:Math.round(e.width),height:Math.round(e.height)};},css:function(t,a){if(arguments.length<2){var n=this[0],o=getComputedStyle(n,"");if(!n)return;if("string"==typeof t)return n.style[s(t)]||o.getPropertyValue(t);if(S(t)){var r={};return i.each(S(t)?t:[t],(function(t,e){r[e]=n.style[s(e)]||o.getPropertyValue(e);})),r;}}var l="";if("string"==N(t))a||0===a?l=P(t)+":"+H(t,a):this.each((function(){this.style.removeProperty(P(t));}));else for(e in t)t[e]||0===t[e]?l+=P(e)+":"+H(e,t[e])+";":this.each((function(){this.style.removeProperty(P(e));}));return this.each((function(){this.style.cssText+=";"+l;}));},index:function(t){return t?this.indexOf(i(t)[0]):this.parent().children().indexOf(this[0]);},hasClass:function(t){return !!t&&o.some.call(this,(function(t){return this.test(W(t));}),z(t));},addClass:function(t){return t?this.each((function(e){a=[];var s=W(this);U(this,t,e,s).split(/\s+/g).forEach((function(t){i(this).hasClass(t)||a.push(t);}),this),a.length&&W(this,s+(s?" ":"")+a.join(" "));})):this;},removeClass:function(e){return this.each((function(i){if(e===t)return W(this,"");a=W(this),U(this,e,i,a).split(/\s+/g).forEach((function(t){a=a.replace(z(t)," ");})),W(this,a.trim());}));},toggleClass:function(e,a){return e?this.each((function(s){var n=i(this);U(this,e,s,W(this)).split(/\s+/g).forEach((function(e){(a===t?!n.hasClass(e):a)?n.addClass(e):n.removeClass(e);}));})):this;},scrollTop:function(e){if(this.length){var i="scrollTop" in this[0];return e===t?i?this[0].scrollTop:this[0].pageYOffset:this.each(i?function(){this.scrollTop=e;}:function(){this.scrollTo(this.scrollX,e);});}},scrollLeft:function(e){if(this.length){var i="scrollLeft" in this[0];return e===t?i?this[0].scrollLeft:this[0].pageXOffset:this.each(i?function(){this.scrollLeft=e;}:function(){this.scrollTo(e,this.scrollY);});}},position:function(){if(this.length){var t=this[0],e=this.offsetParent(),a=this.offset(),s=f.test(e[0].nodeName)?{top:0,left:0}:e.offset();return a.top-=parseFloat(i(t).css("margin-top"))||0,a.left-=parseFloat(i(t).css("margin-left"))||0,s.top+=parseFloat(i(e[0]).css("border-top-width"))||0,s.left+=parseFloat(i(e[0]).css("border-left-width"))||0,{top:a.top-s.top,left
28:a.left-s.left};}},offsetParent:function(){return this.map((function(){for(var t=this.offsetParent||h.body;t&&!f.test(t.nodeName)&&"static"==i(t).css("position");)t=t.offsetParent;return t;}));}},i.fn.detach=i.fn.remove,["width","height"].forEach((function(e){var a=e.replace(/./,(function(t){return t[0].toUpperCase();}));i.fn[e]=function(s){var n,o=this[0];return s===t?C(o)?o["inner"+a]:I(o)?o.documentElement["scroll"+a]:(n=this.offset())&&n[e]:this.each((function(t){(o=i(this)).css(e,U(this,s,t,o[e]()));}));};})),["after","prepend","before","append"].forEach((function(t,e){var a=e%2;i.fn[t]=function(){var t,s,n=i.map(arguments,(function(e){return "object"==(t=N(e))||"array"==t||null==e?e:E.fragment(e);})),o=this.length>1;return n.length<1?this:this.each((function(t,r){s=a?r:r.parentNode,r=0==e?r.nextSibling:1==e?r.firstChild:2==e?r:null,n.forEach((function(t){if(o)t=t.cloneNode(!0);else{if(!s)return i(t).remove();}Y(s.insertBefore(t,r),(function(t){null==t.nodeName||"SCRIPT"!==t.nodeName.toUpperCase()||t.type&&"text/javascript"!==t.type||t.src||window.eval.call(window,t.innerHTML);}));}));}));},i.fn[a?t+"To":"insert"+(e?"Before":"After")]=function(e){return i(e)[t](this),this;};})),E.Z.prototype=i.fn,E.uniq=n,E.deserializeValue=G,i.zepto=E,i;}();window.Zepto=dt,void 0===window.$&&(window.$=dt),function(t){t.zepto.qsa;var e,i=1,a=Array.prototype.slice,s=t.isFunction,n=function(t){return "string"==typeof t;},o={},r={},l="onfocusin" in window,h={focus:"focusin",blur:"focusout"}
28,d={mouseenter:"mouseover",mouseleave:"mouseout"};function c(t){return t._zid||(t._zid=i++);}function u(t,e,i,a){if((e=m(e)).ns)var s=(n=e.ns,new RegExp("(?:^| )"+n.replace(" "," .* ?")+"(?: |$)"));var n;return (o[c(t)]||[]).filter((function(t){return t&&(!e.e||t.e==e.e)&&(!e.ns||s.test(t.ns))&&(!i||c(t.fn)===c(i))&&(!a||t.sel==a);}));}function m(t){var e=(""+t).split(".");return {e:e[0],ns:e.slice(1).sort().join(" ")};}function _(t,e){return t.del&&!l&&t.e in h||!!e;}function p(t){return d[t]||l&&h[t]||t;}function f(i,a,s,n,r,l,h){var u=c(i),f=o[u]||(o[u]=[]);a.split(/\s/).forEach((function(a){if("ready"==a)return t(document).ready(s);var o=m(a);o.fn=s,o.sel=r,o.e in d&&(s=function(e){var i=e.relatedTarget;if(!i||i!==this&&!t.contains(this,i))return o.fn.apply(this,arguments);}),o.del=l;var c=l||s;o.proxy=function(t){if(!(t=k(t)).isImmediatePropagationStopped()){t.data=n;var a=c.apply(i,t._args==e?[t]:[t].concat(t._args));return !1===a&&(t.preventDefault(),t.stopPropagation()),a;}},o.i=f.length,f.push(o),"addEventListener" in i&&i.addEventListener(p(o.e),o.proxy,_(o,h));}));}function g(t,e,i,a,s){var n=c(t);(e||"").split(/\s/).forEach((function(e){u(t,e,i,a).forEach((function(e){delete o[n][e.i],"removeEventListener" in t&&t.removeEventListener(p(e.e),e.proxy,_(e,s));}));}));}r.click=r.mousedown=r.mouseup=r.mousemove="MouseEvents",t.event={add:f,remove:g},t.proxy=function(e,i){if(s(e)){var a=function(){return e.apply(i,arguments);};return a._zid=c(e),a;}if(n(i))return t.proxy(e[i],e);throw new TypeError("expected function");},t.fn.bind=function(t,e,i){return this.on(t,e,i);},t.fn.unbind=function(t,e){return this.off(t,e);},t.fn.one=function(t,e,i,a){return this.on(t,e,i,a,1);};var v=function(){return !0;},y=function(){return !1;},b=/^([A-Z]|returnValue$|layer[XY]$)/,w={preventDefault:"isDefaultPrevented",stopImmediatePropagation:"isImmediatePropagationStopped",stopPropagation:"isPropagationStopped"};function k(i,a){return !a&&i.isDefaultPrevented||(a||(a=i),t.each(w,(function(t,e){var s=a[t];i[t]=function(){return this[e]=v,s&&s.apply(a,arguments);},i[e]=y;})),(a.defaultPrevented!==e?a.defaultPrevented:"returnValue" in a?!1===a.returnValue:a.getPreventDefault&&a.getPreventDefault())&&(i.isDefaultPrevented=v)),i;}function x(t){var i,a={originalEvent:t};for(i in t)b.test(i)||t[i]===e||(a[i]=t[i]);return k(a,t);}t.fn.delegate=function(t,e,i){return this.on(e,t,i);},t.fn.undelegate=function(t,e,i){return this.off(e,t,i);},t.fn.live=function(e,i){return t(document.body).delegate(this.selector,e,i),this;},t.fn.die=function(e,i){return t(document.body).undelegate(this.selector,e,i),this;},t.fn.on=function(i,o,r,l,h){var d,c,u=this;return i&&!n(i)?(t.each(i,(function(t,e){u.on(t,o,r,e,h);})),u):(n(o)||s(l)||!1===l||(l=r,r=o,o=e),(s(r)||!1===r)&&(l=r,r=e),!1===l&&(l=y),u.each((function(e,s){h&&(d=function(t){return g(s,t.type,l),l.apply(this,arguments);}),o&&(c=function(e){var i,n=t(e.target).closest(o,s).get(0);if(n&&n!==s)return i=t.extend(x(e),{currentTarget:n,liveFired:s}),(d||l).apply(n,[i].concat(a.call(arguments,1)));}),f(s,i,l,r,o,c||d);})));},t.fn.off=function(i,a,o){var r=this;return i&&!n(i)?(t.each(i,(function(t,e){r.off(t,a,e);})),r):(n(a)||s(o)||!1===o||(o=a,a=e),!1===o&&(o=y),r.each((function(){g(this,i,o,a);})));},t.fn.trigger=function(e,i){return (e=n(e)||t.isPlainObject(e)?t.Event(e):k(e))._args=i,this.each((function(){"dispatchEvent" in this?this.dispatchEvent(e):t(this).triggerHandler(e,i);}));},t.fn.triggerHandler=function(e,i){var a,s;return this.each((function(o,r){(a=x(n(e)?t.Event(e):e))._args=i,a.target=r,t.each(u(r,e.type||e),(function(t,e){if(s=e.proxy(a),a.isImmediatePropagationStopped())return !1;}));})),s;},"focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select keydown keypress keyup error".split(" ").forEach((function(e){t.fn[e]=function(t){return t?this.bind(e,t):this.trigger(e);};})),["focus","blur"].forEach((function(e){t.fn[e]=function(t){return t?this.bind(e,t):this.each((function(){try{this[e]();}catch(t){}})),this;};})),t.Event=function(t,e){n(t)||(t=(e=t).type);var i=document.createEvent(r[t]||"Events"),a=!0;if(e)for(var s in e)"bubbles"==s?a=!!e[s]:i[s]=e[s];return i.initEvent(t,a,!0),k(i);};}(dt),function(t){var e,i,a=0,s=window.document,n=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,o=/^(?:text|application)\/javascript/i,r=/^(?:text|application)\/xml/i,l="application/json",h="text/html",d=/^\s*$/;
28function c(e,i,a,n){if(e.global)return function(e,i,a){var s=t.Event(i);return t(e).trigger(s,a),!s.isDefaultPrevented();}(i||s,a,n);}function u(t,e){var i=e.context;if(!1===e.beforeSend.call(i,t,e)||!1===c(e,i,"ajaxBeforeSend",[t,e]))return !1;c(e,i,"ajaxSend",[t,e]);}function m(t,e,i,a){var s=i.context,n="success";i.success.call(s,t,n,e),a&&a.resolveWith(s,[t,n,e]),c(i,s,"ajaxSuccess",[e,i,t]),p(n,e,i);}function _(t,e,i,a,s){var n=a.context;a.error.call(n,i,e,t),s&&s.rejectWith(n,[i,e,t]),c(a,n,"ajaxError",[i,a,t||e]),p(e,i,a);}function p(e,i,a){var s=a.context;a.complete.call(s,i,e),c(a,s,"ajaxComplete",[i,a]),function(e){e.global&&!--t.active&&c(e,null,"ajaxStop");}(a);}function f(){}function g(t,e){return ""==e?t:(t+"&"+e).replace(/[&?]{1,2}/,"?");}function v(e,i,a,s){var n=!t.isFunction(i);return {url:e,data:n?i:void 0,success:n?t.isFunction(a)?a:void 0:i,dataType:n&&s||a};}t.active=0,t.ajaxJSONP=function(e,i){if(!("type" in e))return t.ajax(e);var n,o,r=e.jsonpCallback,l=(t.isFunction(r)?r():r)||"jsonp"+ ++a,h=s.createElement("script"),d=window[l],c=function(e){t(h).triggerHandler("error",e||"abort");},p={abort:c};return i&&i.promise(p),t(h).on("load error",(function(a,s){clearTimeout(o),t(h).off().remove(),"error"!=a.type&&n?m(n[0],p,e,i):_(null,s||"error",p,e,i),window[l]=d,n&&t.isFunction(d)&&d(n[0]),d=n=void 0;})),!1===u(p,e)?(c("abort"),p):(window[l]=function(){n=arguments;},h.src=e.url.replace(/\?(.+)=\?/,"?$1="+l),s.head.appendChild(h),e.timeout>0&&(o=setTimeout((function(){c("timeout");}),e.timeout)),p);},t.ajaxSettings={type:"GET",beforeSend:f,success:f,error:f,complete:f,context:null,global:!0,xhr:function(){return new window.XMLHttpRequest();},accepts:{script:"text/javascript, application/javascript, application/x-javascript",json:l,xml:"application/xml, text/xml",html:h,text:"text/plain"},crossDomain:!1,timeout:0,processData:!0,cache:!0},t.ajax=function(a){var s=t.extend({},a||{}),n=t.Deferred&&t.Deferred();for(e in t.ajaxSettings)void 0===s[e]&&(s[e]=t.ajaxSettings[e]);!function(e){e.global&&0==t.active++&&c(e,null,"ajaxStart");}(s),s.crossDomain||(s.crossDomain=/^([\w-]+:)?\/\/([^\/]+)/.test(s.url)&&RegExp.$2!=window.location.host),s.url||(s.url=window.location.toString()),function(e){e.processData&&e.data&&"string"!=t.type(e.data)&&(e.data=t.param(e.data,e.traditional)),!e.data||e.type&&"GET"!=e.type.toUpperCase()||(e.url=g(e.url,e.data),e.data=void 0);}(s),!1===s.cache&&(s.url=g(s.url,"_="+Date.now()));var p=s.dataType,v=/\?.+=\?/.test(s.url);if("jsonp"==p||v)return v||(s.url=g(s.url,s.jsonp?s.jsonp+"=?":!1===s.jsonp?"":"callback=?")),t.ajaxJSONP(s,n);var y,b=s.accepts[p],w={},k=function(t,e){w[t.toLowerCase()]=[t,e];},x=/^([\w-]+:)\/\//.test(s.url)?RegExp.$1:window.location.protocol,T=s.xhr(),M=T.setRequestHeader;if(n&&n.promise(T),s.crossDomain||k("X-Requested-With","XMLHttpRequest"),k("Accept",b||"*/*"),(b=s.mimeType||b)&&(b.indexOf(",")>-1&&(b=b.split(",",2)[0]),T.overrideMimeType&&T.overrideMimeType(b)),(s.contentType||!1!==s.contentType&&s.data&&"GET"!=s.type.toUpperCase())&&k("Content-Type",s.contentType||"application/x-www-form-urlencoded"),s.headers)for(i in s.headers)k(i,s.headers[i]);if(T.setRequestHeader=k,T.onreadystatechange=function(){if(4==T.readyState){T.onreadystatechange=f,clearTimeout(y);var e,i=!1;if(T.status>=200&&T.status<300||304==T.status||0==T.status&&"file:"==x){p=p||function(t){return t&&(t=t.split(";",2)[0]),t&&(t==h?"html":t==l?"json":o.test(t)?"script":r.test(t)&&"xml")||"text";}(s.mimeType||T.getResponseHeader("content-type")),e=T.responseText;try{"script"==p?(0,eval)(e):"xml"==p?e=T.responseXML:"json"==p&&(e=d.test(e)?null:t.parseJSON(e));}catch(t){i=t;}i?_(i,"parsererror",T,s,n):m(e,T,s,n);}else _(T.statusText||null,T.status?"error":"abort",T,s,n);}},!1===u(T,s))return T.abort(),_(null,"abort",T,s,n),T;if(s.xhrFields)for(i in s.xhrFields)T[i]=s.xhrFields[i];var E=!("async" in s)||s.async;for(i in T.open(s.type,s.url,E,s.username,s.password),w)M.apply(T,w[i]);return s.timeout>0&&(y=setTimeout((function(){T.onreadystatechange=f,T.abort(),_(null,"timeout",T,s,n);}),s.timeout)),T.send(s.data?s.data:null),T;},t.get=function(e,i,a,s){return t.ajax(v.apply(null,arguments));},t.post=function(e,i,a,s){var n=v.apply(null,arguments);return n.type="POST",t.ajax(n);},t.getJSON=function(e,i,a){var s=v.apply(null,arguments);return s.dataType="json",t.ajax(s);},t.fetchJSON=function(t){var e=new XMLHttpRequest();return new Promise((function(i,a){e.onreadystatechange=function(){try{if(4!==e.readyState)return;if(e.status>=200&&e.status<300){var s=JSON.parse(e.responseText);i(s);}else a({status:e.status,statusText:e.statusText});}catch(e){a({status:400,statusText:`Error fetching JSON from ${t}: ${e}`});}},e.open("GET",t,!0),e.send();}));},t.fn.load=function(e,i,a){if(!this.length)return this;var s,o=this,r=e.split(/\s/),l=v(e,i,a),h=l.success;return r.length>1&&(l.url=r[0],s=r[1]),l.success=function(e){o.html(s?t("<div>").html(e.replace(n,"")).find(s):e),h&&h.apply(o,arguments);},t.ajax(l),this;};var y=encodeURIComponent;function b(e,i,a,s){var n,o=t.isArray(i),r=t.isPlainObject(i);t.each(i,(function(i,l){n=t.type(l),s&&(i=a?s:s+"["+(r||"object"==n||"array"==n?i:"")+"]"),!s&&o?e.add(l.name,l.value):"array"==n||!a&&"object"==n?b(e,l,a,i):e.add(i,l);}));}t.param=function(t,e){var i=[];return i.add=function(t,e){this.push(y(t)+"="+y(e));},b(i,t,e),i.join("&").replace(/%20/g,"+");};}(dt),(lt=dt).fn.serializeArray=function(){var t,e=[];return lt([].slice.call(this.get(0).elements)).each((function(){var i=(t=lt(this)).attr("type");"fieldset"!=this.nodeName.toLowerCase()&&!this.disabled&&"submit"!=i&&"reset"!=i&&"button"!=i&&("radio"!=i&&"checkbox"!=i||this.checked)&&e.push({name:t.attr("name"),value:t.val()});})),e;},lt.fn.serialize=function(){var t=[];
28return this.serializeArray().forEach((function(e){t.push(encodeURIComponent(e.name)+"="+encodeURIComponent(e.value));})),t.join("&");},lt.fn.submit=function(t){if(t)this.bind("submit",t);else{if(this.length){var e=lt.Event("submit");this.eq(0).trigger(e),e.isDefaultPrevented()||this.get(0).submit();}}return this;},function(t){"__proto__" in {}||t.extend(t.zepto,{Z:function(e,i){return e=e||[],t.extend(e,t.fn),e.selector=i||"",e.__Z=!0,e;},isZ:function(e){return "array"===t.type(e)&&"__Z" in e;}});try{getComputedStyle(void 0);}catch(t){var e=getComputedStyle;window.getComputedStyle=function(t,i){try{return e(t,i);}catch(t){return null;}};}}(dt);const ct=dt.getJSON,ut=dt.ajax,mt=dt.fetchJSON,_t=[["millisecond",1,function(t){}],["second",1e3,function(t){t.setMilliseconds(0);}],["minute",6e4,function(t){t.setSeconds(0);}],["hour",36e5,function(t){t.setMinutes(0);}],["day",864e5,function(t){t.setHours(0);}],["month",2592e6,function(t){t.setDate(1);}],["year",31536e6,function(t){t.setMonth(0);}],["decade",31536e7,function(t){var e=t.getFullYear();t.setFullYear(e-e%10);}],["century",31536e8,function(t){var e=t.getFullYear();t.setFullYear(e-e%100);}],["millennium",31536e9,function(t){var e=t.getFullYear();t.setFullYear(e-e%1e3);}]],pt=["millisecond","second","minute","hour","day","month","year"],ft=/^([\+-]?\d+?)(-\d{2}?)?(-\d{2}?)?$/,gt=/^([\+-]?\d{4}(?!\d{2}\b))((-?)((0[1-9]|1[0-2])(\3([12]\d|0[1-9]|3[01]))?|W([0-4]\d|5[0-2])(-?[1-7])?|(00[1-9]|0[1-9]\d|[12]\d{2}|3([0-5]\d|6[1-6])))([T\s]((([01]\d|2[0-3])((:?)[0-5]\d)?|24\:?00)([\.,]\d+(?!:))?)?(\17[0-5]\d([\.,]\d+)?)?([zZ]|([\+-])([01]\d|2[0-3]):?([0-5]\d)?)?)?)?$/,vt={base:{millisecond:"time_short",second:"time",minute:"time_no_seconds_small_date",hour:"time_no_seconds_small_date",day:"full",month:"month",year:"year",decade:"year",century:"year",millennium:"year",age:"fallback",epoch:"fallback",era:"fallback",eon:"fallback",eon2:"fallback"},short:{millisecond:"time_short",second:"time_short",minute:"time_no_seconds_short",hour:"time_no_minutes_short",day:"full_short",month:"month_short",year:"year",decade:"year",century:"year",millennium:"year",age:"fallback",epoch:"fallback",era:"fallback",eon:"fallback",eon2:"fallback"}},yt=it.extend({initialize:function(t,e,i){"number"==typeof t?this.data={format:"yyyy mmmm",date_obj:new Date(t)}:Date==t.constructor?this.data={format:"yyyy mmmm",date_obj:t}:(this.data=JSON.parse(JSON.stringify(t)),this._createDateObj()),t.format&&!e&&(e=t.format),this._setFormat(e,i);},setDateFormat:function(t){this.data.format=t;},getDisplayDate:function(t,e){if(this.data.display_date)return this.data.display_date;t||(t=Nt.fallback),t.constructor!=Nt&&(S("First argument to getDisplayDate must be type Language"),t=Nt.fallback);var i=e||this.data.format;return t.formatDate(this.data.date_obj,i);},getMillisecond:function(){return this.getTime();},getTime:function(){return this.data.date_obj.getTime();},isBefore:function(t){if(!this.data.date_obj.constructor==t.data.date_obj.constructor)throw new x("date_compare_err");return "isBefore" in this.data.date_obj?this.data.date_obj.isBefore(t.data.date_obj):this.data.date_obj<t.data.date_obj;},isAfter:function(t){if(!this.data.date_obj.constructor==t.data.date_obj.constructor)throw new x("date_compare_err");return "isAfter" in this.data.date_obj?this.data.date_obj.isAfter(t.data.date_obj):this.data.date_obj>t.data.date_obj;},floor:function(t){for(var e=new Date(this.data.date_obj.getTime()),i=0;i<_t.length;i++)if(_t[i][2](e),_t[i][0]==t)return new yt(e);throw new x("invalid_scale_err",t);},_getDateData:function(){var t={year:0,month:1,day:1,hour:0,minute:0,second:0,millisecond:0};for(var e in E(t,this.data),pt){if(!O(t[pt[e]]).match(/^-?\d*$/))throw new x("invalid_date_err",pt[e]+" = '"+t[pt[e]]+"'");var i=parseInt(t[pt[e]]);isNaN(i)&&(i=4==e||5==e?1:0),t[pt[e]]=i;}return t.month>0&&t.month<=12&&(t.month=t.month-1),t;},_createDateObj:function(){var t=this._getDateData();this.data.date_obj=new Date(t.year,t.month,t.day,t.hour,t.minute,t.second,t.millisecond),this.data.date_obj.getFullYear()!=t.year&&this.data.date_obj.setFullYear(t.year);},findBestFormat:function(t){for(var e=pt,i=0;i<e.length;i++)if(this.data[e[i]])return t?t in vt||(t="short"):t="base",vt[t][e[i]];return "";},_setFormat:function(t,e){t?this.data.format=t:this.data.format||(this.data.format=this.findBestFormat()),e?this.data.format_short=e:this.data.format_short||(this.data.format_short=this.findBestFormat(!0));},getFullYear:function(){return this.data.date_obj.getFullYear();}});function bt(t){if(t.match(ft)){var e=t.match(ft).slice(1),i={year:e[0].replace("+","")};return e[1]&&(i.month=e[1].replace("-","")),e[2]&&(i.day=e[2].replace("-","")),i;}if(t.match(gt))return cls.parseISODate(t);if(t.match(/^\-?\d+$/))return {year:t};var a={};if(t.match(/\d+\/\d+\/\d+/)){var s=t.match(/\d+\/\d+\/\d+/)[0];t=O(t.replace(s,""));var n=s.split("/");a.month=n[0],a.day=n[1],a.year=n[2];}if(t.match(/\d+\/\d+/)&&(s=t.match(/\d+\/\d+/)[0],t=O(t.replace(s,"")),n=s.split("/"),a.month=n[0],a.year=n[1]),t.match(":")){var o=t.split(":");
28if(a.hour=o[0],a.minute=o[1],o[2]){let t=o[2].split(".");a.second=t[0],a.millisecond=t[1];}}return a;}const wt=it.extend({initialize:function(t){if(this.year=parseInt(t),isNaN(this.year))throw new x("invalid_year_err",t);},isBefore:function(t){return this.year<t.year;},isAfter:function(t){return this.year>t.year;},getTime:function(){return this.year;}}),kt=1e6,xt=10*kt,Tt=10*xt,Mt=10*Tt;function Et(t){return function(e){var i=e.getTime();return new wt(Math.floor(i/t)*t);};}const Lt=[["year",1,new Et(1)],["decade",10,new Et(10)],["century",100,new Et(100)],["millennium",1e3,new Et(1e3)],["age",kt,new Et(kt)],["epoch",xt,new Et(xt)],["era",Tt,new Et(Tt)],["eon",Mt,new Et(Mt)]],Dt=yt.extend({initialize:function(t,e,i){wt==t.constructor?this.data={date_obj:t}:(this.data=JSON.parse(JSON.stringify(t)),this._createDateObj()),t.format&&!e&&(e=t.format),this._setFormat(e,i);},_createDateObj:function(){var t=this._getDateData();this.data.date_obj=new wt(t.year);},floor:function(t){for(var e=0;e<Lt.length;e++)if(Lt[e][0]==t){var i=Lt[e][2](this.data.date_obj);return new Dt(i);}throw new x("invalid_scale_err",t);},getFullYear:function(){return this.data.date_obj.getTime();}}),St=new RegExp(/\$\{(.+?)\}/g);class Nt{constructor(t,e){for(let t in It.en)this[t]=It.en[t];if(t&&"string"==typeof t&&"en"!=t){var i=t;if(!(i in It)){console.log(`Expected language ${i} to be cached. Did you call the constructor directly?`);var a=At(i,e);mt(a).then(((t)=>{It[i]=t;})).catch(((t)=>{console.log(`Error loading language [${a}] ${t.statusText} [${t.status}]`);}));}E(this,It[i]);}}mergeData(t){for(k in It.en)t[k]&&("object"==typeof this[k]?E(t[k],this[k]):this[k]=t[k]);}formatBigYear(t,e){var i=t.year,a=this.bigdateformats[e]||this.bigdateformats.fallback;if(a){for(var s=0;s<a.length;s++){var n=a[s];if(Math.abs(i/n[0])>1)return Ct(Math.abs(i/n[0]),n[1]);}return i.toString();}return S("Language file dateformats missing cosmological. Falling back."),Ct(i,e);}_(t,e){let i=this.messages[t]||Nt.fallback.messages[t]||t;if(i.match(St)){if(!e)throw new x("template_message_without_context");for(let t of i.matchAll(St)){if(!(t[1] in e))throw new x("template_message_without_context");i=i.replace(t[0],e[t[1]]);}}return i;}formatDate(t,e){return t.constructor==Date?this.formatJSDate(t,e):t.constructor==wt?this.formatBigYear(t,e):t.data&&t.data.date_obj?this.formatDate(t.data.date_obj,e):(S("Unfamiliar date presented for formatting"),t.toString());}formatJSDate(t,e){var i=this,a=function(t,e){var a=i.period_labels[t];return a&&(t=e<12?a[0]:a[1]),"<span class='tl-timeaxis-timesuffix'>"+t+"</span>";};e||(e="full");var s=this.dateformats[e]||Nt.fallback.dateformats[e];s||(s=e);var n="get",o=t[n+"Date"](),r=t[n+"Day"](),l=t[n+"Month"](),h=t[n+"FullYear"](),d=t[n+"Hours"](),c=t[n+"Minutes"](),u=t[n+"Seconds"](),m=t[n+"Milliseconds"](),_=t.getTimezoneOffset(),p={d:o,dd:N(o),ddd:this.date.day_abbr[r],dddd:this.date.day[r],m:l+1,mm:N(l+1),mmm:this.date.month_abbr[l],mmmm:this.date.month[l],yy:String(h).slice(2),yyyy:h<0&&this.has_negative_year_modifier()?Math.abs(h):h,h:d%12||12,hh:N(d%12||12),H:d,HH:N(d),M:c,MM:N(c),s:u,ss:N(u),l:N(m,3),L:N(m>99?Math.round(m/10):m),t:a("t",d),tt:a("tt",d),T:a("T",d),TT:a("TT",d),Z:(String(t).match(/\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g)||[""]).pop().replace(/[^-+\dA-Z]/g,""),o:(_>0?"-":"+")+N(100*Math.floor(Math.abs(_)/60)+Math.abs(_)%60,4),S:["th","st","nd","rd"][o%10>3?0:(o%100-o%10!=10)*o%10]},f=s.replace(Nt.DATE_FORMAT_TOKENS,(function(t){return t in p?p[t]:t.slice(1,t.length-1);}));return this._applyEra(f,h);}has_negative_year_modifier(){return Boolean(this.era_labels.negative_year.prefix||this.era_labels.negative_year.suffix);}_applyEra(t,e){var i=e<0?this.era_labels.negative_year:this.era_labels.positive_year,a="";return i.prefix&&(a+="<span>"+i.prefix+"</span> "),a+=t,i.suffix&&(a+=" <span>"+i.suffix+"</span>"),a;}}function At(t,e){if(/\.json$/.test(t))var i=t;else{var a="/locale/"+t+".json";/\/$/.test(e)&&(a=a.substr(1)),i=e+a;}return i;}function Ct(t,e){if(e.match(/%(\.(\d+))?f/)){var i=e.match(/%(\.(\d+))?f/),a=i[0];return i[2]&&(t=t.toFixed(i[2])),e.replace(a,t);}return e;}Nt.fallback={messages:{}},Nt.DATE_FORMAT_TOKENS=/d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g;
28var It={en:{name:"English (built-in)",lang:"en",api:{wikipedia:"en"},messages:{loading:"Loading",wikipedia:"From Wikipedia, the free encyclopedia",error:"Error",return_to_title:"Return to Title",go_to_end:"Go to the last slide",loading_content:"Loading Content",loading_timeline:"Loading Timeline... ",swipe_to_navigate:"Swipe to Navigate<br><span class='tl-button'>OK</span>",zoom_in:"Zoom in",zoom_out:"Zoom out",unknown_read_err:"An unexpected error occurred trying to read your spreadsheet data",invalid_url_err:"Unable to read Timeline data. Make sure your URL is for a Google Spreadsheet or a Timeline JSON file.",network_err:"Unable to read your Google Spreadsheet. Make sure you have published it to the web.",missing_start_date_err:"Missing start_date",invalid_start_time_without_date:"Invalid configuration: time cannot be used without date.",invalid_end_time_without_date:"Invalid configuration: end time cannot be used without end date.",date_compare_err:"Can't compare timeline date objects on different scales",invalid_scale_err:"Invalid scale",invalid_date_err:"Invalid date: month, day and year must be numbers.",invalid_separator_error:"Invalid time: misuse of : or . as separator.",invalid_hour_err:"Invalid time (hour)",invalid_minute_err:"Invalid time (minute)",invalid_second_err:"Invalid time (second)",invalid_fractional_err:"Invalid time (fractional seconds)",invalid_second_fractional_err:"Invalid time (seconds and fractional seconds)",invalid_year_err:"Invalid year",flickr_notfound_err:"Photo not found or private",flickr_invalidurl_err:"Invalid Flickr URL",imgur_invalidurl_err:"Invalid Imgur URL",twitter_load_err:"Unable to load Tweet",twitterembed_invalidurl_err:"Invalid Twitter Embed url",wikipedia_load_err:"Unable to load Wikipedia entry",wikipedia_image_load_err:"Unable to load Wikipedia image data",spotify_invalid_url:"Invalid Spotify URL",invalid_rgb_err:"Invalid RGB argument",time_scale_scale_err:"Don't know how to get date from time for scale",axis_helper_no_options_err:"Axis helper must be configured with options",axis_helper_scale_err:"No AxisHelper available for scale",invalid_integer_option:"Invalid option valueâmust be a whole number.",instagram_bad_request:"Invalid or private Instagram URL",template_message_without_context:"Required variables not provided for template translation message",aria_label_timeline:"Timeline",aria_label_timeline_navigation:"Timeline navigation",aria_label_timeline_content:"Timeline content",aria_label_zoomin:"Show less than ${start} to ${end}",aria_label_zoomout:"Show more than ${start} to ${end}"},date:{month:["January","February","March","April","May","June","July","August","September","October","November","December"],month_abbr:["Jan.","Feb.","March","April","May","June","July","Aug.","Sept.","Oct.","Nov.","Dec."],day:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],day_abbr:["Sun.","Mon.","Tues.","Wed.","Thurs.","Fri.","Sat."]},era_labels:{positive_year:{prefix:"",suffix:""},negative_year:{prefix:"",suffix:"BCE"}},period_labels:{t:["a","p"],tt:["am","pm"],T:["A","P"],TT:["AM","PM"]},dateformats:{year:"yyyy",month_short:"mmm",month:"mmmm yyyy",full_short:"mmm d",full:"mmmm d',' yyyy",time:"h:MM:ss TT' <small>'mmmm d',' yyyy'</small>'",time_short:"h:MM:ss TT",time_no_seconds_short:"h:MM TT",time_no_minutes_short:"h TT",time_no_seconds_small_date:"h:MM TT' <small>'mmmm d',' yyyy'</small>'",time_milliseconds:"l",full_long:"mmm d',' yyyy 'at' h:MM TT",full_long_small_date:"h:MM TT' <small>mmm d',' yyyy'</small>'"},bigdateformats:{fallback:[[1e9,"%.2f billion years ago"],[1e6,"%.1f million years ago"],[1e3,"%.1f thousand years ago"],[1,"%f years ago"]],compact:[[1e9,"%.2f bya"],[1e6,"%.1f mya"],[1e3,"%.1f kya"],[1,"%f years ago"]],verbose:[[1e9,"%.2f billion years ago"],[1e6,"%.1f million years ago"],[1e3,"%.1f thousand years ago"],[1,"%f years ago"]]}}};let Ot=new Nt();Nt.fallback=Ot;class Rt{setLanguage(t){this.language=t;}getLanguage(){if(this.language){if("object"==typeof this.language)return this.language;S("I18NMixins.getLanguage: this.language should be object, but is "+typeof this.language);}return Ot;}_(t,e){return this.getLanguage()._(t,e);}}class jt{constructor(t,e,i){i&&this.setLanguage(i),this._el={parent:{},container:{},message_container:{},loading_icon:{},message:{}},this.options={width:600,height:600,message_class:"tl-message",message_icon_class:"tl-loading-icon"},this.container=t,E(this.options,e),this._el.container=v("div",this.options.message_class),t&&(t.appendChild(this._el.container),this._el.parent=t),this.animator={},this._initLayout(),this._initEvents();}updateMessage(t){this._el.message.innerHTML=t||this._("loading"),!this._el.parent.atributes&&this.container.attributes&&(this.container.appendChild(this._el.container),this._el.parent=this.container);}updateDisplay(t,e){}_onMouseClick(){this.fire("clicked",this.options);}_onRemove(){this._el.parent={};}_initLayout(){this._el.message_container=v("div","tl-message-container",this._el.container),this._el.loading_icon=v("div",this.options.message_icon_class,this._el.message_container),this._el.message=v("div","tl-message-content",this._el.message_container),this.updateMessage();}_initEvents(){ht.addListener(this._el.container,"click",this._onMouseClick,this),ht.addListener(this,"removed",this._onRemove,this);}}function Pt(t,e){e=e||"start_date",t.sort((function(t,i){return t[e].isBefore(i[e])?-1:t[e].isAfter(i[e])?1:0;}));}function zt(t){var e={hour:null,minute:null,second:null,millisecond:null},i=null,a=t.match(/(\s*[AaPp]\.?[Mm]\.?\s*)$/);a&&(i=O(a[0]),t=O(t.substring(0,t.lastIndexOf(i))));var s=[],n=t.match(/^\s*(\d{1,2})(\d{2})\s*$/);if(n?s=n.slice(1):1==(s=t.split(":")).length&&(s=t.split(".")),s.length>4)throw new x("invalid_separator_error");let o=s[0];if(e.hour=parseInt(o),i&&"p"==i.toLowerCase()[0]&&12!=e.hour?e.hour+=12:i&&"a"==i.toLowerCase()[0]&&12==e.hour&&(e.hour=0),isNaN(e.hour)||e.hour<0||e.hour>23)throw new x("invalid_hour_err",o);if(s.length>1){let t=s[1];if(e.minute=parseInt(t),isNaN(e.minute))throw new x("invalid_minute_err",t);}if(s.length>2){var r=s[2].split(/[\.,]/);if((s=r.concat(s.slice(3))).length>2)throw new x("invalid_second_fractional_err");if(e.second=parseInt(s[0]),isNaN(e.second))throw new x("invalid_second_err",s[0]);if(2==s.length){var l=parseInt(s[1]);if(isNaN(l))throw new x("invalid_fractional_err",s[1]);e.millisecond=100*l;}}return e;}R(jt,Rt,at,ot);const Ht=new RegExp("(^-?\\d+$|^$)");function Ft(t){try{return Object.keys(t).forEach(((e)=>{let i=t[e];if(i&&i.match&&!i.match(Ht))throw `invalid value ${i} for ${e}`;})),!0;}catch(t){return !1;}}const qt={human:yt,cosmological:Dt};var $t=i(838),Ut=i.n($t);const Bt={text:["headline","text"],media:["caption","credit"]},Wt={start_date:["display_date"],end_date:["display_date"],slide:["display_date","group"],date:["display_date"]};
28function Gt(t,e,i){Object.keys(i).forEach(((a)=>{var s="slide"==a?t:t[a];s&&i[a].forEach(((t)=>{void 0!==s[t]&&(s[t]=e(s[t]));}));}));}function Yt(t){return Ut().sanitize(t,{ADD_TAGS:["iframe"],ADD_ATTR:["frameborder","target"]});}Ut().addHook("afterSanitizeAttributes",(function(t){if("A"==t.nodeName&&"href" in t){"target" in t.attributes||t.setAttribute("target","_blank");let e=t.attributes.rel;e?-1==e.value.indexOf("noopener")&&t.setAttribute("rel",`noopener ${e.value}`):t.setAttribute("rel","noopener");}}));class Zt{constructor(t){if(this.title="",this.scale="",this.events=[],this.eras=[],this.event_dict={},this.messages={errors:[],warnings:[]},"object"==typeof t&&t.events){if(this.scale=t.scale,this.events=[],this._ensureValidScale(t.events),t.title){var e=this._assignID(t.title);this._tidyFields(t.title),this.title=t.title,this.event_dict[e]=this.title;}for(var i=0;i<t.events.length;i++)try{this.addEvent(t.events[i],!0);}catch(t){this.logError(t);}t.eras&&t.eras.forEach(((t,e)=>{try{this.addEra(t);}catch(t){this.logError("Era "+e+": "+t);}})),Pt(this.events),Pt(this.eras);}}logError(t){S(`logError: ${t}`),this.messages.errors.push(t);}getErrors(t){return t?this.messages.errors.join(t):this.messages.errors;}validate(){void 0!==this.events&&void 0!==this.events.length&&0!=this.events.length||this.logError("Timeline configuration has no events.");for(var t=0;t<this.eras.length;t++){var e;void 0!==this.eras[t].start_date&&void 0!==this.eras[t].end_date||(e=this.eras[t].headline?this.eras[t].headline:"era "+(t+1),this.logError("All eras must have start and end dates. ["+e+"]"));}}isValid(){return 0==this.messages.errors.length;}addEvent(t,e){var i=this._assignID(t);return void 0===t.start_date?(S("Missing start date, skipping event"),console.log(t),null):(this._processDates(t),this._tidyFields(t),this.events.push(t),this.event_dict[i]=t,e||Pt(this.events),i);}addEra(t){var e=this._assignID(t);if(void 0===t.start_date)throw new x("missing_start_date_err",e);this._processDates(t),this._tidyFields(t),this.eras.push({start_date:t.start_date,end_date:t.end_date,headline:t.text.headline});}_assignID(t){var e=t.unique_id;return O(e)||(e=t.text?j(t.text.headline):null),t.unique_id=function(t,e){if(e||(e=P(6)),!(e in t))return e;var i=e.match(/^(.+)(-\d+)?$/)[1],a=[];for(let e in t)e.match(/^(.+?)(-\d+)?$/)[1]==i&&a.push(e);e=i+"-"+(a.length+1);for(var s=a.length;-1!=a.indexOf(e);s++)e=i+"-"+s;return e;}(this.event_dict,e),t.unique_id;}_makeUniqueIdentifiers(t,e){for(var i=[t],a=0;a<e.length;a++)O(e[a].unique_id)&&(e[a].unique_id=j(e[a].unique_id),-1==i.indexOf(e[a].unique_id)?i.push(e[a].unique_id):e[a].unique_id="");if(i.length!=e.length+1)for(a=0;a<e.length;a++)if(!e[a].unique_id){var s=e[a].text?j(e[a].text.headline):null;s||(s=P(6)),-1!=i.indexOf(s)&&(s=s+"-"+a),i.push(s),e[a].unique_id=s;}}_ensureValidScale(t){if(!this.scale){this.scale="human";
28for(var e=0;e<t.length;e++){if("cosmological"==t[e].scale){this.scale="cosmological";break;}if(t[e].start_date&&void 0!==t[e].start_date.year){var i=new Dt(t[e].start_date).data.date_obj.year;if(i<-271820||i>275759){this.scale="cosmological";break;}}}S(`Determining scale dynamically: ${this.scale}`);}qt[this.scale]||this.logError("Don't know how to process dates on scale "+this.scale);}_processDates(t){var e=qt[this.scale];if(!(t.start_date instanceof e)){var i=t.start_date;if(t.start_date=new e(i),void 0!==t.end_date&&!(t.end_date instanceof e)){var a=t.end_date,s=!0;for(let t in i)s=s&&i[t]==a[t];s?(S("End date same as start date is redundant; dropping end date"),delete t.end_date):t.end_date=new e(a);}}}getEarliestDate(){var t=this.events[0].start_date;return this.eras&&this.eras.length>0&&this.eras[0].start_date.isBefore(t)?this.eras[0].start_date:t;}getLatestDate(){for(var t=[],e=0;e<this.events.length;e++)this.events[e].end_date?t.push({date:this.events[e].end_date}):t.push({date:this.events[e].start_date});for(e=0;e<this.eras.length;e++)this.eras[e].end_date?t.push({date:this.eras[e].end_date}):t.push({date:this.eras[e].start_date});return Pt(t,"date"),t.slice(-1)[0].date;}_tidyFields(t){function e(t,e,i){i||(i=""),t.hasOwnProperty(e)||(t[e]=i);}t.group&&(t.group=O(t.group)),t.text||(t.text={}),e(t.text,"text"),e(t.text,"headline"),Gt(t,Yt,Bt),Gt(t,X,Wt);}}function Vt(t,e){return !0!==(e=e||{}).noHeaderRow&&t.length>0?{fields:t[0].map(((t,e)=>t&&t.trim?t.trim():`untitled${e}`)),records:t.slice(1)}:{records:t};}function Xt(t,e){(!e||e&&!e.lineterminator)&&(t=function(t,e){return e&&!e.lineterminator?t.replace(/(\r\n|\n|\r)/gm,"\n"):t;}(t,e));var i=function(t){var e={delimiter:",",doublequote:!0,lineterminator:"\n",quotechar:'"',skipinitialspace:!0,skipinitialrows:0};for(var i in t)"trim"===i?e.skipinitialspace=t.trim:e[i.toLowerCase()]=t[i];return e;}(e);t=function(t,e){return null==t?"":(e=e||"\n",t.charAt(t.length-e.length)!==e?t:t.substring(0,t.length-e.length));}(t,i.lineterminator);var a,s,n="",o=!1,r=!1,l="",h=[],d=[];for(s=function(t){return !0!==r&&(""===t?t=null:!0===i.skipinitialspace&&(t=t.trim())),t;},a=0;a<t.length;a+=1)n=t.charAt(a),!1!==o||n!==i.delimiter&&n!==i.lineterminator?n!==i.quotechar?l+=n:o?t.charAt(a+1)===i.quotechar?(l+=i.quotechar,a+=1):o=!1:(o=!0,r=!0):(l=s(l),h.push(l),n===i.lineterminator&&(d.push(h),h=[]),l="",r=!1);return l=s(l),h.push(l),d.push(h),i.skipinitialrows&&(d=d.slice(i.skipinitialrows)),d;}function Jt(t){if(t)return t.replace(/[\s,]+/g,"");}function Kt(t){let e={key:null,worksheet:0};var i=/\bkey=([-_A-Za-z0-9]+)&?/i,a=/docs.google.com\/spreadsheets(.*?)\/d\//;if(t.match(i))e.key=t.match(i)[1];else if(t.match(a)){var s=t.search(a)+t.match(a)[0].length,n=t.substr(s);e.key=n.split("/")[0],t.match(/\?gid=(\d+)/)&&(e.worksheet=t.match(/\?gid=(\d+)/)[1]);}else t.match(/^\b[-_A-Za-z0-9]+$/)&&(e.key=t);return e.key?e:null;}async function Qt(t,e){let i=[];t=function(t){if((t=t.trim()).match(/^[a-zA-Z0-9-_]+$/))return `https://docs.google.com/spreadsheets/d/${t}/pub?output=csv`;if(t.startsWith("https://docs.google.com/spreadsheets/")){if(t.match(/\/pub\?output=csv$/))return t;let e=new URL(t),i=new URLSearchParams(e.search);i.set("output","csv"),i.get("gid")&&i.set("single","true"),e.search=`?${i.toString()}`;let a=e.pathname.substr(0,e.pathname.lastIndexOf("/"));return e.pathname=`${a}/pub`,e.toString();}throw new x("invalid_url_err",t);}(t),await async function(t){return new Promise(((e,i)=>{if(t.data){var a=Vt(Xt(t.data,t),t);a.useMemoryStore=!0,e(a);}else t.url&&window.fetch(t.url,{mode:"cors"}).then((function(t){if(200==t.status)return t.text?t.text():t;"application/json"==t.headers.get("content-type")?t.text().then(((t)=>{i(JSON.parse(t));})):i({status_code:t.status,message:`Error fetching CSV: [${t.status} ${t.statusText}]`});})).then((function(i){if(i){var a=function(t,e){let i=Vt(Xt(t,e)),a=[];return i.records.forEach(((t)=>{let e={};i.fields.forEach(((i,a)=>e[i]=t[a])),a.push(e);})),a;}(i,t);a.useMemoryStore=!0,e(a);}})).catch(((t)=>{i({status_code:500,message:`Error fetching CSV: ${t}`});}));}));}({url:`${e}${t}`}).then(((t)=>{i=t;})).catch(((t)=>{if("response_not_csv"==t.proxy_err_code)throw new x("Timeline could not read the data for your timeline. Make sure you have published it to the web.");let e="undefined error";throw e=Array.isArray(t.message)?t.message.join("<br>"):String(t.message),new x(e);}));let a={events:[],errors:[],warnings:[],eras:[]};
28return i.forEach(((t,e)=>{try{if(!function(t){var e=[];if(Object.keys)e=Object.keys(t);else for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&e.push(i);for(var a=0;a<e.length;a++){var s=e[a];if(null!=t[s]&&"string"!=typeof t[s])return !1;if(0!=O(t[s]).length)return !1;}return !0;}(t)){let e=function(t){let e={};Object.keys(t).forEach(((i)=>{e[i]=O(t[i]);}));var i,a={media:{caption:e["Media Caption"]||"",credit:e["Media Credit"]||"",url:e.Media||"",thumbnail:e["Media Thumbnail"]||"",alt:e["Alt Text"]||""},text:{headline:e.Headline||"",text:e.Text||""},display_date:e["Display Date"]||"",group:e.Group||e.Tag||"",background:(i=e.Background,"string"!=typeof i?"":i.match(/^(https?:)?\/\/?/)?{url:i}:{color:i}),type:e.Type||""};if(Object.keys(e).includes("Start Date")||Object.keys(e).includes("End Date"))e["Start Date"]&&(a.start_date=bt(e["Start Date"])),e["End Date"]&&(a.end_date=bt(e["End Date"]));else{if(e.Year&&(a.start_date={year:Jt(e.Year),month:Jt(e.Month)||"",day:Jt(e.Day)||""}),e["End Year"]&&(a.end_date={year:Jt(e["End Year"])||"",month:Jt(e["End Month"])||"",day:Jt(e["End Day"])||""}),e.Time){if(!a.start_date)throw new x("invalid_start_time_without_date");E(a.start_date,zt(e.Time));}if(e["End Time"]){if(!a.end_date)throw new x("invalid_end_time_without_date");E(a.end_date,zt(e["End Time"]));}if(a.start_date&&!Ft(a.start_date))throw new x("invalid_date_err");if(a.end_date&&!Ft(a.end_date))throw new x("invalid_date_err");}return a;}(t);!function(t,e){var i="event";void 0!==t.type&&(i=t.type,delete t.type),"title"==i?e.title?(e.warnings.push("Multiple title slides detected."),e.events.push(t)):e.title=t:"era"==i?e.eras.push(t):e.events.push(t);}(e,a);}}catch(i){if(i.constructor==x)a.errors.push(i);else{i.message&&(i=i.message);let s=t.Headline||e;a.errors.push(i+`[${s}]`);}}})),a;}async function te(t,e){if(!e.sheets_proxy)throw new x("Proxy option must be set to read data from Google");var i=await Qt(t,e.sheets_proxy);if(i)return i;}class ee{constructor(t){if(!t)throw new x("axis_helper_no_options_err");this.scale=t.scale,this.minor=t.minor,this.major=t.major;}getPixelsPerTick(t){return t*this.minor.factor;}getMajorTicks(t){return this._getTicks(t,this.major);}getMinorTicks(t){return this._getTicks(t,this.minor);}_getTicks(t,e){for(var i=t._scaled_padding*e.factor,a=t._earliest-i,s=t._latest+i,n=[],o=a;o<s;o+=e.factor)n.push(t.getDateFromTime(o).floor(e.name));return {name:e.name,ticks:n};}}var ie={},ae=function(t,e){ie[t]=[];for(var i=0;i<e.length-1;i++){var a=e[i],s=e[i+1];ie[t].push(new ee({scale:a[3],minor:{name:a[0],factor:a[1]},major:{name:s[0],factor:s[1]}}));}};ae("human",_t),ae("cosmological",Lt);const se={millisecond:"time_milliseconds",second:"time_short",minute:"time_no_seconds_short",hour:"time_no_minutes_short",day:"full_short",month:"month_short",year:"year",decade:"year",century:"year",millennium:"year",age:"compact",epoch:"compact",era:"compact",eon:"compact",eon2:"compact"};class ne{constructor(t,e){var i=t.events;this._scale=t.scale,e=E({display_width:500,screen_multiplier:3,max_rows:null},e),this._display_width=e.display_width,this._screen_multiplier=e.screen_multiplier,this._pixel_width=this._screen_multiplier*this._display_width,this._group_labels=void 0,this._positions=[],this._pixels_per_milli=0,this._earliest=t.getEarliestDate().getTime(),this._latest=t.getLatestDate().getTime(),this._span_in_millis=this._latest-this._earliest,this._span_in_millis<=0&&(this._span_in_millis=this._computeDefaultSpan(t)),this._average=this._span_in_millis/i.length,this._pixels_per_milli=this.getPixelWidth()/this._span_in_millis,this._axis_helper=function(t,e){"number"!=typeof e&&(e=100);var i=t.getScale(),a=ie[i];if(!a)throw new x("axis_helper_scale_err",i);for(var s=null,n=0;n<a.length;n++){var o=a[n],r=o.getPixelsPerTick(t._pixels_per_milli);if(r>e)return null==s||Math.abs(e-r)<Math.abs(e-r)?o:s;s=o;}return a[a.length-1];}(this),this._scaled_padding=1/this.getPixelsPerTick()*(this._display_width/2),this._computePositionInfo(i,e.max_rows);}_computeDefaultSpan(t){if("human"==t.scale){for(var e={},i=0;i<t.events.length;i++){var a=t.events[i].start_date.findBestFormat();e[a]=e[a]?e[a]+1:1;}for(i=_t.length-1;i>=0;i--)if(e.hasOwnProperty(_t[i][0])){var s=_t[_t.length-1];return _t[i+1]&&(s=_t[i+1]),s[1];}return 31536e6;}return 2e5;}getGroupLabels(){return this._group_labels||[];}getScale(){return this._scale;}getNumberOfRows(){return this._number_of_rows;}getPixelWidth(){return this._pixel_width;}getPosition(t){return (t-this._earliest)*this._pixels_per_milli;}getPositionInfo(t){return this._positions[t];}getPixelsPerTick(){return this._axis_helper.getPixelsPerTick(this._pixels_per_milli);}getTicks(){return {major:this._axis_helper.getMajorTicks(this),minor:this._axis_helper.getMinorTicks(this)};}getDateFromTime(t){if("human"==this._scale)return new yt(t);if("cosmological"==this._scale)return new Dt(new wt(t));throw new x("time_scale_scale_err",this._scale);}getMajorScale(){return this._axis_helper.major.name;}getMinorScale(){return this._axis_helper.minor.name;}_assessGroups(t){for(var e=[],i=!1,a=0;a<t.length;a++)t[a].group&&(e.indexOf(t[a].group)<0?e.push(t[a].group):i=!0);return e.length&&i&&e.push(""),e;}_computeRowInfo(t,e){for(var i=[],a=0,s=0;s<t.length;s++){var n=t[s],o=[];delete n.row;for(var r=0;r<i.length;r++)if(o.push(i[r].end-n.start),o[r]<=0){n.row=r,i[r]=n;break;}if(void 0===n.row)if(null===e)n.row=i.length,i.push(n);else if(e>0)n.row=i.length,i.push(n),e--;else{var l=Math.min.apply(null,o),h=o.indexOf(l);n.row=h,n.end>i[h].end&&(i[h]=n),a++;}}return {n_rows:i.length,n_overlaps:a};}_computePositionInfo(t,e,i){i=i||100;for(var a=[],s=!1,n=0;n<t.length;n++){var o={start:this.getPosition(t[n].start_date.getTime())};if(this._positions.push(o),void 0!==t[n].end_date){var r=this.getPosition(t[n].end_date.getTime());o.width=r-o.start,o.width>i?o.end=o.start+o.width:o.end=o.start+i;}else o.width=i,o.end=o.start+i;t[n].group?a.indexOf(t[n].group)<0&&a.push(t[n].group):s=!0;}if(a.length){s&&a.push("");var l=[];for(n=0;n<a.length;n++)l[n]={label:a[n],idx:n,positions:[],n_rows:1,n_overlaps:0};for(n=0;n<this._positions.length;n++){(o=this._positions[n]).group=a.indexOf(t[n].group||""),o.row=0;for(var h=(u=l[o.group]).positions.length-1;h>=0;h--)u.positions[h].end>o.start&&u.n_overlaps++;u.positions.push(o);}for(var d=a.length;;){var c=Math.max(0,e-d);if(!c)break;if(l.sort((function(t,e){return t.n_overlaps>e.n_overlaps?-1:t.n_overlaps<e.n_overlaps?1:t.idx-e.idx;})),!l[0].n_overlaps)break;for(d=0,n=0;n<l.length;n++){var u;if((u=l[n]).n_overlaps&&c){var m=this._computeRowInfo(u.positions,u.n_rows+1);u.n_rows=m.n_rows,u.n_overlaps=m.n_overlaps,c--;}d+=u.n_rows;}}this._number_of_rows=d,this._group_labels=[],l.sort((function(t,e){return t.idx-e.idx;})),n=0;for(var _=0;n<l.length;n++){for(this._group_labels.push({label:l[n].label,rows:l[n].n_rows}),h=0;h<l[n].positions.length;h++)(o=l[n].positions[h]).row+=_;_+=l[n].n_rows;}}else{var p=this._computeRowInfo(this._positions,e);
28this._number_of_rows=p.n_rows;}}getAxisTickDateFormat(t){return "cosmological"==this._scale?"compact":se[t];}}class oe{constructor(t){this._el={parent:{},container:{},message:{}},this.options={width:600,height:600},this.data={label:"",rows:1},this._el.container=v("div","tl-timegroup"),E(this.data,t),this.animator={},this._initLayout(),this._initEvents();}updateDisplay(t,e){}setRowPosition(t,e){this.options.height=e*this.data.rows,this.setPosition({top:t}),this._el.container.style.height=this.options.height+"px";}setAlternateRowColor(t,e){var i="tl-timegroup";t&&(i+=" tl-timegroup-alternate"),e&&(i+=" tl-timegroup-hidden"),this._el.container.className=i;}_onMouseClick(){this.fire("clicked",this.options);}_initLayout(){this._el.message=v("div","tl-timegroup-message",this._el.container),this._el.message.innerHTML=this.data.label;}_initEvents(){ht.addListener(this._el.container,"click",this._onMouseClick,this);}_updateDisplay(t,e,i){}}R(oe,at,ot);class re{constructor(t,e,i,a){this.start_date=t,this.end_date=e,this.headline=i,this._el={container:{},background:{},content_container:{},content:{},text:{}},this._text={},this._state={loaded:!1},this.options={duration:1e3,ease:Q,width:600,height:600,marker_width_min:100},this.active=!1,this.animator={},this.has_end_date=!1,E(this.options,a),this._initLayout(),this._initEvents();}show(){}hide(){}setActive(t){}addTo(t){t.appendChild(this._el.container);}removeFrom(t){t.removeChild(this._el.container);}updateDisplay(t,e){this._updateDisplay(t,e);}getLeft(){return this._el.container.style.left.slice(0,-2);}getTime(){return this.start_date.getTime();}getEndTime(){return !!this.end_date&&this.end_date.getTime();}setHeight(t){var e=1;this._el.content_container.style.height=t+"px",this._el.content.className="tl-timeera-content",r?((e=Math.floor(t/14))<1&&(e=1),this._text.className="tl-headline",this._text.style.webkitLineClamp=e):(e=t/12,this._text.className=e>1?"tl-headline tl-headline-fadeout":"tl-headline",this._text.style.height=12*e+"px");}setWidth(t){this.end_date&&(this._el.container.style.width=t+"px",t>this.options.marker_width_min?(this._el.content_container.style.width=t+"px",this._el.content_container.className="tl-timeera-content-container tl-timeera-content-container-long"):(this._el.content_container.style.width=this.options.marker_width_min+"px",this._el.content_container.className="tl-timeera-content-container"));}setClass(t){this._el.container.className=t;}setRowPosition(t,e){this.setPosition({top:t}),e<56&&this._el.content_container.remove("tl-timeera-content-container-small");}setColor(t){this._el.container.className="tl-timeera tl-timeera-color"+t;}_initLayout(){this._el.container=v("div","tl-timeera"),this.end_date&&(this.has_end_date=!0,this._el.container.className="tl-timeera tl-timeera-with-end"),this._el.content_container=v("div","tl-timeera-content-container",this._el.container),this._el.background=v("div","tl-timeera-background",this._el.content_container),this._el.content=v("div","tl-timeera-content",this._el.content_container),this._el.text=v("div","tl-timeera-text",this._el.content),this._text=v("h2","tl-headline",this._el.text),this.headline&&""!=this.headline&&(this._text.innerHTML=F(this.headline)),this.onLoaded();}_initEvents(){}_updateDisplay(t,e,i){t&&(this.options.width=t),e&&(this.options.height=e);}}R(re,at,ot);class le{constructor(t,e,i){i&&this.setLanguage(i),this._el={container:{},content_container:{},major:{},minor:{}},this._text={},this._state={loaded:!1},this.data={},this.options={duration:1e3,ease:Q,width:600,height:600},this.active=!1,this.animator={},this.axis_helper={},this.minor_ticks=[],this.major_ticks=[],this._el.container="object"==typeof t?t:g(t),E(this.options,e),this._initLayout(),this._initEvents();}show(){}hide(){}addTo(t){t.appendChild(this._el.container);}removeFrom(t){t.removeChild(this._el.container);}updateDisplay(t,e){this._updateDisplay(t,e);}getLeft(){return this._el.container.style.left.slice(0,-2);}drawTicks(t,e){var i=t.getTicks();this._el.major.className="tl-timeaxis-major",this._el.minor.className="tl-timeaxis-minor",this._el.major.style.opacity=0,this._el.minor.style.opacity=0,this.major_ticks=this._createTickElements(i.major.ticks,this._el.major,t.getAxisTickDateFormat(i.major.name)),this.minor_ticks=this._createTickElements(i.minor.ticks,this._el.minor,t.getAxisTickDateFormat(i.minor.name),i.major.ticks),this.positionTicks(t,e,!0),this._el.major.className="tl-timeaxis-major tl-animate-opacity tl-timeaxis-animate-opacity",this._el.minor.className="tl-timeaxis-minor tl-animate-opacity tl-timeaxis-animate-opacity",this._el.major.style.opacity=1,this._el.minor.style.opacity=1;}_createTickElements(t,e,i,a){e.innerHTML="";var s={};if(s[new Date(-1,13,-30).getTime()]=!0,a)for(var n=0;n<a.length;n++)s[a[n].getTime()]=!0;var o=[];for(n=0;n<t.length;n++){var r=t[n];if(!(r.getTime() in s)){var l=v("div","tl-timeaxis-tick",e),h=v("span","tl-timeaxis-tick-text tl-animate-opacity",l);let t=r.getDisplayDate(this.getLanguage(),i);h.innerHTML=t,o.push({tick:l,tick_text:h,display_date:t,date:r});}}return o;}
28positionTicks(t,e,i){i?(this._el.major.className="tl-timeaxis-major",this._el.minor.className="tl-timeaxis-minor"):(this._el.major.className="tl-timeaxis-major tl-timeaxis-animate",this._el.minor.className="tl-timeaxis-minor tl-timeaxis-animate"),this._positionTickArray(this.major_ticks,t,e),this._positionTickArray(this.minor_ticks,t,e);}_positionTickArray(t,e,i){if(t[1]&&t[0]){var a=1;e.getPosition(t[1].date.getMillisecond())-e.getPosition(t[0].date.getMillisecond())<i&&(a=Math.round(i/e.getPixelsPerTick()));for(var s=1,n=0;n<t.length;n++){var o=t[n];o.tick.style.left=e.getPosition(o.date.getMillisecond())+"px",o.tick_text.innerHTML=o.display_date,a>1?s>=a?(s=1,o.tick_text.style.opacity=1,o.tick.className="tl-timeaxis-tick"):(s++,o.tick_text.style.opacity=0,o.tick.className="tl-timeaxis-tick tl-timeaxis-tick-hidden"):(o.tick_text.style.opacity=1,o.tick.className="tl-timeaxis-tick");}}}getVisibleTicks(){return {major:this._getVisibleTickArray(this.major_ticks),minor:this._getVisibleTickArray(this.minor_ticks)};}_getVisibleTickArray(t){return t.filter((({tick:t})=>function(t){const e=t.getBoundingClientRect();return e.left>=0&&e.right<=(window.innerWidth||document.documentElement.clientWidth);}(t)));}_initLayout(){this._el.content_container=v("div","tl-timeaxis-content-container",this._el.container),this._el.major=v("div","tl-timeaxis-major",this._el.content_container),this._el.minor=v("div","tl-timeaxis-minor",this._el.content_container),this.onLoaded();}_initEvents(){}_updateDisplay(t,e,i){t&&(this.options.width=t),e&&(this.options.height=e);}}R(le,at,ot,Rt);class he{constructor(t,e,i){this._el={container:{},content_container:{},content:{},headline_container:{},headline:{},date:{}},this.options={title:!1},this.data={unique_id:"",headline:"headline",text:"text"},function(t,e){t.data=L({},t.data,e),""===t.data.unique_id&&(t.data.unique_id=P(6));}(this,t),E(this.options,e),this._el.container=v("div","tl-text"),this._el.container.id=this.data.unique_id,this._initLayout(),i&&i.appendChild(this._el.container);}show(){}hide(){}addTo(t){t.appendChild(this._el.container);}removeFrom(t){t.removeChild(this._el.container);}headlineHeight(){return this._el.headline.offsetHeight+40;}addDateText(t){this._el.date.innerHTML=t;}onLoaded(){this.fire("loaded",this.data);}onAdd(){this.fire("added",this.data);}onRemove(){this.fire("removed",this.data);}_initLayout(){if(this._el.content_container=v("div","tl-text-content-container",this._el.container),this._el.headline_container=v("div","tl-text-headline-container",this._el.content_container),""!=this.data.headline){var t="tl-headline";this.options.title&&(t="tl-headline tl-headline-title"),this._el.headline=v("h2",t,this._el.headline_container),this._el.headline.innerHTML=this.data.headline;}if(this._el.date=v("h3","tl-headline-date",this._el.headline_container),""!=this.data.text){var e="";e+=(i=1==this.options.autolink?$(this.data.text):this.data.text).match(/<p>[\s\S]*?<\/p>/)?i:"<p>"+i+"</p>",this._el.content=v("div","tl-text-content",this._el.content_container),this._el.content.innerHTML=e;}var i;this.onLoaded();}}R(he,at);class de{constructor(t,e,i){i&&this.setLanguage(i),this._el={container:{},content_container:{},content:{},content_item:{},content_link:{},caption:null,credit:null,parent:{},link:null},this.player=null,this.timer=null,this.load_timer=null,this.message=null,this.media_id=null,this._state={loaded:!1,show_meta:!1,media_loaded:!1},this.data={unique_id:null,url:null,credit:null,caption:null,credit_alternate:null,caption_alternate:null,link:null,link_target:null},this.options={api_key_flickr:"bd3a7c45ddd52f3101825d41563a6125",api_key_googlemaps:"AIzaSyB9dW8e_iRrATFa8g24qB6BDBGdkrLDZYI",api_key_embedly:"",credit_height:0,caption_height:0,background:0},this.animator={},E(this.options,e),E(this.data,t),this.options.background||(this._el.container=v("div","tl-media"),this.data.unique_id&&(this._el.container.id=this.data.unique_id),this._initLayout());}loadMedia(){var t=this;if(!this._state.loaded)try{this.load_timer=setTimeout((function(){t.loadingMessage(),t._loadMedia(),t._updateDisplay();}),1200);}catch(t){S("Error loading media for ",this._media),S(t);}}_updateMessage(t){this.message&&this.message.updateMessage(t);}loadingMessage(){this._updateMessage(this._("loading")+" "+this.options.media_name);}errorMessage(t){t=t?this._("error")+": "+t:this._("error"),this._updateMessage(t);}updateMediaDisplay(t){this._state.loaded&&!this.options.background&&(this._el.content_item.style.maxHeight=h?this.options.height/2+"px":this.options.height-this.options.credit_height-this.options.caption_height-30+"px",this._el.container.style.maxWidth=this.options.width+"px",m&&(this._el.content_item.offsetWidth,this._el.content_item.offsetHeight),this._updateMediaDisplay(t),this._state.media_loaded&&(this._el.credit&&(this._el.credit.style.width=this._el.content_item.offsetWidth+"px"),this._el.caption&&(this._el.caption.style.width=this._el.content_item.offsetWidth+"px")));}_loadMedia(){this.onLoaded();}_updateMediaDisplay(t){m&&(this._el.content_item.style.maxWidth=this.options.width+"px",this._el.content_item.style.width="auto");}_getMeta(){}_getImageURL(t,e){return "";}show(){}hide(){}addTo(t){t.appendChild(this._el.container),this.onAdd();}removeFrom(t){t.removeChild(this._el.container),this.onRemove();}getImageURL(t,e){return this._getImageURL(t,e);}updateDisplay(t,e,i){this._updateDisplay(t,e,i);}stopMedia(){try{this._stopMedia();}catch(t){S(`stopMedia() exception: ${t}`);}}loadErrorDisplay(t){try{this._el.content.removeChild(this._el.content_item);}catch(t){}this._el.content_item=v("div","tl-media-item tl-media-loaderror",this._el.content),this._el.content_item.innerHTML="<div class='tl-icon-"+this.options.media_type+"'></div><p>"+t+"</p>",this.onLoaded(!0);}onLoaded(t){this._state.loaded=!0,this.fire("loaded",this.data),this.message&&this.message.hide(),t||this.options.background||this.showMeta(),this.updateDisplay();}onMediaLoaded(t){this._state.media_loaded=!0,this.fire("media_loaded",this.data),this._el.credit&&(this._el.credit.style.width=this._el.content_item.offsetWidth+"px"),this._el.caption&&(this._el.caption.style.width=this._el.content_item.offsetWidth+"px");}showMeta(t,e){this._state.show_meta=!0,this.data.credit&&""!=this.data.credit&&(this._el.credit=v("div","tl-credit",this._el.content_container),this._el.credit.innerHTML=1==this.options.autolink?$(this.data.credit):this.data.credit,this.options.credit_height=this._el.credit.offsetHeight),this.data.caption&&""!=this.data.caption&&(this._el.caption=v("div","tl-caption",this._el.content_container),this._el.caption.innerHTML=1==this.options.autolink?$(this.data.caption):this.data.caption,this.options.caption_height=this._el.caption.offsetHeight),this.data.caption&&this.data.credit||this.getMeta();}getMeta(){this._getMeta();}updateMeta(){!this.data.credit&&this.data.credit_alternate&&(this._el.credit=v("div","tl-credit",this._el.content_container),this._el.credit.innerHTML=this.data.credit_alternate,this.options.credit_height=this._el.credit.offsetHeight),!this.data.caption&&this.data.caption_alternate&&(this._el.caption=v("div","tl-caption",this._el.content_container),this._el.caption.innerHTML=this.data.caption_alternate,this.options.caption_height=this._el.caption.offsetHeight),this.updateDisplay();}onAdd(){this.fire("added",this.data);}onRemove(){this.fire("removed",this.data);}_initLayout(){this.message=new jt(this._el.container,this.options,this.getLanguage()),this._el.content_container=v("div","tl-media-content-container",this._el.container),this.data.link&&""!=this.data.link?(this._el.link=v("a","tl-media-link",this._el.content_container),this._el.link.href=this.data.link,this.data.link_target&&""!=this.data.link_target?this._el.link.target=this.data.link_target:this._el.link.target="_blank","_blank"==this._el.link.target&&this._el.link.setAttribute("rel","noopener"),this._el.content=v("div","tl-media-content",this._el.link)):this._el.content=v("div","tl-media-content",this._el.content_container);}_updateDisplay(t,e,i){t&&(this.options.width=t),e&&(this.options.height=e),i&&(this.options.layout=i),this._el.credit&&(this.options.credit_height=this._el.credit.offsetHeight),this._el.caption&&(this.options.caption_height=this._el.caption.offsetHeight+5),this.updateMediaDisplay(this.options.layout);}domCreate(...t){return v(...t);}_stopMedia(){}}R(de,at,Rt);class ce extends de{_loadMedia(){this.loadingMessage(),this.options.background||this.createMedia(),this.onLoaded();}createMedia(){var t=this,e="tl-media-item tl-media-image tl-media-sha
28dow";(this.data.url.match(/.png(\?.*)?$/)||this.data.url.match(/.svg(\?.*)?$/))&&(e="tl-media-item tl-media-image"),this._el.content_item=this.domCreate("img",e,this._el.content),this.data.alt?this._el.content_item.alt=this.data.alt:this.data.caption&&(this._el.content_item.alt=q(this.data.caption)),this.data.title?this._el.content_item.title=this.data.title:this.data.caption&&(this._el.content_item.title=q(this.data.caption)),this._el.content_item.addEventListener("load",(function(e){t.onMediaLoaded();})),this._el.content_item.src=this.getImageURL();}getImageURL(t,e){return U(this.data.url);}_updateMediaDisplay(t){m&&(this._el.content_item.style.width="auto");}}function ue(t,e,i,a){_e.js(t,e,i,a);}function me(t,e,i,a){_e.css(t,e,i,a);}let _e=new class{constructor(t){this.doc=t,this.pending={},this.queue={css:[],js:[]},this.styleSheets=t.styleSheets,this.env=this.getEnv(),this.head=this.doc.head||this.doc.getElementsByTagName("head")[0],this.pollCount=0;}createNode(t,e){var i,a=this.doc.createElement(t);for(i in e)e.hasOwnProperty(i)&&a.setAttribute(i,e[i]);return a;}finish(t){var e,i,a=this.pending[t];a&&(e=a.callback,(i=a.urls).shift(),this.pollCount=0,i.length||(e&&e.call(a.context,a.obj),this.pending[t]=null,this.queue[t].length&&this.load(t)));}getEnv(){var t=navigator.userAgent,e={async:!0===this.doc.createElement("script").async};return (e.webkit=/AppleWebKit\//.test(t))||(e.ie=/MSIE/.test(t))||(e.opera=/Opera/.test(t))||(e.gecko=/Gecko\//.test(t))||(e.unknown=!0),e;}load(t,e,i,a,s){var n,o,r,l,h,d,c=function(){this.finish(t);}.bind(this),u="css"===t,m=[];if(e)if(e="string"==typeof e?[e]:e.concat(),u||this.env.async||this.env.gecko||this.env.opera)this.queue[t].push({urls:e,callback:i,obj:a,context:s});else for(n=0,o=e.length;n<o;++n)this.queue[t].push({urls:[e[n]],callback:n===o-1?i:null,obj:a,context:s});if(!this.pending[t]&&(l=this.pending[t]=this.queue[t].shift())){for(n=0,o=(h=l.urls).length;n<o;++n)d=h[n],u?r=this.env.gecko?this.createNode("style"):this.createNode("link",{href:d,rel:"stylesheet"}):(r=this.createNode("script",{src:d})).async=!1,r.className="lazyload",r.setAttribute("charset","utf-8"),this.env.ie&&!u?r.onreadystatechange=function(){/loaded|complete/.test(r.readyState)&&(r.onreadystatechange=null,c());}:u&&(this.env.gecko||this.env.webkit)?this.env.webkit?(l.urls[n]=r.href,this.pollWebKit()):(r.innerHTML='@import "'+d+'";',this.pollGecko(r)):r.onload=r.onerror=c,m.push(r);for(n=0,o=m.length;n<o;++n)this.head.appendChild(m[n]);}}pollGecko(t){var e;try{e=!!t.sheet.cssRules;}catch(a){if(this.pollCount+=1,this.pollCount<200){var i=this;setTimeout((function(){i.pollGecko(t);}),50);}else e&&this.finish("css");return;}this.finish("css");}pollWebKit(){var t,e=this.pending.css;if(e){for(t=this.styleSheets.length;--t>=0;)if(this.styleSheets[t].href===e.urls[0]){this.finish("css");break;}this.pollCount+=1,e&&(this.pollCount<200?setTimeout(this.pollWebKit.bind(this),50):this.finish("css"));}}css(t,e,i,a){this.load("css",t,e,i,a);}js(t,e,i,a){this.load("js",t,e,i,a);}}(document);class pe extends de{_loadMedia(){var t,e=this;this.youtube_loaded=!1,this._el.content_item=this.domCreate("div","tl-media-item tl-media-youtube tl-media-shadow",this._el.content),this._el.content_item.id=P(7),t=function(t){var e,i,a,s=[];(e=t.toString()).match("&")?e=e.replace("&","&"):e.match("&")?e=e.replace("&","&"):e.match("&")&&(e=e.replace("&","&")),a=e.slice(e.indexOf("?")+1).split("&");for(var n=0;n<a.length;n++)i=a[n].split("="),s.push(i[0]),s[i[0]]=i[1];return s;}(this.data.url),this.media_id={},this.data.url.match("v=")?this.media_id.id=t.v:this.data.url.match("/embed/")?this.media_id.id=this.data.url.split("embed/")[1].split(/[?&]/)[0]:this.data.url.match(/v\/|v=|youtu\.be\//)?this.media_id.id=this.data.url.split(/v\/|v=|youtu\.be\//)[1].split(/[?&]/)[0]:S("YOUTUBE IN URL BUT NOT A VALID VIDEO"),this.data.url.match("start=")?this.media_id.start=V(this.data.url.split("start=")[1]):this.data.url.match("t=")&&(this.media_id.start=V(this.data.url.split("t=")[1])),this.data.url.match("end=")&&(this.media_id.end=V(this.data.url.split("end=")[1])),this.media_id.hd=Boolean(void 0!==t.hd),ue("https://www.youtube.com/iframe_api",(function(){e.createMedia();}));}_updateMediaDisplay(){this._el.content_item.style.height=W({w:this.options.width})+"px",this._el.content_item.style.width=this.options.width+"px";}_stopMedia(){if(this.youtube_loaded)try{this.player.getPlayerState()==YT.PlayerState.PLAYING&&this.player.pauseVideo();}catch(t){S(t);}}createMedia(){var t=this;clearTimeout(this.timer),"undefined"!=typeof YT&&void 0!==YT.Player?this.player=new YT.Player(this._el.content_item.id,{playerVars:{enablejsapi:1,
28color:"white",controls:1,start:this.media_id.start,end:this.media_id.end,fs:1},videoId:this.media_id.id,events:{onReady:function(){t.onPlayerReady(),t.onLoaded();},onStateChange:t.onStateChange}}):this.timer=setTimeout((function(){t.createMedia();}),1e3);}onPlayerReady(t){this.youtube_loaded=!0,this._el.content_item=document.getElementById(this._el.content_item.id),this.onMediaLoaded();}onStateChange(t){t.data==YT.PlayerState.ENDED&&(t.target.seekTo(0),t.target.pauseVideo());}}class fe extends de{_loadMedia(){this._el.content_item=this.domCreate("div","tl-media-item tl-media-map tl-media-shadow",this._el.content),this.media_id=this.data.url,this.mapframe=this.domCreate("iframe","",this._el.content_item),this.mapframe.width="100%",this.mapframe.height="100%",this.mapframe.frameBorder="0",this.mapframe.src=this.makeGoogleMapsEmbedURL(this.media_id,this.options.api_key_googlemaps),this.onLoaded();}_updateMediaDisplay(){if(this._state.loaded){var t=B({w:this._el.content_item.offsetWidth});this._el.content_item.style.height=t.h+"px";}}makeGoogleMapsEmbedURL(t,e){var i=!1,a={view:["center"],place:["q","center"],directions:["origin","destination","center"],search:["q","center"],streetview:["fov","heading","pitch"]},s=/(https:\/\/.+google.+?\/maps)/,n=/@([-\d.]+),([-\d.]+)/,o=/([\w\W]+)/,r=/,((?:[-\d.]+[zmayht],?)*)/,l={view:new RegExp(s.source+"/"+n.source+r.source),place:new RegExp(s.source+"/place/"+o.source+"/"+n.source+r.source),directions:new RegExp(s.source+"/dir/"+o.source+"/"+o.source+"/"+n.source+r.source),search:new RegExp(s.source+"/search/"+o.source+"/"+n.source+r.source)};return function(t){function s(e,s){if("z"==e.slice(-1))s.zoom=e;else if("m"==e.slice(-1))s.zoom=14,s.maptype="satellite";else{if("t"==e.slice(-1)){if(i=!0,"place"==n)var o=t.match(l.place)[3]+","+t.match(l.place)[4];else o=s.center,delete s.center;(s={}).location=o,streetview_params=e.split(",");for(let t in a.streetview){var r=parseInt(t)+1;"pitch"==a.streetview[t]&&"90t"==streetview_params[r]?s[a.streetview[t]]=0:s[a.streetview[t]]=streetview_params[r].slice(0,-1);}}}return s;}let n="view";return t.match(l.place)?n="place":t.match(l.directions)?n="directions":t.match(l.search)&&(n="search"),function(t,n){var o={},r=n[1],l=n[n.length-1];for(let e in a[t]){var h=parseInt(e)+2;"center"==a[t][e]?o[a[t][e]]=n[h]+","+n[++h]:o[a[t][e]]=n[h];}return (o=s(l,o)).key=e,1==i&&(t="streetview"),r+"/embed/v1/"+t+function(t){var e=[];for(var i in t)t.hasOwnProperty(i)&&e.push(i+"="+t[i]);return "?"+e.join("&");}(o);}(n,t.match(l[n]));}(t);}}class ge extends de{constructor(t,e,i){super(t,e,i),this.blockquote=Ut().sanitize(this.data.url);}_loadMedia(){this._el.content_item=this.domCreate("div","tl-media-item tl-media-blockquote",this._el.content),this._el.content_container.className="tl-media-content-container tl-media-content-container-text",this._el.content_item.innerHTML=this.blockquote,this.onLoaded();}updateMediaDisplay(){}}class ve extends de{_loadMedia(){var t,e=this;this._el.content_item=this.domCreate("div","tl-media-item tl-media-wikipedia",this._el.content),this._el.content_container.className="tl-media-content-container tl-media-content-container-text",this.media_id=this.data.url.split("wiki/")[1].split("#")[0].replace("_"," "),this.media_id=this.media_id.replace(" ","%20"),t="https://"+this.data.url.split("//")[1].split(".wikipedia")[0]+".wikipedia.org/w/api.php?action=query&prop=extracts|pageimages&redirects=&titles="+this.media_id+"&exintro=1&format=json&callback=?",ut({type:"GET",url:t,dataType:"json",success:function(t){e.createMedia(t);},error:function(t,i){var a="";a+=e._("wikipedia_load_err")+"<br/>"+e.media_id+"<br/>"+i,e.loadErrorDisplay(a);}});}createMedia(t){var e="";if(t.query){var i="";(e={entry:{},title:"",text:"",extract:"",paragraphs:1,page_image:"",text_array:[]}).entry=function(t){if(void 0!==t){var e=0;for(var i in t){if(0===e)return t[i];e++;}return "";}return "";}(t.query.pages),e.extract=e.entry.extract,e.title=e.entry.title,e.page_image=e.entry.thumbnail,e.extract.match("<p>")?e.text_array=e.extract.split("<p>"):e.text_array.push(e.extract);for(var a=0;a<e.text_array.length;a++)a+1<=e.paragraphs&&a+1<e.text_array.length&&(e.text+="<p>"+e.text_array[a+1]);
28i+="<span class='tl-icon-wikipedia'></span>",i+="<div class='tl-wikipedia-title'><h4><a href='"+this.data.url+"' target='_blank' rel='noopener'>"+e.title+"</a></h4>",i+="<span class='tl-wikipedia-source'>"+this._("wikipedia")+"</span></div>",e.page_image,i+=e.text,e.extract.match("REDIRECT")||(this._el.content_item.innerHTML=i,this.onLoaded());}}updateMediaDisplay(){}}class ye extends de{_loadMedia(){var t,e=Math.round(this.options.width)||1e3,i=this.getLanguage().lang.toLowerCase(),a=this;try{this.establishMediaID(),t=`https://commons.wikimedia.org/w/api.php?action=query&titles=${this.media_id}&prop=imageinfo|entityterms&iiprop=url&&iiurlwidth=${e}&format=json&origin=*&wbetlanguage=${i}`,ct(t,(function(t){let e=function(t){let e={};if(t.query&&t.query.pages){let i=Object.keys(t.query.pages);e.page_id=i[0];let a=t.query.pages[e.page_id];e.url=a.imageinfo[0].thumburl,a.entityterms&&a.entityterms.label&&(e.label=a.entityterms.label[0]);}return e;}(t);e.url?(a.base_image_url=e.url,a.page_id=e.page_id,!a.data.alt&&e.label&&(a.data.alt=e.label),a.options.background||a.createMedia(),a.onLoaded()):a.loadErrorDisplay(a._("wikipedia_image_load_err"));}));}catch(t){a.loadErrorDisplay(a._(t.message_key));}}establishMediaID(){let t=function(t){if(t.match(/^.+#\/media\/.+/))return `File:${t.split("#")[1].split(":")[1]}`;if(t.match(/^.*commons.wikimedia.org\/wiki\/File:.+/)){let e=t.split("/");return e[e.length-1];}return null;}(this.data.url);if(!t)throw new x("Invalid Wikipedia Image URL");this.media_id=t;}createMedia(){var t=this;if(this._el.content_item=this.domCreate("img","tl-media-item tl-media-image tl-media-wikipedia-image tl-media-shadow",this._el.content),this.data.alt)this._el.content_item.alt=this.data.alt;else{if(this.page_id){let e=`M${this.page_id}`;mt(`https://commons.wikimedia.org/w/api.php?action=wbgetentities&format=json&ids=${e}&format=json&origin=*`).then(((i)=>{if(i.entities&&i.entities[e]){let a=i.entities[e].labels,s=t.getLanguage().lang.toLowerCase(),n=null;a[s]?n=a[s]:s.length>2&&a[s.substr(0,2)]?n=a[s.substr(0,2)]:a.en&&(n=a.en),n?(console.log(`wikibase_id: ${t.media_id} alt ${n.value}`),t.data.alt=n.value,t._el.content_item.alt=t.data.alt):console.log(`wikibase_id: ${t.media_id} ain't got no alt`);}}));}}this.data.title&&(this._el.content_item.title=this.data.title),this._el.content_item.addEventListener("load",(function(e){t.onMediaLoaded();})),this._el.content_item.src=this.getImageURL(this.options.width,this.options.height);}_getImageURL(t,e){if(t&&this.base_image_url){let e=this.base_image_url.match(/(\/[\d\.]+px-)/);if(e)return t=Math.round(t),this.base_image_url.replace(e[1],`/${t}px-`);}return this.base_image_url;}}class be extends de{_loadMedia(){var t,e=this;this._el.content_item=this.domCreate("div","tl-media-item tl-media-iframe tl-media-soundcloud tl-media-shadow",this._el.content),this.media_id=this.data.url,t="https://soundcloud.com/oembed?url="+this.media_id+"&format=js&callback=?",ct(t,(function(t){ue("https://w.soundcloud.com/player/api.js",(function(){e.createMedia(t);}));}));}createMedia(t){this._el.content_item.innerHTML=t.html,self.widget=SC.Widget(this._el.content_item.querySelector("iframe")),this.soundCloudCreated=!0,this.onLoaded();}_stopMedia(){this.soundCloudCreated&&self.widget.pause();}}class we extends de{_loadMedia(){var t,e=this;this._el.content_item=this.domCreate("div","tl-media-item tl-media-iframe tl-media-vimeo tl-media-shadow",this._el.content),this.media_id=this.data.url.split(/video\/|\/\/vimeo\.com\//)[1].split(/[?&]/)[0];var i=null;this.data.url.match(/#t=([^&]+).*/)&&(i=this.data.url.match(/#t=([^&]+).*/)[1]),t="https://player.vimeo.com/video/"+this.media_id+"?api=1&title=0&byline=0&portrait=0&color=ffffff",i&&(t=t+="&#t="+i),this.player=this.domCreate("iframe","",this._el.content_item),this.player.addEventListener("load",(function(t){e.onMediaLoaded();})),this.player.width="100%",this.player.height="100%",this.player.frameBorder="0",this.player.src=t,this.player.setAttribute("allowfullscreen",""),this.player.setAttribute("webkitallowfullscreen",""),this.player.setAttribute("mozallowfullscreen",""),this.onLoaded();}_updateMediaDisplay(){this._el.content_item.style.height=W({w:this._el.content_item.offsetWidth})+"px";}_stopMedia(){try{this.player&&this.player.contentWindow&&this.player.contentWindow.postMessage(JSON.stringify({method:"pause"}),"https://player.vimeo.com");}catch(t){S(t);}}}class ke extends de{_loadMedia(){var t;this._el.content_item=this.domCreate("div","tl-media-item tl-media-iframe tl-media-dailymotion",this._el.content),-1!=this.data.url.indexOf("dai.ly/")?this.media_id=this.data.url.substr(this.data.url.indexOf("dai.ly/")+7):this.data.url.match("video")?this.media_id=this.data.url.split("video/")[1].split(/[?&]/)[0]:this.media_id=this.data.url.split("embed/")[1].split(/[?&]/)[0],-1!=this.media_id.indexOf("_")&&(this.media_id=this.media_id.split("_")[0]),t="https://www.dailymotion.com/embed/video/"+this.media_id+"?api=postMessage",this._el.content_item.innerHTML="<iframe autostart='false' frameborder='0' width='100%' height='100%' src='"+t+"'></iframe>",this.onLoaded();}_updateMediaDisplay(){this._state.loaded&&(this._el.content_item.style.height=W({w:this._el.content_item.offsetWidth})+"px");}_stopMedia(){this._state.loaded&&this._el.content_item.querySelector("iframe").contentWindow.postMessage('{"command":"pause","parameters":[]}',"*");}}class xe extends de{_loadMedia(){var t;this._el.content_item=this.domCreate("div","tl-media-item tl-media-iframe tl-media-vine tl-media-sha
28dow",this._el.content),this.media_id=this.data.url.split("vine.co/v/")[1],t="https://vine.co/v/"+this.media_id+"/embed/simple",this._el.content_item.innerHTML="<iframe frameborder='0' width='100%' height='100%' src='"+t+"'></iframe><script async src='https://platform.vine.co/static/scripts/embed.js' charset='utf-8'><\/script>",this.onLoaded();}_updateMediaDisplay(){var t=B({w:this._el.content_item.offsetWidth,h:this.options.height});this._el.content_item.style.height=t.h+"px";}_stopMedia(){this._el.content_item.querySelector("iframe").contentWindow.postMessage("pause","*");}}class Te extends de{_loadMedia(){var t,e=this;if(this._el.content_item=this.domCreate("div","tl-media-twitter",this._el.content),this._el.content_container.className="tl-media-content-container tl-media-content-container-text",this.data.url.match("^(https?:)?/*(www.)?(twitter|x).com"))this.data.url.match("status/")?this.media_id=this.data.url.split("status/")[1]:this.data.url.match("statuses/")?this.media_id=this.data.url.split("statuses/")[1]:this.media_id="";else{if(this.data.url.match("<blockquote class=['\"]twitter-tweet['\"]")){var i=this.data.url.match(/(status|statuses)\/(\d+)/);if(!(i&&i.length>2))return void e.loadErrorDisplay(e._("twitterembed_invalidurl_err"));this.media_id=i[2];}}t="https://api.twitter.com/1/statuses/oembed.json?id="+this.media_id+"&omit_script=true&include_entities=true&callback=?",ut({type:"GET",url:t,dataType:"json",success:function(t){e.createMedia(t);},error:function(t,i){var a="";a+=e._("twitter_load_err")+"<br/>"+e.media_id+"<br/>"+i,e.loadErrorDisplay(a);}});}createMedia(t){var e,i,a,s="",n="",o="",r=this;n=t.html.split("</p>—")[0]+"</p></blockquote>",e=t.author_url.split("twitter.com/")[1],i=(o=t.html.split("</p>—")[1].split('<a href="')[1]).split('">')[0],a=o.split('">')[1].split("</a>")[0],(n=n.replace(/<a href/gi,'<a target="_blank" rel="noopener" href')).includes("pic.twitter.com")||n.includes("pic.x.com")?(ue("https://platform.twitter.com/widgets.js",(function(){twttr.widgets.createTweet(r.media_id,r._el.content_item,{conversation:"none",linkColor:"#cc0000",theme:"light"});})),this.onLoaded()):(s+=n,s+="<div class='vcard'>",s+="<a href='"+i+"' class='twitter-date' rel='noopener' target='_blank'>"+a+"</a>",s+="<img src='' class='tl-media-item tl-media-image'></a>",s+="<div class='author'>",s+="<a class='screen-name url' href='"+t.author_url+"' rel='noopener' target='_blank'>",s+="<span class='avatar'></span>",s+="<span class='fn'>"+t.author_name+" <span class='tl-icon-twitter'></span></span>",s+="<span class='nickname'>@"+e+"<span class='thumbnail-inline'></span></span>",s+="</a>",s+="</div>",s+="</div>",this._el.content_item.innerHTML=s,this.onLoaded());}updateMediaDisplay(){}_updateMediaDisplay(){}}class Me extends de{_loadMedia(){var t,e=this;this._el.content_item=this.domCreate("div","tl-media-twitter",this._el.content),this._el.content_container.className="tl-media-content-container tl-media-content-container-text";var i,a,s,n,o,r,l=this.data.url.match(/(status|statuses)\/(\d+)/);l&&l.length>2?(this.media_id=l[2],t="https://api.twitter.com/1/statuses/oembed.json?id="+this.media_id+"&omit_script=true&include_entities=true&callback=?",window.twttr=(a="script",s="twitter-wjs",o=(i=document).getElementsByTagName(a)[0],r=window.twttr||{},i.getElementById(s)||((n=i.createElement(a)).id=s,n.src="https://platform.twitter.com/widgets.js",o.parentNode.insertBefore(n,o),r._e=[],r.ready=function(t){r._e.push(t);}),r),ut({type:"GET",url:t,dataType:"json",success(t){e.createMedia(t);},error:function(t,i){var a="";a+=e._("twitter_load_err")+"<br/>"+e.media_id+"<br/>"+i,e.loadErrorDisplay(a);}})):e.loadErrorDisplay(e._("twitterembed_invalidurl_err"));}createMedia(t){var e,i,a,s="",n="",o="";n=t.html.split("</p>—")[0]+"</p></blockquote>",e=t.author_url.split("twitter.com/")[1],i=(o=t.html.split("</p>—")[1].split('<a href="')[1]).split('">')[0],a=o.split('">')[1].split("</a>")[0],n=n.replace(/<a href/gi,'<a target="_blank" rel="noopener" href');let r=this.media_id;n.includes("pic.twitter.com")?(twttr.ready((function(t){s=document.getElementsByClassName("tl-media-twitter")[0];var e=String(r);
28twttr.widgets.createTweet(e,s,{conversation:"none",linkColor:"#cc0000",theme:"light"}).then((function(t){this.onLoaded();}));})),this._el.content_item.innerHTML=s,this.onLoaded()):(s+=n,s+="<div class='vcard'>",s+="<a href='"+i+"' class='twitter-date' rel='noopener' target='_blank'>"+a+"</a>",s+="<div class='author'>",s+="<a class='screen-name url' href='"+t.author_url+"' rel='noopener' target='_blank'>",s+="<span class='avatar'></span>",s+="<span class='fn'>"+t.author_name+" <span class='tl-icon-twitter'></span></span>",s+="<span class='nickname'>@"+e+"<span class='thumbnail-inline'></span></span>",s+="</a>",s+="</div>",s+="</div>",this._el.content_item.innerHTML=s,this.onLoaded());}updateMediaDisplay(){}_updateMediaDisplay(){}}class Ee extends de{_loadMedia(){var t,e=this;try{this.establishMediaID(),t="https://api.flickr.com/services/rest/?method=flickr.photos.getSizes&api_key="+this.options.api_key_flickr+"&photo_id="+this.media_id+"&format=json&jsoncallback=?",ct(t,(function(t){"ok"==t.stat?(e.sizes=t.sizes.size,e.options.background||e.createMedia(),e.onLoaded()):e.loadErrorDisplay(e._("flickr_notfound_err"));}));}catch(t){e.loadErrorDisplay(e._(t.message_key));}}establishMediaID(){if(this.data.url.match(/flic.kr\/.+/i)){var t=this.data.url.split("/").slice(-1)[0];this.media_id=G.decode(t);}else{var e=this.data.url.indexOf("flickr.com/photos/");if(-1==e)throw new x("flickr_invalidurl_err");var i=e+18;this.media_id=this.data.url.substr(i).split("/")[1];}}createMedia(){var t=this;this._el.content_link=this.domCreate("a","",this._el.content),this._el.content_link.href=this.data.url,this._el.content_link.target="_blank",this._el.content_link.setAttribute("rel","noopener"),this._el.content_item=this.domCreate("img","tl-media-item tl-media-image tl-media-flickr tl-media-shadow",this._el.content_link),this.data.alt?this._el.content_item.alt=this.data.alt:this.data.caption&&(this._el.content_item.alt=q(this.data.caption)),this.data.title?this._el.content_item.title=this.data.title:this.data.caption&&(this._el.content_item.title=q(this.data.caption)),this._el.content_item.addEventListener("load",(function(e){t.onMediaLoaded();})),this._el.content_item.src=this.getImageURL(this.options.width,this.options.height);}getImageURL(t,e){for(var i=this.size_label(e),a=this.sizes[this.sizes.length-2].source,s=0;s<this.sizes.length;s++)this.sizes[s].label==i&&(a=this.sizes[s].source);return a;}_getMeta(){var t,e=this;t="https://api.flickr.com/services/rest/?method=flickr.photos.getInfo&api_key="+this.options.api_key_flickr+"&photo_id="+this.media_id+"&format=json&jsoncallback=?",ct(t,(function(t){e.data.credit_alternate="<a href='"+e.data.url+"' target='_blank' rel='noopener'>"+t.photo.owner.realname+"</a>",e.data.caption_alternate=t.photo.title._content+" "+t.photo.description._content,e.updateMeta();}));}size_label(t){return t<=75?t<=0?"Large":"Thumbnail":t<=180?"Small":t<=240?"Small 320":t<=375?"Medium":t<=480?"Medium 640":"Large";}}class Le extends de{_loadMedia(){var t=this;this._el.content_item=this.domCreate("div","tl-media-item tl-media-documentcloud tl-media-shadow",this._el.content),this._el.content_item.id=P(7),this.data.url.match(/\.html$/)?this.data.url=this._transformURL(this.data.url):this.data.url.match(/.(json|js)$/)||S("DOCUMENT CLOUD IN URL BUT INVALID SUFFIX"),ue(["https://assets.documentcloud.org/viewer/loader.js","https://assets.documentcloud.org/viewer/viewer.js"],(function(){t.createMedia();}));}_transformURL(t){return t.replace(/(.*)\.html$/,"$1.js");}_updateMediaDisplay(){this._el.content_item.style.height=this.options.height+"px";}createMedia(){DV.load(this.data.url,{container:"#"+this._el.content_item.id,showSidebar:!1}),this.onLoaded();}}const De="https://graph.facebook.com/v8.0/instagram_oembed?access_token=704270473831239|830b21071290df4f81a35c56abbea096&fields=html,thumbnail_url,author_name&url=";function Se(t){this.oembed_response=t,this._el.content_link=this.domCreate("a","",this._el.content),this._el.content_link.href=this.data.url,this._el.content_link.target="_blank",this._el.content_link.setAttribute("rel","noopener"),this._el.content_item=this.domCreate("img","tl-media-item tl-media-image tl-media-instagram tl-media-sha
28dow",this._el.content_link),this.data.alt?this._el.content_item.alt=this.data.alt:this.data.caption&&(this._el.content_item.alt=q(this.data.caption)),this.data.title?this._el.content_item.title=this.data.title:this.data.caption&&(this._el.content_item.title=q(this.data.caption)),this._el.content_item.addEventListener("load",function(t){this.onMediaLoaded();}.bind(this)),this._el.content_item.src=t.thumbnail_url,this.onLoaded();}function Ne(t){let e=`${t.statusText} [${t.status}]`;400==t.status&&(e=this._("instagram_bad_request")),this.loadErrorDisplay(e);}class Ae extends de{_loadMedia(){this.media_id=this.data.url.split("/p/")[1].split("/")[0],this.options.background||this.createMedia();}createMedia(){this.oembed_response=null;let t=`${De}${this.data.url}`;try{ut({url:t,dataType:"json",success:Se,error:Ne,context:this});}catch(e){console.log(`Instagram: error fetching ${t}`),console.log(e);}}getImageURL(){if(this.oembed_response&&this.oembed_response.thumbnail_url)return this.oembed_response.thumbnail_url;mt(`${De}${this.data.url}`).then(((t)=>t.thumbnail_url)).catch(((t)=>{S(`Instagram getImageURL Error: ${t.status} ${t.statusText}`);}));}_getMeta(){this.oembed_response&&this.oembed_response.author_name&&(this.data.credit_alternate=`Instagram: <a href="https://instagram.com/${this.oembed_response.author_name}" target="_blank">@${this.oembed_response.author_name}</a>`),this.updateMeta();}sizes(t){return t<=150?"t":t<=306?"m":"l";}}class Ce extends de{_loadMedia(){this._el.content_item=this.domCreate("img","tl-media-item tl-media-image tl-media-profile tl-media-shadow",this._el.content),this._el.content_item.src=this.data.url,this.onLoaded();}_updateMediaDisplay(t){m&&(this._el.content_item.style.maxWidth=this.options.width/2-40+"px");}}class Ie extends de{_loadMedia(){var t;this._el.content_item=this.domCreate("div","tl-media-item tl-media-iframe",this._el.content),t=this.data.url.match(/open\?id=([^&]+)/)?"https://drive.google.com/file/d/"+this.data.url.match(/open\?id=([^&]+)/)[1]+"/preview":this.data.url.match(/file\/d\/([^/]*)\/?/)?"https://drive.google.com/file/d/"+this.data.url.match(/file\/d\/([^/]*)\/?/)[1]+"/preview":this.data.url,this._el.content_item.innerHTML="<iframe class='doc' frameborder='0' width='100%' height='100%' src='"+t+"'></iframe>",this.onLoaded();}_updateMediaDisplay(){this._el.content_item.style.height=this.options.height+"px";}}class Oe extends de{_loadMedia(){var t,e;this._el.content_item=this.domCreate("div","tl-media-item tl-media-iframe tl-media-spotify",this._el.content),this.media_id=(e=this.data.url).match(/^spotify:/)?e:`spotify${(e=new URL(e)).pathname.replace(/\/$/,"").replace(/\//g,":")}`,this.media_id?(t="https://embed.spotify.com/?uri="+this.media_id+"&theme=white&view=coverart",this.player=this.domCreate("iframe","tl-media-shadow",this._el.content_item),this.player.width="100%",this.player.height="100%",this.player.frameBorder="0",this.player.src=t,this.onLoaded()):this.loadErrorDisplay(this._("spotify_invalid_url"));}_updateMediaDisplay(t){var e=this.options.height,i=0,a=0;e=h?this.options.height/2:this.options.height-this.options.credit_height-this.options.caption_height-30,this._el.content_item.style.maxHeight="none",S(e),S(this.options.width),e>this.options.width?(S("height is greater"),i=this.options.width+80+"px",a=this.options.width+"px"):(S("width is greater"),S(this.options.width),i=e+"px",a=e-80+"px"),this.player.style.width=a,this.player.style.height=i,this._el.credit&&(this._el.credit.style.width=a),this._el.caption&&(this._el.caption.style.width=a);}_stopMedia(){}}class Re extends de{constructor(t,e,i){super(t,e,i),this.iframe=Ut().sanitize(this.data.url,{ADD_TAGS:["iframe"],ADD_ATTR:["frameborder"]});}_loadMedia(){this._el.content_item=this.domCreate("div","tl-media-item tl-media-iframe",this._el.content),this._el.content_item.innerHTML=this.iframe,this.onLoaded();}_updateMediaDisplay(){this._el.content_item.style.height=this.options.height+"px";}}class je extends de{_loadMedia(){try{var t=this;if(this.data.url.match("<blockquote class=['\"]imgur-embed-pub['\"]")){var e=this.data.url.match(/(imgur\.com)\/(\w+)/);this.media_id=e[2],this.data.url="http://imgur.com/gallery/"+this.media_id;}else this.data.url&&(this.media_id=this.data.url.split("/").slice(-1)[0]);ue(["https://s.imgur.com/min/embed.js"],(function(){t.createMedia();}));}catch(t){this.loadErrorDisplay(this._("imgur_invalidurl_err"));}}createMedia(){var t=this,e="https://api.imgur.com/oembed.json?url="+this.data.url;this._el.content_item=this.domCreate("div","tl-media-item tl-media-image tl-media-imgur",this._el.content),ut({type:"GET",url:e,dataType:"json",success:function(e){try{t._el.content_item.innerHTML=e.html,setInterval((function(){null==document.querySelector("blockquote.imgur-embed-pub")?clearInterval():(imgurEmbed.createIframe(),document.getElementById("imageElement").removeAttribute("style"),document.getElementById("image").removeAttribute("style"));}),2e3);}
28catch(t){S("Error processing imgur ajax response");}},error:function(e,i,a){"parsererror"==i?t.loadErrorDisplay(t._("imgur_invalidurl_err")):t.loadErrorDisplay(t._("unknown_read_err",i));}}),this.onLoaded();}_updateMediaDisplay(){this._el.content_item.style.width=this.options.width+"px",this._el.content_item.style.height=W({w:this.options.width})+"px";}}class Pe extends de{_loadMedia(){var t=U(this.data.url);this._el.content_item=this.domCreate("div","tl-media-item tl-media-iframe",this._el.content);var e;e=o||_||t.match(/dl.dropboxusercontent.com/)?"<iframe class='doc' frameborder='0' width='100%' height='100%' src='//docs.google.com/viewer?url="+t+"&embedded=true'></iframe>":"<iframe class='doc' frameborder='0' width='100%' height='100%' src='"+t+"'></iframe>",this._el.content_item.innerHTML=e,this.onLoaded();}_updateMediaDisplay(){this._el.content_item.style.height=this.options.height+"px";}}class ze extends de{_loadMedia(){this.loadingMessage(),this.options.background||this.createMedia(),this.onLoaded();}createMedia(){var t=U(this.data.url),e=this;this._el.content_item=this.domCreate("audio","tl-media-item tl-media-audio tl-media-shadow",this._el.content),this._el.content_item.controls=!0,this._el.source_item=this.domCreate("source","",this._el.content_item),this._el.content_item.addEventListener("load",(function(t){e.onMediaLoaded();})),this._el.source_item.src=t,this._el.source_item.type=this._getType(this.data.url,this.data.mediatype.match_str),this._el.content_item.innerHTML+="Your browser doesn't support HTML5 audio with "+this._el.source_item.type,this.player_element=this._el.content_item;}_updateMediaDisplay(t){m&&(this._el.content_item.style.width="auto");}_stopMedia(){this.player_element&&this.player_element.pause();}_getType(t,e){var i="audio/";switch(t.match(e)[1]){case "mp3":i+="mpeg";break;case "wav":i+="wav";break;case "m4a":i+="mp4";break;default:i="audio";}return i;}}class He extends de{_loadMedia(){this.loadingMessage(),this.options.background||this.createMedia(),this.onLoaded();}createMedia(){var t=U(this.data.url),e=this;this._el.content_item=this.domCreate("video","tl-media-item tl-media-video tl-media-shadow",this._el.content),this._el.content_item.controls=!0,this._el.source_item=this.domCreate("source","",this._el.content_item),this._el.content_item.addEventListener("load",(function(t){e.onMediaLoaded();})),this._el.source_item.src=t,this._el.source_item.type=this._getType(this.data.url,this.data.mediatype.match_str),this._el.content_item.innerHTML+="Your browser doesn't support HTML5 video with "+this._el.source_item.type,this.player_element=this._el.content_item;}_updateMediaDisplay(t){m&&(this._el.content_item.style.width="auto");}_stopMedia(){this.player_element&&this.player_element.pause();}_getType(t,e){var i="video/";switch(t.match(e)[1]){case "mp4":i+="mp4";break;case "webm":i+="webm";break;default:i="video";}return i;}}class Fe extends de{_loadMedia(){var t,e=this;this._el.content_item=this.domCreate("div","tl-media-item tl-media-iframe tl-media-wistia tl-media-shadow",this._el.content),this.media_id=this.data.url.split(/https?:\/\/(.+)?(wistia\.com|wi\.st)\/medias\/(.*)/)[3],S(`Wistia: media_id: ${this.media_id}`),t="https://fast.wistia.com/embed/iframe/"+this.media_id+"?version=v1&controlsVisibleOnLoad=true&playerColor=aae3d8",this.player=this.domCreate("iframe","",this._el.content_item),this.player.addEventListener("load",(function(t){e.onMediaLoaded();})),this.player.width="100%",this.player.height="100%",this.player.frameBorder="0",this.player.src=t,this.player.setAttribute("allowfullscreen",""),this.player.setAttribute("webkitallowfullscreen",""),this.player.setAttribute("mozallowfullscreen",""),this.onLoaded();}_updateMediaDisplay(){this._el.content_item.style.height=W({w:this._el.content_item.offsetWidth})+"px";}_stopMedia(){try{this.player.contentWindow.postMessage(JSON.stringify({method:"pause"}),"https://player.vimeo.com");}catch(t){S(t);}}}function qe(t,e){var i=[{type:"youtube",name:"YouTube",match_str:"^(https?:)?/*(www.|m.)?youtube|youtu.be",cls:pe},{type:"vimeo",name:"Vimeo",match_str:"^(https?:)?/*(player.)?vimeo.com",cls:we},{type:"dailymotion",name:"DailyMotion",match_str:"^(https?:)?/*(www.)?(dailymotion.com|dai.ly)",cls:ke},{type:"vine",name:"Vine",match_str:"^(https?:)?/*(www.)?vine.co",cls:xe},{type:"soundcloud",name:"SoundCloud",match_str:"^(https?:)?/*(player.)?soundcloud.com",cls:be},{type:"twitter",name:"Twitter",match_str:"^(https?:)?/*(www.)?(twitter|x).com",cls:Te},{type:"twitterembed",name:"TwitterEmbed",match_str:"<blockquote class=['\"]twitter-tweet['\"]",cls:Me},{type:"googlemaps",name:"Google Map",match_str:/google.+?\/maps\/@([-\d.]+),([-\d.]+),((?:[-\d.]+[zmayht],?)*)|google.+?\/maps\/search\/([\w\W]+)\/@([-\d.]+),([-\d.]+),((?:[-\d.]+[zmayht],?)*)|google.+?\/maps\/place\/([\w\W]+)\/@([-\d.]+),([-\d.]+),((?:[-\d.]+[zmayht],?)*)|google.+?\/maps\/dir\/([\w\W]+)\/([\w\W]+)\/@([-\d.]+),([-\d.]+),((?:[-\d.]+[zmayht],?)*)/,cls:fe},{type:"flickr",name:"Flickr",match_str:"^(https?:)?/*(www.)?flickr.com/photos",cls:Ee},{type:"flickr",name:"Flickr",match_str:"^(https?://)?flic.kr/.*",cls:Ee},{type:"instagram",name:"Instagram",match_str:/^(https?:)?\/*(www.)?(instagr.am|^(https?:)?\/*(www.)?instagram.com)\/p\//,cls:Ae},{type:"profile",name:"Profile",match_str:/^(https?:)?\/*(www.)?instagr.am\/[a-zA-Z0-9]{2,}|^(https?:)?\/*(www.)?instagram.com\/[a-zA-Z0-9]{2,}/,cls:Ce},{type:"documentcloud",name:"Document Cloud",match_str:/documentcloud.org\//,cls:Le},{type:"wikipedia-image",name:"WikipediaImage",match_str:"^https://.+.wiki[mp]edia.org.+#/media/.+.(jpg|jpeg|png|gif|svg|webp)",cls:ye},{type:"wikipedia-image",name:"WikipediaImage",match_str:"^https://commons.wikimedia.org/wiki/File:.+.(jpg|jpeg|png|gif|svg|webp)",cls:ye},{type:"wikipedia",name:"Wikipedia",match_str:"^(https?:)?/.+.wikipedia.org",cls:ve},{type:"image",name:"Image",match_str:/(jpg|jpeg|png|gif|svg|webp)(\?.*)?$/i,cls:ce},{type:"imgur",name:"Imgur",match_str:/^.*imgur.com\/.+$|<blockquote class=['\"]imgur-embed-pub['\"]/i,cls:je},{type:"googledocs",name:"Google Doc",match_str:"^(https?:)?/*[^.]*.google.com/[^/]*/d/[^/]*/[^/]*?usp=shar.*|^(https?:)?/*drive.google.com/open?id=[^&]*&authuser=0|^(https?:)?//*drive.google.com/open\\?id=[^&]*|^(https?:)?/*[^.]*.googledrive.com/host/[^/]*/",cls:Ie},{type:"pdf",name:"PDF",match_str:/^.*\.pdf(\?.*)?(\#.*)?/,cls:Pe},{type:"spotify",name:"spotify",match_str:"spotify",cls:Oe},{type:"iframe",name:"iFrame",match_str:"iframe",cls:Re},{type:"blockquote",name:"Quote",match_str:"blockquote",cls:ge},{type:"video",name:"Video",match_str:/(mp4|webm)(\?.*)?$/i,cls:He},{type:"wistia",name:"Wistia",match_str:/https?:\/\/(.+)?(wistia\.com|wi\.st)\/.*/i,cls:Fe},{type:"audio",name:"Audio",match_str:/(mp3|wav|m4a)(\?.*)?$/i,cls:ze},{type:"imageblank",name:"Imageblank",match_str:"",cls:ce}];if(e){if(t instanceof Array)return !1;for(var a=0;a<i.length;a++)switch(i[a].type){case "flickr":case "image":case "instagram":if(t.url.match(i[a].match_str))return i[a];}}else{for(a=0;a<i.length;a++)if(t.url.match(i[a].match_str))return i[a];}return !1;}class $e{constructor(t,e){this._el={container:{},content_container:{},media_container:{},timespan:{},line_left:{},line_right:{},content:{},text:{},media:{}},this._text={},this._state={loaded:!1},this.data={unique_id:"",background:null,date:{year:0,month:0,day:0,hour:0,minute:0,second:0,millisecond:0,thumbnail:"",format:""},text:{headline:"",text:""},media:null},this.options={duration:1e3,ease:Q,width:600,height:600,marker_width_min:100},this.active=!1,this.animator={},this.has_end_date=!1,this.ariaLabel="",E(this.options,e),E(this.data,t),this._initLayout(),this._initEvents();}show(){}hide(){}setActive(t){this.active=t,this.active&&this.has_end_date?this._el.container.className="tl-timemarker tl-timemarker-with-end tl-timemarker-active":this.active?this._el.container.className="tl-timemarker tl-timemarker-active":this.has_end_date?this._el.container.className="tl-timemarker tl-timemarker-with-end":this._el.container.className="tl-timemarker",this._el.container.ariaLabel=this.ariaLabel,this.active?this._el.container.ariaLabel+=", shown":this._el.container.ariaLabel+=", press space to show";}setFocus(t={preventScroll:!0}){this._el.container.focus(t);}addTo(t){t.appendChild(this._el.container);}removeFrom(t){t.removeChild(this._el.container);}updateDisplay(t,e){this._updateDisplay(t,e);}loadMedia(){this._media&&!this._state.loaded&&(this._media.loadMedia(),this._state.loaded=!0);}stopMedia(){this._media&&this._state.loaded&&this._media.stopMedia();}getLeft(){return this._el.container.style.left.slice(0,-2);}getTime(){return this.data.start_date.getTime();}getEndTime(){return !!this.data.end_date&&this.data.end_date.getTime();}setHeight(t){var e=1;this._el.content_container.style.height=t+"px",this._el.timespan_content.style.height=t+"px",this._el.content.className=t<=30?"tl-timemarker-content tl-timemarker-content-small":"tl-timemarker-content",t<=56?this._el.content_container.classList.add("tl-timemarker-content-container-small"):this._el.content_container.classList.remove("tl-timemarker-content-container-small"),r?((e=Math.floor(t/14))<1&&(e=1),this._text.className="tl-headline",this._text.style.webkitLineClamp=e):(e=t/12,this._text.className=e>1?"tl-headline tl-headline-fadeout":"tl-headline",this._text.style.height=12*e+"px");}setWidth(t){this.data.end_date&&(this._el.container.style.width=t+"px",t>this.options.marker_width_min?(this._el.content_container.style.width=t+"px",this._el.content_container.className="tl-timemarker-content-container tl-timemarker-content-container-long"):(this._el.content_container.style.width=this.options.marker_width_min+"px",this._el.content_container.className="tl-timemarker-content-container"));}setClass(t){this._el.container.className=t;}setRowPosition(t,e){this.setPosition({top:t}),this._el.timespan.style.height=e+"px";}getFormattedDate(){if(O(this.data.display_date).length>0)return this.data.display_date;let t="";return this.data.end_date&&(t=" to "+this.data.end_date.getDisplayDate(this.getLanguage())),this.data.start_date&&(t=(t?"from ":"")+this.data.start_date.getDisplayDate(this.getLanguage())+t),t;}_onMarkerClick(t){this.fire("markerclick",{unique_id:this.data.unique_id});}_onMarkerKeydown(t){/Space|Enter/.test(t.code)&&this.fire("markerclick",{unique_id:this.data.unique_id});}_onMarkerBlur(t){this.fire("markerblur",{unique_id:this.data.unique_id});}_initLayout(){if(this._el.container=v("div","tl-timemarker"),this._el.container.setAttribute("tabindex","-1"),this.data.unique_id&&(this._el.container.id=this.data.unique_id+"-marker"),this.data.end_date&&(this.has_end_date=!0,this._el.container.className="tl-timemarker tl-timemarker-with-end"),this._el.timespan=v("div","tl-timemarker-timespan",this._el.container),this._el.timespan_content=v("div","tl-timemarker-timespan-content",this._el.timespan),this._el.content_container=v("div","tl-timemarker-content-container",this._el.container),this._el.content=v("div","tl-timemarker-content",this._el.content_container),this._el.line_left=v("div","tl-timemarker-line-left",this._el.timespan),this._el.line_right=v("div","tl-timemarker-line-right",this._el.timespan),this.data.media){this._el.media_container=v("div","tl-timemarker-media-container",this._el.content);var t={url:this.data.media.thumbnail},e=this.data.media.thumbnail?qe(t,!0):null;if(e){var i=new e.cls(t);i.on("loaded",function(){this._el.media=v("img","tl-timemarker-media",this._el.media_container),this._el.media.src=i.getImageURL();}.bind(this)),i.loadMedia();}else{var a=qe(this.data.media).type;this._el.media=v("span","tl-icon-"+a,this._el.media_container);}}this._el.text=v("div","tl-timemarker-text",this._el.content),this._text=v("h2","tl-headline",this._el.text),this.data.text.headline&&""!=this.data.text.headline?this._text.innerHTML=F(this.data.text.headline):this.data.text.text&&""!=this.data.text.text?this._text.innerHTML=F(this.data.text.text):this.data.media&&this.data.media.caption&&""!=this.data.media.caption&&(this._text.innerHTML=F(this.data.media.caption));const s=this.getFormattedDate();this.ariaLabel=`${this._text.innerHTML}, ${s}`,this.onLoaded();}_initEvents(){ht.addListener(this._el.container,"click",this._onMarkerClick,this),ht.addListener(this._el.container,"keydown",this._onMarkerKeydown,this),ht.addListener(this._el.container,"blur",this._onMarkerBlur,this);}_updateDisplay(t,e,i){t&&(this.options.width=t),e&&(this.options.height=e);}}R($e,Rt,at,ot);
28class Ue{constructor(t,e,i){this._el={drag:t,move:t},this.mousedrag={down:"mousedown",up:"mouseup",leave:"mouseleave",move:"mousemove"},this.touchdrag={down:"touchstart",up:"touchend",leave:"mouseleave",move:"touchmove"},e&&(this._el.move=e),this.options={snap:!1,enable:{x:!0,y:!0},constraint:{top:!1,bottom:!1,left:0,right:!1},momentum_multiplier:2e3,duration:1e3,ease:et},this.animator=null,this.dragevent=this.mousedrag,f&&(this.dragevent=this.touchdrag),this.data={sliding:!1,direction:"none",pagex:{start:0,end:0},pagey:{start:0,end:0},pos:{start:{x:0,y:0},end:{x:0,y:0}},new_pos:{x:0,y:0},new_pos_parent:{x:0,y:0},time:{start:0,end:0},touch:!1},E(this.options,i);}enable(t){ht.addListener(this._el.drag,this.dragevent.down,this._onDragStart,this),ht.addListener(this._el.drag,this.dragevent.up,this._onDragEnd,this),this.data.pos.start=0,this._el.move.style.left=this.data.pos.start.x+"px",this._el.move.style.top=this.data.pos.start.y+"px",this._el.move.style.position="absolute";}disable(){ht.removeListener(this._el.drag,this.dragevent.down,this._onDragStart,this),ht.removeListener(this._el.drag,this.dragevent.up,this._onDragEnd,this);}stopMomentum(){this.animator&&this.animator.stop();}updateConstraint(t){this.options.constraint=t;}_onDragStart(t){this.animator&&this.animator.stop(),f?t.originalEvent?(this.data.pagex.start=t.originalEvent.touches[0].screenX,this.data.pagey.start=t.originalEvent.touches[0].screenY):(this.data.pagex.start=t.targetTouches[0].screenX,this.data.pagey.start=t.targetTouches[0].screenY):(this.data.pagex.start=t.pageX,this.data.pagey.start=t.pageY),this.options.enable.x,this.options.enable.y,this.data.pos.start={x:this._el.move.offsetLeft,y:this._el.move.offsetTop},this.data.time.start=(new Date()).getTime(),this.fire("dragstart",this.data),ht.addListener(this._el.drag,this.dragevent.move,this._onDragMove,this),ht.addListener(this._el.drag,this.dragevent.leave,this._onDragEnd,this);}_onDragEnd(t){this.data.sliding=!1,ht.removeListener(this._el.drag,this.dragevent.move,this._onDragMove,this),ht.removeListener(this._el.drag,this.dragevent.leave,this._onDragEnd,this),this.fire("dragend",this.data),this._momentum();}_onDragMove(t){var e={x:0,y:0};this.data.sliding=!0,f?t.originalEvent?(this.data.pagex.end=t.originalEvent.touches[0].screenX,this.data.pagey.end=t.originalEvent.touches[0].screenY):(this.data.pagex.end=t.targetTouches[0].screenX,this.data.pagey.end=t.targetTouches[0].screenY):(this.data.pagex.end=t.pageX,this.data.pagey.end=t.pageY),e.x=this.data.pagex.start-this.data.pagex.end,e.y=this.data.pagey.start-this.data.pagey.end,this.data.pos.end={x:this._el.drag.offsetLeft,y:this._el.drag.offsetTop},this.data.new_pos.x=-(e.x-this.data.pos.start.x),this.data.new_pos.y=-(e.y-this.data.pos.start.y),this.options.enable.x&&Math.abs(e.x)>Math.abs(e.y)&&(t.preventDefault(),this._el.move.style.left=this.data.new_pos.x+"px"),this.options.enable.y&&Math.abs(e.y)>Math.abs(e.y)&&(t.preventDefault(),this._el.move.style.top=this.data.new_pos.y+"px"),this.fire("dragmove",this.data);}_momentum(){var t={x:0,y:0,time:0},e={x:0,y:0,time:0},i={x:!1,y:!1},a=!1;this.data.direction=null,t.time=10*((new Date()).getTime()-this.data.time.start),e.time=10*((new Date()).getTime()-this.data.time.start),e.x=this.options.momentum_multiplier*(Math.abs(this.data.pagex.end)-Math.abs(this.data.pagex.start)),e.y=this.options.momentum_multiplier*(Math.abs(this.data.pagey.end)-Math.abs(this.data.pagey.start)),t.x=Math.round(e.x/e.time),t.y=Math.round(e.y/e.time),this.data.new_pos.x=Math.min(this.data.new_pos.x+t.x),this.data.new_pos.y=Math.min(this.data.new_pos.y+t.y),this.options.enable.x?this.options.constraint.left&&this.data.new_pos.x>this.options.constraint.left&&(this.data.new_pos.x=this.options.constraint.left):this.data.new_pos.x=this.data.pos.start.x,this.options.enable.y?this.data.new_pos.y<0&&(this.data.new_pos.y=0):this.data.new_pos.y=this.data.pos.start.y,e.time<2e3&&(a=!0),this.options.enable.x&&this.options.enable.y?Math.abs(e.x)>Math.abs(e.y)?i.x=!0:i.y=!0:this.options.enable.x?Math.abs(e.x)>Math.abs(e.y)&&(i.x=!0):Math.abs(e.y)>Math.abs(e.x)&&(i.y=!0),i.x&&(Math.abs(e.x)>this._el.drag.offsetWidth/2&&(a=!0),Math.abs(e.x)>1e4&&(this.data.direction="left",e.x>0&&(this.data.direction="right"))),i.y&&(Math.abs(e.y)>this._el.drag.offsetHeight/2&&(a=!0),Math.abs(e.y)>1e4&&(this.data.direction="up",e.y>0&&(this.data.direction="down"))),e.time<1e3||this._animateMomentum(),a&&this.data.direction?this.fire("swipe_"+this.data.direction,this.data):this.data.direction?this.fire("swipe_nodirection",this.data):this.options.snap&&(this.animator.stop(),this.animator=st(this._el.move,{top:this.data.pos.start.y,left
28:this.data.pos.start.x,duration:this.options.duration,easing:tt}));}_animateMomentum(){var t={x:this.data.new_pos.x,y:this.data.new_pos.y},e={duration:this.options.duration,easing:tt};this.options.enable.y&&((this.options.constraint.top||this.options.constraint.bottom)&&(t.y>this.options.constraint.bottom?t.y=this.options.constraint.bottom:t.y<this.options.constraint.top&&(t.y=this.options.constraint.top)),e.top=Math.floor(t.y)+"px"),this.options.enable.x&&(this.options.constraint.left&&t.x>=this.options.constraint.left&&(t.x=this.options.constraint.left),this.options.constraint.right&&t.x<this.options.constraint.right&&(t.x=this.options.constraint.right),e.left=Math.floor(t.x)+"px"),this.animator=st(this._el.move,e),this.fire("momentum",this.data);}}R(Ue,at);class Be{constructor(t,e,i,a){this.language=a,this._el={parent:{},container:{},slider:{},slider_background:{},line:{},marker_container_mask:{},marker_container:{},marker_item_container:{},timeaxis:{},timeaxis_background:{}},this.collapsed=!1,this._el.container="object"==typeof t?t:g(t),this._el.container.setAttribute("tabindex","0"),this._el.container.setAttribute("role","application"),this._el.container.setAttribute("aria-label",this._("aria_label_timeline_navigation")),this._el.container.setAttribute("aria-description",'Navigate between markers with arrow keys. Press "Home" for the first and "End" for the last markers'),this.config=e,this.options={width:600,height:600,duration:1e3,ease:et,has_groups:!1,optimal_tick_width:50,scale_factor:2,marker_padding:5,timenav_height_min:150,marker_height_min:30,marker_width_min:100,zoom_sequence:[.5,1,2,3,5,8,13,21,34,55,89]},this.animator=null,this.ready=!1,this._markers=[],this._eras=[],this.has_eras=!1,this._groups=[],this._calculated_row_height=100,this.current_id="",this.current_focused_id="",this.timescale={},this.timeaxis={},this.max_rows=6,this.animate_css=!1,this._swipable,E(this.options,i);}init(){this._initLayout(),this._initEvents(),this._initData(),this.updateDisplay(),this._onLoaded();}positionMarkers(t){for(var e=0;e<this._markers.length;e++){var i=this.timescale.getPositionInfo(e);t?this._markers[e].setClass("tl-timemarker tl-timemarker-fast"):this._markers[e].setClass("tl-timemarker"),this._markers[e].setPosition({left:i.start}),this._markers[e].setWidth(i.width);}}updateDisplay(t,e,i){let a=!1;t&&(0==this.options.width&&t>0&&(a=!0),this.options.width=t),e&&e!=this.options.height&&(this.options.height=e,this.timescale=this._getTimeScale()),this._assignRowsToMarkers(),this._el.slider_background.style.width=this.timescale.getPixelWidth()+this.options.width+"px",this._el.slider_background.style.left=-this.options.width/2+"px",this._el.slider.style.width=this.timescale.getPixelWidth()+this.options.width+"px",this._swipable.updateConstraint({top:!1,bottom:!1,left:this.options.width/2,right:-(this.timescale.getPixelWidth()-this.options.width/2)}),a&&this._drawTimeline(),this.goToId(this.current_id,!0);}_getTimeScale(){var t=0;try{t=parseInt(this.options.marker_height_min);}catch(e){S("Invalid value for marker_height_min option."),t=30;}return 0==t&&(S("marker_height_min option must not be zero."),t=30),this.max_rows=Math.round((this.options.height-this._el.timeaxis_background.offsetHeight-this.options.marker_padding)/t),this.max_rows<1&&(this.max_rows=1),new ne(this.config,{display_width:this._el.container.offsetWidth,screen_multiplier:this.options.scale_factor,max_rows:this.max_rows});}_updateTimeScale(t){this.options.scale_factor=t,this._updateDrawTimeline();}zoomIn(){var t=function(t,e){for(var i=0;i<t.length;i++)if(e<t[i])return t[i];return e;}(this.options.zoom_sequence,this.options.scale_factor);this.setZoomFactor(t);}zoomOut(){var t=function(t,e){for(var i=t.length-1;i>=0;i--)if(e>t[i])return t[i];return e;}(this.options.zoom_sequence,this.options.scale_factor);this.setZoomFactor(t);}setZoom(t){var e=this.options.zoom_sequence[t];"number"==typeof e?this.setZoomFactor(e):console.warn("Invalid zoom level. Please use an index number between 0 and "+(this.options.zoom_sequence.length-1));}setZoomFactor(t){t<=this.options.zoom_sequence[0]?this.fire("zoomtoggle",{zoom:"out",show:!1}):this.fire("zoomtoggle",{zoom:"out",show:!0}),t>=this.options.zoom_sequence[this.options.zoom_sequence.length-1]?this.fire("zoomtoggle",{zoom:"in",show:!1}):this.fire("zoomtoggle",{zoom:"in",show:!0}),0==t&&(console.warn("Zoom factor must be greater than zero. Using 0.1"),t=.1),this.options.scale_factor=t,this.goToId(this.current_id,!this._updateDrawTimeline(!0),!0);}_createGroups(){this._groups=[];var t=this.timescale.getGroupLabels();if(t){this.options.has_groups=!0;for(var e=0;e<t.length;e++)this._createGroup(t[e]);}}_createGroup(t){var e=new oe(t);this._addGroup(e),this._groups.push(e);}_addGroup(t){t.addTo(this._el.container);}_positionGroups(){if(this.options.has_groups)for(var t=this.options.height-this._el.timeaxis_background.offsetHeight,e=Math.floor(t/this.timescale.getNumberOfRows()-this.options.marker_padding),i=(this.timescale.getGroupLabels(),0),a=0;i<this._groups.length;i++){var s=Math.floor(a*(e+this.options.marker_padding)),n=!1;s>t-this.options.marker_padding&&(n=!0),this._groups[i].setRowPosition(s,this._calculated_row_height+this.options.marker_padding/2),this._groups[i].setAlternateRowColor(z(i),n),a+=this._groups[i].data.rows;}}_addMarker(t){t.addTo(this._el.marker_item_container),t.on("markerclick",this._onMarkerClick,this),t.on("added",this._onMarkerAdded,this);}_createMarker(t,e){var i=new $e(t,this.options);this._addMarker(i),e<0?this._markers.push(i):this._markers.splice(e,0,i);}_createMarkers(t){for(var e=0;e<t.length;e++)this._createMarker(t[e],-1);}_removeMarker(t){t.removeFrom(this._el.marker_item_container);}_destroyMarker(t){this._removeMarker(this._markers[t]),this._markers.splice(t,1);}_calculateMarkerHeight(t){return t/this.timescale.getNumberOfRows()-this.options.marker_padding;}_calculateRowHeight(t){return t/this.timescale.getNumberOfRows();}_calculateAvailableHeight(){return this.options.height-this._el.timeaxis_background.offsetHeight-this.options.marker_padding;}_calculateMinimumTimeNavHeight(){return this.timescale.getNumberOfRows()*this.options.marker_height_min+this._el.timeaxis_background.offsetHeight+this.options.marker_padding;}getMinimumHeight(){return this._calculateMinimumTimeNavHeight();}_assignRowsToMarkers(){var t=this._calculateAvailableHeight(),e=this._calculateMarkerHeight(t);this._positionGroups(),this._calculated_row_height=this._calculateRowHeight(t);for(var i=0;i<this._markers.length;i++){this._markers[i].setHeight(e);var a=this.timescale.getPositionInfo(i).row,s=Math.floor(a*(e+this.options.marker_padding))+this.options.marker_padding,n=t-s+this.options.marker_padding;this._markers[i].setRowPosition(s,n);}}_resetMarkersActive(){for(var t=0;t<this._markers.length;t++)this._markers[t].setActive(!1);}_resetMarkersBlurListeners(){for(var t=0;t<this._markers.length;t++)this._markers[t].off("markerblur",this._onMarkerBlur,this);}_findMarkerIndex(t){var e=-1;return ("string"==typeof t||t instanceof String)&&(e=H(t,this._markers,"unique_id",e)),e;}_createEras(t){for(var e=0;e<t.length;e++){var i=t[e],a=new re(i.start_date,i.end_date,i.headline,this.options);this._eras.push(a),a.addTo(this._el.marker_item_container),a.on("added",this._onEraAdded,this);}}_positionEras(t){for(var e=0,i=0;i<this._eras.length;i++){var a={start:0,end:0,width:0};a.start=this.timescale.getPosition(this._eras[i].start_date.getTime()),a.end=this.timescale.getPosition(this._eras[i].end_date.getTime()),a.width=a.end-a.start,t?this._eras[i].setClass("tl-timeera tl-timeera-fast"):this._eras[i].setClass("tl-timeera"),this._eras[i].setPosition({left:a.start}
28),this._eras[i].setWidth(a.width),++e>5&&(e=0),this._eras[i].setColor(e);}}createMarker(t,e){this._createMarker(t,e);}createMarkers(t){this._createMarkers(t);}destroyMarker(t){this._destroyMarker(t);}destroyMarkerId(t){this.destroyMarker(this._findMarkerIndex(t));}goTo(t,e,i){var a=this.options.ease,s=this.options.duration,n=t<0?0:t;this._resetMarkersActive(),t>=0&&t<this._markers.length&&this._markers[t].setActive(!0),this.animateMovement(n,e,i,s,a),t>=0&&t<this._markers.length?this.current_id=this.current_focused_id=this._markers[t].data.unique_id:this.current_id=this.current_focused_id="",this._setLabelWithCurrentMarker();}goToId(t,e,i){this.goTo(this._findMarkerIndex(t),e,i);}focusOn(t,e,i){const a=this.options.ease,s=this.options.duration,n=t<0?0:t;this.animateMovement(n,e,i,s,a),this._resetMarkersBlurListeners(),t>=0&&t<this._markers.length&&(this._markers[t].setFocus(),this.current_focused_id=this._markers[t].data.unique_id,this._markers[t].on("markerblur",this._onMarkerBlur,this));}focusNext(){const t=this._findMarkerIndex(this.current_focused_id);t+1<this._markers.length?this.focusOn(t+1):this.focusOn(t);}focusPrevious(){const t=this._findMarkerIndex(this.current_focused_id);t-1>=0?this.focusOn(t-1):this.focusOn(t);}animateMovement(t,e,i,a,s){this.animator&&this.animator.stop(),e?(this._el.slider.className="tl-timenav-slider",this._el.slider.style.left=-this._markers[t].getLeft()+this.options.width/2+"px"):i?(this._el.slider.className="tl-timenav-slider tl-timenav-slider-animate",this.animate_css=!0,this._el.slider.style.left=-this._markers[t].getLeft()+this.options.width/2+"px"):(this._el.slider.className="tl-timenav-slider",this.animator=st(this._el.slider,{left:-this._markers[t].getLeft()+this.options.width/2+"px",duration:a,easing:s})),t>=0&&t<this._markers.length?this.current_id=this._markers[t].data.unique_id:this.current_id="",this._dispatchVisibleTicksChange();}goToId(t,e,i){this.goTo(this._findMarkerIndex(t),e,i);}_dispatchVisibleTicksChange(){this.ticks_change_timeout&&(clearTimeout(this.ticks_change_timeout),this.ticks_change_timeout=null),this.ticks_change_timeout=setTimeout((()=>{const t=this.timeaxis.getVisibleTicks();this.fire("visible_ticks_change",{visible_ticks:t});}),this.options.duration);}_onLoaded(){this.ready=!0,this.fire("loaded",this.config);}_onMarkerAdded(t){this.fire("dateAdded",this.config);}_onEraAdded(t){this.fire("eraAdded",this.config);}_onMarkerRemoved(t){this.fire("dateRemoved",this.config);}_onMarkerClick(t){this.goToId(t.unique_id),this.fire("change",{unique_id:t.unique_id});}_onMarkerBlur(t){this.current_focused_id!==this.current_id&&this.focusOn(this._findMarkerIndex(this.current_id));}_onMouseScroll(t){var e=0,i=0,a={right:-(this.timescale.getPixelWidth()-this.options.width/2),left:this.options.width/2};t||(t=window.event),t.originalEvent&&(t=t.originalEvent),void 0!==t.wheelDeltaX&&(e=t.wheelDeltaY/6,e=Math.abs(t.wheelDeltaX)>Math.abs(t.wheelDeltaY)?t.wheelDeltaX/6:0),e&&(t.preventDefault&&t.preventDefault(),t.returnValue=!1),(i=parseInt(this._el.slider.style.left.replace("px",""))+e)>a.left?i=a.left:i<a.right&&(i=a.right),this.animate_css&&(this._el.slider.className="tl-timenav-slider",this.animate_css=!1),this._el.slider.style.left=i+"px";}_onDragMove(t){this.animate_css&&(this._el.slider.className="tl-timenav-slider",this.animate_css=!1);}_onKeydown(t){switch(ht.stopPropagation(t),t.key){case "ArrowUp":case "ArrowRight":this.focusNext();break;case "ArrowDown":case "ArrowLeft":this.focusPrevious();break;case "Home":this.focusOn(0);break;case "End":this.focusOn(this._markers.length-1);}}_drawTimeline(t){this.timescale=this._getTimeScale(),this.timeaxis.drawTicks(this.timescale,this.options.optimal_tick_width),this.positionMarkers(t),this._assignRowsToMarkers(),this._createGroups(),this._positionGroups(),this.has_eras&&this._positionEras(t);}_updateDrawTimeline(t){var e=!1;if(t){var i=new ne(this.config,{display_width:this._el.container.offsetWidth,screen_multiplier:this.options.scale_factor,max_rows:this.max_rows});this.timescale.getMajorScale()==i.getMajorScale()&&this.timescale.getMinorScale()==i.getMinorScale()&&(e=!0);}else e=!0;return e?(this.timescale=this._getTimeScale(),this.timeaxis.positionTicks(this.timescale,this.options.optimal_tick_width),this.positionMarkers(),this._assignRowsToMarkers(),this._positionGroups(),this.has_eras&&this._positionEras(),this.updateDisplay()):this._drawTimeline(!0),e;}_setLabelWithCurrentMarker(){const t=this._markers[this._findMarkerIndex(this.current_focused_id)],e=t&&t.ariaLabel?`, ${t.ariaLabel}, shown`:"";this._el.container.setAttribute("aria-label",`Timeline navigation ${e}`);}_initLayout(){this._el.line=v("div","tl-timenav-line",this._el.container),this._el.slider=v("div","tl-timenav-slider",this._el.container),this._el.slider_background=v("div","tl-timenav-slider-background",this._el.slider),this._el.marker_container_mask=v("div","tl-timenav-container-mask",this._el.slider),this._el.marker_container=v("div","tl-timenav-container",this._el.marker_container_mask),this._el.marker_item_container=v("div","tl-timenav-item-container",this._el.marker_container),this._el.timeaxis=v("div","tl-timeaxis",this._el.slider),this._el.timeaxis_background=v("div","tl-timeaxis-background",this._el.container),this.timeaxis=new le(this._el.timeaxis,this.options,this.language),this._swipable=new Ue(this._el.slider_background,this._el.slider,{enable:{x:!0,y:!1},constraint:{top:!1,bottom:!1,left:this.options.width/2,right:!1},snap:!1}),this._swipable.enable();}_initEvents(){this._swipable.on("dragmove",this._onDragMove,this),ht.addListener(this._el.container,"mousewheel",this._onMouseScroll,this),ht.addListener(this._el.container,"DOMMouseScroll",this._onMouseScroll,this),ht.addListener(this._el.container,"keydown",this._onKeydown,this);}_initData(){this._createMarkers(this.config.events),this.config.eras&&this.config.eras.length>0&&(this.has_eras=!0,this._createEras(this.config.eras)),this._drawTimeline();}}R(Be,at,ot,Rt),i(142);class We{constructor(t,e,i,a){a&&this.setLanguage(a),this._el={container:{},scroll_container:{},background:{},content_container:{},content:{}},this._media=null,this._mediaclass={},this._text={},this._background_media=null,this._state={loaded:!1},this.has={headline:!1,text:!1,media:!1,title:!1,background:{image:!1,
28color:!1,color_value:""}},this.has.title=i,this.data={unique_id:null,background:null,start_date:null,end_date:null,location:null,text:null,media:null,autolink:!0},this.options={duration:1e3,slide_padding_lr:40,ease:Q,width:600,height:600,skinny_size:650,media_name:""},this.active=!1,this.animator={},E(this.options,e),E(this.data,t),this._initLayout(),this._initEvents();}show(){this.animator=st(this._el.slider_container,{left:-this._el.container.offsetWidth*n+"px",duration:this.options.duration,easing:this.options.ease});}hide(){}setActive(t){this.active=t,this.active?(this.data.background&&this.fire("background_change",this.has.background),this._setInteractive(!0),this.loadMedia()):(this.stopMedia(),this._setInteractive(!1));}addTo(t){t.appendChild(this._el.container);}removeFrom(t){t.removeChild(this._el.container);}updateDisplay(t,e,i){var a,s=this.options.slide_padding_lr,n=this.options.slide_padding_lr;this.options.width=t||this._el.container.offsetWidth,a=this.options.width-2*this.options.slide_padding_lr,h&&this.options.width<=this.options.skinny_size?(s=0,n=0,a=this.options.width):"landscape"==i||this.options.width<=this.options.skinny_size&&(s=50,n=50,a=this.options.width-s-n),this._el.content.style.paddingLeft=s+"px",this._el.content.style.paddingRight=n+"px",this._el.content.style.width=a+"px",this.options.height=e||this._el.container.offsetHeight,this._media&&(!this.has.text&&this.has.headline?this._media.updateDisplay(a,this.options.height-this._text.headlineHeight(),i):this.has.text||this.has.headline?this.options.width<=this.options.skinny_size?this._media.updateDisplay(a,this.options.height,i):this._media.updateDisplay(a/2,this.options.height,i):this._media.updateDisplay(a,this.options.height,i)),this._updateBackgroun
28dDisplay();}loadMedia(){var t=this;this._media&&!this._state.loaded&&(this._media.loadMedia(),this._state.loaded=!0),this._background_media&&!this._background_media._state.loaded&&(this._background_media.on("loaded",(function(){t._updateBackgroundDisplay();})),this._background_media.loadMedia());}stopMedia(){this._media&&this._state.loaded&&this._media.stopMedia();}getBackground(){return this.has.background;}scrollToTop(){this._el.container.scrollTop=0;}getFormattedDate(){if(O(this.data.display_date).length>0)return this.data.display_date;var t="";return this.has.title||(this.data.end_date&&(t=" — "+this.data.end_date.getDisplayDate(this.getLanguage())),this.data.start_date&&(t=this.data.start_date.getDisplayDate(this.getLanguage())+t)),t;}_initLayout(){if(this._el.container=v("div","tl-slide"),this.has.title&&(this._el.container.className="tl-slide tl-slide-titleslide"),this.data.unique_id&&(this._el.container.id=this.data.unique_id),this._el.scroll_container=v("div","tl-slide-scrollable-container",this._el.container),this._el.content_container=v("div","tl-slide-content-container",this._el.scroll_container),this._el.content=v("div","tl-slide-content",this._el.content_container),this._el.background=v("div","tl-slide-background",this._el.container),this.data.background){if(this.data.background.url){var t=qe(this.data.background,!0);t&&(this._background_media=new t.cls(this.data.background,{background:1}),this.has.background.image=!0,this._el.container.className+=" tl-full-image-background",this.has.background.color_value="#000",this._el.background.style.display="block"),this.data.background.alt&&(this._el.background.setAttribute("role","img"),this._el.background.setAttribute("aria-label",this.data.background.alt));}this.data.background.color&&(this.has.background.color=!0,this._el.container.className+=" tl-full-color-background",this.has.background.color_value=this.data.background.color),this.data.background.text_background&&(this._el.container.className+=" tl-text-background");}this.data.media&&this.data.media.url&&""!=this.data.media.url&&(this.has.media=!0),this.data.text&&this.data.text.text&&(this.has.text=!0),this.data.text&&this.data.text.headline&&(this.has.headline=!0),this.has.media&&(this.data.media.mediatype=qe(this.data.media),this.options.media_name=this.data.media.mediatype.name,this.options.media_type=this.data.media.mediatype.type,this.options.autolink=this.data.autolink,this._media=new this.data.media.mediatype.cls(this.data.media,this.options,this.getLanguage())),(this.has.text||this.has.headline)&&(this._text=new he(this.data.text,{title:this.has.title,language:this.getLanguage(),autolink:this.data.autolink}),this._text.addDateText(this.getFormattedDate())),this.has.text||this.has.headline||!this.has.media?this.has.headline&&this.has.media&&!this.has.text?(this._el.container.classList.add("tl-slide-media-only"),this._text.addTo(this._el.content),this._media.addTo(this._el.content)):this.has.text&&this.has.media?(this._text.addTo(this._el.content),this._media.addTo(this._el.content)):(this.has.text||this.has.headline)&&(this._el.container.classList.add("tl-slide-text-only"),this._text.addTo(this._el.content)):(this._el.container.classList.add("tl-slide-media-only"),this._media.addTo(this._el.content)),this.onLoaded();}_initEvents(){}
28_updateBackgroundDisplay(){this._background_media&&this._background_media._state.loaded&&(this._el.background.style.backgroundImage="url('"+this._background_media.getImageURL(this.options.width,this.options.height)+"')");}_setInteractive(t){t?this._el.container.removeAttribute("inert"):this._el.container.setAttribute("inert",!0);}}R(We,Rt,at,ot);class Ge{constructor(t,e,i){this._el={container:{},content_container:{},icon:{},title:{},description:{}},this.mediatype={},this.data={title:"Navigation",description:"Description",date:"Date"},this.options={direction:"previous"},this.animator=null,E(this.options,e),E(this.data,t),this._el.container=y("tl-slidenav-"+this.options.direction),h&&this._el.container.setAttribute("ontouchstart"," "),this._initLayout(),this._initEvents(),i&&i.appendChild(this._el.container);}update(t){var e={title:"",description:"",date:t.getFormattedDate()};t.data.text&&t.data.text.headline&&(e.title=t.data.text.headline),this._update(e);}setColor(t){this._el.content_container.className=t?"tl-slidenav-content-container tl-slidenav-inverted":"tl-slidenav-content-container";}_onMouseClick(){this.fire("clicked",this.options);}_update(t){this.data=E(this.data,t);const e=F(this.data.title);this._el.title.innerHTML=e;const i=F(this.data.date);this._el.description.innerHTML=i,this._el.container.setAttribute("aria-label",`${this.options.direction}, ${e}, ${i}`);}_initLayout(){this._el.content_container=v("div","tl-slidenav-content-container",this._el.container),this._el.icon=v("div","tl-slidenav-icon",this._el.content_container),this._el.title=v("div","tl-slidenav-title",this._el.content_container),this._el.description=v("div","tl-slidenav-description",this._el.content_container),this._el.icon.innerHTML=" ",this._update();}_initEvents(){ht.addListener(this._el.container,"click",this._onMouseClick,this);}}R(Ge,ot,at);class Ye{constructor(t,e,i,a){a&&this.setLanguage(a),this._el={container:{},background:{},slider_container_mask:{},slider_container:{},slider_item_container:{}},this._nav={},this._nav.previous={},this._nav.next={},this.slide_spacing=0,this._slides=[],this._swipable,this.preloadTimer,this._message,this.current_id="",this.data={},this.options={id:"",layout:"portrait",width:600,height:600,default_bg_color:{r:255,g:255,b:255},slide_padding_lr:40,start_at_slide:1,slide_default_fade:"0%",duration:1e3,ease:et,dragging:!0,trackResize:!0},"object"==typeof t?(this._el.container=t,this.options.id=P(6,"tl")):(this.options.id=t,this._el.container=g(t)),this._el.container.id||(this._el.container.id=this.options.id),this.animator=null,E(this.options,i),E(this.data,e);}init(){this._initLayout(),this._initEvents(),this._initData(),this.updateDisplay(),this.goTo(this.options.start_at_slide),this._onLoaded();}_addSlide(t){t.addTo(this._el.slider_item_container),t.on("added",this._onSlideAdded,this),t.on("background_change",this._onBackgroundChange,this);}_createSlide(t,e,i){var a=new We(t,this.options,e,this.getLanguage());this._addSlide(a),i<0?this._slides.push(a):this._slides.splice(i,0,a);}_createSlides(t){for(var e=0;e<t.length;e++)""==t[e].unique_id&&(t[e].unique_id=P(6,"tl-slide")),this._createSlide(t[e],!1,-1);}_removeSlide(t){t.removeFrom(this._el.slider_item_container),t.off("added",this._onSlideRemoved,this),t.off("background_change",this._onBackgroundChange);}_destroySlide(t){this._removeSlide(this._slides[t]),this._slides.splice(t,1);}_findSlideIndex(t){var e=t;return ("string"==typeof t||t instanceof String)&&(e=H(t,this._slides,"unique_id")),e;}updateDisplay(t,e,i,a){var s,n;n=void 0===a?this.options.layout:a,this.options.layout=n,this.options.width=t||this._el.container.offsetWidth,this.options.height=e||this._el.container.offsetHeight,this.slide_spacing=2*this.options.width,s=this.options.height/2,this._nav.next.setPosition({top:s}),this._nav.previous.setPosition({top:s});for(var o=0;o<this._slides.length;o++)this._slides[o].updateDisplay(this.options.width,this.options.height,n),this._slides[o].setPosition({left:this.slide_spacing*o,top:0});this.goToId(this.current_id,!0,!0);}createSlide(t,e){this._createSlide(t,!1,e);}createSlides(t){this._createSlides(t);}destroySlide(t){this._destroySlide(t);}destroySlideId(t){this.destroySlide(this._findSlideIndex(t));}goTo(t,e,i){t=parseInt(t),isNaN(t)&&(t=0);var a=this;
28this.changeBackground({color_value:"",image:!1}),this.preloadTimer&&clearTimeout(this.preloadTimer);for(var s=0;s<this._slides.length;s++)this._slides[s].setActive(!1);t<this._slides.length&&t>=0&&(this.current_id=this._slides[t].data.unique_id,this.animator&&this.animator.stop(),this._swipable&&this._swipable.stopMomentum(),e?(this._el.slider_container.style.left=-this.slide_spacing*t+"px",this._onSlideChange(i)):this.animator=st(this._el.slider_container,{left:-this.slide_spacing*t+"px",duration:this.options.duration,easing:this.options.ease,complete:this._onSlideChange(i)}),this._slides[t].setActive(!0),this._slides[t+1]?(this.showNav(this._nav.next,!0),this._nav.next.update(this._slides[t+1])):this.showNav(this._nav.next,!1),this._slides[t-1]?(this.showNav(this._nav.previous,!0),this._nav.previous.update(this._slides[t-1])):this.showNav(this._nav.previous,!1),this.preloadTimer=setTimeout((function(){a.preloadSlides(t);}),this.options.duration));}goToId(t,e,i){this.goTo(this._findSlideIndex(t),e,i);}preloadSlides(t){this._slides[t+1]&&(this._slides[t+1].loadMedia(),this._slides[t+1].scrollToTop()),this._slides[t+2]&&(this._slides[t+2].loadMedia(),this._slides[t+2].scrollToTop()),this._slides[t-1]&&(this._slides[t-1].loadMedia(),this._slides[t-1].scrollToTop()),this._slides[t-2]&&(this._slides[t-2].loadMedia(),this._slides[t-2].scrollToTop());}next(){var t=this._findSlideIndex(this.current_id);t+1<this._slides.length?this.goTo(t+1):this.goTo(t);}previous(){var t=this._findSlideIndex(this.current_id);t-1>=0?this.goTo(t-1):this.goTo(t);}showNav(t,e){this.options.width<=500&&h?t.hide():e?t.show():t.hide();}changeBackground(t){var e={r:256,g:256,b:256};t.color_value&&""!=t.color_value?(e=M(t.color_value))||(S("Invalid color value "+t.color_value),e=this.options.default_bg_color):(e=this.options.default_bg_color,t.color_value="rgb("+e.r+" , "+e.g+", "+e.b+")"),e.r,e.g,e.b,this._el.background.style.backgroundImage="none",t.color_value?this._el.background.style.backgroundColor=t.color_value:this._el.background.style.backgroundColor="transparent",e.r<255||e.g<255||e.b<255||t.image?(this._nav.next.setColor(!0),this._nav.previous.setColor(!0)):(this._nav.next.setColor(!1),this._nav.previous.setColor(!1));}_updateDrawSlides(){for(var t=this.options.layout,e=0;e<this._slides.length;e++)this._slides[e].updateDisplay(this.options.width,this.options.height,t),this._slides[e].setPosition({left:this.slide_spacing*e,top:0});this.goToId(this.current_id,!0,!1);}_initLayout(){this._el.container.classList.add("tl-storyslider"),this._nav.previous=new Ge({title:"Previous",description:"description"},{direction:"previous"},this._el.container),this._nav.next=new Ge({title:"Next",description:"description"},{direction:"next"},this._el.container),this._el.slider_container_mask=v("div","tl-slider-container-mask",this._el.container),this._el.background=v("div","tl-slider-background tl-animate",this._el.container),this._el.slider_container=v("div","tl-slider-container tlanimate",this._el.slider_container_mask),this._el.slider_item_container=v("div","tl-slider-item-container",this._el.slider_container),this._el.slider_container.setAttribute("aria-live","polite"),this.options.width=this._el.container.offsetWidth,this.options.height=this._el.container.offsetHeight,this._el.slider_container.style.left="0px",f&&(this._swipable=new Ue(this._el.slider_container_mask,this._el.slider_container,{enable:{x:!0,y:!1},snap:!0}),this._swipable.enable(),this._message=new jt(this._el.container,{message_class:"tl-message-full",message_icon_class:"tl-icon-swipe-left"},this.getLanguage()),this._message.updateMessage(this._("swipe_to_navigate")),this._message.addTo(this._el.container));}_initEvents(){this._nav.next.on("clicked",this._onNavigation,this),this._nav.previous.on("clicked",this._onNavigation,this),this._message&&this._message.on("clicked",this._onMessageClick,this),this._swipable&&(this._swipable.on("swipe_left",this._onNavigation,this),this._swipable.on("swipe_right",this._onNavigation,this),this._swipable.on("swipe_nodirection",this._onSwipeNoDirection,this));}_initData(){this.data.title&&this._createSlide(this.data.title,!0,-1),this._createSlides(this.data.events);}
28_onBackgroundChange(t){var e=this._findSlideIndex(this.current_id),i=this._slides[e].getBackground();this.changeBackground(t),this.fire("colorchange",i);}_onMessageClick(t){this._message.hide();}_onSwipeNoDirection(t){this.goToId(this.current_id);}_onNavigation(t){"next"==t.direction||"left"==t.direction?this.next():"previous"!=t.direction&&"right"!=t.direction||this.previous(),this.fire("nav_"+t.direction,this.data);}_onSlideAdded(t){S("slideadded"),this.fire("slideAdded",this.data);}_onSlideRemoved(t){this.fire("slideRemoved",this.data);}_onSlideChange(t){t||this.fire("change",{unique_id:this.current_id});}_onMouseClick(t){}_fireMouseEvent(t){if(this._loaded){var e=t.type;e="mouseenter"===e?"mouseover":"mouseleave"===e?"mouseout":e,this.hasEventListeners(e)&&("contextmenu"===e&&ht.preventDefault(t),this.fire(e,{latlng:"something",layerPoint:"something else"}));}}_onLoaded(){this.fire("loaded",this.data);}}R(Ye,Rt,at);class Ze{constructor(t,e,i,a){this._el={parent:{},container:{},button_forwardtoend:{},button_backtostart:{},button_zoomin:{},button_zoomout:{},arrow:{},line:{},coverbar:{},grip:{}},this.collapsed=!1,this._el.container="object"==typeof t?t:g(t),e&&(this._el.parent=e),this.data={visible_ticks_dates:{}},this.options={width:600,height:600,duration:1e3,ease:et,menubar_default_y:0},this.animator={},this.setLanguage(a),E(this.options,i),this._initLayout(),this._initEvents();}show(t){this.options.duration;}hide(t){}toogleZoomIn(t){t?this._el.button_zoomin.removeAttribute("disabled"):this._el.button_zoomin.setAttribute("disabled",!0);}toogleZoomOut(t){t?this._el.button_zoomout.removeAttribute("disabled"):this._el.button_zoomout.setAttribute("disabled",!0);}changeVisibleTicks(t){const e=t.minor;if(!e.length)return void (this.data.visible_ticks_dates={});const i=e[0].date.getFullYear(),a=e[e.length-1].date.getFullYear();this.data.visible_ticks_dates={start:i,end:a},this._updateZoomAriaLabels();}setSticky(t){this.options.menubar_default_y=t;}setColor(t){this._el.container.className=t?"tl-menubar tl-menubar-inverted":"tl-menubar";}updateDisplay(t,e,i,a){this._updateDisplay(t,e,i,a);}_onButtonZoomIn(t){this.fire("zoom_in",t);}_onButtonZoomOut(t){this.fire("zoom_out",t);}_onButtonForwardToEnd(t){this.fire("forward_to_end",t);}_onButtonBackToStart(t){this.fire("back_to_start",t);}_initLayout(){this._el.button_zoomin=y("tl-menubar-button",this._el.container),this._el.button_zoomout=y("tl-menubar-button",this._el.container),this._el.button_forwardtoend=y("tl-menubar-button",this._el.container),this._el.button_backtostart=y("tl-menubar-button",this._el.container),h&&this._el.container.setAttribute("ontouchstart"," "),this._el.button_backtostart.innerHTML="<span class='tl-icon-goback'></span>",this._el.button_backtostart.setAttribute("aria-label",this._("return_to_title")),this._el.button_forwardtoend.innerHTML="<span class='tl-icon-goend'></span>",this._el.button_forwardtoend.setAttribute("aria-label",this._("go_to_end")),this._el.button_zoomin.innerHTML="<span class='tl-icon-zoom-in'></span>",this._el.button_zoomin.setAttribute("aria-label",this._("zoom_in")),this._el.button_zoomout.innerHTML="<span class='tl-icon-zoom-out'></span>",this._el.button_zoomout.setAttribute("aria-label",this._("zoom_out"));}_initEvents(){ht.addListener(this._el.button_forwardtoend,"click",this._onButtonForwardToEnd,this),ht.addListener(this._el.button_backtostart,"click",this._onButtonBackToStart,this),ht.addListener(this._el.button_zoomin,"click",this._onButtonZoomIn,this),ht.addListener(this._el.button_zoomout,"click",this._onButtonZoomOut,this);}_updateDisplay(t,e,i){t&&(this.options.width=t),e&&(this.options.height=e);}_updateZoomAriaLabels(){0==Object.keys(this.data.visible_ticks_dates).length?(this._el.button_zoomin.setAttribute("aria-description",""),this._el.button_zoomout.setAttribute("aria-description","")):(this._el.button_zoomin.setAttribute("aria-description",this._("aria_label_zoomin",this.data.visible_ticks_dates)),this._el.button_zoomout.setAttribute("aria-description",this._("aria_label_zoomout",this.data.visible_ticks_dates)));}}R(Ze,ot,at,Rt);let Ve=null;if(document){let t=document.getElementsByTagName("script");t&&t.length>0&&(Ve=t[t.length-1].src);}class Xe{constructor(t,e,i){if(i||(i={}),this.ready=!1,this._el={container:g(t),storyslider:{},timenav:{},menubar:{}},i.lang&&!i.language&&(i.language=i.lang),this.language=Ot,this._storyslider={},this._timenav={},this._menubar={},this._loaded={storyslider:!1,timenav:!1},this.config=null,this.options={script_path:"https://cdn.knightlab.com/libs/timeline3/latest/js/",height:this._el.container.offsetHeight,width:this._el.container.offsetWidth,debug:!1,font:"default",is_embed:!1,is_full_embed:!1,hash_bookmark:!1,default_bg_color:{r:255,g:255,b:255},scale_factor:2,layout:"landscape",timenav_position:"bottom",optimal_tick_width:60,base_class:"tl-timeline",timenav_height:null,timenav_height_percentage:25,timenav_mobile_height_percentage:40,timenav_height_min:175,marker_height_min:30,marker_width_min:100,marker_padding:5,start_at_slide:0,start_at_end:!1,menubar_height:0,skinny_size:650,medium_size:800,use_bc:!1,duration:1e3,ease:et,dragging:!0,trackResize:!0,map_type:"stamen:toner
28-lite",slide_padding_lr:100,slide_default_fade:"0%",zoom_sequence:[.5,1,2,3,5,8,13,21,34,55,89],language:"en",ga_measurement_id:null,ga_property_id:null,track_events:["back_to_start","nav_next","nav_previous","zoom_in","zoom_out"],theme:null,sheets_proxy:"https://sheets-proxy.knightlab.com/proxy/",soundcite:!1},this.animator_timenav=null,this.animator_storyslider=null,this.animator_menubar=null,this.message=new jt(this._el.container,{message_class:"tl-message-full"}),"string"==typeof i.default_bg_color){var a=M(i.default_bg_color);a?i.default_bg_color=a:(delete i.default_bg_color,S("Invalid default background color. Ignoring."));}var s,n;E(this.options,i),this.options.script_path||(this.options.script_path=this.determineScriptPath()),i.soundcite&&this.on("ready",(()=>{S("Loading Soundcite resources "),me("https://cdn.knightlab.com/libs/soundcite/latest/css/player.css"),ue("https://cdn.knightlab.com/libs/soundcite/latest/js/soundcite.min.js");})),this._loadStyles(),document.addEventListener("keydown",(s=this,function(t){if(s.config){var e=t.key,i=s._getSlideIndex(self.current_id),a=s.config.events.length-1,n=s.config.title?a+1:a;"ArrowLeft"==e?0!=i&&s.goToPrev():"ArrowRight"==e&&i!=n&&s.goToNext();}})),window.addEventListener("resize",function(t){this.updateDisplay();}.bind(this)),this.options.debug&&(n=console.log,D.push(n)),this._el.container.classList.add("tl-timeline"),this._el.container.setAttribute("tabindex","0"),this._el.container.setAttribute("role","region"),this._el.container.setAttribute("aria-label",this._("aria_label_timeline")),this.options.is_embed&&this._el.container.classList.add("tl-timeline-embed"),this.options.is_full_embed&&this._el.container.classList.add("tl-timeline-full-embed"),this._loadLanguage(e);}_loadStyles(){let t=null,e=null;if(this.options.font&&(0==this.options.font.indexOf("http")||this.options.font.match(/\.css$/)))t=this.options.font;else{if(this.options.font){let e="../css/fonts/font."+this.options.font.toLowerCase()+".css";t=new URL(e,this.options.script_path).toString();}}if(t&&me(t),this.options.theme&&(0==this.options.theme.indexOf("http")||this.options.theme.match(/\.css$/)))e=this.options.theme;else{if(this.options.theme){let t="../css/themes/timeline.theme."+this.options.theme.toLowerCase()+".css";e=new URL(t,this.options.script_path).toString();}}e&&me(e);}_loadLanguage(t){try{var e=this.options.language,i=this.options.script_path;(async function(t,e){var i=At(t,e);try{if(!It[t]){let e=await mt(i);It[t]=e;}return new Nt(t,e);}catch(t){return console.log(`Error loading language [${i}] ${t.statusText}`),null;}})(e,i).then(((i)=>{i?(this.language=i,this.message.setLanguage(this.language),this.showMessage(this._("loading_timeline"))):this.showMessage(`Error loading ${e}`),this._initData(t);}));}catch(t){this.showMessage(this._translateError(t));}}_initData(t){"string"==typeof t?async function(t,e){let i=null,a={};if(a=e,i=e.callback,"function"==typeof a.callback&&(i=a.callback),!i)throw new x("Second argument to makeConfig must be either a function or an object which includes a 'callback' property with a 'function' type value");var s,n;if(Kt(t)){try{n=await te(t,a);}catch(t){return s=new Zt(),"NetworkError"==t.name?s.logError(new x("network_err")):"TLError"==t.name?s.logError(t):s.logError(new x("unknown_read_err",t.name)),void i(s);}if(s=new Zt(n),n.errors)for(var o=0;o<n.errors.length;o++)s.logError(n.errors[o]);i(s);}else ut({url:t,dataType:"json",success:function(t){try{s=new Zt(t);}catch(t){(s=new Zt()).logError(t);}i(s);},error:function(t,e,a){s=new Zt(),a="parsererror"==e?new x("invalid_url_err"):new x("unknown_read_err",e),s.logError(a),i(s);}});}(t,{callback:function(t){this.setConfig(t);}.bind(this),sheets_proxy:this.options.sheets_proxy}):Zt==t.constructor?this.setConfig(t):this.setConfig(new Zt(t));}_translateError(t){return t.hasOwnProperty("stack")&&S(t.stack),t.message_key?this._(t.message_key)+(t.detail?" ["+t.detail+"]":""):t;}showMessage(t){this.message?this.message.updateMessage(t):(S("No message display available."),S(t));}determineScriptPath(){let t=null;if(Ve)t=Ve;else{let e=document.getElementById("timeline-script-tag");e&&(t=e.src);}if(!t){let e=document.getElementsByTagName("script");for(let i=e.length-1;i>=0;i--)if(e[i].src){t=e[i].src;break;}}return t?t.substr(0,t.lastIndexOf("/")+1):"";}setConfig(t){if(this.config=t,this.config.isValid()&&(this.config.validate(),this._val
28idateOptions()),this.config.isValid())try{"loading"===document.readyState?document.addEventListener("DOMContentLoaded",this._onDataLoaded.bind(this)):this._onDataLoaded();}catch(t){this.showMessage("<strong>"+this._("error")+":</strong> "+this._translateError(t));}else{for(var e=[],i=0,a=this.config.getErrors();i<a.length;i++)e.push(this._translateError(a[i]));this.showMessage("<strong>"+this._("error")+":</strong> "+e.join("<br>"));}}_onDataLoaded(){this.fire("dataloaded"),this._initLayout(),this._initEvents(),this._initAnalytics(),this.message&&this.message.hide(),new IntersectionObserver(((t,e)=>{t.reduce(((t,e)=>t||e.isIntersecting),!1)&&this.updateDisplay();}).bind(this)).observe(this._el.container),this.ready=!0,this.fire("ready");}_initLayout(){this.message.removeFrom(this._el.container),this._el.container.innerHTML="","top"==this.options.timenav_position?(this._el.timenav=v("div","tl-timenav",this._el.container),this._el.menubar=v("div","tl-menubar",this._el.container),this._el.storyslider=v("div","tl-storyslider",this._el.container)):(this._el.storyslider=v("div","tl-storyslider",this._el.container),this._el.timenav=v("div","tl-timenav",this._el.container),this._el.menubar=v("div","tl-menubar",this._el.container)),this._el.attribution=v("div","tl-attribution",this._el.container),this._el.attribution.innerHTML="<a href='https://timeline.knightlab.com' target='_blank' rel='noopener'><span class='tl-knightlab-logo'></span>TimelineJS</a>",this.options.width=this._el.container.offsetWidth,this.options.height=this._el.container.offsetHeight,this.options.timenav_height=this._calculateTimeNavHeight(this.options.timenav_height),this._timenav=new Be(this._el.timenav,this.config,this.options,this.language),this._timenav.on("loaded",this._onTimeNavLoaded,this),this._timenav.options.height=this.options.timenav_height,this._timenav.init(),this.options.initial_zoom&&this.setZoom(this.options.initial_zoom),this._storyslider=new Ye(this._el.storyslider,this.config,this.options,this.language),this._el.storyslider.setAttribute("role","group"),this._el.storyslider.setAttribute("aria-label",this._("aria_label_timeline_content")),this._storyslider.on("loaded",this._onStorySliderLoaded,this),this._storyslider.init(),this._menubar=new Ze(this._el.menubar,this._el.container,this.options,this.getLanguage()),"portrait"==this.options.layout?this.options.storyslider_height=this.options.height-this.options.timenav_height-1:this.options.storyslider_height=this.options.height-1,this._updateDisplay();}_initEvents(){this._timenav.on("change",this._onTimeNavChange,this),this._timenav.on("zoomtoggle",this._onZoomToggle,this),this._timenav.on("visible_ticks_change",this._onVisibleTicksChange,this),this._storyslider.on("change",this._onSlideChange,this),this._storyslider.on("colorchange",this._onColorChange,this),this._storyslider.on("nav_next",this._onStorySliderNext,this),this._storyslider.on("nav_previous",this._onStorySliderPrevious,this),this._menubar.on("zoom_in",this._onZoomIn,this),this._menubar.on("zoom_out",this._onZoomOut,this),this._menubar.on("forward_to_end",this._onForwardToEnd,this),this._menubar.on("back_to_start",this._onBackToStart,this);}_onColorChange(t){this.fire("color_change",{unique_id:this.current_id},this);}_onSlideChange(t){this.current_id!=t.unique_id&&(this.current_id=t.unique_id,this._timenav.goToId(this.current_id),this._onChange(t));}_onTimeNavChange(t){this.current_id!=t.unique_id&&(this.current_id=t.unique_id,this._storyslider.goToId(this.current_id),this._onChange(t));}_onZoomToggle(t){"in"==t.zoom?this._menubar.toogleZoomIn(t.show):"out"==t.zoom&&this._menubar.toogleZoomOut(t.show);}_onChange(t){this.fire("change",{unique_id:this.current_id},this),this.options.hash_bookmark&&this.current_id&&this._updateHashBookmark(this.current_id);}_onVisibleTicksChange(t){this._menubar.changeVisibleTicks(t.visible_ticks);}_onForwardToEnd(t){this.goToEnd(),this.fire("forward_to_end",{unique_id:this.current_id},this);}_onBackToStart(t){this.goToStart(),this.fire("back_to_start",{unique_id:this.current_id},this);}_onZoomIn(t){this._timenav.zoomIn(),this.fire("zoom_in",{zoom_level:this._timenav.options.scale_factor},this);}_onZoomOut(t){this._timenav.zoomOut(),this.fire("zoom_out",{zoom_level:this._timenav.options.scale_factor},this);}_onTimeNavLoaded(){this._loaded.timenav=!0,this._onLoaded();}_onStorySliderLoaded(){this._loaded.storyslider=!0,this._onLoaded();}_onStorySliderNext(t){this.fire("nav_next",t);}_onStorySliderPrevious(t){this.fire("nav_previous",t);}_updateDisplay(t,e,i){var a,s,n=this.options.duration,o=this.options.base_class;i&&(n=i),this.options.width=this._el.container.offsetWidth,this.options.height=this._el.container.offsetHeight,this.options.width<=this.options.skinny_size?(o+=" tl-skinny",this.options.layout="portrait"):this.options.width<=this.options.medium_size?(o+=" tl-medium",this.options.layout="landscape"):this.options.layout="landscape",f&&(this.options.layout=(a="portrait",window.innerWidth>window.innerHeight&&(a="landscape"),Math.abs(window.orientation),a)),h?(o+=" tl-mobile",this.options.timenav_height=this._calculateTimeNavHeight(t,this.options.timenav_mobile_height_percentage)):this.options.timenav_height=this._calculateTimeNavHeight(t),"portrait"==this.options.layout?o+=" tl-layout-portrait":o+=" tl-layout-landscape",this.options.storyslider_height=this.options.height-this.options.timenav_height,s="top"==this.options.timenav_position?Math.ceil(this.options.timenav_height)/2-this._el.menubar.offsetHeight/2-19.5:Math.round(this.options.storyslider_height+1+Math.ceil(this.options.timenav_height)/2-this._el.menubar.offsetHeight/2-17.5),e?(this._el.timenav.style.height=Math.ceil(this.options.timenav_height)+"px",this.animator_storyslider&&this.animator_storyslider.stop(),this.animator_storyslider=st(this._el.storyslider,{height:this.options.storyslider_height+"px",duration:n/2,easing:tt}
28),this.animator_menubar&&this.animator_menubar.stop(),this.animator_menubar=st(this._el.menubar,{top:s+"px",duration:n/2,easing:tt})):(this._el.timenav.style.height=Math.ceil(this.options.timenav_height)+"px",this._el.storyslider.style.height=this.options.storyslider_height+"px",this._el.menubar.style.top=s+"px"),this.message&&this.message.updateDisplay(this.options.width,this.options.height),this._timenav.updateDisplay(this.options.width,this.options.timenav_height,e),this._storyslider.updateDisplay(this.options.width,this.options.storyslider_height,e,this.options.layout),"rtl"==this.language.direction&&(o+=" tl-rtl"),this._el.container.className=o;}_calculateTimeNavHeight(t,e){var i=0;return (this.options.timenav_height_percentage||e)&&(i=e?Math.round(this.options.height/100*e):Math.round(this.options.height/100*this.options.timenav_height_percentage)),this._timenav.ready&&this.options.timenav_height_min<this._timenav.getMinimumHeight()&&(this.options.timenav_height_min=this._timenav.getMinimumHeight()),i<this.options.timenav_height_min&&(i=this.options.timenav_height_min),i-2*this.options.marker_padding;}_validateOptions(){for(var t=["timenav_height","timenav_height_min","marker_height_min","marker_width_min","marker_padding","start_at_slide","slide_padding_lr"],e=0;e<t.length;e++){var i=t[e],a=this.options[i];let s=!0;"number"==typeof a?s=a==parseInt(a):"string"==typeof a&&(s=a.match(/^\s*(\-?\d+)?\s*$/)),s||this.config.logError({message_key:"invalid_integer_option",detail:i});}}_getSlideIndex(t){if(this.config){if(this.config.title&&this.config.title.unique_id==t)return 0;for(var e=0;e<this.config.events.length;e++)if(t==this.config.events[e].unique_id)return this.config.title?e+1:e;}return -1;}_getEventIndex(t){for(var e=0;e<this.config.events.length;e++)if(t==this.config.events[e].unique_id)return e;return -1;}_onLoaded(){if(this._loaded.storyslider&&this._loaded.timenav&&(this.fire("loaded",this.config),null!=(t=this.options.start_at_end)&&(1==t||"true"==String(t).toLowerCase()||1==Number(t))||this.options.start_at_slide>this.config.events.length?this.goToEnd():this.goTo(this.options.start_at_slide),this.options.hash_bookmark)){""!=window.location.hash?this.goToId(window.location.hash.replace("#event-","")):this._updateHashBookmark(this.current_id);let t=this;window.addEventListener("hashchange",(function(){0==window.location.hash.indexOf("#event-")&&t.goToId(window.location.hash.replace("#event-",""));}),!1);}var t;}_updateHashBookmark(t){if(t){var e="#event-"+t.toString();window.history.replaceState(null,"Browsing TimelineJS",e),this.fire("hash_updated",{unique_id:this.current_id,hashbookmark:"#event-"+t.toString()},this);}}zoomIn(){this._timenav.zoomIn();}zoomOut(){this._timenav.zoomOut();}setZoom(t){this._timenav.setZoom(t);}goToId(t){this.current_id!=t&&(this.current_id=t,this._timenav.goToId(this.current_id),this._storyslider.goToId(this.current_id,!1,!0),this.fire("change",{unique_id:this.current_id},this));}goTo(t){if(!(t<0))try{this.config.title?0===t?this.goToId(this.config.title.unique_id):this.goToId(this.config.events[t-1].unique_id):this.goToId(this.config.events[t].unique_id);}catch{return;}}goToStart(){this.goTo(0);}goToEnd(){var t=this.config.events.length-1;this.goTo(this.config.title?t+1:t);}goToPrev(){this.goTo(this._getSlideIndex(this.current_id)-1),this.focusContainer();}goToNext(){this.goTo(this._getSlideIndex(this.current_id)+1),this.focusContainer();}add(t){var e=this.config.addEvent(t),i=this._getEventIndex(e),a=this.config.events[i];this._storyslider.createSlide(a,this.config.title?i+1:i),this._storyslider._updateDrawSlides(),this._timenav.createMarker(a,i),this._timenav._updateDrawTimeline(!1),this.fire("added",{unique_id:e});}remove(t){if(t>=0&&t<this.config.events.length){this.config.events[t].unique_id==this.current_id&&(t<this.config.events.length-1?this.goTo(t+1):this.goTo(t-1));var e=this.config.events.splice(t,1);delete this.config.event_dict[e[0].unique_id],this._storyslider.destroySlide(this.config.title?t+1:t),this._storyslider._updateDrawSlides(),this._timenav.destroyMarker(t),this._timenav._updateDrawTimeline(!1),this.fire("removed",{unique_id:e[0].unique_id});}}removeId(t){this.remove(this._getEventIndex(t));}getData(t){if(this.config.title){if(0==t)return this.config.title;if(t>0&&t<=this.config.events.length)return this.config.events[t-1];}else{if(t>=0&&t<this.config.events.length)return this.config.events[t];}return null;}getDataById(t){return this.getData(this._getSlideIndex(t));}getSlide(t){return t>=0&&t<this._storyslider._slides.length?this._storyslider._slides[t]:null;}
28getSlideById(t){return this.getSlide(this._getSlideIndex(t));}getCurrentSlide(){return this.getSlideById(this.current_id);}updateDisplay(){this.ready?this._updateDisplay():S("updateDisplay called but timeline is not in ready state");}focusContainer(){this._el.container.focus();}_initGoogleAnalytics(t){ue(`https://www.googletagmanager.com/gtag/js?id=${t}`),window.dataLayer=window.dataLayer||[],window.gtag=function(){dataLayer.push(arguments);},gtag("js",new Date()),gtag("config",t);}_initAnalytics(){let t=this.options.ga_measurement_id||this.options.ga_property_id||null;if(t){this._initGoogleAnalytics(t);var e=this.options.track_events;for(let t=0;t<e.length;t++){var i=e[t];this.addEventListener(i,(function(t){gtag("event",t.type);}));}}}}async function Je(t,e){return e||(e="https://sheets-proxy.knightlab.com/proxy/"),await te(t,{sheets_proxy:e});}R(Xe,Rt,at);})(),TL=a;})();; 29(function mskAjaxOverrides(window,Drupal,drupalSettings){'use strict';Drupal.theme.ajaxProgressIndicatorFullscreen=function ajaxProgressIndicatorFullscreen(){return '<div class="msk-loading-ring msk-loading-ring--fullscreen"><div class="msk-loading-ring__segment"></div><div class="msk-loading-ring__segment"></div><div class="msk-loading-ring__segment"></div><div class="msk-loading-ring__segment"></div></div>';};})(window,Drupal,drupalSettings);; 30(function () { 31 'use strict'; 32 33 function _arrayLikeToArray(r, a) { 34 (null == a || a > r.length) && (a = r.length); 35 for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; 36 return n; 37 } 38 function _arrayWithHoles(r) { 39 if (Array.isArray(r)) return r; 40 } 41 function _arrayWithoutHoles(r) { 42 if (Array.isArray(r)) return _arrayLikeToArray(r); 43 } 44 function _classCallCheck$1(a, n) { 45 if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); 46 } 47 function _defineProperties$1(e, r) { 48 for (var t = 0; t < r.length; t++) { 49 var o = r[t]; 50 o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); 51 } 52 } 53 function _createClass$1(e, r, t) { 54 return r && _defineProperties$1(e.prototype, r), t && _defineProperties$1(e, t), Object.defineProperty(e, "prototype", { 55 writable: !1 56 }), e; 57 } 58 function _defineProperty(e, r, t) { 59 return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { 60 value: t, 61 enumerable: !0, 62 configurable: !0, 63 writable: !0 64 }) : e[r] = t, e; 65 } 66 function _iterableToArray(r) { 67 if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); 68 } 69 function _iterableToArrayLimit(r, l) { 70 var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; 71 if (null != t) { 72 var e, 73 n, 74 i, 75 u, 76 a = [], 77 f = !0, 78 o = !1; 79 try { 80 if (i = (t = t.call(r)).next, 0 === l) { 81 if (Object(t) !== t) return; 82 f = !1; 83 } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); 84 } catch (r) { 85 o = !0, n = r; 86 } finally { 87 try { 88 if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; 89 } finally { 90 if (o) throw n; 91 } 92 } 93 return a; 94 } 95 } 96 function _nonIterableRest() { 97 throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); 98 } 99 function _nonIterableSpread() { 100 throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); 101 } 102 function _slicedToArray(r, e) { 103 return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); 104 } 105 function _toConsumableArray(r) { 106 return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); 107 } 108 function _toPrimitive(t, r) { 109 if ("object" != typeof t || !t) return t; 110 var e = t[Symbol.toPrimitive]; 111 if (void 0 !== e) { 112 var i = e.call(t, r || "default"); 113 if ("object" != typeof i) return i; 114 throw new TypeError("@@toPrimitive must return a primitive value."); 115 } 116 return ("string" === r ? String : Number)(t); 117 } 118 function _toPropertyKey(t) { 119 var i = _toPrimitive(t, "string"); 120 return "symbol" == typeof i ? i : i + ""; 121 } 122 function _typeof$1(o) { 123 "@babel/helpers - typeof"; 124 125 return _typeof$1 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { 126 return typeof o; 127 } : function (o) { 128 return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; 129 }, _typeof$1(o); 130 } 131 function _unsupportedIterableToArray(r, a) { 132 if (r) { 133 if ("string" == typeof r) return _arrayLikeToArray(r, a); 134 var t = {}.toString.call(r).slice(8, -1); 135 return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; 136 } 137 } 138 139 var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; 140 141 var pep = {exports: {}}; 142 143 /*! 144 * PEP v0.5.1 | https://github.com/jquery/PEP 145 * Copyright jQuery Foundation and other contributors | http://jquery.org/license 146 */
147 (function (module, exports) { 148 (function (global, factory) { 149 module.exports = factory() ; 150 })(commonjsGlobal, function () { 151 152 /** 153 * This is the constructor for new PointerEvents. 154 * 155 * New Pointer Events must be given a type, and an optional dictionary of 156 * initialization properties. 157 * 158 * Due to certain platform requirements, events returned from the constructor 159 * identify as MouseEvents. 160 * 161 * @constructor 162 * @param {String} inType The type of the event to create. 163 * @param {Object} [inDict] An optional dictionary of initial event properties. 164 * @return {Event} A new PointerEvent of type `inType`, initialized with properties from `inDict`. 165 */ 166 var MOUSE_PROPS = ['bubbles', 'cancelable', 'view', 'screenX', 'screenY', 'clientX', 'clientY', 'ctrlKey', 'altKey', 'shiftKey', 'metaKey', 'button', 'relatedTarget', 'pageX', 'pageY']; 167 var MOUSE_DEFAULTS = [false, false, null, 0, 0, 0, 0, false, false, false, false, 0, null, 0, 0]; 168 function PointerEvent(inType, inDict) { 169 inDict = inDict || Object.create(null); 170 var e = document.createEvent('Event'); 171 e.initEvent(inType, inDict.bubbles || false, inDict.cancelable || false); 172 173 // define inherited MouseEvent properties 174 // skip bubbles and cancelable since they're set above in initEvent() 175 for (var i = 2, p; i < MOUSE_PROPS.length; i++) { 176 p = MOUSE_PROPS[i]; 177 e[p] = inDict[p] || MOUSE_DEFAULTS[i]; 178 } 179 e.buttons = inDict.buttons || 0; 180 181 // Spec requires that pointers without pressure specified use 0.5 for down 182 // state and 0 for up state. 183 var pressure = 0; 184 if (inDict.pressure !== undefined && e.buttons) { 185 pressure = inDict.pressure; 186 } else { 187 pressure = e.buttons ? 0.5 : 0; 188 } 189 190 // add x/y properties aliased to clientX/Y 191 e.x = e.clientX; 192 e.y = e.clientY; 193 194 // define the properties of the PointerEvent interface 195 e.pointerId = inDict.pointerId || 0; 196 e.width = inDict.width || 1; 197 e.height = inDict.height || 1; 198 e.pressure = pressure; 199 e.tiltX = inDict.tiltX || 0; 200 e.tiltY = inDict.tiltY || 0; 201 e.twist = inDict.twist || 0; 202 e.tangentialPressure = inDict.tangentialPressure || 0; 203 e.pointerType = inDict.pointerType || ''; 204 e.hwTimestamp = inDict.hwTimestamp || 0; 205 e.isPrimary = inDict.isPrimary || false; 206 e.detail = 0; 207 return e; 208 } 209 210 /** 211 * This module implements a map of pointer states 212 */ 213 var USE_MAP = window.Map && window.Map.prototype.forEach; 214 var PointerMap = USE_MAP ? Map : SparseArrayMap; 215 function SparseArrayMap() { 216 this.array = []; 217 this.size = 0; 218 } 219 SparseArrayMap.prototype = { 220 set: function set(k, v) { 221 if (v === undefined) { 222 return this.delete(k); 223 } 224 if (!this.has(k)) { 225 this.size++; 226 } 227 this.array[k] = v; 228 }, 229 has: function has(k) { 230 return this.array[k] !== undefined; 231 }, 232 delete: function _delete(k) { 233 if (this.has(k)) { 234 delete this.array[k]; 235 this.size--; 236 } 237 }, 238 get: function get(k) { 239 return this.array[k]; 240 }, 241 clear: function clear() { 242 this.array.length = 0; 243 this.size = 0; 244 }, 245 // return value, key, map 246 forEach: function forEach(callback, thisArg) { 247 return this.array.forEach(function (v, k) { 248 callback.call(thisArg, v, k, this); 249 }, this); 250 } 251 }; 252 var CLONE_PROPS = [ 253 // MouseEvent 254 'bubbles', 'cancelable', 'view', 'detail', 'screenX', 'screenY', 'clientX', 'clientY', 'ctrlKey', 'altKey', 'shiftKey', 'metaKey', 'button', 'relatedTarget', 255 // DOM Level 3 256 'buttons', 257 // PointerEvent 258 'pointerId', 'width', 'height', 'pressure', 'tiltX', 'tiltY', 'pointerType', 'hwT
258imestamp', 'isPrimary', 259 // event instance 260 'type', 'target', 'currentTarget', 'which', 'pageX', 'pageY', 'timeStamp']; 261 var CLONE_DEFAULTS = [ 262 // MouseEvent 263 false, false, null, null, 0, 0, 0, 0, false, false, false, false, 0, null, 264 // DOM Level 3 265 0, 266 // PointerEvent 267 0, 0, 0, 0, 0, 0, '', 0, false, 268 // event instance 269 '', null, null, 0, 0, 0, 0]; 270 var BOUNDARY_EVENTS = { 271 'pointerover': 1, 272 'pointerout': 1, 273 'pointerenter': 1, 274 'pointerleave': 1 275 }; 276 var HAS_SVG_INSTANCE = typeof SVGElementInstance !== 'undefined'; 277 278 /** 279 * This module is for normalizing events. Mouse and Touch events will be 280 * collected here, and fire PointerEvents that have the same semantics, no 281 * matter the source. 282 * Events fired: 283 * - pointerdown: a pointing is added 284 * - pointerup: a pointer is removed 285 * - pointermove: a pointer is moved 286 * - pointerover: a pointer crosses into an element 287 * - pointerout: a pointer leaves an element 288 * - pointercancel: a pointer will no longer generate events 289 */ 290 var dispatcher = { 291 pointermap: new PointerMap(), 292 eventMap: Object.create(null), 293 captureInfo: Object.create(null), 294 // Scope objects for native events. 295 // This exists for ease of testing. 296 eventSources: Object.create(null), 297 eventSourceList: [], 298 /** 299 * Add a new event source that will generate pointer events. 300 * 301 * `inSource` must contain an array of event names named `events`, and 302 * functions with the names specified in the `events` array. 303 * @param {string} name A name for the event source 304 * @param {Object} source A new source of platform events. 305 */ 306 registerSource: function registerSource(name, source) { 307 var s = source; 308 var newEvents = s.events; 309 if (newEvents) { 310 newEvents.forEach(function (e) { 311 if (s[e]) { 312 this.eventMap[e] = s[e].bind(s); 313 } 314 }, this); 315 this.eventSources[name] = s; 316 this.eventSourceList.push(s); 317 } 318 }, 319 register: function register(element) { 320 var l = this.eventSourceList.length; 321 for (var i = 0, es; i < l && (es = this.eventSourceList[i]); i++) { 322 // call eventsource register 323 es.register.call(es, element); 324 } 325 }, 326 unregister: function unregister(element) { 327 var l = this.eventSourceList.length; 328 for (var i = 0, es; i < l && (es = this.eventSourceList[i]); i++) { 329 // call eventsource register 330 es.unregister.call(es, element); 331 } 332 }, 333 contains: /*scope.external.contains || */function contains(container, contained) { 334 try { 335 return container.contains(contained); 336 } catch (ex) { 337 // most likely: https://bugzilla.mozilla.org/show_bug.cgi?id=208427 338 return false; 339 } 340 }, 341 // EVENTS 342 down: function down(inEvent) { 343 inEvent.bubbles = true; 344 this.fireEvent('pointerdown', inEvent); 345 }, 346 move: function move(inEvent) { 347 inEvent.bubbles = true; 348 this.fireEvent('pointermove', inEvent); 349 }, 350 up: function up(inEvent) { 351 inEvent.bubbles = true; 352 this.fireEvent('pointerup', inEvent); 353 }, 354 enter: function enter(inEvent) { 355 inEvent.bubbles = false; 356 this.fireEvent('pointerenter', inEvent); 357 }, 358 leave: function leave(inEvent) { 359 inEvent.bubbles = false; 360 this.fireEvent('pointerleave', inEvent); 361 }, 362 over: function over(inEvent) { 363 inEvent.bubbles = true; 364 this.fireEvent('pointerover', inEvent); 365 }, 366 out: function out(inEvent) { 367 inEvent.bubbles = true; 368 this.fireEvent('pointerout', inEvent); 369 }, 370 cancel: function cancel(inEvent) { 371 inEvent.bubbles = true; 372 this.fireEvent('pointercancel', inEvent); 373 }, 374 leaveOut: function leaveOut(event) { 375 this.out(event);
376 this.propagate(event, this.leave, false); 377 }, 378 enterOver: function enterOver(event) { 379 this.over(event); 380 this.propagate(event, this.enter, true); 381 }, 382 // LISTENER LOGIC 383 eventHandler: function eventHandler(inEvent) { 384 // This is used to prevent multiple dispatch of pointerevents from 385 // platform events. This can happen when two elements in different scopes 386 // are set up to create pointer events, which is relevant to Shadow DOM. 387 if (inEvent._handledByPE) { 388 return; 389 } 390 var type = inEvent.type; 391 var fn = this.eventMap && this.eventMap[type]; 392 if (fn) { 393 fn(inEvent); 394 } 395 inEvent._handledByPE = true; 396 }, 397 // set up event listeners 398 listen: function listen(target, events) { 399 events.forEach(function (e) { 400 this.addEvent(target, e); 401 }, this); 402 }, 403 // remove event listeners 404 unlisten: function unlisten(target, events) { 405 events.forEach(function (e) { 406 this.removeEvent(target, e); 407 }, this); 408 }, 409 addEvent: /*scope.external.addEvent || */function addEvent(target, eventName) { 410 target.addEventListener(eventName, this.boundHandler); 411 }, 412 removeEvent: /*scope.external.removeEvent || */function removeEvent(target, eventName) { 413 target.removeEventListener(eventName, this.boundHandler); 414 }, 415 // EVENT CREATION AND TRACKING 416 /** 417 * Creates a new Event of type `inType`, based on the information in 418 * `inEvent`. 419 * 420 * @param {string} inType A string representing the type of event to create 421 * @param {Event} inEvent A platform event with a target 422 * @return {Event} A PointerEvent of type `inType` 423 */ 424 makeEvent: function makeEvent(inType, inEvent) { 425 // relatedTarget must be null if pointer is captured 426 if (this.captureInfo[inEvent.pointerId]) { 427 inEvent.relatedTarget = null; 428 } 429 var e = new PointerEvent(inType, inEvent); 430 if (inEvent.preventDefault) { 431 e.preventDefault = inEvent.preventDefault; 432 } 433 e._target = e._target || inEvent.target; 434 return e; 435 }, 436 // make and dispatch an event in one call 437 fireEvent: function fireEvent(inType, inEvent) { 438 var e = this.makeEvent(inType, inEvent); 439 return this.dispatchEvent(e); 440 }, 441 /** 442 * Returns a snapshot of inEvent, with writable properties. 443 * 444 * @param {Event} inEvent An event that contains properties to copy. 445 * @return {Object} An object containing shallow copies of `inEvent`'s 446 * properties. 447 */ 448 cloneEvent: function cloneEvent(inEvent) { 449 var eventCopy = Object.create(null); 450 var p; 451 for (var i = 0; i < CLONE_PROPS.length; i++) { 452 p = CLONE_PROPS[i]; 453 eventCopy[p] = inEvent[p] || CLONE_DEFAULTS[i]; 454 455 // Work around SVGInstanceElement shadow tree 456 // Return the <use> element that is represented by the instance for Safari, Chrome, IE. 457 // This is the behavior implemented by Firefox. 458 if (HAS_SVG_INSTANCE && (p === 'target' || p === 'relatedTarget')) { 459 if (eventCopy[p] instanceof SVGElementInstance) { 460 eventCopy[p] = eventCopy[p].correspondingUseElement; 461 } 462 } 463 } 464 465 // keep the semantics of preventDefault 466 if (inEvent.preventDefault) { 467 eventCopy.preventDefault = function () { 468 inEvent.preventDefault(); 469 }; 470 } 471 return eventCopy; 472 }, 473 getTarget: function getTarget(inEvent) { 474 var capture = this.captureInfo[inEvent.pointerId]; 475 if (!capture) { 476 return inEvent._target; 477 } 478 if (inEvent._target === capture || !(inEvent.type in BOUNDARY_EVENTS)) { 479 return capture; 480 } 481 }, 482 propagate: function propagate(event, fn, propagateDown) { 483 var target = event.target; 484 var targets = []; 485 486 // Order of conditions due to document.contains() missing in IE. 487 while (target != null && target !== document && !target.contains(event.relatedTarget)) { 488 targets.push(target); 489 target = target.parentNode; 490 491 // Touch: Do not propagate if node is detached. 492 if (!target) { 493 return; 494 } 495 } 496 if (propagateDown) { 497 targets.reverse(); 498 }
499 targets.forEach(function (target) { 500 event.target = target; 501 fn.call(this, event); 502 }, this); 503 }, 504 setCapture: function setCapture(inPointerId, inTarget, skipDispatch) { 505 if (this.captureInfo[inPointerId]) { 506 this.releaseCapture(inPointerId, skipDispatch); 507 } 508 this.captureInfo[inPointerId] = inTarget; 509 this.implicitRelease = this.releaseCapture.bind(this, inPointerId, skipDispatch); 510 document.addEventListener('pointerup', this.implicitRelease); 511 document.addEventListener('pointercancel', this.implicitRelease); 512 var e = new PointerEvent('gotpointercapture', { 513 bubbles: true 514 }); 515 e.pointerId = inPointerId; 516 e._target = inTarget; 517 if (!skipDispatch) { 518 this.asyncDispatchEvent(e); 519 } 520 }, 521 releaseCapture: function releaseCapture(inPointerId, skipDispatch) { 522 var t = this.captureInfo[inPointerId]; 523 if (!t) { 524 return; 525 } 526 this.captureInfo[inPointerId] = undefined; 527 document.removeEventListener('pointerup', this.implicitRelease); 528 document.removeEventListener('pointercancel', this.implicitRelease); 529 var e = new PointerEvent('lostpointercapture', { 530 bubbles: true 531 }); 532 e.pointerId = inPointerId; 533 e._target = t; 534 if (!skipDispatch) { 535 this.asyncDispatchEvent(e); 536 } 537 }, 538 /** 539 * Dispatches the event to its target. 540 * 541 * @param {Event} inEvent The event to be dispatched. 542 * @return {Boolean} True if an event handler returns true, false otherwise. 543 */ 544 dispatchEvent: /*scope.external.dispatchEvent || */function dispatchEvent(inEvent) { 545 var t = this.getTarget(inEvent); 546 if (t) { 547 return t.dispatchEvent(inEvent); 548 } 549 }, 550 asyncDispatchEvent: function asyncDispatchEvent(inEvent) { 551 requestAnimationFrame(this.dispatchEvent.bind(this, inEvent)); 552 } 553 }; 554 dispatcher.boundHandler = dispatcher.eventHandler.bind(dispatcher); 555 var targeting = { 556 shadow: function shadow(inEl) { 557 if (inEl) { 558 return inEl.shadowRoot || inEl.webkitShadowRoot; 559 } 560 }, 561 canTarget: function canTarget(shadow) { 562 return shadow && Boolean(shadow.elementFromPoint); 563 }, 564 targetingShadow: function targetingShadow(inEl) { 565 var s = this.shadow(inEl); 566 if (this.canTarget(s)) { 567 return s; 568 } 569 }, 570 olderShadow: function olderShadow(shadow) { 571 var os = shadow.olderShadowRoot; 572 if (!os) { 573 var se = shadow.querySelector('shadow'); 574 if (se) { 575 os = se.olderShadowRoot; 576 } 577 } 578 return os; 579 }, 580 allShadows: function allShadows(element) { 581 var shadows = []; 582 var s = this.shadow(element); 583 while (s) { 584 shadows.push(s); 585 s = this.olderShadow(s); 586 } 587 return shadows; 588 }, 589 searchRoot: function searchRoot(inRoot, x, y) { 590 if (inRoot) { 591 var t = inRoot.elementFromPoint(x, y); 592 var st, sr; 593 594 // is element a shadow host? 595 sr = this.targetingShadow(t); 596 while (sr) { 597 // find the the element inside the shadow root 598 st = sr.elementFromPoint(x, y); 599 if (!st) { 600 // check for older shadows 601 sr = this.olderShadow(sr); 602 } else { 603 // shadowed element may contain a shadow root 604 var ssr = this.targetingShadow(st); 605 return this.searchRoot(ssr, x, y) || st; 606 } 607 } 608 609 // light dom element is the target 610 return t; 611 } 612 }, 613 owner: function owner(element) { 614 var s = element; 615 616 // walk up until you hit the shadow root or document 617 while (s.parentNode) { 618 s = s.parentNode; 619 } 620 621 // the owner element is expected to be a Document or ShadowRoot 622 if (s.nodeType !== Node.DOCUMENT_NODE && s.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) { 623 s = document; 624 } 625 return s; 626 }, 627 findTarget: function findTarget(inEvent) { 628 var x = inEvent.clientX; 629 var y = inEvent.clientY; 630 631 // if the listener is in the shadow root, it is much faster to start there 632 var s = this.owner(inEvent.target); 633 634 // if x, y is not in this root, fall back to document search 635 if (!s.elementFromPoint(x, y)) { 636 s = document; 637 } 638 return this.searchRoot(s, x, y); 639 } 640 };
641 var forEach = Array.prototype.forEach.call.bind(Array.prototype.forEach); 642 var map = Array.prototype.map.call.bind(Array.prototype.map); 643 var toArray = Array.prototype.slice.call.bind(Array.prototype.slice); 644 var filter = Array.prototype.filter.call.bind(Array.prototype.filter); 645 var MO = window.MutationObserver || window.WebKitMutationObserver; 646 var SELECTOR = '[touch-action]'; 647 var OBSERVER_INIT = { 648 subtree: true, 649 childList: true, 650 attributes: true, 651 attributeOldValue: true, 652 attributeFilter: ['touch-action'] 653 }; 654 function Installer(add, remove, changed, binder) { 655 this.addCallback = add.bind(binder); 656 this.removeCallback = remove.bind(binder); 657 this.changedCallback = changed.bind(binder); 658 if (MO) { 659 this.observer = new MO(this.mutationWatcher.bind(this)); 660 } 661 } 662 Installer.prototype = { 663 watchSubtree: function watchSubtree(target) { 664 // Only watch scopes that can target find, as these are top-level. 665 // Otherwise we can see duplicate additions and removals that add noise. 666 // 667 // TODO(dfreedman): For some instances with ShadowDOMPolyfill, we can see 668 // a removal without an insertion when a node is redistributed among 669 // shadows. Since it all ends up correct in the document, watching only 670 // the document will yield the correct mutations to watch. 671 if (this.observer && targeting.canTarget(target)) { 672 this.observer.observe(target, OBSERVER_INIT); 673 } 674 }, 675 enableOnSubtree: function enableOnSubtree(target) { 676 this.watchSubtree(target); 677 if (target === document && document.readyState !== 'complete') { 678 this.installOnLoad(); 679 } else { 680 this.installNewSubtree(target); 681 } 682 }, 683 installNewSubtree: function installNewSubtree(target) { 684 forEach(this.findElements(target), this.addElement, this); 685 }, 686 findElements: function findElements(target) { 687 if (target.querySelectorAll) { 688 return target.querySelectorAll(SELECTOR); 689 } 690 return []; 691 }, 692 removeElement: function removeElement(el) { 693 this.removeCallback(el); 694 }, 695 addElement: function addElement(el) { 696 this.addCallback(el); 697 }, 698 elementChanged: function elementChanged(el, oldValue) { 699 this.changedCallback(el, oldValue); 700 }, 701 concatLists: function concatLists(accum, list) { 702 return accum.concat(toArray(list)); 703 }, 704 // register all touch-action = none nodes on document load 705 installOnLoad: function installOnLoad() { 706 document.addEventListener('readystatechange', function () { 707 if (document.readyState === 'complete') { 708 this.installNewSubtree(document); 709 } 710 }.bind(this)); 711 }, 712 isElement: function isElement(n) { 713 return n.nodeType === Node.ELEMENT_NODE; 714 }, 715 flattenMutationTree: function flattenMutationTree(inNodes) { 716 // find children with touch-action 717 var tree = map(inNodes, this.findElements, this); 718 719 // make sure the added nodes are accounted for 720 tree.push(filter(inNodes, this.isElement)); 721 722 // flatten the list 723 return tree.reduce(this.concatLists, []); 724 }, 725 mutationWatcher: function mutationWatcher(mutations) { 726 mutations.forEach(this.mutationHandler, this); 727 }, 728 mutationHandler: function mutationHandler(m) { 729 if (m.type === 'childList') { 730 var added = this.flattenMutationTree(m.addedNodes); 731 added.forEach(this.addElement, this); 732 var removed = this.flattenMutationTree(m.removedNodes); 733 removed.forEach(this.removeElement, this); 734 } else if (m.type === 'attributes') { 735 this.elementChanged(m.target, m.oldValue); 736 } 737 } 738 }; 739 function shadowSelector(s) { 740 return 'body /shadow-deep/ ' + s; 741 } 742 function rule(v) { 743 return '{ -ms-touch-action: ' + v + '; touch-action: ' + v + '; }'; 744 } 745 var attrib2css = [{ 746 selector: '[touch-action="none"]', 747 value: 'none' 748 }, { 749 selector: '[touch-action="auto"]', 750 value: 'auto' 751 }, { 752 selector: '[touch-action~="pan-x"]', 753 value: 'pan-x' 754 }, { 755 selector: '[touch-action~="pan-y"]', 756 value: 'pan-y' 757 }, { 758 selector: '[touch-action~="pan-up"]', 759 value: 'pan-up' 760 }, { 761 selector: '[touch-action~="pan-down"]', 762 value: 'pan-down' 763 }, { 764 selector: '[touch-action~="pan-left"]', 765 value: 'pan-left' 766 }, { 767 selector: '[touch-action~="pan-right"]', 768 value: 'pan-right' 769 }]; 770 var styles = ''; 771 772 // only install stylesheet if the browser has touch action support 773 var hasNativePE = window.PointerEvent || window.MSPointerEvent; 774 775 // only add shadow selectors if shadowdom is supported 776 var hasShadowRoot = !window.ShadowDOMPolyfill && document.head.createShadowRoot; 777 function applyAttributeStyles() { 778 if (hasNativePE) { 779 attrib2css.forEach(function (r) { 780 styles += r.selector + rule(r.value) + '\n'; 781 if (hasShadowRoot) { 782 styles += shadowSelector(r.selector) + rule(r.value) + '\n'; 783 } 784 }); 785 var el = document.createElement('style'); 786 el.textContent = styles; 787 document.head.appendChild(el); 788 } 789 } 790 var pointermap = dispatcher.pointermap; 791 792 // radius around touchend that swallows mouse events 793 var DEDUP_DIST = 25; 794 795 // left, middle, right, back, forward 796 var BUTTON_TO_BUTTONS = [1, 4, 2, 8, 16]; 797 var HAS_BUTTONS = false;
798 try { 799 HAS_BUTTONS = new MouseEvent('test', { 800 buttons: 1 801 }).buttons === 1; 802 } catch (e) {} 803 804 // handler block for native mouse events 805 var mouseEvents = { 806 POINTER_ID: 1, 807 POINTER_TYPE: 'mouse', 808 events: ['mousedown', 'webkitmouseforcechanged', 'mousemove', 'mouseup', 'mouseover', 'mouseout'], 809 register: function register(target) { 810 dispatcher.listen(target, this.events); 811 }, 812 unregister: function unregister(target) { 813 dispatcher.unlisten(target, this.events); 814 }, 815 lastTouches: [], 816 // collide with the global mouse listener 817 isEventSimulatedFromTouch: function isEventSimulatedFromTouch(inEvent) { 818 var lts = this.lastTouches; 819 var x = inEvent.clientX; 820 var y = inEvent.clientY; 821 for (var i = 0, l = lts.length, t; i < l && (t = lts[i]); i++) { 822 // simulated mouse events will be swallowed near a primary touchend 823 var dx = Math.abs(x - t.x); 824 var dy = Math.abs(y - t.y); 825 if (dx <= DEDUP_DIST && dy <= DEDUP_DIST) { 826 return true; 827 } 828 } 829 }, 830 prepareEvent: function prepareEvent(inEvent) { 831 var e = dispatcher.cloneEvent(inEvent); 832 833 // forward mouse preventDefault 834 var pd = e.preventDefault; 835 e.preventDefault = function () { 836 inEvent.preventDefault(); 837 pd(); 838 }; 839 e.pointerId = this.POINTER_ID; 840 e.isPrimary = true; 841 e.pointerType = this.POINTER_TYPE; 842 if ('webkitForce' in inEvent) { 843 e.pressure = inEvent.webkitForce - MouseEvent.WEBKIT_FORCE_AT_MOUSE_DOWN; 844 } 845 return e; 846 }, 847 prepareButtonsForMove: function prepareButtonsForMove(e, inEvent) { 848 var p = pointermap.get(this.POINTER_ID); 849 850 // Update buttons state after possible out-of-document mouseup. 851 if (inEvent.which === 0 || !p) { 852 e.buttons = 0; 853 } else { 854 e.buttons = p.buttons; 855 } 856 inEvent.buttons = e.buttons; 857 }, 858 mousedown: function mousedown(inEvent) { 859 if (!this.isEventSimulatedFromTouch(inEvent)) { 860 var p = pointermap.get(this.POINTER_ID); 861 var e = this.prepareEvent(inEvent); 862 if (!HAS_BUTTONS) { 863 e.buttons = BUTTON_TO_BUTTONS[e.button]; 864 if (p) { 865 e.buttons |= p.buttons; 866 } 867 inEvent.buttons = e.buttons; 868 } 869 pointermap.set(this.POINTER_ID, inEvent); 870 if (!p || p.buttons === 0) { 871 dispatcher.down(e); 872 } else { 873 dispatcher.move(e); 874 } 875 } 876 }, 877 // This is called when the user force presses without moving x/y 878 webkitmouseforcechanged: function webkitmouseforcechanged(inEvent) { 879 this.mousemove(inEvent); 880 }, 881 mousemove: function mousemove(inEvent) { 882 if (!this.isEventSimulatedFromTouch(inEvent)) { 883 var e = this.prepareEvent(inEvent); 884 if (!HAS_BUTTONS) { 885 this.prepareButtonsForMove(e, inEvent); 886 } 887 e.button = -1; 888 pointermap.set(this.POINTER_ID, inEvent); 889 dispatcher.move(e); 890 } 891 }, 892 mouseup: function mouseup(inEvent) { 893 if (!this.isEventSimulatedFromTouch(inEvent)) { 894 var p = pointermap.get(this.POINTER_ID); 895 var e = this.prepareEvent(inEvent); 896 if (!HAS_BUTTONS) { 897 var up = BUTTON_TO_BUTTONS[e.button]; 898 899 // Produces wrong state of buttons in Browsers without `buttons` support 900 // when a mouse button that was pressed outside the document is released 901 // inside and other buttons are still pressed down. 902 e.buttons = p ? p.buttons & ~up : 0; 903 inEvent.buttons = e.buttons; 904 } 905 pointermap.set(this.POINTER_ID, inEvent); 906
907 // Support: Firefox <=44 only 908 // FF Ubuntu includes the lifted button in the `buttons` property on 909 // mouseup. 910 // https://bugzilla.mozilla.org/show_bug.cgi?id=1223366 911 e.buttons &= ~BUTTON_TO_BUTTONS[e.button]; 912 if (e.buttons === 0) { 913 dispatcher.up(e); 914 } else { 915 dispatcher.move(e); 916 } 917 } 918 }, 919 mouseover: function mouseover(inEvent) { 920 if (!this.isEventSimulatedFromTouch(inEvent)) { 921 var e = this.prepareEvent(inEvent); 922 if (!HAS_BUTTONS) { 923 this.prepareButtonsForMove(e, inEvent); 924 } 925 e.button = -1; 926 pointermap.set(this.POINTER_ID, inEvent); 927 dispatcher.enterOver(e); 928 } 929 }, 930 mouseout: function mouseout(inEvent) { 931 if (!this.isEventSimulatedFromTouch(inEvent)) { 932 var e = this.prepareEvent(inEvent); 933 if (!HAS_BUTTONS) { 934 this.prepareButtonsForMove(e, inEvent); 935 } 936 e.button = -1; 937 dispatcher.leaveOut(e); 938 } 939 }, 940 cancel: function cancel(inEvent) { 941 var e = this.prepareEvent(inEvent); 942 dispatcher.cancel(e); 943 this.deactivateMouse(); 944 }, 945 deactivateMouse: function deactivateMouse() { 946 pointermap.delete(this.POINTER_ID); 947 } 948 }; 949 var captureInfo = dispatcher.captureInfo; 950 var findTarget = targeting.findTarget.bind(targeting); 951 var allShadows = targeting.allShadows.bind(targeting); 952 var pointermap$1 = dispatcher.pointermap; 953 954 // this should be long enough to ignore compat mouse events made by touch 955 var DEDUP_TIMEOUT = 2500; 956 var ATTRIB = 'touch-action'; 957 var INSTALLER; 958 959 // bitmask for _scrollType 960 var _UP = 1; 961 var _DOWN = 2; 962 var _LEFT = 4; 963 var _RIGHT = 8; 964 var AUTO = _UP | _DOWN | _LEFT | _RIGHT; 965 966 // handler block for native touch events 967 var touchEvents = { 968 events: ['touchstart', 'touchmove', 'touchforcechange', 'touchend', 'touchcancel'], 969 register: function register(target) { 970 INSTALLER.enableOnSubtree(target); 971 }, 972 unregister: function unregister() { 973 974 // TODO(dfreedman): is it worth it to disconnect the MO? 975 }, 976 elementAdded: function elementAdded(el) { 977 var a = el.getAttribute(ATTRIB); 978 var st = this.touchActionToScrollType(a); 979 if (typeof st === "number") { 980 el._scrollType = st; 981 dispatcher.listen(el, this.events); 982 983 // set touch-action on shadows as well 984 allShadows(el).forEach(function (s) { 985 s._scrollType = st; 986 dispatcher.listen(s, this.events); 987 }, this); 988 } 989 }, 990 elementRemoved: function elementRemoved(el) { 991 // In some cases, an element is removed before a touchend. 992 // When this is the case, we should wait for the touchend before unlistening, 993 // because we still want pointer events to bubble up after removing from DOM. 994 if (pointermap$1.size > 0) { 995 var evts = this.events; 996 el.addEventListener('touchend', function () { 997 el._scrollType = undefined; 998 dispatcher.unlisten(el, evts); 999 }); 1000 } else { 1001 el._scrollType = undefined; 1002 dispatcher.unlisten(el, this.events); 1003 } 1004 1005 // remove touch-action from shadow 1006 allShadows(el).forEach(function (s) { 1007 s._scrollType = undefined; 1008 dispatcher.unlisten(s, this.events); 1009 }, this); 1010 }, 1011 elementChanged: function elementChanged(el, oldValue) { 1012 var a = el.getAttribute(ATTRIB); 1013 var st = this.touchActionToScrollType(a); 1014 var oldSt = this.touchActionToScrollType(oldValue); 1015 1016 // simply update scrollType if listeners are already established 1017 if (typeof st === "number" && typeof oldSt === "number") { 1018 el._scrollType = st; 1019 allShadows(el).forEach(function (s) { 1020 s._scrollType = st; 1021 }, this); 1022 } else if (typeof oldSt === "number") { 1023 this.elementRemoved(el); 1024 } else if (typeof st === "number") { 1025 this.elementAdded(el); 1026 } 1027 }, 1028 scrollTypes: { 1029 UP: function UP(s) { 1030 return s.includes('pan-y') || s.includes('pan-up') ? _UP : 0; 1031 }, 1032 DOWN: function DOWN(s) { 1033 return s.includes('pan-y') || s.includes('pan-down') ? _DOWN : 0; 1034 }, 1035 LEFT: function LEFT(s) { 1036 return s.includes('pan-x') || s.includes('pan-left') ? _LEFT : 0; 1037 }, 1038 RIGHT: function RIGHT(s) { 1039 return s.includes('pan-x') || s.includes('pan-right') ? _RIGHT : 0; 1040 } 1041 }, 1042 touchActionToScrollType: function touchActionToScrollType(touchAction) { 1043 if (!touchAction) { 1044 return; 1045 } 1046 if (touchAction === "auto") { 1047 return AUTO; 1048 } 1049 if (touchAction === "none") { 1050 return 0; 1051 } 1052 var s = touchAction.split(' '); 1053 var st = this.scrollTypes; 1054 1055 // construct a bitmask of allowed scroll directions 1056 return st.UP(s) | st.DOWN(s) | st.LEFT(s) | st.RIGHT(s); 1057 }, 1058 POINTER_TYPE: 'touch', 1059 firstTouch: null, 1060 isPrimaryTouch: function isPrimaryTouch(inTouch) { 1061 return this.firstTouch === inTouch.identifier; 1062 }, 1063 setPrimaryTouch: function setPrimaryTouch(inTouch) { 1064 // set primary touch if there no pointers, or the only pointer is the mouse 1065 if (pointermap$1.size === 0 || pointermap$1.size === 1 && pointermap$1.has(1)) { 1066 this.firstTouch = inTouch.identifier; 1067 this.firstXY = { 1068 X: inTouch.clientX, 1069 Y: inTouch.clientY 1070 }; 1071 this.scrolling = false;
1072 } 1073 }, 1074 removePrimaryPointer: function removePrimaryPointer(inPointer) { 1075 if (inPointer.isPrimary) { 1076 this.firstTouch = null; 1077 this.firstXY = null; 1078 } 1079 }, 1080 typeToButtons: function typeToButtons(type) { 1081 var ret = 0; 1082 if (type === 'touchstart' || type === 'touchmove' || type === 'touchforcechange') { 1083 ret = 1; 1084 } 1085 return ret; 1086 }, 1087 touchToPointer: function touchToPointer(inTouch) { 1088 var cte = this.currentTouchEvent; 1089 var e = dispatcher.cloneEvent(inTouch); 1090 1091 // We reserve pointerId 1 for Mouse. 1092 // Touch identifiers can start at 0. 1093 // Add 2 to the touch identifier for compatibility. 1094 var id = e.pointerId = inTouch.identifier + 2; 1095 e.target = captureInfo[id] || findTarget(e); 1096 e.bubbles = true; 1097 e.cancelable = true; 1098 e.button = 0; 1099 e.buttons = this.typeToButtons(cte.type); 1100 e.width = (inTouch.radiusX || inTouch.webkitRadiusX || 0) * 2; 1101 e.height = (inTouch.radiusY || inTouch.webkitRadiusY || 0) * 2; 1102 e.pressure = inTouch.force !== undefined ? inTouch.force : inTouch.webkitForce !== undefined ? inTouch.webkitForce : undefined; 1103 e.isPrimary = this.isPrimaryTouch(inTouch); 1104 if (inTouch.altitudeAngle) { 1105 var tan = Math.tan(inTouch.altitudeAngle); 1106 var radToDeg = 180 / Math.PI; 1107 e.tiltX = Math.atan(Math.cos(inTouch.azimuthAngle) / tan) * radToDeg; 1108 e.tiltY = Math.atan(Math.sin(inTouch.azimuthAngle) / tan) * radToDeg; 1109 } else { 1110 e.tiltX = 0; 1111 e.tiltY = 0; 1112 } 1113 if (inTouch.touchType === 'stylus') { 1114 e.pointerType = 'pen'; 1115 } else { 1116 e.pointerType = this.POINTER_TYPE; 1117 } 1118 1119 // forward modifier keys 1120 e.altKey = cte.altKey; 1121 e.ctrlKey = cte.ctrlKey; 1122 e.metaKey = cte.metaKey; 1123 e.shiftKey = cte.shiftKey; 1124 1125 // forward touch preventDefaults 1126 var self = this; 1127 e.preventDefault = function () { 1128 self.scrolling = false; 1129 self.firstXY = null; 1130 cte.preventDefault(); 1131 }; 1132 return e; 1133 }, 1134 processTouches: function processTouches(inEvent, inFunction) { 1135 var tl = inEvent.changedTouches; 1136 this.currentTouchEvent = inEvent; 1137 for (var i = 0, t; i < tl.length; i++) { 1138 t = tl[i]; 1139 inFunction.call(this, this.touchToPointer(t)); 1140 } 1141 }, 1142 // For single axis scrollers, determines whether the element should emit 1143 // pointer events or behave as a scroller 1144 shouldScroll: function shouldScroll(inEvent) { 1145 if (this.firstXY) { 1146 var ret; 1147 var st = inEvent.currentTarget._scrollType; 1148 if (st === 0) { 1149 // this element is a `touch-action: none`, should never scroll 1150 ret = false;
1151 } else if (st === AUTO) { 1152 // this element is a `touch-action: auto`, should always scroll 1153 ret = true; 1154 } else { 1155 var t = inEvent.changedTouches[0]; 1156 var dy = t.clientY - this.firstXY.Y; 1157 var dya = Math.abs(dy); 1158 var dx = t.clientX - this.firstXY.X; 1159 var dxa = Math.abs(dx); 1160 var up = st & _UP; 1161 var down = st & _DOWN; 1162 var left = st & _LEFT; 1163 var right = st & _RIGHT; 1164 if (left && right) { 1165 // should scroll on the x axis 1166 ret = dxa > dya; 1167 } else if (left) { 1168 // should scroll left 1169 ret = dxa > dya && dx > 0; 1170 } else if (right) { 1171 // should scroll right 1172 ret = dxa > dya && dx < 0; 1173 } 1174 if (!ret) { 1175 if (up && down) { 1176 // should scroll on the y axis 1177 ret = dxa < dya; 1178 } else if (up) { 1179 // should scroll up 1180 ret = dxa < dya && dy > 0; 1181 } else if (down) { 1182 // should scroll down 1183 ret = dxa < dya && dy < 0; 1184 } 1185 } 1186 } 1187 this.firstXY = null; 1188 return ret; 1189 } 1190 }, 1191 findTouch: function findTouch(inTL, inId) { 1192 for (var i = 0, l = inTL.length, t; i < l && (t = inTL[i]); i++) { 1193 if (t.identifier === inId) { 1194 return true; 1195 } 1196 } 1197 }, 1198 // In some instances, a touchstart can happen without a touchend. This 1199 // leaves the pointermap in a broken state. 1200 // Therefore, on every touchstart, we remove the touches that did not fire a 1201 // touchend event. 1202 // To keep state globally consistent, we fire a 1203 // pointercancel for this "abandoned" touch 1204 vacuumTouches: function vacuumTouches(inEvent) { 1205 var tl = inEvent.touches; 1206 1207 // pointermap.size should be < tl.length here, as the touchstart has not 1208 // been processed yet. 1209 if (pointermap$1.size >= tl.length) { 1210 var d = []; 1211 pointermap$1.forEach(function (value, key) { 1212 // Never remove pointerId == 1, which is mouse. 1213 // Touch identifiers are 2 smaller than their pointerId, which is the 1214 // index in pointermap. 1215 if (key !== 1 && !this.findTouch(tl, key - 2)) { 1216 var p = value.out; 1217 d.push(p); 1218 } 1219 }, this); 1220 d.forEach(this.cancelOut, this); 1221 } 1222 }, 1223 touchstart: function touchstart(inEvent) { 1224 this.vacuumTouches(inEvent); 1225 this.setPrimaryTouch(inEvent.changedTouches[0]); 1226 this.dedupSynthMouse(inEvent); 1227 if (!this.scrolling) { 1228 this.processTouches(inEvent, this.overDown); 1229 } 1230 }, 1231 overDown: function overDown(inPointer) { 1232 pointermap$1.set(inPointer.pointerId, { 1233 target: inPointer.target, 1234 out: inPointer, 1235 outTarget: inPointer.target 1236 }); 1237 dispatcher.enterOver(inPointer); 1238 dispatcher.down(inPointer); 1239 }, 1240 // Called when pressure or tilt changes without the x/y changing 1241 touchforcechange: function touchforcechange(inEvent) { 1242 this.touchmove(inEvent); 1243 }, 1244 touchmove: function touchmove(inEvent) { 1245 if (!this.scrolling) { 1246 if (this.shouldScroll(inEvent)) { 1247 this.scrolling = true; 1248 this.touchcancel(inEvent); 1249 } else { 1250 if (inEvent.type !== 'touchforcechange') { 1251 inEvent.preventDefault(); 1252 } 1253 this.processTouches(inEvent, this.moveOverOut); 1254 } 1255 } 1256 }, 1257 moveOverOut: function moveOverOut(inPointer) { 1258 var event = inPointer; 1259 var pointer = pointermap$1.get(event.pointerId); 1260 1261 // a finger drifted off the screen, ignore it 1262 if (!pointer) { 1263 return; 1264 } 1265 var outEvent = pointer.out; 1266 var outTarget = pointer.outTarget; 1267 dispatcher.move(event); 1268 if (outEvent && outTarget !== event.target) { 1269 outEvent.relatedTarget = event.target; 1270 event.relatedTarget = outTarget; 1271 1272 // recover from retargeting by shadow 1273 outEvent.target = outTarget; 1274 if (event.target) { 1275 dispatcher.leaveOut(outEvent); 1276 dispatcher.enterOver(event); 1277 } else { 1278 // clean up case when finger leaves the screen 1279 event.target = outTarget; 1280 event.relatedTarget = null; 1281 this.cancelOut(event); 1282 } 1283 } 1284 pointer.out = event; 1285 pointer.outTarget = event.target; 1286 }, 1287 touchend: function touchend(inEvent) { 1288 this.dedupSynthMouse(inEvent); 1289 this.processTouches(inEvent, this.upOut); 1290 }, 1291 upOut: function upOut(inPointer) { 1292 if (!this.scrolling) { 1293 dispatcher.up(inPointer); 1294 dispatcher.leaveOut(inPointer); 1295 } 1296 this.cleanUpPointer(inPointer); 1297 }, 1298 touchcancel: function touchcancel(inEvent) { 1299 this.processTouches(inEvent, this.cancelOut); 1300 }, 1301 cancelOut: function cancelOut(inPointer) { 1302 dispatcher.cancel(inPointer); 1303 dispatcher.leaveOut(inPointer); 1304 this.cleanUpPointer(inPointer); 1305 }, 1306 cleanUpPointer: function cleanUpPointer(inPointer) { 1307 pointermap$1.delete(inPointer.pointerId); 1308 this.removePrimaryPointer(inPointer); 1309 }, 1310 // prevent synth mouse events from creating pointer events 1311 dedupSynthMouse: function dedupSynthMouse(inEvent) { 1312 var lts = mouseEvents.lastTouches; 1313 var t = inEvent.changedTouches[0]; 1314 1315 // only the primary finger will synth mouse events 1316 if (this.isPrimaryTouch(t)) { 1317 // remember x/y of last touch 1318 var lt = { 1319 x: t.clientX, 1320 y: t.clientY 1321 }; 1322 lts.push(lt); 1323 var fn = function (lts, lt) { 1324 var i = lts.indexOf(lt); 1325 if (i > -1) { 1326 lts.splice(i, 1); 1327 } 1328 }.bind(null, lts, lt); 1329 setTimeout(fn, DEDUP_TIMEOUT); 1330 } 1331 } 1332 }; 1333 INSTALLER = new Installer(touchEvents.elementAdded, touchEvents.elementRemoved, touchEvents.elementChanged, touchEvents); 1334 var pointermap$2 = dispatcher.pointermap; 1335 var HAS_BITMAP_TYPE = window.MSPointerEvent && typeof window.MSPointerEvent.MSPOINTER_TYPE_MOUSE === 'number'; 1336 var msEvents = { 1337 events: ['MSPointerDown', 'MSPointerMove', 'MSPointerUp', 'MSPointerOut', 'MSPointerOver', 'MSPointerCancel', 'MSGotPointerCapture', 'MSLostPointerCapture'], 1338 register: function register(target) { 1339 dispatcher.listen(target, this.events); 1340 }, 1341 unregister: function unregister(target) { 1342 dispatcher.unlisten(target, this.events); 1343 }, 1344 POINTER_TYPES: ['', 'unavailable', 'touch', 'pen', 'mouse'], 1345 prepareEvent: function prepareEvent(inEvent) { 1346 var e = inEvent; 1347 if (HAS_BITMAP_TYPE) { 1348 e = dispatcher.cloneEvent(inEvent); 1349 e.pointerType = this.POINTER_TYPES[inEvent.pointerType]; 1350 } 1351 return e; 1352 }, 1353 cleanup: function cleanup(id) { 1354 pointermap$2.delete(id); 1355 }, 1356 MSPointerDown: function MSPointerDown(inEvent) { 1357 pointermap$2.set(inEvent.pointerId, inEvent); 1358 var e = this.prepareEvent(inEvent); 1359 dispatcher.down(e); 1360 }, 1361 MSPointerMove: function MSPointerMove(inEvent) { 1362 var e = this.prepareEvent(inEvent); 1363 dispatcher.move(e); 1364 }, 1365 MSPointerUp: function MSPointerUp(inEvent) { 1366 var e = this.prepareEvent(inEvent); 1367 dispatcher.up(e); 1368 this.cleanup(inEvent.pointerId); 1369 }, 1370 MSPointerOut: function MSPointerOut(inEvent) { 1371 var e = this.prepareEvent(inEvent); 1372 dispatcher.leaveOut(e); 1373 }, 1374 MSPointerOver: function MSPointerOver(inEvent) { 1375 var e = this.prepareEvent(inEvent); 1376 dispatcher.enterOver(e); 1377 }, 1378 MSPointerCancel: function MSPointerCancel(inEvent) { 1379 var e = this.prepareEvent(inEvent); 1380 dispatcher.cancel(e); 1381 this.cleanup(inEvent.pointerId); 1382 }, 1383 MSLostPointerCapture: function MSLostPointerCapture(inEvent) { 1384 var e = dispatcher.makeEvent('lostpointercapture', inEvent); 1385 dispatcher.dispatchEvent(e); 1386 }, 1387 MSGotPointerCapture: function MSGotPointerCapture(inEvent) { 1388 var e = dispatcher.makeEvent('gotpointercapture', inEvent); 1389 dispatcher.dispatchEvent(e); 1390 } 1391 }; 1392 function applyPolyfill() { 1393 // only activate if this platform does not have pointer events 1394 if (!window.PointerEvent) { 1395 window.PointerEvent = PointerEvent; 1396 if (window.navigator.msPointerEnabled) { 1397 var tp = window.navigator.msMaxTouchPoints; 1398 Object.defineProperty(window.navigator, 'maxTouchPoints', { 1399 value: tp, 1400 enumerable: true 1401 }); 1402 dispatcher.registerSource('ms', msEvents); 1403 } else { 1404 Object.defineProperty(window.navigator, 'maxTouchPoints', { 1405 value: 0, 1406 enumerable: true 1407 });
1408 dispatcher.registerSource('mouse', mouseEvents); 1409 if (window.ontouchstart !== undefined) { 1410 dispatcher.registerSource('touch', touchEvents); 1411 } 1412 } 1413 dispatcher.register(document); 1414 } 1415 } 1416 var n = window.navigator; 1417 var s; 1418 var r; 1419 var h; 1420 function assertActive(id) { 1421 if (!dispatcher.pointermap.has(id)) { 1422 var error = new Error('NotFoundError'); 1423 error.name = 'NotFoundError'; 1424 throw error; 1425 } 1426 } 1427 function assertConnected(elem) { 1428 var parent = elem.parentNode; 1429 while (parent && parent !== elem.ownerDocument) { 1430 parent = parent.parentNode; 1431 } 1432 if (!parent) { 1433 var error = new Error('InvalidStateError'); 1434 error.name = 'InvalidStateError'; 1435 throw error; 1436 } 1437 } 1438 function inActiveButtonState(id) { 1439 var p = dispatcher.pointermap.get(id); 1440 return p.buttons !== 0; 1441 } 1442 if (n.msPointerEnabled) { 1443 s = function s(pointerId) { 1444 assertActive(pointerId); 1445 assertConnected(this); 1446 if (inActiveButtonState(pointerId)) { 1447 dispatcher.setCapture(pointerId, this, true); 1448 this.msSetPointerCapture(pointerId); 1449 } 1450 }; 1451 r = function r(pointerId) { 1452 assertActive(pointerId); 1453 dispatcher.releaseCapture(pointerId, true); 1454 this.msReleasePointerCapture(pointerId); 1455 }; 1456 } else { 1457 s = function setPointerCapture(pointerId) { 1458 assertActive(pointerId); 1459 assertConnected(this); 1460 if (inActiveButtonState(pointerId)) { 1461 dispatcher.setCapture(pointerId, this); 1462 } 1463 }; 1464 r = function releasePointerCapture(pointerId) { 1465 assertActive(pointerId); 1466 dispatcher.releaseCapture(pointerId); 1467 }; 1468 } 1469 h = function hasPointerCapture(pointerId) { 1470 return !!dispatcher.captureInfo[pointerId]; 1471 }; 1472 function applyPolyfill$1() { 1473 if (window.Element && !window.Element.prototype.setPointerCapture) { 1474 Object.defineProperties(window.Element.prototype, { 1475 'setPointerCapture': { 1476 value: s 1477 }, 1478 'releasePointerCapture': { 1479 value: r 1480 }, 1481 'hasPointerCapture': { 1482 value: h 1483 } 1484 }); 1485 } 1486 } 1487 applyAttributeStyles(); 1488 applyPolyfill(); 1489 applyPolyfill$1(); 1490 var pointerevents = { 1491 dispatcher: dispatcher, 1492 Installer: Installer, 1493 PointerEvent: PointerEvent, 1494 PointerMap: PointerMap, 1495 targetFinding: targeting 1496 }; 1497 return pointerevents; 1498 }); 1499 })(pep); 1500 1501 var global$1 = typeof globalThis !== 'undefined' && globalThis || typeof self !== 'undefined' && self || typeof global$1 !== 'undefined' && global$1; 1502 var support = { 1503 searchParams: 'URLSearchParams' in global$1, 1504 iterable: 'Symbol' in global$1 && 'iterator' in Symbol, 1505 blob: 'FileReader' in global$1 && 'Blob' in global$1 && function () { 1506 try { 1507 new Blob(); 1508 return true; 1509 } catch (e) { 1510 return false; 1511 } 1512 }(), 1513 formData: 'FormData' in global$1, 1514 arrayBuffer: 'ArrayBuffer' in global$1 1515 }; 1516 function isDataView(obj) { 1517 return obj && DataView.prototype.isPrototypeOf(obj); 1518 } 1519 if (support.arrayBuffer) { 1520 var viewClasses = ['[object Int8Array]', '[object Uint8Array]', '[object Uint8ClampedArray]', '[object Int16Array]', '[object Uint16Array]', '[object Int32Array]', '[object Uint32Array]', '[object Float32Array]', '[object Float64Array]']; 1521 var isArrayBufferView = ArrayBuffer.isView || function (obj) { 1522 return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1; 1523 }; 1524 } 1525 function normalizeName(name) { 1526 if (typeof name !== 'string') { 1527 name = String(name); 1528 } 1529 if (/[^a-z0-9\-#$%&'*+.^_`|~!]/i.test(name) || name === '') { 1530 throw new TypeError('Invalid character in header field name: "' + n
vendor: 15,518 bytes, lines 1530-1982
1530ame + '"'); 1531 } 1532 return name.toLowerCase(); 1533 } 1534 function normalizeValue(value) { 1535 if (typeof value !== 'string') { 1536 value = String(value); 1537 } 1538 return value; 1539 } 1540 1541 // Build a destructive iterator for the value list 1542 function iteratorFor(items) { 1543 var iterator = { 1544 next: function next() { 1545 var value = items.shift(); 1546 return { 1547 done: value === undefined, 1548 value: value 1549 }; 1550 } 1551 }; 1552 if (support.iterable) { 1553 iterator[Symbol.iterator] = function () { 1554 return iterator; 1555 }; 1556 } 1557 return iterator; 1558 } 1559 function Headers(headers) { 1560 this.map = {}; 1561 if (headers instanceof Headers) { 1562 headers.forEach(function (value, name) { 1563 this.append(name, value); 1564 }, this); 1565 } else if (Array.isArray(headers)) { 1566 headers.forEach(function (header) { 1567 this.append(header[0], header[1]); 1568 }, this); 1569 } else if (headers) { 1570 Object.getOwnPropertyNames(headers).forEach(function (name) { 1571 this.append(name, headers[name]); 1572 }, this); 1573 } 1574 } 1575 Headers.prototype.append = function (name, value) { 1576 name = normalizeName(name); 1577 value = normalizeValue(value); 1578 var oldValue = this.map[name]; 1579 this.map[name] = oldValue ? oldValue + ', ' + value : value; 1580 }; 1581 Headers.prototype['delete'] = function (name) { 1582 delete this.map[normalizeName(name)]; 1583 }; 1584 Headers.prototype.get = function (name) { 1585 name = normalizeName(name); 1586 return this.has(name) ? this.map[name] : null; 1587 }; 1588 Headers.prototype.has = function (name) { 1589 return this.map.hasOwnProperty(normalizeName(name)); 1590 }; 1591 Headers.prototype.set = function (name, value) { 1592 this.map[normalizeName(name)] = normalizeValue(value); 1593 }; 1594 Headers.prototype.forEach = function (callback, thisArg) { 1595 for (var name in this.map) { 1596 if (this.map.hasOwnProperty(name)) { 1597 callback.call(thisArg, this.map[name], name, this); 1598 } 1599 } 1600 }; 1601 Headers.prototype.keys = function () { 1602 var items = []; 1603 this.forEach(function (value, name) { 1604 items.push(name); 1605 }); 1606 return iteratorFor(items); 1607 }; 1608 Headers.prototype.values = function () { 1609 var items = []; 1610 this.forEach(function (value) { 1611 items.push(value); 1612 }); 1613 return iteratorFor(items); 1614 }; 1615 Headers.prototype.entries = function () { 1616 var items = []; 1617 this.forEach(function (value, name) { 1618 items.push([name, value]); 1619 }); 1620 return iteratorFor(items); 1621 }; 1622 if (support.iterable) { 1623 Headers.prototype[Symbol.iterator] = Headers.prototype.entries; 1624 } 1625 function consumed(body) { 1626 if (body.bodyUsed) { 1627 return Promise.reject(new TypeError('Already read')); 1628 } 1629 body.bodyUsed = true; 1630 } 1631 function fileReaderReady(reader) { 1632 return new Promise(function (resolve, reject) { 1633 reader.onload = function () { 1634 resolve(reader.result); 1635 }; 1636 reader.onerror = function () { 1637 reject(reader.error); 1638 }; 1639 }); 1640 } 1641 function readBlobAsArrayBuffer(blob) { 1642 var reader = new FileReader(); 1643 var promise = fileReaderReady(reader); 1644 reader.readAsArrayBuffer(blob); 1645 return promise; 1646 } 1647 function readBlobAsText(blob) { 1648 var reader = new FileReader(); 1649 var promise = fileReaderReady(reader); 1650 reader.readAsText(blob); 1651 return promise; 1652 } 1653 function readArrayBufferAsText(buf) { 1654 var view = new Uint8Array(buf); 1655 var chars = new Array(view.length); 1656 for (var i = 0; i < view.length; i++) { 1657 chars[i] = String.fromCharCode(view[i]); 1658 } 1659 return chars.join(''); 1660 } 1661 function bufferClone(buf) { 1662 if (buf.slice) { 1663 return buf.slice(0); 1664 } else { 1665 var view = new Uint8Array(buf.byteLength); 1666 view.set(new Uint8Array(buf)); 1667 return view.buffer; 1668 } 1669 } 1670 function Body() { 1671 this.bodyUsed = false; 1672 this._initBody = function (body) { 1673 /* 1674 fetch-mock wraps the Response object in an ES6 Proxy to 1675 provide useful test harness features such as flush. However, on 1676 ES5 browsers without fetch or Proxy support pollyfills must be used; 1677 the proxy-pollyfill is unable to proxy an attribute unless it exists 1678 on the object before the Proxy is created. This change ensures 1679 Response.bodyUsed exists on the instance, while maintaining the 1680 semantic of setting Request.bodyUsed in the constructor before 1681 _initBody is called. 1682 */ 1683 this.bodyUsed = this.bodyUsed; 1684 this._bodyInit = body; 1685 if (!body) { 1686 this._bodyText = ''; 1687 } else if (typeof body === 'string') { 1688 this._bodyText = body; 1689 } else if (support.blob && Blob.prototype.isPrototypeOf(body)) { 1690 this._bodyBlob = body; 1691 } else if (support.formData && FormData.prototype.isPrototypeOf(body)) { 1692 this._bodyFormData = body; 1693 } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { 1694 this._bodyText = body.toString(); 1695 } else if (support.arrayBuffer && support.blob && isDataView(body)) { 1696 this._bodyArrayBuffer = bufferClone(body.buffer); 1697 // IE 10-11 can't handle a DataView body. 1698 this._bodyInit = new Blob([this._bodyArrayBuffer]); 1699 } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) { 1700 this._bodyArrayBuffer = bufferClone(body); 1701 } else { 1702 this._bodyText = body = Object.prototype.toString.call(body); 1703 } 1704 if (!this.headers.get('content-type')) { 1705 if (typeof body === 'string') { 1706 this.headers.set('content-type', 'text/plain;charset=UTF-8'); 1707 } else if (this._bodyBlob && this._bodyBlob.type) { 1708 this.headers.set('content-type', this._bodyBlob.type); 1709 } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { 1710 this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8'); 1711 } 1712 } 1713 }; 1714 if (support.blob) { 1715 this.blob = function () { 1716 var rejected = consumed(this); 1717 if (rejected) { 1718 return rejected; 1719 } 1720 if (this._bodyBlob) { 1721 return Promise.resolve(this._bodyBlob); 1722 } else if (this._bodyArrayBuffer) { 1723 return Promise.resolve(new Blob([this._bodyArrayBuffer])); 1724 } else if (this._bodyFormData) { 1725 throw new Error('could not read FormData body as blob'); 1726 } else { 1727 return Promise.resolve(new Blob([this._bodyText])); 1728 } 1729 }; 1730 this.arrayBuffer = function () { 1731 if (this._bodyArrayBuffer) { 1732 var isConsumed = consumed(this); 1733 if (isConsumed) { 1734 return isConsumed; 1735 } 1736 if (ArrayBuffer.isView(this._bodyArrayBuffer)) { 1737 return Promise.resolve(this._bodyArrayBuffer.buffer.slice(this._bodyArrayBuffer.byteOffset, this._bodyArrayBuffer.byteOffset + this._bodyArrayBuffer.byteLength)); 1738 } else { 1739 return Promise.resolve(this._bodyArrayBuffer); 1740 } 1741 } else { 1742 return this.blob().then(readBlobAsArrayBuffer); 1743 } 1744 }; 1745 } 1746 this.text = function () { 1747 var rejected = consumed(this); 1748 if (rejected) { 1749 return rejected; 1750 } 1751 if (this._bodyBlob) { 1752 return readBlobAsText(this._bodyBlob); 1753 } else if (this._bodyArrayBuffer) { 1754 return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer)); 1755 } else if (this._bodyFormData) { 1756 throw new Error('could not read FormData body as text'); 1757 } else { 1758 return Promise.resolve(this._bodyText); 1759 } 1760 }; 1761 if (support.formData) { 1762 this.formData = function () { 1763 return this.text().then(decode); 1764 }; 1765 } 1766 this.json = function () { 1767 return this.text().then(JSON.parse); 1768 }; 1769 return this; 1770 } 1771 1772 // HTTP methods whose capitalization should be normalized 1773 var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT']; 1774 function normalizeMethod(method) { 1775 var upcased = method.toUpperCase(); 1776 return methods.indexOf(upcased) > -1 ? upcased : method; 1777 } 1778 function Request(input, options) { 1779 if (!(this instanceof Request)) { 1780 throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.'); 1781 } 1782 options = options || {}; 1783 var body = options.body; 1784 if (input instanceof Request) { 1785 if (input.bodyUsed) { 1786 throw new TypeError('Already read'); 1787 } 1788 this.url = input.url; 1789 this.credentials = input.credentials; 1790 if (!options.headers) { 1791 this.headers = new Headers(input.headers); 1792 } 1793 this.method = input.method; 1794 this.mode = input.mode; 1795 this.signal = input.signal; 1796 if (!body && input._bodyInit != null) { 1797 body = input._bodyInit; 1798 input.bodyUsed = true; 1799 } 1800 } else { 1801 this.url = String(input); 1802 } 1803 this.credentials = options.credentials || this.credentials || 'same-origin'; 1804 if (options.headers || !this.headers) { 1805 this.headers = new Headers(options.headers); 1806 } 1807 this.method = normalizeMethod(options.method || this.method || 'GET'); 1808 this.mode = options.mode || this.mode || null; 1809 this.signal = options.signal || this.signal; 1810 this.referrer = null; 1811 if ((this.method === 'GET' || this.method === 'HEAD') && body) { 1812 throw new TypeError('Body not allowed for GET or HEAD requests'); 1813 } 1814 this._initBody(body); 1815 if (this.method === 'GET' || this.method === 'HEAD') { 1816 if (options.cache === 'no-store' || options.cache === 'no-cache') { 1817 // Search for a '_' parameter in the query string 1818 var reParamSearch = /([?&])_=[^&]*/; 1819 if (reParamSearch.test(this.url)) { 1820 // If it already exists then set the value with the current time 1821 this.url = this.url.replace(reParamSearch, '$1_=' + new Date().getTime()); 1822 } else { 1823 // Otherwise add a new '_' parameter to the end with the current time 1824 var reQueryString = /\?/; 1825 this.url += (reQueryString.test(this.url) ? '&' : '?') + '_=' + new Date().getTime(); 1826 } 1827 } 1828 } 1829 } 1830 Request.prototype.clone = function () { 1831 return new Request(this, { 1832 body: this._bodyInit 1833 }); 1834 }; 1835 function decode(body) { 1836 var form = new FormData(); 1837 body.trim().split('&').forEach(function (bytes) { 1838 if (bytes) { 1839 var split = bytes.split('='); 1840 var name = split.shift().replace(/\+/g, ' '); 1841 var value = split.join('=').replace(/\+/g, ' '); 1842 form.append(decodeURIComponent(name), decodeURIComponent(value)); 1843 } 1844 }); 1845 return form; 1846 } 1847 function parseHeaders(rawHeaders) { 1848 var headers = new Headers(); 1849 // Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space 1850 // https://tools.ietf.org/html/rfc7230#section-3.2 1851 var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' '); 1852 // Avoiding split via regex to work around a common IE11 bug with the core-js 3.6.0 regex polyfill 1853 // https://github.com/github/fetch/issues/748 1854 // https://github.com/zloirock/core-js/issues/751 1855 preProcessedHeaders.split('\r').map(function (header) { 1856 return header.indexOf('\n') === 0 ? header.substr(1, header.length) : header; 1857 }).forEach(function (line) { 1858 var parts = line.split(':'); 1859 var key = parts.shift().trim(); 1860 if (key) { 1861 var value = parts.join(':').trim(); 1862 headers.append(key, value); 1863 } 1864 }); 1865 return headers; 1866 } 1867 Body.call(Request.prototype); 1868 function Response(bodyInit, options) { 1869 if (!(this instanceof Response)) { 1870 throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.'); 1871 } 1872 if (!options) { 1873 options = {}; 1874 } 1875 this.type = 'default'; 1876 this.status = options.status === undefined ? 200 : options.status; 1877 this.ok = this.status >= 200 && this.status < 300; 1878 this.statusText = options.statusText === undefined ? '' : '' + options.statusText; 1879 this.headers = new Headers(options.headers); 1880 this.url = options.url || ''; 1881 this._initBody(bodyInit); 1882 } 1883 Body.call(Response.prototype); 1884 Response.prototype.clone = function () { 1885 return new Response(this._bodyInit, { 1886 status: this.status, 1887 statusText: this.statusText, 1888 headers: new Headers(this.headers), 1889 url: this.url 1890 }); 1891 }; 1892 Response.error = function () { 1893 var response = new Response(null, { 1894 status: 0, 1895 statusText: '' 1896 }); 1897 response.type = 'error'; 1898 return response; 1899 }; 1900 var redirectStatuses = [301, 302, 303, 307, 308]; 1901 Response.redirect = function (url, status) { 1902 if (redirectStatuses.indexOf(status) === -1) { 1903 throw new RangeError('Invalid status code'); 1904 } 1905 return new Response(null, { 1906 status: status, 1907 headers: { 1908 location: url 1909 } 1910 }); 1911 }; 1912 var DOMException = global$1.DOMException; 1913 try { 1914 new DOMException(); 1915 } catch (err) { 1916 DOMException = function DOMException(message, name) { 1917 this.message = message; 1918 this.name = name; 1919 var error = Error(message); 1920 this.stack = error.stack; 1921 }; 1922 DOMException.prototype = Object.create(Error.prototype); 1923 DOMException.prototype.constructor = DOMException; 1924 } 1925 function fetch(input, init) { 1926 return new Promise(function (resolve, reject) { 1927 var request = new Request(input, init); 1928 if (request.signal && request.signal.aborted) { 1929 return reject(new DOMException('Aborted', 'AbortError')); 1930 } 1931 var xhr = new XMLHttpRequest(); 1932 function abortXhr() { 1933 xhr.abort(); 1934 } 1935 xhr.onload = function () { 1936 var options = { 1937 status: xhr.status, 1938 statusText: xhr.statusText, 1939 headers: parseHeaders(xhr.getAllResponseHeaders() || '') 1940 }; 1941 options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL'); 1942 var body = 'response' in xhr ? xhr.response : xhr.responseText; 1943 setTimeout(function () { 1944 resolve(new Response(body, options)); 1945 }, 0); 1946 }; 1947 xhr.onerror = function () { 1948 setTimeout(function () { 1949 reject(new TypeError('Network request failed')); 1950 }, 0); 1951 }; 1952 xhr.ontimeout = function () { 1953 setTimeout(function () { 1954 reject(new TypeError('Network request failed')); 1955 }, 0); 1956 }; 1957 xhr.onabort = function () { 1958 setTimeout(function () { 1959 reject(new DOMException('Aborted', 'AbortError')); 1960 }, 0); 1961 }; 1962 function fixUrl(url) { 1963 try { 1964 return url === '' && global$1.location.href ? global$1.location.href : url; 1965 } catch (e) { 1966 return url; 1967 } 1968 } 1969 xhr.open(request.method, fixUrl(request.url), true); 1970 if (request.credentials === 'include') { 1971 xhr.withCredentials = true; 1972 } else if (request.credentials === 'omit') { 1973 xhr.withCredentials = false; 1974 } 1975 if ('responseType' in xhr) { 1976 if (support.blob) { 1977 xhr.responseType = 'blob'; 1978 } else if (support.arrayBuffer && request.headers.get('Content-Type') && request.headers.get('Content-Type').indexOf('application/octet-stream') !== -1) { 1979 xhr.responseType = 'arraybuffer'; 1980 } 1981 } 1982 if (init && _typeof$1(init.headers) === 'object' && !(init.headers instanceof Headers)) {
1983 Object.getOwnPropertyNames(init.headers).forEach(function (name) { 1984 xhr.setRequestHeader(name, normalizeValue(init.headers[name])); 1985 }); 1986 } else { 1987 request.headers.forEach(function (value, name) { 1988 xhr.setRequestHeader(name, value); 1989 }); 1990 } 1991 if (request.signal) { 1992 request.signal.addEventListener('abort', abortXhr); 1993 xhr.onreadystatechange = function () { 1994 // DONE (success or failure) 1995 if (xhr.readyState === 4) { 1996 request.signal.removeEventListener('abort', abortXhr); 1997 } 1998 }; 1999 } 2000 xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit); 2001 }); 2002 } 2003 fetch.polyfill = true; 2004 if (!global$1.fetch) { 2005 global$1.fetch = fetch; 2006 global$1.Headers = Headers; 2007 global$1.Request = Request; 2008 global$1.Response = Response; 2009 } 2010 2011 // Polyfill for creating CustomEvents on IE9/10/11 2012 2013 // code pulled from: 2014 // https://github.com/d4tocchini/customevent-polyfill 2015 // https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent#Polyfill 2016 2017 (function () { 2018 if (typeof window === 'undefined') { 2019 return; 2020 } 2021 try { 2022 var ce = new window.CustomEvent('test', { 2023 cancelable: true 2024 }); 2025 ce.preventDefault(); 2026 if (ce.defaultPrevented !== true) { 2027 // IE has problems with .preventDefault() on custom events 2028 // http://stackoverflow.com/questions/23349191 2029 throw new Error('Could not prevent default'); 2030 } 2031 } catch (e) { 2032 var CustomEvent = function CustomEvent(event, params) { 2033 var evt, origPrevent; 2034 params = params || {}; 2035 params.bubbles = !!params.bubbles; 2036 params.cancelable = !!params.cancelable; 2037 evt = document.createEvent('CustomEvent'); 2038 evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); 2039 origPrevent = evt.preventDefault; 2040 evt.preventDefault = function () { 2041 origPrevent.call(this); 2042 try { 2043 Object.defineProperty(this, 'defaultPrevented', { 2044 get: function get() { 2045 return true; 2046 } 2047 }); 2048 } catch (e) { 2049 this.defaultPrevented = true; 2050 } 2051 }; 2052 return evt; 2053 }; 2054 CustomEvent.prototype = window.Event.prototype; 2055 window.CustomEvent = CustomEvent; // expose definition to window 2056 } 2057 })(); 2058 2059 function polyfill(window) { 2060 var ElementPrototype = window.Element.prototype; 2061 if (typeof ElementPrototype.matches !== 'function') { 2062 ElementPrototype.matches = ElementPrototype.msMatchesSelector || ElementPrototype.mozMatchesSelector || ElementPrototype.webkitMatchesSelector || function matches(selector) { 2063 var element = this; 2064 var elements = (element.document || element.ownerDocument).querySelectorAll(selector); 2065 var index = 0; 2066 while (elements[index] && elements[index] !== element) { 2067 ++index; 2068 } 2069 return Boolean(elements[index]); 2070 }; 2071 } 2072 if (typeof ElementPrototype.closest !== 'function') { 2073 ElementPrototype.closest = function closest(selector) { 2074 var element = this; 2075 while (element && element.nodeType === 1) { 2076 if (element.matches(selector)) { 2077 return element; 2078 } 2079 element = element.parentNode; 2080 } 2081 return null; 2082 }; 2083 } 2084 } 2085 2086 function focusWithin(document, opts) { 2087 var className = Object(opts).className; 2088 var attr = Object(opts).attr || 'focus-within'; 2089 var force = Object(opts).force; 2090 var lastElements = []; 2091 try { 2092 document.querySelector(':focus-within'); 2093 if (!force) { 2094 return initialize; 2095 } 2096 } catch (ignoredError) { 2097 /* do nothing and continue */ 2098 } 2099 function onfocuschange() { 2100 var lastElement; 2101 while (lastElement = lastElements.pop()) { 2102 if (attr) { 2103 lastElement.removeAttribute(attr); 2104 } 2105 if (className) { 2106 lastElement.classList.remove(className); 2107 } 2108 } 2109 var activeElement = document.activeElement;
2109 // only add focus if it has not been added and is not the document element 2110 2111 if (!/^(#document|HTML|BODY)$/.test(Object(activeElement).nodeName)) { 2112 while (activeElement && activeElement.nodeType === 1) { 2113 if (attr) { 2114 activeElement.setAttribute(attr, ''); 2115 } 2116 if (className) { 2117 activeElement.classList.add(className); 2118 } 2119 lastElements.push(activeElement); 2120 activeElement = activeElement.parentNode; 2121 } 2122 } 2123 } 2124 function initialize() { 2125 document.addEventListener('focus', onfocuschange, true); 2126 document.addEventListener('blur', onfocuschange, true); 2127 } 2128 /** 2129 * Callback wrapper for check loaded state 2130 */ 2131 2132 /* eslint-disable */ 2133 2134 !function load() { 2135 if (/m/.test(document.readyState)) { 2136 document.removeEventListener('readystatechange', load) | initialize(); 2137 } else { 2138 document.addEventListener('readystatechange', load); 2139 } 2140 }(); 2141 /* eslint-enable */ 2142 2143 return initialize; 2144 } 2145 2146 /** 2147 * IE11 Polyfill for `.forEach` on NodeLists. 2148 * @param {Function} callback to call on each iteration. 2149 * @param {object} [thisArg] value to bind to callback's `this`. Defaults to `window`. 2150 * @returns {void} 2151 */ 2152 if ('NodeList' in window && !NodeList.prototype.forEach) { 2153 NodeList.prototype.forEach = function forEach(callback) { 2154 var thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : window; 2155 for (var i = 0; i < this.length; i++) { 2156 callback.call(thisArg, this[i], i, this); 2157 } 2158 }; 2159 } 2160 2161 // CustomEvent micro-polyfill for Internet Explorer 2162 // eslint-disable-next-line func-names
2163 (function () { 2164 if (typeof window.CustomEvent === 'function') { 2165 return false; 2166 } 2167 function CustomEvent(event, params) { 2168 // eslint-disable-next-line no-param-reassign 2169 params = params || { 2170 bubbles: false, 2171 cancelable: false, 2172 detail: undefined 2173 }; 2174 var evt = document.createEvent('CustomEvent'); 2175 evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); 2176 return evt; 2177 } 2178 CustomEvent.prototype = window.Event.prototype; 2179 window.CustomEvent = CustomEvent; 2180 })(); 2181 2182 /** 2183 * IE11 Polyfill for `:focus-within` 2184 */ 2185 focusWithin(document); 2186 2187 /** 2188 * IE11 Polyfill for `.closest()` 2189 */ 2190 polyfill(window); 2191 2192 function enableActions() { 2193 var actions = Array.from(document.querySelectorAll('.msk-actions__item')); 2194 var actionsMenu = document.querySelectorAll('.msk-actions__item-tray'); 2195 var summaries = Array.from(document.querySelectorAll('.msk-actions__item-headline')); 2196 actions.forEach(function (element) { 2197 element.addEventListener("toggle", function () { 2198 summaries.forEach(function (summary) { 2199 if (element.open) { 2200 summary.setAttribute('aria-expanded', 'true'); 2201 handleKeyup(element); 2202 } else { 2203 summary.setAttribute('aria-expanded', 'false'); 2204 } 2205 }); 2206 }); 2207 }); 2208 function handleKeyup(actions) { 2209 window.addEventListener('keydown', function (event) { 2210 actionsMenu.forEach(function () { 2211 if (event.key === 'Escape') { 2212 actions.open = false; 2213 } 2214 }); 2215 }); 2216 } 2217 } 2218 2219 function enableBackToTop() { 2220 if (!document.querySelector('.msk-back-to-top')) { 2221 return; 2222 } 2223 document.documentElement.addEventListener('click', function (event) { 2224 var element = event.target.closest('.msk-back-to-top'); 2225 if (!element) return; 2226 var targetHref = element.getAttribute('href').replace('#', ''); 2227 var target = targetHref && document.getElementById(targetHref) ? document.getElementById(targetHref) : document.body; 2228 if (!target) return; 2229 event.preventDefault(); 2230 target.scrollIntoView({ 2231 behavior: "smooth", 2232 block: "start", 2233 inline: "nearest" 2234 }); 2235 }); 2236 } 2237 2238 /*! 2239 * Glide.js v3.6.0 2240 * (c) 2013-2022 JÄdrzej ChaÅubek (https://github.com/jedrzejchalubek/) 2241 * Released under the MIT License. 2242 */ 2243 2244 function _typeof(obj) { 2245 "@babel/helpers - typeof"; 2246 2247 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { 2248 _typeof = function _typeof(obj) { 2249 return typeof obj; 2250 }; 2251 } else { 2252 _typeof = function _typeof(obj) { 2253 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; 2254 }; 2255 } 2256 return _typeof(obj); 2257 } 2258 function _classCallCheck(instance, Constructor) { 2259 if (!(instance instanceof Constructor)) { 2260 throw new TypeError("Cannot call a class as a function"); 2261 } 2262 } 2263 function _defineProperties(target, props) { 2264 for (var i = 0; i < props.length; i++) { 2265 var descriptor = props[i]; 2266 descriptor.enumerable = descriptor.enumerable || false; 2267 descriptor.configurable = true; 2268 if ("value" in descriptor) descriptor.writable = true; 2269 Object.defineProperty(target, descriptor.key, descriptor); 2270 } 2271 } 2272 function _createClass(Constructor, protoProps, staticProps) { 2273 if (protoProps) _defineProperties(Constructor.prototype, protoProps); 2274 if (staticProps) _defineProperties(Constructor, staticProps); 2275 return Constructor; 2276 } 2277 function _inherits(subClass, superClass) { 2278 if (typeof superClass !== "function" && superClass !== null) { 2279 throw new TypeError("Super expression must either be null or a function"); 2280 } 2281 subClass.prototype = Object.create(superClass && superClass.prototype, { 2282 constructor: { 2283 value: subClass, 2284 writable: true, 2285 configurable: true 2286 } 2287 }); 2288 if (superClass) _setPrototypeOf(subClass, superClass); 2289 }
vendor: 4,926 bytes, lines 2290-2453
2290 function _getPrototypeOf(o) { 2291 _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { 2292 return o.__proto__ || Object.getPrototypeOf(o); 2293 }; 2294 return _getPrototypeOf(o); 2295 } 2296 function _setPrototypeOf(o, p) { 2297 _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { 2298 o.__proto__ = p; 2299 return o; 2300 }; 2301 return _setPrototypeOf(o, p); 2302 } 2303 function _isNativeReflectConstruct() { 2304 if (typeof Reflect === "undefined" || !Reflect.construct) return false; 2305 if (Reflect.construct.sham) return false; 2306 if (typeof Proxy === "function") return true; 2307 try { 2308 Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); 2309 return true; 2310 } catch (e) { 2311 return false; 2312 } 2313 } 2314 function _assertThisInitialized(self) { 2315 if (self === void 0) { 2316 throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); 2317 } 2318 return self; 2319 } 2320 function _possibleConstructorReturn(self, call) { 2321 if (call && (_typeof$1(call) === "object" || typeof call === "function")) { 2322 return call; 2323 } else if (call !== void 0) { 2324 throw new TypeError("Derived constructors may only return object or undefined"); 2325 } 2326 return _assertThisInitialized(self); 2327 } 2328 function _createSuper(Derived) { 2329 var hasNativeReflectConstruct = _isNativeReflectConstruct(); 2330 return function _createSuperInternal() { 2331 var Super = _getPrototypeOf(Derived), 2332 result; 2333 if (hasNativeReflectConstruct) { 2334 var NewTarget = _getPrototypeOf(this).constructor; 2335 result = Reflect.construct(Super, arguments, NewTarget); 2336 } else { 2337 result = Super.apply(this, arguments); 2338 } 2339 return _possibleConstructorReturn(this, result); 2340 }; 2341 } 2342 function _superPropBase(object, property) { 2343 while (!Object.prototype.hasOwnProperty.call(object, property)) { 2344 object = _getPrototypeOf(object); 2345 if (object === null) break; 2346 } 2347 return object; 2348 } 2349 function _get() { 2350 if (typeof Reflect !== "undefined" && Reflect.get) { 2351 _get = Reflect.get; 2352 } else { 2353 _get = function _get(target, property, receiver) { 2354 var base = _superPropBase(target, property); 2355 if (!base) return; 2356 var desc = Object.getOwnPropertyDescriptor(base, property); 2357 if (desc.get) { 2358 return desc.get.call(arguments.length < 3 ? target : receiver); 2359 } 2360 return desc.value; 2361 }; 2362 } 2363 return _get.apply(this, arguments); 2364 } 2365 var defaults = { 2366 /** 2367 * Type of the movement. 2368 * 2369 * Available types: 2370 * `slider` - Rewinds slider to the start/end when it reaches the first or last slide. 2371 * `carousel` - Changes slides without starting over when it reaches the first or last slide. 2372 * 2373 * @type {String} 2374 */ 2375 type: 'slider', 2376 /** 2377 * Start at specific slide number defined with zero-based index. 2378 * 2379 * @type {Number} 2380 */ 2381 startAt: 0, 2382 /** 2383 * A number of slides visible on the single viewport. 2384 * 2385 * @type {Number} 2386 */ 2387 perView: 1, 2388 /** 2389 * Focus currently active slide at a specified position in the track. 2390 * 2391 * Available inputs: 2392 * `center` - Current slide will be always focused at the center of a track. 2393 * `0,1,2,3...` - Current slide will be focused on the specified zero-based index. 2394 * 2395 * @type {String|Number} 2396 */ 2397 focusAt: 0, 2398 /** 2399 * A size of the gap added between slides. 2400 * 2401 * @type {Number} 2402 */ 2403 gap: 10, 2404 /** 2405 * Change slides after a specified interval. Use `false` for turning off autoplay. 2406 * 2407 * @type {Number|Boolean} 2408 */ 2409 autoplay: false, 2410 /** 2411 * Stop autoplay on mouseover event. 2412 * 2413 * @type {Boolean} 2414 */ 2415 hoverpause: true, 2416 /** 2417 * Allow for changing slides with left and right keyboard arrows. 2418 * 2419 * @type {Boolean} 2420 */ 2421 keyboard: true, 2422 /** 2423 * Stop running `perView` number of slides from the end. Use this 2424 * option if you don't want to have an empty space after 2425 * a slider. Works only with `slider` type and a 2426 * non-centered `focusAt` setting. 2427 * 2428 * @type {Boolean} 2429 */ 2430 bound: false, 2431 /** 2432 * Minimal swipe distance needed to change the slide. Use `false` for turning off a swiping. 2433 * 2434 * @type {Number|Boolean} 2435 */ 2436 swipeThreshold: 80, 2437 /** 2438 * Minimal mouse drag distance needed to change the slide. Use `false` for turning off a dragging. 2439 * 2440 * @type {Number|Boolean} 2441 */ 2442 dragThreshold: 120, 2443 /** 2444 * A number of slides moved on single swipe. 2445 * 2446 * Available types: 2447 * `` - Moves slider by one slide per swipe 2448 * `|` - Moves slider between views per swipe (number of slides defined in `perView` options) 2449 * 2450 * @type {String} 2451 */ 2452 perSwipe: '', 2453 /**
2454 * Moving distance ratio of the slides on a swiping and dragging. 2455 * 2456 * @type {Number} 2457 */ 2458 touchRatio: 0.5, 2459 /** 2460 * Angle required to activate slides moving on swiping or dragging. 2461 * 2462 * @type {Number} 2463 */ 2464 touchAngle: 45, 2465 /** 2466 * Duration of the animation in milliseconds. 2467 * 2468 * @type {Number} 2469 */ 2470 animationDuration: 400, 2471 /** 2472 * Allows looping the `slider` type. Slider will rewind to the first/last slide when it's at the start/end. 2473 * 2474 * @type {Boolean} 2475 */ 2476 rewind: true, 2477 /** 2478 * Duration of the rewinding animation of the `slider` type in milliseconds. 2479 * 2480 * @type {Number} 2481 */ 2482 rewindDuration: 800, 2483 /** 2484 * Easing function for the animation. 2485 * 2486 * @type {String} 2487 */ 2488 animationTimingFunc: 'cubic-bezier(.165, .840, .440, 1)', 2489 /** 2490 * Wait for the animation to finish until the next user input can be processed 2491 * 2492 * @type {boolean} 2493 */ 2494 waitForTransition: true, 2495 /** 2496 * Throttle costly events at most once per every wait milliseconds. 2497 * 2498 * @type {Number} 2499 */ 2500 throttle: 10, 2501 /** 2502 * Moving direction mode. 2503 * 2504 * Available inputs: 2505 * - 'ltr' - left to right movement, 2506 * - 'rtl' - right to left movement. 2507 * 2508 * @type {String} 2509 */ 2510 direction: 'ltr', 2511 /** 2512 * The distance value of the next and previous viewports which 2513 * have to peek in the current view. Accepts number and 2514 * pixels as a string. Left and right peeking can be 2515 * set up separately with a directions object. 2516 * 2517 * For example: 2518 * `100` - Peek 100px on the both sides. 2519 * { before: 100, after: 50 }` - Peek 100px on the left side and 50px on the right side. 2520 * 2521 * @type {Number|String|Object} 2522 */ 2523 peek: 0, 2524 /** 2525 * Defines how many clones of current viewport will be generated. 2526 * 2527 * @type {Number} 2528 */ 2529 cloningRatio: 1, 2530 /** 2531 * Collection of options applied at specified media breakpoints. 2532 * For example: display two slides per view under 800px. 2533 * `{ 2534 * '800px': { 2535 * perView: 2 2536 * } 2537 * }` 2538 */ 2539 breakpoints: {}, 2540 /** 2541 * Collection of internally used HTML classes. 2542 * 2543 * @todo Refactor `slider` and `carousel` properties to single `type: { slider: '', carousel: '' }` object 2544 * @type {Object} 2545 */ 2546 classes: { 2547 swipeable: 'glide--swipeable', 2548 dragging: 'glide--dragging', 2549 direction: { 2550 ltr: 'glide--ltr', 2551 rtl: 'glide--rtl' 2552 }, 2553 type: { 2554 slider: 'glide--slider', 2555 carousel: 'glide--carousel' 2556 }, 2557 slide: { 2558 clone: 'glide__slide--clone', 2559 active: 'glide__slide--active' 2560 }, 2561 arrow: { 2562 disabled: 'glide__arrow--disabled' 2563 }, 2564 nav: { 2565 active: 'glide__bullet--active' 2566 } 2567 } 2568 }; 2569 2570 /** 2571 * Outputs warning message to the bowser console. 2572 * 2573 * @param {String} msg 2574 * @return {Void} 2575 */ 2576 function warn(msg) { 2577 console.error("[Glide warn]: ".concat(msg)); 2578 } 2579 2580 /** 2581 * Converts value entered as number 2582 * or string to integer value. 2583 * 2584 * @param {String} value 2585 * @returns {Number} 2586 */ 2587 function toInt(value) { 2588 return parseInt(value); 2589 } 2590 /** 2591 * Converts value entered as number 2592 * or string to flat value. 2593 * 2594 * @param {String} value 2595 * @returns {Number} 2596 */ 2597 2598 function toFloat(value) { 2599 return parseFloat(value); 2600 } 2601 /** 2602 * Indicates whether the specified value is a string. 2603 * 2604 * @param {*} value 2605 * @return {Boolean} 2606 */ 2607 2608 function isString(value) { 2609 return typeof value === 'string'; 2610 } 2611 /** 2612 * Indicates whether the specified value is an object. 2613 * 2614 * @param {*} value 2615 * @return {Boolean} 2616 * 2617 * @see https://github.com/jashkenas/underscore 2618 */ 2619 2620 function isObject$1(value) { 2621 var type = _typeof(value); 2622 return type === 'function' || type === 'object' && !!value; // eslint-disable-line no-mixed-operators 2623 } 2624 /** 2625 * Indicates whether the specified value is a function. 2626 * 2627 * @param {*} value 2628 * @return {Boolean} 2629 */ 2630 2631 function isFunction(value) { 2632 return typeof value === 'function'; 2633 } 2634 /** 2635 * Indicates whether the specified value is undefined. 2636 * 2637 * @param {*} value 2638 * @return {Boolean} 2639 */ 2640 2641 function isUndefined(value) { 2642 return typeof value === 'undefined'; 2643 } 2644 /** 2645 * Indicates whether the specified value is an array.
vendor: 77,794 bytes, lines 2646-5452
2646 * 2647 * @param {*} value 2648 * @return {Boolean} 2649 */ 2650 2651 function isArray(value) { 2652 return value.constructor === Array; 2653 } 2654 2655 /** 2656 * Creates and initializes specified collection of extensions. 2657 * Each extension receives access to instance of glide and rest of components. 2658 * 2659 * @param {Object} glide 2660 * @param {Object} extensions 2661 * 2662 * @returns {Object} 2663 */ 2664 2665 function mount(glide, extensions, events) { 2666 var components = {}; 2667 for (var name in extensions) { 2668 if (isFunction(extensions[name])) { 2669 components[name] = extensions[name](glide, components, events); 2670 } else { 2671 warn('Extension must be a function'); 2672 } 2673 } 2674 for (var _name in components) { 2675 if (isFunction(components[_name].mount)) { 2676 components[_name].mount(); 2677 } 2678 } 2679 return components; 2680 } 2681 2682 /** 2683 * Defines getter and setter property on the specified object. 2684 * 2685 * @param {Object} obj Object where property has to be defined. 2686 * @param {String} prop Name of the defined property. 2687 * @param {Object} definition Get and set definitions for the property. 2688 * @return {Void} 2689 */ 2690 function define(obj, prop, definition) { 2691 Object.defineProperty(obj, prop, definition); 2692 } 2693 /** 2694 * Sorts aphabetically object keys. 2695 * 2696 * @param {Object} obj 2697 * @return {Object} 2698 */ 2699 2700 function sortKeys(obj) { 2701 return Object.keys(obj).sort().reduce(function (r, k) { 2702 r[k] = obj[k]; 2703 return r[k], r; 2704 }, {}); 2705 } 2706 /** 2707 * Merges passed settings object with default options. 2708 * 2709 * @param {Object} defaults 2710 * @param {Object} settings 2711 * @return {Object} 2712 */ 2713 2714 function mergeOptions(defaults, settings) { 2715 var options = Object.assign({}, defaults, settings); // `Object.assign` do not deeply merge objects, so we 2716 // have to do it manually for every nested object 2717 // in options. Although it does not look smart, 2718 // it's smaller and faster than some fancy 2719 // merging deep-merge algorithm script. 2720 2721 if (settings.hasOwnProperty('classes')) { 2722 options.classes = Object.assign({}, defaults.classes, settings.classes); 2723 if (settings.classes.hasOwnProperty('direction')) { 2724 options.classes.direction = Object.assign({}, defaults.classes.direction, settings.classes.direction); 2725 } 2726 if (settings.classes.hasOwnProperty('type')) { 2727 options.classes.type = Object.assign({}, defaults.classes.type, settings.classes.type); 2728 } 2729 if (settings.classes.hasOwnProperty('slide')) { 2730 options.classes.slide = Object.assign({}, defaults.classes.slide, settings.classes.slide); 2731 } 2732 if (settings.classes.hasOwnProperty('arrow')) { 2733 options.classes.arrow = Object.assign({}, defaults.classes.arrow, settings.classes.arrow); 2734 } 2735 if (settings.classes.hasOwnProperty('nav')) { 2736 options.classes.nav = Object.assign({}, defaults.classes.nav, settings.classes.nav); 2737 } 2738 } 2739 if (settings.hasOwnProperty('breakpoints')) { 2740 options.breakpoints = Object.assign({}, defaults.breakpoints, settings.breakpoints); 2741 } 2742 return options; 2743 } 2744 var EventsBus = /*#__PURE__*/function () { 2745 /** 2746 * Construct a EventBus instance. 2747 * 2748 * @param {Object} events 2749 */ 2750 function EventsBus() { 2751 var events = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 2752 _classCallCheck(this, EventsBus); 2753 this.events = events; 2754 this.hop = events.hasOwnProperty; 2755 } 2756 /** 2757 * Adds listener to the specifed event. 2758 * 2759 * @param {String|Array} event 2760 * @param {Function} handler 2761 */ 2762 2763 _createClass(EventsBus, [{ 2764 key: "on", 2765 value: function on(event, handler) { 2766 if (isArray(event)) { 2767 for (var i = 0; i < event.length; i++) { 2768 this.on(event[i], handler); 2769 } 2770 return; 2771 } // Create the event's object if not yet created 2772 2773 if (!this.hop.call(this.events, event)) { 2774 this.events[event] = []; 2775 } // Add the handler to queue 2776 2777 var index = this.events[event].push(handler) - 1; // Provide handle back for removal of event 2778 2779 return { 2780 remove: function remove() { 2781 delete this.events[event][index]; 2782 } 2783 }; 2784 } 2785 /** 2786 * Runs registered handlers for specified event. 2787 * 2788 * @param {String|Array} event 2789 * @param {Object=} context 2790 */ 2791 }, { 2792 key: "emit", 2793 value: function emit(event, context) { 2794 if (isArray(event)) { 2795 for (var i = 0; i < event.length; i++) { 2796 this.emit(event[i], context); 2797 } 2798 return; 2799 } // If the event doesn't exist, or there's no handlers in queue, just leave 2800 2801 if (!this.hop.call(this.events, event)) { 2802 return; 2803 } // Cycle through events queue, fire! 2804 2805 this.events[event].forEach(function (item) { 2806 item(context || {}); 2807 }); 2808 } 2809 }]); 2810 return EventsBus; 2811 }(); 2812 var Glide$1 = /*#__PURE__*/function () { 2813 /** 2814 * Construct glide. 2815 * 2816 * @param {String} selector 2817 * @param {Object} options 2818 */ 2819 function Glide(selector) { 2820 var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; 2821 _classCallCheck(this, Glide); 2822 this._c = {}; 2823 this._t = []; 2824 this._e = new EventsBus(); 2825 this.disabled = false; 2826 this.selector = selector; 2827 this.settings = mergeOptions(defaults, options); 2828 this.index = this.settings.startAt; 2829 } 2830 /** 2831 * Initializes glide. 2832 * 2833 * @param {Object} extensions Collection of extensions to initialize. 2834 * @return {Glide} 2835 */ 2836 2837 _createClass(Glide, [{ 2838 key: "mount", 2839 value: function mount$1() { 2840 var extensions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 2841 this._e.emit('mount.before'); 2842 if (isObject$1(extensions)) { 2843 this._c = mount(this, extensions, this._e); 2844 } else { 2845 warn('You need to provide a object on `mount()`'); 2846 } 2847 this._e.emit('mount.after'); 2848 return this; 2849 } 2850 /** 2851 * Collects an instance `translate` transformers. 2852 * 2853 * @param {Array} transformers Collection of transformers. 2854 * @return {Void} 2855 */ 2856 }, { 2857 key: "mutate", 2858 value: function mutate() { 2859 var transformers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 2860 if (isArray(transformers)) { 2861 this._t = transformers; 2862 } else { 2863 warn('You need to provide a array on `mutate()`'); 2864 } 2865 return this; 2866 } 2867 /** 2868 * Updates glide with specified settings. 2869 * 2870 * @param {Object} settings 2871 * @return {Glide} 2872 */ 2873 }, { 2874 key: "update", 2875 value: function update() { 2876 var settings = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 2877 this.settings = mergeOptions(this.settings, settings); 2878 if (settings.hasOwnProperty('startAt')) { 2879 this.index = settings.startAt; 2880 } 2881 this._e.emit('update'); 2882 return this; 2883 } 2884 /** 2885 * Change slide with specified pattern. A pattern must be in the special format: 2886 * `>` - Move one forward 2887 * `<` - Move one backward 2888 * `={i}` - Go to {i} zero-based slide (eq. '=1', will go to second slide) 2889 * `>>` - Rewinds to end (last slide) 2890 * `<<` - Rewinds to start (first slide) 2891 * `|>` - Move one viewport forward 2892 * `|<` - Move one viewport backward 2893 * 2894 * @param {String} pattern 2895 * @return {Glide} 2896 */ 2897 }, { 2898 key: "go", 2899 value: function go(pattern) { 2900 this._c.Run.make(pattern); 2901 return this; 2902 } 2903 /** 2904 * Move track by specified distance. 2905 * 2906 * @param {String} distance 2907 * @return {Glide} 2908 */ 2909 }, { 2910 key: "move", 2911 value: function move(distance) { 2912 this._c.Transition.disable(); 2913 this._c.Move.make(distance); 2914 return this; 2915 } 2916 /** 2917 * Destroy instance and revert all changes done by this._c. 2918 * 2919 * @return {Glide} 2920 */ 2921 }, { 2922 key: "destroy", 2923 value: function destroy() { 2924 this._e.emit('destroy'); 2925 return this; 2926 } 2927 /** 2928 * Start instance autoplaying. 2929 * 2930 * @param {Boolean|Number} interval Run autoplaying with passed interval regardless of `autoplay` settings 2931 * @return {Glide} 2932 */ 2933 }, { 2934 key: "play", 2935 value: function play() { 2936 var interval = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; 2937 if (interval) { 2938 this.settings.autoplay = interval; 2939 } 2940 this._e.emit('play'); 2941 return this; 2942 } 2943 /** 2944 * Stop instance autoplaying. 2945 * 2946 * @return {Glide} 2947 */ 2948 }, { 2949 key: "pause", 2950 value: function pause() { 2951 this._e.emit('pause'); 2952 return this; 2953 } 2954 /** 2955 * Sets glide into a idle status. 2956 * 2957 * @return {Glide} 2958 */ 2959 }, { 2960 key: "disable", 2961 value: function disable() { 2962 this.disabled = true; 2963 return this; 2964 } 2965 /** 2966 * Sets glide into a active status. 2967 * 2968 * @return {Glide} 2969 */ 2970 }, { 2971 key: "enable", 2972 value: function enable() { 2973 this.disabled = false; 2974 return this; 2975 } 2976 /** 2977 * Adds cuutom event listener with handler. 2978 * 2979 * @param {String|Array} event 2980 * @param {Function} handler 2981 * @return {Glide} 2982 */ 2983 }, { 2984 key: "on", 2985 value: function on(event, handler) { 2986 this._e.on(event, handler); 2987 return this; 2988 } 2989 /** 2990 * Checks if glide is a precised type. 2991 * 2992 * @param {String} name 2993 * @return {Boolean} 2994 */ 2995 }, { 2996 key: "isType", 2997 value: function isType(name) { 2998 return this.settings.type === name; 2999 } 3000 /** 3001 * Gets value of the core options. 3002 * 3003 * @return {Object} 3004 */ 3005 }, { 3006 key: "settings", 3007 get: function get() { 3008 return this._o; 3009 } 3010 /** 3011 * Sets value of the core options. 3012 * 3013 * @param {Object} o 3014 * @return {Void} 3015 */, 3016 3017 set: function set(o) { 3018 if (isObject$1(o)) { 3019 this._o = o; 3020 } else { 3021 warn('Options must be an `object` instance.'); 3022 } 3023 } 3024 /** 3025 * Gets current index of the slider. 3026 * 3027 * @return {Object} 3028 */ 3029 }, { 3030 key: "index", 3031 get: function get() { 3032 return this._i; 3033 } 3034 /** 3035 * Sets current index a slider. 3036 * 3037 * @return {Object} 3038 */, 3039 3040 set: function set(i) { 3041 this._i = toInt(i); 3042 } 3043 /** 3044 * Gets type name of the slider. 3045 * 3046 * @return {String} 3047 */ 3048 }, { 3049 key: "type", 3050 get: function get() { 3051 return this.settings.type; 3052 } 3053 /** 3054 * Gets value of the idle status. 3055 * 3056 * @return {Boolean} 3057 */ 3058 }, { 3059 key: "disabled", 3060 get: function get() { 3061 return this._d; 3062 } 3063 /** 3064 * Sets value of the idle status. 3065 * 3066 * @return {Boolean} 3067 */, 3068 3069 set: function set(status) { 3070 this._d = !!status; 3071 } 3072 }]); 3073 return Glide; 3074 }(); 3075 function Run(Glide, Components, Events) { 3076 var Run = { 3077 /** 3078 * Initializes autorunning of the glide. 3079 * 3080 * @return {Void} 3081 */ 3082 mount: function mount() { 3083 this._o = false; 3084 }, 3085 /** 3086 * Makes glides running based on the passed moving schema. 3087 * 3088 * @param {String} move 3089 */ 3090 make: function make(move) { 3091 var _this = this; 3092 if (!Glide.disabled) { 3093 !Glide.settings.waitForTransition || Glide.disable(); 3094 this.move = move; 3095 Events.emit('run.before', this.move); 3096 this.calculate(); 3097 Events.emit('run', this.move); 3098 Components.Transition.after(function () { 3099 if (_this.isStart()) { 3100 Events.emit('run.start', _this.move); 3101 } 3102 if (_this.isEnd()) { 3103 Events.emit('run.end', _this.move); 3104 } 3105 if (_this.isOffset()) { 3106 _this._o = false; 3107 Events.emit('run.offset', _this.move); 3108 } 3109 Events.emit('run.after', _this.move); 3110 Glide.enable(); 3111 }); 3112 } 3113 }, 3114 /** 3115 * Calculates current index based on defined move. 3116 * 3117 * @return {Number|Undefined} 3118 */ 3119 calculate: function calculate() { 3120 var move = this.move, 3121 length = this.length; 3122 var steps = move.steps, 3123 direction = move.direction; // By default assume that size of view is equal to one slide 3124 3125 var viewSize = 1; // While direction is `=` we want jump to 3126 // a specified index described in steps. 3127 3128 if (direction === '=') { 3129 // Check if bound is true, 3130 // as we want to avoid whitespaces. 3131 if (Glide.settings.bound && toInt(steps) > length) { 3132 Glide.index = length; 3133 return; 3134 } 3135 Glide.index = steps; 3136 return; 3137 } // When pattern is equal to `>>` we want 3138 // fast forward to the last slide. 3139 3140 if (direction === '>' && steps === '>') { 3141 Glide.index = length; 3142 return; 3143 } // When pattern is equal to `<<` we want 3144 // fast forward to the first slide. 3145 3146 if (direction === '<' && steps === '<') { 3147 Glide.index = 0; 3148 return; 3149 } // pagination movement 3150 3151 if (direction === '|') { 3152 viewSize = Glide.settings.perView || 1; 3153 } // we are moving forward 3154 3155 if (direction === '>' || direction === '|' && steps === '>') { 3156 var index = calculateForwardIndex(viewSize); 3157 if (index > length) { 3158 this._o = true; 3159 } 3160 Glide.index = normalizeForwardIndex(index, viewSize); 3161 return; 3162 } // we are moving backward 3163 3164 if (direction === '<' || direction === '|' && steps === '<') { 3165 var _index = calculateBackwardIndex(viewSize); 3166 if (_index < 0) { 3167 this._o = true; 3168 } 3169 Glide.index = normalizeBackwardIndex(_index, viewSize); 3170 return; 3171 } 3172 warn("Invalid direction pattern [".concat(direction).concat(steps, "] has been used")); 3173 }, 3174 /** 3175 * Checks if we are on the first slide. 3176 * 3177 * @return {Boolean} 3178 */ 3179 isStart: function isStart() { 3180 return Glide.index <= 0; 3181 }, 3182 /** 3183 * Checks if we are on the last slide. 3184 * 3185 * @return {Boolean} 3186 */ 3187 isEnd: function isEnd() { 3188 return Glide.index >= this.length; 3189 }, 3190 /** 3191 * Checks if we are making a offset run. 3192 * 3193 * @param {String} direction 3194 * @return {Boolean} 3195 */ 3196 isOffset: function isOffset() { 3197 var direction = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined; 3198 if (!direction) { 3199 return this._o; 3200 } 3201 if (!this._o) { 3202 return false; 3203 } // did we view to the right? 3204 3205 if (direction === '|>') { 3206 return this.move.direction === '|' && this.move.steps === '>'; 3207 } // did we view to the left? 3208 3209 if (direction === '|<') { 3210 return this.move.direction === '|' && this.move.steps === '<'; 3211 } 3212 return this.move.direction === direction; 3213 }, 3214 /** 3215 * Checks if bound mode is active 3216 * 3217 * @return {Boolean} 3218 */ 3219 isBound: function isBound() { 3220 return Glide.isType('slider') && Glide.settings.focusAt !== 'center' && Glide.settings.bound; 3221 } 3222 }; 3223 /** 3224 * Returns index value to move forward/to the right 3225 * 3226 * @param viewSize 3227 * @returns {Number} 3228 */ 3229 3230 function calculateForwardIndex(viewSize) { 3231 var index = Glide.index; 3232 if (Glide.isType('carousel')) { 3233 return index + viewSize; 3234 } 3235 return index + (viewSize - index % viewSize); 3236 } 3237 /** 3238 * Normalizes the given forward index based on glide settings, preventing it to exceed certain boundaries 3239 * 3240 * @param index 3241 * @param length 3242 * @param viewSize 3243 * @returns {Number} 3244 */ 3245 3246 function normalizeForwardIndex(index, viewSize) { 3247 var length = Run.length; 3248 if (index <= length) { 3249 return index; 3250 } 3251 if (Glide.isType('carousel')) { 3252 return index - (length + 1); 3253 } 3254 if (Glide.settings.rewind) { 3255 // bound does funny things with the length, therefor we have to be certain 3256 // that we are on the last possible index value given by bound 3257 if (Run.isBound() && !Run.isEnd()) { 3258 return length; 3259 } 3260 return 0; 3261 } 3262 if (Run.isBound()) { 3263 return length; 3264 } 3265 return Math.floor(length / viewSize) * viewSize; 3266 } 3267 /** 3268 * Calculates index value to move backward/to the left 3269 * 3270 * @param viewSize 3271 * @returns {Number} 3272 */ 3273 3274 function calculateBackwardIndex(viewSize) { 3275 var index = Glide.index; 3276 if (Glide.isType('carousel')) { 3277 return index - viewSize; 3278 } // ensure our back navigation results in the same index as a forward navigation 3279 // to experience a homogeneous paging 3280 3281 var view = Math.ceil(index / viewSize); 3282 return (view - 1) * viewSize; 3283 } 3284 /** 3285 * Normalizes the given backward index based on glide settings, preventing it to exceed certain boundaries 3286 * 3287 * @param index 3288 * @param length 3289 * @param viewSize 3290 * @returns {*} 3291 */ 3292 3293 function normalizeBackwardIndex(index, viewSize) { 3294 var length = Run.length; 3295 if (index >= 0) { 3296 return index; 3297 } 3298 if (Glide.isType('carousel')) { 3299 return index + (length + 1); 3300 } 3301 if (Glide.settings.rewind) { 3302 // bound does funny things with the length, therefor we have to be certain 3303 // that we are on first possible index value before we to rewind to the length given by bound 3304 if (Run.isBound() && Run.isStart()) { 3305 return length; 3306 } 3307 return Math.floor(length / viewSize) * viewSize; 3308 } 3309 return 0; 3310 } 3311 define(Run, 'move', { 3312 /** 3313 * Gets value of the move schema. 3314 * 3315 * @returns {Object} 3316 */ 3317 get: function get() { 3318 return this._m; 3319 }, 3320 /** 3321 * Sets value of the move schema. 3322 * 3323 * @returns {Object} 3324 */ 3325 set: function set(value) { 3326 var step = value.substr(1); 3327 this._m = { 3328 direction: value.substr(0, 1), 3329 steps: step ? toInt(step) ? toInt(step) : step : 0 3330 }; 3331 } 3332 }); 3333 define(Run, 'length', { 3334 /** 3335 * Gets value of the running distance based 3336 * on zero-indexing number of slides. 3337 * 3338 * @return {Number} 3339 */ 3340 get: function get() { 3341 var settings = Glide.settings; 3342 var length = Components.Html.slides.length; // If the `bound` option is active, a maximum running distance should be 3343 // reduced by `perView` and `focusAt` settings. Running distance 3344 // should end before creating an empty space after instance. 3345 3346 if (this.isBound()) { 3347 return length - 1 - (toInt(settings.perView) - 1) + toInt(settings.focusAt); 3348 } 3349 return length - 1; 3350 } 3351 }); 3352 define(Run, 'offset', { 3353 /** 3354 * Gets status of the offsetting flag. 3355 * 3356 * @return {Boolean} 3357 */ 3358 get: function get() { 3359 return this._o; 3360 } 3361 }); 3362 return Run; 3363 } 3364 3365 /** 3366 * Returns a current time. 3367 * 3368 * @return {Number} 3369 */ 3370 function now$2() { 3371 return new Date().getTime(); 3372 } 3373 3374 /** 3375 * Returns a function, that, when invoked, will only be triggered 3376 * at most once during a given window of time. 3377 * 3378 * @param {Function} func 3379 * @param {Number} wait 3380 * @param {Object=} options 3381 * @return {Function} 3382 * 3383 * @see https://github.com/jashkenas/underscore 3384 */ 3385 3386 function throttle(func, wait, options) { 3387 var timeout, context, args, result; 3388 var previous = 0; 3389 if (!options) options = {}; 3390 var later = function later() { 3391 previous = options.leading === false ? 0 : now$2(); 3392 timeout = null; 3393 result = func.apply(context, args); 3394 if (!timeout) context = args = null; 3395 }; 3396 var throttled = function throttled() { 3397 var at = now$2(); 3398 if (!previous && options.leading === false) previous = at; 3399 var remaining = wait - (at - previous); 3400 context = this; 3401 args = arguments; 3402 if (remaining <= 0 || remaining > wait) { 3403 if (timeout) { 3404 clearTimeout(timeout); 3405 timeout = null; 3406 } 3407 previous = at; 3408 result = func.apply(context, args); 3409 if (!timeout) context = args = null; 3410 } else if (!timeout && options.trailing !== false) { 3411 timeout = setTimeout(later, remaining); 3412 } 3413 return result; 3414 }; 3415 throttled.cancel = function () { 3416 clearTimeout(timeout); 3417 previous = 0; 3418 timeout = context = args = null; 3419 }; 3420 return throttled; 3421 } 3422 var MARGIN_TYPE = { 3423 ltr: ['marginLeft', 'marginRight'], 3424 rtl: ['marginRight', 'marginLeft'] 3425 }; 3426 function Gaps(Glide, Components, Events) { 3427 var Gaps = { 3428 /** 3429 * Applies gaps between slides. First and last 3430 * slides do not receive it's edge margins. 3431 * 3432 * @param {HTMLCollection} slides 3433 * @return {Void} 3434 */ 3435 apply: function apply(slides) { 3436 for (var i = 0, len = slides.length; i < len; i++) { 3437 var style = slides[i].style; 3438 var direction = Components.Direction.value; 3439 if (i !== 0) { 3440 style[MARGIN_TYPE[direction][0]] = "".concat(this.value / 2, "px"); 3441 } else { 3442 style[MARGIN_TYPE[direction][0]] = ''; 3443 } 3444 if (i !== slides.length - 1) { 3445 style[MARGIN_TYPE[direction][1]] = "".concat(this.value / 2, "px"); 3446 } else { 3447 style[MARGIN_TYPE[direction][1]] = ''; 3448 } 3449 } 3450 }, 3451 /** 3452 * Removes gaps from the slides. 3453 * 3454 * @param {HTMLCollection} slides 3455 * @returns {Void} 3456 */ 3457 remove: function remove(slides) { 3458 for (var i = 0, len = slides.length; i < len; i++) { 3459 var style = slides[i].style; 3460 style.marginLeft = ''; 3461 style.marginRight = ''; 3462 } 3463 } 3464 }; 3465 define(Gaps, 'value', { 3466 /** 3467 * Gets value of the gap. 3468 * 3469 * @returns {Number} 3470 */ 3471 get: function get() { 3472 return toInt(Glide.settings.gap); 3473 } 3474 }); 3475 define(Gaps, 'grow', { 3476 /** 3477 * Gets additional dimensions value caused by gaps. 3478 * Used to increase width of the slides wrapper. 3479 * 3480 * @returns {Number} 3481 */ 3482 get: function get() { 3483 return Gaps.value * Components.Sizes.length; 3484 } 3485 }); 3486 define(Gaps, 'reductor', { 3487 /** 3488 * Gets reduction value caused by gaps. 3489 * Used to subtract width of the slides. 3490 * 3491 * @returns {Number} 3492 */ 3493 get: function get() { 3494 var perView = Glide.settings.perView; 3495 return Gaps.value * (perView - 1) / perView; 3496 } 3497 }); 3498 /** 3499 * Apply calculated gaps: 3500 * - after building, so slides (including clones) will receive proper margins 3501 * - on updating via API, to recalculate gaps with new options 3502 */ 3503 3504 Events.on(['build.after', 'update'], throttle(function () { 3505 Gaps.apply(Components.Html.wrapper.children); 3506 }, 30)); 3507 /** 3508 * Remove gaps: 3509 * - on destroying to bring markup to its inital state 3510 */ 3511 3512 Events.on('destroy', function () { 3513 Gaps.remove(Components.Html.wrapper.children); 3514 }); 3515 return Gaps; 3516 } 3517 3518 /** 3519 * Finds siblings nodes of the passed node. 3520 * 3521 * @param {Element} node 3522 * @return {Array} 3523 */ 3524 function siblings(node) { 3525 if (node && node.parentNode) { 3526 var n = node.parentNode.firstChild; 3527 var matched = []; 3528 for (; n; n = n.nextSibling) { 3529 if (n.nodeType === 1 && n !== node) { 3530 matched.push(n); 3531 } 3532 } 3533 return matched; 3534 } 3535 return []; 3536 } 3537 /** 3538 * Checks if passed node exist and is a valid element. 3539 * 3540 * @param {Element} node 3541 * @return {Boolean} 3542 */ 3543 3544 function exist(node) { 3545 if (node && node instanceof window.HTMLElement) { 3546 return true; 3547 } 3548 return false; 3549 } 3550 /** 3551 * Coerces a NodeList to an Array. 3552 * 3553 * @param {NodeList} nodeList 3554 * @return {Array} 3555 */ 3556 3557 function toArray(nodeList) { 3558 return Array.prototype.slice.call(nodeList); 3559 } 3560 var TRACK_SELECTOR = '[data-glide-el="track"]'; 3561 function Html(Glide, Components, Events) { 3562 var Html = { 3563 /** 3564 * Setup slider HTML nodes. 3565 * 3566 * @param {Glide} glide 3567 */ 3568 mount: function mount() { 3569 this.root = Glide.selector; 3570 this.track = this.root.querySelector(TRACK_SELECTOR); 3571 this.collectSlides(); 3572 }, 3573 /** 3574 * Collect slides 3575 */ 3576 collectSlides: function collectSlides() { 3577 this.slides = toArray(this.wrapper.children).filter(function (slide) { 3578 return !slide.classList.contains(Glide.settings.classes.slide.clone); 3579 }); 3580 } 3581 }; 3582 define(Html, 'root', { 3583 /** 3584 * Gets node of the glide main element. 3585 * 3586 * @return {Object} 3587 */ 3588 get: function get() { 3589 return Html._r; 3590 }, 3591 /** 3592 * Sets node of the glide main element. 3593 * 3594 * @return {Object} 3595 */ 3596 set: function set(r) { 3597 if (isString(r)) { 3598 r = document.querySelector(r); 3599 } 3600 if (exist(r)) { 3601 Html._r = r; 3602 } else { 3603 warn('Root element must be a existing Html node'); 3604 } 3605 } 3606 }); 3607 define(Html, 'track', { 3608 /** 3609 * Gets node of the glide track with slides. 3610 * 3611 * @return {Object} 3612 */ 3613 get: function get() { 3614 return Html._t; 3615 }, 3616 /** 3617 * Sets node of the glide track with slides. 3618 * 3619 * @return {Object} 3620 */ 3621 set: function set(t) { 3622 if (exist(t)) { 3623 Html._t = t; 3624 } else { 3625 warn("Could not find track element. Please use ".concat(TRACK_SELECTOR, " attribute.")); 3626 } 3627 } 3628 }); 3629 define(Html, 'wrapper', { 3630 /** 3631 * Gets node of the slides wrapper. 3632 * 3633 * @return {Object} 3634 */ 3635 get: function get() { 3636 return Html.track.children[0]; 3637 } 3638 }); 3639 /** 3640 * Add/remove/reorder dynamic slides 3641 */ 3642 3643 Events.on('update', function () { 3644 Html.collectSlides(); 3645 }); 3646 return Html; 3647 } 3648 function Peek(Glide, Components, Events) { 3649 var Peek = { 3650 /** 3651 * Setups how much to peek based on settings. 3652 * 3653 * @return {Void} 3654 */ 3655 mount: function mount() { 3656 this.value = Glide.settings.peek; 3657 } 3658 }; 3659 define(Peek, 'value', { 3660 /** 3661 * Gets value of the peek. 3662 * 3663 * @returns {Number|Object} 3664 */ 3665 get: function get() { 3666 return Peek._v; 3667 }, 3668 /** 3669 * Sets value of the peek. 3670 * 3671 * @param {Number|Object} value 3672 * @return {Void} 3673 */ 3674 set: function set(value) { 3675 if (isObject$1(value)) { 3676 value.before = toInt(value.before); 3677 value.after = toInt(value.after); 3678 } else { 3679 value = toInt(value); 3680 } 3681 Peek._v = value; 3682 } 3683 }); 3684 define(Peek, 'reductor', { 3685 /** 3686 * Gets reduction value caused by peek. 3687 * 3688 * @returns {Number} 3689 */ 3690 get: function get() { 3691 var value = Peek.value; 3692 var perView = Glide.settings.perView; 3693 if (isObject$1(value)) { 3694 return value.before / perView + value.after / perView; 3695 } 3696 return value * 2 / perView; 3697 } 3698 }); 3699 /** 3700 * Recalculate peeking sizes on: 3701 * - when resizing window to update to proper percents 3702 */ 3703 3704 Events.on(['resize', 'update'], function () { 3705 Peek.mount(); 3706 }); 3707 return Peek; 3708 } 3709 function Move(Glide, Components, Events) { 3710 var Move = { 3711 /** 3712 * Constructs move component. 3713 * 3714 * @returns {Void} 3715 */ 3716 mount: function mount() { 3717 this._o = 0; 3718 }, 3719 /** 3720 * Calculates a movement value based on passed offset and currently active index. 3721 * 3722 * @param {Number} offset 3723 * @return {Void} 3724 */ 3725 make: function make() { 3726 var _this = this; 3727 var offset = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; 3728 this.offset = offset; 3729 Events.emit('move', { 3730 movement: this.value 3731 }); 3732 Components.Transition.after(function () { 3733 Events.emit('move.after', { 3734 movement: _this.value 3735 }); 3736 }); 3737 } 3738 }; 3739 define(Move, 'offset', { 3740 /** 3741 * Gets an offset value used to modify current translate. 3742 * 3743 * @return {Object} 3744 */ 3745 get: function get() { 3746 return Move._o; 3747 }, 3748 /** 3749 * Sets an offset value used to modify current translate. 3750 * 3751 * @return {Object} 3752 */ 3753 set: function set(value) { 3754 Move._o = !isUndefined(value) ? toInt(value) : 0; 3755 } 3756 }); 3757 define(Move, 'translate', { 3758 /** 3759 * Gets a raw movement value. 3760 * 3761 * @return {Number} 3762 */ 3763 get: function get() { 3764 return Components.Sizes.slideWidth * Glide.index; 3765 } 3766 }); 3767 define(Move, 'value', { 3768 /** 3769 * Gets an actual movement value corrected by offset. 3770 * 3771 * @return {Number} 3772 */ 3773 get: function get() { 3774 var offset = this.offset; 3775 var translate = this.translate; 3776 if (Components.Direction.is('rtl')) { 3777 return translate + offset; 3778 } 3779 return translate - offset; 3780 } 3781 }); 3782 /** 3783 * Make movement to proper slide on: 3784 * - before build, so glide will start at `startAt` index 3785 * - on each standard run to move to newly calculated index 3786 */ 3787 3788 Events.on(['build.before', 'run'], function () { 3789 Move.make(); 3790 }); 3791 return Move; 3792 } 3793 function Sizes(Glide, Components, Events) { 3794 var Sizes = { 3795 /** 3796 * Setups dimensions of slides. 3797 * 3798 * @return {Void} 3799 */ 3800 setupSlides: function setupSlides() { 3801 var width = "".concat(this.slideWidth, "px"); 3802 var slides = Components.Html.slides; 3803 for (var i = 0; i < slides.length; i++) { 3804 slides[i].style.width = width; 3805 } 3806 }, 3807 /** 3808 * Setups dimensions of slides wrapper. 3809 * 3810 * @return {Void} 3811 */ 3812 setupWrapper: function setupWrapper() { 3813 Components.Html.wrapper.style.width = "".concat(this.wrapperSize, "px"); 3814 }, 3815 /** 3816 * Removes applied styles from HTML elements. 3817 * 3818 * @returns {Void} 3819 */ 3820 remove: function remove() { 3821 var slides = Components.Html.slides; 3822 for (var i = 0; i < slides.length; i++) { 3823 slides[i].style.width = ''; 3824 } 3825 Components.Html.wrapper.style.width = ''; 3826 } 3827 }; 3828 define(Sizes, 'length', { 3829 /** 3830 * Gets count number of the slides. 3831 * 3832 * @return {Number} 3833 */ 3834 get: function get() { 3835 return Components.Html.slides.length; 3836 } 3837 }); 3838 define(Sizes, 'width', { 3839 /** 3840 * Gets width value of the slider (visible area). 3841 * 3842 * @return {Number} 3843 */ 3844 get: function get() { 3845 return Components.Html.track.offsetWidth; 3846 } 3847 }); 3848 define(Sizes, 'wrapperSize', { 3849 /** 3850 * Gets size of the slides wrapper. 3851 * 3852 * @return {Number} 3853 */ 3854 get: function get() { 3855 return Sizes.slideWidth * Sizes.length + Components.Gaps.grow + Components.Clones.grow; 3856 } 3857 }); 3858 define(Sizes, 'slideWidth', { 3859 /** 3860 * Gets width value of a single slide. 3861 * 3862 * @return {Number} 3863 */ 3864 get: function get() { 3865 return Sizes.width / Glide.settings.perView - Components.Peek.reductor - Components.Gaps.reductor; 3866 } 3867 }); 3868 /** 3869 * Apply calculated glide's dimensions: 3870 * - before building, so other dimensions (e.g. translate) will be calculated propertly 3871 * - when resizing window to recalculate sildes dimensions 3872 * - on updating via API, to calculate dimensions based on new options 3873 */ 3874 3875 Events.on(['build.before', 'resize', 'update'], function () { 3876 Sizes.setupSlides(); 3877 Sizes.setupWrapper(); 3878 }); 3879 /** 3880 * Remove calculated glide's dimensions: 3881 * - on destoting to bring markup to its inital state 3882 */ 3883 3884 Events.on('destroy', function () { 3885 Sizes.remove(); 3886 }); 3887 return Sizes; 3888 } 3889 function Build(Glide, Components, Events) { 3890 var Build = { 3891 /** 3892 * Init glide building. Adds classes, sets 3893 * dimensions and setups initial state. 3894 * 3895 * @return {Void} 3896 */ 3897 mount: function mount() { 3898 Events.emit('build.before'); 3899 this.typeClass(); 3900 this.activeClass(); 3901 Events.emit('build.after'); 3902 }, 3903 /** 3904 * Adds `type` class to the glide element. 3905 * 3906 * @return {Void} 3907 */ 3908 typeClass: function typeClass() { 3909 Components.Html.root.classList.add(Glide.settings.classes.type[Glide.settings.type]); 3910 }, 3911 /** 3912 * Sets active class to current slide. 3913 * 3914 * @return {Void} 3915 */ 3916 activeClass: function activeClass() { 3917 var classes = Glide.settings.classes; 3918 var slide = Components.Html.slides[Glide.index]; 3919 if (slide) { 3920 slide.classList.add(classes.slide.active); 3921 siblings(slide).forEach(function (sibling) { 3922 sibling.classList.remove(classes.slide.active); 3923 }); 3924 } 3925 }, 3926 /** 3927 * Removes HTML classes applied at building. 3928 * 3929 * @return {Void} 3930 */ 3931 removeClasses: function removeClasses() { 3932 var _Glide$settings$class = Glide.settings.classes, 3933 type = _Glide$settings$class.type, 3934 slide = _Glide$settings$class.slide; 3935 Components.Html.root.classList.remove(type[Glide.settings.type]); 3936 Components.Html.slides.forEach(function (sibling) { 3937 sibling.classList.remove(slide.active); 3938 }); 3939 } 3940 }; 3941 /** 3942 * Clear building classes: 3943 * - on destroying to bring HTML to its initial state 3944 * - on updating to remove classes before remounting component 3945 */ 3946 3947 Events.on(['destroy', 'update'], function () { 3948 Build.removeClasses(); 3949 }); 3950 /** 3951 * Remount component: 3952 * - on resizing of the window to calculate new dimensions 3953 * - on updating settings via API 3954 */ 3955 3956 Events.on(['resize', 'update'], function () { 3957 Build.mount(); 3958 }); 3959 /** 3960 * Swap active class of current slide: 3961 * - after each move to the new index 3962 */ 3963 3964 Events.on('move.after', function () { 3965 Build.activeClass(); 3966 }); 3967 return Build; 3968 } 3969 function Clones(Glide, Components, Events) { 3970 var Clones = { 3971 /** 3972 * Create pattern map and collect slides to be cloned. 3973 */ 3974 mount: function mount() { 3975 this.items = []; 3976 if (Glide.isType('carousel')) { 3977 this.items = this.collect(); 3978 } 3979 }, 3980 /** 3981 * Collect clones with pattern. 3982 * 3983 * @return {[]} 3984 */ 3985 collect: function collect() { 3986 var items = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; 3987 var slides = Components.Html.slides; 3988 var _Glide$settings = Glide.settings, 3989 perView = _Glide$settings.perView, 3990 classes = _Glide$settings.classes, 3991 cloningRatio = _Glide$settings.cloningRatio; 3992 if (slides.length !== 0) { 3993 var peekIncrementer = +!!Glide.settings.peek; 3994 var cloneCount = perView + peekIncrementer + Math.round(perView / 2); 3995 var append = slides.slice(0, cloneCount).reverse(); 3996 var prepend = slides.slice(cloneCount * -1); 3997 for (var r = 0; r < Math.max(cloningRatio, Math.floor(perView / slides.length)); r++) { 3998 for (var i = 0; i < append.length; i++) { 3999 var clone = append[i].cloneNode(true); 4000 clone.classList.add(classes.slide.clone); 4001 items.push(clone); 4002 } 4003 for (var _i = 0; _i < prepend.length; _i++) { 4004 var _clone = prepend[_i].cloneNode(true); 4005 _clone.classList.add(classes.slide.clone); 4006 items.unshift(_clone); 4007 } 4008 } 4009 } 4010 return items; 4011 }, 4012 /** 4013 * Append cloned slides with generated pattern. 4014 * 4015 * @return {Void} 4016 */ 4017 append: function append() { 4018 var items = this.items; 4019 var _Components$Html = Components.Html, 4020 wrapper = _Components$Html.wrapper, 4021 slides = _Components$Html.slides; 4022 var half = Math.floor(items.length / 2); 4023 var prepend = items.slice(0, half).reverse(); 4024 var append = items.slice(half * -1).reverse(); 4025 var width = "".concat(Components.Sizes.slideWidth, "px"); 4026 for (var i = 0; i < append.length; i++) { 4027 wrapper.appendChild(append[i]); 4028 } 4029 for (var _i2 = 0; _i2 < prepend.length; _i2++) { 4030 wrapper.insertBefore(prepend[_i2], slides[0]); 4031 } 4032 for (var _i3 = 0; _i3 < items.length; _i3++) { 4033 items[_i3].style.width = width; 4034 } 4035 }, 4036 /** 4037 * Remove all cloned slides. 4038 * 4039 * @return {Void} 4040 */ 4041 remove: function remove() { 4042 var items = this.items; 4043 for (var i = 0; i < items.length; i++) { 4044 Components.Html.wrapper.removeChild(items[i]); 4045 } 4046 } 4047 }; 4048 define(Clones, 'grow', { 4049 /** 4050 * Gets additional dimensions value caused by clones. 4051 * 4052 * @return {Number} 4053 */ 4054 get: function get() { 4055 return (Components.Sizes.slideWidth + Components.Gaps.value) * Clones.items.length; 4056 } 4057 }); 4058 /** 4059 * Append additional slide's clones: 4060 * - while glide's type is `carousel` 4061 */ 4062 4063 Events.on('update', function () { 4064 Clones.remove(); 4065 Clones.mount(); 4066 Clones.append(); 4067 }); 4068 /** 4069 * Append additional slide's clones: 4070 * - while glide's type is `carousel` 4071 */ 4072 4073 Events.on('build.before', function () { 4074 if (Glide.isType('carousel')) { 4075 Clones.append(); 4076 } 4077 }); 4078 /** 4079 * Remove clones HTMLElements: 4080 * - on destroying, to bring HTML to its initial state 4081 */ 4082 4083 Events.on('destroy', function () { 4084 Clones.remove(); 4085 }); 4086 return Clones; 4087 } 4088 var EventsBinder = /*#__PURE__*/function () { 4089 /** 4090 * Construct a EventsBinder instance. 4091 */ 4092 function EventsBinder() { 4093 var listeners = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 4094 _classCallCheck(this, EventsBinder); 4095 this.listeners = listeners; 4096 } 4097 /** 4098 * Adds events listeners to arrows HTML elements. 4099 * 4100 * @param {String|Array} events 4101 * @param {Element|Window|Document} el 4102 * @param {Function} closure 4103 * @param {Boolean|Object} capture 4104 * @return {Void} 4105 */ 4106 4107 _createClass(EventsBinder, [{ 4108 key: "on", 4109 value: function on(events, el, closure) { 4110 var capture = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; 4111 if (isString(events)) { 4112 events = [events]; 4113 } 4114 for (var i = 0; i < events.length; i++) { 4115 this.listeners[events[i]] = closure; 4116 el.addEventListener(events[i], this.listeners[events[i]], capture); 4117 } 4118 } 4119 /** 4120 * Removes event listeners from arrows HTML elements. 4121 * 4122 * @param {String|Array} events 4123 * @param {Element|Window|Document} el 4124 * @param {Boolean|Object} capture 4125 * @return {Void} 4126 */ 4127 }, { 4128 key: "off", 4129 value: function off(events, el) { 4130 var capture = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 4131 if (isString(events)) { 4132 events = [events]; 4133 } 4134 for (var i = 0; i < events.length; i++) { 4135 el.removeEventListener(events[i], this.listeners[events[i]], capture); 4136 } 4137 } 4138 /** 4139 * Destroy collected listeners. 4140 * 4141 * @returns {Void} 4142 */ 4143 }, { 4144 key: "destroy", 4145 value: function destroy() { 4146 delete this.listeners; 4147 } 4148 }]); 4149 return EventsBinder; 4150 }(); 4151 function Resize(Glide, Components, Events) { 4152 /** 4153 * Instance of the binder for DOM Events. 4154 * 4155 * @type {EventsBinder} 4156 */ 4157 var Binder = new EventsBinder(); 4158 var Resize = { 4159 /** 4160 * Initializes window bindings. 4161 */ 4162 mount: function mount() { 4163 this.bind(); 4164 }, 4165 /** 4166 * Binds `rezsize` listener to the window. 4167 * It's a costly event, so we are debouncing it. 4168 * 4169 * @return {Void} 4170 */ 4171 bind: function bind() { 4172 Binder.on('resize', window, throttle(function () { 4173 Events.emit('resize'); 4174 }, Glide.settings.throttle)); 4175 }, 4176 /** 4177 * Unbinds listeners from the window. 4178 * 4179 * @return {Void} 4180 */ 4181 unbind: function unbind() { 4182 Binder.off('resize', window); 4183 } 4184 }; 4185 /** 4186 * Remove bindings from window: 4187 * - on destroying, to remove added EventListener 4188 */ 4189 4190 Events.on('destroy', function () { 4191 Resize.unbind(); 4192 Binder.destroy(); 4193 }); 4194 return Resize; 4195 } 4196 var VALID_DIRECTIONS = ['ltr', 'rtl']; 4197 var FLIPED_MOVEMENTS = { 4198 '>': '<', 4199 '<': '>', 4200 '=': '=' 4201 }; 4202 function Direction(Glide, Components, Events) { 4203 var Direction = { 4204 /** 4205 * Setups gap value based on settings. 4206 * 4207 * @return {Void} 4208 */ 4209 mount: function mount() { 4210 this.value = Glide.settings.direction; 4211 }, 4212 /** 4213 * Resolves pattern based on direction value 4214 * 4215 * @param {String} pattern 4216 * @returns {String} 4217 */ 4218 resolve: function resolve(pattern) { 4219 var token = pattern.slice(0, 1); 4220 if (this.is('rtl')) { 4221 return pattern.split(token).join(FLIPED_MOVEMENTS[token]); 4222 } 4223 return pattern; 4224 }, 4225 /** 4226 * Checks value of direction mode. 4227 * 4228 * @param {String} direction 4229 * @returns {Boolean} 4230 */ 4231 is: function is(direction) { 4232 return this.value === direction; 4233 }, 4234 /** 4235 * Applies direction class to the root HTML element. 4236 * 4237 * @return {Void} 4238 */ 4239 addClass: function addClass() { 4240 Components.Html.root.classList.add(Glide.settings.classes.direction[this.value]); 4241 }, 4242 /** 4243 * Removes direction class from the root HTML element. 4244 * 4245 * @return {Void} 4246 */ 4247 removeClass: function removeClass() { 4248 Components.Html.root.classList.remove(Glide.settings.classes.direction[this.value]); 4249 } 4250 }; 4251 define(Direction, 'value', { 4252 /** 4253 * Gets value of the direction. 4254 * 4255 * @returns {Number} 4256 */ 4257 get: function get() { 4258 return Direction._v; 4259 }, 4260 /** 4261 * Sets value of the direction. 4262 * 4263 * @param {String} value 4264 * @return {Void} 4265 */ 4266 set: function set(value) { 4267 if (VALID_DIRECTIONS.indexOf(value) > -1) { 4268 Direction._v = value; 4269 } else { 4270 warn('Direction value must be `ltr` or `rtl`'); 4271 } 4272 } 4273 }); 4274 /** 4275 * Clear direction class: 4276 * - on destroy to bring HTML to its initial state 4277 * - on update to remove class before reappling bellow 4278 */ 4279 4280 Events.on(['destroy', 'update'], function () { 4281 Direction.removeClass(); 4282 }); 4283 /** 4284 * Remount component: 4285 * - on update to reflect changes in direction value 4286 */ 4287 4288 Events.on('update', function () { 4289 Direction.mount(); 4290 }); 4291 /** 4292 * Apply direction class: 4293 * - before building to apply class for the first time 4294 * - on updating to reapply direction class that may changed 4295 */ 4296 4297 Events.on(['build.before', 'update'], function () { 4298 Direction.addClass(); 4299 }); 4300 return Direction; 4301 } 4302 4303 /** 4304 * Reflects value of glide movement. 4305 * 4306 * @param {Object} Glide 4307 * @param {Object} Components 4308 * @return {Object} 4309 */ 4310 function Rtl(Glide, Components) { 4311 return { 4312 /** 4313 * Negates the passed translate if glide is in RTL option. 4314 * 4315 * @param {Number} translate 4316 * @return {Number} 4317 */ 4318 modify: function modify(translate) { 4319 if (Components.Direction.is('rtl')) { 4320 return -translate; 4321 } 4322 return translate; 4323 } 4324 }; 4325 } 4326 4327 /** 4328 * Updates glide movement with a `gap` settings. 4329 * 4330 * @param {Object} Glide 4331 * @param {Object} Components 4332 * @return {Object} 4333 */ 4334 function Gap(Glide, Components) { 4335 return { 4336 /** 4337 * Modifies passed translate value with number in the `gap` settings. 4338 * 4339 * @param {Number} translate 4340 * @return {Number} 4341 */ 4342 modify: function modify(translate) { 4343 var multiplier = Math.floor(translate / Components.Sizes.slideWidth); 4344 return translate + Components.Gaps.value * multiplier; 4345 } 4346 }; 4347 } 4348 4349 /** 4350 * Updates glide movement with width of additional clones width. 4351 * 4352 * @param {Object} Glide 4353 * @param {Object} Components 4354 * @return {Object} 4355 */ 4356 function Grow(Glide, Components) { 4357 return { 4358 /** 4359 * Adds to the passed translate width of the half of clones. 4360 * 4361 * @param {Number} translate 4362 * @return {Number} 4363 */ 4364 modify: function modify(translate) { 4365 return translate + Components.Clones.grow / 2; 4366 } 4367 }; 4368 } 4369 4370 /** 4371 * Updates glide movement with a `peek` settings. 4372 * 4373 * @param {Object} Glide 4374 * @param {Object} Components 4375 * @return {Object} 4376 */ 4377 4378 function Peeking(Glide, Components) { 4379 return { 4380 /** 4381 * Modifies passed translate value with a `peek` setting. 4382 * 4383 * @param {Number} translate 4384 * @return {Number} 4385 */ 4386 modify: function modify(translate) { 4387 if (Glide.settings.focusAt >= 0) { 4388 var peek = Components.Peek.value; 4389 if (isObject$1(peek)) { 4390 return translate - peek.before; 4391 } 4392 return translate - peek; 4393 } 4394 return translate; 4395 } 4396 }; 4397 } 4398 4399 /** 4400 * Updates glide movement with a `focusAt` settings. 4401 * 4402 * @param {Object} Glide 4403 * @param {Object} Components 4404 * @return {Object} 4405 */ 4406 function Focusing(Glide, Components) { 4407 return { 4408 /** 4409 * Modifies passed translate value with index in the `focusAt` setting. 4410 * 4411 * @param {Number} translate 4412 * @return {Number} 4413 */ 4414 modify: function modify(translate) { 4415 var gap = Components.Gaps.value; 4416 var width = Components.Sizes.width; 4417 var focusAt = Glide.settings.focusAt; 4418 var slideWidth = Components.Sizes.slideWidth; 4419 if (focusAt === 'center') { 4420 return translate - (width / 2 - slideWidth / 2); 4421 } 4422 return translate - slideWidth * focusAt - gap * focusAt; 4423 } 4424 }; 4425 } 4426 4427 /** 4428 * Applies diffrent transformers on translate value. 4429 * 4430 * @param {Object} Glide 4431 * @param {Object} Components 4432 * @return {Object} 4433 */ 4434 4435 function mutator(Glide, Components, Events) { 4436 /** 4437 * Merge instance transformers with collection of default transformers. 4438 * It's important that the Rtl component be last on the list, 4439 * so it reflects all previous transformations. 4440 * 4441 * @type {Array} 4442 */ 4443 var TRANSFORMERS = [Gap, Grow, Peeking, Focusing].concat(Glide._t, [Rtl]); 4444 return { 4445 /** 4446 * Piplines translate value with registered transformers. 4447 * 4448 * @param {Number} translate 4449 * @return {Number} 4450 */ 4451 mutate: function mutate(translate) { 4452 for (var i = 0; i < TRANSFORMERS.length; i++) { 4453 var transformer = TRANSFORMERS[i]; 4454 if (isFunction(transformer) && isFunction(transformer().modify)) { 4455 translate = transformer(Glide, Components, Events).modify(translate); 4456 } else { 4457 warn('Transformer should be a function that returns an object with `modify()` method'); 4458 } 4459 } 4460 return translate; 4461 } 4462 }; 4463 } 4464 function Translate(Glide, Components, Events) { 4465 var Translate = { 4466 /** 4467 * Sets value of translate on HTML element. 4468 * 4469 * @param {Number} value 4470 * @return {Void} 4471 */ 4472 set: function set(value) { 4473 var transform = mutator(Glide, Components).mutate(value); 4474 var translate3d = "translate3d(".concat(-1 * transform, "px, 0px, 0px)"); 4475 Components.Html.wrapper.style.mozTransform = translate3d; // needed for supported Firefox 10-15 4476 4477 Components.Html.wrapper.style.webkitTransform = translate3d; // needed for supported Chrome 10-35, Safari 5.1-8, and Opera 15-22 4478 4479 Components.Html.wrapper.style.transform = translate3d; 4480 }, 4481 /** 4482 * Removes value of translate from HTML element. 4483 * 4484 * @return {Void} 4485 */ 4486 remove: function remove() { 4487 Components.Html.wrapper.style.transform = ''; 4488 }, 4489 /** 4490 * @return {number} 4491 */ 4492 getStartIndex: function getStartIndex() { 4493 var length = Components.Sizes.length; 4494 var index = Glide.index; 4495 var perView = Glide.settings.perView; 4496 if (Components.Run.isOffset('>') || Components.Run.isOffset('|>')) { 4497 return length + (index - perView); 4498 } // "modulo length" converts an index that equals length to zero 4499 4500 return (index + perView) % length; 4501 }, 4502 /** 4503 * @return {number} 4504 */ 4505 getTravelDistance: function getTravelDistance() { 4506 var travelDistance = Components.Sizes.slideWidth * Glide.settings.perView; 4507 if (Components.Run.isOffset('>') || Components.Run.isOffset('|>')) { 4508 // reverse travel distance so that we don't have to change subtract operations 4509 return travelDistance * -1; 4510 } 4511 return travelDistance; 4512 } 4513 }; 4514 /** 4515 * Set new translate value: 4516 * - on move to reflect index change 4517 * - on updating via API to reflect possible changes in options 4518 */ 4519 4520 Events.on('move', function (context) { 4521 if (!Glide.isType('carousel') || !Components.Run.isOffset()) { 4522 return Translate.set(context.movement); 4523 } 4524 Components.Transition.after(function () { 4525 Events.emit('translate.jump'); 4526 Translate.set(Components.Sizes.slideWidth * Glide.index); 4527 }); 4528 var startWidth = Components.Sizes.slideWidth * Components.Translate.getStartIndex(); 4529 return Translate.set(startWidth - Components.Translate.getTravelDistance()); 4530 }); 4531 /** 4532 * Remove translate: 4533 * - on destroying to bring markup to its inital state 4534 */ 4535 4536 Events.on('destroy', function () { 4537 Translate.remove(); 4538 }); 4539 return Translate; 4540 } 4541 function Transition(Glide, Components, Events) { 4542 /** 4543 * Holds inactivity status of transition. 4544 * When true transition is not applied. 4545 * 4546 * @type {Boolean} 4547 */ 4548 var disabled = false; 4549 var Transition = { 4550 /** 4551 * Composes string of the CSS transition. 4552 * 4553 * @param {String} property 4554 * @return {String} 4555 */ 4556 compose: function compose(property) { 4557 var settings = Glide.settings; 4558 if (!disabled) { 4559 return "".concat(property, " ").concat(this.duration, "ms ").concat(settings.animationTimingFunc); 4560 } 4561 return "".concat(property, " 0ms ").concat(settings.animationTimingFunc); 4562 }, 4563 /** 4564 * Sets value of transition on HTML element. 4565 * 4566 * @param {String=} property 4567 * @return {Void} 4568 */ 4569 set: function set() { 4570 var property = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'transform'; 4571 Components.Html.wrapper.style.transition = this.compose(property); 4572 }, 4573 /** 4574 * Removes value of transition from HTML element. 4575 * 4576 * @return {Void} 4577 */ 4578 remove: function remove() { 4579 Components.Html.wrapper.style.transition = ''; 4580 }, 4581 /** 4582 * Runs callback after animation. 4583 * 4584 * @param {Function} callback 4585 * @return {Void} 4586 */ 4587 after: function after(callback) { 4588 setTimeout(function () { 4589 callback(); 4590 }, this.duration); 4591 }, 4592 /** 4593 * Enable transition. 4594 * 4595 * @return {Void} 4596 */ 4597 enable: function enable() { 4598 disabled = false; 4599 this.set(); 4600 }, 4601 /** 4602 * Disable transition. 4603 * 4604 * @return {Void} 4605 */ 4606 disable: function disable() { 4607 disabled = true; 4608 this.set(); 4609 } 4610 }; 4611 define(Transition, 'duration', { 4612 /** 4613 * Gets duration of the transition based 4614 * on currently running animation type. 4615 * 4616 * @return {Number} 4617 */ 4618 get: function get() { 4619 var settings = Glide.settings; 4620 if (Glide.isType('slider') && Components.Run.offset) { 4621 return settings.rewindDuration; 4622 } 4623 return settings.animationDuration; 4624 } 4625 }); 4626 /** 4627 * Set transition `style` value: 4628 * - on each moving, because it may be cleared by offset move 4629 */ 4630 4631 Events.on('move', function () { 4632 Transition.set(); 4633 }); 4634 /** 4635 * Disable transition: 4636 * - before initial build to avoid transitioning from `0` to `startAt` index 4637 * - while resizing window and recalculating dimensions 4638 * - on jumping from offset transition at start and end edges in `carousel` type 4639 */ 4640 4641 Events.on(['build.before', 'resize', 'translate.jump'], function () { 4642 Transition.disable(); 4643 }); 4644 /** 4645 * Enable transition: 4646 * - on each running, because it may be disabled by offset move 4647 */ 4648 4649 Events.on('run', function () { 4650 Transition.enable(); 4651 }); 4652 /** 4653 * Remove transition: 4654 * - on destroying to bring markup to its inital state 4655 */ 4656 4657 Events.on('destroy', function () { 4658 Transition.remove(); 4659 }); 4660 return Transition; 4661 } 4662 4663 /** 4664 * Test via a getter in the options object to see 4665 * if the passive property is accessed. 4666 * 4667 * @see https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection 4668 */ 4669 var supportsPassive = false; 4670 try { 4671 var opts = Object.defineProperty({}, 'passive', { 4672 get: function get() { 4673 supportsPassive = true; 4674 } 4675 }); 4676 window.addEventListener('testPassive', null, opts); 4677 window.removeEventListener('testPassive', null, opts); 4678 } catch (e) {} 4679 var supportsPassive$1 = supportsPassive; 4680 var START_EVENTS = ['touchstart', 'mousedown']; 4681 var MOVE_EVENTS = ['touchmove', 'mousemove']; 4682 var END_EVENTS = ['touchend', 'touchcancel', 'mouseup', 'mouseleave']; 4683 var MOUSE_EVENTS = ['mousedown', 'mousemove', 'mouseup', 'mouseleave']; 4684 function swipe(Glide, Components, Events) { 4685 /** 4686 * Instance of the binder for DOM Events. 4687 * 4688 * @type {EventsBinder} 4689 */ 4690 var Binder = new EventsBinder(); 4691 var swipeSin = 0; 4692 var swipeStartX = 0; 4693 var swipeStartY = 0; 4694 var disabled = false; 4695 var capture = supportsPassive$1 ? { 4696 passive: true 4697 } : false; 4698 var Swipe = { 4699 /** 4700 * Initializes swipe bindings. 4701 * 4702 * @return {Void} 4703 */ 4704 mount: function mount() { 4705 this.bindSwipeStart(); 4706 }, 4707 /** 4708 * Handler for `swipestart` event. Calculates entry points of the user's tap. 4709 * 4710 * @param {Object} event 4711 * @return {Void} 4712 */ 4713 start: function start(event) { 4714 if (!disabled && !Glide.disabled) { 4715 this.disable(); 4716 var swipe = this.touches(event); 4717 swipeSin = null; 4718 swipeStartX = toInt(swipe.pageX); 4719 swipeStartY = toInt(swipe.pageY); 4720 this.bindSwipeMove(); 4721 this.bindSwipeEnd(); 4722 Events.emit('swipe.start'); 4723 } 4724 }, 4725 /** 4726 * Handler for `swipemove` event. Calculates user's tap angle and distance. 4727 * 4728 * @param {Object} event 4729 */ 4730 move: function move(event) { 4731 if (!Glide.disabled) { 4732 var _Glide$settings = Glide.settings, 4733 touchAngle = _Glide$settings.touchAngle, 4734 touchRatio = _Glide$settings.touchRatio, 4735 classes = _Glide$settings.classes; 4736 var swipe = this.touches(event); 4737 var subExSx = toInt(swipe.pageX) - swipeStartX; 4738 var subEySy = toInt(swipe.pageY) - swipeStartY; 4739 var powEX = Math.abs(subExSx << 2); 4740 var powEY = Math.abs(subEySy << 2); 4741 var swipeHypotenuse = Math.sqrt(powEX + powEY); 4742 var swipeCathetus = Math.sqrt(powEY); 4743 swipeSin = Math.asin(swipeCathetus / swipeHypotenuse); 4744 if (swipeSin * 180 / Math.PI < touchAngle) { 4745 event.stopPropagation(); 4746 Components.Move.make(subExSx * toFloat(touchRatio)); 4747 Components.Html.root.classList.add(classes.dragging); 4748 Events.emit('swipe.move'); 4749 } else { 4750 return false; 4751 } 4752 } 4753 }, 4754 /** 4755 * Handler for `swipeend` event. Finitializes user's tap and decides about glide move. 4756 * 4757 * @param {Object} event 4758 * @return {Void} 4759 */ 4760 end: function end(event) { 4761 if (!Glide.disabled) { 4762 var _Glide$settings2 = Glide.settings, 4763 perSwipe = _Glide$settings2.perSwipe, 4764 touchAngle = _Glide$settings2.touchAngle, 4765 classes = _Glide$settings2.classes; 4766 var swipe = this.touches(event); 4767 var threshold = this.threshold(event); 4768 var swipeDistance = swipe.pageX - swipeStartX; 4769 var swipeDeg = swipeSin * 180 / Math.PI; 4770 this.enable(); 4771 if (swipeDistance > threshold && swipeDeg < touchAngle) { 4772 Components.Run.make(Components.Direction.resolve("".concat(perSwipe, "<"))); 4773 } else if (swipeDistance < -threshold && swipeDeg < touchAngle) { 4774 Components.Run.make(Components.Direction.resolve("".concat(perSwipe, ">"))); 4775 } else { 4776 // While swipe don't reach distance apply previous transform. 4777 Components.Move.make(); 4778 } 4779 Components.Html.root.classList.remove(classes.dragging); 4780 this.unbindSwipeMove(); 4781 this.unbindSwipeEnd(); 4782 Events.emit('swipe.end'); 4783 } 4784 }, 4785 /** 4786 * Binds swipe's starting event. 4787 * 4788 * @return {Void} 4789 */ 4790 bindSwipeStart: function bindSwipeStart() { 4791 var _this = this; 4792 var _Glide$settings3 = Glide.settings, 4793 swipeThreshold = _Glide$settings3.swipeThreshold, 4794 dragThreshold = _Glide$settings3.dragThreshold; 4795 if (swipeThreshold) { 4796 Binder.on(START_EVENTS[0], Components.Html.wrapper, function (event) { 4797 _this.start(event); 4798 }, capture); 4799 } 4800 if (dragThreshold) { 4801 Binder.on(START_EVENTS[1], Components.Html.wrapper, function (event) { 4802 _this.start(event); 4803 }, capture); 4804 } 4805 }, 4806 /** 4807 * Unbinds swipe's starting event. 4808 * 4809 * @return {Void} 4810 */ 4811 unbindSwipeStart: function unbindSwipeStart() { 4812 Binder.off(START_EVENTS[0], Components.Html.wrapper, capture); 4813 Binder.off(START_EVENTS[1], Components.Html.wrapper, capture); 4814 }, 4815 /** 4816 * Binds swipe's moving event. 4817 * 4818 * @return {Void} 4819 */ 4820 bindSwipeMove: function bindSwipeMove() { 4821 var _this2 = this; 4822 Binder.on(MOVE_EVENTS, Components.Html.wrapper, throttle(function (event) { 4823 _this2.move(event); 4824 }, Glide.settings.throttle), capture); 4825 }, 4826 /** 4827 * Unbinds swipe's moving event. 4828 * 4829 * @return {Void} 4830 */ 4831 unbindSwipeMove: function unbindSwipeMove() { 4832 Binder.off(MOVE_EVENTS, Components.Html.wrapper, capture); 4833 }, 4834 /** 4835 * Binds swipe's ending event. 4836 * 4837 * @return {Void} 4838 */ 4839 bindSwipeEnd: function bindSwipeEnd() { 4840 var _this3 = this; 4841 Binder.on(END_EVENTS, Components.Html.wrapper, function (event) { 4842 _this3.end(event); 4843 }); 4844 }, 4845 /** 4846 * Unbinds swipe's ending event. 4847 * 4848 * @return {Void} 4849 */ 4850 unbindSwipeEnd: function unbindSwipeEnd() { 4851 Binder.off(END_EVENTS, Components.Html.wrapper); 4852 }, 4853 /** 4854 * Normalizes event touches points accorting to different types. 4855 * 4856 * @param {Object} event 4857 */ 4858 touches: function touches(event) { 4859 if (MOUSE_EVENTS.indexOf(event.type) > -1) { 4860 return event; 4861 } 4862 return event.touches[0] || event.changedTouches[0]; 4863 }, 4864 /** 4865 * Gets value of minimum swipe distance settings based on event type. 4866 * 4867 * @return {Number} 4868 */ 4869 threshold: function threshold(event) { 4870 var settings = Glide.settings; 4871 if (MOUSE_EVENTS.indexOf(event.type) > -1) { 4872 return settings.dragThreshold; 4873 } 4874 return settings.swipeThreshold; 4875 }, 4876 /** 4877 * Enables swipe event. 4878 * 4879 * @return {self} 4880 */ 4881 enable: function enable() { 4882 disabled = false; 4883 Components.Transition.enable(); 4884 return this; 4885 }, 4886 /** 4887 * Disables swipe event. 4888 * 4889 * @return {self} 4890 */ 4891 disable: function disable() { 4892 disabled = true; 4893 Components.Transition.disable(); 4894 return this; 4895 } 4896 }; 4897 /** 4898 * Add component class: 4899 * - after initial building 4900 */ 4901 4902 Events.on('build.after', function () { 4903 Components.Html.root.classList.add(Glide.settings.classes.swipeable); 4904 }); 4905 /** 4906 * Remove swiping bindings: 4907 * - on destroying, to remove added EventListeners 4908 */ 4909 4910 Events.on('destroy', function () { 4911 Swipe.unbindSwipeStart(); 4912 Swipe.unbindSwipeMove(); 4913 Swipe.unbindSwipeEnd(); 4914 Binder.destroy(); 4915 }); 4916 return Swipe; 4917 } 4918 var NAV_SELECTOR = '[data-glide-el="controls[nav]"]'; 4919 var CONTROLS_SELECTOR = '[data-glide-el^="controls"]'; 4920 var PREVIOUS_CONTROLS_SELECTOR = "".concat(CONTROLS_SELECTOR, " [data-glide-dir*=\"<\"]"); 4921 var NEXT_CONTROLS_SELECTOR = "".concat(CONTROLS_SELECTOR, " [data-glide-dir*=\">\"]"); 4922 function controls(Glide, Components, Events) { 4923 /** 4924 * Instance of the binder for DOM Events. 4925 * 4926 * @type {EventsBinder} 4927 */ 4928 var Binder = new EventsBinder(); 4929 var capture = supportsPassive$1 ? { 4930 passive: true 4931 } : false; 4932 var Controls = { 4933 /** 4934 * Inits arrows. Binds events listeners 4935 * to the arrows HTML elements. 4936 * 4937 * @return {Void} 4938 */ 4939 mount: function mount() { 4940 /** 4941 * Collection of navigation HTML elements. 4942 * 4943 * @private 4944 * @type {HTMLCollection} 4945 */ 4946 this._n = Components.Html.root.querySelectorAll(NAV_SELECTOR); 4947 /** 4948 * Collection of controls HTML elements. 4949 * 4950 * @private 4951 * @type {HTMLCollection} 4952 */ 4953 4954 this._c = Components.Html.root.querySelectorAll(CONTROLS_SELECTOR); 4955 /** 4956 * Collection of arrow control HTML elements. 4957 * 4958 * @private 4959 * @type {Object} 4960 */ 4961 4962 this._arrowControls = { 4963 previous: Components.Html.root.querySelectorAll(PREVIOUS_CONTROLS_SELECTOR), 4964 next: Components.Html.root.querySelectorAll(NEXT_CONTROLS_SELECTOR) 4965 }; 4966 this.addBindings(); 4967 }, 4968 /** 4969 * Sets active class to current slide. 4970 * 4971 * @return {Void} 4972 */ 4973 setActive: function setActive() { 4974 for (var i = 0; i < this._n.length; i++) { 4975 this.addClass(this._n[i].children); 4976 } 4977 }, 4978 /** 4979 * Removes active class to current slide. 4980 * 4981 * @return {Void} 4982 */ 4983 removeActive: function removeActive() { 4984 for (var i = 0; i < this._n.length; i++) { 4985 this.removeClass(this._n[i].children); 4986 } 4987 }, 4988 /** 4989 * Toggles active class on items inside navigation. 4990 * 4991 * @param {HTMLElement} controls 4992 * @return {Void} 4993 */ 4994 addClass: function addClass(controls) { 4995 var settings = Glide.settings; 4996 var item = controls[Glide.index]; 4997 if (!item) { 4998 return; 4999 } 5000 if (item) { 5001 item.classList.add(settings.classes.nav.active); 5002 siblings(item).forEach(function (sibling) { 5003 sibling.classList.remove(settings.classes.nav.active); 5004 }); 5005 } 5006 }, 5007 /** 5008 * Removes active class from active control. 5009 * 5010 * @param {HTMLElement} controls 5011 * @return {Void} 5012 */ 5013 removeClass: function removeClass(controls) { 5014 var item = controls[Glide.index]; 5015 if (item) { 5016 item.classList.remove(Glide.settings.classes.nav.active); 5017 } 5018 }, 5019 /** 5020 * Calculates, removes or adds `Glide.settings.classes.disabledArrow` class on the control arrows 5021 */ 5022 setArrowState: function setArrowState() { 5023 if (Glide.settings.rewind) { 5024 return; 5025 } 5026 var next = Controls._arrowControls.next; 5027 var previous = Controls._arrowControls.previous; 5028 this.resetArrowState(next, previous); 5029 if (Glide.index === 0) { 5030 this.disableArrow(previous); 5031 } 5032 if (Glide.index === Components.Run.length) { 5033 this.disableArrow(next); 5034 } 5035 }, 5036 /** 5037 * Removes `Glide.settings.classes.disabledArrow` from given NodeList elements 5038 * 5039 * @param {NodeList[]} lists 5040 */ 5041 resetArrowState: function resetArrowState() { 5042 var settings = Glide.settings; 5043 for (var _len = arguments.length, lists = new Array(_len), _key = 0; _key < _len; _key++) { 5044 lists[_key] = arguments[_key]; 5045 } 5046 lists.forEach(function (list) { 5047 toArray(list).forEach(function (element) { 5048 element.classList.remove(settings.classes.arrow.disabled); 5049 }); 5050 }); 5051 }, 5052 /** 5053 * Adds `Glide.settings.classes.disabledArrow` to given NodeList elements 5054 * 5055 * @param {NodeList[]} lists 5056 */ 5057 disableArrow: function disableArrow() { 5058 var settings = Glide.settings; 5059 for (var _len2 = arguments.length, lists = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 5060 lists[_key2] = arguments[_key2]; 5061 } 5062 lists.forEach(function (list) { 5063 toArray(list).forEach(function (element) { 5064 element.classList.add(settings.classes.arrow.disabled); 5065 }); 5066 }); 5067 }, 5068 /** 5069 * Adds handles to the each group of controls. 5070 * 5071 * @return {Void} 5072 */ 5073 addBindings: function addBindings() { 5074 for (var i = 0; i < this._c.length; i++) { 5075 this.bind(this._c[i].children); 5076 } 5077 }, 5078 /** 5079 * Removes handles from the each group of controls. 5080 * 5081 * @return {Void} 5082 */ 5083 removeBindings: function removeBindings() { 5084 for (var i = 0; i < this._c.length; i++) { 5085 this.unbind(this._c[i].children); 5086 } 5087 }, 5088 /** 5089 * Binds events to arrows HTML elements. 5090 * 5091 * @param {HTMLCollection} elements 5092 * @return {Void} 5093 */ 5094 bind: function bind(elements) { 5095 for (var i = 0; i < elements.length; i++) { 5096 Binder.on('click', elements[i], this.click); 5097 Binder.on('touchstart', elements[i], this.click, capture); 5098 } 5099 }, 5100 /** 5101 * Unbinds events binded to the arrows HTML elements. 5102 * 5103 * @param {HTMLCollection} elements 5104 * @return {Void} 5105 */ 5106 unbind: function unbind(elements) { 5107 for (var i = 0; i < elements.length; i++) { 5108 Binder.off(['click', 'touchstart'], elements[i]); 5109 } 5110 }, 5111 /** 5112 * Handles `click` event on the arrows HTML elements. 5113 * Moves slider in direction given via the 5114 * `data-glide-dir` attribute. 5115 * 5116 * @param {Object} event 5117 * @return {void} 5118 */ 5119 click: function click(event) { 5120 if (!supportsPassive$1 && event.type === 'touchstart') { 5121 event.preventDefault(); 5122 } 5123 var direction = event.currentTarget.getAttribute('data-glide-dir'); 5124 Components.Run.make(Components.Direction.resolve(direction)); 5125 } 5126 }; 5127 define(Controls, 'items', { 5128 /** 5129 * Gets collection of the controls HTML elements. 5130 * 5131 * @return {HTMLElement[]} 5132 */ 5133 get: function get() { 5134 return Controls._c; 5135 } 5136 }); 5137 /** 5138 * Swap active class of current navigation item: 5139 * - after mounting to set it to initial index 5140 * - after each move to the new index 5141 */ 5142 5143 Events.on(['mount.after', 'move.after'], function () { 5144 Controls.setActive(); 5145 }); 5146 /** 5147 * Add or remove disabled class of arrow elements 5148 */ 5149 5150 Events.on(['mount.after', 'run'], function () { 5151 Controls.setArrowState(); 5152 }); 5153 /** 5154 * Remove bindings and HTML Classes: 5155 * - on destroying, to bring markup to its initial state 5156 */ 5157 5158 Events.on('destroy', function () { 5159 Controls.removeBindings(); 5160 Controls.removeActive(); 5161 Binder.destroy(); 5162 }); 5163 return Controls; 5164 } 5165 function keyboard(Glide, Components, Events) { 5166 /** 5167 * Instance of the binder for DOM Events. 5168 * 5169 * @type {EventsBinder} 5170 */ 5171 var Binder = new EventsBinder(); 5172 var Keyboard = { 5173 /** 5174 * Binds keyboard events on component mount. 5175 * 5176 * @return {Void} 5177 */ 5178 mount: function mount() { 5179 if (Glide.settings.keyboard) { 5180 this.bind(); 5181 } 5182 }, 5183 /** 5184 * Adds keyboard press events. 5185 * 5186 * @return {Void} 5187 */ 5188 bind: function bind() { 5189 Binder.on('keyup', document, this.press); 5190 }, 5191 /** 5192 * Removes keyboard press events. 5193 * 5194 * @return {Void} 5195 */ 5196 unbind: function unbind() { 5197 Binder.off('keyup', document); 5198 }, 5199 /** 5200 * Handles keyboard's arrows press and moving glide foward and backward. 5201 * 5202 * @param {Object} event 5203 * @return {Void} 5204 */ 5205 press: function press(event) { 5206 var perSwipe = Glide.settings.perSwipe; 5207 if (event.code === 'ArrowRight') { 5208 Components.Run.make(Components.Direction.resolve("".concat(perSwipe, ">"))); 5209 } 5210 if (event.code === 'ArrowLeft') { 5211 Components.Run.make(Components.Direction.resolve("".concat(perSwipe, "<"))); 5212 } 5213 } 5214 }; 5215 /** 5216 * Remove bindings from keyboard: 5217 * - on destroying to remove added events 5218 * - on updating to remove events before remounting 5219 */ 5220 5221 Events.on(['destroy', 'update'], function () { 5222 Keyboard.unbind(); 5223 }); 5224 /** 5225 * Remount component 5226 * - on updating to reflect potential changes in settings 5227 */ 5228 5229 Events.on('update', function () { 5230 Keyboard.mount(); 5231 }); 5232 /** 5233 * Destroy binder: 5234 * - on destroying to remove listeners 5235 */ 5236 5237 Events.on('destroy', function () { 5238 Binder.destroy(); 5239 }); 5240 return Keyboard; 5241 } 5242 function autoplay(Glide, Components, Events) { 5243 /** 5244 * Instance of the binder for DOM Events. 5245 * 5246 * @type {EventsBinder} 5247 */ 5248 var Binder = new EventsBinder(); 5249 var Autoplay = { 5250 /** 5251 * Initializes autoplaying and events. 5252 * 5253 * @return {Void} 5254 */ 5255 mount: function mount() { 5256 this.enable(); 5257 this.start(); 5258 if (Glide.settings.hoverpause) { 5259 this.bind(); 5260 } 5261 }, 5262 /** 5263 * Enables autoplaying 5264 * 5265 * @returns {Void} 5266 */ 5267 enable: function enable() { 5268 this._e = true; 5269 }, 5270 /** 5271 * Disables autoplaying. 5272 * 5273 * @returns {Void} 5274 */ 5275 disable: function disable() { 5276 this._e = false; 5277 }, 5278 /** 5279 * Starts autoplaying in configured interval. 5280 * 5281 * @param {Boolean|Number} force Run autoplaying with passed interval regardless of `autoplay` settings 5282 * @return {Void} 5283 */ 5284 start: function start() { 5285 var _this = this; 5286 if (!this._e) { 5287 return; 5288 } 5289 this.enable(); 5290 if (Glide.settings.autoplay) { 5291 if (isUndefined(this._i)) { 5292 this._i = setInterval(function () { 5293 _this.stop(); 5294 Components.Run.make('>'); 5295 _this.start(); 5296 Events.emit('autoplay'); 5297 }, this.time); 5298 } 5299 } 5300 }, 5301 /** 5302 * Stops autorunning of the glide. 5303 * 5304 * @return {Void} 5305 */ 5306 stop: function stop() { 5307 this._i = clearInterval(this._i); 5308 }, 5309 /** 5310 * Stops autoplaying while mouse is over glide's area. 5311 * 5312 * @return {Void} 5313 */ 5314 bind: function bind() { 5315 var _this2 = this; 5316 Binder.on('mouseover', Components.Html.root, function () { 5317 if (_this2._e) { 5318 _this2.stop(); 5319 } 5320 }); 5321 Binder.on('mouseout', Components.Html.root, function () { 5322 if (_this2._e) { 5323 _this2.start(); 5324 } 5325 }); 5326 }, 5327 /** 5328 * Unbind mouseover events. 5329 * 5330 * @returns {Void} 5331 */ 5332 unbind: function unbind() { 5333 Binder.off(['mouseover', 'mouseout'], Components.Html.root); 5334 } 5335 }; 5336 define(Autoplay, 'time', { 5337 /** 5338 * Gets time period value for the autoplay interval. Prioritizes 5339 * times in `data-glide-autoplay` attrubutes over options. 5340 * 5341 * @return {Number} 5342 */ 5343 get: function get() { 5344 var autoplay = Components.Html.slides[Glide.index].getAttribute('data-glide-autoplay'); 5345 if (autoplay) { 5346 return toInt(autoplay); 5347 } 5348 return toInt(Glide.settings.autoplay); 5349 } 5350 }); 5351 /** 5352 * Stop autoplaying and unbind events: 5353 * - on destroying, to clear defined interval 5354 * - on updating via API to reset interval that may changed 5355 */ 5356 5357 Events.on(['destroy', 'update'], function () { 5358 Autoplay.unbind(); 5359 }); 5360 /** 5361 * Stop autoplaying: 5362 * - before each run, to restart autoplaying 5363 * - on pausing via API 5364 * - on destroying, to clear defined interval 5365 * - while starting a swipe 5366 * - on updating via API to reset interval that may changed 5367 */ 5368 5369 Events.on(['run.before', 'swipe.start', 'update'], function () { 5370 Autoplay.stop(); 5371 }); 5372 Events.on(['pause', 'destroy'], function () { 5373 Autoplay.disable(); 5374 Autoplay.stop(); 5375 }); 5376 /** 5377 * Start autoplaying: 5378 * - after each run, to restart autoplaying 5379 * - on playing via API 5380 * - while ending a swipe 5381 */ 5382 5383 Events.on(['run.after', 'swipe.end'], function () { 5384 Autoplay.start(); 5385 }); 5386 /** 5387 * Start autoplaying: 5388 * - after each run, to restart autoplaying 5389 * - on playing via API 5390 * - while ending a swipe 5391 */ 5392 5393 Events.on(['play'], function () { 5394 Autoplay.enable(); 5395 Autoplay.start(); 5396 }); 5397 /** 5398 * Remount autoplaying: 5399 * - on updating via API to reset interval that may changed 5400 */ 5401 5402 Events.on('update', function () { 5403 Autoplay.mount(); 5404 }); 5405 /** 5406 * Destroy a binder: 5407 * - on destroying glide instance to clearup listeners 5408 */ 5409 5410 Events.on('destroy', function () { 5411 Binder.destroy(); 5412 }); 5413 return Autoplay; 5414 } 5415 5416 /** 5417 * Sorts keys of breakpoint object so they will be ordered from lower to bigger. 5418 * 5419 * @param {Object} points 5420 * @returns {Object} 5421 */ 5422 5423 function sortBreakpoints(points) { 5424 if (isObject$1(points)) { 5425 return sortKeys(points); 5426 } else { 5427 warn("Breakpoints option must be an object"); 5428 } 5429 return {}; 5430 } 5431 function breakpoints(Glide, Components, Events) { 5432 /** 5433 * Instance of the binder for DOM Events. 5434 * 5435 * @type {EventsBinder} 5436 */ 5437 var Binder = new EventsBinder(); 5438 /** 5439 * Holds reference to settings. 5440 * 5441 * @type {Object} 5442 */ 5443 5444 var settings = Glide.settings; 5445 /** 5446 * Holds reference to breakpoints object in settings. Sorts breakpoints 5447 * from smaller to larger. It is required in order to proper 5448 * matching currently active breakpoint settings. 5449 * 5450 * @type {Object} 5451 */ 5452
5453 var points = sortBreakpoints(settings.breakpoints); 5454 /** 5455 * Cache initial settings before overwritting. 5456 * 5457 * @type {Object} 5458 */ 5459 5460 var defaults = Object.assign({}, settings); 5461 var Breakpoints = { 5462 /** 5463 * Matches settings for currectly matching media breakpoint. 5464 * 5465 * @param {Object} points 5466 * @returns {Object} 5467 */ 5468 match: function match(points) { 5469 if (typeof window.matchMedia !== 'undefined') { 5470 for (var point in points) { 5471 if (points.hasOwnProperty(point)) { 5472 if (window.matchMedia("(max-width: ".concat(point, "px)")).matches) { 5473 return points[point]; 5474 } 5475 } 5476 } 5477 } 5478 return defaults; 5479 } 5480 }; 5481 /** 5482 * Overwrite instance settings with currently matching breakpoint settings. 5483 * This happens right after component initialization. 5484 */ 5485 5486 Object.assign(settings, Breakpoints.match(points)); 5487 /** 5488 * Update glide with settings of matched brekpoint: 5489 * - window resize to update slider 5490 */ 5491 5492 Binder.on('resize', window, throttle(function () { 5493 Glide.settings = mergeOptions(settings, Breakpoints.match(points)); 5494 }, Glide.settings.throttle)); 5495 /** 5496 * Resort and update default settings: 5497 * - on reinit via API, so breakpoint matching will be performed with options 5498 */ 5499 5500 Events.on('update', function () { 5501 points = sortBreakpoints(points); 5502 defaults = Object.assign({}, settings); 5503 }); 5504 /** 5505 * Unbind resize listener: 5506 * - on destroying, to bring markup to its initial state 5507 */ 5508 5509 Events.on('destroy', function () { 5510 Binder.off('resize', window); 5511 }); 5512 return Breakpoints; 5513 } 5514 var COMPONENTS = { 5515 Html: Html, 5516 Translate: Translate, 5517 Transition: Transition, 5518 Direction: Direction, 5519 Peek: Peek, 5520 Sizes: Sizes, 5521 Gaps: Gaps, 5522 Move: Move, 5523 Clones: Clones, 5524 Resize: Resize, 5525 Build: Build, 5526 Run: Run 5527 }; 5528 var Glide = /*#__PURE__*/function (_Core) { 5529 _inherits(Glide, _Core); 5530 var _super = _createSuper(Glide); 5531 function Glide() { 5532 _classCallCheck(this, Glide); 5533 return _super.apply(this, arguments); 5534 } 5535 _createClass(Glide, [{ 5536 key: "mount", 5537 value: function mount() { 5538 var extensions = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; 5539 return _get(_getPrototypeOf(Glide.prototype), "mount", this).call(this, Object.assign({}, COMPONENTS, extensions)); 5540 } 5541 }]); 5542 return Glide; 5543 }(Glide$1); 5544 5545 var mskAnimateDelaySlow = 8000; 5546 var mskAnimateDurationSlow = 600; 5547 var mskAnimateTimingDefault = 'ease'; 5548 var mskBreakpointWidth330 = '330px'; 5549 var mskBreakpointWidth480 = '480px'; 5550 var mskBreakpointWidth768 = '768px'; 5551 var mskBreakpointWidthFooterSwitch = '850px'; 5552 var mskBreakpointWidthNavSwitch = '1025px'; 5553 var mskWhitespaceMl = '30px'; 5554 5555 var small = mskBreakpointWidth330.replace("px", ""); 5556 var medium = mskBreakpointWidth480.replace("px", ""); 5557 var large = mskBreakpointWidth768.replace("px", ""); 5558 5559 /** 5560 * Toggle the autoplay carousel play/pause state 5561 * 5562 * @param {object} glideEl The GlideJS element 5563 * @param {string} [state] Optional state to force the carousel to. 5564 * Either "play" or "pause". 5565 * @returns {void} 5566 */ 5567 function toggleAutoplayState(glideEl, state) { 5568 var newState; 5569 if (state === "play") { 5570 newState = true; 5571 glideEl.play(); 5572 } else if (state === "pause") { 5573 newState = false; 5574 glideEl.pause(); 5575 } else { 5576 newState = !JSON.parse(glideEl.selector.dataset.isPlaying); 5577 if (newState) { 5578 glideEl.play(); 5579 } else { 5580 glideEl.pause(); 5581 } 5582 } 5583 glideEl.selector.dataset.isPlaying = newState; 5584 } 5585 function updateCarouselUI(glideEl) { 5586 var currentSlide = glideEl.selector.querySelector(".msk-carousel__slide.glide__slide--active .msk-hero"); 5587 if (currentSlide.classList.contains("msk-hero--theme-light")) { 5588 glideEl.selector.classList.add("msk-carousel--theme-light"); 5589 glideEl.selector.classList.remove("msk-carousel--theme-dark"); 5590 } else { 5591 glideEl.selector.classList.add("msk-carousel--theme-dark"); 5592 glideEl.selector.classList.remove("msk-carousel--theme-light"); 5593 } 5594 } 5595 var handleCarouselClick; 5596 function enableCarousel() { 5597 var direction = document.documentElement.dir || "ltr"; 5598 var carouselEls = Array.from(document.querySelectorAll(".msk-carousel")); 5599 if (!carouselEls.length) return; 5600 var relatedTopics = document.querySelector(".msk-related-content-carou
5600sel"); 5601 // Related topics are not translated in general, on a right to left page, related topics should be fixed to display left to right 5602 if (relatedTopics) { 5603 direction = "ltr"; 5604 } 5605 var glideEls = carouselEls.map(function (carousel) { 5606 var mediumConfig = { 5607 perView: 1, 5608 swipeThreshold: false, 5609 dragThreshold: false 5610 }; 5611 var largeConfig = { 5612 perView: 1, 5613 swipeThreshold: false, 5614 dragThreshold: false 5615 }; 5616 var _carousel$dataset = carousel.dataset, 5617 _carousel$dataset$per = _carousel$dataset.perViewMedium, 5618 perViewMedium = _carousel$dataset$per === void 0 ? "1" : _carousel$dataset$per, 5619 _carousel$dataset$per2 = _carousel$dataset.perViewLarge, 5620 perViewLarge = _carousel$dataset$per2 === void 0 ? "1" : _carousel$dataset$per2, 5621 autoplay$1 = _carousel$dataset.autoplay, 5622 isPeekingString = _carousel$dataset.isPeeking, 5623 minSlides = _carousel$dataset.minSlides; 5624 var slideCount = carousel.querySelectorAll(".msk-carousel__slide").length; 5625 if (slideCount < minSlides) { 5626 carousel.classList.add("msk-carousel__min-slides-not-met"); 5627 return; 5628 } 5629 var isAutoplay = false; 5630 try { 5631 isAutoplay = JSON.parse(autoplay$1); 5632 } catch (error) { 5633 // don't care if we error. 5634 } 5635 var isPeeking = isPeekingString === "yes"; 5636 if (!isPeeking) { 5637 mediumConfig.perView = perViewMedium || 1; 5638 largeConfig.perView = perViewLarge || 1; 5639 } 5640 5641 /** 5642 * @return {number} 5643 */ 5644 function getPeekSetting() { 5645 var _Array$from$map = Array.from(carousel.querySelectorAll(".msk-carousel__slide")).map(function (x) { 5646 return x.offsetWidth; 5647 }), 5648 _Array$from$map2 = _slicedToArray(_Array$from$map, 1), 5649 slide = _Array$from$map2[0]; 5650 return slide / 4; 5651 } 5652 var glide = new Glide(carousel, { 5653 breakpoints: _defineProperty(_defineProperty(_defineProperty(_defineProperty({}, small, { 5654 perView: 1, 5655 peek: 0 5656 }), medium, { 5657 perView: 1, 5658 peek: 0 5659 }), large, mediumConfig), 4000, largeConfig), 5660 gap: mskWhitespaceMl.replace("px", ""), 5661 animationDuration: mskAnimateDurationSlow, 5662 animationTimingFunc: mskAnimateTimingDefault, 5663 type: isPeeking ? "carousel" : "slider", 5664 direction: direction, 5665 peek: isPeeking ? getPeekSetting() : 0, 5666 hoverpause: false, 5667 autoplay: isAutoplay ? mskAnimateDelaySlow : false, 5668 rewind: true, 5669 classes: { 5670 slider: "msk-carousel--slider", 5671 carousel: "msk-carousel--carousel", 5672 swipeable: "msk-carousel--swipeable", 5673 dragging: "msk-carousel--dragging", 5674 cloneSlide: "msk-carousel__slide--clone", 5675 activeNav: "msk-pagination-dots__dot--active", 5676 activeSlide: "msk-carousel__slide--active", 5677 disabledArrow: "msk-pagination__arrow--disabled" 5678 } 5679 }); 5680 glide.on("run.start", function () { 5681 toggleAutoplayState(glide, "pause"); 5682 }); 5683 if (glide.selector.classList.contains("msk-carousel--is-hero")) { 5684 // bind these events to the carousel if it's a hero carousel. 5685 glide.on("build.after", function () { 5686 updateCarouselUI(glide); 5687 }); 5688 glide.on("run.after", function () { 5689 updateCarouselUI(glide); 5690 }); 5691 } 5692 glide.mount({ 5693 Autoplay: autoplay, 5694 Breakpoints: breakpoints, 5695 Controls: controls, 5696 Keyboard: keyboard, 5697 Swipe: swipe 5698 }); 5699 if (window.IntersectionObserver && window.lazyLoad) { 5700 var observer = new IntersectionObserver(function (entries) { 5701 entries.forEach(function (entry) { 5702 if (entry.isIntersecting) { 5703 var carouselImages = entry.target.querySelectorAll("img"); 5704 _toConsumableArray(carouselImages).forEach(function (img) { 5705 return window.lazyLoad.load(img, false); 5706 }); 5707 } 5708 }); 5709 }); 5710 /* Add interseciton observer for lazy-loading images */ 5711 observer.observe(carousel); 5712 } 5713 5714 // Pause autoplay initially if prefers reduced motion is enabled. 5715 if (isAutoplay && window.matchMedia("(prefers-reduced-motion)").matches) { 5716 toggleAutoplayState(glide, "pause"); 5717 } 5718 return glide; 5719 }); 5720 5721 /** 5722 * Handle carousel clicks.
5723 * 5724 * @param {Event} event The pointerup event. 5725 * @returns {void} 5726 */ 5727 handleCarouselClick = function handleCarouselClick(event) { 5728 var carouselEl = event.target.closest(".msk-carousel"); 5729 if (!carouselEl) return; 5730 5731 // If we aren't using autplay, none of the rest of this function applies. 5732 if (!JSON.parse(carouselEl.dataset.autoplay)) return; 5733 5734 // Get the GlideJS object that was interacted with. 5735 var glideEl = glideEls.filter(function (glide) { 5736 return glide.selector === carouselEl; 5737 })[0]; 5738 5739 // If the pagination dots are clicked, pause the autoplay. 5740 if (event.target.closest(".msk-pagination-dots__dot")) { 5741 toggleAutoplayState(glideEl, "pause"); 5742 return; 5743 } 5744 5745 // Handle the play/pause button being clicked. 5746 var toggleEl = event.target.closest(".msk-pagination__toggle"); 5747 if (!toggleEl) return; 5748 toggleAutoplayState(glideEl); 5749 }; 5750 document.documentElement.addEventListener("pointerup", handleCarouselClick); 5751 Array.from(document.querySelectorAll(".msk-carousel__track")).forEach(function (c) { 5752 c.addEventListener("mouseenter", function (event) { 5753 var carouselTrack = event.target; 5754 // Get the GlideJS object that was interacted with. 5755 var glideEl = glideEls.filter(function (glide) { 5756 return glide.selector.getElementsByClassName("msk-carousel__track")[0] === carouselTrack; 5757 })[0]; 5758 // Pause the slideshow. 5759 toggleAutoplayState(glideEl, "pause"); 5760 }, false); 5761 }); 5762 } 5763 5764 function enableDropdownList() { 5765 var gsAccordions = document.querySelectorAll('.msk-dropdown-list'); 5766 if (!gsAccordions.length) return; 5767 function handleInputChange(event) { 5768 var filterInput = event.target; 5769 var filterList = event.target.closest('.msk-dropdown-list__options-search').nextElementSibling; 5770 var originalData = JSON.parse(filterList.dataset.options); 5771 var filteredData = originalData.filter(function (item) { 5772 return item.title.toLowerCase().includes(filterInput.value.toLowerCase()); 5773 }); 5774 var bigString = filteredData.reduce(function (accumulator, item) { 5775 var opts = "".concat(accumulator, "<li class=\"msk-dropdown-list__option\"><a href=\"").concat(item.href, "\">").concat(item.title, "</a></li>"); 5776 return opts; 5777 }, ''); 5778 filterList.innerHTML = bigString; 5779 } 5780 5781 // add handlers to each accordion 5782 gsAccordions.forEach(function (gsa) { 5783 // bind opening & closing 5784 var container = gsa.closest('.msk-dropdown-list'); 5785 var dropdownHelper = gsa.querySelector('.msk-dropdown-list__dropdown-helper'); 5786 if (dropdownHelper) { 5787 dropdownHelper.addEventListener('click', function () { 5788 if (document.querySelectorAll('.msk-dropdown-list--is-open').length) { 5789 dropdownHelper.setAttribute('aria-expanded', 'false'); 5790 document.querySelectorAll('.msk-dropdown-list--is-open').forEach(function (el) { 5791 if (el !== container) { 5792 el.classList.toggle('msk-dropdown-list--is-open'); 5793 } 5794 }); 5795 } else { 5796 dropdownHelper.setAttribute('aria-expanded', 'true'); 5797 } 5798 container.classList.toggle('msk-dropdown-list--is-open'); 5799 }); 5800 } 5801 5802 // bind search/filtering 5803 var search = gsa.querySelector("input[name='optionsSearch']"); 5804 if (search) { 5805 search.addEventListener('input', handleInputChange); 5806 } 5807 }); 5808 } 5809 5810 function enableFooterAccordions() { 5811 var footerItemAccordions = document.querySelectorAll(".msk-site-footer__accordion"); 5812 var mq = window.matchMedia("(min-width: ".concat(mskBreakpointWidthFooterSwitch, ")")); 5813 function handleOrientationChange() { 5814 if (mq.matches) { 5815 // remove button role for screen readers on desktop for accessibility 5816 footerItemAccordions.forEach(function (item) { 5817 item.removeAttribute("role"); 5818 }); 5819 } else { 5820 footerItemAccordions.forEach(function (item) { 5821 item.setAttribute("aria-expanded", false); 5822 item.setAttribute("role", "button"); 5823 item.addEventListener("click", function () { 5824 item.classList.toggle("msk-site-footer__accordion--open"); 5825 var isExpanded = item.getAttribute("aria-expanded") === "true"; 5826 item.setAttribute("aria-expanded", isExpanded ? "false" : "true"); 5827 }); 5828 }); 5829 } 5830 } 5831 mq.addEventListener("change", function () { 5832 handleOrientationChange(); 5833 }); 5834 handleOrientationChange(); 5835 } 5836 5837 function enableHeroClick() { 5838 if (!document.querySelector('.msk-hero')) { 5839 return; 5840 } 5841 document.documentElement.addEventListener('click', function (event) { 5842 // what we're going to catch clicks on 5843 var clickTarget = event.target.closest('.msk-hero__inner'); 5844 if (!clickTarget) return; 5845 5846 // what we're going to get the URL from 5847 var link = clickTarget.querySelector('.msk-hero__button .msk-button'); 5848 if (!link) return; 5849 5850 // if they clicked on the link, return early... that's okay. 5851 if (event.target.closest('.msk-button')) return; 5852 5853 // fire the click event of the button 5854 link.click(); 5855 }); 5856 } 5857 5858 // Public: Create a new SelectorSet. 5859 function SelectorSet() { 5860 // Construct new SelectorSet if called as a function. 5861 if (!(this instanceof SelectorSet)) { 5862 return new SelectorSet(); 5863 } 5864 5865 // Public: Number of selectors added to the set 5866 this.size = 0; 5867 5868 // Internal: Incrementing ID counter 5869 this.uid = 0; 5870 5871 // Internal: Array of String selectors in the set 5872 this.selectors = []; 5873 5874 // Internal: Map of selector ids to objects 5875 this.selectorObjects = {}; 5876 5877 // Internal: All Object index String names mapping to Index objects. 5878 this.indexes = Object.create(this.indexes); 5879 5880 // Internal: Used Object index String names mapping to Index objects. 5881 this.activeIndexes = []; 5882 } 5883 5884 // Detect prefixed Element#matches function. 5885 var docElem = window.document.documentElement; 5886 var matches$1 = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector; 5887 5888 // Public: Check if element matches selector. 5889 // 5890 // Maybe overridden with custom Element.matches function. 5891 // 5892 // el - An Element 5893 // selector - String CSS selector 5894 // 5895 // Returns true or false. 5896 SelectorSet.prototype.matchesSelector = function (el, selector) { 5897 return matches$1.call(el, selector); 5898 }; 5899 5900 // Public: Find all elements in the context that match the selector. 5901 // 5902 // Maybe overridden with custom querySelectorAll function. 5903 // 5904 // selectors - String CSS selectors. 5905 // context - Element context 5906 // 5907 // Returns non-live list of Elements. 5908 SelectorSet.prototype.querySelectorAll = function (selectors, context) { 5909 return context.querySelectorAll(selectors); 5910 }; 5911 5912 // Public: Array of indexes. 5913 // 5914 // name - Unique String name 5915 // selector - Function that takes a String selector and returns a String key 5916 // or undefined if it can't be used by the index. 5917 // element - Function that takes an Element and returns an Array of String 5918 // keys that point to indexed values. 5919 // 5920 SelectorSet.prototype.indexes = []; 5921 5922 // Index by element id 5923 var idRe = /^#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/g; 5924 SelectorSet.prototype.indexes.push({ 5925 name: 'ID', 5926 selector: function matchIdSelector(sel) { 5927 var m; 5928 if (m = sel.match(idRe)) { 5929 return m[0].slice(1); 5930 } 5931 }, 5932 element: function getElementId(el) { 5933 if (el.id) { 5934 return [el.id]; 5935 } 5936 } 5937 }); 5938
5939 // Index by all of its class names 5940 var classRe = /^\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/g; 5941 SelectorSet.prototype.indexes.push({ 5942 name: 'CLASS', 5943 selector: function matchClassSelector(sel) { 5944 var m; 5945 if (m = sel.match(classRe)) { 5946 return m[0].slice(1); 5947 } 5948 }, 5949 element: function getElementClassNames(el) { 5950 var className = el.className; 5951 if (className) { 5952 if (typeof className === 'string') { 5953 return className.split(/\s/); 5954 } else if (_typeof$1(className) === 'object' && 'baseVal' in className) { 5955 // className is a SVGAnimatedString 5956 // global SVGAnimatedString is not an exposed global in Opera 12 5957 return className.baseVal.split(/\s/); 5958 } 5959 } 5960 } 5961 }); 5962 5963 // Index by tag/node name: `DIV`, `FORM`, `A` 5964 var tagRe = /^((?:[\w\u00c0-\uFFFF\-]|\\.)+)/g; 5965 SelectorSet.prototype.indexes.push({ 5966 name: 'TAG', 5967 selector: function matchTagSelector(sel) { 5968 var m; 5969 if (m = sel.match(tagRe)) { 5970 return m[0].toUpperCase(); 5971 } 5972 }, 5973 element: function getElementTagName(el) { 5974 return [el.nodeName.toUpperCase()]; 5975 } 5976 }); 5977 5978 // Default index just contains a single array of elements. 5979 SelectorSet.prototype.indexes['default'] = { 5980 name: 'UNIVERSAL', 5981 selector: function selector() { 5982 return true; 5983 }, 5984 element: function element() { 5985 return [true]; 5986 } 5987 }; 5988 5989 // Use ES Maps when supported 5990 var Map$1; 5991 if (typeof window.Map === 'function') { 5992 Map$1 = window.Map; 5993 } else { 5994 Map$1 = function () { 5995 function Map() { 5996 this.map = {}; 5997 } 5998 Map.prototype.get = function (key) { 5999 return this.map[key + ' ']; 6000 }; 6001 Map.prototype.set = function (key, value) { 6002 this.map[key + ' '] = value; 6003 }; 6004 return Map; 6005 }(); 6006 } 6007 6008 // Regexps adopted from Sizzle 6009 // https://github.com/jquery/sizzle/blob/1.7/sizzle.js 6010 // 6011 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g; 6012 6013 // Internal: Get indexes for selector. 6014 // 6015 // selector - String CSS selector 6016 // 6017 // Returns Array of {index, key}. 6018 function parseSelectorIndexes(allIndexes, selector) { 6019 allIndexes = allIndexes.slice(0).concat(allIndexes['default']); 6020 var allIndexesLen = allIndexes.length, 6021 i, 6022 j, 6023 m, 6024 dup, 6025 rest = selector, 6026 key, 6027 index, 6028 indexes = []; 6029 do { 6030 chunker.exec(''); 6031 if (m = chunker.exec(rest)) { 6032 rest = m[3]; 6033 if (m[2] || !rest) { 6034 for (i = 0; i < allIndexesLen; i++) { 6035 index = allIndexes[i]; 6036 if (key = index.selector(m[1])) { 6037 j = indexes.length; 6038 dup = false; 6039 while (j--) { 6040 if (indexes[j].index === index && indexes[j].key === key) { 6041 dup = true; 6042 break; 6043 } 6044 } 6045 if (!dup) { 6046 indexes.push({ 6047 index: index, 6048 key: key 6049 }); 6050 } 6051 break; 6052 } 6053 } 6054 } 6055 } 6056 } while (m); 6057 return indexes; 6058 } 6059 6060 // Internal: Find first item in Array that is a prototype of `proto`. 6061 // 6062 // ary - Array of objects 6063 // proto - Prototype of expected item in `ary` 6064 // 6065 // Returns object from `ary` if found. Otherwise returns undefined. 6066 function findByPrototype(ary, proto) { 6067 var i, len, item; 6068 for (i = 0, len = ary.length; i < len; i++) { 6069 item = ary[i]; 6070 if (proto.isPrototypeOf(item)) { 6071 return item; 6072 } 6073 } 6074 } 6075 6076 // Public: Log when added selector falls under the default index. 6077 // 6078 // This API should not be considered stable. May change between 6079 // minor versions. 6080 // 6081 // obj - {selector, data} Object 6082 // 6083 // SelectorSet.prototype.logDefaultIndexUsed = function(obj) { 6084 // console.warn(obj.selector, "could not be indexed"); 6085 // }; 6086 // 6087 // Returns nothing. 6088 SelectorSet.prototype.logDefaultIndexUsed = function () {}; 6089 6090 // Public: Add selector to set. 6091 // 6092 // selector - String CSS selector 6093 // data - Optional data Object (default: undefined) 6094 // 6095 // Returns nothing. 6096 SelectorSet.prototype.add = function (selector, data) { 6097 var obj, 6098 i, 6099 indexProto,
6100 key, 6101 index, 6102 objs, 6103 selectorIndexes, 6104 selectorIndex, 6105 indexes = this.activeIndexes, 6106 selectors = this.selectors, 6107 selectorObjects = this.selectorObjects; 6108 if (typeof selector !== 'string') { 6109 return; 6110 } 6111 obj = { 6112 id: this.uid++, 6113 selector: selector, 6114 data: data 6115 }; 6116 selectorObjects[obj.id] = obj; 6117 selectorIndexes = parseSelectorIndexes(this.indexes, selector); 6118 for (i = 0; i < selectorIndexes.length; i++) { 6119 selectorIndex = selectorIndexes[i]; 6120 key = selectorIndex.key; 6121 indexProto = selectorIndex.index; 6122 index = findByPrototype(indexes, indexProto); 6123 if (!index) { 6124 index = Object.create(indexProto); 6125 index.map = new Map$1(); 6126 indexes.push(index); 6127 } 6128 if (indexProto === this.indexes['default']) { 6129 this.logDefaultIndexUsed(obj); 6130 } 6131 objs = index.map.get(key); 6132 if (!objs) { 6133 objs = []; 6134 index.map.set(key, objs); 6135 } 6136 objs.push(obj); 6137 } 6138 this.size++; 6139 selectors.push(selector); 6140 }; 6141 6142 // Public: Remove selector from set. 6143 // 6144 // selector - String CSS selector 6145 // data - Optional data Object (default: undefined) 6146 // 6147 // Returns nothing. 6148 SelectorSet.prototype.remove = function (selector, data) { 6149 if (typeof selector !== 'string') { 6150 return; 6151 } 6152 var selectorIndexes, 6153 selectorIndex, 6154 i, 6155 j, 6156 k, 6157 selIndex, 6158 objs, 6159 obj, 6160 indexes = this.activeIndexes, 6161 selectors = this.selectors = [], 6162 selectorObjects = this.selectorObjects, 6163 removedIds = {}, 6164 removeAll = arguments.length === 1; 6165 selectorIndexes = parseSelectorIndexes(this.indexes, selector); 6166 for (i = 0; i < selectorIndexes.length; i++) { 6167 selectorIndex = selectorIndexes[i]; 6168 j = indexes.length; 6169 while (j--) { 6170 selIndex = indexes[j]; 6171 if (selectorIndex.index.isPrototypeOf(selIndex)) { 6172 objs = selIndex.map.get(selectorIndex.key); 6173 if (objs) { 6174 k = objs.length; 6175 while (k--) { 6176 obj = objs[k]; 6177 if (obj.selector === selector && (removeAll || obj.data === data)) { 6178 objs.splice(k, 1); 6179 removedIds[obj.id] = true; 6180 } 6181 } 6182 } 6183 break; 6184 } 6185 } 6186 } 6187 for (i in removedIds) { 6188 delete selectorObjects[i]; 6189 this.size--; 6190 } 6191 for (i in selectorObjects) { 6192 selectors.push(selectorObjects[i].selector); 6193 } 6194 }; 6195 6196 // Sort by id property handler. 6197 // 6198 // a - Selector obj. 6199 // b - Selector obj. 6200 // 6201 // Returns Number. 6202 function sortById(a, b) { 6203 return a.id - b.id; 6204 } 6205 6206 // Public: Find all matching decendants of the context element. 6207 // 6208 // context - An Element 6209 // 6210 // Returns Array of {selector, data, elements} matches. 6211 SelectorSet.prototype.queryAll = function (context) { 6212 if (!this.selectors.length) { 6213 return []; 6214 } 6215 var matches = {}, 6216 results = []; 6217 var els = this.querySelectorAll(this.selectors.join(', '), context); 6218 var i, j, len, len2, el, m, match, obj; 6219 for (i = 0, len = els.length; i < len; i++) { 6220 el = els[i]; 6221 m = this.matches(el); 6222 for (j = 0, len2 = m.length; j < len2; j++) { 6223 obj = m[j]; 6224 if (!matches[obj.id]) { 6225 match = { 6226 id: obj.id, 6227 selector: obj.selector, 6228 data: obj.data, 6229 elements: [] 6230 }; 6231 matches[obj.id] = match; 6232 results.push(match); 6233 } else { 6234 match = matches[obj.id]; 6235 } 6236 match.elements.push(el); 6237 } 6238 } 6239 return results.sort(sortById); 6240 }; 6241 6242 // Public: Match element against all selectors in set. 6243 // 6244 // el - An Element 6245 // 6246 // Returns Array of {selector, data} matches. 6247 SelectorSet.prototype.matches = function (el) { 6248 if (!el) { 6249 return []; 6250 } 6251 var i, j, k, len, len2, len3, index, keys, objs, obj, id; 6252 var indexes = this.activeIndexes, 6253 matchedIds = {}, 6254 matches = []; 6255 for (i = 0, len = indexes.length; i < len; i++) { 6256 index = indexes[i];
6257 keys = index.element(el); 6258 if (keys) { 6259 for (j = 0, len2 = keys.length; j < len2; j++) { 6260 if (objs = index.map.get(keys[j])) { 6261 for (k = 0, len3 = objs.length; k < len3; k++) { 6262 obj = objs[k]; 6263 id = obj.id; 6264 if (!matchedIds[id] && this.matchesSelector(el, obj.selector)) { 6265 matchedIds[id] = true; 6266 matches.push(obj); 6267 } 6268 } 6269 } 6270 } 6271 } 6272 } 6273 return matches.sort(sortById); 6274 }; 6275 6276 var bubbleEvents = {}; 6277 var captureEvents = {}; 6278 var propagationStopped = new WeakMap(); 6279 var immediatePropagationStopped = new WeakMap(); 6280 var currentTargets = new WeakMap(); 6281 var currentTargetDesc = Object.getOwnPropertyDescriptor(Event.prototype, 'currentTarget'); 6282 function before(subject, verb, fn) { 6283 var source = subject[verb]; 6284 subject[verb] = function () { 6285 fn.apply(subject, arguments); 6286 return source.apply(subject, arguments); 6287 }; 6288 return subject; 6289 } 6290 function matches(selectors, target, reverse) { 6291 var queue = []; 6292 var node = target; 6293 do { 6294 if (node.nodeType !== 1) break; 6295 var _matches = selectors.matches(node); 6296 if (_matches.length) { 6297 var matched = { 6298 node: node, 6299 observers: _matches 6300 }; 6301 if (reverse) { 6302 queue.unshift(matched); 6303 } else { 6304 queue.push(matched); 6305 } 6306 } 6307 } while (node = node.parentElement); 6308 return queue; 6309 } 6310 function trackPropagation() { 6311 propagationStopped.set(this, true); 6312 } 6313 function trackImmediate() { 6314 propagationStopped.set(this, true); 6315 immediatePropagationStopped.set(this, true); 6316 } 6317 function getCurrentTarget() { 6318 return currentTargets.get(this) || null; 6319 } 6320 function defineCurrentTarget(event, getter) { 6321 if (!currentTargetDesc) return; 6322 Object.defineProperty(event, 'currentTarget', { 6323 configurable: true, 6324 enumerable: true, 6325 get: getter || currentTargetDesc.get 6326 }); 6327 } 6328 function canDispatch(event) { 6329 try { 6330 event.eventPhase; 6331 return true; 6332 } catch (_) { 6333 return false; 6334 } 6335 } 6336 function dispatch(event) { 6337 if (!canDispatch(event)) return; 6338 var events = event.eventPhase === 1 ? captureEvents : bubbleEvents; 6339 var selectors = events[event.type]; 6340 if (!selectors) return; 6341 var queue = matches(selectors, event.target, event.eventPhase === 1); 6342 if (!queue.length) return; 6343 before(event, 'stopPropagation', trackPropagation); 6344 before(event, 'stopImmediatePropagation', trackImmediate); 6345 defineCurrentTarget(event, getCurrentTarget); 6346 for (var i = 0, len1 = queue.length; i < len1; i++) { 6347 if (propagationStopped.get(event)) break; 6348 var matched = queue[i]; 6349 currentTargets.set(event, matched.node); 6350 for (var j = 0, len2 = matched.observers.length; j < len2; j++) { 6351 if (immediatePropagationStopped.get(event)) break; 6352 matched.observers[j].data.call(matched.node, event); 6353 } 6354 } 6355 currentTargets["delete"](event); 6356 defineCurrentTarget(event); 6357 } 6358 function on(name, selector, fn) { 6359 var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; 6360 var capture = options.capture ? true : false; 6361 var events = capture ? captureEvents : bubbleEvents; 6362 var selectors = events[name]; 6363 if (!selectors) { 6364 selectors = new SelectorSet(); 6365 events[name] = selectors; 6366 document.addEventListener(name, dispatch, capture); 6367 } 6368 selectors.add(selector, fn); 6369 } 6370 6371 /** 6372 * Test if Element Supports Attribute 6373 * Creates the element (without attaching to DOM) and runs test for attribute (needle) within available attributes (haystack) 6374 * @param {string} element 6375 * @param {string} attribute 6376 * @return {boolean} 6377 */ 6378 6379 /** 6380 * Does user have "Reduced Motion" set? 6381 * Mac users can set this in Sys Prefs > Accessibility > Display > Reduce Motion 6382 * @return {boolean} 6383 * @link https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion 6384 */ 6385 function getReducedMotionSetting() { 6386 return window.matchMedia('(prefers-reduced-motion: reduce)').matches; 6387 } 6388 6389 /** 6390 * Slugify string 6391 * @param {string} string 6392 * @return {string} 6393 * @link https://gist.github.com/hagemann/382adfc57adbd5af078dc93feef01fe1 6394 */ 6395 function slugify(string) { 6396 var a = 'à áäâãåÄæçèéëêǵḧìÃïîḿÅǹñòóöôÅá¹ÅÃÅÈÈùúüûÇáºáºÃ¿ÅºÂ·/_,:;'; 6397 var b = 'aaaaaaaaceeeeghiiiimnnnoooooprssstuuuuuwxyz------'; 6398 var p = new RegExp(a.split('').join('|'), 'g'); 6399 return string.toString().toLowerCase().replace(/\s+/g, '-') // Replace spaces with - 6400 .replace(p, function (c) { 6401 return b.charAt(a.indexOf(c)); 6402 }) // Replace special characters 6403 .replace(/&/g, '-and-') // Replace & with 'and' 6404 .replace(/[^\w-]+/g, '') // Remove all non-word characters 6405 .replace(/--+/g, '-') // Replace multiple - with single - 6406 .replace(/^-+/, '') // Trim - from start of text 6407 .replace(/-+$/, ''); // Trim - from end of text 6408 } 6409 6410 function enableHeroCarousel() { 6411 var heroCarousels = document.querySelectorAll('.msk-hero--carousel'); 6412 if (!heroCarousels.length) return; 6413 var hasReducedMotion = getReducedMotionSetting(); 6414 6415 /** 6416 * How long each image is viewable 6417 * @type {number} 6418 */ 6419 var duration = 8000; // Double the value of the CSS transition time within hero.scss 6420 // const isSmallSizeTransitioning = false; // Not current supported on mobile 6421 var classes = { 6422 play: 'msk-hero__toggle-icon--is-playing', 6423 pause: 'msk-hero__toggle-icon--is-not-playing', 6424 activeSlide: 'msk-hero__carousel-slide--active' 6425 };
6426 heroCarousels.forEach(function (heroCarousel) { 6427 /** 6428 * The current ZERO index of the images that is shown. 6429 * First image is `0`, and this is set to `1` as JS was not needed to show the first image - that was already done in the template 6430 * @type {number} 6431 */ 6432 var currentSlideIndex = 0; 6433 var isPlaying = false; 6434 var cancelId; 6435 var mql = window.matchMedia('screen and (max-width: 1200px)'); 6436 6437 // Define "largeSlides" on page load. 6438 var slideClassName = mql.matches ? '.msk-hero__carousel-slide--medium' : '.msk-hero__carousel-slide--large'; 6439 var largeSlides = heroCarousel.querySelectorAll(slideClassName); 6440 6441 // Define "largeSlides" on screen resize/media query change. 6442 mql.addListener(function (e) { 6443 if (e.matches) { 6444 largeSlides = heroCarousel.querySelectorAll('.msk-hero__carousel-slide--medium'); 6445 } else { 6446 largeSlides = heroCarousel.querySelectorAll('.msk-hero__carousel-slide--large'); 6447 } 6448 }); 6449 var _heroCarousel$querySe = heroCarousel.querySelectorAll('.msk-hero__toggle'), 6450 _heroCarousel$querySe2 = _slicedToArray(_heroCarousel$querySe, 1), 6451 toggle = _heroCarousel$querySe2[0]; 6452 var imgs = Array.from(document.querySelectorAll('.msk-hero__carousel-group .msk-hero__carousel-slide')).filter(function (el) { 6453 return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length); 6454 }); 6455 6456 /* eslint-disable no-use-before-define */ 6457 /** 6458 * Go to next image 6459 * @return {void} 6460 */ 6461 function next() { 6462 var isLastImg = currentSlideIndex === imgs.length - 1; 6463 var currentSlide = largeSlides[currentSlideIndex]; 6464 var nextSlideIndex = isLastImg ? 0 : currentSlideIndex + 1; 6465 var nextSlide = largeSlides[nextSlideIndex]; 6466 6467 // spec says to play through once and then auto-pause unless interacted with. 6468 if (isLastImg) { 6469 stop(); 6470 } 6471 if (!currentSlide) { 6472 console.log('Uh oh! Could not find current slide', { 6473 currentSlide: currentSlide, 6474 largeSlides: largeSlides 6475 }); 6476 return; 6477 } 6478 { 6479 largeSlides.forEach(function (s) { 6480 return s.classList.remove(classes.activeSlide); 6481 }); 6482 nextSlide.classList.add(classes.activeSlide); 6483 currentSlideIndex = isLastImg ? 0 : currentSlideIndex + 1; 6484 } 6485 } 6486 /* eslint-enable no-use-before-define */ 6487 6488 function changeToggleState() { 6489 var play = classes.play, 6490 pause = classes.pause; 6491 isPlaying = !isPlaying; 6492 toggle.classList.remove(isPlaying ? pause : play); 6493 toggle.classList.add(isPlaying ? play : pause); 6494 } 6495 6496 /** 6497 * Start the carousel 6498 * @return {void} 6499 */ 6500 function start() { 6501 changeToggleState(); 6502 cancelId = setInterval(next, duration); 6503 } 6504 6505 /** 6506 * Stop the carousel 6507 * @return {void} 6508 */ 6509 function stop() { 6510 changeToggleState(); 6511 clearInterval(cancelId); 6512 } 6513 on('pointerup', '.msk-hero__toggle', function (e) { 6514 e.stopPropagation(); 6515 if (isPlaying) { 6516 stop(); 6517 } else { 6518 start(); 6519 } 6520 }); 6521 on('keydown', '.msk-hero__toggle', function (e) { 6522 if (e.key === 'Enter' || e.key === ' ') { 6523 if (isPlaying) { 6524 stop(); 6525 } else { 6526 start(); 6527 } 6528 } 6529 }); 6530 if (!hasReducedMotion) { 6531 start(); 6532 } else { 6533 // changeToggleState(); 6534 toggle.classList.add(classes.pause); 6535 } 6536 }); 6537 } 6538 6539 var leafletSrc = {exports: {}}; 6540 6541 (function (module, exports) { 6542 (function (global, factory) { 6543 factory(exports) ; 6544 })(commonjsGlobal, function (exports) { 6545 6546 var version = "1.9.4"; 6547 6548 /* 6549 * @namespace Util 6550 * 6551 * Various utility functions, used by Leaflet internally. 6552 */ 6553 6554 // @function extend(dest: Object, src?: Object): Object 6555 // Merges the properties of the `src` object (or multiple objects) into `dest` object and returns the latter. Has an `L.extend` shortcut. 6556 function extend(dest) { 6557 var i, j, len, src; 6558 for (j = 1, len = arguments.length; j < len; j++) { 6559 src = arguments[j]; 6560 for (i in src) { 6561 dest[i] = src[i]; 6562 } 6563 } 6564 return dest; 6565 } 6566 6567 // @function create(proto: Object, properties?: Object): Object 6568 // Compatibility polyfill for [Object.create](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/create) 6569 var create$2 = Object.create || function () { 6570 function F() {} 6571 return function (proto) { 6572 F.prototype = proto; 6573 return new F(); 6574 }; 6575 }(); 6576 6577 // @function bind(fn: Function, â¦): Function 6578 // 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). 6579 // Has a `L.bind()` shortcut. 6580 function bind(fn, obj) { 6581 var slice = Array.prototype.slice; 6582 if (fn.bind) { 6583 return fn.bind.apply(fn, slice.call(arguments, 1)); 6584 } 6585 var args = slice.call(arguments, 2); 6586 return function () { 6587 return fn.apply(obj, args.length ? args.concat(slice.call(arguments)) : arguments); 6588 }; 6589 } 6590 6591 // @property lastId: Number 6592 // Last unique ID used by [`stamp()`](#util-stamp) 6593 var lastId = 0; 6594 6595 // @function stamp(obj: Object): Number 6596 // Returns the unique ID of an object, assigning it one if it doesn't have it. 6597 function stamp(obj) { 6598 if (!('_leaflet_id' in obj)) { 6599 obj['_leaflet_id'] = ++lastId; 6600 } 6601 return obj._leaflet_id; 6602 } 6603
vendor: 18,887 bytes, lines 6604-7081
6604 // @function throttle(fn: Function, time: Number, context: Object): Function 6605 // Returns a function which executes function `fn` with the given scope `context` 6606 // (so that the `this` keyword refers to `context` inside `fn`'s code). The function 6607 // `fn` will be called no more than one time per given amount of `time`. The arguments 6608 // received by the bound function will be any arguments passed when binding the 6609 // function, followed by any arguments passed when invoking the bound function. 6610 // Has an `L.throttle` shortcut. 6611 function throttle(fn, time, context) { 6612 var lock, args, wrapperFn, later; 6613 later = function later() { 6614 // reset lock and call if queued 6615 lock = false; 6616 if (args) { 6617 wrapperFn.apply(context, args); 6618 args = false; 6619 } 6620 }; 6621 wrapperFn = function wrapperFn() { 6622 if (lock) { 6623 // called too soon, queue to call later 6624 args = arguments; 6625 } else { 6626 // call and lock until later 6627 fn.apply(context, arguments); 6628 setTimeout(later, time); 6629 lock = true; 6630 } 6631 }; 6632 return wrapperFn; 6633 } 6634 6635 // @function wrapNum(num: Number, range: Number[], includeMax?: Boolean): Number 6636 // Returns the number `num` modulo `range` in such a way so it lies within 6637 // `range[0]` and `range[1]`. The returned value will be always smaller than 6638 // `range[1]` unless `includeMax` is set to `true`. 6639 function wrapNum(x, range, includeMax) { 6640 var max = range[1], 6641 min = range[0], 6642 d = max - min; 6643 return x === max && includeMax ? x : ((x - min) % d + d) % d + min; 6644 } 6645 6646 // @function falseFn(): Function 6647 // Returns a function which always returns `false`. 6648 function falseFn() { 6649 return false; 6650 } 6651 6652 // @function formatNum(num: Number, precision?: Number|false): Number 6653 // Returns the number `num` rounded with specified `precision`. 6654 // The default `precision` value is 6 decimal places. 6655 // `false` can be passed to skip any processing (can be useful to avoid round-off errors). 6656 function formatNum(num, precision) { 6657 if (precision === false) { 6658 return num; 6659 } 6660 var pow = Math.pow(10, precision === undefined ? 6 : precision); 6661 return Math.round(num * pow) / pow; 6662 } 6663 6664 // @function trim(str: String): String 6665 // Compatibility polyfill for [String.prototype.trim](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/Trim) 6666 function trim(str) { 6667 return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, ''); 6668 } 6669 6670 // @function splitWords(str: String): String[] 6671 // Trims and splits the string on whitespace and returns the array of parts. 6672 function splitWords(str) { 6673 return trim(str).split(/\s+/); 6674 } 6675 6676 // @function setOptions(obj: Object, options: Object): Object 6677 // Merges the given properties to the `options` of the `obj` object, returning the resulting options. See `Class options`. Has an `L.setOptions` shortcut. 6678 function setOptions(obj, options) { 6679 if (!Object.prototype.hasOwnProperty.call(obj, 'options')) { 6680 obj.options = obj.options ? create$2(obj.options) : {}; 6681 } 6682 for (var i in options) { 6683 obj.options[i] = options[i]; 6684 } 6685 return obj.options; 6686 } 6687 6688 // @function getParamString(obj: Object, existingUrl?: String, uppercase?: Boolean): String 6689 // Converts an object into a parameter URL string, e.g. `{a: "foo", b: "bar"}` 6690 // translates to `'?a=foo&b=bar'`. If `existingUrl` is set, the parameters will 6691 // be appended at the end. If `uppercase` is `true`, the parameter names will 6692 // be uppercased (e.g. `'?A=foo&B=bar'`) 6693 function getParamString(obj, existingUrl, uppercase) { 6694 var params = []; 6695 for (var i in obj) { 6696 params.push(encodeURIComponent(uppercase ? i.toUpperCase() : i) + '=' + encodeURIComponent(obj[i])); 6697 } 6698 return (!existingUrl || existingUrl.indexOf('?') === -1 ? '?' : '&') + params.join('&'); 6699 } 6700 var templateRe = /\{ *([\w_ -]+) *\}/g; 6701 6702 // @function template(str: String, data: Object): String 6703 // Simple templating facility, accepts a template string of the form `'Hello {a}, {b}'` 6704 // and a data object like `{a: 'foo', b: 'bar'}`, returns evaluated string 6705 // `('Hello foo, bar')`. You can also specify functions instead of strings for 6706 // data values â they will be evaluated passing `data` as an argument. 6707 function template(str, data) { 6708 return str.replace(templateRe, function (str, key) { 6709 var value = data[key]; 6710 if (value === undefined) { 6711 throw new Error('No value provided for variable ' + str); 6712 } else if (typeof value === 'function') { 6713 value = value(data); 6714 } 6715 return value; 6716 }); 6717 } 6718 6719 // @function isArray(obj): Boolean 6720 // Compatibility polyfill for [Array.isArray](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray) 6721 var isArray = Array.isArray || function (obj) { 6722 return Object.prototype.toString.call(obj) === '[object Array]'; 6723 }; 6724 6725 // @function indexOf(array: Array, el: Object): Number 6726 // Compatibility polyfill for [Array.prototype.indexOf](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf) 6727 function indexOf(array, el) { 6728 for (var i = 0; i < array.length; i++) { 6729 if (array[i] === el) { 6730 return i; 6731 } 6732 } 6733 return -1; 6734 } 6735 6736 // @property emptyImageUrl: String 6737 // Data URI string containing a base64-encoded empty GIF image. 6738 // Used as a hack to free memory from unused images on WebKit-powered 6739 // mobile devices (by setting image `src` to this string). 6740 var emptyImageUrl = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs='; 6741 6742 // inspired by https://paulirish.com/2011/requestanimationframe-for-smart-animating/ 6743 6744 function getPrefixed(name) { 6745 return window['webkit' + name] || window['moz' + name] || window['ms' + name]; 6746 } 6747 var lastTime = 0; 6748 6749 // fallback for IE 7-8 6750 function timeoutDefer(fn) { 6751 var time = +new Date(), 6752 timeToCall = Math.max(0, 16 - (time - lastTime)); 6753 lastTime = time + timeToCall; 6754 return window.setTimeout(fn, timeToCall); 6755 } 6756 var requestFn = window.requestAnimationFrame || getPrefixed('RequestAnimationFrame') || timeoutDefer; 6757 var cancelFn = window.cancelAnimationFrame || getPrefixed('CancelAnimationFrame') || getPrefixed('CancelRequestAnimationFrame') || function (id) { 6758 window.clearTimeout(id); 6759 }; 6760 6761 // @function requestAnimFrame(fn: Function, context?: Object, immediate?: Boolean): Number 6762 // Schedules `fn` to be executed when the browser repaints. `fn` is bound to 6763 // `context` if given. When `immediate` is set, `fn` is called immediately if 6764 // the browser doesn't have native support for 6765 // [`window.requestAnimationFrame`](https://developer.mozilla.org/docs/Web/API/window/requestAnimationFrame), 6766 // otherwise it's delayed. Returns a request ID that can be used to cancel the request. 6767 function requestAnimFrame(fn, context, immediate) { 6768 if (immediate && requestFn === timeoutDefer) { 6769 fn.call(context); 6770 } else { 6771 return requestFn.call(window, bind(fn, context)); 6772 } 6773 } 6774 6775 // @function cancelAnimFrame(id: Number): undefined 6776 // Cancels a previous `requestAnimFrame`. See also [window.cancelAnimationFrame](https://developer.mozilla.org/docs/Web/API/window/cancelAnimationFrame). 6777 function cancelAnimFrame(id) { 6778 if (id) { 6779 cancelFn.call(window, id); 6780 } 6781 } 6782 var Util = { 6783 __proto__: null, 6784 extend: extend, 6785 create: create$2, 6786 bind: bind, 6787 get lastId() { 6788 return lastId; 6789 }, 6790 stamp: stamp, 6791 throttle: throttle, 6792 wrapNum: wrapNum, 6793 falseFn: falseFn, 6794 formatNum: formatNum, 6795 trim: trim, 6796 splitWords: splitWords, 6797 setOptions: setOptions, 6798 getParamString: getParamString, 6799 template: template, 6800 isArray: isArray, 6801 indexOf: indexOf, 6802 emptyImageUrl: emptyImageUrl, 6803 requestFn: requestFn, 6804 cancelFn: cancelFn, 6805 requestAnimFrame: requestAnimFrame, 6806 cancelAnimFrame: cancelAnimFrame 6807 }; 6808 6809 // @class Class 6810 // @aka L.Class 6811 6812 // @section 6813 // @uninheritable 6814 6815 // Thanks to John Resig and Dean Edwards for inspiration! 6816 6817 function Class() {} 6818 Class.extend = function (props) { 6819 // @function extend(props: Object): Function 6820 // [Extends the current class](#class-inheritance) given the properties to be included. 6821 // Returns a Javascript function that is a class constructor (to be called with `new`). 6822 var NewClass = function NewClass() { 6823 setOptions(this); 6824 6825 // call the constructor 6826 if (this.initialize) { 6827 this.initialize.apply(this, arguments); 6828 } 6829 6830 // call all constructor hooks 6831 this.callInitHooks(); 6832 }; 6833 var parentProto = NewClass.__super__ = this.prototype; 6834 var proto = create$2(parentProto); 6835 proto.constructor = NewClass; 6836 NewClass.prototype = proto; 6837 6838 // inherit parent's statics 6839 for (var i in this) { 6840 if (Object.prototype.hasOwnProperty.call(this, i) && i !== 'prototype' && i !== '__super__') { 6841 NewClass[i] = this[i]; 6842 } 6843 } 6844 6845 // mix static properties into the class 6846 if (props.statics) { 6847 extend(NewClass, props.statics); 6848 } 6849 6850 // mix includes into the prototype 6851 if (props.includes) { 6852 checkDeprecatedMixinEvents(props.includes); 6853 extend.apply(null, [proto].concat(props.includes)); 6854 } 6855 6856 // mix given properties into the prototype 6857 extend(proto, props); 6858 delete proto.statics; 6859 delete proto.includes; 6860 6861 // merge options 6862 if (proto.options) { 6863 proto.options = parentProto.options ? create$2(parentProto.options) : {}; 6864 extend(proto.options, props.options); 6865 } 6866 proto._initHooks = []; 6867 6868 // add method for calling all hooks 6869 proto.callInitHooks = function () { 6870 if (this._initHooksCalled) { 6871 return; 6872 } 6873 if (parentProto.callInitHooks) { 6874 parentProto.callInitHooks.call(this); 6875 } 6876 this._initHooksCalled = true; 6877 for (var i = 0, len = proto._initHooks.length; i < len; i++) { 6878 proto._initHooks[i].call(this); 6879 } 6880 }; 6881 return NewClass; 6882 }; 6883 6884 // @function include(properties: Object): this 6885 // [Includes a mixin](#class-includes) into the current class. 6886 Class.include = function (props) { 6887 var parentOptions = this.prototype.options; 6888 extend(this.prototype, props); 6889 if (props.options) { 6890 this.prototype.options = parentOptions; 6891 this.mergeOptions(props.options); 6892 } 6893 return this; 6894 }; 6895 6896 // @function mergeOptions(options: Object): this 6897 // [Merges `options`](#class-options) into the defaults of the class. 6898 Class.mergeOptions = function (options) { 6899 extend(this.prototype.options, options); 6900 return this; 6901 }; 6902 6903 // @function addInitHook(fn: Function): this 6904 // Adds a [constructor hook](#class-constructor-hooks) to the class. 6905 Class.addInitHook = function (fn) { 6906 // (Function) || (String, args...) 6907 var args = Array.prototype.slice.call(arguments, 1); 6908 var init = typeof fn === 'function' ? fn : function () { 6909 this[fn].apply(this, args); 6910 }; 6911 this.prototype._initHooks = this.prototype._initHooks || []; 6912 this.prototype._initHooks.push(init); 6913 return this; 6914 }; 6915 function checkDeprecatedMixinEvents(includes) { 6916 /* global L: true */ 6917 if (typeof L === 'undefined' || !L || !L.Mixin) { 6918 return; 6919 } 6920 includes = isArray(includes) ? includes : [includes]; 6921 for (var i = 0; i < includes.length; i++) { 6922 if (includes[i] === L.Mixin.Events) { 6923 console.warn('Deprecated include of L.Mixin.Events: ' + 'this property will be removed in future releases, ' + 'please inherit from L.Evented instead.', new Error().stack); 6924 } 6925 } 6926 } 6927 6928 /* 6929 * @class Evented 6930 * @aka L.Evented 6931 * @inherits Class 6932 * 6933 * 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). 6934 * 6935 * @example 6936 * 6937 * ```js 6938 * map.on('click', function(e) { 6939 * alert(e.latlng); 6940 * } ); 6941 * ``` 6942 * 6943 * Leaflet deals with event listeners by reference, so if you want to add a listener and then remove it, define it as a function: 6944 * 6945 * ```js 6946 * function onClick(e) { ... } 6947 * 6948 * map.on('click', onClick); 6949 * map.off('click', onClick); 6950 * ``` 6951 */ 6952 6953 var Events = { 6954 /* @method on(type: String, fn: Function, context?: Object): this 6955 * 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'`). 6956 * 6957 * @alternative 6958 * @method on(eventMap: Object): this 6959 * Adds a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}` 6960 */ 6961 on: function on(types, fn, context) { 6962 // types can be a map of types/handlers 6963 if (_typeof$1(types) === 'object') { 6964 for (var type in types) { 6965 // we don't process space-separated events here for performance; 6966 // it's a hot path since Layer uses the on(obj) syntax 6967 this._on(type, types[type], fn); 6968 } 6969 } else { 6970 // types can be a string of space-separated words 6971 types = splitWords(types); 6972 for (var i = 0, len = types.length; i < len; i++) { 6973 this._on(types[i], fn, context); 6974 } 6975 } 6976 return this; 6977 }, 6978 /* @method off(type: String, fn?: Function, context?: Object): this 6979 * 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. 6980 * 6981 * @alternative 6982 * @method off(eventMap: Object): this 6983 * Removes a set of type/listener pairs. 6984 * 6985 * @alternative 6986 * @method off: this 6987 * Removes all listeners to all events on the object. This includes implicitly attached events. 6988 */ 6989 off: function off(types, fn, context) { 6990 if (!arguments.length) { 6991 // clear all listeners if called without arguments 6992 delete this._events; 6993 } else if (_typeof$1(types) === 'object') { 6994 for (var type in types) { 6995 this._off(type, types[type], fn); 6996 } 6997 } else { 6998 types = splitWords(types); 6999 var removeAll = arguments.length === 1; 7000 for (var i = 0, len = types.length; i < len; i++) { 7001 if (removeAll) { 7002 this._off(types[i]); 7003 } else { 7004 this._off(types[i], fn, context); 7005 } 7006 } 7007 } 7008 return this; 7009 }, 7010 // attach listener (without syntactic sugar now) 7011 _on: function _on(type, fn, context, _once) { 7012 if (typeof fn !== 'function') { 7013 console.warn('wrong listener type: ' + _typeof$1(fn)); 7014 return; 7015 } 7016 7017 // check if fn already there 7018 if (this._listens(type, fn, context) !== false) { 7019 return; 7020 } 7021 if (context === this) { 7022 // Less memory footprint. 7023 context = undefined; 7024 } 7025 var newListener = { 7026 fn: fn, 7027 ctx: context 7028 }; 7029 if (_once) { 7030 newListener.once = true; 7031 } 7032 this._events = this._events || {}; 7033 this._events[type] = this._events[type] || []; 7034 this._events[type].push(newListener); 7035 }, 7036 _off: function _off(type, fn, context) { 7037 var listeners, i, len; 7038 if (!this._events) { 7039 return; 7040 } 7041 listeners = this._events[type]; 7042 if (!listeners) { 7043 return; 7044 } 7045 if (arguments.length === 1) { 7046 // remove all 7047 if (this._firingCount) { 7048 // Set all removed listeners to noop 7049 // so they are not called if remove happens in fire 7050 for (i = 0, len = listeners.length; i < len; i++) { 7051 listeners[i].fn = falseFn; 7052 } 7053 } 7054 // clear all listeners for a type if function isn't specified 7055 delete this._events[type]; 7056 return; 7057 } 7058 if (typeof fn !== 'function') { 7059 console.warn('wrong listener type: ' + _typeof$1(fn)); 7060 return; 7061 } 7062 7063 // find fn and remove it 7064 var index = this._listens(type, fn, context); 7065 if (index !== false) { 7066 var listener = listeners[index]; 7067 if (this._firingCount) { 7068 // set the removed listener to noop so that's not called if remove happens in fire 7069 listener.fn = falseFn; 7070 7071 /* copy array in case events are being fired */ 7072 this._events[type] = listeners = listeners.slice(); 7073 } 7074 listeners.splice(index, 1); 7075 } 7076 }, 7077 // @method fire(type: String, data?: Object, propagate?: Boolean): this 7078 // Fires an event of the specified type. You can optionally provide a data 7079 // object â the first argument of the listener function will contain its 7080 // properties. The event can optionally be propagated to event parents. 7081 fire: function fire(type, data, propagate) {
7082 if (!this.listens(type, propagate)) { 7083 return this; 7084 } 7085 var event = extend({}, data, { 7086 type: type, 7087 target: this, 7088 sourceTarget: data && data.sourceTarget || this 7089 }); 7090 if (this._events) { 7091 var listeners = this._events[type]; 7092 if (listeners) { 7093 this._firingCount = this._firingCount + 1 || 1; 7094 for (var i = 0, len = listeners.length; i < len; i++) { 7095 var l = listeners[i]; 7096 // off overwrites l.fn, so we need to copy fn to a var 7097 var fn = l.fn; 7098 if (l.once) { 7099 this.off(type, fn, l.ctx); 7100 } 7101 fn.call(l.ctx || this, event); 7102 } 7103 this._firingCount--; 7104 } 7105 } 7106 if (propagate) { 7107 // propagate the event to parents (set with addEventParent) 7108 this._propagateEvent(event); 7109 } 7110 return this; 7111 }, 7112 // @method listens(type: String, propagate?: Boolean): Boolean 7113 // @method listens(type: String, fn: Function, context?: Object, propagate?: Boolean): Boolean 7114 // Returns `true` if a particular event type has any listeners attached to it. 7115 // The verification can optionally be propagated, it will return `true` if parents have the listener attached to it. 7116 listens: function listens(type, fn, context, propagate) { 7117 if (typeof type !== 'string') { 7118 console.warn('"string" type argument expected'); 7119 } 7120 7121 // we don't overwrite the input `fn` value, because we need to use it for propagation 7122 var _fn = fn; 7123 if (typeof fn !== 'function') { 7124 propagate = !!fn; 7125 _fn = undefined; 7126 context = undefined; 7127 } 7128 var listeners = this._events && this._events[type]; 7129 if (listeners && listeners.length) { 7130 if (this._listens(type, _fn, context) !== false) { 7131 return true; 7132 } 7133 } 7134 if (propagate) { 7135 // also check parents for listeners if event propagates 7136 for (var id in this._eventParents) { 7137 if (this._eventParents[id].listens(type, fn, context, propagate)) { 7138 return true; 7139 } 7140 } 7141 } 7142 return false; 7143 }, 7144 // returns the index (number) or false 7145 _listens: function _listens(type, fn, context) { 7146 if (!this._events) { 7147 return false; 7148 } 7149 var listeners = this._events[type] || []; 7150 if (!fn) { 7151 return !!listeners.length; 7152 } 7153 if (context === this) { 7154 // Less memory footprint. 7155 context = undefined; 7156 } 7157 for (var i = 0, len = listeners.length; i < len; i++) { 7158 if (listeners[i].fn === fn && listeners[i].ctx === context) { 7159 return i; 7160 } 7161 } 7162 return false; 7163 }, 7164 // @method once(â¦): this 7165 // Behaves as [`on(â¦)`](#evented-on), except the listener will only get fired once and then removed. 7166 once: function once(types, fn, context) { 7167 // types can be a map of types/handlers 7168 if (_typeof$1(types) === 'object') { 7169 for (var type in types) { 7170 // we don't process space-separated events here for performance; 7171 // it's a hot path since Layer uses the on(obj) syntax 7172 this._on(type, types[type], fn, true); 7173 } 7174 } else { 7175 // types can be a string of space-separated words 7176 types = splitWords(types); 7177 for (var i = 0, len = types.length; i < len; i++) { 7178 this._on(types[i], fn, context, true); 7179 } 7180 } 7181 return this; 7182 }, 7183 // @method addEventParent(obj: Evented): this 7184 // Adds an event parent - an `Evented` that will receive propagated events 7185 addEventParent: function addEventParent(obj) { 7186 this._eventParents = this._eventParents || {}; 7187 this._eventParents[stamp(obj)] = obj; 7188 return this; 7189 }, 7190 // @method removeEventParent(obj: Evented): this 7191 // Removes an event parent, so it will stop receiving propagated events 7192 removeEventParent: function removeEventParent(obj) { 7193 if (this._eventParents) { 7194 delete this._eventParents[stamp(obj)]; 7195 } 7196 return this; 7197 }, 7198 _propagateEvent: function _propagateEvent(e) { 7199 for (var id in this._eventParents) { 7200 this._eventParents[id].fire(e.type, extend({ 7201 layer: e.target, 7202 propagatedFrom: e.target 7203 }, e), true); 7204 } 7205 } 7206 }; 7207 7208 // aliases; we should ditch those eventually 7209 7210 // @method addEventListener(â¦): this 7211 // Alias to [`on(â¦)`](#evented-on) 7212 Events.addEventListener = Events.on; 7213 7214 // @method removeEventListener(â¦): this 7215 // Alias to [`off(â¦)`](#evented-off) 7216 7217 // @method clearAllEventListeners(â¦): this 7218 // Alias to [`off()`](#evented-off) 7219 Events.removeEventListener = Events.clearAllEventListeners = Events.off; 7220 7221 // @method addOneTimeEventListener(â¦): this 7222 // Alias to [`once(â¦)`](#evented-once) 7223 Events.addOneTimeEventListener = Events.once; 7224 7225 // @method fireEvent(â¦): this 7226 // Alias to [`fire(â¦)`](#evented-fire) 7227 Events.fireEvent = Events.fire; 7228 7229 // @method hasEventListeners(â¦): Boolean 7230 // Alias to [`listens(â¦)`](#evented-listens) 7231 Events.hasEventListeners = Events.listens; 7232 var Evented = Class.extend(Events); 7233 7234 /* 7235 * @class Point 7236 * @aka L.Point 7237 * 7238 * Represents a point with `x` and `y` coordinates in pixels. 7239 * 7240 * @example 7241 * 7242 * ```js 7243 * var point = L.point(200, 300); 7244 * ``` 7245 * 7246 * 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: 7247 * 7248 * ```js 7249 * map.panBy([200, 300]); 7250 * map.panBy(L.point(200, 300)); 7251 * ``` 7252 * 7253 * Note that `Point` does not inherit from Leaflet's `Class` object, 7254 * which means new classes can't inherit from it, and new methods 7255 * can't be added to it with the `include` function. 7256 */ 7257 7258 function Point(x, y, round) { 7259 // @property x: Number; The `x` coordinate of the point 7260 this.x = round ? Math.round(x) : x; 7261 // @property y: Number; The `y` coordinate of the point 7262 this.y = round ? Math.round(y) : y; 7263 } 7264 var trunc = Math.trunc || function (v) { 7265 return v > 0 ? Math.floor(v) : Math.ceil(v); 7266 }; 7267 Point.prototype = { 7268 // @method clone(): Point 7269 // Returns a copy of the current point. 7270 clone: function clone() { 7271 return new Point(this.x, this.y); 7272 }, 7273 // @method add(otherPoint: Point): Point 7274 // Returns the result of addition of the current and the given points. 7275 add: function add(point) { 7276 // non-destructive, returns a new point 7277 return this.clone()._add(toPoint(point)); 7278 }, 7279 _add: function _add(point) { 7280 // destructive, used directly for performance in situations where it's s
7280afe to modify existing point 7281 this.x += point.x; 7282 this.y += point.y; 7283 return this; 7284 }, 7285 // @method subtract(otherPoint: Point): Point 7286 // Returns the result of subtraction of the given point from the current. 7287 subtract: function subtract(point) { 7288 return this.clone()._subtract(toPoint(point)); 7289 }, 7290 _subtract: function _subtract(point) { 7291 this.x -= point.x; 7292 this.y -= point.y; 7293 return this; 7294 }, 7295 // @method divideBy(num: Number): Point 7296 // Returns the result of division of the current point by the given number. 7297 divideBy: function divideBy(num) { 7298 return this.clone()._divideBy(num); 7299 }, 7300 _divideBy: function _divideBy(num) { 7301 this.x /= num; 7302 this.y /= num; 7303 return this; 7304 }, 7305 // @method multiplyBy(num: Number): Point 7306 // Returns the result of multiplication of the current point by the given number. 7307 multiplyBy: function multiplyBy(num) { 7308 return this.clone()._multiplyBy(num); 7309 }, 7310 _multiplyBy: function _multiplyBy(num) { 7311 this.x *= num; 7312 this.y *= num; 7313 return this; 7314 }, 7315 // @method scaleBy(scale: Point): Point 7316 // Multiply each coordinate of the current point by each coordinate of 7317 // `scale`. In linear algebra terms, multiply the point by the 7318 // [scaling matrix](https://en.wikipedia.org/wiki/Scaling_%28geometry%29#Matrix_representation) 7319 // defined by `scale`. 7320 scaleBy: function scaleBy(point) { 7321 return new Point(this.x * point.x, this.y * point.y); 7322 }, 7323 // @method unscaleBy(scale: Point): Point 7324 // Inverse of `scaleBy`. Divide each coordinate of the current point by 7325 // each coordinate of `scale`. 7326 unscaleBy: function unscaleBy(point) { 7327 return new Point(this.x / point.x, this.y / point.y); 7328 }, 7329 // @method round(): Point 7330 // Returns a copy of the current point with rounded coordinates. 7331 round: function round() { 7332 return this.clone()._round(); 7333 }, 7334 _round: function _round() { 7335 this.x = Math.round(this.x); 7336 this.y = Math.round(this.y); 7337 return this; 7338 }, 7339 // @method floor(): Point 7340 // Returns a copy of the current point with floored coordinates (rounded down). 7341 floor: function floor() { 7342 return this.clone()._floor(); 7343 }, 7344 _floor: function _floor() { 7345 this.x = Math.floor(this.x); 7346 this.y = Math.floor(this.y); 7347 return this; 7348 }, 7349 // @method ceil(): Point 7350 // Returns a copy of the current point with ceiled coordinates (rounded up). 7351 ceil: function ceil() { 7352 return this.clone()._ceil(); 7353 }, 7354 _ceil: function _ceil() { 7355 this.x = Math.ceil(this.x); 7356 this.y = Math.ceil(this.y); 7357 return this; 7358 }, 7359 // @method trunc(): Point 7360 // Returns a copy of the current point with truncated coordinates (rounded towards zero). 7361 trunc: function trunc() { 7362 return this.clone()._trunc(); 7363 }, 7364 _trunc: function _trunc() { 7365 this.x = trunc(this.x); 7366 this.y = trunc(this.y); 7367 return this; 7368 }, 7369 // @method distanceTo(otherPoint: Point): Number 7370 // Returns the cartesian distance between the current and the given points. 7371 distanceTo: function distanceTo(point) { 7372 point = toPoint(point); 7373 var x = point.x - this.x, 7374 y = point.y - this.y; 7375 return Math.sqrt(x * x + y * y); 7376 }, 7377 // @method equals(otherPoint: Point): Boolean 7378 // Returns `true` if the given point has the same coordinates. 7379 equals: function equals(point) { 7380 point = toPoint(point); 7381 return point.x === this.x && point.y === this.y; 7382 }, 7383 // @method contains(otherPoint: Point): Boolean 7384 // Returns `true` if both coordinates of the given point are less than the corresponding current point coordinates (in absolute values). 7385 contains: function contains(point) { 7386 point = toPoint(point); 7387 return Math.abs(point.x) <= Math.abs(this.x) && Math.abs(point.y) <= Math.abs(this.y); 7388 }, 7389 // @method toString(): String 7390 // Returns a string representation of the point for debugging purposes. 7391 toString: function toString() {
7392 return 'Point(' + formatNum(this.x) + ', ' + formatNum(this.y) + ')'; 7393 } 7394 }; 7395 7396 // @factory L.point(x: Number, y: Number, round?: Boolean) 7397 // Creates a Point object with the given `x` and `y` coordinates. If optional `round` is set to true, rounds the `x` and `y` values. 7398 7399 // @alternative 7400 // @factory L.point(coords: Number[]) 7401 // Expects an array of the form `[x, y]` instead. 7402 7403 // @alternative 7404 // @factory L.point(coords: Object) 7405 // Expects a plain object of the form `{x: Number, y: Number}` instead. 7406 function toPoint(x, y, round) { 7407 if (x instanceof Point) { 7408 return x; 7409 } 7410 if (isArray(x)) { 7411 return new Point(x[0], x[1]); 7412 } 7413 if (x === undefined || x === null) { 7414 return x; 7415 } 7416 if (_typeof$1(x) === 'object' && 'x' in x && 'y' in x) { 7417 return new Point(x.x, x.y); 7418 } 7419 return new Point(x, y, round); 7420 } 7421 7422 /* 7423 * @class Bounds 7424 * @aka L.Bounds 7425 * 7426 * Represents a rectangular area in pixel coordinates. 7427 * 7428 * @example 7429 * 7430 * ```js 7431 * var p1 = L.point(10, 10), 7432 * p2 = L.point(40, 60), 7433 * bounds = L.bounds(p1, p2); 7434 * ``` 7435 * 7436 * 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: 7437 * 7438 * ```js 7439 * otherBounds.intersects([[10, 10], [40, 60]]); 7440 * ``` 7441 * 7442 * Note that `Bounds` does not inherit from Leaflet's `Class` object, 7443 * which means new classes can't inherit from it, and new methods 7444 * can't be added to it with the `include` function. 7445 */ 7446 7447 function Bounds(a, b) { 7448 if (!a) { 7449 return; 7450 } 7451 var points = b ? [a, b] : a; 7452 for (var i = 0, len = points.length; i < len; i++) { 7453 this.extend(points[i]); 7454 } 7455 } 7456 Bounds.prototype = { 7457 // @method extend(point: Point): this 7458 // Extends the bounds to contain the given point. 7459 7460 // @alternative 7461 // @method extend(otherBounds: Bounds): this 7462 // Extend the bounds to contain the given bounds 7463 extend: function extend(obj) { 7464 var min2, max2; 7465 if (!obj) { 7466 return this; 7467 } 7468 if (obj instanceof Point || typeof obj[0] === 'number' || 'x' in obj) { 7469 min2 = max2 = toPoint(obj); 7470 } else { 7471 obj = toBounds(obj); 7472 min2 = obj.min; 7473 max2 = obj.max; 7474 if (!min2 || !max2) { 7475 return this; 7476 } 7477 } 7478 7479 // @property min: Point 7480 // The top left corner of the rectangle. 7481 // @property max: Point 7482 // The bottom right corner of the rectangle. 7483 if (!this.min && !this.max) { 7484 this.min = min2.clone(); 7485 this.max = max2.clone(); 7486 } else { 7487 this.min.x = Math.min(min2.x, this.min.x); 7488 this.max.x = Math.max(max2.x, this.max.x); 7489 this.min.y = Math.min(min2.y, this.min.y); 7490 this.max.y = Math.max(max2.y, this.max.y); 7491 } 7492 return this; 7493 }, 7494 // @method getCenter(round?: Boolean): Point 7495 // Returns the center point of the bounds. 7496 getCenter: function getCenter(round) { 7497 return toPoint((this.min.x + this.max.x) / 2, (this.min.y + this.max.y) / 2, round); 7498 }, 7499 // @method getBottomLeft(): Point 7500 // Returns the bottom-left point of the bounds. 7501 getBottomLeft: function getBottomLeft() { 7502 return toPoint(this.min.x, this.max.y); 7503 }, 7504 // @method getTopRight(): Point 7505 // Returns the top-right point of the bounds. 7506 getTopRight: function getTopRight() { 7507 // -> Point 7508 return toPoint(this.max.x, this.min.y); 7509 }, 7510 // @method getTopLeft(): Point 7511 // Returns the top-left point of the bounds (i.e. [`this.min`](#bounds-min)). 7512 getTopLeft: function getTopLeft() { 7513 return this.min; // left, top 7514 }, 7515 // @method getBottomRight(): Point 7516 // Returns the bottom-right point of the bounds (i.e. [`this.max`](#bounds-max)). 7517 getBottomRight: function getBottomRight() { 7518 return this.max; // right, bottom 7519 }, 7520 // @method getSize(): Point 7521 // Returns the size of the given bounds 7522 getSize: function getSize() { 7523 return this.max.subtract(this.min); 7524 }, 7525 // @method contains(otherBounds: Bounds): Boolean 7526 // Returns `true` if the rectangle contains the given one. 7527 // @alternative 7528 // @method contains(point: Point): Boolean 7529 // Returns `true` if the rectangle contains the given point. 7530 contains: function contains(obj) { 7531 var min, max; 7532 if (typeof obj[0] === 'number' || obj instanceof Point) { 7533 obj = toPoint(obj); 7534 } else { 7535 obj = toBounds(obj); 7536 } 7537 if (obj instanceof Bounds) { 7538 min = obj.min; 7539 max = obj.max; 7540 } else { 7541 min = max = obj; 7542 } 7543 return min.x >= this.min.x && max.x <= this.max.x && min.y >= this.min.y && max.y <= this.max.y; 7544 }, 7545 // @method intersects(otherBounds: Bounds): Boolean 7546 // Returns `true` if the rectangle intersects the given bounds. Two bounds 7547 // intersect if they have at least one point in common. 7548 intersects: function intersects(bounds) { 7549 // (Bounds) -> Boolean 7550 bounds = toBounds(bounds); 7551 var min = this.min, 7552 max = this.max, 7553 min2 = bounds.min,
7554 max2 = bounds.max, 7555 xIntersects = max2.x >= min.x && min2.x <= max.x, 7556 yIntersects = max2.y >= min.y && min2.y <= max.y; 7557 return xIntersects && yIntersects; 7558 }, 7559 // @method overlaps(otherBounds: Bounds): Boolean 7560 // Returns `true` if the rectangle overlaps the given bounds. Two bounds 7561 // overlap if their intersection is an area. 7562 overlaps: function overlaps(bounds) { 7563 // (Bounds) -> Boolean 7564 bounds = toBounds(bounds); 7565 var min = this.min, 7566 max = this.max, 7567 min2 = bounds.min, 7568 max2 = bounds.max, 7569 xOverlaps = max2.x > min.x && min2.x < max.x, 7570 yOverlaps = max2.y > min.y && min2.y < max.y; 7571 return xOverlaps && yOverlaps; 7572 }, 7573 // @method isValid(): Boolean 7574 // Returns `true` if the bounds are properly initialized. 7575 isValid: function isValid() { 7576 return !!(this.min && this.max); 7577 }, 7578 // @method pad(bufferRatio: Number): Bounds 7579 // Returns bounds created by extending or retracting the current bounds by a given ratio in each direction. 7580 // For example, a ratio of 0.5 extends the bounds by 50% in each direction. 7581 // Negative values will retract the bounds. 7582 pad: function pad(bufferRatio) { 7583 var min = this.min, 7584 max = this.max, 7585 heightBuffer = Math.abs(min.x - max.x) * bufferRatio, 7586 widthBuffer = Math.abs(min.y - max.y) * bufferRatio; 7587 return toBounds(toPoint(min.x - heightBuffer, min.y - widthBuffer), toPoint(max.x + heightBuffer, max.y + widthBuffer)); 7588 }, 7589 // @method equals(otherBounds: Bounds): Boolean 7590 // Returns `true` if the rectangle is equivalent to the given bounds. 7591 equals: function equals(bounds) { 7592 if (!bounds) { 7593 return false; 7594 } 7595 bounds = toBounds(bounds); 7596 return this.min.equals(bounds.getTopLeft()) && this.max.equals(bounds.getBottomRight()); 7597 } 7598 }; 7599 7600 // @factory L.bounds(corner1: Point, corner2: Point) 7601 // Creates a Bounds object from two corners coordinate pairs. 7602 // @alternative 7603 // @factory L.bounds(points: Point[]) 7604 // Creates a Bounds object from the given array of points. 7605 function toBounds(a, b) { 7606 if (!a || a instanceof Bounds) { 7607 return a; 7608 } 7609 return new Bounds(a, b); 7610 } 7611 7612 /* 7613 * @class LatLngBounds 7614 * @aka L.LatLngBounds 7615 * 7616 * Represents a rectangular geographical area on a map. 7617 * 7618 * @example 7619 * 7620 * ```js 7621 * var corner1 = L.latLng(40.712, -74.227), 7622 * corner2 = L.latLng(40.774, -74.125), 7623 * bounds = L.latLngBounds(corner1, corner2); 7624 * ``` 7625 * 7626 * 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: 7627 * 7628 * ```js 7629 * map.fitBounds([ 7630 * [40.712, -74.227], 7631 * [40.774, -74.125] 7632 * ]); 7633 * ``` 7634 * 7635 * 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. 7636 * 7637 * Note that `LatLngBounds` does not inherit from Leaflet's `Class` object, 7638 * which means new classes can't inherit from it, and new methods 7639 * can't be added to it with the `include` function. 7640 */ 7641 7642 function LatLngBounds(corner1, corner2) { 7643 // (LatLng, LatLng) or (LatLng[]) 7644 if (!corner1) { 7645 return; 7646 } 7647 var latlngs = corner2 ? [corner1, corner2] : corner1; 7648 for (var i = 0, len = latlngs.length; i < len; i++) { 7649 this.extend(latlngs[i]); 7650 } 7651 } 7652 LatLngBounds.prototype = { 7653 // @method extend(latlng: LatLng): this 7654 // Extend the bounds to contain the given point 7655 7656 // @alternative 7657 // @method extend(otherBounds: LatLngBounds): this 7658 // Extend the bounds to contain the given bounds 7659 extend: function extend(obj) { 7660 var sw = this._southWest, 7661 ne = this._northEast, 7662 sw2, 7663 ne2; 7664 if (obj instanceof LatLng) { 7665 sw2 = obj; 7666 ne2 = obj; 7667 } else if (obj instanceof LatLngBounds) { 7668 sw2 = obj._southWest; 7669 ne2 = obj._northEast; 7670 if (!sw2 || !ne2) { 7671 return this; 7672 } 7673 } else { 7674 return obj ? this.extend(toLatLng(obj) || toLatLngBounds(obj)) : this; 7675 } 7676 if (!sw && !ne) { 7677 this._southWest = new LatLng(sw2.lat, sw2.lng); 7678 this._northEast = new LatLng(ne2.lat, ne2.lng); 7679 } else { 7680 sw.lat = Math.min(sw2.lat, sw.lat); 7681 sw.lng = Math.min(sw2.lng, sw.lng); 7682 ne.lat = Math.max(ne2.lat, ne.lat); 7683 ne.lng = Math.max(ne2.lng, ne.lng); 7684 } 7685 return this; 7686 }, 7687 // @method pad(bufferRatio: Number): LatLngBounds 7688 // Returns bounds created by extending or retracting the current bounds by a given ratio in each direction. 7689 // For example, a ratio of 0.5 extends the bounds by 50% in each direction. 7690 // Negative values will retract the bounds. 7691 pad: function pad(bufferRatio) { 7692 var sw = this._southWest, 7693 ne = this._northEast, 7694 heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio, 7695 widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio;
7696 return new LatLngBounds(new LatLng(sw.lat - heightBuffer, sw.lng - widthBuffer), new LatLng(ne.lat + heightBuffer, ne.lng + widthBuffer)); 7697 }, 7698 // @method getCenter(): LatLng 7699 // Returns the center point of the bounds. 7700 getCenter: function getCenter() { 7701 return new LatLng((this._southWest.lat + this._northEast.lat) / 2, (this._southWest.lng + this._northEast.lng) / 2); 7702 }, 7703 // @method getSouthWest(): LatLng 7704 // Returns the south-west point of the bounds. 7705 getSouthWest: function getSouthWest() { 7706 return this._southWest; 7707 }, 7708 // @method getNorthEast(): LatLng 7709 // Returns the north-east point of the bounds. 7710 getNorthEast: function getNorthEast() { 7711 return this._northEast; 7712 }, 7713 // @method getNorthWest(): LatLng 7714 // Returns the north-west point of the bounds. 7715 getNorthWest: function getNorthWest() { 7716 return new LatLng(this.getNorth(), this.getWest()); 7717 }, 7718 // @method getSouthEast(): LatLng 7719 // Returns the south-east point of the bounds. 7720 getSouthEast: function getSouthEast() { 7721 return new LatLng(this.getSouth(), this.getEast()); 7722 }, 7723 // @method getWest(): Number 7724 // Returns the west longitude of the bounds 7725 getWest: function getWest() { 7726 return this._southWest.lng; 7727 }, 7728 // @method getSouth(): Number 7729 // Returns the south latitude of the bounds 7730 getSouth: function getSouth() { 7731 return this._southWest.lat; 7732 }, 7733 // @method getEast(): Number 7734 // Returns the east longitude of the bounds 7735 getEast: function getEast() { 7736 return this._northEast.lng; 7737 }, 7738 // @method getNorth(): Number 7739 // Returns the north latitude of the bounds 7740 getNorth: function getNorth() { 7741 return this._northEast.lat; 7742 }, 7743 // @method contains(otherBounds: LatLngBounds): Boolean 7744 // Returns `true` if the rectangle contains the given one. 7745 7746 // @alternative 7747 // @method contains (latlng: LatLng): Boolean 7748 // Returns `true` if the rectangle contains the given point. 7749 contains: function contains(obj) { 7750 // (LatLngBounds) or (LatLng) -> Boolean 7751 if (typeof obj[0] === 'number' || obj instanceof LatLng || 'lat' in obj) { 7752 obj = toLatLng(obj); 7753 } else { 7754 obj = toLatLngBounds(obj); 7755 } 7756 var sw = this._southWest, 7757 ne = this._northEast, 7758 sw2, 7759 ne2; 7760 if (obj instanceof LatLngBounds) {
7761 sw2 = obj.getSouthWest(); 7762 ne2 = obj.getNorthEast(); 7763 } else { 7764 sw2 = ne2 = obj; 7765 } 7766 return sw2.lat >= sw.lat && ne2.lat <= ne.lat && sw2.lng >= sw.lng && ne2.lng <= ne.lng; 7767 }, 7768 // @method intersects(otherBounds: LatLngBounds): Boolean 7769 // Returns `true` if the rectangle intersects the given bounds. Two bounds intersect if they have at least one point in common. 7770 intersects: function intersects(bounds) { 7771 bounds = toLatLngBounds(bounds); 7772 var sw = this._southWest, 7773 ne = this._northEast, 7774 sw2 = bounds.getSouthWest(), 7775 ne2 = bounds.getNorthEast(), 7776 latIntersects = ne2.lat >= sw.lat && sw2.lat <= ne.lat, 7777 lngIntersects = ne2.lng >= sw.lng && sw2.lng <= ne.lng; 7778 return latIntersects && lngIntersects; 7779 }, 7780 // @method overlaps(otherBounds: LatLngBounds): Boolean 7781 // Returns `true` if the rectangle overlaps the given bounds. Two bounds overlap if their intersection is an area. 7782 overlaps: function overlaps(bounds) { 7783 bounds = toLatLngBounds(bounds); 7784 var sw = this._southWest, 7785 ne = this._northEast,
7786 sw2 = bounds.getSouthWest(), 7787 ne2 = bounds.getNorthEast(), 7788 latOverlaps = ne2.lat > sw.lat && sw2.lat < ne.lat, 7789 lngOverlaps = ne2.lng > sw.lng && sw2.lng < ne.lng; 7790 return latOverlaps && lngOverlaps; 7791 }, 7792 // @method toBBoxString(): String 7793 // 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. 7794 toBBoxString: function toBBoxString() { 7795 return [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()].join(','); 7796 }, 7797 // @method equals(otherBounds: LatLngBounds, maxMargin?: Number): Boolean 7798 // 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. 7799 equals: function equals(bounds, maxMargin) { 7800 if (!bounds) { 7801 return false; 7802 } 7803 bounds = toLatLngBounds(bounds);
7804 return this._southWest.equals(bounds.getSouthWest(), maxMargin) && this._northEast.equals(bounds.getNorthEast(), maxMargin); 7805 }, 7806 // @method isValid(): Boolean 7807 // Returns `true` if the bounds are properly initialized. 7808 isValid: function isValid() { 7809 return !!(this._southWest && this._northEast); 7810 } 7811 }; 7812 7813 // TODO International date line? 7814 7815 // @factory L.latLngBounds(corner1: LatLng, corner2: LatLng) 7816 // Creates a `LatLngBounds` object by defining two diagonally opposite corners of the rectangle. 7817 7818 // @alternative 7819 // @factory L.latLngBounds(latlngs: LatLng[]) 7820 // 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). 7821 function toLatLngBounds(a, b) { 7822 if (a instanceof LatLngBounds) { 7823 return a; 7824 } 7825 return new LatLngBounds(a, b); 7826 } 7827 7828 /* @class LatLng 7829 * @aka L.LatLng 7830 * 7831 * Represents a geographical point with a certain latitude and longitude. 7832 * 7833 * @example 7834 * 7835 * ``` 7836 * var latlng = L.latLng(50.5, 30.5); 7837 * ``` 7838 * 7839 * 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: 7840 * 7841 * ``` 7842 * map.panTo([50, 30]); 7843 * map.panTo({lon: 30, lat: 50}); 7844 * map.panTo({lat: 50, lng: 30}); 7845 * map.panTo(L.latLng(50, 30)); 7846 * ``` 7847 * 7848 * Note that `LatLng` does not inherit from Leaflet's `Class` object, 7849 * which means new classes can't inherit from it, and new methods 7850 * can't be added to it with the `include` function. 7851 */ 7852 7853 function LatLng(lat, lng, alt) { 7854 if (isNaN(lat) || isNaN(lng)) { 7855 throw new Error('Invalid LatLng object: (' + lat + ', ' + lng + ')'); 7856 } 7857 7858 // @property lat: Number 7859 // Latitude in degrees 7860 this.lat = +lat; 7861 7862 // @property lng: Number 7863 // Longitude in degrees 7864 this.lng = +lng; 7865 7866 // @property alt: Number 7867 // Altitude in meters (optional) 7868 if (alt !== undefined) { 7869 this.alt = +alt; 7870 } 7871 } 7872 LatLng.prototype = { 7873 // @method equals(otherLatLng: LatLng, maxMargin?: Number): Boolean 7874 // 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. 7875 equals: function equals(obj, maxMargin) { 7876 if (!obj) { 7877 return false; 7878 } 7879 obj = toLatLng(obj); 7880 var margin = Math.max(Math.abs(this.lat - obj.lat), Math.abs(this.lng - obj.lng)); 7881 return margin <= (maxMargin === undefined ? 1.0E-9 : maxMargin); 7882 }, 7883 // @method toString(): String 7884 // Returns a string representation of the point (for debugging purposes). 7885 toString: function toString(precision) { 7886 return 'LatLng(' + formatNum(this.lat, precision) + ', ' + formatNum(this.lng, precision) + ')'; 7887 }, 7888 // @method distanceTo(otherLatLng: LatLng): Number 7889 // 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). 7890 distanceTo: function distanceTo(other) { 7891 return Earth.distance(this, toLatLng(other)); 7892 }, 7893 // @method wrap(): LatLng 7894 // Returns a new `LatLng` object with the longitude wrapped so it's always between -180 and +180 degrees. 7895 wrap: function wrap() { 7896 return Earth.wrapLatLng(this); 7897 }, 7898 // @method toBounds(sizeInMeters: Number): LatLngBounds 7899 // Returns a new `LatLngBounds` object in which each boundary is `sizeInMeters/2` meters apart from the `LatLng`. 7900 toBounds: function toBounds(sizeInMeters) { 7901 var latAccuracy = 180 * sizeInMeters / 40075017, 7902 lngAccuracy = latAccuracy / Math.cos(Math.PI / 180 * this.lat); 7903 return toLatLngBounds([this.lat - latAccuracy, this.lng - lngAccuracy], [this.lat + latAccuracy, this.lng + lngAccuracy]); 7904 }, 7905 clone: function clone() {
7906 return new LatLng(this.lat, this.lng, this.alt); 7907 } 7908 }; 7909 7910 // @factory L.latLng(latitude: Number, longitude: Number, altitude?: Number): LatLng 7911 // Creates an object representing a geographical point with the given latitude and longitude (and optionally altitude). 7912 7913 // @alternative 7914 // @factory L.latLng(coords: Array): LatLng 7915 // Expects an array of the form `[Number, Number]` or `[Number, Number, Number]` instead. 7916 7917 // @alternative 7918 // @factory L.latLng(coords: Object): LatLng 7919 // Expects an plain object of the form `{lat: Number, lng: Number}` or `{lat: Number, lng: Number, alt: Number}` instead. 7920 7921 function toLatLng(a, b, c) { 7922 if (a instanceof LatLng) { 7923 return a; 7924 } 7925 if (isArray(a) && _typeof$1(a[0]) !== 'object') { 7926 if (a.length === 3) { 7927 return new LatLng(a[0], a[1], a[2]); 7928 } 7929 if (a.length === 2) { 7930 return new LatLng(a[0], a[1]); 7931 } 7932 return null; 7933 } 7934 if (a === undefined || a === null) { 7935 return a; 7936 } 7937 if (_typeof$1(a) === 'object' && 'lat' in a) { 7938 return new LatLng(a.lat, 'lng' in a ? a.lng : a.lon, a.alt); 7939 } 7940 if (b === undefined) { 7941 return null; 7942 } 7943 return new LatLng(a, b, c); 7944 } 7945 7946 /* 7947 * @namespace CRS 7948 * @crs L.CRS.Base 7949 * Object that defines coordinate reference systems for projecting 7950 * geographical points into pixel (screen) coordinates and back (and to
7951 * coordinates in other units for [WMS](https://en.wikipedia.org/wiki/Web_Map_Service) services). See 7952 * [spatial reference system](https://en.wikipedia.org/wiki/Spatial_reference_system). 7953 * 7954 * Leaflet defines the most usual CRSs by default. If you want to use a 7955 * CRS not defined by default, take a look at the 7956 * [Proj4Leaflet](https://github.com/kartena/Proj4Leaflet) plugin. 7957 * 7958 * Note that the CRS instances do not inherit from Leaflet's `Class` object, 7959 * and can't be instantiated. Also, new classes can't inherit from them, 7960 * and methods can't be added to them with the `include` function. 7961 */ 7962 7963 var CRS = { 7964 // @method latLngToPoint(latlng: LatLng, zoom: Number): Point 7965 // Projects geographical coordinates into pixel coordinates for a given zoom. 7966 latLngToPoint: function latLngToPoint(latlng, zoom) { 7967 var projectedPoint = this.projection.project(latlng), 7968 scale = this.scale(zoom); 7969 return this.transformation._transform(projectedPoint, scale); 7970 }, 7971 // @method pointToLatLng(point: Point, zoom: Number): LatLng 7972 // The inverse of `latLngToPoint`. Projects pixel coordinates on a given 7973 // zoom into geographical coordinates. 7974 pointToLatLng: function pointToLatLng(point, zoom) { 7975 var scale = this.scale(zoom), 7976 untransformedPoint = this.transformation.untransform(point, scale); 7977 return this.projection.unproject(untransformedPoint); 7978 }, 7979 // @method project(latlng: LatLng): Point 7980 // Projects geographical coordinates into coordinates in units accepted for 7981 // this CRS (e.g. meters for EPSG:3857, for passing it to WMS services). 7982 project: function project(latlng) { 7983 return this.projection.project(latlng); 7984 }, 7985 // @method unproject(point: Point): LatLng 7986 // Given a projected coordinate returns the corresponding LatLng. 7987 // The inverse of `project`. 7988 unproject: function unproject(point) { 7989 return this.projection.unproject(point); 7990 }, 7991 // @method scale(zoom: Number): Number 7992 // Returns the scale used when transforming projected coordinates into 7993 // pixel coordinates for a particular zoom. For example, it returns 7994 // `256 * 2^zoom` for Mercator-based CRS. 7995 scale: function scale(zoom) { 7996 return 256 * Math.pow(2, zoom); 7997 }, 7998 // @method zoom(scale: Number): Number 7999 // Inverse of `scale()`, returns the zoom level corresponding to a scale 8000 // factor of `scale`. 8001 zoom: function zoom(scale) { 8002 return Math.log(scale / 256) / Math.LN2; 8003 }, 8004 // @method getProjectedBounds(zoom: Number): Bounds 8005 // Returns the projection's bounds scaled and transformed for the provided `zoom`. 8006 getProjectedBounds: function getProjectedBounds(zoom) { 8007 if (this.infinite) { 8008 return null; 8009 } 8010 var b = this.projection.bounds, 8011 s = this.scale(zoom), 8012 min = this.transformation.transform(b.min, s), 8013 max = this.transformation.transform(b.max, s); 8014 return new Bounds(min, max); 8015 }, 8016 // @method distance(latlng1: LatLng, latlng2: LatLng): Number 8017 // Returns the distance between two geographical coordinates. 8018 8019 // @property code: String 8020 // Standard code name of the CRS passed into WMS services (e.g. `'EPSG:3857'`) 8021 // 8022 // @property wrapLng: Number[] 8023 // An array of two numbers defining whether the longitude (horizontal) coordinate 8024 // axis wraps around a given range and how. Defaults to `[-180, 180]` in most 8025 // geographical CRSs. If `undefined`, the longitude axis does not wrap around. 8026 // 8027 // @property wrapLat: Number[] 8028 // Like `wrapLng`, but for the latitude (vertical) axis. 8029 8030 // wrapLng: [min, max], 8031 // wrapLat: [min, max], 8032 8033 // @property infinite: Boolean 8034 // If true, the coordinate space will be unbounded (infinite in both axes) 8035 infinite: false, 8036 // @method wrapLatLng(latlng: LatLng): LatLng 8037 // Returns a `LatLng` where lat and lng has been wrapped according to the 8038 // CRS's `wrapLat` and `wrapLng` properties, if they are outside the CRS's bounds. 8039 wrapLatLng: function wrapLatLng(latlng) { 8040 var lng = this.wrapLng ? wrapNum(latlng.lng, this.wrapLng, true) : latlng.lng, 8041 lat = this.wrapLat ? wrapNum(latlng.lat, this.wrapLat, true) : latlng.lat, 8042 alt = latlng.alt;
8043 return new LatLng(lat, lng, alt); 8044 }, 8045 // @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds 8046 // Returns a `LatLngBounds` with the same size as the given one, ensuring 8047 // that its center is within the CRS's bounds. 8048 // Only accepts actual `L.LatLngBounds` instances, not arrays. 8049 wrapLatLngBounds: function wrapLatLngBounds(bounds) { 8050 var center = bounds.getCenter(), 8051 newCenter = this.wrapLatLng(center), 8052 latShift = center.lat - newCenter.lat, 8053 lngShift = center.lng - newCenter.lng; 8054 if (latShift === 0 && lngShift === 0) { 8055 return bounds; 8056 } 8057 var sw = bounds.getSouthWest(), 8058 ne = bounds.getNorthEast(), 8059 newSw = new LatLng(sw.lat - latShift, sw.lng - lngShift), 8060 newNe = new LatLng(ne.lat - latShift, ne.lng - lngShift); 8061 return new LatLngBounds(newSw, newNe); 8062 } 8063 }; 8064 8065 /* 8066 * @namespace CRS 8067 * @crs L.CRS.Earth 8068 * 8069 * Serves as the base for CRS that are global such that they cover the earth. 8070 * Can only be used as the base for other CRS and cannot be used directly, 8071 * since it does not have a `code`, `projection` or `transformation`. `distance()` returns 8072 * meters. 8073 */ 8074 8075 var Earth = extend({}, CRS, { 8076 wrapLng: [-180, 180], 8077 // Mean Earth Radius, as recommended for use by 8078 // the International Union of Geodesy and Geophysics, 8079 // see https://rosettacode.org/wiki/Haversine_formula 8080 R: 6371000, 8081 // distance between two geographical points using spherical law of cosines approximation 8082 distance: function distance(latlng1, latlng2) { 8083 var rad = Math.PI / 180, 8084 lat1 = latlng1.lat * rad, 8085 lat2 = latlng2.lat * rad, 8086 sinDLat = Math.sin((latlng2.lat - latlng1.lat) * rad / 2), 8087 sinDLon = Math.sin((latlng2.lng - latlng1.lng) * rad / 2), 8088 a = sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon, 8089 c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 8090 return this.R * c; 8091 } 8092 }); 8093 8094 /* 8095 * @namespace Projection 8096 * @projection L.Projection.SphericalMercator 8097 * 8098 * Spherical Mercator projection â the most common projection for online maps, 8099 * used by almost all free and commercial tile providers. Assumes that Earth is 8100 * a sphere. Used by the `EPSG:3857` CRS. 8101 */ 8102 8103 var earthRadius = 6378137; 8104 var SphericalMercator = { 8105 R: earthRadius, 8106 MAX_LATITUDE: 85.0511287798, 8107 project: function project(latlng) { 8108 var d = Math.PI / 180, 8109 max = this.MAX_LATITUDE, 8110 lat = Math.max(Math.min(max, latlng.lat), -max), 8111 sin = Math.sin(lat * d); 8112 return new Point(this.R * latlng.lng * d, this.R * Math.log((1 + sin) / (1 - sin)) / 2); 8113 }, 8114 unproject: function unproject(point) { 8115 var d = 180 / Math.PI; 8116 return new LatLng((2 * Math.atan(Math.exp(point.y / this.R)) - Math.PI / 2) * d, point.x * d / this.R); 8117 }, 8118 bounds: function () { 8119 var d = earthRadius * Math.PI; 8120 return new Bounds([-d, -d], [d, d]); 8121 }() 8122 }; 8123 8124 /* 8125 * @class Transformation 8126 * @aka L.Transformation 8127 * 8128 * Represents an affine transformation: a set of coefficients `a`, `b`, `c`, `d` 8129 * for transforming a point of a form `(x, y)` into `(a*x + b, c*y + d)` and doing 8130 * the reverse. Used by Leaflet in its projections code. 8131 * 8132 * @example 8133 * 8134 * ```js 8135 * var transformation = L.transformation(2, 5, -1, 10), 8136 * p = L.point(1, 2), 8137 * p2 = transformation.transform(p), // L.point(7, 8) 8138 * p3 = transformation.untransform(p2); // L.point(1, 2) 8139 * ``` 8140 */ 8141 8142 // factory new L.Transformation(a: Number, b: Number, c: Number, d: Number) 8143 // Creates a `Transformation` object with the given coefficients. 8144 function Transformation(a, b, c, d) { 8145 if (isArray(a)) { 8146 // use array properties 8147 this._a = a[0]; 8148 this._b = a[1]; 8149 this._c = a[2]; 8150 this._d = a[3]; 8151 return; 8152 } 8153 this._a = a; 8154 this._b = b; 8155 this._c = c; 8156 this._d = d; 8157 } 8158 Transformation.prototype = { 8159 // @method transform(point: Point, scale?: Number): Point 8160 // Returns a transformed point, optionally multiplied by the given scale. 8161 // Only accepts actual `L.Point` instances, not arrays. 8162 transform: function transform(point, scale) { 8163 // (Point, Number) -> Point 8164 return this._transform(point.clone(), scale); 8165 }, 8166 // destructive transform (faster) 8167 _transform: function _transform(point, scale) { 8168 scale = scale || 1; 8169 point.x = scale * (this._a * point.x + this._b); 8170 point.y = scale * (this._c * point.y + this._d); 8171 return point; 8172 }, 8173 // @method untransform(point: Point, scale?: Number): Point 8174 // Returns the reverse transformation of the given point, optionally divi
vendor: 5,571 bytes, lines 8174-8316
8174ded 8175 // by the given scale. Only accepts actual `L.Point` instances, not arrays. 8176 untransform: function untransform(point, scale) { 8177 scale = scale || 1; 8178 return new Point((point.x / scale - this._b) / this._a, (point.y / scale - this._d) / this._c); 8179 } 8180 }; 8181 8182 // factory L.transformation(a: Number, b: Number, c: Number, d: Number) 8183 8184 // @factory L.transformation(a: Number, b: Number, c: Number, d: Number) 8185 // Instantiates a Transformation object with the given coefficients. 8186 8187 // @alternative 8188 // @factory L.transformation(coefficients: Array): Transformation 8189 // Expects an coefficients array of the form 8190 // `[a: Number, b: Number, c: Number, d: Number]`. 8191 8192 function toTransformation(a, b, c, d) { 8193 return new Transformation(a, b, c, d); 8194 } 8195 8196 /* 8197 * @namespace CRS 8198 * @crs L.CRS.EPSG3857 8199 * 8200 * The most common CRS for online maps, used by almost all free and commercial 8201 * tile providers. Uses Spherical Mercator projection. Set in by default in 8202 * Map's `crs` option. 8203 */ 8204 8205 var EPSG3857 = extend({}, Earth, { 8206 code: 'EPSG:3857', 8207 projection: SphericalMercator, 8208 transformation: function () { 8209 var scale = 0.5 / (Math.PI * SphericalMercator.R); 8210 return toTransformation(scale, 0.5, -scale, 0.5); 8211 }() 8212 }); 8213 var EPSG900913 = extend({}, EPSG3857, { 8214 code: 'EPSG:900913' 8215 }); 8216 8217 // @namespace SVG; @section 8218 // There are several static functions which can be called without instantiating L.SVG: 8219 8220 // @function create(name: String): SVGElement 8221 // Returns a instance of [SVGElement](https://developer.mozilla.org/docs/Web/API/SVGElement), 8222 // corresponding to the class name passed. For example, using 'line' will return 8223 // an instance of [SVGLineElement](https://developer.mozilla.org/docs/Web/API/SVGLineElement). 8224 function svgCreate(name) { 8225 return document.createElementNS('http://www.w3.org/2000/svg', name); 8226 } 8227 8228 // @function pointsToPath(rings: Point[], closed: Boolean): String 8229 // Generates a SVG path string for multiple rings, with each ring turning 8230 // into "M..L..L.." instructions 8231 function pointsToPath(rings, closed) { 8232 var str = '', 8233 i, 8234 j, 8235 len, 8236 len2, 8237 points, 8238 p; 8239 for (i = 0, len = rings.length; i < len; i++) { 8240 points = rings[i]; 8241 for (j = 0, len2 = points.length; j < len2; j++) { 8242 p = points[j]; 8243 str += (j ? 'L' : 'M') + p.x + ' ' + p.y; 8244 } 8245 8246 // closes the ring for polygons; "x" is VML syntax 8247 str += closed ? Browser.svg ? 'z' : 'x' : ''; 8248 } 8249 8250 // SVG complains about empty path strings 8251 return str || 'M0 0'; 8252 } 8253 8254 /* 8255 * @namespace Browser 8256 * @aka L.Browser 8257 * 8258 * A namespace with static properties for browser/feature detection used by Leaflet internally. 8259 * 8260 * @example 8261 * 8262 * ```js 8263 * if (L.Browser.ielt9) { 8264 * alert('Upgrade your browser, dude!'); 8265 * } 8266 * ``` 8267 */ 8268 8269 var style = document.documentElement.style; 8270 8271 // @property ie: Boolean; `true` for all Internet Explorer versions (not Edge). 8272 var ie = 'ActiveXObject' in window; 8273 8274 // @property ielt9: Boolean; `true` for Internet Explorer versions less than 9. 8275 var ielt9 = ie && !document.addEventListener; 8276 8277 // @property edge: Boolean; `true` for the Edge web browser. 8278 var edge = 'msLaunchUri' in navigator && !('documentMode' in document); 8279 8280 // @property webkit: Boolean; 8281 // `true` for webkit-based browsers like Chrome and Safari (including mobile versions). 8282 var webkit = userAgentContains('webkit'); 8283 8284 // @property android: Boolean 8285 // **Deprecated.** `true` for any browser running on an Android platform. 8286 var android = userAgentContains('android'); 8287 8288 // @property android23: Boolean; **Deprecated.** `true` for browsers running on Android 2 or Android 3. 8289 var android23 = userAgentContains('android 2') || userAgentContains('android 3'); 8290 8291 /* See https://stackoverflow.com/a/17961266 for details on detecting stock Android */ 8292 var webkitVer = parseInt(/WebKit\/([0-9]+)|$/.exec(navigator.userAgent)[1], 10); // also matches AppleWebKit 8293 // @property androidStock: Boolean; **Deprecated.** `true` for the Android stock browser (i.e. not Chrome) 8294 var androidStock = android && userAgentContains('Google') && webkitVer < 537 && !('AudioNode' in window); 8295 8296 // @property opera: Boolean; `true` for the Opera browser 8297 var opera = !!window.opera; 8298 8299 // @property chrome: Boolean; `true` for the Chrome browser. 8300 var chrome = !edge && userAgentContains('chrome'); 8301 8302 // @property gecko: Boolean; `true` for gecko-based browsers like Firefox. 8303 var gecko = userAgentContains('gecko') && !webkit && !opera && !ie; 8304 8305 // @property safari: Boolean; `true` for the Safari browser. 8306 var safari = !chrome && userAgentContains('safari'); 8307 var phantom = userAgentContains('phantom'); 8308 8309 // @property opera12: Boolean 8310 // `true` for the Opera browser supporting CSS transforms (version 12 or later). 8311 var opera12 = 'OTransition' in style; 8312 8313 // @property win: Boolean; `true` when the browser is running in a Windows platform 8314 var win = navigator.platform.indexOf('Win') === 0; 8315 8316 // @property ie3d: Boolean;
8316 `true` for all Internet Explorer versions supporting CSS transforms. 8317 var ie3d = ie && 'transition' in style; 8318 8319 // @property webkit3d: Boolean; `true` for webkit-based browsers supporting CSS transforms. 8320 var webkit3d = 'WebKitCSSMatrix' in window && 'm11' in new window.WebKitCSSMatrix() && !android23; 8321 8322 // @property gecko3d: Boolean; `true` for gecko-based browsers supporting CSS transforms. 8323 var gecko3d = 'MozPerspective' in style; 8324 8325 // @property any3d: Boolean 8326 // `true` for all browsers supporting CSS transforms. 8327 var any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d) && !opera12 && !phantom; 8328 8329 // @property mobile: Boolean; `true` for all browsers running in a mobile device. 8330 var mobile = typeof orientation !== 'undefined' || userAgentContains('mobile'); 8331 8332 // @property mobileWebkit: Boolean; `true` for all webkit-based browsers in a mobile device. 8333 var mobileWebkit = mobile && webkit; 8334 8335 // @property mobileWebkit3d: Boolean 8336 // `true` for all webkit-based browsers in a mobile device supporting CSS transforms. 8337 var mobileWebkit3d = mobile && webkit3d; 8338 8339 // @property msPointer: Boolean 8340 // `true` for browsers implementing the Microsoft touch events model (notably IE10). 8341 var msPointer = !window.PointerEvent && window.MSPointerEvent; 8342 8343 // @property pointer: Boolean 8344 // `true` for all browsers supporting [pointer events](https://msdn.microsoft.com/en-us/library/dn433244%28v=vs.85%29.aspx). 8345 var pointer = !!(window.PointerEvent || msPointer); 8346 8347 // @property touchNative: Boolean 8348 // `true` for all browsers supporting [touch events](https://developer.mozilla.org/docs/Web/API/Touch_events). 8349 // **This does not necessarily mean** that the browser is running in a computer with 8350 // a touchscreen, it only means that the browser is capable of understanding 8351 // touch events. 8352 var touchNative = 'ontouchstart' in window || !!window.TouchEvent; 8353 8354 // @property touch: Boolean 8355 // `true` for all browsers supporting either [touch](#browser-touch) or [pointer](#browser-pointer) events. 8356 // Note: pointer events will be preferred (if available), and processed for all `touch*` listeners. 8357 var touch = !window.L_NO_TOUCH && (touchNative || pointer); 8358 8359 // @property mobileOpera: Boolean; `true` for the Opera browser in a mobile device. 8360 var mobileOpera = mobile && opera; 8361 8362 // @property mobileGecko: Boolean 8363 // `true` for gecko-based browsers running in a mobile device. 8364 var mobileGecko = mobile && gecko; 8365 8366 // @property retina: Boolean 8367 // `true` for browsers on a high-resolution "retina" screen or on any screen when browser's display zoom is more than 100%. 8368 var retina = (window.devicePixelRatio || window.screen.deviceXDPI / window.screen.logicalXDPI) > 1; 8369 8370 // @property passiveEvents: Boolean 8371 // `true` for browsers that support passive events. 8372 var passiveEvents = function () { 8373 var supportsPassiveOption = false; 8374 try { 8375 var opts = Object.defineProperty({}, 'passive', { 8376 get: function get() { 8377 // eslint-disable-line getter-return 8378 supportsPassiveOption = true; 8379 } 8380 }); 8381 window.addEventListener('testPassiveEventSupport', falseFn, opts); 8382 window.removeEventListener('testPassiveEventSupport', falseFn, opts); 8383 } catch (e) { 8384 // Errors can safely be ignored since this is only a browser support test. 8385 } 8386 return supportsPassiveOption; 8387 }(); 8388 8389 // @property canvas: Boolean 8390 // `true` when the browser supports [`<canvas>`](https://developer.mozilla.org/docs/Web/API/Canvas_API). 8391 var canvas$1 = function () { 8392 return !!document.createElement('canvas').getContext; 8393 }(); 8394 8395 // @property svg: Boolean 8396 // `true` when the browser supports [SVG](https://developer.mozilla.org/docs/Web/SVG). 8397 var svg$1 = !!(document.createElementNS && svgCreate('svg').createSVGRect); 8398 var inlineSvg = !!svg$1 && function () { 8399 var div = document.createElement('div'); 8400 div.innerHTML = '<svg/>'; 8401 return (div.firstChild && div.firstChild.namespaceURI) === 'http://www.w3.org/2000/svg'; 8402 }(); 8403 8404 // @property vml: Boolean 8405 // `true` if the browser supports [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language). 8406 var vml = !svg$1 && function () { 8407 try { 8408 var div = document.createElement('div');
8409 div.innerHTML = '<v:shape adj="1"/>'; 8410 var shape = div.firstChild; 8411 shape.style.behavior = 'url(#default#VML)'; 8412 return shape && _typeof$1(shape.adj) === 'object'; 8413 } catch (e) { 8414 return false; 8415 } 8416 }(); 8417 8418 // @property mac: Boolean; `true` when the browser is running in a Mac platform 8419 var mac = navigator.platform.indexOf('Mac') === 0; 8420 8421 // @property mac: Boolean; `true` when the browser is running in a Linux platform 8422 var linux = navigator.platform.indexOf('Linux') === 0; 8423 function userAgentContains(str) { 8424 return navigator.userAgent.toLowerCase().indexOf(str) >= 0; 8425 } 8426 var Browser = { 8427 ie: ie, 8428 ielt9: ielt9, 8429 edge: edge, 8430 webkit: webkit, 8431 android: android, 8432 android23: android23, 8433 androidStock: androidStock, 8434 opera: opera, 8435 chrome: chrome, 8436 gecko: gecko, 8437 safari: safari, 8438 phantom: phantom, 8439 opera12: opera12, 8440 win: win, 8441 ie3d: ie3d, 8442 webkit3d: webkit3d, 8443 gecko3d: gecko3d, 8444 any3d: any3d, 8445 mobile: mobile, 8446 mobileWebkit: mobileWebkit, 8447 mobileWebkit3d: mobileWebkit3d, 8448 msPointer: msPointer, 8449 pointer: pointer, 8450 touch: touch, 8451 touchNative: touchNative, 8452 mobileOpera: mobileOpera, 8453 mobileGecko: mobileGecko, 8454 retina: retina, 8455 passiveEvents: passiveEvents, 8456 canvas: canvas$1, 8457 svg: svg$1, 8458 vml: vml, 8459 inlineSvg: inlineSvg, 8460 mac: mac, 8461 linux: linux 8462 }; 8463 8464 /* 8465 * Extends L.DomEvent to provide touch support for Internet Explorer and Windows-based devices. 8466 */ 8467 8468 var POINTER_DOWN = Browser.msPointer ? 'MSPointerDown' : 'pointerdown'; 8469 var POINTER_MOVE = Browser.msPointer ? 'MSPointerMove' : 'pointermove'; 8470 var POINTER_UP = Browser.msPointer ? 'MSPointerUp' : 'pointerup'; 8471 var POINTER_CANCEL = Browser.msPointer ? 'MSPointerCancel' : 'pointercancel'; 8472 var pEvent = { 8473 touchstart: POINTER_DOWN, 8474 touchmove: POINTER_MOVE, 8475 touchend: POINTER_UP, 8476 touchcancel: POINTER_CANCEL 8477 }; 8478 var handle = { 8479 touchstart: _onPointerStart, 8480 touchmove: _handlePointer, 8481 touchend: _handlePointer, 8482 touchcancel: _handlePointer 8483 }; 8484 var _pointers = {}; 8485 var _pointerDocListener = false;
vendor: 28,128 bytes, lines 8486-9206
8486 8487 // Provides a touch events wrapper for (ms)pointer events. 8488 // ref https://www.w3.org/TR/pointerevents/ https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890 8489 8490 function addPointerListener(obj, type, handler) { 8491 if (type === 'touchstart') { 8492 _addPointerDocListener(); 8493 } 8494 if (!handle[type]) { 8495 console.warn('wrong event specified:', type); 8496 return falseFn; 8497 } 8498 handler = handle[type].bind(this, handler); 8499 obj.addEventListener(pEvent[type], handler, false); 8500 return handler; 8501 } 8502 function removePointerListener(obj, type, handler) { 8503 if (!pEvent[type]) { 8504 console.warn('wrong event specified:', type); 8505 return; 8506 } 8507 obj.removeEventListener(pEvent[type], handler, false); 8508 } 8509 function _globalPointerDown(e) { 8510 _pointers[e.pointerId] = e; 8511 } 8512 function _globalPointerMove(e) { 8513 if (_pointers[e.pointerId]) { 8514 _pointers[e.pointerId] = e; 8515 } 8516 } 8517 function _globalPointerUp(e) { 8518 delete _pointers[e.pointerId]; 8519 } 8520 function _addPointerDocListener() { 8521 // need to keep track of what pointers and how many are active to provide e.touches emulation 8522 if (!_pointerDocListener) { 8523 // we listen document as any drags that end by moving the touch off the screen get fired there 8524 document.addEventListener(POINTER_DOWN, _globalPointerDown, true); 8525 document.addEventListener(POINTER_MOVE, _globalPointerMove, true); 8526 document.addEventListener(POINTER_UP, _globalPointerUp, true); 8527 document.addEventListener(POINTER_CANCEL, _globalPointerUp, true); 8528 _pointerDocListener = true; 8529 } 8530 } 8531 function _handlePointer(handler, e) { 8532 if (e.pointerType === (e.MSPOINTER_TYPE_MOUSE || 'mouse')) { 8533 return; 8534 } 8535 e.touches = []; 8536 for (var i in _pointers) { 8537 e.touches.push(_pointers[i]); 8538 } 8539 e.changedTouches = [e]; 8540 handler(e); 8541 } 8542 function _onPointerStart(handler, e) { 8543 // IE10 specific: MsTouch needs preventDefault. See #2000 8544 if (e.MSPOINTER_TYPE_TOUCH && e.pointerType === e.MSPOINTER_TYPE_TOUCH) { 8545 preventDefault(e); 8546 } 8547 _handlePointer(handler, e); 8548 } 8549 8550 /* 8551 * Extends the event handling code with double tap support for mobile browsers. 8552 * 8553 * Note: currently most browsers fire native dblclick, with only a few exceptions 8554 * (see https://github.com/Leaflet/Leaflet/issues/7012#issuecomment-595087386) 8555 */ 8556 8557 function makeDblclick(event) { 8558 // in modern browsers `type` cannot be just overridden: 8559 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only 8560 var newEvent = {}, 8561 prop, 8562 i; 8563 for (i in event) { 8564 prop = event[i]; 8565 newEvent[i] = prop && prop.bind ? prop.bind(event) : prop; 8566 } 8567 event = newEvent; 8568 newEvent.type = 'dblclick'; 8569 newEvent.detail = 2; 8570 newEvent.isTrusted = false; 8571 newEvent._simulated = true; // for debug purposes 8572 return newEvent; 8573 } 8574 var delay = 200; 8575 function addDoubleTapListener(obj, handler) { 8576 // Most browsers handle double tap natively 8577 obj.addEventListener('dblclick', handler); 8578 8579 // On some platforms the browser doesn't fire native dblclicks for touch events. 8580 // It seems that in all such cases `detail` property of `click` event is always `1`. 8581 // So here we rely on that fact to avoid excessive 'dblclick' simulation when not needed. 8582 var last = 0, 8583 detail; 8584 function simDblclick(e) { 8585 if (e.detail !== 1) { 8586 detail = e.detail; // keep in sync to avoid false dblclick in some cases 8587 return; 8588 } 8589 if (e.pointerType === 'mouse' || e.sourceCapabilities && !e.sourceCapabilities.firesTouchEvents) { 8590 return; 8591 } 8592 8593 // When clicking on an <input>, the browser generates a click on its 8594 // <label> (and vice versa) triggering two clicks in quick succession. 8595 // This ignores clicks on elements which are a label with a 'for' 8596 // attribute (or children of such a label), but not children of 8597 // a <input>. 8598 var path = getPropagationPath(e); 8599 if (path.some(function (el) { 8600 return el instanceof HTMLLabelElement && el.attributes.for; 8601 }) && !path.some(function (el) { 8602 return el instanceof HTMLInputElement || el instanceof HTMLSelectElement; 8603 })) { 8604 return; 8605 } 8606 var now = Date.now(); 8607 if (now - last <= delay) { 8608 detail++; 8609 if (detail === 2) { 8610 handler(makeDblclick(e)); 8611 } 8612 } else { 8613 detail = 1; 8614 } 8615 last = now; 8616 } 8617 obj.addEventListener('click', simDblclick); 8618 return { 8619 dblclick: handler, 8620 simDblclick: simDblclick 8621 }; 8622 } 8623 function removeDoubleTapListener(obj, handlers) { 8624 obj.removeEventListener('dblclick', handlers.dblclick); 8625 obj.removeEventListener('click', handlers.simDblclick); 8626 } 8627 8628 /* 8629 * @namespace DomUtil 8630 * 8631 * Utility functions to work with the [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) 8632 * tree, used by Leaflet internally. 8633 * 8634 * Most functions expecting or returning a `HTMLElement` also work for 8635 * SVG elements. The only difference is that classes refer to CSS classes 8636 * in HTML and SVG classes in SVG. 8637 */ 8638 8639 // @property TRANSFORM: String 8640 // Vendor-prefixed transform style name (e.g. `'webkitTransform'` for WebKit). 8641 var TRANSFORM = testProp(['transform', 'webkitTransform', 'OTransform', 'MozTransform', 'msTransform']); 8642 8643 // webkitTransition comes first because some browser versions that drop vendor prefix don't do 8644 // the same for the transitionend event, in particular the Android 4.1 stock browser 8645 8646 // @property TRANSITION: String 8647 // Vendor-prefixed transition style name. 8648 var TRANSITION = testProp(['webkitTransition', 'transition', 'OTransition', 'MozTransition', 'msTransition']); 8649 8650 // @property TRANSITION_END: String 8651 // Vendor-prefixed transitionend event name. 8652 var TRANSITION_END = TRANSITION === 'webkitTransition' || TRANSITION === 'OTransition' ? TRANSITION + 'End' : 'transitionend'; 8653 8654 // @function get(id: String|HTMLElement): HTMLElement 8655 // Returns an element given its DOM id, or returns the element itself 8656 // if it was passed directly. 8657 function get(id) { 8658 return typeof id === 'string' ? document.getElementById(id) : id; 8659 } 8660 8661 // @function getStyle(el: HTMLElement, styleAttrib: String): String 8662 // Returns the value for a certain style attribute on an element, 8663 // including computed values or values set through CSS. 8664 function getStyle(el, style) { 8665 var value = el.style[style] || el.currentStyle && el.currentStyle[style]; 8666 if ((!value || value === 'auto') && document.defaultView) { 8667 var css = document.defaultView.getComputedStyle(el, null); 8668 value = css ? css[style] : null; 8669 } 8670 return value === 'auto' ? null : value; 8671 } 8672 8673 // @function create(tagName: String, className?: String, container?: HTMLElement): HTMLElement 8674 // Creates an HTML element with `tagName`, sets its class to `className`, and optionally appends it to `container` element. 8675 function create$1(tagName, className, container) { 8676 var el = document.createElement(tagName); 8677 el.className = className || ''; 8678 if (container) { 8679 container.appendChild(el); 8680 } 8681 return el; 8682 } 8683 8684 // @function remove(el: HTMLElement) 8685 // Removes `el` from its parent element 8686 function _remove(el) { 8687 var parent = el.parentNode; 8688 if (parent) { 8689 parent.removeChild(el); 8690 } 8691 } 8692 8693 // @function empty(el: HTMLElement) 8694 // Removes all of `el`'s children elements from `el` 8695 function empty(el) { 8696 while (el.firstChild) { 8697 el.removeChild(el.firstChild); 8698 } 8699 } 8700 8701 // @function toFront(el: HTMLElement) 8702 // Makes `el` the last child of its parent, so it renders in front of the other children. 8703 function toFront(el) { 8704 var parent = el.parentNode; 8705 if (parent && parent.lastChild !== el) { 8706 parent.appendChild(el); 8707 } 8708 } 8709 8710 // @function toBack(el: HTMLElement) 8711 // Makes `el` the first child of its parent, so it renders behind the other children. 8712 function toBack(el) { 8713 var parent = el.parentNode; 8714 if (parent && parent.firstChild !== el) { 8715 parent.insertBefore(el, parent.firstChild); 8716 } 8717 } 8718 8719 // @function hasClass(el: HTMLElement, name: String): Boolean 8720 // Returns `true` if the element's class attribute contains `name`. 8721 function hasClass(el, name) { 8722 if (el.classList !== undefined) { 8723 return el.classList.contains(name); 8724 } 8725 var className = getClass(el); 8726 return className.length > 0 && new RegExp('(^|\\s)' + name + '(\\s|$)').test(className); 8727 } 8728 8729 // @function addClass(el: HTMLElement, name: String) 8730 // Adds `name` to the element's class attribute. 8731 function addClass(el, name) { 8732 if (el.classList !== undefined) { 8733 var classes = splitWords(name); 8734 for (var i = 0, len = classes.length; i < len; i++) { 8735 el.classList.add(classes[i]); 8736 } 8737 } else if (!hasClass(el, name)) { 8738 var className = getClass(el); 8739 setClass(el, (className ? className + ' ' : '') + name); 8740 } 8741 } 8742 8743 // @function removeClass(el: HTMLElement, name: String) 8744 // Removes `name` from the element's class attribute. 8745 function removeClass(el, name) { 8746 if (el.classList !== undefined) { 8747 el.classList.remove(name); 8748 } else { 8749 setClass(el, trim((' ' + getClass(el) + ' ').replace(' ' + name + ' ', ' '))); 8750 } 8751 } 8752 8753 // @function setClass(el: HTMLElement, name: String) 8754 // Sets the element's class. 8755 function setClass(el, name) { 8756 if (el.className.baseVal === undefined) { 8757 el.className = name; 8758 } else { 8759 // in case of SVG element 8760 el.className.baseVal = name; 8761 } 8762 } 8763 8764 // @function getClass(el: HTMLElement): String 8765 // Returns the element's class. 8766 function getClass(el) { 8767 // Check if the element is an SVGElementInstance and use the correspondingElement instead 8768 // (Required for linked SVG elements in IE11.) 8769 if (el.correspondingElement) { 8770 el = el.correspondingElement; 8771 } 8772 return el.className.baseVal === undefined ? el.className : el.className.baseVal; 8773 } 8774 8775 // @function setOpacity(el: HTMLElement, opacity: Number) 8776 // Set the opacity of an element (including old IE support). 8777 // `opacity` must be a number from `0` to `1`. 8778 function _setOpacity(el, value) { 8779 if ('opacity' in el.style) { 8780 el.style.opacity = value; 8781 } else if ('filter' in el.style) { 8782 _setOpacityIE(el, value); 8783 } 8784 } 8785 function _setOpacityIE(el, value) { 8786 var filter = false, 8787 filterName = 'DXImageTransform.Microsoft.Alpha'; 8788 8789 // filters collection throws an error if we try to retrieve a filter that doesn't exist 8790 try { 8791 filter = el.filters.item(filterName); 8792 } catch (e) { 8793 // don't set opacity to 1 if we haven't already set an opacity, 8794 // it isn't needed and breaks transparent pngs. 8795 if (value === 1) { 8796 return; 8797 } 8798 } 8799 value = Math.round(value * 100); 8800 if (filter) { 8801 filter.Enabled = value !== 100; 8802 filter.Opacity = value; 8803 } else { 8804 el.style.filter += ' progid:' + filterName + '(opacity=' + value + ')'; 8805 } 8806 } 8807 8808 // @function testProp(props: String[]): String|false 8809 // Goes through the array of style names and returns the first name 8810 // that is a valid style name for an element. If no such name is found, 8811 // it returns false. Useful for vendor-prefixed styles like `transform`. 8812 function testProp(props) { 8813 var style = document.documentElement.style; 8814 for (var i = 0; i < props.length; i++) { 8815 if (props[i] in style) { 8816 return props[i]; 8817 } 8818 } 8819 return false; 8820 } 8821 8822 // @function setTransform(el: HTMLElement, offset: Point, scale?: Number) 8823 // Resets the 3D CSS transform of `el` so it is translated by `offset` pixels 8824 // and optionally scaled by `scale`. Does not have an effect if the 8825 // browser doesn't support 3D CSS transforms. 8826 function setTransform(el, offset, scale) { 8827 var pos = offset || new Point(0, 0); 8828 el.style[TRANSFORM] = (Browser.ie3d ? 'translate(' + pos.x + 'px,' + pos.y + 'px)' : 'translate3d(' + pos.x + 'px,' + pos.y + 'px,0)') + (scale ? ' scale(' + scale + ')' : ''); 8829 } 8830 8831 // @function setPosition(el: HTMLElement, position: Point) 8832 // Sets the position of `el` to coordinates specified by `position`, 8833 // using CSS translate or top/left positioning depending on the browser 8834 // (used by Leaflet internally to position its layers). 8835 function setPosition(el, point) { 8836 /*eslint-disable */ 8837 el._leaflet_pos = point; 8838 /* eslint-enable */ 8839 8840 if (Browser.any3d) { 8841 setTransform(el, point); 8842 } else { 8843 el.style.left = point.x + 'px'; 8844 el.style.top = point.y + 'px'; 8845 } 8846 } 8847 8848 // @function getPosition(el: HTMLElement): Point 8849 // Returns the coordinates of an element previously positioned with setPosition. 8850 function getPosition(el) { 8851 // this method is only used for elements previously positioned using setPosition, 8852 // so it's safe to cache the position for performance 8853 8854 return el._leaflet_pos || new Point(0, 0); 8855 } 8856 8857 // @function disableTextSelection() 8858 // Prevents the user from generating `selectstart` DOM events, usually generated 8859 // when the user drags the mouse through a page with text. Used internally 8860 // by Leaflet to override the behaviour of any click-and-drag interaction on 8861 // the map. Affects drag interactions on the whole document. 8862 8863 // @function enableTextSelection() 8864 // Cancels the effects of a previous [`L.DomUtil.disableTextSelection`](#domutil-disabletextselection). 8865 var disableTextSelection; 8866 var enableTextSelection; 8867 var _userSelect; 8868 if ('onselectstart' in document) { 8869 disableTextSelection = function disableTextSelection() { 8870 on(window, 'selectstart', preventDefault); 8871 }; 8872 enableTextSelection = function enableTextSelection() { 8873 off(window, 'selectstart', preventDefault); 8874 }; 8875 } else { 8876 var userSelectProperty = testProp(['userSelect', 'WebkitUserSelect', 'OUserSelect', 'MozUserSelect', 'msUserSelect']); 8877 disableTextSelection = function disableTextSelection() { 8878 if (userSelectProperty) { 8879 var style = document.documentElement.style; 8880 _userSelect = style[userSelectProperty]; 8881 style[userSelectProperty] = 'none'; 8882 } 8883 }; 8884 enableTextSelection = function enableTextSelection() { 8885 if (userSelectProperty) { 8886 document.documentElement.style[userSelectProperty] = _userSelect; 8887 _userSelect = undefined; 8888 } 8889 }; 8890 } 8891 8892 // @function disableImageDrag() 8893 // As [`L.DomUtil.disableTextSelection`](#domutil-disabletextselection), but 8894 // for `dragstart` DOM events, usually generated when the user drags an image. 8895 function disableImageDrag() { 8896 on(window, 'dragstart', preventDefault); 8897 } 8898 8899 // @function enableImageDrag() 8900 // Cancels the effects of a previous [`L.DomUtil.disableImageDrag`](#domutil-disabletextselection). 8901 function enableImageDrag() { 8902 off(window, 'dragstart', preventDefault); 8903 } 8904 var _outlineElement, _outlineStyle; 8905 // @function preventOutline(el: HTMLElement) 8906 // Makes the [outline](https://developer.mozilla.org/docs/Web/CSS/outline) 8907 // of the element `el` invisible. Used internally by Leaflet to prevent 8908 // focusable elements from displaying an outline when the user performs a 8909 // drag interaction on them. 8910 function preventOutline(element) { 8911 while (element.tabIndex === -1) { 8912 element = element.parentNode; 8913 } 8914 if (!element.style) { 8915 return; 8916 } 8917 restoreOutline(); 8918 _outlineElement = element; 8919 _outlineStyle = element.style.outlineStyle; 8920 element.style.outlineStyle = 'none'; 8921 on(window, 'keydown', restoreOutline); 8922 } 8923 8924 // @function restoreOutline() 8925 // Cancels the effects of a previous [`L.DomUtil.preventOutline`](). 8926 function restoreOutline() { 8927 if (!_outlineElement) { 8928 return; 8929 } 8930 _outlineElement.style.outlineStyle = _outlineStyle; 8931 _outlineElement = undefined; 8932 _outlineStyle = undefined; 8933 off(window, 'keydown', restoreOutline); 8934 } 8935 8936 // @function getSizedParentNode(el: HTMLElement): HTMLElement 8937 // Finds the closest parent node which size (width and height) is not null. 8938 function getSizedParentNode(element) { 8939 do { 8940 element = element.parentNode; 8941 } while ((!element.offsetWidth || !element.offsetHeight) && element !== document.body); 8942 return element; 8943 } 8944 8945 // @function getScale(el: HTMLElement): Object 8946 // Computes the CSS scale currently applied on the element. 8947 // Returns an object with `x` and `y` members as horizontal and vertical scales respectively, 8948 // and `boundingClientRect` as the result of [`getBoundingClientRect()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect). 8949 function getScale(element) { 8950 var rect = element.getBoundingClientRect(); // Read-only in old browsers. 8951 8952 return { 8953 x: rect.width / element.offsetWidth || 1, 8954 y: rect.height / element.offsetHeight || 1, 8955 boundingClientRect: rect 8956 }; 8957 } 8958 var DomUtil = { 8959 __proto__: null, 8960 TRANSFORM: TRANSFORM, 8961 TRANSITION: TRANSITION, 8962 TRANSITION_END: TRANSITION_END, 8963 get: get, 8964 getStyle: getStyle, 8965 create: create$1, 8966 remove: _remove, 8967 empty: empty, 8968 toFront: toFront, 8969 toBack: toBack, 8970 hasClass: hasClass, 8971 addClass: addClass, 8972 removeClass: removeClass, 8973 setClass: setClass, 8974 getClass: getClass, 8975 setOpacity: _setOpacity, 8976 testProp: testProp, 8977 setTransform: setTransform, 8978 setPosition: setPosition, 8979 getPosition: getPosition, 8980 get disableTextSelection() { 8981 return disableTextSelection; 8982 }, 8983 get enableTextSelection() { 8984 return enableTextSelection; 8985 }, 8986 disableImageDrag: disableImageDrag, 8987 enableImageDrag: enableImageDrag, 8988 preventOutline: preventOutline, 8989 restoreOutline: restoreOutline, 8990 getSizedParentNode: getSizedParentNode, 8991 getScale: getScale 8992 }; 8993 8994 /* 8995 * @namespace DomEvent 8996 * Utility functions to work with the [DOM events](https://developer.mozilla.org/docs/Web/API/Event), used by Leaflet internally. 8997 */ 8998 8999 // Inspired by John Resig, Dean Edwards and YUI addEvent implementations. 9000 9001 // @function on(el: HTMLElement, types: String, fn: Function, context?: Object): this 9002 // Adds a listener function (`fn`) to a particular DOM event type of the 9003 // element `el`. You can optionally specify the context of the listener 9004 // (object the `this` keyword will point to). You can also pass several 9005 // space-separated types (e.g. `'click dblclick'`). 9006 9007 // @alternative 9008 // @function on(el: HTMLElement, eventMap: Object, context?: Object): this 9009 // Adds a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}` 9010 function on(obj, types, fn, context) { 9011 if (types && _typeof$1(types) === 'object') { 9012 for (var type in types) { 9013 addOne(obj, type, types[type], fn); 9014 } 9015 } else { 9016 types = splitWords(types); 9017 for (var i = 0, len = types.length; i < len; i++) { 9018 addOne(obj, types[i], fn, context); 9019 } 9020 } 9021 return this; 9022 } 9023 var eventsKey = '_leaflet_events'; 9024 9025 // @function off(el: HTMLElement, types: String, fn: Function, context?: Object): this 9026 // Removes a previously added listener function. 9027 // Note that if you passed a custom context to on, you must pass the same 9028 // context to `off` in order to remove the listener. 9029 9030 // @alternative 9031 // @function off(el: HTMLElement, eventMap: Object, context?: Object): this 9032 // Removes a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}` 9033 9034 // @alternative 9035 // @function off(el: HTMLElement, types: String): this 9036 // Removes all previously added listeners of given types. 9037 9038 // @alternative 9039 // @function off(el: HTMLElement): this 9040 // Removes all previously added listeners from given HTMLElement 9041 function off(obj, types, fn, context) { 9042 if (arguments.length === 1) { 9043 batchRemove(obj); 9044 delete obj[eventsKey]; 9045 } else if (types && _typeof$1(types) === 'object') { 9046 for (var type in types) { 9047 removeOne(obj, type, types[type], fn); 9048 } 9049 } else { 9050 types = splitWords(types); 9051 if (arguments.length === 2) { 9052 batchRemove(obj, function (type) { 9053 return indexOf(types, type) !== -1; 9054 }); 9055 } else { 9056 for (var i = 0, len = types.length; i < len; i++) { 9057 removeOne(obj, types[i], fn, context); 9058 } 9059 } 9060 } 9061 return this; 9062 } 9063 function batchRemove(obj, filterFn) { 9064 for (var id in obj[eventsKey]) { 9065 var type = id.split(/\d/)[0]; 9066 if (!filterFn || filterFn(type)) { 9067 removeOne(obj, type, null, null, id); 9068 } 9069 } 9070 } 9071 var mouseSubst = { 9072 mouseenter: 'mouseover', 9073 mouseleave: 'mouseout', 9074 wheel: !('onwheel' in window) && 'mousewheel' 9075 }; 9076 function addOne(obj, type, fn, context) { 9077 var id = type + stamp(fn) + (context ? '_' + stamp(context) : ''); 9078 if (obj[eventsKey] && obj[eventsKey][id]) { 9079 return this; 9080 } 9081 var handler = function handler(e) { 9082 return fn.call(context || obj, e || window.event); 9083 }; 9084 var originalHandler = handler; 9085 if (!Browser.touchNative && Browser.pointer && type.indexOf('touch') === 0) { 9086 // Needs DomEvent.Pointer.js 9087 handler = addPointerListener(obj, type, handler); 9088 } else if (Browser.touch && type === 'dblclick') { 9089 handler = addDoubleTapListener(obj, handler); 9090 } else if ('addEventListener' in obj) { 9091 if (type === 'touchstart' || type === 'touchmove' || type === 'wheel' || type === 'mousewheel') { 9092 obj.addEventListener(mouseSubst[type] || type, handler, Browser.passiveEvents ? { 9093 passive: false 9094 } : false); 9095 } else if (type === 'mouseenter' || type === 'mouseleave') { 9096 handler = function handler(e) { 9097 e = e || window.event; 9098 if (isExternalTarget(obj, e)) { 9099 originalHandler(e); 9100 } 9101 }; 9102 obj.addEventListener(mouseSubst[type], handler, false); 9103 } else { 9104 obj.addEventListener(type, originalHandler, false); 9105 } 9106 } else { 9107 obj.attachEvent('on' + type, handler); 9108 } 9109 obj[eventsKey] = obj[eventsKey] || {}; 9110 obj[eventsKey][id] = handler; 9111 } 9112 function removeOne(obj, type, fn, context, id) { 9113 id = id || type + stamp(fn) + (context ? '_' + stamp(context) : ''); 9114 var handler = obj[eventsKey] && obj[eventsKey][id]; 9115 if (!handler) { 9116 return this; 9117 } 9118 if (!Browser.touchNative && Browser.pointer && type.indexOf('touch') === 0) { 9119 removePointerListener(obj, type, handler); 9120 } else if (Browser.touch && type === 'dblclick') { 9121 removeDoubleTapListener(obj, handler); 9122 } else if ('removeEventListener' in obj) { 9123 obj.removeEventListener(mouseSubst[type] || type, handler, false); 9124 } else { 9125 obj.detachEvent('on' + type, handler); 9126 } 9127 obj[eventsKey][id] = null; 9128 } 9129 9130 // @function stopPropagation(ev: DOMEvent): this 9131 // Stop the given event from propagation to parent elements. Used inside the listener functions: 9132 // ```js 9133 // L.DomEvent.on(div, 'click', function (ev) { 9134 // L.DomEvent.stopPropagation(ev); 9135 // }); 9136 // ``` 9137 function stopPropagation(e) { 9138 if (e.stopPropagation) { 9139 e.stopPropagation(); 9140 } else if (e.originalEvent) { 9141 // In case of Leaflet event. 9142 e.originalEvent._stopped = true; 9143 } else { 9144 e.cancelBubble = true; 9145 } 9146 return this; 9147 } 9148 9149 // @function disableScrollPropagation(el: HTMLElement): this 9150 // Adds `stopPropagation` to the element's `'wheel'` events (plus browser variants). 9151 function disableScrollPropagation(el) { 9152 addOne(el, 'wheel', stopPropagation); 9153 return this; 9154 } 9155 9156 // @function disableClickPropagation(el: HTMLElement): this 9157 // Adds `stopPropagation` to the element's `'click'`, `'dblclick'`, `'contextmenu'`, 9158 // `'mousedown'` and `'touchstart'` events (plus browser variants). 9159 function disableClickPropagation(el) { 9160 on(el, 'mousedown touchstart dblclick contextmenu', stopPropagation); 9161 el['_leaflet_disable_click'] = true; 9162 return this; 9163 } 9164 9165 // @function preventDefault(ev: DOMEvent): this 9166 // Prevents the default action of the DOM Event `ev` from happening (such as 9167 // following a link in the href of the a element, or doing a POST request 9168 // with page reload when a `<form>` is submitted). 9169 // Use it inside listener functions. 9170 function preventDefault(e) { 9171 if (e.preventDefault) { 9172 e.preventDefault(); 9173 } else { 9174 e.returnValue = false; 9175 } 9176 return this; 9177 } 9178 9179 // @function stop(ev: DOMEvent): this 9180 // Does `stopPropagation` and `preventDefault` at the same time. 9181 function stop(e) { 9182 preventDefault(e); 9183 stopPropagation(e); 9184 return this; 9185 } 9186 9187 // @function getPropagationPath(ev: DOMEvent): Array 9188 // Compatibility polyfill for [`Event.composedPath()`](https://developer.mozilla.org/en-US/docs/Web/API/Event/composedPath). 9189 // Returns an array containing the `HTMLElement`s that the given DOM event 9190 // should propagate to (if not stopped). 9191 function getPropagationPath(ev) { 9192 if (ev.composedPath) { 9193 return ev.composedPath(); 9194 } 9195 var path = []; 9196 var el = ev.target; 9197 while (el) { 9198 path.push(el); 9199 el = el.parentNode; 9200 } 9201 return path; 9202 } 9203 9204 // @function getMousePosition(ev: DOMEvent, container?: HTMLElement): Point 9205 // Gets normalized mouse position from a DOM event relative to the 9206 // `container` (border excluded) or to the whole page if not specified.
9207 function getMousePosition(e, container) { 9208 if (!container) { 9209 return new Point(e.clientX, e.clientY); 9210 } 9211 var scale = getScale(container), 9212 offset = scale.boundingClientRect; // left and top values are in page scale (like the event clientX/Y) 9213 9214 return new Point( 9215 // offset.left/top values are in page scale (like clientX/Y), 9216 // whereas clientLeft/Top (border width) values are the original values (before CSS scale applies). 9217 (e.clientX - offset.left) / scale.x - container.clientLeft, (e.clientY - offset.top) / scale.y - container.clientTop); 9218 } 9219 9220 // except , Safari and 9221 // We need double the scroll pixels (see #7403 and #4538) for all Browsers 9222 // except OSX (Mac) -> 3x, Chrome running on Linux 1x 9223 9224 var wheelPxFactor = Browser.linux && Browser.chrome ? window.devicePixelRatio : Browser.mac ? window.devicePixelRatio * 3 : window.devicePixelRatio > 0 ? 2 * window.devicePixelRatio : 1; 9225 // @function getWheelDelta(ev: DOMEvent): Number 9226 // Gets normalized wheel delta from a wheel DOM event, in vertical 9227 // pixels scrolled (negative if scrolling down). 9228 // Events from pointing devices without precise scrolling are mapped to 9229 // a best guess of 60 pixels. 9230 function getWheelDelta(e) { 9231 return Browser.edge ? e.wheelDeltaY / 2 : 9232 // Don't trust window-geometry-based delta 9233 e.deltaY && e.deltaMode === 0 ? -e.deltaY / wheelPxFactor : 9234 // Pixels 9235 e.deltaY && e.deltaMode === 1 ? -e.deltaY * 20 : 9236 // Lines 9237 e.deltaY && e.deltaMode === 2 ? -e.deltaY * 60 : 9238 // Pages 9239 e.deltaX || e.deltaZ ? 0 : 9240 // Skip horizontal/depth wheel events
9241 e.wheelDelta ? (e.wheelDeltaY || e.wheelDelta) / 2 : 9242 // Legacy IE pixels 9243 e.detail && Math.abs(e.detail) < 32765 ? -e.detail * 20 : 9244 // Legacy Moz lines 9245 e.detail ? e.detail / -32765 * 60 : 9246 // Legacy Moz pages 9247 0; 9248 } 9249 9250 // check if element really left/entered the event target (for mouseenter/mouseleave) 9251 function isExternalTarget(el, e) { 9252 var related = e.relatedTarget; 9253 if (!related) { 9254 return true; 9255 } 9256 try { 9257 while (related && related !== el) { 9258 related = related.parentNode; 9259 } 9260 } catch (err) { 9261 return false; 9262 } 9263 return related !== el; 9264 } 9265 var DomEvent = { 9266 __proto__: null, 9267 on: on, 9268 off: off, 9269 stopPropagation: stopPropagation, 9270 disableScrollPropagation: disableScrollPropagation, 9271 disableClickPropagation: disableClickPropagation, 9272 preventDefault: preventDefault, 9273 stop: stop, 9274 getPropagationPath: getPropagationPath, 9275 getMousePosition: getMousePosition, 9276 getWheelDelta: getWheelDelta, 9277 isExternalTarget: isExternalTarget, 9278 addListener: on, 9279 removeListener: off 9280 }; 9281 9282 /* 9283 * @class PosAnimation 9284 * @aka L.PosAnimation 9285 * @inherits Evented 9286 * Used internally for panning animations, utilizing CSS3 Transitions for modern browsers and a timer fallback for IE6-9. 9287 * 9288 * @example 9289 * ```js 9290 * var myPositionMarker = L.marker([48.864716, 2.294694]).addTo(map); 9291 * 9292 * myPositionMarker.on("click", function() { 9293 * var pos = map.latLngToLayerPoint(myPositionMarker.getLatLng()); 9294 * pos.y -= 25; 9295 * var fx = new L.PosAnimation(); 9296 * 9297 * fx.once('end',function() { 9298 * pos.y += 25; 9299 * fx.run(myPositionMarker._icon, pos, 0.8); 9300 * }); 9301 * 9302 * fx.run(myPositionMarker._icon, pos, 0.3); 9303 * }); 9304 * 9305 * ``` 9306 * 9307 * @constructor L.PosAnimation() 9308 * Creates a `PosAnimation` object. 9309 * 9310 */ 9311 9312 var PosAnimation = Evented.extend({ 9313 // @method run(el: HTMLElement, newPos: Point, duration?: Number, easeLinearity?: Number) 9314 // Run an animation of a given element to a new position, optionally setting 9315 // duration in seconds (`0.25` by default) and easing linearity factor (3rd 9316 // argument of the [cubic bezier curve](https://cubic-bezier.com/#0,0,.5,1), 9317 // `0.5` by default). 9318 run: function run(el, newPos, duration, easeLinearity) { 9319 this.stop(); 9320 this._el = el; 9321 this._inProgress = true; 9322 this._duration = duration || 0.25; 9323 this._easeOutPower = 1 / Math.max(easeLinearity || 0.5, 0.2); 9324 this._startPos = getPosition(el); 9325 this._offset = newPos.subtract(this._startPos); 9326 this._startTime = +new Date(); 9327 9328 // @event start: Event 9329 // Fired when the animation starts 9330 this.fire('start'); 9331 this._animate(); 9332 }, 9333 // @method stop() 9334 // Stops the animation (if currently running). 9335 stop: function stop() { 9336 if (!this._inProgress) { 9337 return; 9338 } 9339 this._step(true); 9340 this._complete(); 9341 }, 9342 _animate: function _animate() { 9343 // animation loop 9344 this._animId = requestAnimFrame(this._animate, this); 9345 this._step(); 9346 }, 9347 _step: function _step(round) { 9348 var elapsed = +new Date() - this._startTime, 9349 duration = this._duration * 1000; 9350 if (elapsed < duration) { 9351 this._runFrame(this._easeOut(elapsed / duration), round); 9352 } else { 9353 this._runFrame(1); 9354 this._complete(); 9355 } 9356 }, 9357 _runFrame: function _runFrame(progress, round) { 9358 var pos = this._startPos.add(this._offset.multiplyBy(progress)); 9359 if (round) { 9360 pos._round(); 9361 } 9362 setPosition(this._el, pos); 9363 9364 // @event step: Event 9365 // Fired continuously during the animation. 9366 this.fire('step'); 9367 }, 9368 _complete: function _complete() {
vendor: 29,718 bytes, lines 9369-10036
9369 cancelAnimFrame(this._animId); 9370 this._inProgress = false; 9371 // @event end: Event 9372 // Fired when the animation ends. 9373 this.fire('end'); 9374 }, 9375 _easeOut: function _easeOut(t) { 9376 return 1 - Math.pow(1 - t, this._easeOutPower); 9377 } 9378 }); 9379 9380 /* 9381 * @class Map 9382 * @aka L.Map 9383 * @inherits Evented 9384 * 9385 * The central class of the API â it is used to create a map on a page and manipulate it. 9386 * 9387 * @example 9388 * 9389 * ```js 9390 * // initialize the map on the "map" div with a given center and zoom 9391 * var map = L.map('map', { 9392 * center: [51.505, -0.09], 9393 * zoom: 13 9394 * }); 9395 * ``` 9396 * 9397 */ 9398 9399 var Map = Evented.extend({ 9400 options: { 9401 // @section Map State Options 9402 // @option crs: CRS = L.CRS.EPSG3857 9403 // The [Coordinate Reference System](#crs) to use. Don't change this if you're not 9404 // sure what it means. 9405 crs: EPSG3857, 9406 // @option center: LatLng = undefined 9407 // Initial geographic center of the map 9408 center: undefined, 9409 // @option zoom: Number = undefined 9410 // Initial map zoom level 9411 zoom: undefined, 9412 // @option minZoom: Number = * 9413 // Minimum zoom level of the map. 9414 // If not specified and at least one `GridLayer` or `TileLayer` is in the map, 9415 // the lowest of their `minZoom` options will be used instead. 9416 minZoom: undefined, 9417 // @option maxZoom: Number = * 9418 // Maximum zoom level of the map. 9419 // If not specified and at least one `GridLayer` or `TileLayer` is in the map, 9420 // the highest of their `maxZoom` options will be used instead. 9421 maxZoom: undefined, 9422 // @option layers: Layer[] = [] 9423 // Array of layers that will be added to the map initially 9424 layers: [], 9425 // @option maxBounds: LatLngBounds = null 9426 // When this option is set, the map restricts the view to the given 9427 // geographical bounds, bouncing the user back if the user tries to pan 9428 // outside the view. To set the restriction dynamically, use 9429 // [`setMaxBounds`](#map-setmaxbounds) method. 9430 maxBounds: undefined, 9431 // @option renderer: Renderer = * 9432 // The default method for drawing vector layers on the map. `L.SVG` 9433 // or `L.Canvas` by default depending on browser support. 9434 renderer: undefined, 9435 // @section Animation Options 9436 // @option zoomAnimation: Boolean = true 9437 // Whether the map zoom animation is enabled. By default it's enabled 9438 // in all browsers that support CSS3 Transitions except Android. 9439 zoomAnimation: true, 9440 // @option zoomAnimationThreshold: Number = 4 9441 // Won't animate zoom if the zoom difference exceeds this value. 9442 zoomAnimationThreshold: 4, 9443 // @option fadeAnimation: Boolean = true 9444 // Whether the tile fade animation is enabled. By default it's enabled 9445 // in all browsers that support CSS3 Transitions except Android. 9446 fadeAnimation: true, 9447 // @option markerZoomAnimation: Boolean = true 9448 // Whether markers animate their zoom with the zoom animation, if disabled 9449 // they will disappear for the length of the animation. By default it's 9450 // enabled in all browsers that support CSS3 Transitions except Android. 9451 markerZoomAnimation: true, 9452 // @option transform3DLimit: Number = 2^23 9453 // Defines the maximum size of a CSS translation transform. The default 9454 // value should not be changed unless a web browser positions layers in 9455 // the wrong place after doing a large `panBy`. 9456 transform3DLimit: 8388608, 9457 // Precision limit of a 32-bit float 9458 9459 // @section Interaction Options 9460 // @option zoomSnap: Number = 1 9461 // Forces the map's zoom level to always be a multiple of this, particularly 9462 // right after a [`fitBounds()`](#map-fitbounds) or a pinch-zoom. 9463 // By default, the zoom level snaps to the nearest integer; lower values 9464 // (e.g. `0.5` or `0.1`) allow for greater granularity. A value of `0` 9465 // means the zoom level will not be snapped after `fitBounds` or a pinch-zoom. 9466 zoomSnap: 1, 9467 // @option zoomDelta: Number = 1 9468 // Controls how much the map's zoom level will change after a 9469 // [`zoomIn()`](#map-zoomin), [`zoomOut()`](#map-zoomout), pressing `+` 9470 // or `-` on the keyboard, or using the [zoom controls](#control-zoom). 9471 // Values smaller than `1` (e.g. `0.5`) allow for greater granularity. 9472 zoomDelta: 1, 9473 // @option trackResize: Boolean = true 9474 // Whether the map automatically handles browser window resize to update itself. 9475 trackResize: true 9476 }, 9477 initialize: function initialize(id, options) { 9478 // (HTMLElement or String, Object) 9479 options = setOptions(this, options); 9480 9481 // Make sure to assign internal flags at the beginning, 9482 // to avoid inconsistent state in some edge cases. 9483 this._handlers = []; 9484 this._layers = {}; 9485 this._zoomBoundLayers = {}; 9486 this._sizeChanged = true; 9487 this._initContainer(id); 9488 this._initLayout(); 9489 9490 // hack for https://github.com/Leaflet/Leaflet/issues/1980 9491 this._onResize = bind(this._onResize, this); 9492 this._initEvents(); 9493 if (options.maxBounds) { 9494 this.setMaxBounds(options.maxBounds); 9495 } 9496 if (options.zoom !== undefined) { 9497 this._zoom = this._limitZoom(options.zoom); 9498 } 9499 if (options.center && options.zoom !== undefined) { 9500 this.setView(toLatLng(options.center), options.zoom, { 9501 reset: true 9502 }); 9503 } 9504 this.callInitHooks(); 9505 9506 // don't animate on browsers without hardware-accelerated transitions or old Android/Opera 9507 this._zoomAnimated = TRANSITION && Browser.any3d && !Browser.mobileOpera && this.options.zoomAnimation; 9508 9509 // zoom transitions run with the same duration for all layers, so if one of transitionend events 9510 // happens after starting zoom animation (propagating to the map pane), we know that it ended globally 9511 if (this._zoomAnimated) { 9512 this._createAnimProxy(); 9513 on(this._proxy, TRANSITION_END, this._catchTransitionEnd, this); 9514 } 9515 this._addLayers(this.options.layers); 9516 }, 9517 // @section Methods for modifying map state 9518 9519 // @method setView(center: LatLng, zoom: Number, options?: Zoom/pan options): this 9520 // Sets the view of the map (geographical center and zoom) with the given 9521 // animation options. 9522 setView: function setView(center, zoom, options) { 9523 zoom = zoom === undefined ? this._zoom : this._limitZoom(zoom); 9524 center = this._limitCenter(toLatLng(center), zoom, this.options.maxBounds); 9525 options = options || {}; 9526 this._stop(); 9527 if (this._loaded && !options.reset && options !== true) { 9528 if (options.animate !== undefined) { 9529 options.zoom = extend({ 9530 animate: options.animate 9531 }, options.zoom); 9532 options.pan = extend({ 9533 animate: options.animate, 9534 duration: options.duration 9535 }, options.pan); 9536 } 9537 9538 // try animating pan or zoom 9539 var moved = this._zoom !== zoom ? this._tryAnimatedZoom && this._tryAnimatedZoom(center, zoom, options.zoom) : this._tryAnimatedPan(center, options.pan); 9540 if (moved) { 9541 // prevent resize handler call, the view will refresh after animation anyway 9542 clearTimeout(this._sizeTimer); 9543 return this; 9544 } 9545 } 9546 9547 // animation didn't start, just reset the map view 9548 this._resetView(center, zoom, options.pan && options.pan.noMoveStart); 9549 return this; 9550 }, 9551 // @method setZoom(zoom: Number, options?: Zoom/pan options): this 9552 // Sets the zoom of the map. 9553 setZoom: function setZoom(zoom, options) { 9554 if (!this._loaded) { 9555 this._zoom = zoom; 9556 return this; 9557 } 9558 return this.setView(this.getCenter(), zoom, { 9559 zoom: options 9560 }); 9561 }, 9562 // @method zoomIn(delta?: Number, options?: Zoom options): this 9563 // Increases the zoom of the map by `delta` ([`zoomDelta`](#map-zoomdelta) by default). 9564 zoomIn: function zoomIn(delta, options) { 9565 delta = delta || (Browser.any3d ? this.options.zoomDelta : 1); 9566 return this.setZoom(this._zoom + delta, options); 9567 }, 9568 // @method zoomOut(delta?: Number, options?: Zoom options): this 9569 // Decreases the zoom of the map by `delta` ([`zoomDelta`](#map-zoomdelta) by default). 9570 zoomOut: function zoomOut(delta, options) { 9571 delta = delta || (Browser.any3d ? this.options.zoomDelta : 1); 9572 return this.setZoom(this._zoom - delta, options); 9573 }, 9574 // @method setZoomAround(latlng: LatLng, zoom: Number, options: Zoom options): this 9575 // Zooms the map while keeping a specified geographical point on the map 9576 // stationary (e.g. used internally for scroll zoom and double-click zoom). 9577 // @alternative 9578 // @method setZoomAround(offset: Point, zoom: Number, options: Zoom options): this 9579 // Zooms the map while keeping a specified pixel on the map (relative to the top-left corner) stationary. 9580 setZoomAround: function setZoomAround(latlng, zoom, options) { 9581 var scale = this.getZoomScale(zoom), 9582 viewHalf = this.getSize().divideBy(2), 9583 containerPoint = latlng instanceof Point ? latlng : this.latLngToContainerPoint(latlng), 9584 centerOffset = containerPoint.subtract(viewHalf).multiplyBy(1 - 1 / scale), 9585 newCenter = this.containerPointToLatLng(viewHalf.add(centerOffset)); 9586 return this.setView(newCenter, zoom, { 9587 zoom: options 9588 }); 9589 }, 9590 _getBoundsCenterZoom: function _getBoundsCenterZoom(bounds, options) { 9591 options = options || {}; 9592 bounds = bounds.getBounds ? bounds.getBounds() : toLatLngBounds(bounds); 9593 var paddingTL = toPoint(options.paddingTopLeft || options.padding || [0, 0]), 9594 paddingBR = toPoint(options.paddingBottomRight || options.padding || [0, 0]), 9595 zoom = this.getBoundsZoom(bounds, false, paddingTL.add(paddingBR)); 9596 zoom = typeof options.maxZoom === 'number' ? Math.min(options.maxZoom, zoom) : zoom; 9597 if (zoom === Infinity) { 9598 return { 9599 center: bounds.getCenter(), 9600 zoom: zoom 9601 }; 9602 } 9603 var paddingOffset = paddingBR.subtract(paddingTL).divideBy(2), 9604 swPoint = this.project(bounds.getSouthWest(), zoom), 9605 nePoint = this.project(bounds.getNorthEast(), zoom), 9606 center = this.unproject(swPoint.add(nePoint).divideBy(2).add(paddingOffset), zoom); 9607 return { 9608 center: center, 9609 zoom: zoom 9610 }; 9611 }, 9612 // @method fitBounds(bounds: LatLngBounds, options?: fitBounds options): this 9613 // Sets a map view that contains the given geographical bounds with the 9614 // maximum zoom level possible. 9615 fitBounds: function fitBounds(bounds, options) { 9616 bounds = toLatLngBounds(bounds); 9617 if (!bounds.isValid()) { 9618 throw new Error('Bounds are not valid.'); 9619 } 9620 var target = this._getBoundsCenterZoom(bounds, options); 9621 return this.setView(target.center, target.zoom, options); 9622 }, 9623 // @method fitWorld(options?: fitBounds options): this 9624 // Sets a map view that mostly contains the whole world with the maximum 9625 // zoom level possible. 9626 fitWorld: function fitWorld(options) { 9627 return this.fitBounds([[-90, -180], [90, 180]], options); 9628 }, 9629 // @method panTo(latlng: LatLng, options?: Pan options): this 9630 // Pans the map to a given center. 9631 panTo: function panTo(center, options) { 9632 // (LatLng) 9633 return this.setView(center, this._zoom, { 9634 pan: options 9635 }); 9636 }, 9637 // @method panBy(offset: Point, options?: Pan options): this 9638 // Pans the map by a given number of pixels (animated). 9639 panBy: function panBy(offset, options) { 9640 offset = toPoint(offset).round(); 9641 options = options || {}; 9642 if (!offset.x && !offset.y) { 9643 return this.fire('moveend'); 9644 } 9645 // If we pan too far, Chrome gets issues with tiles 9646 // and makes them disappear or appear in the wrong place (slightly offset) #2602 9647 if (options.animate !== true && !this.getSize().contains(offset)) { 9648 this._resetView(this.unproject(this.project(this.getCenter()).add(offset)), this.getZoom()); 9649 return this; 9650 } 9651 if (!this._panAnim) { 9652 this._panAnim = new PosAnimation(); 9653 this._panAnim.on({ 9654 'step': this._onPanTransitionStep, 9655 'end': this._onPanTransitionEnd 9656 }, this); 9657 } 9658 9659 // don't fire movestart if animating inertia 9660 if (!options.noMoveStart) { 9661 this.fire('movestart'); 9662 } 9663 9664 // animate pan unless animate: false specified 9665 if (options.animate !== false) { 9666 addClass(this._mapPane, 'leaflet-pan-anim'); 9667 var newPos = this._getMapPanePos().subtract(offset).round(); 9668 this._panAnim.run(this._mapPane, newPos, options.duration || 0.25, options.easeLinearity); 9669 } else { 9670 this._rawPanBy(offset); 9671 this.fire('move').fire('moveend'); 9672 } 9673 return this; 9674 }, 9675 // @method flyTo(latlng: LatLng, zoom?: Number, options?: Zoom/pan options): this 9676 // Sets the view of the map (geographical center and zoom) performing a smooth 9677 // pan-zoom animation. 9678 flyTo: function flyTo(targetCenter, targetZoom, options) { 9679 options = options || {}; 9680 if (options.animate === false || !Browser.any3d) { 9681 return this.setView(targetCenter, targetZoom, options); 9682 } 9683 this._stop(); 9684 var from = this.project(this.getCenter()), 9685 to = this.project(targetCenter), 9686 size = this.getSize(), 9687 startZoom = this._zoom; 9688 targetCenter = toLatLng(targetCenter); 9689 targetZoom = targetZoom === undefined ? startZoom : targetZoom; 9690 var w0 = Math.max(size.x, size.y), 9691 w1 = w0 * this.getZoomScale(startZoom, targetZoom), 9692 u1 = to.distanceTo(from) || 1, 9693 rho = 1.42, 9694 rho2 = rho * rho; 9695 function r(i) { 9696 var s1 = i ? -1 : 1, 9697 s2 = i ? w1 : w0, 9698 t1 = w1 * w1 - w0 * w0 + s1 * rho2 * rho2 * u1 * u1, 9699 b1 = 2 * s2 * rho2 * u1, 9700 b = t1 / b1, 9701 sq = Math.sqrt(b * b + 1) - b; 9702 9703 // workaround for floating point precision bug when sq = 0, log = -Infinite, 9704 // thus triggering an infinite loop in flyTo 9705 var log = sq < 0.000000001 ? -18 : Math.log(sq); 9706 return log; 9707 } 9708 function sinh(n) { 9709 return (Math.exp(n) - Math.exp(-n)) / 2; 9710 } 9711 function cosh(n) { 9712 return (Math.exp(n) + Math.exp(-n)) / 2; 9713 } 9714 function tanh(n) { 9715 return sinh(n) / cosh(n); 9716 } 9717 var r0 = r(0); 9718 function w(s) { 9719 return w0 * (cosh(r0) / cosh(r0 + rho * s)); 9720 } 9721 function u(s) { 9722 return w0 * (cosh(r0) * tanh(r0 + rho * s) - sinh(r0)) / rho2; 9723 } 9724 function easeOut(t) { 9725 return 1 - Math.pow(1 - t, 1.5); 9726 } 9727 var start = Date.now(), 9728 S = (r(1) - r0) / rho, 9729 duration = options.duration ? 1000 * options.duration : 1000 * S * 0.8; 9730 function frame() { 9731 var t = (Date.now() - start) / duration, 9732 s = easeOut(t) * S; 9733 if (t <= 1) { 9734 this._flyToFrame = requestAnimFrame(frame, this); 9735 this._move(this.unproject(from.add(to.subtract(from).multiplyBy(u(s) / u1)), startZoom), this.getScaleZoom(w0 / w(s), startZoom), { 9736 flyTo: true 9737 }); 9738 } else { 9739 this._move(targetCenter, targetZoom)._moveEnd(true); 9740 } 9741 } 9742 this._moveStart(true, options.noMoveStart); 9743 frame.call(this); 9744 return this; 9745 }, 9746 // @method flyToBounds(bounds: LatLngBounds, options?: fitBounds options): this 9747 // Sets the view of the map with a smooth animation like [`flyTo`](#map-flyto), 9748 // but takes a bounds parameter like [`fitBounds`](#map-fitbounds). 9749 flyToBounds: function flyToBounds(bounds, options) { 9750 var target = this._getBoundsCenterZoom(bounds, options); 9751 return this.flyTo(target.center, target.zoom, options); 9752 }, 9753 // @method setMaxBounds(bounds: LatLngBounds): this 9754 // Restricts the map view to the given bounds (see the [maxBounds](#map-maxbounds) option). 9755 setMaxBounds: function setMaxBounds(bounds) { 9756 bounds = toLatLngBounds(bounds); 9757 if (this.listens('moveend', this._panInsideMaxBounds)) { 9758 this.off('moveend', this._panInsideMaxBounds); 9759 } 9760 if (!bounds.isValid()) { 9761 this.options.maxBounds = null; 9762 return this; 9763 } 9764 this.options.maxBounds = bounds; 9765 if (this._loaded) { 9766 this._panInsideMaxBounds(); 9767 } 9768 return this.on('moveend', this._panInsideMaxBounds); 9769 }, 9770 // @method setMinZoom(zoom: Number): this 9771 // Sets the lower limit for the available zoom levels (see the [minZoom](#map-minzoom) option). 9772 setMinZoom: function setMinZoom(zoom) { 9773 var oldZoom = this.options.minZoom; 9774 this.options.minZoom = zoom; 9775 if (this._loaded && oldZoom !== zoom) { 9776 this.fire('zoomlevelschange'); 9777 if (this.getZoom() < this.options.minZoom) { 9778 return this.setZoom(zoom); 9779 } 9780 } 9781 return this; 9782 }, 9783 // @method setMaxZoom(zoom: Number): this 9784 // Sets the upper limit for the available zoom levels (see the [maxZoom](#map-maxzoom) option). 9785 setMaxZoom: function setMaxZoom(zoom) { 9786 var oldZoom = this.options.maxZoom; 9787 this.options.maxZoom = zoom; 9788 if (this._loaded && oldZoom !== zoom) { 9789 this.fire('zoomlevelschange'); 9790 if (this.getZoom() > this.options.maxZoom) { 9791 return this.setZoom(zoom); 9792 } 9793 } 9794 return this; 9795 }, 9796 // @method panInsideBounds(bounds: LatLngBounds, options?: Pan options): this 9797 // 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. 9798 panInsideBounds: function panInsideBounds(bounds, options) { 9799 this._enforcingBounds = true; 9800 var center = this.getCenter(), 9801 newCenter = this._limitCenter(center, this._zoom, toLatLngBounds(bounds)); 9802 if (!center.equals(newCenter)) { 9803 this.panTo(newCenter, options); 9804 } 9805 this._enforcingBounds = false; 9806 return this; 9807 }, 9808 // @method panInside(latlng: LatLng, options?: padding options): this 9809 // Pans the map the minimum amount to make the `latlng` visible. Use 9810 // padding options to fit the display to more restricted bounds. 9811 // If `latlng` is already within the (optionally padded) display bounds, 9812 // the map will not be panned. 9813 panInside: function panInside(latlng, options) { 9814 options = options || {}; 9815 var paddingTL = toPoint(options.paddingTopLeft || options.padding || [0, 0]), 9816 paddingBR = toPoint(options.paddingBottomRight || options.padding || [0, 0]), 9817 pixelCenter = this.project(this.getCenter()), 9818 pixelPoint = this.project(latlng), 9819 pixelBounds = this.getPixelBounds(), 9820 paddedBounds = toBounds([pixelBounds.min.add(paddingTL), pixelBounds.max.subtract(paddingBR)]), 9821 paddedSize = paddedBounds.getSize(); 9822 if (!paddedBounds.contains(pixelPoint)) { 9823 this._enforcingBounds = true; 9824 var centerOffset = pixelPoint.subtract(paddedBounds.getCenter()); 9825 var offset = paddedBounds.extend(pixelPoint).getSize().subtract(paddedSize); 9826 pixelCenter.x += centerOffset.x < 0 ? -offset.x : offset.x; 9827 pixelCenter.y += centerOffset.y < 0 ? -offset.y : offset.y; 9828 this.panTo(this.unproject(pixelCenter), options); 9829 this._enforcingBounds = false; 9830 } 9831 return this; 9832 }, 9833 // @method invalidateSize(options: Zoom/pan options): this 9834 // Checks if the map container size changed and updates the map if so â 9835 // call it after you've changed the map size dynamically, also animating 9836 // pan by default. If `options.pan` is `false`, panning will not occur. 9837 // If `options.debounceMoveend` is `true`, it will delay `moveend` event so 9838 // that it doesn't happen often even if the method is called many 9839 // times in a row. 9840 9841 // @alternative 9842 // @method invalidateSize(animate: Boolean): this 9843 // Checks if the map container size changed and updates the map if so â 9844 // call it after you've changed the map size dynamically, also animating 9845 // pan by default. 9846 invalidateSize: function invalidateSize(options) { 9847 if (!this._loaded) { 9848 return this; 9849 } 9850 options = extend({ 9851 animate: false, 9852 pan: true 9853 }, options === true ? { 9854 animate: true 9855 } : options); 9856 var oldSize = this.getSize(); 9857 this._sizeChanged = true; 9858 this._lastCenter = null; 9859 var newSize = this.getSize(), 9860 oldCenter = oldSize.divideBy(2).round(), 9861 newCenter = newSize.divideBy(2).round(), 9862 offset = oldCenter.subtract(newCenter); 9863 if (!offset.x && !offset.y) { 9864 return this; 9865 } 9866 if (options.animate && options.pan) { 9867 this.panBy(offset); 9868 } else { 9869 if (options.pan) { 9870 this._rawPanBy(offset); 9871 } 9872 this.fire('move'); 9873 if (options.debounceMoveend) { 9874 clearTimeout(this._sizeTimer); 9875 this._sizeTimer = setTimeout(bind(this.fire, this, 'moveend'), 200); 9876 } else { 9877 this.fire('moveend'); 9878 } 9879 } 9880 9881 // @section Map state change events 9882 // @event resize: ResizeEvent 9883 // Fired when the map is resized. 9884 return this.fire('resize', { 9885 oldSize: oldSize, 9886 newSize: newSize 9887 }); 9888 }, 9889 // @section Methods for modifying map state 9890 // @method stop(): this 9891 // Stops the currently running `panTo` or `flyTo` animation, if any. 9892 stop: function stop() { 9893 this.setZoom(this._limitZoom(this._zoom)); 9894 if (!this.options.zoomSnap) { 9895 this.fire('viewreset'); 9896 } 9897 return this._stop(); 9898 }, 9899 // @section Geolocation methods 9900 // @method locate(options?: Locate options): this 9901 // Tries to locate the user using the Geolocation API, firing a [`locationfound`](#map-locationfound) 9902 // event with location data on success or a [`locationerror`](#map-locationerror) event on failure, 9903 // and optionally sets the map view to the user's location with respect to 9904 // detection accuracy (or to the world view if geolocation failed). 9905 // Note that, if your page doesn't use HTTPS, this method will fail in 9906 // modern browsers ([Chrome 50 and newer](https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-powerful-features-on-insecure-origins)) 9907 // See `Locate options` for more details. 9908 locate: function locate(options) { 9909 options = this._locateOptions = extend({ 9910 timeout: 10000, 9911 watch: false 9912 // setView: false 9913 // maxZoom: <Number> 9914 // maximumAge: 0 9915 // enableHighAccuracy: false 9916 }, options); 9917 if (!('geolocation' in navigator)) { 9918 this._handleGeolocationError({ 9919 code: 0, 9920 message: 'Geolocation not supported.' 9921 }); 9922 return this; 9923 } 9924 var onResponse = bind(this._handleGeolocationResponse, this), 9925 onError = bind(this._handleGeolocationError, this); 9926 if (options.watch) { 9927 this._locationWatchId = navigator.geolocation.watchPosition(onResponse, onError, options); 9928 } else { 9929 navigator.geolocation.getCurrentPosition(onResponse, onError, options); 9930 } 9931 return this; 9932 }, 9933 // @method stopLocate(): this 9934 // Stops watching location previously initiated by `map.locate({watch: true})` 9935 // and aborts resetting the map view if map.locate was called with 9936 // `{setView: true}`. 9937 stopLocate: function stopLocate() { 9938 if (navigator.geolocation && navigator.geolocation.clearWatch) { 9939 navigator.geolocation.clearWatch(this._locationWatchId); 9940 } 9941 if (this._locateOptions) { 9942 this._locateOptions.setView = false; 9943 } 9944 return this; 9945 }, 9946 _handleGeolocationError: function _handleGeolocationError(error) { 9947 if (!this._container._leaflet_id) { 9948 return; 9949 } 9950 var c = error.code, 9951 message = error.message || (c === 1 ? 'permission denied' : c === 2 ? 'position unavailable' : 'timeout'); 9952 if (this._locateOptions.setView && !this._loaded) { 9953 this.fitWorld(); 9954 } 9955 9956 // @section Location events 9957 // @event locationerror: ErrorEvent 9958 // Fired when geolocation (using the [`locate`](#map-locate) method) failed. 9959 this.fire('locationerror', { 9960 code: c, 9961 message: 'Geolocation error: ' + message + '.' 9962 }); 9963 }, 9964 _handleGeolocationResponse: function _handleGeolocationResponse(pos) { 9965 if (!this._container._leaflet_id) { 9966 return; 9967 } 9968 var lat = pos.coords.latitude, 9969 lng = pos.coords.longitude, 9970 latlng = new LatLng(lat, lng), 9971 bounds = latlng.toBounds(pos.coords.accuracy * 2), 9972 options = this._locateOptions; 9973 if (options.setView) { 9974 var zoom = this.getBoundsZoom(bounds); 9975 this.setView(latlng, options.maxZoom ? Math.min(zoom, options.maxZoom) : zoom); 9976 } 9977 var data = { 9978 latlng: latlng, 9979 bounds: bounds, 9980 timestamp: pos.timestamp 9981 }; 9982 for (var i in pos.coords) { 9983 if (typeof pos.coords[i] === 'number') { 9984 data[i] = pos.coords[i]; 9985 } 9986 } 9987 9988 // @event locationfound: LocationEvent 9989 // Fired when geolocation (using the [`locate`](#map-locate) method) 9990 // went successfully. 9991 this.fire('locationfound', data); 9992 }, 9993 // TODO Appropriate docs section? 9994 // @section Other Methods 9995 // @method addHandler(name: String, HandlerClass: Function): this 9996 // Adds a new `Handler` to the map, given its name and constructor function. 9997 addHandler: function addHandler(name, HandlerClass) { 9998 if (!HandlerClass) { 9999 return this; 10000 } 10001 var handler = this[name] = new HandlerClass(this); 10002 this._handlers.push(handler); 10003 if (this.options[name]) { 10004 handler.enable(); 10005 } 10006 return this; 10007 }, 10008 // @method remove(): this 10009 // Destroys the map and clears all related event listeners. 10010 remove: function remove() { 10011 this._initEvents(true); 10012 if (this.options.maxBounds) { 10013 this.off('moveend', this._panInsideMaxBounds); 10014 } 10015 if (this._containerId !== this._container._leaflet_id) { 10016 throw new Error('Map container is being reused by another instance'); 10017 } 10018 try { 10019 // throws error in IE6-8 10020 delete this._container._leaflet_id; 10021 delete this._containerId; 10022 } catch (e) { 10023 /*eslint-disable */ 10024 this._container._leaflet_id = undefined; 10025 /* eslint-enable */ 10026 this._containerId = undefined; 10027 } 10028 if (this._locationWatchId !== undefined) { 10029 this.stopLocate(); 10030 } 10031 this._stop(); 10032 _remove(this._mapPane); 10033 if (this._clearControlPos) { 10034 this._clearControlPos(); 10035 } 10036 if (this._resizeRequest) {
10037 cancelAnimFrame(this._resizeRequest); 10038 this._resizeRequest = null; 10039 } 10040 this._clearHandlers(); 10041 if (this._loaded) { 10042 // @section Map state change events 10043 // @event unload: Event 10044 // Fired when the map is destroyed with [remove](#map-remove) method. 10045 this.fire('unload'); 10046 } 10047 var i; 10048 for (i in this._layers) { 10049 this._layers[i].remove(); 10050 } 10051 for (i in this._panes) { 10052 _remove(this._panes[i]); 10053 } 10054 this._layers = []; 10055 this._panes = []; 10056 delete this._mapPane; 10057 delete this._renderer; 10058 return this; 10059 }, 10060 // @section Other Methods 10061 // @method createPane(name: String, container?: HTMLElement): HTMLElement 10062 // Creates a new [map pane](#map-pane) with the given name if it doesn't exist already, 10063 // then returns it. The pane is created as a child of `container`, or 10064 // as a child of the main map pane if not set. 10065 createPane: function createPane(name, container) { 10066 var className = 'leaflet-pane' + (name ? ' leaflet-' + name.replace('Pane', '') + '-pane' : ''), 10067 pane = create$1('div', className, container || this._mapPane); 10068 if (name) { 10069 this._panes[name] = pane; 10070 } 10071 return pane; 10072 }, 10073 // @section Methods for Getting Map State 10074 10075 // @method getCenter(): LatLng 10076 // Returns the geographical center of the map view 10077 getCenter: function getCenter() { 10078 this._checkIfLoaded(); 10079 if (this._lastCenter && !this._moved()) { 10080 return this._lastCenter.clone(); 10081 } 10082 return this.layerPointToLatLng(this._getCenterLayerPoint()); 10083 }, 10084 // @method getZoom(): Number 10085 // Returns the current zoom level of the map view 10086 getZoom: function getZoom() { 10087 return this._zoom; 10088 }, 10089 // @method getBounds(): LatLngBounds 10090 // Returns the geographical bounds visible in the current map view 10091 getBounds: function getBounds() { 10092 var bounds = this.getPixelBounds(), 10093 sw = this.unproject(bounds.getBottomLeft()), 10094 ne = this.unproject(bounds.getTopRight()); 10095 return new LatLngBounds(sw, ne); 10096 }, 10097 // @method getMinZoom(): Number 10098 // 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. 10099 getMinZoom: function getMinZoom() { 10100 return this.options.minZoom === undefined ? this._layersMinZoom || 0 : this.options.minZoom; 10101 }, 10102 // @method getMaxZoom(): Number 10103 // Returns the maximum zoom level of the map (if set in the `maxZoom` option of the map or of any layers). 10104 getMaxZoom: function getMaxZoom() { 10105 return this.options.maxZoom === undefined ? this._layersMaxZoom === undefined ? Infinity : this._layersMaxZoom : this.options.maxZoom; 10106 }, 10107 // @method getBoundsZoom(bounds: LatLngBounds, inside?: Boolean, padding?: Point): Number 10108 // Returns the maximum zoom level on which the given bounds fit to the map 10109 // view in its entirety. If `inside` (optional) is set to `true`, the method 10110 // instead returns the minimum zoom level on which the map view fits into 10111 // the given bounds in its entirety. 10112 getBoundsZoom: function getBoundsZoom(bounds, inside, padding) { 10113 // (LatLngBounds[, Boolean, Point]) -> Number 10114 bounds = toLatLngBounds(bounds); 10115 padding = toPoint(padding || [0, 0]); 10116 var zoom = this.getZoom() || 0, 10117 min = this.getMinZoom(), 10118 max = this.getMaxZoom(), 10119 nw = bounds.getNorthWest(), 10120 se = bounds.getSouthEast(), 10121 size = this.getSize().subtract(padding), 10122 boundsSize = toBounds(this.project(se, zoom), this.project(nw, zoom)).getSize(), 10123 snap = Browser.any3d ? this.options.zoomSnap : 1, 10124 scalex = size.x / boundsSize.x,
10125 scaley = size.y / boundsSize.y, 10126 scale = inside ? Math.max(scalex, scaley) : Math.min(scalex, scaley); 10127 zoom = this.getScaleZoom(scale, zoom); 10128 if (snap) { 10129 zoom = Math.round(zoom / (snap / 100)) * (snap / 100); // don't jump if within 1% of a snap level 10130 zoom = inside ? Math.ceil(zoom / snap) * snap : Math.floor(zoom / snap) * snap; 10131 } 10132 return Math.max(min, Math.min(max, zoom)); 10133 }, 10134 // @method getSize(): Point 10135 // Returns the current size of the map container (in pixels). 10136 getSize: function getSize() { 10137 if (!this._size || this._sizeChanged) { 10138 this._size = new Point(this._container.clientWidth || 0, this._container.clientHeight || 0); 10139 this._sizeChanged = false; 10140 } 10141 return this._size.clone(); 10142 }, 10143 // @method getPixelBounds(): Bounds 10144 // Returns the bounds of the current map view in projected pixel 10145 // coordinates (sometimes useful in layer and overlay implementations). 10146 getPixelBounds: function getPixelBounds(center, zoom) { 10147 var topLeftPoint = this._getTopLeftPoint(center, zoom); 10148 return new Bounds(topLeftPoint, topLeftPoint.add(this.getSize())); 10149 }, 10150 // TODO: Check semantics - isn't the pixel origin the 0,0 coord relative to 10151 // the map pane? "left point of the map layer" can be confusing, specially 10152 // since there can be negative offsets. 10153 // @method getPixelOrigin(): Point 10154 // Returns the projected pixel coordinates of the top left point of 10155 // the map layer (useful in custom layer and overlay implementations). 10156 getPixelOrigin: function getPixelOrigin() { 10157 this._checkIfLoaded(); 10158 return this._pixelOrigin; 10159 }, 10160 // @method getPixelWorldBounds(zoom?: Number): Bounds 10161 // Returns the world's bounds in pixel coordinates for zoom level `zoom`. 10162 // If `zoom` is omitted, the map's current zoom level is used. 10163 getPixelWorldBounds: function getPixelWorldBounds(zoom) { 10164 return this.options.crs.getProjectedBounds(zoom === undefined ? this.getZoom() : zoom); 10165 }, 10166 // @section Other Methods 10167 10168 // @method getPane(pane: String|HTMLElement): HTMLElement 10169 // Returns a [map pane](#map-pane), given its name or its HTML element (its identity). 10170 getPane: function getPane(pane) { 10171 return typeof pane === 'string' ? this._panes[pane] : pane; 10172 }, 10173 // @method getPanes(): Object
10174 // Returns a plain object containing the names of all [panes](#map-pane) as keys and 10175 // the panes as values. 10176 getPanes: function getPanes() { 10177 return this._panes; 10178 }, 10179 // @method getContainer: HTMLElement 10180 // Returns the HTML element that contains the map. 10181 getContainer: function getContainer() { 10182 return this._container; 10183 }, 10184 // @section Conversion Methods 10185 10186 // @method getZoomScale(toZoom: Number, fromZoom: Number): Number 10187 // Returns the scale factor to be applied to a map transition from zoom level 10188 // `fromZoom` to `toZoom`. Used internally to help with zoom animations. 10189 getZoomScale: function getZoomScale(toZoom, fromZoom) { 10190 // TODO replace with universal implementation after refactoring projections 10191 var crs = this.options.crs; 10192 fromZoom = fromZoom === undefined ? this._zoom : fromZoom; 10193 return crs.scale(toZoom) / crs.scale(fromZoom); 10194 }, 10195 // @method getScaleZoom(scale: Number, fromZoom: Number): Number 10196 // Returns the zoom level that the map would end up at, if it is at `fromZoom` 10197 // level and everything is scaled by a factor of `scale`. Inverse of 10198 // [`getZoomScale`](#map-getZoomScale). 10199 getScaleZoom: function getScaleZoom(scale, fromZoom) { 10200 var crs = this.options.crs; 10201 fromZoom = fromZoom === undefined ? this._zoom : fromZoom; 10202 var zoom = crs.zoom(scale * crs.scale(fromZoom)); 10203 return isNaN(zoom) ? Infinity : zoom; 10204 }, 10205 // @method project(latlng: LatLng, zoom: Number): Point 10206 // Projects a geographical coordinate `LatLng` according to the projection 10207 // of the map's CRS, then scales it according to `zoom` and the CRS's 10208 // `Transformation`. The result is pixel coordinate relative to 10209 // the CRS origin. 10210 project: function project(latlng, zoom) { 10211 zoom = zoom === undefined ? this._zoom : zoom; 10212 return this.options.crs.latLngToPoint(toLatLng(latlng), zoom); 10213 }, 10214 // @method unproject(point: Point, zoom: Number): LatLng 10215 // Inverse of [`project`](#map-project). 10216 unproject: function unproject(point, zoom) { 10217 zoom = zoom === undefined ? this._zoom : zoom; 10218 return this.options.crs.pointToLatLng(toPoint(point), zoom); 10219 }, 10220 // @method layerPointToLatLng(point: Point): LatLng 10221 // Given a pixel coordinate relative to the [origin pixel](#map-getpixelorigin), 10222 // returns the corresponding geographical coordinate (for the current zoom level). 10223 layerPointToLatLng: function layerPointToLatLng(point) { 10224 var projectedPoint = toPoint(point).add(this.getPixelOrigin()); 10225 return this.unproject(projectedPoint); 10226 }, 10227 // @method latLngToLayerPoint(latlng: LatLng): Point 10228 // Given a geographical coordinate, returns the corresponding pixel coordinate 10229 // relative to the [origin pixel](#map-getpixelorigin). 10230 latLngToLayerPoint: function latLngToLayerPoint(latlng) { 10231 var projectedPoint = this.project(toLatLng(latlng))._round(); 10232 return projectedPoint._subtract(this.getPixelOrigin()); 10233 }, 10234 // @method wrapLatLng(latlng: LatLng): LatLng 10235 // Returns a `LatLng` where `lat` and `lng` has been wrapped according to the 10236 // map's CRS's `wrapLat` and `wrapLng` properties, if they are outside the 10237 // CRS's bounds. 10238 // By default this means longitude is wrapped around the dateline so its 10239 // value is between -180 and +180 degrees. 10240 wrapLatLng: function wrapLatLng(latlng) { 10241 return this.options.crs.wrapLatLng(toLatLng(latlng)); 10242 }, 10243 // @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds 10244 // Returns a `LatLngBounds` with the same size as the given one, ensuring that 10245 // its center is within the CRS's bounds. 10246 // By default this means the center longitude is wrapped around the dateline so its 10247 // value is between -180 and +180 degrees, and the majority of the bounds 10248 // overlaps the CRS's bounds. 10249 wrapLatLngBounds: function wrapLatLngBounds(latlng) { 10250 return this.options.crs.wrapLatLngBounds(toLatLngBounds(latlng)); 10251 }, 10252 // @method distance(latlng1: LatLng, latlng2: LatLng): Number 10253 // Returns the distance between two geographical coordinates according to 10254 // the map's CRS. By default this measures distance in meters. 10255 distance: function distance(latlng1, latlng2) { 10256 return this.options.crs.distance(toLatLng(latlng1), toLatLng(latlng2)); 10257 }, 10258 // @method containerPointToLayerPoint(point: Point): Point 10259 // Given a pixel coordinate relative to the map container, returns the corresponding 10260 // pixel coordinate relative to the [origin pixel](#map-getpixelorigin). 10261 containerPointToLayerPoint: function containerPointToLayerPoint(point) { 10262 // (Point) 10263 return toPoint(point).subtract(this._getMapPanePos()); 10264 }, 10265 // @method layerPointToContainerPoint(point: Point): Point 10266 // Given a pixel coordinate relative to the [origin pixel](#map-getpixelorigin), 10267 // returns the corresponding pixel coordinate relative to the map container. 10268 layerPointToContainerPoint: function layerPointToContainerPoint(point) { 10269 // (Point) 10270 return toPoint(point).add(this._getMapPanePos()); 10271 }, 10272 // @method containerPointToLatLng(point: Point): LatLng 10273 // Given a pixel coordinate relative to the map container, returns 10274 // the corresponding geographical coordinate (for the current zoom level). 10275 containerPointToLatLng: function containerPointToLatLng(point) { 10276 var layerPoint = this.containerPointToLayerPoint(toPoint(point)); 10277 return this.layerPointToLatLng(layerPoint); 10278 }, 10279 // @method latLngToContainerPoint(latlng: LatLng): Point 10280 // Given a geographical coordinate, returns the corresponding pixel coordinate 10281 // relative to the map container. 10282 latLngToContainerPoint: function latLngToContainerPoint(latlng) { 10283 return this.layerPointToContainerPoint(this.latLngToLayerPoint(toLatLng(latlng))); 10284 }, 10285 // @method mouseEventToContainerPoint(ev: MouseEvent): Point 10286 // Given a MouseEvent object, returns the pixel coordinate relative to the 10287 // map container where the event took place. 10288 mouseEventToContainerPoint: function mouseEventToContainerPoint(e) { 10289 return getMousePosition(e, this._container); 10290 }, 10291 // @method mouseEventToLayerPoint(ev: MouseEvent): Point 10292 // Given a MouseEvent object, returns the pixel coordinate relative to 10293 // the [origin pixel](#map-getpixelorigin) where the event took place. 10294 mouseEventToLayerPoint: function mouseEventToLayerPoint(e) { 10295 return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(e)); 10296 }, 10297 // @method mouseEventToLatLng(ev: MouseEvent): LatLng 10298 // Given a MouseEvent object, returns geographical coordinate where the 10299 // event took place. 10300 mouseEventToLatLng: function mouseEventToLatLng(e) { 10301 // (MouseEvent) 10302 return this.layerPointToLatLng(this.mouseEventToLayerPoint(e)); 10303 }, 10304 // map initialization methods 10305 10306 _initContainer: function _initContainer(id) { 10307 var container = this._container = get(id); 10308 if (!container) { 10309 throw new Error('Map container not found.'); 10310 } else if (container._leaflet_id) { 10311 throw new Error('Map container is already initialized.'); 10312 } 10313 on(container, 'scroll', this._onScroll, this); 10314 this._containerId = stamp(container); 10315 }, 10316 _initLayout: function _initLayout() { 10317 var container = this._container; 10318 this._fadeAnimated = this.options.fadeAnimation && Browser.any3d; 10319 addClass(container, 'leaflet-container' + (Browser.touch ? ' leaflet-touch' : '') + (Browser.retina ? ' leaflet-retina' : '') + (Browser.ielt9 ? ' leaflet-oldie' : '') + (Browser.safari ? ' leaflet-safari' : '') + (this._fadeAnimated ? ' leaflet-fade-anim' : '')); 10320 var position = getStyle(container, 'position'); 10321 if (position !== 'absolute' && position !== 'relative' && position !== 'fixed' && position !== 'sticky') { 10322 container.style.position = 'relative'; 10323 } 10324 this._initPanes(); 10325 if (this._initControlPos) { 10326 this._initControlPos(); 10327 } 10328 }, 10329 _initPanes: function _initPanes() { 10330 var panes = this._panes = {}; 10331 this._paneRenderers = {}; 10332 10333 // @section 10334 // 10335 // Panes are DOM elements used to control the ordering of layers on the map. You 10336 // can access panes with [`map.getPane`](#map-getpane) or 10337 // [`map.getPanes`](#map-getpanes) methods. New panes can be created with the 10338 // [`map.createPane`](#map-createpane) method. 10339 // 10340 // Every map has the following default panes that differ only in zIndex. 10341 // 10342 // @pane mapPane: HTMLElement = 'auto'
vendor: 4,258 bytes, lines 10343-10447
10343 // Pane that contains all other map panes 10344 10345 this._mapPane = this.createPane('mapPane', this._container); 10346 setPosition(this._mapPane, new Point(0, 0)); 10347 10348 // @pane tilePane: HTMLElement = 200 10349 // Pane for `GridLayer`s and `TileLayer`s 10350 this.createPane('tilePane'); 10351 // @pane overlayPane: HTMLElement = 400 10352 // Pane for vectors (`Path`s, like `Polyline`s and `Polygon`s), `ImageOverlay`s and `VideoOverlay`s 10353 this.createPane('overlayPane'); 10354 // @pane shadowPane: HTMLElement = 500 10355 // Pane for overlay shadows (e.g. `Marker` shadows) 10356 this.createPane('shadowPane'); 10357 // @pane markerPane: HTMLElement = 600 10358 // Pane for `Icon`s of `Marker`s 10359 this.createPane('markerPane'); 10360 // @pane tooltipPane: HTMLElement = 650 10361 // Pane for `Tooltip`s. 10362 this.createPane('tooltipPane'); 10363 // @pane popupPane: HTMLElement = 700 10364 // Pane for `Popup`s. 10365 this.createPane('popupPane'); 10366 if (!this.options.markerZoomAnimation) { 10367 addClass(panes.markerPane, 'leaflet-zoom-hide'); 10368 addClass(panes.shadowPane, 'leaflet-zoom-hide'); 10369 } 10370 }, 10371 // private methods that modify map state 10372 10373 // @section Map state change events 10374 _resetView: function _resetView(center, zoom, noMoveStart) { 10375 setPosition(this._mapPane, new Point(0, 0)); 10376 var loading = !this._loaded; 10377 this._loaded = true; 10378 zoom = this._limitZoom(zoom); 10379 this.fire('viewprereset'); 10380 var zoomChanged = this._zoom !== zoom; 10381 this._moveStart(zoomChanged, noMoveStart)._move(center, zoom)._moveEnd(zoomChanged); 10382 10383 // @event viewreset: Event 10384 // Fired when the map needs to redraw its content (this usually happens 10385 // on map zoom or load). Very useful for creating custom overlays. 10386 this.fire('viewreset'); 10387 10388 // @event load: Event 10389 // Fired when the map is initialized (when its center and zoom are set 10390 // for the first time). 10391 if (loading) { 10392 this.fire('load'); 10393 } 10394 }, 10395 _moveStart: function _moveStart(zoomChanged, noMoveStart) { 10396 // @event zoomstart: Event 10397 // Fired when the map zoom is about to change (e.g. before zoom animation). 10398 // @event movestart: Event 10399 // Fired when the view of the map starts changing (e.g. user starts dragging the map). 10400 if (zoomChanged) { 10401 this.fire('zoomstart'); 10402 } 10403 if (!noMoveStart) { 10404 this.fire('movestart'); 10405 } 10406 return this; 10407 }, 10408 _move: function _move(center, zoom, data, supressEvent) { 10409 if (zoom === undefined) { 10410 zoom = this._zoom; 10411 } 10412 var zoomChanged = this._zoom !== zoom; 10413 this._zoom = zoom; 10414 this._lastCenter = center; 10415 this._pixelOrigin = this._getNewPixelOrigin(center); 10416 if (!supressEvent) { 10417 // @event zoom: Event 10418 // Fired repeatedly during any change in zoom level, 10419 // including zoom and fly animations. 10420 if (zoomChanged || data && data.pinch) { 10421 // Always fire 'zoom' if pinching because #3530 10422 this.fire('zoom', data); 10423 } 10424 10425 // @event move: Event 10426 // Fired repeatedly during any movement of the map, 10427 // including pan and fly animations. 10428 this.fire('move', data); 10429 } else if (data && data.pinch) { 10430 // Always fire 'zoom' if pinching because #3530 10431 this.fire('zoom', data); 10432 } 10433 return this; 10434 }, 10435 _moveEnd: function _moveEnd(zoomChanged) { 10436 // @event zoomend: Event 10437 // Fired when the map zoom changed, after any animations. 10438 if (zoomChanged) { 10439 this.fire('zoomend'); 10440 } 10441 10442 // @event moveend: Event 10443 // Fired when the center of the map stops changing 10444 // (e.g. user stopped dragging the map or after non-centered zoom). 10445 return this.fire('moveend'); 10446 }, 10447 _stop: function _stop() {
10448 cancelAnimFrame(this._flyToFrame); 10449 if (this._panAnim) { 10450 this._panAnim.stop(); 10451 } 10452 return this; 10453 }, 10454 _rawPanBy: function _rawPanBy(offset) { 10455 setPosition(this._mapPane, this._getMapPanePos().subtract(offset)); 10456 }, 10457 _getZoomSpan: function _getZoomSpan() { 10458 return this.getMaxZoom() - this.getMinZoom(); 10459 }, 10460 _panInsideMaxBounds: function _panInsideMaxBounds() { 10461 if (!this._enforcingBounds) { 10462 this.panInsideBounds(this.options.maxBounds); 10463 } 10464 }, 10465 _checkIfLoaded: function _checkIfLoaded() { 10466 if (!this._loaded) { 10467 throw new Error('Set map center and zoom first.'); 10468 } 10469 }, 10470 // DOM event handling 10471 10472 // @section Interaction events 10473 _initEvents: function _initEvents(remove) { 10474 this._targets = {}; 10475 this._targets[stamp(this._container)] = this; 10476 var onOff = remove ? off : on; 10477 10478 // @event click: MouseEvent 10479 // Fired when the user clicks (or taps) the map. 10480 // @event dblclick: MouseEvent 10481 // Fired when the user double-clicks (or double-taps) the map. 10482 // @event mousedown: MouseEvent 10483 // Fired when the user pushes the mouse button on the map. 10484 // @event mouseup: MouseEvent 10485 // Fired when the user releases the mouse button on the map. 10486 // @event mouseover: MouseEvent 10487 // Fired when the mouse enters the map. 10488 // @event mouseout: MouseEvent 10489 // Fired when the mouse leaves the map. 10490 // @event mousemove: MouseEvent 10491 // Fired while the mouse moves over the map. 10492 // @event contextmenu: MouseEvent 10493 // Fired when the user pushes the right mouse button on the map, prevents 10494 // default browser context menu from showing if there are listeners on 10495 // this event. Also fired on mobile when the user holds a single touch 10496 // for a second (also called long press). 10497 // @event keypress: KeyboardEvent 10498 // Fired when the user presses a key from the keyboard that produces a character value while the map is focused. 10499 // @event keydown: KeyboardEvent 10500 // Fired when the user presses a key from the keyboard while the map is focused. Unlike the `keypress` event, 10501 // the `keydown` event is fired for keys that produce a character value and for keys 10502 // that do not produce a character value. 10503 // @event keyup: KeyboardEvent 10504 // Fired when the user releases a key from the keyboard while the map is focused. 10505 onOff(this._container, 'click dblclick mousedown mouseup ' + 'mouseover mouseout mousemove contextmenu keypress keydown keyup', this._handleDOMEvent, this); 10506 if (this.options.trackResize) { 10507 onOff(window, 'resize', this._onResize, this); 10508 } 10509 if (Browser.any3d && this.options.transform3DLimit) { 10510 (remove ? this.off : this.on).call(this, 'moveend', this._onMoveEnd); 10511 } 10512 }, 10513 _onResize: function _onResize() { 10514 cancelAnimFrame(this._resizeRequest); 10515 this._resizeRequest = requestAnimFrame(function () { 10516 this.invalidateSize({ 10517 debounceMoveend: true 10518 }); 10519 }, this); 10520 }, 10521 _onScroll: function _onScroll() { 10522 this._container.scrollTop = 0; 10523 this._container.scrollLeft = 0; 10524 }, 10525 _onMoveEnd: function _onMoveEnd() { 10526 var pos = this._getMapPanePos(); 10527 if (Math.max(Math.abs(pos.x), Math.abs(pos.y)) >= this.options.transform3DLimit) { 10528 // https://bugzilla.mozilla.org/show_bug.cgi?id=1203873 but Webkit also have 10529 // a pixel offset on very high values, see: https://jsfiddle.net/dg6r5hhb/ 10530 this._resetView(this.getCenter(), this.getZoom()); 10531 } 10532 }, 10533 _findEventTargets: function _findEventTargets(e, type) { 10534 var targets = [], 10535 target, 10536 isHover = type === 'mouseout' || type === 'mouseover', 10537 src = e.target || e.srcElement, 10538 dragging = false;
10539 while (src) { 10540 target = this._targets[stamp(src)]; 10541 if (target && (type === 'click' || type === 'preclick') && this._draggableMoved(target)) { 10542 // Prevent firing click after you just dragged an object. 10543 dragging = true; 10544 break; 10545 } 10546 if (target && target.listens(type, true)) { 10547 if (isHover && !isExternalTarget(src, e)) { 10548 break; 10549 } 10550 targets.push(target); 10551 if (isHover) { 10552 break; 10553 } 10554 } 10555 if (src === this._container) { 10556 break; 10557 } 10558 src = src.parentNode; 10559 } 10560 if (!targets.length && !dragging && !isHover && this.listens(type, true)) { 10561 targets = [this]; 10562 } 10563 return targets; 10564 }, 10565 _isClickDisabled: function _isClickDisabled(el) { 10566 while (el && el !== this._container) { 10567 if (el['_leaflet_disable_click']) { 10568 return true; 10569 } 10570 el = el.parentNode; 10571 } 10572 }, 10573 _handleDOMEvent: function _handleDOMEvent(e) { 10574 var el = e.target || e.srcElement; 10575 if (!this._loaded || el['_leaflet_disable_events'] || e.type === 'click' && this._isClickDisabled(el)) { 10576 return; 10577 } 10578 var type = e.type; 10579 if (type === 'mousedown') { 10580 // prevents outline when clicking on keyboard-focusable element 10581 preventOutline(el); 10582 } 10583 this._fireDOMEvent(e, type); 10584 }, 10585 _mouseEvents: ['click', 'dblclick', 'mouseover', 'mouseout', 'contextmenu'], 10586 _fireDOMEvent: function _fireDOMEvent(e, type, canvasTargets) { 10587 if (e.type === 'click') { 10588 // Fire a synthetic 'preclick' event which propagates up (mainly for closing popups). 10589 // @event preclick: MouseEvent 10590 // Fired before mouse click on the map (sometimes useful when you 10591 // want something to happen on click before any existing click 10592 // handlers start running). 10593 var synth = extend({}, e); 10594 synth.type = 'preclick'; 10595 this._fireDOMEvent(synth, synth.type, canvasTargets); 10596 } 10597 10598 // Find the layer the event is propagating from and its parents. 10599 var targets = this._findEventTargets(e, type); 10600 if (canvasTargets) { 10601 var filtered = []; // pick only targets with listeners 10602 for (var i = 0; i < canvasTargets.length; i++) { 10603 if (canvasTargets[i].listens(type, true)) { 10604 filtered.push(canvasTargets[i]); 10605 } 10606 } 10607 targets = filtered.concat(targets); 10608 } 10609 if (!targets.length) { 10610 return; 10611 } 10612 if (type === 'contextmenu') { 10613 preventDefault(e); 10614 } 10615 var target = targets[0]; 10616 var data = { 10617 originalEvent: e 10618 }; 10619 if (e.type !== 'keypress' && e.type !== 'keydown' && e.type !== 'keyup') { 10620 var isMarker = target.getLatLng && (!target._radius || target._radius <= 10); 10621 data.containerPoint = isMarker ? this.latLngToContainerPoint(target.getLatLng()) : this.mouseEventToContainerPoint(e); 10622 data.layerPoint = this.containerPointToLayerPoint(data.containerPoint); 10623 data.latlng = isMarker ? target.getLatLng() : this.layerPointToLatLng(data.layerPoint); 10624 } 10625 for (i = 0; i < targets.length; i++) { 10626 targets[i].fire(type, data, true); 10627 if (data.originalEvent._stopped || targets[i].options.bubblingMouseEvents === false && indexOf(this._mouseEvents, type) !== -1) { 10628 return; 10629 } 10630 } 10631 }, 10632 _draggableMoved: function _draggableMoved(obj) { 10633 obj = obj.dragging && obj.dragging.enabled() ? obj : this; 10634 return obj.dragging && obj.dragging.moved() || this.boxZoom && this.boxZoom.moved(); 10635 }, 10636 _clearHandlers: function _clearHandlers() { 10637 for (var i = 0, len = this._handlers.length; i < len; i++) { 10638 this._handlers[i].disable(); 10639 } 10640 }, 10641 // @section Other Methods 10642 10643 // @method whenReady(fn: Function, context?: Object): this 10644 // Runs the given function `fn` when the map gets initialized with 10645 // a view (center and zoom) and at least one layer, or immediately 10646 // if it's already initialized, optionally passing a function context. 10647 whenReady: function whenReady(callback, context) { 10648 if (this._loaded) { 10649 callback.call(context || this, { 10650 target: this 10651 }); 10652 } else { 10653 this.on('load', callback, context); 10654 } 10655 return this; 10656 }, 10657 // private methods for getting map state 10658 10659 _getMapPanePos: function _getMapPanePos() { 10660 return getPosition(this._mapPane) || new Point(0, 0); 10661 }, 10662 _moved: function _moved() { 10663 var pos = this._getMapPanePos(); 10664 return pos && !pos.equals([0, 0]); 10665 }, 10666 _getTopLeftPoint: function _getTopLeftPoint(center, zoom) { 10667 var pixelOrigin = center && zoom !== undefined ? this._getNewPixelOrigin(center, zoom) : this.getPixelOrigin(); 10668 return pixelOrigin.subtract(this._getMapPanePos()); 10669 }, 10670 _getNewPixelOrigin: function _getNewPixelOrigin(center, zoom) {
10671 var viewHalf = this.getSize()._divideBy(2); 10672 return this.project(center, zoom)._subtract(viewHalf)._add(this._getMapPanePos())._round(); 10673 }, 10674 _latLngToNewLayerPoint: function _latLngToNewLayerPoint(latlng, zoom, center) { 10675 var topLeft = this._getNewPixelOrigin(center, zoom); 10676 return this.project(latlng, zoom)._subtract(topLeft); 10677 }, 10678 _latLngBoundsToNewLayerBounds: function _latLngBoundsToNewLayerBounds(latLngBounds, zoom, center) { 10679 var topLeft = this._getNewPixelOrigin(center, zoom); 10680 return toBounds([this.project(latLngBounds.getSouthWest(), zoom)._subtract(topLeft), this.project(latLngBounds.getNorthWest(), zoom)._subtract(topLeft), this.project(latLngBounds.getSouthEast(), zoom)._subtract(topLeft), this.project(latLngBounds.getNorthEast(), zoom)._subtract(topLeft)]); 10681 }, 10682 // layer point of the current center 10683 _getCenterLayerPoint: function _getCenterLayerPoint() { 10684 return this.containerPointToLayerPoint(this.getSize()._divideBy(2)); 10685 }, 10686 // offset of the specified place to the current center in pixels 10687 _getCenterOffset: function _getCenterOffset(latlng) { 10688 return this.latLngToLayerPoint(latlng).subtract(this._getCenterLayerPoint()); 10689 }, 10690 // adjust center for view to get inside bounds 10691 _limitCenter: function _limitCenter(center, zoom, bounds) { 10692 if (!bounds) { 10693 return center; 10694 } 10695 var centerPoint = this.project(center, zoom), 10696 viewHalf = this.getSize().divideBy(2),
10697 viewBounds = new Bounds(centerPoint.subtract(viewHalf), centerPoint.add(viewHalf)), 10698 offset = this._getBoundsOffset(viewBounds, bounds, zoom); 10699 10700 // If offset is less than a pixel, ignore. 10701 // This prevents unstable projections from getting into 10702 // an infinite loop of tiny offsets. 10703 if (Math.abs(offset.x) <= 1 && Math.abs(offset.y) <= 1) { 10704 return center; 10705 } 10706 return this.unproject(centerPoint.add(offset), zoom); 10707 }, 10708 // adjust offset for view to get inside bounds 10709 _limitOffset: function _limitOffset(offset, bounds) { 10710 if (!bounds) { 10711 return offset; 10712 } 10713 var viewBounds = this.getPixelBounds(), 10714 newBounds = new Bounds(viewBounds.min.add(offset), viewBounds.max.add(offset)); 10715 return offset.add(this._getBoundsOffset(newBounds, bounds)); 10716 }, 10717 // returns offset needed for pxBounds to get inside maxBounds at a specified zoom 10718 _getBoundsOffset: function _getBoundsOffset(pxBounds, maxBounds, zoom) { 10719 var projectedMaxBounds = toBounds(this.project(maxBounds.getNorthEast(), zoom), this.project(maxBounds.getSouthWest
10719(), zoom)), 10720 minOffset = projectedMaxBounds.min.subtract(pxBounds.min), 10721 maxOffset = projectedMaxBounds.max.subtract(pxBounds.max), 10722 dx = this._rebound(minOffset.x, -maxOffset.x), 10723 dy = this._rebound(minOffset.y, -maxOffset.y); 10724 return new Point(dx, dy); 10725 }, 10726 _rebound: function _rebound(left, right) { 10727 return left + right > 0 ? Math.round(left - right) / 2 : Math.max(0, Math.ceil(left)) - Math.max(0, Math.floor(right)); 10728 }, 10729 _limitZoom: function _limitZoom(zoom) { 10730 var min = this.getMinZoom(), 10731 max = this.getMaxZoom(), 10732 snap = Browser.any3d ? this.options.zoomSnap : 1; 10733 if (snap) { 10734 zoom = Math.round(zoom / snap) * snap; 10735 } 10736 return Math.max(min, Math.min(max, zoom)); 10737 }, 10738 _onPanTransitionStep: function _onPanTransitionStep() { 10739 this.fire('move'); 10740 }, 10741 _onPanTransitionEnd: function _onPanTransitionEnd() { 10742 removeClass(this._mapPane, 'leaflet-pan-anim'); 10743 this.fire('moveend'); 10744 }, 10745 _tryAnimatedPan: function _tryAnimatedPan(center, options) { 10746 // difference between the new and current centers in pixels 10747 var offset = this._getCenterOffset(center)._trunc(); 10748 10749 // don't animate too far unless animate: true specified in options 10750 if ((options && options.animate) !== true && !this.getSize().contains(offset)) { 10751 return false; 10752 } 10753 this.panBy(offset, options); 10754 return true; 10755 }, 10756 _createAnimProxy: function _createAnimProxy() { 10757 var proxy = this._proxy = create$1('div', 'leaflet-proxy leaflet-zoom-animated'); 10758 this._panes.mapPane.appendChild(proxy); 10759 this.on('zoomanim', function (e) { 10760 var prop = TRANSFORM, 10761 transform = this._proxy.style[prop]; 10762 setTransform(this._proxy, this.project(e.center, e.zoom), this.getZoomScale(e.zoom, 1)); 10763 10764 // workaround for case when transform is the same and so transitionend event is not fired 10765 if (transform === this._proxy.style[prop] && this._animatingZoom) { 10766 this._onZoomTransitionEnd(); 10767 } 10768 }, this); 10769 this.on('load moveend', this._animMoveEnd, this); 10770 this._on('unload', this._destroyAnimProxy, this); 10771 }, 10772 _destroyAnimProxy: function _destroyAnimProxy() { 10773 _remove(this._proxy); 10774 this.off('load moveend', this._animMoveEnd, this); 10775 delete this._proxy; 10776 }, 10777 _animMoveEnd: function _animMoveEnd() { 10778 var c = this.getCenter(), 10779 z = this.getZoom(); 10780 setTransform(this._proxy, this.project(c, z), this.getZoomScale(z, 1)); 10781 }, 10782 _catchTransitionEnd: function _catchTransitionEnd(e) { 10783 if (this._animatingZoom && e.propertyName.indexOf('transform') >= 0) { 10784 this._onZoomTransitionEnd(); 10785 } 10786 }, 10787 _nothingToAnimate: function _nothingToAnimate() { 10788 return !this._container.getElementsByClassName('leaflet-zoom-animated').length; 10789 }, 10790 _tryAnimatedZoom: function _tryAnimatedZoom(center, zoom, options) { 10791 if (this._animatingZoom) { 10792 return true; 10793 } 10794 options = options || {}; 10795 10796 // don't animate if disabled, not supported or zoom difference is too large 10797 if (!this._zoomAnimated || options.animate === false || this._nothingToAnimate() || Math.abs(zoom - this._zoom) > this.options.zoomAnimationThreshold) { 10798 return false; 10799 } 10800 10801 // offset is the pixel coords of the zoom origin relative to the current center 10802 var scale = this.getZoomScale(zoom), 10803 offset = this._getCenterOffset(center)._divideBy(1 - 1 / scale); 10804 10805 // don't animate if the zoom origin isn't within one screen from the current center, unless forced 10806 if (options.animate !== true && !this.getSize().contains(offset)) { 10807 return false; 10808 }
vendor: 1,646 bytes, lines 10809-10850
10809 requestAnimFrame(function () { 10810 this._moveStart(true, options.noMoveStart || false)._animateZoom(center, zoom, true); 10811 }, this); 10812 return true; 10813 }, 10814 _animateZoom: function _animateZoom(center, zoom, startAnim, noUpdate) { 10815 if (!this._mapPane) { 10816 return; 10817 } 10818 if (startAnim) { 10819 this._animatingZoom = true; 10820 10821 // remember what center/zoom to set after animation 10822 this._animateToCenter = center; 10823 this._animateToZoom = zoom; 10824 addClass(this._mapPane, 'leaflet-zoom-anim'); 10825 } 10826 10827 // @section Other Events 10828 // @event zoomanim: ZoomAnimEvent 10829 // Fired at least once per zoom animation. For continuous zoom, like pinch zooming, fired once per frame during zoom. 10830 this.fire('zoomanim', { 10831 center: center, 10832 zoom: zoom, 10833 noUpdate: noUpdate 10834 }); 10835 if (!this._tempFireZoomEvent) { 10836 this._tempFireZoomEvent = this._zoom !== this._animateToZoom; 10837 } 10838 this._move(this._animateToCenter, this._animateToZoom, undefined, true); 10839 10840 // Work around webkit not firing 'transitionend', see https://github.com/Leaflet/Leaflet/issues/3689, 2693 10841 setTimeout(bind(this._onZoomTransitionEnd, this), 250); 10842 }, 10843 _onZoomTransitionEnd: function _onZoomTransitionEnd() { 10844 if (!this._animatingZoom) { 10845 return; 10846 } 10847 if (this._mapPane) { 10848 removeClass(this._mapPane, 'leaflet-zoom-anim'); 10849 } 10850 this._animatingZoom = false;
10851 this._move(this._animateToCenter, this._animateToZoom, undefined, true); 10852 if (this._tempFireZoomEvent) { 10853 this.fire('zoom'); 10854 } 10855 delete this._tempFireZoomEvent; 10856 this.fire('move'); 10857 this._moveEnd(true); 10858 } 10859 }); 10860 10861 // @section 10862 10863 // @factory L.map(id: String, options?: Map options) 10864 // Instantiates a map object given the DOM ID of a `<div>` element 10865 // and optionally an object literal with `Map options`. 10866 // 10867 // @alternative 10868 // @factory L.map(el: HTMLElement, options?: Map options) 10869 // Instantiates a map object given an instance of a `<div>` HTML element 10870 // and optionally an object literal with `Map options`. 10871 function createMap(id, options) { 10872 return new Map(id, options); 10873 } 10874 10875 /* 10876 * @class Control 10877 * @aka L.Control 10878 * @inherits Class 10879 * 10880 * L.Control is a base class for implementing map controls. Handles positioning. 10881 * All other controls extend from this class. 10882 */ 10883 10884 var Control = Class.extend({ 10885 // @section 10886 // @aka Control Options 10887 options: { 10888 // @option position: String = 'topright' 10889 // The position of the control (one of the map corners). Possible values are `'topleft'`, 10890 // `'topright'`, `'bottomleft'` or `'bottomright'` 10891 position: 'topright' 10892 }, 10893 initialize: function initialize(options) { 10894 setOptions(this, options); 10895 }, 10896 /* @section 10897 * Classes extending L.Control will inherit the following methods: 10898 * 10899 * @method getPosition: string 10900 * Returns the position of the control. 10901 */ 10902 getPosition: function getPosition() { 10903 return this.options.position; 10904 }, 10905 // @method setPosition(position: string): this 10906 // Sets the position of the control. 10907 setPosition: function setPosition(position) { 10908 var map = this._map; 10909 if (map) { 10910 map.removeControl(this); 10911 } 10912 this.options.position = position; 10913 if (map) { 10914 map.addControl(this); 10915 } 10916 return this; 10917 }, 10918 // @method getContainer: HTMLElement 10919 // Returns the HTMLElement that contains the control. 10920 getContainer: function getContainer() { 10921 return this._container; 10922 }, 10923 // @method addTo(map: Map): this 10924 // Adds the control to the given map. 10925 addTo: function addTo(map) { 10926 this.remove(); 10927 this._map = map; 10928 var container = this._container = this.onAdd(map), 10929 pos = this.getPosition(), 10930 corner = map._controlCorners[pos]; 10931 addClass(container, 'leaflet-control'); 10932 if (pos.indexOf('bottom') !== -1) { 10933 corner.insertBefore(container, corner.firstChild); 10934 } else { 10935 corner.appendChild(container); 10936 } 10937 this._map.on('unload', this.remove, this); 10938 return this; 10939 }, 10940 // @method remove: this 10941 // Removes the control from the map it is currently active on. 10942 remove: function remove() { 10943 if (!this._map) { 10944 return this; 10945 } 10946 _remove(this._container); 10947 if (this.onRemove) { 10948 this.onRemove(this._map); 10949 } 10950 this._map.off('unload', this.remove, this); 10951 this._map = null; 10952 return this; 10953 }, 10954 _refocusOnMap: function _refocusOnMap(e) { 10955 // if map exists and event is not a keyboard event 10956 if (this._map && e && e.screenX > 0 && e.screenY > 0) { 10957 this._map.getContainer().focus(); 10958 } 10959 } 10960 }); 10961 var control = function control(options) { 10962 return new Control(options); 10963 }; 10964 10965 /* @section Extension methods 10966 * @uninheritable 10967 * 10968 * Every control should extend from `L.Control` and (re-)implement the following methods. 10969 * 10970 * @method onAdd(map: Map): HTMLElement 10971 * Should return the container DOM element for the control and add listeners on relevant map events. Called on [`control.addTo(map)`](#control-addTo). 10972 * 10973 * @method onRemove(map: Map) 10974 * Optional method. Should contain all clean up code that removes the listeners previously added in [`onAdd`](#control-onadd). Called on [`control.remove()`](#control-remove). 10975 */ 10976 10977 /* @namespace Map 10978 * @section Methods for Layers and Controls 10979 */ 10980 Map.include({ 10981 // @method addControl(control: Control): this 10982 // Adds the given control to the map 10983 addControl: function addControl(control) { 10984 control.addTo(this); 10985 return this; 10986 }, 10987 // @method removeControl(control: Control): this 10988 // Removes the given control from the map 10989 removeControl: function removeControl(control) { 10990 control.remove(); 10991 return this; 10992 }, 10993 _initControlPos: function _initControlPos() { 10994 var corners = this._controlCorners = {}, 10995 l = 'leaflet-', 10996 container = this._controlContainer = create$1('div', l + 'control-container', this._container); 10997 function createCorner(vSide, hSide) { 10998 var className = l + vSide + ' ' + l + hSide; 10999 corners[vSide + hSide] = create$1('div', className, container); 11000 } 11001 createCorner('top', 'left'); 11002 createCorner('top', 'right'); 11003 createCorner('bottom', 'left'); 11004 createCorner('bottom', 'right'); 11005 }, 11006 _clearControlPos: function _clearControlPos() { 11007 for (var i in this._controlCorners) { 11008 _remove(this._controlCorners[i]); 11009 } 11010 _remove(this._controlContainer); 11011 delete this._controlCorners; 11012 delete this._controlContainer; 11013 } 11014 }); 11015 11016 /* 11017 * @class Control.Layers 11018 * @aka L.Control.Layers 11019 * @inherits Control 11020 * 11021 * The layers control gives users the ability to switch between different base layers and switch overlays on/off (check out the [detailed example](https://leafletjs.com/examples/layers-control/)). Extends `Control`. 11022 * 11023 * @example 11024 * 11025 * ```js 11026 * var baseLayers = { 11027 * "Mapbox": mapbox, 11028 * "OpenStreetMap": osm 11029 * }; 11030 * 11031 * var overlays = { 11032 * "Marker": marker, 11033 * "Roads": roadsLayer 11034 * }; 11035 * 11036 * L.control.layers(baseLayers, overlays).addTo(map); 11037 * ``` 11038 * 11039 * The `baseLayers` and `overlays` parameters are object literals with layer names as keys and `Layer` objects as values: 11040 * 11041 * ```js 11042 * { 11043 * "<someName1>": layer1, 11044 * "<someName2>": layer2 11045 * } 11046 * ``` 11047 * 11048 * The layer names can contain HTML, which allows you to add additional styling to the items: 11049 * 11050 * ```js 11051 * {"<img src='my-layer-icon' /> <span class='my-layer-item'>
11051My Layer</span>": myLayer} 11052 * ``` 11053 */ 11054 11055 var Layers = Control.extend({ 11056 // @section 11057 // @aka Control.Layers options 11058 options: { 11059 // @option collapsed: Boolean = true 11060 // If `true`, the control will be collapsed into an icon and expanded on mouse hover, touch, or keyboard activation. 11061 collapsed: true, 11062 position: 'topright', 11063 // @option autoZIndex: Boolean = true 11064 // 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. 11065 autoZIndex: true, 11066 // @option hideSingleBase: Boolean = false 11067 // If `true`, the base layers in the control will be hidden when there is only one. 11068 hideSingleBase: false, 11069 // @option sortLayers: Boolean = false 11070 // Whether to sort the layers. When `false`, layers will keep the order 11071 // in which they were added to the control. 11072 sortLayers: false, 11073 // @option sortFunction: Function = * 11074 // A [compare function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 11075 // that will be used for sorting the layers, when `sortLayers` is `true`. 11076 // The function receives both the `L.Layer` instances and their names, as in 11077 // `sortFunction(layerA, layerB, nameA, nameB)`. 11078 // By default, it sorts layers alphabetically by their name. 11079 sortFunction: function sortFunction(layerA, layerB, nameA, nameB) { 11080 return nameA < nameB ? -1 : nameB < nameA ? 1 : 0; 11081 } 11082 }, 11083 initialize: function initialize(baseLayers, overlays, options) { 11084 setOptions(this, options); 11085 this._layerControlInputs = []; 11086 this._layers = []; 11087 this._lastZIndex = 0; 11088 this._handlingClick = false; 11089 this._preventClick = false; 11090 for (var i in baseLayers) { 11091 this._addLayer(baseLayers[i], i); 11092 } 11093 for (i in overlays) { 11094 this._addLayer(overlays[i], i, true); 11095 } 11096 }, 11097 onAdd: function onAdd(map) { 11098 this._initLayout(); 11099 this._update(); 11100 this._map = map; 11101 map.on('zoomend', this._checkDisabledLayers, this); 11102 for (var i = 0; i < this._layers.length; i++) { 11103 this._layers[i].layer.on('add remove', this._onLayerChange, this); 11104 } 11105 return this._container; 11106 }, 11107 addTo: function addTo(map) { 11108 Control.prototype.addTo.call(this, map); 11109 // Trigger expand after Layers Control has been inserted into DOM so that is now has an actual height. 11110 return this._expandIfNotCollapsed(); 11111 }, 11112 onRemove: function onRemove() { 11113 this._map.off('zoomend', this._checkDisabledLayers, this); 11114 for (var i = 0; i < this._layers.length; i++) { 11115 this._layers[i].layer.off('add remove', this._onLayerChange, this); 11116 } 11117 }, 11118 // @method addBaseLayer(layer: Layer, name: String): this 11119 // Adds a base layer (radio button entry) with the given name to the control. 11120 addBaseLayer: function addBaseLayer(layer, name) { 11121 this._addLayer(layer, name); 11122 return this._map ? this._update() : this; 11123 }, 11124 // @method addOverlay(layer: Layer, name: String): this 11125 // Adds an overlay (checkbox entry) with the given name to the control. 11126 addOverlay: function addOverlay(layer, name) { 11127 this._addLayer(layer, name, true); 11128 return this._map ? this._update() : this; 11129 }, 11130 // @method removeLayer(layer: Layer): this 11131 // Remove the given layer from the control. 11132 removeLayer: function removeLayer(layer) { 11133 layer.off('add remove', this._onLayerChange, this); 11134 var obj = this._getLayer(stamp(layer)); 11135 if (obj) { 11136 this._layers.splice(this._layers.indexOf(obj), 1); 11137 } 11138 return this._map ? this._update() : this; 11139 }, 11140 // @method expand(): this 11141 // Expand the control container if collapsed. 11142 expand: function expand() { 11143 addClass(this._container, 'leaflet-control-layers-expanded'); 11144 this._section.style.height = null; 11145 var acceptableHeight = this._map.getSize().y - (this._container.offsetTop + 50); 11146 if (acceptableHeight < this._section.clientHeight) { 11147 addClass(this._section, 'leaflet-control-layers-scrollbar'); 11148 this._section.style.height = acceptableHeight + 'px'; 11149 } else { 11150 removeClass(this._section, 'leaflet-control-layers-scrollbar'); 11151 } 11152 this._checkDisabledLayers(); 11153 return this; 11154 }, 11155 // @method collapse(): this 11156 // Collapse the control container if expanded. 11157 collapse: function collapse() { 11158 removeClass(this._container, 'leaflet-control-layers-expanded'); 11159 return this; 11160 }, 11161 _initLayout: function _initLayout() { 11162 var className = 'leaflet-control-layers', 11163 container = this._container = create$1('div', className), 11164 collapsed = this.options.collapsed; 11165 11166 // makes this work on IE touch devices by stopping it from firing a mouseout event when the touch is released 11167 container.setAttribute('aria-haspopup', true); 11168 disableClickPropagation(container); 11169 disableScrollPropagation(container); 11170 var section = this._section = create$1('section', className + '-list'); 11171 if (collapsed) { 11172 this._map.on('click', this.collapse, this); 11173 on(container, { 11174 mouseenter: this._expandSafely, 11175 mouseleave: this.collapse 11176 }, this); 11177 } 11178 var link = this._layersLink = create$1('a', className + '-toggle', container); 11179 link.href = '#'; 11180 link.title = 'Layers'; 11181 link.setAttribute('role', 'button'); 11182 on(link, { 11183 keydown: function keydown(e) { 11184 if (e.keyCode === 13) { 11185 this._expandSafely(); 11186 } 11187 }, 11188 // Certain screen readers intercept the key event and instead send a click event 11189 click: function click(e) { 11190 preventDefault(e); 11191 this._expandSafely(); 11192 } 11193 }, this); 11194 if (!collapsed) { 11195 this.expand(); 11196 } 11197 this._baseLayersList = create$1('div', className + '-base', section); 11198 this._separator = create$1('div', className + '-separator', section); 11199 this._overlaysList = create$1('div', className + '-overlays', section); 11200 container.appendChild(section); 11201 }, 11202 _getLayer: function _getLayer(id) { 11203 for (var i = 0; i < this._layers.length; i++) { 11204 if (this._layers[i] && stamp(this._layers[i].layer) === id) { 11205 return this._layers[i]; 11206 } 11207 } 11208 }, 11209 _addLayer: function _addLayer(layer, name, overlay) { 11210 if (this._map) { 11211 layer.on('add remove', this._onLayerChange, this); 11212 } 11213 this._layers.push({ 11214 layer: layer, 11215 name: name, 11216 overlay: overlay 11217 }); 11218 if (this.options.sortLayers) { 11219 this._layers.sort(bind(function (a, b) { 11220 return this.options.sortFunction(a.layer, b.layer, a.name, b.name); 11221 }, this)); 11222 }
11223 if (this.options.autoZIndex && layer.setZIndex) { 11224 this._lastZIndex++; 11225 layer.setZIndex(this._lastZIndex); 11226 } 11227 this._expandIfNotCollapsed(); 11228 }, 11229 _update: function _update() { 11230 if (!this._container) { 11231 return this; 11232 } 11233 empty(this._baseLayersList); 11234 empty(this._overlaysList); 11235 this._layerControlInputs = []; 11236 var baseLayersPresent, 11237 overlaysPresent, 11238 i, 11239 obj, 11240 baseLayersCount = 0; 11241 for (i = 0; i < this._layers.length; i++) { 11242 obj = this._layers[i]; 11243 this._addItem(obj); 11244 overlaysPresent = overlaysPresent || obj.overlay; 11245 baseLayersPresent = baseLayersPresent || !obj.overlay; 11246 baseLayersCount += !obj.overlay ? 1 : 0; 11247 } 11248 11249 // Hide base layers section if there's only one layer. 11250 if (this.options.hideSingleBase) { 11251 baseLayersPresent = baseLayersPresent && baseLayersCount > 1; 11252 this._baseLayersList.style.display = baseLayersPresent ? '' : 'none'; 11253 } 11254 this._separator.style.display = overlaysPresent && baseLayersPresent ? '' : 'none'; 11255 return this; 11256 }, 11257 _onLayerChange: function _onLayerChange(e) { 11258 if (!this._handlingClick) { 11259 this._update(); 11260 } 11261 var obj = this._getLayer(stamp(e.target)); 11262 11263 // @namespace Map 11264 // @section Layer events 11265 // @event baselayerchange: LayersControlEvent 11266 // Fired when the base layer is changed through the [layers control](#control-layers). 11267 // @event overlayadd: LayersControlEvent 11268 // Fired when an overlay is selected through the [layers control](#control-layers). 11269 // @event overlayremove: LayersControlEvent 11270 // Fired when an overlay is deselected through the [layers control](#control-layers). 11271 // @namespace Control.Layers 11272 var type = obj.overlay ? e.type === 'add' ? 'overlayadd' : 'overlayremove' : e.type === 'add' ? 'baselayerchange' : null; 11273 if (type) { 11274 this._map.fire(type, obj); 11275 } 11276 }, 11277 // IE7 bugs out if you create a radio dynamically, so you have to do it this hacky way (see https://stackoverflow.com/a/119079) 11278 _createRadioElement: function _createRadioElement(name, checked) { 11279 var radioHtml = '<input type="radio" class="leaflet-control-layers-selector" name="' + name + '"' + (checked ? ' checked="checked"' : '') + '/>'; 11280 var radioFragment = document.createElement('div'); 11281 radioFragment.innerHTML = radioHtml; 11282 return radioFragment.firstChild; 11283 }, 11284 _addItem: function _addItem(obj) { 11285 var label = document.createElement('label'), 11286 checked = this._map.hasLayer(obj.layer), 11287 input; 11288 if (obj.overlay) { 11289 input = document.createElement('input'); 11290 input.type = 'checkbox'; 11291 input.className = 'leaflet-control-layers-selector'; 11292 input.defaultChecked = checked; 11293 } else { 11294 input = this._createRadioElement('leaflet-base-layers_' + stamp(this), checked); 11295 } 11296 this._layerControlInputs.push(input); 11297 input.layerId = stamp(obj.layer); 11298 on(input, 'click', this._onInputClick, this); 11299 var name = document.createElement('span'); 11300 name.innerHTML = ' ' + obj.name; 11301 11302 // Helps from preventing layer control flicker when checkboxes are disabled 11303 // https://github.com/Leaflet/Leaflet/issues/2771 11304 var holder = document.createElement('span'); 11305 label.appendChild(holder); 11306 holder.appendChild(input); 11307 holder.appendChild(name); 11308 var container = obj.overlay ? this._overlaysList : this._baseLayersList; 11309 container.appendChild(label); 11310 this._checkDisabledLayers(); 11311 return label; 11312 }, 11313 _onInputClick: function _onInputClick() { 11314 // expanding the control on mobile with a click can cause adding a layer - we don't want this 11315 if (this._preventClick) { 11316 return; 11317 } 11318 var inputs = this._layerControlInputs, 11319 input, 11320 layer; 11321 var addedLayers = [], 11322 removedLayers = []; 11323 this._handlingClick = true;
11324 for (var i = inputs.length - 1; i >= 0; i--) { 11325 input = inputs[i]; 11326 layer = this._getLayer(input.layerId).layer; 11327 if (input.checked) { 11328 addedLayers.push(layer); 11329 } else if (!input.checked) { 11330 removedLayers.push(layer); 11331 } 11332 } 11333 11334 // Bugfix issue 2318: Should remove all old layers before readding new ones 11335 for (i = 0; i < removedLayers.length; i++) { 11336 if (this._map.hasLayer(removedLayers[i])) { 11337 this._map.removeLayer(removedLayers[i]); 11338 } 11339 } 11340 for (i = 0; i < addedLayers.length; i++) { 11341 if (!this._map.hasLayer(addedLayers[i])) { 11342 this._map.addLayer(addedLayers[i]); 11343 } 11344 } 11345 this._handlingClick = false; 11346 this._refocusOnMap(); 11347 }, 11348 _checkDisabledLayers: function _checkDisabledLayers() { 11349 var inputs = this._layerControlInputs, 11350 input, 11351 layer, 11352 zoom = this._map.getZoom(); 11353 for (var i = inputs.length - 1; i >= 0; i--) { 11354 input = inputs[i]; 11355 layer = this._getLayer(input.layerId).layer; 11356 input.disabled = layer.options.minZoom !== undefined && zoom < layer.options.minZoom || layer.options.maxZoom !== undefined && zoom > layer.options.maxZoom; 11357 } 11358 }, 11359 _expandIfNotCollapsed: function _expandIfNotCollapsed() { 11360 if (this._map && !this.options.collapsed) { 11361 this.expand(); 11362 } 11363 return this; 11364 }, 11365 _expandSafely: function _expandSafely() { 11366 var section = this._section; 11367 this._preventClick = true; 11368 on(section, 'click', preventDefault); 11369 this.expand(); 11370 var that = this; 11371 setTimeout(function () { 11372 off(section, 'click', preventDefault); 11373 that._preventClick = false; 11374 }); 11375 } 11376 }); 11377 11378 // @factory L.control.layers(baselayers?: Object, overlays?: Object, options?: Control.Layers options) 11379 // 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. 11380 var layers = function layers(baseLayers, overlays, options) { 11381 return new Layers(baseLayers, overlays, options); 11382 }; 11383 11384 /* 11385 * @class Control.Zoom 11386 * @aka L.Control.Zoom 11387 * @inherits Control 11388 * 11389 * 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`. 11390 */ 11391 11392 var Zoom = Control.extend({ 11393 // @section 11394 // @aka Control.Zoom options 11395 options: { 11396 position: 'topleft', 11397 // @option zoomInText: String = '<span aria-hidden="true">+</span>' 11398 // The text set on the 'zoom in' button. 11399 zoomInText: '<span aria-hidden="true">+</span>', 11400 // @option zoomInTitle: String = 'Zoom in' 11401 // The title set on the 'zoom in' button. 11402 zoomInTitle: 'Zoom in', 11403 // @option zoomOutText: String = '<span aria-hidden="true">−</span>' 11404 // The text set on the 'zoom out' button. 11405 zoomOutText: '<span aria-hidden="true">−</span>', 11406 // @option zoomOutTitle: String = 'Zoom out' 11407 // The title set on the 'zoom out' button. 11408 zoomOutTitle: 'Zoom out' 11409 }, 11410 onAdd: function onAdd(map) { 11411 var zoomName = 'leaflet-control-zoom', 11412 container = create$1('div', zoomName + ' leaflet-bar'), 11413 options = this.options; 11414 this._zoomInButton = this._createButton(options.zoomInText, options.zoomInTitle, zoomName + '-in', container, this._zoomIn); 11415 this._zoomOutButton = this._createButton(options.zoomOutText, options.zoomOutTitle, zoomName + '-out', container, this._zoomOut); 11416 this._updateDisabled(); 11417 map.on('zoomend zoomlevelschange', this._updateDisabled, this); 11418 return container; 11419 }, 11420 onRemove: function onRemove(map) { 11421 map.off('zoomend zoomlevelschange', this._updateDisabled, this); 11422 }, 11423 disable: function disable() { 11424 this._disabled = true; 11425 this._updateDisabled(); 11426 return this; 11427 }, 11428 enable: function enable() { 11429 this._disabled = false;
11430 this._updateDisabled(); 11431 return this; 11432 }, 11433 _zoomIn: function _zoomIn(e) { 11434 if (!this._disabled && this._map._zoom < this._map.getMaxZoom()) { 11435 this._map.zoomIn(this._map.options.zoomDelta * (e.shiftKey ? 3 : 1)); 11436 } 11437 }, 11438 _zoomOut: function _zoomOut(e) { 11439 if (!this._disabled && this._map._zoom > this._map.getMinZoom()) { 11440 this._map.zoomOut(this._map.options.zoomDelta * (e.shiftKey ? 3 : 1)); 11441 } 11442 }, 11443 _createButton: function _createButton(html, title, className, container, fn) { 11444 var link = create$1('a', className, container); 11445 link.innerHTML = html; 11446 link.href = '#'; 11447 link.title = title; 11448 11449 /* 11450 * Will force screen readers like VoiceOver to read this as "Zoom in - button" 11451 */ 11452 link.setAttribute('role', 'button'); 11453 link.setAttribute('aria-label', title); 11454 disableClickPropagation(link); 11455 on(link, 'click', stop); 11456 on(link, 'click', fn, this); 11457 on(link, 'click', this._refocusOnMap, this); 11458 return link; 11459 }, 11460 _updateDisabled: function _updateDisabled() { 11461 var map = this._map, 11462 className = 'leaflet-disabled'; 11463 removeClass(this._zoomInButton, className); 11464 removeClass(this._zoomOutButton, className); 11465 this._zoomInButton.setAttribute('aria-disabled', 'false'); 11466 this._zoomOutButton.setAttribute('aria-disabled', 'false'); 11467 if (this._disabled || map._zoom === map.getMinZoom()) { 11468 addClass(this._zoomOutButton, className); 11469 this._zoomOutButton.setAttribute('aria-disabled', 'true'); 11470 } 11471 if (this._disabled || map._zoom === map.getMaxZoom()) { 11472 addClass(this._zoomInButton, className); 11473 this._zoomInButton.setAttribute('aria-disabled', 'true'); 11474 } 11475 } 11476 }); 11477 11478 // @namespace Map 11479 // @section Control options 11480 // @option zoomControl: Boolean = true 11481 // Whether a [zoom control](#control-zoom) is added to the map by default. 11482 Map.mergeOptions({ 11483 zoomControl: true 11484 }); 11485 Map.addInitHook(function () { 11486 if (this.options.zoomControl) { 11487 // @section Controls 11488 // @property zoomControl: Control.Zoom 11489 // The default zoom control (only available if the 11490 // [`zoomControl` option](#map-zoomcontrol) was `true` when creating the map). 11491 this.zoomControl = new Zoom(); 11492 this.addControl(this.zoomControl); 11493 } 11494 }); 11495 11496 // @namespace Control.Zoom 11497 // @factory L.control.zoom(options: Control.Zoom options) 11498 // Creates a zoom control 11499 var zoom = function zoom(options) { 11500 return new Zoom(options); 11501 }; 11502 11503 /* 11504 * @class Control.Scale 11505 * @aka L.Control.Scale 11506 * @inherits Control 11507 * 11508 * 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`. 11509 * 11510 * @example 11511 * 11512 * ```js 11513 * L.control.scale().addTo(map); 11514 * ``` 11515 */ 11516 11517 var Scale = Control.extend({ 11518 // @section 11519 // @aka Control.Scale options 11520 options: { 11521 position: 'bottomleft', 11522 // @option maxWidth: Number = 100 11523 // Maximum width of the control in pixels. The width is set dynamically to show round values (e.g. 100, 200, 500). 11524 maxWidth: 100, 11525 // @option metric: Boolean = True 11526 // Whether to show the metric scale line (m/km). 11527 metric: true, 11528 // @option imperial: Boolean = True 11529 // Whether to show the imperial scale line (mi/ft). 11530 imperial: true 11531 11532 // @option updateWhenIdle: Boolean = false 11533 // If `true`, the control is updated on [`moveend`](#map-moveend), otherwise it's always up-to-date (updated on [`move`](#map-move)). 11534 }, 11535 onAdd: function onAdd(map) { 11536 var className = 'leaflet-control-scale', 11537 container = create$1('div', className), 11538 options = this.options; 11539 this._addScales(options, className + '-line', container); 11540 map.on(options.updateWhenIdle ? 'moveend' : 'move', this._update, this); 11541 map.whenReady(this._update, this); 11542 return container; 11543 }, 11544 onRemove: function onRemove(map) { 11545 map.off(this.options.updateWhenIdle ? 'moveend' : 'move', this._update, this); 11546 }, 11547 _addScales: function _addScales(options, className, container) { 11548 if (options.metric) { 11549 this._mScale = create$1('div', className, container); 11550 } 11551 if (options.imperial) { 11552 this._iScale = create$1('div', className, container); 11553 } 11554 }, 11555 _update: function _update() { 11556 var map = this._map, 11557 y = map.getSize().y / 2; 11558 var maxMeters = map.distance(map.containerPointToLatLng([0, y]), map.containerPointToLatLng([this.options.maxWidth, y])); 11559 this._updateScales(maxMeters); 11560 }, 11561 _updateScales: function _updateScales(maxMeters) { 11562 if (this.options.metric && maxMeters) { 11563 this._updateMetric(maxMeters); 11564 } 11565 if (this.options.imperial && maxMeters) { 11566 this._updateImperial(maxMeters); 11567 } 11568 }, 11569 _updateMetric: function _updateMetric(maxMeters) { 11570 var meters = this._getRoundNum(maxMeters), 11571 label = meters < 1000 ? meters + ' m' : meters / 1000 + ' km'; 11572 this._updateScale(this._mScale, label, meters / maxMeters); 11573 }, 11574 _updateImperial: function _updateImperial(maxMeters) { 11575 var maxFeet = maxMeters * 3.2808399, 11576 maxMiles, 11577 miles, 11578 feet; 11579 if (maxFeet > 5280) { 11580 maxMiles = maxFeet / 5280; 11581 miles = this._getRoundNum(maxMiles); 11582 this._updateScale(this._iScale, miles + ' mi', miles / max
vendor: 32,690 bytes, lines 11582-12450
11582Miles); 11583 } else { 11584 feet = this._getRoundNum(maxFeet); 11585 this._updateScale(this._iScale, feet + ' ft', feet / maxFeet); 11586 } 11587 }, 11588 _updateScale: function _updateScale(scale, text, ratio) { 11589 scale.style.width = Math.round(this.options.maxWidth * ratio) + 'px'; 11590 scale.innerHTML = text; 11591 }, 11592 _getRoundNum: function _getRoundNum(num) { 11593 var pow10 = Math.pow(10, (Math.floor(num) + '').length - 1), 11594 d = num / pow10; 11595 d = d >= 10 ? 10 : d >= 5 ? 5 : d >= 3 ? 3 : d >= 2 ? 2 : 1; 11596 return pow10 * d; 11597 } 11598 }); 11599 11600 // @factory L.control.scale(options?: Control.Scale options) 11601 // Creates an scale control with the given options. 11602 var scale = function scale(options) { 11603 return new Scale(options); 11604 }; 11605 var ukrainianFlag = '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="12" height="8" viewBox="0 0 12 8" class="leaflet-attribution-flag"><path fill="#4C7BE1" d="M0 0h12v4H0z"/><path fill="#FFD500" d="M0 4h12v3H0z"/><path fill="#E0BC00" d="M0 7h12v1H0z"/></svg>'; 11606 11607 /* 11608 * @class Control.Attribution 11609 * @aka L.Control.Attribution 11610 * @inherits Control 11611 * 11612 * 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. 11613 */ 11614 11615 var Attribution = Control.extend({ 11616 // @section 11617 // @aka Control.Attribution options 11618 options: { 11619 position: 'bottomright', 11620 // @option prefix: String|false = 'Leaflet' 11621 // The HTML text shown before the attributions. Pass `false` to disable. 11622 prefix: '<a href="https://leafletjs.com" title="A JavaScript library for interactive maps">' + (Browser.inlineSvg ? ukrainianFlag + ' ' : '') + 'Leaflet</a>' 11623 }, 11624 initialize: function initialize(options) { 11625 setOptions(this, options); 11626 this._attributions = {}; 11627 }, 11628 onAdd: function onAdd(map) { 11629 map.attributionControl = this; 11630 this._container = create$1('div', 'leaflet-control-attribution'); 11631 disableClickPropagation(this._container); 11632 11633 // TODO ugly, refactor 11634 for (var i in map._layers) { 11635 if (map._layers[i].getAttribution) { 11636 this.addAttribution(map._layers[i].getAttribution()); 11637 } 11638 } 11639 this._update(); 11640 map.on('layeradd', this._addAttribution, this); 11641 return this._container; 11642 }, 11643 onRemove: function onRemove(map) { 11644 map.off('layeradd', this._addAttribution, this); 11645 }, 11646 _addAttribution: function _addAttribution(ev) { 11647 if (ev.layer.getAttribution) { 11648 this.addAttribution(ev.layer.getAttribution()); 11649 ev.layer.once('remove', function () { 11650 this.removeAttribution(ev.layer.getAttribution()); 11651 }, this); 11652 } 11653 }, 11654 // @method setPrefix(prefix: String|false): this 11655 // The HTML text shown before the attributions. Pass `false` to disable. 11656 setPrefix: function setPrefix(prefix) { 11657 this.options.prefix = prefix; 11658 this._update(); 11659 return this; 11660 }, 11661 // @method addAttribution(text: String): this 11662 // Adds an attribution text (e.g. `'© OpenStreetMap contributors'`). 11663 addAttribution: function addAttribution(text) { 11664 if (!text) { 11665 return this; 11666 } 11667 if (!this._attributions[text]) { 11668 this._attributions[text] = 0; 11669 } 11670 this._attributions[text]++; 11671 this._update(); 11672 return this; 11673 }, 11674 // @method removeAttribution(text: String): this 11675 // Removes an attribution text. 11676 removeAttribution: function removeAttribution(text) { 11677 if (!text) { 11678 return this; 11679 } 11680 if (this._attributions[text]) { 11681 this._attributions[text]--; 11682 this._update(); 11683 } 11684 return this; 11685 }, 11686 _update: function _update() { 11687 if (!this._map) { 11688 return; 11689 } 11690 var attribs = []; 11691 for (var i in this._attributions) { 11692 if (this._attributions[i]) { 11693 attribs.push(i); 11694 } 11695 } 11696 var prefixAndAttribs = []; 11697 if (this.options.prefix) { 11698 prefixAndAttribs.push(this.options.prefix); 11699 } 11700 if (attribs.length) { 11701 prefixAndAttribs.push(attribs.join(', ')); 11702 } 11703 this._container.innerHTML = prefixAndAttribs.join(' <span aria-hidden="true">|</span> '); 11704 } 11705 }); 11706 11707 // @namespace Map 11708 // @section Control options 11709 // @option attributionControl: Boolean = true 11710 // Whether a [attribution control](#control-attribution) is added to the map by default. 11711 Map.mergeOptions({ 11712 attributionControl: true 11713 }); 11714 Map.addInitHook(function () { 11715 if (this.options.attributionControl) { 11716 new Attribution().addTo(this); 11717 } 11718 }); 11719 11720 // @namespace Control.Attribution 11721 // @factory L.control.attribution(options: Control.Attribution options) 11722 // Creates an attribution control. 11723 var attribution = function attribution(options) { 11724 return new Attribution(options); 11725 }; 11726 Control.Layers = Layers; 11727 Control.Zoom = Zoom; 11728 Control.Scale = Scale; 11729 Control.Attribution = Attribution; 11730 control.layers = layers; 11731 control.zoom = zoom; 11732 control.scale = scale; 11733 control.attribution = attribution; 11734 11735 /* 11736 L.Handler is a base class for handler classes that are used internally to inject 11737 interaction features like dragging to classes like Map and Marker. 11738 */ 11739 11740 // @class Handler 11741 // @aka L.Handler 11742 // Abstract class for map interaction handlers 11743 11744 var Handler = Class.extend({ 11745 initialize: function initialize(map) { 11746 this._map = map; 11747 }, 11748 // @method enable(): this 11749 // Enables the handler 11750 enable: function enable() { 11751 if (this._enabled) { 11752 return this; 11753 } 11754 this._enabled = true; 11755 this.addHooks(); 11756 return this; 11757 }, 11758 // @method disable(): this 11759 // Disables the handler 11760 disable: function disable() { 11761 if (!this._enabled) { 11762 return this; 11763 } 11764 this._enabled = false; 11765 this.removeHooks(); 11766 return this; 11767 }, 11768 // @method enabled(): Boolean 11769 // Returns `true` if the handler is enabled 11770 enabled: function enabled() { 11771 return !!this._enabled; 11772 } 11773 11774 // @section Extension methods 11775 // Classes inheriting from `Handler` must implement the two following methods: 11776 // @method addHooks() 11777 // Called when the handler is enabled, should add event hooks. 11778 // @method removeHooks() 11779 // Called when the handler is disabled, should remove the event hooks added previously. 11780 }); 11781 11782 // @section There is static function which can be called without instantiating L.Handler: 11783 // @function addTo(map: Map, name: String): this 11784 // Adds a new Handler to the given map with the given name. 11785 Handler.addTo = function (map, name) { 11786 map.addHandler(name, this); 11787 return this; 11788 }; 11789 var Mixin = { 11790 Events: Events 11791 }; 11792 11793 /* 11794 * @class Draggable 11795 * @aka L.Draggable 11796 * @inherits Evented 11797 * 11798 * A class for making DOM elements draggable (including touch support). 11799 * Used internally for map and marker dragging. Only works for elements 11800 * that were positioned with [`L.DomUtil.setPosition`](#domutil-setposition). 11801 * 11802 * @example 11803 * ```js 11804 * var draggable = new L.Draggable(elementToDrag); 11805 * draggable.enable(); 11806 * ``` 11807 */ 11808 11809 var START = Browser.touch ? 'touchstart mousedown' : 'mousedown'; 11810 var Draggable = Evented.extend({ 11811 options: { 11812 // @section 11813 // @aka Draggable options 11814 // @option clickTolerance: Number = 3 11815 // The max number of pixels a user can shift the mouse pointer during a click 11816 // for it to be considered a valid click (as opposed to a mouse drag). 11817 clickTolerance: 3 11818 }, 11819 // @constructor L.Draggable(el: HTMLElement, dragHandle?: HTMLElement, preventOutline?: Boolean, options?: Draggable options) 11820 // Creates a `Draggable` object for moving `el` when you start dragging the `dragHandle` element (equals `el` itself by default). 11821 initialize: function initialize(element, dragStartTarget, preventOutline, options) { 11822 setOptions(this, options); 11823 this._element = element; 11824 this._dragStartTarget = dragStartTarget || element; 11825 this._preventOutline = preventOutline; 11826 }, 11827 // @method enable() 11828 // Enables the dragging ability 11829 enable: function enable() { 11830 if (this._enabled) { 11831 return; 11832 } 11833 on(this._dragStartTarget, START, this._onDown, this); 11834 this._enabled = true; 11835 }, 11836 // @method disable() 11837 // Disables the dragging ability 11838 disable: function disable() { 11839 if (!this._enabled) { 11840 return; 11841 } 11842 11843 // If we're currently dragging this draggable, 11844 // disabling it counts as first ending the drag. 11845 if (Draggable._dragging === this) { 11846 this.finishDrag(true); 11847 } 11848 off(this._dragStartTarget, START, this._onDown, this); 11849 this._enabled = false; 11850 this._moved = false; 11851 }, 11852 _onDown: function _onDown(e) { 11853 // Ignore the event if disabled; this happens in IE11 11854 // under some circumstances, see #3666. 11855 if (!this._enabled) { 11856 return; 11857 } 11858 this._moved = false; 11859 if (hasClass(this._element, 'leaflet-zoom-anim')) { 11860 return; 11861 } 11862 if (e.touches && e.touches.length !== 1) { 11863 // Finish dragging to avoid conflict with touchZoom 11864 if (Draggable._dragging === this) { 11865 this.finishDrag(); 11866 } 11867 return; 11868 } 11869 if (Draggable._dragging || e.shiftKey || e.which !== 1 && e.button !== 1 && !e.touches) { 11870 return; 11871 } 11872 Draggable._dragging = this; // Prevent dragging multiple objects at once. 11873 11874 if (this._preventOutline) { 11875 preventOutline(this._element); 11876 } 11877 disableImageDrag(); 11878 disableTextSelection(); 11879 if (this._moving) { 11880 return; 11881 } 11882 11883 // @event down: Event 11884 // Fired when a drag is about to start. 11885 this.fire('down'); 11886 var first = e.touches ? e.touches[0] : e, 11887 sizedParent = getSizedParentNode(this._element); 11888 this._startPoint = new Point(first.clientX, first.clientY); 11889 this._startPos = getPosition(this._element); 11890 11891 // Cache the scale, so that we can continuously compensate for it during drag (_onMove). 11892 this._parentScale = getScale(sizedParent); 11893 var mouseevent = e.type === 'mousedown'; 11894 on(document, mouseevent ? 'mousemove' : 'touchmove', this._onMove, this); 11895 on(document, mouseevent ? 'mouseup' : 'touchend touchcancel', this._onUp, this); 11896 }, 11897 _onMove: function _onMove(e) { 11898 // Ignore the event if disabled; this happens in IE11 11899 // under some circumstances, see #3666. 11900 if (!this._enabled) { 11901 return; 11902 } 11903 if (e.touches && e.touches.length > 1) { 11904 this._moved = true; 11905 return; 11906 } 11907 var first = e.touches && e.touches.length === 1 ? e.touches[0] : e, 11908 offset = new Point(first.clientX, first.clientY)._subtract(this._startPoint); 11909 if (!offset.x && !offset.y) { 11910 return; 11911 } 11912 if (Math.abs(offset.x) + Math.abs(offset.y) < this.options.clickTolerance) { 11913 return; 11914 } 11915 11916 // We assume that the parent container's position, border and scale do not change for the duration of the drag. 11917 // Therefore there is no need to account for the position and border (they are eliminated by the subtraction) 11918 // and we can use the cached value for the scale. 11919 offset.x /= this._parentScale.x; 11920 offset.y /= this._parentScale.y; 11921 preventDefault(e); 11922 if (!this._moved) { 11923 // @event dragstart: Event 11924 // Fired when a drag starts 11925 this.fire('dragstart'); 11926 this._moved = true; 11927 addClass(document.body, 'leaflet-dragging'); 11928 this._lastTarget = e.target || e.srcElement; 11929 // IE and Edge do not give the <use> element, so fetch it 11930 // if necessary 11931 if (window.SVGElementInstance && this._lastTarget instanceof window.SVGElementInstance) { 11932 this._lastTarget = this._lastTarget.correspondingUseElement; 11933 } 11934 addClass(this._lastTarget, 'leaflet-drag-target'); 11935 } 11936 this._newPos = this._startPos.add(offset); 11937 this._moving = true; 11938 this._lastEvent = e; 11939 this._updatePosition(); 11940 }, 11941 _updatePosition: function _updatePosition() { 11942 var e = { 11943 originalEvent: this._lastEvent 11944 }; 11945 11946 // @event predrag: Event 11947 // Fired continuously during dragging *before* each corresponding 11948 // update of the element's position. 11949 this.fire('predrag', e); 11950 setPosition(this._element, this._newPos); 11951 11952 // @event drag: Event 11953 // Fired continuously during dragging. 11954 this.fire('drag', e); 11955 }, 11956 _onUp: function _onUp() { 11957 // Ignore the event if disabled; this happens in IE11 11958 // under some circumstances, see #3666. 11959 if (!this._enabled) { 11960 return; 11961 } 11962 this.finishDrag(); 11963 }, 11964 finishDrag: function finishDrag(noInertia) { 11965 removeClass(document.body, 'leaflet-dragging'); 11966 if (this._lastTarget) { 11967 removeClass(this._lastTarget, 'leaflet-drag-target'); 11968 this._lastTarget = null; 11969 } 11970 off(document, 'mousemove touchmove', this._onMove, this); 11971 off(document, 'mouseup touchend touchcancel', this._onUp, this); 11972 enableImageDrag(); 11973 enableTextSelection(); 11974 var fireDragend = this._moved && this._moving; 11975 this._moving = false; 11976 Draggable._dragging = false; 11977 if (fireDragend) { 11978 // @event dragend: DragEndEvent 11979 // Fired when the drag ends. 11980 this.fire('dragend', { 11981 noInertia: noInertia, 11982 distance: this._newPos.distanceTo(this._startPos) 11983 }); 11984 } 11985 } 11986 }); 11987 11988 /* 11989 * @namespace PolyUtil 11990 * Various utility functions for polygon geometries. 11991 */ 11992 11993 /* @function clipPolygon(points: Point[], bounds: Bounds, round?: Boolean): Point[] 11994 * 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)). 11995 * Used by Leaflet to only show polygon points that are on the screen or near, increasing 11996 * performance. Note that polygon points needs different algorithm for clipping 11997 * than polyline, so there's a separate method for it. 11998 */ 11999 function clipPolygon(points, bounds, round) { 12000 var clippedPoints, 12001 edges = [1, 4, 2, 8], 12002 i, 12003 j, 12004 k, 12005 a, 12006 b, 12007 len, 12008 edge, 12009 p; 12010 for (i = 0, len = points.length; i < len; i++) { 12011 points[i]._code = _getBitCode(points[i], bounds); 12012 } 12013 12014 // for each edge (left, bottom, right, top) 12015 for (k = 0; k < 4; k++) { 12016 edge = edges[k]; 12017 clippedPoints = []; 12018 for (i = 0, len = points.length, j = len - 1; i < len; j = i++) { 12019 a = points[i]; 12020 b = points[j]; 12021 12022 // if a is inside the clip window 12023 if (!(a._code & edge)) { 12024 // if b is outside the clip window (a->b goes out of screen) 12025 if (b._code & edge) { 12026 p = _getEdgeIntersection(b, a, edge, bounds, round); 12027 p._code = _getBitCode(p, bounds); 12028 clippedPoints.push(p); 12029 } 12030 clippedPoints.push(a); 12031 12032 // else if b is inside the clip window (a->b enters the screen) 12033 } else if (!(b._code & edge)) { 12034 p = _getEdgeIntersection(b, a, edge, bounds, round); 12035 p._code = _getBitCode(p, bounds); 12036 clippedPoints.push(p); 12037 } 12038 } 12039 points = clippedPoints; 12040 } 12041 return points; 12042 } 12043 12044 /* @function polygonCenter(latlngs: LatLng[], crs: CRS): LatLng 12045 * Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the passed LatLngs (first ring) from a polygon. 12046 */ 12047 function polygonCenter(latlngs, crs) { 12048 var i, j, p1, p2, f, area, x, y, center; 12049 if (!latlngs || latlngs.length === 0) { 12050 throw new Error('latlngs not passed'); 12051 } 12052 if (!isFlat(latlngs)) { 12053 console.warn('latlngs are not flat! Only the first ring will be used'); 12054 latlngs = latlngs[0]; 12055 } 12056 var centroidLatLng = toLatLng([0, 0]); 12057 var bounds = toLatLngBounds(latlngs); 12058 var areaBounds = bounds.getNorthWest().distanceTo(bounds.getSouthWest()) * bounds.getNorthEast().distanceTo(bounds.getNorthWest()); 12059 // tests showed that below 1700 rounding errors are happening 12060 if (areaBounds < 1700) { 12061 // getting a inexact center, to move the latlngs near to [0, 0] to prevent rounding errors 12062 centroidLatLng = centroid(latlngs); 12063 } 12064 var len = latlngs.length; 12065 var points = []; 12066 for (i = 0; i < len; i++) { 12067 var latlng = toLatLng(latlngs[i]); 12068 points.push(crs.project(toLatLng([latlng.lat - centroidLatLng.lat, latlng.lng - centroidLatLng.lng]))); 12069 } 12070 area = x = y = 0; 12071 12072 // polygon centroid algorithm; 12073 for (i = 0, j = len - 1; i < len; j = i++) { 12074 p1 = points[i]; 12075 p2 = points[j]; 12076 f = p1.y * p2.x - p2.y * p1.x; 12077 x += (p1.x + p2.x) * f; 12078 y += (p1.y + p2.y) * f; 12079 area += f * 3; 12080 } 12081 if (area === 0) { 12082 // Polygon is so small that all points are on same pixel. 12083 center = points[0]; 12084 } else { 12085 center = [x / area, y / area]; 12086 } 12087 var latlngCenter = crs.unproject(toPoint(center)); 12088 return toLatLng([latlngCenter.lat + centroidLatLng.lat, latlngCenter.lng + centroidLatLng.lng]); 12089 } 12090 12091 /* @function centroid(latlngs: LatLng[]): LatLng 12092 * Returns the 'center of mass' of the passed LatLngs. 12093 */ 12094 function centroid(coords) { 12095 var latSum = 0; 12096 var lngSum = 0; 12097 var len = 0; 12098 for (var i = 0; i < coords.length; i++) { 12099 var latlng = toLatLng(coords[i]); 12100 latSum += latlng.lat; 12101 lngSum += latlng.lng; 12102 len++; 12103 } 12104 return toLatLng([latSum / len, lngSum / len]); 12105 } 12106 var PolyUtil = { 12107 __proto__: null, 12108 clipPolygon: clipPolygon, 12109 polygonCenter: polygonCenter, 12110 centroid: centroid 12111 }; 12112 12113 /* 12114 * @namespace LineUtil 12115 * 12116 * Various utility functions for polyline points processing, used by Leaflet internally to make polylines lightning-fast. 12117 */ 12118 12119 // Simplify polyline with vertex reduction and Douglas-Peucker simplification. 12120 // Improves rendering performance dramatically by lessening the number of points to draw. 12121 12122 // @function simplify(points: Point[], tolerance: Number): Point[] 12123 // Dramatically reduces the number of points in a polyline while retaining 12124 // its shape and returns a new array of simplified points, using the 12125 // [Ramer-Douglas-Peucker algorithm](https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm). 12126 // Used for a huge performance boost when processing/displaying Leaflet polylines for 12127 // each zoom level and also reducing visual noise. tolerance affects the amount of 12128 // simplification (lesser value means higher quality but slower and with more points). 12129 // Also released as a separated micro-library [Simplify.js](https://mourner.github.io/simplify-js/). 12130 function simplify(points, tolerance) { 12131 if (!tolerance || !points.length) { 12132 return points.slice(); 12133 } 12134 var sqTolerance = tolerance * tolerance; 12135 12136 // stage 1: vertex reduction 12137 points = _reducePoints(points, sqTolerance); 12138 12139 // stage 2: Douglas-Peucker simplification 12140 points = _simplifyDP(points, sqTolerance); 12141 return points; 12142 } 12143 12144 // @function pointToSegmentDistance(p: Point, p1: Point, p2: Point): Number 12145 // Returns the distance between point `p` and segment `p1` to `p2`. 12146 function pointToSegmentDistance(p, p1, p2) { 12147 return Math.sqrt(_sqClosestPointOnSegment(p, p1, p2, true)); 12148 } 12149 12150 // @function closestPointOnSegment(p: Point, p1: Point, p2: Point): Number 12151 // Returns the closest point from a point `p` on a segment `p1` to `p2`. 12152 function closestPointOnSegment(p, p1, p2) { 12153 return _sqClosestPointOnSegment(p, p1, p2); 12154 } 12155 12156 // Ramer-Douglas-Peucker simplification, see https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm 12157 function _simplifyDP(points, sqTolerance) { 12158 var len = points.length, 12159 ArrayConstructor = (typeof Uint8Array === "undefined" ? "undefined" : _typeof$1(Uint8Array)) !== undefined + '' ? Uint8Array : Array, 12160 markers = new ArrayConstructor(len); 12161 markers[0] = markers[len - 1] = 1; 12162 _simplifyDPStep(points, markers, sqTolerance, 0, len - 1); 12163 var i, 12164 newPoints = []; 12165 for (i = 0; i < len; i++) { 12166 if (markers[i]) { 12167 newPoints.push(points[i]); 12168 } 12169 } 12170 return newPoints; 12171 } 12172 function _simplifyDPStep(points, markers, sqTolerance, first, last) { 12173 var maxSqDist = 0, 12174 index, 12175 i, 12176 sqDist; 12177 for (i = first + 1; i <= last - 1; i++) { 12178 sqDist = _sqClosestPointOnSegment(points[i], points[first], points[last], true); 12179 if (sqDist > maxSqDist) { 12180 index = i; 12181 maxSqDist = sqDist; 12182 } 12183 } 12184 if (maxSqDist > sqTolerance) { 12185 markers[index] = 1; 12186 _simplifyDPStep(points, markers, sqTolerance, first, index); 12187 _simplifyDPStep(points, markers, sqTolerance, index, last); 12188 } 12189 } 12190 12191 // reduce points that are too close to each other to a single point 12192 function _reducePoints(points, sqTolerance) { 12193 var reducedPoints = [points[0]]; 12194 for (var i = 1, prev = 0, len = points.length; i < len; i++) { 12195 if (_sqDist(points[i], points[prev]) > sqTolerance) { 12196 reducedPoints.push(points[i]); 12197 prev = i; 12198 } 12199 } 12200 if (prev < len - 1) { 12201 reducedPoints.push(points[len - 1]); 12202 } 12203 return reducedPoints; 12204 } 12205 var _lastCode; 12206 12207 // @function clipSegment(a: Point, b: Point, bounds: Bounds, useLastCode?: Boolean, round?: Boolean): Point[]|Boolean 12208 // Clips the segment a to b by rectangular bounds with the 12209 // [Cohen-Sutherland algorithm](https://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm) 12210 // (modifying the segment points directly!). Used by Leaflet to only show polyline 12211 // points that are on the screen or near, increasing performance. 12212 function clipSegment(a, b, bounds, useLastCode, round) { 12213 var codeA = useLastCode ? _lastCode : _getBitCode(a, bounds), 12214 codeB = _getBitCode(b, bounds), 12215 codeOut, 12216 p, 12217 newCode; 12218 12219 // save 2nd code to avoid calculating it on the next segment 12220 _lastCode = codeB; 12221 while (true) { 12222 // if a,b is inside the clip window (trivial accept) 12223 if (!(codeA | codeB)) { 12224 return [a, b]; 12225 } 12226 12227 // if a,b is outside the clip window (trivial reject) 12228 if (codeA & codeB) { 12229 return false; 12230 } 12231 12232 // other cases 12233 codeOut = codeA || codeB; 12234 p = _getEdgeIntersection(a, b, codeOut, bounds, round); 12235 newCode = _getBitCode(p, bounds); 12236 if (codeOut === codeA) { 12237 a = p; 12238 codeA = newCode; 12239 } else { 12240 b = p; 12241 codeB = newCode; 12242 } 12243 } 12244 } 12245 function _getEdgeIntersection(a, b, code, bounds, round) { 12246 var dx = b.x - a.x, 12247 dy = b.y - a.y, 12248 min = bounds.min, 12249 max = bounds.max, 12250 x, 12251 y; 12252 if (code & 8) { 12253 // top 12254 x = a.x + dx * (max.y - a.y) / dy; 12255 y = max.y; 12256 } else if (code & 4) { 12257 // bottom 12258 x = a.x + dx * (min.y - a.y) / dy; 12259 y = min.y; 12260 } else if (code & 2) { 12261 // right 12262 x = max.x; 12263 y = a.y + dy * (max.x - a.x) / dx; 12264 } else if (code & 1) { 12265 // left 12266 x = min.x; 12267 y = a.y + dy * (min.x - a.x) / dx; 12268 } 12269 return new Point(x, y, round); 12270 } 12271 function _getBitCode(p, bounds) { 12272 var code = 0; 12273 if (p.x < bounds.min.x) { 12274 // left 12275 code |= 1; 12276 } else if (p.x > bounds.max.x) { 12277 // right 12278 code |= 2; 12279 } 12280 if (p.y < bounds.min.y) { 12281 // bottom 12282 code |= 4; 12283 } else if (p.y > bounds.max.y) { 12284 // top 12285 code |= 8; 12286 } 12287 return code; 12288 } 12289 12290 // square distance (to avoid unnecessary Math.sqrt calls) 12291 function _sqDist(p1, p2) { 12292 var dx = p2.x - p1.x, 12293 dy = p2.y - p1.y; 12294 return dx * dx + dy * dy; 12295 } 12296 12297 // return closest point on segment or distance to that point 12298 function _sqClosestPointOnSegment(p, p1, p2, sqDist) { 12299 var x = p1.x, 12300 y = p1.y, 12301 dx = p2.x - x, 12302 dy = p2.y - y, 12303 dot = dx * dx + dy * dy, 12304 t; 12305 if (dot > 0) { 12306 t = ((p.x - x) * dx + (p.y - y) * dy) / dot; 12307 if (t > 1) { 12308 x = p2.x; 12309 y = p2.y; 12310 } else if (t > 0) { 12311 x += dx * t; 12312 y += dy * t; 12313 } 12314 } 12315 dx = p.x - x; 12316 dy = p.y - y; 12317 return sqDist ? dx * dx + dy * dy : new Point(x, y); 12318 } 12319 12320 // @function isFlat(latlngs: LatLng[]): Boolean 12321 // Returns true if `latlngs` is a flat array, false is nested. 12322 function isFlat(latlngs) { 12323 return !isArray(latlngs[0]) || _typeof$1(latlngs[0][0]) !== 'object' && typeof latlngs[0][0] !== 'undefined'; 12324 } 12325 function _flat(latlngs) { 12326 console.warn('Deprecated use of _flat, please use L.LineUtil.isFlat instead.'); 12327 return isFlat(latlngs); 12328 } 12329 12330 /* @function polylineCenter(latlngs: LatLng[], crs: CRS): LatLng 12331 * Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the passed LatLngs (first ring) from a polyline. 12332 */ 12333 function polylineCenter(latlngs, crs) { 12334 var i, halfDist, segDist, dist, p1, p2, ratio, center; 12335 if (!latlngs || latlngs.length === 0) { 12336 throw new Error('latlngs not passed'); 12337 } 12338 if (!isFlat(latlngs)) { 12339 console.warn('latlngs are not flat! Only the first ring will be used'); 12340 latlngs = latlngs[0]; 12341 } 12342 var centroidLatLng = toLatLng([0, 0]); 12343 var bounds = toLatLngBounds(latlngs); 12344 var areaBounds = bounds.getNorthWest().distanceTo(bounds.getSouthWest()) * bounds.getNorthEast().distanceTo(bounds.getNorthWest()); 12345 // tests showed that below 1700 rounding errors are happening 12346 if (areaBounds < 1700) { 12347 // getting a inexact center, to move the latlngs near to [0, 0] to prevent rounding errors 12348 centroidLatLng = centroid(latlngs); 12349 } 12350 var len = latlngs.length; 12351 var points = []; 12352 for (i = 0; i < len; i++) { 12353 var latlng = toLatLng(latlngs[i]); 12354 points.push(crs.project(toLatLng([latlng.lat - centroidLatLng.lat, latlng.lng - centroidLatLng.lng]))); 12355 } 12356 for (i = 0, halfDist = 0; i < len - 1; i++) { 12357 halfDist += points[i].distanceTo(points[i + 1]) / 2; 12358 } 12359 12360 // The line is so small in the current view that all points are on the same pixel. 12361 if (halfDist === 0) { 12362 center = points[0]; 12363 } else { 12364 for (i = 0, dist = 0; i < len - 1; i++) { 12365 p1 = points[i]; 12366 p2 = points[i + 1]; 12367 segDist = p1.distanceTo(p2); 12368 dist += segDist; 12369 if (dist > halfDist) { 12370 ratio = (dist - halfDist) / segDist; 12371 center = [p2.x - ratio * (p2.x - p1.x), p2.y - ratio * (p2.y - p1.y)]; 12372 break; 12373 } 12374 } 12375 } 12376 var latlngCenter = crs.unproject(toPoint(center)); 12377 return toLatLng([latlngCenter.lat + centroidLatLng.lat, latlngCenter.lng + centroidLatLng.lng]); 12378 } 12379 var LineUtil = { 12380 __proto__: null, 12381 simplify: simplify, 12382 pointToSegmentDistance: pointToSegmentDistance, 12383 closestPointOnSegment: closestPointOnSegment, 12384 clipSegment: clipSegment, 12385 _getEdgeIntersection: _getEdgeIntersection, 12386 _getBitCode: _getBitCode, 12387 _sqClosestPointOnSegment: _sqClosestPointOnSegment, 12388 isFlat: isFlat, 12389 _flat: _flat, 12390 polylineCenter: polylineCenter 12391 }; 12392 12393 /* 12394 * @namespace Projection 12395 * @section 12396 * Leaflet comes with a set of already defined Projections out of the box: 12397 * 12398 * @projection L.Projection.LonLat 12399 * 12400 * Equirectangular, or Plate Carree projection â the most simple projection, 12401 * mostly used by GIS enthusiasts. Directly maps `x` as longitude, and `y` as 12402 * latitude. Also suitable for flat worlds, e.g. game maps. Used by the 12403 * `EPSG:4326` and `Simple` CRS. 12404 */ 12405 12406 var LonLat = { 12407 project: function project(latlng) { 12408 return new Point(latlng.lng, latlng.lat); 12409 }, 12410 unproject: function unproject(point) { 12411 return new LatLng(point.y, point.x); 12412 }, 12413 bounds: new Bounds([-180, -90], [180, 90]) 12414 }; 12415 12416 /* 12417 * @namespace Projection 12418 * @projection L.Projection.Mercator 12419 * 12420 * Elliptical Mercator projection â more complex than Spherical Mercator. Assumes that Earth is an ellipsoid. Used by the EPSG:3395 CRS. 12421 */ 12422 12423 var Mercator = { 12424 R: 6378137, 12425 R_MINOR: 6356752.314245179, 12426 bounds: new Bounds([-20037508.34279, -15496570.73972], [20037508.34279, 18764656.23138]), 12427 project: function project(latlng) { 12428 var d = Math.PI / 180, 12429 r = this.R, 12430 y = latlng.lat * d, 12431 tmp = this.R_MINOR / r, 12432 e = Math.sqrt(1 - tmp * tmp), 12433 con = e * Math.sin(y); 12434 var ts = Math.tan(Math.PI / 4 - y / 2) / Math.pow((1 - con) / (1 + con), e / 2); 12435 y = -r * Math.log(Math.max(ts, 1E-10)); 12436 return new Point(latlng.lng * d * r, y); 12437 }, 12438 unproject: function unproject(point) { 12439 var d = 180 / Math.PI, 12440 r = this.R, 12441 tmp = this.R_MINOR / r, 12442 e = Math.sqrt(1 - tmp * tmp), 12443 ts = Math.exp(-point.y / r), 12444 phi = Math.PI / 2 - 2 * Math.atan(ts); 12445 for (var i = 0, dphi = 0.1, con; i < 15 && Math.abs(dphi) > 1e-7; i++) { 12446 con = e * Math.sin(phi); 12447 con = Math.pow((1 - con) / (1 + con), e / 2); 12448 dphi = Math.PI / 2 - 2 * Math.atan(ts * con) - phi; 12449 phi += dphi; 12450 }
12451 return new LatLng(phi * d, point.x * d / r); 12452 } 12453 }; 12454 12455 /* 12456 * @class Projection 12457 * An object with methods for projecting geographical coordinates of the world onto 12458 * a flat surface (and back). See [Map projection](https://en.wikipedia.org/wiki/Map_projection). 12459 * @property bounds: Bounds 12460 * The bounds (specified in CRS units) where the projection is valid 12461 * @method project(latlng: LatLng): Point 12462 * Projects geographical coordinates into a 2D point. 12463 * Only accepts actual `L.LatLng` instances, not arrays. 12464 * @method unproject(point: Point): LatLng 12465 * The inverse of `project`. Projects a 2D point into a geographical location. 12466 * Only accepts actual `L.Point` instances, not arrays. 12467 * Note that the projection instances do not inherit from Leaflet's `Class` object, 12468 * and can't be instantiated. Also, new classes can't inherit from them, 12469 * and methods can't be added to them with the `include` function. 12470 */ 12471 12472 var index = { 12473 __proto__: null, 12474 LonLat: LonLat, 12475 Mercator: Mercator, 12476 SphericalMercator: SphericalMercator 12477 }; 12478 12479 /* 12480 * @namespace CRS 12481 * @crs L.CRS.EPSG3395 12482 * 12483 * Rarely used by some commercial tile providers. Uses Elliptical Mercator projection. 12484 */ 12485 var EPSG3395 = extend({}, Earth, { 12486 code: 'EPSG:3395', 12487 projection: Mercator, 12488 transformation: function () { 12489 var scale = 0.5 / (Math.PI * Mercator.R); 12490 return toTransformation(scale, 0.5, -scale, 0.5); 12491 }() 12492 }); 12493 12494 /* 12495 * @namespace CRS 12496 * @crs L.CRS.EPSG4326 12497 * 12498 * A common CRS among GIS enthusiasts. Uses simple Equirectangular projection. 12499 * 12500 * Leaflet 1.0.x complies with the [TMS coordinate scheme for EPSG:4326](https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification#global-geodetic), 12501 * which is a breaking change from 0.7.x behaviour. If you are using a `TileLayer` 12502 * with this CRS, ensure that there are two 256x256 pixel tiles covering the 12503 * whole earth at zoom level zero, and that the tile coordinate origin is (-180,+90), 12504 * or (-180,-90) for `TileLayer`s with [the `tms` option](#tilelayer-tms) set. 12505 */ 12506 12507 var EPSG4326 = extend({}, Earth, { 12508 code: 'EPSG:4326', 12509 projection: LonLat, 12510 transformation: toTransformation(1 / 180, 1, -1 / 180, 0.5) 12511 }); 12512 12513 /* 12514 * @namespace CRS 12515 * @crs L.CRS.Simple 12516 * 12517 * A simple CRS that maps longitude and latitude into `x` and `y` directly. 12518 * May be used for maps of flat surfaces (e.g. game maps). Note that the `y` 12519 * axis should still be inverted (going from bottom to top). `distance()` returns 12520 * simple euclidean distance. 12521 */ 12522 12523 var Simple = extend({}, CRS, { 12524 projection: LonLat, 12525 transformation: toTransformation(1, 0, -1, 0), 12526 scale: function scale(zoom) { 12527 return Math.pow(2, zoom); 12528 }, 12529 zoom: function zoom(scale) { 12530 return Math.log(scale) / Math.LN2; 12531 }, 12532 distance: function distance(latlng1, latlng2) { 12533 var dx = latlng2.lng - latlng1.lng, 12534 dy = latlng2.lat - latlng1.lat; 12535 return Math.sqrt(dx * dx + dy * dy); 12536 }, 12537 infinite: true 12538 });
12539 CRS.Earth = Earth; 12540 CRS.EPSG3395 = EPSG3395; 12541 CRS.EPSG3857 = EPSG3857; 12542 CRS.EPSG900913 = EPSG900913; 12543 CRS.EPSG4326 = EPSG4326; 12544 CRS.Simple = Simple; 12545 12546 /* 12547 * @class Layer 12548 * @inherits Evented 12549 * @aka L.Layer 12550 * @aka ILayer 12551 * 12552 * A set of methods from the Layer base class that all Leaflet layers use. 12553 * Inherits all methods, options and events from `L.Evented`. 12554 * 12555 * @example 12556 * 12557 * ```js 12558 * var layer = L.marker(latlng).addTo(map); 12559 * layer.addTo(map); 12560 * layer.remove(); 12561 * ``` 12562 * 12563 * @event add: Event 12564 * Fired after the layer is added to a map 12565 * 12566 * @event remove: Event 12567 * Fired after the layer is removed from a map 12568 */ 12569 12570 var Layer = Evented.extend({ 12571 // Classes extending `L.Layer` will inherit the following options: 12572 options: { 12573 // @option pane: String = 'overlayPane' 12574 // 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. 12575 pane: 'overlayPane', 12576 // @option attribution: String = null 12577 // 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. 12578 attribution: null, 12579 bubblingMouseEvents: true 12580 }, 12581 /* @section 12582 * Classes extending `L.Layer` will inherit the following methods: 12583 * 12584 * @method addTo(map: Map|LayerGroup): this 12585 * Adds the layer to the given map or layer group. 12586 */ 12587 addTo: function addTo(map) { 12588 map.addLayer(this); 12589 return this; 12590 }, 12591 // @method remove: this 12592 // Removes the layer from the map it is currently active on. 12593 remove: function remove() { 12594 return this.removeFrom(this._map || this._mapToAdd); 12595 }, 12596 // @method removeFrom(map: Map): this 12597 // Removes the layer from the given map 12598 // 12599 // @alternative 12600 // @method removeFrom(group: LayerGroup): this 12601 // Removes the layer from the given `LayerGroup` 12602 removeFrom: function removeFrom(obj) { 12603 if (obj) { 12604 obj.removeLayer(this); 12605 } 12606 return this; 12607 }, 12608 // @method getPane(name? : String): HTMLElement 12609 // Returns the `HTMLElement` representing the named pane on the map. If `name` is omitted, returns the pane for this layer. 12610 getPane: function getPane(name) { 12611 return this._map.getPane(name ? this.options[name] || name : this.options.pane); 12612 }, 12613 addInteractiveTarget: function addInteractiveTarget(targetEl) { 12614 this._map._targets[stamp(targetEl)] = this; 12615 return this; 12616 }, 12617 removeInteractiveTarget: function removeInteractiveTarget(targetEl) { 12618 delete this._map._targets[stamp(targetEl)]; 12619 return this; 12620 }, 12621 // @method getAttribution: String 12622 // Used by the `attribution control`, returns the [attribution option](#gridlayer-attribution). 12623 getAttribution: function getAttribution() { 12624 return this.options.attribution; 12625 }, 12626 _layerAdd: function _layerAdd(e) { 12627 var map = e.target; 12628 12629 // check in case layer gets added and then removed before the map is ready 12630 if (!map.hasLayer(this)) { 12631 return; 12632 } 12633 this._map = map; 12634 this._zoomAnimated = map._zoomAnimated; 12635 if (this.getEvents) { 12636 var events = this.getEvents(); 12637 map.on(events, this); 12638 this.once('remove', function () { 12639 map.off(events, this); 12640 }, this); 12641 } 12642 this.onAdd(map); 12643 this.fire('add'); 12644 map.fire('layeradd', { 12645 layer: this 12646 }); 12647 } 12648 }); 12649 12650 /* @section Extension methods 12651 * @uninheritable 12652 * 12653 * Every layer should extend from `L.Layer` and (re-)implement the following methods. 12654 *
12655 * @method onAdd(map: Map): this 12656 * 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). 12657 * 12658 * @method onRemove(map: Map): this 12659 * 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). 12660 * 12661 * @method getEvents(): Object 12662 * 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. 12663 * 12664 * @method getAttribution(): String 12665 * This optional method should return a string containing HTML to be shown on the `Attribution control` whenever the layer is visible. 12666 * 12667 * @method beforeAdd(map: Map): this 12668 * 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. 12669 */ 12670 12671 /* @namespace Map 12672 * @section Layer events 12673 * 12674 * @event layeradd: LayerEvent 12675 * Fired when a new layer is added to the map. 12676 * 12677 * @event layerremove: LayerEvent 12678 * Fired when some layer is removed from the map 12679 * 12680 * @section Methods for Layers and Controls 12681 */ 12682 Map.include({ 12683 // @method addLayer(layer: Layer): this 12684 // Adds the given layer to the map 12685 addLayer: function addLayer(layer) { 12686 if (!layer._layerAdd) { 12687 throw new Error('The provided object is not a Layer.'); 12688 } 12689 var id = stamp(layer); 12690 if (this._layers[id]) { 12691 return this; 12692 } 12693 this._layers[id] = layer; 12694 layer._mapToAdd = this; 12695 if (layer.beforeAdd) { 12696 layer.beforeAdd(this); 12697 } 12698 this.whenReady(layer._layerAdd, layer); 12699 return this; 12700 }, 12701 // @method removeLayer(layer: Layer): this 12702 // Removes the given layer from the map. 12703 removeLayer: function removeLayer(layer) { 12704 var id = stamp(layer); 12705 if (!this._layers[id]) { 12706 return this; 12707 } 12708 if (this._loaded) { 12709 layer.onRemove(this); 12710 } 12711 delete this._layers[id]; 12712 if (this._loaded) { 12713 this.fire('layerremove', { 12714 layer: layer 12715 }); 12716 layer.fire('remove'); 12717 } 12718 layer._map = layer._mapToAdd = null; 12719 return this; 12720 }, 12721 // @method hasLayer(layer: Layer): Boolean 12722 // Returns `true` if the given layer is currently added to the map 12723 hasLayer: function hasLayer(layer) { 12724 return stamp(layer) in this._layers; 12725 }, 12726 /* @method eachLayer(fn: Function, context?: Object): this 12727 * Iterates over the layers of the map, optionally specifying context of the iterator function. 12728 * ``` 12729 * map.eachLayer(function(layer){ 12730 * layer.bindPopup('Hello'); 12731 * }); 12732 * ``` 12733 */ 12734 eachLayer: function eachLayer(method, context) { 12735 for (var i in this._layers) { 12736 method.call(context, this._layers[i]); 12737 } 12738 return this; 12739 }, 12740 _addLayers: function _addLayers(layers) { 12741 layers = layers ? isArray(layers) ? layers : [layers] : []; 12742 for (var i = 0, len = layers.length; i < len; i++) { 12743 this.addLayer(layers[i]); 12744 } 12745 }, 12746 _addZoomLimit: function _addZoomLimit(layer) { 12747 if (!isNaN(layer.options.maxZoom) || !isNaN(layer.options.minZoom)) { 12748 this._zoomBoundLayers[stamp(layer)] = layer; 12749 this._updateZoomLevels(); 12750 } 12751 }, 12752 _removeZoomLimit: function _removeZoomLimit(layer) { 12753 var id = stamp(layer); 12754 if (this._zoomBoundLayers[id]) { 12755 delete this._zoomBoundLayers[id]; 12756 this._updateZoomLevels(); 12757 } 12758 }, 12759 _updateZoomLevels: function _updateZoomLevels() { 12760 var minZoom = Infinity, 12761 maxZoom = -Infinity, 12762 oldZoomSpan = this._getZoomSpan(); 12763 for (var i in this._zoomBoundLayers) { 12764 var options = this._zoomBoundLayers[i].options;
12765 minZoom = options.minZoom === undefined ? minZoom : Math.min(minZoom, options.minZoom); 12766 maxZoom = options.maxZoom === undefined ? maxZoom : Math.max(maxZoom, options.maxZoom); 12767 } 12768 this._layersMaxZoom = maxZoom === -Infinity ? undefined : maxZoom; 12769 this._layersMinZoom = minZoom === Infinity ? undefined : minZoom; 12770 12771 // @section Map state change events 12772 // @event zoomlevelschange: Event 12773 // Fired when the number of zoomlevels on the map is changed due 12774 // to adding or removing a layer. 12775 if (oldZoomSpan !== this._getZoomSpan()) { 12776 this.fire('zoomlevelschange'); 12777 } 12778 if (this.options.maxZoom === undefined && this._layersMaxZoom && this.getZoom() > this._layersMaxZoom) { 12779 this.setZoom(this._layersMaxZoom); 12780 } 12781 if (this.options.minZoom === undefined && this._layersMinZoom && this.getZoom() < this._layersMinZoom) { 12782 this.setZoom(this._layersMinZoom); 12783 } 12784 } 12785 }); 12786 12787 /* 12788 * @class LayerGroup 12789 * @aka L.LayerGroup 12790 * @inherits Interactive layer 12791 * 12792 * Used to group several layers and handle them as one. If you add it to the map, 12793 * any layers added or removed from the group will be added/removed on the map as 12794 * well. Extends `Layer`. 12795 * 12796 * @example 12797 * 12798 * ```js 12799 * L.layerGroup([marker1, marker2]) 12800 * .addLayer(polyline) 12801 * .addTo(map); 12802 * ``` 12803 */ 12804 12805 var LayerGroup = Layer.extend({ 12806 initialize: function initialize(layers, options) { 12807 setOptions(this, options); 12808 this._layers = {}; 12809 var i, len; 12810 if (layers) { 12811 for (i = 0, len = layers.length; i < len; i++) { 12812 this.addLayer(layers[i]); 12813 } 12814 } 12815 }, 12816 // @method addLayer(layer: Layer): this 12817 // Adds the given layer to the group. 12818 addLayer: function addLayer(layer) { 12819 var id = this.getLayerId(layer); 12820 this._layers[id] = layer; 12821 if (this._map) { 12822 this._map.addLayer(layer); 12823 } 12824 return this; 12825 }, 12826 // @method removeLayer(layer: Layer): this 12827 // Removes the given layer from the group. 12828 // @alternative 12829 // @method removeLayer(id: Number): this 12830 // Removes the layer with the given internal ID from the group. 12831 removeLayer: function removeLayer(layer) { 12832 var id = layer in this._layers ? layer : this.getLayerId(layer); 12833 if (this._map && this._layers[id]) { 12834 this._map.removeLayer(this._layers[id]); 12835 } 12836 delete this._layers[id]; 12837 return this; 12838 }, 12839 // @method hasLayer(layer: Layer): Boolean 12840 // Returns `true` if the given layer is currently added to the group. 12841 // @alternative 12842 // @method hasLayer(id: Number): Boolean 12843 // Returns `true` if the given internal ID is currently added to the group. 12844 hasLayer: function hasLayer(layer) { 12845 var layerId = typeof layer === 'number' ? layer : this.getLayerId(layer); 12846 return layerId in this._layers; 12847 }, 12848 // @method clearLayers(): this 12849 // Removes all the layers from the group. 12850 clearLayers: function clearLayers() { 12851 return this.eachLayer(this.removeLayer, this); 12852 }, 12853 // @method invoke(methodName: String, â¦): this 12854 // Calls `methodName` on every layer contained in this group, passing any 12855 // additional parameters. Has no effect if the layers contained do not 12856 // implement `methodName`. 12857 invoke: function invoke(methodName) { 12858 var args = Array.prototype.slice.call(arguments, 1), 12859 i, 12860 layer; 12861 for (i in this._layers) { 12862 layer = this._layers[i]; 12863 if (layer[methodName]) { 12864 layer[methodName].apply(layer, args); 12865 } 12866 } 12867 return this; 12868 }, 12869 onAdd: function onAdd(map) { 12870 this.eachLayer(map.addLayer, map); 12871 }, 12872 onRemove: function onRemove(map) { 12873 this.eachLayer(map.removeLayer, map); 12874 }, 12875 // @method eachLayer(fn: Function, context?: Object): this 12876 // Iterates over the layers of the group, optionally specifying context of the iterator function. 12877 // ```js 12878 // group.eachLayer(function (layer) { 12879 // layer.bindPopup('Hello'); 12880 // }); 12881 // ``` 12882 eachLayer: function eachLayer(method, context) { 12883 for (var i in this._layers) { 12884 method.call(context, this._layers[i]); 12885 } 12886 return this; 12887 }, 12888 // @method getLayer(id: Number): Layer 12889 // Returns the layer with the given internal ID. 12890 getLayer: function getLayer(id) { 12891 return this._layers[id]; 12892 }, 12893 // @method getLayers(): Layer[] 12894 // Returns an array of all the layers added to the group. 12895 getLayers: function getLayers() { 12896 var layers = []; 12897 this.eachLayer(layers.push, layers); 12898 return layers; 12899 }, 12900 // @method setZIndex(zIndex: Number): this 12901 // Calls `setZIndex` on every layer contained in this group, passing the z-index. 12902 setZIndex: function setZIndex(zIndex) { 12903 return this.invoke('setZIndex', zIndex); 12904 }, 12905 // @method getLayerId(layer: Layer): Number 12906 // Returns the internal ID for a layer 12907 getLayerId: function getLayerId(layer) { 12908 return stamp(layer); 12909 } 12910 }); 12911 12912 // @factory L.layerGroup(layers?: Layer[], options?: Object) 12913 // Create a layer group, optionally given an initial set of layers and an `options` object. 12914 var layerGroup = function layerGroup(layers, options) {
12915 return new LayerGroup(layers, options); 12916 }; 12917 12918 /* 12919 * @class FeatureGroup 12920 * @aka L.FeatureGroup 12921 * @inherits LayerGroup 12922 * 12923 * Extended `LayerGroup` that makes it easier to do the same thing to all its member layers: 12924 * * [`bindPopup`](#layer-bindpopup) binds a popup to all of the layers at once (likewise with [`bindTooltip`](#layer-bindtooltip)) 12925 * * Events are propagated to the `FeatureGroup`, so if the group has an event 12926 * handler, it will handle events from any of the layers. This includes mouse events 12927 * and custom events. 12928 * * Has `layeradd` and `layerremove` events 12929 * 12930 * @example 12931 * 12932 * ```js 12933 * L.featureGroup([marker1, marker2, polyline]) 12934 * .bindPopup('Hello world!') 12935 * .on('click', function() { alert('Clicked on a member of the group!'); }) 12936 * .addTo(map); 12937 * ``` 12938 */ 12939 12940 var FeatureGroup = LayerGroup.extend({ 12941 addLayer: function addLayer(layer) { 12942 if (this.hasLayer(layer)) { 12943 return this; 12944 } 12945 layer.addEventParent(this); 12946 LayerGroup.prototype.addLayer.call(this, layer); 12947 12948 // @event layeradd: LayerEvent 12949 // Fired when a layer is added to this `FeatureGroup` 12950 return this.fire('layeradd', { 12951 layer: layer 12952 }); 12953 }, 12954 removeLayer: function removeLayer(layer) { 12955 if (!this.hasLayer(layer)) { 12956 return this; 12957 } 12958 if (layer in this._layers) { 12959 layer = this._layers[layer]; 12960 } 12961 layer.removeEventParent(this); 12962 LayerGroup.prototype.removeLayer.call(this, layer); 12963 12964 // @event layerremove: LayerEvent 12965 // Fired when a layer is removed from this `FeatureGroup` 12966 return this.fire('layerremove', { 12967 layer: layer 12968 }); 12969 }, 12970 // @method setStyle(style: Path options): this 12971 // Sets the given path options to each layer of the group that has a `setStyle` method. 12972 setStyle: function setStyle(style) { 12973 return this.invoke('setStyle', style); 12974 }, 12975 // @method bringToFront(): this 12976 // Brings the layer group to the top of all other layers 12977 bringToFront: function bringToFront() { 12978 return this.invoke('bringToFront'); 12979 }, 12980 // @method bringToBack(): this 12981 // Brings the layer group to the back of all other layers 12982 bringToBack: function bringToBack() { 12983 return this.invoke('bringToBack'); 12984 }, 12985 // @method getBounds(): LatLngBounds 12986 // Returns the LatLngBounds of the Feature Group (created from bounds and coordinates of its children). 12987 getBounds: function getBounds() { 12988 var bounds = new LatLngBounds(); 12989 for (var id in this._layers) { 12990 var layer = this._layers[id]; 12991 bounds.extend(layer.getBounds ? layer.getBounds() : layer.getLatLng()); 12992 } 12993 return bounds; 12994 } 12995 }); 12996 12997 // @factory L.featureGroup(layers?: Layer[], options?: Object) 12998 // Create a feature group, optionally given an initial set of layers and an `options` object. 12999 var featureGroup = function featureGroup(layers, options) { 13000 return new FeatureGroup(layers, options); 13001 }; 13002 13003 /* 13004 * @class Icon 13005 * @aka L.Icon 13006 * 13007 * Represents an icon to provide when creating a marker. 13008 * 13009 * @example 13010 * 13011 * ```js 13012 * var myIcon = L.icon({ 13013 * iconUrl: 'my-icon.png', 13014 * iconRetinaUrl: '[email protected]', 13015 * iconSize: [38, 95], 13016 * iconAnchor: [22, 94], 13017 * popupAnchor: [-3, -76], 13018 * shadowUrl: 'my-icon-shadow.png', 13019 * shadowRetinaUrl: '[email protected]', 13020 * shadowSize: [68, 95], 13021 * shadowAnchor: [22, 94] 13022 * }); 13023 * 13024 * L.marker([50.505, 30.57], {icon: myIcon}).addTo(map); 13025 * ``` 13026 * 13027 * `L.Icon.Default` extends `L.Icon` and is the blue icon Leaflet uses for markers by default. 13028 * 13029 */ 13030 13031 var Icon = Class.extend({ 13032 /* @section 13033 * @aka Icon options 13034 * 13035 * @option iconUrl: String = null 13036 * **(required)** The URL to the icon image (absolute or relative to your script path). 13037 * 13038 * @option iconRetinaUrl: String = null
13039 * The URL to a retina sized version of the icon image (absolute or relative to your 13040 * script path). Used for Retina screen devices. 13041 * 13042 * @option iconSize: Point = null 13043 * Size of the icon image in pixels. 13044 * 13045 * @option iconAnchor: Point = null 13046 * The coordinates of the "tip" of the icon (relative to its top left corner). The icon 13047 * will be aligned so that this point is at the marker's geographical location. Centered 13048 * by default if size is specified, also can be set in CSS with negative margins. 13049 * 13050 * @option popupAnchor: Point = [0, 0] 13051 * The coordinates of the point from which popups will "open", relative to the icon anchor. 13052 * 13053 * @option tooltipAnchor: Point = [0, 0] 13054 * The coordinates of the point from which tooltips will "open", relative to the icon anchor. 13055 * 13056 * @option shadowUrl: String = null 13057 * The URL to the icon shadow image. If not specified, no shadow image will be created. 13058 * 13059 * @option shadowRetinaUrl: String = null 13060 * 13061 * @option shadowSize: Point = null 13062 * Size of the shadow image in pixels. 13063 * 13064 * @option shadowAnchor: Point = null 13065 * The coordinates of the "tip" of the shadow (relative to its top left corner) (the same 13066 * as iconAnchor if not specified). 13067 * 13068 * @option className: String = '' 13069 * A custom class name to assign to both icon and shadow images. Empty by default. 13070 */ 13071 13072 options: { 13073 popupAnchor: [0, 0], 13074 tooltipAnchor: [0, 0], 13075 // @option crossOrigin: Boolean|String = false 13076 // Whether the crossOrigin attribute will be added to the tiles. 13077 // 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. 13078 // Refer to [CORS Settings](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) for valid String values. 13079 crossOrigin: false 13080 }, 13081 initialize: function initialize(options) { 13082 setOptions(this, options); 13083 }, 13084 // @method createIcon(oldIcon?: HTMLElement): HTMLElement 13085 // Called internally when the icon has to be shown, returns a `<img>` HTML element 13086 // styled according to the options. 13087 createIcon: function createIcon(oldIcon) { 13088 return this._createIcon('icon', oldIcon); 13089 }, 13090 // @method createShadow(oldIcon?: HTMLElement): HTMLElement 13091 // As `createIcon`, but for the shadow beneath it. 13092 createShadow: function createShadow(oldIcon) { 13093 return this._createIcon('shadow', oldIcon); 13094 }, 13095 _createIcon: function _createIcon(name, oldIcon) { 13096 var src = this._getIconUrl(name); 13097 if (!src) { 13098 if (name === 'icon') { 13099 throw new Error('iconUrl not set in Icon options (see the docs).'); 13100 } 13101 return null; 13102 } 13103 var img = this._createImg(src, oldIcon && oldIcon.tagName === 'IMG' ? oldIcon : null); 13104 this._setIconStyles(img, name); 13105 if (this.options.crossOrigin || this.options.crossOrigin === '') { 13106 img.crossOrigin = this.options.crossOrigin === true ? '' : this.options.crossOrigin; 13107 } 13108 return img; 13109 }, 13110 _setIconStyles: function _setIconStyles(img, name) { 13111 var options = this.options; 13112 var sizeOption = options[name + 'Size']; 13113 if (typeof sizeOption === 'number') { 13114 sizeOption = [sizeOption, sizeOption]; 13115 } 13116 var size = toPoint(sizeOption), 13117 anchor = toPoint(name === 'shadow' && options.shadowAnchor || options.iconAnchor || size && size.divideBy(2, true)); 13118 img.className = 'leaflet-marker-' + name + ' ' + (options.className || ''); 13119 if (anchor) { 13120 img.style.marginLeft = -anchor.x + 'px'; 13121 img.style.marginTop = -anchor.y + 'px'; 13122 } 13123 if (size) { 13124 img.style.width = size.x + 'px'; 13125 img.style.height = size.y + 'px'; 13126 } 13127 },
vendor: 6,173 bytes, lines 13128-13275
13128 _createImg: function _createImg(src, el) { 13129 el = el || document.createElement('img'); 13130 el.src = src; 13131 return el; 13132 }, 13133 _getIconUrl: function _getIconUrl(name) { 13134 return Browser.retina && this.options[name + 'RetinaUrl'] || this.options[name + 'Url']; 13135 } 13136 }); 13137 13138 // @factory L.icon(options: Icon options) 13139 // Creates an icon instance with the given options. 13140 function icon(options) { 13141 return new Icon(options); 13142 } 13143 13144 /* 13145 * @miniclass Icon.Default (Icon) 13146 * @aka L.Icon.Default 13147 * @section 13148 * 13149 * A trivial subclass of `Icon`, represents the icon to use in `Marker`s when 13150 * no icon is specified. Points to the blue marker image distributed with Leaflet 13151 * releases. 13152 * 13153 * In order to customize the default icon, just change the properties of `L.Icon.Default.prototype.options` 13154 * (which is a set of `Icon options`). 13155 * 13156 * If you want to _completely_ replace the default icon, override the 13157 * `L.Marker.prototype.options.icon` with your own icon instead. 13158 */ 13159 13160 var IconDefault = Icon.extend({ 13161 options: { 13162 iconUrl: 'marker-icon.png', 13163 iconRetinaUrl: 'marker-icon-2x.png', 13164 shadowUrl: 'marker-shadow.png', 13165 iconSize: [25, 41], 13166 iconAnchor: [12, 41], 13167 popupAnchor: [1, -34], 13168 tooltipAnchor: [16, -28], 13169 shadowSize: [41, 41] 13170 }, 13171 _getIconUrl: function _getIconUrl(name) { 13172 if (typeof IconDefault.imagePath !== 'string') { 13173 // Deprecated, backwards-compatibility only 13174 IconDefault.imagePath = this._detectIconPath(); 13175 } 13176 13177 // @option imagePath: String 13178 // `Icon.Default` will try to auto-detect the location of the 13179 // blue icon images. If you are placing these images in a non-standard 13180 // way, set this option to point to the right path. 13181 return (this.options.imagePath || IconDefault.imagePath) + Icon.prototype._getIconUrl.call(this, name); 13182 }, 13183 _stripUrl: function _stripUrl(path) { 13184 // separate function to use in tests 13185 var strip = function strip(str, re, idx) { 13186 var match = re.exec(str); 13187 return match && match[idx]; 13188 }; 13189 path = strip(path, /^url\((['"])?(.+)\1\)$/, 2); 13190 return path && strip(path, /^(.*)marker-icon\.png$/, 1); 13191 }, 13192 _detectIconPath: function _detectIconPath() { 13193 var el = create$1('div', 'leaflet-default-icon-path', document.body); 13194 var path = getStyle(el, 'background-image') || getStyle(el, 'backgroundImage'); // IE8 13195 13196 document.body.removeChild(el); 13197 path = this._stripUrl(path); 13198 if (path) { 13199 return path; 13200 } 13201 var link = document.querySelector('link[href$="leaflet.css"]'); 13202 if (!link) { 13203 return ''; 13204 } 13205 return link.href.substring(0, link.href.length - 'leaflet.css'.length - 1); 13206 } 13207 }); 13208 13209 /* 13210 * L.Handler.MarkerDrag is used internally by L.Marker to make the markers draggable. 13211 */ 13212 13213 /* @namespace Marker 13214 * @section Interaction handlers 13215 * 13216 * 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: 13217 * 13218 * ```js 13219 * marker.dragging.disable(); 13220 * ``` 13221 * 13222 * @property dragging: Handler 13223 * Marker dragging handler (by both mouse and touch). Only valid when the marker is on the map (Otherwise set [`marker.options.draggable`](#marker-draggable)). 13224 */ 13225 13226 var MarkerDrag = Handler.extend({ 13227 initialize: function initialize(marker) { 13228 this._marker = marker; 13229 }, 13230 addHooks: function addHooks() { 13231 var icon = this._marker._icon; 13232 if (!this._draggable) { 13233 this._draggable = new Draggable(icon, icon, true); 13234 } 13235 this._draggable.on({ 13236 dragstart: this._onDragStart, 13237 predrag: this._onPreDrag, 13238 drag: this._onDrag, 13239 dragend: this._onDragEnd 13240 }, this).enable(); 13241 addClass(icon, 'leaflet-marker-draggable'); 13242 }, 13243 removeHooks: function removeHooks() { 13244 this._draggable.off({ 13245 dragstart: this._onDragStart, 13246 predrag: this._onPreDrag, 13247 drag: this._onDrag, 13248 dragend: this._onDragEnd 13249 }, this).disable(); 13250 if (this._marker._icon) { 13251 removeClass(this._marker._icon, 'leaflet-marker-draggable'); 13252 } 13253 }, 13254 moved: function moved() { 13255 return this._draggable && this._draggable._moved; 13256 }, 13257 _adjustPan: function _adjustPan(e) { 13258 var marker = this._marker, 13259 map = marker._map, 13260 speed = this._marker.options.autoPanSpeed, 13261 padding = this._marker.options.autoPanPadding, 13262 iconPos = getPosition(marker._icon), 13263 bounds = map.getPixelBounds(), 13264 origin = map.getPixelOrigin(); 13265 var panBounds = toBounds(bounds.min._subtract(origin).add(padding), bounds.max._subtract(origin).subtract(padding)); 13266 if (!panBounds.contains(iconPos)) { 13267 // Compute incremental movement 13268 var movement = toPoint((Math.max(panBounds.max.x, iconPos.x) - panBounds.max.x) / (bounds.max.x - panBounds.max.x) - (Math.min(panBounds.min.x, iconPos.x) - panBounds.min.x) / (bounds.min.x - panBounds.min.x), (Math.max(panBounds.max.y, iconPos.y) - panBounds.max.y) / (bounds.max.y - panBounds.max.y) - (Math.min(panBounds.min.y, iconPos.y) - panBounds.min.y) / (bounds.min.y - panBounds.min.y)).multiplyBy(speed); 13269 map.panBy(movement, { 13270 animate: false 13271 }); 13272 this._draggable._newPos._add(movement); 13273 this._draggable._startPos._add(movement); 13274 setPosition(marker._icon, this._draggable._newPos); 13275 this._onDrag(e);
13276 this._panRequest = requestAnimFrame(this._adjustPan.bind(this, e)); 13277 } 13278 }, 13279 _onDragStart: function _onDragStart() { 13280 // @section Dragging events 13281 // @event dragstart: Event 13282 // Fired when the user starts dragging the marker. 13283 13284 // @event movestart: Event 13285 // Fired when the marker starts moving (because of dragging). 13286 13287 this._oldLatLng = this._marker.getLatLng(); 13288 13289 // When using ES6 imports it could not be set when `Popup` was not imported as well 13290 this._marker.closePopup && this._marker.closePopup(); 13291 this._marker.fire('movestart').fire('dragstart'); 13292 }, 13293 _onPreDrag: function _onPreDrag(e) { 13294 if (this._marker.options.autoPan) { 13295 cancelAnimFrame(this._panRequest); 13296 this._panRequest = requestAnimFrame(this._adjustPan.bind(this, e)); 13297 } 13298 }, 13299 _onDrag: function _onDrag(e) { 13300 var marker = this._marker, 13301 shadow = marker._shadow, 13302 iconPos = getPosition(marker._icon), 13303 latlng = marker._map.layerPointToLatLng(iconPos); 13304 13305 // update shadow position 13306 if (shadow) { 13307 setPosition(shadow, iconPos); 13308 } 13309 marker._latlng = latlng; 13310 e.latlng = latlng; 13311 e.oldLatLng = this._oldLatLng; 13312 13313 // @event drag: Event 13314 // Fired repeatedly while the user drags the marker. 13315 marker.fire('move', e).fire('drag', e); 13316 }, 13317 _onDragEnd: function _onDragEnd(e) { 13318 // @event dragend: DragEndEvent 13319 // Fired when the user stops dragging the marker. 13320 13321 cancelAnimFrame(this._panRequest); 13322 13323 // @event moveend: Event 13324 // Fired when the marker stops moving (because of dragging). 13325 delete this._oldLatLng; 13326 this._marker.fire('moveend').fire('dragend', e); 13327 } 13328 }); 13329 13330 /* 13331 * @class Marker 13332 * @inherits Interactive layer 13333 * @aka L.Marker 13334 * L.Marker is used to display clickable/draggable icons on the map. Extends `Layer`. 13335 * 13336 * @example 13337 * 13338 * ```js 13339 * L.marker([50.5, 30.5]).addTo(map); 13340 * ``` 13341 */ 13342 13343 var Marker = Layer.extend({ 13344 // @section 13345 // @aka Marker options 13346 options: { 13347 // @option icon: Icon = * 13348 // Icon instance to use for rendering the marker. 13349 // See [Icon documentation](#L.Icon) for details on how to customize the marker icon. 13350 // If not specified, a common instance of `L.Icon.Default` is used. 13351 icon: new IconDefault(), 13352 // Option inherited from "Interactive layer" abstract class 13353 interactive: true, 13354 // @option keyboard: Boolean = true 13355 // Whether the marker can be tabbed to with a keyboard and clicked by pressing enter. 13356 keyboard: true, 13357 // @option title: String = '' 13358 // Text for the browser tooltip that appear on marker hover (no tooltip by default). 13359 // [Useful for accessibility](https://leafletjs.com/examples/accessibility/#markers-must-be-labelled). 13360 title: '', 13361 // @option alt: String = 'Marker' 13362 // Text for the `alt` attribute of the icon image. 13363 // [Useful for accessibility](https://leafletjs.com/examples/accessibility/#markers-must-be-labelled). 13364 alt: 'Marker', 13365 // @option zIndexOffset: Number = 0 13366 // 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). 13367 zIndexOffset: 0, 13368 // @option opacity: Number = 1.0 13369 // The opacity of the marker. 13370 opacity: 1, 13371 // @option riseOnHover: Boolean = false 13372 // If `true`, the marker will get on top of others when you hover the mouse over it. 13373 riseOnHover: false, 13374 // @option riseOffset: Number = 250 13375 // The z-index offset used for the `riseOnHover` feature. 13376 riseOffset: 250, 13377 // @option pane: String = 'markerPane' 13378 // `Map pane` where the markers icon will be added. 13379 pane: 'markerPane', 13380 // @option shadowPane: String = 'shadowPane' 13381 // `Map pane` where the markers shadow will be added. 13382 shadowPane: 'shadowPane', 13383 // @option bubblingMouseEvents: Boolean = false 13384 // When `true`, a mouse event on this marker will trigger the same event on the map 13385 // (unless [`L.DomEvent.stopPropagation`](#domevent-stoppropagation) is used). 13386 bubblingMouseEvents: false, 13387 // @option autoPanOnFocus: Boolean = true 13388 // When `true`, the map will pan whenever the marker is focused (via 13389 // e.g. pressing `tab` on the keyboard) to ensure the marker is 13390 // visible within the map's bounds 13391 autoPanOnFocus: true, 13392 // @section Draggable marker options 13393 // @option draggable: Boolean = false 13394 // Whether the marker is draggable with mouse/touch or not. 13395 draggable: false, 13396 // @option autoPan: Boolean = false 13397 // Whether to pan the map when dragging this marker near its edge or not. 13398 autoPan: false, 13399 // @option autoPanPadding: Point = Point(50, 50) 13400 // Distance (in pixels to the left/right and to the top/bottom) of the 13401 // map edge to start panning the map. 13402 autoPanPadding: [50, 50], 13403 // @option autoPanSpeed: Number = 10 13404 // Number of pixels the map should pan by. 13405 autoPanSpeed: 10 13406 }, 13407 /* @section 13408 * 13409 * In addition to [shared layer methods](#Layer) like `addTo()` and `remove()` and [popup methods](#Popup) like bindPopup() you can also use the following methods: 13410 */ 13411 13412 initialize: function initialize(latlng, options) { 13413 setOptions(this, options); 13414 this._latlng = toLatLng(latlng); 13415 },
vendor: 8,789 bytes, lines 13416-13669
13416 onAdd: function onAdd(map) { 13417 this._zoomAnimated = this._zoomAnimated && map.options.markerZoomAnimation; 13418 if (this._zoomAnimated) { 13419 map.on('zoomanim', this._animateZoom, this); 13420 } 13421 this._initIcon(); 13422 this.update(); 13423 }, 13424 onRemove: function onRemove(map) { 13425 if (this.dragging && this.dragging.enabled()) { 13426 this.options.draggable = true; 13427 this.dragging.removeHooks(); 13428 } 13429 delete this.dragging; 13430 if (this._zoomAnimated) { 13431 map.off('zoomanim', this._animateZoom, this); 13432 } 13433 this._removeIcon(); 13434 this._removeShadow(); 13435 }, 13436 getEvents: function getEvents() { 13437 return { 13438 zoom: this.update, 13439 viewreset: this.update 13440 }; 13441 }, 13442 // @method getLatLng: LatLng 13443 // Returns the current geographical position of the marker. 13444 getLatLng: function getLatLng() { 13445 return this._latlng; 13446 }, 13447 // @method setLatLng(latlng: LatLng): this 13448 // Changes the marker position to the given point. 13449 setLatLng: function setLatLng(latlng) { 13450 var oldLatLng = this._latlng; 13451 this._latlng = toLatLng(latlng); 13452 this.update(); 13453 13454 // @event move: Event 13455 // 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`. 13456 return this.fire('move', { 13457 oldLatLng: oldLatLng, 13458 latlng: this._latlng 13459 }); 13460 }, 13461 // @method setZIndexOffset(offset: Number): this 13462 // Changes the [zIndex offset](#marker-zindexoffset) of the marker. 13463 setZIndexOffset: function setZIndexOffset(offset) { 13464 this.options.zIndexOffset = offset; 13465 return this.update(); 13466 }, 13467 // @method getIcon: Icon 13468 // Returns the current icon used by the marker 13469 getIcon: function getIcon() { 13470 return this.options.icon; 13471 }, 13472 // @method setIcon(icon: Icon): this 13473 // Changes the marker icon. 13474 setIcon: function setIcon(icon) { 13475 this.options.icon = icon; 13476 if (this._map) { 13477 this._initIcon(); 13478 this.update(); 13479 } 13480 if (this._popup) { 13481 this.bindPopup(this._popup, this._popup.options); 13482 } 13483 return this; 13484 }, 13485 getElement: function getElement() { 13486 return this._icon; 13487 }, 13488 update: function update() { 13489 if (this._icon && this._map) { 13490 var pos = this._map.latLngToLayerPoint(this._latlng).round(); 13491 this._setPos(pos); 13492 } 13493 return this; 13494 }, 13495 _initIcon: function _initIcon() { 13496 var options = this.options, 13497 classToAdd = 'leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide'); 13498 var icon = options.icon.createIcon(this._icon), 13499 addIcon = false; 13500 13501 // if we're not reusing the icon, remove the old one and init new one 13502 if (icon !== this._icon) { 13503 if (this._icon) { 13504 this._removeIcon(); 13505 } 13506 addIcon = true; 13507 if (options.title) { 13508 icon.title = options.title; 13509 } 13510 if (icon.tagName === 'IMG') { 13511 icon.alt = options.alt || ''; 13512 } 13513 } 13514 addClass(icon, classToAdd); 13515 if (options.keyboard) { 13516 icon.tabIndex = '0'; 13517 icon.setAttribute('role', 'button'); 13518 } 13519 this._icon = icon; 13520 if (options.riseOnHover) { 13521 this.on({ 13522 mouseover: this._bringToFront, 13523 mouseout: this._resetZIndex 13524 }); 13525 } 13526 if (this.options.autoPanOnFocus) { 13527 on(icon, 'focus', this._panOnFocus, this); 13528 } 13529 var newShadow = options.icon.createShadow(this._shadow), 13530 addShadow = false; 13531 if (newShadow !== this._shadow) { 13532 this._removeShadow(); 13533 addShadow = true; 13534 } 13535 if (newShadow) { 13536 addClass(newShadow, classToAdd); 13537 newShadow.alt = ''; 13538 } 13539 this._shadow = newShadow; 13540 if (options.opacity < 1) { 13541 this._updateOpacity(); 13542 } 13543 if (addIcon) { 13544 this.getPane().appendChild(this._icon); 13545 } 13546 this._initInteraction(); 13547 if (newShadow && addShadow) { 13548 this.getPane(options.shadowPane).appendChild(this._shadow); 13549 } 13550 }, 13551 _removeIcon: function _removeIcon() { 13552 if (this.options.riseOnHover) { 13553 this.off({ 13554 mouseover: this._bringToFront, 13555 mouseout: this._resetZIndex 13556 }); 13557 } 13558 if (this.options.autoPanOnFocus) { 13559 off(this._icon, 'focus', this._panOnFocus, this); 13560 } 13561 _remove(this._icon); 13562 this.removeInteractiveTarget(this._icon); 13563 this._icon = null; 13564 }, 13565 _removeShadow: function _removeShadow() { 13566 if (this._shadow) { 13567 _remove(this._shadow); 13568 } 13569 this._shadow = null; 13570 }, 13571 _setPos: function _setPos(pos) { 13572 if (this._icon) { 13573 setPosition(this._icon, pos); 13574 } 13575 if (this._shadow) { 13576 setPosition(this._shadow, pos); 13577 } 13578 this._zIndex = pos.y + this.options.zIndexOffset; 13579 this._resetZIndex(); 13580 }, 13581 _updateZIndex: function _updateZIndex(offset) { 13582 if (this._icon) { 13583 this._icon.style.zIndex = this._zIndex + offset; 13584 } 13585 }, 13586 _animateZoom: function _animateZoom(opt) { 13587 var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round(); 13588 this._setPos(pos); 13589 }, 13590 _initInteraction: function _initInteraction() { 13591 if (!this.options.interactive) { 13592 return; 13593 } 13594 addClass(this._icon, 'leaflet-interactive'); 13595 this.addInteractiveTarget(this._icon); 13596 if (MarkerDrag) { 13597 var draggable = this.options.draggable; 13598 if (this.dragging) { 13599 draggable = this.dragging.enabled(); 13600 this.dragging.disable(); 13601 } 13602 this.dragging = new MarkerDrag(this); 13603 if (draggable) { 13604 this.dragging.enable(); 13605 } 13606 } 13607 }, 13608 // @method setOpacity(opacity: Number): this 13609 // Changes the opacity of the marker. 13610 setOpacity: function setOpacity(opacity) { 13611 this.options.opacity = opacity; 13612 if (this._map) { 13613 this._updateOpacity(); 13614 } 13615 return this; 13616 }, 13617 _updateOpacity: function _updateOpacity() { 13618 var opacity = this.options.opacity; 13619 if (this._icon) { 13620 _setOpacity(this._icon, opacity); 13621 } 13622 if (this._shadow) { 13623 _setOpacity(this._shadow, opacity); 13624 } 13625 }, 13626 _bringToFront: function _bringToFront() { 13627 this._updateZIndex(this.options.riseOffset); 13628 }, 13629 _resetZIndex: function _resetZIndex() { 13630 this._updateZIndex(0); 13631 }, 13632 _panOnFocus: function _panOnFocus() { 13633 var map = this._map; 13634 if (!map) { 13635 return; 13636 } 13637 var iconOpts = this.options.icon.options; 13638 var size = iconOpts.iconSize ? toPoint(iconOpts.iconSize) : toPoint(0, 0); 13639 var anchor = iconOpts.iconAnchor ? toPoint(iconOpts.iconAnchor) : toPoint(0, 0); 13640 map.panInside(this._latlng, { 13641 paddingTopLeft: anchor, 13642 paddingBottomRight: size.subtract(anchor) 13643 }); 13644 }, 13645 _getPopupAnchor: function _getPopupAnchor() { 13646 return this.options.icon.options.popupAnchor; 13647 }, 13648 _getTooltipAnchor: function _getTooltipAnchor() { 13649 return this.options.icon.options.tooltipAnchor; 13650 } 13651 }); 13652 13653 // factory L.marker(latlng: LatLng, options? : Marker options) 13654 13655 // @factory L.marker(latlng: LatLng, options? : Marker options) 13656 // Instantiates a Marker object given a geographical point and optionally an options object. 13657 function marker(latlng, options) { 13658 return new Marker(latlng, options); 13659 } 13660 13661 /* 13662 * @class Path 13663 * @aka L.Path 13664 * @inherits Interactive layer 13665 * 13666 * An abstract class that contains options and constants shared between vector 13667 * overlays (Polygon, Polyline, Circle). Do not use it directly. Extends `Layer`. 13668 */ 13669
13670 var Path = Layer.extend({ 13671 // @section 13672 // @aka Path options 13673 options: { 13674 // @option stroke: Boolean = true 13675 // Whether to draw stroke along the path. Set it to `false` to disable borders on polygons or circles. 13676 stroke: true, 13677 // @option color: String = '#3388ff' 13678 // Stroke color 13679 color: '#3388ff', 13680 // @option weight: Number = 3 13681 // Stroke width in pixels 13682 weight: 3, 13683 // @option opacity: Number = 1.0 13684 // Stroke opacity 13685 opacity: 1, 13686 // @option lineCap: String= 'round' 13687 // A string that defines [shape to be used at the end](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-linecap) of the stroke. 13688 lineCap: 'round', 13689 // @option lineJoin: String = 'round' 13690 // A string that defines [shape to be used at the corners](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-linejoin) of the stroke. 13691 lineJoin: 'round', 13692 // @option dashArray: String = null 13693 // 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). 13694 dashArray: null, 13695 // @option dashOffset: String = null 13696 // 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). 13697 dashOffset: null, 13698 // @option fill: Boolean = depends 13699 // Whether to fill the path with color. Set it to `false` to disable filling on polygons or circles. 13700 fill: false, 13701 // @option fillColor: String = * 13702 // Fill color. Defaults to the value of the [`color`](#path-color) option 13703 fillColor: null, 13704 // @option fillOpacity: Number = 0.2 13705 // Fill opacity. 13706 fillOpacity: 0.2, 13707 // @option fillRule: String = 'evenodd' 13708 // A string that defines [how the inside of a shape](https://developer.mozilla.org/docs/Web/SVG/Attribute/fill-rule) is determined. 13709 fillRule: 'evenodd', 13710 // className: '', 13711 13712 // Option inherited from "Interactive layer" abstract class 13713 interactive: true, 13714 // @option bubblingMouseEvents: Boolean = true 13715 // When `true`, a mouse event on this path will trigger the same event on the map 13716 // (unless [`L.DomEvent.stopPropagation`](#domevent-stoppropagation) is used). 13717 bubblingMouseEvents: true 13718 }, 13719 beforeAdd: function beforeAdd(map) { 13720 // Renderer is set here because we need to call renderer.getEvents 13721 // before this.getEvents. 13722 this._renderer = map.getRenderer(this); 13723 }, 13724 onAdd: function onAdd() { 13725 this._renderer._initPath(this); 13726 this._reset(); 13727 this._renderer._addPath(this); 13728 }, 13729 onRemove: function onRemove() { 13730 this._renderer._removePath(this); 13731 }, 13732 // @method redraw(): this 13733 // Redraws the layer. Sometimes useful after you changed the coordinates that the path uses. 13734 redraw: function redraw() { 13735 if (this._map) { 13736 this._renderer._updatePath(this); 13737 } 13738 return this; 13739 }, 13740 // @method setStyle(style: Path options): this 13741 // Changes the appearance of a Path based on the options in the `Path options` object. 13742 setStyle: function setStyle(style) { 13743 setOptions(this, style); 13744 if (this._renderer) { 13745 this._renderer._updateStyle(this); 13746 if (this.options.stroke && style && Object.prototype.hasOwnProperty.call(style, 'weight')) { 13747 this._updateBounds(); 13748 } 13749 } 13750 return this; 13751 }, 13752 // @method bringToFront(): this 13753 // Brings the layer to the top of all path layers. 13754 bringToFront: function bringToFront() { 13755 if (this._renderer) { 13756 this._renderer._bringToFront(this); 13757 } 13758 return this; 13759 }, 13760 // @method bringToBack(): this 13761 // Brings the layer to the bottom of all path layers. 13762 bringToBack: function bringToBack() { 13763 if (this._renderer) { 13764 this._renderer._bringToBack(this); 13765 } 13766 return this; 13767 }, 13768 getElement: function getElement() { 13769 return this._path; 13770 }, 13771 _reset: function _reset() { 13772 // defined in child classes 13773 this._project(); 13774 this._update(); 13775 }, 13776 _clickTolerance: function _clickTolerance() { 13777 // used when doing hit detection for Canvas layers 13778 return (this.options.stroke ? this.options.weight / 2 : 0) + (this._renderer.options.tolerance || 0); 13779 } 13780 }); 13781 13782 /* 13783 * @class CircleMarker 13784 * @aka L.CircleMarker 13785 * @inherits Path 13786 * 13787 * A circle of a fixed size with radius specified in pixels. Extends `Path`. 13788 */ 13789 13790 var CircleMarker = Path.extend({ 13791 // @section 13792 // @aka CircleMarker options 13793 options: { 13794 fill: true, 13795 // @option radius: Number = 10 13796 // Radius of the circle marker, in pixels 13797 radius: 10 13798 }, 13799 initialize: function initialize(latlng, options) { 13800 setOptions(this, options); 13801 this._latlng = toLatLng(latlng); 13802 this._radius = this.options.radius; 13803 }, 13804 // @method setLatLng(latLng: LatLng): this 13805 // Sets the position of a circle marker to a new location. 13806 setLatLng: function setLatLng(latlng) { 13807 var oldLatLng = this._latlng; 13808 this._latlng = toLatLng(latlng); 13809 this.redraw(); 13810 13811 // @event move: Event 13812 // Fired when the marker is moved via [`setLatLng`](#circlemarker-setlatlng). Old and new co
13812ordinates are included in event arguments as `oldLatLng`, `latlng`. 13813 return this.fire('move', { 13814 oldLatLng: oldLatLng, 13815 latlng: this._latlng 13816 }); 13817 }, 13818 // @method getLatLng(): LatLng 13819 // Returns the current geographical position of the circle marker 13820 getLatLng: function getLatLng() { 13821 return this._latlng; 13822 }, 13823 // @method setRadius(radius: Number): this 13824 // Sets the radius of a circle marker. Units are in pixels. 13825 setRadius: function setRadius(radius) { 13826 this.options.radius = this._radius = radius; 13827 return this.redraw(); 13828 }, 13829 // @method getRadius(): Number 13830 // Returns the current radius of the circle 13831 getRadius: function getRadius() { 13832 return this._radius; 13833 }, 13834 setStyle: function setStyle(options) { 13835 var radius = options && options.radius || this._radius; 13836 Path.prototype.setStyle.call(this, options); 13837 this.setRadius(radius); 13838 return this; 13839 }, 13840 _project: function _project() { 13841 this._point = this._map.latLngToLayerPoint(this._latlng); 13842 this._updateBounds(); 13843 }, 13844 _updateBounds: function _updateBounds() { 13845 var r = this._radius, 13846 r2 = this._radiusY || r, 13847 w = this._clickTolerance(), 13848 p = [r + w, r2 + w]; 13849 this._pxBounds = new Bounds(this._point.subtract(p), this._point.add(p)); 13850 }, 13851 _update: function _update() { 13852 if (this._map) { 13853 this._updatePath(); 13854 } 13855 }, 13856 _updatePath: function _updatePath() { 13857 this._renderer._updateCircle(this); 13858 }, 13859 _empty: function _empty() { 13860 return this._radius && !this._renderer._bounds.intersects(this._pxBounds); 13861 }, 13862 // Needed by the `Canvas` renderer for interactivity 13863 _containsPoint: function _containsPoint(p) { 13864 return p.distanceTo(this._point) <= this._radius + this._clickTolerance(); 13865 } 13866 }); 13867 13868 // @factory L.circleMarker(latlng: LatLng, options?: CircleMarker options) 13869 // Instantiates a circle marker object given a geographical point, and an optional options object. 13870 function circleMarker(latlng, options) { 13871 return new CircleMarker(latlng, options); 13872 } 13873 13874 /* 13875 * @class Circle 13876 * @aka L.Circle 13877 * @inherits CircleMarker 13878 * 13879 * A class for drawing circle overlays on a map. Extends `CircleMarker`. 13880 * 13881 * It's an approximation and starts to diverge from a real circle closer to poles (due to projection distortion). 13882 * 13883 * @example 13884 * 13885 * ```js 13886 * L.circle([50.5, 30.5], {radius: 200}).addTo(map); 13887 * ``` 13888 */ 13889 13890 var Circle = CircleMarker.extend({ 13891 initialize: function initialize(latlng, options, legacyOptions) { 13892 if (typeof options === 'number') { 13893 // Backwards compatibility with 0.7.x factory (latlng, radius, options?) 13894 options = extend({}, legacyOptions, { 13895 radius: options 13896 }); 13897 } 13898 setOptions(this, options); 13899 this._latlng = toLatLng(latlng); 13900 if (isNaN(this.options.radius)) { 13901 throw new Error('Circle radius cannot be NaN'); 13902 } 13903 13904 // @section 13905 // @aka Circle options 13906 // @option radius: Number; Radius of the circle, in meters. 13907 this._mRadius = this.options.radius; 13908 }, 13909 // @method setRadius(radius: Number): this 13910 // Sets the radius of a circle. Units are in meters. 13911 setRadius: function setRadius(radius) { 13912 this._mRadius = radius; 13913 return this.redraw(); 13914 }, 13915 // @method getRadius(): Number 13916 // Returns the current radius of a circle. Units are in meters. 13917 getRadius: function getRadius() { 13918 return this._mRadius; 13919 }, 13920 // @method getBounds(): LatLngBounds 13921 // Returns the `LatLngBounds` of the path. 13922 getBounds: function getBounds() { 13923 var half = [this._radius, this._radiusY || this._radius];
vendor: 5,938 bytes, lines 13924-14071
13924 return new LatLngBounds(this._map.layerPointToLatLng(this._point.subtract(half)), this._map.layerPointToLatLng(this._point.add(half))); 13925 }, 13926 setStyle: Path.prototype.setStyle, 13927 _project: function _project() { 13928 var lng = this._latlng.lng, 13929 lat = this._latlng.lat, 13930 map = this._map, 13931 crs = map.options.crs; 13932 if (crs.distance === Earth.distance) { 13933 var d = Math.PI / 180, 13934 latR = this._mRadius / Earth.R / d, 13935 top = map.project([lat + latR, lng]), 13936 bottom = map.project([lat - latR, lng]), 13937 p = top.add(bottom).divideBy(2), 13938 lat2 = map.unproject(p).lat, 13939 lngR = Math.acos((Math.cos(latR * d) - Math.sin(lat * d) * Math.sin(lat2 * d)) / (Math.cos(lat * d) * Math.cos(lat2 * d))) / d; 13940 if (isNaN(lngR) || lngR === 0) { 13941 lngR = latR / Math.cos(Math.PI / 180 * lat); // Fallback for edge case, #2425 13942 } 13943 this._point = p.subtract(map.getPixelOrigin()); 13944 this._radius = isNaN(lngR) ? 0 : p.x - map.project([lat2, lng - lngR]).x; 13945 this._radiusY = p.y - top.y; 13946 } else { 13947 var latlng2 = crs.unproject(crs.project(this._latlng).subtract([this._mRadius, 0])); 13948 this._point = map.latLngToLayerPoint(this._latlng); 13949 this._radius = this._point.x - map.latLngToLayerPoint(latlng2).x; 13950 } 13951 this._updateBounds(); 13952 } 13953 }); 13954 13955 // @factory L.circle(latlng: LatLng, options?: Circle options) 13956 // Instantiates a circle object given a geographical point, and an options object 13957 // which contains the circle radius. 13958 // @alternative 13959 // @factory L.circle(latlng: LatLng, radius: Number, options?: Circle options) 13960 // Obsolete way of instantiating a circle, for compatibility with 0.7.x code. 13961 // Do not use in new applications or plugins. 13962 function circle(latlng, options, legacyOptions) { 13963 return new Circle(latlng, options, legacyOptions); 13964 } 13965 13966 /* 13967 * @class Polyline 13968 * @aka L.Polyline 13969 * @inherits Path 13970 * 13971 * A class for drawing polyline overlays on a map. Extends `Path`. 13972 * 13973 * @example 13974 * 13975 * ```js 13976 * // create a red polyline from an array of LatLng points 13977 * var latlngs = [ 13978 * [45.51, -122.68], 13979 * [37.77, -122.43], 13980 * [34.04, -118.2] 13981 * ]; 13982 * 13983 * var polyline = L.polyline(latlngs, {color: 'red'}).addTo(map); 13984 * 13985 * // zoom the map to the polyline 13986 * map.fitBounds(polyline.getBounds()); 13987 * ``` 13988 * 13989 * You can also pass a multi-dimensional array to represent a `MultiPolyline` shape: 13990 * 13991 * ```js 13992 * // create a red polyline from an array of arrays of LatLng points 13993 * var latlngs = [ 13994 * [[45.51, -122.68], 13995 * [37.77, -122.43], 13996 * [34.04, -118.2]], 13997 * [[40.78, -73.91], 13998 * [41.83, -87.62], 13999 * [32.76, -96.72]] 14000 * ]; 14001 * ``` 14002 */ 14003 14004 var Polyline = Path.extend({ 14005 // @section 14006 // @aka Polyline options 14007 options: { 14008 // @option smoothFactor: Number = 1.0 14009 // How much to simplify the polyline on each zoom level. More means 14010 // better performance and smoother look, and less means more accurate representation. 14011 smoothFactor: 1.0, 14012 // @option noClip: Boolean = false 14013 // Disable polyline clipping. 14014 noClip: false 14015 }, 14016 initialize: function initialize(latlngs, options) { 14017 setOptions(this, options); 14018 this._setLatLngs(latlngs); 14019 }, 14020 // @method getLatLngs(): LatLng[] 14021 // Returns an array of the points in the path, or nested arrays of points in case of multi-polyline. 14022 getLatLngs: function getLatLngs() { 14023 return this._latlngs; 14024 }, 14025 // @method setLatLngs(latlngs: LatLng[]): this 14026 // Replaces all the points in the polyline with the given array of geographical points. 14027 setLatLngs: function setLatLngs(latlngs) { 14028 this._setLatLngs(latlngs); 14029 return this.redraw(); 14030 }, 14031 // @method isEmpty(): Boolean 14032 // Returns `true` if the Polyline has no LatLngs. 14033 isEmpty: function isEmpty() { 14034 return !this._latlngs.length; 14035 }, 14036 // @method closestLayerPoint(p: Point): Point 14037 // Returns the point closest to `p` on the Polyline. 14038 closestLayerPoint: function closestLayerPoint(p) { 14039 var minDistance = Infinity, 14040 minPoint = null, 14041 closest = _sqClosestPointOnSegment, 14042 p1, 14043 p2; 14044 for (var j = 0, jLen = this._parts.length; j < jLen; j++) { 14045 var points = this._parts[j]; 14046 for (var i = 1, len = points.length; i < len; i++) { 14047 p1 = points[i - 1]; 14048 p2 = points[i]; 14049 var sqDist = closest(p, p1, p2, true); 14050 if (sqDist < minDistance) { 14051 minDistance = sqDist; 14052 minPoint = closest(p, p1, p2); 14053 } 14054 } 14055 } 14056 if (minPoint) { 14057 minPoint.distance = Math.sqrt(minDistance); 14058 } 14059 return minPoint; 14060 }, 14061 // @method getCenter(): LatLng 14062 // Returns the center ([centroid](https://en.wikipedia.org/wiki/Centroid)) of the polyline. 14063 getCenter: function getCenter() { 14064 // throws error when not yet added to map as this center calculation requires projected coordinates 14065 if (!this._map) { 14066 throw new Error('Must add layer to map before using getCenter()'); 14067 } 14068 return polylineCenter(this._defaultShape(), this._map.options.crs); 14069 }, 14070 // @method getBounds(): LatLngBounds 14071 // Returns the `LatLngBounds` of the path.
14072 getBounds: function getBounds() { 14073 return this._bounds; 14074 }, 14075 // @method addLatLng(latlng: LatLng, latlngs?: LatLng[]): this 14076 // Adds a given point to the polyline. By default, adds to the first ring of 14077 // the polyline in case of a multi-polyline, but can be overridden by passing 14078 // a specific ring as a LatLng array (that you can earlier access with [`getLatLngs`](#polyline-getlatlngs)). 14079 addLatLng: function addLatLng(latlng, latlngs) { 14080 latlngs = latlngs || this._defaultShape(); 14081 latlng = toLatLng(latlng); 14082 latlngs.push(latlng); 14083 this._bounds.extend(latlng); 14084 return this.redraw(); 14085 }, 14086 _setLatLngs: function _setLatLngs(latlngs) { 14087 this._bounds = new LatLngBounds(); 14088 this._latlngs = this._convertLatLngs(latlngs); 14089 }, 14090 _defaultShape: function _defaultShape() { 14091 return isFlat(this._latlngs) ? this._latlngs : this._latlngs[0]; 14092 }, 14093 // recursively convert latlngs input into actual LatLng instances; calculate bounds along the way 14094 _convertLatLngs: function _convertLatLngs(latlngs) { 14095 var result = [], 14096 flat = isFlat(latlngs); 14097 for (var i = 0, len = latlngs.length; i < len; i++) { 14098 if (flat) { 14099 result[i] = toLatLng(latlngs[i]); 14100 this._bounds.extend(result[i]); 14101 } else { 14102 result[i] = this._convertLatLngs(latlngs[i]); 14103 } 14104 } 14105 return result; 14106 }, 14107 _project: function _project() { 14108 var pxBounds = new Bounds(); 14109 this._rings = []; 14110 this._projectLatlngs(this._latlngs, this._rings, pxBounds); 14111 if (this._bounds.isValid() && pxBounds.isValid()) { 14112 this._rawPxBounds = pxBounds; 14113 this._updateBounds(); 14114 } 14115 }, 14116 _updateBounds: function _updateBounds() { 14117 var w = this._clickTolerance(), 14118 p = new Point(w, w); 14119 if (!this._rawPxBounds) { 14120 return; 14121 } 14122 this._pxBounds = new Bounds([this._rawPxBounds.min.subtract(p), this._rawPxBounds.max.add(p)]); 14123 }, 14124 // recursively turns latlngs into a set of rings with projected coordinates 14125 _projectLatlngs: function _projectLatlngs(latlngs, result, projectedBounds) { 14126 var flat = latlngs[0] instanceof LatLng, 14127 len = latlngs.length, 14128 i, 14129 ring; 14130 if (flat) { 14131 ring = []; 14132 for (i = 0; i < len; i++) { 14133 ring[i] = this._map.latLngToLayerPoint(latlngs[i]); 14134 projectedBounds.extend(ring[i]); 14135 } 14136 result.push(ring); 14137 } else { 14138 for (i = 0; i < len; i++) { 14139 this._projectLatlngs(latlngs[i], result, projectedBounds); 14140 } 14141 } 14142 }, 14143 // clip polyline by renderer bounds so that we have less to render for performance 14144 _clipPoints: function _clipPoints() { 14145 var bounds = this._renderer._bounds; 14146 this._parts = []; 14147 if (!this._pxBounds || !this._pxBounds.intersects(bounds)) { 14148 return; 14149 } 14150 if (this.options.noClip) { 14151 this._parts = this._rings; 14152 return; 14153 } 14154 var parts = this._parts, 14155 i, 14156 j, 14157 k, 14158 len, 14159 len2, 14160 segment, 14161 points; 14162 for (i = 0, k = 0, len = this._rings.length; i < len; i++) { 14163 points = this._rings[i]; 14164 for (j = 0, len2 = points.length; j < len2 - 1; j++) { 14165 segment = clipSegment(points[j], points[j + 1], bounds, j, true); 14166 if (!segment) { 14167 continue; 14168 } 14169 parts[k] = parts[k] || []; 14170 parts[k].push(segment[0]); 14171 14172 // if segment goes out of screen, or it's the last one, it's the end of the line part 14173 if (segment[1] !== points[j + 1] || j === len2 - 2) { 14174 parts[k].push(segment[1]); 14175 k++; 14176 } 14177 } 14178 } 14179 }, 14180 // simplify each clipped part of the polyline for performance 14181 _simplifyPoints: function _simplifyPoints() { 14182 var parts = this._parts, 14183 tolerance = this.options.smoothFactor; 14184 for (var i = 0, len = parts.length; i < len; i++) { 14185 parts[i] = simplify(parts[i], tolerance); 14186 } 14187 }, 14188 _update: function _update() { 14189 if (!this._map) { 14190 return; 14191 } 14192 this._clipPoints(); 14193 this._simplifyPoints(); 14194 this._updatePath(); 14195 }, 14196 _updatePath: function _updatePath() { 14197 this._renderer._updatePoly(this); 14198 }, 14199 // Needed by the `Canvas` renderer for interactivity 14200 _containsPoint: function _containsPoint(p, closed) { 14201 var i, 14202 j, 14203 k, 14204 len, 14205 len2, 14206 part, 14207 w = this._clickTolerance(); 14208 if (!this._pxBounds || !this._pxBounds.contains(p)) { 14209 return false;
14210 } 14211 14212 // hit detection for polylines 14213 for (i = 0, len = this._parts.length; i < len; i++) { 14214 part = this._parts[i]; 14215 for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) { 14216 if (!closed && j === 0) { 14217 continue; 14218 } 14219 if (pointToSegmentDistance(p, part[k], part[j]) <= w) { 14220 return true; 14221 } 14222 } 14223 } 14224 return false; 14225 } 14226 }); 14227 14228 // @factory L.polyline(latlngs: LatLng[], options?: Polyline options) 14229 // Instantiates a polyline object given an array of geographical points and 14230 // optionally an options object. You can create a `Polyline` object with 14231 // multiple separate lines (`MultiPolyline`) by passing an array of arrays 14232 // of geographic points. 14233 function polyline(latlngs, options) { 14234 return new Polyline(latlngs, options); 14235 } 14236 14237 // Retrocompat. Allow plugins to support Leaflet versions before and after 1.1. 14238 Polyline._flat = _flat; 14239 14240 /* 14241 * @class Polygon 14242 * @aka L.Polygon 14243 * @inherits Polyline 14244 * 14245 * A class for drawing polygon overlays on a map. Extends `Polyline`. 14246 * 14247 * 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. 14248 * 14249 * 14250 * @example 14251 * 14252 * ```js 14253 * // create a red polygon from an array of LatLng points 14254 * var latlngs = [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]]; 14255 * 14256 * var polygon = L.polygon(latlngs, {color: 'red'}).addTo(map); 14257 * 14258 * // zoom the map to the polygon 14259 * map.fitBounds(polygon.getBounds()); 14260 * ``` 14261 * 14262 * 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: 14263 * 14264 * ```js 14265 * var latlngs = [ 14266 * [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]], // outer ring 14267 * [[37.29, -108.58],[40.71, -108.58],[40.71, -102.50],[37.29, -102.50]] // hole 14268 * ]; 14269 * ``` 14270 * 14271 * Additionally, you can pass a multi-dimensional array to represent a MultiPolygon shape. 14272 * 14273 * ```js 14274 * var latlngs = [ 14275 * [ // first polygon 14276 * [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]], // outer ring 14277 * [[37.29, -108.58],[40.71, -108.58],[40.71, -102.50],[37.29, -102.50]] // hole 14278 * ], 14279 * [ // second polygon 14280 * [[41, -111.03],[45, -111.04],[45, -104.05],[41, -104.05]] 14281 * ] 14282 * ]; 14283 * ``` 14284 */ 14285 14286 var Polygon = Polyline.extend({ 14287 options: { 14288 fill: true 14289 }, 14290 isEmpty: function isEmpty() { 14291 return !this._latlngs.length || !this._latlngs[0].length; 14292 }, 14293 // @method getCenter(): LatLng 14294 // Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the Polygon. 14295 getCenter: function getCenter() { 14296 // throws error when not yet added to map as this center calculation requires projected coordinates 14297 if (!this._map) { 14298 throw new Error('Must add layer to map before using getCenter()'); 14299 } 14300 return polygonCenter(this._defaultShape(), this._map.options.crs); 14301 }, 14302 _convertLatLngs: function _convertLatLngs(latlngs) { 14303 var result = Polyline.prototype._convertLatLngs.call(this, latlngs), 14304 len = result.length; 14305 14306 // remove last point if it equals first one 14307 if (len >= 2 && result[0] instanceof LatLng && result[0].equals(result[len - 1])) { 14308 result.pop(); 14309 } 14310 return result; 14311 }, 14312 _setLatLngs: function _setLatLngs(latlngs) { 14313 Polyline.prototype._setLatLngs.call(this, latlngs); 14314 if (isFlat(this._latlngs)) { 14315 this._latlngs = [this._latlngs]; 14316 } 14317 }, 14318 _defaultShape: function _defaultShape() { 14319 return isFlat(this._latlngs[0]) ? this._latlngs[0] : this._latlngs[0][0]; 14320 }, 14321 _clipPoints: function _clipPoints() { 14322 // polygons need a different clipping algorithm so we redefine that 14323 14324 var bounds = this._renderer._bounds, 14325 w = this.options.weight, 14326 p = new Point(w, w); 14327 14328 // increase clip padding by stroke width to avoid stroke on clip edges 14329 bounds = new Bounds(bounds.min.subtract(p), bounds.max.add(p)); 14330 this._parts = []; 14331 if (!this._pxBounds || !this._pxBounds.intersects(bounds)) { 14332 return; 14333 } 14334 if (this.options.noClip) { 14335 this._parts = this._rings; 14336 return; 14337 } 14338 for (var i = 0, len = this._rings.length, clipped; i < len; i++) { 14339 clipped = clipPolygon(this._rings[i], bounds, true); 14340 if (clipped.length) { 14341 this._parts.push(clipped); 14342 } 14343 } 14344 }, 14345 _updatePath: function _updatePath() { 14346 this._renderer._updatePoly(this, true); 14347 }, 14348 // Needed by the `Canvas` renderer for interactivity 14349 _containsPoint: function _containsPoint(p) { 14350 var inside = false, 14351 part, 14352 p1, 14353 p2, 14354 i, 14355 j, 14356 k, 14357 len, 14358 len2; 14359 if (!this._pxBounds || !this._pxBounds.contains(p)) { 14360 return false;
vendor: 17,625 bytes, lines 14361-14778
14361 } 14362 14363 // ray casting algorithm for detecting if point is in polygon 14364 for (i = 0, len = this._parts.length; i < len; i++) { 14365 part = this._parts[i]; 14366 for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) { 14367 p1 = part[j]; 14368 p2 = part[k]; 14369 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) { 14370 inside = !inside; 14371 } 14372 } 14373 } 14374 14375 // also check if it's on polygon stroke 14376 return inside || Polyline.prototype._containsPoint.call(this, p, true); 14377 } 14378 }); 14379 14380 // @factory L.polygon(latlngs: LatLng[], options?: Polyline options) 14381 function polygon(latlngs, options) { 14382 return new Polygon(latlngs, options); 14383 } 14384 14385 /* 14386 * @class GeoJSON 14387 * @aka L.GeoJSON 14388 * @inherits FeatureGroup 14389 * 14390 * Represents a GeoJSON object or an array of GeoJSON objects. Allows you to parse 14391 * GeoJSON data and display it on the map. Extends `FeatureGroup`. 14392 * 14393 * @example 14394 * 14395 * ```js 14396 * L.geoJSON(data, { 14397 * style: function (feature) { 14398 * return {color: feature.properties.color}; 14399 * } 14400 * }).bindPopup(function (layer) { 14401 * return layer.feature.properties.description; 14402 * }).addTo(map); 14403 * ``` 14404 */ 14405 14406 var GeoJSON = FeatureGroup.extend({ 14407 /* @section 14408 * @aka GeoJSON options 14409 * 14410 * @option pointToLayer: Function = * 14411 * A `Function` defining how GeoJSON points spawn Leaflet layers. It is internally 14412 * called when data is added, passing the GeoJSON point feature and its `LatLng`. 14413 * The default is to spawn a default `Marker`: 14414 * ```js 14415 * function(geoJsonPoint, latlng) { 14416 * return L.marker(latlng); 14417 * } 14418 * ``` 14419 * 14420 * @option style: Function = * 14421 * A `Function` defining the `Path options` for styling GeoJSON lines and polygons, 14422 * called internally when data is added. 14423 * The default value is to not override any defaults: 14424 * ```js 14425 * function (geoJsonFeature) { 14426 * return {} 14427 * } 14428 * ``` 14429 * 14430 * @option onEachFeature: Function = * 14431 * A `Function` that will be called once for each created `Feature`, after it has 14432 * been created and styled. Useful for attaching events and popups to features. 14433 * The default is to do nothing with the newly created layers: 14434 * ```js 14435 * function (feature, layer) {} 14436 * ``` 14437 * 14438 * @option filter: Function = * 14439 * A `Function` that will be used to decide whether to include a feature or not. 14440 * The default is to include all features: 14441 * ```js 14442 * function (geoJsonFeature) { 14443 * return true; 14444 * } 14445 * ``` 14446 * Note: dynamically changing the `filter` option will have effect only on newly 14447 * added data. It will _not_ re-evaluate already included features. 14448 * 14449 * @option coordsToLatLng: Function = * 14450 * A `Function` that will be used for converting GeoJSON coordinates to `LatLng`s. 14451 * The default is the `coordsToLatLng` static method. 14452 * 14453 * @option markersInheritOptions: Boolean = false 14454 * Whether default Markers for "Point" type Features inherit from group options. 14455 */ 14456 14457 initialize: function initialize(geojson, options) { 14458 setOptions(this, options); 14459 this._layers = {}; 14460 if (geojson) { 14461 this.addData(geojson); 14462 } 14463 }, 14464 // @method addData( <GeoJSON> data ): this 14465 // Adds a GeoJSON object to the layer. 14466 addData: function addData(geojson) { 14467 var features = isArray(geojson) ? geojson : geojson.features, 14468 i, 14469 len, 14470 feature; 14471 if (features) { 14472 for (i = 0, len = features.length; i < len; i++) { 14473 // only add this if geometry or geometries are set and not null 14474 feature = features[i]; 14475 if (feature.geometries || feature.geometry || feature.features || feature.coordinates) { 14476 this.addData(feature); 14477 } 14478 } 14479 return this; 14480 } 14481 var options = this.options; 14482 if (options.filter && !options.filter(geojson)) { 14483 return this; 14484 } 14485 var layer = geometryToLayer(geojson, options); 14486 if (!layer) { 14487 return this; 14488 } 14489 layer.feature = asFeature(geojson); 14490 layer.defaultOptions = layer.options; 14491 this.resetStyle(layer); 14492 if (options.onEachFeature) { 14493 options.onEachFeature(geojson, layer); 14494 } 14495 return this.addLayer(layer); 14496 }, 14497 // @method resetStyle( <Path> layer? ): this 14498 // Resets the given vector layer's style to the original GeoJSON style, useful for resetting style after hover events. 14499 // If `layer` is omitted, the style of all features in the current layer is reset. 14500 resetStyle: function resetStyle(layer) { 14501 if (layer === undefined) { 14502 return this.eachLayer(this.resetStyle, this); 14503 } 14504 // reset any custom styles 14505 layer.options = extend({}, layer.defaultOptions); 14506 this._setLayerStyle(layer, this.options.style); 14507 return this; 14508 }, 14509 // @method setStyle( <Function> style ): this 14510 // Changes styles of GeoJSON vector layers with the given style function. 14511 setStyle: function setStyle(style) { 14512 return this.eachLayer(function (layer) { 14513 this._setLayerStyle(layer, style); 14514 }, this); 14515 }, 14516 _setLayerStyle: function _setLayerStyle(layer, style) { 14517 if (layer.setStyle) { 14518 if (typeof style === 'function') { 14519 style = style(layer.feature); 14520 } 14521 layer.setStyle(style); 14522 } 14523 } 14524 }); 14525 14526 // @section 14527 // There are several static functions which can be called without instantiating L.GeoJSON: 14528 14529 // @function geometryToLayer(featureData: Object, options?: GeoJSON options): Layer 14530 // Creates a `Layer` from a given GeoJSON feature. Can use a custom 14531 // [`pointToLayer`](#geojson-pointtolayer) and/or [`coordsToLatLng`](#geojson-coordstolatlng) 14532 // functions if provided as options. 14533 function geometryToLayer(geojson, options) { 14534 var geometry = geojson.type === 'Feature' ? geojson.geometry : geojson, 14535 coords = geometry ? geometry.coordinates : null, 14536 layers = [], 14537 pointToLayer = options && options.pointToLayer, 14538 _coordsToLatLng = options && options.coordsToLatLng || coordsToLatLng, 14539 latlng, 14540 latlngs, 14541 i, 14542 len; 14543 if (!coords && !geometry) { 14544 return null; 14545 } 14546 switch (geometry.type) { 14547 case 'Point': 14548 latlng = _coordsToLatLng(coords); 14549 return _pointToLayer(pointToLayer, geojson, latlng, options); 14550 case 'MultiPoint': 14551 for (i = 0, len = coords.length; i < len; i++) { 14552 latlng = _coordsToLatLng(coords[i]); 14553 layers.push(_pointToLayer(pointToLayer, geojson, latlng, options)); 14554 } 14555 return new FeatureGroup(layers); 14556 case 'LineString': 14557 case 'MultiLineString': 14558 latlngs = coordsToLatLngs(coords, geometry.type === 'LineString' ? 0 : 1, _coordsToLatLng); 14559 return new Polyline(latlngs, options); 14560 case 'Polygon': 14561 case 'MultiPolygon': 14562 latlngs = coordsToLatLngs(coords, geometry.type === 'Polygon' ? 1 : 2, _coordsToLatLng); 14563 return new Polygon(latlngs, options); 14564 case 'GeometryCollection': 14565 for (i = 0, len = geometry.geometries.length; i < len; i++) { 14566 var geoLayer = geometryToLayer({ 14567 geometry: geometry.geometries[i], 14568 type: 'Feature', 14569 properties: geojson.properties 14570 }, options); 14571 if (geoLayer) { 14572 layers.push(geoLayer); 14573 } 14574 } 14575 return new FeatureGroup(layers); 14576 case 'FeatureCollection': 14577 for (i = 0, len = geometry.features.length; i < len; i++) { 14578 var featureLayer = geometryToLayer(geometry.features[i], options); 14579 if (featureLayer) { 14580 layers.push(featureLayer); 14581 } 14582 } 14583 return new FeatureGroup(layers); 14584 default: 14585 throw new Error('Invalid GeoJSON object.'); 14586 } 14587 } 14588 function _pointToLayer(pointToLayerFn, geojson, latlng, options) { 14589 return pointToLayerFn ? pointToLayerFn(geojson, latlng) : new Marker(latlng, options && options.markersInheritOptions && options); 14590 } 14591 14592 // @function coordsToLatLng(coords: Array): LatLng 14593 // Creates a `LatLng` object from an array of 2 numbers (longitude, latitude) 14594 // or 3 numbers (longitude, latitude, altitude) used in GeoJSON for points. 14595 function coordsToLatLng(coords) { 14596 return new LatLng(coords[1], coords[0], coords[2]); 14597 } 14598 14599 // @function coordsToLatLngs(coords: Array, levelsDeep?: Number, coordsToLatLng?: Function): Array 14600 // Creates a multidimensional array of `LatLng`s from a GeoJSON coordinates array. 14601 // `levelsDeep` specifies the nesting level (0 is for an array of points, 1 for an array of arrays of points, etc., 0 by default). 14602 // Can use a custom [`coordsToLatLng`](#geojson-coordstolatlng) function. 14603 function coordsToLatLngs(coords, levelsDeep, _coordsToLatLng) { 14604 var latlngs = []; 14605 for (var i = 0, len = coords.length, latlng; i < len; i++) { 14606 latlng = levelsDeep ? coordsToLatLngs(coords[i], levelsDeep - 1, _coordsToLatLng) : (_coordsToLatLng || coordsToLatLng)(coords[i]); 14607 latlngs.push(latlng); 14608 } 14609 return latlngs; 14610 } 14611 14612 // @function latLngToCoords(latlng: LatLng, precision?: Number|false): Array 14613 // Reverse of [`coordsToLatLng`](#geojson-coordstolatlng) 14614 // Coordinates values are rounded with [`formatNum`](#util-formatnum) function. 14615 function latLngToCoords(latlng, precision) { 14616 latlng = toLatLng(latlng); 14617 return latlng.alt !== undefined ? [formatNum(latlng.lng, precision), formatNum(latlng.lat, precision), formatNum(latlng.alt, precision)] : [formatNum(latlng.lng, precision), formatNum(latlng.lat, precision)]; 14618 } 14619 14620 // @function latLngsToCoords(latlngs: Array, levelsDeep?: Number, closed?: Boolean, precision?: Number|false): Array 14621 // Reverse of [`coordsToLatLngs`](#geojson-coordstolatlngs) 14622 // `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. 14623 // Coordinates values are rounded with [`formatNum`](#util-formatnum) function. 14624 function latLngsToCoords(latlngs, levelsDeep, closed, precision) { 14625 var coords = []; 14626 for (var i = 0, len = latlngs.length; i < len; i++) { 14627 // Check for flat arrays required to ensure unbalanced arrays are correctly converted in recursion 14628 coords.push(levelsDeep ? latLngsToCoords(latlngs[i], isFlat(latlngs[i]) ? 0 : levelsDeep - 1, closed, precision) : latLngToCoords(latlngs[i], precision)); 14629 } 14630 if (!levelsDeep && closed && coords.length > 0) { 14631 coords.push(coords[0].slice()); 14632 } 14633 return coords; 14634 } 14635 function getFeature(layer, newGeometry) { 14636 return layer.feature ? extend({}, layer.feature, { 14637 geometry: newGeometry 14638 }) : asFeature(newGeometry); 14639 } 14640 14641 // @function asFeature(geojson: Object): Object 14642 // Normalize GeoJSON geometries/features into GeoJSON features. 14643 function asFeature(geojson) { 14644 if (geojson.type === 'Feature' || geojson.type === 'FeatureCollection') { 14645 return geojson; 14646 } 14647 return { 14648 type: 'Feature', 14649 properties: {}, 14650 geometry: geojson 14651 }; 14652 } 14653 var PointToGeoJSON = { 14654 toGeoJSON: function toGeoJSON(precision) { 14655 return getFeature(this, { 14656 type: 'Point', 14657 coordinates: latLngToCoords(this.getLatLng(), precision) 14658 }); 14659 } 14660 }; 14661 14662 // @namespace Marker 14663 // @section Other methods 14664 // @method toGeoJSON(precision?: Number|false): Object 14665 // Coordinates values are rounded with [`formatNum`](#util-formatnum) function with given `precision`. 14666 // Returns a [`GeoJSON`](https://en.wikipedia.org/wiki/GeoJSON) representation of the marker (as a GeoJSON `Point` Feature). 14667 Marker.include(PointToGeoJSON); 14668 14669 // @namespace CircleMarker 14670 // @method toGeoJSON(precision?: Number|false): Object 14671 // Coordinates values are rounded with [`formatNum`](#util-formatnum) function with given `precision`. 14672 // Returns a [`GeoJSON`](https://en.wikipedia.org/wiki/GeoJSON) representation of the circle marker (as a GeoJSON `Point` Feature). 14673 Circle.include(PointToGeoJSON); 14674 CircleMarker.include(PointToGeoJSON); 14675 14676 // @namespace Polyline 14677 // @method toGeoJSON(precision?: Number|false): Object 14678 // Coordinates values are rounded with [`formatNum`](#util-formatnum) function with given `precision`. 14679 // Returns a [`GeoJSON`](https://en.wikipedia.org/wiki/GeoJSON) representation of the polyline (as a GeoJSON `LineString` or `MultiLineString` Feature). 14680 Polyline.include({ 14681 toGeoJSON: function toGeoJSON(precision) { 14682 var multi = !isFlat(this._latlngs); 14683 var coords = latLngsToCoords(this._latlngs, multi ? 1 : 0, false, precision); 14684 return getFeature(this, { 14685 type: (multi ? 'Multi' : '') + 'LineString', 14686 coordinates: coords 14687 }); 14688 } 14689 }); 14690 14691 // @namespace Polygon 14692 // @method toGeoJSON(precision?: Number|false): Object 14693 // Coordinates values are rounded with [`formatNum`](#util-formatnum) function with given `precision`. 14694 // Returns a [`GeoJSON`](https://en.wikipedia.org/wiki/GeoJSON) representation of the polygon (as a GeoJSON `Polygon` or `MultiPolygon` Feature). 14695 Polygon.include({ 14696 toGeoJSON: function toGeoJSON(precision) { 14697 var holes = !isFlat(this._latlngs), 14698 multi = holes && !isFlat(this._latlngs[0]); 14699 var coords = latLngsToCoords(this._latlngs, multi ? 2 : holes ? 1 : 0, true, precision); 14700 if (!holes) { 14701 coords = [coords]; 14702 } 14703 return getFeature(this, { 14704 type: (multi ? 'Multi' : '') + 'Polygon', 14705 coordinates: coords 14706 }); 14707 } 14708 }); 14709 14710 // @namespace LayerGroup 14711 LayerGroup.include({ 14712 toMultiPoint: function toMultiPoint(precision) { 14713 var coords = []; 14714 this.eachLayer(function (layer) { 14715 coords.push(layer.toGeoJSON(precision).geometry.coordinates); 14716 }); 14717 return getFeature(this, { 14718 type: 'MultiPoint', 14719 coordinates: coords 14720 }); 14721 }, 14722 // @method toGeoJSON(precision?: Number|false): Object 14723 // Coordinates values are rounded with [`formatNum`](#util-formatnum) function with given `precision`. 14724 // Returns a [`GeoJSON`](https://en.wikipedia.org/wiki/GeoJSON) representation of the layer group (as a GeoJSON `FeatureCollection`, `GeometryCollection`, or `MultiPoint`). 14725 toGeoJSON: function toGeoJSON(precision) { 14726 var type = this.feature && this.feature.geometry && this.feature.geometry.type; 14727 if (type === 'MultiPoint') { 14728 return this.toMultiPoint(precision); 14729 } 14730 var isGeometryCollection = type === 'GeometryCollection', 14731 jsons = []; 14732 this.eachLayer(function (layer) { 14733 if (layer.toGeoJSON) { 14734 var json = layer.toGeoJSON(precision); 14735 if (isGeometryCollection) { 14736 jsons.push(json.geometry); 14737 } else { 14738 var feature = asFeature(json); 14739 // Squash nested feature collections 14740 if (feature.type === 'FeatureCollection') { 14741 jsons.push.apply(jsons, feature.features); 14742 } else { 14743 jsons.push(feature); 14744 } 14745 } 14746 } 14747 }); 14748 if (isGeometryCollection) { 14749 return getFeature(this, { 14750 geometries: jsons, 14751 type: 'GeometryCollection' 14752 }); 14753 } 14754 return { 14755 type: 'FeatureCollection', 14756 features: jsons 14757 }; 14758 } 14759 }); 14760 14761 // @namespace GeoJSON 14762 // @factory L.geoJSON(geojson?: Object, options?: GeoJSON options) 14763 // Creates a GeoJSON layer. Optionally accepts an object in 14764 // [GeoJSON format](https://tools.ietf.org/html/rfc7946) to display on the map 14765 // (you can alternatively add it later with `addData` method) and an `options` object. 14766 function geoJSON(geojson, options) { 14767 return new GeoJSON(geojson, options); 14768 } 14769 14770 // Backward compatibility. 14771 var geoJson = geoJSON; 14772 14773 /* 14774 * @class ImageOverlay 14775 * @aka L.ImageOverlay 14776 * @inherits Interactive layer 14777 * 14778 * Used to load and display a single image over specific boun
14778ds of the map. Extends `Layer`. 14779 * 14780 * @example 14781 * 14782 * ```js 14783 * var imageUrl = 'https://maps.lib.utexas.edu/maps/historical/newark_nj_1922.jpg', 14784 * imageBounds = [[40.712216, -74.22655], [40.773941, -74.12544]]; 14785 * L.imageOverlay(imageUrl, imageBounds).addTo(map); 14786 * ``` 14787 */ 14788 14789 var ImageOverlay = Layer.extend({ 14790 // @section 14791 // @aka ImageOverlay options 14792 options: { 14793 // @option opacity: Number = 1.0 14794 // The opacity of the image overlay. 14795 opacity: 1, 14796 // @option alt: String = '' 14797 // Text for the `alt` attribute of the image (useful for accessibility). 14798 alt: '', 14799 // @option interactive: Boolean = false 14800 // If `true`, the image overlay will emit [mouse events](#interactive-layer) when clicked or hovered. 14801 interactive: false, 14802 // @option crossOrigin: Boolean|String = false 14803 // Whether the crossOrigin attribute will be added to the image. 14804 // 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. 14805 // Refer to [CORS Settings](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) for valid String values. 14806 crossOrigin: false, 14807 // @option errorOverlayUrl: String = '' 14808 // URL to the overlay image to show in place of the overlay that failed to load. 14809 errorOverlayUrl: '', 14810 // @option zIndex: Number = 1 14811 // The explicit [zIndex](https://developer.mozilla.org/docs/Web/CSS/CSS_Positioning/Understanding_z_index) of the overlay layer. 14812 zIndex: 1, 14813 // @option className: String = '' 14814 // A custom class name to assign to the image. Empty by default. 14815 className: '' 14816 }, 14817 initialize: function initialize(url, bounds, options) { 14818 // (String, LatLngBounds, Object) 14819 this._url = url; 14820 this._bounds = toLatLngBounds(bounds); 14821 setOptions(this, options); 14822 }, 14823 onAdd: function onAdd() { 14824 if (!this._image) { 14825 this._initImage(); 14826 if (this.options.opacity < 1) { 14827 this._updateOpacity(); 14828 } 14829 } 14830 if (this.options.interactive) { 14831 addClass(this._image, 'leaflet-interactive'); 14832 this.addInteractiveTarget(this._image); 14833 } 14834 this.getPane().appendChild(this._image); 14835 this._reset(); 14836 }, 14837 onRemove: function onRemove() { 14838 _remove(this._image); 14839 if (this.options.interactive) { 14840 this.removeInteractiveTarget(this._image); 14841 } 14842 }, 14843 // @method setOpacity(opacity: Number): this 14844 // Sets the opacity of the overlay. 14845 setOpacity: function setOpacity(opacity) { 14846 this.options.opacity = opacity; 14847 if (this._image) { 14848 this._updateOpacity(); 14849 } 14850 return this; 14851 }, 14852 setStyle: function setStyle(styleOpts) { 14853 if (styleOpts.opacity) { 14854 this.setOpacity(styleOpts.opacity); 14855 } 14856 return this; 14857 }, 14858 // @method bringToFront(): this 14859 // Brings the layer to the top of all overlays. 14860 bringToFront: function bringToFront() { 14861 if (this._map) { 14862 toFront(this._image); 14863 } 14864 return this; 14865 }, 14866 // @method bringToBack(): this 14867 // Brings the layer to the bottom of all overlays. 14868 bringToBack: function bringToBack() { 14869 if (this._map) { 14870 toBack(this._image); 14871 } 14872 return this; 14873 }, 14874 // @method setUrl(url: String): this 14875 // Changes the URL of the image. 14876 setUrl: function setUrl(url) { 14877 this._url = url; 14878 if (this._image) { 14879 this._image.src = url; 14880 } 14881 return this; 14882 }, 14883 // @method setBounds(bounds: LatLngBounds): this 14884 // Update the bounds that this ImageOverlay covers 14885 setBounds: function setBounds(bounds) { 14886 this._bounds = toLatLngBounds(bounds); 14887 if (this._map) { 14888 this._reset(); 14889 } 14890 return this; 14891 }, 14892 getEvents: function getEvents() { 14893 var events = { 14894 zoom: this._reset, 14895 viewreset: this._reset 14896 }; 14897 if (this._zoomAnimated) { 14898 events.zoomanim = this._animateZoom; 14899 } 14900 return events; 14901 }, 14902 // @method setZIndex(value: Number): this 14903 // Changes the [zIndex](#imageoverlay-zindex) of the image overlay. 14904 setZIndex: function setZIndex(value) { 14905 this.options.zIndex = value; 14906 this._updateZIndex(); 14907 return this; 14908 }, 14909 // @method getBounds(): LatLngBounds 14910 // Get the bounds that this ImageOverlay covers 14911 getBounds: function getBounds() { 14912 return this._bounds; 14913 }, 14914 // @method getElement(): HTMLElement 14915 // Returns the instance of [`HTMLImageElement`](https://developer.mozilla.org/docs/Web/API/HTMLImageElement) 14916 // used by this overlay. 14917 getElement: function getElement() { 14918 return this._image; 14919 }, 14920 _initImage: function _initImage() { 14921 var wasElementSupplied = this._url.tagName === 'IMG'; 14922 var img = this._image = wasElementSupplied ? this._url : create$1('img'); 14923 addClass(img, 'leaflet-image-layer'); 14924 if (this._zoomAnimated) { 14925 addClass(img, 'leaflet-zoom-animated'); 14926 } 14927 if (this.options.className) { 14928 addClass(img, this.options.className); 14929 } 14930 img.onselectstart = falseFn; 14931 img.onmousemove = falseFn; 14932 14933 // @event load: Event 14934 // Fired when the ImageOverlay layer has loaded its image 14935 img.onload = bind(this.fire, this, 'load'); 14936 img.onerror = bind(this._overlayOnError, this, 'error'); 14937 if (this.options.crossOrigin || this.options.crossOrigin === '') { 14938 img.crossOrigin = this.options.crossOrigin === true ? '' : this.options.crossOrigin; 14939 } 14940 if (this.options.zIndex) { 14941 this._updateZIndex(); 14942 } 14943 if (wasElementSupplied) { 14944 this._url = img.src; 14945 return; 14946 } 14947 img.src = this._url; 14948 img.alt = this.options.alt; 14949 }, 14950 _animateZoom: function _animateZoom(e) { 14951 var scale = this._map.getZoomScale(e.zoom), 14952 offset = this._map._latLngBoundsToNewLayerBounds(this._bounds, e.zoom, e.center).min; 14953 setTransform(this._image, offset, scale); 14954 }, 14955 _reset: function _reset() { 14956 var image = this._image, 14957 bounds = new Bounds(this._map.latLngToLayerPoint(this._bounds.getNorthWest()), this._map.latLngToLayerPoint(this._bounds.getSouthEast())), 14958 size = bounds.getSize(); 14959 setPosition(image, bounds.min); 14960 image.style.width = size.x + 'px'; 14961 image.style.height = size.y + 'px'; 14962 }, 14963 _updateOpacity: function _updateOpacity() { 14964 _setOpacity(this._image, this.options.opacity); 14965 }, 14966 _updateZIndex: function _updateZIndex() { 14967 if (this._image && this.options.zIndex !== undefined && this.options.zIndex !== null) { 14968 this._image.style.zIndex = this.options.zIndex; 14969 } 14970 }, 14971 _overlayOnError: function _overlayOnError() { 14972 // @event error: Event 14973 // Fired when the ImageOverlay layer fails to load its image 14974 this.fire('error'); 14975 var errorUrl = this.options.errorOverlayUrl; 14976 if (errorUrl && this._url !== errorUrl) { 14977 this._url = errorUrl; 14978 this._image.src = errorUrl; 14979 } 14980 }, 14981 // @method getCenter(): LatLng 14982 // Returns the center of the ImageOverlay. 14983 getCenter: function getCenter() { 14984 return this._bounds.getCenter(); 14985 } 14986 }); 14987 14988 // @factory L.imageOverlay(imageUrl: String, bounds: LatLngBounds, options?: ImageOverlay options) 14989 // Instantiates an image overlay object given the URL of the image and the 14990 // geographical bounds it is tied to. 14991 var imageOverlay = function imageOverlay(url, bounds, options) { 14992 return new ImageOverlay(url, bounds, options); 14993 }; 14994 14995 /* 14996 * @class VideoOverlay 14997 * @aka L.VideoOverlay 14998 * @inherits ImageOverlay 14999 * 15000 * Used to load and display a video player over specific boun
15000ds of the map. Extends `ImageOverlay`. 15001 * 15002 * A video overlay uses the [`<video>`](https://developer.mozilla.org/docs/Web/HTML/Element/video) 15003 * HTML5 element. 15004 * 15005 * @example 15006 * 15007 * ```js 15008 * var videoUrl = 'https://www.mapbox.com/bites/00188/patricia_nasa.webm', 15009 * videoBounds = [[ 32, -130], [ 13, -100]]; 15010 * L.videoOverlay(videoUrl, videoBounds ).addTo(map); 15011 * ``` 15012 */ 15013 15014 var VideoOverlay = ImageOverlay.extend({ 15015 // @section 15016 // @aka VideoOverlay options 15017 options: { 15018 // @option autoplay: Boolean = true 15019 // Whether the video starts playing automatically when loaded. 15020 // On some browsers autoplay will only work with `muted: true` 15021 autoplay: true, 15022 // @option loop: Boolean = true 15023 // Whether the video will loop back to the beginning when played. 15024 loop: true, 15025 // @option keepAspectRatio: Boolean = true 15026 // Whether the video will save aspect ratio after the projection. 15027 // Relevant for supported browsers. See [browser compatibility](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit) 15028 keepAspectRatio: true, 15029 // @option muted: Boolean = false 15030 // Whether the video starts on mute when loaded. 15031 muted: false, 15032 // @option playsInline: Boolean = true 15033 // Mobile browsers will play the video right where it is instead of open it up in fullscreen mode. 15034 playsInline: true 15035 }, 15036 _initImage: function _initImage() { 15037 var wasElementSupplied = this._url.tagName === 'VIDEO'; 15038 var vid = this._image = wasElementSupplied ? this._url : create$1('video'); 15039 addClass(vid, 'leaflet-image-layer'); 15040 if (this._zoomAnimated) { 15041 addClass(vid, 'leaflet-zoom-animated'); 15042 } 15043 if (this.options.className) { 15044 addClass(vid, this.options.className); 15045 } 15046 vid.onselectstart = falseFn; 15047 vid.onmousemove = falseFn; 15048 15049 // @event load: Event 15050 // Fired when the video has finished loading the first frame 15051 vid.onloadeddata = bind(this.fire, this, 'load'); 15052 if (wasElementSupplied) { 15053 var sourceElements = vid.getElementsByTagName('source'); 15054 var sources = []; 15055 for (var j = 0; j < sourceElements.length; j++) { 15056 sources.push(sourceElements[j].src); 15057 } 15058 this._url = sourceElements.length > 0 ? sources : [vid.src]; 15059 return; 15060 } 15061 if (!isArray(this._url)) { 15062 this._url = [this._url]; 15063 } 15064 if (!this.options.keepAspectRatio && Object.prototype.hasOwnProperty.call(vid.style, 'objectFit')) { 15065 vid.style['objectFit'] = 'fill'; 15066 } 15067 vid.autoplay = !!this.options.autoplay; 15068 vid.loop = !!this.options.loop; 15069 vid.muted = !!this.options.muted; 15070 vid.playsInline = !!this.options.playsInline; 15071 for (var i = 0; i < this._url.length; i++) { 15072 var source = create$1('source'); 15073 source.src = this._url[i]; 15074 vid.appendChild(source); 15075 } 15076 } 15077 15078 // @method getElement(): HTMLVideoElement 15079 // Returns the instance of [`HTMLVideoElement`](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement) 15080 // used by this overlay. 15081 }); 15082 15083 // @factory L.videoOverlay(video: String|Array|HTMLVideoElement, bounds: LatLngBounds, options?: VideoOverlay options) 15084 // Instantiates an image overlay object given the URL of the video (or array of URLs, or even a video element) and the 15085 // geographical bounds it is tied to. 15086 15087 function videoOverlay(video, bounds, options) { 15088 return new VideoOverlay(video, bounds, options); 15089 } 15090 15091 /* 15092 * @class SVGOverlay 15093 * @aka L.SVGOverlay 15094 * @inherits ImageOverlay 15095 * 15096 * Used to load, display and provide DOM access to an SVG file over specific bounds of the map. Extends `ImageOverlay`. 15097 * 15098 * An SVG overlay uses the [`<svg>`](https://developer.mozilla.org/docs/Web/SVG/Element/svg) element. 15099 * 15100 * @example 15101 * 15102 * ```js 15103 * var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg"); 15104 * svgElement.setAttribute('xmlns', "http://www.w3.org/2000/svg"); 15105 * svgElement.setAttribute('viewBox', "0 0 200 200"); 15106 * 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"/>'; 15107 * var svgElementBounds = [ [ 32, -130 ], [ 13, -100 ] ]; 15108 * L.svgOverlay(svgElement, svgElementBounds).addTo(map); 15109 * ``` 15110 */ 15111 15112 var SVGOverlay = ImageOverlay.extend({ 15113 _initImage: function _initImage() { 15114 var el = this._image = this._url; 15115 addClass(el, 'leaflet-image-layer'); 15116 if (this._zoomAnimated) { 15117 addClass(el, 'leaflet-zoom-animated'); 15118 } 15119 if (this.options.className) { 15120 addClass(el, this.options.className); 15121 } 15122 el.onselectstart = falseFn; 15123 el.onmousemove = falseFn; 15124 } 15125 15126 // @method getElement(): SVGElement 15127 // Returns the instance of [`SVGElement`](https://developer.mozilla.org/docs/Web/API/SVGElement) 15128 // used by this overlay. 15129 }); 15130 15131 // @factory L.svgOverlay(svg: String|SVGElement, bounds: LatLngBounds, options?: SVGOverlay options) 15132 // Instantiates an image overlay object given an SVG element and the geographical bounds it is tied to. 15133 // A viewBox attribute is required on the SVG element to zoom in and out properly. 15134 15135 function svgOverlay(el, bounds, options) { 15136 return new SVGOverlay(el, bounds, options); 15137 } 15138 15139 /* 15140 * @class DivOverlay 15141 * @inherits Interactive layer 15142 * @aka L.DivOverlay 15143 * Base model for L.Popup and L.Tooltip. Inherit from it for custom overlays like plugins. 15144 */ 15145 15146 // @namespace DivOverlay 15147 var DivOverlay = Layer.extend({ 15148 // @section 15149 // @aka DivOverlay options 15150 options: { 15151 // @option interactive: Boolean = false 15152 // If true, the popup/tooltip will listen to the mouse events. 15153 interactive: false, 15154 // @option offset: Point = Point(0, 0) 15155 // The offset of the overlay position. 15156 offset: [0, 0], 15157 // @option className: String = '' 15158 // A custom CSS class name to assign to the overlay. 15159 className: '', 15160 // @option pane: String = undefined 15161 // `Map pane` where the overlay will be added. 15162 pane: undefined, 15163 // @option content: String|HTMLElement|Function = '' 15164 // Sets the HTML content of the overlay while initializing. If a function is passed the source layer will be 15165 // passed to the function. The function should return a `String` or `HTMLElement` to be used in the overlay. 15166 content: '' 15167 }, 15168 initialize: function initialize(options, source) { 15169 if (options && (options instanceof LatLng || isArray(options))) { 15170 this._latlng = toLatLng(options); 15171 setOptions(this, source); 15172 } else { 15173 setOptions(this, options); 15174 this._source = source; 15175 } 15176 if (this.options.content) { 15177 this._content = this.options.content; 15178 } 15179 }, 15180 // @method openOn(map: Map): this 15181 // Adds the overlay to the map. 15182 // Alternative to `map.openPopup(popup)`/`.openTooltip(tooltip)`. 15183 openOn: function openOn(map) { 15184 map = arguments.length ? map : this._source._map; // experimental, not the part of public api 15185 if (!map.hasLayer(this)) { 15186 map.addLayer(this); 15187 } 15188 return this; 15189 }, 15190 // @method close(): this 15191 // Closes the overlay. 15192 // Alternative to `map.closePopup(popup)`/`.closeTooltip(tooltip)` 15193 // and `layer.closePopup()`/`.closeTooltip()`. 15194 close: function close() { 15195 if (this._map) { 15196 this._map.removeLayer(this); 15197 } 15198 return this; 15199 }, 15200 // @method toggle(layer?: Layer): this 15201 // Opens or closes the overlay bound to layer depending on its current state. 15202 // Argument may be omitted only for overlay bound to layer. 15203 // Alternative to `layer.togglePopup()`/`.toggleTooltip()`. 15204 toggle: function toggle(layer) { 15205 if (this._map) { 15206 this.close(); 15207 } else { 15208 if (arguments.length) { 15209 this._source = layer; 15210 } else { 15211 layer = this._source; 15212 } 15213 this._prepareOpen(); 15214 15215 // open the overlay on the map 15216 this.openOn(layer._map); 15217 } 15218 return this; 15219 },
15220 onAdd: function onAdd(map) { 15221 this._zoomAnimated = map._zoomAnimated; 15222 if (!this._container) { 15223 this._initLayout(); 15224 } 15225 if (map._fadeAnimated) { 15226 _setOpacity(this._container, 0); 15227 } 15228 clearTimeout(this._removeTimeout); 15229 this.getPane().appendChild(this._container); 15230 this.update(); 15231 if (map._fadeAnimated) { 15232 _setOpacity(this._container, 1); 15233 } 15234 this.bringToFront(); 15235 if (this.options.interactive) { 15236 addClass(this._container, 'leaflet-interactive'); 15237 this.addInteractiveTarget(this._container); 15238 } 15239 }, 15240 onRemove: function onRemove(map) { 15241 if (map._fadeAnimated) { 15242 _setOpacity(this._container, 0); 15243 this._removeTimeout = setTimeout(bind(_remove, undefined, this._container), 200); 15244 } else { 15245 _remove(this._container); 15246 } 15247 if (this.options.interactive) { 15248 removeClass(this._container, 'leaflet-interactive'); 15249 this.removeInteractiveTarget(this._container); 15250 } 15251 }, 15252 // @namespace DivOverlay 15253 // @method getLatLng: LatLng 15254 // Returns the geographical point of the overlay. 15255 getLatLng: function getLatLng() { 15256 return this._latlng; 15257 }, 15258 // @method setLatLng(latlng: LatLng): this 15259 // Sets the geographical point where the overlay will open. 15260 setLatLng: function setLatLng(latlng) { 15261 this._latlng = toLatLng(latlng); 15262 if (this._map) { 15263 this._updatePosition(); 15264 this._adjustPan(); 15265 } 15266 return this; 15267 }, 15268 // @method getContent: String|HTMLElement 15269 // Returns the content of the overlay. 15270 getContent: function getContent() { 15271 return this._content; 15272 }, 15273 // @method setContent(htmlContent: String|HTMLElement|Function): this 15274 // Sets the HTML content of the overlay. If a function is passed the source layer will be passed to the function. 15275 // The function should return a `String` or `HTMLElement` to be used in the overlay. 15276 setContent: function setContent(content) { 15277 this._content = content; 15278 this.update(); 15279 return this; 15280 }, 15281 // @method getElement: String|HTMLElement 15282 // Returns the HTML container of the overlay. 15283 getElement: function getElement() { 15284 return this._container; 15285 }, 15286 // @method update: null 15287 // Updates the overlay content, layout and position. Useful for updating the overlay after something inside changed, e.g. image loaded. 15288 update: function update() { 15289 if (!this._map) { 15290 return; 15291 } 15292 this._container.style.visibility = 'hidden'; 15293 this._updateContent(); 15294 this._updateLayout(); 15295 this._updatePosition(); 15296 this._container.style.visibility = ''; 15297 this._adjustPan(); 15298 }, 15299 getEvents: function getEvents() { 15300 var events = { 15301 zoom: this._updatePosition, 15302 viewreset: this._updatePosition 15303 }; 15304 if (this._zoomAnimated) { 15305 events.zoomanim = this._animateZoom; 15306 } 15307 return events; 15308 }, 15309 // @method isOpen: Boolean 15310 // Returns `true` when the overlay is visible on the map. 15311 isOpen: function isOpen() { 15312 return !!this._map && this._map.hasLayer(this); 15313 }, 15314 // @method bringToFront: this 15315 // Brings this overlay in front of other overlays (in the same map pane). 15316 bringToFront: function bringToFront() { 15317 if (this._map) { 15318 toFront(this._container); 15319 } 15320 return this; 15321 }, 15322 // @method bringToBack: this 15323 // Brings this overlay to the back of other overlays (in the same map pane). 15324 bringToBack: function bringToBack() { 15325 if (this._map) { 15326 toBack(this._container); 15327 } 15328 return this; 15329 }, 15330 // prepare bound overlay to open: update latlng pos / content source (for FeatureGroup) 15331 _prepareOpen: function _prepareOpen(latlng) { 15332 var source = this._source; 15333 if (!source._map) { 15334 return false;
vendor: 18,615 bytes, lines 15335-15784
15335 } 15336 if (source instanceof FeatureGroup) { 15337 source = null; 15338 var layers = this._source._layers; 15339 for (var id in layers) { 15340 if (layers[id]._map) { 15341 source = layers[id]; 15342 break; 15343 } 15344 } 15345 if (!source) { 15346 return false; 15347 } // Unable to get source layer. 15348 15349 // set overlay source to this layer 15350 this._source = source; 15351 } 15352 if (!latlng) { 15353 if (source.getCenter) { 15354 latlng = source.getCenter(); 15355 } else if (source.getLatLng) { 15356 latlng = source.getLatLng(); 15357 } else if (source.getBounds) { 15358 latlng = source.getBounds().getCenter(); 15359 } else { 15360 throw new Error('Unable to get source layer LatLng.'); 15361 } 15362 } 15363 this.setLatLng(latlng); 15364 if (this._map) { 15365 // update the overlay (content, layout, etc...) 15366 this.update(); 15367 } 15368 return true; 15369 }, 15370 _updateContent: function _updateContent() { 15371 if (!this._content) { 15372 return; 15373 } 15374 var node = this._contentNode; 15375 var content = typeof this._content === 'function' ? this._content(this._source || this) : this._content; 15376 if (typeof content === 'string') { 15377 node.innerHTML = content; 15378 } else { 15379 while (node.hasChildNodes()) { 15380 node.removeChild(node.firstChild); 15381 } 15382 node.appendChild(content); 15383 } 15384 15385 // @namespace DivOverlay 15386 // @section DivOverlay events 15387 // @event contentupdate: Event 15388 // Fired when the content of the overlay is updated 15389 this.fire('contentupdate'); 15390 }, 15391 _updatePosition: function _updatePosition() { 15392 if (!this._map) { 15393 return; 15394 } 15395 var pos = this._map.latLngToLayerPoint(this._latlng), 15396 offset = toPoint(this.options.offset), 15397 anchor = this._getAnchor(); 15398 if (this._zoomAnimated) { 15399 setPosition(this._container, pos.add(anchor)); 15400 } else { 15401 offset = offset.add(pos).add(anchor); 15402 } 15403 var bottom = this._containerBottom = -offset.y, 15404 left = this._containerLeft = -Math.round(this._containerWidth / 2) + offset.x; 15405 15406 // bottom position the overlay in case the height of the overlay changes (images loading etc) 15407 this._container.style.bottom = bottom + 'px'; 15408 this._container.style.left = left + 'px'; 15409 }, 15410 _getAnchor: function _getAnchor() { 15411 return [0, 0]; 15412 } 15413 }); 15414 Map.include({ 15415 _initOverlay: function _initOverlay(OverlayClass, content, latlng, options) { 15416 var overlay = content; 15417 if (!(overlay instanceof OverlayClass)) { 15418 overlay = new OverlayClass(options).setContent(content); 15419 } 15420 if (latlng) { 15421 overlay.setLatLng(latlng); 15422 } 15423 return overlay; 15424 } 15425 }); 15426 Layer.include({ 15427 _initOverlay: function _initOverlay(OverlayClass, old, content, options) { 15428 var overlay = content; 15429 if (overlay instanceof OverlayClass) { 15430 setOptions(overlay, options); 15431 overlay._source = this; 15432 } else { 15433 overlay = old && !options ? old : new OverlayClass(options, this); 15434 overlay.setContent(content); 15435 } 15436 return overlay; 15437 } 15438 }); 15439 15440 /* 15441 * @class Popup 15442 * @inherits DivOverlay 15443 * @aka L.Popup 15444 * Used to open popups in certain places of the map. Use [Map.openPopup](#map-openpopup) to 15445 * open popups while making sure that only one popup is open at one time 15446 * (recommended for usability), or use [Map.addLayer](#map-addlayer) to open as many as you want. 15447 * 15448 * @example 15449 * 15450 * If you want to just bind a popup to marker click and then open it, it's really easy: 15451 * 15452 * ```js 15453 * marker.bindPopup(popupContent).openPopup(); 15454 * ``` 15455 * Path overlays like polylines also have a `bindPopup` method. 15456 * 15457 * A popup can be also standalone: 15458 * 15459 * ```js 15460 * var popup = L.popup() 15461 * .setLatLng(latlng) 15462 * .setContent('<p>Hello world!<br />This is a nice popup.</p>') 15463 * .openOn(map); 15464 * ``` 15465 * or 15466 * ```js 15467 * var popup = L.popup(latlng, {content: '<p>Hello world!<br />This is a nice popup.</p>') 15468 * .openOn(map); 15469 * ``` 15470 */ 15471 15472 // @namespace Popup 15473 var Popup = DivOverlay.extend({ 15474 // @section 15475 // @aka Popup options 15476 options: { 15477 // @option pane: String = 'popupPane' 15478 // `Map pane` where the popup will be added. 15479 pane: 'popupPane', 15480 // @option offset: Point = Point(0, 7) 15481 // The offset of the popup position. 15482 offset: [0, 7], 15483 // @option maxWidth: Number = 300 15484 // Max width of the popup, in pixels. 15485 maxWidth: 300, 15486 // @option minWidth: Number = 50 15487 // Min width of the popup, in pixels. 15488 minWidth: 50, 15489 // @option maxHeight: Number = null 15490 // If set, creates a scrollable container of the given height 15491 // inside a popup if its content exceeds it. 15492 // The scrollable container can be styled using the 15493 // `leaflet-popup-scrolled` CSS class selector. 15494 maxHeight: null, 15495 // @option autoPan: Boolean = true 15496 // Set it to `false` if you don't want the map to do panning animation 15497 // to fit the opened popup. 15498 autoPan: true, 15499 // @option autoPanPaddingTopLeft: Point = null 15500 // The margin between the popup and the top left corner of the map 15501 // view after autopanning was performed. 15502 autoPanPaddingTopLeft: null, 15503 // @option autoPanPaddingBottomRight: Point = null 15504 // The margin between the popup and the bottom right corner of the map 15505 // view after autopanning was performed. 15506 autoPanPaddingBottomRight: null, 15507 // @option autoPanPadding: Point = Point(5, 5) 15508 // Equivalent of setting both top left and bottom right autopan padding to the same value. 15509 autoPanPadding: [5, 5], 15510 // @option keepInView: Boolean = false 15511 // Set it to `true` if you want to prevent users from panning the popup 15512 // off of the screen while it is open. 15513 keepInView: false, 15514 // @option closeButton: Boolean = true 15515 // Controls the presence of a close button in the popup. 15516 closeButton: true, 15517 // @option autoClose: Boolean = true 15518 // Set it to `false` if you want to override the default behavior of 15519 // the popup closing when another popup is opened. 15520 autoClose: true, 15521 // @option closeOnEscapeKey: Boolean = true 15522 // Set it to `false` if you want to override the default behavior of 15523 // the ESC key for closing of the popup. 15524 closeOnEscapeKey: true, 15525 // @option closeOnClick: Boolean = * 15526 // Set it if you want to override the default behavior of the popup closing when user clicks 15527 // on the map. Defaults to the map's [`closePopupOnClick`](#map-closepopuponclick) option. 15528 15529 // @option className: String = '' 15530 // A custom CSS class name to assign to the popup. 15531 className: '' 15532 }, 15533 // @namespace Popup 15534 // @method openOn(map: Map): this 15535 // Alternative to `map.openPopup(popup)`. 15536 // Adds the popup to the map and closes the previous one. 15537 openOn: function openOn(map) { 15538 map = arguments.length ? map : this._source._map; // experimental, not the part of public api 15539 15540 if (!map.hasLayer(this) && map._popup && map._popup.options.autoClose) { 15541 map.removeLayer(map._popup); 15542 } 15543 map._popup = this; 15544 return DivOverlay.prototype.openOn.call(this, map); 15545 }, 15546 onAdd: function onAdd(map) { 15547 DivOverlay.prototype.onAdd.call(this, map); 15548 15549 // @namespace Map 15550 // @section Popup events 15551 // @event popupopen: PopupEvent 15552 // Fired when a popup is opened in the map 15553 map.fire('popupopen', { 15554 popup: this 15555 }); 15556 if (this._source) { 15557 // @namespace Layer 15558 // @section Popup events 15559 // @event popupopen: PopupEvent 15560 // Fired when a popup bound to this layer is opened 15561 this._source.fire('popupopen', { 15562 popup: this 15563 }, true); 15564 // For non-path layers, we toggle the popup when clicking 15565 // again the layer, so prevent the map to reopen it. 15566 if (!(this._source instanceof Path)) { 15567 this._source.on('preclick', stopPropagation); 15568 } 15569 } 15570 }, 15571 onRemove: function onRemove(map) { 15572 DivOverlay.prototype.onRemove.call(this, map); 15573 15574 // @namespace Map 15575 // @section Popup events 15576 // @event popupclose: PopupEvent 15577 // Fired when a popup in the map is closed 15578 map.fire('popupclose', { 15579 popup: this 15580 }); 15581 if (this._source) { 15582 // @namespace Layer 15583 // @section Popup events 15584 // @event popupclose: PopupEvent 15585 // Fired when a popup bound to this layer is closed 15586 this._source.fire('popupclose', { 15587 popup: this 15588 }, true); 15589 if (!(this._source instanceof Path)) { 15590 this._source.off('preclick', stopPropagation); 15591 } 15592 } 15593 }, 15594 getEvents: function getEvents() { 15595 var events = DivOverlay.prototype.getEvents.call(this); 15596 if (this.options.closeOnClick !== undefined ? this.options.closeOnClick : this._map.options.closePopupOnClick) { 15597 events.preclick = this.close; 15598 } 15599 if (this.options.keepInView) { 15600 events.moveend = this._adjustPan; 15601 } 15602 return events; 15603 }, 15604 _initLayout: function _initLayout() { 15605 var prefix = 'leaflet-popup', 15606 container = this._container = create$1('div', prefix + ' ' + (this.options.className || '') + ' leaflet-zoom-animated'); 15607 var wrapper = this._wrapper = create$1('div', prefix + '-content-wrapper', container); 15608 this._contentNode = create$1('div', prefix + '-content', wrapper); 15609 disableClickPropagation(container); 15610 disableScrollPropagation(this._contentNode); 15611 on(container, 'contextmenu', stopPropagation); 15612 this._tipContainer = create$1('div', prefix + '-tip-container', container); 15613 this._tip = create$1('div', prefix + '-tip', this._tipContainer); 15614 if (this.options.closeButton) { 15615 var closeButton = this._closeButton = create$1('a', prefix + '-close-button', container); 15616 closeButton.setAttribute('role', 'button'); // overrides the implicit role=link of <a> elements #7399 15617 closeButton.setAttribute('aria-label', 'Close popup'); 15618 closeButton.href = '#close'; 15619 closeButton.innerHTML = '<span aria-hidden="true">×</span>'; 15620 on(closeButton, 'click', function (ev) { 15621 preventDefault(ev); 15622 this.close(); 15623 }, this); 15624 } 15625 }, 15626 _updateLayout: function _updateLayout() { 15627 var container = this._contentNode, 15628 style = container.style; 15629 style.width = ''; 15630 style.whiteSpace = 'nowrap'; 15631 var width = container.offsetWidth; 15632 width = Math.min(width, this.options.maxWidth); 15633 width = Math.max(width, this.options.minWidth); 15634 style.width = width + 1 + 'px'; 15635 style.whiteSpace = ''; 15636 style.height = ''; 15637 var height = container.offsetHeight, 15638 maxHeight = this.options.maxHeight, 15639 scrolledClass = 'leaflet-popup-scrolled'; 15640 if (maxHeight && height > maxHeight) { 15641 style.height = maxHeight + 'px'; 15642 addClass(container, scrolledClass); 15643 } else { 15644 removeClass(container, scrolledClass); 15645 } 15646 this._containerWidth = this._container.offsetWidth; 15647 }, 15648 _animateZoom: function _animateZoom(e) { 15649 var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center), 15650 anchor = this._getAnchor(); 15651 setPosition(this._container, pos.add(anchor)); 15652 }, 15653 _adjustPan: function _adjustPan() { 15654 if (!this.options.autoPan) { 15655 return; 15656 } 15657 if (this._map._panAnim) { 15658 this._map._panAnim.stop(); 15659 } 15660 15661 // We can endlessly recurse if keepInView is set and the view resets. 15662 // Let's guard against that by exiting early if we're responding to our own autopan. 15663 if (this._autopanning) { 15664 this._autopanning = false; 15665 return; 15666 } 15667 var map = this._map, 15668 marginBottom = parseInt(getStyle(this._container, 'marginBottom'), 10) || 0, 15669 containerHeight = this._container.offsetHeight + marginBottom, 15670 containerWidth = this._containerWidth, 15671 layerPos = new Point(this._containerLeft, -containerHeight - this._containerBottom); 15672 layerPos._add(getPosition(this._container)); 15673 var containerPos = map.layerPointToContainerPoint(layerPos), 15674 padding = toPoint(this.options.autoPanPadding), 15675 paddingTL = toPoint(this.options.autoPanPaddingTopLeft || padding), 15676 paddingBR = toPoint(this.options.autoPanPaddingBottomRight || padding), 15677 size = map.getSize(), 15678 dx = 0, 15679 dy = 0; 15680 if (containerPos.x + containerWidth + paddingBR.x > size.x) { 15681 // right 15682 dx = containerPos.x + containerWidth - size.x + paddingBR.x; 15683 } 15684 if (containerPos.x - dx - paddingTL.x < 0) { 15685 // left 15686 dx = containerPos.x - paddingTL.x; 15687 } 15688 if (containerPos.y + containerHeight + paddingBR.y > size.y) { 15689 // bottom 15690 dy = containerPos.y + containerHeight - size.y + paddingBR.y; 15691 } 15692 if (containerPos.y - dy - paddingTL.y < 0) { 15693 // top 15694 dy = containerPos.y - paddingTL.y; 15695 } 15696 15697 // @namespace Map 15698 // @section Popup events 15699 // @event autopanstart: Event 15700 // Fired when the map starts autopanning when opening a popup. 15701 if (dx || dy) { 15702 // Track that we're autopanning, as this function will be re-ran on moveend 15703 if (this.options.keepInView) { 15704 this._autopanning = true; 15705 } 15706 map.fire('autopanstart').panBy([dx, dy]); 15707 } 15708 }, 15709 _getAnchor: function _getAnchor() { 15710 // Where should we anchor the popup on the source layer? 15711 return toPoint(this._source && this._source._getPopupAnchor ? this._source._getPopupAnchor() : [0, 0]); 15712 } 15713 }); 15714 15715 // @namespace Popup 15716 // @factory L.popup(options?: Popup options, source?: Layer) 15717 // 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. 15718 // @alternative 15719 // @factory L.popup(latlng: LatLng, options?: Popup options) 15720 // Instantiates a `Popup` object given `latlng` where the popup will open and an optional `options` object that describes its appearance and location. 15721 var popup = function popup(options, source) { 15722 return new Popup(options, source); 15723 }; 15724 15725 /* @namespace Map 15726 * @section Interaction Options 15727 * @option closePopupOnClick: Boolean = true 15728 * Set it to `false` if you don't want popups to close when user clicks the map. 15729 */ 15730 Map.mergeOptions({ 15731 closePopupOnClick: true 15732 }); 15733 15734 // @namespace Map 15735 // @section Methods for Layers and Controls 15736 Map.include({ 15737 // @method openPopup(popup: Popup): this 15738 // Opens the specified popup while closing the previously opened (to make sure only one is opened at one time for usability). 15739 // @alternative 15740 // @method openPopup(content: String|HTMLElement, latlng: LatLng, options?: Popup options): this 15741 // Creates a popup with the specified content and options and opens it in the given point on a map. 15742 openPopup: function openPopup(popup, latlng, options) { 15743 this._initOverlay(Popup, popup, latlng, options).openOn(this); 15744 return this; 15745 }, 15746 // @method closePopup(popup?: Popup): this 15747 // Closes the popup previously opened with [openPopup](#map-openpopup) (or the given one). 15748 closePopup: function closePopup(popup) { 15749 popup = arguments.length ? popup : this._popup; 15750 if (popup) { 15751 popup.close(); 15752 } 15753 return this; 15754 } 15755 }); 15756 15757 /* 15758 * @namespace Layer 15759 * @section Popup methods example 15760 * 15761 * All layers share a set of methods convenient for binding popups to it. 15762 * 15763 * ```js 15764 * var layer = L.Polygon(latlngs).bindPopup('Hi There!').addTo(map); 15765 * layer.openPopup(); 15766 * layer.closePopup(); 15767 * ``` 15768 * 15769 * 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. 15770 */ 15771 15772 // @section Popup methods 15773 Layer.include({ 15774 // @method bindPopup(content: String|HTMLElement|Function|Popup, options?: Popup options): this 15775 // Binds a popup to the layer with the passed `content` and sets up the 15776 // necessary event listeners. If a `Function` is passed it will receive 15777 // the layer as the first argument and should return a `String` or `HTMLElement`. 15778 bindPopup: function bindPopup(content, options) { 15779 this._popup = this._initOverlay(Popup, this._popup, content, options); 15780 if (!this._popupHandlersAdded) { 15781 this.on({ 15782 click: this._openPopup, 15783 keypress: this._onKeyPress, 15784 remove: this.closePopup,
15785 move: this._movePopup 15786 }); 15787 this._popupHandlersAdded = true; 15788 } 15789 return this; 15790 }, 15791 // @method unbindPopup(): this 15792 // Removes the popup previously bound with `bindPopup`. 15793 unbindPopup: function unbindPopup() { 15794 if (this._popup) { 15795 this.off({ 15796 click: this._openPopup, 15797 keypress: this._onKeyPress, 15798 remove: this.closePopup, 15799 move: this._movePopup 15800 }); 15801 this._popupHandlersAdded = false; 15802 this._popup = null; 15803 } 15804 return this; 15805 }, 15806 // @method openPopup(latlng?: LatLng): this 15807 // Opens the bound popup at the specified `latlng` or at the default popup anchor if no `latlng` is passed. 15808 openPopup: function openPopup(latlng) { 15809 if (this._popup) { 15810 if (!(this instanceof FeatureGroup)) { 15811 this._popup._source = this; 15812 } 15813 if (this._popup._prepareOpen(latlng || this._latlng)) { 15814 // open the popup on the map 15815 this._popup.openOn(this._map); 15816 } 15817 } 15818 return this; 15819 }, 15820 // @method closePopup(): this 15821 // Closes the popup bound to this layer if it is open. 15822 closePopup: function closePopup() { 15823 if (this._popup) { 15824 this._popup.close(); 15825 } 15826 return this; 15827 }, 15828 // @method togglePopup(): this 15829 // Opens or closes the popup bound to this layer depending on its current state. 15830 togglePopup: function togglePopup() { 15831 if (this._popup) { 15832 this._popup.toggle(this); 15833 } 15834 return this; 15835 }, 15836 // @method isPopupOpen(): boolean 15837 // Returns `true` if the popup bound to this layer is currently open. 15838 isPopupOpen: function isPopupOpen() { 15839 return this._popup ? this._popup.isOpen() : false; 15840 }, 15841 // @method setPopupContent(content: String|HTMLElement|Popup): this 15842 // Sets the content of the popup bound to this layer. 15843 setPopupContent: function setPopupContent(content) { 15844 if (this._popup) { 15845 this._popup.setContent(content); 15846 } 15847 return this; 15848 }, 15849 // @method getPopup(): Popup 15850 // Returns the popup bound to this layer. 15851 getPopup: function getPopup() { 15852 return this._popup; 15853 }, 15854 _openPopup: function _openPopup(e) { 15855 if (!this._popup || !this._map) { 15856 return; 15857 } 15858 // prevent map click 15859 stop(e); 15860 var target = e.layer || e.target; 15861 if (this._popup._source === target && !(target instanceof Path)) { 15862 // treat it like a marker and figure out 15863 // if we should toggle it open/closed 15864 if (this._map.hasLayer(this._popup)) { 15865 this.closePopup(); 15866 } else { 15867 this.openPopup(e.latlng); 15868 } 15869 return; 15870 } 15871 this._popup._source = target; 15872 this.openPopup(e.latlng); 15873 }, 15874 _movePopup: function _movePopup(e) { 15875 this._popup.setLatLng(e.latlng); 15876 }, 15877 _onKeyPress: function _onKeyPress(e) { 15878 if (e.originalEvent.keyCode === 13) { 15879 this._openPopup(e); 15880 } 15881 } 15882 }); 15883 15884 /* 15885 * @class Tooltip 15886 * @inherits DivOverlay 15887 * @aka L.Tooltip 15888 * Used to display small texts on top of map layers. 15889 * 15890 * @example 15891 * If you want to just bind a tooltip to marker: 15892 * 15893 * ```js 15894 * marker.bindTooltip("my tooltip text").openTooltip(); 15895 * ``` 15896 * Path overlays like polylines also have a `bindTooltip` method. 15897 * 15898 * A tooltip can be also standalone: 15899 * 15900 * ```js 15901 * var tooltip = L.tooltip() 15902 * .setLatLng(latlng) 15903 * .setContent('Hello world!<br />This is a nice tooltip.') 15904 * .addTo(map); 15905 * ``` 15906 * or 15907 * ```js 15908 * var tooltip = L.tooltip(latlng, {content: 'Hello world!<br />This is a nice tooltip.'}) 15909 * .addTo(map); 15910 * ``` 15911 * 15912 * 15913 * Note about tooltip offset. Leaflet takes two options in consideration 15914 * for computing tooltip offsetting: 15915 * - the `offset` Tooltip option: it defaults to [0, 0], and it's specific to one tooltip. 15916 * Add a positive x offset to move the tooltip to the right, and a positive y offset to 15917 * move it to the bottom. Negatives will move to the left and top. 15918 * - the `tooltipAnchor` Icon option: this will only be considered for Marker. You 15919 * should adapt this value if you use a custom icon. 15920 */ 15921 15922 // @namespace Tooltip 15923 var Tooltip = DivOverlay.extend({ 15924 // @section 15925 // @aka Tooltip options 15926 options: { 15927 // @option pane: String = 'tooltipPane' 15928 // `Map pane` where the tooltip will be added. 15929 pane: 'tooltipPane', 15930 // @option offset: Point = Point(0, 0) 15931 // Optional offset of the tooltip position. 15932 offset: [0, 0], 15933 // @option direction: String = 'auto' 15934 // Direction where to open the tooltip. Possible values are: `right`, `left`, 15935 // `top`, `bottom`, `center`, `auto`. 15936 // `auto` will dynamically switch between `right` and `left` according to the tooltip 15937 // position on the map. 15938 direction: 'auto', 15939 // @option permanent: Boolean = false 15940 // Whether to open the tooltip permanently or only on mouseover. 15941 permanent: false, 15942 // @option sticky: Boolean = false 15943 // If true, the tooltip will follow the mouse instead of being fixed at the feature center.
vendor: 12,622 bytes, lines 15944-16256
15944 sticky: false, 15945 // @option opacity: Number = 0.9 15946 // Tooltip container opacity. 15947 opacity: 0.9 15948 }, 15949 onAdd: function onAdd(map) { 15950 DivOverlay.prototype.onAdd.call(this, map); 15951 this.setOpacity(this.options.opacity); 15952 15953 // @namespace Map 15954 // @section Tooltip events 15955 // @event tooltipopen: TooltipEvent 15956 // Fired when a tooltip is opened in the map. 15957 map.fire('tooltipopen', { 15958 tooltip: this 15959 }); 15960 if (this._source) { 15961 this.addEventParent(this._source); 15962 15963 // @namespace Layer 15964 // @section Tooltip events 15965 // @event tooltipopen: TooltipEvent 15966 // Fired when a tooltip bound to this layer is opened. 15967 this._source.fire('tooltipopen', { 15968 tooltip: this 15969 }, true); 15970 } 15971 }, 15972 onRemove: function onRemove(map) { 15973 DivOverlay.prototype.onRemove.call(this, map); 15974 15975 // @namespace Map 15976 // @section Tooltip events 15977 // @event tooltipclose: TooltipEvent 15978 // Fired when a tooltip in the map is closed. 15979 map.fire('tooltipclose', { 15980 tooltip: this 15981 }); 15982 if (this._source) { 15983 this.removeEventParent(this._source); 15984 15985 // @namespace Layer 15986 // @section Tooltip events 15987 // @event tooltipclose: TooltipEvent 15988 // Fired when a tooltip bound to this layer is closed. 15989 this._source.fire('tooltipclose', { 15990 tooltip: this 15991 }, true); 15992 } 15993 }, 15994 getEvents: function getEvents() { 15995 var events = DivOverlay.prototype.getEvents.call(this); 15996 if (!this.options.permanent) { 15997 events.preclick = this.close; 15998 } 15999 return events; 16000 }, 16001 _initLayout: function _initLayout() { 16002 var prefix = 'leaflet-tooltip', 16003 className = prefix + ' ' + (this.options.className || '') + ' leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide'); 16004 this._contentNode = this._container = create$1('div', className); 16005 this._container.setAttribute('role', 'tooltip'); 16006 this._container.setAttribute('id', 'leaflet-tooltip-' + stamp(this)); 16007 }, 16008 _updateLayout: function _updateLayout() {}, 16009 _adjustPan: function _adjustPan() {}, 16010 _setPosition: function _setPosition(pos) { 16011 var subX, 16012 subY, 16013 map = this._map, 16014 container = this._container, 16015 centerPoint = map.latLngToContainerPoint(map.getCenter()), 16016 tooltipPoint = map.layerPointToContainerPoint(pos), 16017 direction = this.options.direction, 16018 tooltipWidth = container.offsetWidth, 16019 tooltipHeight = container.offsetHeight, 16020 offset = toPoint(this.options.offset), 16021 anchor = this._getAnchor(); 16022 if (direction === 'top') { 16023 subX = tooltipWidth / 2; 16024 subY = tooltipHeight; 16025 } else if (direction === 'bottom') { 16026 subX = tooltipWidth / 2; 16027 subY = 0; 16028 } else if (direction === 'center') { 16029 subX = tooltipWidth / 2; 16030 subY = tooltipHeight / 2; 16031 } else if (direction === 'right') { 16032 subX = 0; 16033 subY = tooltipHeight / 2; 16034 } else if (direction === 'left') { 16035 subX = tooltipWidth; 16036 subY = tooltipHeight / 2; 16037 } else if (tooltipPoint.x < centerPoint.x) { 16038 direction = 'right'; 16039 subX = 0; 16040 subY = tooltipHeight / 2; 16041 } else { 16042 direction = 'left'; 16043 subX = tooltipWidth + (offset.x + anchor.x) * 2; 16044 subY = tooltipHeight / 2; 16045 } 16046 pos = pos.subtract(toPoint(subX, subY, true)).add(offset).add(anchor); 16047 removeClass(container, 'leaflet-tooltip-right'); 16048 removeClass(container, 'leaflet-tooltip-left'); 16049 removeClass(container, 'leaflet-tooltip-top'); 16050 removeClass(container, 'leaflet-tooltip-bottom'); 16051 addClass(container, 'leaflet-tooltip-' + direction); 16052 setPosition(container, pos); 16053 }, 16054 _updatePosition: function _updatePosition() { 16055 var pos = this._map.latLngToLayerPoint(this._latlng); 16056 this._setPosition(pos); 16057 }, 16058 setOpacity: function setOpacity(opacity) { 16059 this.options.opacity = opacity; 16060 if (this._container) { 16061 _setOpacity(this._container, opacity); 16062 } 16063 }, 16064 _animateZoom: function _animateZoom(e) { 16065 var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center); 16066 this._setPosition(pos); 16067 }, 16068 _getAnchor: function _getAnchor() { 16069 // Where should we anchor the tooltip on the source layer? 16070 return toPoint(this._source && this._source._getTooltipAnchor && !this.options.sticky ? this._source._getTooltipAnchor() : [0, 0]); 16071 } 16072 }); 16073 16074 // @namespace Tooltip 16075 // @factory L.tooltip(options?: Tooltip options, source?: Layer) 16076 // 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. 16077 // @alternative 16078 // @factory L.tooltip(latlng: LatLng, options?: Tooltip options) 16079 // Instantiates a `Tooltip` object given `latlng` where the tooltip will open and an optional `options` object that describes its appearance and location. 16080 var tooltip = function tooltip(options, source) { 16081 return new Tooltip(options, source); 16082 }; 16083 16084 // @namespace Map 16085 // @section Methods for Layers and Controls 16086 Map.include({ 16087 // @method openTooltip(tooltip: Tooltip): this 16088 // Opens the specified tooltip. 16089 // @alternative 16090 // @method openTooltip(content: String|HTMLElement, latlng: LatLng, options?: Tooltip options): this 16091 // Creates a tooltip with the specified content and options and open it. 16092 openTooltip: function openTooltip(tooltip, latlng, options) { 16093 this._initOverlay(Tooltip, tooltip, latlng, options).openOn(this); 16094 return this; 16095 }, 16096 // @method closeTooltip(tooltip: Tooltip): this 16097 // Closes the tooltip given as parameter. 16098 closeTooltip: function closeTooltip(tooltip) { 16099 tooltip.close(); 16100 return this; 16101 } 16102 }); 16103 16104 /* 16105 * @namespace Layer 16106 * @section Tooltip methods example 16107 * 16108 * All layers share a set of methods convenient for binding tooltips to it. 16109 * 16110 * ```js 16111 * var layer = L.Polygon(latlngs).bindTooltip('Hi There!').addTo(map); 16112 * layer.openTooltip(); 16113 * layer.closeTooltip(); 16114 * ``` 16115 */ 16116 16117 // @section Tooltip methods 16118 Layer.include({ 16119 // @method bindTooltip(content: String|HTMLElement|Function|Tooltip, options?: Tooltip options): this 16120 // Binds a tooltip to the layer with the passed `content` and sets up the 16121 // necessary event listeners. If a `Function` is passed it will receive 16122 // the layer as the first argument and should return a `String` or `HTMLElement`. 16123 bindTooltip: function bindTooltip(content, options) { 16124 if (this._tooltip && this.isTooltipOpen()) { 16125 this.unbindTooltip(); 16126 } 16127 this._tooltip = this._initOverlay(Tooltip, this._tooltip, content, options); 16128 this._initTooltipInteractions(); 16129 if (this._tooltip.options.permanent && this._map && this._map.hasLayer(this)) { 16130 this.openTooltip(); 16131 } 16132 return this; 16133 }, 16134 // @method unbindTooltip(): this 16135 // Removes the tooltip previously bound with `bindTooltip`. 16136 unbindTooltip: function unbindTooltip() { 16137 if (this._tooltip) { 16138 this._initTooltipInteractions(true); 16139 this.closeTooltip(); 16140 this._tooltip = null; 16141 } 16142 return this; 16143 }, 16144 _initTooltipInteractions: function _initTooltipInteractions(remove) { 16145 if (!remove && this._tooltipHandlersAdded) { 16146 return; 16147 } 16148 var onOff = remove ? 'off' : 'on', 16149 events = { 16150 remove: this.closeTooltip, 16151 move: this._moveTooltip 16152 }; 16153 if (!this._tooltip.options.permanent) { 16154 events.mouseover = this._openTooltip; 16155 events.mouseout = this.closeTooltip; 16156 events.click = this._openTooltip; 16157 if (this._map) { 16158 this._addFocusListeners(); 16159 } else { 16160 events.add = this._addFocusListeners; 16161 } 16162 } else { 16163 events.add = this._openTooltip; 16164 } 16165 if (this._tooltip.options.sticky) { 16166 events.mousemove = this._moveTooltip; 16167 } 16168 this[onOff](events); 16169 this._tooltipHandlersAdded = !remove; 16170 }, 16171 // @method openTooltip(latlng?: LatLng): this 16172 // Opens the bound tooltip at the specified `latlng` or at the default tooltip anchor if no `latlng` is passed. 16173 openTooltip: function openTooltip(latlng) { 16174 if (this._tooltip) { 16175 if (!(this instanceof FeatureGroup)) { 16176 this._tooltip._source = this; 16177 } 16178 if (this._tooltip._prepareOpen(latlng)) { 16179 // open the tooltip on the map 16180 this._tooltip.openOn(this._map); 16181 if (this.getElement) { 16182 this._setAriaDescribedByOnLayer(this); 16183 } else if (this.eachLayer) { 16184 this.eachLayer(this._setAriaDescribedByOnLayer, this); 16185 } 16186 } 16187 } 16188 return this; 16189 }, 16190 // @method closeTooltip(): this 16191 // Closes the tooltip bound to this layer if it is open. 16192 closeTooltip: function closeTooltip() { 16193 if (this._tooltip) { 16194 return this._tooltip.close(); 16195 } 16196 }, 16197 // @method toggleTooltip(): this 16198 // Opens or closes the tooltip bound to this layer depending on its current state. 16199 toggleTooltip: function toggleTooltip() { 16200 if (this._tooltip) { 16201 this._tooltip.toggle(this); 16202 } 16203 return this; 16204 }, 16205 // @method isTooltipOpen(): boolean 16206 // Returns `true` if the tooltip bound to this layer is currently open. 16207 isTooltipOpen: function isTooltipOpen() { 16208 return this._tooltip.isOpen(); 16209 }, 16210 // @method setTooltipContent(content: String|HTMLElement|Tooltip): this 16211 // Sets the content of the tooltip bound to this layer. 16212 setTooltipContent: function setTooltipContent(content) { 16213 if (this._tooltip) { 16214 this._tooltip.setContent(content); 16215 } 16216 return this; 16217 }, 16218 // @method getTooltip(): Tooltip 16219 // Returns the tooltip bound to this layer. 16220 getTooltip: function getTooltip() { 16221 return this._tooltip; 16222 }, 16223 _addFocusListeners: function _addFocusListeners() { 16224 if (this.getElement) { 16225 this._addFocusListenersOnLayer(this); 16226 } else if (this.eachLayer) { 16227 this.eachLayer(this._addFocusListenersOnLayer, this); 16228 } 16229 }, 16230 _addFocusListenersOnLayer: function _addFocusListenersOnLayer(layer) { 16231 var el = typeof layer.getElement === 'function' && layer.getElement(); 16232 if (el) { 16233 on(el, 'focus', function () { 16234 this._tooltip._source = layer; 16235 this.openTooltip(); 16236 }, this); 16237 on(el, 'blur', this.closeTooltip, this); 16238 } 16239 }, 16240 _setAriaDescribedByOnLayer: function _setAriaDescribedByOnLayer(layer) { 16241 var el = typeof layer.getElement === 'function' && layer.getElement(); 16242 if (el) { 16243 el.setAttribute('aria-describedby', this._tooltip._container.id); 16244 } 16245 }, 16246 _openTooltip: function _openTooltip(e) { 16247 if (!this._tooltip || !this._map) { 16248 return; 16249 } 16250 16251 // If the map is moving, we will show the tooltip after it's done. 16252 if (this._map.dragging && this._map.dragging.moving() && !this._openOnceFlag) { 16253 this._openOnceFlag = true; 16254 var that = this; 16255 this._map.once('moveend', function () { 16256 that._openOnceFlag = false;
16257 that._openTooltip(e); 16258 }); 16259 return; 16260 } 16261 this._tooltip._source = e.layer || e.target; 16262 this.openTooltip(this._tooltip.options.sticky ? e.latlng : undefined); 16263 }, 16264 _moveTooltip: function _moveTooltip(e) { 16265 var latlng = e.latlng, 16266 containerPoint, 16267 layerPoint; 16268 if (this._tooltip.options.sticky && e.originalEvent) { 16269 containerPoint = this._map.mouseEventToContainerPoint(e.originalEvent); 16270 layerPoint = this._map.containerPointToLayerPoint(containerPoint); 16271 latlng = this._map.layerPointToLatLng(layerPoint); 16272 } 16273 this._tooltip.setLatLng(latlng); 16274 } 16275 }); 16276 16277 /* 16278 * @class DivIcon 16279 * @aka L.DivIcon 16280 * @inherits Icon 16281 * 16282 * Represents a lightweight icon for markers that uses a simple `<div>` 16283 * element instead of an image. Inherits from `Icon` but ignores the `iconUrl` and shadow options. 16284 * 16285 * @example 16286 * ```js 16287 * var myIcon = L.divIcon({className: 'my-div-icon'}); 16288 * // you can set .my-div-icon styles in CSS 16289 * 16290 * L.marker([50.505, 30.57], {icon: myIcon}).addTo(map); 16291 * ``` 16292 * 16293 * By default, it has a 'leaflet-div-icon' CSS class and is styled as a little white square with a shadow. 16294 */ 16295 16296 var DivIcon = Icon.extend({ 16297 options: { 16298 // @section 16299 // @aka DivIcon options 16300 iconSize: [12, 12], 16301 // also can be set through CSS 16302 16303 // iconAnchor: (Point), 16304 // popupAnchor: (Point), 16305 16306 // @option html: String|HTMLElement = '' 16307 // Custom HTML code to put inside the div element, empty by default. Alternatively, 16308 // an instance of `HTMLElement`. 16309 html: false, 16310 // @option bgPos: Point = [0, 0] 16311 // Optional relative position of the background, in pixels 16312 bgPos: null, 16313 className: 'leaflet-div-icon' 16314 }, 16315 createIcon: function createIcon(oldIcon) { 16316 var div = oldIcon && oldIcon.tagName === 'DIV' ? oldIcon : document.createElement('div'), 16317 options = this.options; 16318 if (options.html instanceof Element) { 16319 empty(div); 16320 div.appendChild(options.html); 16321 } else { 16322 div.innerHTML = options.html !== false ? options.html : ''; 16323 } 16324 if (options.bgPos) { 16325 var bgPos = toPoint(options.bgPos); 16326 div.style.backgroundPosition = -bgPos.x + 'px ' + -bgPos.y + 'px'; 16327 } 16328 this._setIconStyles(div, 'icon'); 16329 return div; 16330 }, 16331 createShadow: function createShadow() { 16332 return null; 16333 } 16334 }); 16335 16336 // @factory L.divIcon(options: DivIcon options) 16337 // Creates a `DivIcon` instance with the given options. 16338 function divIcon(options) { 16339 return new DivIcon(options); 16340 } 16341 Icon.Default = IconDefault; 16342 16343 /* 16344 * @class GridLayer 16345 * @inherits Layer 16346 * @aka L.GridLayer 16347 * 16348 * Generic class for handling a tiled grid of HTML elements. This is the base class for all tile layers and replaces `TileLayer.Canvas`. 16349 * 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. 16350 * 16351 * 16352 * @section Synchronous usage 16353 * @example 16354 * 16355 * 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. 16356 * 16357 * ```js 16358 * var CanvasLayer = L.GridLayer.extend({ 16359 * createTile: function(coords){ 16360 * // create a <canvas> element for drawing 16361 * var tile = L.DomUtil.create('canvas', 'leaflet-tile'); 16362 * 16363 * // setup tile width and height according to the options 16364 * var size = this.getTileSize(); 16365 * tile.width = size.x; 16366 * tile.height = size.y; 16367 * 16368 * // get a canvas context and draw something on it using coords.x, coords.y and coords.z 16369 * var ctx = tile.getContext('2d'); 16370 * 16371 * // return the tile so it can be rendered on screen 16372 * return tile; 16373 * } 16374 * }); 16375 * ``` 16376 * 16377 * @section Asynchronous usage 16378 * @example 16379 * 16380 * Tile creation can also be asynchronous, this is useful when using a third-party drawing library. O
16380nce the tile is finished drawing it can be passed to the `done()` callback. 16381 * 16382 * ```js 16383 * var CanvasLayer = L.GridLayer.extend({ 16384 * createTile: function(coords, done){ 16385 * var error; 16386 * 16387 * // create a <canvas> element for drawing 16388 * var tile = L.DomUtil.create('canvas', 'leaflet-tile'); 16389 * 16390 * // setup tile width and height according to the options 16391 * var size = this.getTileSize(); 16392 * tile.width = size.x; 16393 * tile.height = size.y; 16394 * 16395 * // draw something asynchronously and pass the tile to the done() callback 16396 * setTimeout(function() { 16397 * done(error, tile); 16398 * }, 1000); 16399 * 16400 * return tile; 16401 * } 16402 * }); 16403 * ``` 16404 * 16405 * @section 16406 */ 16407 16408 var GridLayer = Layer.extend({ 16409 // @section 16410 // @aka GridLayer options 16411 options: { 16412 // @option tileSize: Number|Point = 256
16413 // Width and height of tiles in the grid. Use a number if width and height are equal, or `L.point(width, height)` otherwise. 16414 tileSize: 256, 16415 // @option opacity: Number = 1.0 16416 // Opacity of the tiles. Can be used in the `createTile()` function. 16417 opacity: 1, 16418 // @option updateWhenIdle: Boolean = (depends) 16419 // Load new tiles only when panning ends. 16420 // `true` by default on mobile browsers, in order to avoid too many requests and keep smooth navigation. 16421 // `false` otherwise in order to display new tiles _during_ panning, since it is easy to pan outside the 16422 // [`keepBuffer`](#gridlayer-keepbuffer) option in desktop browsers. 16423 updateWhenIdle: Browser.mobile, 16424 // @option updateWhenZooming: Boolean = true 16425 // 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. 16426 updateWhenZooming: true, 16427 // @option updateInterval: Number = 200 16428 // Tiles will not update more than once every `updateInterval` milliseconds when panning. 16429 updateInterval: 200, 16430 // @option zIndex: Number = 1 16431 // The explicit zIndex of the tile layer. 16432 zIndex: 1, 16433 // @option bounds: LatLngBounds = undefined 16434 // If set, tiles will only be loaded inside the set `LatLngBounds`. 16435 bounds: null, 16436 // @option minZoom: Number = 0 16437 // The minimum zoom level down to which this layer will be displayed (inclusive). 16438 minZoom: 0, 16439 // @option maxZoom: Number = undefined 16440 // The maximum zoom level up to which this layer will be displayed (inclusive). 16441 maxZoom: undefined, 16442 // @option maxNativeZoom: Number = undefined 16443 // Maximum zoom number the tile source has available. If it is specified, 16444 // the tiles on all zoom levels higher than `maxNativeZoom` will be loaded 16445 // from `maxNativeZoom` level and auto-scaled. 16446 maxNativeZoom: undefined, 16447 // @option minNativeZoom: Number = undefined 16448 // Minimum zoom number the tile source has available. If it is specified, 16449 // the tiles on all zoom levels lower than `minNativeZoom` will be loaded 16450 // from `minNativeZoom` level and auto-scaled. 16451 minNativeZoom: undefined, 16452 // @option noWrap: Boolean = false 16453 // Whether the layer is wrapped around the antimeridian. If `true`, the 16454 // GridLayer will only be displayed once at low zoom levels. Has no 16455 // effect when the [map CRS](#map-crs) doesn't wrap around. Can be used 16456 // in combination with [`bounds`](#gridlayer-bounds) to prevent requesting 16457 // tiles outside the CRS limits. 16458 noWrap: false, 16459 // @option pane: String = 'tilePane' 16460 // `Map pane` where the grid layer will be added. 16461 pane: 'tilePane', 16462 // @option className: String = '' 16463 // A custom class name to assign to the tile layer. Empty by default. 16464 className: '', 16465 // @option keepBuffer: Number = 2 16466 // When panning the map, keep this many rows and columns of tiles before unloading them. 16467 keepBuffer: 2 16468 }, 16469 initialize: function initialize(options) { 16470 setOptions(this, options); 16471 }, 16472 onAdd: function onAdd() { 16473 this._initContainer(); 16474 this._levels = {}; 16475 this._tiles = {}; 16476 this._resetView(); // implicit _update() call 16477 }, 16478 beforeAdd: function beforeAdd(map) { 16479 map._addZoomLimit(this); 16480 }, 16481 onRemove: function onRemove(map) { 16482 this._removeAllTiles(); 16483 _remove(this._container); 16484 map._removeZoomLimit(this); 16485 this._container = null; 16486 this._tileZoom = undefined; 16487 }, 16488 // @method bringToFront: this 16489 // Brings the tile layer to the top of all tile layers. 16490 bringToFront: function bringToFront() { 16491 if (this._map) { 16492 toFront(this._container); 16493 this._setAutoZIndex(Math.max); 16494 } 16495 return this; 16496 }, 16497 // @method bringToBack: this 16498 // Brings the tile layer to the bottom of all tile layers. 16499 bringToBack: function bringToBack() { 16500 if (this._map) { 16501 toBack(this._container); 16502 this._setAutoZIndex(Math.min); 16503 } 16504 return this; 16505 }, 16506 // @method getContainer: HTMLElement 16507 // Returns the HTML element that contains the tiles for this layer. 16508 getContainer: function getContainer() { 16509 return this._container; 16510 }, 16511 // @method setOpacity(opacity: Number): this 16512 // Changes the [opacity](#gridlayer-opacity) of the grid layer. 16513 setOpacity: function setOpacity(opacity) { 16514 this.options.opacity = opacity; 16515 this._updateOpacity(); 16516 return this; 16517 }, 16518 // @method setZIndex(zIndex: Number): this 16519 // Changes the [zIndex](#gridlayer-zindex) of the grid layer. 16520 setZIndex: function setZIndex(zIndex) { 16521 this.options.zIndex = zIndex; 16522 this._updateZIndex(); 16523 return this; 16524 }, 16525 // @method isLoading: Boolean 16526 // Returns `true` if any tile in the grid layer has not finished loading. 16527 isLoading: function isLoading() { 16528 return this._loading; 16529 }, 16530 // @method redraw: this 16531 // Causes the layer to clear all the tiles and request them again. 16532 redraw: function redraw() { 16533 if (this._map) { 16534 this._removeAllTiles(); 16535 var tileZoom = this._clampZoom(this._map.getZoom()); 16536 if (tileZoom !== this._tileZoom) { 16537 this._tileZoom = tileZoom; 16538 this._updateLevels(); 16539 } 16540 this._update(); 16541 } 16542 return this; 16543 }, 16544 getEvents: function getEvents() { 16545 var events = { 16546 viewprereset: this._invalidateAll, 16547 viewreset: this._resetView, 16548 zoom: this._resetView, 16549 moveend: this._onMoveEnd 16550 }; 16551 if (!this.options.updateWhenIdle) { 16552 // update tiles on move, but not more often than once per given interval 16553 if (!this._onMove) { 16554 this._onMove = throttle(this._onMoveEnd, this.options.updateInterval, this); 16555 } 16556 events.move = this._onMove; 16557 } 16558 if (this._zoomAnimated) { 16559 events.zoomanim = this._animateZoom; 16560 } 16561 return events; 16562 }, 16563 // @section Extension methods 16564 // Layers extending `GridLayer` shall reimplement the following method. 16565 // @method createTile(coords: Object, done?: Function): HTMLElement 16566 // Called only internally, must be overridden by classes extending `GridLayer`. 16567 // Returns the `HTMLElement` corresponding to the given `coords`. If the `done` callback 16568 // is specified, it must be called when the tile has finished loading and drawing. 16569 createTile: function createTile() { 16570 return document.createElement('div'); 16571 }, 16572 // @section 16573 // @method getTileSize: Point 16574 // Normalizes the [tileSize option](#gridlayer-tilesize)
16574into a point. Used by the `createTile()` method. 16575 getTileSize: function getTileSize() { 16576 var s = this.options.tileSize; 16577 return s instanceof Point ? s : new Point(s, s); 16578 }, 16579 _updateZIndex: function _updateZIndex() { 16580 if (this._container && this.options.zIndex !== undefined && this.options.zIndex !== null) { 16581 this._container.style.zIndex = this.options.zIndex; 16582 } 16583 }, 16584 _setAutoZIndex: function _setAutoZIndex(compare) { 16585 // go through all other layers of the same pane, set zIndex to max + 1 (front) or min - 1 (back) 16586 16587 var layers = this.getPane().children, 16588 edgeZIndex = -compare(-Infinity, Infinity); // -Infinity for max, Infinity for min 16589 16590 for (var i = 0, len = layers.length, zIndex; i < len; i++) { 16591 zIndex = layers[i].style.zIndex; 16592 if (layers[i] !== this._container && zIndex) { 16593 edgeZIndex = compare(edgeZIndex, +zIndex); 16594 } 16595 } 16596 if (isFinite(edgeZIndex)) { 16597 this.options.zIndex = edgeZIndex + compare(-1, 1); 16598 this._updateZIndex(); 16599 } 16600 }, 16601 _updateOpacity: function _updateOpacity() { 16602 if (!this._map) { 16603 return; 16604 } 16605 16606 // IE doesn't inherit filter opacity properly, so we're forced to set it on tiles 16607 if (Browser.ielt9) { 16608 return; 16609 } 16610 _setOpacity(this._container, this.options.opacity); 16611 var now = +new Date(), 16612 nextFrame = false, 16613 willPrune = false;
vendor: 28,045 bytes, lines 16614-17278
16614 for (var key in this._tiles) { 16615 var tile = this._tiles[key]; 16616 if (!tile.current || !tile.loaded) { 16617 continue; 16618 } 16619 var fade = Math.min(1, (now - tile.loaded) / 200); 16620 _setOpacity(tile.el, fade); 16621 if (fade < 1) { 16622 nextFrame = true; 16623 } else { 16624 if (tile.active) { 16625 willPrune = true; 16626 } else { 16627 this._onOpaqueTile(tile); 16628 } 16629 tile.active = true; 16630 } 16631 } 16632 if (willPrune && !this._noPrune) { 16633 this._pruneTiles(); 16634 } 16635 if (nextFrame) { 16636 cancelAnimFrame(this._fadeFrame); 16637 this._fadeFrame = requestAnimFrame(this._updateOpacity, this); 16638 } 16639 }, 16640 _onOpaqueTile: falseFn, 16641 _initContainer: function _initContainer() { 16642 if (this._container) { 16643 return; 16644 } 16645 this._container = create$1('div', 'leaflet-layer ' + (this.options.className || '')); 16646 this._updateZIndex(); 16647 if (this.options.opacity < 1) { 16648 this._updateOpacity(); 16649 } 16650 this.getPane().appendChild(this._container); 16651 }, 16652 _updateLevels: function _updateLevels() { 16653 var zoom = this._tileZoom, 16654 maxZoom = this.options.maxZoom; 16655 if (zoom === undefined) { 16656 return undefined; 16657 } 16658 for (var z in this._levels) { 16659 z = Number(z); 16660 if (this._levels[z].el.children.length || z === zoom) { 16661 this._levels[z].el.style.zIndex = maxZoom - Math.abs(zoom - z); 16662 this._onUpdateLevel(z); 16663 } else { 16664 _remove(this._levels[z].el); 16665 this._removeTilesAtZoom(z); 16666 this._onRemoveLevel(z); 16667 delete this._levels[z]; 16668 } 16669 } 16670 var level = this._levels[zoom], 16671 map = this._map; 16672 if (!level) { 16673 level = this._levels[zoom] = {}; 16674 level.el = create$1('div', 'leaflet-tile-container leaflet-zoom-animated', this._container); 16675 level.el.style.zIndex = maxZoom; 16676 level.origin = map.project(map.unproject(map.getPixelOrigin()), zoom).round(); 16677 level.zoom = zoom; 16678 this._setZoomTransform(level, map.getCenter(), map.getZoom()); 16679 16680 // force the browser to consider the newly added element for transition 16681 falseFn(level.el.offsetWidth); 16682 this._onCreateLevel(level); 16683 } 16684 this._level = level; 16685 return level; 16686 }, 16687 _onUpdateLevel: falseFn, 16688 _onRemoveLevel: falseFn, 16689 _onCreateLevel: falseFn, 16690 _pruneTiles: function _pruneTiles() { 16691 if (!this._map) { 16692 return; 16693 } 16694 var key, tile; 16695 var zoom = this._map.getZoom(); 16696 if (zoom > this.options.maxZoom || zoom < this.options.minZoom) { 16697 this._removeAllTiles(); 16698 return; 16699 } 16700 for (key in this._tiles) { 16701 tile = this._tiles[key]; 16702 tile.retain = tile.current; 16703 } 16704 for (key in this._tiles) { 16705 tile = this._tiles[key]; 16706 if (tile.current && !tile.active) { 16707 var coords = tile.coords; 16708 if (!this._retainParent(coords.x, coords.y, coords.z, coords.z - 5)) { 16709 this._retainChildren(coords.x, coords.y, coords.z, coords.z + 2); 16710 } 16711 } 16712 } 16713 for (key in this._tiles) { 16714 if (!this._tiles[key].retain) { 16715 this._removeTile(key); 16716 } 16717 } 16718 }, 16719 _removeTilesAtZoom: function _removeTilesAtZoom(zoom) { 16720 for (var key in this._tiles) { 16721 if (this._tiles[key].coords.z !== zoom) { 16722 continue; 16723 } 16724 this._removeTile(key); 16725 } 16726 }, 16727 _removeAllTiles: function _removeAllTiles() { 16728 for (var key in this._tiles) { 16729 this._removeTile(key); 16730 } 16731 }, 16732 _invalidateAll: function _invalidateAll() { 16733 for (var z in this._levels) { 16734 _remove(this._levels[z].el); 16735 this._onRemoveLevel(Number(z)); 16736 delete this._levels[z]; 16737 } 16738 this._removeAllTiles(); 16739 this._tileZoom = undefined; 16740 }, 16741 _retainParent: function _retainParent(x, y, z, minZoom) { 16742 var x2 = Math.floor(x / 2), 16743 y2 = Math.floor(y / 2), 16744 z2 = z - 1, 16745 coords2 = new Point(+x2, +y2); 16746 coords2.z = +z2; 16747 var key = this._tileCoordsToKey(coords2), 16748 tile = this._tiles[key]; 16749 if (tile && tile.active) { 16750 tile.retain = true; 16751 return true; 16752 } else if (tile && tile.loaded) { 16753 tile.retain = true; 16754 } 16755 if (z2 > minZoom) { 16756 return this._retainParent(x2, y2, z2, minZoom); 16757 } 16758 return false; 16759 }, 16760 _retainChildren: function _retainChildren(x, y, z, maxZoom) { 16761 for (var i = 2 * x; i < 2 * x + 2; i++) { 16762 for (var j = 2 * y; j < 2 * y + 2; j++) { 16763 var coords = new Point(i, j); 16764 coords.z = z + 1; 16765 var key = this._tileCoordsToKey(coords), 16766 tile = this._tiles[key]; 16767 if (tile && tile.active) { 16768 tile.retain = true; 16769 continue; 16770 } else if (tile && tile.loaded) { 16771 tile.retain = true; 16772 } 16773 if (z + 1 < maxZoom) { 16774 this._retainChildren(i, j, z + 1, maxZoom); 16775 } 16776 } 16777 } 16778 }, 16779 _resetView: function _resetView(e) { 16780 var animating = e && (e.pinch || e.flyTo); 16781 this._setView(this._map.getCenter(), this._map.getZoom(), animating, animating); 16782 }, 16783 _animateZoom: function _animateZoom(e) { 16784 this._setView(e.center, e.zoom, true, e.noUpdate); 16785 }, 16786 _clampZoom: function _clampZoom(zoom) { 16787 var options = this.options; 16788 if (undefined !== options.minNativeZoom && zoom < options.minNativeZoom) { 16789 return options.minNativeZoom; 16790 } 16791 if (undefined !== options.maxNativeZoom && options.maxNativeZoom < zoom) { 16792 return options.maxNativeZoom; 16793 } 16794 return zoom; 16795 }, 16796 _setView: function _setView(center, zoom, noPrune, noUpdate) { 16797 var tileZoom = Math.round(zoom); 16798 if (this.options.maxZoom !== undefined && tileZoom > this.options.maxZoom || this.options.minZoom !== undefined && tileZoom < this.options.minZoom) { 16799 tileZoom = undefined; 16800 } else { 16801 tileZoom = this._clampZoom(tileZoom); 16802 } 16803 var tileZoomChanged = this.options.updateWhenZooming && tileZoom !== this._tileZoom; 16804 if (!noUpdate || tileZoomChanged) { 16805 this._tileZoom = tileZoom; 16806 if (this._abortLoading) { 16807 this._abortLoading(); 16808 } 16809 this._updateLevels(); 16810 this._resetGrid(); 16811 if (tileZoom !== undefined) { 16812 this._update(center); 16813 } 16814 if (!noPrune) { 16815 this._pruneTiles(); 16816 } 16817 16818 // Flag to prevent _updateOpacity from pruning tiles during 16819 // a zoom anim or a pinch gesture 16820 this._noPrune = !!noPrune; 16821 } 16822 this._setZoomTransforms(center, zoom); 16823 }, 16824 _setZoomTransforms: function _setZoomTransforms(center, zoom) { 16825 for (var i in this._levels) { 16826 this._setZoomTransform(this._levels[i], center, zoom); 16827 } 16828 }, 16829 _setZoomTransform: function _setZoomTransform(level, center, zoom) { 16830 var scale = this._map.getZoomScale(zoom, level.zoom), 16831 translate = level.origin.multiplyBy(scale).subtract(this._map._getNewPixelOrigin(center, zoom)).round(); 16832 if (Browser.any3d) { 16833 setTransform(level.el, translate, scale); 16834 } else { 16835 setPosition(level.el, translate); 16836 } 16837 }, 16838 _resetGrid: function _resetGrid() { 16839 var map = this._map, 16840 crs = map.options.crs, 16841 tileSize = this._tileSize = this.getTileSize(), 16842 tileZoom = this._tileZoom; 16843 var bounds = this._map.getPixelWorldBounds(this._tileZoom); 16844 if (bounds) { 16845 this._globalTileRange = this._pxBoundsToTileRange(bounds); 16846 } 16847 this._wrapX = crs.wrapLng && !this.options.noWrap && [Math.floor(map.project([0, crs.wrapLng[0]], tileZoom).x / tileSize.x), Math.ceil(map.project([0, crs.wrapLng[1]], tileZoom).x / tileSize.y)]; 16848 this._wrapY = crs.wrapLat && !this.options.noWrap && [Math.floor(map.project([crs.wrapLat[0], 0], tileZoom).y / tileSize.x), Math.ceil(map.project([crs.wrapLat[1], 0], tileZoom).y / tileSize.y)]; 16849 }, 16850 _onMoveEnd: function _onMoveEnd() { 16851 if (!this._map || this._map._animatingZoom) { 16852 return; 16853 } 16854 this._update(); 16855 }, 16856 _getTiledPixelBounds: function _getTiledPixelBounds(center) { 16857 var map = this._map, 16858 mapZoom = map._animatingZoom ? Math.max(map._animateToZoom, map.getZoom()) : map.getZoom(), 16859 scale = map.getZoomScale(mapZoom, this._tileZoom), 16860 pixelCenter = map.project(center, this._tileZoom).floor(), 16861 halfSize = map.getSize().divideBy(scale * 2); 16862 return new Bounds(pixelCenter.subtract(halfSize), pixelCenter.add(halfSize)); 16863 }, 16864 // Private method to load tiles in the grid's active zoom level according to map bounds 16865 _update: function _update(center) { 16866 var map = this._map; 16867 if (!map) { 16868 return; 16869 } 16870 var zoom = this._clampZoom(map.getZoom()); 16871 if (center === undefined) { 16872 center = map.getCenter(); 16873 } 16874 if (this._tileZoom === undefined) { 16875 return; 16876 } // if out of minzoom/maxzoom 16877 16878 var pixelBounds = this._getTiledPixelBounds(center), 16879 tileRange = this._pxBoundsToTileRange(pixelBounds), 16880 tileCenter = tileRange.getCenter(), 16881 queue = [], 16882 margin = this.options.keepBuffer, 16883 noPruneRange = new Bounds(tileRange.getBottomLeft().subtract([margin, -margin]), tileRange.getTopRight().add([margin, -margin])); 16884 16885 // Sanity check: panic if the tile range contains Infinity somewhere. 16886 if (!(isFinite(tileRange.min.x) && isFinite(tileRange.min.y) && isFinite(tileRange.max.x) && isFinite(tileRange.max.y))) { 16887 throw new Error('Attempted to load an infinite number of tiles'); 16888 } 16889 for (var key in this._tiles) { 16890 var c = this._tiles[key].coords; 16891 if (c.z !== this._tileZoom || !noPruneRange.contains(new Point(c.x, c.y))) { 16892 this._tiles[key].current = false; 16893 } 16894 } 16895 16896 // _update just loads more tiles. If the tile zoom level differs too much 16897 // from the map's, let _setView reset levels and prune old tiles. 16898 if (Math.abs(zoom - this._tileZoom) > 1) { 16899 this._setView(center, zoom); 16900 return; 16901 } 16902 16903 // create a queue of coordinates to load tiles from 16904 for (var j = tileRange.min.y; j <= tileRange.max.y; j++) { 16905 for (var i = tileRange.min.x; i <= tileRange.max.x; i++) { 16906 var coords = new Point(i, j); 16907 coords.z = this._tileZoom; 16908 if (!this._isValidTile(coords)) { 16909 continue; 16910 } 16911 var tile = this._tiles[this._tileCoordsToKey(coords)]; 16912 if (tile) { 16913 tile.current = true; 16914 } else { 16915 queue.push(coords); 16916 } 16917 } 16918 } 16919 16920 // sort tile queue to load tiles in order of their distance to center 16921 queue.sort(function (a, b) { 16922 return a.distanceTo(tileCenter) - b.distanceTo(tileCenter); 16923 }); 16924 if (queue.length !== 0) { 16925 // if it's the first batch of tiles to load 16926 if (!this._loading) { 16927 this._loading = true; 16928 // @event loading: Event 16929 // Fired when the grid layer starts loading tiles. 16930 this.fire('loading'); 16931 } 16932 16933 // create DOM fragment to append tiles in one batch 16934 var fragment = document.createDocumentFragment(); 16935 for (i = 0; i < queue.length; i++) { 16936 this._addTile(queue[i], fragment); 16937 } 16938 this._level.el.appendChild(fragment); 16939 } 16940 }, 16941 _isValidTile: function _isValidTile(coords) { 16942 var crs = this._map.options.crs; 16943 if (!crs.infinite) { 16944 // don't load tile if it's out of bounds and not wrapped 16945 var bounds = this._globalTileRange; 16946 if (!crs.wrapLng && (coords.x < bounds.min.x || coords.x > bounds.max.x) || !crs.wrapLat && (coords.y < bounds.min.y || coords.y > bounds.max.y)) { 16947 return false; 16948 } 16949 } 16950 if (!this.options.bounds) { 16951 return true; 16952 } 16953 16954 // don't load tile if it doesn't intersect the bounds in options 16955 var tileBounds = this._tileCoordsToBounds(coords); 16956 return toLatLngBounds(this.options.bounds).overlaps(tileBounds); 16957 }, 16958 _keyToBounds: function _keyToBounds(key) { 16959 return this._tileCoordsToBounds(this._keyToTileCoords(key)); 16960 }, 16961 _tileCoordsToNwSe: function _tileCoordsToNwSe(coords) { 16962 var map = this._map, 16963 tileSize = this.getTileSize(), 16964 nwPoint = coords.scaleBy(tileSize), 16965 sePoint = nwPoint.add(tileSize), 16966 nw = map.unproject(nwPoint, coords.z), 16967 se = map.unproject(sePoint, coords.z); 16968 return [nw, se]; 16969 }, 16970 // converts tile coordinates to its geographical bounds 16971 _tileCoordsToBounds: function _tileCoordsToBounds(coords) { 16972 var bp = this._tileCoordsToNwSe(coords), 16973 bounds = new LatLngBounds(bp[0], bp[1]); 16974 if (!this.options.noWrap) { 16975 bounds = this._map.wrapLatLngBounds(bounds); 16976 } 16977 return bounds; 16978 }, 16979 // converts tile coordinates to key for the tile cache 16980 _tileCoordsToKey: function _tileCoordsToKey(coords) { 16981 return coords.x + ':' + coords.y + ':' + coords.z; 16982 }, 16983 // converts tile cache key to coordinates 16984 _keyToTileCoords: function _keyToTileCoords(key) { 16985 var k = key.split(':'), 16986 coords = new Point(+k[0], +k[1]); 16987 coords.z = +k[2]; 16988 return coords; 16989 }, 16990 _removeTile: function _removeTile(key) { 16991 var tile = this._tiles[key]; 16992 if (!tile) { 16993 return; 16994 } 16995 _remove(tile.el); 16996 delete this._tiles[key]; 16997 16998 // @event tileunload: TileEvent 16999 // Fired when a tile is removed (e.g. when a tile goes off the screen). 17000 this.fire('tileunload', { 17001 tile: tile.el, 17002 coords: this._keyToTileCoords(key) 17003 }); 17004 }, 17005 _initTile: function _initTile(tile) { 17006 addClass(tile, 'leaflet-tile'); 17007 var tileSize = this.getTileSize(); 17008 tile.style.width = tileSize.x + 'px'; 17009 tile.style.height = tileSize.y + 'px'; 17010 tile.onselectstart = falseFn; 17011 tile.onmousemove = falseFn; 17012 17013 // update opacity on tiles in IE7-8 because of filter inheritance problems 17014 if (Browser.ielt9 && this.options.opacity < 1) { 17015 _setOpacity(tile, this.options.opacity); 17016 } 17017 }, 17018 _addTile: function _addTile(coords, container) { 17019 var tilePos = this._getTilePos(coords), 17020 key = this._tileCoordsToKey(coords); 17021 var tile = this.createTile(this._wrapCoords(coords), bind(this._tileReady, this, coords)); 17022 this._initTile(tile); 17023 17024 // if createTile is defined with a second argument ("done" callback), 17025 // we know that tile is async and will be ready later; otherwise 17026 if (this.createTile.length < 2) { 17027 // mark tile as ready, but delay one frame for opacity animation to happen 17028 requestAnimFrame(bind(this._tileReady, this, coords, null, tile)); 17029 } 17030 setPosition(tile, tilePos); 17031 17032 // save tile in cache 17033 this._tiles[key] = { 17034 el: tile, 17035 coords: coords, 17036 current: true 17037 }; 17038 container.appendChild(tile); 17039 // @event tileloadstart: TileEvent 17040 // Fired when a tile is requested and starts loading. 17041 this.fire('tileloadstart', { 17042 tile: tile, 17043 coords: coords 17044 }); 17045 }, 17046 _tileReady: function _tileReady(coords, err, tile) { 17047 if (err) { 17048 // @event tileerror: TileErrorEvent 17049 // Fired when there is an error loading a tile. 17050 this.fire('tileerror', { 17051 error: err, 17052 tile: tile, 17053 coords: coords 17054 }); 17055 } 17056 var key = this._tileCoordsToKey(coords); 17057 tile = this._tiles[key]; 17058 if (!tile) { 17059 return; 17060 } 17061 tile.loaded = +new Date(); 17062 if (this._map._fadeAnimated) { 17063 _setOpacity(tile.el, 0); 17064 cancelAnimFrame(this._fadeFrame); 17065 this._fadeFrame = requestAnimFrame(this._updateOpacity, this); 17066 } else { 17067 tile.active = true; 17068 this._pruneTiles(); 17069 } 17070 if (!err) { 17071 addClass(tile.el, 'leaflet-tile-loaded'); 17072 17073 // @event tileload: TileEvent 17074 // Fired when a tile loads. 17075 this.fire('tileload', { 17076 tile: tile.el, 17077 coords: coords 17078 }); 17079 } 17080 if (this._noTilesToLoad()) { 17081 this._loading = false; 17082 // @event load: Event 17083 // Fired when the grid layer loaded all visible tiles. 17084 this.fire('load'); 17085 if (Browser.ielt9 || !this._map._fadeAnimated) { 17086 requestAnimFrame(this._pruneTiles, this); 17087 } else { 17088 // Wait a bit more than 0.2 secs (the duration of the tile fade-in) 17089 // to trigger a pruning. 17090 setTimeout(bind(this._pruneTiles, this), 250); 17091 } 17092 } 17093 }, 17094 _getTilePos: function _getTilePos(coords) { 17095 return coords.scaleBy(this.getTileSize()).subtract(this._level.origin); 17096 }, 17097 _wrapCoords: function _wrapCoords(coords) { 17098 var newCoords = new Point(this._wrapX ? wrapNum(coords.x, this._wrapX) : coords.x, this._wrapY ? wrapNum(coords.y, this._wrapY) : coords.y); 17099 newCoords.z = coords.z; 17100 return newCoords; 17101 }, 17102 _pxBoundsToTileRange: function _pxBoundsToTileRange(bounds) { 17103 var tileSize = this.getTileSize(); 17104 return new Bounds(bounds.min.unscaleBy(tileSize).floor(), bounds.max.unscaleBy(tileSize).ceil().subtract([1, 1])); 17105 }, 17106 _noTilesToLoad: function _noTilesToLoad() { 17107 for (var key in this._tiles) { 17108 if (!this._tiles[key].loaded) { 17109 return false; 17110 } 17111 } 17112 return true; 17113 } 17114 }); 17115 17116 // @factory L.gridLayer(options?: GridLayer options) 17117 // Creates a new instance of GridLayer with the supplied options. 17118 function gridLayer(options) { 17119 return new GridLayer(options); 17120 } 17121 17122 /* 17123 * @class TileLayer 17124 * @inherits GridLayer 17125 * @aka L.TileLayer 17126 * 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`. 17127 * 17128 * @example 17129 * 17130 * ```js 17131 * L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png?{foo}', {foo: 'bar', attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'}).addTo(map); 17132 * ``` 17133 * 17134 * @section URL template 17135 * @example 17136 * 17137 * A string of the following form: 17138 * 17139 * ``` 17140 * 'https://{s}.somedomain.com/blabla/{z}/{x}/{y}{r}.png' 17141 * ``` 17142 * 17143 * `{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 "@2x" to the URL to load retina tiles. 17144 * 17145 * You can use custom keys in the template, which will be [evaluated](#util-template) from TileLayer options, like this: 17146 * 17147 * ``` 17148 * L.tileLayer('https://{s}.somedomain.com/{foo}/{z}/{x}/{y}.png', {foo: 'bar'}); 17149 * ``` 17150 */ 17151 17152 var TileLayer = GridLayer.extend({ 17153 // @section 17154 // @aka TileLayer options 17155 options: { 17156 // @option minZoom: Number = 0 17157 // The minimum zoom level down to which this layer will be displayed (inclusive). 17158 minZoom: 0, 17159 // @option maxZoom: Number = 18 17160 // The maximum zoom level up to which this layer will be displayed (inclusive). 17161 maxZoom: 18, 17162 // @option subdomains: String|String[] = 'abc' 17163 // 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. 17164 subdomains: 'abc', 17165 // @option errorTileUrl: String = '' 17166 // URL to the tile image to show in place of the tile that failed to load. 17167 errorTileUrl: '', 17168 // @option zoomOffset: Number = 0 17169 // The zoom number used in tile URLs will be offset with this value. 17170 zoomOffset: 0, 17171 // @option tms: Boolean = false 17172 // If `true`, inverses Y axis numbering for tiles (turn this on for [TMS](https://en.wikipedia.org/wiki/Tile_Map_Service) services). 17173 tms: false, 17174 // @option zoomReverse: Boolean = false 17175 // If set to true, the zoom number used in tile URLs will be reversed (`maxZoom - zoom` instead of `zoom`) 17176 zoomReverse: false, 17177 // @option detectRetina: Boolean = false 17178 // 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. 17179 detectRetina: false, 17180 // @option crossOrigin: Boolean|String = false 17181 // Whether the crossOrigin attribute will be added to the tiles. 17182 // 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. 17183 // Refer to [CORS Settings](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) for valid String values. 17184 crossOrigin: false, 17185 // @option referrerPolicy: Boolean|String = false 17186 // Whether the referrerPolicy attribute will be added to the tiles. 17187 // If a String is provided, all tiles will have their referrerPolicy attribute set to the String provided. 17188 // This may be needed if your map's rendering context has a strict default but your tile provider expects a valid referrer 17189 // (e.g. to validate an API token). 17190 // Refer to [HTMLImageElement.referrerPolicy](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/referrerPolicy) for valid String values. 17191 referrerPolicy: false 17192 }, 17193 initialize: function initialize(url, options) { 17194 this._url = url; 17195 options = setOptions(this, options); 17196 17197 // detecting retina displays, adjusting tileSize and zoom levels 17198 if (options.detectRetina && Browser.retina && options.maxZoom > 0) { 17199 options.tileSize = Math.floor(options.tileSize / 2); 17200 if (!options.zoomReverse) { 17201 options.zoomOffset++; 17202 options.maxZoom = Math.max(options.minZoom, options.maxZoom - 1); 17203 } else { 17204 options.zoomOffset--; 17205 options.minZoom = Math.min(options.maxZoom, options.minZoom + 1); 17206 } 17207 options.minZoom = Math.max(0, options.minZoom); 17208 } else if (!options.zoomReverse) { 17209 // make sure maxZoom is gte minZoom 17210 options.maxZoom = Math.max(options.minZoom, options.maxZoom); 17211 } else { 17212 // make sure minZoom is lte maxZoom 17213 options.minZoom = Math.min(options.maxZoom, options.minZoom); 17214 } 17215 if (typeof options.subdomains === 'string') { 17216 options.subdomains = options.subdomains.split(''); 17217 } 17218 this.on('tileunload', this._onTileRemove); 17219 }, 17220 // @method setUrl(url: String, noRedraw?: Boolean): this 17221 // Updates the layer's URL template and redraws it (unless `noRedraw` is set to `true`). 17222 // If the URL does not change, the layer will not be redrawn unless 17223 // the noRedraw parameter is set to false. 17224 setUrl: function setUrl(url, noRedraw) { 17225 if (this._url === url && noRedraw === undefined) { 17226 noRedraw = true; 17227 } 17228 this._url = url; 17229 if (!noRedraw) { 17230 this.redraw(); 17231 } 17232 return this; 17233 }, 17234 // @method createTile(coords: Object, done?: Function): HTMLElement 17235 // Called only internally, overrides GridLayer's [`createTile()`](#gridlayer-createtile) 17236 // to return an `<img>` HTML element with the appropriate image URL given `coords`. The `done` 17237 // callback is called when the tile has been loaded. 17238 createTile: function createTile(coords, done) { 17239 var tile = document.createElement('img'); 17240 on(tile, 'load', bind(this._tileOnLoad, this, done, tile)); 17241 on(tile, 'error', bind(this._tileOnError, this, done, tile)); 17242 if (this.options.crossOrigin || this.options.crossOrigin === '') { 17243 tile.crossOrigin = this.options.crossOrigin === true ? '' : this.options.crossOrigin; 17244 } 17245 17246 // for this new option we follow the documented behavior 17247 // more closely by only setting the property when string 17248 if (typeof this.options.referrerPolicy === 'string') { 17249 tile.referrerPolicy = this.options.referrerPolicy; 17250 } 17251 17252 // The alt attribute is set to the empty string, 17253 // allowing screen readers to ignore the decorative image tiles. 17254 // https://www.w3.org/WAI/tutorials/images/decorative/ 17255 // https://www.w3.org/TR/html-aria/#el-img-empty-alt 17256 tile.alt = ''; 17257 tile.src = this.getTileUrl(coords); 17258 return tile; 17259 }, 17260 // @section Extension methods 17261 // @uninheritable 17262 // Layers extending `TileLayer` might reimplement the following method. 17263 // @method getTileUrl(coords: Object): String 17264 // Called only internally, returns the URL for a tile given its coordinates. 17265 // Classes extending `TileLayer` can override this function to provide custom tile URL naming schemes. 17266 getTileUrl: function getTileUrl(coords) { 17267 var data = { 17268 r: Browser.retina ? '@2x' : '', 17269 s: this._getSubdomain(coords), 17270 x: coords.x, 17271 y: coords.y, 17272 z: this._getZoomForUrl() 17273 }; 17274 if (this._map && !this._map.options.crs.infinite) { 17275 var invertedY = this._globalTileRange.max.y - coords.y; 17276 if (this.options.tms) { 17277 data['y'] = invertedY; 17278 }
17279 data['-y'] = invertedY; 17280 } 17281 return template(this._url, extend(data, this.options)); 17282 }, 17283 _tileOnLoad: function _tileOnLoad(done, tile) { 17284 // For https://github.com/Leaflet/Leaflet/issues/3332 17285 if (Browser.ielt9) { 17286 setTimeout(bind(done, this, null, tile), 0); 17287 } else { 17288 done(null, tile); 17289 } 17290 }, 17291 _tileOnError: function _tileOnError(done, tile, e) { 17292 var errorUrl = this.options.errorTileUrl; 17293 if (errorUrl && tile.getAttribute('src') !== errorUrl) { 17294 tile.src = errorUrl; 17295 } 17296 done(e, tile); 17297 }, 17298 _onTileRemove: function _onTileRemove(e) { 17299 e.tile.onload = null; 17300 }, 17301 _getZoomForUrl: function _getZoomForUrl() { 17302 var zoom = this._tileZoom, 17303 maxZoom = this.options.maxZoom, 17304 zoomReverse = this.options.zoomReverse, 17305 zoomOffset = this.options.zoomOffset; 17306 if (zoomReverse) { 17307 zoom = maxZoom - zoom; 17308 } 17309 return zoom + zoomOffset; 17310 }, 17311 _getSubdomain: function _getSubdomain(tilePoint) { 17312 var index = Math.abs(tilePoint.x + tilePoint.y) % this.options.subdomains.length; 17313 return this.options.subdomains[index]; 17314 }, 17315 // stops loading all tiles in the background layer 17316 _abortLoading: function _abortLoading() { 17317 var i, tile; 17318 for (i in this._tiles) { 17319 if (this._tiles[i].coords.z !== this._tileZoom) { 17320 tile = this._tiles[i].el; 17321 tile.onload = falseFn; 17322 tile.onerror = falseFn; 17323 if (!tile.complete) { 17324 tile.src = emptyImageUrl; 17325 var coords = this._tiles[i].coords; 17326 _remove(tile); 17327 delete this._tiles[i]; 17328 // @event tileabort: TileEvent 17329 // Fired when a tile was loading but is now not wanted. 17330 this.fire('tileabort', { 17331 tile: tile, 17332 coords: coords 17333 }); 17334 } 17335 } 17336 } 17337 }, 17338 _removeTile: function _removeTile(key) { 17339 var tile = this._tiles[key]; 17340 if (!tile) { 17341 return; 17342 } 17343 17344 // Cancels any pending http requests associated with the tile 17345 tile.el.setAttribute('src', emptyImageUrl); 17346 return GridLayer.prototype._removeTile.call(this, key); 17347 }, 17348 _tileReady: function _tileReady(coords, err, tile) { 17349 if (!this._map || tile && tile.getAttribute('src') === emptyImageUrl) { 17350 return; 17351 } 17352 return GridLayer.prototype._tileReady.call(this, coords, err, tile); 17353 } 17354 }); 17355 17356 // @factory L.tilelayer(urlTemplate: String, options?: TileLayer options) 17357 // Instantiates a tile layer object given a `URL template` and optionally an options object. 17358 17359 function tileLayer(url, options) { 17360 return new TileLayer(url, options); 17361 } 17362 17363 /* 17364 * @class TileLayer.WMS 17365 * @inherits TileLayer 17366 * @aka L.TileLayer.WMS 17367 * Used to display [WMS](https://en.wikipedia.org/wiki/Web_Map_Service) services as tile layers on the map. Extends `TileLayer`. 17368 * 17369 * @example 17370 * 17371 * ```js 17372 * var nexrad = L.tileLayer.wms("http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi", { 17373 * layers: 'nexrad-n0r-900913', 17374 * format: 'image/png', 17375 * transparent: true, 17376 * attribution: "Weather data © 2012 IEM Nexrad" 17377 * }); 17378 * ``` 17379 */ 17380 17381 var TileLayerWMS = TileLayer.extend({ 17382 // @section 17383 // @aka TileLayer.WMS options 17384 // If any custom options not documented here are used, they will be sent to the 17385 // WMS server as extra parameters in each request URL. This can be useful for 17386 // [non-standard vendor WMS parameters](https://docs.geoserver.org/stable/en/user/services/wms/vendor.html). 17387 defaultWmsParams: { 17388 service: 'WMS', 17389 request: 'GetMap', 17390 // @option layers: String = '' 17391 // **(required)** Comma-separated list of WMS layers to show. 17392 layers: '', 17393 // @option styles: String = '' 17394 // Comma-separated list of WMS styles. 17395 styles: '', 17396 // @option format: String = 'image/jpeg' 17397 // WMS image format (use `'image/png'` for layers with transparency). 17398 format: 'image/jpeg', 17399 // @option transparent: Boolean = false 17400 // If `true`, the WMS service will return images with transparency. 17401 transparent: false, 17402 // @option version: String = '1.1.1' 17403 // Version of the WMS service to use 17404 version: '1.1.1' 17405 }, 17406 options: { 17407 // @option crs: CRS = null 17408 // Coordinate Reference System to use for the WMS requests, defaults to 17409 // map CRS. Don't change this if you're not sure what it means. 17410 crs: null, 17411 // @option uppercase: Boolean = false 17412 // If `true`, WMS request parameter keys will be uppercase. 17413 uppercase: false 17414 }, 17415 initialize: function initialize(url, options) { 17416 this._url = url; 17417 var wmsParams = extend({}, this.defaultWmsParams); 17418 17419 // all keys that are not TileLayer options go to WMS params 17420 for (var i in options) { 17421 if (!(i in this.options)) { 17422 wmsParams[i] = options[i]; 17423 } 17424 } 17425 options = setOptions(this, options); 17426 var realRetina = options.detectRetina && Browser.retina ? 2 : 1; 17427 var tileSize = this.getTileSize(); 17428 wmsParams.width = tileSize.x * realRetina; 17429 wmsParams.height = tileSize.y * realRetina; 17430 this.wmsParams = wmsParams; 17431 },
vendor: 26,199 bytes, lines 17432-18133
17432 onAdd: function onAdd(map) { 17433 this._crs = this.options.crs || map.options.crs; 17434 this._wmsVersion = parseFloat(this.wmsParams.version); 17435 var projectionKey = this._wmsVersion >= 1.3 ? 'crs' : 'srs'; 17436 this.wmsParams[projectionKey] = this._crs.code; 17437 TileLayer.prototype.onAdd.call(this, map); 17438 }, 17439 getTileUrl: function getTileUrl(coords) { 17440 var tileBounds = this._tileCoordsToNwSe(coords), 17441 crs = this._crs, 17442 bounds = toBounds(crs.project(tileBounds[0]), crs.project(tileBounds[1])), 17443 min = bounds.min, 17444 max = bounds.max, 17445 bbox = (this._wmsVersion >= 1.3 && this._crs === EPSG4326 ? [min.y, min.x, max.y, max.x] : [min.x, min.y, max.x, max.y]).join(','), 17446 url = TileLayer.prototype.getTileUrl.call(this, coords); 17447 return url + getParamString(this.wmsParams, url, this.options.uppercase) + (this.options.uppercase ? '&BBOX=' : '&bbox=') + bbox; 17448 }, 17449 // @method setParams(params: Object, noRedraw?: Boolean): this 17450 // Merges an object with the new parameters and re-requests tiles on the current screen (unless `noRedraw` was set to true). 17451 setParams: function setParams(params, noRedraw) { 17452 extend(this.wmsParams, params); 17453 if (!noRedraw) { 17454 this.redraw(); 17455 } 17456 return this; 17457 } 17458 }); 17459 17460 // @factory L.tileLayer.wms(baseUrl: String, options: TileLayer.WMS options) 17461 // Instantiates a WMS tile layer object given a base URL of the WMS service and a WMS parameters/options object. 17462 function tileLayerWMS(url, options) { 17463 return new TileLayerWMS(url, options); 17464 } 17465 TileLayer.WMS = TileLayerWMS; 17466 tileLayer.wms = tileLayerWMS; 17467 17468 /* 17469 * @class Renderer 17470 * @inherits Layer 17471 * @aka L.Renderer 17472 * 17473 * Base class for vector renderer implementations (`SVG`, `Canvas`). Handles the 17474 * DOM container of the renderer, its bounds, and its zoom animation. 17475 * 17476 * A `Renderer` works as an implicit layer group for all `Path`s - the renderer 17477 * itself can be added or removed to the map. All paths use a renderer, which can 17478 * be implicit (the map will decide the type of renderer and use it automatically) 17479 * or explicit (using the [`renderer`](#path-renderer) option of the path). 17480 * 17481 * Do not use this class directly, use `SVG` and `Canvas` instead. 17482 * 17483 * @event update: Event 17484 * Fired when the renderer updates its bounds, center and zoom, for example when 17485 * its map has moved 17486 */ 17487 17488 var Renderer = Layer.extend({ 17489 // @section 17490 // @aka Renderer options 17491 options: { 17492 // @option padding: Number = 0.1 17493 // How much to extend the clip area around the map view (relative to its size) 17494 // e.g. 0.1 would be 10% of map view in each direction 17495 padding: 0.1 17496 }, 17497 initialize: function initialize(options) { 17498 setOptions(this, options); 17499 stamp(this); 17500 this._layers = this._layers || {}; 17501 }, 17502 onAdd: function onAdd() { 17503 if (!this._container) { 17504 this._initContainer(); // defined by renderer implementations 17505 17506 // always keep transform-origin as 0 0 17507 addClass(this._container, 'leaflet-zoom-animated'); 17508 } 17509 this.getPane().appendChild(this._container); 17510 this._update(); 17511 this.on('update', this._updatePaths, this); 17512 }, 17513 onRemove: function onRemove() { 17514 this.off('update', this._updatePaths, this); 17515 this._destroyContainer(); 17516 }, 17517 getEvents: function getEvents() { 17518 var events = { 17519 viewreset: this._reset, 17520 zoom: this._onZoom, 17521 moveend: this._update, 17522 zoomend: this._onZoomEnd 17523 }; 17524 if (this._zoomAnimated) { 17525 events.zoomanim = this._onAnimZoom; 17526 } 17527 return events; 17528 }, 17529 _onAnimZoom: function _onAnimZoom(ev) { 17530 this._updateTransform(ev.center, ev.zoom); 17531 }, 17532 _onZoom: function _onZoom() { 17533 this._updateTransform(this._map.getCenter(), this._map.getZoom()); 17534 }, 17535 _updateTransform: function _updateTransform(center, zoom) { 17536 var scale = this._map.getZoomScale(zoom, this._zoom), 17537 viewHalf = this._map.getSize().multiplyBy(0.5 + this.options.padding), 17538 currentCenterPoint = this._map.project(this._center, zoom), 17539 topLeftOffset = viewHalf.multiplyBy(-scale).add(currentCenterPoint).subtract(this._map._getNewPixelOrigin(center, zoom)); 17540 if (Browser.any3d) { 17541 setTransform(this._container, topLeftOffset, scale); 17542 } else { 17543 setPosition(this._container, topLeftOffset); 17544 } 17545 }, 17546 _reset: function _reset() { 17547 this._update(); 17548 this._updateTransform(this._center, this._zoom); 17549 for (var id in this._layers) { 17550 this._layers[id]._reset(); 17551 } 17552 }, 17553 _onZoomEnd: function _onZoomEnd() { 17554 for (var id in this._layers) { 17555 this._layers[id]._project(); 17556 } 17557 }, 17558 _updatePaths: function _updatePaths() { 17559 for (var id in this._layers) { 17560 this._layers[id]._update(); 17561 } 17562 }, 17563 _update: function _update() { 17564 // Update pixel bounds of renderer container (for positioning/sizing/clipping later) 17565 // Subclasses are responsible of firing the 'update' event. 17566 var p = this.options.padding, 17567 size = this._map.getSize(), 17568 min = this._map.containerPointToLayerPoint(size.multiplyBy(-p)).round(); 17569 this._bounds = new Bounds(min, min.add(size.multiplyBy(1 + p * 2)).round()); 17570 this._center = this._map.getCenter(); 17571 this._zoom = this._map.getZoom(); 17572 } 17573 }); 17574 17575 /* 17576 * @class Canvas 17577 * @inherits Renderer 17578 * @aka L.Canvas 17579 * 17580 * Allows vector layers to be displayed with [`<canvas>`](https://developer.mozilla.org/docs/Web/API/Canvas_API). 17581 * Inherits `Renderer`. 17582 * 17583 * Due to [technical limitations](https://caniuse.com/canvas), Canvas is not 17584 * available in all web browsers, notably IE8, and overlapping geometries might 17585 * not display properly in some edge cases. 17586 * 17587 * @example 17588 * 17589 * Use Canvas by default for all paths in the map: 17590 * 17591 * ```js 17592 * var map = L.map('map', { 17593 * renderer: L.canvas() 17594 * }); 17595 * ``` 17596 * 17597 * Use a Canvas renderer with extra padding for specific vector geometries: 17598 * 17599 * ```js 17600 * var map = L.map('map'); 17601 * var myRenderer = L.canvas({ padding: 0.5 }); 17602 * var line = L.polyline( coordinates, { renderer: myRenderer } ); 17603 * var circle = L.circle( center, { renderer: myRenderer } ); 17604 * ``` 17605 */ 17606 17607 var Canvas = Renderer.extend({ 17608 // @section 17609 // @aka Canvas options 17610 options: { 17611 // @option tolerance: Number = 0 17612 // How much to extend the click tolerance around a path/object on the map. 17613 tolerance: 0 17614 }, 17615 getEvents: function getEvents() { 17616 var events = Renderer.prototype.getEvents.call(this); 17617 events.viewprereset = this._onViewPreReset; 17618 return events; 17619 }, 17620 _onViewPreReset: function _onViewPreReset() { 17621 // Set a flag so that a viewprereset+moveend+viewreset only updates&redraws once 17622 this._postponeUpdatePaths = true; 17623 }, 17624 onAdd: function onAdd() { 17625 Renderer.prototype.onAdd.call(this); 17626 17627 // Redraw vectors since canvas is cleared upon removal, 17628 // in case of removing the renderer itself from the map. 17629 this._draw(); 17630 }, 17631 _initContainer: function _initContainer() { 17632 var container = this._container = document.createElement('canvas'); 17633 on(container, 'mousemove', this._onMouseMove, this); 17634 on(container, 'click dblclick mousedown mouseup contextmenu', this._onClick, this); 17635 on(container, 'mouseout', this._handleMouseOut, this); 17636 container['_leaflet_disable_events'] = true; 17637 this._ctx = container.getContext('2d'); 17638 }, 17639 _destroyContainer: function _destroyContainer() { 17640 cancelAnimFrame(this._redrawRequest); 17641 delete this._ctx; 17642 _remove(this._container); 17643 off(this._container); 17644 delete this._container; 17645 }, 17646 _updatePaths: function _updatePaths() { 17647 if (this._postponeUpdatePaths) { 17648 return; 17649 } 17650 var layer; 17651 this._redrawBounds = null; 17652 for (var id in this._layers) { 17653 layer = this._layers[id]; 17654 layer._update(); 17655 } 17656 this._redraw(); 17657 }, 17658 _update: function _update() { 17659 if (this._map._animatingZoom && this._bounds) { 17660 return; 17661 } 17662 Renderer.prototype._update.call(this); 17663 var b = this._bounds, 17664 container = this._container, 17665 size = b.getSize(), 17666 m = Browser.retina ? 2 : 1; 17667 setPosition(container, b.min); 17668 17669 // set canvas size (also clearing it); use double size on retina 17670 container.width = m * size.x; 17671 container.height = m * size.y; 17672 container.style.width = size.x + 'px'; 17673 container.style.height = size.y + 'px'; 17674 if (Browser.retina) { 17675 this._ctx.scale(2, 2); 17676 } 17677 17678 // translate so we use the same path coordinates after canvas element moves 17679 this._ctx.translate(-b.min.x, -b.min.y); 17680 17681 // Tell paths to redraw themselves 17682 this.fire('update'); 17683 }, 17684 _reset: function _reset() { 17685 Renderer.prototype._reset.call(this); 17686 if (this._postponeUpdatePaths) { 17687 this._postponeUpdatePaths = false; 17688 this._updatePaths(); 17689 } 17690 }, 17691 _initPath: function _initPath(layer) { 17692 this._updateDashArray(layer); 17693 this._layers[stamp(layer)] = layer; 17694 var order = layer._order = { 17695 layer: layer, 17696 prev: this._drawLast, 17697 next: null 17698 }; 17699 if (this._drawLast) { 17700 this._drawLast.next = order; 17701 } 17702 this._drawLast = order; 17703 this._drawFirst = this._drawFirst || this._drawLast; 17704 }, 17705 _addPath: function _addPath(layer) { 17706 this._requestRedraw(layer); 17707 }, 17708 _removePath: function _removePath(layer) { 17709 var order = layer._order; 17710 var next = order.next; 17711 var prev = order.prev; 17712 if (next) { 17713 next.prev = prev; 17714 } else { 17715 this._drawLast = prev; 17716 } 17717 if (prev) { 17718 prev.next = next; 17719 } else { 17720 this._drawFirst = next; 17721 } 17722 delete layer._order; 17723 delete this._layers[stamp(layer)]; 17724 this._requestRedraw(layer); 17725 }, 17726 _updatePath: function _updatePath(layer) { 17727 // Redraw the union of the layer's old pixel 17728 // bounds and the new pixel bounds. 17729 this._extendRedrawBounds(layer); 17730 layer._project(); 17731 layer._update(); 17732 // The redraw will extend the redraw bounds 17733 // with the new pixel bounds. 17734 this._requestRedraw(layer); 17735 }, 17736 _updateStyle: function _updateStyle(layer) { 17737 this._updateDashArray(layer); 17738 this._requestRedraw(layer); 17739 }, 17740 _updateDashArray: function _updateDashArray(layer) { 17741 if (typeof layer.options.dashArray === 'string') { 17742 var parts = layer.options.dashArray.split(/[, ]+/), 17743 dashArray = [], 17744 dashValue, 17745 i; 17746 for (i = 0; i < parts.length; i++) { 17747 dashValue = Number(parts[i]); 17748 // Ignore dash array containing invalid lengths 17749 if (isNaN(dashValue)) { 17750 return; 17751 } 17752 dashArray.push(dashValue); 17753 } 17754 layer.options._dashArray = dashArray; 17755 } else { 17756 layer.options._dashArray = layer.options.dashArray; 17757 } 17758 }, 17759 _requestRedraw: function _requestRedraw(layer) { 17760 if (!this._map) { 17761 return; 17762 } 17763 this._extendRedrawBounds(layer); 17764 this._redrawRequest = this._redrawRequest || requestAnimFrame(this._redraw, this); 17765 }, 17766 _extendRedrawBounds: function _extendRedrawBounds(layer) { 17767 if (layer._pxBounds) { 17768 var padding = (layer.options.weight || 0) + 1; 17769 this._redrawBounds = this._redrawBounds || new Bounds(); 17770 this._redrawBounds.extend(layer._pxBounds.min.subtract([padding, padding])); 17771 this._redrawBounds.extend(layer._pxBounds.max.add([padding, padding])); 17772 } 17773 }, 17774 _redraw: function _redraw() { 17775 this._redrawRequest = null; 17776 if (this._redrawBounds) { 17777 this._redrawBounds.min._floor(); 17778 this._redrawBounds.max._ceil(); 17779 } 17780 this._clear(); // clear layers in redraw bounds 17781 this._draw(); // draw layers 17782 17783 this._redrawBounds = null; 17784 }, 17785 _clear: function _clear() { 17786 var bounds = this._redrawBounds; 17787 if (bounds) { 17788 var size = bounds.getSize(); 17789 this._ctx.clearRect(bounds.min.x, bounds.min.y, size.x, size.y); 17790 } else { 17791 this._ctx.save(); 17792 this._ctx.setTransform(1, 0, 0, 1, 0, 0); 17793 this._ctx.clearRect(0, 0, this._container.width, this._container.height); 17794 this._ctx.restore(); 17795 } 17796 }, 17797 _draw: function _draw() { 17798 var layer, 17799 bounds = this._redrawBounds; 17800 this._ctx.save(); 17801 if (bounds) { 17802 var size = bounds.getSize(); 17803 this._ctx.beginPath(); 17804 this._ctx.rect(bounds.min.x, bounds.min.y, size.x, size.y); 17805 this._ctx.clip(); 17806 } 17807 this._drawing = true; 17808 for (var order = this._drawFirst; order; order = order.next) { 17809 layer = order.layer; 17810 if (!bounds || layer._pxBounds && layer._pxBounds.intersects(bounds)) { 17811 layer._updatePath(); 17812 } 17813 } 17814 this._drawing = false; 17815 this._ctx.restore(); // Restore state before clipping. 17816 }, 17817 _updatePoly: function _updatePoly(layer, closed) { 17818 if (!this._drawing) { 17819 return; 17820 } 17821 var i, 17822 j, 17823 len2, 17824 p, 17825 parts = layer._parts, 17826 len = parts.length, 17827 ctx = this._ctx; 17828 if (!len) { 17829 return; 17830 } 17831 ctx.beginPath(); 17832 for (i = 0; i < len; i++) { 17833 for (j = 0, len2 = parts[i].length; j < len2; j++) { 17834 p = parts[i][j]; 17835 ctx[j ? 'lineTo' : 'moveTo'](p.x, p.y); 17836 } 17837 if (closed) { 17838 ctx.closePath(); 17839 } 17840 } 17841 this._fillStroke(ctx, layer); 17842 17843 // TODO optimization: 1 fill/stroke for all features with equal style instead of 1 for each feature 17844 }, 17845 _updateCircle: function _updateCircle(layer) { 17846 if (!this._drawing || layer._empty()) { 17847 return; 17848 } 17849 var p = layer._point, 17850 ctx = this._ctx, 17851 r = Math.max(Math.round(layer._radius), 1), 17852 s = (Math.max(Math.round(layer._radiusY), 1) || r) / r; 17853 if (s !== 1) { 17854 ctx.save(); 17855 ctx.scale(1, s); 17856 } 17857 ctx.beginPath(); 17858 ctx.arc(p.x, p.y / s, r, 0, Math.PI * 2, false); 17859 if (s !== 1) { 17860 ctx.restore(); 17861 } 17862 this._fillStroke(ctx, layer); 17863 }, 17864 _fillStroke: function _fillStroke(ctx, layer) { 17865 var options = layer.options; 17866 if (options.fill) { 17867 ctx.globalAlpha = options.fillOpacity; 17868 ctx.fillStyle = options.fillColor || options.color; 17869 ctx.fill(options.fillRule || 'evenodd'); 17870 } 17871 if (options.stroke && options.weight !== 0) { 17872 if (ctx.setLineDash) { 17873 ctx.setLineDash(layer.options && layer.options._dashArray || []); 17874 } 17875 ctx.globalAlpha = options.opacity; 17876 ctx.lineWidth = options.weight; 17877 ctx.strokeStyle = options.color; 17878 ctx.lineCap = options.lineCap; 17879 ctx.lineJoin = options.lineJoin; 17880 ctx.stroke(); 17881 } 17882 }, 17883 // Canvas obviously doesn't have mouse events for individual drawn objects, 17884 // so we emulate that by calculating what's under the mouse on mousemove/click manually 17885 17886 _onClick: function _onClick(e) { 17887 var point = this._map.mouseEventToLayerPoint(e), 17888 layer, 17889 clickedLayer; 17890 for (var order = this._drawFirst; order; order = order.next) { 17891 layer = order.layer; 17892 if (layer.options.interactive && layer._containsPoint(point)) { 17893 if (!(e.type === 'click' || e.type === 'preclick') || !this._map._draggableMoved(layer)) { 17894 clickedLayer = layer; 17895 } 17896 } 17897 } 17898 this._fireEvent(clickedLayer ? [clickedLayer] : false, e); 17899 }, 17900 _onMouseMove: function _onMouseMove(e) { 17901 if (!this._map || this._map.dragging.moving() || this._map._animatingZoom) { 17902 return; 17903 } 17904 var point = this._map.mouseEventToLayerPoint(e); 17905 this._handleMouseHover(e, point); 17906 }, 17907 _handleMouseOut: function _handleMouseOut(e) { 17908 var layer = this._hoveredLayer; 17909 if (layer) { 17910 // if we're leaving the layer, fire mouseout 17911 removeClass(this._container, 'leaflet-interactive'); 17912 this._fireEvent([layer], e, 'mouseout'); 17913 this._hoveredLayer = null; 17914 this._mouseHoverThrottled = false; 17915 } 17916 }, 17917 _handleMouseHover: function _handleMouseHover(e, point) { 17918 if (this._mouseHoverThrottled) { 17919 return; 17920 } 17921 var layer, candidateHoveredLayer; 17922 for (var order = this._drawFirst; order; order = order.next) { 17923 layer = order.layer; 17924 if (layer.options.interactive && layer._containsPoint(point)) { 17925 candidateHoveredLayer = layer; 17926 } 17927 } 17928 if (candidateHoveredLayer !== this._hoveredLayer) { 17929 this._handleMouseOut(e); 17930 if (candidateHoveredLayer) { 17931 addClass(this._container, 'leaflet-interactive'); // change cursor 17932 this._fireEvent([candidateHoveredLayer], e, 'mouseover'); 17933 this._hoveredLayer = candidateHoveredLayer; 17934 } 17935 } 17936 this._fireEvent(this._hoveredLayer ? [this._hoveredLayer] : false, e); 17937 this._mouseHoverThrottled = true; 17938 setTimeout(bind(function () { 17939 this._mouseHoverThrottled = false; 17940 }, this), 32); 17941 }, 17942 _fireEvent: function _fireEvent(layers, e, type) { 17943 this._map._fireDOMEvent(e, type || e.type, layers); 17944 }, 17945 _bringToFront: function _bringToFront(layer) { 17946 var order = layer._order; 17947 if (!order) { 17948 return; 17949 } 17950 var next = order.next; 17951 var prev = order.prev; 17952 if (next) { 17953 next.prev = prev; 17954 } else { 17955 // Already last 17956 return; 17957 } 17958 if (prev) { 17959 prev.next = next; 17960 } else if (next) { 17961 // Update first entry unless this is the 17962 // single entry 17963 this._drawFirst = next; 17964 } 17965 order.prev = this._drawLast; 17966 this._drawLast.next = order; 17967 order.next = null; 17968 this._drawLast = order; 17969 this._requestRedraw(layer); 17970 }, 17971 _bringToBack: function _bringToBack(layer) { 17972 var order = layer._order; 17973 if (!order) { 17974 return; 17975 } 17976 var next = order.next; 17977 var prev = order.prev; 17978 if (prev) { 17979 prev.next = next; 17980 } else { 17981 // Already first 17982 return; 17983 } 17984 if (next) { 17985 next.prev = prev; 17986 } else if (prev) { 17987 // Update last entry unless this is the 17988 // single entry 17989 this._drawLast = prev; 17990 } 17991 order.prev = null; 17992 order.next = this._drawFirst; 17993 this._drawFirst.prev = order; 17994 this._drawFirst = order; 17995 this._requestRedraw(layer); 17996 } 17997 }); 17998 17999 // @factory L.canvas(options?: Renderer options) 18000 // Creates a Canvas renderer with the given options. 18001 function canvas(options) { 18002 return Browser.canvas ? new Canvas(options) : null; 18003 } 18004 18005 /* 18006 * Thanks to Dmitry Baranovsky and his Raphael library for inspiration! 18007 */ 18008 18009 var vmlCreate = function () { 18010 try { 18011 document.namespaces.add('lvml', 'urn:schemas-microsoft-com:vml'); 18012 return function (name) { 18013 return document.createElement('<lvml:' + name + ' class="lvml">'); 18014 }; 18015 } catch (e) { 18016 // Do not return fn from catch block so `e` can be garbage collected 18017 // See https://github.com/Leaflet/Leaflet/pull/7279 18018 } 18019 return function (name) { 18020 return document.createElement('<' + name + ' xmlns="urn:schemas-microsoft.com:vml" class="lvml">'); 18021 }; 18022 }(); 18023 18024 /* 18025 * @class SVG 18026 * 18027 * 18028 * VML was deprecated in 2012, which means VML functionality exists only for backwards compatibility 18029 * with old versions of Internet Explorer. 18030 */ 18031 18032 // mixin to redefine some SVG methods to handle VML syntax which is similar but with some differences 18033 var vmlMixin = { 18034 _initContainer: function _initContainer() { 18035 this._container = create$1('div', 'leaflet-vml-container'); 18036 }, 18037 _update: function _update() { 18038 if (this._map._animatingZoom) { 18039 return; 18040 } 18041 Renderer.prototype._update.call(this); 18042 this.fire('update'); 18043 }, 18044 _initPath: function _initPath(layer) { 18045 var container = layer._container = vmlCreate('shape'); 18046 addClass(container, 'leaflet-vml-shape ' + (this.options.className || '')); 18047 container.coordsize = '1 1'; 18048 layer._path = vmlCreate('path'); 18049 container.appendChild(layer._path); 18050 this._updateStyle(layer); 18051 this._layers[stamp(layer)] = layer; 18052 }, 18053 _addPath: function _addPath(layer) { 18054 var container = layer._container; 18055 this._container.appendChild(container); 18056 if (layer.options.interactive) { 18057 layer.addInteractiveTarget(container); 18058 } 18059 }, 18060 _removePath: function _removePath(layer) { 18061 var container = layer._container; 18062 _remove(container); 18063 layer.removeInteractiveTarget(container); 18064 delete this._layers[stamp(layer)]; 18065 }, 18066 _updateStyle: function _updateStyle(layer) { 18067 var stroke = layer._stroke, 18068 fill = layer._fill, 18069 options = layer.options, 18070 container = layer._container; 18071 container.stroked = !!options.stroke; 18072 container.filled = !!options.fill; 18073 if (options.stroke) { 18074 if (!stroke) { 18075 stroke = layer._stroke = vmlCreate('stroke'); 18076 } 18077 container.appendChild(stroke); 18078 stroke.weight = options.weight + 'px'; 18079 stroke.color = options.color; 18080 stroke.opacity = options.opacity; 18081 if (options.dashArray) { 18082 stroke.dashStyle = isArray(options.dashArray) ? options.dashArray.join(' ') : options.dashArray.replace(/( *, *)/g, ' '); 18083 } else { 18084 stroke.dashStyle = ''; 18085 } 18086 stroke.endcap = options.lineCap.replace('butt', 'flat'); 18087 stroke.joinstyle = options.lineJoin; 18088 } else if (stroke) { 18089 container.removeChild(stroke); 18090 layer._stroke = null; 18091 } 18092 if (options.fill) { 18093 if (!fill) { 18094 fill = layer._fill = vmlCreate('fill'); 18095 } 18096 container.appendChild(fill); 18097 fill.color = options.fillColor || options.color; 18098 fill.opacity = options.fillOpacity; 18099 } else if (fill) { 18100 container.removeChild(fill); 18101 layer._fill = null; 18102 } 18103 }, 18104 _updateCircle: function _updateCircle(layer) { 18105 var p = layer._point.round(), 18106 r = Math.round(layer._radius), 18107 r2 = Math.round(layer._radiusY || r); 18108 this._setPath(layer, layer._empty() ? 'M0 0' : 'AL ' + p.x + ',' + p.y + ' ' + r + ',' + r2 + ' 0,' + 65535 * 360); 18109 }, 18110 _setPath: function _setPath(layer, path) { 18111 layer._path.v = path; 18112 }, 18113 _bringToFront: function _bringToFront(layer) { 18114 toFront(layer._container); 18115 }, 18116 _bringToBack: function _bringToBack(layer) { 18117 toBack(layer._container); 18118 } 18119 }; 18120 var create = Browser.vml ? vmlCreate : svgCreate; 18121 18122 /* 18123 * @class SVG 18124 * @inherits Renderer 18125 * @aka L.SVG 18126 * 18127 * Allows vector layers to be displayed with [SVG](https://developer.mozilla.org/docs/Web/SVG). 18128 * Inherits `Renderer`. 18129 * 18130 * Due to [technical limitations](https://caniuse.com/svg), SVG is not 18131 * available in all web browsers, notably Android 2.x and 3.x. 18132 * 18133 * Although SVG is not available on IE7 and IE8, these browsers support
18134 * [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language) 18135 * (a now deprecated technology), and the SVG renderer will fall back to VML in 18136 * this case. 18137 * 18138 * @example 18139 * 18140 * Use SVG by default for all paths in the map: 18141 * 18142 * ```js 18143 * var map = L.map('map', { 18144 * renderer: L.svg() 18145 * }); 18146 * ``` 18147 * 18148 * Use a SVG renderer with extra padding for specific vector geometries: 18149 * 18150 * ```js 18151 * var map = L.map('map'); 18152 * var myRenderer = L.svg({ padding: 0.5 }); 18153 * var line = L.polyline( coordinates, { renderer: myRenderer } ); 18154 * var circle = L.circle( center, { renderer: myRenderer } ); 18155 * ``` 18156 */ 18157 18158 var SVG = Renderer.extend({ 18159 _initContainer: function _initContainer() { 18160 this._container = create('svg'); 18161 18162 // makes it possible to click through svg root; we'll reset it back in individual paths 18163 this._container.setAttribute('pointer-events', 'none'); 18164 this._rootGroup = create('g'); 18165 this._container.appendChild(this._rootGroup); 18166 }, 18167 _destroyContainer: function _destroyContainer() { 18168 _remove(this._container); 18169 off(this._container); 18170 delete this._container; 18171 delete this._rootGroup; 18172 delete this._svgSize; 18173 }, 18174 _update: function _update() { 18175 if (this._map._animatingZoom && this._bounds) { 18176 return; 18177 } 18178 Renderer.prototype._update.call(this); 18179 var b = this._bounds, 18180 size = b.getSize(), 18181 container = this._container; 18182 18183 // set size of svg-container if changed 18184 if (!this._svgSize || !this._svgSize.equals(size)) { 18185 this._svgSize = size; 18186 container.setAttribute('width', size.x); 18187 container.setAttribute('height', size.y); 18188 } 18189 18190 // movement: update container viewBox so that we don't have to change coordinates of individual layers 18191 setPosition(container, b.min); 18192 container.setAttribute('viewBox', [b.min.x, b.min.y, size.x, size.y].join(' ')); 18193 this.fire('update'); 18194 }, 18195 // methods below are called by vector layers implementations 18196 18197 _initPath: function _initPath(layer) { 18198 var path = layer._path = create('path'); 18199 18200 // @namespace Path 18201 // @option className: String = null 18202 // Custom class name set on an element. Only for SVG renderer. 18203 if (layer.options.className) { 18204 addClass(path, layer.options.className); 18205 } 18206 if (layer.options.interactive) { 18207 addClass(path, 'leaflet-interactive'); 18208 } 18209 this._updateStyle(layer); 18210 this._layers[stamp(layer)] = layer; 18211 }, 18212 _addPath: function _addPath(layer) { 18213 if (!this._rootGroup) { 18214 this._initContainer(); 18215 } 18216 this._rootGroup.appendChild(layer._path); 18217 layer.addInteractiveTarget(layer._path); 18218 }, 18219 _removePath: function _removePath(layer) { 18220 _remove(layer._path); 18221 layer.removeInteractiveTarget(layer._path); 18222 delete this._layers[stamp(layer)]; 18223 }, 18224 _updatePath: function _updatePath(layer) { 18225 layer._project(); 18226 layer._update(); 18227 }, 18228 _updateStyle: function _updateStyle(layer) { 18229 var path = layer._path, 18230 options = layer.options; 18231 if (!path) { 18232 return; 18233 } 18234 if (options.stroke) { 18235 path.setAttribute('stroke', options.color); 18236 path.setAttribute('stroke-opacity', options.opacity); 18237 path.setAttribute('stroke-width', options.weight); 18238 path.setAttribute('stroke-linecap', options.lineCap); 18239 path.setAttribute('stroke-linejoin', options.lineJoin); 18240 if (options.dashArray) { 18241 path.setAttribute('stroke-dasharray', options.dashArray); 18242 } else { 18243 path.removeAttribute('stroke-dasharray'); 18244 } 18245 if (options.dashOffset) { 18246 path.setAttribute('stroke-dashoffset', options.dashOffset); 18247 } else { 18248 path.removeAttribute('stroke-dashoffset'); 18249 } 18250 } else { 18251 path.setAttribute('stroke', 'none'); 18252 } 18253 if (options.fill) { 18254 path.setAttribute('fill', options.fillColor || options.color); 18255 path.setAttribute('fill-opacity', options.fillOpacity); 18256 path.setAttribute('fill-rule', options.fillRule || 'evenodd'); 18257 } else { 18258 path.setAttribute('fill', 'none'); 18259 } 18260 }, 18261 _updatePoly: function _updatePoly(layer, closed) { 18262 this._setPath(layer, pointsToPath(layer._parts, closed)); 18263 }, 18264 _updateCircle: function _updateCircle(layer) { 18265 var p = layer._point, 18266 r = Math.max(Math.round(layer._radius), 1), 18267 r2 = Math.max(Math.round(layer._radiusY), 1) || r, 18268 arc = 'a' + r + ',' + r2 + ' 0 1,0 '; 18269 18270 // drawing a circle with two half-arcs 18271 var d = layer._empty() ? 'M0 0' : 'M' + (p.x - r) + ',' + p.y + arc + r * 2 + ',0 ' + arc + -r * 2 + ',0 '; 18272 this._setPath(layer, d); 18273 }, 18274 _setPath: function _setPath(layer, path) { 18275 layer._path.setAttribute('d', path); 18276 }, 18277 // SVG does not have the concept of zIndex so we resort to changing the DOM order of elements 18278 _bringToFront: function _bringToFront(layer) { 18279 toFront(layer._path); 18280 }, 18281 _bringToBack: function _bringToBack(layer) { 18282 toBack(layer._path); 18283 } 18284 }); 18285 if (Browser.vml) { 18286 SVG.include(vmlMixin); 18287 } 18288 18289 // @namespace SVG 18290 // @factory L.svg(options?: Renderer options) 18291 // Creates a SVG renderer with the given options. 18292 function svg(options) { 18293 return Browser.svg || Browser.vml ? new SVG(options) : null; 18294 } 18295 Map.include({ 18296 // @namespace Map; @method getRenderer(layer: Path): Renderer 18297 // Returns the instance of `Renderer` that should be used to render the given 18298 // `Path`. It will ensure that the `renderer` options of the map and paths 18299 // are respected, and that the renderers do exist on the map. 18300 getRenderer: function getRenderer(layer) { 18301 // @namespace Path; @option renderer: Renderer 18302 // Use this specific instance of `Renderer` for this path. Takes 18303 // precedence over the map's [default renderer](#map-renderer). 18304 var renderer = layer.options.renderer || this._getPaneRenderer(layer.options.pane) || this.options.renderer || this._renderer; 18305 if (!renderer) { 18306 renderer = this._renderer = this._createRenderer(); 18307 } 18308 if (!this.hasLayer(renderer)) { 18309 this.addLayer(renderer); 18310 } 18311 return renderer; 18312 }, 18313 _getPaneRenderer: function _getPaneRenderer(name) { 18314 if (name === 'overlayPane' || name === undefined) { 18315 return false;
18316 } 18317 var renderer = this._paneRenderers[name]; 18318 if (renderer === undefined) { 18319 renderer = this._createRenderer({ 18320 pane: name 18321 }); 18322 this._paneRenderers[name] = renderer; 18323 } 18324 return renderer; 18325 }, 18326 _createRenderer: function _createRenderer(options) { 18327 // @namespace Map; @option preferCanvas: Boolean = false 18328 // Whether `Path`s should be rendered on a `Canvas` renderer. 18329 // By default, all `Path`s are rendered in a `SVG` renderer. 18330 return this.options.preferCanvas && canvas(options) || svg(options); 18331 } 18332 }); 18333 18334 /* 18335 * L.Rectangle extends Polygon and creates a rectangle when passed a LatLngBounds object. 18336 */ 18337 18338 /* 18339 * @class Rectangle 18340 * @aka L.Rectangle 18341 * @inherits Polygon 18342 * 18343 * A class for drawing rectangle overlays on a map. Extends `Polygon`. 18344 * 18345 * @example 18346 * 18347 * ```js 18348 * // define rectangle geographical bounds 18349 * var bounds = [[54.559322, -5.767822], [56.1210604, -3.021240]]; 18350 * 18351 * // create an orange rectangle 18352 * L.rectangle(bounds, {color: "#ff7800", weight: 1}).addTo(map); 18353 * 18354 * // zoom the map to the rectangle bounds 18355 * map.fitBounds(bounds); 18356 * ``` 18357 * 18358 */ 18359 18360 var Rectangle = Polygon.extend({ 18361 initialize: function initialize(latLngBounds, options) { 18362 Polygon.prototype.initialize.call(this, this._boundsToLatLngs(latLngBounds), options); 18363 }, 18364 // @method setBounds(latLngBounds: LatLngBounds): this 18365 // Redraws the rectangle with the passed bounds. 18366 setBounds: function setBounds(latLngBounds) { 18367 return this.setLatLngs(this._boundsToLatLngs(latLngBounds)); 18368 }, 18369 _boundsToLatLngs: function _boundsToLatLngs(latLngBounds) { 18370 latLngBounds = toLatLngBounds(latLngBounds);
18371 return [latLngBounds.getSouthWest(), latLngBounds.getNorthWest(), latLngBounds.getNorthEast(), latLngBounds.getSouthEast()]; 18372 } 18373 }); 18374 18375 // @factory L.rectangle(latLngBounds: LatLngBounds, options?: Polyline options) 18376 function rectangle(latLngBounds, options) { 18377 return new Rectangle(latLngBounds, options); 18378 } 18379 SVG.create = create; 18380 SVG.pointsToPath = pointsToPath; 18381 GeoJSON.geometryToLayer = geometryToLayer; 18382 GeoJSON.coordsToLatLng = coordsToLatLng; 18383 GeoJSON.coordsToLatLngs = coordsToLatLngs; 18384 GeoJSON.latLngToCoords = latLngToCoords; 18385 GeoJSON.latLngsToCoords = latLngsToCoords; 18386 GeoJSON.getFeature = getFeature; 18387 GeoJSON.asFeature = asFeature; 18388 18389 /* 18390 * L.Handler.BoxZoom is used to add shift-drag zoom interaction to the map 18391 * (zoom to a selected bounding box), enabled by default. 18392 */ 18393 18394 // @namespace Map 18395 // @section Interaction Options 18396 Map.mergeOptions({ 18397 // @option boxZoom: Boolean = true 18398 // Whether the map can be zoomed to a rectangular area specified by 18399 // dragging the mouse while pressing the shift key. 18400 boxZoom: true 18401 }); 18402 var BoxZoom = Handler.extend({ 18403 initialize: function initialize(map) { 18404 this._map = map; 18405 this._container = map._container; 18406 this._pane = map._panes.overlayPane; 18407 this._resetStateTimeout = 0; 18408 map.on('unload', this._destroy, this); 18409 }, 18410 addHooks: function addHooks() { 18411 on(this._container, 'mousedown', this._onMouseDown, this); 18412 }, 18413 removeHooks: function removeHooks() { 18414 off(this._container, 'mousedown', this._onMouseDown, this); 18415 }, 18416 moved: function moved() { 18417 return this._moved; 18418 }, 18419 _destroy: function _destroy() { 18420 _remove(this._pane); 18421 delete this._pane; 18422 }, 18423 _resetState: function _resetState() { 18424 this._resetStateTimeout = 0; 18425 this._moved = false; 18426 }, 18427 _clearDeferredResetState: function _clearDeferredResetState() { 18428 if (this._resetStateTimeout !== 0) { 18429 clearTimeout(this._resetStateTimeout); 18430 this._resetStateTimeout = 0; 18431 } 18432 }, 18433 _onMouseDown: function _onMouseDown(e) { 18434 if (!e.shiftKey || e.which !== 1 && e.button !== 1) { 18435 return false; 18436 } 18437 18438 // Clear the deferred resetState if it hasn't executed yet, otherwise it 18439 // will interrupt the interaction and orphan a box element in the container. 18440 this._clearDeferredResetState(); 18441 this._resetState(); 18442 disableTextSelection(); 18443 disableImageDrag(); 18444 this._startPoint = this._map.mouseEventToContainerPoint(e); 18445 on(document, { 18446 contextmenu: stop, 18447 mousemove: this._onMouseMove, 18448 mouseup: this._onMouseUp, 18449 keydown: this._onKeyDown 18450 }, this); 18451 }, 18452 _onMouseMove: function _onMouseMove(e) { 18453 if (!this._moved) { 18454 this._moved = true; 18455 this._box = create$1('div', 'leaflet-zoom-box', this._container); 18456 addClass(this._container, 'leaflet-crosshair'); 18457 this._map.fire('boxzoomstart'); 18458 } 18459 this._point = this._map.mouseEventToContainerPoint(e); 18460 var bounds = new Bounds(this._point, this._startPoint), 18461 size = bounds.getSize(); 18462 setPosition(this._box, bounds.min); 18463 this._box.style.width = size.x + 'px'; 18464 this._box.style.height = size.y + 'px'; 18465 }, 18466 _finish: function _finish() { 18467 if (this._moved) { 18468 _remove(this._box); 18469 removeClass(this._container, 'leaflet-crosshair'); 18470 } 18471 enableTextSelection(); 18472 enableImageDrag(); 18473 off(document, { 18474 contextmenu: stop, 18475 mousemove: this._onMouseMove, 18476 mouseup: this._onMouseUp, 18477 keydown: this._onKeyDown 18478 }, this); 18479 }, 18480 _onMouseUp: function _onMouseUp(e) { 18481 if (e.which !== 1 && e.button !== 1) { 18482 return; 18483 } 18484 this._finish(); 18485 if (!this._moved) { 18486 return; 18487 }
vendor: 28,387 bytes, lines 18488-19192
18488 // Postpone to next JS tick so internal click event handling 18489 // still see it as "moved". 18490 this._clearDeferredResetState(); 18491 this._resetStateTimeout = setTimeout(bind(this._resetState, this), 0); 18492 var bounds = new LatLngBounds(this._map.containerPointToLatLng(this._startPoint), this._map.containerPointToLatLng(this._point)); 18493 this._map.fitBounds(bounds).fire('boxzoomend', { 18494 boxZoomBounds: bounds 18495 }); 18496 }, 18497 _onKeyDown: function _onKeyDown(e) { 18498 if (e.keyCode === 27) { 18499 this._finish(); 18500 this._clearDeferredResetState(); 18501 this._resetState(); 18502 } 18503 } 18504 }); 18505 18506 // @section Handlers 18507 // @property boxZoom: Handler 18508 // Box (shift-drag with mouse) zoom handler. 18509 Map.addInitHook('addHandler', 'boxZoom', BoxZoom); 18510 18511 /* 18512 * L.Handler.DoubleClickZoom is used to handle double-click zoom on the map, enabled by default. 18513 */ 18514 18515 // @namespace Map 18516 // @section Interaction Options 18517 18518 Map.mergeOptions({ 18519 // @option doubleClickZoom: Boolean|String = true 18520 // Whether the map can be zoomed in by double clicking on it and 18521 // zoomed out by double clicking while holding shift. If passed 18522 // `'center'`, double-click zoom will zoom to the center of the 18523 // view regardless of where the mouse was. 18524 doubleClickZoom: true 18525 }); 18526 var DoubleClickZoom = Handler.extend({ 18527 addHooks: function addHooks() { 18528 this._map.on('dblclick', this._onDoubleClick, this); 18529 }, 18530 removeHooks: function removeHooks() { 18531 this._map.off('dblclick', this._onDoubleClick, this); 18532 }, 18533 _onDoubleClick: function _onDoubleClick(e) { 18534 var map = this._map, 18535 oldZoom = map.getZoom(), 18536 delta = map.options.zoomDelta, 18537 zoom = e.originalEvent.shiftKey ? oldZoom - delta : oldZoom + delta; 18538 if (map.options.doubleClickZoom === 'center') { 18539 map.setZoom(zoom); 18540 } else { 18541 map.setZoomAround(e.containerPoint, zoom); 18542 } 18543 } 18544 }); 18545 18546 // @section Handlers 18547 // 18548 // Map properties include interaction handlers that allow you to control 18549 // interaction behavior in runtime, enabling or disabling certain features such 18550 // as dragging or touch zoom (see `Handler` methods). For example: 18551 // 18552 // ```js 18553 // map.doubleClickZoom.disable(); 18554 // ``` 18555 // 18556 // @property doubleClickZoom: Handler 18557 // Double click zoom handler. 18558 Map.addInitHook('addHandler', 'doubleClickZoom', DoubleClickZoom); 18559 18560 /* 18561 * L.Handler.MapDrag is used to make the map draggable (with panning inertia), enabled by default. 18562 */ 18563 18564 // @namespace Map 18565 // @section Interaction Options 18566 Map.mergeOptions({ 18567 // @option dragging: Boolean = true 18568 // Whether the map is draggable with mouse/touch or not. 18569 dragging: true, 18570 // @section Panning Inertia Options 18571 // @option inertia: Boolean = * 18572 // If enabled, panning of the map will have an inertia effect where 18573 // the map builds momentum while dragging and continues moving in 18574 // the same direction for some time. Feels especially nice on touch 18575 // devices. Enabled by default. 18576 inertia: true, 18577 // @option inertiaDeceleration: Number = 3000 18578 // The rate with which the inertial movement slows down, in pixels/second². 18579 inertiaDeceleration: 3400, 18580 // px/s^2 18581 18582 // @option inertiaMaxSpeed: Number = Infinity 18583 // Max speed of the inertial movement, in pixels/second. 18584 inertiaMaxSpeed: Infinity, 18585 // px/s 18586 18587 // @option easeLinearity: Number = 0.2 18588 easeLinearity: 0.2, 18589 // TODO refactor, move to CRS 18590 // @option worldCopyJump: Boolean = false 18591 // With this option enabled, the map tracks when you pan to another "copy" 18592 // of the world and seamlessly jumps to the original one so that all overlays 18593 // like markers and vector layers are still visible. 18594 worldCopyJump: false, 18595 // @option maxBoundsViscosity: Number = 0.0 18596 // If `maxBounds` is set, this option will control how solid the bounds 18597 // are when dragging the map around. The default value of `0.0` allows the 18598 // user to drag outside the bounds at normal speed, higher values will 18599 // slow down map dragging outside bounds, and `1.0` makes the bounds fully 18600 // solid, preventing the user from dragging outside the bounds. 18601 maxBoundsViscosity: 0.0 18602 }); 18603 var Drag = Handler.extend({ 18604 addHooks: function addHooks() { 18605 if (!this._draggable) { 18606 var map = this._map; 18607 this._draggable = new Draggable(map._mapPane, map._container); 18608 this._draggable.on({ 18609 dragstart: this._onDragStart, 18610 drag: this._onDrag, 18611 dragend: this._onDragEnd 18612 }, this); 18613 this._draggable.on('predrag', this._onPreDragLimit, this); 18614 if (map.options.worldCopyJump) { 18615 this._draggable.on('predrag', this._onPreDragWrap, this); 18616 map.on('zoomend', this._onZoomEnd, this); 18617 map.whenReady(this._onZoomEnd, this); 18618 } 18619 } 18620 addClass(this._map._container, 'leaflet-grab leaflet-touch-drag'); 18621 this._draggable.enable(); 18622 this._positions = []; 18623 this._times = []; 18624 }, 18625 removeHooks: function removeHooks() { 18626 removeClass(this._map._container, 'leaflet-grab'); 18627 removeClass(this._map._container, 'leaflet-touch-drag'); 18628 this._draggable.disable(); 18629 }, 18630 moved: function moved() { 18631 return this._draggable && this._draggable._moved; 18632 }, 18633 moving: function moving() { 18634 return this._draggable && this._draggable._moving; 18635 }, 18636 _onDragStart: function _onDragStart() { 18637 var map = this._map; 18638 map._stop(); 18639 if (this._map.options.maxBounds && this._map.options.maxBoundsViscosity) { 18640 var bounds = toLatLngBounds(this._map.options.maxBounds); 18641 this._offsetLimit = toBounds(this._map.latLngToContainerPoint(bounds.getNorthWest()).multiplyBy(-1), this._map.latLngToContainerPoint(bounds.getSouthEast()).multiplyBy(-1).add(this._map.getSize())); 18642 this._viscosity = Math.min(1.0, Math.max(0.0, this._map.options.maxBoundsViscosity)); 18643 } else { 18644 this._offsetLimit = null; 18645 } 18646 map.fire('movestart').fire('dragstart'); 18647 if (map.options.inertia) { 18648 this._positions = []; 18649 this._times = []; 18650 } 18651 }, 18652 _onDrag: function _onDrag(e) { 18653 if (this._map.options.inertia) { 18654 var time = this._lastTime = +new Date(), 18655 pos = this._lastPos = this._draggable._absPos || this._draggable._newPos; 18656 this._positions.push(pos); 18657 this._times.push(time); 18658 this._prunePositions(time); 18659 } 18660 this._map.fire('move', e).fire('drag', e); 18661 }, 18662 _prunePositions: function _prunePositions(time) { 18663 while (this._positions.length > 1 && time - this._times[0] > 50) { 18664 this._positions.shift(); 18665 this._times.shift(); 18666 } 18667 }, 18668 _onZoomEnd: function _onZoomEnd() { 18669 var pxCenter = this._map.getSize().divideBy(2), 18670 pxWorldCenter = this._map.latLngToLayerPoint([0, 0]); 18671 this._initialWorldOffset = pxWorldCenter.subtract(pxCenter).x; 18672 this._worldWidth = this._map.getPixelWorldBounds().getSize().x; 18673 }, 18674 _viscousLimit: function _viscousLimit(value, threshold) { 18675 return value - (value - threshold) * this._viscosity; 18676 }, 18677 _onPreDragLimit: function _onPreDragLimit() { 18678 if (!this._viscosity || !this._offsetLimit) { 18679 return; 18680 } 18681 var offset = this._draggable._newPos.subtract(this._draggable._startPos); 18682 var limit = this._offsetLimit; 18683 if (offset.x < limit.min.x) { 18684 offset.x = this._viscousLimit(offset.x, limit.min.x); 18685 } 18686 if (offset.y < limit.min.y) { 18687 offset.y = this._viscousLimit(offset.y, limit.min.y); 18688 } 18689 if (offset.x > limit.max.x) { 18690 offset.x = this._viscousLimit(offset.x, limit.max.x); 18691 } 18692 if (offset.y > limit.max.y) { 18693 offset.y = this._viscousLimit(offset.y, limit.max.y); 18694 } 18695 this._draggable._newPos = this._draggable._startPos.add(offset); 18696 }, 18697 _onPreDragWrap: function _onPreDragWrap() { 18698 // TODO refactor to be able to adjust map pane position after zoom 18699 var worldWidth = this._worldWidth, 18700 halfWidth = Math.round(worldWidth / 2), 18701 dx = this._initialWorldOffset, 18702 x = this._draggable._newPos.x, 18703 newX1 = (x - halfWidth + dx) % worldWidth + halfWidth - dx, 18704 newX2 = (x + halfWidth + dx) % worldWidth - halfWidth - dx, 18705 newX = Math.abs(newX1 + dx) < Math.abs(newX2 + dx) ? newX1 : newX2; 18706 this._draggable._absPos = this._draggable._newPos.clone(); 18707 this._draggable._newPos.x = newX; 18708 }, 18709 _onDragEnd: function _onDragEnd(e) { 18710 var map = this._map, 18711 options = map.options, 18712 noInertia = !options.inertia || e.noInertia || this._times.length < 2; 18713 map.fire('dragend', e); 18714 if (noInertia) { 18715 map.fire('moveend'); 18716 } else { 18717 this._prunePositions(+new Date()); 18718 var direction = this._lastPos.subtract(this._positions[0]), 18719 duration = (this._lastTime - this._times[0]) / 1000, 18720 ease = options.easeLinearity, 18721 speedVector = direction.multiplyBy(ease / duration), 18722 speed = speedVector.distanceTo([0, 0]), 18723 limitedSpeed = Math.min(options.inertiaMaxSpeed, speed), 18724 limitedSpeedVector = speedVector.multiplyBy(limitedSpeed / speed), 18725 decelerationDuration = limitedSpeed / (options.inertiaDeceleration * ease), 18726 offset = limitedSpeedVector.multiplyBy(-decelerationDuration / 2).round(); 18727 if (!offset.x && !offset.y) { 18728 map.fire('moveend'); 18729 } else { 18730 offset = map._limitOffset(offset, map.options.maxBounds); 18731 requestAnimFrame(function () { 18732 map.panBy(offset, { 18733 duration: decelerationDuration, 18734 easeLinearity: ease, 18735 noMoveStart: true, 18736 animate: true 18737 }); 18738 }); 18739 } 18740 } 18741 } 18742 }); 18743 18744 // @section Handlers 18745 // @property dragging: Handler 18746 // Map dragging handler (by both mouse and touch). 18747 Map.addInitHook('addHandler', 'dragging', Drag); 18748 18749 /* 18750 * L.Map.Keyboard is handling keyboard interaction with the map, enabled by default. 18751 */ 18752 18753 // @namespace Map 18754 // @section Keyboard Navigation Options 18755 Map.mergeOptions({ 18756 // @option keyboard: Boolean = true 18757 // Makes the map focusable and allows users to navigate the map with keyboard 18758 // arrows and `+`/`-` keys. 18759 keyboard: true, 18760 // @option keyboardPanDelta: Number = 80 18761 // Amount of pixels to pan when pressing an arrow key. 18762 keyboardPanDelta: 80 18763 }); 18764 var Keyboard = Handler.extend({ 18765 keyCodes: { 18766 left: [37], 18767 right: [39], 18768 down: [40], 18769 up: [38], 18770 zoomIn: [187, 107, 61, 171], 18771 zoomOut: [189, 109, 54, 173] 18772 }, 18773 initialize: function initialize(map) { 18774 this._map = map; 18775 this._setPanDelta(map.options.keyboardPanDelta); 18776 this._setZoomDelta(map.options.zoomDelta); 18777 }, 18778 addHooks: function addHooks() { 18779 var container = this._map._container; 18780 18781 // make the container focusable by tabbing 18782 if (container.tabIndex <= 0) { 18783 container.tabIndex = '0'; 18784 } 18785 on(container, { 18786 focus: this._onFocus, 18787 blur: this._onBlur, 18788 mousedown: this._onMouseDown 18789 }, this); 18790 this._map.on({ 18791 focus: this._addHooks, 18792 blur: this._removeHooks 18793 }, this); 18794 }, 18795 removeHooks: function removeHooks() { 18796 this._removeHooks(); 18797 off(this._map._container, { 18798 focus: this._onFocus, 18799 blur: this._onBlur, 18800 mousedown: this._onMouseDown 18801 }, this); 18802 this._map.off({ 18803 focus: this._addHooks, 18804 blur: this._removeHooks 18805 }, this); 18806 }, 18807 _onMouseDown: function _onMouseDown() { 18808 if (this._focused) { 18809 return; 18810 } 18811 var body = document.body, 18812 docEl = document.documentElement, 18813 top = body.scrollTop || docEl.scrollTop, 18814 left = body.scrollLeft || docEl.scrollLeft; 18815 this._map._container.focus(); 18816 window.scrollTo(left, top); 18817 }, 18818 _onFocus: function _onFocus() { 18819 this._focused = true; 18820 this._map.fire('focus'); 18821 }, 18822 _onBlur: function _onBlur() { 18823 this._focused = false; 18824 this._map.fire('blur'); 18825 }, 18826 _setPanDelta: function _setPanDelta(panDelta) { 18827 var keys = this._panKeys = {}, 18828 codes = this.keyCodes, 18829 i, 18830 len; 18831 for (i = 0, len = codes.left.length; i < len; i++) { 18832 keys[codes.left[i]] = [-1 * panDelta, 0]; 18833 } 18834 for (i = 0, len = codes.right.length; i < len; i++) { 18835 keys[codes.right[i]] = [panDelta, 0]; 18836 } 18837 for (i = 0, len = codes.down.length; i < len; i++) { 18838 keys[codes.down[i]] = [0, panDelta]; 18839 } 18840 for (i = 0, len = codes.up.length; i < len; i++) { 18841 keys[codes.up[i]] = [0, -1 * panDelta]; 18842 } 18843 }, 18844 _setZoomDelta: function _setZoomDelta(zoomDelta) { 18845 var keys = this._zoomKeys = {}, 18846 codes = this.keyCodes, 18847 i, 18848 len; 18849 for (i = 0, len = codes.zoomIn.length; i < len; i++) { 18850 keys[codes.zoomIn[i]] = zoomDelta; 18851 } 18852 for (i = 0, len = codes.zoomOut.length; i < len; i++) { 18853 keys[codes.zoomOut[i]] = -zoomDelta; 18854 } 18855 }, 18856 _addHooks: function _addHooks() { 18857 on(document, 'keydown', this._onKeyDown, this); 18858 }, 18859 _removeHooks: function _removeHooks() { 18860 off(document, 'keydown', this._onKeyDown, this); 18861 }, 18862 _onKeyDown: function _onKeyDown(e) { 18863 if (e.altKey || e.ctrlKey || e.metaKey) { 18864 return; 18865 } 18866 var key = e.keyCode, 18867 map = this._map, 18868 offset; 18869 if (key in this._panKeys) { 18870 if (!map._panAnim || !map._panAnim._inProgress) { 18871 offset = this._panKeys[key]; 18872 if (e.shiftKey) { 18873 offset = toPoint(offset).multiplyBy(3); 18874 } 18875 if (map.options.maxBounds) { 18876 offset = map._limitOffset(toPoint(offset), map.options.maxBounds); 18877 } 18878 if (map.options.worldCopyJump) { 18879 var newLatLng = map.wrapLatLng(map.unproject(map.project(map.getCenter()).add(offset))); 18880 map.panTo(newLatLng); 18881 } else { 18882 map.panBy(offset); 18883 } 18884 } 18885 } else if (key in this._zoomKeys) { 18886 map.setZoom(map.getZoom() + (e.shiftKey ? 3 : 1) * this._zoomKeys[key]); 18887 } else if (key === 27 && map._popup && map._popup.options.closeOnEscapeKey) { 18888 map.closePopup(); 18889 } else { 18890 return; 18891 } 18892 stop(e); 18893 } 18894 }); 18895 18896 // @section Handlers 18897 // @section Handlers 18898 // @property keyboard: Handler 18899 // Keyboard navigation handler. 18900 Map.addInitHook('addHandler', 'keyboard', Keyboard); 18901 18902 /* 18903 * L.Handler.ScrollWheelZoom is used by L.Map to enable mouse scroll wheel zoom on the map. 18904 */ 18905 18906 // @namespace Map 18907 // @section Interaction Options 18908 Map.mergeOptions({ 18909 // @section Mouse wheel options 18910 // @option scrollWheelZoom: Boolean|String = true 18911 // Whether the map can be zoomed by using the mouse wheel. If passed `'center'`, 18912 // it will zoom to the center of the view regardless of where the mouse was. 18913 scrollWheelZoom: true, 18914 // @option wheelDebounceTime: Number = 40 18915 // Limits the rate at which a wheel can fire (in milliseconds). By default 18916 // user can't zoom via wheel more often than once per 40 ms. 18917 wheelDebounceTime: 40, 18918 // @option wheelPxPerZoomLevel: Number = 60 18919 // How many scroll pixels (as reported by [L.DomEvent.getWheelDelta](#domevent-getwheeldelta)) 18920 // mean a change of one full zoom level. Smaller values will make wheel-zooming 18921 // faster (and vice versa). 18922 wheelPxPerZoomLevel: 60 18923 }); 18924 var ScrollWheelZoom = Handler.extend({ 18925 addHooks: function addHooks() { 18926 on(this._map._container, 'wheel', this._onWheelScroll, this); 18927 this._delta = 0; 18928 }, 18929 removeHooks: function removeHooks() { 18930 off(this._map._container, 'wheel', this._onWheelScroll, this); 18931 }, 18932 _onWheelScroll: function _onWheelScroll(e) { 18933 var delta = getWheelDelta(e); 18934 var debounce = this._map.options.wheelDebounceTime; 18935 this._delta += delta; 18936 this._lastMousePos = this._map.mouseEventToContainerPoint(e); 18937 if (!this._startTime) { 18938 this._startTime = +new Date(); 18939 } 18940 var left = Math.max(debounce - (+new Date() - this._startTime), 0); 18941 clearTimeout(this._timer); 18942 this._timer = setTimeout(bind(this._performZoom, this), left); 18943 stop(e); 18944 }, 18945 _performZoom: function _performZoom() { 18946 var map = this._map, 18947 zoom = map.getZoom(), 18948 snap = this._map.options.zoomSnap || 0; 18949 map._stop(); // stop panning and fly animations if any 18950 18951 // map the delta with a sigmoid function to -4..4 range leaning on -1..1 18952 var d2 = this._delta / (this._map.options.wheelPxPerZoomLevel * 4), 18953 d3 = 4 * Math.log(2 / (1 + Math.exp(-Math.abs(d2)))) / Math.LN2, 18954 d4 = snap ? Math.ceil(d3 / snap) * snap : d3, 18955 delta = map._limitZoom(zoom + (this._delta > 0 ? d4 : -d4)) - zoom; 18956 this._delta = 0; 18957 this._startTime = null; 18958 if (!delta) { 18959 return; 18960 } 18961 if (map.options.scrollWheelZoom === 'center') { 18962 map.setZoom(zoom + delta); 18963 } else { 18964 map.setZoomAround(this._lastMousePos, zoom + delta); 18965 } 18966 } 18967 }); 18968 18969 // @section Handlers 18970 // @property scrollWheelZoom: Handler 18971 // Scroll wheel zoom handler. 18972 Map.addInitHook('addHandler', 'scrollWheelZoom', ScrollWheelZoom); 18973 18974 /* 18975 * L.Map.TapHold is used to simulate `contextmenu` event on long hold, 18976 * which otherwise is not fired by mobile Safari. 18977 */ 18978 18979 var tapHoldDelay = 600; 18980 18981 // @namespace Map 18982 // @section Interaction Options 18983 Map.mergeOptions({ 18984 // @section Touch interaction options 18985 // @option tapHold: Boolean 18986 // Enables simulation of `contextmenu` event, default is `true` for mobile Safari. 18987 tapHold: Browser.touchNative && Browser.safari && Browser.mobile, 18988 // @option tapTolerance: Number = 15 18989 // The max number of pixels a user can shift his finger during touch 18990 // for it to be considered a valid tap. 18991 tapTolerance: 15 18992 }); 18993 var TapHold = Handler.extend({ 18994 addHooks: function addHooks() { 18995 on(this._map._container, 'touchstart', this._onDown, this); 18996 }, 18997 removeHooks: function removeHooks() { 18998 off(this._map._container, 'touchstart', this._onDown, this); 18999 }, 19000 _onDown: function _onDown(e) { 19001 clearTimeout(this._holdTimeout); 19002 if (e.touches.length !== 1) { 19003 return; 19004 } 19005 var first = e.touches[0]; 19006 this._startPos = this._newPos = new Point(first.clientX, first.clientY); 19007 this._holdTimeout = setTimeout(bind(function () { 19008 this._cancel(); 19009 if (!this._isTapValid()) { 19010 return; 19011 } 19012 19013 // prevent simulated mouse events https://w3c.github.io/touch-events/#mouse-events 19014 on(document, 'touchend', preventDefault); 19015 on(document, 'touchend touchcancel', this._cancelClickPrevent); 19016 this._simulateEvent('contextmenu', first); 19017 }, this), tapHoldDelay); 19018 on(document, 'touchend touchcancel contextmenu', this._cancel, this); 19019 on(document, 'touchmove', this._onMove, this); 19020 }, 19021 _cancelClickPrevent: function cancelClickPrevent() { 19022 off(document, 'touchend', preventDefault); 19023 off(document, 'touchend touchcancel', cancelClickPrevent); 19024 }, 19025 _cancel: function _cancel() { 19026 clearTimeout(this._holdTimeout); 19027 off(document, 'touchend touchcancel contextmenu', this._cancel, this); 19028 off(document, 'touchmove', this._onMove, this); 19029 }, 19030 _onMove: function _onMove(e) { 19031 var first = e.touches[0]; 19032 this._newPos = new Point(first.clientX, first.clientY); 19033 }, 19034 _isTapValid: function _isTapValid() { 19035 return this._newPos.distanceTo(this._startPos) <= this._map.options.tapTolerance; 19036 }, 19037 _simulateEvent: function _simulateEvent(type, e) { 19038 var simulatedEvent = new MouseEvent(type, { 19039 bubbles: true, 19040 cancelable: true, 19041 view: window, 19042 // detail: 1, 19043 screenX: e.screenX, 19044 screenY: e.screenY, 19045 clientX: e.clientX, 19046 clientY: e.clientY 19047 // button: 2, 19048 // buttons: 2 19049 }); 19050 simulatedEvent._simulated = true; 19051 e.target.dispatchEvent(simulatedEvent); 19052 } 19053 }); 19054 19055 // @section Handlers 19056 // @property tapHold: Handler 19057 // Long tap handler to simulate `contextmenu` event (useful in mobile Safari). 19058 Map.addInitHook('addHandler', 'tapHold', TapHold); 19059 19060 /* 19061 * L.Handler.TouchZoom is used by L.Map to add pinch zoom on supported mobile browsers. 19062 */ 19063 19064 // @namespace Map 19065 // @section Interaction Options 19066 Map.mergeOptions({ 19067 // @section Touch interaction options 19068 // @option touchZoom: Boolean|String = * 19069 // Whether the map can be zoomed by touch-dragging with two fingers. If 19070 // passed `'center'`, it will zoom to the center of the view regardless of 19071 // where the touch events (fingers) were. Enabled for touch-capable web 19072 // browsers. 19073 touchZoom: Browser.touch, 19074 // @option bounceAtZoomLimits: Boolean = true 19075 // Set it to false if you don't want the map to zoom beyond min/max zoom 19076 // and then bounce back when pinch-zooming. 19077 bounceAtZoomLimits: true 19078 }); 19079 var TouchZoom = Handler.extend({ 19080 addHooks: function addHooks() { 19081 addClass(this._map._container, 'leaflet-touch-zoom'); 19082 on(this._map._container, 'touchstart', this._onTouchStart, this); 19083 }, 19084 removeHooks: function removeHooks() { 19085 removeClass(this._map._container, 'leaflet-touch-zoom'); 19086 off(this._map._container, 'touchstart', this._onTouchStart, this); 19087 }, 19088 _onTouchStart: function _onTouchStart(e) { 19089 var map = this._map; 19090 if (!e.touches || e.touches.length !== 2 || map._animatingZoom || this._zooming) { 19091 return; 19092 } 19093 var p1 = map.mouseEventToContainerPoint(e.touches[0]), 19094 p2 = map.mouseEventToContainerPoint(e.touches[1]); 19095 this._centerPoint = map.getSize()._divideBy(2); 19096 this._startLatLng = map.containerPointToLatLng(this._centerPoint); 19097 if (map.options.touchZoom !== 'center') { 19098 this._pinchStartLatLng = map.containerPointToLatLng(p1.add(p2)._divideBy(2)); 19099 } 19100 this._startDist = p1.distanceTo(p2); 19101 this._startZoom = map.getZoom(); 19102 this._moved = false; 19103 this._zooming = true; 19104 map._stop(); 19105 on(document, 'touchmove', this._onTouchMove, this); 19106 on(document, 'touchend touchcancel', this._onTouchEnd, this); 19107 preventDefault(e); 19108 }, 19109 _onTouchMove: function _onTouchMove(e) { 19110 if (!e.touches || e.touches.length !== 2 || !this._zooming) { 19111 return; 19112 } 19113 var map = this._map, 19114 p1 = map.mouseEventToContainerPoint(e.touches[0]), 19115 p2 = map.mouseEventToContainerPoint(e.touches[1]), 19116 scale = p1.distanceTo(p2) / this._startDist; 19117 this._zoom = map.getScaleZoom(scale, this._startZoom); 19118 if (!map.options.bounceAtZoomLimits && (this._zoom < map.getMinZoom() && scale < 1 || this._zoom > map.getMaxZoom() && scale > 1)) { 19119 this._zoom = map._limitZoom(this._zoom); 19120 } 19121 if (map.options.touchZoom === 'center') { 19122 this._center = this._startLatLng; 19123 if (scale === 1) { 19124 return; 19125 } 19126 } else { 19127 // Get delta from pinch to center, so centerLatLng is delta applied to initial pinchLatLng 19128 var delta = p1._add(p2)._divideBy(2)._subtract(this._centerPoint); 19129 if (scale === 1 && delta.x === 0 && delta.y === 0) { 19130 return; 19131 } 19132 this._center = map.unproject(map.project(this._pinchStartLatLng, this._zoom).subtract(delta), this._zoom); 19133 } 19134 if (!this._moved) { 19135 map._moveStart(true, false); 19136 this._moved = true; 19137 } 19138 cancelAnimFrame(this._animRequest); 19139 var moveFn = bind(map._move, map, this._center, this._zoom, { 19140 pinch: true, 19141 round: false 19142 }, undefined); 19143 this._animRequest = requestAnimFrame(moveFn, this, true); 19144 preventDefault(e); 19145 }, 19146 _onTouchEnd: function _onTouchEnd() { 19147 if (!this._moved || !this._zooming) { 19148 this._zooming = false; 19149 return; 19150 } 19151 this._zooming = false; 19152 cancelAnimFrame(this._animRequest); 19153 off(document, 'touchmove', this._onTouchMove, this); 19154 off(document, 'touchend touchcancel', this._onTouchEnd, this); 19155 19156 // Pinch updates GridLayers' levels only when zoomSnap is off, so zoomSnap becomes noUpdate. 19157 if (this._map.options.zoomAnimation) { 19158 this._map._animateZoom(this._center, this._map._limitZoom(this._zoom), true, this._map.options.zoomSnap); 19159 } else { 19160 this._map._resetView(this._center, this._map._limitZoom(this._zoom)); 19161 } 19162 } 19163 }); 19164 19165 // @section Handlers 19166 // @property touchZoom: Handler 19167 // Touch zoom handler. 19168 Map.addInitHook('addHandler', 'touchZoom', TouchZoom); 19169 Map.BoxZoom = BoxZoom; 19170 Map.DoubleClickZoom = DoubleClickZoom; 19171 Map.Drag = Drag; 19172 Map.Keyboard = Keyboard; 19173 Map.ScrollWheelZoom = ScrollWheelZoom; 19174 Map.TapHold = TapHold; 19175 Map.TouchZoom = TouchZoom; 19176 exports.Bounds = Bounds; 19177 exports.Browser = Browser; 19178 exports.CRS = CRS; 19179 exports.Canvas = Canvas; 19180 exports.Circle = Circle; 19181 exports.CircleMarker = CircleMarker; 19182 exports.Class = Class; 19183 exports.Control = Control; 19184 exports.DivIcon = DivIcon; 19185 exports.DivOverlay = DivOverlay; 19186 exports.DomEvent = DomEvent; 19187 exports.DomUtil = DomUtil; 19188 exports.Draggable = Draggable; 19189 exports.Evented = Evented; 19190 exports.FeatureGroup = FeatureGroup; 19191 exports.GeoJSON = GeoJSON; 19192 exports.GridLayer = GridLayer;
19193 exports.Handler = Handler; 19194 exports.Icon = Icon; 19195 exports.ImageOverlay = ImageOverlay; 19196 exports.LatLng = LatLng; 19197 exports.LatLngBounds = LatLngBounds; 19198 exports.Layer = Layer; 19199 exports.LayerGroup = LayerGroup; 19200 exports.LineUtil = LineUtil; 19201 exports.Map = Map; 19202 exports.Marker = Marker; 19203 exports.Mixin = Mixin; 19204 exports.Path = Path; 19205 exports.Point = Point; 19206 exports.PolyUtil = PolyUtil; 19207 exports.Polygon = Polygon; 19208 exports.Polyline = Polyline; 19209 exports.Popup = Popup; 19210 exports.PosAnimation = PosAnimation; 19211 exports.Projection = index; 19212 exports.Rectangle = Rectangle; 19213 exports.Renderer = Renderer; 19214 exports.SVG = SVG; 19215 exports.SVGOverlay = SVGOverlay; 19216 exports.TileLayer = TileLayer; 19217 exports.Tooltip = Tooltip; 19218 exports.Transformation = Transformation; 19219 exports.Util = Util; 19220 exports.VideoOverlay = VideoOverlay; 19221 exports.bind = bind; 19222 exports.bounds = toBounds; 19223 exports.canvas = canvas; 19224 exports.circle = circle; 19225 exports.circleMarker = circleMarker; 19226 exports.control = control; 19227 exports.divIcon = divIcon; 19228 exports.extend = extend; 19229 exports.featureGroup = featureGroup; 19230 exports.geoJSON = geoJSON; 19231 exports.geoJson = geoJson; 19232 exports.gridLayer = gridLayer; 19233 exports.icon = icon; 19234 exports.imageOverlay = imageOverlay; 19235 exports.latLng = toLatLng; 19236 exports.latLngBounds = toLatLngBounds; 19237 exports.layerGroup = layerGroup; 19238 exports.map = createMap; 19239 exports.marker = marker; 19240 exports.point = toPoint; 19241 exports.polygon = polygon; 19242 exports.polyline = polyline; 19243 exports.popup = popup; 19244 exports.rectangle = rectangle; 19245 exports.setOptions = setOptions; 19246 exports.stamp = stamp; 19247 exports.svg = svg; 19248 exports.svgOverlay = svgOverlay; 19249 exports.tileLayer = tileLayer; 19250 exports.tooltip = tooltip; 19251 exports.transformation = toTransformation; 19252 exports.version = version; 19253 exports.videoOverlay = videoOverlay; 19254 var oldL = window.L; 19255 exports.noConflict = function () { 19256 window.L = oldL; 19257 return this; 19258 }; 19259 // Always export us to window global (see #2364) 19260 window.L = exports; 19261 }); 19262 })(leafletSrc, leafletSrc.exports); 19263 var L$1 = leafletSrc.exports; 19264 19265 var leafletGestureHandling_min = {exports: {}}; 19266 19267 (function (module, exports) { 19268 !function (a, t) { 19269 t(exports) ; 19270 }(commonjsGlobal, function (a) { 19271 19272 var o = { 19273 ar: { 19274 touch: "استخد٠إصبعÙÙ ÙØªØØ±ÙÙ Ø§ÙØ®Ø±Ùطة", 19275 scroll: "âØ§Ø³ØªØ®Ø¯Ù ctrl + scroll ÙØªØµØºÙر/ØªÙØ¨Ùر Ø§ÙØ®Ø±Ùطة", 19276 scrollMac: "ÙÙ ÙÙ٠استخدا٠â + Ø§ÙØªÙ Ø±ÙØ± ÙØªÙØ¨ÙØ±/ØªØµØºÙØ± Ø§ÙØ®Ø±Ùطة" 19277 }, 19278 bg: { 19279 touch: "ÐзползвайÑе два пÑÑÑÑа, за да пÑемеÑÑиÑе каÑÑаÑа", 19280 scroll: "ÐадÑÑжÑе бÑÑона Ctrl наÑиÑнаÑ, докаÑо пÑевÑÑÑаÑе, за да пÑомениÑе маÑаба на каÑÑаÑа", 19281 scrollMac: "ÐадÑÑжÑе бÑÑона â наÑиÑнаÑ, докаÑо пÑевÑÑÑаÑе, за да пÑомениÑе маÑаба на каÑÑаÑа" 19282 }, 19283 bn: { 19284 touch: "মানà¦à¦¿à¦¤à§à¦°à¦à¦¿à¦à§ সরাতৠদà§à¦à¦¿ à¦à¦à§à¦à§à¦² বà§à¦¯à¦¬à¦¹à¦¾à¦° à¦à¦°à§à¦¨", 19285 scroll: "মà§à¦¯à¦¾à¦ª à¦à§à¦® à¦à¦°à¦¤à§ ctrl + scroll বà§à¦¯à¦¬à¦¹à¦¾à¦° à¦à¦°à§à¦¨", 19286 scrollMac: "মà§à¦¯à¦¾à¦ªà§ à¦à§à¦® à¦à¦°à¦¤à§ â বà§à¦¤à¦¾à¦® à¦à¦¿à¦ªà§ সà§à¦à§à¦°à¦² à¦à¦°à§à¦¨" 19287 }, 19288 ca: { 19289 touch: "Fes servir dos dits per moure el mapa", 19290 scroll: "Prem la tecla Control mentre et desplaces per apropar i allunyar el mapa", 19291 scrollMac: "Prem la tecla â mentre et desplaces per apropar i allunyar el mapa" 19292 }, 19293 cs: { 19294 touch: "K posunutà mapy použijte dva prsty", 19295 scroll: "Velikost zobrazenà mapy zmÄÅte podrženÃm klávesy Ctrl a posouvánÃm koleÄka myÅ¡i", 19296 scrollMac: "Velikost zobrazenà mapy zmÄnÃte podrženÃm klávesy â a posunutÃm koleÄka myÅ¡i / touchpadu" 19297 }, 19298 da: { 19299 touch: "Brug to fingre til at flytte kortet", 19300 scroll: "Brug ctrl + rullefunktionen til at zoome ind og ud pÃ¥ kortet", 19301 scrollMac: "Brug â + rullefunktionen til at zoome ind og ud pÃ¥ kortet" 19302 }, 19303 de: { 19304 touch: "Verschieben der Karte mit zwei Fingern", 19305 scroll: "Verwende Strg+Scrollen zum Zoomen der Karte", 19306 scrollMac: "â" 19307 }, 19308 el: { 19309 touch: "ΧÏηÏιμοÏοιήÏÏε δÏο δάÏÏÏ Î»Î± για μεÏακίνηÏη ÏÏον ÏάÏÏη", 19310 scroll: "ΧÏηÏιμοÏοιήÏÏε Ïο ÏλήκÏÏο Ctrl και κÏλιÏη, για να μεγεθÏνεÏε Ïον ÏάÏÏη", 19311 scrollMac: "ΧÏηÏιμοÏοιήÏÏε Ïο ÏλήκÏÏο â + κÏλιÏη για εÏÏίαÏη ÏÏον ÏάÏÏη" 19312 }, 19313 en: { 19314 touch: "Use two fingers to move the map", 19315 scroll: "Use ctrl + scroll to zoom the map", 19316 scrollMac: "Use â + scroll to zoom the map" 19317 }, 19318 "en-AU": { 19319 touch: "Use two fingers to move the map", 19320 scroll: "Use ctrl + scroll to zoom the map", 19321 scrollMac: "Use â + scroll to zoom the map" 19322 }, 19323 "en-GB": { 19324 touch: "Use two fingers to move the map", 19325 scroll: "Use ctrl + scroll to zoom the map", 19326 scrollMac: "Use â + scroll to zoom the map" 19327 }, 19328 es: { 19329 touch: "Para mover el mapa, utiliza dos dedos", 19330 scroll: "Mantén pulsada la tecla Ctrl mientras te desplazas para acercar o alejar el mapa", 19331 scrollMac: "Mantén pulsada la tecla â mientras te desplazas para acercar o alejar el mapa" 19332 }, 19333 eu: { 19334 touch: "Erabili bi hatz mapa mugitzeko", 19335 scroll: "Mapan zooma aplikatzeko, sakatu Ktrl eta egin gora edo behera", 19336 scrollMac: "Eduki sakatuta â eta egin gora eta behera mapa handitu eta txikitzeko" 19337 }, 19338 fa: { 19339 touch: "Ø¨Ø±Ø§Û ØØ±Ú©Øª داد٠ÙÙØ´Ù از د٠اÙگشت Ø§Ø³ØªÙØ§Ø¯Ù Ú©ÙÛØ¯.", 19340 scroll: "âØ¨Ø±Ø§Û Ø¨Ø²Ø±Ú¯âÙ٠اÛÛ ÙÙØ´Ù از ctrl + scroll Ø§Ø³ØªÙØ§Ø¯Ù Ú©ÙÛØ¯", 19341 scrollMac: "Ø¨Ø±Ø§Û Ø¨Ø²Ø±Ú¯âÙ٠اÛÛ ÙÙØ´ÙØ Ø§Ø² â + Ù¾ÛÙ Ø§ÛØ´ Ø§Ø³ØªÙØ§Ø¯Ù Ú©ÙÛØ¯." 19342 }, 19343 fi: { 19344 touch: "Siirrä karttaa kahdella sormella.",
19345 scroll: "Zoomaa karttaa painamalla Ctrl-painiketta ja vierittämällä.", 19346 scrollMac: "Zoomaa karttaa pitämällä painike â painettuna ja vierittämällä." 19347 }, 19348 fil: { 19349 touch: "Gumamit ng dalawang daliri upang iusog ang mapa", 19350 scroll: "Gamitin ang ctrl + scroll upang i-zoom ang mapa", 19351 scrollMac: "Gamitin ang â + scroll upang i-zoom ang mapa" 19352 }, 19353 fr: { 19354 touch: "Utilisez deux doigts pour déplacer la carte", 19355 scroll: "Vous pouvez zoomer sur la carte à l'aide de CTRL+Molette de défilement", 19356 scrollMac: "Vous pouvez zoomer sur la carte à l'aide de â+Molette de défilement" 19357 }, 19358 gl: { 19359 touch: "Utiliza dous dedos para mover o mapa", 19360 scroll: "Preme Ctrl mentres te desprazas para ampliar o mapa", 19361 scrollMac: "Preme â e desprázate para ampliar o mapa" 19362 }, 19363 gu: { 19364 touch: "નàªàª¶à« àªàª¸à«àª¡àªµàª¾ બૠàªàªàªàª³à«àªàª¨à« àªàªªàª¯à«àª àªàª°à«", 19365 scroll: "નàªàª¶àª¾àª¨à« àªà«àª® àªàª°àªµàª¾ માàªà« ctrl + સà«àªà«àª°à«àª²àª¨à« àªàªªàª¯à«àª àªàª°à«", 19366 scrollMac: "નàªàª¶àª¾àª¨à« àªà«àª® àªàª°àªµàª¾ â + સà«àªà«àª°à«àª²àª¨à« àªàªªàª¯à«àª àªàª°à«" 19367 }, 19368 hi: { 19369 touch: "मà¥à¤ª à¤à¤ à¤à¤à¤¹ सॠदà¥à¤¸à¤°à¥ à¤à¤à¤¹ लॠà¤à¤¾à¤¨à¥ à¤à¥ लिठदॠà¤à¤à¤à¤²à¤¿à¤¯à¥à¤ à¤à¤¾ à¤à¤¸à¥à¤¤à¥à¤®à¤¾à¤² à¤à¤°à¥à¤", 19370 scroll: "मà¥à¤ª à¤à¥ à¤à¤¼à¥à¤® à¤à¤°à¤¨à¥ à¤à¥ लिठctrl + सà¥à¤à¥à¤°à¥à¤² à¤à¤¾ à¤à¤ªà¤¯à¥à¤ à¤à¤°à¥à¤", 19371 scrollMac: "मà¥à¤ª à¤à¥ à¤à¤¼à¥à¤® à¤à¤°à¤¨à¥ à¤à¥ लिठâ + सà¥à¤à¥à¤°à¥à¤² à¤à¤¾ à¤à¤ªà¤¯à¥à¤ à¤à¤°à¥à¤" 19372 }, 19373 hr: { 19374 touch: "PomiÄite kartu pomoÄu dva prsta", 19375 scroll: "Upotrijebite Ctrl i klizaÄ miÅ¡a da biste zumirali kartu", 19376 scrollMac: "Upotrijebite gumb â dok se pomiÄete za zumiranje karte" 19377 }, 19378 hu: { 19379 touch: "Két ujjal mozgassa a térképet", 19380 scroll: "A térkép a ctrl + görgetés használatával nagyÃtható", 19381 scrollMac: "A térkép a â + görgetés használatával nagyÃtható" 19382 }, 19383 id: { 19384 touch: "Gunakan dua jari untuk menggerakkan peta", 19385 scroll: "Gunakan ctrl + scroll untuk memperbesar atau memperkecil peta", 19386 scrollMac: "Gunakan â + scroll untuk memperbesar atau memperkecil peta" 19387 }, 19388 it: { 19389 touch: "Utilizza due dita per spostare la mappa", 19390 scroll: "Utilizza CTRL + scorrimento per eseguire lo zoom della mappa", 19391 scrollMac: "Utilizza â + scorrimento per eseguire lo zoom della mappa" 19392 }, 19393 iw: { 19394 touch: "××× ×ת ×××¤× ×××צע×ת ×©×ª× ×צ××¢×ת", 19395 scroll: "â×פשר ××©× ×ת ×ת ×ר××§ ×תצ××× ×××¤× ×××צע×ת ×קש ctrl ××××××", 19396 scrollMac: "×פשר ××©× ×ת ×ת ×ר××§ ×תצ××× ×××¤× ×××צע×ת ×קש â ××××××" 19397 }, 19398 ja: { 19399 touch: "å°å³ãç§»åãããã«ã¯æ 2 æ¬ã§æä½ãã¾ã", 19400 scroll: "å°å³ããºã¼ã ããã«ã¯ãCtrl ãã¼ãæ¼ããªããã¹ã¯ãã¼ã«ãã¦ãã ãã", 19401 scrollMac: "å°å³ããºã¼ã ããã«ã¯ãâ ãã¼ãæ¼ããªããã¹ã¯ãã¼ã«ãã¦ãã ãã" 19402 }, 19403 kn: { 19404 touch: "Use two fingers to move the map", 19405 scroll: "Use Ctrl + scroll to zoom the map", 19406 scrollMac: "Use â + scroll to zoom the map" 19407 }, 19408 ko: { 19409 touch: "ì§ë를 ìì§ì´ë ¤ë©´ ë ìê°ë½ì ì¬ì©íì¸ì.", 19410 scroll: "ì§ë를 íë/ì¶ìíë ¤ë©´ Ctrlì ë른 ì± ì¤í¬ë¡¤íì¸ì.", 19411 scrollMac: "ì§ë를 íëíë ¤ë©´ â + ì¤í¬ë¡¤ ì¬ì©" 19412 }, 19413 lt: { 19414 touch: "Perkelkite žemÄlapį dviem pirÅ¡tais", 19415 scroll: "Slinkite nuspaudÄ klaviÅ¡Ä âCtrlâ, kad pakeistumÄte žemÄlapio mastelį", 19416 scrollMac: "Paspauskite klaviÅ¡Ä â ir slinkite, kad priartintumÄte žemÄlapį" 19417 }, 19418 lv: { 19419 touch: "Lai pÄrvietotu karti, bÄ«diet to ar diviem pirkstiem", 19420 scroll: "Kartes tÄlummaiÅai izmantojiet ctrl + ritinÄÅ¡anu", 19421 scrollMac: "Lai veiktu kartes tÄlummaiÅu, izmantojiet â + ritinÄÅ¡anu" 19422 }, 19423 ml: { 19424 touch: "മാപàµà´ªàµ à´¨àµà´àµà´à´¾àµ» à´°à´£àµà´àµ വിരലàµà´àµ¾ à´à´ªà´¯àµà´à´¿à´àµà´àµà´", 19425 scroll: "à´àµºà´àµà´°àµàµ¾ + à´¸àµâà´àµà´°àµàµ¾ à´à´ªà´¯àµà´à´¿à´àµà´à
19425µ âമാപàµà´ªàµ âà´¸àµà´ à´àµà´¯àµà´¯àµà´", 19426 scrollMac: "â + à´¸àµâà´àµà´°àµàµ¾ à´à´ªà´¯àµà´à´¿à´àµà´àµ âമാപàµà´ªàµ âà´¸àµà´ à´àµà´¯àµà´¯àµà´" 19427 }, 19428 mr: { 19429 touch: "नà¤à¤¾à¤¶à¤¾ हलविणà¥à¤¯à¤¾à¤¸à¤¾à¤ ॠदà¥à¤¨ बà¥à¤à¥ वापरा", 19430 scroll: "नà¤à¤¾à¤¶à¤¾ à¤à¥à¤® à¤à¤°à¤£à¥à¤¯à¤¾à¤¸à¤¾à¤ ॠctrl + scroll वापरा", 19431 scrollMac: "नà¤à¤¾à¤¶à¤¾à¤µà¤° à¤à¥à¤® à¤à¤°à¤£à¥à¤¯à¤¾à¤¸à¤¾à¤ ॠâ + सà¥à¤à¥à¤°à¥à¤² वापरा" 19432 }, 19433 nl: { 19434 touch: "Gebruik twee vingers om de kaart te verplaatsen", 19435 scroll: "Gebruik Ctrl + scrollen om in- en uit te zoomen op de kaart", 19436 scrollMac: "Gebruik â + scrollen om in en uit te zoomen op de kaart" 19437 }, 19438 no: { 19439 touch: "Bruk to fingre for Ã¥ flytte kartet", 19440 scroll: "Hold ctrl-tasten inne og rull for Ã¥ zoome pÃ¥ kartet", 19441 scrollMac: "Hold inne â-tasten og rull for Ã¥ zoome pÃ¥ kartet" 19442 }, 19443 pl: { 19444 touch: "PrzesuÅ mapÄ dwoma palcami", 19445 scroll: "NaciÅnij CTRL i przewiÅ, by przybliżyÄ mapÄ", 19446 scrollMac: "NaciÅnij â i przewiÅ, by przybliżyÄ mapÄ" 19447 }, 19448 pt: { 19449 touch: "Use dois dedos para mover o mapa", 19450 scroll: "Pressione Ctrl e role a tela simultaneamente para aplicar zoom no mapa", 19451 scrollMac: "Use â e role a tela simultaneamente para aplicar zoom no mapa" 19452 }, 19453 "pt-BR": { 19454 touch: "Use dois dedos para mover o mapa", 19455 scroll: "Pressione Ctrl e role a tela simultaneamente para aplicar zoom no mapa", 19456 scrollMac: "Use â e role a tela simultaneamente para aplicar zoom no mapa" 19457 }, 19458 "pt-PT": { 19459 touch: "Utilize dois dedos para mover o mapa", 19460 scroll: "Utilizar ctrl + deslocar para aumentar/diminuir zoom do mapa", 19461 scrollMac: "Utilize â + deslocar para aumentar/diminuir o zoom do mapa" 19462 }, 19463 ro: { 19464 touch: "FolosiÈi douÄ degete pentru a deplasa harta", 19465 scroll: "ApÄsaÈi tasta ctrl Èi derulaÈi simultan pentru a mÄri harta", 19466 scrollMac: "FolosiÈi â Èi derulaÈi pentru a mÄri/micÈora harta" 19467 }, 19468 ru: { 19469 touch: "ЧÑÐ¾Ð±Ñ Ð¿ÐµÑемеÑÑиÑÑ ÐºÐ°ÑÑÑ, пÑоведиÑе по ней двÑÐ¼Ñ Ð¿Ð°Ð»ÑÑами", 19470 scroll: "ЧÑÐ¾Ð±Ñ Ð¸Ð·Ð¼ÐµÐ½Ð¸ÑÑ Ð¼Ð°ÑÑÑаб, пÑокÑÑÑивайÑе каÑÑÑ, ÑдеÑÐ¶Ð¸Ð²Ð°Ñ ÐºÐ»Ð°Ð²Ð¸ÑÑ Ctrl.", 19471 scrollMac: "ЧÑÐ¾Ð±Ñ Ð¸Ð·Ð¼ÐµÐ½Ð¸ÑÑ Ð¼Ð°ÑÑÑаб, нажмиÑе â + пÑокÑÑÑка" 19472 }, 19473 sk: { 19474 touch: "Mapu môžete posunúť dvoma prstami", 19475 scroll: "Ak chcete priblÞiÅ¥ mapu, stlaÄte kláves ctrl a posúvajte", 19476 scrollMac: "Ak chcete priblÞiÅ¥ mapu, stlaÄte kláves â a posúvajte kolieskom myÅ¡i" 19477 }, 19478 sl: { 19479 touch: "Premaknite zemljevid z dvema prstoma", 19480 scroll: "Zemljevid poveÄate tako, da držite tipko Ctrl in vrtite kolesce na miÅ¡ki", 19481 scrollMac: "Uporabite â + funkcijo pomika, da poveÄate ali pomanjÅ¡ate zemljevid" 19482 }, 19483 sr: { 19484 touch: "ÐÐ°Ð¿Ñ Ð¿Ð¾Ð¼ÐµÑаÑÑе помоÑÑ Ð´Ð²Ð° пÑÑÑа", 19485 scroll: "ÐÑиÑиÑниÑе ctrl ÑаÑÑÐµÑ Ð´Ð¾Ðº помеÑаÑе да биÑÑе зÑмиÑали мапÑ", 19486 scrollMac: "ÐÑиÑиÑниÑе ÑаÑÑÐµÑ â док помеÑаÑе да биÑÑе зÑмиÑали мапÑ" 19487 }, 19488 sv: { 19489 touch: "Använd tvÃ¥ fingrar för att flytta kartan", 19490 scroll: "Använd ctrl + rulla för att zooma kartan", 19491 scrollMac: "Använd â + rulla för att zooma pÃ¥ kartan" 19492 }, 19493 ta: { 19494 touch: "à®®à¯à®ªà¯à®ªà¯ நà®à®°à¯à®¤à¯à®¤ à®à®°à®£à¯à®à¯ விரலà¯à®à®³à¯à®ªà¯ பயனà¯à®ªà®à¯à®¤à¯à®¤à®µà¯à®®à¯", 19495 scroll: "à®®à¯à®ªà¯à®ªà¯ பà¯à®°à®¿à®¤à®¾à®à¯à®à®¿/à®à®¿à®±à®¿à®¤à®¾à®à¯à®à®¿à®ªà¯ பாரà¯à®à¯à®, ctrl பà®à¯à®à®©à¯à®ªà¯ பிà®à®¿à®¤à¯à®¤à®ªà®à®¿, à®®à¯à®²à¯/à®à¯à®´à¯ ஸà¯à®à¯à®°à®¾à®²à¯ à®à¯à®¯à¯à®¯à®µà¯à®®à¯",
19496 scrollMac: "à®®à¯à®ªà¯à®ªà¯ பà¯à®°à®¿à®¤à®¾à®à¯à®à®¿/à®à®¿à®±à®¿à®¤à®¾à®à¯à®à®¿à®ªà¯ பாரà¯à®à¯à®, â பà®à¯à®à®©à¯à®ªà¯ பிà®à®¿à®¤à¯à®¤à®ªà®à®¿, à®®à¯à®²à¯/à®à¯à®´à¯ ஸà¯à®à¯à®°à®¾à®²à¯ à®à¯à®¯à¯à®¯à®µà¯à®®à¯" 19497 }, 19498 te: { 19499 touch: "à°®à±à°¯à°¾à°ªà±âని తరలిà°à°à°¡à° à°à±à°¸à° à°°à±à°à°¡à± à°µà±à°³à±à°²à°¨à± à°à°ªà°¯à±à°à°¿à°à°à°à°¡à°¿", 19500 scroll: "à°®à±à°¯à°¾à°ªà±âని à°à±à°®à± à°à±à°¯à°¡à°¾à°¨à°¿à°à°¿ ctrl à°¬à°à°¨à±âనౠనà±à°à±à°à°¿ à°à°à°à°¿, à°¸à±à°à±à°°à±à°²à± à°à±à°¯à°à°¡à°¿", 19501 scrollMac: "à°®à±à°¯à°¾à°ªà± à°à±à°®à± à°à±à°¯à°¾à°²à°à°à± â + à°¸à±à°à±à°°à±à°²à± à°à°ªà°¯à±à°à°¿à°à°à°à°¡à°¿" 19502 }, 19503 th: { 19504 touch: "à¹à¸à¹ 2 à¸à¸´à¹à¸§à¹à¸à¸·à¹à¸à¹à¸¥à¸·à¹à¸à¸à¹à¸à¸à¸à¸µà¹", 19505 scroll: "à¸à¸ Ctrl à¸à¹à¸²à¸à¹à¸§à¹ à¹à¸¥à¹à¸§à¹à¸¥à¸·à¹à¸à¸à¸«à¸à¹à¸²à¸à¸à¹à¸à¸·à¹à¸à¸à¸¹à¸¡à¹à¸à¸à¸à¸µà¹", 19506 scrollMac: "à¸à¸ â à¹à¸¥à¹à¸§à¹à¸¥à¸·à¹à¸à¸à¸«à¸à¹à¸²à¸à¸à¹à¸à¸·à¹à¸à¸à¸¹à¸¡à¹à¸à¸à¸à¸µà¹" 19507 }, 19508 tl: { 19509 touch: "Gumamit ng dalawang daliri upang iusog ang mapa", 19510 scroll: "Gamitin ang ctrl + scroll upang i-zoom ang mapa", 19511 scrollMac: "Gamitin ang â + scroll upang i-zoom ang mapa" 19512 }, 19513 tr: { 19514 touch: "Haritada gezinmek için iki parmaÄınızı kullanın", 19515 scroll: "Haritayı yakınlaÅtırmak için ctrl + kaydırma kombinasyonunu kullanın", 19516 scrollMac: "Haritayı yakınlaÅtırmak için â tuÅuna basıp ekranı kaydırın" 19517 }, 19518 uk: { 19519 touch: "ÐеÑемÑÑÑйÑе каÑÑÑ Ð´Ð²Ð¾Ð¼Ð° палÑÑÑми", 19520 scroll: "Щоб змÑнÑваÑи маÑÑÑаб каÑÑи, пÑокÑÑÑÑйÑе колÑÑаÑко миÑÑ, ÑÑÑимÑÑÑи клавÑÑÑ Ctrl", 19521 scrollMac: "Щоб змÑниÑи маÑÑÑаб каÑÑи, викоÑиÑÑовÑйÑе â + пÑокÑÑÑÑваннÑ" 19522 }, 19523 vi: { 19524 touch: "Sá» dụng hai ngón tay Äá» di chuyá»n bản Äá»", 19525 scroll: "Sá» dụng ctrl + cuá»n Äá» thu phóng bản Äá»", 19526 scrollMac: "Sá» dụng â + cuá»n Äá» thu phóng bản Äá»" 19527 }, 19528 "zh-CN": { 19529 touch: "使ç¨åæç§»å¨å°å¾", 19530 scroll: "æä½ Ctrl å¹¶æ»å¨é¼ æ æ»è½®æå¯ç¼©æ¾å°å¾", 19531 scrollMac: "æä½ â å¹¶æ»å¨é¼ æ æ»è½®æå¯ç¼©æ¾å°å¾" 19532 }, 19533 "zh-TW": { 19534 touch: "åæä»¥å ©æç§»åå°å", 19535 scroll: "æä½ ctrl éµå 䏿²åæ»é¼ å¯ä»¥ç¸®æ¾å°å", 19536 scrollMac: "æ â å 䏿»¾åæ²è»¸å¯ä»¥ç¸®æ¾å°å" 19537 } 19538 }; 19539 L.Map.mergeOptions({ 19540 gestureHandlingOptions: { 19541 text: {}, 19542 duration: 1e3 19543 } 19544 }); 19545 var t = !1, 19546 e = L.Handler.extend({ 19547 addHooks: function addHooks() { 19548 this._handleTouch = this._handleTouch.bind(this), this._setupPluginOptions(), this._setLanguageContent(), this._disableInteractions(), this._map._container.addEventListener("touchstart", this._handleTouch), this._map._container.addEventListener("touchmove", this._handleTouch), this._map._container.addEventListener("touchend", this._handleTouch), this._map._container.addEventListener("touchcancel", this._handleTouch), this._map._container.addEventListener("click", this._handleTouch), L.DomEvent.on(this._map._container, "wheel", this._handleScroll, this), L.DomEvent.on(this._map, "mouseover", this._handleMouseOver, this), L.DomEvent.on(this._map, "mouseout", this._handleMouseOut, this), L.DomEvent.on(this._map, "movestart", this._handleDragging, this), L.DomEvent.on(this._map, "move", this._handleDragging, this), L.DomEvent.on(this._map, "moveend", this._handleDragging, this); 19549 }, 19550 removeHooks: function removeHooks() { 19551 this._enableInteractions(), this._map._container.removeEventListener("touchstart", this._handleTouch), this._map._container.removeEventListener("touchmove", this._handleTouch), this._map._container.removeEventListener("touchend", this._handleTouch), this._map._container.removeEventListener("touchcancel", this._handleTouch), this._map._container.removeEventListener("click", this._handleTouch), L.DomEvent.off(this._map._container, "wheel", this._handleScroll, this), L.DomEvent.off(this._map, "mouseover", this._handleMouseOver, this), L.DomEvent.off(this._map, "mouseout", this._handleMouseOut, this), L.DomEvent.off(this._map, "movestart", this._handleDragging, this), L.DomEvent.off(this._map, "move", this._handleDragging, this), L.DomEvent.off(this._map, "moveend", this._handleDragging, this); 19552 }, 19553 _handleDragging: function _handleDragging(a) { 19554 "movestart" == a.type || "move" == a.type ? t = !0 : "moveend" == a.type && (t = !1); 19555 }, 19556 _disableInteractions: function _disableInteractions() { 19557 this._map.dragging.disable(), this._map.scrollWheelZoom.disable(), this._map.tap && this._map.tap.disable(); 19558 }, 19559 _enableInteractions: function _enableInteractions() { 19560 this._map.dragging.enable(), this._map.scrollWheelZoom.enable(), this._map.tap && this._map.tap.enable(); 19561 }, 19562 _setupPluginOptions: function _setupPluginOptions() { 19563 this._map.options.gestureHandlingText && (this._map.options.gestureHandlingOptions.text = this._map.options.gestureHandlingText); 19564 }, 19565 _setLanguageContent: function _setLanguageContent() { 19566 var a; 19567 if (this._map.options.gestureHandlingOptions && this._map.options.gestureHandlingOptions.text && this._map.options.gestureHandlingOptions.text.touch && this._map.options.gestureHandlingOptions.text.scroll && this._map.options.gestureHandlingOptions.text.scrollMac) a = this._map.options.gestureHandlingOptions.text;else { 19568 var t = this._getUserLanguage(); 19569 t || (t = "en"), o[t] && (a = o[t]), a || -1 === t.indexOf("-") || (t = t.split("-")[0], a = o[t]), a || (a = o[t = "en"]); 19570 } 19571 var e = !1; 19572 0 <= navigator.platform.toUpperCase().indexOf("MAC") && (e = !0); 19573 var l = a.scroll; 19574 e && (l = a.scrollMac), this._map._container.setAttribute("data-gesture-handling-touch-content", a.touch), this._map._container.setAttribute("data-gesture-handling-scroll-content", l); 19575 }, 19576 _getUserLanguage: function _getUserLanguage() { 19577 return navigator.languages ? navigator.languages[0] : navigator.language || navigator.userLanguage; 19578 }, 19579 _handleTouch: function _handleTouch(a) { 19580 for (var t = ["leaflet-control-minimap", "leaflet-interactive", "leaflet-popup-content", "leaflet-popup-content-wrapper", "leaflet-popup-close-button", "leaflet-control-zoom-in", "leaflet-control-zoom-out"], e = !1, l = 0; l < t.length; l++) L.DomUtil.hasClass(a.target, t[l]) && (e = !0); 19581 e ? L.DomUtil.hasClass(a.target, "leaflet-interactive") && "touchmove" === a.type && 1 === a.touches.length ? (L.DomUtil.addClass(this._map._container, "leaflet-gesture-handling-touch-warning"), this._disableInteractions()) : L.DomUtil.removeClass(this._map._container, "leaflet-gesture-handling-touch-warning") : "touchmove" === a.type || "touchstart" === a.type ? 1 === a.touches.length ? (L.DomUtil.addClass(this._map._container, "leaflet-gesture-handling-touch-warning"), this._disableInteractions()) : (a.preventDefault(), this._enableInteractions(), L.DomUtil.removeClass(this._map._container, "leaflet-gesture-handling-touch-warning")) : L.DomUtil.removeClass(this._map._container, "leaflet-gesture-handling-touch-warning"); 19582 }, 19583 _isScrolling: !1, 19584 _handleScroll: function _handleScroll(a) { 19585 a.metaKey || a.ctrlKey ? (a.preventDefault(), L.DomUtil.removeClass(this._map._container, "leaflet-gesture-handling-scroll-warning"), this._map.scrollWheelZoom.enable()) : (L.DomUtil.addClass(this._map._container, "leaflet-gesture-handling-scroll-warning"), this._map.scrollWheelZoom.disable(), clearTimeout(this._isScrolling), this._isScrolling = setTimeout(function () { 19586 for (var a = document.getElementsByClassName("leaflet-gesture-handling-scroll-warning"), t = 0; t < a.length; t++) L.DomUtil.removeClass(a[t], "leaflet-gesture-handling-scroll-warning"); 19587 }, this._map.options.gestureHandlingOptions.duration)); 19588 }, 19589 _handleMouseOver: function _handleMouseOver(a) { 19590 this._enableInteractions(); 19591 }, 19592 _handleMouseOut: function _handleMouseOut(a) { 19593 t || this._disableInteractions(); 19594 } 19595 }); 19596 L.Map.addInitHook("addHandler", "gestureHandling", e), a.GestureHandling = e, a.default = e, Object.defineProperty(a, "__esModule", { 19597 value: !0 19598 }); 19599 }); 19600 })(leafletGestureHandling_min, leafletGestureHandling_min.exports
19600); 19601 19602 /* Note, this implies only a single map per page */ 19603 function enableMap() { 19604 var mapID = 'map'; 19605 var mapEl = document.getElementById(mapID); 19606 if (!mapEl) { 19607 return; 19608 } 19609 var updateLocationCount = function updateLocationCount() { 19610 var count = document.querySelector('.msk-map-widget__count-value'); 19611 var label = document.querySelector('.msk-map-widget__count-label'); 19612 if (!count || !label) return; 19613 var cards = Array.from(document.querySelectorAll('.msk-map-location-card:not(.msk-map-location-card[hidden]')); 19614 count.innerHTML = "".concat(cards.length, " "); 19615 if (window.Drupal) { 19616 label.innerHTML = cards.length === 1 ? window.Drupal.t('location found') : window.Drupal.t('locations found'); 19617 } else { 19618 label.innerHTML = cards.length === 1 ? 'location found' : 'locations found'; 19619 } 19620 }; 19621 L$1.Map.addInitHook("addHandler", "gestureHandling", leafletGestureHandling_min.exports.GestureHandling); 19622 if (window.Drupal) { 19623 var mapRefs = []; 19624 L$1.Map.addInitHook(function () { 19625 mapRefs.push(this); 19626 }); 19627 window.Drupal['mapRefs'] = mapRefs; 19628 } 19629 19630 // set up the leaflet map 19631 var map = L$1.map(mapID, { 19632 gestureHandling: true 19633 }); 19634 var lg = L$1.layerGroup([]).addTo(map); 19635 19636 /* render map function */ 19637 var renderMap = function renderMap() { 19638 if (map) { 19639 map.invalidateSize(); 19640 map.removeLayer(lg); 19641 } 19642 19643 // get the marker data 19644 var markers; 19645 if (document.querySelectorAll('.msk-map-location-card').length) { 19646 markers = Array.from(document.querySelectorAll('.msk-map-location-card:not([hidden]')).map(function (card) { 19647 return JSON.parse(card.dataset.location); 19648 }); 19649 } else if (mapEl.dataset.markers) { 19650 markers = JSON.parse(mapEl.dataset.markers); 19651 } 19652 if (!markers) { 19653 // set a default on 1275 York Ave, zoomed out to the region.
19654 map.setView([40.764275080086, -73.956726193428], 8); 19655 } 19656 19657 // set up tiles 19658 // Carto API key 19659 var cartoAPIKey = "cb1_2nab_1_f0e3d49f8a6ebba623d2b91d"; 19660 /* Carto Positron */ 19661 var tileURL = "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png?key=".concat(cartoAPIKey); 19662 var tileAttribution = '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors; © <a href="https://carto.com/attributions">CARTO</a>.'; 19663 L$1.tileLayer(tileURL, { 19664 subdomains: 'abcd', 19665 maxZoom: 17, 19666 attribution: tileAttribution 19667 }).addTo(map); 19668 19669 // set up markers based on location data 19670 if (markers) { 19671 // coordinate storage to find the bounds 19672 var a_latitude = []; 19673 var a_longitude = []; 19674 var layerGroup = []; 19675 markers.forEach(function (marker) { 19676 // store the coordinates for use later 19677 a_latitude.push(parseFloat(marker.latitude)); 19678 a_longitude.push(parseFloat(marker.longitude)); 19679 var markerClass = markers.length === 1 ? 'mskMapIcon__pin mskMapIcon__pin--is-active' : 'mskMapIcon__pin'; 19680 var mskIcon = L$1.divIcon({ 19681 html: "<svg role=\"img\" class=\"".concat(markerClass, "\" id=\"marker-").concat(marker.nid, "\" width=\"43\" height=\"44\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-describedby=\"map-icon msk-map-icon\"><title id=\"map-icon\">Map Marker</title><desc id=\"msk-map-icon\">A msk map marker icon</desc><path class=\"markerPin\" d=\"M21.5 3.61C14.568 3.61 8.96 9.218 8.96 16.152c0 9.406 12.542 23.292 12.542 23.292s12.541-13.886 12.541-23.292c0-6.934-5.608-12.542-12.541-12.542z\" /><g clip-path=\"url(#a)\"><path d=\"M26.541 11.434c-1.139-1.328-2.834-2-5.041-2-2.207 0-3.902.672-5.04 2-1.114 1.298-1.679 3.225-1.679 5.727 0 2.502.566 4.428 1.679 5.726 1.139 1.327 2.834 2.001 5.04 2.001s3.902-.673 5.04-2c1.114-1.299 1.679-3.226 1.679-5.727 0-2.502-.566-4.429-1.679-5.727h.002zm-5.04 12.563c-3.896 0-5.845-2.279-5.845-6.836 0-4.558 1.948-6.836 5.844-6.836 3.896 0 5.845 2.278 5.845 6.836 0 4.557-1.949 6.836-5.845 6.836h.001zm0-12.092 2.667 2.724-.617.63-1.615-1.65v2.81h1.915v.891h-1.915V18h1.915v.89h-1.915v.69h1.915v.89h-1.915v1.948h-.872V20.47h-1.9
1968115v-.891h1.915v-.69h-1.915V18h1.915v-.69h-1.915v-.891h1.915v-2.81l-1.613 1.649-.617-.63 2.666-2.724.001.001z\" fill=\"#fff\"/></g><defs><clipPath id=\"a\"><path fill=\"#fff\" transform=\"translate(14.781 9.434)\" d=\"M0 0h13.438v15.453H0z\"/></clipPath></defs></svg>"), 19682 className: "mskMapIcon", 19683 iconSize: [44, 44], 19684 // size of the icon 19685 iconAnchor: [22, 44], 19686 // point of the icon which will correspond to marker's location 19687 popupAnchor: [0, -44], 19688 // point from which the popup should open relative to the iconAnchor 19689 nid: marker.nid 19690 }); 19691 layerGroup.push(L$1.marker([marker.latitude, marker.longitude], { 19692 icon: mskIcon 19693 }).on('click', function (e) { 19694 handleMarkerClick(e); 19695 })); 19696 }); 19697 lg = L$1.layerGroup(layerGroup); 19698 lg.addTo(map); 19699 19700 // set up bounds for maps to never have a pin off the map on load 19701 var coordinateBounds = [[Math.min.apply(Math, a_latitude), Math.min.apply(Math, a_longitude)], [Math.max.apply(Math, a_latitude), Math.max.apply(Math, a_longitude)]]; 19702 var bounds = L$1.latLngBounds(coordinateBounds); 19703 19704 // add some padding to the map so the pins aren't right at the edge 19705 var zoomOpts = document.querySelector('.msk-map-widget__with-filter') ? { 19706 padding: [35, 35] 19707 } : { 19708 padding: [20, 20] 19709 }; 19710 var wideZoomOpts = document.querySelector('.msk-map-widget__with-filter') ? zoomOpts : { 19711 paddingTopLeft: [410, 0] 19712 }; 19713 map.fitBounds(bounds, zoomOpts); 19714 19715 // if the map is being used as part of the map-widget with cards, 19716 // we need to set up a matchMedia case to handle padding the map appropriately 19717 if (mapEl.closest('.msk-map-widget')) { 19718 var mapWideMin = 700; 19719 if (markers.length == 1 && !document.querySelector('.msk-map-widget__with-filter')) { 19720 // when there's only one location and we're not filtering locations, 19721 // the card is superimposed on the map, so we need to pad the 19722 // left side of the map to make sure the pin doesn't wind up behind the card. 19723 19724 // const wideZoomOpts = {paddingTopLeft: [410, 0]}; 19725 map.fitBounds(bounds, map._size.x >= mapWideMin ? wideZoomOpts : zoomOpts); 19726 19727 // handle map re-size to switch the paddings out as needed 19728 map.on('resize', function (ev) { 19729 map.invalidateSize(); 19730 map.fitBounds(bounds, ev.oldSize.x >= mapWideMin ? wideZoomOpts : zoomOpts); 19731 }); 19732 } else { 19733 // if there's more than one location or we're filtering locations, the cards are displayed 19734 // next to the map, so we don't have to worry about padding. 19735 19736 // fit all pins onto the map 19737 map.fitBounds(bounds, zoomOpts); 19738 map.on('resize', function () { 19739 map.invalidateSize(); 19740 map.fitBounds(bounds, zoomOpts); 19741 }); 19742 updateLocationCount(); 19743 } 19744 } 19745 } 19746 }; 19747 renderMap(); 19748 var handleMarkerClick = function handleMarkerClick(e) { 19749 var cards = Array.from(document.querySelectorAll('.msk-map-location-card')); 19750 if (!cards) return; 19751 Array.from(document.querySelectorAll('.mskMapIcon__pin--is-active')).forEach(function (pin) { 19752 pin.classList.remove('mskMapIcon__pin--is-active'); 19753 }); 19754 var opts = e.target.options.icon.options; 19755 cards.forEach(function (card) { 19756 card.classList.remove('msk-map-location-card--is-selected'); 19757 }); 19758 var theCard = document.getElementById("locationCard-".concat(opts.nid)); 19759 var thePin = document.getElementById("marker-".concat(opts.nid)); 19760 if (theCard) { 19761 theCard.classList.add('msk-map-location-card--is-selected'); 19762 theCard.scrollIntoView({ 19763 block: "nearest", 19764 inline: "nearest" 19765 }); 19766 } 19767 if (thePin) { 19768 thePin.classList.add('mskMapIcon__pin--is-active'); 19769 } 19770 }; 19771 var handleFilterChange = function handleFilterChange(e) { 19772 var region = e.target.value; 19773 updateFilteredCards(region); 19774 }; 19775 var updateFilteredCards = function updateFilteredCards(region) { 19776 if (region === undefined) return;
19777 var cards = Array.from(document.querySelectorAll('.msk-map-location-card')); 19778 if (region === '') { 19779 cards.forEach(function (card) { 19780 card.hidden = false; 19781 }); 19782 } else { 19783 cards.forEach(function (card) { 19784 card.hidden = false; 19785 if (card.dataset.region != region) { 19786 card.hidden = true; 19787 } 19788 }); 19789 } 19790 renderMap(); 19791 }; 19792 var mapFilter = document.getElementById('map-filter'); 19793 if (mapFilter) { 19794 mapFilter.addEventListener('change', function (event) { 19795 handleFilterChange(event); 19796 }); 19797 } 19798 } 19799 19800 /** 19801 * Dismiss message. 19802 * @param {Event} event - The pointerup event. 19803 * @return {void} 19804 */ 19805 function messageDismiss(event) { 19806 var closeElement = event.target.closest('.msk-message__close'); 19807 if (!closeElement) return; 19808 var messageElement = closeElement.closest('.msk-message'); 19809 if (!messageElement.hasAttribute('id')) { 19810 messageElement = closeElement.closest('.msk-message__wrapper'); 19811 } 19812 messageElement.classList.add('msk-message--dismissed'); 19813 window.localStorage.setItem("msk-message-dismissed-".concat(messageElement.id), true); 19814 } 19815 function enableMessage() { 19816 document.documentElement.addEventListener('pointerup', messageDismiss, false); 19817 var messages = document.querySelectorAll('.msk-message'); 19818 messages.forEach(function (message) { 19819 var isDismissed = !!window.localStorage.getItem("msk-message-dismissed-".concat(message.id)); 19820 if (isDismissed) { 19821 message.classList.add('msk-message--dismissed'); 19822 } 19823 }); 19824 } 19825 19826 /** 19827 * Dismiss the currently open modal. 19828 * @param {Element} [element=modal] - The modal element to operate on. Fallback to finding the element in the DOM. 19829 * @return {void} 19830 */ 19831 function dismissModal() { 19832 var element = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : document.querySelector('.msk-modal[data-modal-state="open"]'); 19833 // Modals loaded via AJAX don't get the necessary data attributes, so element will be null. 19834 // Those modals have their own close functionality so we can safely return :-) 19835 if (!element) { 19836 return; 19837 } 19838 19839 // If modal is gated we do not want the user to be able to dismiss through normal means 19840 if (element.dataset.preventDismissal && element.dataset.preventDismissal === 'true') { 19841 return; 19842 } 19843 19844 // If there's a video here, pause the video before closing. 19845 var player = element.querySelector('.msk-cfplayer'); 19846 if (player && window.cfPlayers) { 19847 window.cfPlayers.some(function (p) { 19848 if (p[player.id]) { 19849 p[player.id].pause(); 19850 return true; 19851 } 19852 }); 19853 } 19854 19855 // Reset values back to original state 19856 element.dataset.modalState = 'dismissed'; 19857 element.setAttribute('aria-hidden', 'true'); 19858 // If we've added the visibility class we need to remove that here 19859 if (element.classList.contains('msk-modal--visible')) { 19860 element.classList.remove('msk-modal--visible'); 19861 } 19862 } 19863 19864 /** 19865 * Toggle modal visibility. 19866 * @param {Event} event triggered event. 19867 * @return {void} 19868 */ 19869 function toggleModal(event) { 19870 var modalTrigger = event.target.closest('[data-toggle="modal"][data-target]'); 19871 if (modalTrigger) { 19872 var modal = document.getElementById("".concat(modalTrigger.dataset.target)); 19873 modal.dataset.modalState = 'open'; 19874 modal.setAttribute('aria-hidden', 'false'); 19875 return; 19876 } 19877 if (event.target.closest('.msk-modal__close')) { 19878 dismissModal(); 19879 return; 19880 } 19881 if (event.target.classList.contains('msk-modal')) { 19882 dismissModal(event.target); 19883 } 19884 } 19885 19886 /** 19887 * Keyup event handler. 19888 * @param {Event} event triggered keyup event. 19889 * @return {void} 19890 */ 19891 function handleKeyup(event) { 19892 if (!document.querySelector('.msk-modal[data-modal-state="open"]')) return; 19893 if (event.key === 'Escape') { 19894 dismissModal(); 19895 } 19896 } 19897 function enableModals() { 19898 on('pointerup', 'body', toggleModal); 19899 on('keyup', 'body', handleKeyup); 19900 } 19901 19902 /** 19903 * Checks if `value` is the 19904 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) 19905 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) 19906 * 19907 * @static 19908 * @memberOf _ 19909 * @since 0.1.0 19910 * @category Lang 19911 * @param {*} value The value to check. 19912 * @returns {boolean} Returns `true` if `value` is an object, else `false`. 19913 * @example 19914 * 19915 * _.isObject({}); 19916 * // => true 19917 * 19918 * _.isObject([1, 2, 3]); 19919 * // => true 19920 * 19921 * _.isObject(_.noop); 19922 * // => true 19923 * 19924 * _.isObject(null); 19925 * // => false 19926 */ 19927 function isObject(value) { 19928 var type = _typeof$1(value); 19929 return value != null && (type == 'object' || type == 'function'); 19930 } 19931 19932 /** Detect free variable `global` from Node.js. */ 19933 var freeGlobal = (typeof global === "undefined" ? "undefined" : _typeof$1(global)) == 'object' && global && global.Object === Object && global; 19934 var freeGlobal$1 = freeGlobal; 19935 19936 /** Detect free variable `self`. */ 19937 var freeSelf = (typeof self === "undefined" ? "undefined" : _typeof$1(self)) == 'object' && self && self.Object === Object && self; 19938 19939 /** Used as a reference to the global object. */ 19940 var root = freeGlobal$1 || freeSelf || Function('return this')(); 19941 var root$1 = root; 19942 19943 /** 19944 * Gets the timestamp of the number of milliseconds that have elapsed since 19945 * the Unix epoch (1 January 1970 00:00:00 UTC). 19946 * 19947 * @static 19948 * @memberOf _ 19949 * @since 2.4.0 19950 * @category Date 19951 * @returns {number} Returns the timestamp. 19952 * @example 19953 * 19954 * _.defer(function(stamp) { 19955 * console.log(_.now() - stamp); 19956 * }, _.now()); 19957 * // => Logs the number of milliseconds it took for the deferred invocation. 19958 */ 19959 var now = function now() { 19960 return root$1.Date.now(); 19961 }; 19962 var now$1 = now; 19963 19964 /** Used to match a single whitespace character. */ 19965 var reWhitespace = /\s/; 19966 19967 /** 19968 * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace 19969 * character of `string`. 19970 * 19971 * @private 19972 * @param {string} string The string to inspect. 19973 * @returns {number} Returns the index of the last non-whitespace character. 19974 */ 19975 function trimmedEndIndex(string) { 19976 var index = string.length; 19977 while (index-- && reWhitespace.test(string.charAt(index))) {} 19978 return index; 19979 } 19980 19981 /** Used to match leading whitespace. */ 19982 var reTrimStart = /^\s+/; 19983 19984 /** 19985 * The base implementation of `_.trim`. 19986 * 19987 * @private 19988 * @param {string} string The string to trim. 19989 * @returns {string} Returns the trimmed string. 19990 */ 19991 function baseTrim(string) {
19992 return string ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '') : string; 19993 } 19994 19995 /** Built-in value references. */ 19996 var _Symbol = root$1.Symbol; 19997 var _Symbol$1 = _Symbol; 19998 19999 /** Used for built-in method references. */ 20000 var objectProto$1 = Object.prototype; 20001 20002 /** Used to check objects for own properties. */ 20003 var hasOwnProperty = objectProto$1.hasOwnProperty; 20004 20005 /** 20006 * Used to resolve the 20007 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) 20008 * of values. 20009 */ 20010 var nativeObjectToString$1 = objectProto$1.toString; 20011 20012 /** Built-in value references. */ 20013 var symToStringTag$1 = _Symbol$1 ? _Symbol$1.toStringTag : undefined; 20014 20015 /** 20016 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. 20017 * 20018 * @private 20019 * @param {*} value The value to query. 20020 * @returns {string} Returns the raw `toStringTag`. 20021 */ 20022 function getRawTag(value) { 20023 var isOwn = hasOwnProperty.call(value, symToStringTag$1), 20024 tag = value[symToStringTag$1]; 20025 try { 20026 value[symToStringTag$1] = undefined; 20027 var unmasked = true; 20028 } catch (e) {} 20029 var result = nativeObjectToString$1.call(value); 20030 if (unmasked) { 20031 if (isOwn) { 20032 value[symToStringTag$1] = tag; 20033 } else { 20034 delete value[symToStringTag$1]; 20035 } 20036 } 20037 return result; 20038 } 20039 20040 /** Used for built-in method references. */ 20041 var objectProto = Object.prototype; 20042 20043 /** 20044 * Used to resolve the 20045 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) 20046 * of values. 20047 */ 20048 var nativeObjectToString = objectProto.toString; 20049 20050 /** 20051 * Converts `value` to a string using `Object.prototype.toString`. 20052 * 20053 * @private 20054 * @param {*} value The value to convert. 20055 * @returns {string} Returns the converted string. 20056 */ 20057 function objectToString(value) { 20058 return nativeObjectToString.call(value); 20059 } 20060 20061 /** `Object#toString` result references. */ 20062 var nullTag = '[object Null]', 20063 undefinedTag = '[object Undefined]'; 20064 20065 /** Built-in value references. */ 20066 var symToStringTag = _Symbol$1 ? _Symbol$1.toStringTag : undefined; 20067 20068 /** 20069 * The base implementation of `getTag` without fallbacks for buggy environments. 20070 * 20071 * @private 20072 * @param {*} value The value to query. 20073 * @returns {string} Returns the `toStringTag`. 20074 */ 20075 function baseGetTag(value) { 20076 if (value == null) { 20077 return value === undefined ? undefinedTag : nullTag; 20078 } 20079 return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value); 20080 } 20081 20082 /** 20083 * Checks if `value` is object-like. A value is object-like if it's not `null` 20084 * and has a `typeof` result of "object". 20085 * 20086 * @static 20087 * @memberOf _ 20088 * @since 4.0.0 20089 * @category Lang 20090 * @param {*} value The value to check. 20091 * @returns {boolean} Returns `true` if `value` is object-like, else `false`. 20092 * @example 20093 * 20094 * _.isObjectLike({}); 20095 * // => true 20096 * 20097 * _.isObjectLike([1, 2, 3]); 20098 * // => true 20099 * 20100 * _.isObjectLike(_.noop); 20101 * // => false 20102 * 20103 * _.isObjectLike(null); 20104 * // => false 20105 */ 20106 function isObjectLike(value) { 20107 return value != null && _typeof$1(value) == 'object'; 20108 } 20109 20110 /** `Object#toString` result references. */ 20111 var symbolTag = '[object Symbol]'; 20112 20113 /** 20114 * Checks if `value` is classified as a `Symbol` primitive or object. 20115 * 20116 * @static 20117 * @memberOf _ 20118 * @since 4.0.0 20119 * @category Lang 20120 * @param {*} value The value to check. 20121 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. 20122 * @example 20123 * 20124 * _.isSymbol(Symbol.iterator); 20125 * // => true 20126 * 20127 * _.isSymbol('abc'); 20128 * // => false 20129 */ 20130 function isSymbol(value) { 20131 return _typeof$1(value) == 'symbol' || isObjectLike(value) && baseGetTag(value) == symbolTag; 20132 } 20133 20134 /** Used as references for various `Number` constants. */ 20135 var NAN = 0 / 0; 20136 20137 /** Used to detect bad signed hexadecimal string values. */ 20138 var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; 20139 20140 /** Used to detect binary string values. */
vendor: 7,925 bytes, lines 20141-20382
20141 var reIsBinary = /^0b[01]+$/i; 20142 20143 /** Used to detect octal string values. */ 20144 var reIsOctal = /^0o[0-7]+$/i; 20145 20146 /** Built-in method references without a dependency on `root`. */ 20147 var freeParseInt = parseInt; 20148 20149 /** 20150 * Converts `value` to a number. 20151 * 20152 * @static 20153 * @memberOf _ 20154 * @since 4.0.0 20155 * @category Lang 20156 * @param {*} value The value to process. 20157 * @returns {number} Returns the number. 20158 * @example 20159 * 20160 * _.toNumber(3.2); 20161 * // => 3.2 20162 * 20163 * _.toNumber(Number.MIN_VALUE); 20164 * // => 5e-324 20165 * 20166 * _.toNumber(Infinity); 20167 * // => Infinity 20168 * 20169 * _.toNumber('3.2'); 20170 * // => 3.2 20171 */ 20172 function toNumber(value) { 20173 if (typeof value == 'number') { 20174 return value; 20175 } 20176 if (isSymbol(value)) { 20177 return NAN; 20178 } 20179 if (isObject(value)) { 20180 var other = typeof value.valueOf == 'function' ? value.valueOf() : value; 20181 value = isObject(other) ? other + '' : other; 20182 } 20183 if (typeof value != 'string') { 20184 return value === 0 ? value : +value; 20185 } 20186 value = baseTrim(value); 20187 var isBinary = reIsBinary.test(value); 20188 return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; 20189 } 20190 20191 /** Error message constants. */ 20192 var FUNC_ERROR_TEXT = 'Expected a function'; 20193 20194 /* Built-in method references for those with the same name as other `lodash` methods. */ 20195 var nativeMax = Math.max, 20196 nativeMin = Math.min; 20197 20198 /** 20199 * Creates a debounced function that delays invoking `func` until after `wait` 20200 * milliseconds have elapsed since the last time the debounced function was 20201 * invoked. The debounced function comes with a `cancel` method to cancel 20202 * delayed `func` invocations and a `flush` method to immediately invoke them. 20203 * Provide `options` to indicate whether `func` should be invoked on the 20204 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked 20205 * with the last arguments provided to the debounced function. Subsequent 20206 * calls to the debounced function return the result of the last `func` 20207 * invocation. 20208 * 20209 * **Note:** If `leading` and `trailing` options are `true`, `func` is 20210 * invoked on the trailing edge of the timeout only if the debounced function 20211 * is invoked more than once during the `wait` timeout. 20212 * 20213 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred 20214 * until to the next tick, similar to `setTimeout` with a timeout of `0`. 20215 * 20216 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) 20217 * for details over the differences between `_.debounce` and `_.throttle`. 20218 * 20219 * @static 20220 * @memberOf _ 20221 * @since 0.1.0 20222 * @category Function 20223 * @param {Function} func The function to debounce. 20224 * @param {number} [wait=0] The number of milliseconds to delay. 20225 * @param {Object} [options={}] The options object. 20226 * @param {boolean} [options.leading=false] 20227 * Specify invoking on the leading edge of the timeout. 20228 * @param {number} [options.maxWait] 20229 * The maximum time `func` is allowed to be delayed before it's invoked. 20230 * @param {boolean} [options.trailing=true] 20231 * Specify invoking on the trailing edge of the timeout. 20232 * @returns {Function} Returns the new debounced function. 20233 * @example 20234 * 20235 * // Avoid costly calculations while the window size is in flux. 20236 * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); 20237 * 20238 * // Invoke `sendMail` when clicked, debouncing subsequent calls. 20239 * jQuery(element).on('click', _.debounce(sendMail, 300, { 20240 * 'leading': true, 20241 * 'trailing': false 20242 * })); 20243 * 20244 * // Ensure `batchLog` is invoked once after 1 second of debounced calls. 20245 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); 20246 * var source = new EventSource('/stream'); 20247 * jQuery(source).on('message', debounced); 20248 * 20249 * // Cancel the trailing debounced invocation. 20250 * jQuery(window).on('popstate', debounced.cancel); 20251 */ 20252 function debounce(func, wait, options) { 20253 var lastArgs, 20254 lastThis, 20255 maxWait, 20256 result, 20257 timerId, 20258 lastCallTime, 20259 lastInvokeTime = 0, 20260 leading = false, 20261 maxing = false, 20262 trailing = true; 20263 if (typeof func != 'function') { 20264 throw new TypeError(FUNC_ERROR_TEXT); 20265 } 20266 wait = toNumber(wait) || 0; 20267 if (isObject(options)) { 20268 leading = !!options.leading; 20269 maxing = 'maxWait' in options; 20270 maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; 20271 trailing = 'trailing' in options ? !!options.trailing : trailing; 20272 } 20273 function invokeFunc(time) { 20274 var args = lastArgs, 20275 thisArg = lastThis; 20276 lastArgs = lastThis = undefined; 20277 lastInvokeTime = time; 20278 result = func.apply(thisArg, args); 20279 return result; 20280 } 20281 function leadingEdge(time) { 20282 // Reset any `maxWait` timer. 20283 lastInvokeTime = time; 20284 // Start the timer for the trailing edge. 20285 timerId = setTimeout(timerExpired, wait); 20286 // Invoke the leading edge. 20287 return leading ? invokeFunc(time) : result; 20288 } 20289 function remainingWait(time) { 20290 var timeSinceLastCall = time - lastCallTime, 20291 timeSinceLastInvoke = time - lastInvokeTime, 20292 timeWaiting = wait - timeSinceLastCall; 20293 return maxing ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting; 20294 } 20295 function shouldInvoke(time) { 20296 var timeSinceLastCall = time - lastCallTime, 20297 timeSinceLastInvoke = time - lastInvokeTime; 20298 20299 // Either this is the first call, activity has stopped and we're at the 20300 // trailing edge, the system time has gone backwards and we're treating 20301 // it as the trailing edge, or we've hit the `maxWait` limit. 20302 return lastCallTime === undefined || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait; 20303 } 20304 function timerExpired() { 20305 var time = now$1(); 20306 if (shouldInvoke(time)) { 20307 return trailingEdge(time); 20308 } 20309 // Restart the timer. 20310 timerId = setTimeout(timerExpired, remainingWait(time)); 20311 } 20312 function trailingEdge(time) { 20313 timerId = undefined; 20314 20315 // Only invoke if we have `lastArgs` which means `func` has been 20316 // debounced at least once. 20317 if (trailing && lastArgs) { 20318 return invokeFunc(time); 20319 } 20320 lastArgs = lastThis = undefined; 20321 return result; 20322 } 20323 function cancel() { 20324 if (timerId !== undefined) { 20325 clearTimeout(timerId); 20326 } 20327 lastInvokeTime = 0; 20328 lastArgs = lastCallTime = lastThis = timerId = undefined; 20329 } 20330 function flush() { 20331 return timerId === undefined ? result : trailingEdge(now$1()); 20332 } 20333 function debounced() { 20334 var time = now$1(), 20335 isInvoking = shouldInvoke(time); 20336 lastArgs = arguments; 20337 lastThis = this; 20338 lastCallTime = time; 20339 if (isInvoking) { 20340 if (timerId === undefined) { 20341 return leadingEdge(lastCallTime); 20342 } 20343 if (maxing) { 20344 // Handle invocations in a tight loop. 20345 clearTimeout(timerId); 20346 timerId = setTimeout(timerExpired, wait); 20347 return invokeFunc(lastCallTime); 20348 } 20349 } 20350 if (timerId === undefined) { 20351 timerId = setTimeout(timerExpired, wait); 20352 } 20353 return result; 20354 } 20355 debounced.cancel = cancel; 20356 debounced.flush = flush; 20357 return debounced; 20358 } 20359 20360 /** 20361 * @typedef {object} HeaderSet 20362 * @prop {string} id 20363 * @prop {string} text 20364 */ 20365 20366 /** 20367 * @param {string} id 20368 * @param {HeaderSet[]} array 20369 * @return {boolean} 20370 */ 20371 function isUnique(id, array) { 20372 return !array.some(function (item) { 20373 return item.id === id; 20374 }); 20375 } 20376 20377 /** 20378 * @param {HTMLElement} element 20379 * @param {HeaderSet[]} existingSets 20380 * @return {string} 20381 */ 20382 function createUniqueId(element, existingSets) {
20383 var id = element.id ? element.id : slugify(element.innerText); 20384 while (!isUnique(id, existingSets)) { 20385 id = "".concat(slugify(element.innerText), "-").concat(Math.floor(Math.random() * 100)); 20386 } 20387 return id; 20388 } 20389 20390 /** 20391 * @param {HeaderSet} set 20392 * @return {string} 20393 */ 20394 function makeListItem(set) { 20395 return "\n <li class=\"msk-nav-widget__list-item\">\n <a href=\"#".concat(set.id, "\" class=\"msk-nav-widget__link\" tabindex=\"0\">").concat(set.text, "</a>\n </li>\n ").trim(); 20396 } 20397 20398 // Test/implement passive event support. 20399 // Greatly improves event performance for browsers that do. 20400 var passiveSupported = false; 20401 try { 20402 var options = { 20403 get passive() { 20404 passiveSupported = true; 20405 return false; 20406 } 20407 }; 20408 window.addEventListener('test', null, options); 20409 window.removeEventListener('test', null, options); 20410 } catch (err) { 20411 passiveSupported = false; 20412 } 20413 function enableNavWidget() { 20414 var sets = []; 20415 var navWidget = document.querySelector('.msk-nav-widget'); 20416 if (!navWidget) return; 20417 var widgetList = navWidget.querySelector('.msk-nav-widget__list'); 20418 // Build sets variable 20419 document.querySelectorAll('[class$="__accordion-title"]').forEach(function (header) { 20420 var uniqueId = createUniqueId(header, sets); 20421 header.setAttribute('id', uniqueId); 20422 sets.push({ 20423 text: header.innerText, 20424 id: uniqueId 20425 }); 20426 }); 20427 if (sets.length > 0) { 20428 widgetList.innerHTML = sets.map(makeListItem).join('\n'); 20429 } 20430 var listLinks = Array.from(navWidget.querySelectorAll('.msk-nav-widget__link')); 20431 var parentLinks = navWidget.querySelectorAll('.msk-nav-widget__list-item'); 20432 if (parentLinks.length > 0) { 20433 parentLinks.forEach(function (x) { 20434 return x.setAttribute('data-nav-state', 'inactive'); 20435 }); 20436 parentLinks[0].setAttribute('data-nav-state', 'active'); 20437 } 20438 var sections = document.querySelectorAll(listLinks.map(function (listLink) { 20439 return listLink.getAttribute('href'); 20440 }).join(', ')); 20441 var elementsAboveFold = new Set(); 20442 function getLastValue(set) { 20443 return set[set.length - 1]; 20444 } 20445 function findActiveItemOnScroll() { 20446 // Link highlight logic. 20447 listLinks.forEach(function (listLink) { 20448 var listId = listLink.getAttribute('href').replace('#', ''); 20449 var section = Array.from(sections).find(function (s) { 20450 return s.id === listId; 20451 }); 20452 var linkParent = listLink.parentNode; 20453 // Subtract 20 from the threashold for when the heading 20454 // triggers highlighting the menu item. This helps ensure that 20455 // when clicking the a nav menu item, the clicked link will be 20456 // highlighted, instead of the one above it. Highlighting the 20457 // above element can occur because of, I assume, pixel rounding 20458 // in the browser, since 1px down will trigger the highlight. 20459 // The 20 pixel value is abitrary. 20460 if (section.offsetTop - 20 <= window.pageYOffset) { 20461 elementsAboveFold.add(linkParent); 20462 } else { 20463 elementsAboveFold.delete(linkParent); 20464 } 20465 }); 20466 if (elementsAboveFold.size >= 1) { 20467 parentLinks.forEach(function (element) { 20468 element.setAttribute('data-nav-state', 'inactive'); 20469 }); 20470 var currentlyActive = getLastValue(_toConsumableArray(elementsAboveFold)); 20471 currentlyActive.setAttribute('data-nav-state', 'active'); 20472 } 20473 } 20474 var debounceScrollEvent = debounce(findActiveItemOnScroll, 10); 20475 window.addEventListener('scroll', debounceScrollEvent, passiveSupported); 20476 } 20477 20478 function handleRevealCallouts() { 20479 var revealItems = document.querySelectorAll('.msk-rich-callout--has-select-action-reveal'); 20480 if (revealItems.length === 0) { 20481 return; 20482 } 20483 revealItems.forEach(function (revealItem) { 20484 var descriptions = revealItem.querySelectorAll('.msk-rich-callout__select-description'); 20485 var _revealItem$querySele = revealItem.querySelectorAll('.msk-rich-callout__select'), 20486 _revealItem$querySele2 = _slicedToArray(_revealItem$querySele, 1), 20487 select = _revealItem$querySele2[0]; 20488 select.addEventListener('change', function (_ref) { 20489 var value = _ref.detail.value; 20490 descriptions.forEach(function (d) { 20491 return d.classList.remove('msk-rich-callout__select-description--visible'); 20492 }); 20493 descriptions.forEach(function (d) { 20494 console.log(d.dataset, d.dataset.id === value); 20495 }); 20496 var currentDescription = Array.from(descriptions).find(function (d) { 20497 return d.dataset.id === value; 20498 }); 20499 if (!currentDescription) { 20500 console.error("Could not find a description that has selector \".msk-rich-callout__select-description[data-id='".concat(value, "']\" to reveal as current open description"), { 20501 revealItem: revealItem 20502 }); 20503 return; 20504 } 20505 currentDescription.classList.add('msk-rich-callout__select-description--visible'); 20506 }); 20507 }); 20508 } 20509 function handleGoToCallouts() { 20510 var goToItems = document.querySelectorAll('.msk-rich-callout--has-select-action-goto'); 20511 if (goToItems.length === 0) { 20512 return; 20513 }
20514 goToItems.forEach(function (goToItem) { 20515 var _goToItem$querySelect = goToItem.querySelectorAll('.msk-rich-callout__select'), 20516 _goToItem$querySelect2 = _slicedToArray(_goToItem$querySelect, 1), 20517 select = _goToItem$querySelect2[0]; 20518 select.addEventListener('change', function (_ref2) { 20519 var value = _ref2.detail.value; 20520 // @todo check if this looks like a URL 20521 window.location = value; 20522 }); 20523 }); 20524 } 20525 function enableRichCallout() { 20526 handleRevealCallouts(); 20527 handleGoToCallouts(); 20528 } 20529 20530 function enableSiteNavigation() { 20531 var navSwitch = parseInt(mskBreakpointWidthNavSwitch.replace("px", "")); 20532 var mobileMenuLinks = document.querySelector(".msk-site-navigation__primary-links"); 20533 var navScrollTop = 0; 20534 if (window.innerWidth < navSwitch) { 20535 document.getElementById('msk-site-navigation__primary-links').setAttribute('inert', true); 20536 Array.from(mobileMenuLinks.querySelectorAll("a")).forEach(function (link) { 20537 link.setAttribute("tabindex", "-1"); 20538 }); 20539 } 20540 20541 // toggle mobile drawers 20542 window.addEventListener("click", function (e) { 20543 if (window.innerWidth < navSwitch) { 20544 // nav drawer 20545 if (e.target.closest(".msk-site-navigation__nav-toggle")) { 20546 var _document$querySelect, _document$getElementB; 20547 var button = e.target.closest("button"); 20548 var drawer = document.getElementById("msk-site-navigation__primary-links"); 20549 20550 // isExpanded is reversed.. if the drawer is currently closed, isExpanded === false 20551 var isExpanded = button.getAttribute("aria-expanded") === "true"; 20552 button.setAttribute("aria-expanded", isExpanded ? "false" : "true"); 20553 drawer.classList.toggle("is-expanded", isExpanded ? false : true); 20554 document.documentElement.dataset.isMobileNavExpanded = !isExpanded; 20555 document.documentElement.dataset.navDrawer = !isExpanded; 20556 20557 // force other drawer closed 20558 (_document$querySelect = document.querySelector(".msk-site-navigation__search-toggle-button")) === null || _document$querySelect === void 0 ? void 0 : _document$querySelect.setAttribute("aria-expanded", "false"); 20559 (_document$getElementB = document.getElementById("coveo-header-search-box")) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.classList.remove("is-expanded"); 20560 document.documentElement.dataset.isMobileSearchExpanded = false; 20561 document.documentElement.dataset.searchDrawer = false; 20562 Array.from(document.querySelectorAll(".content-main, .region-footer")).forEach(function (el) { 20563 return el.inert = !isExpanded; 20564 }); 20565 Array.from(mobileMenuLinks.querySelectorAll("a")).forEach(function (link) { 20566 link.setAttribute("tabindex", "-1"); 20567 }); 20568 if (!isExpanded) { 20569 drawer.removeAttribute('inert'); 20570 _updateTabIndices(drawer); 20571 } else { 20572 drawer.setAttribute('inert', true); 20573 } 20574 button.addEventListener("keydown", function (e) { 20575 if (e.key === "Escape") { 20576 closeDrawer(drawer); 20577 } 20578 }); 20579 } 20580 20581 // search drawer .. Removed since Coveo's gone. 20582 // if (window.drupalSettings.msk_search_coveo === 'coveo') { 20583 20584 // if (e.target.closest(".msk-site-navigation__search-toggle-button")) { 20585 // const button = e.target.closest("button"); 20586 // const drawer = document.getElementById("coveo-header-search-box"); 20587 20588 // // isExpanded is reversed.. if the drawer is currently closed, isExpanded === false 20589 // const isExpanded = button.getAttribute("aria-expanded") === "true"; 20590 20591 // button.setAttribute("aria-expanded", isExpanded ? "false" : "true"); 20592 // drawer.classList.toggle("is-expanded", isExpanded ? false : true); 20593 // document.documentElement.dataset.isMobileSearchExpanded = !isExpanded; 20594 // document.documentElement.dataset.searchDrawer = !isExpanded; 20595 20596 // // force other drawer closed 20597 // document 20598 // .querySelector(".msk-site-navigation__nav-toggle") 20599 // ?.setAttribute("aria-expanded", "false"); 20600 // document 20601 // .getElementById("msk-site-navigation__primary-links") 20602 // .classList.remove("is-expanded"); 20603 // document.documentElement.dataset.isMobileNavExpanded = false;
20604 // document.documentElement.dataset.navDrawer = false; 20605 20606 // Array.from( 20607 // document.querySelectorAll(".content-main, .region-footer"), 20608 // ).forEach((el) => (el.inert = !isExpanded)); 20609 20610 // if (!isExpanded) { 20611 // updateTabIndices(drawer); 20612 // } 20613 20614 // button.addEventListener("keydown", function (e) { 20615 // if (e.key === "Escape") { 20616 // closeDrawer(drawer); 20617 // } 20618 // }); 20619 // } 20620 // } 20621 } 20622 }); 20623 var DisclosureNav = /*#__PURE__*/function () { 20624 function DisclosureNav(domNode) { 20625 var _this = this; 20626 _classCallCheck$1(this, DisclosureNav); 20627 this.rootNode = domNode; 20628 this.controlledNodes = []; 20629 this.openIndex = null; 20630 this.useArrowKeys = true; 20631 this.topLevelNodes = _toConsumableArray(this.rootNode.querySelectorAll(".msk-site-navigation__utility-links--masthead .msk-site-navigation__utility-item > .msk-site-navigation__utility-link,\n .msk-site-navigation__primary-link-item > .msk-site-navigation__primary-link,\n .msk-site-navigation__primary-link--utility-links .msk-site-navigation__utility-item > .msk-site-navigation__utility-link")); 20632 this.topLevelNodes.forEach(function (node) { 20633 // handle button + menu 20634 if (node.hasAttribute("aria-controls")) { 20635 var menu = document.getElementById(node.getAttribute("aria-controls")); 20636 if (menu) { 20637 // save ref controlled menu 20638 _this.controlledNodes.push(menu); 20639 20640 // collapse menus 20641 node.setAttribute("aria-expanded", "false"); 20642 _this.toggleMenu(menu, false, true); 20643 20644 // attach event listeners 20645 menu.addEventListener("keydown", _this.onMenuKeyDown.bind(_this)); 20646 menu.addEventListener("click", _this.onBackClick.bind(_this)); 20647 node.addEventListener("click", _this.onButtonClick.bind(_this)); 20648 node.addEventListener("keydown", _this.onButtonKeyDown.bind(_this)); 20649 } 20650 } 20651 // handle links 20652 else { 20653 _this.controlledNodes.push(null); 20654 node.addEventListener("keydown", _this.onLinkKeyDown.bind(_this)); 20655 } 20656 }); 20657 this.rootNode.addEventListener("focusout", this.onBlur.bind(this)); 20658 } 20659 return _createClass$1(DisclosureNav, [{ 20660 key: "controlFocusByKey", 20661 value: function controlFocusByKey(keyboardEvent, nodeList, currentIndex) { 20662 switch (keyboardEvent.key) { 20663 case "ArrowUp": 20664 case "ArrowLeft": 20665 keyboardEvent.preventDefault(); 20666 if (currentIndex > -1) { 20667 var prevIndex = Math.max(0, currentIndex - 1); 20668 nodeList[prevIndex].focus(); 20669 } 20670 break; 20671 case "ArrowDown": 20672 case "ArrowRight": 20673 keyboardEvent.preventDefault(); 20674 if (currentIndex > -1) { 20675 var nextIndex = Math.min(nodeList.length - 1, currentIndex + 1); 20676 nodeList[nextIndex].focus(); 20677 } 20678 break; 20679 case "Home": 20680 keyboardEvent.preventDefault(); 20681 nodeList[0].focus(); 20682 break; 20683 case "End": 20684 keyboardEvent.preventDefault(); 20685 nodeList[nodeList.length - 1].focus(); 20686 break; 20687 } 20688 } 20689 20690 // public function to close open menu 20691 }, { 20692 key: "close", 20693 value: function close() { 20694 this.toggleExpand(this.openIndex, false); 20695 } 20696 }, { 20697 key: "onBlur", 20698 value: function onBlur(event) { 20699 // this makes trouble on mobile 20700 if (window.innerWidth >= navSwitch) { 20701 var menuContainsFocus = this.rootNode.contains(event.relatedTarget); 20702 if (!menuContainsFocus && this.openIndex !== null) { 20703 this.toggleExpand(this.openIndex, false); 20704 } 20705 } 20706 } 20707 }, { 20708 key: "onButtonClick", 20709 value: function onButtonClick(event) { 20710 var button = event.target.closest("a"); 20711 if (button.hasAttribute("aria-controls")) { 20712 event.preventDefault(); 20713 var buttonIndex = this.topLevelNodes.indexOf(button); 20714 var buttonExpanded = button.getAttribute("aria-expanded") === "true"; 20715 this.toggleExpand(buttonIndex, !buttonExpanded); 20716 } 20717 } 20718 }, { 20719 key: "onBackClick", 20720 value: function onBackClick(event) { 20721 var backLink = event.target.closest("a"); 20722 if (backLink.hasAttribute("aria-controls")) { 20723 event.preventDefault(); 20724 this.toggleExpand(this.openIndex, false); 20725 } 20726 } 20727 }, { 20728 key: "onButtonKeyDown", 20729 value: function onButtonKeyDown(event) { 20730 var targetButtonIndex = this.topLevelNodes.indexOf(document.activeElement); 20731 20732 // close on escape 20733 if (event.key === "Escape") { 20734 if (parseInt(this.openIndex) >= 0) { 20735 this.toggleExpand(this.openIndex, false); 20736 } else { 20737 closeDrawer(document.getElementById("msk-site-navigation__primary-links")); 20738 } 20739 } 20740 20741 // move focus into the open menu if the current menu is open 20742 else if (this.useArrowKeys && this.openIndex === targetButtonIndex && event.key === "ArrowDown") { 20743 event.preventDefault(); 20744 this.controlledNodes[this.openIndex].querySelector("a").focus(); 20745 } 20746 20747 // handle arrow key navigation between top-level buttons, if set 20748 else if (this.useArrowKeys) { 20749 this.controlFocusByKey(event, this.topLevelNodes, targetButtonIndex); 20750 } 20751 } 20752 }, { 20753 key: "onLinkKeyDown", 20754 value: function onLinkKeyDown(event) { 20755 var targetLinkIndex = this.topLevelNodes.indexOf(document.activeElement); 20756 20757 // handle arrow key navigation between top-level buttons, if set 20758 if (this.useArrowKeys) { 20759 this.controlFocusByKey(event, this.topLevelNodes, targetLinkIndex); 20760 } 20761 } 20762 }, { 20763 key: "onMenuKeyDown", 20764 value: function onMenuKeyDown(event) { 20765 if (this.openIndex === null) { 20766 return; 20767 } 20768 var menuLinks = Array.prototype.slice.call(this.controlledNodes[this.openIndex].querySelectorAll("a")); 20769 var currentIndex = menuLinks.indexOf(document.activeElement); 20770 20771 // close on escape 20772 if (event.key === "Escape") { 20773 this.toggleExpand(this.openIndex, false); 20774 } 20775 20776 // handle arrow key navigation within menu links, if set 20777 else if (this.useArrowKeys) { 20778 this.controlFocusByKey(event, menuLinks, currentIndex); 20779 } 20780 } 20781 }, { 20782 key: "toggleExpand", 20783 value: function toggleExpand(index, expanded) { 20784 // close open menu, if applicable 20785 if (this.openIndex !== index) { 20786 this.toggleExpand(this.openIndex, false); 20787 } 20788
20789 // handle menu at called index 20790 if (this.topLevelNodes[index]) { 20791 this.openIndex = expanded ? index : null; 20792 this.topLevelNodes[index].setAttribute("aria-expanded", expanded); 20793 this.toggleMenu(this.controlledNodes[index], expanded); 20794 } 20795 } 20796 }, { 20797 key: "toggleMenu", 20798 value: function toggleMenu(domNode, show) { 20799 var isInit = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; 20800 if (domNode) { 20801 domNode.classList.toggle("is-expanded", show); 20802 if (show) { 20803 _updateTabIndices(domNode); 20804 if (window.innerWidth < navSwitch) { 20805 var _domNode$querySelecto; 20806 navScrollTop = document.documentElement.scrollTop; 20807 document.documentElement.scrollTop = document.getElementById("msk-site-navigation").offsetTop; 20808 mobileMenuLinks.style.height = ((_domNode$querySelecto = domNode.querySelector(".msk-site-navigation__submenu-inner")) === null || _domNode$querySelecto === void 0 ? void 0 : _domNode$querySelecto.offsetHeight) + "px"; 20809 20810 // This was choking if trying to fire immediately. 20811 var backButton = domNode.querySelector(".msk-site-navigation__mobile-back"); 20812 if (backButton) { 20813 window.setTimeout(function () { 20814 backButton.focus(); 20815 }, 150); 20816 } 20817 } 20818 } else { 20819 _updateTabIndices(domNode, true); 20820 if (window.innerWidth < navSwitch) { 20821 if (!isInit) { 20822 var parentMenuItem = document.querySelector("[aria-controls=\"".concat(domNode.id, "\"]")); 20823 mobileMenuLinks.style.height = ""; 20824 document.documentElement.scrollTop = navScrollTop; 20825 parentMenuItem.focus(); 20826 } 20827 } 20828 } 20829 } 20830 } 20831 }, { 20832 key: "updateKeyControls", 20833 value: function updateKeyControls(useArrowKeys) { 20834 this.useArrowKeys = useArrowKeys; 20835 } 20836 }]); 20837 }(); 20838 var closeDrawer = function closeDrawer(drawer) { 20839 if (window.innerWidth >= navSwitch) return; 20840 var button = document.querySelector(".msk-site-navigation__nav-toggle"); 20841 button.setAttribute("aria-expanded", "false"); 20842 drawer.classList.remove("is-expanded"); 20843 if (drawer.id === "msk-site-navigation__primary-links") { 20844 document.documentElement.dataset.isMobileNavExpanded = false; 20845 document.documentElement.dataset.navDrawer = false; 20846 Array.from(mobileMenuLinks.querySelectorAll("a")).forEach(function (link) { 20847 link.setAttribute("tabindex", "-1"); 20848 }); 20849 button.focus(); 20850 } 20851 if (drawer.id === "coveo-header-search-box") { 20852 document.documentElement.dataset.isMobileSearchExpanded = false; 20853 document.documentElement.dataset.searchDrawer = false; 20854 } 20855 }; 20856 var _updateTabIndices = function updateTabIndices(menu) { 20857 var reset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; 20858 if (window.innerWidth >= navSwitch) return; 20859 if (!menu) return; 20860 if (reset) { 20861 var drawer = document.getElementById("msk-site-navigation__primary-links"); 20862 _updateTabIndices(drawer); 20863 return; 20864 } 20865 Array.from(mobileMenuLinks.querySelectorAll("a")).forEach(function (link) { 20866 link.setAttribute("tabindex", "-1"); 20867 }); 20868 var links; 20869 if (menu.id == "msk-site-navigation__primary-links") { 20870 links = Array.from(menu.querySelectorAll(".msk-site-navigation__primary-link-item > a, .msk-site-navigation__utility-item > a")); 20871 } else { 20872 links = Array.from(menu.querySelectorAll("a")); 20873 } 20874 if (!links.length) return; 20875 links.forEach(function (el) { 20876 el.setAttribute("tabindex", "0"); 20877 }); 20878 }; 20879 20880 /* Initialize Disclosure Menus */ 20881 window.addEventListener("load", function () { 20882 var menus = document.querySelectorAll(".msk-site-navigation__utility-links--masthead,\n .msk-site-navigation__primary-links"); 20883 for (var i = 0; i < menus.length; i++) { 20884 new DisclosureNav(menus[i]); 20885 } 20886 }, false); 20887 } 20888 20889 var isEnabled = false;
20890 20891 /** 20892 * Move Slider 20893 * @param {Event} event 20894 * @returns {void} 20895 */ 20896 function moveSlider(event) { 20897 var tab = event.target; 20898 if (tab.classList.contains('msk-tabs__tab--disabled')) return; 20899 var tabs = tab.closest('.msk-tabs'); 20900 // set accessibility and panel display properties. 20901 tabs.querySelectorAll('[aria-hidden]').forEach(function (panel) { 20902 return panel.setAttribute('aria-hidden', 'true'); 20903 }); 20904 document.getElementById("".concat(tab.getAttribute('aria-controls'))).setAttribute('aria-hidden', 'false'); 20905 tabs.querySelectorAll('[aria-selected]').forEach(function (t) { 20906 return t.setAttribute('aria-selected', 'false'); 20907 }); 20908 tab.setAttribute('aria-selected', 'true'); 20909 } 20910 function enableTabs() { 20911 // Only enable once, since we're using event delegation. 20912 if (isEnabled) return; 20913 isEnabled = true; 20914 on('pointerup', '.msk-tabs__tab', moveSlider); 20915 on('keyup', '.msk-tabs__tab', moveSlider); 20916 document.querySelectorAll('.msk-tabs').forEach(function (tabs) { 20917 moveSlider({ 20918 target: tabs.getElementsByClassName('msk-tabs__tab')[0] 20919 }); 20920 }); 20921 } 20922 20923 function enableVideo() { 20924 const players = Array.from( 20925 document.querySelectorAll('.msk-video__player__cloudflare .msk-cfplayer'), 20926 ); 20927 let cfPlayers = []; 20928 window.dataLayer = window.dataLayer || []; 20929 20930 players.forEach((p) => { 20931 let player = window.Stream(p); 20932 player.preload = true; 20933 20934 cfPlayers.push({ 20935 [p.id]: player, 20936 }); 20937 20938 const playButton = p 20939 .closest('.msk-video__player') 20940 .querySelector('.msk-cfplayer__poster'); 20941 if (playButton) { 20942 playButton.onclick = function () { 20943 playButton.hidden = true; 20944 player.play().catch(() => { 20945 console.log("Player didn't start properly; trying again."); 20946 player.play(); 20947 }); 20948 }; 20949 } 20950 20951 20952 // Instantiate these vars for use later during the `playing` event 20953 let duration = 0; 20954 let firstQuarter = 0; 20955 let secondQuarter = 0; 20956 let thirdQuarter = 0; 20957 let firedFirstQuarter = false; 20958 let firedSecondQuarter = false; 20959 let firedThirdQuarter = false; 20960 20961 const eventLabel = p.dataset.cfid + ' | ' + p.dataset.cftitle ?? ''; 20962 const pushToHeap = (eventAction = '', eventLabel = '') => { 20963 window.dataLayer.push({ 20964 event: 'videoEvent', 20965 videoCategory: 'Cloudflare Player', 20966 videoAction: eventAction, 20967 videoLabel: eventLabel, 20968 }); 20969 console.log(eventAction); 20970 }; 20971 20972 player.addEventListener('loadedmetadata', () => { 20973 // Populate these vars for use later during the `playing` event 20974 duration = player.duration; 20975 firstQuarter = Math.floor(duration / 4); 20976 secondQuarter = firstQuarter * 2; 20977 thirdQuarter = firstQuarter * 3; 20978 20979 pushToHeap('Video Load', eventLabel); 20980 }); 20981 20982 player.addEventListener('timeupdate', () => { 20983 const t = player.currentTime; 20984 if (duration !== 0) { 20985 if (t >= firstQuarter && !firedFirstQuarter) { 20986 pushToHeap('25% Milestone Passed', eventLabel); 20987 firedFirstQuarter = true; 20988 } 20989 20990 if (t >= secondQuarter && !firedSecondQuarter) { 20991 pushToHeap('50% Milestone Passed', eventLabel); 20992 firedSecondQuarter = true; 20993 } 20994 20995 if (t >= thirdQuarter && !firedThirdQuarter) { 20996 pushToHeap('75% Milestone Passed', eventLabel); 20997 firedThirdQuarter = true; 20998 } 20999 } 21000 }); 21001 21002 player.addEventListener('play', () => { 21003 const t = player.currentTime; 21004 if (t == 0) { 21005 pushToHeap('Media Begin', eventLabel); 21006 } else { 21007 pushToHeap('Media Play', eventLabel); 21008 if (playButton) { 21009 playButton.hidden = true; 21010 } 21011 } 21012 p.classList.add('msk-video--is-playing'); 21013 p.classList.remove('msk-video--is-paused'); 21014 }); 21015 21016 player.addEventListener('pause', () => { 21017 const t = player.currentTime; 21018 // don't log pause event when video ends 21019 if (t >= duration) return; 21020 pushToHeap('Media Pause', eventLabel); 21021 p.classList.remove('msk-video--is-playing'); 21022 p.classList.add('msk-video--is-paused'); 21023 }); 21024 21025 player.addEventListener('ended', () => { 21026 pushToHeap('Media Complete', eventLabel); 21027 }); 21028 21029 document.addEventListener('fullscreenchange', () => { 21030 p.classList.toggle( 21031 'msk-video--is-fullscreen', 21032 p === document.fullscreenElement, 21033 ); 21034 }); 21035 }); 21036 21037 window.cfPlayers = cfPlayers; 21038 } 21039 21040 document.addEventListener('DOMContentLoaded', function () { 21041 enableActions(); 21042 enableBackToTop(); 21043 enableCarousel(); 21044 enableDropdownList(); 21045 enableFooterAccordions(); 21046 enableHeroClick(); 21047 enableHeroCarousel(); 21048 enableMap(); 21049 enableMessage(); 21050 enableModals(); 21051 enableNavWidget(); 21052 // enableRadios(); 21053 enableRichCallout(); 21054 enableSiteNavigation(); 21055 enableTabs(); 21056 }); 21057 if ((typeof Drupal === "undefined" ? "undefined" : _typeof$1(Drupal)) === 'object') { 21058 (function (Drupal, once) { 21059 Drupal.behaviors.enableVideo = { 21060 attach: function attach(context) { 21061 enableVideo(); 21062 } 21063 }; 21064 })(Drupal, once); 21065 } else { 21066 document.addEventListener('DOMContentLoaded', function () { 21067 enableVideo(); 21068 }); 21069 } 21070 21071})(); 21072; 21073var APP=window.APP=window.APP||{};APP.global=(function global(){'use strict';var initGlobalComponents=function initGlobalComponents(){try{APP.vars.init();}catch(err){console.error('Error caught while trying to init "vars": ',err);}try{APP.mskVideo.init();}catch(err){console.error('Error caught while trying to init "mskVideo": ',err);}try{APP.forms.init();}catch(err){console.error('Error caught while trying to init "forms": ',err);}try{APP.containerTile.init();}catch(err){console.error('Error caught while trying to init "containerTile": ',err);}try{APP.baseBallCard.init();}catch(err){console.error('Error caught while trying to init "baseBallCard": ',err);}try{APP.navigateMenu.init();}catch(err){console.error('Error caught while trying to init "navigateMenu": ',err);}try{APP.artWalk.init();}catch(err){console.error('Error caught while trying to init "artWalk": ',err);}try{APP.listFilter.init();}catch(err){console.error('Error caught while trying to init "listFilter": ',err);}};
21073var init=function init(){initGlobalComponents();};return {init};}());document.addEventListener('DOMContentLoaded',APP.global.init);; 21074Drupal.behaviors.accordionContainer={attach:function(e,r){once("accordionContainer",".msk-accordion-container").forEach(function(e){e.querySelector(".msk-accordion")&&Array.from(e.querySelectorAll(".msk-accordion")).forEach(r=>{r.querySelector(".msk-details__toggle").addEventListener("click",o=>{if("true"==r.dataset.open)return;const a=o.target.closest(".msk-details");Array.from(e.querySelectorAll(".msk-details[data-open='true']")).forEach(e=>{e!=a&&(e.dataset.open="false")})})})})}};; 21075Drupal.behaviors.details={attach:function(t,a){document.querySelector(".node--view-mode-search-index")||(once("mskDetails",".msk-details").forEach(function(e){const t=e.querySelector(".msk-details__toggle");t.addEventListener("click",t=>{t.preventDefault(),e.dataset.open="true"==e.dataset.open?"false":"true"}),new MutationObserver((e,a)=>{for(const a of e)if("data-open"==a.attributeName){const e="true"==a.target.dataset.open;t.setAttribute("aria-expanded",e?"true":"false")}}).observe(e,{attributes:!0,childList:!1,subtree:!1})}),window.addEventListener("hashchange",e=>{const t=window.matchMedia("(max-width: 834px)"),a=new URL(e.newURL).hash,o=document.querySelectorAll(`${a}, a[name="${a.replace("#","")}"]`);if(!o.length)return;const n=o[0],s=n.closest(".msk-details");if(s)if(s.dataset.open="true",t.matches){let e=n.getBoundingClientRect().top+document.documentElement.scrollTop;document.querySelector(".msk-side-navigation")&&(e-=document.querySelector(".msk-side-navigation").getBoundingClientRect().height,e-=12),window.scrollTo({top:e})}else n.scrollIntoView(!0)}),window.addEventListener("beforeprint",t=>{for(e of(elms=document.body.querySelectorAll(".msk-details:not([data-open='true'])"),elms))e.dataset.open="true",e.dataset.wasclosed=""}),window.addEventListener("afterprint",t=>{for(e of(elms=document.body.querySelectorAll(".msk-details[data-wasclosed]"),elms))e.dataset.open="false",delete e.dataset.wasclosed}))}};; 21076(()=>{var e={6871(){(window.APP=window.APP||{}).containerTile=function(e){"use strict";return {init:function(){e(".container-tile--video, .container-tile--video-2").on("click",function(t){e(this).find(".video-modal-trigger").length&&t.preventDefault();}),e(".container-tile__link").on("click",function(){e(this).parents(".container-tile--video, .container-tile--video-2").find(".video-modal-trigger").trigger("click");}),window.matchMedia("(max-width:992px)").matches&&e(".container-tile").not(".container-tile--text").removeAttr("style");}};}(jQuery);},80(){(window.APP=window.APP||{}).listFilter=function(){"use strict";function e(e){const t=e.target,n=e.target.nextElementSibling,a=JSON.parse(n.dataset.listContents).filter((e)=>e.label.toLowerCase().includes(t.value.toLowerCase())).reduce((e,t)=>e+`<li><a href="${t.href}">${t.label}</a></li>`,"");n.innerHTML=a;}function t(t){t.addEventListener("input",e);}return {init:function(){const e=document.querySelectorAll(".get-started__filter");e&&Array.from(e).forEach(t);}};}();},1984(){(window.APP=window.APP||{}).navigateMenu=function(e){"use strict";var t=e(window),n=e("body, html"),a=function(){e(".navigate-menu__list__link").on("click",function(t){t.preventDefault();var a=e(this.hash).offset().top-105;n.animate({scrollTop:a},"500","swing");});},i=function(n){var a,i;window.matchMedia(n).matches?(a=e(".navigate-section"),i=e(".navigate-menu__list__link"),t.on("scroll",function(){for(var e=a.length-1;e>=0;e--)if(a.eq(e).offset().top<t.scrollTop()+100){i.removeClass("navigate-menu__list__link--active").eq(e).addClass("navigate-menu__list__link--active");break;}a.eq(0).offset().top>t.scrollTop()+100&&i.removeClass("navigate-menu__list__link--active");})):t.unbind("scroll");};return {init:function(e){!function(e){i(e),a();}(e);}};}(jQuery);},9658(){(window.APP=window.APP||{}).mskVideo=function(){"use strict";return {init:function(){document.addEventListener("DOMContentLoaded",()=>{const e=document.querySelectorAll(".vjs-playlist");e.length&&e.forEach((e)=>
21076{const t=document.querySelector(`[data-playlist-id="${e.dataset.playlistId}"]`);t&&window.bc(t);});});}};}();},2725(){(window.APP=window.APP||{}).artWalk=function(){"use strict";return {init:function(){document.querySelector(".art-walk-map__link")&&document.documentElement.addEventListener("pointerup",function(e){const t=e.target.closest(".art-walk-map__link");if(!t)return !1;const n=document.querySelector(t.getAttribute("xlink:href"));if(!n)return !1;n.scrollIntoView({behavior:"smooth"}),window.history.pushState({},"art walk map link",t.getAttribute("xlink:href")),window.dataLayer.push({event:"mapClick",eventLabel:t.id});},!1);}};}();},4905(){(window.APP=window.APP||{}).forms=function(e){"use strict";var t=e(".form-keyboard-letter"),n=e(".form-by-letter-select");return {init:function(){var a,i;a=document.querySelector(".js-datepicker"),i='<svg width="9" height="12" viewBox="0 0 9 12" xmlns="http://www.w3.org/2000/svg"><title>right-arrow</title><path d="M1.632 12c-.41 0-.82-.15-1.077-.5-.565-.601-.513-1.502.102-2.054l3.848-3.405L.504 2.537A1.463 1.463 0 0 1 .35.484c.564-.601 1.488-.65 2.103-.1L7.737 5.04c.308.25.513.65.513 1.051 0 .401-.154.801-.513 1.052L2.659 11.6c-.308.3-.668.4-1.027.4z" fill="#1C75CD" fill-rule="nonzero"/></svg>',e(".form-info-shade__trigger").on("click",function(){e(this).parent(".form-info-shade").toggleClass("form-info-shade--collapsed");}),e(".form-keyboard").on("click",".form-keyboard-letter",function(a){a.preventDefault();var i=e(this);i.hasClass("disabled")||i.hasClass("active")||(t.removeClass("active"),i.addClass("active"),n.data("helper-active")===e(a.delegateTarget).attr("id")&&n.val(i.data("letter")));}),e(".form-by-letter-select").on("change",function(){var n=e(this);t.removeClass("active"),t.each(function(){var t=e(this);t.data("letter")===n.val()&&t.addClass("active");});}),a&&(new MutationObserver(function(e){e.forEach(function(e){e.addedNodes.forEach(function(e){e.classList&&e.classList.contains("ui-datepicker-header")&&(e.querySelector(".ui-datepicker-prev").innerHTML=i,e.querySelector(".ui-datepicker-next").innerHTML=i);});});}).observe(document.body,{subtree:!0,childList:!0}),e(a).datepicker({showOn:"both",buttonText:"Choose",showOptions:{direction:"down"}}));}};}(jQuery);},698(){(window.APP=window.APP||{}).vars=function(){"use strict";return Element.prototype.matches=Element.prototype.matches||Element.prototype.msMatchesSelector,{init:function(){},screen:{xs:480,sm:768,md:992,lg:1200,nav:950},fetch:{isOK:function(e){if(e.ok)return e;throw Error(e.status+" "+e.statusText+" attempting "+e.url);},checkStatus:function(e){return e.status>=200&&e.status<300?Promise.resolve(e):Promise.reject(new Error(e.statusText));},parseJson:function(e){return e.json();},error:function(e){return Promise.reject(e);}},getUrlParams:function(){var e,t={},n=/\+/g,a=/([^&=]+)=?([^&]*)/g,i=window.location.search.substring(1);function o(e){return decodeURIComponent(e.replace(n," "));}for(;e=a.exec(i);)t[o(e[1])]=o(e[2]);return t;}};}();},6819(){(window.APP=window.APP||{}).baseBallCard=function(){"use strict";var e=document.querySelectorAll("[data-callout-open]");return {init:function(){(document.querySelector("[data-callout-id]")||document.getElementById("algolia-doctor-search-box-container"))&&(document.documentElement.addEventListener("click",function(e){const t=e.target.closest(".baseball-card__callout-title[data-callout-id]");if(!t||window.innerWidth>=950)return !1;const n=t.parentNode.querySelector('.baseball-card__callout-body[data-callout-id="'+t.getAttribute("data-callout-id")+'"]');"true"===n.getAttribute("data-callout-open")?(n.setAttribute("data-callout-open","false"),t.setAttribute("data-callout-open","false")):(n.setAttribute("data-callout-open","true"),t.setAttribute("data-callout-open","true"));},!1),window.matchMedia("(min-width: 950px)").matches?e.forEach(function(e){e.setAttribute("data-callout-open","true");}):e.forEach(function(e){e.setAttribute("data-callout-open","false");}));}};}();},2157(){((e)=>{document.querySelector(".msk-site-header--search");const t=150;let n=window.matchMedia("(max-width:1023px)");function a(e){const a=Array.from(document.querySelectorAll('.msk-site-navigation__primary-link[aria-expanded="true"]')),i=e.currentTarget;a.filter((e)=>
21076e!=i).forEach((e)=>{e.setAttribute("aria-expanded",!1),document.getElementById(e.getAttribute("aria-controls")).classList.remove("is-expanded");});const o="true"===i.getAttribute("data-isexpanded");i.setAttribute("aria-expanded",!o),i.dataset.isexpanded=!o;const s=document.getElementById(i.getAttribute("aria-controls"));o?(s.setAttribute("inert",!0),n.matches&&Array.from(document.querySelectorAll(".msk-site-navigation__menu-item--search")).forEach((e)=>{e.setAttribute("tabindex","0");}),setTimeout(function(){i.closest(".msk-site-navigation__menu-item")?.querySelector(".msk-site-navigation__menu-item--search")?.focus();},t)):(s.removeAttribute("inert"),setTimeout(function(){s.querySelector(".msk-site-navigation__megamenu-container").querySelector('input[type="text"]').focus(),r(s);},t),n.matches&&(Array.from(document.querySelectorAll(".msk-site-navigation__menu-item--search")).forEach((e)=>{e.setAttribute("tabindex","-1");}),setTimeout(function(){s.querySelectorAll("a, button")[0].focus();},t))),s.querySelector(".msk-site-header--search__close").setAttribute("data-isexpanded",!o);}function i(e){const t=document.querySelector(".msk-site-navigation__menu-item--search");t&&"true"==t.dataset.isexpanded&&"Escape"===e.key&&(t.dataset.isexpanded="false",t.setAttribute("aria-expanded","false"));}function o(){const e=document.querySelector("#msk-site-navigation")?.offsetHeight;if(!e)return;const t=document.documentElement.closest("html");let n=t?.style;n.setProperty("--msk-masthead-height",e+"px");}e.behaviors.headersearch={attach:function(e){once("headerSearch",".msk-site-navigation__menu-item--search").forEach((e)=>{!function(e){e.setAttribute("aria-expanded","false"),e.dataset.isexpanded="false",e.addEventListener("click",a),document.addEventListener("keydown",i),o(),window.onresize=()=>{o();};}(e);}),once("headerSearchBodyClose",".msk-site-header--search__close").forEach((e)=>{!function(e){e.addEventListener("click",function(e){const t=document.querySelector('.msk-site-navigation__menu-item--search[data-isexpanded="true"]');t&&(t.setAttribute("aria-expanded","false"),t.dataset.isexpanded=!1);});}(e);}),once("headerSearchBodyClick","body").forEach((e)=>{document.documentElement.addEventListener("click",function(e){if(e.target.closest(".msk-site-navigation__menu-item"))return !1;const t=document.querySelector('.msk-site-navigation__menu-item__link[data-isexpanded="true"]');t&&(t.setAttribute("aria-expanded","false"),t.dataset.isexpanded=!1);});});}};const r=(e)=>{let t=e.querySelectorAll('a[href], button, textarea, input[type="text"], input[type="radio"], input[type="checkbox"], input[type="submit"], select');t=Array.from(t).filter((e)=>e.checkVisibility());const n=t[0],a=t[t.length-1];e.addEventListener("keydown",function(t){("Tab"===t.key||9===t.keyCode)&&(e.querySelector(".msk-site-navigation__search-toggle-button")&&"true"!==e.querySelector(".msk-site-navigation__search-toggle-button").getAttribute("aria-expanded")||(t.shiftKey?document.activeElement===n&&(a.focus(),t.preventDefault()):document.activeElement===a&&(n.focus(),t.preventDefault())));});};e.behaviors.navDrawer={attach:function(e){once("navDrawer",".msk-site-navigation__search-toggle-button").forEach((e)=>{!function(e){e.addEventListener("click",(e)=>function(e){document.querySelectorAll("[data-isexpanded]").forEach((e)=>{e.setAttribute("data-isexpanded",!1),e.hasAttribute("aria-expanded")&&e.setAttribute("aria-expanded","false");});const n=e.target.closest("button"),a=document.getElementById(n.getAttribute("aria-controls")),i=n.classList.contains("msk-site-navigation__nav-toggle-button")?"nav":"search",o=n.classList.contains("msk-site-navigation__nav-toggle-button")?"isMobileNavExpanded":"isMobileSearchExpanded",s="true"===n.getAttribute("aria-expanded");n.setAttribute("aria-expanded",!s),s?(a.removeAttribute("aria-labelledby"),document.querySelectorAll(".msk-section--main, .msk-section--site-footer").forEach((e)=>{e.removeAttribute("inert");}),a.style.height=null):("nav"==i?(document.documentElement.dataset.searchDrawer="false",document.documentElement.dataset.isMobileSearchExpanded="false",n.previousElementSibling?.setAttribute("aria-expanded","fal
21076se"),document.querySelector(".msk-site-navigation__search-toggle-button")?.setAttribute("aria-expanded","false"),a.setAttribute("aria-labelledby","header-nav-label"),setTimeout(function(){topLevelLinks[0].focus();},t)):(document.documentElement.dataset.navDrawer="false",document.documentElement.dataset.isMobileNavExpanded="false",document.querySelector(".msk-site-navigation__primary-links").classList.remove("is-expanded"),n.nextElementSibling.setAttribute("aria-expanded","false"),document.querySelector(".msk-site-navigation__nav-toggle")?.setAttribute("aria-expanded","false"),a.style.height=null,a.setAttribute("aria-labelledby","header-search-label"),setTimeout(function(){document.getElementById("msk-header-search-drawer").removeAttribute("inert"),document.getElementById("msk-header-search-drawer")?.querySelector('input[type="text"]').focus(),r(document.getElementById("header-search"));},t)),document.querySelectorAll(".msk-section--main, .msk-section--site-footer").forEach((e)=>{e.setAttribute("inert",!0);})),document.documentElement.dataset[i+"Drawer"]=!s,document.documentElement.dataset[o]=!s;}(e)),e.setAttribute("aria-expanded","false"),document.documentElement.dataset.navDrawer="false",document.documentElement.dataset.searchDrawer="false",document.documentElement.dataset.isMobileSearchExpanded="false",document.documentElement.dataset.isMobileNavExpanded="false";}(e);});}};})(Drupal);}};const t={};function n(a){const i=t[a];if(void 0!==i)return i.exports;const o=t[a]={exports:{}};return e[a](o,o.exports,n),o.exports;}(()=>{"use strict";n(4905),n(698),n(2725),n(6871),n(80),n(1984),n(9658),n(6819),n(2157),function(e,t){Drupal.behaviors.preventExposedFormAjax={attach:function(){var t=e(".view-display-id-embed_teaser form.views-exposed-form");e("input[type=submit], input[type=image]",t).unbind();}},Drupal.behaviors.dialogStatus={attach:function(){e(t).on("dialogopen",function(){e("body").addClass("modal-open");}),e(t).on("dialogclose",function(){e("body").removeClass("modal-open");});}};}(jQuery,window);})();})();; 21077(function($,Drupal,once){"use strict";Drupal.tocFilterScrollToOnClick=function(){if(!this.hash||this.hash==='#')return true;var href=this.href.replace(/#[^#]*$/,'');var url=window.location.toString();if(href&&url.indexOf(href)===-1)return true;return Drupal.tocFilterScrollTo(this.hash);};Drupal.tocFilterScrollTo=function(hash){var $a=$("a[name='"+hash.substring(1)+"']");if(!$a.length)return true;var duration=drupalSettings.toc_filter.smooth_scroll_duration||'medium';$('html, body').animate({scrollTop:$a.offset().top},duration);$a.parent().prev('.toc-filter-back-to-top').find('a').focus();return false;};Drupal.behaviors.tocFilterSmoothScroll={attach:function(context){if(drupalSettings.toc_filter.smooth_scroll)$(once('toc-filter','a[href*="#"]',context)).click(Drupal.tocFilterScrollToOnClick);}};Drupal.behaviors.tocFilterMenu={attach:function(context){$(once('toc-filter-contents-menu-select','.toc-filter-contents-menu select')).change(function(){var hash=$(this).val();setTimeout(function(){if(drupalSettings.toc_filter.smooth_scroll)Drupal.tocFilterScrollTo(hash);else location.hash=hash;},1);});}};})(jQuery,Drupal,once);;
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.