ol-elevation-profile 2.1.0 → 2.1.2

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.
@@ -262,12 +262,20 @@ export type ElevationProfileOptions = {
262
262
  * `{exaggeration}` fixes the ratio between the two axes instead, which makes SLOPES
263
263
  * comparable: the gradient read off the chart is the real one, multiplied by the same
264
264
  * factor on every track, and the control recomputes it per track and per A/B crop.
265
- * Either form is a **floor**, not a cage: a track whose range exceeds what the height
266
- * can show would spill out of the frame, which is worse than losing comparability, so
267
- * the scale then widens silently, nothing being drawn on the chart to say so.
265
+ * `{maxExaggeration}` keeps `'auto'` the height is filled, which reads best and
266
+ * only reins in the absurd: a short, gently sloping track whose 2 % ramp would
267
+ * otherwise be drawn as a wall. A track already under the cap is untouched, so unlike
268
+ * a fixed exaggeration it never flattens a mountain traverse to fit a rule.
269
+ * A number or `{exaggeration}` is a **floor**, not a cage: a track whose range exceeds
270
+ * what the height can show would spill out of the frame, which is worse than losing
271
+ * comparability, so the scale then widens silently, nothing being drawn on the chart
272
+ * to say so. The extra room the scale asks for is added ABOVE the track, never below:
273
+ * centring it would push the axis under sea level on a mountain profile.
268
274
  */
269
275
  verticalScale?: ('auto' | number | {
270
276
  exaggeration: number;
277
+ } | {
278
+ maxExaggeration: number;
271
279
  });
272
280
  /**
273
281
  * How a track is selected on the map.
@@ -419,16 +427,22 @@ export type ElevationProfileOptions = {
419
427
  * @property {number} [smoothing=0] Elevation smoothing window, in METERS (0 = none).
420
428
  * @property {?number} [xTicks=null] X axis ticks (null = auto from width).
421
429
  * @property {?number} [yTicks=null] Y axis ticks (null = auto from height).
422
- * @property {('auto'|number|{exaggeration:number})} [verticalScale='auto'] `'auto'`: the
430
+ * @property {('auto'|number|{exaggeration:number}|{maxExaggeration:number})} [verticalScale='auto'] `'auto'`: the
423
431
  * profile fills the height, which is legible but changes scale from one track to the
424
432
  * next, so a 2 % ramp looks like a wall and two profiles cannot be compared. A number
425
433
  * fixes the metres covered per physical centimetre, which makes RANGES comparable.
426
434
  * `{exaggeration}` fixes the ratio between the two axes instead, which makes SLOPES
427
435
  * comparable: the gradient read off the chart is the real one, multiplied by the same
428
436
  * factor on every track, and the control recomputes it per track and per A/B crop.
429
- * Either form is a **floor**, not a cage: a track whose range exceeds what the height
430
- * can show would spill out of the frame, which is worse than losing comparability, so
431
- * the scale then widens silently, nothing being drawn on the chart to say so.
437
+ * `{maxExaggeration}` keeps `'auto'` the height is filled, which reads best and
438
+ * only reins in the absurd: a short, gently sloping track whose 2 % ramp would
439
+ * otherwise be drawn as a wall. A track already under the cap is untouched, so unlike
440
+ * a fixed exaggeration it never flattens a mountain traverse to fit a rule.
441
+ * A number or `{exaggeration}` is a **floor**, not a cage: a track whose range exceeds
442
+ * what the height can show would spill out of the frame, which is worse than losing
443
+ * comparability, so the scale then widens silently, nothing being drawn on the chart
444
+ * to say so. The extra room the scale asks for is added ABOVE the track, never below:
445
+ * centring it would push the axis under sea level on a mountain profile.
432
446
  * @property {'click'|'mouseover'} [show='click'] How a track is selected on the map.
433
447
  * @property {boolean} [showWithoutElevation=true] What to do with a track that ends up
434
448
  * with no elevation at all: none in its geometry, and none the terrain model could
@@ -742,7 +756,9 @@ declare class ElevationProfile extends Control {
742
756
  *
743
757
  * @private
744
758
  */
745
- private _verticalScaleFor;
759
+ /** Le rapport à ne pas dépasser, `0` s'il n'en est pas demandé. @private */
760
+ private _plafondExageration;
761
+ _verticalScaleFor(s: any, innerW: any): number;
746
762
  _statsOf(samples: any, fromTotal: any): {
747
763
  distance: number;
748
764
  duration: number;
@@ -1,4 +1,4 @@
1
- /*! ol-elevation-profile 2.1.0 | MIT License | https://github.com/lc-4918/ol-elevation-profile */
1
+ /*! ol-elevation-profile 2.1.2 | MIT License | https://github.com/lc-4918/ol-elevation-profile */
2
2
  import Control from 'ol/control/Control.js';
3
3
  import Overlay from 'ol/Overlay.js';
4
4
  import { unByKey } from 'ol/Observable.js';
@@ -116,7 +116,8 @@ import * as d3 from 'd3';
116
116
  yTicks: null,
117
117
  verticalScale: 'auto', // 'auto' : le profil remplit la hauteur ;
118
118
  // un nombre : mètres par centimètre physique ;
119
- // { exaggeration } : rapport fixe vertical/horizontal
119
+ // { exaggeration } : rapport fixe vertical/horizontal ;
120
+ // { maxExaggeration } : 'auto' sans dépasser ce rapport
120
121
  show: 'click',
121
122
  showWithoutElevation: true, // trace sans Z, et aucun MNT n'a pu en fournir :
122
123
  // le panneau paraît quand même, avec un message
@@ -838,16 +839,22 @@ import * as d3 from 'd3';
838
839
  * @property {number} [smoothing=0] Elevation smoothing window, in METERS (0 = none).
839
840
  * @property {?number} [xTicks=null] X axis ticks (null = auto from width).
840
841
  * @property {?number} [yTicks=null] Y axis ticks (null = auto from height).
841
- * @property {('auto'|number|{exaggeration:number})} [verticalScale='auto'] `'auto'`: the
842
+ * @property {('auto'|number|{exaggeration:number}|{maxExaggeration:number})} [verticalScale='auto'] `'auto'`: the
842
843
  * profile fills the height, which is legible but changes scale from one track to the
843
844
  * next, so a 2 % ramp looks like a wall and two profiles cannot be compared. A number
844
845
  * fixes the metres covered per physical centimetre, which makes RANGES comparable.
845
846
  * `{exaggeration}` fixes the ratio between the two axes instead, which makes SLOPES
846
847
  * comparable: the gradient read off the chart is the real one, multiplied by the same
847
848
  * factor on every track, and the control recomputes it per track and per A/B crop.
848
- * Either form is a **floor**, not a cage: a track whose range exceeds what the height
849
- * can show would spill out of the frame, which is worse than losing comparability, so
850
- * the scale then widens silently, nothing being drawn on the chart to say so.
849
+ * `{maxExaggeration}` keeps `'auto'` the height is filled, which reads best and
850
+ * only reins in the absurd: a short, gently sloping track whose 2 % ramp would
851
+ * otherwise be drawn as a wall. A track already under the cap is untouched, so unlike
852
+ * a fixed exaggeration it never flattens a mountain traverse to fit a rule.
853
+ * A number or `{exaggeration}` is a **floor**, not a cage: a track whose range exceeds
854
+ * what the height can show would spill out of the frame, which is worse than losing
855
+ * comparability, so the scale then widens silently, nothing being drawn on the chart
856
+ * to say so. The extra room the scale asks for is added ABOVE the track, never below:
857
+ * centring it would push the axis under sea level on a mountain profile.
851
858
  * @property {'click'|'mouseover'} [show='click'] How a track is selected on the map.
852
859
  * @property {boolean} [showWithoutElevation=true] What to do with a track that ends up
853
860
  * with no elevation at all: none in its geometry, and none the terrain model could
@@ -1507,23 +1514,44 @@ import * as d3 from 'd3';
1507
1514
  // La publier partout est le seul moyen de voir la différence plutôt que d'y croire.
1508
1515
  const rapport = (etendue) => (cmH > 0 && etendue > 0) ? (s.distance / cmH) / (etendue / cm) : null;
1509
1516
 
1510
- const vs = this._verticalScaleFor(s, innerW);
1517
+ let vs = this._verticalScaleFor(s, innerW);
1511
1518
  if (!(vs > 0)) {
1512
1519
  // `'auto'` : la hauteur est remplie, donc c'est l'amplitude qui décide de tout.
1513
1520
  // `nice()` arrondit le domaine vers l'extérieur, d'où la lecture APRÈS coup.
1514
1521
  const echelle = d3.scaleLinear().domain([bas, haut]).range([innerH, 0]).nice();
1515
1522
  const dom = echelle.domain();
1516
- this._vScale = null; // aucune échelle absolue demandée
1517
- this._vExaggeration = rapport(dom[1] - dom[0]);
1518
- return echelle;
1523
+ const obtenu = rapport(dom[1] - dom[0]);
1524
+ // Un PLAFOND d'exagération, s'il en est demandé un. Remplir la hauteur est ce
1525
+ // qui se lit le mieux, mais sur une trace courte et peu accidentée cela dresse
1526
+ // une pente de 2 % en muraille. Le plafond n'intervient que là : quand le
1527
+ // remplissage dépasse le rapport permis, on élargit l'échelle jusqu'à lui. Une
1528
+ // trace assez accidentée pour rester en dessous n'est jamais aplatie, ce qu'une
1529
+ // exagération FIXE lui imposerait — à 680 km d'une traversée, elle n'occuperait
1530
+ // plus qu'un dixième du cadre.
1531
+ const plafond = this._plafondExageration();
1532
+ if (!(plafond > 0) || obtenu == null || obtenu <= plafond) {
1533
+ this._vScale = null; // aucune échelle absolue demandée
1534
+ this._vExaggeration = obtenu;
1535
+ return echelle;
1536
+ }
1537
+ vs = (s.distance / cmH) / plafond; // l'échelle qui donne exactement le plafond
1519
1538
  }
1520
1539
  const etendue = Math.max(vs * cm, haut - bas); // jamais moins qu'il n'en faut
1521
- const milieu = (bas + haut) / 2;
1522
1540
  this._vScale = etendue / cm; // m/cm effectivement appliqués
1523
1541
  // Sous le plancher, le rapport retombe sous celui demandé : c'est la seule façon de
1524
1542
  // savoir que c'est arrivé.
1525
1543
  this._vExaggeration = rapport(etendue);
1526
- return d3.scaleLinear().domain([milieu - etendue / 2, milieu + etendue / 2]).range([innerH, 0]);
1544
+
1545
+ // La marge que l'échelle impose se place AU-DESSUS, pas de part et d'autre.
1546
+ // Centrer la fenêtre creuse sous la trace : une échelle large - ce que demande
1547
+ // une exagération fixe sur une trace longue - fait alors descendre l'axe sous le
1548
+ // niveau de la mer, et on lit « -900 m » sur un profil de montagne. Le plancher
1549
+ // est donc zéro, ou le point le plus bas de la trace s'il passe dessous : une
1550
+ // dépression existe, une altitude négative inventée, non.
1551
+ const plancher = Math.min(0, bas);
1552
+ let y0 = (bas + haut) / 2 - etendue / 2; // le centrage, quand il tient
1553
+ if (y0 < plancher) y0 = plancher;
1554
+ return d3.scaleLinear().domain([y0, y0 + etendue]).range([innerH, 0]);
1527
1555
  }
1528
1556
 
1529
1557
  /**
@@ -1541,6 +1569,13 @@ import * as d3 from 'd3';
1541
1569
  *
1542
1570
  * @private
1543
1571
  */
1572
+ /** Le rapport à ne pas dépasser, `0` s'il n'en est pas demandé. @private */
1573
+ _plafondExageration() {
1574
+ const v = this.options.verticalScale;
1575
+ const n = (v && typeof v === 'object') ? Number(v.maxExaggeration) : 0;
1576
+ return n > 0 ? n : 0;
1577
+ }
1578
+
1544
1579
  _verticalScaleFor(s, innerW) {
1545
1580
  const v = this.options.verticalScale;
1546
1581
  if (typeof v === 'number') return v;
@@ -1750,7 +1785,9 @@ import * as d3 from 'd3';
1750
1785
  this._statsEl.setAttribute('title', text.join(' · '));
1751
1786
 
1752
1787
  this._legendEl.innerHTML = '';
1753
- if (o.slope && o.slopeLegend) {
1788
+ // Une légende de pentes sans altitude ne légende rien : elle annoncerait des
1789
+ // classes qu'aucun trait ne porte, sous un panneau qui dit n'avoir pas de profil.
1790
+ if (o.slope && o.slopeLegend && !sansAltimetrie) {
1754
1791
  const sc = this._slopeScale();
1755
1792
  for (let idx = 0; idx <= sc.maxIdx; idx++) {
1756
1793
  const color = sc.colorByIndex(idx);
@@ -2259,6 +2296,6 @@ import * as d3 from 'd3';
2259
2296
  // Stamped at build time from package.json - see rollup.config.mjs, which fails the build
2260
2297
  // if this placeholder ever stops matching. Read from the source rather than the bundle,
2261
2298
  // it says just that: a development copy, of no released version.
2262
- ElevationProfile.version = '2.1.0';
2299
+ ElevationProfile.version = '2.1.2';
2263
2300
 
2264
2301
  export { ElevationProfile as default };
@@ -1,4 +1,4 @@
1
- /*! ol-elevation-profile 2.1.0 | MIT License | https://github.com/lc-4918/ol-elevation-profile */
1
+ /*! ol-elevation-profile 2.1.2 | MIT License | https://github.com/lc-4918/ol-elevation-profile */
2
2
  import t from"ol/control/Control.js";import e from"ol/Overlay.js";import{unByKey as s}from"ol/Observable.js";import{toLonLat as o,transform as n,get as i,fromLonLat as l}from"ol/proj.js";import r from"ol/TileState.js";import{getDistance as a}from"ol/sphere.js";import{boundingExtent as h}from"ol/extent.js";import*as c from"d3";
3
3
  /**
4
4
  * Synchronized elevation profile control for OpenLayers, rendered with d3.
@@ -15,4 +15,4 @@ import t from"ol/control/Control.js";import e from"ol/Overlay.js";import{unByKey
15
15
  *
16
16
  * @module ol-elevation-profile
17
17
  * @license MIT
18
- */const p={steelblue:{area:"#4682b4",line:"#3a6d96",axis:"#555",text:"#222",focus:"#e6550d"},lime:{area:"#9ccc2f",line:"#7da521",axis:"#555",text:"#222",focus:"#d62728"},purple:{area:"#9467bd",line:"#76529c",axis:"#555",text:"#222",focus:"#ff9f1c"},slate:{area:"#7c8a99",line:"#4a5560",axis:"#5a6570",text:"#26303a",focus:"#2f81f7"},graphite:{area:"#9a948c",line:"#5c574f",axis:"#5c574f",text:"#2b2823",focus:"#e07a3f"},amber:{area:"#f0a23b",line:"#c4671a",axis:"#7a5a36",text:"#3a2a16",focus:"#1f6fb2"}},u=["top","bottom","left","right","top-left","top-right","bottom-left","bottom-right"],d={en:{distance:"Distance",elevation:"Elevation",slope:"Slope",ascent:"D+",descent:"D-",empty:"Click a track",noElevation:"No elevation data",untitled:"Profile",time:"Time",duration:"Duration",durationUnits:{s:"sec",m:"min",h:"h",d:"d"},zoomStart:"Set start (A)",zoomEnd:"Set end (B)",zoomAll:"Show all",zoomBack:"Back one level",exportPng:"Export as PNG",collapse:"Collapse the profile",expand:"Expand the profile",loading:"Loading the elevation profile"},fr:{distance:"Distance",elevation:"Altitude",slope:"Pente",ascent:"D+",descent:"D-",empty:"Cliquez un tracé",noElevation:"Aucune altimétrie",untitled:"Profil",time:"Temps",duration:"Durée",durationUnits:{s:"sec",m:"min",h:"h",d:"j"},zoomStart:"Définir le début (A)",zoomEnd:"Définir la fin (B)",zoomAll:"Tout voir",zoomBack:"Revenir au niveau précédent",exportPng:"Exporter en PNG",collapse:"Réduire le profil",expand:"Agrandir le profil",loading:"Chargement du profil altimétrique"},es:{distance:"Distancia",elevation:"Altitud",slope:"Pendiente",ascent:"D+",descent:"D-",empty:"Haga clic en una traza",noElevation:"Sin datos de altitud",untitled:"Perfil",time:"Tiempo",duration:"Duración",durationUnits:{s:"seg",m:"min",h:"h",d:"d"},zoomStart:"Definir el inicio (A)",zoomEnd:"Definir el final (B)",zoomAll:"Ver todo",zoomBack:"Volver al nivel anterior",exportPng:"Exportar como PNG",collapse:"Contraer el perfil",expand:"Desplegar el perfil",loading:"Cargando el perfil de elevación"}},m={immersion:"docked",position:"bottom",width:520,height:180,margins:{unit:"px",top:20,right:24,bottom:30,left:48},units:"meters",dataProjection:null,dem:"terrarium",maxPoints:2e3,smoothing:0,theme:"steelblue",color:null,trackLayer:null,transparency:!1,transparencyLevel:.45,grid:!0,slope:!1,slopeClassSize:2.5,slopeColors:null,slopeSeparators:!0,slopeLegend:!0,maxClasses:8,xTicks:null,yTicks:null,verticalScale:"auto",show:"click",showWithoutElevation:!0,collapsable:!0,collapsed:!1,followMap:!0,marker:!0,hideOnMapClick:!0,responsive:!0,mobileBreakpoint:640,zoom:!1,zoomLevels:3,exportPng:!1,ignoreStops:!0,stopSpeed:.5,tooltipItems:["distance","elevation"],headerItems:["distance","ascent","descent","minmax"],titleProperty:"name",titleLink:null,lang:"en",labels:{}};function _(t,e){return f(d[t]||d.en,e||null)}function f(t,e){const s={};return Object.keys(t).forEach(e=>{s[e]=t[e]}),e&&Object.keys(e).forEach(o=>{e[o]&&"object"==typeof e[o]&&!Array.isArray(e[o])&&t[o]&&"object"==typeof t[o]?s[o]=f(t[o],e[o]):s[o]=e[o]}),s}const g=t=>String(t).replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[t])),y=t=>"string"==typeof t&&/^(https?:)?\/\/|^mailto:/i.test(t);function x(t){if(!t||!t.getCoordinates)return[];const e=t.getCoordinates();switch(t.getType()){case"LineString":case"LinearRing":return[e];case"MultiLineString":return e;case"Polygon":return e.length?[e[0]]:[];case"MultiPolygon":return e.map(t=>t[0]).filter(Boolean);default:return[]}}function b(t,e){const s=t&&t.getProperties?t.getProperties():{};let o=s.coordTimes;null==o&&s.coordinateProperties&&(o=s.coordinateProperties.times||s.coordinateProperties.coordTimes);let n=null;if(Array.isArray(o)&&(n=Array.isArray(o[0])?o.reduce((t,e)=>t.concat(e),[]):o.slice()),!n&&e){const t=[];let s=!1;for(const o of e)for(const e of o){const o=e.length>3?e[3]:null;t.push(o),null!=o&&isFinite(o)&&(s=!0)}n=s?t:null}if(!n)return null;let i=0;const l=n.map(t=>{if(null==t||""===t)return null;const e="number"==typeof t?t>1e12?t:1e3*t:Date.parse(t);return isFinite(e)?(i++,e):null});return i>=2?l:null}function v(t,e,s){let o=t;if("function"==typeof o)try{o=o(e,s)}catch(t){return null}if(Array.isArray(o)&&(o=o[0]),o&&o.getStroke){const t=o.getStroke();if(t)return t.getColor()}return null}const S=(t,e)=>{if("imperial"===e){const e=t/1609.344;return e<.2?`${Math.round(3.28084*t)} ft`:`${e.toFixed(e<10?2:1)} mi`}return t<1e3?`${Math.round(t)} m`:`${(t/1e3).toFixed(t<1e4?2:1)} km`},M=(t,e)=>"imperial"===e?`${Math.round(3.28084*t)} ft`:`${Math.round(t)} m`;const E='<svg viewBox="0 0 24 24"><path d="M5 13h14" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></svg>',k='<svg viewBox="0 0 24 24"><path d="M3 19l5-7 4 4 4-6 5 9z" fill="currentColor" opacity=".85"/></svg>',w=c.bisector(t=>t.x).left,z={terrarium:{url:"https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png",encoding:"terrarium",maxZoom:14,attributions:'Elevation: <a href="https://registry.opendata.aws/terrain-tiles/">Terrain Tiles</a> (AWS Open Data)'},ign:{api:"ign",url:"https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevation.json",resource:"ign_rge_alti_wld",batch:200,minInterval:1100,attributions:'Elevation: <a href="https://geoservices.ign.fr/rgealti">RGE ALTI</a> (IGN)'}};function C(t){const e=Math.max(1,t.batch||200),s=t.minInterval||0;return o=>{const n=[];let i=0;const l=r=>{if(r>=o.length)return Promise.resolve(n);const a=o.slice(r,r+e),h=Math.max(0,s-(Date.now()-i));return new Promise(t=>setTimeout(t,h)).then(()=>(i=Date.now(),fetch(function(t,e){const s=t=>t.toFixed(6),o=t.url.indexOf("?")>=0?"&":"?";let n=t.url+o+"resource="+encodeURIComponent(t.resource)+"&delimiter=|&zonly=true&lon="+e.map(t=>s(t[0])).join("|")+"&lat="+e.map(t=>s(t[1])).join("|");return t.apiKey&&(n+="&"+(t.apiKeyParam||"apikey")+"="+encodeURIComponent(t.apiKey)),n}(t,a)))).then(t=>t&&t.ok?t.json():null).then(t=>{const s=t&&t.elevations;if(!Array.isArray(s)||s.length!==a.length)return null;for(const t of s)n.push(null==t||t<=-99999?null:t);return l(r+e)})};return l(0)}}const P={source:"terrarium",zoom:"auto",maxZoom:14,maxTiles:32,concurrency:6,tileSize:256},T={terrarium:(t,e,s)=>256*t+e+s/256-32768,mapbox:(t,e,s)=>.1*(65536*t+256*e+s)-1e4},A=20037508.342789244;function $(t,e){const s=t.indexOf("?")>=0?"&":"?";return t.replace(/[?&]$/,"")+s+Object.keys(e).map(t=>t+"="+encodeURIComponent(e[t])).join("&")}function L(t,e,s,o,n){const i=Object.assign({SERVICE:"WMS",REQUEST:"GetMap",VERSION:"1.3.0",FORMAT:"image/png",TRANSPARENT:"false",STYLES:""},t.params||{}),l=0===String(i.VERSION).indexOf("1.1")?"SRS":"CRS";return delete i.SRS,delete i.CRS,i[l]=t.projection||"EPSG:3857",i.LAYERS=t.layers,i.WIDTH=n,i.HEIGHT=n,i.BBOX=function(t,e,s){const o=2*A/Math.pow(2,t),n=e*o-A,i=A-s*o;return[n,i-o,n+o,i]}(e,s,o).join(","),$(t.url,i)}function j(t){const e=t.olSource,s=t.band||0;return o=>{const l=e.getTileGrid&&e.getTileGrid();return(l?Promise.resolve(null):Promise.resolve(e.getView?e.getView():null)).then(a=>{const h=l||e.getTileGrid&&e.getTileGrid()||a&&a.tileGrid;if(!h)return null;const c=i(a&&a.projection||e.getProjection&&e.getProjection()||"EPSG:3857"),p=h.getResolutions?h.getResolutions().length-1:0,u=e.bandCount||1,d=o.map(t=>n([t[0],t[1]],"EPSG:4326",c)),m=h.getExtent&&h.getExtent()||a&&a.extent||null,_=t=>{const e=h.getResolution(t),s=h.getOrigin(t);let o=h.getTileSize(t);o=Array.isArray(o)?o:[o,o];const n=m?Math.round((m[2]-m[0])/e):1/0,i=m?Math.round((m[3]-m[1])/e):1/0,l=t=>Math.min(n-1,Math.max(0,t)),r=t=>Math.min(i-1,Math.max(0,t)),a=new Map,c=d.map(t=>{const n=(t[0]-s[0])/e-.5,i=(s[1]-t[1])/e-.5,h=l(Math.floor(n)),c=r(Math.floor(i));for(let t=0;t<2;t++)for(let e=0;e<2;e++){const s=Math.floor(l(h+t)/o[0]),n=Math.floor(r(c+e)/o[1]);a.set(s+"/"+n,[s,n])}return{i0:h,j0:c,tx:Math.min(1,Math.max(0,n-h)),ty:Math.min(1,Math.max(0,i-c)),clampI:l,clampJ:r}});return{res:e,origin:s,ts:o,need:a,at:c,clampI:l,clampJ:r}};let f=p,g=_(f);for(;f>0&&g.need.size>t.maxTiles;)f--,g=_(f);if(g.need.size>t.maxTiles)return null;const y=Array.from(g.need.keys());return Promise.all(y.map(t=>{const s=g.need.get(t);return(o=e.getTile(f,s[0],s[1],1,c),new Promise(t=>{const e=()=>{const e=o.getState();return e===r.LOADED?(t(o.getData?o.getData():null),!0):(e===r.ERROR||e===r.EMPTY)&&(t(null),!0)};if(e())return;const s=()=>{e()&&o.removeEventListener("change",s)};o.addEventListener("change",s),o.load&&o.load()})).then(e=>[t,e]);var o})).then(t=>{const e=new Map(t),o=(t,o)=>{const n=Math.floor(g.clampI(t)/g.ts[0]),i=Math.floor(g.clampJ(o)/g.ts[1]);t=g.clampI(t),o=g.clampJ(o);const l=e.get(n+"/"+i);if(!l)return null;const r=t-n*g.ts[0],a=l[((o-i*g.ts[1])*g.ts[0]+r)*u+s];return null!=a&&isFinite(a)?a:null};return g.at.map(t=>{const e=o(t.i0,t.j0),s=o(t.i0+1,t.j0),n=o(t.i0,t.j0+1),i=o(t.i0+1,t.j0+1);if(null==e||null==s||null==n||null==i)return null;const l=e+(s-e)*t.tx;return l+(n+(i-n)*t.tx-l)*t.ty})})})}}function B(t){const e=t.featureInfo,s=Math.max(1,t.concurrency||6);return t=>{const o=new Array(t.length);let n=0,i=!1;const r=()=>{if(i||n>=t.length)return Promise.resolve();const s=n++;return fetch(function(t,e){const s=l([e[0],e[1]]),o=t.resolution||1,n=Object.assign({SERVICE:"WMS",REQUEST:"GetFeatureInfo",VERSION:"1.3.0",INFO_FORMAT:"application/json",STYLES:"",FEATURE_COUNT:1},t.params||{}),i=0===String(n.VERSION).indexOf("1.1")?"SRS":"CRS";return delete n.SRS,delete n.CRS,n[i]=t.projection||"EPSG:3857",n.LAYERS=t.layers,n.QUERY_LAYERS=t.queryLayers||t.layers,n.WIDTH=1,n.HEIGHT=1,n.I=0,n.J=0,n.X=0,n.Y=0,n.BBOX=[s[0]-o,s[1]-o,s[0]+o,s[1]+o].join(","),$(t.url,n)}(e,t[s])).then(t=>t&&t.ok?t.json():null).then(t=>(o[s]=function(t,e){const s=t&&t.features&&t.features[0],o=s&&s.properties;if(!o)return null;if(e){const t=Number(o[e]);return isFinite(t)?t:null}for(const t of Object.keys(o)){const e=Number(o[t]);if(null!==o[t]&&""!==o[t]&&isFinite(e))return e}return null}(t,e.property),r())).catch(()=>{i=!0})},a=[];for(let e=0;e<Math.min(s,t.length);e++)a.push(r());return Promise.all(a).then(()=>i?null:o)}}class F{constructor(t){this.cfg=t,this.decode="function"==typeof t.encoding?t.encoding:T[t.encoding]||T.terrarium,this.tileUrl=function(t){const e=t.olSource;if(e&&"function"==typeof e.getTileUrlFunction){const t=e.getTileUrlFunction(),s=i("EPSG:3857");return(e,o,n)=>t([e,o,n],1,s)}return t.wms?(e,s,o)=>L(t.wms,e,s,o,t.tileSize):(e,s,o)=>t.url.replace("{z}",e).replace("{x}",s).replace("{y}",o)}(t),this.tiles=new Map}_neighbours(t,e,s){const o=function(t,e,s,o){const n=o*Math.pow(2,s),i=Math.sin(e*Math.PI/180);return[(t+180)/360*n,(.5-Math.log((1+i)/(1-i))/(4*Math.PI))*n]}(t,e,s,this.cfg.tileSize),n=o[0]-.5,i=o[1]-.5,l=Math.floor(n),r=Math.floor(i);return{i0:l,j0:r,tx:n-l,ty:i-r}}_key(t,e,s){const o=this.cfg.tileSize,n=o*Math.pow(2,s),i=Math.min(n-1,Math.max(0,e)),l=(t%n+n)%n;return{key:s+"/"+Math.floor(l/o)+"/"+Math.floor(i/o),ii:l,jj:i}}_at(t,e,s){const o=this.cfg.tileSize,n=this._key(t,e,s),i=this.tiles.get(n.key);if(!i)return null;const l=4*(n.jj%o*o+n.ii%o),r=this.decode(i[l],i[l+1],i[l+2],i[l+3]);return null!=r&&isFinite(r)?r:null}sample(t,e,s){const o=this._neighbours(t,e,s),n=this._at(o.i0,o.j0,s),i=this._at(o.i0+1,o.j0,s),l=this._at(o.i0,o.j0+1,s),r=this._at(o.i0+1,o.j0+1,s);if(null==n||null==i||null==l||null==r)return null;const a=n+(i-n)*o.tx;return a+(l+(r-l)*o.tx-a)*o.ty}tilesFor(t,e){const s=new Set;for(const o of t){const t=this._neighbours(o[0],o[1],e);for(let o=0;o<2;o++)for(let n=0;n<2;n++)s.add(this._key(t.i0+o,t.j0+n,e).key)}return s}_fetch(t){const e=t.split("/"),s=this.tileUrl(+e[0],+e[1],+e[2]);return new Promise(t=>{const e=new Image;e.crossOrigin="anonymous",e.onload=()=>{try{const s=this.cfg.tileSize,o=document.createElement("canvas");o.width=s,o.height=s;const n=o.getContext("2d",{willReadFrequently:!0});n.drawImage(e,0,0,s,s),t(n.getImageData(0,0,s,s).data)}catch(e){t(null)}},e.onerror=()=>t(null),e.src=s})}load(t){const e=Array.from(t).filter(t=>!this.tiles.has(t));let s=0,o=!0;const n=()=>{if(s>=e.length)return Promise.resolve();const t=e[s++];return this._fetch(t).then(e=>(this.tiles.set(t,e),e||(o=!1),n()))},i=[];for(let t=0;t<Math.min(this.cfg.concurrency,e.length);t++)i.push(n());return Promise.all(i).then(()=>o)}}class R extends t{constructor(t){const e=f(m,t||{});-1===u.indexOf(e.position)&&(e.position="bottom");const s=e.labels;e.labels=_(e.lang,s);const o=function(t){const e=document.createElement("div");return e.className=`ol-elevation-profile ol-unselectable ol-control oep-pos-${t.position} oep-theme-${"string"==typeof t.theme?t.theme:"custom"}`+("floating"===t.immersion?" oep-floating":""),e}(e);super({element:o,target:t&&t.target}),this.options=e,this._userLabels=s,this.slopeColors=e.slopeColors||null,this._feature=null,this._fullSamples=null,this._fullStats=null,this._samples=null,this._stats=null,this._marker=null,this._collapsed=!!e.collapsed,this._crops=[],this._off=0,this._zoomA=null,this._zoomB=null,this._armed=null,this._demZ=null,this._demFor=null,this._demSeq=0,this._demLoading=!1,this._trackLines=null,this._linesFor=null,this._onResize=()=>{this._feature&&!this._collapsed&&this._render()},this._buildDom(o),o.style.display="none"}get _cropMode(){return this._crops.length>0}get _cropDepth(){return this._crops.length}get _cropMax(){const t=this.options.zoomLevels;return null==t?3:Math.max(1,0|t)}static featureHasZ(t){const e=t&&t.getGeometry&&t.getGeometry();if(!e)return!1;for(const t of x(e))for(const e of t)if(e.length>2&&isFinite(e[2]))return!0;return!1}static featureHasTime(t){const e=t&&t.getGeometry&&t.getGeometry();return!!e&&!!b(t,x(e))}_buildDom(t){const e=this.options;this._applyTheme(),this._applyTransparency();const s=document.createElement("div");s.className="oep-header",this._titleEl=document.createElement("span"),this._titleEl.className="oep-title",this._titleEl.textContent=e.labels.empty,this._statsEl=document.createElement("span"),this._statsEl.className="oep-stats",s.appendChild(this._titleEl),s.appendChild(this._statsEl),this._toolbar=document.createElement("span"),this._toolbar.className="oep-toolbar";const o=(t,e,s,o)=>{const n=document.createElement("button");return n.type="button",n.className=`oep-tbtn ${t}`,n.innerHTML=e,n.title=s,n.setAttribute("aria-label",s),n.addEventListener("click",o),this._toolbar.appendChild(n),n};this._btnA=o("oep-a",'<svg viewBox="0 0 24 24"><path d="M7 5v14M11 12h8m0 0-3-3m3 3-3 3" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.zoomStart,()=>this._arm("A")),this._btnB=o("oep-b",'<svg viewBox="0 0 24 24"><path d="M17 5v14M13 12H5m0 0 3-3m-3 3 3 3" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.zoomEnd,()=>this._arm("B")),this._btnBack=o("oep-back",'<svg viewBox="0 0 24 24"><path d="M10 6 4 12l6 6M4 12h10a6 6 0 0 1 6 6" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.zoomBack,()=>this._popCrop()),this._btnAll=o("oep-all",'<svg viewBox="0 0 24 24"><path d="M4 12h16M4 12l4-4M4 12l4 4M20 12l-4-4M20 12l-4 4" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.zoomAll,()=>this._exitZoom()),this._btnPng=o("oep-png",'<svg viewBox="0 0 24 24"><path d="M12 4v10m0 0 4-4m-4 4-4-4M5 18h14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.exportPng,()=>this.exportPNG()),s.appendChild(this._toolbar);const n=document.createElement("button");n.className="oep-toggle",n.type="button",n.innerHTML=this._collapsed?k:E,n.addEventListener("click",()=>this.toggleCollapsed()),s.appendChild(n),this._toggleBtn=n,this._applyToggleLabel(),this._legendEl=document.createElement("div"),this._legendEl.className="oep-legend",this._legendEl.style.display="none",this._body=document.createElement("div"),this._body.className="oep-body",t.appendChild(s),t.appendChild(this._legendEl),t.appendChild(this._body),this._applyCollapsable(),this._updateZoomButtons(),this._collapsed&&t.classList.add("oep-collapsed")}_applyLabels(){const t=this.options.labels,e=(t,e)=>{t&&e&&(t.title=e,t.setAttribute("aria-label",e))};e(this._btnA,t.zoomStart),e(this._btnB,t.zoomEnd),e(this._btnBack,t.zoomBack),e(this._btnAll,t.zoomAll),e(this._btnPng,t.exportPng),this._applyToggleLabel(),this._titleEl&&!this._feature&&(this._titleEl.textContent=t.empty)}_applyToggleLabel(){const t=this.options.labels,e=this._collapsed?t.expand:t.collapse;this._toggleBtn&&e&&(this._toggleBtn.title=e,this._toggleBtn.setAttribute("aria-label",e))}_resolveColor(){const t=this.options;return t.color?"auto"===t.color?this._featureColor():t.color:null}_featureColor(){const t=this._feature;if(!t)return null;const e=this.getMap()?this.getMap().getView().getResolution():1;let s=v(t.getStyle&&t.getStyle(),t,e);return!s&&this.options.trackLayer&&(s=v(this.options.trackLayer.getStyle&&this.options.trackLayer.getStyle(),t,e)),function(t){if(null==t)return null;if("string"==typeof t)return t;if(Array.isArray(t)){const e=t.length>3?t[3]:1;return`rgba(${0|t[0]},${0|t[1]},${0|t[2]},${e})`}return null}(s)}_applyTheme(){const t=this.options,e="object"==typeof t.theme?t.theme:p[t.theme]||p.steelblue;this.themeColors=e;const s=this.element,o=this._resolveColor(),n=o||e.area;let i=e.line;if(o)try{i=String(c.color(o).darker(.7))}catch(t){i=o}s.style.setProperty("--oep-area",n),s.style.setProperty("--oep-line",i),s.style.setProperty("--oep-axis",e.axis),s.style.setProperty("--oep-text",e.text),s.style.setProperty("--oep-focus",e.focus)}_applyTransparency(){const t=this.options.transparency;let e;e=!1===t||null==t?1:!0===t?this.options.transparencyLevel:Math.max(0,Math.min(1,+t)),this.element.style.setProperty("--oep-bg",`rgba(255,255,255,${e})`),this.element.classList.toggle("oep-transparent",e<1)}_applyCollapsable(){const t=this.options.collapsable;this._toggleBtn.style.display=t?"":"none",!t&&this._collapsed&&this.toggleCollapsed(!1)}toggleCollapsed(t){this._collapsed="boolean"==typeof t?t:!this._collapsed,this.element.classList.toggle("oep-collapsed",this._collapsed),this._toggleBtn.innerHTML=this._collapsed?k:E,this._applyToggleLabel(),!this._collapsed&&this._feature&&this._render(),this._adjustAttribution()}_availWidth(){const t=this.getMap(),e=t&&t.getTargetElement&&t.getTargetElement();return e&&e.clientWidth||("undefined"!=typeof window?window.innerWidth:1024)}_isMobile(){return this.options.responsive&&"undefined"!=typeof window&&window.innerWidth<=(this.options.mobileBreakpoint||640)}_applyPlacement(){const t=this._isMobile();let e=this.options.position;return t&&(e=/top/.test(e)?"top":"bottom"),this.element.className=this.element.className.replace(/oep-pos-\S+/,`oep-pos-${e}`),this.element.classList.toggle("oep-mobile",t),t}_adjustAttribution(){const t=this.getMap(),e=t&&t.getTargetElement&&t.getTargetElement(),s=e&&e.querySelector&&e.querySelector(".ol-attribution");if(!s)return;if(s.style.bottom="",s.style.right="","none"===this.element.style.display||this._collapsed)return;const o=e.getBoundingClientRect(),n=this.element.getBoundingClientRect();if(!n.height)return;const i=o.bottom-n.bottom,l=o.right-n.right;i<n.height&&l<24&&(s.style.right=`${Math.max(0,Math.round(l))}px`,s.style.bottom=`${Math.round(n.height+2*i)}px`)}setMap(t){const o=this.getMap();if(super.setMap(t),this._mapKeys&&(this._mapKeys.forEach(s),this._mapKeys=null),o&&"undefined"!=typeof window&&window.removeEventListener("resize",this._onResize),this._marker&&!t&&this._marker.setPosition(void 0),!t)return;const n=this.options;if(n.dataProjection||(n.dataProjection=t.getView().getProjection()),n.marker&&!this._marker){const s=document.createElement("div");s.className="oep-marker",this._marker=new e({element:s,positioning:"center-center",stopEvent:!1}),t.addOverlay(this._marker)}"undefined"!=typeof window&&window.addEventListener("resize",this._onResize);const i=e=>t.forEachFeatureAtPixel(e,t=>{const e=t.getGeometry();return(s=e)&&/^(Multi)?(LineString|Polygon)$|^LinearRing$/.test(s.getType())?t:void 0;var s});this._mapKeys=[],this._mapKeys.push(t.on("click",t=>{const e=i(t.pixel);"mouseover"!==this.options.show&&e&&e!==this._feature&&this.setFeature(e),this.options.hideOnMapClick&&!e&&this._feature&&this.clear()})),this._mapKeys.push(t.on("pointermove",e=>{if("mouseover"===this.options.show){const t=i(e.pixel);t&&t!==this._feature&&this.setFeature(t)}if(!this.options.followMap||!this._feature||this._collapsed)return;const s=this._closestOnProfile(e.coordinate);if(!s)return;const o=t.getPixelFromCoordinate(s);o&&(Math.hypot(o[0]-e.pixel[0],o[1]-e.pixel[1])<14?this._focusByCoord(s):this._clearFocus())})),this._mapKeys.push(t.on("moveend",()=>{const e=this._crops[this._crops.length-1];e&&e.fitRes&&t.getView().getResolution()>1.25*e.fitRes&&this._popCrop()})),this._mapKeys.push(t.on("change:size",this._onResize))}setFeature(t){return this._feature=t||null,this._crops=[],this._off=0,this._zoomA=null,this._zoomB=null,this._armed=null,t?(this.element.style.display="",this._compute(),this._fillFromDem(t),this._updateZoomButtons(),this._collapsed?this._renderTitle():this._render(),this):(this._fullSamples=this._samples=null,this._demZ=this._demFor=null,this._trackLines=this._linesFor=null,this._clear(),this)}clear(){return this.setFeature(null)}getStats(){return this._stats}setTheme(t){return this.options.theme=t,this._applyTheme(),this._feature&&!this._collapsed&&this._render(),this}setColor(t){return this.options.color=t||null,this._applyTheme(),this._feature&&!this._collapsed&&this._render(),this}setOptions(t){return this.options=f(this.options,t||{}),t&&"slopeColors"in t&&(this.slopeColors=t.slopeColors||null),t&&(t.theme||"color"in t)&&this._applyTheme(),t&&("transparency"in t||"transparencyLevel"in t)&&this._applyTransparency(),t&&"collapsable"in t&&this._applyCollapsable(),t&&"labels"in t&&(this._userLabels=f(this._userLabels||{},t.labels)),t&&("lang"in t||"labels"in t)&&(this.options.labels=_(this.options.lang,this._userLabels),this._applyLabels()),t&&("zoom"in t||"exportPng"in t)&&this._updateZoomButtons(),t&&void 0!==t.width&&"number"==typeof t.width&&(this.options.width=t.width),t&&"dem"in t&&(this._demZ=null,this._demFor=null,this._trackLines=null,this._linesFor=null),this._feature&&(this._compute(),this._fillFromDem(this._feature),this._updateZoomButtons(),this._collapsed?this._renderTitle():this._render()),this}_fillFromDem(t){const e=function(t){if(!t)return null;if("function"==typeof t)return Object.assign({},P,{sample:t});const e=!0===t||"string"==typeof t?{source:!0===t?"terrarium":t}:Object.assign({},t);if("function"==typeof e.sample)return Object.assign({},P,e);if(e.track){const t=Object.assign({},P,e);return t.track=Object.assign({coords:"coords",parse:null,fetchOptions:null},"string"==typeof e.track?{url:e.track}:e.track),t.track.url?t:null}if(e.featureInfo){const t=Object.assign({},P,e);return t.sample=B(t),t}if(e.olSource&&"function"!=typeof e.olSource.getTileUrlFunction&&"function"==typeof e.olSource.getTile){const t=Object.assign({},P,e);return t.sample=j(t),t}const s=e.url||e.wms||e.olSource,o=z[e.source]||(s?{}:z.terrarium),n=Object.assign({},P,o,e);return"ign"===n.api?(n.sample=C(n),n):n.url||n.wms||n.olSource?n:null}(this.options.dem);if(!e||!t||this._demFor===t||this._linesFor===t)return;if(R.featureHasZ(t))return;if(!e.sample&&("undefined"==typeof Image||"undefined"==typeof document))return;const s=t.getGeometry&&t.getGeometry(),n=s?x(s):[],i=this.options.dataProjection||this.getMap()&&this.getMap().getView().getProjection()||"EPSG:3857",l=[];for(const t of n)for(const e of t)l.push(o(e,i));if(!l.length&&!e.track)return;const r=++this._demSeq;this._demLoading=!0;try{this._startFill(e,r,t,l,i)}catch(e){this._demDone(r,t,null,l.length,null,0)}}_startFill(t,e,s,o,n){if(t.track)return void this._startTrackFill(t,e,s,o.length,n);if(t.sample)return void Promise.resolve().then(()=>t.sample(o,{feature:s,projection:n})).then(t=>this._demDone(e,s,t,o.length,null,0)).catch(()=>this._demDone(e,s,null,o.length,null,0));const i=new F(t),l=function(t,e,s){if("number"==typeof s.zoom)return s.zoom;for(let o=s.maxZoom;o>0;o--)if(t.tilesFor(e,o).size<=s.maxTiles)return o;return 1}(i,o,t);i.load(i.tilesFor(o,l)).then(t=>{const n=t?o.map(t=>i.sample(t[0],t[1],l)):null;this._demDone(e,s,n,o.length,l,i.tiles.size)}).catch(()=>this._demDone(e,s,null,o.length,l,0))}_startTrackFill(t,e,s,o,n){const i=function(t,e){if("function"==typeof t)return t(e)||null;if("string"!=typeof t||!e)return null;let s=!0;const o=t.replace(/\{(\w+)\}/g,(t,o)=>{const n=e.get(o);return null==n||""===n?(s=!1,""):encodeURIComponent(String(n))});return s?o:null}(t.track.url,s);i?Promise.resolve().then(()=>fetch(i,t.track.fetchOptions||void 0)).then(t=>{if(!t.ok)throw new Error(String(t.status));return t.json()}).then(i=>{const l=t.track.parse?t.track.parse(i,s):Array.isArray(i)?i:i&&i[t.track.coords];this._trackDone(e,s,l,o,n)}).catch(()=>this._demDone(e,s,null,o,null,0)):this._demDone(e,s,null,o,null,0)}_trackDone(t,e,s,o,i){const l=()=>this._demDone(t,e,null,o,null,0);if(!Array.isArray(s)||!s.length)return l();if("number"==typeof s[0])return void this._demDone(t,e,s,o,null,0);if(t!==this._demSeq||this._feature!==e)return;const r=t=>null!=t&&isFinite(t),a=[];for(const t of s){if(!t||t.length<3||!r(t[0])||!r(t[1])||!r(t[2]))return l();const e=n([t[0],t[1]],"EPSG:4326",i);a.push([e[0],e[1],t[2]])}if(a.length<2)return l();this._demLoading=!1,this._trackLines=[a],this._linesFor=e,this._demZ=null,this._demFor=null,this._compute(),this._updateZoomButtons(),this._collapsed||this._render(),this.dispatchEvent({type:"demload",ok:!0,zoom:null,tiles:0})}_demDone(t,e,s,o,n,i){if(t!==this._demSeq||this._feature!==e)return;const l=Array.isArray(s)&&s.length===o&&s.every(t=>null!=t&&isFinite(t));this._demLoading=!1,l&&(this._demZ=s,this._demFor=e,this._compute()),this._updateZoomButtons(),this._collapsed||this._render(),this.dispatchEvent({type:"demload",ok:l,zoom:n,tiles:i})}_compute(){const t=this.options,e=this._linesFor===this._feature&&this._trackLines,s=this._feature.getGeometry&&this._feature.getGeometry(),n=e?this._trackLines:s?x(s):[],i=t.dataProjection||this.getMap()&&this.getMap().getView().getProjection()||"EPSG:3857",l=this._demFor===this._feature?this._demZ:null,r=e?null:b(this._feature,n);this._hasTime=!!r;const h=!1!==t.ignoreStops,c=null!=t.stopSpeed?t.stopSpeed:.5,p=[];let u=0,d=null,m=-1,_=0,f=null;for(const t of n)for(const e of t){m++;const t=o(e,i);let s=0;d&&(s=a(d,t),u+=s);let n=null;if(r&&null!=r[m]){const t=r[m];if(null!=f){const e=(t-f)/1e3;e>0&&(!h||s/e>=c)&&(_+=e)}n=_,f=t}d=t;const g=e.length>2&&isFinite(e[2])?e[2]:l?l[m]:0;p.push({x:u,z:g,coord:e,t:n})}t.smoothing>0&&this._smooth(p,t.smoothing);const g=this._decimate(p,t.maxPoints);this._addSlope(g),this._fullSamples=g,this._fullStats=this._statsOf(g,!0),this._applyCrops()}_pxPerCm(){try{const t=document.createElement("div");t.style.cssText="position:absolute;left:-9999px;top:0;width:1cm;height:1cm",(this.element||document.body).appendChild(t);const e=t.getBoundingClientRect().height;if(t.remove(),e>0)return e}catch(t){}return 96/2.54}_yScale(t,e,s,o){const n=t.min-e,i=t.max+e,l=s/this._pxPerCm(),r=o/this._pxPerCm(),a=e=>r>0&&e>0?t.distance/r/(e/l):null,h=this._verticalScaleFor(t,o);if(!(h>0)){const t=c.scaleLinear().domain([n,i]).range([s,0]).nice(),e=t.domain();return this._vScale=null,this._vExaggeration=a(e[1]-e[0]),t}const p=Math.max(h*l,i-n),u=(n+i)/2;return this._vScale=p/l,this._vExaggeration=a(p),c.scaleLinear().domain([u-p/2,u+p/2]).range([s,0])}_verticalScaleFor(t,e){const s=this.options.verticalScale;if("number"==typeof s)return s;const o=s&&"object"==typeof s?Number(s.exaggeration):0;if(!(o>0&&t.distance>0&&e>0))return 0;const n=e/this._pxPerCm();return t.distance/n/o}_statsOf(t,e){let s=0,o=0,n=1/0,i=-1/0,l=0;for(let e=0;e<t.length;e++){const r=t[e].z;if(r<n&&(n=r),r>i&&(i=r),e>0){const n=r-t[e-1].z;n>0?s+=n:o-=n}const a=Math.abs(t[e].slope||0);a>l&&(l=a)}const r=t.length?t[t.length-1].x-t[0].x:0,a=t.length?t[0].t:null,h=t.length?t[t.length-1].t:null;return{distance:r,duration:null!=a&&null!=h?h-a:null,ascent:s,descent:o,min:isFinite(n)?n:0,max:isFinite(i)?i:0,maxAbsSlope:l,points:t.length}}_smooth(t,e){if(!(e>0)||t.length<3)return;const s=e/2,o=t.map(t=>t.z);let n=0,i=0,l=0;for(let e=0;e<t.length;e++){const r=t[e].x;for(;n<t.length&&t[n].x<r-s;)l-=o[n],n++;for(;i<t.length&&t[i].x<=r+s;)l+=o[i],i++;t[e].z=i>n?l/(i-n):o[e]}}_decimate(t,e){const s=t=>({x:t.x,z:t.z,coord:t.coord,t:t.t});if(!e||t.length<=e)return t.map(s);const o=t.length/e,n=[];for(let i=0;i<e;i++)n.push(s(t[Math.floor(i*o)]));return n.push(s(t[t.length-1])),n}_addSlope(t){for(let e=1;e<t.length;e++){const s=t[e].x-t[e-1].x;t[e].slope=s>0?(t[e].z-t[e-1].z)/s*100:0}t.length&&(t[0].slope=t.length>1?t[1].slope:0)}_slopeScale(){const t=this.options.slopeClassSize||2.5,e=this.options.maxClasses||8,s=Math.max(1,Math.floor((this._stats.maxAbsSlope||0)/t)),o=Math.min(s,e-1),n=s>o;let i;if(this.slopeColors&&this.slopeColors.length){const t=c.interpolateRgbBasis(this.slopeColors);i=e=>t(o?e/o:0)}else{const t=c.scaleLinear().domain([0,.16,.42,.68,1]).range(["#2166ac","#27a35a","#ffe000","#f4791f","#d7191c"]).interpolate(c.interpolateRgb).clamp(!0);i=e=>String(t(o?e/o:0))}return{classSize:t,maxIdx:o,capped:n,colorByIndex:i}}_classIndex(t,e){return Math.min(e.maxIdx,Math.floor(Math.abs(t)/e.classSize))}_fmtDuration(t){if(null==t||!isFinite(t))return"";const e=this.options.labels&&this.options.labels.durationUnits||d.en.durationUnits;if((t=Math.max(0,Math.round(t)))<60)return t+" "+e.s;if(t<3600)return Math.round(t/60)+" "+e.m;if(t<86400){let s=Math.floor(t/3600),o=Math.round(t%3600/60);return 60===o&&(s++,o=0),o?`${s} ${e.h} ${o} ${e.m}`:`${s} ${e.h}`}let s=Math.floor(t/86400),o=Math.round(t%86400/3600);return 24===o&&(s++,o=0),o?`${s} ${e.d} ${o} ${e.h}`:`${s} ${e.d}`}_hasElevation(){const t=this._feature;return!!t&&(!!R.featureHasZ(t)||(!(this._demFor!==t||!this._demZ)||!(this._linesFor!==t||!this._trackLines)))}_renderNoElevation(){if(!this.options.showWithoutElevation)return void(this.element.style.display="none");this.element.style.display="",this._applyTheme(),this._applyPlacement(),this._renderHeader(!0);const t="number"==typeof this.options.height?this.options.height:180;this._body.innerHTML="";const e=document.createElement("div");e.className="oep-noelev",e.style.height=`${t}px`,e.setAttribute("role","status"),e.textContent=this.options.labels.noElevation,this._body.appendChild(e),this._clearFocus()}_pickProperty(t,e,s){if(!e||!t||!t.get)return null;for(const o of Array.isArray(e)?e:[e]){const e=t.get(o);if(null!=e&&""!==e&&(!s||s(e)))return e}return null}_renderTitle(){const t=this.options,e=this._feature;if(!e)return;const s=this._pickProperty(e,t.titleProperty)||t.labels.untitled,o=this._pickProperty(e,t.titleLink,y);y(o)?this._titleEl.innerHTML=`<a href="${g(o)}" target="_blank" rel="noopener">${g(s)}</a>`:this._titleEl.textContent=s,this._titleEl.setAttribute("title",s)}_renderHeader(t){const e=this.options,s=this._stats,o=this._feature;if(this._renderTitle(),this._demLoading)return this._statsEl.innerHTML="",this._statsEl.removeAttribute("title"),this._legendEl.innerHTML="",void(this._legendEl.style.display="none");const n=[],i=[];if(e.headerItems.forEach(l=>{if("string"==typeof l){if(t&&("ascent"===l||"descent"===l||"min"===l||"max"===l||"minmax"===l))return;if("distance"===l){if(!(s&&s.distance>0))return;n.push(`<b>${S(s.distance,e.units)}</b>`),i.push(S(s.distance,e.units))}else if("ascent"===l)n.push(`<span class="oep-up">${e.labels.ascent} ${M(s.ascent,e.units)}</span>`),i.push(`${e.labels.ascent} ${M(s.ascent,e.units)}`);else if("descent"===l)n.push(`<span class="oep-down">${e.labels.descent} ${M(s.descent,e.units)}</span>`),i.push(`${e.labels.descent} ${M(s.descent,e.units)}`);else if("min"===l)n.push(M(s.min,e.units)),i.push(M(s.min,e.units));else if("max"===l)n.push(M(s.max,e.units)),i.push(M(s.max,e.units));else if("minmax"===l){const t=`${M(s.min,e.units)}-${M(s.max,e.units)}`;n.push(t),i.push(t)}else if("duration"===l&&null!=s.duration){const t=this._fmtDuration(s.duration);n.push(`<span class="oep-time">${g(e.labels.duration)} ${t}</span>`),i.push(`${e.labels.duration} ${t}`)}}else if(l&&l.property){const t=o.get&&o.get(l.property);if(null==t||""===t)return;const e=l.label?`${l.label} `:"";l.asLink&&y(t)?(n.push(`${e}<a href="${g(t)}" target="_blank" rel="noopener">${g(l.linkText||l.label||t)}</a>`),i.push(`${l.label||""} ${t}`)):(n.push(g(e+t)),i.push(e+t))}}),this._statsEl.innerHTML=n.join(" · "),this._statsEl.setAttribute("title",i.join(" · ")),this._legendEl.innerHTML="",e.slope&&e.slopeLegend){const t=this._slopeScale();for(let e=0;e<=t.maxIdx;e++){const s=t.colorByIndex(e),o=t.capped&&e===t.maxIdx?`≥ ${e*t.classSize} %`:`${e*t.classSize}-${(e+1)*t.classSize} %`,n=document.createElement("span");n.className="oep-leg-it",n.innerHTML=`<i class="oep-sw" style="background:${s}"></i>${o}`,this._legendEl.appendChild(n)}this._legendEl.style.display=""}else this._legendEl.style.display="none"}_renderSpinner(){const t="number"==typeof this.options.height?this.options.height:180;this._body.innerHTML="";const e=document.createElement("div");e.className="oep-loading",e.style.height=`${t}px`,e.setAttribute("role","status"),e.setAttribute("aria-label",this.options.labels.loading);const s=document.createElement("div");s.className="oep-spinner",e.appendChild(s),this._body.appendChild(e)}_render(){const t=this.options,e=this._stats,s=this._samples;if(!this._demLoading&&!this._hasElevation())return void this._renderNoElevation();if(!s||!s.length)return;this._applyTheme();const o=this._applyPlacement();if(this._renderHeader(),this._demLoading)return void this._renderSpinner();const n=t.margins,i=n.unit||"px",l=t=>"px"===i?t:t*(parseFloat(getComputedStyle(this.element).fontSize)||16),r=this._availWidth(),a="auto"===t.width||"100%"===t.width||"full"===t.width?r:Math.min("number"==typeof t.width?t.width:parseFloat(t.width)||r,r);this.element.style.width=o?"":`${a}px`;const h=this.element.clientWidth||(o?r:a),p=Math.max(220,h-16),u="number"==typeof t.height?t.height:180,d=l(n.top),m=l(n.right),_=l(n.bottom),f=l(n.left),g=Math.max(10,p-f-m),y=Math.max(10,u-d-_),x=null!=t.xTicks?t.xTicks:Math.max(2,Math.round(g/80)),b=null!=t.yTicks?t.yTicks:Math.max(2,Math.round(y/40));this._body.innerHTML="";const v=c.select(this._body).append("svg").attr("class","oep-svg").attr("width",p).attr("height",u).attr("viewBox",`0 0 ${p} ${u}`),S=v.append("g").attr("transform",`translate(${f},${d})`),M=c.scaleLinear().domain([0,e.distance]).range([0,g]),E=.1*(e.max-e.min)||10,k=this._yScale(e,E,y,g);this._x=M,this._y=k,this._dims={innerW:g,innerH:y},t.grid&&S.append("g").attr("class","oep-grid").call(c.axisLeft(k).ticks(b).tickSize(-g).tickFormat(""));const w="imperial"===t.units?1609.344:1e3;const z=c.area().x(t=>M(t.x)).y0(y).y1(t=>k(t.z));if(t.slope){const e=this._slopeScale(),o=[];let n=1;for(;n<s.length;){const t=this._classIndex(s[n].slope,e);let i=n;for(;i+1<s.length&&this._classIndex(s[i+1].slope,e)===t;)i++;S.append("path").datum(s.slice(n-1,i+1)).attr("class","oep-area-slope").attr("fill",e.colorByIndex(t)).attr("d",z),n>1&&o.push(s[n-1]),n=i+1}t.slopeSeparators&&o.forEach(t=>{S.append("line").attr("class","oep-slope-sep").attr("x1",M(t.x)).attr("x2",M(t.x)).attr("y1",k(t.z)).attr("y2",y)})}else S.append("path").datum(s).attr("class","oep-area").attr("d",z);S.append("path").datum(s).attr("class","oep-line").attr("d",c.line().x(t=>M(t.x)).y(t=>k(t.z))),S.append("g").attr("class","oep-axis oep-axis-x").attr("transform",`translate(0,${y})`).call(c.axisBottom(M).ticks(x).tickFormat(t=>(t/w).toFixed(t/w<10?1:0))),S.append("text").attr("class","oep-axis-label").attr("x",g).attr("y",y+_-4).attr("text-anchor","end").text((t=>"imperial"===t?"mi":"km")(t.units)),S.append("g").attr("class","oep-axis oep-axis-y").call(c.axisLeft(k).ticks(b).tickFormat(e=>"imperial"===t.units?Math.round(3.28084*e):e)),t.zoom&&this._cropDepth<this._cropMax&&[["A",this._zoomA],["B",this._zoomB]].forEach(([t,e])=>{if(null==e)return;const s=M(e);S.append("line").attr("class","oep-ab-line").attr("x1",s).attr("x2",s).attr("y1",0).attr("y2",y),S.append("text").attr("class","oep-ab-label").attr("x",s).attr("y",-6).attr("text-anchor","middle").text(t)});const C=S.append("g").attr("class","oep-focus").style("display","none");C.append("line").attr("class","oep-focus-line").attr("y1",0).attr("y2",y),C.append("circle").attr("class","oep-focus-dot").attr("r",4);const P=C.append("g").attr("class","oep-focus-label");P.append("rect").attr("class","oep-focus-bg"),P.append("text").attr("class","oep-focus-txt"),this._focus=C;const T=t=>{const s=c.pointer(t,S.node())[0];return Math.max(0,Math.min(e.distance,M.invert(s)))},A=v.append("rect").attr("class","oep-overlay").attr("x",f).attr("y",d).attr("width",g).attr("height",y);A.on("mousemove",t=>{const e=this._sampleAt(T(t));e&&(this._setFocus(e),this._marker&&this._marker.setPosition(e.coord))}).on("mouseout",()=>this._clearFocus()),A.on("click",t=>this._placeBound(T(t))),this._armed&&A.style("cursor","col-resize"),this._adjustAttribution()}static get _EXPORT_PROPS(){return["fill","fill-opacity","stroke","stroke-width","stroke-dasharray","stroke-linecap","stroke-linejoin","opacity","font-family","font-size","font-weight","text-anchor","shape-rendering"]}_freezeStyles(t,e){const s=R._EXPORT_PROPS,o=getComputedStyle(t);let n="";for(const t of s){const e=o.getPropertyValue(t);e&&(n+=`${t}:${e};`)}e.setAttribute("style",n);const i=t.children,l=e.children;for(let t=0;t<i.length&&t<l.length;t++)this._freezeStyles(i[t],l[t])}_exportSvg(){const t=this._body.querySelector("svg");if(!t)return null;const e=getComputedStyle(this.element),s=e.getPropertyValue("--oep-bg").trim()||"#fff",o=e.getPropertyValue("--oep-text").trim()||"#222",n=e.fontFamily||"system-ui, sans-serif",i=+t.getAttribute("width"),l=+t.getAttribute("height"),r=this._statsEl.textContent?15:0,a="none"!==this._legendEl.style.display?this._legendEl:null,h=28+r+(a?18:0),c=t.cloneNode(!0);c.querySelectorAll(".oep-focus, .oep-overlay").forEach(t=>t.remove()),this._freezeStyles(t,c);const p=t=>g(String(t)),u=[];if(u.push(`<rect width="${i+16}" height="${l+h+8}" fill="${p(s)}"/>`),u.push(`<text x="8" y="21" style="font-family:${p(n)};font-size:13px;font-weight:600;fill:${p(o)}">${p(this._titleEl.textContent)}</text>`),r&&u.push(`<text x="8" y="38" style="font-family:${p(n)};font-size:11px;fill:${p(o)};opacity:.85">${p(this._statsEl.textContent)}</text>`),a){let t=8;const e=28+r+12;for(const s of a.querySelectorAll(".oep-leg-it")){const i=s.querySelector(".oep-sw"),l=i?getComputedStyle(i).backgroundColor:"none",r=s.textContent.trim();u.push(`<rect x="${t}" y="${e-8}" width="10" height="10" fill="${p(l)}"/>`),u.push(`<text x="${t+14}" y="${e}" style="font-family:${p(n)};font-size:10px;fill:${p(o)}">${p(r)}</text>`),t+=14+5.6*r.length+10}}return u.push(`<g transform="translate(8,${h})">${(new XMLSerializer).serializeToString(c)}</g>`),{width:i+16,height:l+h+8,svg:`<svg xmlns="http://www.w3.org/2000/svg" width="${i+16}" height="${l+h+8}" viewBox="0 0 ${i+16} ${l+h+8}">${u.join("")}</svg>`}}exportPNG(t){const e=t||{},s=this._exportSvg();if(!s)return Promise.reject(new Error("ol-elevation-profile: nothing to export"));const o=e.scale||"undefined"!=typeof window&&window.devicePixelRatio||1;return new Promise((t,n)=>{const i=new Image;i.onload=()=>{try{const l=document.createElement("canvas");l.width=Math.round(s.width*o),l.height=Math.round(s.height*o);const r=l.getContext("2d");r.scale(o,o),r.drawImage(i,0,0),l.toBlob(s=>{s?(!1!==e.download&&this._save(s,e.filename),t(s)):n(new Error("ol-elevation-profile: PNG encoding failed"))},"image/png")}catch(t){n(t)}},i.onerror=()=>n(new Error("ol-elevation-profile: SVG could not be rasterised")),i.src="data:image/svg+xml;charset=utf-8,"+encodeURIComponent(s.svg)})}_save(t,e){const s=e||`${(this._titleEl.textContent||"profile").replace(/[\\/:*?"<>|]+/g,"-").trim()}.png`,o=URL.createObjectURL(t),n=document.createElement("a");n.href=o,n.download=s,document.body.appendChild(n),n.click(),n.remove(),setTimeout(()=>URL.revokeObjectURL(o),1e3)}_arm(t){this._armed=this._armed===t?null:t,this._updateZoomButtons(),this._focus&&this._render()}_placeBound(t){if(!this._armed||this._cropDepth>=this._cropMax)return;const e="A"===this._armed?"B":"A";"A"===this._armed?this._zoomA=t:this._zoomB=t;const s=null!=this._zoomA&&null!=this._zoomB;this._armed=s?null:e,this._updateZoomButtons(),s?this._pushCrop(this._zoomA,this._zoomB):this._render()}_updateZoomButtons(){const t=this.options,e=!!this._feature,s=!!t.zoom&&e,o=!!t.exportPng&&e;this._toolbar.style.display=s||o?"":"none",this._btnPng.style.display=o?"":"none";const n=this._cropDepth,i=n<this._cropMax;this._btnA.style.display=s&&i?"":"none",this._btnB.style.display=s&&i?"":"none",this._btnBack.style.display=s&&n>1?"":"none",this._btnAll.style.display=s&&n>0?"":"none",this._btnA.classList.toggle("armed","A"===this._armed),this._btnB.classList.toggle("armed","B"===this._armed)}_applyCrops(){if(!this._crops.length)return this._off=0,this._samples=this._fullSamples,this._stats=this._fullStats,null;const{a:t,b:e}=this._crops[this._crops.length-1],s=this._fullSamples.filter(s=>s.x>=t&&s.x<=e);if(s.length<2)return this._crops.pop(),this._applyCrops();const o=s[0].x,n=null!=s[0].t?s[0].t:0;return this._off=o,this._samples=s.map(t=>({x:t.x-o,z:t.z,coord:t.coord,slope:t.slope,t:null!=t.t?t.t-n:null})),this._stats=this._statsOf(this._samples,!1),s.map(t=>t.coord)}_fitMap(t){const e=this.getMap();if(!e)return null;let s=null;if(t&&t.length?s=h(t):this._feature&&(s=this._feature.getGeometry().getExtent()),!s)return null;const o=e.getView();let n=null;try{n=o.getResolutionForExtent(s,e.getSize())}catch(t){n=null}return o.fit(s,{padding:[40,40,40,40],duration:400}),n}_pushCrop(t,e){if(this._zoomA=null,this._zoomB=null,this._armed=null,this._cropDepth>=this._cropMax)return this._updateZoomButtons(),void this._render();const s=this._off+Math.min(t,e),o=this._off+Math.max(t,e);let n=0;for(let t=0;t<this._fullSamples.length;t++){const e=this._fullSamples[t].x;e>=s&&e<=o&&n++}if(n<2)return this._updateZoomButtons(),void this._render();this._crops.push({a:s,b:o,fitRes:null});const i=this._applyCrops();this._updateZoomButtons(),this._render();const l=this._crops[this._crops.length-1];l&&(l.fitRes=this._fitMap(i))}_applyZoom(){null!=this._zoomA&&null!=this._zoomB&&this._pushCrop(this._zoomA,this._zoomB)}_popCrop(){if(!this._crops.length)return;this._crops.pop(),this._zoomA=null,this._zoomB=null,this._armed=null;const t=this._applyCrops();this._updateZoomButtons(),this._collapsed||this._render(),this._fitMap(t)}_exitZoom(){this._crops.length=0,this._zoomA=null,this._zoomB=null,this._armed=null,this._applyCrops(),this._updateZoomButtons(),this._collapsed||this._render(),this._fitMap(null)}_closestOnProfile(t){const e=this._feature&&this._feature.getGeometry();if(!e)return null;if(!/Polygon/.test(e.getType()))return e.getClosestPoint(t);const s=this._projectOn(this._fullSamples,t);return s?s.coord:null}_projectOn(t,e){if(!t||!t.length)return null;if(1===t.length)return{x:t[0].x,coord:t[0].coord.slice(0,2)};let s=null,o=1/0;for(let n=1;n<t.length;n++){const i=t[n-1].coord,l=t[n].coord,r=l[0]-i[0],a=l[1]-i[1],h=r*r+a*a;let c=h>0?((e[0]-i[0])*r+(e[1]-i[1])*a)/h:0;c=c<0?0:c>1?1:c;const p=i[0]+r*c,u=i[1]+a*c,d=p-e[0],m=u-e[1],_=d*d+m*m;_<o&&(o=_,s={x:t[n-1].x+(t[n].x-t[n-1].x)*c,coord:[p,u]})}return s}_tooltipText(t){const e=this.options,s=[];return e.tooltipItems.forEach(o=>{var n;"distance"===o?s.push(S(t.x,e.units)):"elevation"===o?s.push(M(t.z,e.units)):"slope"===o?s.push(`${(n=t.slope||0)>=0?"+":""}${n.toFixed(1)} %`):"time"===o&&null!=t.t&&s.push(this._fmtDuration(t.t))}),s.join(" · ")}_setFocus(t){if(!this._focus)return;const e=this._x,s=this._y;this._focus.style("display",null),this._focus.select(".oep-focus-line").attr("x1",e(t.x)).attr("x2",e(t.x)),this._focus.select(".oep-focus-dot").attr("cx",e(t.x)).attr("cy",s(t.z));let o=s(t.z)-16;o<12&&(o=s(t.z)+22);const n=this._focus.select(".oep-focus-txt").attr("x",e(t.x)).attr("y",o).text(this._tooltipText(t)),i=n.node().getBBox();this._focus.select(".oep-focus-bg").attr("x",i.x-4).attr("y",i.y-2).attr("width",i.width+8).attr("height",i.height+4),e(t.x)+i.width/2>this._dims.innerW?n.attr("text-anchor","end"):e(t.x)-i.width/2<0?n.attr("text-anchor","start"):n.attr("text-anchor","middle")}_sampleAt(t){const e=this._samples;if(!e||!e.length)return null;if(1===e.length)return e[0];const s=e[0].x,o=e[e.length-1].x,n=Math.max(s,Math.min(o,t)),i=Math.min(Math.max(w(e,n,1),1),e.length-1),l=e[i-1],r=e[i],a=r.x-l.x,h=a>0?(n-l.x)/a:0,c=(t,e)=>t+(e-t)*h;return{x:n,z:c(l.z,r.z),coord:[c(l.coord[0],r.coord[0]),c(l.coord[1],r.coord[1])],slope:r.slope,t:null!=l.t&&null!=r.t?c(l.t,r.t):null}}_focusByCoord(t){const e=this._projectOn(this._samples,t);if(!e)return;const s=this._sampleAt(e.x);s&&(this._setFocus(s),this._marker&&this._marker.setPosition(s.coord))}_clearFocus(){this._focus&&this._focus.style("display","none"),this._marker&&this._marker.setPosition(void 0)}_clear(){this._body.innerHTML="",this._legendEl.innerHTML="",this._legendEl.style.display="none",this._titleEl.textContent=this.options.labels.empty,this._titleEl.removeAttribute("title"),this._statsEl.innerHTML="",this._statsEl.removeAttribute("title"),this._crops=[],this._off=0,this._demLoading=!1,this._updateZoomButtons(),this._clearFocus(),this.element.style.display="none",this._adjustAttribution()}}R.addTheme=(t,e)=>{p[t]=e},R.THEMES=p,R.DEM_PRESETS=z,R.DemSampler=F,R.POSITIONS=u,R.version="2.1.0";export{R as default};
18
+ */const p={steelblue:{area:"#4682b4",line:"#3a6d96",axis:"#555",text:"#222",focus:"#e6550d"},lime:{area:"#9ccc2f",line:"#7da521",axis:"#555",text:"#222",focus:"#d62728"},purple:{area:"#9467bd",line:"#76529c",axis:"#555",text:"#222",focus:"#ff9f1c"},slate:{area:"#7c8a99",line:"#4a5560",axis:"#5a6570",text:"#26303a",focus:"#2f81f7"},graphite:{area:"#9a948c",line:"#5c574f",axis:"#5c574f",text:"#2b2823",focus:"#e07a3f"},amber:{area:"#f0a23b",line:"#c4671a",axis:"#7a5a36",text:"#3a2a16",focus:"#1f6fb2"}},u=["top","bottom","left","right","top-left","top-right","bottom-left","bottom-right"],d={en:{distance:"Distance",elevation:"Elevation",slope:"Slope",ascent:"D+",descent:"D-",empty:"Click a track",noElevation:"No elevation data",untitled:"Profile",time:"Time",duration:"Duration",durationUnits:{s:"sec",m:"min",h:"h",d:"d"},zoomStart:"Set start (A)",zoomEnd:"Set end (B)",zoomAll:"Show all",zoomBack:"Back one level",exportPng:"Export as PNG",collapse:"Collapse the profile",expand:"Expand the profile",loading:"Loading the elevation profile"},fr:{distance:"Distance",elevation:"Altitude",slope:"Pente",ascent:"D+",descent:"D-",empty:"Cliquez un tracé",noElevation:"Aucune altimétrie",untitled:"Profil",time:"Temps",duration:"Durée",durationUnits:{s:"sec",m:"min",h:"h",d:"j"},zoomStart:"Définir le début (A)",zoomEnd:"Définir la fin (B)",zoomAll:"Tout voir",zoomBack:"Revenir au niveau précédent",exportPng:"Exporter en PNG",collapse:"Réduire le profil",expand:"Agrandir le profil",loading:"Chargement du profil altimétrique"},es:{distance:"Distancia",elevation:"Altitud",slope:"Pendiente",ascent:"D+",descent:"D-",empty:"Haga clic en una traza",noElevation:"Sin datos de altitud",untitled:"Perfil",time:"Tiempo",duration:"Duración",durationUnits:{s:"seg",m:"min",h:"h",d:"d"},zoomStart:"Definir el inicio (A)",zoomEnd:"Definir el final (B)",zoomAll:"Ver todo",zoomBack:"Volver al nivel anterior",exportPng:"Exportar como PNG",collapse:"Contraer el perfil",expand:"Desplegar el perfil",loading:"Cargando el perfil de elevación"}},m={immersion:"docked",position:"bottom",width:520,height:180,margins:{unit:"px",top:20,right:24,bottom:30,left:48},units:"meters",dataProjection:null,dem:"terrarium",maxPoints:2e3,smoothing:0,theme:"steelblue",color:null,trackLayer:null,transparency:!1,transparencyLevel:.45,grid:!0,slope:!1,slopeClassSize:2.5,slopeColors:null,slopeSeparators:!0,slopeLegend:!0,maxClasses:8,xTicks:null,yTicks:null,verticalScale:"auto",show:"click",showWithoutElevation:!0,collapsable:!0,collapsed:!1,followMap:!0,marker:!0,hideOnMapClick:!0,responsive:!0,mobileBreakpoint:640,zoom:!1,zoomLevels:3,exportPng:!1,ignoreStops:!0,stopSpeed:.5,tooltipItems:["distance","elevation"],headerItems:["distance","ascent","descent","minmax"],titleProperty:"name",titleLink:null,lang:"en",labels:{}};function f(t,e){return _(d[t]||d.en,e||null)}function _(t,e){const s={};return Object.keys(t).forEach(e=>{s[e]=t[e]}),e&&Object.keys(e).forEach(o=>{e[o]&&"object"==typeof e[o]&&!Array.isArray(e[o])&&t[o]&&"object"==typeof t[o]?s[o]=_(t[o],e[o]):s[o]=e[o]}),s}const g=t=>String(t).replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[t])),y=t=>"string"==typeof t&&/^(https?:)?\/\/|^mailto:/i.test(t);function x(t){if(!t||!t.getCoordinates)return[];const e=t.getCoordinates();switch(t.getType()){case"LineString":case"LinearRing":return[e];case"MultiLineString":return e;case"Polygon":return e.length?[e[0]]:[];case"MultiPolygon":return e.map(t=>t[0]).filter(Boolean);default:return[]}}function b(t,e){const s=t&&t.getProperties?t.getProperties():{};let o=s.coordTimes;null==o&&s.coordinateProperties&&(o=s.coordinateProperties.times||s.coordinateProperties.coordTimes);let n=null;if(Array.isArray(o)&&(n=Array.isArray(o[0])?o.reduce((t,e)=>t.concat(e),[]):o.slice()),!n&&e){const t=[];let s=!1;for(const o of e)for(const e of o){const o=e.length>3?e[3]:null;t.push(o),null!=o&&isFinite(o)&&(s=!0)}n=s?t:null}if(!n)return null;let i=0;const l=n.map(t=>{if(null==t||""===t)return null;const e="number"==typeof t?t>1e12?t:1e3*t:Date.parse(t);return isFinite(e)?(i++,e):null});return i>=2?l:null}function v(t,e,s){let o=t;if("function"==typeof o)try{o=o(e,s)}catch(t){return null}if(Array.isArray(o)&&(o=o[0]),o&&o.getStroke){const t=o.getStroke();if(t)return t.getColor()}return null}const S=(t,e)=>{if("imperial"===e){const e=t/1609.344;return e<.2?`${Math.round(3.28084*t)} ft`:`${e.toFixed(e<10?2:1)} mi`}return t<1e3?`${Math.round(t)} m`:`${(t/1e3).toFixed(t<1e4?2:1)} km`},E=(t,e)=>"imperial"===e?`${Math.round(3.28084*t)} ft`:`${Math.round(t)} m`;const M='<svg viewBox="0 0 24 24"><path d="M5 13h14" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></svg>',k='<svg viewBox="0 0 24 24"><path d="M3 19l5-7 4 4 4-6 5 9z" fill="currentColor" opacity=".85"/></svg>',w=c.bisector(t=>t.x).left,z={terrarium:{url:"https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png",encoding:"terrarium",maxZoom:14,attributions:'Elevation: <a href="https://registry.opendata.aws/terrain-tiles/">Terrain Tiles</a> (AWS Open Data)'},ign:{api:"ign",url:"https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevation.json",resource:"ign_rge_alti_wld",batch:200,minInterval:1100,attributions:'Elevation: <a href="https://geoservices.ign.fr/rgealti">RGE ALTI</a> (IGN)'}};function C(t){const e=Math.max(1,t.batch||200),s=t.minInterval||0;return o=>{const n=[];let i=0;const l=r=>{if(r>=o.length)return Promise.resolve(n);const a=o.slice(r,r+e),h=Math.max(0,s-(Date.now()-i));return new Promise(t=>setTimeout(t,h)).then(()=>(i=Date.now(),fetch(function(t,e){const s=t=>t.toFixed(6),o=t.url.indexOf("?")>=0?"&":"?";let n=t.url+o+"resource="+encodeURIComponent(t.resource)+"&delimiter=|&zonly=true&lon="+e.map(t=>s(t[0])).join("|")+"&lat="+e.map(t=>s(t[1])).join("|");return t.apiKey&&(n+="&"+(t.apiKeyParam||"apikey")+"="+encodeURIComponent(t.apiKey)),n}(t,a)))).then(t=>t&&t.ok?t.json():null).then(t=>{const s=t&&t.elevations;if(!Array.isArray(s)||s.length!==a.length)return null;for(const t of s)n.push(null==t||t<=-99999?null:t);return l(r+e)})};return l(0)}}const P={source:"terrarium",zoom:"auto",maxZoom:14,maxTiles:32,concurrency:6,tileSize:256},T={terrarium:(t,e,s)=>256*t+e+s/256-32768,mapbox:(t,e,s)=>.1*(65536*t+256*e+s)-1e4},A=20037508.342789244;function $(t,e){const s=t.indexOf("?")>=0?"&":"?";return t.replace(/[?&]$/,"")+s+Object.keys(e).map(t=>t+"="+encodeURIComponent(e[t])).join("&")}function L(t,e,s,o,n){const i=Object.assign({SERVICE:"WMS",REQUEST:"GetMap",VERSION:"1.3.0",FORMAT:"image/png",TRANSPARENT:"false",STYLES:""},t.params||{}),l=0===String(i.VERSION).indexOf("1.1")?"SRS":"CRS";return delete i.SRS,delete i.CRS,i[l]=t.projection||"EPSG:3857",i.LAYERS=t.layers,i.WIDTH=n,i.HEIGHT=n,i.BBOX=function(t,e,s){const o=2*A/Math.pow(2,t),n=e*o-A,i=A-s*o;return[n,i-o,n+o,i]}(e,s,o).join(","),$(t.url,i)}function j(t){const e=t.olSource,s=t.band||0;return o=>{const l=e.getTileGrid&&e.getTileGrid();return(l?Promise.resolve(null):Promise.resolve(e.getView?e.getView():null)).then(a=>{const h=l||e.getTileGrid&&e.getTileGrid()||a&&a.tileGrid;if(!h)return null;const c=i(a&&a.projection||e.getProjection&&e.getProjection()||"EPSG:3857"),p=h.getResolutions?h.getResolutions().length-1:0,u=e.bandCount||1,d=o.map(t=>n([t[0],t[1]],"EPSG:4326",c)),m=h.getExtent&&h.getExtent()||a&&a.extent||null,f=t=>{const e=h.getResolution(t),s=h.getOrigin(t);let o=h.getTileSize(t);o=Array.isArray(o)?o:[o,o];const n=m?Math.round((m[2]-m[0])/e):1/0,i=m?Math.round((m[3]-m[1])/e):1/0,l=t=>Math.min(n-1,Math.max(0,t)),r=t=>Math.min(i-1,Math.max(0,t)),a=new Map,c=d.map(t=>{const n=(t[0]-s[0])/e-.5,i=(s[1]-t[1])/e-.5,h=l(Math.floor(n)),c=r(Math.floor(i));for(let t=0;t<2;t++)for(let e=0;e<2;e++){const s=Math.floor(l(h+t)/o[0]),n=Math.floor(r(c+e)/o[1]);a.set(s+"/"+n,[s,n])}return{i0:h,j0:c,tx:Math.min(1,Math.max(0,n-h)),ty:Math.min(1,Math.max(0,i-c)),clampI:l,clampJ:r}});return{res:e,origin:s,ts:o,need:a,at:c,clampI:l,clampJ:r}};let _=p,g=f(_);for(;_>0&&g.need.size>t.maxTiles;)_--,g=f(_);if(g.need.size>t.maxTiles)return null;const y=Array.from(g.need.keys());return Promise.all(y.map(t=>{const s=g.need.get(t);return(o=e.getTile(_,s[0],s[1],1,c),new Promise(t=>{const e=()=>{const e=o.getState();return e===r.LOADED?(t(o.getData?o.getData():null),!0):(e===r.ERROR||e===r.EMPTY)&&(t(null),!0)};if(e())return;const s=()=>{e()&&o.removeEventListener("change",s)};o.addEventListener("change",s),o.load&&o.load()})).then(e=>[t,e]);var o})).then(t=>{const e=new Map(t),o=(t,o)=>{const n=Math.floor(g.clampI(t)/g.ts[0]),i=Math.floor(g.clampJ(o)/g.ts[1]);t=g.clampI(t),o=g.clampJ(o);const l=e.get(n+"/"+i);if(!l)return null;const r=t-n*g.ts[0],a=l[((o-i*g.ts[1])*g.ts[0]+r)*u+s];return null!=a&&isFinite(a)?a:null};return g.at.map(t=>{const e=o(t.i0,t.j0),s=o(t.i0+1,t.j0),n=o(t.i0,t.j0+1),i=o(t.i0+1,t.j0+1);if(null==e||null==s||null==n||null==i)return null;const l=e+(s-e)*t.tx;return l+(n+(i-n)*t.tx-l)*t.ty})})})}}function B(t){const e=t.featureInfo,s=Math.max(1,t.concurrency||6);return t=>{const o=new Array(t.length);let n=0,i=!1;const r=()=>{if(i||n>=t.length)return Promise.resolve();const s=n++;return fetch(function(t,e){const s=l([e[0],e[1]]),o=t.resolution||1,n=Object.assign({SERVICE:"WMS",REQUEST:"GetFeatureInfo",VERSION:"1.3.0",INFO_FORMAT:"application/json",STYLES:"",FEATURE_COUNT:1},t.params||{}),i=0===String(n.VERSION).indexOf("1.1")?"SRS":"CRS";return delete n.SRS,delete n.CRS,n[i]=t.projection||"EPSG:3857",n.LAYERS=t.layers,n.QUERY_LAYERS=t.queryLayers||t.layers,n.WIDTH=1,n.HEIGHT=1,n.I=0,n.J=0,n.X=0,n.Y=0,n.BBOX=[s[0]-o,s[1]-o,s[0]+o,s[1]+o].join(","),$(t.url,n)}(e,t[s])).then(t=>t&&t.ok?t.json():null).then(t=>(o[s]=function(t,e){const s=t&&t.features&&t.features[0],o=s&&s.properties;if(!o)return null;if(e){const t=Number(o[e]);return isFinite(t)?t:null}for(const t of Object.keys(o)){const e=Number(o[t]);if(null!==o[t]&&""!==o[t]&&isFinite(e))return e}return null}(t,e.property),r())).catch(()=>{i=!0})},a=[];for(let e=0;e<Math.min(s,t.length);e++)a.push(r());return Promise.all(a).then(()=>i?null:o)}}class F{constructor(t){this.cfg=t,this.decode="function"==typeof t.encoding?t.encoding:T[t.encoding]||T.terrarium,this.tileUrl=function(t){const e=t.olSource;if(e&&"function"==typeof e.getTileUrlFunction){const t=e.getTileUrlFunction(),s=i("EPSG:3857");return(e,o,n)=>t([e,o,n],1,s)}return t.wms?(e,s,o)=>L(t.wms,e,s,o,t.tileSize):(e,s,o)=>t.url.replace("{z}",e).replace("{x}",s).replace("{y}",o)}(t),this.tiles=new Map}_neighbours(t,e,s){const o=function(t,e,s,o){const n=o*Math.pow(2,s),i=Math.sin(e*Math.PI/180);return[(t+180)/360*n,(.5-Math.log((1+i)/(1-i))/(4*Math.PI))*n]}(t,e,s,this.cfg.tileSize),n=o[0]-.5,i=o[1]-.5,l=Math.floor(n),r=Math.floor(i);return{i0:l,j0:r,tx:n-l,ty:i-r}}_key(t,e,s){const o=this.cfg.tileSize,n=o*Math.pow(2,s),i=Math.min(n-1,Math.max(0,e)),l=(t%n+n)%n;return{key:s+"/"+Math.floor(l/o)+"/"+Math.floor(i/o),ii:l,jj:i}}_at(t,e,s){const o=this.cfg.tileSize,n=this._key(t,e,s),i=this.tiles.get(n.key);if(!i)return null;const l=4*(n.jj%o*o+n.ii%o),r=this.decode(i[l],i[l+1],i[l+2],i[l+3]);return null!=r&&isFinite(r)?r:null}sample(t,e,s){const o=this._neighbours(t,e,s),n=this._at(o.i0,o.j0,s),i=this._at(o.i0+1,o.j0,s),l=this._at(o.i0,o.j0+1,s),r=this._at(o.i0+1,o.j0+1,s);if(null==n||null==i||null==l||null==r)return null;const a=n+(i-n)*o.tx;return a+(l+(r-l)*o.tx-a)*o.ty}tilesFor(t,e){const s=new Set;for(const o of t){const t=this._neighbours(o[0],o[1],e);for(let o=0;o<2;o++)for(let n=0;n<2;n++)s.add(this._key(t.i0+o,t.j0+n,e).key)}return s}_fetch(t){const e=t.split("/"),s=this.tileUrl(+e[0],+e[1],+e[2]);return new Promise(t=>{const e=new Image;e.crossOrigin="anonymous",e.onload=()=>{try{const s=this.cfg.tileSize,o=document.createElement("canvas");o.width=s,o.height=s;const n=o.getContext("2d",{willReadFrequently:!0});n.drawImage(e,0,0,s,s),t(n.getImageData(0,0,s,s).data)}catch(e){t(null)}},e.onerror=()=>t(null),e.src=s})}load(t){const e=Array.from(t).filter(t=>!this.tiles.has(t));let s=0,o=!0;const n=()=>{if(s>=e.length)return Promise.resolve();const t=e[s++];return this._fetch(t).then(e=>(this.tiles.set(t,e),e||(o=!1),n()))},i=[];for(let t=0;t<Math.min(this.cfg.concurrency,e.length);t++)i.push(n());return Promise.all(i).then(()=>o)}}class R extends t{constructor(t){const e=_(m,t||{});-1===u.indexOf(e.position)&&(e.position="bottom");const s=e.labels;e.labels=f(e.lang,s);const o=function(t){const e=document.createElement("div");return e.className=`ol-elevation-profile ol-unselectable ol-control oep-pos-${t.position} oep-theme-${"string"==typeof t.theme?t.theme:"custom"}`+("floating"===t.immersion?" oep-floating":""),e}(e);super({element:o,target:t&&t.target}),this.options=e,this._userLabels=s,this.slopeColors=e.slopeColors||null,this._feature=null,this._fullSamples=null,this._fullStats=null,this._samples=null,this._stats=null,this._marker=null,this._collapsed=!!e.collapsed,this._crops=[],this._off=0,this._zoomA=null,this._zoomB=null,this._armed=null,this._demZ=null,this._demFor=null,this._demSeq=0,this._demLoading=!1,this._trackLines=null,this._linesFor=null,this._onResize=()=>{this._feature&&!this._collapsed&&this._render()},this._buildDom(o),o.style.display="none"}get _cropMode(){return this._crops.length>0}get _cropDepth(){return this._crops.length}get _cropMax(){const t=this.options.zoomLevels;return null==t?3:Math.max(1,0|t)}static featureHasZ(t){const e=t&&t.getGeometry&&t.getGeometry();if(!e)return!1;for(const t of x(e))for(const e of t)if(e.length>2&&isFinite(e[2]))return!0;return!1}static featureHasTime(t){const e=t&&t.getGeometry&&t.getGeometry();return!!e&&!!b(t,x(e))}_buildDom(t){const e=this.options;this._applyTheme(),this._applyTransparency();const s=document.createElement("div");s.className="oep-header",this._titleEl=document.createElement("span"),this._titleEl.className="oep-title",this._titleEl.textContent=e.labels.empty,this._statsEl=document.createElement("span"),this._statsEl.className="oep-stats",s.appendChild(this._titleEl),s.appendChild(this._statsEl),this._toolbar=document.createElement("span"),this._toolbar.className="oep-toolbar";const o=(t,e,s,o)=>{const n=document.createElement("button");return n.type="button",n.className=`oep-tbtn ${t}`,n.innerHTML=e,n.title=s,n.setAttribute("aria-label",s),n.addEventListener("click",o),this._toolbar.appendChild(n),n};this._btnA=o("oep-a",'<svg viewBox="0 0 24 24"><path d="M7 5v14M11 12h8m0 0-3-3m3 3-3 3" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.zoomStart,()=>this._arm("A")),this._btnB=o("oep-b",'<svg viewBox="0 0 24 24"><path d="M17 5v14M13 12H5m0 0 3-3m-3 3 3 3" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.zoomEnd,()=>this._arm("B")),this._btnBack=o("oep-back",'<svg viewBox="0 0 24 24"><path d="M10 6 4 12l6 6M4 12h10a6 6 0 0 1 6 6" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.zoomBack,()=>this._popCrop()),this._btnAll=o("oep-all",'<svg viewBox="0 0 24 24"><path d="M4 12h16M4 12l4-4M4 12l4 4M20 12l-4-4M20 12l-4 4" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.zoomAll,()=>this._exitZoom()),this._btnPng=o("oep-png",'<svg viewBox="0 0 24 24"><path d="M12 4v10m0 0 4-4m-4 4-4-4M5 18h14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.exportPng,()=>this.exportPNG()),s.appendChild(this._toolbar);const n=document.createElement("button");n.className="oep-toggle",n.type="button",n.innerHTML=this._collapsed?k:M,n.addEventListener("click",()=>this.toggleCollapsed()),s.appendChild(n),this._toggleBtn=n,this._applyToggleLabel(),this._legendEl=document.createElement("div"),this._legendEl.className="oep-legend",this._legendEl.style.display="none",this._body=document.createElement("div"),this._body.className="oep-body",t.appendChild(s),t.appendChild(this._legendEl),t.appendChild(this._body),this._applyCollapsable(),this._updateZoomButtons(),this._collapsed&&t.classList.add("oep-collapsed")}_applyLabels(){const t=this.options.labels,e=(t,e)=>{t&&e&&(t.title=e,t.setAttribute("aria-label",e))};e(this._btnA,t.zoomStart),e(this._btnB,t.zoomEnd),e(this._btnBack,t.zoomBack),e(this._btnAll,t.zoomAll),e(this._btnPng,t.exportPng),this._applyToggleLabel(),this._titleEl&&!this._feature&&(this._titleEl.textContent=t.empty)}_applyToggleLabel(){const t=this.options.labels,e=this._collapsed?t.expand:t.collapse;this._toggleBtn&&e&&(this._toggleBtn.title=e,this._toggleBtn.setAttribute("aria-label",e))}_resolveColor(){const t=this.options;return t.color?"auto"===t.color?this._featureColor():t.color:null}_featureColor(){const t=this._feature;if(!t)return null;const e=this.getMap()?this.getMap().getView().getResolution():1;let s=v(t.getStyle&&t.getStyle(),t,e);return!s&&this.options.trackLayer&&(s=v(this.options.trackLayer.getStyle&&this.options.trackLayer.getStyle(),t,e)),function(t){if(null==t)return null;if("string"==typeof t)return t;if(Array.isArray(t)){const e=t.length>3?t[3]:1;return`rgba(${0|t[0]},${0|t[1]},${0|t[2]},${e})`}return null}(s)}_applyTheme(){const t=this.options,e="object"==typeof t.theme?t.theme:p[t.theme]||p.steelblue;this.themeColors=e;const s=this.element,o=this._resolveColor(),n=o||e.area;let i=e.line;if(o)try{i=String(c.color(o).darker(.7))}catch(t){i=o}s.style.setProperty("--oep-area",n),s.style.setProperty("--oep-line",i),s.style.setProperty("--oep-axis",e.axis),s.style.setProperty("--oep-text",e.text),s.style.setProperty("--oep-focus",e.focus)}_applyTransparency(){const t=this.options.transparency;let e;e=!1===t||null==t?1:!0===t?this.options.transparencyLevel:Math.max(0,Math.min(1,+t)),this.element.style.setProperty("--oep-bg",`rgba(255,255,255,${e})`),this.element.classList.toggle("oep-transparent",e<1)}_applyCollapsable(){const t=this.options.collapsable;this._toggleBtn.style.display=t?"":"none",!t&&this._collapsed&&this.toggleCollapsed(!1)}toggleCollapsed(t){this._collapsed="boolean"==typeof t?t:!this._collapsed,this.element.classList.toggle("oep-collapsed",this._collapsed),this._toggleBtn.innerHTML=this._collapsed?k:M,this._applyToggleLabel(),!this._collapsed&&this._feature&&this._render(),this._adjustAttribution()}_availWidth(){const t=this.getMap(),e=t&&t.getTargetElement&&t.getTargetElement();return e&&e.clientWidth||("undefined"!=typeof window?window.innerWidth:1024)}_isMobile(){return this.options.responsive&&"undefined"!=typeof window&&window.innerWidth<=(this.options.mobileBreakpoint||640)}_applyPlacement(){const t=this._isMobile();let e=this.options.position;return t&&(e=/top/.test(e)?"top":"bottom"),this.element.className=this.element.className.replace(/oep-pos-\S+/,`oep-pos-${e}`),this.element.classList.toggle("oep-mobile",t),t}_adjustAttribution(){const t=this.getMap(),e=t&&t.getTargetElement&&t.getTargetElement(),s=e&&e.querySelector&&e.querySelector(".ol-attribution");if(!s)return;if(s.style.bottom="",s.style.right="","none"===this.element.style.display||this._collapsed)return;const o=e.getBoundingClientRect(),n=this.element.getBoundingClientRect();if(!n.height)return;const i=o.bottom-n.bottom,l=o.right-n.right;i<n.height&&l<24&&(s.style.right=`${Math.max(0,Math.round(l))}px`,s.style.bottom=`${Math.round(n.height+2*i)}px`)}setMap(t){const o=this.getMap();if(super.setMap(t),this._mapKeys&&(this._mapKeys.forEach(s),this._mapKeys=null),o&&"undefined"!=typeof window&&window.removeEventListener("resize",this._onResize),this._marker&&!t&&this._marker.setPosition(void 0),!t)return;const n=this.options;if(n.dataProjection||(n.dataProjection=t.getView().getProjection()),n.marker&&!this._marker){const s=document.createElement("div");s.className="oep-marker",this._marker=new e({element:s,positioning:"center-center",stopEvent:!1}),t.addOverlay(this._marker)}"undefined"!=typeof window&&window.addEventListener("resize",this._onResize);const i=e=>t.forEachFeatureAtPixel(e,t=>{const e=t.getGeometry();return(s=e)&&/^(Multi)?(LineString|Polygon)$|^LinearRing$/.test(s.getType())?t:void 0;var s});this._mapKeys=[],this._mapKeys.push(t.on("click",t=>{const e=i(t.pixel);"mouseover"!==this.options.show&&e&&e!==this._feature&&this.setFeature(e),this.options.hideOnMapClick&&!e&&this._feature&&this.clear()})),this._mapKeys.push(t.on("pointermove",e=>{if("mouseover"===this.options.show){const t=i(e.pixel);t&&t!==this._feature&&this.setFeature(t)}if(!this.options.followMap||!this._feature||this._collapsed)return;const s=this._closestOnProfile(e.coordinate);if(!s)return;const o=t.getPixelFromCoordinate(s);o&&(Math.hypot(o[0]-e.pixel[0],o[1]-e.pixel[1])<14?this._focusByCoord(s):this._clearFocus())})),this._mapKeys.push(t.on("moveend",()=>{const e=this._crops[this._crops.length-1];e&&e.fitRes&&t.getView().getResolution()>1.25*e.fitRes&&this._popCrop()})),this._mapKeys.push(t.on("change:size",this._onResize))}setFeature(t){return this._feature=t||null,this._crops=[],this._off=0,this._zoomA=null,this._zoomB=null,this._armed=null,t?(this.element.style.display="",this._compute(),this._fillFromDem(t),this._updateZoomButtons(),this._collapsed?this._renderTitle():this._render(),this):(this._fullSamples=this._samples=null,this._demZ=this._demFor=null,this._trackLines=this._linesFor=null,this._clear(),this)}clear(){return this.setFeature(null)}getStats(){return this._stats}setTheme(t){return this.options.theme=t,this._applyTheme(),this._feature&&!this._collapsed&&this._render(),this}setColor(t){return this.options.color=t||null,this._applyTheme(),this._feature&&!this._collapsed&&this._render(),this}setOptions(t){return this.options=_(this.options,t||{}),t&&"slopeColors"in t&&(this.slopeColors=t.slopeColors||null),t&&(t.theme||"color"in t)&&this._applyTheme(),t&&("transparency"in t||"transparencyLevel"in t)&&this._applyTransparency(),t&&"collapsable"in t&&this._applyCollapsable(),t&&"labels"in t&&(this._userLabels=_(this._userLabels||{},t.labels)),t&&("lang"in t||"labels"in t)&&(this.options.labels=f(this.options.lang,this._userLabels),this._applyLabels()),t&&("zoom"in t||"exportPng"in t)&&this._updateZoomButtons(),t&&void 0!==t.width&&"number"==typeof t.width&&(this.options.width=t.width),t&&"dem"in t&&(this._demZ=null,this._demFor=null,this._trackLines=null,this._linesFor=null),this._feature&&(this._compute(),this._fillFromDem(this._feature),this._updateZoomButtons(),this._collapsed?this._renderTitle():this._render()),this}_fillFromDem(t){const e=function(t){if(!t)return null;if("function"==typeof t)return Object.assign({},P,{sample:t});const e=!0===t||"string"==typeof t?{source:!0===t?"terrarium":t}:Object.assign({},t);if("function"==typeof e.sample)return Object.assign({},P,e);if(e.track){const t=Object.assign({},P,e);return t.track=Object.assign({coords:"coords",parse:null,fetchOptions:null},"string"==typeof e.track?{url:e.track}:e.track),t.track.url?t:null}if(e.featureInfo){const t=Object.assign({},P,e);return t.sample=B(t),t}if(e.olSource&&"function"!=typeof e.olSource.getTileUrlFunction&&"function"==typeof e.olSource.getTile){const t=Object.assign({},P,e);return t.sample=j(t),t}const s=e.url||e.wms||e.olSource,o=z[e.source]||(s?{}:z.terrarium),n=Object.assign({},P,o,e);return"ign"===n.api?(n.sample=C(n),n):n.url||n.wms||n.olSource?n:null}(this.options.dem);if(!e||!t||this._demFor===t||this._linesFor===t)return;if(R.featureHasZ(t))return;if(!e.sample&&("undefined"==typeof Image||"undefined"==typeof document))return;const s=t.getGeometry&&t.getGeometry(),n=s?x(s):[],i=this.options.dataProjection||this.getMap()&&this.getMap().getView().getProjection()||"EPSG:3857",l=[];for(const t of n)for(const e of t)l.push(o(e,i));if(!l.length&&!e.track)return;const r=++this._demSeq;this._demLoading=!0;try{this._startFill(e,r,t,l,i)}catch(e){this._demDone(r,t,null,l.length,null,0)}}_startFill(t,e,s,o,n){if(t.track)return void this._startTrackFill(t,e,s,o.length,n);if(t.sample)return void Promise.resolve().then(()=>t.sample(o,{feature:s,projection:n})).then(t=>this._demDone(e,s,t,o.length,null,0)).catch(()=>this._demDone(e,s,null,o.length,null,0));const i=new F(t),l=function(t,e,s){if("number"==typeof s.zoom)return s.zoom;for(let o=s.maxZoom;o>0;o--)if(t.tilesFor(e,o).size<=s.maxTiles)return o;return 1}(i,o,t);i.load(i.tilesFor(o,l)).then(t=>{const n=t?o.map(t=>i.sample(t[0],t[1],l)):null;this._demDone(e,s,n,o.length,l,i.tiles.size)}).catch(()=>this._demDone(e,s,null,o.length,l,0))}_startTrackFill(t,e,s,o,n){const i=function(t,e){if("function"==typeof t)return t(e)||null;if("string"!=typeof t||!e)return null;let s=!0;const o=t.replace(/\{(\w+)\}/g,(t,o)=>{const n=e.get(o);return null==n||""===n?(s=!1,""):encodeURIComponent(String(n))});return s?o:null}(t.track.url,s);i?Promise.resolve().then(()=>fetch(i,t.track.fetchOptions||void 0)).then(t=>{if(!t.ok)throw new Error(String(t.status));return t.json()}).then(i=>{const l=t.track.parse?t.track.parse(i,s):Array.isArray(i)?i:i&&i[t.track.coords];this._trackDone(e,s,l,o,n)}).catch(()=>this._demDone(e,s,null,o,null,0)):this._demDone(e,s,null,o,null,0)}_trackDone(t,e,s,o,i){const l=()=>this._demDone(t,e,null,o,null,0);if(!Array.isArray(s)||!s.length)return l();if("number"==typeof s[0])return void this._demDone(t,e,s,o,null,0);if(t!==this._demSeq||this._feature!==e)return;const r=t=>null!=t&&isFinite(t),a=[];for(const t of s){if(!t||t.length<3||!r(t[0])||!r(t[1])||!r(t[2]))return l();const e=n([t[0],t[1]],"EPSG:4326",i);a.push([e[0],e[1],t[2]])}if(a.length<2)return l();this._demLoading=!1,this._trackLines=[a],this._linesFor=e,this._demZ=null,this._demFor=null,this._compute(),this._updateZoomButtons(),this._collapsed||this._render(),this.dispatchEvent({type:"demload",ok:!0,zoom:null,tiles:0})}_demDone(t,e,s,o,n,i){if(t!==this._demSeq||this._feature!==e)return;const l=Array.isArray(s)&&s.length===o&&s.every(t=>null!=t&&isFinite(t));this._demLoading=!1,l&&(this._demZ=s,this._demFor=e,this._compute()),this._updateZoomButtons(),this._collapsed||this._render(),this.dispatchEvent({type:"demload",ok:l,zoom:n,tiles:i})}_compute(){const t=this.options,e=this._linesFor===this._feature&&this._trackLines,s=this._feature.getGeometry&&this._feature.getGeometry(),n=e?this._trackLines:s?x(s):[],i=t.dataProjection||this.getMap()&&this.getMap().getView().getProjection()||"EPSG:3857",l=this._demFor===this._feature?this._demZ:null,r=e?null:b(this._feature,n);this._hasTime=!!r;const h=!1!==t.ignoreStops,c=null!=t.stopSpeed?t.stopSpeed:.5,p=[];let u=0,d=null,m=-1,f=0,_=null;for(const t of n)for(const e of t){m++;const t=o(e,i);let s=0;d&&(s=a(d,t),u+=s);let n=null;if(r&&null!=r[m]){const t=r[m];if(null!=_){const e=(t-_)/1e3;e>0&&(!h||s/e>=c)&&(f+=e)}n=f,_=t}d=t;const g=e.length>2&&isFinite(e[2])?e[2]:l?l[m]:0;p.push({x:u,z:g,coord:e,t:n})}t.smoothing>0&&this._smooth(p,t.smoothing);const g=this._decimate(p,t.maxPoints);this._addSlope(g),this._fullSamples=g,this._fullStats=this._statsOf(g,!0),this._applyCrops()}_pxPerCm(){try{const t=document.createElement("div");t.style.cssText="position:absolute;left:-9999px;top:0;width:1cm;height:1cm",(this.element||document.body).appendChild(t);const e=t.getBoundingClientRect().height;if(t.remove(),e>0)return e}catch(t){}return 96/2.54}_yScale(t,e,s,o){const n=t.min-e,i=t.max+e,l=s/this._pxPerCm(),r=o/this._pxPerCm(),a=e=>r>0&&e>0?t.distance/r/(e/l):null;let h=this._verticalScaleFor(t,o);if(!(h>0)){const e=c.scaleLinear().domain([n,i]).range([s,0]).nice(),o=e.domain(),l=a(o[1]-o[0]),p=this._plafondExageration();if(!(p>0)||null==l||l<=p)return this._vScale=null,this._vExaggeration=l,e;h=t.distance/r/p}const p=Math.max(h*l,i-n);this._vScale=p/l,this._vExaggeration=a(p);const u=Math.min(0,n);let d=(n+i)/2-p/2;return d<u&&(d=u),c.scaleLinear().domain([d,d+p]).range([s,0])}_plafondExageration(){const t=this.options.verticalScale,e=t&&"object"==typeof t?Number(t.maxExaggeration):0;return e>0?e:0}_verticalScaleFor(t,e){const s=this.options.verticalScale;if("number"==typeof s)return s;const o=s&&"object"==typeof s?Number(s.exaggeration):0;if(!(o>0&&t.distance>0&&e>0))return 0;const n=e/this._pxPerCm();return t.distance/n/o}_statsOf(t,e){let s=0,o=0,n=1/0,i=-1/0,l=0;for(let e=0;e<t.length;e++){const r=t[e].z;if(r<n&&(n=r),r>i&&(i=r),e>0){const n=r-t[e-1].z;n>0?s+=n:o-=n}const a=Math.abs(t[e].slope||0);a>l&&(l=a)}const r=t.length?t[t.length-1].x-t[0].x:0,a=t.length?t[0].t:null,h=t.length?t[t.length-1].t:null;return{distance:r,duration:null!=a&&null!=h?h-a:null,ascent:s,descent:o,min:isFinite(n)?n:0,max:isFinite(i)?i:0,maxAbsSlope:l,points:t.length}}_smooth(t,e){if(!(e>0)||t.length<3)return;const s=e/2,o=t.map(t=>t.z);let n=0,i=0,l=0;for(let e=0;e<t.length;e++){const r=t[e].x;for(;n<t.length&&t[n].x<r-s;)l-=o[n],n++;for(;i<t.length&&t[i].x<=r+s;)l+=o[i],i++;t[e].z=i>n?l/(i-n):o[e]}}_decimate(t,e){const s=t=>({x:t.x,z:t.z,coord:t.coord,t:t.t});if(!e||t.length<=e)return t.map(s);const o=t.length/e,n=[];for(let i=0;i<e;i++)n.push(s(t[Math.floor(i*o)]));return n.push(s(t[t.length-1])),n}_addSlope(t){for(let e=1;e<t.length;e++){const s=t[e].x-t[e-1].x;t[e].slope=s>0?(t[e].z-t[e-1].z)/s*100:0}t.length&&(t[0].slope=t.length>1?t[1].slope:0)}_slopeScale(){const t=this.options.slopeClassSize||2.5,e=this.options.maxClasses||8,s=Math.max(1,Math.floor((this._stats.maxAbsSlope||0)/t)),o=Math.min(s,e-1),n=s>o;let i;if(this.slopeColors&&this.slopeColors.length){const t=c.interpolateRgbBasis(this.slopeColors);i=e=>t(o?e/o:0)}else{const t=c.scaleLinear().domain([0,.16,.42,.68,1]).range(["#2166ac","#27a35a","#ffe000","#f4791f","#d7191c"]).interpolate(c.interpolateRgb).clamp(!0);i=e=>String(t(o?e/o:0))}return{classSize:t,maxIdx:o,capped:n,colorByIndex:i}}_classIndex(t,e){return Math.min(e.maxIdx,Math.floor(Math.abs(t)/e.classSize))}_fmtDuration(t){if(null==t||!isFinite(t))return"";const e=this.options.labels&&this.options.labels.durationUnits||d.en.durationUnits;if((t=Math.max(0,Math.round(t)))<60)return t+" "+e.s;if(t<3600)return Math.round(t/60)+" "+e.m;if(t<86400){let s=Math.floor(t/3600),o=Math.round(t%3600/60);return 60===o&&(s++,o=0),o?`${s} ${e.h} ${o} ${e.m}`:`${s} ${e.h}`}let s=Math.floor(t/86400),o=Math.round(t%86400/3600);return 24===o&&(s++,o=0),o?`${s} ${e.d} ${o} ${e.h}`:`${s} ${e.d}`}_hasElevation(){const t=this._feature;return!!t&&(!!R.featureHasZ(t)||(!(this._demFor!==t||!this._demZ)||!(this._linesFor!==t||!this._trackLines)))}_renderNoElevation(){if(!this.options.showWithoutElevation)return void(this.element.style.display="none");this.element.style.display="",this._applyTheme(),this._applyPlacement(),this._renderHeader(!0);const t="number"==typeof this.options.height?this.options.height:180;this._body.innerHTML="";const e=document.createElement("div");e.className="oep-noelev",e.style.height=`${t}px`,e.setAttribute("role","status"),e.textContent=this.options.labels.noElevation,this._body.appendChild(e),this._clearFocus()}_pickProperty(t,e,s){if(!e||!t||!t.get)return null;for(const o of Array.isArray(e)?e:[e]){const e=t.get(o);if(null!=e&&""!==e&&(!s||s(e)))return e}return null}_renderTitle(){const t=this.options,e=this._feature;if(!e)return;const s=this._pickProperty(e,t.titleProperty)||t.labels.untitled,o=this._pickProperty(e,t.titleLink,y);y(o)?this._titleEl.innerHTML=`<a href="${g(o)}" target="_blank" rel="noopener">${g(s)}</a>`:this._titleEl.textContent=s,this._titleEl.setAttribute("title",s)}_renderHeader(t){const e=this.options,s=this._stats,o=this._feature;if(this._renderTitle(),this._demLoading)return this._statsEl.innerHTML="",this._statsEl.removeAttribute("title"),this._legendEl.innerHTML="",void(this._legendEl.style.display="none");const n=[],i=[];if(e.headerItems.forEach(l=>{if("string"==typeof l){if(t&&("ascent"===l||"descent"===l||"min"===l||"max"===l||"minmax"===l))return;if("distance"===l){if(!(s&&s.distance>0))return;n.push(`<b>${S(s.distance,e.units)}</b>`),i.push(S(s.distance,e.units))}else if("ascent"===l)n.push(`<span class="oep-up">${e.labels.ascent} ${E(s.ascent,e.units)}</span>`),i.push(`${e.labels.ascent} ${E(s.ascent,e.units)}`);else if("descent"===l)n.push(`<span class="oep-down">${e.labels.descent} ${E(s.descent,e.units)}</span>`),i.push(`${e.labels.descent} ${E(s.descent,e.units)}`);else if("min"===l)n.push(E(s.min,e.units)),i.push(E(s.min,e.units));else if("max"===l)n.push(E(s.max,e.units)),i.push(E(s.max,e.units));else if("minmax"===l){const t=`${E(s.min,e.units)}-${E(s.max,e.units)}`;n.push(t),i.push(t)}else if("duration"===l&&null!=s.duration){const t=this._fmtDuration(s.duration);n.push(`<span class="oep-time">${g(e.labels.duration)} ${t}</span>`),i.push(`${e.labels.duration} ${t}`)}}else if(l&&l.property){const t=o.get&&o.get(l.property);if(null==t||""===t)return;const e=l.label?`${l.label} `:"";l.asLink&&y(t)?(n.push(`${e}<a href="${g(t)}" target="_blank" rel="noopener">${g(l.linkText||l.label||t)}</a>`),i.push(`${l.label||""} ${t}`)):(n.push(g(e+t)),i.push(e+t))}}),this._statsEl.innerHTML=n.join(" · "),this._statsEl.setAttribute("title",i.join(" · ")),this._legendEl.innerHTML="",e.slope&&e.slopeLegend&&!t){const t=this._slopeScale();for(let e=0;e<=t.maxIdx;e++){const s=t.colorByIndex(e),o=t.capped&&e===t.maxIdx?`≥ ${e*t.classSize} %`:`${e*t.classSize}-${(e+1)*t.classSize} %`,n=document.createElement("span");n.className="oep-leg-it",n.innerHTML=`<i class="oep-sw" style="background:${s}"></i>${o}`,this._legendEl.appendChild(n)}this._legendEl.style.display=""}else this._legendEl.style.display="none"}_renderSpinner(){const t="number"==typeof this.options.height?this.options.height:180;this._body.innerHTML="";const e=document.createElement("div");e.className="oep-loading",e.style.height=`${t}px`,e.setAttribute("role","status"),e.setAttribute("aria-label",this.options.labels.loading);const s=document.createElement("div");s.className="oep-spinner",e.appendChild(s),this._body.appendChild(e)}_render(){const t=this.options,e=this._stats,s=this._samples;if(!this._demLoading&&!this._hasElevation())return void this._renderNoElevation();if(!s||!s.length)return;this._applyTheme();const o=this._applyPlacement();if(this._renderHeader(),this._demLoading)return void this._renderSpinner();const n=t.margins,i=n.unit||"px",l=t=>"px"===i?t:t*(parseFloat(getComputedStyle(this.element).fontSize)||16),r=this._availWidth(),a="auto"===t.width||"100%"===t.width||"full"===t.width?r:Math.min("number"==typeof t.width?t.width:parseFloat(t.width)||r,r);this.element.style.width=o?"":`${a}px`;const h=this.element.clientWidth||(o?r:a),p=Math.max(220,h-16),u="number"==typeof t.height?t.height:180,d=l(n.top),m=l(n.right),f=l(n.bottom),_=l(n.left),g=Math.max(10,p-_-m),y=Math.max(10,u-d-f),x=null!=t.xTicks?t.xTicks:Math.max(2,Math.round(g/80)),b=null!=t.yTicks?t.yTicks:Math.max(2,Math.round(y/40));this._body.innerHTML="";const v=c.select(this._body).append("svg").attr("class","oep-svg").attr("width",p).attr("height",u).attr("viewBox",`0 0 ${p} ${u}`),S=v.append("g").attr("transform",`translate(${_},${d})`),E=c.scaleLinear().domain([0,e.distance]).range([0,g]),M=.1*(e.max-e.min)||10,k=this._yScale(e,M,y,g);this._x=E,this._y=k,this._dims={innerW:g,innerH:y},t.grid&&S.append("g").attr("class","oep-grid").call(c.axisLeft(k).ticks(b).tickSize(-g).tickFormat(""));const w="imperial"===t.units?1609.344:1e3;const z=c.area().x(t=>E(t.x)).y0(y).y1(t=>k(t.z));if(t.slope){const e=this._slopeScale(),o=[];let n=1;for(;n<s.length;){const t=this._classIndex(s[n].slope,e);let i=n;for(;i+1<s.length&&this._classIndex(s[i+1].slope,e)===t;)i++;S.append("path").datum(s.slice(n-1,i+1)).attr("class","oep-area-slope").attr("fill",e.colorByIndex(t)).attr("d",z),n>1&&o.push(s[n-1]),n=i+1}t.slopeSeparators&&o.forEach(t=>{S.append("line").attr("class","oep-slope-sep").attr("x1",E(t.x)).attr("x2",E(t.x)).attr("y1",k(t.z)).attr("y2",y)})}else S.append("path").datum(s).attr("class","oep-area").attr("d",z);S.append("path").datum(s).attr("class","oep-line").attr("d",c.line().x(t=>E(t.x)).y(t=>k(t.z))),S.append("g").attr("class","oep-axis oep-axis-x").attr("transform",`translate(0,${y})`).call(c.axisBottom(E).ticks(x).tickFormat(t=>(t/w).toFixed(t/w<10?1:0))),S.append("text").attr("class","oep-axis-label").attr("x",g).attr("y",y+f-4).attr("text-anchor","end").text((t=>"imperial"===t?"mi":"km")(t.units)),S.append("g").attr("class","oep-axis oep-axis-y").call(c.axisLeft(k).ticks(b).tickFormat(e=>"imperial"===t.units?Math.round(3.28084*e):e)),t.zoom&&this._cropDepth<this._cropMax&&[["A",this._zoomA],["B",this._zoomB]].forEach(([t,e])=>{if(null==e)return;const s=E(e);S.append("line").attr("class","oep-ab-line").attr("x1",s).attr("x2",s).attr("y1",0).attr("y2",y),S.append("text").attr("class","oep-ab-label").attr("x",s).attr("y",-6).attr("text-anchor","middle").text(t)});const C=S.append("g").attr("class","oep-focus").style("display","none");C.append("line").attr("class","oep-focus-line").attr("y1",0).attr("y2",y),C.append("circle").attr("class","oep-focus-dot").attr("r",4);const P=C.append("g").attr("class","oep-focus-label");P.append("rect").attr("class","oep-focus-bg"),P.append("text").attr("class","oep-focus-txt"),this._focus=C;const T=t=>{const s=c.pointer(t,S.node())[0];return Math.max(0,Math.min(e.distance,E.invert(s)))},A=v.append("rect").attr("class","oep-overlay").attr("x",_).attr("y",d).attr("width",g).attr("height",y);A.on("mousemove",t=>{const e=this._sampleAt(T(t));e&&(this._setFocus(e),this._marker&&this._marker.setPosition(e.coord))}).on("mouseout",()=>this._clearFocus()),A.on("click",t=>this._placeBound(T(t))),this._armed&&A.style("cursor","col-resize"),this._adjustAttribution()}static get _EXPORT_PROPS(){return["fill","fill-opacity","stroke","stroke-width","stroke-dasharray","stroke-linecap","stroke-linejoin","opacity","font-family","font-size","font-weight","text-anchor","shape-rendering"]}_freezeStyles(t,e){const s=R._EXPORT_PROPS,o=getComputedStyle(t);let n="";for(const t of s){const e=o.getPropertyValue(t);e&&(n+=`${t}:${e};`)}e.setAttribute("style",n);const i=t.children,l=e.children;for(let t=0;t<i.length&&t<l.length;t++)this._freezeStyles(i[t],l[t])}_exportSvg(){const t=this._body.querySelector("svg");if(!t)return null;const e=getComputedStyle(this.element),s=e.getPropertyValue("--oep-bg").trim()||"#fff",o=e.getPropertyValue("--oep-text").trim()||"#222",n=e.fontFamily||"system-ui, sans-serif",i=+t.getAttribute("width"),l=+t.getAttribute("height"),r=this._statsEl.textContent?15:0,a="none"!==this._legendEl.style.display?this._legendEl:null,h=28+r+(a?18:0),c=t.cloneNode(!0);c.querySelectorAll(".oep-focus, .oep-overlay").forEach(t=>t.remove()),this._freezeStyles(t,c);const p=t=>g(String(t)),u=[];if(u.push(`<rect width="${i+16}" height="${l+h+8}" fill="${p(s)}"/>`),u.push(`<text x="8" y="21" style="font-family:${p(n)};font-size:13px;font-weight:600;fill:${p(o)}">${p(this._titleEl.textContent)}</text>`),r&&u.push(`<text x="8" y="38" style="font-family:${p(n)};font-size:11px;fill:${p(o)};opacity:.85">${p(this._statsEl.textContent)}</text>`),a){let t=8;const e=28+r+12;for(const s of a.querySelectorAll(".oep-leg-it")){const i=s.querySelector(".oep-sw"),l=i?getComputedStyle(i).backgroundColor:"none",r=s.textContent.trim();u.push(`<rect x="${t}" y="${e-8}" width="10" height="10" fill="${p(l)}"/>`),u.push(`<text x="${t+14}" y="${e}" style="font-family:${p(n)};font-size:10px;fill:${p(o)}">${p(r)}</text>`),t+=14+5.6*r.length+10}}return u.push(`<g transform="translate(8,${h})">${(new XMLSerializer).serializeToString(c)}</g>`),{width:i+16,height:l+h+8,svg:`<svg xmlns="http://www.w3.org/2000/svg" width="${i+16}" height="${l+h+8}" viewBox="0 0 ${i+16} ${l+h+8}">${u.join("")}</svg>`}}exportPNG(t){const e=t||{},s=this._exportSvg();if(!s)return Promise.reject(new Error("ol-elevation-profile: nothing to export"));const o=e.scale||"undefined"!=typeof window&&window.devicePixelRatio||1;return new Promise((t,n)=>{const i=new Image;i.onload=()=>{try{const l=document.createElement("canvas");l.width=Math.round(s.width*o),l.height=Math.round(s.height*o);const r=l.getContext("2d");r.scale(o,o),r.drawImage(i,0,0),l.toBlob(s=>{s?(!1!==e.download&&this._save(s,e.filename),t(s)):n(new Error("ol-elevation-profile: PNG encoding failed"))},"image/png")}catch(t){n(t)}},i.onerror=()=>n(new Error("ol-elevation-profile: SVG could not be rasterised")),i.src="data:image/svg+xml;charset=utf-8,"+encodeURIComponent(s.svg)})}_save(t,e){const s=e||`${(this._titleEl.textContent||"profile").replace(/[\\/:*?"<>|]+/g,"-").trim()}.png`,o=URL.createObjectURL(t),n=document.createElement("a");n.href=o,n.download=s,document.body.appendChild(n),n.click(),n.remove(),setTimeout(()=>URL.revokeObjectURL(o),1e3)}_arm(t){this._armed=this._armed===t?null:t,this._updateZoomButtons(),this._focus&&this._render()}_placeBound(t){if(!this._armed||this._cropDepth>=this._cropMax)return;const e="A"===this._armed?"B":"A";"A"===this._armed?this._zoomA=t:this._zoomB=t;const s=null!=this._zoomA&&null!=this._zoomB;this._armed=s?null:e,this._updateZoomButtons(),s?this._pushCrop(this._zoomA,this._zoomB):this._render()}_updateZoomButtons(){const t=this.options,e=!!this._feature,s=!!t.zoom&&e,o=!!t.exportPng&&e;this._toolbar.style.display=s||o?"":"none",this._btnPng.style.display=o?"":"none";const n=this._cropDepth,i=n<this._cropMax;this._btnA.style.display=s&&i?"":"none",this._btnB.style.display=s&&i?"":"none",this._btnBack.style.display=s&&n>1?"":"none",this._btnAll.style.display=s&&n>0?"":"none",this._btnA.classList.toggle("armed","A"===this._armed),this._btnB.classList.toggle("armed","B"===this._armed)}_applyCrops(){if(!this._crops.length)return this._off=0,this._samples=this._fullSamples,this._stats=this._fullStats,null;const{a:t,b:e}=this._crops[this._crops.length-1],s=this._fullSamples.filter(s=>s.x>=t&&s.x<=e);if(s.length<2)return this._crops.pop(),this._applyCrops();const o=s[0].x,n=null!=s[0].t?s[0].t:0;return this._off=o,this._samples=s.map(t=>({x:t.x-o,z:t.z,coord:t.coord,slope:t.slope,t:null!=t.t?t.t-n:null})),this._stats=this._statsOf(this._samples,!1),s.map(t=>t.coord)}_fitMap(t){const e=this.getMap();if(!e)return null;let s=null;if(t&&t.length?s=h(t):this._feature&&(s=this._feature.getGeometry().getExtent()),!s)return null;const o=e.getView();let n=null;try{n=o.getResolutionForExtent(s,e.getSize())}catch(t){n=null}return o.fit(s,{padding:[40,40,40,40],duration:400}),n}_pushCrop(t,e){if(this._zoomA=null,this._zoomB=null,this._armed=null,this._cropDepth>=this._cropMax)return this._updateZoomButtons(),void this._render();const s=this._off+Math.min(t,e),o=this._off+Math.max(t,e);let n=0;for(let t=0;t<this._fullSamples.length;t++){const e=this._fullSamples[t].x;e>=s&&e<=o&&n++}if(n<2)return this._updateZoomButtons(),void this._render();this._crops.push({a:s,b:o,fitRes:null});const i=this._applyCrops();this._updateZoomButtons(),this._render();const l=this._crops[this._crops.length-1];l&&(l.fitRes=this._fitMap(i))}_applyZoom(){null!=this._zoomA&&null!=this._zoomB&&this._pushCrop(this._zoomA,this._zoomB)}_popCrop(){if(!this._crops.length)return;this._crops.pop(),this._zoomA=null,this._zoomB=null,this._armed=null;const t=this._applyCrops();this._updateZoomButtons(),this._collapsed||this._render(),this._fitMap(t)}_exitZoom(){this._crops.length=0,this._zoomA=null,this._zoomB=null,this._armed=null,this._applyCrops(),this._updateZoomButtons(),this._collapsed||this._render(),this._fitMap(null)}_closestOnProfile(t){const e=this._feature&&this._feature.getGeometry();if(!e)return null;if(!/Polygon/.test(e.getType()))return e.getClosestPoint(t);const s=this._projectOn(this._fullSamples,t);return s?s.coord:null}_projectOn(t,e){if(!t||!t.length)return null;if(1===t.length)return{x:t[0].x,coord:t[0].coord.slice(0,2)};let s=null,o=1/0;for(let n=1;n<t.length;n++){const i=t[n-1].coord,l=t[n].coord,r=l[0]-i[0],a=l[1]-i[1],h=r*r+a*a;let c=h>0?((e[0]-i[0])*r+(e[1]-i[1])*a)/h:0;c=c<0?0:c>1?1:c;const p=i[0]+r*c,u=i[1]+a*c,d=p-e[0],m=u-e[1],f=d*d+m*m;f<o&&(o=f,s={x:t[n-1].x+(t[n].x-t[n-1].x)*c,coord:[p,u]})}return s}_tooltipText(t){const e=this.options,s=[];return e.tooltipItems.forEach(o=>{var n;"distance"===o?s.push(S(t.x,e.units)):"elevation"===o?s.push(E(t.z,e.units)):"slope"===o?s.push(`${(n=t.slope||0)>=0?"+":""}${n.toFixed(1)} %`):"time"===o&&null!=t.t&&s.push(this._fmtDuration(t.t))}),s.join(" · ")}_setFocus(t){if(!this._focus)return;const e=this._x,s=this._y;this._focus.style("display",null),this._focus.select(".oep-focus-line").attr("x1",e(t.x)).attr("x2",e(t.x)),this._focus.select(".oep-focus-dot").attr("cx",e(t.x)).attr("cy",s(t.z));let o=s(t.z)-16;o<12&&(o=s(t.z)+22);const n=this._focus.select(".oep-focus-txt").attr("x",e(t.x)).attr("y",o).text(this._tooltipText(t)),i=n.node().getBBox();this._focus.select(".oep-focus-bg").attr("x",i.x-4).attr("y",i.y-2).attr("width",i.width+8).attr("height",i.height+4),e(t.x)+i.width/2>this._dims.innerW?n.attr("text-anchor","end"):e(t.x)-i.width/2<0?n.attr("text-anchor","start"):n.attr("text-anchor","middle")}_sampleAt(t){const e=this._samples;if(!e||!e.length)return null;if(1===e.length)return e[0];const s=e[0].x,o=e[e.length-1].x,n=Math.max(s,Math.min(o,t)),i=Math.min(Math.max(w(e,n,1),1),e.length-1),l=e[i-1],r=e[i],a=r.x-l.x,h=a>0?(n-l.x)/a:0,c=(t,e)=>t+(e-t)*h;return{x:n,z:c(l.z,r.z),coord:[c(l.coord[0],r.coord[0]),c(l.coord[1],r.coord[1])],slope:r.slope,t:null!=l.t&&null!=r.t?c(l.t,r.t):null}}_focusByCoord(t){const e=this._projectOn(this._samples,t);if(!e)return;const s=this._sampleAt(e.x);s&&(this._setFocus(s),this._marker&&this._marker.setPosition(s.coord))}_clearFocus(){this._focus&&this._focus.style("display","none"),this._marker&&this._marker.setPosition(void 0)}_clear(){this._body.innerHTML="",this._legendEl.innerHTML="",this._legendEl.style.display="none",this._titleEl.textContent=this.options.labels.empty,this._titleEl.removeAttribute("title"),this._statsEl.innerHTML="",this._statsEl.removeAttribute("title"),this._crops=[],this._off=0,this._demLoading=!1,this._updateZoomButtons(),this._clearFocus(),this.element.style.display="none",this._adjustAttribution()}}R.addTheme=(t,e)=>{p[t]=e},R.THEMES=p,R.DEM_PRESETS=z,R.DemSampler=F,R.POSITIONS=u,R.version="2.1.2";export{R as default};
@@ -1,4 +1,4 @@
1
- /*! ol-elevation-profile 2.1.0 | MIT License | https://github.com/lc-4918/ol-elevation-profile */
1
+ /*! ol-elevation-profile 2.1.2 | MIT License | https://github.com/lc-4918/ol-elevation-profile */
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('ol/control/Control.js'), require('ol/Overlay.js'), require('ol/Observable.js'), require('ol/proj.js'), require('ol/TileState.js'), require('ol/sphere.js'), require('ol/extent.js'), require('d3')) :
4
4
  typeof define === 'function' && define.amd ? define(['ol/control/Control.js', 'ol/Overlay.js', 'ol/Observable.js', 'ol/proj.js', 'ol/TileState.js', 'ol/sphere.js', 'ol/extent.js', 'd3'], factory) :
@@ -132,7 +132,8 @@
132
132
  yTicks: null,
133
133
  verticalScale: 'auto', // 'auto' : le profil remplit la hauteur ;
134
134
  // un nombre : mètres par centimètre physique ;
135
- // { exaggeration } : rapport fixe vertical/horizontal
135
+ // { exaggeration } : rapport fixe vertical/horizontal ;
136
+ // { maxExaggeration } : 'auto' sans dépasser ce rapport
136
137
  show: 'click',
137
138
  showWithoutElevation: true, // trace sans Z, et aucun MNT n'a pu en fournir :
138
139
  // le panneau paraît quand même, avec un message
@@ -854,16 +855,22 @@
854
855
  * @property {number} [smoothing=0] Elevation smoothing window, in METERS (0 = none).
855
856
  * @property {?number} [xTicks=null] X axis ticks (null = auto from width).
856
857
  * @property {?number} [yTicks=null] Y axis ticks (null = auto from height).
857
- * @property {('auto'|number|{exaggeration:number})} [verticalScale='auto'] `'auto'`: the
858
+ * @property {('auto'|number|{exaggeration:number}|{maxExaggeration:number})} [verticalScale='auto'] `'auto'`: the
858
859
  * profile fills the height, which is legible but changes scale from one track to the
859
860
  * next, so a 2 % ramp looks like a wall and two profiles cannot be compared. A number
860
861
  * fixes the metres covered per physical centimetre, which makes RANGES comparable.
861
862
  * `{exaggeration}` fixes the ratio between the two axes instead, which makes SLOPES
862
863
  * comparable: the gradient read off the chart is the real one, multiplied by the same
863
864
  * factor on every track, and the control recomputes it per track and per A/B crop.
864
- * Either form is a **floor**, not a cage: a track whose range exceeds what the height
865
- * can show would spill out of the frame, which is worse than losing comparability, so
866
- * the scale then widens silently, nothing being drawn on the chart to say so.
865
+ * `{maxExaggeration}` keeps `'auto'` the height is filled, which reads best and
866
+ * only reins in the absurd: a short, gently sloping track whose 2 % ramp would
867
+ * otherwise be drawn as a wall. A track already under the cap is untouched, so unlike
868
+ * a fixed exaggeration it never flattens a mountain traverse to fit a rule.
869
+ * A number or `{exaggeration}` is a **floor**, not a cage: a track whose range exceeds
870
+ * what the height can show would spill out of the frame, which is worse than losing
871
+ * comparability, so the scale then widens silently, nothing being drawn on the chart
872
+ * to say so. The extra room the scale asks for is added ABOVE the track, never below:
873
+ * centring it would push the axis under sea level on a mountain profile.
867
874
  * @property {'click'|'mouseover'} [show='click'] How a track is selected on the map.
868
875
  * @property {boolean} [showWithoutElevation=true] What to do with a track that ends up
869
876
  * with no elevation at all: none in its geometry, and none the terrain model could
@@ -1523,23 +1530,44 @@
1523
1530
  // La publier partout est le seul moyen de voir la différence plutôt que d'y croire.
1524
1531
  const rapport = (etendue) => (cmH > 0 && etendue > 0) ? (s.distance / cmH) / (etendue / cm) : null;
1525
1532
 
1526
- const vs = this._verticalScaleFor(s, innerW);
1533
+ let vs = this._verticalScaleFor(s, innerW);
1527
1534
  if (!(vs > 0)) {
1528
1535
  // `'auto'` : la hauteur est remplie, donc c'est l'amplitude qui décide de tout.
1529
1536
  // `nice()` arrondit le domaine vers l'extérieur, d'où la lecture APRÈS coup.
1530
1537
  const echelle = d3__namespace.scaleLinear().domain([bas, haut]).range([innerH, 0]).nice();
1531
1538
  const dom = echelle.domain();
1532
- this._vScale = null; // aucune échelle absolue demandée
1533
- this._vExaggeration = rapport(dom[1] - dom[0]);
1534
- return echelle;
1539
+ const obtenu = rapport(dom[1] - dom[0]);
1540
+ // Un PLAFOND d'exagération, s'il en est demandé un. Remplir la hauteur est ce
1541
+ // qui se lit le mieux, mais sur une trace courte et peu accidentée cela dresse
1542
+ // une pente de 2 % en muraille. Le plafond n'intervient que là : quand le
1543
+ // remplissage dépasse le rapport permis, on élargit l'échelle jusqu'à lui. Une
1544
+ // trace assez accidentée pour rester en dessous n'est jamais aplatie, ce qu'une
1545
+ // exagération FIXE lui imposerait — à 680 km d'une traversée, elle n'occuperait
1546
+ // plus qu'un dixième du cadre.
1547
+ const plafond = this._plafondExageration();
1548
+ if (!(plafond > 0) || obtenu == null || obtenu <= plafond) {
1549
+ this._vScale = null; // aucune échelle absolue demandée
1550
+ this._vExaggeration = obtenu;
1551
+ return echelle;
1552
+ }
1553
+ vs = (s.distance / cmH) / plafond; // l'échelle qui donne exactement le plafond
1535
1554
  }
1536
1555
  const etendue = Math.max(vs * cm, haut - bas); // jamais moins qu'il n'en faut
1537
- const milieu = (bas + haut) / 2;
1538
1556
  this._vScale = etendue / cm; // m/cm effectivement appliqués
1539
1557
  // Sous le plancher, le rapport retombe sous celui demandé : c'est la seule façon de
1540
1558
  // savoir que c'est arrivé.
1541
1559
  this._vExaggeration = rapport(etendue);
1542
- return d3__namespace.scaleLinear().domain([milieu - etendue / 2, milieu + etendue / 2]).range([innerH, 0]);
1560
+
1561
+ // La marge que l'échelle impose se place AU-DESSUS, pas de part et d'autre.
1562
+ // Centrer la fenêtre creuse sous la trace : une échelle large - ce que demande
1563
+ // une exagération fixe sur une trace longue - fait alors descendre l'axe sous le
1564
+ // niveau de la mer, et on lit « -900 m » sur un profil de montagne. Le plancher
1565
+ // est donc zéro, ou le point le plus bas de la trace s'il passe dessous : une
1566
+ // dépression existe, une altitude négative inventée, non.
1567
+ const plancher = Math.min(0, bas);
1568
+ let y0 = (bas + haut) / 2 - etendue / 2; // le centrage, quand il tient
1569
+ if (y0 < plancher) y0 = plancher;
1570
+ return d3__namespace.scaleLinear().domain([y0, y0 + etendue]).range([innerH, 0]);
1543
1571
  }
1544
1572
 
1545
1573
  /**
@@ -1557,6 +1585,13 @@
1557
1585
  *
1558
1586
  * @private
1559
1587
  */
1588
+ /** Le rapport à ne pas dépasser, `0` s'il n'en est pas demandé. @private */
1589
+ _plafondExageration() {
1590
+ const v = this.options.verticalScale;
1591
+ const n = (v && typeof v === 'object') ? Number(v.maxExaggeration) : 0;
1592
+ return n > 0 ? n : 0;
1593
+ }
1594
+
1560
1595
  _verticalScaleFor(s, innerW) {
1561
1596
  const v = this.options.verticalScale;
1562
1597
  if (typeof v === 'number') return v;
@@ -1766,7 +1801,9 @@
1766
1801
  this._statsEl.setAttribute('title', text.join(' · '));
1767
1802
 
1768
1803
  this._legendEl.innerHTML = '';
1769
- if (o.slope && o.slopeLegend) {
1804
+ // Une légende de pentes sans altitude ne légende rien : elle annoncerait des
1805
+ // classes qu'aucun trait ne porte, sous un panneau qui dit n'avoir pas de profil.
1806
+ if (o.slope && o.slopeLegend && !sansAltimetrie) {
1770
1807
  const sc = this._slopeScale();
1771
1808
  for (let idx = 0; idx <= sc.maxIdx; idx++) {
1772
1809
  const color = sc.colorByIndex(idx);
@@ -2275,7 +2312,7 @@
2275
2312
  // Stamped at build time from package.json - see rollup.config.mjs, which fails the build
2276
2313
  // if this placeholder ever stops matching. Read from the source rather than the bundle,
2277
2314
  // it says just that: a development copy, of no released version.
2278
- ElevationProfile.version = '2.1.0';
2315
+ ElevationProfile.version = '2.1.2';
2279
2316
 
2280
2317
  return ElevationProfile;
2281
2318
 
@@ -1,4 +1,4 @@
1
- /*! ol-elevation-profile 2.1.0 | MIT License | https://github.com/lc-4918/ol-elevation-profile */
1
+ /*! ol-elevation-profile 2.1.2 | MIT License | https://github.com/lc-4918/ol-elevation-profile */
2
2
  !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e(require("ol/control/Control.js"),require("ol/Overlay.js"),require("ol/Observable.js"),require("ol/proj.js"),require("ol/TileState.js"),require("ol/sphere.js"),require("ol/extent.js"),require("d3")):"function"==typeof define&&define.amd?define(["ol/control/Control.js","ol/Overlay.js","ol/Observable.js","ol/proj.js","ol/TileState.js","ol/sphere.js","ol/extent.js","d3"],e):(t="undefined"!=typeof globalThis?globalThis:t||self).OlElevationProfile=e(t.ol.control.Control,t.ol.Overlay,t.ol.Observable,t.ol.proj,t.ol.TileState,t.ol.sphere,t.ol.extent,t.d3)}(this,function(t,e,s,o,n,i,l,r){"use strict";function a(t){var e=Object.create(null);return t&&Object.keys(t).forEach(function(s){if("default"!==s){var o=Object.getOwnPropertyDescriptor(t,s);Object.defineProperty(e,s,o.get?o:{enumerable:!0,get:function(){return t[s]}})}}),e.default=t,Object.freeze(e)}var h=a(r);
3
3
  /**
4
4
  * Synchronized elevation profile control for OpenLayers, rendered with d3.
@@ -15,4 +15,4 @@
15
15
  *
16
16
  * @module ol-elevation-profile
17
17
  * @license MIT
18
- */const c={steelblue:{area:"#4682b4",line:"#3a6d96",axis:"#555",text:"#222",focus:"#e6550d"},lime:{area:"#9ccc2f",line:"#7da521",axis:"#555",text:"#222",focus:"#d62728"},purple:{area:"#9467bd",line:"#76529c",axis:"#555",text:"#222",focus:"#ff9f1c"},slate:{area:"#7c8a99",line:"#4a5560",axis:"#5a6570",text:"#26303a",focus:"#2f81f7"},graphite:{area:"#9a948c",line:"#5c574f",axis:"#5c574f",text:"#2b2823",focus:"#e07a3f"},amber:{area:"#f0a23b",line:"#c4671a",axis:"#7a5a36",text:"#3a2a16",focus:"#1f6fb2"}},u=["top","bottom","left","right","top-left","top-right","bottom-left","bottom-right"],p={en:{distance:"Distance",elevation:"Elevation",slope:"Slope",ascent:"D+",descent:"D-",empty:"Click a track",noElevation:"No elevation data",untitled:"Profile",time:"Time",duration:"Duration",durationUnits:{s:"sec",m:"min",h:"h",d:"d"},zoomStart:"Set start (A)",zoomEnd:"Set end (B)",zoomAll:"Show all",zoomBack:"Back one level",exportPng:"Export as PNG",collapse:"Collapse the profile",expand:"Expand the profile",loading:"Loading the elevation profile"},fr:{distance:"Distance",elevation:"Altitude",slope:"Pente",ascent:"D+",descent:"D-",empty:"Cliquez un tracé",noElevation:"Aucune altimétrie",untitled:"Profil",time:"Temps",duration:"Durée",durationUnits:{s:"sec",m:"min",h:"h",d:"j"},zoomStart:"Définir le début (A)",zoomEnd:"Définir la fin (B)",zoomAll:"Tout voir",zoomBack:"Revenir au niveau précédent",exportPng:"Exporter en PNG",collapse:"Réduire le profil",expand:"Agrandir le profil",loading:"Chargement du profil altimétrique"},es:{distance:"Distancia",elevation:"Altitud",slope:"Pendiente",ascent:"D+",descent:"D-",empty:"Haga clic en una traza",noElevation:"Sin datos de altitud",untitled:"Perfil",time:"Tiempo",duration:"Duración",durationUnits:{s:"seg",m:"min",h:"h",d:"d"},zoomStart:"Definir el inicio (A)",zoomEnd:"Definir el final (B)",zoomAll:"Ver todo",zoomBack:"Volver al nivel anterior",exportPng:"Exportar como PNG",collapse:"Contraer el perfil",expand:"Desplegar el perfil",loading:"Cargando el perfil de elevación"}},d={immersion:"docked",position:"bottom",width:520,height:180,margins:{unit:"px",top:20,right:24,bottom:30,left:48},units:"meters",dataProjection:null,dem:"terrarium",maxPoints:2e3,smoothing:0,theme:"steelblue",color:null,trackLayer:null,transparency:!1,transparencyLevel:.45,grid:!0,slope:!1,slopeClassSize:2.5,slopeColors:null,slopeSeparators:!0,slopeLegend:!0,maxClasses:8,xTicks:null,yTicks:null,verticalScale:"auto",show:"click",showWithoutElevation:!0,collapsable:!0,collapsed:!1,followMap:!0,marker:!0,hideOnMapClick:!0,responsive:!0,mobileBreakpoint:640,zoom:!1,zoomLevels:3,exportPng:!1,ignoreStops:!0,stopSpeed:.5,tooltipItems:["distance","elevation"],headerItems:["distance","ascent","descent","minmax"],titleProperty:"name",titleLink:null,lang:"en",labels:{}};function m(t,e){return f(p[t]||p.en,e||null)}function f(t,e){const s={};return Object.keys(t).forEach(e=>{s[e]=t[e]}),e&&Object.keys(e).forEach(o=>{e[o]&&"object"==typeof e[o]&&!Array.isArray(e[o])&&t[o]&&"object"==typeof t[o]?s[o]=f(t[o],e[o]):s[o]=e[o]}),s}const _=t=>String(t).replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[t])),g=t=>"string"==typeof t&&/^(https?:)?\/\/|^mailto:/i.test(t);function y(t){if(!t||!t.getCoordinates)return[];const e=t.getCoordinates();switch(t.getType()){case"LineString":case"LinearRing":return[e];case"MultiLineString":return e;case"Polygon":return e.length?[e[0]]:[];case"MultiPolygon":return e.map(t=>t[0]).filter(Boolean);default:return[]}}function x(t,e){const s=t&&t.getProperties?t.getProperties():{};let o=s.coordTimes;null==o&&s.coordinateProperties&&(o=s.coordinateProperties.times||s.coordinateProperties.coordTimes);let n=null;if(Array.isArray(o)&&(n=Array.isArray(o[0])?o.reduce((t,e)=>t.concat(e),[]):o.slice()),!n&&e){const t=[];let s=!1;for(const o of e)for(const e of o){const o=e.length>3?e[3]:null;t.push(o),null!=o&&isFinite(o)&&(s=!0)}n=s?t:null}if(!n)return null;let i=0;const l=n.map(t=>{if(null==t||""===t)return null;const e="number"==typeof t?t>1e12?t:1e3*t:Date.parse(t);return isFinite(e)?(i++,e):null});return i>=2?l:null}function b(t,e,s){let o=t;if("function"==typeof o)try{o=o(e,s)}catch(t){return null}if(Array.isArray(o)&&(o=o[0]),o&&o.getStroke){const t=o.getStroke();if(t)return t.getColor()}return null}const v=(t,e)=>{if("imperial"===e){const e=t/1609.344;return e<.2?`${Math.round(3.28084*t)} ft`:`${e.toFixed(e<10?2:1)} mi`}return t<1e3?`${Math.round(t)} m`:`${(t/1e3).toFixed(t<1e4?2:1)} km`},S=(t,e)=>"imperial"===e?`${Math.round(3.28084*t)} ft`:`${Math.round(t)} m`;const E='<svg viewBox="0 0 24 24"><path d="M5 13h14" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></svg>',M='<svg viewBox="0 0 24 24"><path d="M3 19l5-7 4 4 4-6 5 9z" fill="currentColor" opacity=".85"/></svg>',k=h.bisector(t=>t.x).left,w={terrarium:{url:"https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png",encoding:"terrarium",maxZoom:14,attributions:'Elevation: <a href="https://registry.opendata.aws/terrain-tiles/">Terrain Tiles</a> (AWS Open Data)'},ign:{api:"ign",url:"https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevation.json",resource:"ign_rge_alti_wld",batch:200,minInterval:1100,attributions:'Elevation: <a href="https://geoservices.ign.fr/rgealti">RGE ALTI</a> (IGN)'}};function z(t){const e=Math.max(1,t.batch||200),s=t.minInterval||0;return o=>{const n=[];let i=0;const l=r=>{if(r>=o.length)return Promise.resolve(n);const a=o.slice(r,r+e),h=Math.max(0,s-(Date.now()-i));return new Promise(t=>setTimeout(t,h)).then(()=>(i=Date.now(),fetch(function(t,e){const s=t=>t.toFixed(6),o=t.url.indexOf("?")>=0?"&":"?";let n=t.url+o+"resource="+encodeURIComponent(t.resource)+"&delimiter=|&zonly=true&lon="+e.map(t=>s(t[0])).join("|")+"&lat="+e.map(t=>s(t[1])).join("|");return t.apiKey&&(n+="&"+(t.apiKeyParam||"apikey")+"="+encodeURIComponent(t.apiKey)),n}(t,a)))).then(t=>t&&t.ok?t.json():null).then(t=>{const s=t&&t.elevations;if(!Array.isArray(s)||s.length!==a.length)return null;for(const t of s)n.push(null==t||t<=-99999?null:t);return l(r+e)})};return l(0)}}const C={source:"terrarium",zoom:"auto",maxZoom:14,maxTiles:32,concurrency:6,tileSize:256},P={terrarium:(t,e,s)=>256*t+e+s/256-32768,mapbox:(t,e,s)=>.1*(65536*t+256*e+s)-1e4},T=20037508.342789244;function j(t,e){const s=t.indexOf("?")>=0?"&":"?";return t.replace(/[?&]$/,"")+s+Object.keys(e).map(t=>t+"="+encodeURIComponent(e[t])).join("&")}function A(t,e,s,o,n){const i=Object.assign({SERVICE:"WMS",REQUEST:"GetMap",VERSION:"1.3.0",FORMAT:"image/png",TRANSPARENT:"false",STYLES:""},t.params||{}),l=0===String(i.VERSION).indexOf("1.1")?"SRS":"CRS";return delete i.SRS,delete i.CRS,i[l]=t.projection||"EPSG:3857",i.LAYERS=t.layers,i.WIDTH=n,i.HEIGHT=n,i.BBOX=function(t,e,s){const o=2*T/Math.pow(2,t),n=e*o-T,i=T-s*o;return[n,i-o,n+o,i]}(e,s,o).join(","),j(t.url,i)}function L(t){const e=t.olSource,s=t.band||0;return i=>{const l=e.getTileGrid&&e.getTileGrid();return(l?Promise.resolve(null):Promise.resolve(e.getView?e.getView():null)).then(r=>{const a=l||e.getTileGrid&&e.getTileGrid()||r&&r.tileGrid;if(!a)return null;const h=o.get(r&&r.projection||e.getProjection&&e.getProjection()||"EPSG:3857"),c=a.getResolutions?a.getResolutions().length-1:0,u=e.bandCount||1,p=i.map(t=>o.transform([t[0],t[1]],"EPSG:4326",h)),d=a.getExtent&&a.getExtent()||r&&r.extent||null,m=t=>{const e=a.getResolution(t),s=a.getOrigin(t);let o=a.getTileSize(t);o=Array.isArray(o)?o:[o,o];const n=d?Math.round((d[2]-d[0])/e):1/0,i=d?Math.round((d[3]-d[1])/e):1/0,l=t=>Math.min(n-1,Math.max(0,t)),r=t=>Math.min(i-1,Math.max(0,t)),h=new Map,c=p.map(t=>{const n=(t[0]-s[0])/e-.5,i=(s[1]-t[1])/e-.5,a=l(Math.floor(n)),c=r(Math.floor(i));for(let t=0;t<2;t++)for(let e=0;e<2;e++){const s=Math.floor(l(a+t)/o[0]),n=Math.floor(r(c+e)/o[1]);h.set(s+"/"+n,[s,n])}return{i0:a,j0:c,tx:Math.min(1,Math.max(0,n-a)),ty:Math.min(1,Math.max(0,i-c)),clampI:l,clampJ:r}});return{res:e,origin:s,ts:o,need:h,at:c,clampI:l,clampJ:r}};let f=c,_=m(f);for(;f>0&&_.need.size>t.maxTiles;)f--,_=m(f);if(_.need.size>t.maxTiles)return null;const g=Array.from(_.need.keys());return Promise.all(g.map(t=>{const s=_.need.get(t);return(o=e.getTile(f,s[0],s[1],1,h),new Promise(t=>{const e=()=>{const e=o.getState();return e===n.LOADED?(t(o.getData?o.getData():null),!0):(e===n.ERROR||e===n.EMPTY)&&(t(null),!0)};if(e())return;const s=()=>{e()&&o.removeEventListener("change",s)};o.addEventListener("change",s),o.load&&o.load()})).then(e=>[t,e]);var o})).then(t=>{const e=new Map(t),o=(t,o)=>{const n=Math.floor(_.clampI(t)/_.ts[0]),i=Math.floor(_.clampJ(o)/_.ts[1]);t=_.clampI(t),o=_.clampJ(o);const l=e.get(n+"/"+i);if(!l)return null;const r=t-n*_.ts[0],a=l[((o-i*_.ts[1])*_.ts[0]+r)*u+s];return null!=a&&isFinite(a)?a:null};return _.at.map(t=>{const e=o(t.i0,t.j0),s=o(t.i0+1,t.j0),n=o(t.i0,t.j0+1),i=o(t.i0+1,t.j0+1);if(null==e||null==s||null==n||null==i)return null;const l=e+(s-e)*t.tx;return l+(n+(i-n)*t.tx-l)*t.ty})})})}}function $(t){const e=t.featureInfo,s=Math.max(1,t.concurrency||6);return t=>{const n=new Array(t.length);let i=0,l=!1;const r=()=>{if(l||i>=t.length)return Promise.resolve();const s=i++;return fetch(function(t,e){const s=o.fromLonLat([e[0],e[1]]),n=t.resolution||1,i=Object.assign({SERVICE:"WMS",REQUEST:"GetFeatureInfo",VERSION:"1.3.0",INFO_FORMAT:"application/json",STYLES:"",FEATURE_COUNT:1},t.params||{}),l=0===String(i.VERSION).indexOf("1.1")?"SRS":"CRS";return delete i.SRS,delete i.CRS,i[l]=t.projection||"EPSG:3857",i.LAYERS=t.layers,i.QUERY_LAYERS=t.queryLayers||t.layers,i.WIDTH=1,i.HEIGHT=1,i.I=0,i.J=0,i.X=0,i.Y=0,i.BBOX=[s[0]-n,s[1]-n,s[0]+n,s[1]+n].join(","),j(t.url,i)}(e,t[s])).then(t=>t&&t.ok?t.json():null).then(t=>(n[s]=function(t,e){const s=t&&t.features&&t.features[0],o=s&&s.properties;if(!o)return null;if(e){const t=Number(o[e]);return isFinite(t)?t:null}for(const t of Object.keys(o)){const e=Number(o[t]);if(null!==o[t]&&""!==o[t]&&isFinite(e))return e}return null}(t,e.property),r())).catch(()=>{l=!0})},a=[];for(let e=0;e<Math.min(s,t.length);e++)a.push(r());return Promise.all(a).then(()=>l?null:n)}}class B{constructor(t){this.cfg=t,this.decode="function"==typeof t.encoding?t.encoding:P[t.encoding]||P.terrarium,this.tileUrl=function(t){const e=t.olSource;if(e&&"function"==typeof e.getTileUrlFunction){const t=e.getTileUrlFunction(),s=o.get("EPSG:3857");return(e,o,n)=>t([e,o,n],1,s)}return t.wms?(e,s,o)=>A(t.wms,e,s,o,t.tileSize):(e,s,o)=>t.url.replace("{z}",e).replace("{x}",s).replace("{y}",o)}(t),this.tiles=new Map}_neighbours(t,e,s){const o=function(t,e,s,o){const n=o*Math.pow(2,s),i=Math.sin(e*Math.PI/180);return[(t+180)/360*n,(.5-Math.log((1+i)/(1-i))/(4*Math.PI))*n]}(t,e,s,this.cfg.tileSize),n=o[0]-.5,i=o[1]-.5,l=Math.floor(n),r=Math.floor(i);return{i0:l,j0:r,tx:n-l,ty:i-r}}_key(t,e,s){const o=this.cfg.tileSize,n=o*Math.pow(2,s),i=Math.min(n-1,Math.max(0,e)),l=(t%n+n)%n;return{key:s+"/"+Math.floor(l/o)+"/"+Math.floor(i/o),ii:l,jj:i}}_at(t,e,s){const o=this.cfg.tileSize,n=this._key(t,e,s),i=this.tiles.get(n.key);if(!i)return null;const l=4*(n.jj%o*o+n.ii%o),r=this.decode(i[l],i[l+1],i[l+2],i[l+3]);return null!=r&&isFinite(r)?r:null}sample(t,e,s){const o=this._neighbours(t,e,s),n=this._at(o.i0,o.j0,s),i=this._at(o.i0+1,o.j0,s),l=this._at(o.i0,o.j0+1,s),r=this._at(o.i0+1,o.j0+1,s);if(null==n||null==i||null==l||null==r)return null;const a=n+(i-n)*o.tx;return a+(l+(r-l)*o.tx-a)*o.ty}tilesFor(t,e){const s=new Set;for(const o of t){const t=this._neighbours(o[0],o[1],e);for(let o=0;o<2;o++)for(let n=0;n<2;n++)s.add(this._key(t.i0+o,t.j0+n,e).key)}return s}_fetch(t){const e=t.split("/"),s=this.tileUrl(+e[0],+e[1],+e[2]);return new Promise(t=>{const e=new Image;e.crossOrigin="anonymous",e.onload=()=>{try{const s=this.cfg.tileSize,o=document.createElement("canvas");o.width=s,o.height=s;const n=o.getContext("2d",{willReadFrequently:!0});n.drawImage(e,0,0,s,s),t(n.getImageData(0,0,s,s).data)}catch(e){t(null)}},e.onerror=()=>t(null),e.src=s})}load(t){const e=Array.from(t).filter(t=>!this.tiles.has(t));let s=0,o=!0;const n=()=>{if(s>=e.length)return Promise.resolve();const t=e[s++];return this._fetch(t).then(e=>(this.tiles.set(t,e),e||(o=!1),n()))},i=[];for(let t=0;t<Math.min(this.cfg.concurrency,e.length);t++)i.push(n());return Promise.all(i).then(()=>o)}}class F extends t{constructor(t){const e=f(d,t||{});-1===u.indexOf(e.position)&&(e.position="bottom");const s=e.labels;e.labels=m(e.lang,s);const o=function(t){const e=document.createElement("div");return e.className=`ol-elevation-profile ol-unselectable ol-control oep-pos-${t.position} oep-theme-${"string"==typeof t.theme?t.theme:"custom"}`+("floating"===t.immersion?" oep-floating":""),e}(e);super({element:o,target:t&&t.target}),this.options=e,this._userLabels=s,this.slopeColors=e.slopeColors||null,this._feature=null,this._fullSamples=null,this._fullStats=null,this._samples=null,this._stats=null,this._marker=null,this._collapsed=!!e.collapsed,this._crops=[],this._off=0,this._zoomA=null,this._zoomB=null,this._armed=null,this._demZ=null,this._demFor=null,this._demSeq=0,this._demLoading=!1,this._trackLines=null,this._linesFor=null,this._onResize=()=>{this._feature&&!this._collapsed&&this._render()},this._buildDom(o),o.style.display="none"}get _cropMode(){return this._crops.length>0}get _cropDepth(){return this._crops.length}get _cropMax(){const t=this.options.zoomLevels;return null==t?3:Math.max(1,0|t)}static featureHasZ(t){const e=t&&t.getGeometry&&t.getGeometry();if(!e)return!1;for(const t of y(e))for(const e of t)if(e.length>2&&isFinite(e[2]))return!0;return!1}static featureHasTime(t){const e=t&&t.getGeometry&&t.getGeometry();return!!e&&!!x(t,y(e))}_buildDom(t){const e=this.options;this._applyTheme(),this._applyTransparency();const s=document.createElement("div");s.className="oep-header",this._titleEl=document.createElement("span"),this._titleEl.className="oep-title",this._titleEl.textContent=e.labels.empty,this._statsEl=document.createElement("span"),this._statsEl.className="oep-stats",s.appendChild(this._titleEl),s.appendChild(this._statsEl),this._toolbar=document.createElement("span"),this._toolbar.className="oep-toolbar";const o=(t,e,s,o)=>{const n=document.createElement("button");return n.type="button",n.className=`oep-tbtn ${t}`,n.innerHTML=e,n.title=s,n.setAttribute("aria-label",s),n.addEventListener("click",o),this._toolbar.appendChild(n),n};this._btnA=o("oep-a",'<svg viewBox="0 0 24 24"><path d="M7 5v14M11 12h8m0 0-3-3m3 3-3 3" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.zoomStart,()=>this._arm("A")),this._btnB=o("oep-b",'<svg viewBox="0 0 24 24"><path d="M17 5v14M13 12H5m0 0 3-3m-3 3 3 3" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.zoomEnd,()=>this._arm("B")),this._btnBack=o("oep-back",'<svg viewBox="0 0 24 24"><path d="M10 6 4 12l6 6M4 12h10a6 6 0 0 1 6 6" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.zoomBack,()=>this._popCrop()),this._btnAll=o("oep-all",'<svg viewBox="0 0 24 24"><path d="M4 12h16M4 12l4-4M4 12l4 4M20 12l-4-4M20 12l-4 4" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.zoomAll,()=>this._exitZoom()),this._btnPng=o("oep-png",'<svg viewBox="0 0 24 24"><path d="M12 4v10m0 0 4-4m-4 4-4-4M5 18h14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.exportPng,()=>this.exportPNG()),s.appendChild(this._toolbar);const n=document.createElement("button");n.className="oep-toggle",n.type="button",n.innerHTML=this._collapsed?M:E,n.addEventListener("click",()=>this.toggleCollapsed()),s.appendChild(n),this._toggleBtn=n,this._applyToggleLabel(),this._legendEl=document.createElement("div"),this._legendEl.className="oep-legend",this._legendEl.style.display="none",this._body=document.createElement("div"),this._body.className="oep-body",t.appendChild(s),t.appendChild(this._legendEl),t.appendChild(this._body),this._applyCollapsable(),this._updateZoomButtons(),this._collapsed&&t.classList.add("oep-collapsed")}_applyLabels(){const t=this.options.labels,e=(t,e)=>{t&&e&&(t.title=e,t.setAttribute("aria-label",e))};e(this._btnA,t.zoomStart),e(this._btnB,t.zoomEnd),e(this._btnBack,t.zoomBack),e(this._btnAll,t.zoomAll),e(this._btnPng,t.exportPng),this._applyToggleLabel(),this._titleEl&&!this._feature&&(this._titleEl.textContent=t.empty)}_applyToggleLabel(){const t=this.options.labels,e=this._collapsed?t.expand:t.collapse;this._toggleBtn&&e&&(this._toggleBtn.title=e,this._toggleBtn.setAttribute("aria-label",e))}_resolveColor(){const t=this.options;return t.color?"auto"===t.color?this._featureColor():t.color:null}_featureColor(){const t=this._feature;if(!t)return null;const e=this.getMap()?this.getMap().getView().getResolution():1;let s=b(t.getStyle&&t.getStyle(),t,e);return!s&&this.options.trackLayer&&(s=b(this.options.trackLayer.getStyle&&this.options.trackLayer.getStyle(),t,e)),function(t){if(null==t)return null;if("string"==typeof t)return t;if(Array.isArray(t)){const e=t.length>3?t[3]:1;return`rgba(${0|t[0]},${0|t[1]},${0|t[2]},${e})`}return null}(s)}_applyTheme(){const t=this.options,e="object"==typeof t.theme?t.theme:c[t.theme]||c.steelblue;this.themeColors=e;const s=this.element,o=this._resolveColor(),n=o||e.area;let i=e.line;if(o)try{i=String(h.color(o).darker(.7))}catch(t){i=o}s.style.setProperty("--oep-area",n),s.style.setProperty("--oep-line",i),s.style.setProperty("--oep-axis",e.axis),s.style.setProperty("--oep-text",e.text),s.style.setProperty("--oep-focus",e.focus)}_applyTransparency(){const t=this.options.transparency;let e;e=!1===t||null==t?1:!0===t?this.options.transparencyLevel:Math.max(0,Math.min(1,+t)),this.element.style.setProperty("--oep-bg",`rgba(255,255,255,${e})`),this.element.classList.toggle("oep-transparent",e<1)}_applyCollapsable(){const t=this.options.collapsable;this._toggleBtn.style.display=t?"":"none",!t&&this._collapsed&&this.toggleCollapsed(!1)}toggleCollapsed(t){this._collapsed="boolean"==typeof t?t:!this._collapsed,this.element.classList.toggle("oep-collapsed",this._collapsed),this._toggleBtn.innerHTML=this._collapsed?M:E,this._applyToggleLabel(),!this._collapsed&&this._feature&&this._render(),this._adjustAttribution()}_availWidth(){const t=this.getMap(),e=t&&t.getTargetElement&&t.getTargetElement();return e&&e.clientWidth||("undefined"!=typeof window?window.innerWidth:1024)}_isMobile(){return this.options.responsive&&"undefined"!=typeof window&&window.innerWidth<=(this.options.mobileBreakpoint||640)}_applyPlacement(){const t=this._isMobile();let e=this.options.position;return t&&(e=/top/.test(e)?"top":"bottom"),this.element.className=this.element.className.replace(/oep-pos-\S+/,`oep-pos-${e}`),this.element.classList.toggle("oep-mobile",t),t}_adjustAttribution(){const t=this.getMap(),e=t&&t.getTargetElement&&t.getTargetElement(),s=e&&e.querySelector&&e.querySelector(".ol-attribution");if(!s)return;if(s.style.bottom="",s.style.right="","none"===this.element.style.display||this._collapsed)return;const o=e.getBoundingClientRect(),n=this.element.getBoundingClientRect();if(!n.height)return;const i=o.bottom-n.bottom,l=o.right-n.right;i<n.height&&l<24&&(s.style.right=`${Math.max(0,Math.round(l))}px`,s.style.bottom=`${Math.round(n.height+2*i)}px`)}setMap(t){const o=this.getMap();if(super.setMap(t),this._mapKeys&&(this._mapKeys.forEach(s.unByKey),this._mapKeys=null),o&&"undefined"!=typeof window&&window.removeEventListener("resize",this._onResize),this._marker&&!t&&this._marker.setPosition(void 0),!t)return;const n=this.options;if(n.dataProjection||(n.dataProjection=t.getView().getProjection()),n.marker&&!this._marker){const s=document.createElement("div");s.className="oep-marker",this._marker=new e({element:s,positioning:"center-center",stopEvent:!1}),t.addOverlay(this._marker)}"undefined"!=typeof window&&window.addEventListener("resize",this._onResize);const i=e=>t.forEachFeatureAtPixel(e,t=>{const e=t.getGeometry();return(s=e)&&/^(Multi)?(LineString|Polygon)$|^LinearRing$/.test(s.getType())?t:void 0;var s});this._mapKeys=[],this._mapKeys.push(t.on("click",t=>{const e=i(t.pixel);"mouseover"!==this.options.show&&e&&e!==this._feature&&this.setFeature(e),this.options.hideOnMapClick&&!e&&this._feature&&this.clear()})),this._mapKeys.push(t.on("pointermove",e=>{if("mouseover"===this.options.show){const t=i(e.pixel);t&&t!==this._feature&&this.setFeature(t)}if(!this.options.followMap||!this._feature||this._collapsed)return;const s=this._closestOnProfile(e.coordinate);if(!s)return;const o=t.getPixelFromCoordinate(s);o&&(Math.hypot(o[0]-e.pixel[0],o[1]-e.pixel[1])<14?this._focusByCoord(s):this._clearFocus())})),this._mapKeys.push(t.on("moveend",()=>{const e=this._crops[this._crops.length-1];e&&e.fitRes&&t.getView().getResolution()>1.25*e.fitRes&&this._popCrop()})),this._mapKeys.push(t.on("change:size",this._onResize))}setFeature(t){return this._feature=t||null,this._crops=[],this._off=0,this._zoomA=null,this._zoomB=null,this._armed=null,t?(this.element.style.display="",this._compute(),this._fillFromDem(t),this._updateZoomButtons(),this._collapsed?this._renderTitle():this._render(),this):(this._fullSamples=this._samples=null,this._demZ=this._demFor=null,this._trackLines=this._linesFor=null,this._clear(),this)}clear(){return this.setFeature(null)}getStats(){return this._stats}setTheme(t){return this.options.theme=t,this._applyTheme(),this._feature&&!this._collapsed&&this._render(),this}setColor(t){return this.options.color=t||null,this._applyTheme(),this._feature&&!this._collapsed&&this._render(),this}setOptions(t){return this.options=f(this.options,t||{}),t&&"slopeColors"in t&&(this.slopeColors=t.slopeColors||null),t&&(t.theme||"color"in t)&&this._applyTheme(),t&&("transparency"in t||"transparencyLevel"in t)&&this._applyTransparency(),t&&"collapsable"in t&&this._applyCollapsable(),t&&"labels"in t&&(this._userLabels=f(this._userLabels||{},t.labels)),t&&("lang"in t||"labels"in t)&&(this.options.labels=m(this.options.lang,this._userLabels),this._applyLabels()),t&&("zoom"in t||"exportPng"in t)&&this._updateZoomButtons(),t&&void 0!==t.width&&"number"==typeof t.width&&(this.options.width=t.width),t&&"dem"in t&&(this._demZ=null,this._demFor=null,this._trackLines=null,this._linesFor=null),this._feature&&(this._compute(),this._fillFromDem(this._feature),this._updateZoomButtons(),this._collapsed?this._renderTitle():this._render()),this}_fillFromDem(t){const e=function(t){if(!t)return null;if("function"==typeof t)return Object.assign({},C,{sample:t});const e=!0===t||"string"==typeof t?{source:!0===t?"terrarium":t}:Object.assign({},t);if("function"==typeof e.sample)return Object.assign({},C,e);if(e.track){const t=Object.assign({},C,e);return t.track=Object.assign({coords:"coords",parse:null,fetchOptions:null},"string"==typeof e.track?{url:e.track}:e.track),t.track.url?t:null}if(e.featureInfo){const t=Object.assign({},C,e);return t.sample=$(t),t}if(e.olSource&&"function"!=typeof e.olSource.getTileUrlFunction&&"function"==typeof e.olSource.getTile){const t=Object.assign({},C,e);return t.sample=L(t),t}const s=e.url||e.wms||e.olSource,o=w[e.source]||(s?{}:w.terrarium),n=Object.assign({},C,o,e);return"ign"===n.api?(n.sample=z(n),n):n.url||n.wms||n.olSource?n:null}(this.options.dem);if(!e||!t||this._demFor===t||this._linesFor===t)return;if(F.featureHasZ(t))return;if(!e.sample&&("undefined"==typeof Image||"undefined"==typeof document))return;const s=t.getGeometry&&t.getGeometry(),n=s?y(s):[],i=this.options.dataProjection||this.getMap()&&this.getMap().getView().getProjection()||"EPSG:3857",l=[];for(const t of n)for(const e of t)l.push(o.toLonLat(e,i));if(!l.length&&!e.track)return;const r=++this._demSeq;this._demLoading=!0;try{this._startFill(e,r,t,l,i)}catch(e){this._demDone(r,t,null,l.length,null,0)}}_startFill(t,e,s,o,n){if(t.track)return void this._startTrackFill(t,e,s,o.length,n);if(t.sample)return void Promise.resolve().then(()=>t.sample(o,{feature:s,projection:n})).then(t=>this._demDone(e,s,t,o.length,null,0)).catch(()=>this._demDone(e,s,null,o.length,null,0));const i=new B(t),l=function(t,e,s){if("number"==typeof s.zoom)return s.zoom;for(let o=s.maxZoom;o>0;o--)if(t.tilesFor(e,o).size<=s.maxTiles)return o;return 1}(i,o,t);i.load(i.tilesFor(o,l)).then(t=>{const n=t?o.map(t=>i.sample(t[0],t[1],l)):null;this._demDone(e,s,n,o.length,l,i.tiles.size)}).catch(()=>this._demDone(e,s,null,o.length,l,0))}_startTrackFill(t,e,s,o,n){const i=function(t,e){if("function"==typeof t)return t(e)||null;if("string"!=typeof t||!e)return null;let s=!0;const o=t.replace(/\{(\w+)\}/g,(t,o)=>{const n=e.get(o);return null==n||""===n?(s=!1,""):encodeURIComponent(String(n))});return s?o:null}(t.track.url,s);i?Promise.resolve().then(()=>fetch(i,t.track.fetchOptions||void 0)).then(t=>{if(!t.ok)throw new Error(String(t.status));return t.json()}).then(i=>{const l=t.track.parse?t.track.parse(i,s):Array.isArray(i)?i:i&&i[t.track.coords];this._trackDone(e,s,l,o,n)}).catch(()=>this._demDone(e,s,null,o,null,0)):this._demDone(e,s,null,o,null,0)}_trackDone(t,e,s,n,i){const l=()=>this._demDone(t,e,null,n,null,0);if(!Array.isArray(s)||!s.length)return l();if("number"==typeof s[0])return void this._demDone(t,e,s,n,null,0);if(t!==this._demSeq||this._feature!==e)return;const r=t=>null!=t&&isFinite(t),a=[];for(const t of s){if(!t||t.length<3||!r(t[0])||!r(t[1])||!r(t[2]))return l();const e=o.transform([t[0],t[1]],"EPSG:4326",i);a.push([e[0],e[1],t[2]])}if(a.length<2)return l();this._demLoading=!1,this._trackLines=[a],this._linesFor=e,this._demZ=null,this._demFor=null,this._compute(),this._updateZoomButtons(),this._collapsed||this._render(),this.dispatchEvent({type:"demload",ok:!0,zoom:null,tiles:0})}_demDone(t,e,s,o,n,i){if(t!==this._demSeq||this._feature!==e)return;const l=Array.isArray(s)&&s.length===o&&s.every(t=>null!=t&&isFinite(t));this._demLoading=!1,l&&(this._demZ=s,this._demFor=e,this._compute()),this._updateZoomButtons(),this._collapsed||this._render(),this.dispatchEvent({type:"demload",ok:l,zoom:n,tiles:i})}_compute(){const t=this.options,e=this._linesFor===this._feature&&this._trackLines,s=this._feature.getGeometry&&this._feature.getGeometry(),n=e?this._trackLines:s?y(s):[],l=t.dataProjection||this.getMap()&&this.getMap().getView().getProjection()||"EPSG:3857",r=this._demFor===this._feature?this._demZ:null,a=e?null:x(this._feature,n);this._hasTime=!!a;const h=!1!==t.ignoreStops,c=null!=t.stopSpeed?t.stopSpeed:.5,u=[];let p=0,d=null,m=-1,f=0,_=null;for(const t of n)for(const e of t){m++;const t=o.toLonLat(e,l);let s=0;d&&(s=i.getDistance(d,t),p+=s);let n=null;if(a&&null!=a[m]){const t=a[m];if(null!=_){const e=(t-_)/1e3;e>0&&(!h||s/e>=c)&&(f+=e)}n=f,_=t}d=t;const g=e.length>2&&isFinite(e[2])?e[2]:r?r[m]:0;u.push({x:p,z:g,coord:e,t:n})}t.smoothing>0&&this._smooth(u,t.smoothing);const g=this._decimate(u,t.maxPoints);this._addSlope(g),this._fullSamples=g,this._fullStats=this._statsOf(g,!0),this._applyCrops()}_pxPerCm(){try{const t=document.createElement("div");t.style.cssText="position:absolute;left:-9999px;top:0;width:1cm;height:1cm",(this.element||document.body).appendChild(t);const e=t.getBoundingClientRect().height;if(t.remove(),e>0)return e}catch(t){}return 96/2.54}_yScale(t,e,s,o){const n=t.min-e,i=t.max+e,l=s/this._pxPerCm(),r=o/this._pxPerCm(),a=e=>r>0&&e>0?t.distance/r/(e/l):null,c=this._verticalScaleFor(t,o);if(!(c>0)){const t=h.scaleLinear().domain([n,i]).range([s,0]).nice(),e=t.domain();return this._vScale=null,this._vExaggeration=a(e[1]-e[0]),t}const u=Math.max(c*l,i-n),p=(n+i)/2;return this._vScale=u/l,this._vExaggeration=a(u),h.scaleLinear().domain([p-u/2,p+u/2]).range([s,0])}_verticalScaleFor(t,e){const s=this.options.verticalScale;if("number"==typeof s)return s;const o=s&&"object"==typeof s?Number(s.exaggeration):0;if(!(o>0&&t.distance>0&&e>0))return 0;const n=e/this._pxPerCm();return t.distance/n/o}_statsOf(t,e){let s=0,o=0,n=1/0,i=-1/0,l=0;for(let e=0;e<t.length;e++){const r=t[e].z;if(r<n&&(n=r),r>i&&(i=r),e>0){const n=r-t[e-1].z;n>0?s+=n:o-=n}const a=Math.abs(t[e].slope||0);a>l&&(l=a)}const r=t.length?t[t.length-1].x-t[0].x:0,a=t.length?t[0].t:null,h=t.length?t[t.length-1].t:null;return{distance:r,duration:null!=a&&null!=h?h-a:null,ascent:s,descent:o,min:isFinite(n)?n:0,max:isFinite(i)?i:0,maxAbsSlope:l,points:t.length}}_smooth(t,e){if(!(e>0)||t.length<3)return;const s=e/2,o=t.map(t=>t.z);let n=0,i=0,l=0;for(let e=0;e<t.length;e++){const r=t[e].x;for(;n<t.length&&t[n].x<r-s;)l-=o[n],n++;for(;i<t.length&&t[i].x<=r+s;)l+=o[i],i++;t[e].z=i>n?l/(i-n):o[e]}}_decimate(t,e){const s=t=>({x:t.x,z:t.z,coord:t.coord,t:t.t});if(!e||t.length<=e)return t.map(s);const o=t.length/e,n=[];for(let i=0;i<e;i++)n.push(s(t[Math.floor(i*o)]));return n.push(s(t[t.length-1])),n}_addSlope(t){for(let e=1;e<t.length;e++){const s=t[e].x-t[e-1].x;t[e].slope=s>0?(t[e].z-t[e-1].z)/s*100:0}t.length&&(t[0].slope=t.length>1?t[1].slope:0)}_slopeScale(){const t=this.options.slopeClassSize||2.5,e=this.options.maxClasses||8,s=Math.max(1,Math.floor((this._stats.maxAbsSlope||0)/t)),o=Math.min(s,e-1),n=s>o;let i;if(this.slopeColors&&this.slopeColors.length){const t=h.interpolateRgbBasis(this.slopeColors);i=e=>t(o?e/o:0)}else{const t=h.scaleLinear().domain([0,.16,.42,.68,1]).range(["#2166ac","#27a35a","#ffe000","#f4791f","#d7191c"]).interpolate(h.interpolateRgb).clamp(!0);i=e=>String(t(o?e/o:0))}return{classSize:t,maxIdx:o,capped:n,colorByIndex:i}}_classIndex(t,e){return Math.min(e.maxIdx,Math.floor(Math.abs(t)/e.classSize))}_fmtDuration(t){if(null==t||!isFinite(t))return"";const e=this.options.labels&&this.options.labels.durationUnits||p.en.durationUnits;if((t=Math.max(0,Math.round(t)))<60)return t+" "+e.s;if(t<3600)return Math.round(t/60)+" "+e.m;if(t<86400){let s=Math.floor(t/3600),o=Math.round(t%3600/60);return 60===o&&(s++,o=0),o?`${s} ${e.h} ${o} ${e.m}`:`${s} ${e.h}`}let s=Math.floor(t/86400),o=Math.round(t%86400/3600);return 24===o&&(s++,o=0),o?`${s} ${e.d} ${o} ${e.h}`:`${s} ${e.d}`}_hasElevation(){const t=this._feature;return!!t&&(!!F.featureHasZ(t)||(!(this._demFor!==t||!this._demZ)||!(this._linesFor!==t||!this._trackLines)))}_renderNoElevation(){if(!this.options.showWithoutElevation)return void(this.element.style.display="none");this.element.style.display="",this._applyTheme(),this._applyPlacement(),this._renderHeader(!0);const t="number"==typeof this.options.height?this.options.height:180;this._body.innerHTML="";const e=document.createElement("div");e.className="oep-noelev",e.style.height=`${t}px`,e.setAttribute("role","status"),e.textContent=this.options.labels.noElevation,this._body.appendChild(e),this._clearFocus()}_pickProperty(t,e,s){if(!e||!t||!t.get)return null;for(const o of Array.isArray(e)?e:[e]){const e=t.get(o);if(null!=e&&""!==e&&(!s||s(e)))return e}return null}_renderTitle(){const t=this.options,e=this._feature;if(!e)return;const s=this._pickProperty(e,t.titleProperty)||t.labels.untitled,o=this._pickProperty(e,t.titleLink,g);g(o)?this._titleEl.innerHTML=`<a href="${_(o)}" target="_blank" rel="noopener">${_(s)}</a>`:this._titleEl.textContent=s,this._titleEl.setAttribute("title",s)}_renderHeader(t){const e=this.options,s=this._stats,o=this._feature;if(this._renderTitle(),this._demLoading)return this._statsEl.innerHTML="",this._statsEl.removeAttribute("title"),this._legendEl.innerHTML="",void(this._legendEl.style.display="none");const n=[],i=[];if(e.headerItems.forEach(l=>{if("string"==typeof l){if(t&&("ascent"===l||"descent"===l||"min"===l||"max"===l||"minmax"===l))return;if("distance"===l){if(!(s&&s.distance>0))return;n.push(`<b>${v(s.distance,e.units)}</b>`),i.push(v(s.distance,e.units))}else if("ascent"===l)n.push(`<span class="oep-up">${e.labels.ascent} ${S(s.ascent,e.units)}</span>`),i.push(`${e.labels.ascent} ${S(s.ascent,e.units)}`);else if("descent"===l)n.push(`<span class="oep-down">${e.labels.descent} ${S(s.descent,e.units)}</span>`),i.push(`${e.labels.descent} ${S(s.descent,e.units)}`);else if("min"===l)n.push(S(s.min,e.units)),i.push(S(s.min,e.units));else if("max"===l)n.push(S(s.max,e.units)),i.push(S(s.max,e.units));else if("minmax"===l){const t=`${S(s.min,e.units)}-${S(s.max,e.units)}`;n.push(t),i.push(t)}else if("duration"===l&&null!=s.duration){const t=this._fmtDuration(s.duration);n.push(`<span class="oep-time">${_(e.labels.duration)} ${t}</span>`),i.push(`${e.labels.duration} ${t}`)}}else if(l&&l.property){const t=o.get&&o.get(l.property);if(null==t||""===t)return;const e=l.label?`${l.label} `:"";l.asLink&&g(t)?(n.push(`${e}<a href="${_(t)}" target="_blank" rel="noopener">${_(l.linkText||l.label||t)}</a>`),i.push(`${l.label||""} ${t}`)):(n.push(_(e+t)),i.push(e+t))}}),this._statsEl.innerHTML=n.join(" · "),this._statsEl.setAttribute("title",i.join(" · ")),this._legendEl.innerHTML="",e.slope&&e.slopeLegend){const t=this._slopeScale();for(let e=0;e<=t.maxIdx;e++){const s=t.colorByIndex(e),o=t.capped&&e===t.maxIdx?`≥ ${e*t.classSize} %`:`${e*t.classSize}-${(e+1)*t.classSize} %`,n=document.createElement("span");n.className="oep-leg-it",n.innerHTML=`<i class="oep-sw" style="background:${s}"></i>${o}`,this._legendEl.appendChild(n)}this._legendEl.style.display=""}else this._legendEl.style.display="none"}_renderSpinner(){const t="number"==typeof this.options.height?this.options.height:180;this._body.innerHTML="";const e=document.createElement("div");e.className="oep-loading",e.style.height=`${t}px`,e.setAttribute("role","status"),e.setAttribute("aria-label",this.options.labels.loading);const s=document.createElement("div");s.className="oep-spinner",e.appendChild(s),this._body.appendChild(e)}_render(){const t=this.options,e=this._stats,s=this._samples;if(!this._demLoading&&!this._hasElevation())return void this._renderNoElevation();if(!s||!s.length)return;this._applyTheme();const o=this._applyPlacement();if(this._renderHeader(),this._demLoading)return void this._renderSpinner();const n=t.margins,i=n.unit||"px",l=t=>"px"===i?t:t*(parseFloat(getComputedStyle(this.element).fontSize)||16),r=this._availWidth(),a="auto"===t.width||"100%"===t.width||"full"===t.width?r:Math.min("number"==typeof t.width?t.width:parseFloat(t.width)||r,r);this.element.style.width=o?"":`${a}px`;const c=this.element.clientWidth||(o?r:a),u=Math.max(220,c-16),p="number"==typeof t.height?t.height:180,d=l(n.top),m=l(n.right),f=l(n.bottom),_=l(n.left),g=Math.max(10,u-_-m),y=Math.max(10,p-d-f),x=null!=t.xTicks?t.xTicks:Math.max(2,Math.round(g/80)),b=null!=t.yTicks?t.yTicks:Math.max(2,Math.round(y/40));this._body.innerHTML="";const v=h.select(this._body).append("svg").attr("class","oep-svg").attr("width",u).attr("height",p).attr("viewBox",`0 0 ${u} ${p}`),S=v.append("g").attr("transform",`translate(${_},${d})`),E=h.scaleLinear().domain([0,e.distance]).range([0,g]),M=.1*(e.max-e.min)||10,k=this._yScale(e,M,y,g);this._x=E,this._y=k,this._dims={innerW:g,innerH:y},t.grid&&S.append("g").attr("class","oep-grid").call(h.axisLeft(k).ticks(b).tickSize(-g).tickFormat(""));const w="imperial"===t.units?1609.344:1e3;const z=h.area().x(t=>E(t.x)).y0(y).y1(t=>k(t.z));if(t.slope){const e=this._slopeScale(),o=[];let n=1;for(;n<s.length;){const t=this._classIndex(s[n].slope,e);let i=n;for(;i+1<s.length&&this._classIndex(s[i+1].slope,e)===t;)i++;S.append("path").datum(s.slice(n-1,i+1)).attr("class","oep-area-slope").attr("fill",e.colorByIndex(t)).attr("d",z),n>1&&o.push(s[n-1]),n=i+1}t.slopeSeparators&&o.forEach(t=>{S.append("line").attr("class","oep-slope-sep").attr("x1",E(t.x)).attr("x2",E(t.x)).attr("y1",k(t.z)).attr("y2",y)})}else S.append("path").datum(s).attr("class","oep-area").attr("d",z);S.append("path").datum(s).attr("class","oep-line").attr("d",h.line().x(t=>E(t.x)).y(t=>k(t.z))),S.append("g").attr("class","oep-axis oep-axis-x").attr("transform",`translate(0,${y})`).call(h.axisBottom(E).ticks(x).tickFormat(t=>(t/w).toFixed(t/w<10?1:0))),S.append("text").attr("class","oep-axis-label").attr("x",g).attr("y",y+f-4).attr("text-anchor","end").text((t=>"imperial"===t?"mi":"km")(t.units)),S.append("g").attr("class","oep-axis oep-axis-y").call(h.axisLeft(k).ticks(b).tickFormat(e=>"imperial"===t.units?Math.round(3.28084*e):e)),t.zoom&&this._cropDepth<this._cropMax&&[["A",this._zoomA],["B",this._zoomB]].forEach(([t,e])=>{if(null==e)return;const s=E(e);S.append("line").attr("class","oep-ab-line").attr("x1",s).attr("x2",s).attr("y1",0).attr("y2",y),S.append("text").attr("class","oep-ab-label").attr("x",s).attr("y",-6).attr("text-anchor","middle").text(t)});const C=S.append("g").attr("class","oep-focus").style("display","none");C.append("line").attr("class","oep-focus-line").attr("y1",0).attr("y2",y),C.append("circle").attr("class","oep-focus-dot").attr("r",4);const P=C.append("g").attr("class","oep-focus-label");P.append("rect").attr("class","oep-focus-bg"),P.append("text").attr("class","oep-focus-txt"),this._focus=C;const T=t=>{const s=h.pointer(t,S.node())[0];return Math.max(0,Math.min(e.distance,E.invert(s)))},j=v.append("rect").attr("class","oep-overlay").attr("x",_).attr("y",d).attr("width",g).attr("height",y);j.on("mousemove",t=>{const e=this._sampleAt(T(t));e&&(this._setFocus(e),this._marker&&this._marker.setPosition(e.coord))}).on("mouseout",()=>this._clearFocus()),j.on("click",t=>this._placeBound(T(t))),this._armed&&j.style("cursor","col-resize"),this._adjustAttribution()}static get _EXPORT_PROPS(){return["fill","fill-opacity","stroke","stroke-width","stroke-dasharray","stroke-linecap","stroke-linejoin","opacity","font-family","font-size","font-weight","text-anchor","shape-rendering"]}_freezeStyles(t,e){const s=F._EXPORT_PROPS,o=getComputedStyle(t);let n="";for(const t of s){const e=o.getPropertyValue(t);e&&(n+=`${t}:${e};`)}e.setAttribute("style",n);const i=t.children,l=e.children;for(let t=0;t<i.length&&t<l.length;t++)this._freezeStyles(i[t],l[t])}_exportSvg(){const t=this._body.querySelector("svg");if(!t)return null;const e=getComputedStyle(this.element),s=e.getPropertyValue("--oep-bg").trim()||"#fff",o=e.getPropertyValue("--oep-text").trim()||"#222",n=e.fontFamily||"system-ui, sans-serif",i=+t.getAttribute("width"),l=+t.getAttribute("height"),r=this._statsEl.textContent?15:0,a="none"!==this._legendEl.style.display?this._legendEl:null,h=28+r+(a?18:0),c=t.cloneNode(!0);c.querySelectorAll(".oep-focus, .oep-overlay").forEach(t=>t.remove()),this._freezeStyles(t,c);const u=t=>_(String(t)),p=[];if(p.push(`<rect width="${i+16}" height="${l+h+8}" fill="${u(s)}"/>`),p.push(`<text x="8" y="21" style="font-family:${u(n)};font-size:13px;font-weight:600;fill:${u(o)}">${u(this._titleEl.textContent)}</text>`),r&&p.push(`<text x="8" y="38" style="font-family:${u(n)};font-size:11px;fill:${u(o)};opacity:.85">${u(this._statsEl.textContent)}</text>`),a){let t=8;const e=28+r+12;for(const s of a.querySelectorAll(".oep-leg-it")){const i=s.querySelector(".oep-sw"),l=i?getComputedStyle(i).backgroundColor:"none",r=s.textContent.trim();p.push(`<rect x="${t}" y="${e-8}" width="10" height="10" fill="${u(l)}"/>`),p.push(`<text x="${t+14}" y="${e}" style="font-family:${u(n)};font-size:10px;fill:${u(o)}">${u(r)}</text>`),t+=14+5.6*r.length+10}}return p.push(`<g transform="translate(8,${h})">${(new XMLSerializer).serializeToString(c)}</g>`),{width:i+16,height:l+h+8,svg:`<svg xmlns="http://www.w3.org/2000/svg" width="${i+16}" height="${l+h+8}" viewBox="0 0 ${i+16} ${l+h+8}">${p.join("")}</svg>`}}exportPNG(t){const e=t||{},s=this._exportSvg();if(!s)return Promise.reject(new Error("ol-elevation-profile: nothing to export"));const o=e.scale||"undefined"!=typeof window&&window.devicePixelRatio||1;return new Promise((t,n)=>{const i=new Image;i.onload=()=>{try{const l=document.createElement("canvas");l.width=Math.round(s.width*o),l.height=Math.round(s.height*o);const r=l.getContext("2d");r.scale(o,o),r.drawImage(i,0,0),l.toBlob(s=>{s?(!1!==e.download&&this._save(s,e.filename),t(s)):n(new Error("ol-elevation-profile: PNG encoding failed"))},"image/png")}catch(t){n(t)}},i.onerror=()=>n(new Error("ol-elevation-profile: SVG could not be rasterised")),i.src="data:image/svg+xml;charset=utf-8,"+encodeURIComponent(s.svg)})}_save(t,e){const s=e||`${(this._titleEl.textContent||"profile").replace(/[\\/:*?"<>|]+/g,"-").trim()}.png`,o=URL.createObjectURL(t),n=document.createElement("a");n.href=o,n.download=s,document.body.appendChild(n),n.click(),n.remove(),setTimeout(()=>URL.revokeObjectURL(o),1e3)}_arm(t){this._armed=this._armed===t?null:t,this._updateZoomButtons(),this._focus&&this._render()}_placeBound(t){if(!this._armed||this._cropDepth>=this._cropMax)return;const e="A"===this._armed?"B":"A";"A"===this._armed?this._zoomA=t:this._zoomB=t;const s=null!=this._zoomA&&null!=this._zoomB;this._armed=s?null:e,this._updateZoomButtons(),s?this._pushCrop(this._zoomA,this._zoomB):this._render()}_updateZoomButtons(){const t=this.options,e=!!this._feature,s=!!t.zoom&&e,o=!!t.exportPng&&e;this._toolbar.style.display=s||o?"":"none",this._btnPng.style.display=o?"":"none";const n=this._cropDepth,i=n<this._cropMax;this._btnA.style.display=s&&i?"":"none",this._btnB.style.display=s&&i?"":"none",this._btnBack.style.display=s&&n>1?"":"none",this._btnAll.style.display=s&&n>0?"":"none",this._btnA.classList.toggle("armed","A"===this._armed),this._btnB.classList.toggle("armed","B"===this._armed)}_applyCrops(){if(!this._crops.length)return this._off=0,this._samples=this._fullSamples,this._stats=this._fullStats,null;const{a:t,b:e}=this._crops[this._crops.length-1],s=this._fullSamples.filter(s=>s.x>=t&&s.x<=e);if(s.length<2)return this._crops.pop(),this._applyCrops();const o=s[0].x,n=null!=s[0].t?s[0].t:0;return this._off=o,this._samples=s.map(t=>({x:t.x-o,z:t.z,coord:t.coord,slope:t.slope,t:null!=t.t?t.t-n:null})),this._stats=this._statsOf(this._samples,!1),s.map(t=>t.coord)}_fitMap(t){const e=this.getMap();if(!e)return null;let s=null;if(t&&t.length?s=l.boundingExtent(t):this._feature&&(s=this._feature.getGeometry().getExtent()),!s)return null;const o=e.getView();let n=null;try{n=o.getResolutionForExtent(s,e.getSize())}catch(t){n=null}return o.fit(s,{padding:[40,40,40,40],duration:400}),n}_pushCrop(t,e){if(this._zoomA=null,this._zoomB=null,this._armed=null,this._cropDepth>=this._cropMax)return this._updateZoomButtons(),void this._render();const s=this._off+Math.min(t,e),o=this._off+Math.max(t,e);let n=0;for(let t=0;t<this._fullSamples.length;t++){const e=this._fullSamples[t].x;e>=s&&e<=o&&n++}if(n<2)return this._updateZoomButtons(),void this._render();this._crops.push({a:s,b:o,fitRes:null});const i=this._applyCrops();this._updateZoomButtons(),this._render();const l=this._crops[this._crops.length-1];l&&(l.fitRes=this._fitMap(i))}_applyZoom(){null!=this._zoomA&&null!=this._zoomB&&this._pushCrop(this._zoomA,this._zoomB)}_popCrop(){if(!this._crops.length)return;this._crops.pop(),this._zoomA=null,this._zoomB=null,this._armed=null;const t=this._applyCrops();this._updateZoomButtons(),this._collapsed||this._render(),this._fitMap(t)}_exitZoom(){this._crops.length=0,this._zoomA=null,this._zoomB=null,this._armed=null,this._applyCrops(),this._updateZoomButtons(),this._collapsed||this._render(),this._fitMap(null)}_closestOnProfile(t){const e=this._feature&&this._feature.getGeometry();if(!e)return null;if(!/Polygon/.test(e.getType()))return e.getClosestPoint(t);const s=this._projectOn(this._fullSamples,t);return s?s.coord:null}_projectOn(t,e){if(!t||!t.length)return null;if(1===t.length)return{x:t[0].x,coord:t[0].coord.slice(0,2)};let s=null,o=1/0;for(let n=1;n<t.length;n++){const i=t[n-1].coord,l=t[n].coord,r=l[0]-i[0],a=l[1]-i[1],h=r*r+a*a;let c=h>0?((e[0]-i[0])*r+(e[1]-i[1])*a)/h:0;c=c<0?0:c>1?1:c;const u=i[0]+r*c,p=i[1]+a*c,d=u-e[0],m=p-e[1],f=d*d+m*m;f<o&&(o=f,s={x:t[n-1].x+(t[n].x-t[n-1].x)*c,coord:[u,p]})}return s}_tooltipText(t){const e=this.options,s=[];return e.tooltipItems.forEach(o=>{var n;"distance"===o?s.push(v(t.x,e.units)):"elevation"===o?s.push(S(t.z,e.units)):"slope"===o?s.push(`${(n=t.slope||0)>=0?"+":""}${n.toFixed(1)} %`):"time"===o&&null!=t.t&&s.push(this._fmtDuration(t.t))}),s.join(" · ")}_setFocus(t){if(!this._focus)return;const e=this._x,s=this._y;this._focus.style("display",null),this._focus.select(".oep-focus-line").attr("x1",e(t.x)).attr("x2",e(t.x)),this._focus.select(".oep-focus-dot").attr("cx",e(t.x)).attr("cy",s(t.z));let o=s(t.z)-16;o<12&&(o=s(t.z)+22);const n=this._focus.select(".oep-focus-txt").attr("x",e(t.x)).attr("y",o).text(this._tooltipText(t)),i=n.node().getBBox();this._focus.select(".oep-focus-bg").attr("x",i.x-4).attr("y",i.y-2).attr("width",i.width+8).attr("height",i.height+4),e(t.x)+i.width/2>this._dims.innerW?n.attr("text-anchor","end"):e(t.x)-i.width/2<0?n.attr("text-anchor","start"):n.attr("text-anchor","middle")}_sampleAt(t){const e=this._samples;if(!e||!e.length)return null;if(1===e.length)return e[0];const s=e[0].x,o=e[e.length-1].x,n=Math.max(s,Math.min(o,t)),i=Math.min(Math.max(k(e,n,1),1),e.length-1),l=e[i-1],r=e[i],a=r.x-l.x,h=a>0?(n-l.x)/a:0,c=(t,e)=>t+(e-t)*h;return{x:n,z:c(l.z,r.z),coord:[c(l.coord[0],r.coord[0]),c(l.coord[1],r.coord[1])],slope:r.slope,t:null!=l.t&&null!=r.t?c(l.t,r.t):null}}_focusByCoord(t){const e=this._projectOn(this._samples,t);if(!e)return;const s=this._sampleAt(e.x);s&&(this._setFocus(s),this._marker&&this._marker.setPosition(s.coord))}_clearFocus(){this._focus&&this._focus.style("display","none"),this._marker&&this._marker.setPosition(void 0)}_clear(){this._body.innerHTML="",this._legendEl.innerHTML="",this._legendEl.style.display="none",this._titleEl.textContent=this.options.labels.empty,this._titleEl.removeAttribute("title"),this._statsEl.innerHTML="",this._statsEl.removeAttribute("title"),this._crops=[],this._off=0,this._demLoading=!1,this._updateZoomButtons(),this._clearFocus(),this.element.style.display="none",this._adjustAttribution()}}return F.addTheme=(t,e)=>{c[t]=e},F.THEMES=c,F.DEM_PRESETS=w,F.DemSampler=B,F.POSITIONS=u,F.version="2.1.0",F});
18
+ */const c={steelblue:{area:"#4682b4",line:"#3a6d96",axis:"#555",text:"#222",focus:"#e6550d"},lime:{area:"#9ccc2f",line:"#7da521",axis:"#555",text:"#222",focus:"#d62728"},purple:{area:"#9467bd",line:"#76529c",axis:"#555",text:"#222",focus:"#ff9f1c"},slate:{area:"#7c8a99",line:"#4a5560",axis:"#5a6570",text:"#26303a",focus:"#2f81f7"},graphite:{area:"#9a948c",line:"#5c574f",axis:"#5c574f",text:"#2b2823",focus:"#e07a3f"},amber:{area:"#f0a23b",line:"#c4671a",axis:"#7a5a36",text:"#3a2a16",focus:"#1f6fb2"}},u=["top","bottom","left","right","top-left","top-right","bottom-left","bottom-right"],p={en:{distance:"Distance",elevation:"Elevation",slope:"Slope",ascent:"D+",descent:"D-",empty:"Click a track",noElevation:"No elevation data",untitled:"Profile",time:"Time",duration:"Duration",durationUnits:{s:"sec",m:"min",h:"h",d:"d"},zoomStart:"Set start (A)",zoomEnd:"Set end (B)",zoomAll:"Show all",zoomBack:"Back one level",exportPng:"Export as PNG",collapse:"Collapse the profile",expand:"Expand the profile",loading:"Loading the elevation profile"},fr:{distance:"Distance",elevation:"Altitude",slope:"Pente",ascent:"D+",descent:"D-",empty:"Cliquez un tracé",noElevation:"Aucune altimétrie",untitled:"Profil",time:"Temps",duration:"Durée",durationUnits:{s:"sec",m:"min",h:"h",d:"j"},zoomStart:"Définir le début (A)",zoomEnd:"Définir la fin (B)",zoomAll:"Tout voir",zoomBack:"Revenir au niveau précédent",exportPng:"Exporter en PNG",collapse:"Réduire le profil",expand:"Agrandir le profil",loading:"Chargement du profil altimétrique"},es:{distance:"Distancia",elevation:"Altitud",slope:"Pendiente",ascent:"D+",descent:"D-",empty:"Haga clic en una traza",noElevation:"Sin datos de altitud",untitled:"Perfil",time:"Tiempo",duration:"Duración",durationUnits:{s:"seg",m:"min",h:"h",d:"d"},zoomStart:"Definir el inicio (A)",zoomEnd:"Definir el final (B)",zoomAll:"Ver todo",zoomBack:"Volver al nivel anterior",exportPng:"Exportar como PNG",collapse:"Contraer el perfil",expand:"Desplegar el perfil",loading:"Cargando el perfil de elevación"}},d={immersion:"docked",position:"bottom",width:520,height:180,margins:{unit:"px",top:20,right:24,bottom:30,left:48},units:"meters",dataProjection:null,dem:"terrarium",maxPoints:2e3,smoothing:0,theme:"steelblue",color:null,trackLayer:null,transparency:!1,transparencyLevel:.45,grid:!0,slope:!1,slopeClassSize:2.5,slopeColors:null,slopeSeparators:!0,slopeLegend:!0,maxClasses:8,xTicks:null,yTicks:null,verticalScale:"auto",show:"click",showWithoutElevation:!0,collapsable:!0,collapsed:!1,followMap:!0,marker:!0,hideOnMapClick:!0,responsive:!0,mobileBreakpoint:640,zoom:!1,zoomLevels:3,exportPng:!1,ignoreStops:!0,stopSpeed:.5,tooltipItems:["distance","elevation"],headerItems:["distance","ascent","descent","minmax"],titleProperty:"name",titleLink:null,lang:"en",labels:{}};function m(t,e){return f(p[t]||p.en,e||null)}function f(t,e){const s={};return Object.keys(t).forEach(e=>{s[e]=t[e]}),e&&Object.keys(e).forEach(o=>{e[o]&&"object"==typeof e[o]&&!Array.isArray(e[o])&&t[o]&&"object"==typeof t[o]?s[o]=f(t[o],e[o]):s[o]=e[o]}),s}const _=t=>String(t).replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"}[t])),g=t=>"string"==typeof t&&/^(https?:)?\/\/|^mailto:/i.test(t);function y(t){if(!t||!t.getCoordinates)return[];const e=t.getCoordinates();switch(t.getType()){case"LineString":case"LinearRing":return[e];case"MultiLineString":return e;case"Polygon":return e.length?[e[0]]:[];case"MultiPolygon":return e.map(t=>t[0]).filter(Boolean);default:return[]}}function x(t,e){const s=t&&t.getProperties?t.getProperties():{};let o=s.coordTimes;null==o&&s.coordinateProperties&&(o=s.coordinateProperties.times||s.coordinateProperties.coordTimes);let n=null;if(Array.isArray(o)&&(n=Array.isArray(o[0])?o.reduce((t,e)=>t.concat(e),[]):o.slice()),!n&&e){const t=[];let s=!1;for(const o of e)for(const e of o){const o=e.length>3?e[3]:null;t.push(o),null!=o&&isFinite(o)&&(s=!0)}n=s?t:null}if(!n)return null;let i=0;const l=n.map(t=>{if(null==t||""===t)return null;const e="number"==typeof t?t>1e12?t:1e3*t:Date.parse(t);return isFinite(e)?(i++,e):null});return i>=2?l:null}function b(t,e,s){let o=t;if("function"==typeof o)try{o=o(e,s)}catch(t){return null}if(Array.isArray(o)&&(o=o[0]),o&&o.getStroke){const t=o.getStroke();if(t)return t.getColor()}return null}const v=(t,e)=>{if("imperial"===e){const e=t/1609.344;return e<.2?`${Math.round(3.28084*t)} ft`:`${e.toFixed(e<10?2:1)} mi`}return t<1e3?`${Math.round(t)} m`:`${(t/1e3).toFixed(t<1e4?2:1)} km`},S=(t,e)=>"imperial"===e?`${Math.round(3.28084*t)} ft`:`${Math.round(t)} m`;const E='<svg viewBox="0 0 24 24"><path d="M5 13h14" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></svg>',M='<svg viewBox="0 0 24 24"><path d="M3 19l5-7 4 4 4-6 5 9z" fill="currentColor" opacity=".85"/></svg>',k=h.bisector(t=>t.x).left,w={terrarium:{url:"https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png",encoding:"terrarium",maxZoom:14,attributions:'Elevation: <a href="https://registry.opendata.aws/terrain-tiles/">Terrain Tiles</a> (AWS Open Data)'},ign:{api:"ign",url:"https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevation.json",resource:"ign_rge_alti_wld",batch:200,minInterval:1100,attributions:'Elevation: <a href="https://geoservices.ign.fr/rgealti">RGE ALTI</a> (IGN)'}};function z(t){const e=Math.max(1,t.batch||200),s=t.minInterval||0;return o=>{const n=[];let i=0;const l=r=>{if(r>=o.length)return Promise.resolve(n);const a=o.slice(r,r+e),h=Math.max(0,s-(Date.now()-i));return new Promise(t=>setTimeout(t,h)).then(()=>(i=Date.now(),fetch(function(t,e){const s=t=>t.toFixed(6),o=t.url.indexOf("?")>=0?"&":"?";let n=t.url+o+"resource="+encodeURIComponent(t.resource)+"&delimiter=|&zonly=true&lon="+e.map(t=>s(t[0])).join("|")+"&lat="+e.map(t=>s(t[1])).join("|");return t.apiKey&&(n+="&"+(t.apiKeyParam||"apikey")+"="+encodeURIComponent(t.apiKey)),n}(t,a)))).then(t=>t&&t.ok?t.json():null).then(t=>{const s=t&&t.elevations;if(!Array.isArray(s)||s.length!==a.length)return null;for(const t of s)n.push(null==t||t<=-99999?null:t);return l(r+e)})};return l(0)}}const C={source:"terrarium",zoom:"auto",maxZoom:14,maxTiles:32,concurrency:6,tileSize:256},P={terrarium:(t,e,s)=>256*t+e+s/256-32768,mapbox:(t,e,s)=>.1*(65536*t+256*e+s)-1e4},T=20037508.342789244;function j(t,e){const s=t.indexOf("?")>=0?"&":"?";return t.replace(/[?&]$/,"")+s+Object.keys(e).map(t=>t+"="+encodeURIComponent(e[t])).join("&")}function A(t,e,s,o,n){const i=Object.assign({SERVICE:"WMS",REQUEST:"GetMap",VERSION:"1.3.0",FORMAT:"image/png",TRANSPARENT:"false",STYLES:""},t.params||{}),l=0===String(i.VERSION).indexOf("1.1")?"SRS":"CRS";return delete i.SRS,delete i.CRS,i[l]=t.projection||"EPSG:3857",i.LAYERS=t.layers,i.WIDTH=n,i.HEIGHT=n,i.BBOX=function(t,e,s){const o=2*T/Math.pow(2,t),n=e*o-T,i=T-s*o;return[n,i-o,n+o,i]}(e,s,o).join(","),j(t.url,i)}function L(t){const e=t.olSource,s=t.band||0;return i=>{const l=e.getTileGrid&&e.getTileGrid();return(l?Promise.resolve(null):Promise.resolve(e.getView?e.getView():null)).then(r=>{const a=l||e.getTileGrid&&e.getTileGrid()||r&&r.tileGrid;if(!a)return null;const h=o.get(r&&r.projection||e.getProjection&&e.getProjection()||"EPSG:3857"),c=a.getResolutions?a.getResolutions().length-1:0,u=e.bandCount||1,p=i.map(t=>o.transform([t[0],t[1]],"EPSG:4326",h)),d=a.getExtent&&a.getExtent()||r&&r.extent||null,m=t=>{const e=a.getResolution(t),s=a.getOrigin(t);let o=a.getTileSize(t);o=Array.isArray(o)?o:[o,o];const n=d?Math.round((d[2]-d[0])/e):1/0,i=d?Math.round((d[3]-d[1])/e):1/0,l=t=>Math.min(n-1,Math.max(0,t)),r=t=>Math.min(i-1,Math.max(0,t)),h=new Map,c=p.map(t=>{const n=(t[0]-s[0])/e-.5,i=(s[1]-t[1])/e-.5,a=l(Math.floor(n)),c=r(Math.floor(i));for(let t=0;t<2;t++)for(let e=0;e<2;e++){const s=Math.floor(l(a+t)/o[0]),n=Math.floor(r(c+e)/o[1]);h.set(s+"/"+n,[s,n])}return{i0:a,j0:c,tx:Math.min(1,Math.max(0,n-a)),ty:Math.min(1,Math.max(0,i-c)),clampI:l,clampJ:r}});return{res:e,origin:s,ts:o,need:h,at:c,clampI:l,clampJ:r}};let f=c,_=m(f);for(;f>0&&_.need.size>t.maxTiles;)f--,_=m(f);if(_.need.size>t.maxTiles)return null;const g=Array.from(_.need.keys());return Promise.all(g.map(t=>{const s=_.need.get(t);return(o=e.getTile(f,s[0],s[1],1,h),new Promise(t=>{const e=()=>{const e=o.getState();return e===n.LOADED?(t(o.getData?o.getData():null),!0):(e===n.ERROR||e===n.EMPTY)&&(t(null),!0)};if(e())return;const s=()=>{e()&&o.removeEventListener("change",s)};o.addEventListener("change",s),o.load&&o.load()})).then(e=>[t,e]);var o})).then(t=>{const e=new Map(t),o=(t,o)=>{const n=Math.floor(_.clampI(t)/_.ts[0]),i=Math.floor(_.clampJ(o)/_.ts[1]);t=_.clampI(t),o=_.clampJ(o);const l=e.get(n+"/"+i);if(!l)return null;const r=t-n*_.ts[0],a=l[((o-i*_.ts[1])*_.ts[0]+r)*u+s];return null!=a&&isFinite(a)?a:null};return _.at.map(t=>{const e=o(t.i0,t.j0),s=o(t.i0+1,t.j0),n=o(t.i0,t.j0+1),i=o(t.i0+1,t.j0+1);if(null==e||null==s||null==n||null==i)return null;const l=e+(s-e)*t.tx;return l+(n+(i-n)*t.tx-l)*t.ty})})})}}function $(t){const e=t.featureInfo,s=Math.max(1,t.concurrency||6);return t=>{const n=new Array(t.length);let i=0,l=!1;const r=()=>{if(l||i>=t.length)return Promise.resolve();const s=i++;return fetch(function(t,e){const s=o.fromLonLat([e[0],e[1]]),n=t.resolution||1,i=Object.assign({SERVICE:"WMS",REQUEST:"GetFeatureInfo",VERSION:"1.3.0",INFO_FORMAT:"application/json",STYLES:"",FEATURE_COUNT:1},t.params||{}),l=0===String(i.VERSION).indexOf("1.1")?"SRS":"CRS";return delete i.SRS,delete i.CRS,i[l]=t.projection||"EPSG:3857",i.LAYERS=t.layers,i.QUERY_LAYERS=t.queryLayers||t.layers,i.WIDTH=1,i.HEIGHT=1,i.I=0,i.J=0,i.X=0,i.Y=0,i.BBOX=[s[0]-n,s[1]-n,s[0]+n,s[1]+n].join(","),j(t.url,i)}(e,t[s])).then(t=>t&&t.ok?t.json():null).then(t=>(n[s]=function(t,e){const s=t&&t.features&&t.features[0],o=s&&s.properties;if(!o)return null;if(e){const t=Number(o[e]);return isFinite(t)?t:null}for(const t of Object.keys(o)){const e=Number(o[t]);if(null!==o[t]&&""!==o[t]&&isFinite(e))return e}return null}(t,e.property),r())).catch(()=>{l=!0})},a=[];for(let e=0;e<Math.min(s,t.length);e++)a.push(r());return Promise.all(a).then(()=>l?null:n)}}class B{constructor(t){this.cfg=t,this.decode="function"==typeof t.encoding?t.encoding:P[t.encoding]||P.terrarium,this.tileUrl=function(t){const e=t.olSource;if(e&&"function"==typeof e.getTileUrlFunction){const t=e.getTileUrlFunction(),s=o.get("EPSG:3857");return(e,o,n)=>t([e,o,n],1,s)}return t.wms?(e,s,o)=>A(t.wms,e,s,o,t.tileSize):(e,s,o)=>t.url.replace("{z}",e).replace("{x}",s).replace("{y}",o)}(t),this.tiles=new Map}_neighbours(t,e,s){const o=function(t,e,s,o){const n=o*Math.pow(2,s),i=Math.sin(e*Math.PI/180);return[(t+180)/360*n,(.5-Math.log((1+i)/(1-i))/(4*Math.PI))*n]}(t,e,s,this.cfg.tileSize),n=o[0]-.5,i=o[1]-.5,l=Math.floor(n),r=Math.floor(i);return{i0:l,j0:r,tx:n-l,ty:i-r}}_key(t,e,s){const o=this.cfg.tileSize,n=o*Math.pow(2,s),i=Math.min(n-1,Math.max(0,e)),l=(t%n+n)%n;return{key:s+"/"+Math.floor(l/o)+"/"+Math.floor(i/o),ii:l,jj:i}}_at(t,e,s){const o=this.cfg.tileSize,n=this._key(t,e,s),i=this.tiles.get(n.key);if(!i)return null;const l=4*(n.jj%o*o+n.ii%o),r=this.decode(i[l],i[l+1],i[l+2],i[l+3]);return null!=r&&isFinite(r)?r:null}sample(t,e,s){const o=this._neighbours(t,e,s),n=this._at(o.i0,o.j0,s),i=this._at(o.i0+1,o.j0,s),l=this._at(o.i0,o.j0+1,s),r=this._at(o.i0+1,o.j0+1,s);if(null==n||null==i||null==l||null==r)return null;const a=n+(i-n)*o.tx;return a+(l+(r-l)*o.tx-a)*o.ty}tilesFor(t,e){const s=new Set;for(const o of t){const t=this._neighbours(o[0],o[1],e);for(let o=0;o<2;o++)for(let n=0;n<2;n++)s.add(this._key(t.i0+o,t.j0+n,e).key)}return s}_fetch(t){const e=t.split("/"),s=this.tileUrl(+e[0],+e[1],+e[2]);return new Promise(t=>{const e=new Image;e.crossOrigin="anonymous",e.onload=()=>{try{const s=this.cfg.tileSize,o=document.createElement("canvas");o.width=s,o.height=s;const n=o.getContext("2d",{willReadFrequently:!0});n.drawImage(e,0,0,s,s),t(n.getImageData(0,0,s,s).data)}catch(e){t(null)}},e.onerror=()=>t(null),e.src=s})}load(t){const e=Array.from(t).filter(t=>!this.tiles.has(t));let s=0,o=!0;const n=()=>{if(s>=e.length)return Promise.resolve();const t=e[s++];return this._fetch(t).then(e=>(this.tiles.set(t,e),e||(o=!1),n()))},i=[];for(let t=0;t<Math.min(this.cfg.concurrency,e.length);t++)i.push(n());return Promise.all(i).then(()=>o)}}class F extends t{constructor(t){const e=f(d,t||{});-1===u.indexOf(e.position)&&(e.position="bottom");const s=e.labels;e.labels=m(e.lang,s);const o=function(t){const e=document.createElement("div");return e.className=`ol-elevation-profile ol-unselectable ol-control oep-pos-${t.position} oep-theme-${"string"==typeof t.theme?t.theme:"custom"}`+("floating"===t.immersion?" oep-floating":""),e}(e);super({element:o,target:t&&t.target}),this.options=e,this._userLabels=s,this.slopeColors=e.slopeColors||null,this._feature=null,this._fullSamples=null,this._fullStats=null,this._samples=null,this._stats=null,this._marker=null,this._collapsed=!!e.collapsed,this._crops=[],this._off=0,this._zoomA=null,this._zoomB=null,this._armed=null,this._demZ=null,this._demFor=null,this._demSeq=0,this._demLoading=!1,this._trackLines=null,this._linesFor=null,this._onResize=()=>{this._feature&&!this._collapsed&&this._render()},this._buildDom(o),o.style.display="none"}get _cropMode(){return this._crops.length>0}get _cropDepth(){return this._crops.length}get _cropMax(){const t=this.options.zoomLevels;return null==t?3:Math.max(1,0|t)}static featureHasZ(t){const e=t&&t.getGeometry&&t.getGeometry();if(!e)return!1;for(const t of y(e))for(const e of t)if(e.length>2&&isFinite(e[2]))return!0;return!1}static featureHasTime(t){const e=t&&t.getGeometry&&t.getGeometry();return!!e&&!!x(t,y(e))}_buildDom(t){const e=this.options;this._applyTheme(),this._applyTransparency();const s=document.createElement("div");s.className="oep-header",this._titleEl=document.createElement("span"),this._titleEl.className="oep-title",this._titleEl.textContent=e.labels.empty,this._statsEl=document.createElement("span"),this._statsEl.className="oep-stats",s.appendChild(this._titleEl),s.appendChild(this._statsEl),this._toolbar=document.createElement("span"),this._toolbar.className="oep-toolbar";const o=(t,e,s,o)=>{const n=document.createElement("button");return n.type="button",n.className=`oep-tbtn ${t}`,n.innerHTML=e,n.title=s,n.setAttribute("aria-label",s),n.addEventListener("click",o),this._toolbar.appendChild(n),n};this._btnA=o("oep-a",'<svg viewBox="0 0 24 24"><path d="M7 5v14M11 12h8m0 0-3-3m3 3-3 3" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.zoomStart,()=>this._arm("A")),this._btnB=o("oep-b",'<svg viewBox="0 0 24 24"><path d="M17 5v14M13 12H5m0 0 3-3m-3 3 3 3" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.zoomEnd,()=>this._arm("B")),this._btnBack=o("oep-back",'<svg viewBox="0 0 24 24"><path d="M10 6 4 12l6 6M4 12h10a6 6 0 0 1 6 6" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.zoomBack,()=>this._popCrop()),this._btnAll=o("oep-all",'<svg viewBox="0 0 24 24"><path d="M4 12h16M4 12l4-4M4 12l4 4M20 12l-4-4M20 12l-4 4" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.zoomAll,()=>this._exitZoom()),this._btnPng=o("oep-png",'<svg viewBox="0 0 24 24"><path d="M12 4v10m0 0 4-4m-4 4-4-4M5 18h14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>',e.labels.exportPng,()=>this.exportPNG()),s.appendChild(this._toolbar);const n=document.createElement("button");n.className="oep-toggle",n.type="button",n.innerHTML=this._collapsed?M:E,n.addEventListener("click",()=>this.toggleCollapsed()),s.appendChild(n),this._toggleBtn=n,this._applyToggleLabel(),this._legendEl=document.createElement("div"),this._legendEl.className="oep-legend",this._legendEl.style.display="none",this._body=document.createElement("div"),this._body.className="oep-body",t.appendChild(s),t.appendChild(this._legendEl),t.appendChild(this._body),this._applyCollapsable(),this._updateZoomButtons(),this._collapsed&&t.classList.add("oep-collapsed")}_applyLabels(){const t=this.options.labels,e=(t,e)=>{t&&e&&(t.title=e,t.setAttribute("aria-label",e))};e(this._btnA,t.zoomStart),e(this._btnB,t.zoomEnd),e(this._btnBack,t.zoomBack),e(this._btnAll,t.zoomAll),e(this._btnPng,t.exportPng),this._applyToggleLabel(),this._titleEl&&!this._feature&&(this._titleEl.textContent=t.empty)}_applyToggleLabel(){const t=this.options.labels,e=this._collapsed?t.expand:t.collapse;this._toggleBtn&&e&&(this._toggleBtn.title=e,this._toggleBtn.setAttribute("aria-label",e))}_resolveColor(){const t=this.options;return t.color?"auto"===t.color?this._featureColor():t.color:null}_featureColor(){const t=this._feature;if(!t)return null;const e=this.getMap()?this.getMap().getView().getResolution():1;let s=b(t.getStyle&&t.getStyle(),t,e);return!s&&this.options.trackLayer&&(s=b(this.options.trackLayer.getStyle&&this.options.trackLayer.getStyle(),t,e)),function(t){if(null==t)return null;if("string"==typeof t)return t;if(Array.isArray(t)){const e=t.length>3?t[3]:1;return`rgba(${0|t[0]},${0|t[1]},${0|t[2]},${e})`}return null}(s)}_applyTheme(){const t=this.options,e="object"==typeof t.theme?t.theme:c[t.theme]||c.steelblue;this.themeColors=e;const s=this.element,o=this._resolveColor(),n=o||e.area;let i=e.line;if(o)try{i=String(h.color(o).darker(.7))}catch(t){i=o}s.style.setProperty("--oep-area",n),s.style.setProperty("--oep-line",i),s.style.setProperty("--oep-axis",e.axis),s.style.setProperty("--oep-text",e.text),s.style.setProperty("--oep-focus",e.focus)}_applyTransparency(){const t=this.options.transparency;let e;e=!1===t||null==t?1:!0===t?this.options.transparencyLevel:Math.max(0,Math.min(1,+t)),this.element.style.setProperty("--oep-bg",`rgba(255,255,255,${e})`),this.element.classList.toggle("oep-transparent",e<1)}_applyCollapsable(){const t=this.options.collapsable;this._toggleBtn.style.display=t?"":"none",!t&&this._collapsed&&this.toggleCollapsed(!1)}toggleCollapsed(t){this._collapsed="boolean"==typeof t?t:!this._collapsed,this.element.classList.toggle("oep-collapsed",this._collapsed),this._toggleBtn.innerHTML=this._collapsed?M:E,this._applyToggleLabel(),!this._collapsed&&this._feature&&this._render(),this._adjustAttribution()}_availWidth(){const t=this.getMap(),e=t&&t.getTargetElement&&t.getTargetElement();return e&&e.clientWidth||("undefined"!=typeof window?window.innerWidth:1024)}_isMobile(){return this.options.responsive&&"undefined"!=typeof window&&window.innerWidth<=(this.options.mobileBreakpoint||640)}_applyPlacement(){const t=this._isMobile();let e=this.options.position;return t&&(e=/top/.test(e)?"top":"bottom"),this.element.className=this.element.className.replace(/oep-pos-\S+/,`oep-pos-${e}`),this.element.classList.toggle("oep-mobile",t),t}_adjustAttribution(){const t=this.getMap(),e=t&&t.getTargetElement&&t.getTargetElement(),s=e&&e.querySelector&&e.querySelector(".ol-attribution");if(!s)return;if(s.style.bottom="",s.style.right="","none"===this.element.style.display||this._collapsed)return;const o=e.getBoundingClientRect(),n=this.element.getBoundingClientRect();if(!n.height)return;const i=o.bottom-n.bottom,l=o.right-n.right;i<n.height&&l<24&&(s.style.right=`${Math.max(0,Math.round(l))}px`,s.style.bottom=`${Math.round(n.height+2*i)}px`)}setMap(t){const o=this.getMap();if(super.setMap(t),this._mapKeys&&(this._mapKeys.forEach(s.unByKey),this._mapKeys=null),o&&"undefined"!=typeof window&&window.removeEventListener("resize",this._onResize),this._marker&&!t&&this._marker.setPosition(void 0),!t)return;const n=this.options;if(n.dataProjection||(n.dataProjection=t.getView().getProjection()),n.marker&&!this._marker){const s=document.createElement("div");s.className="oep-marker",this._marker=new e({element:s,positioning:"center-center",stopEvent:!1}),t.addOverlay(this._marker)}"undefined"!=typeof window&&window.addEventListener("resize",this._onResize);const i=e=>t.forEachFeatureAtPixel(e,t=>{const e=t.getGeometry();return(s=e)&&/^(Multi)?(LineString|Polygon)$|^LinearRing$/.test(s.getType())?t:void 0;var s});this._mapKeys=[],this._mapKeys.push(t.on("click",t=>{const e=i(t.pixel);"mouseover"!==this.options.show&&e&&e!==this._feature&&this.setFeature(e),this.options.hideOnMapClick&&!e&&this._feature&&this.clear()})),this._mapKeys.push(t.on("pointermove",e=>{if("mouseover"===this.options.show){const t=i(e.pixel);t&&t!==this._feature&&this.setFeature(t)}if(!this.options.followMap||!this._feature||this._collapsed)return;const s=this._closestOnProfile(e.coordinate);if(!s)return;const o=t.getPixelFromCoordinate(s);o&&(Math.hypot(o[0]-e.pixel[0],o[1]-e.pixel[1])<14?this._focusByCoord(s):this._clearFocus())})),this._mapKeys.push(t.on("moveend",()=>{const e=this._crops[this._crops.length-1];e&&e.fitRes&&t.getView().getResolution()>1.25*e.fitRes&&this._popCrop()})),this._mapKeys.push(t.on("change:size",this._onResize))}setFeature(t){return this._feature=t||null,this._crops=[],this._off=0,this._zoomA=null,this._zoomB=null,this._armed=null,t?(this.element.style.display="",this._compute(),this._fillFromDem(t),this._updateZoomButtons(),this._collapsed?this._renderTitle():this._render(),this):(this._fullSamples=this._samples=null,this._demZ=this._demFor=null,this._trackLines=this._linesFor=null,this._clear(),this)}clear(){return this.setFeature(null)}getStats(){return this._stats}setTheme(t){return this.options.theme=t,this._applyTheme(),this._feature&&!this._collapsed&&this._render(),this}setColor(t){return this.options.color=t||null,this._applyTheme(),this._feature&&!this._collapsed&&this._render(),this}setOptions(t){return this.options=f(this.options,t||{}),t&&"slopeColors"in t&&(this.slopeColors=t.slopeColors||null),t&&(t.theme||"color"in t)&&this._applyTheme(),t&&("transparency"in t||"transparencyLevel"in t)&&this._applyTransparency(),t&&"collapsable"in t&&this._applyCollapsable(),t&&"labels"in t&&(this._userLabels=f(this._userLabels||{},t.labels)),t&&("lang"in t||"labels"in t)&&(this.options.labels=m(this.options.lang,this._userLabels),this._applyLabels()),t&&("zoom"in t||"exportPng"in t)&&this._updateZoomButtons(),t&&void 0!==t.width&&"number"==typeof t.width&&(this.options.width=t.width),t&&"dem"in t&&(this._demZ=null,this._demFor=null,this._trackLines=null,this._linesFor=null),this._feature&&(this._compute(),this._fillFromDem(this._feature),this._updateZoomButtons(),this._collapsed?this._renderTitle():this._render()),this}_fillFromDem(t){const e=function(t){if(!t)return null;if("function"==typeof t)return Object.assign({},C,{sample:t});const e=!0===t||"string"==typeof t?{source:!0===t?"terrarium":t}:Object.assign({},t);if("function"==typeof e.sample)return Object.assign({},C,e);if(e.track){const t=Object.assign({},C,e);return t.track=Object.assign({coords:"coords",parse:null,fetchOptions:null},"string"==typeof e.track?{url:e.track}:e.track),t.track.url?t:null}if(e.featureInfo){const t=Object.assign({},C,e);return t.sample=$(t),t}if(e.olSource&&"function"!=typeof e.olSource.getTileUrlFunction&&"function"==typeof e.olSource.getTile){const t=Object.assign({},C,e);return t.sample=L(t),t}const s=e.url||e.wms||e.olSource,o=w[e.source]||(s?{}:w.terrarium),n=Object.assign({},C,o,e);return"ign"===n.api?(n.sample=z(n),n):n.url||n.wms||n.olSource?n:null}(this.options.dem);if(!e||!t||this._demFor===t||this._linesFor===t)return;if(F.featureHasZ(t))return;if(!e.sample&&("undefined"==typeof Image||"undefined"==typeof document))return;const s=t.getGeometry&&t.getGeometry(),n=s?y(s):[],i=this.options.dataProjection||this.getMap()&&this.getMap().getView().getProjection()||"EPSG:3857",l=[];for(const t of n)for(const e of t)l.push(o.toLonLat(e,i));if(!l.length&&!e.track)return;const r=++this._demSeq;this._demLoading=!0;try{this._startFill(e,r,t,l,i)}catch(e){this._demDone(r,t,null,l.length,null,0)}}_startFill(t,e,s,o,n){if(t.track)return void this._startTrackFill(t,e,s,o.length,n);if(t.sample)return void Promise.resolve().then(()=>t.sample(o,{feature:s,projection:n})).then(t=>this._demDone(e,s,t,o.length,null,0)).catch(()=>this._demDone(e,s,null,o.length,null,0));const i=new B(t),l=function(t,e,s){if("number"==typeof s.zoom)return s.zoom;for(let o=s.maxZoom;o>0;o--)if(t.tilesFor(e,o).size<=s.maxTiles)return o;return 1}(i,o,t);i.load(i.tilesFor(o,l)).then(t=>{const n=t?o.map(t=>i.sample(t[0],t[1],l)):null;this._demDone(e,s,n,o.length,l,i.tiles.size)}).catch(()=>this._demDone(e,s,null,o.length,l,0))}_startTrackFill(t,e,s,o,n){const i=function(t,e){if("function"==typeof t)return t(e)||null;if("string"!=typeof t||!e)return null;let s=!0;const o=t.replace(/\{(\w+)\}/g,(t,o)=>{const n=e.get(o);return null==n||""===n?(s=!1,""):encodeURIComponent(String(n))});return s?o:null}(t.track.url,s);i?Promise.resolve().then(()=>fetch(i,t.track.fetchOptions||void 0)).then(t=>{if(!t.ok)throw new Error(String(t.status));return t.json()}).then(i=>{const l=t.track.parse?t.track.parse(i,s):Array.isArray(i)?i:i&&i[t.track.coords];this._trackDone(e,s,l,o,n)}).catch(()=>this._demDone(e,s,null,o,null,0)):this._demDone(e,s,null,o,null,0)}_trackDone(t,e,s,n,i){const l=()=>this._demDone(t,e,null,n,null,0);if(!Array.isArray(s)||!s.length)return l();if("number"==typeof s[0])return void this._demDone(t,e,s,n,null,0);if(t!==this._demSeq||this._feature!==e)return;const r=t=>null!=t&&isFinite(t),a=[];for(const t of s){if(!t||t.length<3||!r(t[0])||!r(t[1])||!r(t[2]))return l();const e=o.transform([t[0],t[1]],"EPSG:4326",i);a.push([e[0],e[1],t[2]])}if(a.length<2)return l();this._demLoading=!1,this._trackLines=[a],this._linesFor=e,this._demZ=null,this._demFor=null,this._compute(),this._updateZoomButtons(),this._collapsed||this._render(),this.dispatchEvent({type:"demload",ok:!0,zoom:null,tiles:0})}_demDone(t,e,s,o,n,i){if(t!==this._demSeq||this._feature!==e)return;const l=Array.isArray(s)&&s.length===o&&s.every(t=>null!=t&&isFinite(t));this._demLoading=!1,l&&(this._demZ=s,this._demFor=e,this._compute()),this._updateZoomButtons(),this._collapsed||this._render(),this.dispatchEvent({type:"demload",ok:l,zoom:n,tiles:i})}_compute(){const t=this.options,e=this._linesFor===this._feature&&this._trackLines,s=this._feature.getGeometry&&this._feature.getGeometry(),n=e?this._trackLines:s?y(s):[],l=t.dataProjection||this.getMap()&&this.getMap().getView().getProjection()||"EPSG:3857",r=this._demFor===this._feature?this._demZ:null,a=e?null:x(this._feature,n);this._hasTime=!!a;const h=!1!==t.ignoreStops,c=null!=t.stopSpeed?t.stopSpeed:.5,u=[];let p=0,d=null,m=-1,f=0,_=null;for(const t of n)for(const e of t){m++;const t=o.toLonLat(e,l);let s=0;d&&(s=i.getDistance(d,t),p+=s);let n=null;if(a&&null!=a[m]){const t=a[m];if(null!=_){const e=(t-_)/1e3;e>0&&(!h||s/e>=c)&&(f+=e)}n=f,_=t}d=t;const g=e.length>2&&isFinite(e[2])?e[2]:r?r[m]:0;u.push({x:p,z:g,coord:e,t:n})}t.smoothing>0&&this._smooth(u,t.smoothing);const g=this._decimate(u,t.maxPoints);this._addSlope(g),this._fullSamples=g,this._fullStats=this._statsOf(g,!0),this._applyCrops()}_pxPerCm(){try{const t=document.createElement("div");t.style.cssText="position:absolute;left:-9999px;top:0;width:1cm;height:1cm",(this.element||document.body).appendChild(t);const e=t.getBoundingClientRect().height;if(t.remove(),e>0)return e}catch(t){}return 96/2.54}_yScale(t,e,s,o){const n=t.min-e,i=t.max+e,l=s/this._pxPerCm(),r=o/this._pxPerCm(),a=e=>r>0&&e>0?t.distance/r/(e/l):null;let c=this._verticalScaleFor(t,o);if(!(c>0)){const e=h.scaleLinear().domain([n,i]).range([s,0]).nice(),o=e.domain(),l=a(o[1]-o[0]),u=this._plafondExageration();if(!(u>0)||null==l||l<=u)return this._vScale=null,this._vExaggeration=l,e;c=t.distance/r/u}const u=Math.max(c*l,i-n);this._vScale=u/l,this._vExaggeration=a(u);const p=Math.min(0,n);let d=(n+i)/2-u/2;return d<p&&(d=p),h.scaleLinear().domain([d,d+u]).range([s,0])}_plafondExageration(){const t=this.options.verticalScale,e=t&&"object"==typeof t?Number(t.maxExaggeration):0;return e>0?e:0}_verticalScaleFor(t,e){const s=this.options.verticalScale;if("number"==typeof s)return s;const o=s&&"object"==typeof s?Number(s.exaggeration):0;if(!(o>0&&t.distance>0&&e>0))return 0;const n=e/this._pxPerCm();return t.distance/n/o}_statsOf(t,e){let s=0,o=0,n=1/0,i=-1/0,l=0;for(let e=0;e<t.length;e++){const r=t[e].z;if(r<n&&(n=r),r>i&&(i=r),e>0){const n=r-t[e-1].z;n>0?s+=n:o-=n}const a=Math.abs(t[e].slope||0);a>l&&(l=a)}const r=t.length?t[t.length-1].x-t[0].x:0,a=t.length?t[0].t:null,h=t.length?t[t.length-1].t:null;return{distance:r,duration:null!=a&&null!=h?h-a:null,ascent:s,descent:o,min:isFinite(n)?n:0,max:isFinite(i)?i:0,maxAbsSlope:l,points:t.length}}_smooth(t,e){if(!(e>0)||t.length<3)return;const s=e/2,o=t.map(t=>t.z);let n=0,i=0,l=0;for(let e=0;e<t.length;e++){const r=t[e].x;for(;n<t.length&&t[n].x<r-s;)l-=o[n],n++;for(;i<t.length&&t[i].x<=r+s;)l+=o[i],i++;t[e].z=i>n?l/(i-n):o[e]}}_decimate(t,e){const s=t=>({x:t.x,z:t.z,coord:t.coord,t:t.t});if(!e||t.length<=e)return t.map(s);const o=t.length/e,n=[];for(let i=0;i<e;i++)n.push(s(t[Math.floor(i*o)]));return n.push(s(t[t.length-1])),n}_addSlope(t){for(let e=1;e<t.length;e++){const s=t[e].x-t[e-1].x;t[e].slope=s>0?(t[e].z-t[e-1].z)/s*100:0}t.length&&(t[0].slope=t.length>1?t[1].slope:0)}_slopeScale(){const t=this.options.slopeClassSize||2.5,e=this.options.maxClasses||8,s=Math.max(1,Math.floor((this._stats.maxAbsSlope||0)/t)),o=Math.min(s,e-1),n=s>o;let i;if(this.slopeColors&&this.slopeColors.length){const t=h.interpolateRgbBasis(this.slopeColors);i=e=>t(o?e/o:0)}else{const t=h.scaleLinear().domain([0,.16,.42,.68,1]).range(["#2166ac","#27a35a","#ffe000","#f4791f","#d7191c"]).interpolate(h.interpolateRgb).clamp(!0);i=e=>String(t(o?e/o:0))}return{classSize:t,maxIdx:o,capped:n,colorByIndex:i}}_classIndex(t,e){return Math.min(e.maxIdx,Math.floor(Math.abs(t)/e.classSize))}_fmtDuration(t){if(null==t||!isFinite(t))return"";const e=this.options.labels&&this.options.labels.durationUnits||p.en.durationUnits;if((t=Math.max(0,Math.round(t)))<60)return t+" "+e.s;if(t<3600)return Math.round(t/60)+" "+e.m;if(t<86400){let s=Math.floor(t/3600),o=Math.round(t%3600/60);return 60===o&&(s++,o=0),o?`${s} ${e.h} ${o} ${e.m}`:`${s} ${e.h}`}let s=Math.floor(t/86400),o=Math.round(t%86400/3600);return 24===o&&(s++,o=0),o?`${s} ${e.d} ${o} ${e.h}`:`${s} ${e.d}`}_hasElevation(){const t=this._feature;return!!t&&(!!F.featureHasZ(t)||(!(this._demFor!==t||!this._demZ)||!(this._linesFor!==t||!this._trackLines)))}_renderNoElevation(){if(!this.options.showWithoutElevation)return void(this.element.style.display="none");this.element.style.display="",this._applyTheme(),this._applyPlacement(),this._renderHeader(!0);const t="number"==typeof this.options.height?this.options.height:180;this._body.innerHTML="";const e=document.createElement("div");e.className="oep-noelev",e.style.height=`${t}px`,e.setAttribute("role","status"),e.textContent=this.options.labels.noElevation,this._body.appendChild(e),this._clearFocus()}_pickProperty(t,e,s){if(!e||!t||!t.get)return null;for(const o of Array.isArray(e)?e:[e]){const e=t.get(o);if(null!=e&&""!==e&&(!s||s(e)))return e}return null}_renderTitle(){const t=this.options,e=this._feature;if(!e)return;const s=this._pickProperty(e,t.titleProperty)||t.labels.untitled,o=this._pickProperty(e,t.titleLink,g);g(o)?this._titleEl.innerHTML=`<a href="${_(o)}" target="_blank" rel="noopener">${_(s)}</a>`:this._titleEl.textContent=s,this._titleEl.setAttribute("title",s)}_renderHeader(t){const e=this.options,s=this._stats,o=this._feature;if(this._renderTitle(),this._demLoading)return this._statsEl.innerHTML="",this._statsEl.removeAttribute("title"),this._legendEl.innerHTML="",void(this._legendEl.style.display="none");const n=[],i=[];if(e.headerItems.forEach(l=>{if("string"==typeof l){if(t&&("ascent"===l||"descent"===l||"min"===l||"max"===l||"minmax"===l))return;if("distance"===l){if(!(s&&s.distance>0))return;n.push(`<b>${v(s.distance,e.units)}</b>`),i.push(v(s.distance,e.units))}else if("ascent"===l)n.push(`<span class="oep-up">${e.labels.ascent} ${S(s.ascent,e.units)}</span>`),i.push(`${e.labels.ascent} ${S(s.ascent,e.units)}`);else if("descent"===l)n.push(`<span class="oep-down">${e.labels.descent} ${S(s.descent,e.units)}</span>`),i.push(`${e.labels.descent} ${S(s.descent,e.units)}`);else if("min"===l)n.push(S(s.min,e.units)),i.push(S(s.min,e.units));else if("max"===l)n.push(S(s.max,e.units)),i.push(S(s.max,e.units));else if("minmax"===l){const t=`${S(s.min,e.units)}-${S(s.max,e.units)}`;n.push(t),i.push(t)}else if("duration"===l&&null!=s.duration){const t=this._fmtDuration(s.duration);n.push(`<span class="oep-time">${_(e.labels.duration)} ${t}</span>`),i.push(`${e.labels.duration} ${t}`)}}else if(l&&l.property){const t=o.get&&o.get(l.property);if(null==t||""===t)return;const e=l.label?`${l.label} `:"";l.asLink&&g(t)?(n.push(`${e}<a href="${_(t)}" target="_blank" rel="noopener">${_(l.linkText||l.label||t)}</a>`),i.push(`${l.label||""} ${t}`)):(n.push(_(e+t)),i.push(e+t))}}),this._statsEl.innerHTML=n.join(" · "),this._statsEl.setAttribute("title",i.join(" · ")),this._legendEl.innerHTML="",e.slope&&e.slopeLegend&&!t){const t=this._slopeScale();for(let e=0;e<=t.maxIdx;e++){const s=t.colorByIndex(e),o=t.capped&&e===t.maxIdx?`≥ ${e*t.classSize} %`:`${e*t.classSize}-${(e+1)*t.classSize} %`,n=document.createElement("span");n.className="oep-leg-it",n.innerHTML=`<i class="oep-sw" style="background:${s}"></i>${o}`,this._legendEl.appendChild(n)}this._legendEl.style.display=""}else this._legendEl.style.display="none"}_renderSpinner(){const t="number"==typeof this.options.height?this.options.height:180;this._body.innerHTML="";const e=document.createElement("div");e.className="oep-loading",e.style.height=`${t}px`,e.setAttribute("role","status"),e.setAttribute("aria-label",this.options.labels.loading);const s=document.createElement("div");s.className="oep-spinner",e.appendChild(s),this._body.appendChild(e)}_render(){const t=this.options,e=this._stats,s=this._samples;if(!this._demLoading&&!this._hasElevation())return void this._renderNoElevation();if(!s||!s.length)return;this._applyTheme();const o=this._applyPlacement();if(this._renderHeader(),this._demLoading)return void this._renderSpinner();const n=t.margins,i=n.unit||"px",l=t=>"px"===i?t:t*(parseFloat(getComputedStyle(this.element).fontSize)||16),r=this._availWidth(),a="auto"===t.width||"100%"===t.width||"full"===t.width?r:Math.min("number"==typeof t.width?t.width:parseFloat(t.width)||r,r);this.element.style.width=o?"":`${a}px`;const c=this.element.clientWidth||(o?r:a),u=Math.max(220,c-16),p="number"==typeof t.height?t.height:180,d=l(n.top),m=l(n.right),f=l(n.bottom),_=l(n.left),g=Math.max(10,u-_-m),y=Math.max(10,p-d-f),x=null!=t.xTicks?t.xTicks:Math.max(2,Math.round(g/80)),b=null!=t.yTicks?t.yTicks:Math.max(2,Math.round(y/40));this._body.innerHTML="";const v=h.select(this._body).append("svg").attr("class","oep-svg").attr("width",u).attr("height",p).attr("viewBox",`0 0 ${u} ${p}`),S=v.append("g").attr("transform",`translate(${_},${d})`),E=h.scaleLinear().domain([0,e.distance]).range([0,g]),M=.1*(e.max-e.min)||10,k=this._yScale(e,M,y,g);this._x=E,this._y=k,this._dims={innerW:g,innerH:y},t.grid&&S.append("g").attr("class","oep-grid").call(h.axisLeft(k).ticks(b).tickSize(-g).tickFormat(""));const w="imperial"===t.units?1609.344:1e3;const z=h.area().x(t=>E(t.x)).y0(y).y1(t=>k(t.z));if(t.slope){const e=this._slopeScale(),o=[];let n=1;for(;n<s.length;){const t=this._classIndex(s[n].slope,e);let i=n;for(;i+1<s.length&&this._classIndex(s[i+1].slope,e)===t;)i++;S.append("path").datum(s.slice(n-1,i+1)).attr("class","oep-area-slope").attr("fill",e.colorByIndex(t)).attr("d",z),n>1&&o.push(s[n-1]),n=i+1}t.slopeSeparators&&o.forEach(t=>{S.append("line").attr("class","oep-slope-sep").attr("x1",E(t.x)).attr("x2",E(t.x)).attr("y1",k(t.z)).attr("y2",y)})}else S.append("path").datum(s).attr("class","oep-area").attr("d",z);S.append("path").datum(s).attr("class","oep-line").attr("d",h.line().x(t=>E(t.x)).y(t=>k(t.z))),S.append("g").attr("class","oep-axis oep-axis-x").attr("transform",`translate(0,${y})`).call(h.axisBottom(E).ticks(x).tickFormat(t=>(t/w).toFixed(t/w<10?1:0))),S.append("text").attr("class","oep-axis-label").attr("x",g).attr("y",y+f-4).attr("text-anchor","end").text((t=>"imperial"===t?"mi":"km")(t.units)),S.append("g").attr("class","oep-axis oep-axis-y").call(h.axisLeft(k).ticks(b).tickFormat(e=>"imperial"===t.units?Math.round(3.28084*e):e)),t.zoom&&this._cropDepth<this._cropMax&&[["A",this._zoomA],["B",this._zoomB]].forEach(([t,e])=>{if(null==e)return;const s=E(e);S.append("line").attr("class","oep-ab-line").attr("x1",s).attr("x2",s).attr("y1",0).attr("y2",y),S.append("text").attr("class","oep-ab-label").attr("x",s).attr("y",-6).attr("text-anchor","middle").text(t)});const C=S.append("g").attr("class","oep-focus").style("display","none");C.append("line").attr("class","oep-focus-line").attr("y1",0).attr("y2",y),C.append("circle").attr("class","oep-focus-dot").attr("r",4);const P=C.append("g").attr("class","oep-focus-label");P.append("rect").attr("class","oep-focus-bg"),P.append("text").attr("class","oep-focus-txt"),this._focus=C;const T=t=>{const s=h.pointer(t,S.node())[0];return Math.max(0,Math.min(e.distance,E.invert(s)))},j=v.append("rect").attr("class","oep-overlay").attr("x",_).attr("y",d).attr("width",g).attr("height",y);j.on("mousemove",t=>{const e=this._sampleAt(T(t));e&&(this._setFocus(e),this._marker&&this._marker.setPosition(e.coord))}).on("mouseout",()=>this._clearFocus()),j.on("click",t=>this._placeBound(T(t))),this._armed&&j.style("cursor","col-resize"),this._adjustAttribution()}static get _EXPORT_PROPS(){return["fill","fill-opacity","stroke","stroke-width","stroke-dasharray","stroke-linecap","stroke-linejoin","opacity","font-family","font-size","font-weight","text-anchor","shape-rendering"]}_freezeStyles(t,e){const s=F._EXPORT_PROPS,o=getComputedStyle(t);let n="";for(const t of s){const e=o.getPropertyValue(t);e&&(n+=`${t}:${e};`)}e.setAttribute("style",n);const i=t.children,l=e.children;for(let t=0;t<i.length&&t<l.length;t++)this._freezeStyles(i[t],l[t])}_exportSvg(){const t=this._body.querySelector("svg");if(!t)return null;const e=getComputedStyle(this.element),s=e.getPropertyValue("--oep-bg").trim()||"#fff",o=e.getPropertyValue("--oep-text").trim()||"#222",n=e.fontFamily||"system-ui, sans-serif",i=+t.getAttribute("width"),l=+t.getAttribute("height"),r=this._statsEl.textContent?15:0,a="none"!==this._legendEl.style.display?this._legendEl:null,h=28+r+(a?18:0),c=t.cloneNode(!0);c.querySelectorAll(".oep-focus, .oep-overlay").forEach(t=>t.remove()),this._freezeStyles(t,c);const u=t=>_(String(t)),p=[];if(p.push(`<rect width="${i+16}" height="${l+h+8}" fill="${u(s)}"/>`),p.push(`<text x="8" y="21" style="font-family:${u(n)};font-size:13px;font-weight:600;fill:${u(o)}">${u(this._titleEl.textContent)}</text>`),r&&p.push(`<text x="8" y="38" style="font-family:${u(n)};font-size:11px;fill:${u(o)};opacity:.85">${u(this._statsEl.textContent)}</text>`),a){let t=8;const e=28+r+12;for(const s of a.querySelectorAll(".oep-leg-it")){const i=s.querySelector(".oep-sw"),l=i?getComputedStyle(i).backgroundColor:"none",r=s.textContent.trim();p.push(`<rect x="${t}" y="${e-8}" width="10" height="10" fill="${u(l)}"/>`),p.push(`<text x="${t+14}" y="${e}" style="font-family:${u(n)};font-size:10px;fill:${u(o)}">${u(r)}</text>`),t+=14+5.6*r.length+10}}return p.push(`<g transform="translate(8,${h})">${(new XMLSerializer).serializeToString(c)}</g>`),{width:i+16,height:l+h+8,svg:`<svg xmlns="http://www.w3.org/2000/svg" width="${i+16}" height="${l+h+8}" viewBox="0 0 ${i+16} ${l+h+8}">${p.join("")}</svg>`}}exportPNG(t){const e=t||{},s=this._exportSvg();if(!s)return Promise.reject(new Error("ol-elevation-profile: nothing to export"));const o=e.scale||"undefined"!=typeof window&&window.devicePixelRatio||1;return new Promise((t,n)=>{const i=new Image;i.onload=()=>{try{const l=document.createElement("canvas");l.width=Math.round(s.width*o),l.height=Math.round(s.height*o);const r=l.getContext("2d");r.scale(o,o),r.drawImage(i,0,0),l.toBlob(s=>{s?(!1!==e.download&&this._save(s,e.filename),t(s)):n(new Error("ol-elevation-profile: PNG encoding failed"))},"image/png")}catch(t){n(t)}},i.onerror=()=>n(new Error("ol-elevation-profile: SVG could not be rasterised")),i.src="data:image/svg+xml;charset=utf-8,"+encodeURIComponent(s.svg)})}_save(t,e){const s=e||`${(this._titleEl.textContent||"profile").replace(/[\\/:*?"<>|]+/g,"-").trim()}.png`,o=URL.createObjectURL(t),n=document.createElement("a");n.href=o,n.download=s,document.body.appendChild(n),n.click(),n.remove(),setTimeout(()=>URL.revokeObjectURL(o),1e3)}_arm(t){this._armed=this._armed===t?null:t,this._updateZoomButtons(),this._focus&&this._render()}_placeBound(t){if(!this._armed||this._cropDepth>=this._cropMax)return;const e="A"===this._armed?"B":"A";"A"===this._armed?this._zoomA=t:this._zoomB=t;const s=null!=this._zoomA&&null!=this._zoomB;this._armed=s?null:e,this._updateZoomButtons(),s?this._pushCrop(this._zoomA,this._zoomB):this._render()}_updateZoomButtons(){const t=this.options,e=!!this._feature,s=!!t.zoom&&e,o=!!t.exportPng&&e;this._toolbar.style.display=s||o?"":"none",this._btnPng.style.display=o?"":"none";const n=this._cropDepth,i=n<this._cropMax;this._btnA.style.display=s&&i?"":"none",this._btnB.style.display=s&&i?"":"none",this._btnBack.style.display=s&&n>1?"":"none",this._btnAll.style.display=s&&n>0?"":"none",this._btnA.classList.toggle("armed","A"===this._armed),this._btnB.classList.toggle("armed","B"===this._armed)}_applyCrops(){if(!this._crops.length)return this._off=0,this._samples=this._fullSamples,this._stats=this._fullStats,null;const{a:t,b:e}=this._crops[this._crops.length-1],s=this._fullSamples.filter(s=>s.x>=t&&s.x<=e);if(s.length<2)return this._crops.pop(),this._applyCrops();const o=s[0].x,n=null!=s[0].t?s[0].t:0;return this._off=o,this._samples=s.map(t=>({x:t.x-o,z:t.z,coord:t.coord,slope:t.slope,t:null!=t.t?t.t-n:null})),this._stats=this._statsOf(this._samples,!1),s.map(t=>t.coord)}_fitMap(t){const e=this.getMap();if(!e)return null;let s=null;if(t&&t.length?s=l.boundingExtent(t):this._feature&&(s=this._feature.getGeometry().getExtent()),!s)return null;const o=e.getView();let n=null;try{n=o.getResolutionForExtent(s,e.getSize())}catch(t){n=null}return o.fit(s,{padding:[40,40,40,40],duration:400}),n}_pushCrop(t,e){if(this._zoomA=null,this._zoomB=null,this._armed=null,this._cropDepth>=this._cropMax)return this._updateZoomButtons(),void this._render();const s=this._off+Math.min(t,e),o=this._off+Math.max(t,e);let n=0;for(let t=0;t<this._fullSamples.length;t++){const e=this._fullSamples[t].x;e>=s&&e<=o&&n++}if(n<2)return this._updateZoomButtons(),void this._render();this._crops.push({a:s,b:o,fitRes:null});const i=this._applyCrops();this._updateZoomButtons(),this._render();const l=this._crops[this._crops.length-1];l&&(l.fitRes=this._fitMap(i))}_applyZoom(){null!=this._zoomA&&null!=this._zoomB&&this._pushCrop(this._zoomA,this._zoomB)}_popCrop(){if(!this._crops.length)return;this._crops.pop(),this._zoomA=null,this._zoomB=null,this._armed=null;const t=this._applyCrops();this._updateZoomButtons(),this._collapsed||this._render(),this._fitMap(t)}_exitZoom(){this._crops.length=0,this._zoomA=null,this._zoomB=null,this._armed=null,this._applyCrops(),this._updateZoomButtons(),this._collapsed||this._render(),this._fitMap(null)}_closestOnProfile(t){const e=this._feature&&this._feature.getGeometry();if(!e)return null;if(!/Polygon/.test(e.getType()))return e.getClosestPoint(t);const s=this._projectOn(this._fullSamples,t);return s?s.coord:null}_projectOn(t,e){if(!t||!t.length)return null;if(1===t.length)return{x:t[0].x,coord:t[0].coord.slice(0,2)};let s=null,o=1/0;for(let n=1;n<t.length;n++){const i=t[n-1].coord,l=t[n].coord,r=l[0]-i[0],a=l[1]-i[1],h=r*r+a*a;let c=h>0?((e[0]-i[0])*r+(e[1]-i[1])*a)/h:0;c=c<0?0:c>1?1:c;const u=i[0]+r*c,p=i[1]+a*c,d=u-e[0],m=p-e[1],f=d*d+m*m;f<o&&(o=f,s={x:t[n-1].x+(t[n].x-t[n-1].x)*c,coord:[u,p]})}return s}_tooltipText(t){const e=this.options,s=[];return e.tooltipItems.forEach(o=>{var n;"distance"===o?s.push(v(t.x,e.units)):"elevation"===o?s.push(S(t.z,e.units)):"slope"===o?s.push(`${(n=t.slope||0)>=0?"+":""}${n.toFixed(1)} %`):"time"===o&&null!=t.t&&s.push(this._fmtDuration(t.t))}),s.join(" · ")}_setFocus(t){if(!this._focus)return;const e=this._x,s=this._y;this._focus.style("display",null),this._focus.select(".oep-focus-line").attr("x1",e(t.x)).attr("x2",e(t.x)),this._focus.select(".oep-focus-dot").attr("cx",e(t.x)).attr("cy",s(t.z));let o=s(t.z)-16;o<12&&(o=s(t.z)+22);const n=this._focus.select(".oep-focus-txt").attr("x",e(t.x)).attr("y",o).text(this._tooltipText(t)),i=n.node().getBBox();this._focus.select(".oep-focus-bg").attr("x",i.x-4).attr("y",i.y-2).attr("width",i.width+8).attr("height",i.height+4),e(t.x)+i.width/2>this._dims.innerW?n.attr("text-anchor","end"):e(t.x)-i.width/2<0?n.attr("text-anchor","start"):n.attr("text-anchor","middle")}_sampleAt(t){const e=this._samples;if(!e||!e.length)return null;if(1===e.length)return e[0];const s=e[0].x,o=e[e.length-1].x,n=Math.max(s,Math.min(o,t)),i=Math.min(Math.max(k(e,n,1),1),e.length-1),l=e[i-1],r=e[i],a=r.x-l.x,h=a>0?(n-l.x)/a:0,c=(t,e)=>t+(e-t)*h;return{x:n,z:c(l.z,r.z),coord:[c(l.coord[0],r.coord[0]),c(l.coord[1],r.coord[1])],slope:r.slope,t:null!=l.t&&null!=r.t?c(l.t,r.t):null}}_focusByCoord(t){const e=this._projectOn(this._samples,t);if(!e)return;const s=this._sampleAt(e.x);s&&(this._setFocus(s),this._marker&&this._marker.setPosition(s.coord))}_clearFocus(){this._focus&&this._focus.style("display","none"),this._marker&&this._marker.setPosition(void 0)}_clear(){this._body.innerHTML="",this._legendEl.innerHTML="",this._legendEl.style.display="none",this._titleEl.textContent=this.options.labels.empty,this._titleEl.removeAttribute("title"),this._statsEl.innerHTML="",this._statsEl.removeAttribute("title"),this._crops=[],this._off=0,this._demLoading=!1,this._updateZoomButtons(),this._clearFocus(),this.element.style.display="none",this._adjustAttribution()}}return F.addTheme=(t,e)=>{c[t]=e},F.THEMES=c,F.DEM_PRESETS=w,F.DemSampler=B,F.POSITIONS=u,F.version="2.1.2",F});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ol-elevation-profile",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
4
4
  "description": "Synchronized elevation profile control for OpenLayers, rendered with d3. Reads elevation from 3D GPX/GeoJSON, or fills it from a terrain model: AWS tiles, IGN RGE ALTI, XYZ, WMS, GeoTIFF, GeoServer, or your own source.",
5
5
  "type": "module",
6
6
  "main": "dist/ol-elevation-profile.js",
@@ -114,7 +114,8 @@ import * as d3 from 'd3';
114
114
  yTicks: null,
115
115
  verticalScale: 'auto', // 'auto' : le profil remplit la hauteur ;
116
116
  // un nombre : mètres par centimètre physique ;
117
- // { exaggeration } : rapport fixe vertical/horizontal
117
+ // { exaggeration } : rapport fixe vertical/horizontal ;
118
+ // { maxExaggeration } : 'auto' sans dépasser ce rapport
118
119
  show: 'click',
119
120
  showWithoutElevation: true, // trace sans Z, et aucun MNT n'a pu en fournir :
120
121
  // le panneau paraît quand même, avec un message
@@ -836,16 +837,22 @@ import * as d3 from 'd3';
836
837
  * @property {number} [smoothing=0] Elevation smoothing window, in METERS (0 = none).
837
838
  * @property {?number} [xTicks=null] X axis ticks (null = auto from width).
838
839
  * @property {?number} [yTicks=null] Y axis ticks (null = auto from height).
839
- * @property {('auto'|number|{exaggeration:number})} [verticalScale='auto'] `'auto'`: the
840
+ * @property {('auto'|number|{exaggeration:number}|{maxExaggeration:number})} [verticalScale='auto'] `'auto'`: the
840
841
  * profile fills the height, which is legible but changes scale from one track to the
841
842
  * next, so a 2 % ramp looks like a wall and two profiles cannot be compared. A number
842
843
  * fixes the metres covered per physical centimetre, which makes RANGES comparable.
843
844
  * `{exaggeration}` fixes the ratio between the two axes instead, which makes SLOPES
844
845
  * comparable: the gradient read off the chart is the real one, multiplied by the same
845
846
  * factor on every track, and the control recomputes it per track and per A/B crop.
846
- * Either form is a **floor**, not a cage: a track whose range exceeds what the height
847
- * can show would spill out of the frame, which is worse than losing comparability, so
848
- * the scale then widens silently, nothing being drawn on the chart to say so.
847
+ * `{maxExaggeration}` keeps `'auto'` the height is filled, which reads best and
848
+ * only reins in the absurd: a short, gently sloping track whose 2 % ramp would
849
+ * otherwise be drawn as a wall. A track already under the cap is untouched, so unlike
850
+ * a fixed exaggeration it never flattens a mountain traverse to fit a rule.
851
+ * A number or `{exaggeration}` is a **floor**, not a cage: a track whose range exceeds
852
+ * what the height can show would spill out of the frame, which is worse than losing
853
+ * comparability, so the scale then widens silently, nothing being drawn on the chart
854
+ * to say so. The extra room the scale asks for is added ABOVE the track, never below:
855
+ * centring it would push the axis under sea level on a mountain profile.
849
856
  * @property {'click'|'mouseover'} [show='click'] How a track is selected on the map.
850
857
  * @property {boolean} [showWithoutElevation=true] What to do with a track that ends up
851
858
  * with no elevation at all: none in its geometry, and none the terrain model could
@@ -1505,23 +1512,44 @@ import * as d3 from 'd3';
1505
1512
  // La publier partout est le seul moyen de voir la différence plutôt que d'y croire.
1506
1513
  const rapport = (etendue) => (cmH > 0 && etendue > 0) ? (s.distance / cmH) / (etendue / cm) : null;
1507
1514
 
1508
- const vs = this._verticalScaleFor(s, innerW);
1515
+ let vs = this._verticalScaleFor(s, innerW);
1509
1516
  if (!(vs > 0)) {
1510
1517
  // `'auto'` : la hauteur est remplie, donc c'est l'amplitude qui décide de tout.
1511
1518
  // `nice()` arrondit le domaine vers l'extérieur, d'où la lecture APRÈS coup.
1512
1519
  const echelle = d3.scaleLinear().domain([bas, haut]).range([innerH, 0]).nice();
1513
1520
  const dom = echelle.domain();
1514
- this._vScale = null; // aucune échelle absolue demandée
1515
- this._vExaggeration = rapport(dom[1] - dom[0]);
1516
- return echelle;
1521
+ const obtenu = rapport(dom[1] - dom[0]);
1522
+ // Un PLAFOND d'exagération, s'il en est demandé un. Remplir la hauteur est ce
1523
+ // qui se lit le mieux, mais sur une trace courte et peu accidentée cela dresse
1524
+ // une pente de 2 % en muraille. Le plafond n'intervient que là : quand le
1525
+ // remplissage dépasse le rapport permis, on élargit l'échelle jusqu'à lui. Une
1526
+ // trace assez accidentée pour rester en dessous n'est jamais aplatie, ce qu'une
1527
+ // exagération FIXE lui imposerait — à 680 km d'une traversée, elle n'occuperait
1528
+ // plus qu'un dixième du cadre.
1529
+ const plafond = this._plafondExageration();
1530
+ if (!(plafond > 0) || obtenu == null || obtenu <= plafond) {
1531
+ this._vScale = null; // aucune échelle absolue demandée
1532
+ this._vExaggeration = obtenu;
1533
+ return echelle;
1534
+ }
1535
+ vs = (s.distance / cmH) / plafond; // l'échelle qui donne exactement le plafond
1517
1536
  }
1518
1537
  const etendue = Math.max(vs * cm, haut - bas); // jamais moins qu'il n'en faut
1519
- const milieu = (bas + haut) / 2;
1520
1538
  this._vScale = etendue / cm; // m/cm effectivement appliqués
1521
1539
  // Sous le plancher, le rapport retombe sous celui demandé : c'est la seule façon de
1522
1540
  // savoir que c'est arrivé.
1523
1541
  this._vExaggeration = rapport(etendue);
1524
- return d3.scaleLinear().domain([milieu - etendue / 2, milieu + etendue / 2]).range([innerH, 0]);
1542
+
1543
+ // La marge que l'échelle impose se place AU-DESSUS, pas de part et d'autre.
1544
+ // Centrer la fenêtre creuse sous la trace : une échelle large - ce que demande
1545
+ // une exagération fixe sur une trace longue - fait alors descendre l'axe sous le
1546
+ // niveau de la mer, et on lit « -900 m » sur un profil de montagne. Le plancher
1547
+ // est donc zéro, ou le point le plus bas de la trace s'il passe dessous : une
1548
+ // dépression existe, une altitude négative inventée, non.
1549
+ const plancher = Math.min(0, bas);
1550
+ let y0 = (bas + haut) / 2 - etendue / 2; // le centrage, quand il tient
1551
+ if (y0 < plancher) y0 = plancher;
1552
+ return d3.scaleLinear().domain([y0, y0 + etendue]).range([innerH, 0]);
1525
1553
  }
1526
1554
 
1527
1555
  /**
@@ -1539,6 +1567,13 @@ import * as d3 from 'd3';
1539
1567
  *
1540
1568
  * @private
1541
1569
  */
1570
+ /** Le rapport à ne pas dépasser, `0` s'il n'en est pas demandé. @private */
1571
+ _plafondExageration() {
1572
+ const v = this.options.verticalScale;
1573
+ const n = (v && typeof v === 'object') ? Number(v.maxExaggeration) : 0;
1574
+ return n > 0 ? n : 0;
1575
+ }
1576
+
1542
1577
  _verticalScaleFor(s, innerW) {
1543
1578
  const v = this.options.verticalScale;
1544
1579
  if (typeof v === 'number') return v;
@@ -1748,7 +1783,9 @@ import * as d3 from 'd3';
1748
1783
  this._statsEl.setAttribute('title', text.join(' · '));
1749
1784
 
1750
1785
  this._legendEl.innerHTML = '';
1751
- if (o.slope && o.slopeLegend) {
1786
+ // Une légende de pentes sans altitude ne légende rien : elle annoncerait des
1787
+ // classes qu'aucun trait ne porte, sous un panneau qui dit n'avoir pas de profil.
1788
+ if (o.slope && o.slopeLegend && !sansAltimetrie) {
1752
1789
  const sc = this._slopeScale();
1753
1790
  for (let idx = 0; idx <= sc.maxIdx; idx++) {
1754
1791
  const color = sc.colorByIndex(idx);