From 3f23bdc1e85cdbfa7f8f7ab86f0f9e2abbadd1e0 Mon Sep 17 00:00:00 2001 From: tyrasd Date: Sun, 3 Nov 2024 19:36:28 +0000 Subject: [PATCH] deploy: 0ff477e87d947645a6f70a4d408edf42d1166306 --- assets/{index-C8Z-o-ll.js => index-B-00UnUQ.js} | 6 +++--- assets/{index-C8Z-o-ll.js.map => index-B-00UnUQ.js.map} | 2 +- index.html | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename assets/{index-C8Z-o-ll.js => index-B-00UnUQ.js} (99%) rename assets/{index-C8Z-o-ll.js.map => index-B-00UnUQ.js.map} (69%) diff --git a/assets/index-C8Z-o-ll.js b/assets/index-B-00UnUQ.js similarity index 99% rename from assets/index-C8Z-o-ll.js rename to assets/index-B-00UnUQ.js index 7ac3ba26..555b2baa 100644 --- a/assets/index-C8Z-o-ll.js +++ b/assets/index-B-00UnUQ.js @@ -751,7 +751,7 @@ ${H}${D}`)}for(let D=0;D{var R=(G,Y)=>{G?M(new Error(G)):H(Y)};_generatePkceChallenge(G=>x(G,R))}))};function x(H,M){var R=generateState(),G=g.url+"/oauth2/authorize?"+utilQsString({client_id:g.client_id,redirect_uri:g.redirect_uri,response_type:"code",scope:g.scope,state:R,code_challenge:H.code_challenge,code_challenge_method:H.code_challenge_method});if(g.singlepage){if(!store.enabled){var Y=new Error("local storage unavailable, but require in singlepage mode");Y.status="pkce-localstorage-unavailable",M(Y);return}var J=utilStringQs(window.location.search.slice(1));J.code?w.bootstrapToken(J.code,M):(S("oauth2_state",R),S("oauth2_pkce_code_verifier",H.code_verifier),window.location=G)}else{var X=600,re=550,ae=[["width",X],["height",re],["left",window.screen.width/2-X/2],["top",window.screen.height/2-re/2]].map(function(fe){return fe.join("=")}).join(","),oe=window.open("about:blank","oauth_window",ae);w.popupWindow=oe,oe.location=G,oe||(Y=new Error("Popup was blocked"),Y.status="popup-blocked",M(Y))}window.authComplete=function(fe){var _e=utilStringQs(fe.split("?")[1]);if(_e.state!==R){Y=new Error("Invalid state"),Y.status="invalid-state",M(Y);return}Q(_e.code,H.code_verifier,pe),delete window.authComplete};function pe(fe,_e){if(g.done(),fe){M(fe);return}var me=JSON.parse(_e.response);S("oauth2_access_token",me.access_token),M(null,w)}}function Q(H,M,R){var G=g.url+"/oauth2/token?"+utilQsString({client_id:g.client_id,redirect_uri:g.redirect_uri,grant_type:"authorization_code",code:H,code_verifier:M});w.rawxhr("POST",G,null,null,null,R),g.loading()}w.bringPopupWindowToFront=function(){var H=!1;try{w.popupWindow&&!w.popupWindow.closed&&(w.popupWindow.focus(),H=!0)}catch{}return H},w.bootstrapToken=function(H,M){var R=S("oauth2_state");S("oauth2_state","");var G=utilStringQs(window.location.search.slice(1));if(G.state!==R){var Y=new Error("Invalid state");Y.status="invalid-state",M(Y);return}var J=S("oauth2_pkce_code_verifier");S("oauth2_pkce_code_verifier",""),Q(H,J,X);function X(re,ae){if(g.done(),re){M(re);return}var oe=JSON.parse(ae.response);S("oauth2_access_token",oe.access_token),M(null,w)}},w.fetch=function(H,M){if(w.authenticated())return R();return g.auto?w.authenticateAsync().then(R):Promise.reject(new Error("not authenticated"));function R(){return M=M||{},M.headers||(M.headers={"Content-Type":"application/x-www-form-urlencoded"}),M.headers.Authorization="Bearer "+S("oauth2_access_token"),fetch(H,M)}},w.xhr=function(H,M){if(w.authenticated())return R();if(g.auto){w.authenticate(R);return}else{M("not authenticated",null);return}function R(){var Y=H.prefix!==!1?g.url+H.path:H.path;return w.rawxhr(H.method,Y,S("oauth2_access_token"),H.content,H.headers,G)}function G(Y,J){Y?M(Y):J.responseXML?M(Y,J.responseXML):M(Y,J.response)}},w.rawxhr=function(H,M,R,G,Y,J){Y=Y||{"Content-Type":"application/x-www-form-urlencoded"},R&&(Y.Authorization="Bearer "+R);var X=new XMLHttpRequest;X.onreadystatechange=function(){X.readyState===4&&X.status!==0&&(/^20\d$/.test(X.status)?J(null,X):J(X,null))},X.onerror=function(ae){J(ae,null)},X.open(H,M,!0);for(var re in Y)X.setRequestHeader(re,Y[re]);return X.send(G),X},w.preauth=function(H){return H&&H.access_token&&S("oauth2_access_token",H.access_token),w},w.options=function(H){return arguments.length?(g=H,g.url=g.url||"https://www.openstreetmap.org",g.auto=g.auto||!1,g.singlepage=g.singlepage||!1,g.loading=g.loading||function(){},g.done=g.done||function(){},w.preauth(g)):g};var S;if(store.enabled)S=function(H,M){if(arguments.length===1)return store.get(g.url+H);if(arguments.length===2)return store.set(g.url+H,M)};else{var D={};S=function(H,M){if(arguments.length===1)return D[g.url+H];if(arguments.length===2)return D[g.url+H]=M}}return w.options(g),w}function utilQsString(g){return Object.keys(g).filter(function(w){return g[w]!==void 0}).sort().map(function(w){return encodeURIComponent(w)+"="+encodeURIComponent(g[w])}).join("&")}function utilStringQs(g){for(var w=0;w{if(w)return g(w);loadQueries(g)})},save(g,w){auth.authenticated()?saveQuery(g,w):auth.authenticate(x=>{if(x)return w(x);saveQuery(g,w)})},delete(g,w){if(!auth.authenticated())return w(new Error("must be logged in to delete a synced query"));g={name:g,deleteMe:!0},saveQuery(g,w)},logout(){auth.authenticated()&&auth.logout()},authenticated(){return enabled&&auth.authenticated()}};function loadQueries(g){auth.xhr({method:"GET",path:"/api/0.6/user/preferences"},(w,x)=>{if(w)return g(w);let Q=0,S;(S=x.querySelector(`preference[k="${configs.settingNamespace}_query-count"]`))&&(Q=+S.getAttribute("v"));const D=[];for(let H=0;H{if(x)return w(x);const D=S.querySelector("preferences"),H=D.querySelectorAll(`preference[k^="${configs.settingNamespace}_query"]`);for(const G of H)G.remove();let M=!0;Q.forEach((G,Y)=>{G.name==g.name&&(G.query=g.query,M=Y)}),M===!0?Q.push(g):g.deleteMe&&Q.splice(M,1);const R=S.createElement("preference");R.setAttribute("k",`${configs.settingNamespace}_query-count`),R.setAttribute("v",Q.length),D.appendChild(R);for(let G=0;G200)return w(new Error("query name too long to be saved on osm.org"));const J=Math.ceil((Y.query.length+Y.name.length+8)/255);if(J>9)return w(new Error("query too long to be saved on osm.org"));let X=`p=${J}`;X+=`&n=${Y.name}`,X+=`&q=${Y.query}`,X=X.match(/.{1,255}/g);for(let re=0;re{if(G)return w(G);w(null,Q)})})}const cache={};class nominatim{static request(w,x){$.ajax(`https://nominatim.openstreetmap.org/search?X-Requested-With=${configs.appname}`,{data:{format:"json",q:w},success(Q){if(typeof Q=="string")try{Q=JSON.parse(Q)}catch{}cache[w]=Q,x(void 0,Q)},error(){const Q="An error occurred while contacting the osm search server nominatim.openstreetmap.org :(";console.log(Q),x(Q,null)}})}static get(w,x){return cache[w]===void 0?this.request(w,x):x(void 0,cache[w]),this}static getBest(w,x,Q){return Q||(Q=x,x=null),this.get(w,(S,D)=>{if(S){Q(S,null);return}x&&(D=D.filter(x)),D.length===0?Q("No result found",null):Q(S,D[0])}),this}}function map2bbox(g){let w;ide.map.bboxfilter&&ide.map.bboxfilter.isEnabled()?w=ide.map.bboxfilter.getBounds():w=ide.map.getBounds();const x=Math.min(Math.max(w.getSouthWest().lat,-90),90),Q=Math.min(Math.max(w.getNorthEast().lat,-90),90),S=Math.min(Math.max(w.getSouthWest().lng,-180),180),D=Math.min(Math.max(w.getNorthEast().lng,-180),180);if(g=="OverpassQL")return`${x},${S},${Q},${D}`;if(g=="xml")return`s="${x}" w="${S}" n="${Q}" e="${D}"`}function map2coord(g){const w=ide.map.getCenter();if(g=="OverpassQL")return`${w.lat},${w.lng}`;if(g=="xml")return`lat="${w.lat}" lon="${w.lng}"`}function relativeTime(g,w){const x=Date.now();if(g==""&&(g="0 seconds"),g=g.toLowerCase().match(/(-?[0-9]+) ?(seconds?|minutes?|hours?|days?|weeks?|months?|years?)?/),g===null){w("");return}const Q=parseInt(g[1]);let S;switch(g[2]){case"second":case"seconds":S=1;break;case"minute":case"minutes":S=60;break;case"hour":case"hours":S=3600;break;case"day":case"days":default:S=86400;break;case"week":case"weeks":S=604800;break;case"month":case"months":S=2628e3;break;case"year":case"years":S=31536e3;break}const D=x-Q*S*1e3;w(new Date(D).toISOString())}function geocodeId(g,w){const x=ide.getQueryLang();function Q(S){return S.osm_type&&S.osm_id}nominatim.getBest(g,Q,(S,D)=>{if(S)return ide.onNominatimError(g,"Id");x=="OverpassQL"?D=`${D.osm_type}(${D.osm_id})`:x=="xml"&&(D=`type="${D.osm_type}" ref="${D.osm_id}"`),w(D)})}function geocodeArea(g,w){const x=ide.getQueryLang();function Q(S){return S.osm_type&&S.osm_id&&S.osm_type!=="node"}nominatim.getBest(g,Q,(S,D)=>{if(S)return ide.onNominatimError(g,"Area");let H=1*D.osm_id;if(D.osm_type=="way"&&(H+=24e8),D.osm_type=="relation"&&(H+=36e8),x=="OverpassQL")return D.osm_type==="way"&&(H+=`,${D.osm_id}`),w(`area(id:${H})`);if(x=="xml")return D.osm_type==="way"&&(H+=`" ref_1="${D.osm_id}`),w(`type="area" ref="${H}"`)})}function geocodeBbox(g,w){const x=ide.getQueryLang();nominatim.getBest(g,(Q,S)=>{if(Q)return ide.onNominatimError(g,"Bbox");const D=Math.min(Math.max(S.boundingbox[0],-90),90),H=Math.min(Math.max(S.boundingbox[1],-90),90),M=Math.min(Math.max(S.boundingbox[2],-180),180),R=Math.min(Math.max(S.boundingbox[3],-180),180);x=="OverpassQL"?S=`${D},${M},${H},${R}`:x=="xml"&&(S=`s="${D}" w="${M}" n="${H}" e="${R}"`),w(S)})}function geocodeCoords(g,w){const x=ide.getQueryLang();nominatim.getBest(g,(Q,S)=>{if(Q)return ide.onNominatimError(g,"Coords");x=="OverpassQL"?S=`${S.lat},${S.lon}`:x=="xml"&&(S=`lat="${S.lat}" lon="${S.lon}"`),w(S)})}function shortcuts(){const g=ide.getQueryLang();return{bbox:map2bbox(g),center:map2coord(g),__bbox__global_bbox_xml__ezs4K8__:map2bbox("OverpassQL"),date:relativeTime,geocodeId,geocodeArea,geocodeBbox,geocodeCoords,nominatimId:g=="xml"?geocodeId:(w,x)=>geocodeId(w,Q=>x(`${Q};`)),nominatimArea:g=="xml"?geocodeArea:(w,x)=>geocodeArea(w,Q=>x(`${Q};`)),nominatimBbox:geocodeBbox,nominatimCoords:geocodeCoords}}let copyData;$(document).on("copy",g=>{copyData&&g.originalEvent&&g.originalEvent.clipboardData?(Object.keys(copyData).forEach(w=>{g.originalEvent.clipboardData.setData(w,copyData[w])}),g.originalEvent.preventDefault(),copyData=void 0):copyData&©Data["text/plain"]&&(prompt(i18n.t("export.copy_to_clipboard"),copyData["text/plain"]),copyData=null)});function make_combobox(g,w,x,Q){if(g[0].is_combobox){g.autocomplete("option",{source:w});return}const S=g.wrap("").parent().addClass("ui-combobox");g.autocomplete({source:w,minLength:0}).addClass("ui-widget ui-widget-content ui-corner-left ui-state-default").autocomplete("instance")._renderItem=(D,H)=>$("
  • ").append(x&&x.indexOf(H.value)!==-1?`
    ${H.label}
    `:`
    ${H.label}
    `).on("click",function(M){if(M.shiftKey&&x.indexOf(H.value)!==-1){Q(H.value),$(this).remove();const R=g.autocomplete("option","source");return R.splice(R.indexOf(H),1),g.autocomplete("option","source",R),!1}}).appendTo(D),$("").attr("tabIndex",-1).attr("title","show all items").appendTo(S).button({icons:{primary:"ui-icon-triangle-1-s"},text:!1}).removeClass("ui-corner-all").addClass("ui-corner-right ui-combobox-toggle").click(()=>{if(g.autocomplete("widget").is(":visible")){g.autocomplete("close");return}g.autocomplete("search",""),g.focus()}),g[0].is_combobox=!0}function showDialog(g,w,x){const Q=` `,S=$(Q);$(".delete",S).click(()=>$(S).remove());for(const D in x){const H=x[D];$(``).click(()=>{var M;(M=H.callback)==null||M.call(H),$(S).remove()}).appendTo($("footer .level-item",S))}S.appendTo("body")}class IDE{constructor(){this.attribControl=null,this.scaleControl=null,this.queryParser=new parser,this.run_query_on_startup=!1,this.codeEditor=null,this.dataViewer=null,this.map=null,this.waiter=new class{constructor(){this.opened=!0,this.frames=["◴","◷","◶","◵"],this.frameDelay=250,this.onAbort=void 0,this.interval=0,this._initialTitle=document.title}open(x){x?($(".modal .wait-info h4").text(x),$(".wait-info").show()):$(".wait-info").hide(),$("#loading-dialog").addClass("is-active"),document.title=`${this.frames[0]} ${this._initialTitle}`;let Q=0;this.interval=setInterval(()=>{const S=this.isAlert?this.alertFrame:this.frames[++Q%this.frames.length];document.title=`${S} ${this._initialTitle}`},this.frameDelay),this.opened=!0}close(x=""){this.opened&&(clearInterval(this.interval),document.title=`${x}${this._initialTitle}`,$("#loading-dialog").removeClass("is-active"),$(".wait-info ul li").remove(),delete this.onAbort,this.opened=!1)}addInfo(x,Q){$("#aborter").remove(),$(".wait-info ul li:nth-child(n+1)").css("opacity",.5),$(".wait-info ul li span.fas").removeClass("fa-spinner").removeClass("fa-spin").addClass("fa-check"),$(".wait-info ul li:nth-child(n+4)").hide();const S=$(`
  • ${x}
  • `);if(typeof Q=="function"){this.onAbort=Q;const D=$(' (abort)
    ').on("click",()=>(this.abort(),!1));S.append(D)}$(".wait-info ul").prepend(S)}abort(){typeof this.onAbort=="function"&&(this.addInfo("aborting"),this.onAbort(this.close))}}}init(){this.waiter.addInfo("ide starting up"),$("#overpass-turbo-version").html("overpass-turbo 2024-11-03/cbfdd99"),$("#overpass-turbo-dependencies").html('@fortawesome/fontawesome-free 5.15.4 ((CC-BY-4.0 AND OFL-1.1 AND MIT)), @openstreetmap/id-tagging-schema 3.5.1 (ISC), bulma 0.9.4 (MIT), canvg 4.0.1 (MIT), codemirror 2.38.00 (undefined), colorbrewer 1.5.7 ([object Object]), colormap 2.3.2 (MIT), html2canvas 1.4.1 (MIT), jquery 3.7.1 (MIT), jquery-ui 1.13.2 (MIT), jquery-ui-dist 1.13.2 (MIT), leaflet 1.9.4 (BSD-2-Clause), leaflet-polylineoffset 1.1.1 (MIT), leaflet-locationfilter 0.1.3 (MIT), lodash 4.17.21 (MIT), osm-auth 2.2.0 (ISC), osmtogeojson 3.0.0-beta.5 (MIT), rgbcolor 1.0.1 (MIT OR SEE LICENSE IN FEEL-FREE.md), stackblur 1.0.0 (BSD-2-Clause), tag2link 2024.05.21 (ISC), togpx 0.5.4 (MIT), tokml 0.4.0 (BSD-2-Clause)'),($.support.cors!=!0||typeof function(){let w;try{localStorage.setItem("startup_localstorage_quota_test",123),localStorage.removeItem("startup_localstorage_quota_test"),w=localStorage}catch{}return w}()!="object")&&(this.not_supported=!0,$("#warning-unsupported-browser").addClass("is-active")),this.waiter.addInfo("load settings"),settings.load(),this.waiter.addInfo("translate ui"),i18n.translate().then(()=>this.initAfterI18n()),sync.enabled&&($("#load-dialog .osm").show(),sync.authenticated()&&($("#logout").show(),$("#logout").appendTo($("#logout").parent())))}initAfterI18n(){const w=this;w.waiter.addInfo("parse url parameters");const x=urlParameters();x.has_coords&&(settings.coords_lat=x.coords.lat,settings.coords_lon=x.coords.lng),x.has_zoom&&(settings.coords_zoom=x.zoom),x.run_query&&(w.run_query_on_startup=!0),settings.save(),w.waiter.addInfo("initialize page");const Q=$(window).width()/$(window).height()<.8;if(settings.editor_width!=""&&!Q&&($("#editor").css("width",settings.editor_width),$("#dataviewer").css("left",settings.editor_width)),Q&&$("#editor, #dataviewer").addClass("portrait"),$("#editor").resizable({handles:Q?"s":"e",minWidth:Q?void 0:"200",resize(){if(!Q)$(this).next().css("left",`${$(this).outerWidth()}px`);else{const J=$(this).offset().top+$(this).outerHeight();$(this).next().css("top",`${J}px`)}w.map.invalidateSize(!1)},stop(){Q||(settings.editor_width=$("#editor").css("width"),settings.save())}}),$("#editor").prepend(""),$("#editor textarea")[0].value=settings.code.overpass,settings.use_rich_editor){let J=0;CodeMirror.defineMIME("text/x-overpassQL",{name:"clike",keywords:function(X){const re={},ae=X.split(" ");for(const oe of ae)re[oe]=!0;return re}("out json xml custom popup timeout maxsize bbox date diff adiff foreach relation rel way node is_in area around user uid newer changed poly pivot nwr nw nr wr derived out meta body skel tags ids count qt asc center bb geom")}),CodeMirror.defineMIME("text/x-overpassXML","xml"),CodeMirror.defineMode("xml+mustache",X=>CodeMirror.multiplexingMode(CodeMirror.multiplexingMode(CodeMirror.getMode(X,"xml"),{open:"{{",close:"}}",mode:CodeMirror.getMode(X,"text/plain"),delimStyle:"mustache"}),{open:"{{style:",close:"}}",mode:CodeMirror.getMode(X,"text/css"),delimStyle:"mustache"})),CodeMirror.defineMode("ql+mustache",X=>CodeMirror.multiplexingMode(CodeMirror.multiplexingMode(CodeMirror.getMode(X,"text/x-overpassQL"),{open:"{{",close:"}}",mode:CodeMirror.getMode(X,"text/plain"),delimStyle:"mustache"}),{open:"{{style:",close:"}}",mode:CodeMirror.getMode(X,"text/css"),delimStyle:"mustache"})),w.codeEditor=CodeMirror.fromTextArea($("#editor textarea")[0],{lineNumbers:!0,lineWrapping:!0,mode:"text/plain",onChange(X){clearTimeout(J),J=setTimeout(()=>{w.getQueryLang()=="xml"?X.getOption("mode")!="xml+mustache"&&(X.closeTagEnabled=!0,X.setOption("matchBrackets",!1),X.setOption("mode","xml+mustache")):X.getOption("mode")!="ql+mustache"&&(X.closeTagEnabled=!1,X.setOption("matchBrackets",!0),X.setOption("mode","ql+mustache"));const re=$(".leaflet-control-buttons-bboxfilter");w.getRawQuery().match(/\{\{bbox\}\}/)?re.hasClass("disabled")&&(re.removeClass("disabled"),re.attr("data-t","[title]map_controlls.select_bbox"),i18n.translate_ui(re[0])):re.hasClass("disabled")||(re.addClass("disabled"),re.attr("data-t","[title]map_controlls.select_bbox_disabled"),i18n.translate_ui(re[0]))},500),settings.code.overpass=X.getValue(),settings.save()},closeTagEnabled:!0,closeTagIndent:["osm-script","query","union","foreach","difference"],extraKeys:{"'>'"(X){X.closeTag(X,">")},"'/'"(X){X.closeTag(X,"/")}}}),w.codeEditor.getOption("onChange")(w.codeEditor)}else w.codeEditor=$("#editor textarea")[0],w.codeEditor.getValue=function(){return this.value},w.codeEditor.setValue=function(J){this.value=J},w.codeEditor.lineCount=function(){return this.value.split(/\r\n|\r|\n/).length},w.codeEditor.setLineClass=function(){},$("#editor textarea").bind("input change",J=>{settings.code.overpass=J.target.getValue(),settings.save()});x.has_query&&w.codeEditor.setValue(x.query),w.dataViewer=CodeMirror($("#data")[0],{value:"no data loaded yet",lineNumbers:!0,readOnly:!0,mode:"javascript"}),w.map=new L.Map("map",{attributionControl:!1,minZoom:0,maxZoom:configs.maxMapZoom,worldCopyJump:!1});const S=settings.tile_server,D=configs.tileServerAttribution,H=new L.TileLayer(S,{attribution:D,noWrap:!0,maxNativeZoom:19,maxZoom:w.map.options.maxZoom}),M=new L.Control.Attribution({position:"bottomright"});M.addAttribution(D),M.addTo(w.map);const R=new L.LatLng(settings.coords_lat,settings.coords_lon);w.map.setView(R,settings.coords_zoom).addLayer(H),w.map.tile_layer=H,w.map.inv_opacity_layer=L.tileLayer("data:image/gif;base64,R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==").setOpacity(1-settings.background_opacity),settings.background_opacity!=1&&w.map.inv_opacity_layer.addTo(w.map),w.scaleControl=new L.Control.Scale({metric:!0,imperial:!1}),w.scaleControl.addTo(w.map),w.map.on("moveend",()=>{settings.coords_lat=w.map.getCenter().lat,settings.coords_lon=w.map.getCenter().lng,settings.coords_zoom=w.map.getZoom(),settings.save()}),$("#dataviewer > div#data")[0].style.zIndex=-1001,$(".tabs li").bind("click",J=>{$(J.target).hasClass("is-active")||($("#dataviewer > div#data")[0].style.zIndex=-1*$("#dataviewer > div#data")[0].style.zIndex,$(".tabs li").toggleClass("is-active"))}),$(document).keydown(J=>w.onKeyPress(J));const G=L.Control.extend({options:{position:"topleft"},onAdd(){const J=L.DomUtil.create("div","leaflet-control-buttons leaflet-bar");let X=L.DomUtil.create("a","leaflet-control-buttons-fitdata leaflet-bar-part leaflet-bar-part-top",J);return $('').appendTo($(X)),X.href="#",X.className+=" t",X.setAttribute("data-t","[title]map_controlls.zoom_to_data"),i18n.translate_ui(X),L.DomEvent.addListener(X,"click",()=>{try{w.map.fitBounds(overpass.osmLayer.getBaseLayer().getBounds(),{maxZoom:18})}catch{}return!1},w.map),X=L.DomUtil.create("a","leaflet-control-buttons-myloc leaflet-bar-part",J),$('').appendTo($(X)),X.href="#",X.className+=" t",X.setAttribute("data-t","[title]map_controlls.localize_user"),window.isSecureContext||(X.className+=" disabled",X.setAttribute("data-t","[title]map_controlls.localize_user_disabled")),i18n.translate_ui(X),L.DomEvent.addListener(X,"click",()=>{try{navigator.geolocation.getCurrentPosition(re=>{const ae=new L.LatLng(re.coords.latitude,re.coords.longitude);w.map.setView(ae,settings.coords_zoom)})}catch{}return!1},w.map),X=L.DomUtil.create("a","leaflet-control-buttons-bboxfilter leaflet-bar-part",J),$('').appendTo($(X)),X.href="#",X.className+=" t",X.setAttribute("data-t","[title]map_controlls.select_bbox"),i18n.translate_ui(X),L.DomEvent.addListener(X,"click",re=>($(re.target).parent().hasClass("disabled")||(w.map.bboxfilter.isEnabled()?w.map.bboxfilter.disable():(w.map.bboxfilter.setBounds(w.map.getBounds().pad(-.2)),w.map.bboxfilter.enable()),$(re.target).toggleClass("fa-times-circle").toggleClass("fa-image")),!1),w.map),X=L.DomUtil.create("a","leaflet-control-buttons-fullscreen leaflet-bar-part",J),$('').appendTo($(X)),X.href="#",X.className+=" t",X.setAttribute("data-t","[title]map_controlls.toggle_wide_map"),i18n.translate_ui(X),L.DomEvent.addListener(X,"click",re=>($("#dataviewer").toggleClass("fullscreen"),w.map.invalidateSize(),$(re.target).toggleClass("fa-step-forward").toggleClass("fa-step-backward"),$("#editor").toggleClass("hidden"),$("#editor").resizable("option","disabled")?$("#editor").resizable("enable"):$("#editor").resizable("disable"),!1),w.map),X=L.DomUtil.create("a","leaflet-control-buttons-clearoverlay leaflet-bar-part leaflet-bar-part-bottom",J),$('').appendTo($(X)),X.href="#",X.className+=" t",X.setAttribute("data-t","[title]map_controlls.toggle_data"),i18n.translate_ui(X),L.DomEvent.addListener(X,"click",re=>(re.preventDefault(),w.map.hasLayer(overpass.osmLayer)?w.map.removeLayer(overpass.osmLayer):w.map.addLayer(overpass.osmLayer),!1),w.map),J}});w.map.addControl(new G),$(".leaflet-control-buttons > a").bind("dblclick",J=>J.stopPropagation()),$(".leaflet-control-buttons > a").tooltip({items:"a[title]",hide:{effect:"fadeOut",duration:100},position:{my:"left+5 center",at:"right center"}});const Y=L.Control.extend({options:{position:"topright"},onAdd(){const J=L.DomUtil.create("div","leaflet-control-search control has-icons-left");J.style.position="absolute",J.style.right="0";const X=L.DomUtil.create("input","input is-rounded",J);return $('').click(function(){$(this).prev().autocomplete("search")}).insertAfter(X),X.id="search",X.type="search",X.onclick=function(){this.focus()},J.ondblclick=function(re){re.stopPropagation()},$(X).autocomplete({source(re,ae){$.ajax(`https://search.osmnames.org/q/${encodeURIComponent(re.term)}.js?key=${configs.osmnamesApiKey}`,{success(oe){if(typeof oe=="string")try{oe=$.parseJSON(oe)}catch{}ae($.map(oe.results.slice(0,10),pe=>({label:pe.display_name,value:pe.display_name,lat:pe.lat,lon:pe.lon,boundingbox:pe.boundingbox})))},error(){console.error("An error occurred while contacting the search server osmnames.org :(")}})},minLength:2,autoFocus:!0,select(re,ae){return ae.item.boundingbox&&ae.item.boundingbox instanceof Array?w.map.fitBounds(L.latLngBounds([[ae.item.boundingbox[1],ae.item.boundingbox[0]],[ae.item.boundingbox[3],ae.item.boundingbox[2]]]),{maxZoom:18}):w.map.panTo(new L.LatLng(ae.item.lat,ae.item.lon)),this.value="",!1},open(){$(this).removeClass("ui-corner-all").addClass("ui-corner-top")},close(){$(this).addClass("ui-corner-all").removeClass("ui-corner-top")}}),$(X).autocomplete("option","delay",20),J}});w.map.addControl(new Y),$('').addClass("crosshairs").hide().appendTo("#map"),settings.enable_crosshairs&&$(".crosshairs").show(),w.map.bboxfilter=new L.LocationFilter({enable:!1,adjustButton:!1,enableButton:!1}).addTo(w.map),w.map.on("popupopen popupclose",J=>{if(typeof J.popup.layer<"u"){const X=J.popup.layer.placeholder||J.popup.layer,re=overpass.osmLayer._baseLayer.options.style(X.feature,J.type=="popupopen");typeof X.eachLayer!="function"?typeof X.setStyle=="function"&&X.setStyle(re):X.eachLayer(ae=>{typeof ae.setStyle=="function"&&ae.setStyle(re)})}}),overpass.init(),overpass.handlers.onProgress=function(J,X){w.waiter.addInfo(J,X)},overpass.handlers.onDone=function(){const J=w.getRawQuery().match(/@name ([^\n]+)/),X=J?`${J[1]} | `:"";w.waiter.close(X);const re=w.map.getBounds(),ae=overpass.osmLayer.getBaseLayer().getBounds();if(ae.isValid()&&!re.intersects(ae)){const oe=$(".leaflet-control-buttons-fitdata").tooltip("option","content");$(".leaflet-control-buttons-fitdata").tooltip("option","content",`← ${i18n.t("map_controlls.suggest_zoom_to_data")}`),$(".leaflet-control-buttons-fitdata").tooltip("open"),$(".leaflet-control-buttons-fitdata").tooltip("option","hide",{effect:"fadeOut",duration:1e3}),setTimeout(()=>{$(".leaflet-control-buttons-fitdata").tooltip("option","content",oe),$(".leaflet-control-buttons-fitdata").tooltip("close"),$(".leaflet-control-buttons-fitdata").tooltip("option","hide",{effect:"fadeOut",duration:100})},2600)}},overpass.handlers.onEmptyMap=function(J,X){const re=w.getRawQuery(),ae=/out[^;]+?count/.test(re);if(J=="no visible data")if(!ae&&!settings.no_autorepair){const oe=`

    ${i18n.t("warning.incomplete.expl.1")}

    ${i18n.t("warning.incomplete.expl.2")}

     ${i18n.t("warning.incomplete.not_again")}

    `,pe=[{name:i18n.t("dialog.repair_query"),callback(){w.repairQuery("no visible data")}},{name:i18n.t("dialog.show_data"),callback(){var fe,_e;(_e=(fe=$("input[name=hide_incomplete_data_warning]"))==null?void 0:fe[0])!=null&&_e.checked&&(settings.no_autorepair=!0,settings.save()),w.switchTab("Data")}}];showDialog(i18n.t("warning.incomplete.title"),oe,pe)}else ae&&w.switchTab("Data");J=="only areas returned"&&w.switchTab("Data"),J=="no coordinates returned"&&w.switchTab("Data"),X=="unknown"&&w.switchTab("Data"),$(`
    ${i18n.t("map.intentionally_blank")} (${J})
    `).appendTo("#map")},overpass.handlers.onDataReceived=function(J,X,re,ae){if(J>1e6){w.waiter.close();const oe=document.title;document.title=`❗ ${oe}`;const pe=[{name:i18n.t("dialog.abort"),callback(){document.title=oe,re()}},{name:i18n.t("dialog.continue_anyway"),callback(){document.title=oe,ae()}}],fe=`

    ${i18n.t("warning.huge_data.expl.1").replace("{{amount_txt}}",X)}

    ${i18n.t("warning.huge_data.expl.2")}

    `;showDialog(i18n.t("warning.huge_data.title"),fe,pe)}else ae()},overpass.handlers.onAbort=function(){w.waiter.close()},overpass.handlers.onAjaxError=function(J){w.waiter.close();const X=document.title;document.title=`❗ ${X}`;const re=[{name:i18n.t("dialog.dismiss"),callback(){document.title=X}}],ae=`

    ${i18n.t("error.ajax.expl")}

    ${J}`;showDialog(i18n.t("error.ajax.title"),ae,re),overpass.resultText&&w.dataViewer.setValue(overpass.resultText)},overpass.handlers.onQueryError=function(J){w.waiter.close();const X=document.title;document.title=`❗ ${X}`;const re=[{name:i18n.t("dialog.dismiss"),callback(){document.title=X}}],ae=`
    ${i18n.t("error.query.expl")}
    ${J}
    `;showDialog(i18n.t("error.query.title"),ae,re)},overpass.handlers.onStyleError=function(J){const X=[{name:i18n.t("dialog.dismiss")}],re=`

    ${i18n.t("error.mapcss.expl")}

    ${J}`;showDialog(i18n.t("error.mapcss.title"),re,X)},overpass.handlers.onQueryErrorLine=function(J){w.highlightError(J)},overpass.handlers.onRawDataPresent=function(){w.dataViewer.setOption("mode",overpass.resultType),w.dataViewer.setValue(overpass.resultText)},overpass.handlers.onGeoJsonReady=function(){if(w.map.addLayer(overpass.osmLayer),typeof w.run_query_on_startup=="function"&&w.run_query_on_startup(),$("#styler-button").show(),settings.show_data_stats){const J=overpass.stats,X=`${i18n.t("data_stats.loaded")} – ${i18n.t("data_stats.nodes")}: ${J.data.nodes}, ${i18n.t("data_stats.ways")}: ${J.data.ways}, ${i18n.t("data_stats.relations")}: ${J.data.relations}${J.data.areas>0?`, ${i18n.t("data_stats.areas")}: ${J.data.areas}`:""}
    ${i18n.t("data_stats.displayed")} – ${i18n.t("data_stats.pois")}: ${J.geojson.pois}, ${i18n.t("data_stats.lines")}: ${J.geojson.lines}, ${i18n.t("data_stats.polygons")}: ${J.geojson.polys}`;$(`
    ${X}
    `).insertAfter("#map .leaflet-control-attribution");const re=overpass.timestamp&&Date.now()-Date.parse(overpass.timestamp),ae=overpass.timestampAreas&&Date.now()-Date.parse(overpass.timestampAreas);$("#data_stats").tooltip({items:"div",tooltipClass:"stats",content(){let oe="
    ";if(overpass.ajax_request_duration){let pe=overpass.ajax_request_duration;pe.toLocaleString&&(pe=pe.toLocaleString()),oe+=`${i18n.t("data_stats.request_duration")}: ${pe}ms
    `}return overpass.timestamp&&(oe+=`${i18n.t("data_stats.lag")}: ${Math.floor(re/1e3)}s ${i18n.t("data_stats.lag.expl")}`),overpass.timestampAreas&&(oe+=`
    ${i18n.t("data_stats.lag_areas")}: ${Math.floor(ae/1e3)}s ${i18n.t("data_stats.lag.expl")}`),oe+="
    ",oe},hide:{effect:"fadeOut",duration:100},position:{my:"right bottom-5",at:"right top"}}),(re>24*60*60*1e3||ae>96*60*60*1e3)&&$("#data_stats").css("background-color","yellow")}},overpass.handlers.onPopupReady=function(J){J.openOn(w.map)},w.waiter.close(),w.run_query_on_startup===!0&&(w.update_map(),!x.has_coords&&x.has_query&&x.query.match(/\{\{(bbox|center)\}\}/)===null&&(w.run_query_on_startup=function(){w.run_query_on_startup=null;try{w.map.fitBounds(overpass.osmLayer.getBaseLayer().getBounds(),{maxZoom:18})}catch{}}))}onNominatimError(w,x){this.waiter.close();let Q=this.getRawQuery();Q=Q.split(` +`+H+"}":"{"+M.join(",")+"}",gap=H,S}}typeof JSON.stringify!="function"&&(meta={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},JSON.stringify=function(g,w,x){var Q;if(gap="",indent="",typeof x=="number")for(Q=0;Q{var R=(G,Y)=>{G?M(new Error(G)):H(Y)};_generatePkceChallenge(G=>x(G,R))}))};function x(H,M){var R=generateState(),G=g.url+"/oauth2/authorize?"+utilQsString({client_id:g.client_id,redirect_uri:g.redirect_uri,response_type:"code",scope:g.scope,state:R,code_challenge:H.code_challenge,code_challenge_method:H.code_challenge_method});if(g.singlepage){if(!store.enabled){var Y=new Error("local storage unavailable, but require in singlepage mode");Y.status="pkce-localstorage-unavailable",M(Y);return}var J=utilStringQs(window.location.search.slice(1));J.code?w.bootstrapToken(J.code,M):(S("oauth2_state",R),S("oauth2_pkce_code_verifier",H.code_verifier),window.location=G)}else{var X=600,re=550,ae=[["width",X],["height",re],["left",window.screen.width/2-X/2],["top",window.screen.height/2-re/2]].map(function(fe){return fe.join("=")}).join(","),oe=window.open("about:blank","oauth_window",ae);w.popupWindow=oe,oe.location=G,oe||(Y=new Error("Popup was blocked"),Y.status="popup-blocked",M(Y))}window.authComplete=function(fe){var _e=utilStringQs(fe.split("?")[1]);if(_e.state!==R){Y=new Error("Invalid state"),Y.status="invalid-state",M(Y);return}Q(_e.code,H.code_verifier,pe),delete window.authComplete};function pe(fe,_e){if(g.done(),fe){M(fe);return}var me=JSON.parse(_e.response);S("oauth2_access_token",me.access_token),M(null,w)}}function Q(H,M,R){var G=g.url+"/oauth2/token?"+utilQsString({client_id:g.client_id,redirect_uri:g.redirect_uri,grant_type:"authorization_code",code:H,code_verifier:M});w.rawxhr("POST",G,null,null,null,R),g.loading()}w.bringPopupWindowToFront=function(){var H=!1;try{w.popupWindow&&!w.popupWindow.closed&&(w.popupWindow.focus(),H=!0)}catch{}return H},w.bootstrapToken=function(H,M){var R=S("oauth2_state");S("oauth2_state","");var G=utilStringQs(window.location.search.slice(1));if(G.state!==R){var Y=new Error("Invalid state");Y.status="invalid-state",M(Y);return}var J=S("oauth2_pkce_code_verifier");S("oauth2_pkce_code_verifier",""),Q(H,J,X);function X(re,ae){if(g.done(),re){M(re);return}var oe=JSON.parse(ae.response);S("oauth2_access_token",oe.access_token),M(null,w)}},w.fetch=function(H,M){if(w.authenticated())return R();return g.auto?w.authenticateAsync().then(R):Promise.reject(new Error("not authenticated"));function R(){return M=M||{},M.headers||(M.headers={"Content-Type":"application/x-www-form-urlencoded"}),M.headers.Authorization="Bearer "+S("oauth2_access_token"),fetch(H,M)}},w.xhr=function(H,M){if(w.authenticated())return R();if(g.auto){w.authenticate(R);return}else{M("not authenticated",null);return}function R(){var Y=H.prefix!==!1?g.url+H.path:H.path;return w.rawxhr(H.method,Y,S("oauth2_access_token"),H.content,H.headers,G)}function G(Y,J){Y?M(Y):J.responseXML?M(Y,J.responseXML):M(Y,J.response)}},w.rawxhr=function(H,M,R,G,Y,J){Y=Y||{"Content-Type":"application/x-www-form-urlencoded"},R&&(Y.Authorization="Bearer "+R);var X=new XMLHttpRequest;X.onreadystatechange=function(){X.readyState===4&&X.status!==0&&(/^20\d$/.test(X.status)?J(null,X):J(X,null))},X.onerror=function(ae){J(ae,null)},X.open(H,M,!0);for(var re in Y)X.setRequestHeader(re,Y[re]);return X.send(G),X},w.preauth=function(H){return H&&H.access_token&&S("oauth2_access_token",H.access_token),w},w.options=function(H){return arguments.length?(g=H,g.url=g.url||"https://www.openstreetmap.org",g.auto=g.auto||!1,g.singlepage=g.singlepage||!1,g.loading=g.loading||function(){},g.done=g.done||function(){},w.preauth(g)):g};var S;if(store.enabled)S=function(H,M){if(arguments.length===1)return store.get(g.url+H);if(arguments.length===2)return store.set(g.url+H,M)};else{var D={};S=function(H,M){if(arguments.length===1)return D[g.url+H];if(arguments.length===2)return D[g.url+H]=M}}return w.options(g),w}function utilQsString(g){return Object.keys(g).filter(function(w){return g[w]!==void 0}).sort().map(function(w){return encodeURIComponent(w)+"="+encodeURIComponent(g[w])}).join("&")}function utilStringQs(g){for(var w=0;w{if(w)return g(w);loadQueries(g)})},save(g,w){auth.authenticated()?saveQuery(g,w):auth.authenticate(x=>{if(x)return w(x);saveQuery(g,w)})},delete(g,w){if(!auth.authenticated())return w(new Error("must be logged in to delete a synced query"));g={name:g,deleteMe:!0},saveQuery(g,w)},logout(){auth.authenticated()&&auth.logout()},authenticated(){return enabled&&auth.authenticated()}};function loadQueries(g){auth.xhr({method:"GET",path:"/api/0.6/user/preferences"},(w,x)=>{if(w)return g(w);let Q=0,S;(S=x.querySelector(`preference[k="${configs.settingNamespace}_query-count"]`))&&(Q=+S.getAttribute("v"));const D=[];for(let H=0;H{if(x)return w(x);const D=S.querySelector("preferences"),H=D.querySelectorAll(`preference[k^="${configs.settingNamespace}_query"]`);for(const G of H)G.remove();let M=!0;Q.forEach((G,Y)=>{G.name==g.name&&(G.query=g.query,M=Y)}),M===!0?Q.push(g):g.deleteMe&&Q.splice(M,1);const R=S.createElement("preference");R.setAttribute("k",`${configs.settingNamespace}_query-count`),R.setAttribute("v",Q.length),D.appendChild(R);for(let G=0;G200)return w(new Error("query name too long to be saved on osm.org"));const J=Math.ceil((Y.query.length+Y.name.length+8)/255);if(J>9)return w(new Error("query too long to be saved on osm.org"));let X=`p=${J}`;X+=`&n=${Y.name}`,X+=`&q=${Y.query}`,X=X.match(/.{1,255}/g);for(let re=0;re{if(G)return w(G);w(null,Q)})})}const cache={};class nominatim{static request(w,x){$.ajax(`https://nominatim.openstreetmap.org/search?X-Requested-With=${configs.appname}`,{data:{format:"json",q:w},success(Q){if(typeof Q=="string")try{Q=JSON.parse(Q)}catch{}cache[w]=Q,x(void 0,Q)},error(){const Q="An error occurred while contacting the osm search server nominatim.openstreetmap.org :(";console.log(Q),x(Q,null)}})}static get(w,x){return cache[w]===void 0?this.request(w,x):x(void 0,cache[w]),this}static getBest(w,x,Q){return Q||(Q=x,x=null),this.get(w,(S,D)=>{if(S){Q(S,null);return}x&&(D=D.filter(x)),D.length===0?Q("No result found",null):Q(S,D[0])}),this}}function map2bbox(g){let w;ide.map.bboxfilter&&ide.map.bboxfilter.isEnabled()?w=ide.map.bboxfilter.getBounds():w=ide.map.getBounds();const x=Math.min(Math.max(w.getSouthWest().lat,-90),90),Q=Math.min(Math.max(w.getNorthEast().lat,-90),90),S=Math.min(Math.max(w.getSouthWest().lng,-180),180),D=Math.min(Math.max(w.getNorthEast().lng,-180),180);if(g=="OverpassQL")return`${x},${S},${Q},${D}`;if(g=="xml")return`s="${x}" w="${S}" n="${Q}" e="${D}"`}function map2coord(g){const w=ide.map.getCenter();if(g=="OverpassQL")return`${w.lat},${w.lng}`;if(g=="xml")return`lat="${w.lat}" lon="${w.lng}"`}function relativeTime(g,w){const x=Date.now();if(g==""&&(g="0 seconds"),g=g.toLowerCase().match(/(-?[0-9]+) ?(seconds?|minutes?|hours?|days?|weeks?|months?|years?)?/),g===null){w("");return}const Q=parseInt(g[1]);let S;switch(g[2]){case"second":case"seconds":S=1;break;case"minute":case"minutes":S=60;break;case"hour":case"hours":S=3600;break;case"day":case"days":default:S=86400;break;case"week":case"weeks":S=604800;break;case"month":case"months":S=2628e3;break;case"year":case"years":S=31536e3;break}const D=x-Q*S*1e3;w(new Date(D).toISOString())}function geocodeId(g,w){const x=ide.getQueryLang();function Q(S){return S.osm_type&&S.osm_id}nominatim.getBest(g,Q,(S,D)=>{if(S)return ide.onNominatimError(g,"Id");x=="OverpassQL"?D=`${D.osm_type}(${D.osm_id})`:x=="xml"&&(D=`type="${D.osm_type}" ref="${D.osm_id}"`),w(D)})}function geocodeArea(g,w){const x=ide.getQueryLang();function Q(S){return S.osm_type&&S.osm_id&&S.osm_type!=="node"}nominatim.getBest(g,Q,(S,D)=>{if(S)return ide.onNominatimError(g,"Area");let H=1*D.osm_id;if(D.osm_type=="way"&&(H+=24e8),D.osm_type=="relation"&&(H+=36e8),x=="OverpassQL")return D.osm_type==="way"&&(H+=`,${D.osm_id}`),w(`area(id:${H})`);if(x=="xml")return D.osm_type==="way"&&(H+=`" ref_1="${D.osm_id}`),w(`type="area" ref="${H}"`)})}function geocodeBbox(g,w){const x=ide.getQueryLang();nominatim.getBest(g,(Q,S)=>{if(Q)return ide.onNominatimError(g,"Bbox");const D=Math.min(Math.max(S.boundingbox[0],-90),90),H=Math.min(Math.max(S.boundingbox[1],-90),90),M=Math.min(Math.max(S.boundingbox[2],-180),180),R=Math.min(Math.max(S.boundingbox[3],-180),180);x=="OverpassQL"?S=`${D},${M},${H},${R}`:x=="xml"&&(S=`s="${D}" w="${M}" n="${H}" e="${R}"`),w(S)})}function geocodeCoords(g,w){const x=ide.getQueryLang();nominatim.getBest(g,(Q,S)=>{if(Q)return ide.onNominatimError(g,"Coords");x=="OverpassQL"?S=`${S.lat},${S.lon}`:x=="xml"&&(S=`lat="${S.lat}" lon="${S.lon}"`),w(S)})}function shortcuts(){const g=ide.getQueryLang();return{bbox:map2bbox(g),center:map2coord(g),__bbox__global_bbox_xml__ezs4K8__:map2bbox("OverpassQL"),date:relativeTime,geocodeId,geocodeArea,geocodeBbox,geocodeCoords,nominatimId:g=="xml"?geocodeId:(w,x)=>geocodeId(w,Q=>x(`${Q};`)),nominatimArea:g=="xml"?geocodeArea:(w,x)=>geocodeArea(w,Q=>x(`${Q};`)),nominatimBbox:geocodeBbox,nominatimCoords:geocodeCoords}}let copyData;$(document).on("copy",g=>{copyData&&g.originalEvent&&g.originalEvent.clipboardData?(Object.keys(copyData).forEach(w=>{g.originalEvent.clipboardData.setData(w,copyData[w])}),g.originalEvent.preventDefault(),copyData=void 0):copyData&©Data["text/plain"]&&(prompt(i18n.t("export.copy_to_clipboard"),copyData["text/plain"]),copyData=null)});function make_combobox(g,w,x,Q){if(g[0].is_combobox){g.autocomplete("option",{source:w});return}const S=g.wrap("").parent().addClass("ui-combobox");g.autocomplete({source:w,minLength:0}).addClass("ui-widget ui-widget-content ui-corner-left ui-state-default").autocomplete("instance")._renderItem=(D,H)=>$("
  • ").append(x&&x.indexOf(H.value)!==-1?`
    ${H.label}
    `:`
    ${H.label}
    `).on("click",function(M){if(M.shiftKey&&x.indexOf(H.value)!==-1){Q(H.value),$(this).remove();const R=g.autocomplete("option","source");return R.splice(R.indexOf(H),1),g.autocomplete("option","source",R),!1}}).appendTo(D),$("").attr("tabIndex",-1).attr("title","show all items").appendTo(S).button({icons:{primary:"ui-icon-triangle-1-s"},text:!1}).removeClass("ui-corner-all").addClass("ui-corner-right ui-combobox-toggle").click(()=>{if(g.autocomplete("widget").is(":visible")){g.autocomplete("close");return}g.autocomplete("search",""),g.focus()}),g[0].is_combobox=!0}function showDialog(g,w,x){const Q=` `,S=$(Q);$(".delete",S).click(()=>$(S).remove());for(const D in x){const H=x[D];$(``).click(()=>{var M;(M=H.callback)==null||M.call(H),$(S).remove()}).appendTo($("footer .level-item",S))}S.appendTo("body")}class IDE{constructor(){this.attribControl=null,this.scaleControl=null,this.queryParser=new parser,this.run_query_on_startup=!1,this.codeEditor=null,this.dataViewer=null,this.map=null,this.waiter=new class{constructor(){this.opened=!0,this.frames=["◴","◷","◶","◵"],this.frameDelay=250,this.onAbort=void 0,this.interval=0,this._initialTitle=document.title}open(x){x?($(".modal .wait-info h4").text(x),$(".wait-info").show()):$(".wait-info").hide(),$("#loading-dialog").addClass("is-active"),document.title=`${this.frames[0]} ${this._initialTitle}`;let Q=0;this.interval=setInterval(()=>{const S=this.isAlert?this.alertFrame:this.frames[++Q%this.frames.length];document.title=`${S} ${this._initialTitle}`},this.frameDelay),this.opened=!0}close(x=""){this.opened&&(clearInterval(this.interval),document.title=`${x}${this._initialTitle}`,$("#loading-dialog").removeClass("is-active"),$(".wait-info ul li").remove(),delete this.onAbort,this.opened=!1)}addInfo(x,Q){$("#aborter").remove(),$(".wait-info ul li:nth-child(n+1)").css("opacity",.5),$(".wait-info ul li span.fas").removeClass("fa-spinner").removeClass("fa-spin").addClass("fa-check"),$(".wait-info ul li:nth-child(n+4)").hide();const S=$(`
  • ${x}
  • `);if(typeof Q=="function"){this.onAbort=Q;const D=$(' (abort)
    ').on("click",()=>(this.abort(),!1));S.append(D)}$(".wait-info ul").prepend(S)}abort(){typeof this.onAbort=="function"&&(this.addInfo("aborting"),this.onAbort(this.close))}}}init(){this.waiter.addInfo("ide starting up"),$("#overpass-turbo-version").html("overpass-turbo 2024-11-03/0ff477e"),$("#overpass-turbo-dependencies").html('@fortawesome/fontawesome-free 5.15.4 ((CC-BY-4.0 AND OFL-1.1 AND MIT)), @openstreetmap/id-tagging-schema 3.5.1 (ISC), bulma 0.9.4 (MIT), canvg 4.0.1 (MIT), codemirror 2.38.00 (undefined), colorbrewer 1.5.7 ([object Object]), colormap 2.3.2 (MIT), html2canvas 1.4.1 (MIT), jquery 3.7.1 (MIT), jquery-ui 1.13.2 (MIT), jquery-ui-dist 1.13.2 (MIT), leaflet 1.9.4 (BSD-2-Clause), leaflet-polylineoffset 1.1.1 (MIT), leaflet-locationfilter 0.1.3 (MIT), lodash 4.17.21 (MIT), osm-auth 2.2.0 (ISC), osmtogeojson 3.0.0-beta.5 (MIT), rgbcolor 1.0.1 (MIT OR SEE LICENSE IN FEEL-FREE.md), stackblur 1.0.0 (BSD-2-Clause), tag2link 2024.05.21 (ISC), togpx 0.5.4 (MIT), tokml 0.4.0 (BSD-2-Clause)'),($.support.cors!=!0||typeof function(){let w;try{localStorage.setItem("startup_localstorage_quota_test",123),localStorage.removeItem("startup_localstorage_quota_test"),w=localStorage}catch{}return w}()!="object")&&(this.not_supported=!0,$("#warning-unsupported-browser").addClass("is-active")),this.waiter.addInfo("load settings"),settings.load(),this.waiter.addInfo("translate ui"),i18n.translate().then(()=>this.initAfterI18n()),sync.enabled&&($("#load-dialog .osm").show(),sync.authenticated()&&($("#logout").show(),$("#logout").appendTo($("#logout").parent())))}initAfterI18n(){const w=this;w.waiter.addInfo("parse url parameters");const x=urlParameters();x.has_coords&&(settings.coords_lat=x.coords.lat,settings.coords_lon=x.coords.lng),x.has_zoom&&(settings.coords_zoom=x.zoom),x.run_query&&(w.run_query_on_startup=!0),settings.save(),w.waiter.addInfo("initialize page");const Q=$(window).width()/$(window).height()<.8;if(settings.editor_width!=""&&!Q&&($("#editor").css("width",settings.editor_width),$("#dataviewer").css("left",settings.editor_width)),Q&&$("#editor, #dataviewer").addClass("portrait"),$("#editor").resizable({handles:Q?"s":"e",minWidth:Q?void 0:"200",resize(){if(!Q)$(this).next().css("left",`${$(this).outerWidth()}px`);else{const J=$(this).offset().top+$(this).outerHeight();$(this).next().css("top",`${J}px`)}w.map.invalidateSize(!1)},stop(){Q||(settings.editor_width=$("#editor").css("width"),settings.save())}}),$("#editor").prepend(""),$("#editor textarea")[0].value=settings.code.overpass,settings.use_rich_editor){let J=0;CodeMirror.defineMIME("text/x-overpassQL",{name:"clike",keywords:function(X){const re={},ae=X.split(" ");for(const oe of ae)re[oe]=!0;return re}("out json xml custom popup timeout maxsize bbox date diff adiff foreach relation rel way node is_in area around user uid newer changed poly pivot nwr nw nr wr derived out meta body skel tags ids count qt asc center bb geom")}),CodeMirror.defineMIME("text/x-overpassXML","xml"),CodeMirror.defineMode("xml+mustache",X=>CodeMirror.multiplexingMode(CodeMirror.multiplexingMode(CodeMirror.getMode(X,"xml"),{open:"{{",close:"}}",mode:CodeMirror.getMode(X,"text/plain"),delimStyle:"mustache"}),{open:"{{style:",close:"}}",mode:CodeMirror.getMode(X,"text/css"),delimStyle:"mustache"})),CodeMirror.defineMode("ql+mustache",X=>CodeMirror.multiplexingMode(CodeMirror.multiplexingMode(CodeMirror.getMode(X,"text/x-overpassQL"),{open:"{{",close:"}}",mode:CodeMirror.getMode(X,"text/plain"),delimStyle:"mustache"}),{open:"{{style:",close:"}}",mode:CodeMirror.getMode(X,"text/css"),delimStyle:"mustache"})),w.codeEditor=CodeMirror.fromTextArea($("#editor textarea")[0],{lineNumbers:!0,lineWrapping:!0,mode:"text/plain",onChange(X){clearTimeout(J),J=setTimeout(()=>{w.getQueryLang()=="xml"?X.getOption("mode")!="xml+mustache"&&(X.closeTagEnabled=!0,X.setOption("matchBrackets",!1),X.setOption("mode","xml+mustache")):X.getOption("mode")!="ql+mustache"&&(X.closeTagEnabled=!1,X.setOption("matchBrackets",!0),X.setOption("mode","ql+mustache"));const re=$(".leaflet-control-buttons-bboxfilter");w.getRawQuery().match(/\{\{bbox\}\}/)?re.hasClass("disabled")&&(re.removeClass("disabled"),re.attr("data-t","[title]map_controlls.select_bbox"),i18n.translate_ui(re[0])):re.hasClass("disabled")||(re.addClass("disabled"),re.attr("data-t","[title]map_controlls.select_bbox_disabled"),i18n.translate_ui(re[0]))},500),settings.code.overpass=X.getValue(),settings.save()},closeTagEnabled:!0,closeTagIndent:["osm-script","query","union","foreach","difference"],extraKeys:{"'>'"(X){X.closeTag(X,">")},"'/'"(X){X.closeTag(X,"/")}}}),w.codeEditor.getOption("onChange")(w.codeEditor)}else w.codeEditor=$("#editor textarea")[0],w.codeEditor.getValue=function(){return this.value},w.codeEditor.setValue=function(J){this.value=J},w.codeEditor.lineCount=function(){return this.value.split(/\r\n|\r|\n/).length},w.codeEditor.setLineClass=function(){},$("#editor textarea").bind("input change",J=>{settings.code.overpass=J.target.getValue(),settings.save()});x.has_query&&w.codeEditor.setValue(x.query),w.dataViewer=CodeMirror($("#data")[0],{value:"no data loaded yet",lineNumbers:!0,readOnly:!0,mode:"javascript"}),w.map=new L.Map("map",{attributionControl:!1,minZoom:0,maxZoom:configs.maxMapZoom,worldCopyJump:!1});const S=settings.tile_server,D=configs.tileServerAttribution,H=new L.TileLayer(S,{attribution:D,noWrap:!0,maxNativeZoom:19,maxZoom:w.map.options.maxZoom}),M=new L.Control.Attribution({position:"bottomright"});M.addAttribution(D),M.addTo(w.map);const R=new L.LatLng(settings.coords_lat,settings.coords_lon);w.map.setView(R,settings.coords_zoom).addLayer(H),w.map.tile_layer=H,w.map.inv_opacity_layer=L.tileLayer("data:image/gif;base64,R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==").setOpacity(1-settings.background_opacity),settings.background_opacity!=1&&w.map.inv_opacity_layer.addTo(w.map),w.scaleControl=new L.Control.Scale({metric:!0,imperial:!1}),w.scaleControl.addTo(w.map),w.map.on("moveend",()=>{settings.coords_lat=w.map.getCenter().lat,settings.coords_lon=w.map.getCenter().lng,settings.coords_zoom=w.map.getZoom(),settings.save()}),$("#dataviewer > div#data")[0].style.zIndex=-1001,$(".tabs li").bind("click",J=>{$(J.target).hasClass("is-active")||($("#dataviewer > div#data")[0].style.zIndex=-1*$("#dataviewer > div#data")[0].style.zIndex,$(".tabs li").toggleClass("is-active"))}),$(document).keydown(J=>w.onKeyPress(J));const G=L.Control.extend({options:{position:"topleft"},onAdd(){const J=L.DomUtil.create("div","leaflet-control-buttons leaflet-bar");let X=L.DomUtil.create("a","leaflet-control-buttons-fitdata leaflet-bar-part leaflet-bar-part-top",J);return $('').appendTo($(X)),X.href="#",X.className+=" t",X.setAttribute("data-t","[title]map_controlls.zoom_to_data"),i18n.translate_ui(X),L.DomEvent.addListener(X,"click",()=>{try{w.map.fitBounds(overpass.osmLayer.getBaseLayer().getBounds(),{maxZoom:18})}catch{}return!1},w.map),X=L.DomUtil.create("a","leaflet-control-buttons-myloc leaflet-bar-part",J),$('').appendTo($(X)),X.href="#",X.className+=" t",X.setAttribute("data-t","[title]map_controlls.localize_user"),window.isSecureContext||(X.className+=" disabled",X.setAttribute("data-t","[title]map_controlls.localize_user_disabled")),i18n.translate_ui(X),L.DomEvent.addListener(X,"click",()=>{try{navigator.geolocation.getCurrentPosition(re=>{const ae=new L.LatLng(re.coords.latitude,re.coords.longitude);w.map.setView(ae,settings.coords_zoom)})}catch{}return!1},w.map),X=L.DomUtil.create("a","leaflet-control-buttons-bboxfilter leaflet-bar-part",J),$('').appendTo($(X)),X.href="#",X.className+=" t",X.setAttribute("data-t","[title]map_controlls.select_bbox"),i18n.translate_ui(X),L.DomEvent.addListener(X,"click",re=>($(re.target).parent().hasClass("disabled")||(w.map.bboxfilter.isEnabled()?w.map.bboxfilter.disable():(w.map.bboxfilter.setBounds(w.map.getBounds().pad(-.2)),w.map.bboxfilter.enable()),$(re.target).toggleClass("fa-times-circle").toggleClass("fa-image")),!1),w.map),X=L.DomUtil.create("a","leaflet-control-buttons-fullscreen leaflet-bar-part",J),$('').appendTo($(X)),X.href="#",X.className+=" t",X.setAttribute("data-t","[title]map_controlls.toggle_wide_map"),i18n.translate_ui(X),L.DomEvent.addListener(X,"click",re=>($("#dataviewer").toggleClass("fullscreen"),w.map.invalidateSize(),$(re.target).toggleClass("fa-step-forward").toggleClass("fa-step-backward"),$("#editor").toggleClass("hidden"),$("#editor").resizable("option","disabled")?$("#editor").resizable("enable"):$("#editor").resizable("disable"),!1),w.map),X=L.DomUtil.create("a","leaflet-control-buttons-clearoverlay leaflet-bar-part leaflet-bar-part-bottom",J),$('').appendTo($(X)),X.href="#",X.className+=" t",X.setAttribute("data-t","[title]map_controlls.toggle_data"),i18n.translate_ui(X),L.DomEvent.addListener(X,"click",re=>(re.preventDefault(),w.map.hasLayer(overpass.osmLayer)?w.map.removeLayer(overpass.osmLayer):w.map.addLayer(overpass.osmLayer),!1),w.map),J}});w.map.addControl(new G),$(".leaflet-control-buttons > a").bind("dblclick",J=>J.stopPropagation()),$(".leaflet-control-buttons > a").tooltip({items:"a[title]",hide:{effect:"fadeOut",duration:100},position:{my:"left+5 center",at:"right center"}});const Y=L.Control.extend({options:{position:"topright"},onAdd(){const J=L.DomUtil.create("div","leaflet-control-search control has-icons-left");J.style.position="absolute",J.style.right="0";const X=L.DomUtil.create("input","input is-rounded",J);return $('').click(function(){$(this).prev().autocomplete("search")}).insertAfter(X),X.id="search",X.type="search",X.onclick=function(){this.focus()},J.ondblclick=function(re){re.stopPropagation()},$(X).autocomplete({source(re,ae){$.ajax(`https://search.osmnames.org/q/${encodeURIComponent(re.term)}.js?key=${configs.osmnamesApiKey}`,{success(oe){if(typeof oe=="string")try{oe=$.parseJSON(oe)}catch{}ae($.map(oe.results.slice(0,10),pe=>({label:pe.display_name,value:pe.display_name,lat:pe.lat,lon:pe.lon,boundingbox:pe.boundingbox})))},error(){console.error("An error occurred while contacting the search server osmnames.org :(")}})},minLength:2,autoFocus:!0,select(re,ae){return ae.item.boundingbox&&ae.item.boundingbox instanceof Array?w.map.fitBounds(L.latLngBounds([[ae.item.boundingbox[1],ae.item.boundingbox[0]],[ae.item.boundingbox[3],ae.item.boundingbox[2]]]),{maxZoom:18}):w.map.panTo(new L.LatLng(ae.item.lat,ae.item.lon)),this.value="",!1},open(){$(this).removeClass("ui-corner-all").addClass("ui-corner-top")},close(){$(this).addClass("ui-corner-all").removeClass("ui-corner-top")}}),$(X).autocomplete("option","delay",20),J}});w.map.addControl(new Y),$('').addClass("crosshairs").hide().appendTo("#map"),settings.enable_crosshairs&&$(".crosshairs").show(),w.map.bboxfilter=new L.LocationFilter({enable:!1,adjustButton:!1,enableButton:!1}).addTo(w.map),w.map.on("popupopen popupclose",J=>{if(typeof J.popup.layer<"u"){const X=J.popup.layer.placeholder||J.popup.layer,re=overpass.osmLayer._baseLayer.options.style(X.feature,J.type=="popupopen");typeof X.eachLayer!="function"?typeof X.setStyle=="function"&&X.setStyle(re):X.eachLayer(ae=>{typeof ae.setStyle=="function"&&ae.setStyle(re)})}}),overpass.init(),overpass.handlers.onProgress=function(J,X){w.waiter.addInfo(J,X)},overpass.handlers.onDone=function(){const J=w.getRawQuery().match(/@name ([^\n]+)/),X=J?`${J[1]} | `:"";w.waiter.close(X);const re=w.map.getBounds(),ae=overpass.osmLayer.getBaseLayer().getBounds();if(ae.isValid()&&!re.intersects(ae)){const oe=$(".leaflet-control-buttons-fitdata").tooltip("option","content");$(".leaflet-control-buttons-fitdata").tooltip("option","content",`← ${i18n.t("map_controlls.suggest_zoom_to_data")}`),$(".leaflet-control-buttons-fitdata").tooltip("open"),$(".leaflet-control-buttons-fitdata").tooltip("option","hide",{effect:"fadeOut",duration:1e3}),setTimeout(()=>{$(".leaflet-control-buttons-fitdata").tooltip("option","content",oe),$(".leaflet-control-buttons-fitdata").tooltip("close"),$(".leaflet-control-buttons-fitdata").tooltip("option","hide",{effect:"fadeOut",duration:100})},2600)}},overpass.handlers.onEmptyMap=function(J,X){const re=w.getRawQuery(),ae=/out[^;]+?count/.test(re);if(J=="no visible data")if(!ae&&!settings.no_autorepair){const oe=`

    ${i18n.t("warning.incomplete.expl.1")}

    ${i18n.t("warning.incomplete.expl.2")}

     ${i18n.t("warning.incomplete.not_again")}

    `,pe=[{name:i18n.t("dialog.repair_query"),callback(){w.repairQuery("no visible data")}},{name:i18n.t("dialog.show_data"),callback(){var fe,_e;(_e=(fe=$("input[name=hide_incomplete_data_warning]"))==null?void 0:fe[0])!=null&&_e.checked&&(settings.no_autorepair=!0,settings.save()),w.switchTab("Data")}}];showDialog(i18n.t("warning.incomplete.title"),oe,pe)}else ae&&w.switchTab("Data");J=="only areas returned"&&w.switchTab("Data"),J=="no coordinates returned"&&w.switchTab("Data"),X=="unknown"&&w.switchTab("Data"),$(`
    ${i18n.t("map.intentionally_blank")} (${J})
    `).appendTo("#map")},overpass.handlers.onDataReceived=function(J,X,re,ae){if(J>1e6){w.waiter.close();const oe=document.title;document.title=`❗ ${oe}`;const pe=[{name:i18n.t("dialog.abort"),callback(){document.title=oe,re()}},{name:i18n.t("dialog.continue_anyway"),callback(){document.title=oe,ae()}}],fe=`

    ${i18n.t("warning.huge_data.expl.1").replace("{{amount_txt}}",X)}

    ${i18n.t("warning.huge_data.expl.2")}

    `;showDialog(i18n.t("warning.huge_data.title"),fe,pe)}else ae()},overpass.handlers.onAbort=function(){w.waiter.close()},overpass.handlers.onAjaxError=function(J){w.waiter.close();const X=document.title;document.title=`❗ ${X}`;const re=[{name:i18n.t("dialog.dismiss"),callback(){document.title=X}}],ae=`

    ${i18n.t("error.ajax.expl")}

    ${J}`;showDialog(i18n.t("error.ajax.title"),ae,re),overpass.resultText&&w.dataViewer.setValue(overpass.resultText)},overpass.handlers.onQueryError=function(J){w.waiter.close();const X=document.title;document.title=`❗ ${X}`;const re=[{name:i18n.t("dialog.dismiss"),callback(){document.title=X}}],ae=`
    ${i18n.t("error.query.expl")}
    ${J}
    `;showDialog(i18n.t("error.query.title"),ae,re)},overpass.handlers.onStyleError=function(J){const X=[{name:i18n.t("dialog.dismiss")}],re=`

    ${i18n.t("error.mapcss.expl")}

    ${J}`;showDialog(i18n.t("error.mapcss.title"),re,X)},overpass.handlers.onQueryErrorLine=function(J){w.highlightError(J)},overpass.handlers.onRawDataPresent=function(){w.dataViewer.setOption("mode",overpass.resultType),w.dataViewer.setValue(overpass.resultText)},overpass.handlers.onGeoJsonReady=function(){if(w.map.addLayer(overpass.osmLayer),typeof w.run_query_on_startup=="function"&&w.run_query_on_startup(),$("#styler-button").show(),settings.show_data_stats){const J=overpass.stats,X=`${i18n.t("data_stats.loaded")} – ${i18n.t("data_stats.nodes")}: ${J.data.nodes}, ${i18n.t("data_stats.ways")}: ${J.data.ways}, ${i18n.t("data_stats.relations")}: ${J.data.relations}${J.data.areas>0?`, ${i18n.t("data_stats.areas")}: ${J.data.areas}`:""}
    ${i18n.t("data_stats.displayed")} – ${i18n.t("data_stats.pois")}: ${J.geojson.pois}, ${i18n.t("data_stats.lines")}: ${J.geojson.lines}, ${i18n.t("data_stats.polygons")}: ${J.geojson.polys}`;$(`
    ${X}
    `).insertAfter("#map .leaflet-control-attribution");const re=overpass.timestamp&&Date.now()-Date.parse(overpass.timestamp),ae=overpass.timestampAreas&&Date.now()-Date.parse(overpass.timestampAreas);$("#data_stats").tooltip({items:"div",tooltipClass:"stats",content(){let oe="
    ";if(overpass.ajax_request_duration){let pe=overpass.ajax_request_duration;pe.toLocaleString&&(pe=pe.toLocaleString()),oe+=`${i18n.t("data_stats.request_duration")}: ${pe}ms
    `}return overpass.timestamp&&(oe+=`${i18n.t("data_stats.lag")}: ${Math.floor(re/1e3)}s ${i18n.t("data_stats.lag.expl")}`),overpass.timestampAreas&&(oe+=`
    ${i18n.t("data_stats.lag_areas")}: ${Math.floor(ae/1e3)}s ${i18n.t("data_stats.lag.expl")}`),oe+="
    ",oe},hide:{effect:"fadeOut",duration:100},position:{my:"right bottom-5",at:"right top"}}),(re>24*60*60*1e3||ae>96*60*60*1e3)&&$("#data_stats").css("background-color","yellow")}},overpass.handlers.onPopupReady=function(J){J.openOn(w.map)},w.waiter.close(),w.run_query_on_startup===!0&&(w.update_map(),!x.has_coords&&x.has_query&&x.query.match(/\{\{(bbox|center)\}\}/)===null&&(w.run_query_on_startup=function(){w.run_query_on_startup=null;try{w.map.fitBounds(overpass.osmLayer.getBaseLayer().getBounds(),{maxZoom:18})}catch{}}))}onNominatimError(w,x){this.waiter.close();let Q=this.getRawQuery();Q=Q.split(` `),Q.forEach((H,M)=>{H.indexOf(`{{geocode${x}:${w}}}`)!==-1&&this.highlightError(M+1)});const S=[{name:i18n.t("dialog.dismiss")}],D=`

    ${i18n.t("error.nominatim.expl")}

    ${htmlentities(w)}

    `;showDialog(i18n.t("error.nominatim.title"),D,S)}getRawQuery(){return this.codeEditor.getValue()}async getQuery(){let w=this.getRawQuery();w=w.replace(/(]+bbox[^=]*=[^"'']*["'])({{bbox}})(["'])/,"$1{{__bbox__global_bbox_xml__ezs4K8__}}$3"),w=await this.queryParser.parse(w,shortcuts());let x="";this.queryParser.hasStatement("style")&&(x=this.queryParser.getStatement("style")),this.mapcss=x;let Q=null;if(this.queryParser.hasStatement("data")){Q=this.queryParser.getStatement("data"),Q=Q.split(",");const S=Q[0].toLowerCase();Q=Q.slice(1);const D={};for(const H of Q){const M=H.split("=");D[M[0]]=M[1]}Q={mode:S,options:D}}return this.data_source=Q,w}setQuery(w){this.codeEditor.setValue(w)}getQueryLang(){return $.trim(this.getRawQuery().replace(/{{.*?}}/g,"")).match(/^{delete settings.saves[w],settings.save(),this.onLoadClick()}},{name:i18n.t("dialog.cancel")}],Q=`

    ${i18n.t("dialog.delete_query.expl")}: "${w}"?

    `;showDialog(i18n.t("dialog.delete_query.title"),Q,x)}removeExampleSync(w,x){const Q=[{name:i18n.t("dialog.delete"),callback(){sync.delete(w.name,D=>{if(D)return console.error(D);$(x).parent().remove()})}},{name:i18n.t("dialog.cancel")}],S=`

    ${i18n.t("dialog.delete_query.expl-osm")}: "${w.name}"?

    `;showDialog(i18n.t("dialog.delete_query.title"),S,Q)}onLoadClick(){const w=this;$("#load-dialog .panel.saved_query .panel-block").remove(),$("#load-dialog .panel.example .panel-block").remove();let x=!1;for(const Q in settings.saves){const S=settings.saves[Q].type;S!="template"&&($('').attr("href","#").text(Q).on("click",()=>(w.loadExample(Q),$("#load-dialog").removeClass("is-active"),!1)).append($('`).on("click",()=>{w.loadOsmQueries()})).appendTo(Q)):Q.hide()}}loadOsmQueries(){const w=this,x=$("#load-dialog .panel.osm-queries");x.show(),x.find(".panel-block").remove(),$('
    ').text(i18n.t("load.saved_queries-osm-loading")).appendTo(x),sync.load((Q,S)=>{if(Q)return x.find(".panel-block").remove(),$('
    ').text(i18n.t("load.saved_queries-osm-error")).appendTo(x),console.error(Q);x.find(".panel-block").remove(),$("#logout").show(),$("#logout").appendTo($("#logout").parent()),S.forEach(D=>{$('').attr("href","#").text(D.name).on("click",()=>(w.setQuery(lzw_decode(Base64.decode(D.query))),$("#load-dialog").removeClass("is-active"),!1)).append($('\\\n \\\n
    \\\n ${content}\\\n
    \\\n
    \\\n
    \\\n
    \\\n
    \\\n
    \\\n
    \\\n
    \\\n
    \\\n
    \\\n
    \\\n `;\n\n // Create modal in body\n const element = $(dialogContent);\n // Handle close event\n $(\".delete\", element).click(() => $(element).remove());\n\n // Add all the buttons\n for (const index in buttons) {\n const button = buttons[index];\n $(``)\n .click(() => {\n button.callback?.();\n // destroy modal dialog after callback, see #528\n $(element).remove();\n })\n .appendTo($(\"footer .level-item\", element));\n }\n\n // Add the element to the body\n element.appendTo(\"body\");\n}\n\nclass IDE {\n // == private members ==\n private attribControl = null;\n private scaleControl = null;\n private queryParser = new Query();\n private run_query_on_startup = false;\n // == public members ==\n codeEditor = null;\n dataViewer = null;\n map: L.Map = null;\n\n // == public sub objects ==\n\n waiter = new (class Waiter {\n opened = true;\n frames = [\"◴\", \"◷\", \"◶\", \"◵\"];\n frameDelay = 250;\n onAbort = undefined;\n interval = 0;\n _initialTitle = document.title;\n\n open(show_info) {\n if (show_info) {\n $(\".modal .wait-info h4\").text(show_info);\n $(\".wait-info\").show();\n } else {\n $(\".wait-info\").hide();\n }\n $(\"#loading-dialog\").addClass(\"is-active\");\n document.title = `${this.frames[0]} ${this._initialTitle}`;\n let f = 0;\n this.interval = setInterval(() => {\n const title = this.isAlert\n ? this.alertFrame\n : this.frames[++f % this.frames.length];\n document.title = `${title} ${this._initialTitle}`;\n }, this.frameDelay);\n this.opened = true;\n }\n close(title_prefix = \"\") {\n if (!this.opened) return;\n clearInterval(this.interval);\n document.title = `${title_prefix}${this._initialTitle}`;\n $(\"#loading-dialog\").removeClass(\"is-active\");\n $(\".wait-info ul li\").remove();\n delete this.onAbort;\n this.opened = false;\n }\n addInfo(txt, abortCallback) {\n $(\"#aborter\").remove(); // remove previously added abort button, which cannot be used anymore.\n $(\".wait-info ul li:nth-child(n+1)\").css(\"opacity\", 0.5);\n $(\".wait-info ul li span.fas\")\n .removeClass(\"fa-spinner\")\n .removeClass(\"fa-spin\")\n .addClass(\"fa-check\");\n $(\".wait-info ul li:nth-child(n+4)\").hide();\n const li = $(\n `
  • ${txt}
  • `\n );\n if (typeof abortCallback == \"function\") {\n this.onAbort = abortCallback;\n const aborter = $(\n ' (
    abort)
    '\n ).on(\"click\", () => {\n this.abort();\n return false;\n });\n li.append(aborter);\n }\n $(\".wait-info ul\").prepend(li);\n }\n abort() {\n if (typeof this.onAbort == \"function\") {\n this.addInfo(\"aborting\");\n this.onAbort(this.close);\n }\n }\n })();\n\n // == public methods ==\n\n init() {\n this.waiter.addInfo(\"ide starting up\");\n $(\"#overpass-turbo-version\").html(\n `overpass-turbo ${GIT_VERSION}` // eslint-disable-line no-undef\n );\n $(\"#overpass-turbo-dependencies\").html(\n APP_DEPENDENCIES // eslint-disable-line no-undef\n );\n // (very raw) compatibility check <- TODO: put this into its own function\n if (\n jQuery.support.cors != true ||\n //typeof localStorage != \"object\" ||\n typeof (function () {\n let ls = undefined;\n try {\n localStorage.setItem(\"startup_localstorage_quota_test\", 123);\n localStorage.removeItem(\"startup_localstorage_quota_test\");\n ls = localStorage;\n } catch (e) {}\n return ls;\n })() != \"object\" ||\n false\n ) {\n // the currently used browser is not capable of running the IDE. :(\n this.not_supported = true;\n $(\"#warning-unsupported-browser\").addClass(\"is-active\");\n }\n // load settings\n this.waiter.addInfo(\"load settings\");\n settings.load();\n // translate ui\n this.waiter.addInfo(\"translate ui\");\n i18n.translate().then(() => this.initAfterI18n());\n\n if (sync.enabled) {\n $(\"#load-dialog .osm\").show();\n if (sync.authenticated()) {\n $(\"#logout\").show();\n $(\"#logout\").appendTo($(\"#logout\").parent());\n }\n }\n }\n\n initAfterI18n() {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const ide = this;\n // parse url string parameters\n ide.waiter.addInfo(\"parse url parameters\");\n const args = urlParameters();\n // set appropriate settings\n if (args.has_coords) {\n // map center coords set via url\n settings.coords_lat = args.coords.lat;\n settings.coords_lon = args.coords.lng;\n }\n if (args.has_zoom) {\n // map zoom set via url\n settings.coords_zoom = args.zoom;\n }\n if (args.run_query) {\n // query autorun activated via url\n ide.run_query_on_startup = true;\n }\n settings.save();\n\n ide.waiter.addInfo(\"initialize page\");\n // init page layout\n const isInitialAspectPortrait =\n $(window).width() / $(window).height() < 0.8;\n if (settings.editor_width != \"\" && !isInitialAspectPortrait) {\n $(\"#editor\").css(\"width\", settings.editor_width);\n $(\"#dataviewer\").css(\"left\", settings.editor_width);\n }\n if (isInitialAspectPortrait) {\n $(\"#editor, #dataviewer\").addClass(\"portrait\");\n }\n // make panels resizable\n $(\"#editor\").resizable({\n handles: isInitialAspectPortrait ? \"s\" : \"e\",\n minWidth: isInitialAspectPortrait ? undefined : \"200\",\n resize() {\n if (!isInitialAspectPortrait) {\n $(this)\n .next()\n .css(\"left\", `${$(this).outerWidth()}px`);\n } else {\n const top = $(this).offset().top + $(this).outerHeight();\n $(this).next().css(\"top\", `${top}px`);\n }\n ide.map.invalidateSize(false);\n },\n stop() {\n if (isInitialAspectPortrait) return;\n settings.editor_width = $(\"#editor\").css(\"width\");\n settings.save();\n }\n });\n $(\"#editor\").prepend(\n \"\"\n );\n\n // init codemirror\n $(\"#editor textarea\")[0].value = settings.code[\"overpass\"];\n if (settings.use_rich_editor) {\n let pending = 0;\n CodeMirror.defineMIME(\"text/x-overpassQL\", {\n name: \"clike\",\n keywords: (function (str) {\n const r = {};\n const a = str.split(\" \");\n for (const ai of a) r[ai] = true;\n return r;\n })(\n \"out json xml custom popup timeout maxsize bbox\" + // initial declarations\n \" date diff adiff\" + //attic declarations\n \" foreach\" + // block statements\n \" relation rel way node is_in area around user uid newer changed poly pivot nwr nw nr wr derived\" + // queries\n \" out meta body skel tags ids count qt asc\" + // actions\n \" center bb geom\" // geometry types\n //+\"r w n br bw\" // recursors\n )\n });\n CodeMirror.defineMIME(\"text/x-overpassXML\", \"xml\");\n CodeMirror.defineMode(\"xml+mustache\", (config) =>\n CodeMirror.multiplexingMode(\n CodeMirror.multiplexingMode(CodeMirror.getMode(config, \"xml\"), {\n open: \"{{\",\n close: \"}}\",\n mode: CodeMirror.getMode(config, \"text/plain\"),\n delimStyle: \"mustache\"\n }),\n {\n open: \"{{style:\",\n close: \"}}\",\n mode: CodeMirror.getMode(config, \"text/css\"),\n delimStyle: \"mustache\"\n }\n )\n );\n CodeMirror.defineMode(\"ql+mustache\", (config) =>\n CodeMirror.multiplexingMode(\n CodeMirror.multiplexingMode(\n CodeMirror.getMode(config, \"text/x-overpassQL\"),\n {\n open: \"{{\",\n close: \"}}\",\n mode: CodeMirror.getMode(config, \"text/plain\"),\n delimStyle: \"mustache\"\n }\n ),\n {\n open: \"{{style:\",\n close: \"}}\",\n mode: CodeMirror.getMode(config, \"text/css\"),\n delimStyle: \"mustache\"\n }\n )\n );\n ide.codeEditor = CodeMirror.fromTextArea($(\"#editor textarea\")[0], {\n //value: settings.code[\"overpass\"],\n lineNumbers: true,\n lineWrapping: true,\n mode: \"text/plain\",\n onChange(e) {\n clearTimeout(pending);\n pending = setTimeout(() => {\n // update syntax highlighting mode\n if (ide.getQueryLang() == \"xml\") {\n if (e.getOption(\"mode\") != \"xml+mustache\") {\n e.closeTagEnabled = true;\n e.setOption(\"matchBrackets\", false);\n e.setOption(\"mode\", \"xml+mustache\");\n }\n } else {\n if (e.getOption(\"mode\") != \"ql+mustache\") {\n e.closeTagEnabled = false;\n e.setOption(\"matchBrackets\", true);\n e.setOption(\"mode\", \"ql+mustache\");\n }\n }\n // check for inactive ui elements\n const bbox_filter = $(\".leaflet-control-buttons-bboxfilter\");\n if (ide.getRawQuery().match(/\\{\\{bbox\\}\\}/)) {\n if (bbox_filter.hasClass(\"disabled\")) {\n bbox_filter.removeClass(\"disabled\");\n bbox_filter.attr(\"data-t\", \"[title]map_controlls.select_bbox\");\n i18n.translate_ui(bbox_filter[0]);\n }\n } else {\n if (!bbox_filter.hasClass(\"disabled\")) {\n bbox_filter.addClass(\"disabled\");\n bbox_filter.attr(\n \"data-t\",\n \"[title]map_controlls.select_bbox_disabled\"\n );\n i18n.translate_ui(bbox_filter[0]);\n }\n }\n }, 500);\n settings.code[\"overpass\"] = e.getValue();\n settings.save();\n },\n closeTagEnabled: true,\n closeTagIndent: [\n \"osm-script\",\n \"query\",\n \"union\",\n \"foreach\",\n \"difference\"\n ],\n extraKeys: {\n \"'>'\"(cm) {\n cm.closeTag(cm, \">\");\n },\n \"'/'\"(cm) {\n cm.closeTag(cm, \"/\");\n }\n }\n });\n // fire onChange after initialization\n ide.codeEditor.getOption(\"onChange\")(ide.codeEditor);\n } else {\n // use non-rich editor\n ide.codeEditor = $(\"#editor textarea\")[0];\n ide.codeEditor.getValue = function () {\n return this.value;\n };\n ide.codeEditor.setValue = function (v) {\n this.value = v;\n };\n ide.codeEditor.lineCount = function () {\n return this.value.split(/\\r\\n|\\r|\\n/).length;\n };\n ide.codeEditor.setLineClass = function () {};\n $(\"#editor textarea\").bind(\"input change\", (e) => {\n settings.code[\"overpass\"] = e.target.getValue();\n settings.save();\n });\n }\n // set query if provided as url parameter or template:\n if (args.has_query) {\n // query set via url\n ide.codeEditor.setValue(args.query);\n }\n // init dataviewer\n ide.dataViewer = CodeMirror($(\"#data\")[0], {\n value: \"no data loaded yet\",\n lineNumbers: true,\n readOnly: true,\n mode: \"javascript\"\n });\n\n // init leaflet\n ide.map = new L.Map(\"map\", {\n attributionControl: false,\n minZoom: 0,\n maxZoom: configs.maxMapZoom,\n worldCopyJump: false\n });\n const tilesUrl = settings.tile_server;\n const tilesAttrib = configs.tileServerAttribution;\n const tiles = new L.TileLayer(tilesUrl, {\n attribution: tilesAttrib,\n noWrap: true,\n maxNativeZoom: 19,\n maxZoom: ide.map.options.maxZoom\n });\n const attribControl = new L.Control.Attribution({position: \"bottomright\"});\n attribControl.addAttribution(tilesAttrib);\n attribControl.addTo(ide.map);\n const pos = new L.LatLng(settings.coords_lat, settings.coords_lon);\n ide.map.setView(pos, settings.coords_zoom).addLayer(tiles);\n ide.map.tile_layer = tiles;\n // inverse opacity layer\n ide.map.inv_opacity_layer = L.tileLayer(\n \"data:image/gif;base64,R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==\"\n ).setOpacity(1 - settings.background_opacity);\n if (settings.background_opacity != 1)\n ide.map.inv_opacity_layer.addTo(ide.map);\n ide.scaleControl = new L.Control.Scale({metric: true, imperial: false});\n ide.scaleControl.addTo(ide.map);\n ide.map.on(\"moveend\", () => {\n settings.coords_lat = ide.map.getCenter().lat;\n settings.coords_lon = ide.map.getCenter().lng;\n settings.coords_zoom = ide.map.getZoom();\n settings.save(); // save settings\n });\n\n // tabs\n $(\"#dataviewer > div#data\")[0].style.zIndex = -1001;\n $(\".tabs li\").bind(\"click\", (e) => {\n if ($(e.target).hasClass(\"is-active\")) {\n return;\n } else {\n $(\"#dataviewer > div#data\")[0].style.zIndex =\n -1 * $(\"#dataviewer > div#data\")[0].style.zIndex;\n $(\".tabs li\").toggleClass(\"is-active\");\n }\n });\n\n // keyboard event listener\n $(document).keydown((event) => ide.onKeyPress(event));\n\n // leaflet extension: more map controls\n const MapButtons = L.Control.extend({\n options: {\n position: \"topleft\"\n },\n onAdd() {\n // create the control container with a particular class name\n const container = L.DomUtil.create(\n \"div\",\n \"leaflet-control-buttons leaflet-bar\"\n );\n let link = L.DomUtil.create(\n \"a\",\n \"leaflet-control-buttons-fitdata leaflet-bar-part leaflet-bar-part-top\",\n container\n );\n $('').appendTo($(link));\n link.href = \"#\";\n link.className += \" t\";\n link.setAttribute(\"data-t\", \"[title]map_controlls.zoom_to_data\");\n i18n.translate_ui(link);\n L.DomEvent.addListener(\n link,\n \"click\",\n () => {\n // hardcoded maxZoom of 18, should be ok for most real-world use-cases\n try {\n ide.map.fitBounds(overpass.osmLayer.getBaseLayer().getBounds(), {\n maxZoom: 18\n });\n } catch (e) {}\n return false;\n },\n ide.map\n );\n link = L.DomUtil.create(\n \"a\",\n \"leaflet-control-buttons-myloc leaflet-bar-part\",\n container\n );\n $('').appendTo($(link));\n link.href = \"#\";\n link.className += \" t\";\n link.setAttribute(\"data-t\", \"[title]map_controlls.localize_user\");\n if (!window.isSecureContext) {\n link.className += \" disabled\";\n link.setAttribute(\n \"data-t\",\n \"[title]map_controlls.localize_user_disabled\"\n );\n }\n i18n.translate_ui(link);\n L.DomEvent.addListener(\n link,\n \"click\",\n () => {\n // One-shot position request.\n try {\n navigator.geolocation.getCurrentPosition((position) => {\n const pos = new L.LatLng(\n position.coords.latitude,\n position.coords.longitude\n );\n ide.map.setView(pos, settings.coords_zoom);\n });\n } catch (e) {}\n return false;\n },\n ide.map\n );\n link = L.DomUtil.create(\n \"a\",\n \"leaflet-control-buttons-bboxfilter leaflet-bar-part\",\n container\n );\n $('').appendTo($(link));\n link.href = \"#\";\n link.className += \" t\";\n link.setAttribute(\"data-t\", \"[title]map_controlls.select_bbox\");\n i18n.translate_ui(link);\n L.DomEvent.addListener(\n link,\n \"click\",\n (e) => {\n if (\n $(e.target).parent().hasClass(\"disabled\") // check if this button is enabled\n )\n return false;\n if (!ide.map.bboxfilter.isEnabled()) {\n ide.map.bboxfilter.setBounds(ide.map.getBounds().pad(-0.2));\n ide.map.bboxfilter.enable();\n } else {\n ide.map.bboxfilter.disable();\n }\n $(e.target).toggleClass(\"fa-times-circle\").toggleClass(\"fa-image\");\n return false;\n },\n ide.map\n );\n link = L.DomUtil.create(\n \"a\",\n \"leaflet-control-buttons-fullscreen leaflet-bar-part\",\n container\n );\n $('').appendTo($(link));\n link.href = \"#\";\n link.className += \" t\";\n link.setAttribute(\"data-t\", \"[title]map_controlls.toggle_wide_map\");\n i18n.translate_ui(link);\n L.DomEvent.addListener(\n link,\n \"click\",\n (e) => {\n $(\"#dataviewer\").toggleClass(\"fullscreen\");\n ide.map.invalidateSize();\n $(e.target)\n .toggleClass(\"fa-step-forward\")\n .toggleClass(\"fa-step-backward\");\n $(\"#editor\").toggleClass(\"hidden\");\n if ($(\"#editor\").resizable(\"option\", \"disabled\"))\n $(\"#editor\").resizable(\"enable\");\n else $(\"#editor\").resizable(\"disable\");\n return false;\n },\n ide.map\n );\n link = L.DomUtil.create(\n \"a\",\n \"leaflet-control-buttons-clearoverlay leaflet-bar-part leaflet-bar-part-bottom\",\n container\n );\n $('').appendTo($(link));\n link.href = \"#\";\n link.className += \" t\";\n link.setAttribute(\"data-t\", \"[title]map_controlls.toggle_data\");\n i18n.translate_ui(link);\n L.DomEvent.addListener(\n link,\n \"click\",\n (e) => {\n e.preventDefault();\n if (ide.map.hasLayer(overpass.osmLayer))\n ide.map.removeLayer(overpass.osmLayer);\n else ide.map.addLayer(overpass.osmLayer);\n return false;\n },\n ide.map\n );\n return container;\n }\n });\n ide.map.addControl(new MapButtons());\n // prevent propagation of doubleclicks on map controls\n $(\".leaflet-control-buttons > a\").bind(\"dblclick\", (e) =>\n e.stopPropagation()\n );\n // add tooltips to map controls\n $(\".leaflet-control-buttons > a\").tooltip({\n items: \"a[title]\",\n hide: {\n effect: \"fadeOut\",\n duration: 100\n },\n position: {\n my: \"left+5 center\",\n at: \"right center\"\n }\n });\n // leaflet extension: search box\n const SearchBox = L.Control.extend({\n options: {\n position: \"topright\"\n },\n onAdd() {\n const container = L.DomUtil.create(\n \"div\",\n \"leaflet-control-search control has-icons-left\"\n );\n container.style.position = \"absolute\";\n container.style.right = \"0\";\n const inp = L.DomUtil.create(\"input\", \"input is-rounded\", container);\n $('')\n .click(function () {\n $(this).prev().autocomplete(\"search\");\n })\n .insertAfter(inp);\n inp.id = \"search\";\n inp.type = \"search\";\n // hack against focus stealing leaflet :/\n inp.onclick = function () {\n this.focus();\n };\n // prevent propagation of doubleclicks to map container\n container.ondblclick = function (e) {\n e.stopPropagation();\n };\n // autocomplete functionality\n $(inp).autocomplete({\n source(request, response) {\n // ajax (GET) request to nominatim\n $.ajax(\n `https://search.osmnames.org/q/${encodeURIComponent(\n request.term\n )}.js?key=${configs.osmnamesApiKey}`,\n {\n success(data) {\n // hacky firefox hack :( (it is not properly detecting json from the content-type header)\n if (typeof data == \"string\") {\n // if the data is a string, but looks more like a json object\n try {\n data = $.parseJSON(data);\n } catch (e) {}\n }\n response(\n $.map(data.results.slice(0, 10), (item) => ({\n label: item.display_name,\n value: item.display_name,\n lat: item.lat,\n lon: item.lon,\n boundingbox: item.boundingbox\n }))\n );\n },\n error() {\n // todo: better error handling\n console.error(\n \"An error occurred while contacting the search server osmnames.org :(\"\n );\n }\n }\n );\n },\n minLength: 2,\n autoFocus: true,\n select(event, ui) {\n if (ui.item.boundingbox && ui.item.boundingbox instanceof Array)\n ide.map.fitBounds(\n L.latLngBounds([\n [ui.item.boundingbox[1], ui.item.boundingbox[0]],\n [ui.item.boundingbox[3], ui.item.boundingbox[2]]\n ]),\n {maxZoom: 18}\n );\n else ide.map.panTo(new L.LatLng(ui.item.lat, ui.item.lon));\n this.value = \"\";\n return false;\n },\n open() {\n $(this).removeClass(\"ui-corner-all\").addClass(\"ui-corner-top\");\n },\n close() {\n $(this).addClass(\"ui-corner-all\").removeClass(\"ui-corner-top\");\n }\n });\n $(inp).autocomplete(\"option\", \"delay\", 20);\n return container;\n }\n });\n ide.map.addControl(new SearchBox());\n // add cross hairs to map\n $('')\n .addClass(\"crosshairs\")\n .hide()\n .appendTo(\"#map\");\n if (settings.enable_crosshairs) $(\".crosshairs\").show();\n\n ide.map.bboxfilter = new L.LocationFilter({\n enable: !true,\n adjustButton: false,\n enableButton: false\n }).addTo(ide.map);\n\n ide.map.on(\"popupopen popupclose\", (e) => {\n if (typeof e.popup.layer != \"undefined\") {\n const layer = e.popup.layer.placeholder || e.popup.layer;\n // re-call style handler to eventually modify the style of the clicked feature\n const stl = overpass.osmLayer._baseLayer.options.style(\n layer.feature,\n e.type == \"popupopen\"\n );\n if (typeof layer.eachLayer != \"function\") {\n if (typeof layer.setStyle == \"function\") layer.setStyle(stl); // other objects (pois, ways)\n } else\n layer.eachLayer((layer) => {\n if (typeof layer.setStyle == \"function\") layer.setStyle(stl);\n }); // for multipolygons!\n }\n });\n\n // init overpass object\n overpass.init();\n\n // event handlers for overpass object\n overpass.handlers[\"onProgress\"] = function (msg, abortcallback) {\n ide.waiter.addInfo(msg, abortcallback);\n };\n overpass.handlers[\"onDone\"] = function () {\n const name_match = ide.getRawQuery().match(/@name ([^\\n]+)/);\n // parse document title from @name in query\n const title_prefix = name_match ? `${name_match[1]} | ` : \"\";\n ide.waiter.close(title_prefix);\n const map_bounds = ide.map.getBounds();\n const data_bounds = overpass.osmLayer.getBaseLayer().getBounds();\n if (data_bounds.isValid() && !map_bounds.intersects(data_bounds)) {\n // show tooltip for button \"zoom to data\"\n const prev_content = $(\".leaflet-control-buttons-fitdata\").tooltip(\n \"option\",\n \"content\"\n );\n $(\".leaflet-control-buttons-fitdata\").tooltip(\n \"option\",\n \"content\",\n `← ${i18n.t(\"map_controlls.suggest_zoom_to_data\")}`\n );\n $(\".leaflet-control-buttons-fitdata\").tooltip(\"open\");\n $(\".leaflet-control-buttons-fitdata\").tooltip(\"option\", \"hide\", {\n effect: \"fadeOut\",\n duration: 1000\n });\n setTimeout(() => {\n $(\".leaflet-control-buttons-fitdata\").tooltip(\n \"option\",\n \"content\",\n prev_content\n );\n $(\".leaflet-control-buttons-fitdata\").tooltip(\"close\");\n $(\".leaflet-control-buttons-fitdata\").tooltip(\"option\", \"hide\", {\n effect: \"fadeOut\",\n duration: 100\n });\n }, 2600);\n }\n };\n overpass.handlers[\"onEmptyMap\"] = function (empty_msg, data_mode) {\n // get the current query\n const query = ide.getRawQuery();\n\n // check if 'out' followed by any number of characters (non-greedy) and then 'count' is present in the query\n const isCountPresent = /out[^;]+?count/.test(query);\n\n // show warning/info if only invisible data is returned and 'out...count' is not present in the query\n if (empty_msg == \"no visible data\") {\n if (!isCountPresent && !settings.no_autorepair) {\n const content = `

    ${i18n.t(\n \"warning.incomplete.expl.1\"\n )}

    ${i18n.t(\n \"warning.incomplete.expl.2\"\n )}

     ${i18n.t(\n \"warning.incomplete.not_again\"\n )}

    `;\n\n const dialog_buttons = [\n {\n name: i18n.t(\"dialog.repair_query\"),\n callback() {\n ide.repairQuery(\"no visible data\");\n }\n },\n {\n name: i18n.t(\"dialog.show_data\"),\n callback() {\n if (\n $(\"input[name=hide_incomplete_data_warning]\")?.[0]?.checked\n ) {\n settings.no_autorepair = true;\n settings.save();\n }\n ide.switchTab(\"Data\");\n }\n }\n ];\n showDialog(\n i18n.t(\"warning.incomplete.title\"),\n content,\n dialog_buttons\n );\n } else if (isCountPresent) {\n ide.switchTab(\"Data\");\n }\n }\n // auto tab switching (if only areas are returned)\n if (empty_msg == \"only areas returned\") ide.switchTab(\"Data\");\n // auto tab switching (if nodes without coordinates are returned)\n if (empty_msg == \"no coordinates returned\") ide.switchTab(\"Data\");\n // auto tab switching (if unstructured data is returned)\n if (data_mode == \"unknown\") ide.switchTab(\"Data\");\n // display empty map badge\n $(\n `
    ${i18n.t(\n \"map.intentionally_blank\"\n )} (${empty_msg})
    `\n ).appendTo(\"#map\");\n };\n overpass.handlers[\"onDataReceived\"] = function (\n amount,\n amount_txt,\n abortCB,\n continueCB\n ) {\n if (amount > 1000000) {\n ide.waiter.close();\n const _originalDocumentTitle = document.title;\n document.title = `❗ ${_originalDocumentTitle}`;\n // more than ~1MB of data\n // show warning dialog\n const dialog_buttons = [\n {\n name: i18n.t(\"dialog.abort\"),\n callback() {\n document.title = _originalDocumentTitle;\n abortCB();\n }\n },\n {\n name: i18n.t(\"dialog.continue_anyway\"),\n callback() {\n document.title = _originalDocumentTitle;\n continueCB();\n }\n }\n ];\n\n const content = `

    ${i18n\n .t(\"warning.huge_data.expl.1\")\n .replace(\"{{amount_txt}}\", amount_txt)}

    ${i18n.t(\n \"warning.huge_data.expl.2\"\n )}

    `;\n showDialog(i18n.t(\"warning.huge_data.title\"), content, dialog_buttons);\n } else continueCB();\n };\n overpass.handlers[\"onAbort\"] = function () {\n ide.waiter.close();\n };\n overpass.handlers[\"onAjaxError\"] = function (errmsg) {\n ide.waiter.close();\n const _originalDocumentTitle = document.title;\n document.title = `❗ ${_originalDocumentTitle}`;\n // show error dialog\n const dialog_buttons = [\n {\n name: i18n.t(\"dialog.dismiss\"),\n callback() {\n document.title = _originalDocumentTitle;\n }\n }\n ];\n\n const content = `

    ${i18n.t(\n \"error.ajax.expl\"\n )}

    ${errmsg}`;\n showDialog(i18n.t(\"error.ajax.title\"), content, dialog_buttons);\n\n // print error text, if present\n if (overpass.resultText) ide.dataViewer.setValue(overpass.resultText);\n };\n overpass.handlers[\"onQueryError\"] = function (errmsg) {\n ide.waiter.close();\n const _originalDocumentTitle = document.title;\n document.title = `❗ ${_originalDocumentTitle}`;\n const dialog_buttons = [\n {\n name: i18n.t(\"dialog.dismiss\"),\n callback() {\n document.title = _originalDocumentTitle;\n }\n }\n ];\n const content = `
    ${i18n.t(\n \"error.query.expl\"\n )}
    ${errmsg}
    `;\n showDialog(i18n.t(\"error.query.title\"), content, dialog_buttons);\n };\n overpass.handlers[\"onStyleError\"] = function (errmsg) {\n const dialog_buttons = [{name: i18n.t(\"dialog.dismiss\")}];\n const content = `

    ${i18n.t(\n \"error.mapcss.expl\"\n )}

    ${errmsg}`;\n showDialog(i18n.t(\"error.mapcss.title\"), content, dialog_buttons);\n };\n overpass.handlers[\"onQueryErrorLine\"] = function (linenumber) {\n ide.highlightError(linenumber);\n };\n overpass.handlers[\"onRawDataPresent\"] = function () {\n ide.dataViewer.setOption(\"mode\", overpass.resultType);\n ide.dataViewer.setValue(overpass.resultText);\n };\n overpass.handlers[\"onGeoJsonReady\"] = function () {\n // show layer\n ide.map.addLayer(overpass.osmLayer);\n // autorun callback (e.g. zoom to data)\n if (typeof ide.run_query_on_startup === \"function\") {\n ide.run_query_on_startup();\n }\n // enable auto-styler\n $(\"#styler-button\").show();\n // display stats\n if (settings.show_data_stats) {\n const stats = overpass.stats;\n const stats_txt =\n `${i18n.t(\"data_stats.loaded\")} – ` +\n `${i18n.t(\"data_stats.nodes\")}: ${stats.data.nodes}, ${i18n.t(\n \"data_stats.ways\"\n )}: ${stats.data.ways}, ${i18n.t(\n \"data_stats.relations\"\n )}: ${stats.data.relations}${\n stats.data.areas > 0\n ? `, ${i18n.t(\"data_stats.areas\")}: ${stats.data.areas}`\n : \"\"\n }
    ` +\n `${i18n.t(\n \"data_stats.displayed\"\n )} – ` +\n `${i18n.t(\"data_stats.pois\")}: ${stats.geojson.pois}, ${i18n.t(\n \"data_stats.lines\"\n )}: ${stats.geojson.lines}, ${i18n.t(\n \"data_stats.polygons\"\n )}: ${stats.geojson.polys}`;\n $(\n `
    ${stats_txt}
    `\n ).insertAfter(\"#map .leaflet-control-attribution\");\n // show more stats as a tooltip\n const backlogOverpass =\n overpass.timestamp && Date.now() - Date.parse(overpass.timestamp);\n const backlogOverpassAreas =\n overpass.timestampAreas &&\n Date.now() - Date.parse(overpass.timestampAreas);\n $(\"#data_stats\").tooltip({\n items: \"div\",\n tooltipClass: \"stats\",\n content() {\n let str = \"
    \";\n if (overpass.ajax_request_duration) {\n let duration = overpass.ajax_request_duration;\n if (duration.toLocaleString) {\n duration = duration.toLocaleString();\n }\n str += `${i18n.t(\n \"data_stats.request_duration\"\n )}: ${duration}ms
    `;\n }\n if (overpass.timestamp) {\n str +=\n `${i18n.t(\"data_stats.lag\")}: ${Math.floor(\n backlogOverpass / 1000\n )}s` + ` ${i18n.t(\"data_stats.lag.expl\")}`;\n }\n if (overpass.timestampAreas) {\n str +=\n `
    ${i18n.t(\"data_stats.lag_areas\")}: ${Math.floor(\n backlogOverpassAreas / 1000\n )}s` + ` ${i18n.t(\"data_stats.lag.expl\")}`;\n }\n str += \"
    \";\n return str;\n },\n hide: {\n effect: \"fadeOut\",\n duration: 100\n },\n position: {\n my: \"right bottom-5\",\n at: \"right top\"\n }\n });\n if (\n backlogOverpass > 24 * 60 * 60 * 1000 ||\n backlogOverpassAreas > 96 * 60 * 60 * 1000\n ) {\n $(\"#data_stats\").css(\"background-color\", \"yellow\");\n }\n }\n };\n overpass.handlers[\"onPopupReady\"] = function (p) {\n p.openOn(ide.map);\n };\n\n // close startup waiter\n ide.waiter.close();\n\n // run the query immediately, if the appropriate flag was set.\n if (ide.run_query_on_startup === true) {\n ide.update_map();\n // automatically zoom to data.\n if (\n !args.has_coords &&\n args.has_query &&\n args.query.match(/\\{\\{(bbox|center)\\}\\}/) === null\n ) {\n ide.run_query_on_startup = function () {\n ide.run_query_on_startup = null;\n // hardcoded maxZoom of 18, should be ok for most real-world use-cases\n try {\n ide.map.fitBounds(overpass.osmLayer.getBaseLayer().getBounds(), {\n maxZoom: 18\n });\n } catch (e) {}\n // todo: zoom only to specific zoomlevel if args.has_zoom is given\n };\n }\n }\n } // init()\n\n onNominatimError(search, type) {\n // close waiter\n this.waiter.close();\n // highlight error lines\n let query = this.getRawQuery();\n query = query.split(\"\\n\");\n query.forEach((line, i) => {\n if (line.indexOf(`{{geocode${type}:${search}}}`) !== -1)\n this.highlightError(i + 1);\n });\n // show error message dialog\n const dialog_buttons = [{name: i18n.t(\"dialog.dismiss\")}];\n const content = `

    ${i18n.t(\n \"error.nominatim.expl\"\n )}

    ${htmlentities(search)}

    `;\n showDialog(i18n.t(\"error.nominatim.title\"), content, dialog_buttons);\n }\n\n /* this returns the current raw query in the editor.\n * shortcuts are not expanded. */\n getRawQuery() {\n return this.codeEditor.getValue();\n }\n\n /* this returns the current query in the editor.\n * shortcuts are expanded. */\n async getQuery(): Promise {\n let query = this.getRawQuery();\n // parse query and process shortcuts\n // special handling for global bbox in xml queries (which uses an OverpassQL-like notation instead of n/s/e/w parameters):\n query = query.replace(\n /(]+bbox[^=]*=[^\"'']*[\"'])({{bbox}})([\"'])/,\n \"$1{{__bbox__global_bbox_xml__ezs4K8__}}$3\"\n );\n query = await this.queryParser.parse(query, shortcuts());\n // parse mapcss declarations\n let mapcss = \"\";\n if (this.queryParser.hasStatement(\"style\"))\n mapcss = this.queryParser.getStatement(\"style\");\n this.mapcss = mapcss;\n // parse data-source statements\n let data_source = null;\n if (this.queryParser.hasStatement(\"data\")) {\n data_source = this.queryParser.getStatement(\"data\");\n data_source = data_source.split(\",\");\n const data_mode = data_source[0].toLowerCase();\n data_source = data_source.slice(1);\n const options = {};\n for (const src of data_source) {\n const tmp = src.split(\"=\");\n options[tmp[0]] = tmp[1];\n }\n data_source = {\n mode: data_mode,\n options: options\n };\n }\n this.data_source = data_source;\n return query;\n }\n\n setQuery(query) {\n this.codeEditor.setValue(query);\n }\n getQueryLang() {\n if ($.trim(this.getRawQuery().replace(/{{.*?}}/g, \"\")).match(/^ {\n delete settings.saves[ex];\n settings.save();\n this.onLoadClick();\n }\n },\n {name: i18n.t(\"dialog.cancel\")}\n ];\n\n const content =\n `

    ` +\n `${i18n.t(\n \"dialog.delete_query.expl\"\n )}: "${ex}"?

    `;\n showDialog(i18n.t(\"dialog.delete_query.title\"), content, dialog_buttons);\n }\n removeExampleSync(query, self) {\n const dialog_buttons = [\n {\n name: i18n.t(\"dialog.delete\"),\n callback() {\n sync.delete(query.name, (err) => {\n if (err) return console.error(err);\n\n $(self).parent().remove();\n });\n }\n },\n {\n name: i18n.t(\"dialog.cancel\")\n }\n ];\n\n const content = `

    ${i18n.t(\n \"dialog.delete_query.expl-osm\"\n )}: "${query.name}"?

    `;\n showDialog(i18n.t(\"dialog.delete_query.title\"), content, dialog_buttons);\n }\n\n // Event handlers\n onLoadClick() {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const ide = this;\n $(\"#load-dialog .panel.saved_query .panel-block\").remove();\n $(\"#load-dialog .panel.example .panel-block\").remove();\n // load example list\n let has_saved_query = false;\n for (const example in settings.saves) {\n const type = settings.saves[example].type;\n if (type == \"template\") continue;\n $('')\n .attr(\"href\", \"#\")\n .text(example)\n .on(\"click\", () => {\n ide.loadExample(example);\n $(\"#load-dialog\").removeClass(\"is-active\");\n return false;\n })\n .append(\n $('`\n ).on(\"click\", () => {\n ide.loadOsmQueries();\n })\n )\n .appendTo(ui);\n } else {\n ui.hide();\n }\n }\n }\n loadOsmQueries() {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const ide = this;\n const ui = $(\"#load-dialog .panel.osm-queries\");\n ui.show();\n ui.find(\".panel-block\").remove();\n $('
    ')\n .text(i18n.t(\"load.saved_queries-osm-loading\"))\n .appendTo(ui);\n\n sync.load((err, queries) => {\n if (err) {\n ui.find(\".panel-block\").remove();\n $('
    ')\n .text(i18n.t(\"load.saved_queries-osm-error\"))\n .appendTo(ui);\n return console.error(err);\n }\n ui.find(\".panel-block\").remove();\n $(\"#logout\").show();\n $(\"#logout\").appendTo($(\"#logout\").parent());\n queries.forEach((q) => {\n $('')\n .attr(\"href\", \"#\")\n .text(q.name)\n .on(\"click\", () => {\n ide.setQuery(lzw_decode(Base64.decode(q.query)));\n $(\"#load-dialog\").removeClass(\"is-active\");\n return false;\n })\n .append(\n $('\\\n \\\n
    \\\n ${content}\\\n
    \\\n
    \\\n
    \\\n
    \\\n
    \\\n
    \\\n
    \\\n
    \\\n
    \\\n
    \\\n
    \\\n `;\n\n // Create modal in body\n const element = $(dialogContent);\n // Handle close event\n $(\".delete\", element).click(() => $(element).remove());\n\n // Add all the buttons\n for (const index in buttons) {\n const button = buttons[index];\n $(``)\n .click(() => {\n button.callback?.();\n // destroy modal dialog after callback, see #528\n $(element).remove();\n })\n .appendTo($(\"footer .level-item\", element));\n }\n\n // Add the element to the body\n element.appendTo(\"body\");\n}\n\nclass IDE {\n // == private members ==\n private attribControl = null;\n private scaleControl = null;\n private queryParser = new Query();\n private run_query_on_startup = false;\n // == public members ==\n codeEditor = null;\n dataViewer = null;\n map: L.Map = null;\n\n // == public sub objects ==\n\n waiter = new (class Waiter {\n opened = true;\n frames = [\"◴\", \"◷\", \"◶\", \"◵\"];\n frameDelay = 250;\n onAbort = undefined;\n interval = 0;\n _initialTitle = document.title;\n\n open(show_info) {\n if (show_info) {\n $(\".modal .wait-info h4\").text(show_info);\n $(\".wait-info\").show();\n } else {\n $(\".wait-info\").hide();\n }\n $(\"#loading-dialog\").addClass(\"is-active\");\n document.title = `${this.frames[0]} ${this._initialTitle}`;\n let f = 0;\n this.interval = setInterval(() => {\n const title = this.isAlert\n ? this.alertFrame\n : this.frames[++f % this.frames.length];\n document.title = `${title} ${this._initialTitle}`;\n }, this.frameDelay);\n this.opened = true;\n }\n close(title_prefix = \"\") {\n if (!this.opened) return;\n clearInterval(this.interval);\n document.title = `${title_prefix}${this._initialTitle}`;\n $(\"#loading-dialog\").removeClass(\"is-active\");\n $(\".wait-info ul li\").remove();\n delete this.onAbort;\n this.opened = false;\n }\n addInfo(txt, abortCallback) {\n $(\"#aborter\").remove(); // remove previously added abort button, which cannot be used anymore.\n $(\".wait-info ul li:nth-child(n+1)\").css(\"opacity\", 0.5);\n $(\".wait-info ul li span.fas\")\n .removeClass(\"fa-spinner\")\n .removeClass(\"fa-spin\")\n .addClass(\"fa-check\");\n $(\".wait-info ul li:nth-child(n+4)\").hide();\n const li = $(\n `
  • ${txt}
  • `\n );\n if (typeof abortCallback == \"function\") {\n this.onAbort = abortCallback;\n const aborter = $(\n ' (
    abort)
    '\n ).on(\"click\", () => {\n this.abort();\n return false;\n });\n li.append(aborter);\n }\n $(\".wait-info ul\").prepend(li);\n }\n abort() {\n if (typeof this.onAbort == \"function\") {\n this.addInfo(\"aborting\");\n this.onAbort(this.close);\n }\n }\n })();\n\n // == public methods ==\n\n init() {\n this.waiter.addInfo(\"ide starting up\");\n $(\"#overpass-turbo-version\").html(\n `overpass-turbo ${GIT_VERSION}` // eslint-disable-line no-undef\n );\n $(\"#overpass-turbo-dependencies\").html(\n APP_DEPENDENCIES // eslint-disable-line no-undef\n );\n // (very raw) compatibility check <- TODO: put this into its own function\n if (\n jQuery.support.cors != true ||\n //typeof localStorage != \"object\" ||\n typeof (function () {\n let ls = undefined;\n try {\n localStorage.setItem(\"startup_localstorage_quota_test\", 123);\n localStorage.removeItem(\"startup_localstorage_quota_test\");\n ls = localStorage;\n } catch (e) {}\n return ls;\n })() != \"object\" ||\n false\n ) {\n // the currently used browser is not capable of running the IDE. :(\n this.not_supported = true;\n $(\"#warning-unsupported-browser\").addClass(\"is-active\");\n }\n // load settings\n this.waiter.addInfo(\"load settings\");\n settings.load();\n // translate ui\n this.waiter.addInfo(\"translate ui\");\n i18n.translate().then(() => this.initAfterI18n());\n\n if (sync.enabled) {\n $(\"#load-dialog .osm\").show();\n if (sync.authenticated()) {\n $(\"#logout\").show();\n $(\"#logout\").appendTo($(\"#logout\").parent());\n }\n }\n }\n\n initAfterI18n() {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const ide = this;\n // parse url string parameters\n ide.waiter.addInfo(\"parse url parameters\");\n const args = urlParameters();\n // set appropriate settings\n if (args.has_coords) {\n // map center coords set via url\n settings.coords_lat = args.coords.lat;\n settings.coords_lon = args.coords.lng;\n }\n if (args.has_zoom) {\n // map zoom set via url\n settings.coords_zoom = args.zoom;\n }\n if (args.run_query) {\n // query autorun activated via url\n ide.run_query_on_startup = true;\n }\n settings.save();\n\n ide.waiter.addInfo(\"initialize page\");\n // init page layout\n const isInitialAspectPortrait =\n $(window).width() / $(window).height() < 0.8;\n if (settings.editor_width != \"\" && !isInitialAspectPortrait) {\n $(\"#editor\").css(\"width\", settings.editor_width);\n $(\"#dataviewer\").css(\"left\", settings.editor_width);\n }\n if (isInitialAspectPortrait) {\n $(\"#editor, #dataviewer\").addClass(\"portrait\");\n }\n // make panels resizable\n $(\"#editor\").resizable({\n handles: isInitialAspectPortrait ? \"s\" : \"e\",\n minWidth: isInitialAspectPortrait ? undefined : \"200\",\n resize() {\n if (!isInitialAspectPortrait) {\n $(this)\n .next()\n .css(\"left\", `${$(this).outerWidth()}px`);\n } else {\n const top = $(this).offset().top + $(this).outerHeight();\n $(this).next().css(\"top\", `${top}px`);\n }\n ide.map.invalidateSize(false);\n },\n stop() {\n if (isInitialAspectPortrait) return;\n settings.editor_width = $(\"#editor\").css(\"width\");\n settings.save();\n }\n });\n $(\"#editor\").prepend(\n \"\"\n );\n\n // init codemirror\n $(\"#editor textarea\")[0].value = settings.code[\"overpass\"];\n if (settings.use_rich_editor) {\n let pending = 0;\n CodeMirror.defineMIME(\"text/x-overpassQL\", {\n name: \"clike\",\n keywords: (function (str) {\n const r = {};\n const a = str.split(\" \");\n for (const ai of a) r[ai] = true;\n return r;\n })(\n \"out json xml custom popup timeout maxsize bbox\" + // initial declarations\n \" date diff adiff\" + //attic declarations\n \" foreach\" + // block statements\n \" relation rel way node is_in area around user uid newer changed poly pivot nwr nw nr wr derived\" + // queries\n \" out meta body skel tags ids count qt asc\" + // actions\n \" center bb geom\" // geometry types\n //+\"r w n br bw\" // recursors\n )\n });\n CodeMirror.defineMIME(\"text/x-overpassXML\", \"xml\");\n CodeMirror.defineMode(\"xml+mustache\", (config) =>\n CodeMirror.multiplexingMode(\n CodeMirror.multiplexingMode(CodeMirror.getMode(config, \"xml\"), {\n open: \"{{\",\n close: \"}}\",\n mode: CodeMirror.getMode(config, \"text/plain\"),\n delimStyle: \"mustache\"\n }),\n {\n open: \"{{style:\",\n close: \"}}\",\n mode: CodeMirror.getMode(config, \"text/css\"),\n delimStyle: \"mustache\"\n }\n )\n );\n CodeMirror.defineMode(\"ql+mustache\", (config) =>\n CodeMirror.multiplexingMode(\n CodeMirror.multiplexingMode(\n CodeMirror.getMode(config, \"text/x-overpassQL\"),\n {\n open: \"{{\",\n close: \"}}\",\n mode: CodeMirror.getMode(config, \"text/plain\"),\n delimStyle: \"mustache\"\n }\n ),\n {\n open: \"{{style:\",\n close: \"}}\",\n mode: CodeMirror.getMode(config, \"text/css\"),\n delimStyle: \"mustache\"\n }\n )\n );\n ide.codeEditor = CodeMirror.fromTextArea($(\"#editor textarea\")[0], {\n //value: settings.code[\"overpass\"],\n lineNumbers: true,\n lineWrapping: true,\n mode: \"text/plain\",\n onChange(e) {\n clearTimeout(pending);\n pending = setTimeout(() => {\n // update syntax highlighting mode\n if (ide.getQueryLang() == \"xml\") {\n if (e.getOption(\"mode\") != \"xml+mustache\") {\n e.closeTagEnabled = true;\n e.setOption(\"matchBrackets\", false);\n e.setOption(\"mode\", \"xml+mustache\");\n }\n } else {\n if (e.getOption(\"mode\") != \"ql+mustache\") {\n e.closeTagEnabled = false;\n e.setOption(\"matchBrackets\", true);\n e.setOption(\"mode\", \"ql+mustache\");\n }\n }\n // check for inactive ui elements\n const bbox_filter = $(\".leaflet-control-buttons-bboxfilter\");\n if (ide.getRawQuery().match(/\\{\\{bbox\\}\\}/)) {\n if (bbox_filter.hasClass(\"disabled\")) {\n bbox_filter.removeClass(\"disabled\");\n bbox_filter.attr(\"data-t\", \"[title]map_controlls.select_bbox\");\n i18n.translate_ui(bbox_filter[0]);\n }\n } else {\n if (!bbox_filter.hasClass(\"disabled\")) {\n bbox_filter.addClass(\"disabled\");\n bbox_filter.attr(\n \"data-t\",\n \"[title]map_controlls.select_bbox_disabled\"\n );\n i18n.translate_ui(bbox_filter[0]);\n }\n }\n }, 500);\n settings.code[\"overpass\"] = e.getValue();\n settings.save();\n },\n closeTagEnabled: true,\n closeTagIndent: [\n \"osm-script\",\n \"query\",\n \"union\",\n \"foreach\",\n \"difference\"\n ],\n extraKeys: {\n \"'>'\"(cm) {\n cm.closeTag(cm, \">\");\n },\n \"'/'\"(cm) {\n cm.closeTag(cm, \"/\");\n }\n }\n });\n // fire onChange after initialization\n ide.codeEditor.getOption(\"onChange\")(ide.codeEditor);\n } else {\n // use non-rich editor\n ide.codeEditor = $(\"#editor textarea\")[0];\n ide.codeEditor.getValue = function () {\n return this.value;\n };\n ide.codeEditor.setValue = function (v) {\n this.value = v;\n };\n ide.codeEditor.lineCount = function () {\n return this.value.split(/\\r\\n|\\r|\\n/).length;\n };\n ide.codeEditor.setLineClass = function () {};\n $(\"#editor textarea\").bind(\"input change\", (e) => {\n settings.code[\"overpass\"] = e.target.getValue();\n settings.save();\n });\n }\n // set query if provided as url parameter or template:\n if (args.has_query) {\n // query set via url\n ide.codeEditor.setValue(args.query);\n }\n // init dataviewer\n ide.dataViewer = CodeMirror($(\"#data\")[0], {\n value: \"no data loaded yet\",\n lineNumbers: true,\n readOnly: true,\n mode: \"javascript\"\n });\n\n // init leaflet\n ide.map = new L.Map(\"map\", {\n attributionControl: false,\n minZoom: 0,\n maxZoom: configs.maxMapZoom,\n worldCopyJump: false\n });\n const tilesUrl = settings.tile_server;\n const tilesAttrib = configs.tileServerAttribution;\n const tiles = new L.TileLayer(tilesUrl, {\n attribution: tilesAttrib,\n noWrap: true,\n maxNativeZoom: 19,\n maxZoom: ide.map.options.maxZoom\n });\n const attribControl = new L.Control.Attribution({position: \"bottomright\"});\n attribControl.addAttribution(tilesAttrib);\n attribControl.addTo(ide.map);\n const pos = new L.LatLng(settings.coords_lat, settings.coords_lon);\n ide.map.setView(pos, settings.coords_zoom).addLayer(tiles);\n ide.map.tile_layer = tiles;\n // inverse opacity layer\n ide.map.inv_opacity_layer = L.tileLayer(\n \"data:image/gif;base64,R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==\"\n ).setOpacity(1 - settings.background_opacity);\n if (settings.background_opacity != 1)\n ide.map.inv_opacity_layer.addTo(ide.map);\n ide.scaleControl = new L.Control.Scale({metric: true, imperial: false});\n ide.scaleControl.addTo(ide.map);\n ide.map.on(\"moveend\", () => {\n settings.coords_lat = ide.map.getCenter().lat;\n settings.coords_lon = ide.map.getCenter().lng;\n settings.coords_zoom = ide.map.getZoom();\n settings.save(); // save settings\n });\n\n // tabs\n $(\"#dataviewer > div#data\")[0].style.zIndex = -1001;\n $(\".tabs li\").bind(\"click\", (e) => {\n if ($(e.target).hasClass(\"is-active\")) {\n return;\n } else {\n $(\"#dataviewer > div#data\")[0].style.zIndex =\n -1 * $(\"#dataviewer > div#data\")[0].style.zIndex;\n $(\".tabs li\").toggleClass(\"is-active\");\n }\n });\n\n // keyboard event listener\n $(document).keydown((event) => ide.onKeyPress(event));\n\n // leaflet extension: more map controls\n const MapButtons = L.Control.extend({\n options: {\n position: \"topleft\"\n },\n onAdd() {\n // create the control container with a particular class name\n const container = L.DomUtil.create(\n \"div\",\n \"leaflet-control-buttons leaflet-bar\"\n );\n let link = L.DomUtil.create(\n \"a\",\n \"leaflet-control-buttons-fitdata leaflet-bar-part leaflet-bar-part-top\",\n container\n );\n $('').appendTo($(link));\n link.href = \"#\";\n link.className += \" t\";\n link.setAttribute(\"data-t\", \"[title]map_controlls.zoom_to_data\");\n i18n.translate_ui(link);\n L.DomEvent.addListener(\n link,\n \"click\",\n () => {\n // hardcoded maxZoom of 18, should be ok for most real-world use-cases\n try {\n ide.map.fitBounds(overpass.osmLayer.getBaseLayer().getBounds(), {\n maxZoom: 18\n });\n } catch (e) {}\n return false;\n },\n ide.map\n );\n link = L.DomUtil.create(\n \"a\",\n \"leaflet-control-buttons-myloc leaflet-bar-part\",\n container\n );\n $('').appendTo($(link));\n link.href = \"#\";\n link.className += \" t\";\n link.setAttribute(\"data-t\", \"[title]map_controlls.localize_user\");\n if (!window.isSecureContext) {\n link.className += \" disabled\";\n link.setAttribute(\n \"data-t\",\n \"[title]map_controlls.localize_user_disabled\"\n );\n }\n i18n.translate_ui(link);\n L.DomEvent.addListener(\n link,\n \"click\",\n () => {\n // One-shot position request.\n try {\n navigator.geolocation.getCurrentPosition((position) => {\n const pos = new L.LatLng(\n position.coords.latitude,\n position.coords.longitude\n );\n ide.map.setView(pos, settings.coords_zoom);\n });\n } catch (e) {}\n return false;\n },\n ide.map\n );\n link = L.DomUtil.create(\n \"a\",\n \"leaflet-control-buttons-bboxfilter leaflet-bar-part\",\n container\n );\n $('').appendTo($(link));\n link.href = \"#\";\n link.className += \" t\";\n link.setAttribute(\"data-t\", \"[title]map_controlls.select_bbox\");\n i18n.translate_ui(link);\n L.DomEvent.addListener(\n link,\n \"click\",\n (e) => {\n if (\n $(e.target).parent().hasClass(\"disabled\") // check if this button is enabled\n )\n return false;\n if (!ide.map.bboxfilter.isEnabled()) {\n ide.map.bboxfilter.setBounds(ide.map.getBounds().pad(-0.2));\n ide.map.bboxfilter.enable();\n } else {\n ide.map.bboxfilter.disable();\n }\n $(e.target).toggleClass(\"fa-times-circle\").toggleClass(\"fa-image\");\n return false;\n },\n ide.map\n );\n link = L.DomUtil.create(\n \"a\",\n \"leaflet-control-buttons-fullscreen leaflet-bar-part\",\n container\n );\n $('').appendTo($(link));\n link.href = \"#\";\n link.className += \" t\";\n link.setAttribute(\"data-t\", \"[title]map_controlls.toggle_wide_map\");\n i18n.translate_ui(link);\n L.DomEvent.addListener(\n link,\n \"click\",\n (e) => {\n $(\"#dataviewer\").toggleClass(\"fullscreen\");\n ide.map.invalidateSize();\n $(e.target)\n .toggleClass(\"fa-step-forward\")\n .toggleClass(\"fa-step-backward\");\n $(\"#editor\").toggleClass(\"hidden\");\n if ($(\"#editor\").resizable(\"option\", \"disabled\"))\n $(\"#editor\").resizable(\"enable\");\n else $(\"#editor\").resizable(\"disable\");\n return false;\n },\n ide.map\n );\n link = L.DomUtil.create(\n \"a\",\n \"leaflet-control-buttons-clearoverlay leaflet-bar-part leaflet-bar-part-bottom\",\n container\n );\n $('').appendTo($(link));\n link.href = \"#\";\n link.className += \" t\";\n link.setAttribute(\"data-t\", \"[title]map_controlls.toggle_data\");\n i18n.translate_ui(link);\n L.DomEvent.addListener(\n link,\n \"click\",\n (e) => {\n e.preventDefault();\n if (ide.map.hasLayer(overpass.osmLayer))\n ide.map.removeLayer(overpass.osmLayer);\n else ide.map.addLayer(overpass.osmLayer);\n return false;\n },\n ide.map\n );\n return container;\n }\n });\n ide.map.addControl(new MapButtons());\n // prevent propagation of doubleclicks on map controls\n $(\".leaflet-control-buttons > a\").bind(\"dblclick\", (e) =>\n e.stopPropagation()\n );\n // add tooltips to map controls\n $(\".leaflet-control-buttons > a\").tooltip({\n items: \"a[title]\",\n hide: {\n effect: \"fadeOut\",\n duration: 100\n },\n position: {\n my: \"left+5 center\",\n at: \"right center\"\n }\n });\n // leaflet extension: search box\n const SearchBox = L.Control.extend({\n options: {\n position: \"topright\"\n },\n onAdd() {\n const container = L.DomUtil.create(\n \"div\",\n \"leaflet-control-search control has-icons-left\"\n );\n container.style.position = \"absolute\";\n container.style.right = \"0\";\n const inp = L.DomUtil.create(\"input\", \"input is-rounded\", container);\n $('')\n .click(function () {\n $(this).prev().autocomplete(\"search\");\n })\n .insertAfter(inp);\n inp.id = \"search\";\n inp.type = \"search\";\n // hack against focus stealing leaflet :/\n inp.onclick = function () {\n this.focus();\n };\n // prevent propagation of doubleclicks to map container\n container.ondblclick = function (e) {\n e.stopPropagation();\n };\n // autocomplete functionality\n $(inp).autocomplete({\n source(request, response) {\n // ajax (GET) request to nominatim\n $.ajax(\n `https://search.osmnames.org/q/${encodeURIComponent(\n request.term\n )}.js?key=${configs.osmnamesApiKey}`,\n {\n success(data) {\n // hacky firefox hack :( (it is not properly detecting json from the content-type header)\n if (typeof data == \"string\") {\n // if the data is a string, but looks more like a json object\n try {\n data = $.parseJSON(data);\n } catch (e) {}\n }\n response(\n $.map(data.results.slice(0, 10), (item) => ({\n label: item.display_name,\n value: item.display_name,\n lat: item.lat,\n lon: item.lon,\n boundingbox: item.boundingbox\n }))\n );\n },\n error() {\n // todo: better error handling\n console.error(\n \"An error occurred while contacting the search server osmnames.org :(\"\n );\n }\n }\n );\n },\n minLength: 2,\n autoFocus: true,\n select(event, ui) {\n if (ui.item.boundingbox && ui.item.boundingbox instanceof Array)\n ide.map.fitBounds(\n L.latLngBounds([\n [ui.item.boundingbox[1], ui.item.boundingbox[0]],\n [ui.item.boundingbox[3], ui.item.boundingbox[2]]\n ]),\n {maxZoom: 18}\n );\n else ide.map.panTo(new L.LatLng(ui.item.lat, ui.item.lon));\n this.value = \"\";\n return false;\n },\n open() {\n $(this).removeClass(\"ui-corner-all\").addClass(\"ui-corner-top\");\n },\n close() {\n $(this).addClass(\"ui-corner-all\").removeClass(\"ui-corner-top\");\n }\n });\n $(inp).autocomplete(\"option\", \"delay\", 20);\n return container;\n }\n });\n ide.map.addControl(new SearchBox());\n // add cross hairs to map\n $('')\n .addClass(\"crosshairs\")\n .hide()\n .appendTo(\"#map\");\n if (settings.enable_crosshairs) $(\".crosshairs\").show();\n\n ide.map.bboxfilter = new L.LocationFilter({\n enable: !true,\n adjustButton: false,\n enableButton: false\n }).addTo(ide.map);\n\n ide.map.on(\"popupopen popupclose\", (e) => {\n if (typeof e.popup.layer != \"undefined\") {\n const layer = e.popup.layer.placeholder || e.popup.layer;\n // re-call style handler to eventually modify the style of the clicked feature\n const stl = overpass.osmLayer._baseLayer.options.style(\n layer.feature,\n e.type == \"popupopen\"\n );\n if (typeof layer.eachLayer != \"function\") {\n if (typeof layer.setStyle == \"function\") layer.setStyle(stl); // other objects (pois, ways)\n } else\n layer.eachLayer((layer) => {\n if (typeof layer.setStyle == \"function\") layer.setStyle(stl);\n }); // for multipolygons!\n }\n });\n\n // init overpass object\n overpass.init();\n\n // event handlers for overpass object\n overpass.handlers[\"onProgress\"] = function (msg, abortcallback) {\n ide.waiter.addInfo(msg, abortcallback);\n };\n overpass.handlers[\"onDone\"] = function () {\n const name_match = ide.getRawQuery().match(/@name ([^\\n]+)/);\n // parse document title from @name in query\n const title_prefix = name_match ? `${name_match[1]} | ` : \"\";\n ide.waiter.close(title_prefix);\n const map_bounds = ide.map.getBounds();\n const data_bounds = overpass.osmLayer.getBaseLayer().getBounds();\n if (data_bounds.isValid() && !map_bounds.intersects(data_bounds)) {\n // show tooltip for button \"zoom to data\"\n const prev_content = $(\".leaflet-control-buttons-fitdata\").tooltip(\n \"option\",\n \"content\"\n );\n $(\".leaflet-control-buttons-fitdata\").tooltip(\n \"option\",\n \"content\",\n `← ${i18n.t(\"map_controlls.suggest_zoom_to_data\")}`\n );\n $(\".leaflet-control-buttons-fitdata\").tooltip(\"open\");\n $(\".leaflet-control-buttons-fitdata\").tooltip(\"option\", \"hide\", {\n effect: \"fadeOut\",\n duration: 1000\n });\n setTimeout(() => {\n $(\".leaflet-control-buttons-fitdata\").tooltip(\n \"option\",\n \"content\",\n prev_content\n );\n $(\".leaflet-control-buttons-fitdata\").tooltip(\"close\");\n $(\".leaflet-control-buttons-fitdata\").tooltip(\"option\", \"hide\", {\n effect: \"fadeOut\",\n duration: 100\n });\n }, 2600);\n }\n };\n overpass.handlers[\"onEmptyMap\"] = function (empty_msg, data_mode) {\n // get the current query\n const query = ide.getRawQuery();\n\n // check if 'out' followed by any number of characters (non-greedy) and then 'count' is present in the query\n const isCountPresent = /out[^;]+?count/.test(query);\n\n // show warning/info if only invisible data is returned and 'out...count' is not present in the query\n if (empty_msg == \"no visible data\") {\n if (!isCountPresent && !settings.no_autorepair) {\n const content = `

    ${i18n.t(\n \"warning.incomplete.expl.1\"\n )}

    ${i18n.t(\n \"warning.incomplete.expl.2\"\n )}

     ${i18n.t(\n \"warning.incomplete.not_again\"\n )}

    `;\n\n const dialog_buttons = [\n {\n name: i18n.t(\"dialog.repair_query\"),\n callback() {\n ide.repairQuery(\"no visible data\");\n }\n },\n {\n name: i18n.t(\"dialog.show_data\"),\n callback() {\n if (\n $(\"input[name=hide_incomplete_data_warning]\")?.[0]?.checked\n ) {\n settings.no_autorepair = true;\n settings.save();\n }\n ide.switchTab(\"Data\");\n }\n }\n ];\n showDialog(\n i18n.t(\"warning.incomplete.title\"),\n content,\n dialog_buttons\n );\n } else if (isCountPresent) {\n ide.switchTab(\"Data\");\n }\n }\n // auto tab switching (if only areas are returned)\n if (empty_msg == \"only areas returned\") ide.switchTab(\"Data\");\n // auto tab switching (if nodes without coordinates are returned)\n if (empty_msg == \"no coordinates returned\") ide.switchTab(\"Data\");\n // auto tab switching (if unstructured data is returned)\n if (data_mode == \"unknown\") ide.switchTab(\"Data\");\n // display empty map badge\n $(\n `
    ${i18n.t(\n \"map.intentionally_blank\"\n )} (${empty_msg})
    `\n ).appendTo(\"#map\");\n };\n overpass.handlers[\"onDataReceived\"] = function (\n amount,\n amount_txt,\n abortCB,\n continueCB\n ) {\n if (amount > 1000000) {\n ide.waiter.close();\n const _originalDocumentTitle = document.title;\n document.title = `❗ ${_originalDocumentTitle}`;\n // more than ~1MB of data\n // show warning dialog\n const dialog_buttons = [\n {\n name: i18n.t(\"dialog.abort\"),\n callback() {\n document.title = _originalDocumentTitle;\n abortCB();\n }\n },\n {\n name: i18n.t(\"dialog.continue_anyway\"),\n callback() {\n document.title = _originalDocumentTitle;\n continueCB();\n }\n }\n ];\n\n const content = `

    ${i18n\n .t(\"warning.huge_data.expl.1\")\n .replace(\"{{amount_txt}}\", amount_txt)}

    ${i18n.t(\n \"warning.huge_data.expl.2\"\n )}

    `;\n showDialog(i18n.t(\"warning.huge_data.title\"), content, dialog_buttons);\n } else continueCB();\n };\n overpass.handlers[\"onAbort\"] = function () {\n ide.waiter.close();\n };\n overpass.handlers[\"onAjaxError\"] = function (errmsg) {\n ide.waiter.close();\n const _originalDocumentTitle = document.title;\n document.title = `❗ ${_originalDocumentTitle}`;\n // show error dialog\n const dialog_buttons = [\n {\n name: i18n.t(\"dialog.dismiss\"),\n callback() {\n document.title = _originalDocumentTitle;\n }\n }\n ];\n\n const content = `

    ${i18n.t(\n \"error.ajax.expl\"\n )}

    ${errmsg}`;\n showDialog(i18n.t(\"error.ajax.title\"), content, dialog_buttons);\n\n // print error text, if present\n if (overpass.resultText) ide.dataViewer.setValue(overpass.resultText);\n };\n overpass.handlers[\"onQueryError\"] = function (errmsg) {\n ide.waiter.close();\n const _originalDocumentTitle = document.title;\n document.title = `❗ ${_originalDocumentTitle}`;\n const dialog_buttons = [\n {\n name: i18n.t(\"dialog.dismiss\"),\n callback() {\n document.title = _originalDocumentTitle;\n }\n }\n ];\n const content = `
    ${i18n.t(\n \"error.query.expl\"\n )}
    ${errmsg}
    `;\n showDialog(i18n.t(\"error.query.title\"), content, dialog_buttons);\n };\n overpass.handlers[\"onStyleError\"] = function (errmsg) {\n const dialog_buttons = [{name: i18n.t(\"dialog.dismiss\")}];\n const content = `

    ${i18n.t(\n \"error.mapcss.expl\"\n )}

    ${errmsg}`;\n showDialog(i18n.t(\"error.mapcss.title\"), content, dialog_buttons);\n };\n overpass.handlers[\"onQueryErrorLine\"] = function (linenumber) {\n ide.highlightError(linenumber);\n };\n overpass.handlers[\"onRawDataPresent\"] = function () {\n ide.dataViewer.setOption(\"mode\", overpass.resultType);\n ide.dataViewer.setValue(overpass.resultText);\n };\n overpass.handlers[\"onGeoJsonReady\"] = function () {\n // show layer\n ide.map.addLayer(overpass.osmLayer);\n // autorun callback (e.g. zoom to data)\n if (typeof ide.run_query_on_startup === \"function\") {\n ide.run_query_on_startup();\n }\n // enable auto-styler\n $(\"#styler-button\").show();\n // display stats\n if (settings.show_data_stats) {\n const stats = overpass.stats;\n const stats_txt =\n `${i18n.t(\"data_stats.loaded\")} – ` +\n `${i18n.t(\"data_stats.nodes\")}: ${stats.data.nodes}, ${i18n.t(\n \"data_stats.ways\"\n )}: ${stats.data.ways}, ${i18n.t(\n \"data_stats.relations\"\n )}: ${stats.data.relations}${\n stats.data.areas > 0\n ? `, ${i18n.t(\"data_stats.areas\")}: ${stats.data.areas}`\n : \"\"\n }
    ` +\n `${i18n.t(\n \"data_stats.displayed\"\n )} – ` +\n `${i18n.t(\"data_stats.pois\")}: ${stats.geojson.pois}, ${i18n.t(\n \"data_stats.lines\"\n )}: ${stats.geojson.lines}, ${i18n.t(\n \"data_stats.polygons\"\n )}: ${stats.geojson.polys}`;\n $(\n `
    ${stats_txt}
    `\n ).insertAfter(\"#map .leaflet-control-attribution\");\n // show more stats as a tooltip\n const backlogOverpass =\n overpass.timestamp && Date.now() - Date.parse(overpass.timestamp);\n const backlogOverpassAreas =\n overpass.timestampAreas &&\n Date.now() - Date.parse(overpass.timestampAreas);\n $(\"#data_stats\").tooltip({\n items: \"div\",\n tooltipClass: \"stats\",\n content() {\n let str = \"
    \";\n if (overpass.ajax_request_duration) {\n let duration = overpass.ajax_request_duration;\n if (duration.toLocaleString) {\n duration = duration.toLocaleString();\n }\n str += `${i18n.t(\n \"data_stats.request_duration\"\n )}: ${duration}ms
    `;\n }\n if (overpass.timestamp) {\n str +=\n `${i18n.t(\"data_stats.lag\")}: ${Math.floor(\n backlogOverpass / 1000\n )}s` + ` ${i18n.t(\"data_stats.lag.expl\")}`;\n }\n if (overpass.timestampAreas) {\n str +=\n `
    ${i18n.t(\"data_stats.lag_areas\")}: ${Math.floor(\n backlogOverpassAreas / 1000\n )}s` + ` ${i18n.t(\"data_stats.lag.expl\")}`;\n }\n str += \"
    \";\n return str;\n },\n hide: {\n effect: \"fadeOut\",\n duration: 100\n },\n position: {\n my: \"right bottom-5\",\n at: \"right top\"\n }\n });\n if (\n backlogOverpass > 24 * 60 * 60 * 1000 ||\n backlogOverpassAreas > 96 * 60 * 60 * 1000\n ) {\n $(\"#data_stats\").css(\"background-color\", \"yellow\");\n }\n }\n };\n overpass.handlers[\"onPopupReady\"] = function (p) {\n p.openOn(ide.map);\n };\n\n // close startup waiter\n ide.waiter.close();\n\n // run the query immediately, if the appropriate flag was set.\n if (ide.run_query_on_startup === true) {\n ide.update_map();\n // automatically zoom to data.\n if (\n !args.has_coords &&\n args.has_query &&\n args.query.match(/\\{\\{(bbox|center)\\}\\}/) === null\n ) {\n ide.run_query_on_startup = function () {\n ide.run_query_on_startup = null;\n // hardcoded maxZoom of 18, should be ok for most real-world use-cases\n try {\n ide.map.fitBounds(overpass.osmLayer.getBaseLayer().getBounds(), {\n maxZoom: 18\n });\n } catch (e) {}\n // todo: zoom only to specific zoomlevel if args.has_zoom is given\n };\n }\n }\n } // init()\n\n onNominatimError(search, type) {\n // close waiter\n this.waiter.close();\n // highlight error lines\n let query = this.getRawQuery();\n query = query.split(\"\\n\");\n query.forEach((line, i) => {\n if (line.indexOf(`{{geocode${type}:${search}}}`) !== -1)\n this.highlightError(i + 1);\n });\n // show error message dialog\n const dialog_buttons = [{name: i18n.t(\"dialog.dismiss\")}];\n const content = `

    ${i18n.t(\n \"error.nominatim.expl\"\n )}

    ${htmlentities(search)}

    `;\n showDialog(i18n.t(\"error.nominatim.title\"), content, dialog_buttons);\n }\n\n /* this returns the current raw query in the editor.\n * shortcuts are not expanded. */\n getRawQuery() {\n return this.codeEditor.getValue();\n }\n\n /* this returns the current query in the editor.\n * shortcuts are expanded. */\n async getQuery(): Promise {\n let query = this.getRawQuery();\n // parse query and process shortcuts\n // special handling for global bbox in xml queries (which uses an OverpassQL-like notation instead of n/s/e/w parameters):\n query = query.replace(\n /(]+bbox[^=]*=[^\"'']*[\"'])({{bbox}})([\"'])/,\n \"$1{{__bbox__global_bbox_xml__ezs4K8__}}$3\"\n );\n query = await this.queryParser.parse(query, shortcuts());\n // parse mapcss declarations\n let mapcss = \"\";\n if (this.queryParser.hasStatement(\"style\"))\n mapcss = this.queryParser.getStatement(\"style\");\n this.mapcss = mapcss;\n // parse data-source statements\n let data_source = null;\n if (this.queryParser.hasStatement(\"data\")) {\n data_source = this.queryParser.getStatement(\"data\");\n data_source = data_source.split(\",\");\n const data_mode = data_source[0].toLowerCase();\n data_source = data_source.slice(1);\n const options = {};\n for (const src of data_source) {\n const tmp = src.split(\"=\");\n options[tmp[0]] = tmp[1];\n }\n data_source = {\n mode: data_mode,\n options: options\n };\n }\n this.data_source = data_source;\n return query;\n }\n\n setQuery(query) {\n this.codeEditor.setValue(query);\n }\n getQueryLang() {\n if ($.trim(this.getRawQuery().replace(/{{.*?}}/g, \"\")).match(/^ {\n delete settings.saves[ex];\n settings.save();\n this.onLoadClick();\n }\n },\n {name: i18n.t(\"dialog.cancel\")}\n ];\n\n const content =\n `

    ` +\n `${i18n.t(\n \"dialog.delete_query.expl\"\n )}: "${ex}"?

    `;\n showDialog(i18n.t(\"dialog.delete_query.title\"), content, dialog_buttons);\n }\n removeExampleSync(query, self) {\n const dialog_buttons = [\n {\n name: i18n.t(\"dialog.delete\"),\n callback() {\n sync.delete(query.name, (err) => {\n if (err) return console.error(err);\n\n $(self).parent().remove();\n });\n }\n },\n {\n name: i18n.t(\"dialog.cancel\")\n }\n ];\n\n const content = `

    ${i18n.t(\n \"dialog.delete_query.expl-osm\"\n )}: "${query.name}"?

    `;\n showDialog(i18n.t(\"dialog.delete_query.title\"), content, dialog_buttons);\n }\n\n // Event handlers\n onLoadClick() {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const ide = this;\n $(\"#load-dialog .panel.saved_query .panel-block\").remove();\n $(\"#load-dialog .panel.example .panel-block\").remove();\n // load example list\n let has_saved_query = false;\n for (const example in settings.saves) {\n const type = settings.saves[example].type;\n if (type == \"template\") continue;\n $('')\n .attr(\"href\", \"#\")\n .text(example)\n .on(\"click\", () => {\n ide.loadExample(example);\n $(\"#load-dialog\").removeClass(\"is-active\");\n return false;\n })\n .append(\n $('`\n ).on(\"click\", () => {\n ide.loadOsmQueries();\n })\n )\n .appendTo(ui);\n } else {\n ui.hide();\n }\n }\n }\n loadOsmQueries() {\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const ide = this;\n const ui = $(\"#load-dialog .panel.osm-queries\");\n ui.show();\n ui.find(\".panel-block\").remove();\n $('
    ')\n .text(i18n.t(\"load.saved_queries-osm-loading\"))\n .appendTo(ui);\n\n sync.load((err, queries) => {\n if (err) {\n ui.find(\".panel-block\").remove();\n $('
    ')\n .text(i18n.t(\"load.saved_queries-osm-error\"))\n .appendTo(ui);\n return console.error(err);\n }\n ui.find(\".panel-block\").remove();\n $(\"#logout\").show();\n $(\"#logout\").appendTo($(\"#logout\").parent());\n queries.forEach((q) => {\n $('')\n .attr(\"href\", \"#\")\n .text(q.name)\n .on(\"click\", () => {\n ide.setQuery(lzw_decode(Base64.decode(q.query)));\n $(\"#load-dialog\").removeClass(\"is-active\");\n return false;\n })\n .append(\n $('