maparea 0.1.10 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- const{PI:e}=Math,t=e/180,n=180/e,r={spherical:0,ellipsoidal:.0818191908426},i=-85.05,a=85.05,o=-180,s=180,{PI:c,sin:l,tan:u,atan:d,pow:f,exp:p,log:m,abs:h}=Math;var g=class{_p;_c;_cc;_r=new Set;constructor(e){this._p=e,this.container.style=`position: relative; overflow: hidden;`,this.container.dataset.type=`maparea`}render(){for(let e of this._r)e(this)}onRender(e,t=!1){return this._r.add(e),t||e(this),()=>{this._r.delete(e)}}getOptions(){return{...this._p,center:this.center,bounds:this.bounds}}setOptions(e){this._p={...this._p,...e},delete this._c,delete this._cc,this.render()}get container(){if(!this._c){let e=document.querySelector(this._p.container);if(!e)throw Error(`missing container element`);this._c=e}return this._c}get box(){let e=this.container.getBoundingClientRect();return{x:e.left,y:e.top,w:e.width,h:e.height}}get bounds(){let e=this._p.bounds;return e?{...e}:{}}set bounds(e){this._p.bounds=e}get center(){let e=this._p.center;return e?e.slice():[0,0]}set center(e){this._p.center=e,delete this._cc,this.render()}get centerCoords(){if(!this._cc){let[e,t]=this.center;this._cc=this.toPixelCoords(e,t)}return this._cc}get zoom(){return this._p.zoom??this._p.minZoom??0}set zoom(e){let{minZoom:t,maxZoom:n}=this,r=e;e<t&&(r=t),e>n&&(r=n),this._p.zoom=r,delete this._cc,this.render()}get minZoom(){return this._p.minZoom??-1/0}set minZoom(e){this._p.minZoom=e,this.zoom<this.minZoom&&(this.zoom=this.minZoom)}get maxZoom(){return this._p.maxZoom??1/0}set maxZoom(e){this._p.maxZoom=e,this.zoom>this.maxZoom&&(this.zoom=this.maxZoom)}get projection(){return this._p.projection??`spherical`}set projection(e){this._p.projection=e,this.render()}get lang(){return this._p.lang??``}set lang(e){this._p.lang=e,this.render()}inPixelBounds(e,t){let[n,r]=this.toGeoCoords(e,t);return this.inBounds(n,r)}inBounds(e,t){let{minLat:n=i,maxLat:r=a,minLon:s=o,maxLon:c=180}=this.bounds;return e>=n&&e<=r&&t>=s&&t<=c}canMoveTo(e,t){if(!this.inBounds(e,t))return!1;let{w:n,h:r}=this.box;if(n===0||r===0)return!1;let[i,a]=this.toPixelCoords(e,t);return this.inPixelBounds(i-n/2,a-r/2)&&this.inPixelBounds(i+n/2,a+r/2)}toPixelCoords(e,n){let i=r[this.projection],a=f(2,this.zoom+7)/c,o=e*t,s=i===0?1:f((1-i*l(o))/(1+i*l(o)),i/2);return[a*(c+n*t),a*(c-m(s*u(c/4+o/2)))]}toGeoCoords(e,t){let o=r[this.projection],s=f(2,this.zoom+7)/c,l=(e/s-c)*n,u;if(o===0)u=2*(d(p(c-t/s))-c/4)*n;else{u=i;let e=a-i,n=NaN,r=0;for(;(Number.isNaN(n)||h(n-t)>.1)&&r++<30;)e/=2,n=this.toPixelCoords(u+e,l)[1],n>t&&(u+=e)}return(l<-180||l>=180)&&(l=(l+180)%360-180),(u<-90||u>=90)&&(u=(u+90)%180-90),[u,l]}};function _(e){let t=`touches`in e?e.touches[0]:e;return t?[t.clientX,t.clientY]:null}function v(e,t){return t===void 0||!(e instanceof HTMLElement)?!1:typeof t==`function`&&t(e)||typeof t==`string`&&e.closest(t)!==null}function y(e,t,n){let r=Date.now(),i=null,a=e=>{r=Date.now(),i=_(e)},o=a=>{if(v(a.target,n)||!i||Date.now()-r>150)return;let{box:o,centerCoords:[s,c]}=e,l=i[0]-o.x,u=i[1]-o.y,[d,f]=e.toGeoCoords(l-.5*o.w+s,u-.5*o.h+c);t({x:l,y:u,lat:d,lon:f,originalEvent:a}),i=null};return e.container.addEventListener(`mousedown`,a),e.container.addEventListener(`mouseup`,o),e.container.addEventListener(`touchstart`,a),e.container.addEventListener(`touchend`,o),()=>{e.container.removeEventListener(`mousedown`,a),e.container.removeEventListener(`mouseup`,o),e.container.removeEventListener(`touchstart`,a),e.container.removeEventListener(`touchend`,o)}}function b(){return Math.random().toString(36).slice(2)}function x(e,{id:t,className:n,inset:r=`0`}={}){let i=`${n?`.${n}`:``}${t?`[data-id="${t}"]`:``}`,a=document.querySelector(i);return a||(a=document.createElement(`div`),a.className=`${n?`${n} `:``}layer`,a.dataset.id=t??b(),a.style=`position: absolute; inset: ${r};`,e.container.append(a)),a}function S(e,t){return typeof t==`function`?t(e):t??``}function C(e,t){return e.toFixed(t).replace(/\.(\d*[^0])0+$/,`.$1`).replace(/\.0+$/,``)}function w(e,t,{className:n,coords:r,inset:i,layer:a,content:o}){let s=a??x(e,{className:`elements`});n&&t.setAttribute(`class`,n),t.style.position=`absolute`,s.append(t),e.onRender(()=>{if(i)t.style.inset=S(e,i);else if(r){let{centerCoords:[n,i],box:{w:a,h:o}}=e,[s,c]=e.toPixelCoords(...r),l=C(s-n+a/2,2),u=C(c-i+o/2,2);t.style.transform=`translate3d(${l}px, ${u}px, 0)`}if(o){let n=S(e,o);t.innerHTML!==n&&(t.innerHTML=n)}})}function T(e,{onStart:t,onMove:n,onEnd:r,wheel:i}={}){let a=null,o=null,s=Date.now(),c=!1,l=null,u=null;function d(t,r,i=100){u!==null&&(clearTimeout(u),u=null),l!==null&&(cancelAnimationFrame(l),l=null);let c=Date.now();c-s<i||(a!==null&&(a-=t),o!==null&&(o-=r),s=c,e.dataset.dragged||(e.dataset.dragged=`true`),l=requestAnimationFrame(()=>{l=null,(t!==0||r!==0)&&n?.(t,r)}))}function f(e,t,n){a!==null&&o!==null&&d(a-e,o-t,n)}function p(e,n){c=!0,t?.(),e!==void 0&&(a=e),n!==void 0&&(o=n),s=Date.now()}function m(t,n){c=!1,u=null,t!==void 0&&n!==void 0&&f(t,n),delete e.dataset.dragged,a=null,o=null,requestAnimationFrame(()=>{r?.()})}e.dataset.draggable=`true`;let h=null,g=null;e.addEventListener(`mousedown`,t=>{t.preventDefault(),!h&&(p(t.clientX,t.clientY),h=e=>{e.preventDefault(),f(e.clientX,e.clientY)},e.addEventListener(`mousemove`,h))}),e.addEventListener(`mouseup`,t=>{t.preventDefault(),h&&=(m(t.clientX,t.clientY),e.removeEventListener(`mousemove`,h),null)}),e.addEventListener(`touchstart`,t=>{t.preventDefault(),!g&&(p(t.touches[0]?.clientX,t.touches[0]?.clientY),g=e=>{e.preventDefault(),f(e.touches[0]?.clientX,e.touches[0]?.clientY)},e.addEventListener(`touchmove`,g))}),e.addEventListener(`touchend`,t=>{t.preventDefault(),g&&=(m(t.touches[0]?.clientX,t.touches[0]?.clientY),e.removeEventListener(`touchmove`,g),null)}),e.addEventListener(`touchcancel`,t=>{t.preventDefault(),g&&=(m(t.touches[0]?.clientX,t.touches[0]?.clientY),e.removeEventListener(`touchmove`,g),null)}),i&&e.addEventListener(`wheel`,e=>{e.preventDefault(),c||p(),e.shiftKey?d(e.deltaY,e.deltaX,10):d(e.deltaX,e.deltaY,10),u=setTimeout(()=>{m()},200)})}function E(e){let t=0,n=0;T(e.container,{onStart(){[t,n]=e.centerCoords},onMove(r,i){let a=t+r,o=n+i,s=e.toGeoCoords(a,o);e.canMoveTo(...s)&&(e.center=s,t=a,n=o)},wheel:!0})}function D(e,{storageKey:t,session:n=!1}={}){let r=n?window.sessionStorage:window.localStorage,i=t??[`maparea`,e.container.id].filter(Boolean).join(`#`),a=e.getOptions(),o=!1,s=()=>{try{r.setItem(i,JSON.stringify(e.getOptions()))}catch{}},c=()=>{try{let t=r.getItem(i);t===null?s():e.setOptions(JSON.parse(t))}catch{}},l=e=>{o=e===void 0?!o:e},u=()=>{e.setOptions(a)};c();let d=null;return e.onRender(()=>{o||(d&&=(clearTimeout(d),null),d=setTimeout(()=>{d=null,s()},350))}),{sync:c,write:s,toggle:l,reset:u}}function O(e,t){let n=new ResizeObserver(n=>{for(let r of n)if(r.contentBoxSize){if(t)if(r.contentBoxSize){let{inlineSize:e,blockSize:n}=r.contentBoxSize[0]??r.contentBoxSize;t({inlineSize:e,blockSize:n})}else{let{width:e,height:n}=r.contentRect;t({width:e,height:n})}e.render()}});return n.observe(e.container),()=>{n.unobserve(e.container)}}const k=`http://www.w3.org/2000/svg`,A={className:`shape`};function j(e,t,n){let r=x(e,n??A);r.toggleAttribute(`hidden`,t.length===0);let i=r.querySelector(`svg`);i||(i=document.createElementNS(k,`svg`),i.setAttribute(`xmlns`,k),r.append(i));let a=N(i,t.map(({id:t,coords:[n,r]})=>({id:t,coords:e.toPixelCoords(n,r)})),n);if(a){let{xMin:t,xMax:n,yMin:r,yMax:o}=a,{centerCoords:[s,c],box:l}=e,u=C(n-t,3),d=C(o-r,3),f=C(.5*l.w+t-s,2),p=C(.5*l.h+r-c,2);i.setAttribute(`viewBox`,`0 0 ${u} ${d}`),i.setAttribute(`width`,u),i.setAttribute(`height`,d),i.setAttribute(`style`,`position: absolute; transform: translate3d(${f}px, ${p}px, 0);`)}return r}function M(e){return parseFloat(window.getComputedStyle(e).strokeWidth||e.getAttribute(`stroke-width`)||`1`)}function N(e,t,n){if(t.length===0){e.innerHTML=``;return}let r=e.querySelector(`path`);r||(r=document.createElementNS(k,`path`),e.append(r));let i=t[0].coords[0],a=i,o=t[0].coords[1],s=o,c=``;for(let{coords:[e,n]}of t)i>e&&(i=e),a<e&&(a=e),o>n&&(o=n),s<n&&(s=n);i-=10,a+=10,o-=10,s+=10;let l=Array.from(e.querySelectorAll(`.marker`)),u=0;for(let{id:a,coords:[s,d]}of t){let t=C(s-i,3),f=C(d-o,3);if(c+=`${c?` L`:`M`} ${t} ${f}`,n?.markers){let n=l[u++];n||(n=document.createElementNS(k,`circle`),n.setAttribute(`class`,`marker`),n.setAttribute(`r`,String(1.5*M(r))),e.append(n)),n.setAttribute(`cx`,t),n.setAttribute(`cy`,f),n.dataset.id=a}}for(let e=u;e<l.length;e++)l[e].remove();return r.setAttribute(`d`,c),{xMin:i,xMax:a,yMin:o,yMax:s}}function P(e,t,n){let r=t.map(e=>({id:b(),coords:e}));e.onRender(()=>{j(e,r,{className:`shape`,...n})})}function F(e,t){let n=[],r=null,i={className:`shape-editor`,markers:!0},a=()=>{j(e,n,i),t?.onUpdate?.(n)};y(e,({lat:e,lon:t,originalEvent:i})=>{let o=(i.target?.closest(`.marker`))?.dataset.id;if(o&&r){clearTimeout(r),r=null,n=n.filter(({id:e})=>e!==o),a();return}let s=()=>{n.push({id:b(),coords:[e,t]}),a(),r=null};o?r=setTimeout(s,250):s()},t?.ignoreClicks),e.onRender(a)}const{floor:I,ceil:L,random:R}=Math,ee=256;function z(e,t,n){return`${t},${n},${e.zoom},${e.lang}`}function B(e,t,n,{size:r=256,url:i,subdomains:a,retries:o=0,error:s}){let c=new Image,l=0,u=(r,o)=>{if(!i)return``;if(typeof i==`function`)return i(e,t,n);let s=i.replaceAll(`{x}`,String(r)).replaceAll(`{y}`,String(o)).replaceAll(`{z}`,String(e.zoom)).replaceAll(`{lang}`,e.lang);return a&&s.includes(`{s}`)&&(s=s.replaceAll(`{s}`,a[I(a.length*R())])),s};return c.width=r,c.height=r,c.src=u(t,n),c.dataset.id=z(e,t,n),c.style=`position: absolute;`,c.onerror=()=>{l++;let{src:i}=c;if(!i||l>o){let t=S(e,s);t&&(c.onerror=()=>{},c.dataset.src=i,c.src=t);return}let a=t*r,d=n*r,f=e.toPixelCoords(...e.toGeoCoords(a,d))[0],p=I(f/r);if(t!==p)c.src=u(p,n);else{let e=new URL(i);e.searchParams.set(`_t`,String(Date.now())),c.src=e.href}},c}function V(e){return e.querySelectorAll(`img[data-id]`)}function H(e,t){return e.querySelector(`img[data-id="${t}"]`)}function U(e,t={}){let{id:n=b(),attribution:r,attributionInset:i=`auto 0 0 auto`}=t,a=x(e,{id:n,className:`tiles`,...t}),o=x(e,{id:n,className:`tiles-attribution`,inset:i}),s=()=>{let{box:{w:n,h:i},centerCoords:[s,c]}=e,{size:l=256,margin:u=0}=t,d=Array.isArray(u)?u[0]:u,f=Array.isArray(u)?u[1]:u,p=L((n+2*d)/l),m=L((i+2*f)/l),h=I(s/l),g=I(c/l),_=null,v=new Set,y=``;for(let r=0;r<=p;r++){let o=h+(r%2==0?-1:1)*I(r/2);for(let r=0;r<=m;r++){let u=g+(r%2==0?-1:1)*I(r/2);y=z(e,o,u),_=H(a,y),_||(_=B(e,o,u,t),a.append(_));let d=C(.5*n+o*l-s,2),f=C(.5*i+u*l-c,2);_.style.transform=`translate3d(${d}px, ${f}px, 0)`,v.add(y)}}for(let e of V(a)){let{id:t}=e.dataset;t&&!v.has(t)&&e.remove()}let b=S(e,r);o.toggleAttribute(`hidden`,!b),o.innerHTML!==b&&(o.innerHTML=b)},c=e.zoom,l=null;return e.onRender(()=>{l!==null&&(clearTimeout(l),l=null),e.zoom===c?(a.style.opacity=``,s()):(a.style.opacity=`0`,l=setTimeout(()=>{l=null,a.style.opacity=``,s()},300)),c=e.zoom}),a}function W(e,t={}){let{plus:n=`➕`,minus:r=`➖`,inset:i=`0 0 auto auto`}=t,a=x(e,{className:`zoom-controls`,inset:i}),o=document.createElement(`button`);o.dataset.id=`plus`,o.innerHTML=n;let s=document.createElement(`button`);s.dataset.id=`minus`,s.innerHTML=r;let c=()=>{o.toggleAttribute(`disabled`,e.zoom+1>e.maxZoom),s.toggleAttribute(`disabled`,e.zoom-1<e.minZoom)};return y(e,({originalEvent:t})=>{let n=t.target?.closest(`button`);n&&(t.stopPropagation(),e.zoom+=n.dataset.id===`minus`?-1:1,c())}),e.onRender(c),a.append(o,s),a}const{abs:G,log2:K,min:q,floor:J}=Math;function Y(e,t){let{box:{w:n,h:r},center:[i,a],zoom:o}=e,{minLat:s,maxLat:c,minLon:l,maxLon:u}=t,d=0,f=0;if(l!==void 0&&u!==void 0){let t=G(e.toPixelCoords(i,u)[0]-e.toPixelCoords(i,l)[0]);t!==0&&(d=K(n/t))}if(s!==void 0&&c!==void 0){let t=G(e.toPixelCoords(s,a)[1]-e.toPixelCoords(c,a)[1]);t!==0&&(f=K(r/t))}let p=J(q(o+d,o+f));p!==o&&(e.zoom=p)}function X(e){if(e.length===0)return{};let t=e[0][0],n=t,r=e[0][1],i=r;for(let[a,o]of e)t>a&&(t=a),n<a&&(n=a),r>o&&(r=o),i<o&&(i=o);return{minLat:t,maxLat:n,minLon:r,maxLon:i}}function Z(e){let{minLat:t,maxLat:n,minLon:r,maxLon:i}=X(e);return[t===void 0||n===void 0?0:(n+t)/2,r===void 0||i===void 0?0:(i+r)/2]}function Q(e){return Array.isArray(e)&&e.length===2&&typeof e[0]==`number`&&typeof e[1]==`number`}const $=[.005,.018];function te(e){return Array.isArray(e)?Q(e)?{minLat:e[0],maxLat:e[0],minLon:e[1],maxLon:e[1]}:X(e):e}function ne(e,[t,n]=$){let{minLat:r=0,maxLat:i=0,minLon:a=0,maxLon:o=0}=te(e);return{minLat:r-t,maxLat:i+t,minLon:a-n,maxLon:o+n}}exports.DEG=n,exports.MAX_LAT=a,exports.MAX_LON=180,exports.MIN_LAT=i,exports.MIN_LON=o,exports.MapArea=g,exports.RAD=t,exports.addClickListener=y,exports.addElement=w,exports.addNavigation=E,exports.addPersistence=D,exports.addResizeObserver=O,exports.addShape=P,exports.addShapeEditor=F,exports.addTiles=U,exports.addZoomControls=W,exports.eccentricityMap=r,exports.fitBounds=Y,exports.getCenter=Z,exports.getGeoBounds=X,exports.getId=b,exports.getLayer=x,exports.getPointerPosition=_,exports.getVicinity=ne,exports.isGeoCoords=Q,exports.resolveString=S,exports.toPrecision=C;
1
+ const{PI:e}=Math,t=e/180,n=180/e,r={spherical:0,ellipsoidal:.0818191908426},i=-85.05,a=85.05,o=-180,s=180,{PI:c,sin:l,tan:u,atan:d,pow:f,exp:p,log:m,abs:h}=Math;var g=class{_p;_c;_cc;_r=new Set;constructor(e){this._p=e,this.container.style=`position: relative; overflow: hidden;`,this.container.dataset.type=`maparea`}render(){for(let e of this._r)e(this)}onRender(e,t=!1){return this._r.add(e),t||e(this),()=>{this._r.delete(e)}}getOptions(){return{...this._p,center:this.center,bounds:this.bounds}}setOptions(e){this._p={...this._p,...e},`container`in e&&delete this._c,delete this._cc,this.render()}get container(){if(!this._c){let e=document.querySelector(this._p.container);if(!e)throw Error(`missing container element`);this._c=e}return this._c}get box(){let e=this.container.getBoundingClientRect();return{x:e.left,y:e.top,w:e.width,h:e.height}}get bounds(){let e=this._p.bounds;return e?{...e}:{}}set bounds(e){this._p.bounds=e}get center(){let e=this._p.center;return e?e.slice():[0,0]}set center(e){this._p.center=e,delete this._cc,this.render()}get centerCoords(){if(!this._cc){let[e,t]=this.center;this._cc=this.toPixelCoords(e,t)}return this._cc}get zoom(){return this._p.zoom??this._p.minZoom??0}set zoom(e){let{minZoom:t,maxZoom:n}=this,r=e;e<t&&(r=t),e>n&&(r=n),this._p.zoom=r,delete this._cc,this.render()}get minZoom(){return this._p.minZoom??-1/0}set minZoom(e){this._p.minZoom=e,this.zoom<this.minZoom&&(this.zoom=this.minZoom)}get maxZoom(){return this._p.maxZoom??1/0}set maxZoom(e){this._p.maxZoom=e,this.zoom>this.maxZoom&&(this.zoom=this.maxZoom)}get projection(){return this._p.projection??`spherical`}set projection(e){this._p.projection=e,this.render()}get lang(){return this._p.lang??``}set lang(e){this._p.lang=e,this.render()}inPixelBounds(e,t){let[n,r]=this.toGeoCoords(e,t);return this.inBounds(n,r)}inBounds(e,t){let{minLat:n=i,maxLat:r=a,minLon:s=o,maxLon:c=180}=this.bounds;return e>=n&&e<=r&&t>=s&&t<=c}canMoveTo(e,t){if(!this.inBounds(e,t))return!1;let{w:n,h:r}=this.box;if(n===0||r===0)return!1;let[i,a]=this.toPixelCoords(e,t);return this.inPixelBounds(i-n/2,a-r/2)&&this.inPixelBounds(i+n/2,a+r/2)}toPixelCoords(e,n){let i=r[this.projection],a=f(2,this.zoom+7)/c,o=e*t,s=i===0?1:f((1-i*l(o))/(1+i*l(o)),i/2);return[a*(c+n*t),a*(c-m(s*u(c/4+o/2)))]}toGeoCoords(e,t){let o=r[this.projection],s=f(2,this.zoom+7)/c,l=(e/s-c)*n,u;if(o===0)u=2*(d(p(c-t/s))-c/4)*n;else{u=i;let e=a-i,n=NaN,r=0;for(;(Number.isNaN(n)||h(n-t)>.1)&&r++<30;)e/=2,n=this.toPixelCoords(u+e,l)[1],n>t&&(u+=e)}return(l<-180||l>=180)&&(l=(l+180)%360-180),(u<-90||u>=90)&&(u=(u+90)%180-90),[u,l]}};function _(e){let t=`touches`in e?e.touches[0]:e;return t?[t.clientX,t.clientY]:null}function v(e,t){return t===void 0||!(e instanceof HTMLElement)?!1:typeof t==`function`&&t(e)||typeof t==`string`&&e.closest(t)!==null}function y(e,t,n){let r=Date.now(),i=null,a=e=>{r=Date.now(),i=_(e)},o=a=>{if(v(a.target,n)||!i||Date.now()-r>150)return;let{box:o,centerCoords:[s,c]}=e,l=i[0]-o.x,u=i[1]-o.y,[d,f]=e.toGeoCoords(l-.5*o.w+s,u-.5*o.h+c);t({x:l,y:u,lat:d,lon:f,originalEvent:a}),i=null};return e.container.addEventListener(`mousedown`,a),e.container.addEventListener(`mouseup`,o),e.container.addEventListener(`touchstart`,a),e.container.addEventListener(`touchend`,o),()=>{e.container.removeEventListener(`mousedown`,a),e.container.removeEventListener(`mouseup`,o),e.container.removeEventListener(`touchstart`,a),e.container.removeEventListener(`touchend`,o)}}function b(){return Math.random().toString(36).slice(2)}function x(e,{id:t,className:n,inset:r=`0`}={}){let i=`${n?`.${n}`:``}${t?`[data-id="${t}"]`:``}`,a=document.querySelector(i);return a||(a=document.createElement(`div`),a.className=`${n?`${n} `:``}layer`,a.dataset.id=t??b(),a.style=`position: absolute; inset: ${r};`,e.container.append(a)),a}function S(e,t){return t===void 0?t:t instanceof Function?t(e):t}function C(e,t){return e.toFixed(t).replace(/\.(\d*[^0])0+$/,`.$1`).replace(/\.0+$/,``)}function w(e,t,{className:n,coords:r,inset:i,layer:a,content:o}){let s=a??x(e,{className:`elements`});n&&t.setAttribute(`class`,n),t.style.position=`absolute`,s.append(t),e.onRender(()=>{if(i)t.style.inset=S(e,i)??``;else if(r){let{centerCoords:[n,i],box:{w:a,h:o}}=e,[s,c]=e.toPixelCoords(...r),l=C(s-n+a/2,2),u=C(c-i+o/2,2);t.style.transform=`translate3d(${l}px, ${u}px, 0)`}if(o){let n=S(e,o)??``;t.innerHTML!==n&&(t.innerHTML=n)}})}function T(e,{onStart:t,onMove:n,onEnd:r,wheel:i}={}){let a=null,o=null,s=Date.now(),c=!1,l=null,u=null;function d(t,r,i=100){u!==null&&(clearTimeout(u),u=null),l!==null&&(cancelAnimationFrame(l),l=null);let c=Date.now();c-s<i||(a!==null&&(a-=t),o!==null&&(o-=r),s=c,e.dataset.dragged||(e.dataset.dragged=`true`),l=requestAnimationFrame(()=>{l=null,(t!==0||r!==0)&&n?.(t,r)}))}function f(e,t,n){a!==null&&o!==null&&d(a-e,o-t,n)}function p(e,n){c=!0,t?.(),e!==void 0&&(a=e),n!==void 0&&(o=n),s=Date.now()}function m(t,n){c=!1,u=null,t!==void 0&&n!==void 0&&f(t,n),delete e.dataset.dragged,a=null,o=null,requestAnimationFrame(()=>{r?.()})}e.dataset.draggable=`true`;let h=null,g=null;e.addEventListener(`mousedown`,t=>{t.preventDefault(),!h&&(p(t.clientX,t.clientY),h=e=>{e.preventDefault(),f(e.clientX,e.clientY)},e.addEventListener(`mousemove`,h))}),e.addEventListener(`mouseup`,t=>{t.preventDefault(),h&&=(m(t.clientX,t.clientY),e.removeEventListener(`mousemove`,h),null)}),e.addEventListener(`touchstart`,t=>{t.preventDefault(),!g&&(p(t.touches[0]?.clientX,t.touches[0]?.clientY),g=e=>{e.preventDefault(),f(e.touches[0]?.clientX,e.touches[0]?.clientY)},e.addEventListener(`touchmove`,g))}),e.addEventListener(`touchend`,t=>{t.preventDefault(),g&&=(m(t.touches[0]?.clientX,t.touches[0]?.clientY),e.removeEventListener(`touchmove`,g),null)}),e.addEventListener(`touchcancel`,t=>{t.preventDefault(),g&&=(m(t.touches[0]?.clientX,t.touches[0]?.clientY),e.removeEventListener(`touchmove`,g),null)}),i&&e.addEventListener(`wheel`,e=>{e.preventDefault(),c||p(),e.shiftKey?d(e.deltaY,e.deltaX,10):d(e.deltaX,e.deltaY,10),u=setTimeout(()=>{m()},200)})}function E(e,t){let n=0,r=0;T(e.container,{onStart(){[n,r]=e.centerCoords},onMove(t,i){let a=n+t,o=r+i,s=e.toGeoCoords(a,o);e.canMoveTo(...s)&&(e.center=s,n=a,r=o)},wheel:t?.wheel??!0})}function D(e,{storageKey:t,session:n=!1}={}){let r=n?window.sessionStorage:window.localStorage,i=t??[`maparea`,e.container.id].filter(Boolean).join(`#`),a=e.getOptions(),o=!1,s=()=>{try{r.setItem(i,JSON.stringify(e.getOptions()))}catch{}},c=()=>{try{let t=r.getItem(i);t===null?s():e.setOptions(JSON.parse(t))}catch{}},l=e=>{o=e===void 0?!o:e},u=()=>{e.setOptions(a)};c();let d=null;return e.onRender(()=>{o||(d&&=(clearTimeout(d),null),d=setTimeout(()=>{d=null,s()},350))}),{sync:c,write:s,toggle:l,reset:u}}function O(e,t){let n=new ResizeObserver(n=>{for(let r of n)if(r.contentBoxSize){if(t)if(r.contentBoxSize){let{inlineSize:e,blockSize:n}=r.contentBoxSize[0]??r.contentBoxSize;t({inlineSize:e,blockSize:n})}else{let{width:e,height:n}=r.contentRect;t({width:e,height:n})}e.render()}});return n.observe(e.container),()=>{n.unobserve(e.container)}}const k=`http://www.w3.org/2000/svg`,A={className:`shape`};function j(e,t,n){let r=x(e,n??A);r.toggleAttribute(`hidden`,t.length===0);let i=r.querySelector(`svg`);i||(i=document.createElementNS(k,`svg`),i.setAttribute(`xmlns`,k),r.append(i));let a=N(i,t.map(({id:t,coords:[n,r]})=>({id:t,coords:e.toPixelCoords(n,r)})),n);if(a){let{xMin:t,xMax:n,yMin:r,yMax:o}=a,{centerCoords:[s,c],box:l}=e,u=C(n-t,3),d=C(o-r,3),f=C(.5*l.w+t-s,2),p=C(.5*l.h+r-c,2);i.setAttribute(`viewBox`,`0 0 ${u} ${d}`),i.setAttribute(`width`,u),i.setAttribute(`height`,d),i.setAttribute(`style`,`position: absolute; transform: translate3d(${f}px, ${p}px, 0);`)}return r}function M(e){return parseFloat(window.getComputedStyle(e).strokeWidth||e.getAttribute(`stroke-width`)||`1`)}function N(e,t,n){if(t.length===0){e.innerHTML=``;return}let r=e.querySelector(`path`);r||(r=document.createElementNS(k,`path`),e.append(r));let i=t[0].coords[0],a=i,o=t[0].coords[1],s=o,c=``;for(let{coords:[e,n]}of t)i>e&&(i=e),a<e&&(a=e),o>n&&(o=n),s<n&&(s=n);i-=10,a+=10,o-=10,s+=10;let l=Array.from(e.querySelectorAll(`.marker`)),u=0;for(let{id:a,coords:[s,d]}of t){let t=C(s-i,3),f=C(d-o,3);if(c+=`${c?` L`:`M`} ${t} ${f}`,n?.markers){let n=l[u++];n||(n=document.createElementNS(k,`circle`),n.setAttribute(`class`,`marker`),n.setAttribute(`r`,String(1.5*M(r))),e.append(n)),n.setAttribute(`cx`,t),n.setAttribute(`cy`,f),n.dataset.id=a}}for(let e=u;e<l.length;e++)l[e].remove();return r.setAttribute(`d`,c),{xMin:i,xMax:a,yMin:o,yMax:s}}function P(e,t,n){let r=t.map(e=>({id:b(),coords:e}));e.onRender(()=>{j(e,r,{className:`shape`,...n})})}function F(e,t){let n=[],r=null,i={className:`shape-editor`,markers:!0},a=()=>{j(e,n,i),t?.onUpdate?.(n)};y(e,({lat:e,lon:t,originalEvent:i})=>{let o=(i.target?.closest(`.marker`))?.dataset.id;if(o&&r){clearTimeout(r),r=null,n=n.filter(({id:e})=>e!==o),a();return}let s=()=>{n.push({id:b(),coords:[e,t]}),a(),r=null};o?r=setTimeout(s,250):s()},t?.ignoreClicks),e.onRender(a)}const{floor:I,ceil:L,random:R}=Math,ee=256;function z(e,t,n){return`${t},${n},${e.zoom},${e.lang}`}function B(e,t,n,{size:r,url:i,subdomains:a,error:o}){let s=new Image,c=S(e,r)??256;return s.width=c,s.height=c,s.src=((r,o)=>{if(!i)return``;if(typeof i==`function`)return i(e,t,n);let s=i.replaceAll(`{x}`,String(r)).replaceAll(`{y}`,String(o)).replaceAll(`{z}`,String(e.zoom)).replaceAll(`{lang}`,e.lang);return a&&s.includes(`{s}`)&&(s=s.replaceAll(`{s}`,a[I(a.length*R())])),s})(t,n),s.dataset.id=z(e,t,n),s.style=`position: absolute;`,s.addEventListener(`error`,t=>{let n=t.target;if(n instanceof HTMLImageElement){let t=S(e,o);t&&(n.dataset.src=s.src,n.src=t)}}),s}function V(e){return e.querySelectorAll(`img[data-id]`)}function H(e,t){return e.querySelector(`img[data-id="${t}"]`)}function U(e,t={}){let{id:n=b(),attribution:r,attributionInset:i=`auto 0 0 auto`}=t,a=x(e,{id:n,className:`tiles`,...t}),o=x(e,{id:n,className:`tiles-attribution`,inset:i}),s=()=>{let{box:{w:n,h:i},centerCoords:[s,c]}=e,{size:l,margin:u=0}=t,d=S(e,l)??256,f=Array.isArray(u)?u[0]:u,p=Array.isArray(u)?u[1]:u,m=L((n+2*f)/d),h=L((i+2*p)/d),g=I(s/d),_=I(c/d),v=null,y=new Set,b=``;for(let r=0;r<=m;r++){let o=g+(r%2==0?-1:1)*I(r/2);for(let r=0;r<=h;r++){let l=_+(r%2==0?-1:1)*I(r/2);b=z(e,o,l),v=H(a,b),v||(v=B(e,o,l,t),a.append(v));let u=C(.5*n+o*d-s,2),f=C(.5*i+l*d-c,2);v.style.transform=`translate3d(${u}px, ${f}px, 0)`,y.add(b)}}for(let e of V(a)){let{id:t}=e.dataset;t&&!y.has(t)&&e.remove()}let x=S(e,r)??``;o.toggleAttribute(`hidden`,!x),o.innerHTML!==x&&(o.innerHTML=x)},c=e.zoom,l=null;return e.onRender(()=>{l!==null&&(clearTimeout(l),l=null),e.zoom===c?(a.style.opacity=``,s()):(a.style.opacity=`0`,l=setTimeout(()=>{l=null,a.style.opacity=``,s()},300)),c=e.zoom}),a}function W(e,t={}){let{plus:n=`➕`,minus:r=`➖`,inset:i=`0 0 auto auto`}=t,a=x(e,{className:`zoom-controls`,inset:i}),o=document.createElement(`button`);o.dataset.id=`plus`,o.innerHTML=n;let s=document.createElement(`button`);s.dataset.id=`minus`,s.innerHTML=r;let c=()=>{o.toggleAttribute(`disabled`,e.zoom+1>e.maxZoom),s.toggleAttribute(`disabled`,e.zoom-1<e.minZoom)};return y(e,({originalEvent:t})=>{let n=t.target?.closest(`button`);n&&(t.stopPropagation(),e.zoom+=n.dataset.id===`minus`?-1:1,c())}),e.onRender(c),a.append(o,s),a}function G(e){if(e.length===0)return{};let t=e[0][0],n=t,r=e[0][1],i=r;for(let[a,o]of e)t>a&&(t=a),n<a&&(n=a),r>o&&(r=o),i<o&&(i=o);return{minLat:t,maxLat:n,minLon:r,maxLon:i}}function K(e){return Array.isArray(e)&&e.length===2&&typeof e[0]==`number`&&typeof e[1]==`number`}function q(e){return K(e)?{minLat:e[0],maxLat:e[0],minLon:e[1],maxLon:e[1]}:Array.isArray(e)?G(e):e}function J(e){let{minLat:t,maxLat:n,minLon:r,maxLon:i}=q(e);return[t===void 0||n===void 0?0:(n+t)/2,r===void 0||i===void 0?0:(i+r)/2]}const{abs:Y,log2:X,min:Z,floor:Q}=Math;function $(e,t){let{box:{w:n,h:r},center:[i,a],zoom:o}=e,{minLat:s,maxLat:c,minLon:l,maxLon:u}=t,d=0,f=0;if(l!==void 0&&u!==void 0){let t=Y(e.toPixelCoords(i,u)[0]-e.toPixelCoords(i,l)[0]);t!==0&&(d=X(n/t))}if(s!==void 0&&c!==void 0){let t=Y(e.toPixelCoords(s,a)[1]-e.toPixelCoords(c,a)[1]);t!==0&&(f=X(r/t))}let p=Q(Z(o+d,o+f)),m={center:J(t)};p!==o&&(m.zoom=p),e.setOptions(m)}const te=[.005,.018];function ne(e,t=te){let{minLat:n=0,maxLat:r=0,minLon:i=0,maxLon:a=0}=q(e),[o,s]=t;return{minLat:n-o,maxLat:r+o,minLon:i-s,maxLon:a+s}}exports.DEG=n,exports.MAX_LAT=a,exports.MAX_LON=180,exports.MIN_LAT=i,exports.MIN_LON=o,exports.MapArea=g,exports.RAD=t,exports.addClickListener=y,exports.addElement=w,exports.addMovableViewport=E,exports.addPersistence=D,exports.addResizeObserver=O,exports.addShape=P,exports.addShapeEditor=F,exports.addTiles=U,exports.addZoomControls=W,exports.eccentricityMap=r,exports.fitGeoBounds=$,exports.getCenter=J,exports.getGeoBounds=G,exports.getId=b,exports.getLayer=x,exports.getPointerPosition=_,exports.getVicinity=ne,exports.isCoordsArray=K,exports.resolveDynamic=S,exports.toGeoBounds=q,exports.toPrecision=C;
package/dist/index.d.ts CHANGED
@@ -41,9 +41,9 @@ type RenderCallback = (map: MapArea) => void;
41
41
  declare class MapArea {
42
42
  /** Map parameters */
43
43
  _p: MapAreaOptions;
44
- /** Container */
44
+ /** Map container */
45
45
  _c: HTMLElement | undefined;
46
- /** Pixel coordinates of the center */
46
+ /** Pixel coordinates of the map center */
47
47
  _cc: PixelCoords | undefined;
48
48
  /** Render callbacks */
49
49
  _r: Set<RenderCallback>;
@@ -51,7 +51,7 @@ declare class MapArea {
51
51
  render(): void;
52
52
  onRender(callback: RenderCallback, skipInitialCall?: boolean): () => void;
53
53
  getOptions(): MapAreaOptions;
54
- setOptions(options: MapAreaOptions): void;
54
+ setOptions(options: Partial<MapAreaOptions>): void;
55
55
  get container(): HTMLElement;
56
56
  get box(): BoxDimensions;
57
57
  get bounds(): GeoBounds;
@@ -89,19 +89,19 @@ type MapAreaClickEvent = {
89
89
  };
90
90
  type MapAreaClickCallback = (event: MapAreaClickEvent) => void;
91
91
  /**
92
- * Adds a click listener to the map and returns a function
93
- * removing the added click listener.
92
+ * Adds a click listener to the map and returns a function that removes
93
+ * the added listener.
94
94
  */
95
95
  declare function addClickListener(map: MapArea, callback: MapAreaClickCallback, ignored?: IgnoredElement): () => void;
96
96
 
97
- type DynamicString = string | ((map: MapArea) => string);
97
+ type Dynamic<T> = T | ((map: MapArea) => T);
98
98
 
99
99
  type MapAreaElementOptions = {
100
100
  className?: string; /** Geographical position (`[lat, lon]`) of the element's top left corner. */
101
101
  coords?: GeoCoords; /** CSS `inset` (disregarding `coords`). */
102
- inset?: DynamicString; /** Target layer. */
102
+ inset?: Dynamic<string>; /** Target layer. */
103
103
  layer?: Element; /** HTML content of the element. */
104
- content?: DynamicString;
104
+ content?: Dynamic<string>;
105
105
  };
106
106
  /**
107
107
  * Adds an HTML or SVG element to the map.
@@ -118,12 +118,25 @@ declare function addElement(map: MapArea, element: HTMLElement | SVGSVGElement,
118
118
  content
119
119
  }: MapAreaElementOptions): void;
120
120
 
121
- declare function addNavigation(map: MapArea): void;
121
+ type MapAreaNavigationOptions = {
122
+ wheel?: boolean;
123
+ };
124
+ /**
125
+ * Enables navigation over the given map container with a mouse or touches
126
+ * or a scroll wheel (the latter can be disabled by setting `options.wheel`
127
+ * to `false`).
128
+ */
129
+ declare function addMovableViewport(map: MapArea, options?: MapAreaNavigationOptions): void;
122
130
 
123
131
  type PersistenceOptions = {
124
132
  storageKey?: string;
125
133
  session?: boolean;
126
134
  };
135
+ /**
136
+ * Enables persistence of the map's state across page reloads by saving it to
137
+ * the browser storage (`localStorage` by default, `sessionStorage` with
138
+ * `session` set to `true`).
139
+ */
127
140
  declare function addPersistence(map: MapArea, {
128
141
  storageKey,
129
142
  session
@@ -145,6 +158,9 @@ type MapAreaResizeEvent = {
145
158
  height?: number;
146
159
  };
147
160
  type MapAreaResizeCallback = (event: MapAreaResizeEvent) => void;
161
+ /**
162
+ * Adds a resize observer to the map and returns a function turning it off.
163
+ */
148
164
  declare function addResizeObserver(map: MapArea, callback?: MapAreaResizeCallback): () => void;
149
165
 
150
166
  type LayerOptions = {
@@ -153,6 +169,10 @@ type LayerOptions = {
153
169
  inset?: string;
154
170
  };
155
171
 
172
+ /**
173
+ * Adds a shape based on the given array of geographic coordinates to
174
+ * the specified map layer.
175
+ */
156
176
  declare function addShape(map: MapArea, coords: GeoCoords[], layerOptions?: LayerOptions): void;
157
177
 
158
178
  type Vertex<T> = {
@@ -166,6 +186,9 @@ type ShapeEditorOptions = {
166
186
  onUpdate?: (shape: GeoVertex[]) => void;
167
187
  ignoreClicks?: IgnoredElement;
168
188
  };
189
+ /**
190
+ * Adds a shape editor to the given map container.
191
+ */
169
192
  declare function addShapeEditor(map: MapArea, options?: ShapeEditorOptions): void;
170
193
 
171
194
  type MapAreaTileOptions = LayerOptions & {
@@ -175,18 +198,22 @@ type MapAreaTileOptions = LayerOptions & {
175
198
  * or a function of `(map, x, y) => string` returning a fixed string URL.
176
199
  */
177
200
  url?: string | ((map: MapArea, xIndex: number, yIndex: number) => string); /** Values of the `{s}` placeholder of the tile URLs. */
178
- subdomains?: string[]; /** Maximum retry count per tile. */
179
- retries?: number; /** URL to be used instead of a tile that failed to load. */
180
- error?: DynamicString; /** Tile size. */
181
- size?: number;
201
+ subdomains?: string[]; /** URL to be used instead of a tile that failed to load. */
202
+ error?: Dynamic<string>; /** Tile size. */
203
+ size?: Dynamic<number>;
182
204
  /**
183
205
  * Margin in pixels, or a tuple of an x- and y-margin, to be tiled
184
206
  * outside the viewport.
185
207
  */
186
208
  margin?: number | [number, number]; /** Attribution HTML content. */
187
- attribution?: DynamicString; /** Attribution's CSS `inset`. */
209
+ attribution?: Dynamic<string>; /** Attribution's CSS `inset`. */
188
210
  attributionInset?: string;
189
211
  };
212
+ /**
213
+ * Adds image tiles to the given map container based on `options.url`,
214
+ * which is a string URL with placeholders or a function of
215
+ * `(map, xIndex, yIndex) => string`.
216
+ */
190
217
  declare function addTiles(map: MapArea, options?: MapAreaTileOptions): HTMLElement;
191
218
 
192
219
  type ZoomControlOptions = {
@@ -194,6 +221,9 @@ type ZoomControlOptions = {
194
221
  minus?: string; /** CSS `inset` */
195
222
  inset?: string;
196
223
  };
224
+ /**
225
+ * Adds customizable zoom controls to the given map container.
226
+ */
197
227
  declare function addZoomControls(map: MapArea, options?: ZoomControlOptions): HTMLElement;
198
228
 
199
229
  type PixelVertex = Vertex<PixelCoords>;
@@ -202,12 +232,26 @@ type ShapeLayerOptions = LayerOptions & {
202
232
  markers?: boolean;
203
233
  };
204
234
 
205
- declare function fitBounds(map: MapArea, bounds: GeoBounds): void;
235
+ /**
236
+ * Fits the map to the given geographic bounds.
237
+ */
238
+ declare function fitGeoBounds(map: MapArea, bounds: GeoBounds): void;
206
239
 
207
- declare function getCenter(coords: GeoCoords[]): GeoCoords;
240
+ /**
241
+ * Calculates the geographic coordinates of the center of an array
242
+ * of geographic coordinates or a geographic region.
243
+ */
244
+ declare function getCenter(coords: GeoCoords[] | GeoBounds): GeoCoords;
208
245
 
246
+ /**
247
+ * Returns the minimal and maximal latitudes and longitudes of
248
+ * an array of geographic coordinates.
249
+ */
209
250
  declare function getGeoBounds(coords: GeoCoords[]): GeoBounds;
210
251
 
252
+ /**
253
+ * Generates a string ID.
254
+ */
211
255
  declare function getId(): string;
212
256
 
213
257
  /**
@@ -220,14 +264,31 @@ declare function getLayer(map: MapArea, {
220
264
  inset
221
265
  }?: LayerOptions): HTMLElement;
222
266
 
267
+ /**
268
+ * Returns the pointer pixel position `[x, y]` of the given mouse or
269
+ * touch event.
270
+ */
223
271
  declare function getPointerPosition(event: MouseEvent | TouchEvent): [number, number] | null;
224
272
 
225
- declare function getVicinity(x: GeoCoords | GeoCoords[] | GeoBounds, [dLat, dLon]?: GeoCoords): GeoBounds;
273
+ /**
274
+ * Returns the minimal and maximal latitudes and longitudes of a region
275
+ * surrounding a geographic area, an array of geographic coordinates,
276
+ * or a single point.
277
+ */
278
+ declare function getVicinity(x: GeoCoords | GeoCoords[] | GeoBounds, padding?: GeoCoords): GeoBounds;
279
+
280
+ /**
281
+ * Checks whether the given value is an array of coordinates.
282
+ */
283
+ declare function isCoordsArray(x: unknown): x is [number, number];
226
284
 
227
- declare function isGeoCoords(x: unknown): x is GeoCoords;
285
+ /**
286
+ * Resolves a dynamic value to a static value based on the context.
287
+ */
288
+ declare function resolveDynamic<T>(map: MapArea, x: Dynamic<T> | undefined): T | undefined;
228
289
 
229
- declare function resolveString(map: MapArea, x: DynamicString | undefined): string;
290
+ declare function toGeoBounds(x: GeoCoords | GeoCoords[] | GeoBounds): GeoBounds;
230
291
 
231
292
  declare function toPrecision(x: number, n: number): string;
232
293
 
233
- export { BoxDimensions, DEG, DynamicString, GeoBounds, GeoCoords, GeoVertex, IgnoredElement, LayerOptions, MAX_LAT, MAX_LON, MIN_LAT, MIN_LON, MapArea, MapAreaClickCallback, MapAreaClickEvent, MapAreaElementOptions, MapAreaOptions, MapAreaResizeCallback, MapAreaResizeEvent, MapAreaTileOptions, PersistenceOptions, PixelCoords, PixelVertex, Projection, RAD, RenderCallback, ShapeEditorOptions, ShapeLayerOptions, ZoomControlOptions, addClickListener, addElement, addNavigation, addPersistence, addResizeObserver, addShape, addShapeEditor, addTiles, addZoomControls, eccentricityMap, fitBounds, getCenter, getGeoBounds, getId, getLayer, getPointerPosition, getVicinity, isGeoCoords, resolveString, toPrecision };
294
+ export { BoxDimensions, DEG, Dynamic, GeoBounds, GeoCoords, GeoVertex, IgnoredElement, LayerOptions, MAX_LAT, MAX_LON, MIN_LAT, MIN_LON, MapArea, MapAreaClickCallback, MapAreaClickEvent, MapAreaElementOptions, MapAreaNavigationOptions, MapAreaOptions, MapAreaResizeCallback, MapAreaResizeEvent, MapAreaTileOptions, PersistenceOptions, PixelCoords, PixelVertex, Projection, RAD, RenderCallback, ShapeEditorOptions, ShapeLayerOptions, ZoomControlOptions, addClickListener, addElement, addMovableViewport, addPersistence, addResizeObserver, addShape, addShapeEditor, addTiles, addZoomControls, eccentricityMap, fitGeoBounds, getCenter, getGeoBounds, getId, getLayer, getPointerPosition, getVicinity, isCoordsArray, resolveDynamic, toGeoBounds, toPrecision };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- const{PI:e}=Math,t=e/180,n=180/e,r={spherical:0,ellipsoidal:.0818191908426},i=-85.05,a=85.05,o=-180,s=180,{PI:c,sin:l,tan:u,atan:d,pow:f,exp:p,log:m,abs:h}=Math;var g=class{_p;_c;_cc;_r=new Set;constructor(e){this._p=e,this.container.style=`position: relative; overflow: hidden;`,this.container.dataset.type=`maparea`}render(){for(let e of this._r)e(this)}onRender(e,t=!1){return this._r.add(e),t||e(this),()=>{this._r.delete(e)}}getOptions(){return{...this._p,center:this.center,bounds:this.bounds}}setOptions(e){this._p={...this._p,...e},delete this._c,delete this._cc,this.render()}get container(){if(!this._c){let e=document.querySelector(this._p.container);if(!e)throw Error(`missing container element`);this._c=e}return this._c}get box(){let e=this.container.getBoundingClientRect();return{x:e.left,y:e.top,w:e.width,h:e.height}}get bounds(){let e=this._p.bounds;return e?{...e}:{}}set bounds(e){this._p.bounds=e}get center(){let e=this._p.center;return e?e.slice():[0,0]}set center(e){this._p.center=e,delete this._cc,this.render()}get centerCoords(){if(!this._cc){let[e,t]=this.center;this._cc=this.toPixelCoords(e,t)}return this._cc}get zoom(){return this._p.zoom??this._p.minZoom??0}set zoom(e){let{minZoom:t,maxZoom:n}=this,r=e;e<t&&(r=t),e>n&&(r=n),this._p.zoom=r,delete this._cc,this.render()}get minZoom(){return this._p.minZoom??-1/0}set minZoom(e){this._p.minZoom=e,this.zoom<this.minZoom&&(this.zoom=this.minZoom)}get maxZoom(){return this._p.maxZoom??1/0}set maxZoom(e){this._p.maxZoom=e,this.zoom>this.maxZoom&&(this.zoom=this.maxZoom)}get projection(){return this._p.projection??`spherical`}set projection(e){this._p.projection=e,this.render()}get lang(){return this._p.lang??``}set lang(e){this._p.lang=e,this.render()}inPixelBounds(e,t){let[n,r]=this.toGeoCoords(e,t);return this.inBounds(n,r)}inBounds(e,t){let{minLat:n=i,maxLat:r=a,minLon:s=o,maxLon:c=180}=this.bounds;return e>=n&&e<=r&&t>=s&&t<=c}canMoveTo(e,t){if(!this.inBounds(e,t))return!1;let{w:n,h:r}=this.box;if(n===0||r===0)return!1;let[i,a]=this.toPixelCoords(e,t);return this.inPixelBounds(i-n/2,a-r/2)&&this.inPixelBounds(i+n/2,a+r/2)}toPixelCoords(e,n){let i=r[this.projection],a=f(2,this.zoom+7)/c,o=e*t,s=i===0?1:f((1-i*l(o))/(1+i*l(o)),i/2);return[a*(c+n*t),a*(c-m(s*u(c/4+o/2)))]}toGeoCoords(e,t){let o=r[this.projection],s=f(2,this.zoom+7)/c,l=(e/s-c)*n,u;if(o===0)u=2*(d(p(c-t/s))-c/4)*n;else{u=i;let e=a-i,n=NaN,r=0;for(;(Number.isNaN(n)||h(n-t)>.1)&&r++<30;)e/=2,n=this.toPixelCoords(u+e,l)[1],n>t&&(u+=e)}return(l<-180||l>=180)&&(l=(l+180)%360-180),(u<-90||u>=90)&&(u=(u+90)%180-90),[u,l]}};function _(e){let t=`touches`in e?e.touches[0]:e;return t?[t.clientX,t.clientY]:null}function v(e,t){return t===void 0||!(e instanceof HTMLElement)?!1:typeof t==`function`&&t(e)||typeof t==`string`&&e.closest(t)!==null}function y(e,t,n){let r=Date.now(),i=null,a=e=>{r=Date.now(),i=_(e)},o=a=>{if(v(a.target,n)||!i||Date.now()-r>150)return;let{box:o,centerCoords:[s,c]}=e,l=i[0]-o.x,u=i[1]-o.y,[d,f]=e.toGeoCoords(l-.5*o.w+s,u-.5*o.h+c);t({x:l,y:u,lat:d,lon:f,originalEvent:a}),i=null};return e.container.addEventListener(`mousedown`,a),e.container.addEventListener(`mouseup`,o),e.container.addEventListener(`touchstart`,a),e.container.addEventListener(`touchend`,o),()=>{e.container.removeEventListener(`mousedown`,a),e.container.removeEventListener(`mouseup`,o),e.container.removeEventListener(`touchstart`,a),e.container.removeEventListener(`touchend`,o)}}function b(){return Math.random().toString(36).slice(2)}function x(e,{id:t,className:n,inset:r=`0`}={}){let i=`${n?`.${n}`:``}${t?`[data-id="${t}"]`:``}`,a=document.querySelector(i);return a||(a=document.createElement(`div`),a.className=`${n?`${n} `:``}layer`,a.dataset.id=t??b(),a.style=`position: absolute; inset: ${r};`,e.container.append(a)),a}function S(e,t){return typeof t==`function`?t(e):t??``}function C(e,t){return e.toFixed(t).replace(/\.(\d*[^0])0+$/,`.$1`).replace(/\.0+$/,``)}function w(e,t,{className:n,coords:r,inset:i,layer:a,content:o}){let s=a??x(e,{className:`elements`});n&&t.setAttribute(`class`,n),t.style.position=`absolute`,s.append(t),e.onRender(()=>{if(i)t.style.inset=S(e,i);else if(r){let{centerCoords:[n,i],box:{w:a,h:o}}=e,[s,c]=e.toPixelCoords(...r),l=C(s-n+a/2,2),u=C(c-i+o/2,2);t.style.transform=`translate3d(${l}px, ${u}px, 0)`}if(o){let n=S(e,o);t.innerHTML!==n&&(t.innerHTML=n)}})}function T(e,{onStart:t,onMove:n,onEnd:r,wheel:i}={}){let a=null,o=null,s=Date.now(),c=!1,l=null,u=null;function d(t,r,i=100){u!==null&&(clearTimeout(u),u=null),l!==null&&(cancelAnimationFrame(l),l=null);let c=Date.now();c-s<i||(a!==null&&(a-=t),o!==null&&(o-=r),s=c,e.dataset.dragged||(e.dataset.dragged=`true`),l=requestAnimationFrame(()=>{l=null,(t!==0||r!==0)&&n?.(t,r)}))}function f(e,t,n){a!==null&&o!==null&&d(a-e,o-t,n)}function p(e,n){c=!0,t?.(),e!==void 0&&(a=e),n!==void 0&&(o=n),s=Date.now()}function m(t,n){c=!1,u=null,t!==void 0&&n!==void 0&&f(t,n),delete e.dataset.dragged,a=null,o=null,requestAnimationFrame(()=>{r?.()})}e.dataset.draggable=`true`;let h=null,g=null;e.addEventListener(`mousedown`,t=>{t.preventDefault(),!h&&(p(t.clientX,t.clientY),h=e=>{e.preventDefault(),f(e.clientX,e.clientY)},e.addEventListener(`mousemove`,h))}),e.addEventListener(`mouseup`,t=>{t.preventDefault(),h&&=(m(t.clientX,t.clientY),e.removeEventListener(`mousemove`,h),null)}),e.addEventListener(`touchstart`,t=>{t.preventDefault(),!g&&(p(t.touches[0]?.clientX,t.touches[0]?.clientY),g=e=>{e.preventDefault(),f(e.touches[0]?.clientX,e.touches[0]?.clientY)},e.addEventListener(`touchmove`,g))}),e.addEventListener(`touchend`,t=>{t.preventDefault(),g&&=(m(t.touches[0]?.clientX,t.touches[0]?.clientY),e.removeEventListener(`touchmove`,g),null)}),e.addEventListener(`touchcancel`,t=>{t.preventDefault(),g&&=(m(t.touches[0]?.clientX,t.touches[0]?.clientY),e.removeEventListener(`touchmove`,g),null)}),i&&e.addEventListener(`wheel`,e=>{e.preventDefault(),c||p(),e.shiftKey?d(e.deltaY,e.deltaX,10):d(e.deltaX,e.deltaY,10),u=setTimeout(()=>{m()},200)})}function E(e){let t=0,n=0;T(e.container,{onStart(){[t,n]=e.centerCoords},onMove(r,i){let a=t+r,o=n+i,s=e.toGeoCoords(a,o);e.canMoveTo(...s)&&(e.center=s,t=a,n=o)},wheel:!0})}function D(e,{storageKey:t,session:n=!1}={}){let r=n?window.sessionStorage:window.localStorage,i=t??[`maparea`,e.container.id].filter(Boolean).join(`#`),a=e.getOptions(),o=!1,s=()=>{try{r.setItem(i,JSON.stringify(e.getOptions()))}catch{}},c=()=>{try{let t=r.getItem(i);t===null?s():e.setOptions(JSON.parse(t))}catch{}},l=e=>{o=e===void 0?!o:e},u=()=>{e.setOptions(a)};c();let d=null;return e.onRender(()=>{o||(d&&=(clearTimeout(d),null),d=setTimeout(()=>{d=null,s()},350))}),{sync:c,write:s,toggle:l,reset:u}}function O(e,t){let n=new ResizeObserver(n=>{for(let r of n)if(r.contentBoxSize){if(t)if(r.contentBoxSize){let{inlineSize:e,blockSize:n}=r.contentBoxSize[0]??r.contentBoxSize;t({inlineSize:e,blockSize:n})}else{let{width:e,height:n}=r.contentRect;t({width:e,height:n})}e.render()}});return n.observe(e.container),()=>{n.unobserve(e.container)}}const k=`http://www.w3.org/2000/svg`,A={className:`shape`};function j(e,t,n){let r=x(e,n??A);r.toggleAttribute(`hidden`,t.length===0);let i=r.querySelector(`svg`);i||(i=document.createElementNS(k,`svg`),i.setAttribute(`xmlns`,k),r.append(i));let a=N(i,t.map(({id:t,coords:[n,r]})=>({id:t,coords:e.toPixelCoords(n,r)})),n);if(a){let{xMin:t,xMax:n,yMin:r,yMax:o}=a,{centerCoords:[s,c],box:l}=e,u=C(n-t,3),d=C(o-r,3),f=C(.5*l.w+t-s,2),p=C(.5*l.h+r-c,2);i.setAttribute(`viewBox`,`0 0 ${u} ${d}`),i.setAttribute(`width`,u),i.setAttribute(`height`,d),i.setAttribute(`style`,`position: absolute; transform: translate3d(${f}px, ${p}px, 0);`)}return r}function M(e){return parseFloat(window.getComputedStyle(e).strokeWidth||e.getAttribute(`stroke-width`)||`1`)}function N(e,t,n){if(t.length===0){e.innerHTML=``;return}let r=e.querySelector(`path`);r||(r=document.createElementNS(k,`path`),e.append(r));let i=t[0].coords[0],a=i,o=t[0].coords[1],s=o,c=``;for(let{coords:[e,n]}of t)i>e&&(i=e),a<e&&(a=e),o>n&&(o=n),s<n&&(s=n);i-=10,a+=10,o-=10,s+=10;let l=Array.from(e.querySelectorAll(`.marker`)),u=0;for(let{id:a,coords:[s,d]}of t){let t=C(s-i,3),f=C(d-o,3);if(c+=`${c?` L`:`M`} ${t} ${f}`,n?.markers){let n=l[u++];n||(n=document.createElementNS(k,`circle`),n.setAttribute(`class`,`marker`),n.setAttribute(`r`,String(1.5*M(r))),e.append(n)),n.setAttribute(`cx`,t),n.setAttribute(`cy`,f),n.dataset.id=a}}for(let e=u;e<l.length;e++)l[e].remove();return r.setAttribute(`d`,c),{xMin:i,xMax:a,yMin:o,yMax:s}}function P(e,t,n){let r=t.map(e=>({id:b(),coords:e}));e.onRender(()=>{j(e,r,{className:`shape`,...n})})}function F(e,t){let n=[],r=null,i={className:`shape-editor`,markers:!0},a=()=>{j(e,n,i),t?.onUpdate?.(n)};y(e,({lat:e,lon:t,originalEvent:i})=>{let o=(i.target?.closest(`.marker`))?.dataset.id;if(o&&r){clearTimeout(r),r=null,n=n.filter(({id:e})=>e!==o),a();return}let s=()=>{n.push({id:b(),coords:[e,t]}),a(),r=null};o?r=setTimeout(s,250):s()},t?.ignoreClicks),e.onRender(a)}const{floor:I,ceil:L,random:R}=Math;function z(e,t,n){return`${t},${n},${e.zoom},${e.lang}`}function B(e,t,n,{size:r=256,url:i,subdomains:a,retries:o=0,error:s}){let c=new Image,l=0,u=(r,o)=>{if(!i)return``;if(typeof i==`function`)return i(e,t,n);let s=i.replaceAll(`{x}`,String(r)).replaceAll(`{y}`,String(o)).replaceAll(`{z}`,String(e.zoom)).replaceAll(`{lang}`,e.lang);return a&&s.includes(`{s}`)&&(s=s.replaceAll(`{s}`,a[I(a.length*R())])),s};return c.width=r,c.height=r,c.src=u(t,n),c.dataset.id=z(e,t,n),c.style=`position: absolute;`,c.onerror=()=>{l++;let{src:i}=c;if(!i||l>o){let t=S(e,s);t&&(c.onerror=()=>{},c.dataset.src=i,c.src=t);return}let a=t*r,d=n*r,f=e.toPixelCoords(...e.toGeoCoords(a,d))[0],p=I(f/r);if(t!==p)c.src=u(p,n);else{let e=new URL(i);e.searchParams.set(`_t`,String(Date.now())),c.src=e.href}},c}function V(e){return e.querySelectorAll(`img[data-id]`)}function H(e,t){return e.querySelector(`img[data-id="${t}"]`)}function U(e,t={}){let{id:n=b(),attribution:r,attributionInset:i=`auto 0 0 auto`}=t,a=x(e,{id:n,className:`tiles`,...t}),o=x(e,{id:n,className:`tiles-attribution`,inset:i}),s=()=>{let{box:{w:n,h:i},centerCoords:[s,c]}=e,{size:l=256,margin:u=0}=t,d=Array.isArray(u)?u[0]:u,f=Array.isArray(u)?u[1]:u,p=L((n+2*d)/l),m=L((i+2*f)/l),h=I(s/l),g=I(c/l),_=null,v=new Set,y=``;for(let r=0;r<=p;r++){let o=h+(r%2==0?-1:1)*I(r/2);for(let r=0;r<=m;r++){let u=g+(r%2==0?-1:1)*I(r/2);y=z(e,o,u),_=H(a,y),_||(_=B(e,o,u,t),a.append(_));let d=C(.5*n+o*l-s,2),f=C(.5*i+u*l-c,2);_.style.transform=`translate3d(${d}px, ${f}px, 0)`,v.add(y)}}for(let e of V(a)){let{id:t}=e.dataset;t&&!v.has(t)&&e.remove()}let b=S(e,r);o.toggleAttribute(`hidden`,!b),o.innerHTML!==b&&(o.innerHTML=b)},c=e.zoom,l=null;return e.onRender(()=>{l!==null&&(clearTimeout(l),l=null),e.zoom===c?(a.style.opacity=``,s()):(a.style.opacity=`0`,l=setTimeout(()=>{l=null,a.style.opacity=``,s()},300)),c=e.zoom}),a}function W(e,t={}){let{plus:n=`➕`,minus:r=`➖`,inset:i=`0 0 auto auto`}=t,a=x(e,{className:`zoom-controls`,inset:i}),o=document.createElement(`button`);o.dataset.id=`plus`,o.innerHTML=n;let s=document.createElement(`button`);s.dataset.id=`minus`,s.innerHTML=r;let c=()=>{o.toggleAttribute(`disabled`,e.zoom+1>e.maxZoom),s.toggleAttribute(`disabled`,e.zoom-1<e.minZoom)};return y(e,({originalEvent:t})=>{let n=t.target?.closest(`button`);n&&(t.stopPropagation(),e.zoom+=n.dataset.id===`minus`?-1:1,c())}),e.onRender(c),a.append(o,s),a}const{abs:G,log2:K,min:q,floor:J}=Math;function Y(e,t){let{box:{w:n,h:r},center:[i,a],zoom:o}=e,{minLat:s,maxLat:c,minLon:l,maxLon:u}=t,d=0,f=0;if(l!==void 0&&u!==void 0){let t=G(e.toPixelCoords(i,u)[0]-e.toPixelCoords(i,l)[0]);t!==0&&(d=K(n/t))}if(s!==void 0&&c!==void 0){let t=G(e.toPixelCoords(s,a)[1]-e.toPixelCoords(c,a)[1]);t!==0&&(f=K(r/t))}let p=J(q(o+d,o+f));p!==o&&(e.zoom=p)}function X(e){if(e.length===0)return{};let t=e[0][0],n=t,r=e[0][1],i=r;for(let[a,o]of e)t>a&&(t=a),n<a&&(n=a),r>o&&(r=o),i<o&&(i=o);return{minLat:t,maxLat:n,minLon:r,maxLon:i}}function Z(e){let{minLat:t,maxLat:n,minLon:r,maxLon:i}=X(e);return[t===void 0||n===void 0?0:(n+t)/2,r===void 0||i===void 0?0:(i+r)/2]}function Q(e){return Array.isArray(e)&&e.length===2&&typeof e[0]==`number`&&typeof e[1]==`number`}const $=[.005,.018];function ee(e){return Array.isArray(e)?Q(e)?{minLat:e[0],maxLat:e[0],minLon:e[1],maxLon:e[1]}:X(e):e}function te(e,[t,n]=$){let{minLat:r=0,maxLat:i=0,minLon:a=0,maxLon:o=0}=ee(e);return{minLat:r-t,maxLat:i+t,minLon:a-n,maxLon:o+n}}export{n as DEG,a as MAX_LAT,s as MAX_LON,i as MIN_LAT,o as MIN_LON,g as MapArea,t as RAD,y as addClickListener,w as addElement,E as addNavigation,D as addPersistence,O as addResizeObserver,P as addShape,F as addShapeEditor,U as addTiles,W as addZoomControls,r as eccentricityMap,Y as fitBounds,Z as getCenter,X as getGeoBounds,b as getId,x as getLayer,_ as getPointerPosition,te as getVicinity,Q as isGeoCoords,S as resolveString,C as toPrecision};
1
+ const{PI:e}=Math,t=e/180,n=180/e,r={spherical:0,ellipsoidal:.0818191908426},i=-85.05,a=85.05,o=-180,s=180,{PI:c,sin:l,tan:u,atan:d,pow:f,exp:p,log:m,abs:h}=Math;var g=class{_p;_c;_cc;_r=new Set;constructor(e){this._p=e,this.container.style=`position: relative; overflow: hidden;`,this.container.dataset.type=`maparea`}render(){for(let e of this._r)e(this)}onRender(e,t=!1){return this._r.add(e),t||e(this),()=>{this._r.delete(e)}}getOptions(){return{...this._p,center:this.center,bounds:this.bounds}}setOptions(e){this._p={...this._p,...e},`container`in e&&delete this._c,delete this._cc,this.render()}get container(){if(!this._c){let e=document.querySelector(this._p.container);if(!e)throw Error(`missing container element`);this._c=e}return this._c}get box(){let e=this.container.getBoundingClientRect();return{x:e.left,y:e.top,w:e.width,h:e.height}}get bounds(){let e=this._p.bounds;return e?{...e}:{}}set bounds(e){this._p.bounds=e}get center(){let e=this._p.center;return e?e.slice():[0,0]}set center(e){this._p.center=e,delete this._cc,this.render()}get centerCoords(){if(!this._cc){let[e,t]=this.center;this._cc=this.toPixelCoords(e,t)}return this._cc}get zoom(){return this._p.zoom??this._p.minZoom??0}set zoom(e){let{minZoom:t,maxZoom:n}=this,r=e;e<t&&(r=t),e>n&&(r=n),this._p.zoom=r,delete this._cc,this.render()}get minZoom(){return this._p.minZoom??-1/0}set minZoom(e){this._p.minZoom=e,this.zoom<this.minZoom&&(this.zoom=this.minZoom)}get maxZoom(){return this._p.maxZoom??1/0}set maxZoom(e){this._p.maxZoom=e,this.zoom>this.maxZoom&&(this.zoom=this.maxZoom)}get projection(){return this._p.projection??`spherical`}set projection(e){this._p.projection=e,this.render()}get lang(){return this._p.lang??``}set lang(e){this._p.lang=e,this.render()}inPixelBounds(e,t){let[n,r]=this.toGeoCoords(e,t);return this.inBounds(n,r)}inBounds(e,t){let{minLat:n=i,maxLat:r=a,minLon:s=o,maxLon:c=180}=this.bounds;return e>=n&&e<=r&&t>=s&&t<=c}canMoveTo(e,t){if(!this.inBounds(e,t))return!1;let{w:n,h:r}=this.box;if(n===0||r===0)return!1;let[i,a]=this.toPixelCoords(e,t);return this.inPixelBounds(i-n/2,a-r/2)&&this.inPixelBounds(i+n/2,a+r/2)}toPixelCoords(e,n){let i=r[this.projection],a=f(2,this.zoom+7)/c,o=e*t,s=i===0?1:f((1-i*l(o))/(1+i*l(o)),i/2);return[a*(c+n*t),a*(c-m(s*u(c/4+o/2)))]}toGeoCoords(e,t){let o=r[this.projection],s=f(2,this.zoom+7)/c,l=(e/s-c)*n,u;if(o===0)u=2*(d(p(c-t/s))-c/4)*n;else{u=i;let e=a-i,n=NaN,r=0;for(;(Number.isNaN(n)||h(n-t)>.1)&&r++<30;)e/=2,n=this.toPixelCoords(u+e,l)[1],n>t&&(u+=e)}return(l<-180||l>=180)&&(l=(l+180)%360-180),(u<-90||u>=90)&&(u=(u+90)%180-90),[u,l]}};function _(e){let t=`touches`in e?e.touches[0]:e;return t?[t.clientX,t.clientY]:null}function v(e,t){return t===void 0||!(e instanceof HTMLElement)?!1:typeof t==`function`&&t(e)||typeof t==`string`&&e.closest(t)!==null}function y(e,t,n){let r=Date.now(),i=null,a=e=>{r=Date.now(),i=_(e)},o=a=>{if(v(a.target,n)||!i||Date.now()-r>150)return;let{box:o,centerCoords:[s,c]}=e,l=i[0]-o.x,u=i[1]-o.y,[d,f]=e.toGeoCoords(l-.5*o.w+s,u-.5*o.h+c);t({x:l,y:u,lat:d,lon:f,originalEvent:a}),i=null};return e.container.addEventListener(`mousedown`,a),e.container.addEventListener(`mouseup`,o),e.container.addEventListener(`touchstart`,a),e.container.addEventListener(`touchend`,o),()=>{e.container.removeEventListener(`mousedown`,a),e.container.removeEventListener(`mouseup`,o),e.container.removeEventListener(`touchstart`,a),e.container.removeEventListener(`touchend`,o)}}function b(){return Math.random().toString(36).slice(2)}function x(e,{id:t,className:n,inset:r=`0`}={}){let i=`${n?`.${n}`:``}${t?`[data-id="${t}"]`:``}`,a=document.querySelector(i);return a||(a=document.createElement(`div`),a.className=`${n?`${n} `:``}layer`,a.dataset.id=t??b(),a.style=`position: absolute; inset: ${r};`,e.container.append(a)),a}function S(e,t){return t===void 0?t:t instanceof Function?t(e):t}function C(e,t){return e.toFixed(t).replace(/\.(\d*[^0])0+$/,`.$1`).replace(/\.0+$/,``)}function w(e,t,{className:n,coords:r,inset:i,layer:a,content:o}){let s=a??x(e,{className:`elements`});n&&t.setAttribute(`class`,n),t.style.position=`absolute`,s.append(t),e.onRender(()=>{if(i)t.style.inset=S(e,i)??``;else if(r){let{centerCoords:[n,i],box:{w:a,h:o}}=e,[s,c]=e.toPixelCoords(...r),l=C(s-n+a/2,2),u=C(c-i+o/2,2);t.style.transform=`translate3d(${l}px, ${u}px, 0)`}if(o){let n=S(e,o)??``;t.innerHTML!==n&&(t.innerHTML=n)}})}function T(e,{onStart:t,onMove:n,onEnd:r,wheel:i}={}){let a=null,o=null,s=Date.now(),c=!1,l=null,u=null;function d(t,r,i=100){u!==null&&(clearTimeout(u),u=null),l!==null&&(cancelAnimationFrame(l),l=null);let c=Date.now();c-s<i||(a!==null&&(a-=t),o!==null&&(o-=r),s=c,e.dataset.dragged||(e.dataset.dragged=`true`),l=requestAnimationFrame(()=>{l=null,(t!==0||r!==0)&&n?.(t,r)}))}function f(e,t,n){a!==null&&o!==null&&d(a-e,o-t,n)}function p(e,n){c=!0,t?.(),e!==void 0&&(a=e),n!==void 0&&(o=n),s=Date.now()}function m(t,n){c=!1,u=null,t!==void 0&&n!==void 0&&f(t,n),delete e.dataset.dragged,a=null,o=null,requestAnimationFrame(()=>{r?.()})}e.dataset.draggable=`true`;let h=null,g=null;e.addEventListener(`mousedown`,t=>{t.preventDefault(),!h&&(p(t.clientX,t.clientY),h=e=>{e.preventDefault(),f(e.clientX,e.clientY)},e.addEventListener(`mousemove`,h))}),e.addEventListener(`mouseup`,t=>{t.preventDefault(),h&&=(m(t.clientX,t.clientY),e.removeEventListener(`mousemove`,h),null)}),e.addEventListener(`touchstart`,t=>{t.preventDefault(),!g&&(p(t.touches[0]?.clientX,t.touches[0]?.clientY),g=e=>{e.preventDefault(),f(e.touches[0]?.clientX,e.touches[0]?.clientY)},e.addEventListener(`touchmove`,g))}),e.addEventListener(`touchend`,t=>{t.preventDefault(),g&&=(m(t.touches[0]?.clientX,t.touches[0]?.clientY),e.removeEventListener(`touchmove`,g),null)}),e.addEventListener(`touchcancel`,t=>{t.preventDefault(),g&&=(m(t.touches[0]?.clientX,t.touches[0]?.clientY),e.removeEventListener(`touchmove`,g),null)}),i&&e.addEventListener(`wheel`,e=>{e.preventDefault(),c||p(),e.shiftKey?d(e.deltaY,e.deltaX,10):d(e.deltaX,e.deltaY,10),u=setTimeout(()=>{m()},200)})}function E(e,t){let n=0,r=0;T(e.container,{onStart(){[n,r]=e.centerCoords},onMove(t,i){let a=n+t,o=r+i,s=e.toGeoCoords(a,o);e.canMoveTo(...s)&&(e.center=s,n=a,r=o)},wheel:t?.wheel??!0})}function D(e,{storageKey:t,session:n=!1}={}){let r=n?window.sessionStorage:window.localStorage,i=t??[`maparea`,e.container.id].filter(Boolean).join(`#`),a=e.getOptions(),o=!1,s=()=>{try{r.setItem(i,JSON.stringify(e.getOptions()))}catch{}},c=()=>{try{let t=r.getItem(i);t===null?s():e.setOptions(JSON.parse(t))}catch{}},l=e=>{o=e===void 0?!o:e},u=()=>{e.setOptions(a)};c();let d=null;return e.onRender(()=>{o||(d&&=(clearTimeout(d),null),d=setTimeout(()=>{d=null,s()},350))}),{sync:c,write:s,toggle:l,reset:u}}function O(e,t){let n=new ResizeObserver(n=>{for(let r of n)if(r.contentBoxSize){if(t)if(r.contentBoxSize){let{inlineSize:e,blockSize:n}=r.contentBoxSize[0]??r.contentBoxSize;t({inlineSize:e,blockSize:n})}else{let{width:e,height:n}=r.contentRect;t({width:e,height:n})}e.render()}});return n.observe(e.container),()=>{n.unobserve(e.container)}}const k=`http://www.w3.org/2000/svg`,A={className:`shape`};function j(e,t,n){let r=x(e,n??A);r.toggleAttribute(`hidden`,t.length===0);let i=r.querySelector(`svg`);i||(i=document.createElementNS(k,`svg`),i.setAttribute(`xmlns`,k),r.append(i));let a=N(i,t.map(({id:t,coords:[n,r]})=>({id:t,coords:e.toPixelCoords(n,r)})),n);if(a){let{xMin:t,xMax:n,yMin:r,yMax:o}=a,{centerCoords:[s,c],box:l}=e,u=C(n-t,3),d=C(o-r,3),f=C(.5*l.w+t-s,2),p=C(.5*l.h+r-c,2);i.setAttribute(`viewBox`,`0 0 ${u} ${d}`),i.setAttribute(`width`,u),i.setAttribute(`height`,d),i.setAttribute(`style`,`position: absolute; transform: translate3d(${f}px, ${p}px, 0);`)}return r}function M(e){return parseFloat(window.getComputedStyle(e).strokeWidth||e.getAttribute(`stroke-width`)||`1`)}function N(e,t,n){if(t.length===0){e.innerHTML=``;return}let r=e.querySelector(`path`);r||(r=document.createElementNS(k,`path`),e.append(r));let i=t[0].coords[0],a=i,o=t[0].coords[1],s=o,c=``;for(let{coords:[e,n]}of t)i>e&&(i=e),a<e&&(a=e),o>n&&(o=n),s<n&&(s=n);i-=10,a+=10,o-=10,s+=10;let l=Array.from(e.querySelectorAll(`.marker`)),u=0;for(let{id:a,coords:[s,d]}of t){let t=C(s-i,3),f=C(d-o,3);if(c+=`${c?` L`:`M`} ${t} ${f}`,n?.markers){let n=l[u++];n||(n=document.createElementNS(k,`circle`),n.setAttribute(`class`,`marker`),n.setAttribute(`r`,String(1.5*M(r))),e.append(n)),n.setAttribute(`cx`,t),n.setAttribute(`cy`,f),n.dataset.id=a}}for(let e=u;e<l.length;e++)l[e].remove();return r.setAttribute(`d`,c),{xMin:i,xMax:a,yMin:o,yMax:s}}function P(e,t,n){let r=t.map(e=>({id:b(),coords:e}));e.onRender(()=>{j(e,r,{className:`shape`,...n})})}function F(e,t){let n=[],r=null,i={className:`shape-editor`,markers:!0},a=()=>{j(e,n,i),t?.onUpdate?.(n)};y(e,({lat:e,lon:t,originalEvent:i})=>{let o=(i.target?.closest(`.marker`))?.dataset.id;if(o&&r){clearTimeout(r),r=null,n=n.filter(({id:e})=>e!==o),a();return}let s=()=>{n.push({id:b(),coords:[e,t]}),a(),r=null};o?r=setTimeout(s,250):s()},t?.ignoreClicks),e.onRender(a)}const{floor:I,ceil:L,random:R}=Math;function z(e,t,n){return`${t},${n},${e.zoom},${e.lang}`}function B(e,t,n,{size:r,url:i,subdomains:a,error:o}){let s=new Image,c=S(e,r)??256;return s.width=c,s.height=c,s.src=((r,o)=>{if(!i)return``;if(typeof i==`function`)return i(e,t,n);let s=i.replaceAll(`{x}`,String(r)).replaceAll(`{y}`,String(o)).replaceAll(`{z}`,String(e.zoom)).replaceAll(`{lang}`,e.lang);return a&&s.includes(`{s}`)&&(s=s.replaceAll(`{s}`,a[I(a.length*R())])),s})(t,n),s.dataset.id=z(e,t,n),s.style=`position: absolute;`,s.addEventListener(`error`,t=>{let n=t.target;if(n instanceof HTMLImageElement){let t=S(e,o);t&&(n.dataset.src=s.src,n.src=t)}}),s}function V(e){return e.querySelectorAll(`img[data-id]`)}function H(e,t){return e.querySelector(`img[data-id="${t}"]`)}function U(e,t={}){let{id:n=b(),attribution:r,attributionInset:i=`auto 0 0 auto`}=t,a=x(e,{id:n,className:`tiles`,...t}),o=x(e,{id:n,className:`tiles-attribution`,inset:i}),s=()=>{let{box:{w:n,h:i},centerCoords:[s,c]}=e,{size:l,margin:u=0}=t,d=S(e,l)??256,f=Array.isArray(u)?u[0]:u,p=Array.isArray(u)?u[1]:u,m=L((n+2*f)/d),h=L((i+2*p)/d),g=I(s/d),_=I(c/d),v=null,y=new Set,b=``;for(let r=0;r<=m;r++){let o=g+(r%2==0?-1:1)*I(r/2);for(let r=0;r<=h;r++){let l=_+(r%2==0?-1:1)*I(r/2);b=z(e,o,l),v=H(a,b),v||(v=B(e,o,l,t),a.append(v));let u=C(.5*n+o*d-s,2),f=C(.5*i+l*d-c,2);v.style.transform=`translate3d(${u}px, ${f}px, 0)`,y.add(b)}}for(let e of V(a)){let{id:t}=e.dataset;t&&!y.has(t)&&e.remove()}let x=S(e,r)??``;o.toggleAttribute(`hidden`,!x),o.innerHTML!==x&&(o.innerHTML=x)},c=e.zoom,l=null;return e.onRender(()=>{l!==null&&(clearTimeout(l),l=null),e.zoom===c?(a.style.opacity=``,s()):(a.style.opacity=`0`,l=setTimeout(()=>{l=null,a.style.opacity=``,s()},300)),c=e.zoom}),a}function W(e,t={}){let{plus:n=`➕`,minus:r=`➖`,inset:i=`0 0 auto auto`}=t,a=x(e,{className:`zoom-controls`,inset:i}),o=document.createElement(`button`);o.dataset.id=`plus`,o.innerHTML=n;let s=document.createElement(`button`);s.dataset.id=`minus`,s.innerHTML=r;let c=()=>{o.toggleAttribute(`disabled`,e.zoom+1>e.maxZoom),s.toggleAttribute(`disabled`,e.zoom-1<e.minZoom)};return y(e,({originalEvent:t})=>{let n=t.target?.closest(`button`);n&&(t.stopPropagation(),e.zoom+=n.dataset.id===`minus`?-1:1,c())}),e.onRender(c),a.append(o,s),a}function G(e){if(e.length===0)return{};let t=e[0][0],n=t,r=e[0][1],i=r;for(let[a,o]of e)t>a&&(t=a),n<a&&(n=a),r>o&&(r=o),i<o&&(i=o);return{minLat:t,maxLat:n,minLon:r,maxLon:i}}function K(e){return Array.isArray(e)&&e.length===2&&typeof e[0]==`number`&&typeof e[1]==`number`}function q(e){return K(e)?{minLat:e[0],maxLat:e[0],minLon:e[1],maxLon:e[1]}:Array.isArray(e)?G(e):e}function J(e){let{minLat:t,maxLat:n,minLon:r,maxLon:i}=q(e);return[t===void 0||n===void 0?0:(n+t)/2,r===void 0||i===void 0?0:(i+r)/2]}const{abs:Y,log2:X,min:Z,floor:Q}=Math;function $(e,t){let{box:{w:n,h:r},center:[i,a],zoom:o}=e,{minLat:s,maxLat:c,minLon:l,maxLon:u}=t,d=0,f=0;if(l!==void 0&&u!==void 0){let t=Y(e.toPixelCoords(i,u)[0]-e.toPixelCoords(i,l)[0]);t!==0&&(d=X(n/t))}if(s!==void 0&&c!==void 0){let t=Y(e.toPixelCoords(s,a)[1]-e.toPixelCoords(c,a)[1]);t!==0&&(f=X(r/t))}let p=Q(Z(o+d,o+f)),m={center:J(t)};p!==o&&(m.zoom=p),e.setOptions(m)}const ee=[.005,.018];function te(e,t=ee){let{minLat:n=0,maxLat:r=0,minLon:i=0,maxLon:a=0}=q(e),[o,s]=t;return{minLat:n-o,maxLat:r+o,minLon:i-s,maxLon:a+s}}export{n as DEG,a as MAX_LAT,s as MAX_LON,i as MIN_LAT,o as MIN_LON,g as MapArea,t as RAD,y as addClickListener,w as addElement,E as addMovableViewport,D as addPersistence,O as addResizeObserver,P as addShape,F as addShapeEditor,U as addTiles,W as addZoomControls,r as eccentricityMap,$ as fitGeoBounds,J as getCenter,G as getGeoBounds,b as getId,x as getLayer,_ as getPointerPosition,te as getVicinity,K as isCoordsArray,S as resolveDynamic,q as toGeoBounds,C as toPrecision};
package/index.ts CHANGED
@@ -2,7 +2,7 @@ export * from "./src/MapArea/const.ts";
2
2
  export * from "./src/MapArea/index.ts";
3
3
  export * from "./src/plugins/addClickListener.ts";
4
4
  export * from "./src/plugins/addElement.ts";
5
- export * from "./src/plugins/addNavigation.ts";
5
+ export * from "./src/plugins/addMovableViewport.ts";
6
6
  export * from "./src/plugins/addPersistence.ts";
7
7
  export * from "./src/plugins/addResizeObserver.ts";
8
8
  export * from "./src/plugins/addShape.ts";
@@ -10,7 +10,7 @@ export * from "./src/plugins/addShapeEditor.ts";
10
10
  export * from "./src/plugins/addTiles.ts";
11
11
  export * from "./src/plugins/addZoomControls.ts";
12
12
  export * from "./src/types/BoxDimensions.ts";
13
- export * from "./src/types/DynamicString.ts";
13
+ export * from "./src/types/Dynamic.ts";
14
14
  export * from "./src/types/GeoBounds.ts";
15
15
  export * from "./src/types/GeoCoords.ts";
16
16
  export * from "./src/types/GeoVertex.ts";
@@ -20,13 +20,14 @@ export * from "./src/types/PixelCoords.ts";
20
20
  export * from "./src/types/PixelVertex.ts";
21
21
  export * from "./src/types/Projection.ts";
22
22
  export * from "./src/types/ShapeLayerOptions.ts";
23
- export * from "./src/utils/fitBounds.ts";
23
+ export * from "./src/utils/fitGeoBounds.ts";
24
24
  export * from "./src/utils/getCenter.ts";
25
25
  export * from "./src/utils/getGeoBounds.ts";
26
26
  export * from "./src/utils/getId.ts";
27
27
  export * from "./src/utils/getLayer.ts";
28
28
  export * from "./src/utils/getPointerPosition.ts";
29
29
  export * from "./src/utils/getVicinity.ts";
30
- export * from "./src/utils/isGeoCoords.ts";
31
- export * from "./src/utils/resolveString.ts";
30
+ export * from "./src/utils/isCoordsArray.ts";
31
+ export * from "./src/utils/resolveDynamic.ts";
32
+ export * from "./src/utils/toGeoBounds.ts";
32
33
  export * from "./src/utils/toPrecision.ts";
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
- {
2
- "name": "maparea",
3
- "version": "0.1.10",
4
- "type": "module",
5
- "main": "./dist/index.cjs",
6
- "module": "./dist/index.mjs",
7
- "types": "./dist/index.d.ts",
8
- "scripts": {
9
- "preversion": "npm run shape",
10
- "shape": "npx codeshape --minify",
11
- "start": "npx @t8/serve test --spa -b --watch"
12
- },
13
- "repository": {
14
- "type": "git",
15
- "url": "git://github.com/axtk/maparea.git"
16
- },
17
- "author": "axtk",
18
- "license": "MIT"
19
- }
1
+ {
2
+ "name": "maparea",
3
+ "version": "0.1.12",
4
+ "type": "module",
5
+ "main": "./dist/index.cjs",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "scripts": {
9
+ "preversion": "npm run shape",
10
+ "shape": "npx codeshape --minify",
11
+ "start": "npx @t8/serve test --spa -b --watch"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git://github.com/axtk/maparea.git"
16
+ },
17
+ "author": "axtk",
18
+ "license": "MIT"
19
+ }