@bitalltech-maplibre/core 1.0.0 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/README.md +183 -6
  2. package/dist/index.cjs.js +1 -1
  3. package/dist/index.esm.js +3021 -139
  4. package/dist/index.umd.js +1 -1
  5. package/dist/types/basemaps/index.d.ts +5 -1
  6. package/dist/types/basemaps/tianditu.d.ts +7 -4
  7. package/dist/types/effects/electronic-fence-common.d.ts +76 -0
  8. package/dist/types/effects/electronic-fence-types.d.ts +131 -0
  9. package/dist/types/effects/geometry.d.ts +2 -0
  10. package/dist/types/effects/index.d.ts +5 -2
  11. package/dist/types/effects/low-altitude/breach-alert.d.ts +61 -0
  12. package/dist/types/effects/low-altitude/breathing-circle.d.ts +5 -0
  13. package/dist/types/effects/low-altitude/coordinated-countermeasure.d.ts +5 -0
  14. package/dist/types/effects/low-altitude/countermeasure-beam.d.ts +5 -0
  15. package/dist/types/effects/low-altitude/defence-circle.d.ts +5 -0
  16. package/dist/types/effects/low-altitude/directional-pulse.d.ts +6 -0
  17. package/dist/types/effects/low-altitude/navigation-spoofing.d.ts +6 -0
  18. package/dist/types/effects/low-altitude/pulse-marker.d.ts +5 -0
  19. package/dist/types/effects/low-altitude/radar-sweep.d.ts +5 -0
  20. package/dist/types/effects/low-altitude/ring-pulse-marker.d.ts +5 -0
  21. package/dist/types/effects/low-altitude/sector-scan.d.ts +5 -0
  22. package/dist/types/effects/low-altitude/shared.d.ts +67 -0
  23. package/dist/types/effects/low-altitude/target-lock.d.ts +4 -0
  24. package/dist/types/effects/low-altitude/types.d.ts +333 -0
  25. package/dist/types/effects/low-altitude/visual.d.ts +15 -0
  26. package/dist/types/effects/low-altitude.d.ts +15 -126
  27. package/dist/types/effects/standard-electronic-fence.d.ts +7 -0
  28. package/dist/types/effects/webgl-electronic-fence.d.ts +7 -0
  29. package/dist/types/index.d.ts +2 -2
  30. package/dist/types/map/create-map.d.ts +6 -1
  31. package/package.json +1 -1
package/dist/index.umd.js CHANGED
@@ -1 +1 @@
1
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("maplibre-gl")):"function"==typeof define&&define.amd?define(["exports","maplibre-gl"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).BitAllTechMaplibreCore={},t.maplibregl)}(this,function(t,e){"use strict";const i={},a=()=>({...i}),n="https://tiles.openfreemap.org/styles",r=(t,e,i)=>({type:t,label:e,style:`${n}/${i}`}),o={"openfreemap-liberty":r("openfreemap-liberty","OpenFreeMap Liberty","liberty"),"openfreemap-bright":r("openfreemap-bright","OpenFreeMap Bright","bright"),"openfreemap-positron":r("openfreemap-positron","OpenFreeMap Positron","positron"),"openfreemap-dark":r("openfreemap-dark","OpenFreeMap Dark","dark"),"openfreemap-fiord":r("openfreemap-fiord","OpenFreeMap Fiord","fiord")},l=Object.keys(o),c=(t="openfreemap-liberty")=>o[t].style,s=["0","1","2","3","4","5","6","7"],p=(t,e)=>{const i=(t=>{const e=t||a().tdtToken;if(!e)throw new Error("Tianditu token is required. Pass token or call setMaplibreToolsConfig({ tdtToken }).");return e})(e);return s.map(e=>`https://t${e}.tianditu.gov.cn/DataServer?T=${t}&x={x}&y={y}&l={z}&tk=${i}`)},d=(t,e={})=>({type:"raster",tiles:p(t,e.token),tileSize:256,minzoom:0,maxzoom:18,attribution:"&copy; 天地图"}),h=(t={})=>{const e=!1!==t.label,i={"tdt-image":d("img_w",t)},a=[{id:"tdt-image",type:"raster",source:"tdt-image"}];return e&&(i["tdt-image-label"]=d("cia_w",t),a.push({id:"tdt-image-label",type:"raster",source:"tdt-image-label"})),{version:8,sources:i,layers:a}},f=[...Object.keys(o),"tdt-image","tdt-image-label"],y=t=>f.includes(t),u=(t="openfreemap-liberty",e={})=>"tdt-image"===t?h({...e,label:!1}):"tdt-image-label"===t?h({...e,label:!0}):c(t),m=t=>t*Math.PI/180,g=t=>180*t/Math.PI,M=t=>(t%360+360)%360,b=(t,e,i)=>{const a=e/6378137,n=m(i),r=m(t[1]),o=m(t[0]),l=Math.asin(Math.sin(r)*Math.cos(a)+Math.cos(r)*Math.sin(a)*Math.cos(n)),c=o+Math.atan2(Math.sin(n)*Math.sin(a)*Math.cos(r),Math.cos(a)-Math.sin(r)*Math.sin(l));return[(s=g(c),s>180?s-360:s<-180?s+360:s),g(l)];var s},k=(t,e,i=64)=>{const a=((t,e)=>{const i=M(e)-M(t);return i<=0?i+360:i})(t,e),n=Math.max(12,Math.ceil(i*a/360));return Array.from({length:n+1},(e,i)=>M(t+a*i/n))},v=(t,e,i=64)=>(t=>{if(0===t.length)return t;const[e,i]=t[0],a=t[t.length-1];return a[0]===e&&a[1]===i?t:[...t,[e,i]]})(Array.from({length:i},(a,n)=>b(t,e,360*n/i))),A=(t,e,i=64)=>({type:"Polygon",coordinates:[v(t,e,i)]}),$=(t,e,i=64)=>({type:"LineString",coordinates:v(t,e,i)}),w=(t,e,i,a,n=64)=>{const r=k(i,a,n).map(i=>b(t,e,i));return{type:"Polygon",coordinates:[[t,...r,t]]}},x=(t,e,i,a,n=64)=>({type:"LineString",coordinates:k(i,a,n).map(i=>b(t,e,i))}),F=(t,e,i)=>({type:"LineString",coordinates:[t,b(t,e,i)]}),O=(t,e)=>({type:"Feature",geometry:t,properties:e}),q=t=>({type:"FeatureCollection",features:t}),S=(t,e,i)=>{const a=i?"visible":"none";e.forEach(e=>{t.getLayer(e)&&t.setLayoutProperty(e,"visibility",a)})},D=(t,e,i)=>{const a=e.id,n=`${a}-source`;let r,o={...e},l=[],c=[n],s=!1,p=!1;const d=()=>{null==r||r(),r=void 0,[...l].reverse().forEach(e=>{((t,e)=>{t.getLayer(e)&&t.removeLayer(e)})(t,e)}),[...c].reverse().forEach(e=>{((t,e)=>{t.getSource(e)&&t.removeSource(e)})(t,e)}),l=[],c=[n]},h=e=>{const i=t.getSource(n);i&&i.setData(e)},f=()=>{var e,a;if(s)return;d();const p=i(o);t.addSource(n,{type:"geojson",data:p.data}),null==(e=p.canvasSources)||e.forEach(e=>{t.addSource(e.id,e.source)}),c=[n,...(null==(a=p.canvasSources)?void 0:a.map(t=>t.id))||[]],l=p.layers.map(t=>t.id),p.layers.forEach(e=>{var i;const a="raster"===e.type&&(null==(i=p.canvasSources)?void 0:i[0])?p.canvasSources[0].id:n;t.addLayer({...e,source:a},o.beforeId)}),S(t,l,!1!==o.visible),p.startAnimation&&(r=p.startAnimation({getOptions:()=>o,setData:h})||void 0)},y=()=>{p&&!s&&t.isStyleLoaded()&&(p=!1,t.off("styledata",y),f())},u=()=>{s||(t.isStyleLoaded()?(p&&(p=!1,t.off("styledata",y)),f()):p||(p=!0,t.on("styledata",y)))};return u(),{id:a,update(t){s||(o={...o,...t,id:a},u())},show(){s||(o={...o,visible:!0},S(t,l,!0))},hide(){s||(o={...o,visible:!1},S(t,l,!1))},remove(){s||(s=!0,p&&(p=!1,t.off("styledata",y)),d())}}},j=(t,e=0)=>{const i=Math.max(10,t.radius??70),a=Math.max(i,t.maxRadius??2.3*i),n=Math.max(1,t.pulseCount??2),r=Math.max(1,t.lineWidth??2),o=t.pulseOpacity??.9,l=[O(A(t.center,i),{kind:"core"})];for(let c=0;c<n;c+=1){const s=(e+c/n)%1,p=i+(a-i)*s;l.push(O($(t.center,p),{kind:"pulse",opacity:o*(1-s),width:r*(1-.35*s)}))}return q(l)},T=t=>{const e=t.color||"#ff3b30",i=t.fillColor||e;return{data:j(t),layers:[{id:`${t.id}-core`,type:"fill",filter:["==",["get","kind"],"core"],paint:{"fill-color":i,"fill-opacity":t.fillOpacity??.28}},{id:`${t.id}-pulse`,type:"line",filter:["==",["get","kind"],"pulse"],paint:{"line-color":e,"line-opacity":["coalesce",["get","opacity"],t.pulseOpacity??.9],"line-width":["coalesce",["get","width"],t.lineWidth??2]}}],startAnimation({getOptions:t,setData:e}){const i=Math.max(400,t().duration??1800);let a=0;const n=performance.now(),r=o=>{const l=t();e(j(l,(o-n)%i/i)),a=requestAnimationFrame(r)};return a=requestAnimationFrame(r),()=>{cancelAnimationFrame(a)}}}},L=(t,e=0)=>{var i,a;const n=Math.max(16,t.radius??110),r=Math.max(0,t.pulseScale??.16),o=(1-Math.cos(e*Math.PI*2))/2,l=n*(1+r*o),c=1.28*l,s=Math.max(1,t.ringCount??(null==(i=t.radii)?void 0:i.length)??3),p=Math.max(2.2*l,t.maxRadius??((null==(a=t.radii)?void 0:a.length)?Math.max(...t.radii):n*(2.5*s))),d=p/s,h=[O(A(t.center,c),{kind:"halo",opacity:(t.haloOpacity??.16)*(.75+.65*o)}),O(A(t.center,l),{kind:"core",opacity:(t.fillOpacity??.28)*(.88+.2*o)}),O($(t.center,1.06*l),{kind:"core-ring",opacity:(t.lineOpacity??.95)*(.8+.2*o),width:Math.max(1,(t.lineWidth??3)*(.92+.12*o))})];for(let f=0;f<s;f+=1){const i=(f+e+1)*d%p||p,a=i/p;h.push(O($(t.center,i),{kind:"ring",opacity:Math.max(.18,(t.lineOpacity??.95)*(1-.42*a)),width:Math.max(1,(t.lineWidth??3)*(1-.18*a))}))}return q(h)},z=t=>{const e=t.color||"#ef4444",i=t.fillColor||e;return{data:L(t),layers:[{id:`${t.id}-halo`,type:"fill",filter:["==",["get","kind"],"halo"],paint:{"fill-color":i,"fill-opacity":["coalesce",["get","opacity"],t.haloOpacity??.16]}},{id:`${t.id}-core`,type:"fill",filter:["==",["get","kind"],"core"],paint:{"fill-color":i,"fill-opacity":["coalesce",["get","opacity"],t.fillOpacity??.28]}},{id:`${t.id}-rings`,type:"line",filter:["any",["==",["get","kind"],"ring"]],paint:{"line-color":e,"line-opacity":["coalesce",["get","opacity"],t.lineOpacity??.95],"line-width":["coalesce",["get","width"],t.lineWidth??3]}}],startAnimation({getOptions:t,setData:e}){const i=Math.max(600,t().duration??2e3);let a=0;const n=performance.now(),r=o=>{const l=t();e(L(l,(o-n)%i/i)),a=requestAnimationFrame(r)};return a=requestAnimationFrame(r),()=>{cancelAnimationFrame(a)}}}},P=(t,e,i)=>Math.min(i,Math.max(e,t)),I=t=>(t%360+360)%360,N=(t,e)=>{const i=(t=>{const e=t.trim(),i=e.match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);if(i){const t=i[1],e=3===t.length?t.split("").map(t=>t+t).join(""):t;return[parseInt(e.slice(0,2),16),parseInt(e.slice(2,4),16),parseInt(e.slice(4,6),16)]}const a=e.match(/^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/i);if(a)return[P(Number(a[1]),0,255),P(Number(a[2]),0,255),P(Number(a[3]),0,255)]})(t);return i?`rgba(${i[0]}, ${i[1]}, ${i[2]}, ${P(e,0,1)})`:t},B=(t,e)=>{const i=b(t,e,0)[1],a=b(t,e,90)[0],n=b(t,e,180)[1],r=b(t,e,270)[0];return[[r,i],[a,i],[a,n],[r,n]]},C=t=>{var e;const i=null==(e=t.gradient)?void 0:e.colors;return Array.isArray(i)&&i.length>=2?i:void 0},_=(t,e,i=0)=>{const a=t.getContext("2d"),n=C(e);if(!a||!e.gradient||!n)return;const r=t.width,o=r/2,l=o-2,c=e.startAngle+i,s=((t,e)=>{const i=I(e)-I(t);return i<=0?i+360:i})(c,e.endAngle+i),p=(c-90)*Math.PI/180;const d=p+s*Math.PI/180,h=e.gradient.opacity??e.opacity??.28,f=e.gradient.centerOpacity??e.gradient.tailOpacity??.25*h,y=e.gradient.edgeOpacity??e.gradient.headOpacity??h,u=a.createRadialGradient(o,o,0,o,o,l);n.forEach((t,e)=>{const i=e/Math.max(1,n.length-1),a=f+(y-f)*i;u.addColorStop(i,N(t,a))}),a.clearRect(0,0,r,r),a.save(),a.beginPath(),a.moveTo(o,o),a.arc(o,o,l,p,d,!1),a.closePath(),a.clip(),a.fillStyle=u,a.fillRect(0,0,r,r),a.restore()},E=t=>{if(!C(t))return;const e=(()=>{const t=document.createElement("canvas");return t.width=768,t.height=768,t})();return _(e,t),e},G=(t,e,i)=>C(t)?[]:[O(w(t.center,t.radius,e,i),{kind:"sector",color:t.color||"#ff453a",opacity:t.opacity??.28})],H=(t,e=0)=>{const i=t.startAngle+e,a=t.endAngle+e,n=[...G(t,i,a),O(F(t.center,t.radius,i),{kind:"frame"}),O(F(t.center,t.radius,a),{kind:"frame"})];return q(n)},J=t=>{const e=E(t),i=e?{id:`${t.id}-sector-fill`,type:"raster",paint:{"raster-opacity":1,"raster-fade-duration":0}}:{id:`${t.id}-sector-fill`,type:"fill",filter:["==",["get","kind"],"sector"],paint:{"fill-color":["coalesce",["get","color"],t.color||"#ff453a"],"fill-opacity":["coalesce",["get","opacity"],t.opacity??.28],"fill-antialias":!1}};return{data:H(t),canvasSources:e?[{id:`${t.id}-canvas-source`,source:{type:"canvas",canvas:e,coordinates:B(t.center,t.radius),animate:Boolean(t.rotationSpeed&&0!==t.rotationSpeed)}}]:void 0,layers:[i,{id:`${t.id}-sector-frame`,type:"line",filter:["==",["get","kind"],"frame"],paint:{"line-color":t.outlineColor||t.color||"#ff453a","line-opacity":t.outlineOpacity??.95,"line-width":t.outlineWidth??2}}],startAnimation:t.rotationSpeed&&0!==t.rotationSpeed?({getOptions:t,setData:i})=>{const a=performance.now();let n=0;const r=o=>{const l=t(),c=(o-a)/1e3*(l.rotationSpeed||0);e&&_(e,l,c),i(H(l,c)),n=requestAnimationFrame(r)};return n=requestAnimationFrame(r),()=>{cancelAnimationFrame(n)}}:void 0}},K=(t,e)=>{const i=Math.max(40,t.radius),a=t.direction??270,n=Math.min(180,Math.max(8,t.spread??72)),r=Math.max(1,t.lineCount??7),o=Math.max(20,t.lineSpacing??Math.max(80,i/9)),l=e??0,c=Math.max(0,Math.min(.35*i,t.innerRadius??Math.min(.4*o,120))),s=a-n/2,p=a+n/2,d=[];for(let h=0;h<r;h+=1){const e=c+l+h*o;if(e>i)continue;const a=e/i,n=1-h/Math.max(1,r);d.push(O(x(t.center,e,s,p),{kind:"directional-pulse-line",opacity:Math.max(.08,(t.opacity??.92)*(.42+.58*n)*(1-.28*a)),width:Math.max(1,(t.lineWidth??2.8)*(.86+.24*n)*(1-.08*a))}))}return q(d)},Q=t=>({data:K(t),layers:[{id:`${t.id}-directional-pulse`,type:"line",filter:["==",["get","kind"],"directional-pulse-line"],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":t.color||"#ef4444","line-opacity":["coalesce",["get","opacity"],t.opacity??.92],"line-width":["coalesce",["get","width"],t.lineWidth??2.8]}}],startAnimation:t.speed&&t.speed>0?({getOptions:t,setData:e})=>{const i=performance.now();let a=0;const n=r=>{const o=t(),l=Math.max(40,o.radius),c=Math.max(20,o.lineSpacing??Math.max(80,l/9)),s=(r-i)/1e3*(o.speed??0)%c;e(K(o,s)),a=requestAnimationFrame(n)};return a=requestAnimationFrame(n),()=>{cancelAnimationFrame(a)}}:void 0}),R=(t,e=0)=>{var i;const a=Math.max(0,t.ringCount??4),n=Math.max(1,t.trailCount??8),r=Math.max(12,t.sweepAngle??42),o=.22*r,l=t.tailOpacity??.04,c=t.headOpacity??Math.max(.24,t.opacity??.3),s=(t.sweepStartAngle??0)+e,p=!1!==t.showCrosshair,d=!1!==t.showDistanceLabels,h=Math.max(20,t.coreRadius??Math.min(160,.035*t.radius)),f=[];for(let y=a;y>=1;y-=1){const e=t.radius*y/a;if(f.push(O($(t.center,e),{kind:"ring"})),d){const a=(null==(i=t.distanceLabelFormatter)?void 0:i.call(t,e,y))??`${Math.round(e)}`;[{bearing:0,textAnchor:"bottom"},{bearing:90,textAnchor:"left"},{bearing:180,textAnchor:"top"},{bearing:270,textAnchor:"right"}].forEach(i=>{f.push(O({type:"Point",coordinates:b(t.center,e,i.bearing)},{kind:"distance-label",text:a,textAnchor:i.textAnchor}))})}}p&&f.push(O({type:"LineString",coordinates:[b(t.center,t.radius,180),b(t.center,t.radius,0)]},{kind:"crosshair"}),O({type:"LineString",coordinates:[b(t.center,t.radius,270),b(t.center,t.radius,90)]},{kind:"crosshair"})),f.push(O(A(t.center,h),{kind:"core"}));for(let y=n-1;y>=0;y-=1){const e=s-o*y,i=e+r,a=(n-y)/n,p=l+(c-l)*a*a;f.push(O(w(t.center,t.radius,e,i),{kind:"sweep",opacity:p}))}return f.push(O(w(t.center,t.radius,s+.42*r,s+r),{kind:"head",opacity:Math.min(1,c+.08)})),q(f)},U=t=>({data:R(t),layers:[{id:`${t.id}-radar-trail`,type:"fill",filter:["==",["get","kind"],"sweep"],paint:{"fill-color":t.color||"#22c55e","fill-opacity":["coalesce",["get","opacity"],t.opacity??.32]}},{id:`${t.id}-radar-rings`,type:"line",filter:["==",["get","kind"],"ring"],paint:{"line-color":t.ringColor||t.color||"#22c55e","line-opacity":t.ringOpacity??.95,"line-width":t.ringWidth??2}},{id:`${t.id}-radar-crosshair`,type:"line",filter:["==",["get","kind"],"crosshair"],paint:{"line-color":t.crosshairColor||t.ringColor||t.color||"#22c55e","line-opacity":t.crosshairOpacity??.5,"line-width":t.crosshairWidth??1.4}},{id:`${t.id}-radar-distance-labels`,type:"symbol",filter:["==",["get","kind"],"distance-label"],layout:{"text-field":["get","text"],"text-size":t.distanceLabelSize??12,"text-anchor":["get","textAnchor"],"text-allow-overlap":!0,"text-ignore-placement":!0},paint:{"text-color":t.distanceLabelColor||t.ringColor||t.color||"#22c55e","text-opacity":t.distanceLabelOpacity??.92,"text-halo-color":t.distanceLabelHaloColor||"rgba(15, 23, 42, 0.42)","text-halo-width":1}}],startAnimation({getOptions:t,setData:e}){const i=performance.now();let a=0;const n=r=>{const o=t(),l=(r-i)/1e3*(o.rotationSpeed??36);e(R(o,l)),a=requestAnimationFrame(n)};return a=requestAnimationFrame(n),()=>{cancelAnimationFrame(a)}}}),V=(t,e)=>t?"string"==typeof t&&y(t)?u(t,{token:e}):t:u("openfreemap-liberty");t.maplibregl=e,t.BASE_MAP_TYPES=f,t.OPENFREEMAP_STYLES=o,t.OPENFREEMAP_STYLE_BASE_URL=n,t.OPENFREEMAP_STYLE_TYPES=l,t.TDT_STYLE_TYPES=["tdt-image","tdt-image-label"],t.addDirectionalPulse=(t,e)=>D(t,e,Q),t.addPulseMarker=(t,e)=>D(t,e,T),t.addRadarSweep=(t,e)=>D(t,e,U),t.addRingPulseMarker=(t,e)=>D(t,e,z),t.addSectorScan=(t,e)=>D(t,e,J),t.createMap=t=>{const{style:i,tdtToken:a,...n}=t;return new e.Map({...n,style:V(i,a)})},t.createTiandituImageStyle=h,t.createTiandituRasterSource=d,t.getBaseMapStyle=u,t.getMaplibreToolsConfig=a,t.getOpenFreeMapStyle=c,t.isBaseMapType=y,t.setBaseMap=(t,e,i={})=>{const{diff:a=!1,...n}=i;t.setStyle(u(e,n),{diff:a})},t.setMaplibreToolsConfig=t=>{Object.assign(i,t)},Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})});
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("maplibre-gl")):"function"==typeof define&&define.amd?define(["exports","maplibre-gl"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).BitAllTechMaplibreCore={},t.maplibregl)}(this,function(t,e){"use strict";const o={},n=()=>({...o}),i="https://tiles.openfreemap.org/styles",r=(t,e,o)=>({type:t,label:e,style:`${i}/${o}`}),a={"openfreemap-liberty":r("openfreemap-liberty","OpenFreeMap Liberty","liberty"),"openfreemap-bright":r("openfreemap-bright","OpenFreeMap Bright","bright"),"openfreemap-positron":r("openfreemap-positron","OpenFreeMap Positron","positron"),"openfreemap-dark":r("openfreemap-dark","OpenFreeMap Dark","dark"),"openfreemap-fiord":r("openfreemap-fiord","OpenFreeMap Fiord","fiord")},l=Object.keys(a),c=(t="openfreemap-liberty")=>a[t].style,s=["0","1","2","3","4","5","6","7"],d="&copy; 天地图",f=(t,e)=>{const o=(t=>{const e=t||n().tdtToken;if(!e)throw new Error("Tianditu token is required. Pass token or call setMaplibreToolsConfig({ tdtToken }).");return e})(e);return s.map(e=>`https://t${e}.tianditu.gov.cn/DataServer?T=${t}&x={x}&y={y}&l={z}&tk=${o}`)},h=(t,e={})=>({type:"raster",tiles:f(t,e.token),tileSize:256,minzoom:0,maxzoom:18,attribution:d}),p=(t={})=>({type:"raster",tiles:f("vec_w",t.token),tileSize:256,minzoom:0,maxzoom:18,attribution:d}),u=(t={})=>{const e=!1!==t.label,o={"tdt-image":h("img_w",t)},n=[{id:"tdt-image",type:"raster",source:"tdt-image"}];return e&&(o["tdt-image-label"]=h("cia_w",t),n.push({id:"tdt-image-label",type:"raster",source:"tdt-image-label"})),{version:8,sources:o,layers:n}},g=(t={})=>{const e=!1!==t.label,o={"tdt-mvt":p(t)},n=[{id:"tdt-mvt",type:"raster",source:"tdt-mvt"}];return e&&(o["tdt-mvt-label"]=h("cva_w",t),n.push({id:"tdt-mvt-label",type:"raster",source:"tdt-mvt-label"})),{version:8,sources:o,layers:n}},y=[...Object.keys(a),"tdt-image","tdt-image-label","tdt-mvt","tdt-mvt-label"],m=t=>y.includes(t),_=(t="openfreemap-liberty",e={})=>"tdt-image"===t?u({...e,label:!1}):"tdt-image-label"===t?u({...e,label:!0}):"tdt-mvt"===t?g({...e,label:!1}):"tdt-mvt-label"===t?g({...e,label:!0}):c(t),w=6378137,v=t=>t*Math.PI/180,b=t=>180*t/Math.PI,M=t=>(t%360+360)%360,$=(t,e,o)=>{const n=e/w,i=v(o),r=v(t[1]),a=v(t[0]),l=Math.asin(Math.sin(r)*Math.cos(n)+Math.cos(r)*Math.sin(n)*Math.cos(i)),c=a+Math.atan2(Math.sin(i)*Math.sin(n)*Math.cos(r),Math.cos(n)-Math.sin(r)*Math.sin(l));return[(s=b(c),s>180?s-360:s<-180?s+360:s),b(l)];var s},k=(t,e)=>{const o=v(e[1]-t[1]),n=v(e[0]-t[0]),i=v(t[1]),r=v(e[1]),a=Math.sin(o/2)*Math.sin(o/2)+Math.cos(i)*Math.cos(r)*Math.sin(n/2)*Math.sin(n/2);return 12756274*Math.atan2(Math.sqrt(a),Math.sqrt(1-a))},A=(t,e)=>{const o=v(t[1]),n=v(e[1]),i=v(e[0]-t[0]),r=Math.sin(i)*Math.cos(n),a=Math.cos(o)*Math.sin(n)-Math.sin(o)*Math.cos(n)*Math.cos(i);return M(b(Math.atan2(r,a)))},x=(t,e,o=64)=>{const n=((t,e)=>{const o=M(e)-M(t);return o<=0?o+360:o})(t,e),i=Math.max(12,Math.ceil(o*n/360));return Array.from({length:i+1},(e,o)=>M(t+n*o/i))},F=(t,e,o=64)=>(t=>{if(0===t.length)return t;const[e,o]=t[0],n=t[t.length-1];return n[0]===e&&n[1]===o?t:[...t,[e,o]]})(Array.from({length:o},(n,i)=>$(t,e,360*i/o))),C=(t,e,o=64)=>({type:"Polygon",coordinates:[F(t,e,o)]}),P=(t,e,o=64)=>({type:"LineString",coordinates:F(t,e,o)}),S=(t,e,o,n,i=64)=>{const r=x(o,n,i).map(o=>$(t,e,o));return{type:"Polygon",coordinates:[[t,...r,t]]}},O=(t,e,o,n,i=64)=>({type:"LineString",coordinates:x(o,n,i).map(o=>$(t,e,o))}),L=(t,e,o)=>({type:"LineString",coordinates:[t,$(t,e,o)]}),W=(t,e)=>({type:"Feature",geometry:t,properties:e}),N=t=>({type:"FeatureCollection",features:t}),q=(t,e)=>{t.getLayer(e)&&t.removeLayer(e)},G=(t,e)=>{t.getSource(e)&&t.removeSource(e)},E=(t,e,o)=>{const n=o?"visible":"none";e.forEach(e=>{t.getLayer(e)&&t.setLayoutProperty(e,"visibility",n)})},I=t=>t instanceof Error&&"Style is not done loading."===t.message,R=(t,e,o)=>{const n=e.id,i=`${n}-source`;let r,a={...e},l=[],c=[i],s=!1,d=!1;const f=()=>{null==r||r(),r=void 0,[...l].reverse().forEach(e=>{q(t,e)}),[...c].reverse().forEach(e=>{G(t,e)}),l=[],c=[i]},h=e=>{const o=t.getSource(i);o&&o.setData(e)},p=()=>{try{(()=>{var e,n,d;if(s)return;f();const p=o(a);t.addSource(i,{type:"geojson",data:p.data}),null==(e=p.canvasSources)||e.forEach(e=>{t.addSource(e.id,e.source)}),c=[i,...(null==(n=p.canvasSources)?void 0:n.map(t=>t.id))||[]],l=p.layers.map(t=>t.id),p.layers.forEach(e=>{var o;const n="raster"===e.type&&(null==(o=p.canvasSources)?void 0:o[0])?p.canvasSources[0].id:i;t.addLayer({...e,source:n},a.beforeId)}),E(t,l,!1!==a.visible),null==(d=p.canvasSources)||d.forEach(e=>{var o;const n=t.style,i=null==(o=null==n?void 0:n.tileManagers)?void 0:o[e.id];if(!i||!i.t)return;const r=i.used;i.used=!0;const a=t;i.update(a.transform,a.terrain),i.used=r}),p.startAnimation&&(r=p.startAnimation({getOptions:()=>a,setData:h})||void 0)})(),d&&(d=!1,t.off("styledata",u))}catch(e){if(!I(e))throw e;d||(d=!0,t.on("styledata",u))}},u=()=>{d&&!s&&p()},g=()=>{s||p()};return g(),{id:n,update(t){s||(a={...a,...t,id:n},g())},show(){s||(a={...a,visible:!0},E(t,l,!0))},hide(){s||(a={...a,visible:!1},E(t,l,!1))},remove(){s||(s=!0,d&&(d=!1,t.off("styledata",u)),f())}}},j=(t,e=0)=>{const o=Math.max(10,t.radius??70),n=Math.max(o,t.maxRadius??2.3*o),i=Math.max(1,t.pulseCount??2),r=Math.max(1,t.lineWidth??2),a=t.pulseOpacity??.9,l=[W(C(t.center,o),{kind:"core"})];for(let c=0;c<i;c+=1){const s=(e+c/i)%1,d=o+(n-o)*s;l.push(W(P(t.center,d),{kind:"pulse",opacity:a*(1-s),width:r*(1-.35*s)}))}return N(l)},T=t=>{const e=t.color||"#ff3b30",o=t.fillColor||e;return{data:j(t),layers:[{id:`${t.id}-core`,type:"fill",filter:["==",["get","kind"],"core"],paint:{"fill-color":o,"fill-opacity":t.fillOpacity??.28}},{id:`${t.id}-pulse`,type:"line",filter:["==",["get","kind"],"pulse"],paint:{"line-color":e,"line-opacity":["coalesce",["get","opacity"],t.pulseOpacity??.9],"line-width":["coalesce",["get","width"],t.lineWidth??2]}}],startAnimation({getOptions:t,setData:e}){const o=Math.max(400,t().duration??1800);let n=0;const i=performance.now(),r=a=>{const l=t();e(j(l,(a-i)%o/o)),n=requestAnimationFrame(r)};return n=requestAnimationFrame(r),()=>{cancelAnimationFrame(n)}}}},D=(t,e=0)=>{const o=Math.max(1,t.radius??90),n=Math.max(1,t.minRadius??.78*o),i=Math.max(n,t.maxRadius??1.22*o),r=(1-Math.cos(e*Math.PI*2))/2,a=n+(i-n)*r,l=t.fillOpacity??.28,c=t.minFillOpacity??.46*l,s=t.strokeOpacity??.82,d=t.minStrokeOpacity??.38*s,f=1-r,h=[W(C(t.center,a),{kind:"breathing-fill",opacity:c+(l-c)*f})];return(t.strokeWidth??2)>0&&h.push(W(P(t.center,a),{kind:"breathing-stroke",opacity:d+(s-d)*f})),N(h)},V=t=>{const e=t.color||"#1677ff",o=t.fillColor||e,n=t.strokeColor||e,i=Math.max(0,t.strokeWidth??2);return{data:D(t),layers:[{id:`${t.id}-breathing-fill`,type:"fill",filter:["==",["get","kind"],"breathing-fill"],paint:{"fill-color":o,"fill-opacity":["coalesce",["get","opacity"],t.fillOpacity??.28]}},{id:`${t.id}-breathing-stroke`,type:"line",filter:["==",["get","kind"],"breathing-stroke"],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":n,"line-opacity":["coalesce",["get","opacity"],t.strokeOpacity??.82],"line-width":i}}],startAnimation({getOptions:t,setData:e}){const o=Math.max(400,t().duration??1800),n=performance.now();let i=0;const r=a=>{const l=t();e(D(l,(a-n)%o/o)),i=requestAnimationFrame(r)};return i=requestAnimationFrame(r),()=>{cancelAnimationFrame(i)}}}},Y=(t,e=0)=>{const o=Math.max(16,t.radius??110),n=Math.max(0,t.pulseScale??.16),i=(1-Math.cos(e*Math.PI*2))/2,r=o*(1+n*i),a=Math.max(1,t.ringCount??3),l=Math.max(2.2*r,t.maxRadius??o*(2.5*a)),c=l/a,s=t.fillOpacity??.28,d=[W(C(t.center,r),{kind:"core",opacity:s*(.88+.2*i)}),W(P(t.center,1.06*r),{kind:"core-ring",opacity:(t.lineOpacity??.95)*(.8+.2*i),width:Math.max(1,(t.lineWidth??3)*(.92+.12*i))})];for(let f=0;f<a;f+=1){const o=(f+e+1)*c%l||l,n=o/l;d.push(W(P(t.center,o),{kind:"ring",opacity:Math.max(.18,(t.lineOpacity??.95)*(1-.42*n)),width:Math.max(1,(t.lineWidth??3)*(1-.18*n))}))}return N(d)},z=t=>{const e=t.color||"#ef4444",o=t.fillColor||e;return{data:Y(t),layers:[{id:`${t.id}-core`,type:"fill",filter:["==",["get","kind"],"core"],paint:{"fill-color":o,"fill-opacity":["coalesce",["get","opacity"],t.fillOpacity??.28]}},{id:`${t.id}-rings`,type:"line",filter:["any",["==",["get","kind"],"ring"]],paint:{"line-color":e,"line-opacity":["coalesce",["get","opacity"],t.lineOpacity??.95],"line-width":["coalesce",["get","width"],t.lineWidth??3]}}],startAnimation({getOptions:t,setData:e}){const o=Math.max(600,t().duration??2e3);let n=0;const i=performance.now(),r=a=>{const l=t();e(Y(l,(a-i)%o/o)),n=requestAnimationFrame(r)};return n=requestAnimationFrame(r),()=>{cancelAnimationFrame(n)}}}},U=(t,e,o)=>Math.min(o,Math.max(e,t)),B=t=>{const e=t.trim(),o=e.match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);if(o){const t=o[1],e=3===t.length?t.split("").map(t=>t+t).join(""):t;return[parseInt(e.slice(0,2),16),parseInt(e.slice(2,4),16),parseInt(e.slice(4,6),16)]}const n=e.match(/^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/i);if(n)return[U(Number(n[1]),0,255),U(Number(n[2]),0,255),U(Number(n[3]),0,255)]},H=t=>(t%360+360)%360,J=t=>(t-90)*Math.PI/180,X=(t,e)=>{const o=B(t);return o?`rgba(${o[0]}, ${o[1]}, ${o[2]}, ${U(e,0,1)})`:t},K=t=>t*(2-t),Q=(t,e)=>{const o=t.length-1;if(e<=0)return t[0];if(e>=o)return t[o];const n=Math.floor(e),i=e-n,[r,a]=[B(t[n]),B(t[n+1])];if(!r||!a)return t[Math.round(e)];const[l,c,s]=((t,e,o)=>[Math.round(t[0]+(e[0]-t[0])*o),Math.round(t[1]+(e[1]-t[1])*o),Math.round(t[2]+(e[2]-t[2])*o)])(r,a,i);return`rgb(${l},${c},${s})`},Z=(t,e)=>{const o=$(t,e,0)[1],n=$(t,e,90)[0],i=$(t,e,180)[1],r=$(t,e,270)[0];return[[r,o],[n,o],[n,i],[r,i]]},tt=t=>{var e;const o=null==(e=t.gradient)?void 0:e.colors;return Array.isArray(o)&&o.length>=2?o:void 0},et=(t,e,o=0)=>{const n=t.getContext("2d"),i=tt(e);if(!n||!e.gradient||!i)return;const r=t.width,a=r/2,l=a-2,c=e.startAngle+o,s=((t,e)=>{const o=H(e)-H(t);return o<=0?o+360:o})(c,e.endAngle+o),d=J(c),f=d+s*Math.PI/180,h=e.gradient.opacity??e.opacity??.28,p=e.gradient.centerOpacity??.25*h,u=e.gradient.edgeOpacity??h,g=n.createRadialGradient(a,a,0,a,a,l);i.forEach((t,e)=>{const o=e/Math.max(1,i.length-1),n=p+(u-p)*o;g.addColorStop(o,X(t,n))}),n.clearRect(0,0,r,r),n.save(),n.beginPath(),n.moveTo(a,a),n.arc(a,a,l,d,f,!1),n.closePath(),n.clip(),n.fillStyle=g,n.fillRect(0,0,r,r),n.restore()},ot=t=>{if(!tt(t))return;const e=(()=>{const t=document.createElement("canvas");return t.width=768,t.height=768,t})();return et(e,t),e},nt=(t,e,o)=>tt(t)?[]:[W(S(t.center,t.radius,e,o),{kind:"sector",color:t.color||"#ff453a",opacity:t.opacity??.28})],it=(t,e=0)=>{const o=t.startAngle+e,n=t.endAngle+e,i=[...nt(t,o,n),W(L(t.center,t.radius,o),{kind:"frame"}),W(L(t.center,t.radius,n),{kind:"frame"})];return N(i)},rt=t=>{const e=ot(t),o=e?{id:`${t.id}-sector-fill`,type:"raster",paint:{"raster-opacity":1,"raster-fade-duration":0}}:{id:`${t.id}-sector-fill`,type:"fill",filter:["==",["get","kind"],"sector"],paint:{"fill-color":["coalesce",["get","color"],t.color||"#ff453a"],"fill-opacity":["coalesce",["get","opacity"],t.opacity??.28],"fill-antialias":!1}};return{data:it(t),canvasSources:e?[{id:`${t.id}-canvas-source`,source:{type:"canvas",canvas:e,coordinates:Z(t.center,t.radius),animate:Boolean(t.rotationSpeed&&0!==t.rotationSpeed)}}]:void 0,layers:[o,{id:`${t.id}-sector-frame`,type:"line",filter:["==",["get","kind"],"frame"],paint:{"line-color":t.outlineColor||t.color||"#ff453a","line-opacity":t.outlineOpacity??.95,"line-width":t.outlineWidth??2}}],startAnimation:t.rotationSpeed&&0!==t.rotationSpeed?({getOptions:t,setData:o})=>{const n=performance.now();let i=0;const r=a=>{const l=t(),c=(a-n)/1e3*(l.rotationSpeed||0);e&&et(e,l,c),o(it(l,c)),i=requestAnimationFrame(r)};return i=requestAnimationFrame(r),()=>{cancelAnimationFrame(i)}}:void 0}},at=(t,e)=>{const o=Math.max(40,t.radius),n=t.direction??270,i=Math.min(180,Math.max(8,t.spread??72)),r=Math.max(1,t.lineCount??7),a=Math.max(20,t.lineSpacing??Math.max(80,o/9)),l=e??0,c=Math.max(0,Math.min(.35*o,t.innerRadius??Math.min(.4*a,120))),s=n-i/2,d=n+i/2,f=[];for(let h=0;h<r;h+=1){const e=c+l+h*a;if(e>o)continue;const n=e/o,i=1-h/Math.max(1,r);f.push(W(O(t.center,e,s,d),{kind:"directional-pulse-line",opacity:Math.max(.08,(t.opacity??.92)*(.42+.58*i)*(1-.28*n)),width:Math.max(1,(t.lineWidth??2.8)*(.86+.24*i)*(1-.08*n))}))}return N(f)},lt=t=>({data:at(t),layers:[{id:`${t.id}-directional-pulse`,type:"line",filter:["==",["get","kind"],"directional-pulse-line"],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":t.color||"#ef4444","line-opacity":["coalesce",["get","opacity"],t.opacity??.92],"line-width":["coalesce",["get","width"],t.lineWidth??2.8]}}],startAnimation:t.speed&&t.speed>0?({getOptions:t,setData:e})=>{const o=performance.now();let n=0;const i=r=>{const a=t(),l=Math.max(40,a.radius),c=Math.max(20,a.lineSpacing??Math.max(80,l/9)),s=(r-o)/1e3*(a.speed??0)%c;e(at(a,s)),n=requestAnimationFrame(i)};return n=requestAnimationFrame(i),()=>{cancelAnimationFrame(n)}}:void 0}),ct=t=>{var e;const o=null==(e=t.gradient)?void 0:e.colors;return Array.isArray(o)&&o.length>=2},st=(t,e)=>{const o=$(t,e,0)[1],n=$(t,e,90)[0],i=$(t,e,180)[1],r=$(t,e,270)[0];return[[r,o],[n,o],[n,i],[r,i]]},dt=(t,e,o=0)=>{const n=t.getContext("2d"),i=e.gradient,r=null==i?void 0:i.colors;if(!n||!i||!r||r.length<2)return;const a=t.width,l=a/2,c=l-2,s=Math.max(12,e.sweepAngle??42),d=e.tailOpacity??.04,f=Math.max(.24,e.opacity??.3),h=(e.sweepStartAngle??0)+o,p=h,u=h+s,g=s;n.clearRect(0,0,a,a);const y=n.createConicGradient(J(p),l,l),m=g/360,_=Math.min(1,f+.08);for(let w=0;w<=128;w++){const t=w/128,e=d+(_-d)*K(t),o=t*(r.length-1),n=Q(r,o);y.addColorStop(t*m,X(n,Math.max(0,e)))}n.save(),n.beginPath(),n.moveTo(l,l),n.arc(l,l,c,J(p),J(u),!1),n.closePath(),n.fillStyle=y,n.fill(),n.restore()},ft=(t,e=0)=>{var o;const n=Math.max(0,t.ringCount??4),i=Math.max(12,t.sweepAngle??42),r=t.headOpacity??Math.max(.24,t.opacity??.3),a=(t.sweepStartAngle??0)+e,l=!1!==t.showCrosshair,c=!1!==t.showDistanceLabels,s=Math.max(20,t.coreRadius??Math.min(160,.035*t.radius)),d=ct(t),f=[];for(let h=n;h>=1;h-=1){const e=t.radius*h/n;if(f.push(W(P(t.center,e),{kind:"ring"})),c){const n=(null==(o=t.distanceLabelFormatter)?void 0:o.call(t,e,h))??`${Math.round(e)}`;[{bearing:0,textAnchor:"bottom"},{bearing:90,textAnchor:"left"},{bearing:180,textAnchor:"top"},{bearing:270,textAnchor:"right"}].forEach(o=>{f.push(W({type:"Point",coordinates:$(t.center,e,o.bearing)},{kind:"distance-label",text:n,textAnchor:o.textAnchor}))})}}return l&&f.push(W({type:"LineString",coordinates:[$(t.center,t.radius,180),$(t.center,t.radius,0)]},{kind:"crosshair"}),W({type:"LineString",coordinates:[$(t.center,t.radius,270),$(t.center,t.radius,90)]},{kind:"crosshair"})),f.push(W(C(t.center,s),{kind:"core"})),d||f.push(W(S(t.center,t.radius,a,a+i),{kind:"sweep",opacity:r})),N(f)},ht=t=>{const e=ct(t)?(()=>{const t=document.createElement("canvas");return t.width=768,t.height=768,t})():void 0;e&&dt(e,t);const o=e?{id:`${t.id}-radar-trail`,type:"raster",paint:{"raster-opacity":1,"raster-fade-duration":0}}:{id:`${t.id}-radar-trail`,type:"fill",filter:["==",["get","kind"],"sweep"],paint:{"fill-color":t.color||"#22c55e","fill-opacity":["coalesce",["get","opacity"],t.opacity??.32]}};return{data:ft(t),canvasSources:e?[{id:`${t.id}-canvas-source`,source:{type:"canvas",canvas:e,coordinates:st(t.center,t.radius),animate:!0}}]:void 0,layers:[o,{id:`${t.id}-radar-rings`,type:"line",filter:["==",["get","kind"],"ring"],paint:{"line-color":t.ringColor||t.color||"#22c55e","line-opacity":t.ringOpacity??.95,"line-width":t.ringWidth??2}},{id:`${t.id}-radar-crosshair`,type:"line",filter:["==",["get","kind"],"crosshair"],paint:{"line-color":t.crosshairColor||t.ringColor||t.color||"#22c55e","line-opacity":t.crosshairOpacity??.5,"line-width":t.crosshairWidth??1.4}},{id:`${t.id}-radar-distance-labels`,type:"symbol",filter:["==",["get","kind"],"distance-label"],layout:{"text-field":["get","text"],"text-size":t.distanceLabelSize??12,"text-anchor":["get","textAnchor"],"text-allow-overlap":!0,"text-ignore-placement":!0},paint:{"text-color":t.distanceLabelColor||t.ringColor||t.color||"#22c55e","text-opacity":t.distanceLabelOpacity??.92,"text-halo-color":t.distanceLabelHaloColor||"rgba(15, 23, 42, 0.42)","text-halo-width":1}}],startAnimation({getOptions:t,setData:o}){const n=performance.now();let i=0;const r=a=>{const l=t(),c=(a-n)/1e3*(l.rotationSpeed??36);e&&dt(e,l,c),o(ft(l,c)),i=requestAnimationFrame(r)};return i=requestAnimationFrame(r),()=>{cancelAnimationFrame(i)}}}},pt=(t,e)=>{const o=$(t,e,0)[1],n=$(t,e,90)[0],i=$(t,e,180)[1],r=$(t,e,270)[0];return[[r,o],[n,o],[n,i],[r,i]]},ut=t=>{const e=(()=>{const t=document.createElement("canvas");return t.width=512,t.height=512,t})();((t,e)=>{const o=t.getContext("2d");if(!o)return;const n=t.width,i=n/2,r=i-1,a=e.color||"#06c536",l=e.fillColor||a,c=e.borderColor||a,s=e.fillOpacity??.06,d=e.borderOpacity??.92;o.clearRect(0,0,n,n),o.save(),o.beginPath(),o.arc(i,i,r,0,2*Math.PI),o.clip();const f=o.createRadialGradient(i,i,0,i,i,r),h=Math.min(.8,s+.85*(d-s));f.addColorStop(0,X(l,s)),f.addColorStop(.85,X(l,s)),f.addColorStop(.92,X(c,s+.3*(h-s))),f.addColorStop(.96,X(c,s+.7*(h-s))),f.addColorStop(1,X(c,h)),o.fillStyle=f,o.fillRect(0,0,n,n),o.restore()})(e,t);const o=t.borderColor||t.color||"#06c536";return{data:N([W(P(t.center,t.radius),{kind:"defence-border"})]),canvasSources:[{id:`${t.id}-canvas-source`,source:{type:"canvas",canvas:e,coordinates:pt(t.center,t.radius),animate:!0}}],layers:[{id:`${t.id}-defence-circle`,type:"raster",paint:{"raster-opacity":1,"raster-fade-duration":0}},{id:`${t.id}-defence-border`,type:"line",filter:["==",["get","kind"],"defence-border"],paint:{"line-color":o,"line-opacity":t.borderOpacity??.92,"line-width":t.borderWidth??2}}]}},gt=(t,e=0)=>{const o=Math.max(1,t.sourceWidth??220),n=Math.max(1,t.targetWidth??45),i=(t=>{const e=t.target||$(t.center,t.distance||0,t.bearing||0),o=void 0!==t.target?A(t.center,t.target):M(t.bearing||0),n=$(t.center,t.startWidth/2,o-90),i=$(t.center,t.startWidth/2,o+90);return{polygon:{type:"Polygon",coordinates:[[n,$(e,t.endWidth/2,o-90),$(e,t.endWidth/2,o+90),i,n]]},centerLine:{type:"LineString",coordinates:[t.center,e]}}})({center:t.center,target:t.target,startWidth:o,endWidth:n}),r=[W(i.polygon,{kind:"countermeasure-channel"}),W(i.centerLine,{kind:"countermeasure-line"})],a=k(t.center,t.target),l=A(t.center,t.target),c=Math.max(0,Math.floor(t.particleCount??18)),s=Math.max(300,t.particleDuration??1200),d=e%s/s,f=Math.max(1,t.particleRadius??2.8);if(a>0)for(let h=0;h<c;h+=1){const e=(d+h/c)%1;r.push(W({type:"Point",coordinates:$(t.center,a*e,l)},{kind:"countermeasure-particle",opacity:.25+.75*e,radius:f*(.7+.3*e)}))}if(!1!==t.targetRipple){const o=Math.max(1,Math.floor(t.targetRippleCount??2)),n=Math.max(10,t.targetRippleRadius??120),i=Math.max(300,t.targetRippleDuration??900),a=e%i/i;for(let e=0;e<o;e+=1){const i=(a+e/o)%1,l="forcedLanding"===t.mode?1-i:i;r.push(W(P(t.target,Math.max(2,n*l)),{kind:"countermeasure-target-ripple",opacity:.9*Math.sin(Math.PI*i)}))}}return N(r)},yt=t=>{const e=t.color??"#a855f7",o=t.lineColor??"#f0abfc",n=Math.max(1,t.lineWidth??2.5);return{data:gt(t),layers:[{id:`${t.id}-countermeasure-channel`,type:"fill",filter:["==",["get","kind"],"countermeasure-channel"],paint:{"fill-color":t.channelColor??e,"fill-opacity":t.channelOpacity??.16}},{id:`${t.id}-countermeasure-glow`,type:"line",filter:["==",["get","kind"],"countermeasure-line"],layout:{"line-cap":"round"},paint:{"line-color":o,"line-opacity":.28*(t.lineOpacity??.92),"line-width":4*n,"line-blur":1.4*n}},{id:`${t.id}-countermeasure-line`,type:"line",filter:["==",["get","kind"],"countermeasure-line"],layout:{"line-cap":"round"},paint:{"line-color":o,"line-opacity":t.lineOpacity??.92,"line-width":n}},{id:`${t.id}-countermeasure-target-ripple`,type:"line",filter:["==",["get","kind"],"countermeasure-target-ripple"],paint:{"line-color":e,"line-opacity":["coalesce",["get","opacity"],.9],"line-width":Math.max(1,t.targetRippleWidth??2.5)}},{id:`${t.id}-countermeasure-particle`,type:"circle",filter:["==",["get","kind"],"countermeasure-particle"],paint:{"circle-color":t.particleColor??o,"circle-opacity":["coalesce",["get","opacity"],1],"circle-radius":["coalesce",["get","radius"],2.8],"circle-blur":.18,"circle-stroke-color":"#ffffff","circle-stroke-opacity":.45,"circle-stroke-width":.5}}],startAnimation:({getOptions:t,setData:e})=>{let o=0;const n=performance.now(),i=r=>{e(gt(t(),r-n)),o=requestAnimationFrame(i)};return o=requestAnimationFrame(i),()=>cancelAnimationFrame(o)}}},mt=(t,e=0)=>{const o=[],n=new Set,i=Math.max(0,Math.floor(t.particleCount??5)),r=Math.max(300,t.particleDuration??1600),a=e%r/r,l=Math.max(1,t.particleRadius??2.5);if(t.links.forEach((e,r)=>{const c=e.color??("detection"===(s=e.type)?"#38bdf8":"command"===s?"#22d3ee":"#f97316");var s;const d=k(e.from,e.to),f=A(e.from,e.to);if(o.push(W({type:"LineString",coordinates:[e.from,e.to]},{kind:"coordination-link",linkType:e.type,color:c})),!1!==t.showNodes&&[e.from,e.to].forEach(t=>{const e=`${t[0]},${t[1]}`;n.has(e)||(n.add(e),o.push(W({type:"Point",coordinates:t},{kind:"coordination-node",color:c})))}),!(d<=0))for(let n=0;n<i;n+=1){const s=(a+n/i+r/t.links.length)%1;o.push(W({type:"Point",coordinates:$(e.from,d*s,f)},{kind:"coordination-particle",color:c,opacity:.35+.65*s,radius:l}))}}),!1!==t.targetRipple){const n=Math.max(300,t.targetRippleDuration??1200),i=e%n/n,r=Math.max(10,t.targetRippleRadius??100)*i;o.push(W(P(t.center,Math.max(2,r)),{kind:"coordination-target-ripple",opacity:.9*(1-i)}))}return N(o)},_t=t=>{const e=Math.max(1,t.lineWidth??2.2),o=t.lineOpacity??.9;return{data:mt(t),layers:[{id:`${t.id}-coordination-detection`,type:"line",filter:["==",["get","linkType"],"detection"],paint:{"line-color":["coalesce",["get","color"],"#38bdf8"],"line-opacity":o,"line-width":e,"line-dasharray":[2,2]}},{id:`${t.id}-coordination-command`,type:"line",filter:["==",["get","linkType"],"command"],paint:{"line-color":["coalesce",["get","color"],"#22d3ee"],"line-opacity":o,"line-width":e,"line-dasharray":[.5,1.8]}},{id:`${t.id}-coordination-countermeasure`,type:"line",filter:["==",["get","linkType"],"countermeasure"],paint:{"line-color":["coalesce",["get","color"],"#f97316"],"line-opacity":o,"line-width":e+.8}},{id:`${t.id}-coordination-target-ripple`,type:"line",filter:["==",["get","kind"],"coordination-target-ripple"],paint:{"line-color":"#ff3b30","line-opacity":["coalesce",["get","opacity"],.9],"line-width":2.5}},{id:`${t.id}-coordination-node`,type:"circle",filter:["==",["get","kind"],"coordination-node"],paint:{"circle-color":["coalesce",["get","color"],"#ffffff"],"circle-radius":Math.max(2,t.nodeRadius??5),"circle-stroke-color":"#ffffff","circle-stroke-width":1.5}},{id:`${t.id}-coordination-particle`,type:"circle",filter:["==",["get","kind"],"coordination-particle"],paint:{"circle-color":["coalesce",["get","color"],"#ffffff"],"circle-opacity":["coalesce",["get","opacity"],1],"circle-radius":["coalesce",["get","radius"],2.5],"circle-blur":.1}}],startAnimation:({getOptions:t,setData:e})=>{let o=0;const n=performance.now(),i=r=>{e(mt(t(),r-n)),o=requestAnimationFrame(i)};return o=requestAnimationFrame(i),()=>cancelAnimationFrame(o)}}},wt=(t,e=0)=>{const o=[W({type:"LineString",coordinates:[t.center,t.spoofedPosition]},{kind:"spoofing-offset"})],n=k(t.center,t.spoofedPosition),i=A(t.center,t.spoofedPosition),r=Math.max(0,Math.floor(t.particleCount??10)),a=Math.max(300,t.particleDuration??1800),l=e%a/a;if(!1!==t.showTruePosition&&o.push(W({type:"Point",coordinates:t.center},{kind:"spoofing-true-position"})),!1!==t.showSpoofedPosition&&o.push(W({type:"Point",coordinates:t.spoofedPosition},{kind:"spoofing-ghost"})),n>0)for(let c=0;c<r;c+=1){const e=(l+c/r)%1;o.push(W({type:"Point",coordinates:$(t.center,n*e,i)},{kind:"spoofing-particle",opacity:.25+.75*e}))}if(!1!==t.ripple){const n=Math.max(1,Math.floor(t.rippleCount??2)),i=Math.max(300,t.rippleDuration??1200),r=Math.max(10,t.rippleRadius??120),a=e%i/i;for(let e=0;e<n;e+=1){const i=(a+e/n)%1;o.push(W(P(t.spoofedPosition,Math.max(2,r*i)),{kind:"spoofing-ripple",opacity:.75*(1-i)}))}}return N(o)},vt=t=>{const e=t.color??"#8b5cf6";return{data:wt(t),layers:[{id:`${t.id}-spoofing-offset`,type:"line",filter:["==",["get","kind"],"spoofing-offset"],layout:{"line-cap":"round"},paint:{"line-color":t.lineColor??e,"line-opacity":t.lineOpacity??.82,"line-width":Math.max(1,t.lineWidth??2),"line-dasharray":[1.2,2]}},{id:`${t.id}-spoofing-ripple`,type:"line",filter:["==",["get","kind"],"spoofing-ripple"],paint:{"line-color":e,"line-opacity":["coalesce",["get","opacity"],.75],"line-width":2}},{id:`${t.id}-spoofing-true-position`,type:"circle",filter:["==",["get","kind"],"spoofing-true-position"],paint:{"circle-color":"#ffffff","circle-radius":5,"circle-stroke-color":e,"circle-stroke-width":2}},{id:`${t.id}-spoofing-ghost`,type:"circle",filter:["==",["get","kind"],"spoofing-ghost"],paint:{"circle-color":e,"circle-opacity":t.ghostOpacity??.42,"circle-radius":Math.max(2,t.ghostRadius??8),"circle-stroke-color":"#ffffff","circle-stroke-opacity":.8,"circle-stroke-width":1.5}},{id:`${t.id}-spoofing-particle`,type:"circle",filter:["==",["get","kind"],"spoofing-particle"],paint:{"circle-color":e,"circle-opacity":["coalesce",["get","opacity"],1],"circle-radius":Math.max(1,t.particleRadius??2.5),"circle-blur":.12}}],startAnimation:({getOptions:t,setData:e})=>{let o=0;const n=performance.now(),i=r=>{e(wt(t(),r-n)),o=requestAnimationFrame(i)};return o=requestAnimationFrame(i),()=>cancelAnimationFrame(o)}}},bt="__electronic_fence_id",Mt=t=>JSON.parse(JSON.stringify(t)),$t=t=>{const e=t.map(t=>{const e=Number(t[0]),o=Number(t[1]);if(!Number.isFinite(e)||!Number.isFinite(o))throw new Error("电子围栏坐标必须是有限数字。");return[e,o]});if(e.length<3)throw new Error("电子围栏的每个环至少需要 3 个不同坐标。");var o,n;if(o=e[0],n=e[e.length-1],(o[0]!==n[0]||o[1]!==n[1])&&e.push([...e[0]]),e.length<4)throw new Error("电子围栏 Polygon 环无效。");return e},kt=t=>{if("string"!=typeof t.id||!t.id.trim())throw new Error("电子围栏必须提供非空字符串 id。");if(!t.geometry||"Polygon"!==t.geometry.type)throw new Error(`电子围栏 ${t.id} 仅支持 Polygon geometry。`);const e=Mt(t.properties||{});return{type:"Feature",id:t.id,geometry:{type:"Polygon",coordinates:t.geometry.coordinates.map($t)},properties:e}};class At{constructor(){this.features=new Map,this.states=new Map,this.activeIds=new Set,this.hiddenIds=new Set}setData(t){const e=new Map;t.features.forEach(t=>{const o=kt(t);if(e.has(o.id))throw new Error(`电子围栏 id 重复:${o.id}`);e.set(o.id,o)}),this.features=e,this.states.clear(),this.activeIds.clear(),this.hiddenIds.clear()}add(t){const e=kt(t);if(this.features.has(e.id))throw new Error(`电子围栏 id 已存在:${e.id}`);return this.features.set(e.id,e),e.id}update(t,e){const o=this.requireFeature(t);this.features.set(t,((t,e)=>{const o=t.properties||{},n=e.properties||{},i=n.style?{...o.style||{},...n.style}:o.style;return kt({...Mt(t),geometry:e.geometry?Mt(e.geometry):Mt(t.geometry),properties:{...Mt(o),...Mt(n),...i?{style:i}:{}}})})(o,e))}remove(t){this.requireFeature(t),this.features.delete(t),this.states.delete(t),this.activeIds.delete(t),this.hiddenIds.delete(t)}clear(){this.features.clear(),this.states.clear(),this.activeIds.clear(),this.hiddenIds.clear()}setActive(t,e){this.requireFeature(t),e?this.activeIds.add(t):this.activeIds.delete(t)}setState(t,e){if(this.requireFeature(t),"normal"!==e&&"warning"!==e&&"alarm"!==e&&"disabled"!==e)throw new Error(`电子围栏 ${t} 的渲染状态无效。`);"normal"===e?this.states.delete(t):this.states.set(t,e)}setVisible(t,e){this.requireFeature(t),e?this.hiddenIds.delete(t):this.hiddenIds.add(t)}isActive(t){return this.activeIds.has(t)}getState(t){return this.requireFeature(t),this.states.get(t)||"normal"}get(t){const e=this.features.get(t);return e?Mt(e):void 0}values(){return Array.from(this.features.values())}visibleValues(){return this.values().filter(t=>!this.hiddenIds.has(t.id))}requireFeature(t){const e=this.features.get(t);if(!e)throw new Error(`电子围栏不存在:${t}`);return e}}const xt=(t,e,o,n=!1)=>{const i=void 0===t?e:Number(t);if(!Number.isFinite(i)||n&&i<=0)throw new Error(`${o} 必须是${n?"大于 0 的":"有限"}数字。`);return i},Ft=(t,e)=>{if(!t.trim())throw new Error("电子围栏插件 id 不能为空。");xt(e.baseHeight,0,"defaults.baseHeight"),xt(e.height,0,"defaults.height",!0),xt(e.thickness,1,"defaults.thickness",!0)},Ct=t=>({baseHeight:xt(t.baseHeight,0,"defaults.baseHeight"),height:xt(t.height,0,"defaults.height",!0),thickness:xt(t.thickness,1,"defaults.thickness",!0)}),Pt=(t,e)=>"normal"!==t?t:e?"active":"normal",St=t=>{var e,o;return{...{...t.defaults.normal,...(null==(e=t.overrides)?void 0:e.normal)||{}},..."normal"===t.state?{}:{...t.defaults[t.state],...(null==(o=t.overrides)?void 0:o[t.state])||{}}}},Ot=(t,e)=>{const o=e/2,n=[];return t.coordinates.forEach(t=>{const e=[];for(let o=0;o<t.length-1;o+=1){const n=[t[o][0],t[o][1]],i=[t[o+1][0],t[o+1][1]],r=k(n,i);r<.01||e.push({start:n,end:i,length:r,bearing:A(n,i)})}const i=e.reduce((t,e)=>t+e.length,0);let r=0;e.forEach(t=>{const e=$(t.start,o,t.bearing+180),a=$(t.end,o,t.bearing);n.push({startLeft:$(e,o,t.bearing-90),startRight:$(e,o,t.bearing+90),endLeft:$(a,o,t.bearing-90),endRight:$(a,o,t.bearing+90),startProgress:i?r/i:0,endProgress:i?(r+t.length)/i:1}),r+=t.length})}),n},Lt=t=>({type:"MultiPolygon",coordinates:t.map(t=>[[t.startLeft,t.endLeft,t.endRight,t.startRight,t.startLeft]])}),Wt=(t,e,o)=>Math.min(o,Math.max(e,t)),Nt=t=>{const e=t.trim().toLowerCase();if(e.startsWith("#")){const t=e.slice(1),o=3===t.length||4===t.length?t.split("").map(t=>t+t).join(""):t;if(6===o.length||8===o.length){const t=Number.parseInt(o,16);if(Number.isFinite(t))return[(t>>(8===o.length?24:16)&255)/255,(t>>(8===o.length?16:8)&255)/255,(t>>(8===o.length?8:0)&255)/255,8===o.length?(255&t)/255:1]}}const o=e.match(/^rgba?\(([^)]+)\)$/);if(o){const t=o[1].split(",").map(t=>Number(t.trim()));if(t.length>=3&&t.every(t=>Number.isFinite(t)))return[Wt(t[0]/255,0,1),Wt(t[1]/255,0,1),Wt(t[2]/255,0,1),Wt(t[3]??1,0,1)]}throw new Error(`暂不支持的围栏颜色格式:${t}`)},qt=(t,e=1)=>{const[o,n,i,r]=Nt(t);return`rgba(${Math.round(255*o)}, ${Math.round(255*n)}, ${Math.round(255*i)}, ${Wt(r*e,0,1)})`},Gt=Wt,Et=t=>({type:"FeatureCollection",features:t.visibleValues().map(t=>({type:"Feature",id:`${t.id}:interaction`,geometry:Mt(t.geometry),properties:{[bt]:t.id}}))}),It=t=>{let e;const o=e=>{var o;if(!t.map.getLayer(t.layerId))return;const n=t.map.queryRenderedFeatures(e.point,{layers:[t.layerId]})[0],i=null==(o=null==n?void 0:n.properties)?void 0:o[bt];return"string"==typeof i?i:void 0},n=(e,o,n)=>{const i=t.store.get(o);i&&t.map.fire(`fence.${e}`,{instanceId:t.instanceId,renderer:t.renderer,id:o,feature:i,originalEvent:n})},i=t=>{const e=o(t);e&&n("click",e,t)},r=t=>{const i=o(t);i!==e&&(e&&n("mouseleave",e,t),e=i,e&&n("mouseenter",e,t))},a=t=>{e&&(n("mouseleave",e,t),e=void 0)};return t.map.on("click",i),t.map.on("mousemove",r),t.map.on("mouseout",a),()=>{t.map.off("click",i),t.map.off("mousemove",r),t.map.off("mouseout",a)}},Rt=t=>t instanceof Error&&"Style is not done loading."===t.message,jt=(t,e,o)=>{e.forEach(e=>{t.getLayer(e)&&t.setLayoutProperty(e,"visibility",o?"visible":"none")})},Tt=t=>{let e=!1;const o=()=>{if(e)throw new Error(`电子围栏插件 ${t.id} 已销毁。`)};return{id:t.id,renderer:t.renderer,setData(e){o(),t.store.setData(e),t.refresh()},add(e){o();const n=t.store.add(e);return t.refresh(),n},update(e,n){o(),t.store.update(e,n),t.refresh()},removeFeature(e){o(),t.store.remove(e),t.refresh()},clear(){o(),t.store.clear(),t.refresh()},setFeatureState(e,n){o(),t.store.setState(e,n),t.refresh()},setFeatureActive(e,n){o(),t.store.setActive(e,n),t.refresh()},setFeatureVisible(e,n){o(),t.store.setVisible(e,n),t.refresh()},show(){o(),t.setPluginVisible(!0)},hide(){o(),t.setPluginVisible(!1)},destroy(){e||(e=!0,t.destroy())}}},Dt="__electronic_fence_kind",Vt="__electronic_fence_color",Yt="__electronic_fence_outline_color",zt="__electronic_fence_outline_width",Ut="__electronic_fence_base",Bt="__electronic_fence_top",Ht={normal:{color:"#d8b4fe",opacity:.28,outlineColor:"#f5e9ff",outlineWidth:1.5},active:{color:"#c084fc",opacity:.42,outlineColor:"#ffffff",outlineWidth:2.5},warning:{color:"#f59e0b",opacity:.38,outlineColor:"#fde68a",outlineWidth:2},alarm:{color:"#ef4444",opacity:.48,outlineColor:"#ffffff",outlineWidth:2.5},disabled:{color:"#94a3b8",opacity:.16,outlineColor:"#cbd5e1",outlineWidth:1}},Jt=(t,e)=>{const o=[],n=Ct(e.defaults);return t.visibleValues().forEach(i=>{const r=Pt(t.getState(i.id),t.isActive(i.id)),a=St({defaults:Ht,overrides:e.styles,state:r}),l=Ot(i.geometry,n.thickness),c={[bt]:i.id,[Vt]:qt(a.color,Gt(a.opacity,0,1)),[Yt]:qt(a.outlineColor),[zt]:Math.max(0,a.outlineWidth),[Ut]:n.baseHeight,[Bt]:n.baseHeight+n.height};l.length&&o.push({type:"Feature",id:`${i.id}:wall`,geometry:Lt(l),properties:{...c,[Dt]:"wall"}}),o.push({type:"Feature",id:`${i.id}:boundary`,geometry:i.geometry,properties:{...c,[Dt]:"boundary"}})}),{type:"FeatureCollection",features:o}},Xt=[{thicknessScale:.08,opacity:1},{thicknessScale:.22,opacity:.56},{thicknessScale:.45,opacity:.28},{thicknessScale:.8,opacity:.12},{thicknessScale:1.3,opacity:.045}],Kt={normal:{color:"#d8b4fe",opacity:.2,outlineColor:"#f5e9ff",outlineWidth:1.5,glowStrength:1,flowColor:"#ffffff",flowCount:3,flowLineStyle:"dashed",flowWidth:.18},active:{color:"#e9d5ff",opacity:.28,outlineColor:"#ffffff",outlineWidth:2.5,glowStrength:1.25,flowColor:"#ffffff",flowCount:3,flowLineStyle:"dashed",flowWidth:.2},warning:{color:"#f59e0b",opacity:.25,outlineColor:"#fde68a",outlineWidth:2,glowStrength:1.1,flowColor:"#ffffff",flowCount:4,flowLineStyle:"dashed",flowWidth:.18},alarm:{color:"#ef4444",opacity:.3,outlineColor:"#ffffff",outlineWidth:2.5,glowStrength:1.35,flowColor:"#ffffff",flowCount:4,flowLineStyle:"dashed",flowWidth:.2},disabled:{color:"#94a3b8",opacity:.12,outlineColor:"#cbd5e1",outlineWidth:1,glowStrength:0,flowColor:"#ffffff",flowCount:0,flowLineStyle:"dashed",flowWidth:0}},Qt=(t,o)=>{const n=e.MercatorCoordinate.fromLngLat(t,o);return[n.x,n.y,n.z]},Zt=(t,e)=>[t[0]-e[0],t[1]-e[1],t[2]-e[2]],te=(t,e,o)=>{const n=Zt(e,t),i=Zt(o,t);return(t=>{const e=Math.hypot(t[0],t[1],t[2])||1;return[t[0]/e,t[1]/e,t[2]/e]})([n[1]*i[2]-n[2]*i[1],n[2]*i[0]-n[0]*i[2],n[0]*i[1]-n[1]*i[0]])},ee=(t,e,o,n,i)=>{const r=te(e[0],e[1],e[2]);[0,1,2,0,2,3].forEach(a=>{((t,e,o,n,i,r)=>{t.push(...e,...o,n,i,...r.color,r.flowColor[0],r.flowColor[1],r.flowColor[2],r.glowStrength,r.flowWidth,r.flowCount,r.flowLineStyle)})(t,e[a],r,o[a],n[a],i)})},oe=(t,e,o,n,i)=>{const r=o+n,a=Qt(e.startLeft,o),l=Qt(e.startRight,o),c=Qt(e.endLeft,o),s=Qt(e.endRight,o),d=Qt(e.startLeft,r),f=Qt(e.startRight,r),h=Qt(e.endLeft,r),p=Qt(e.endRight,r);ee(t,[d,h,p,f],[1,1,1,1],[e.startProgress,e.endProgress,e.endProgress,e.startProgress],i),ee(t,[a,c,h,d],[0,0,1,1],[e.startProgress,e.endProgress,e.endProgress,e.startProgress],i),ee(t,[s,l,f,p],[0,0,1,1],[e.endProgress,e.startProgress,e.startProgress,e.endProgress],i)},ne=(t,e,o)=>{const n=Xt.map(()=>[]),i=[],r=Ct(e.defaults);let a=!1;t.visibleValues().forEach(l=>{const c=t.isActive(l.id),s=Pt(t.getState(l.id),c),d=St({defaults:Kt,overrides:e.styles,state:s}),f=o.enabled&&("all"===o.scope||(t=>"active"===t||"warning"===t||"alarm"===t)(s)),h=((t,e)=>{const o=Nt(t.color),n=Nt(t.flowColor),i=e&&t.flowCount>0?Math.round(Gt(t.flowCount,1,8)):0;return{color:[o[0],o[1],o[2],Gt(o[3]*t.opacity,0,1)],flowColor:n,glowStrength:Gt(t.glowStrength,0,4),flowCount:i,flowLineStyle:"solid"===t.flowLineStyle?0:1,flowWidth:i>0?Gt(t.flowWidth,.01,.49):0}})(d,f);Ot(l.geometry,r.thickness).forEach(t=>{oe(i,t,r.baseHeight,r.height,h)}),h.glowStrength>0&&Xt.forEach((t,e)=>{const o=r.thickness*(1+Math.min(h.glowStrength,2)*t.thicknessScale);Ot(l.geometry,o).forEach(t=>{oe(n[e],t,r.baseHeight,r.height,h)})}),a||(a=h.flowCount>0&&h.flowWidth>0)});const l=n.reduce((t,e)=>t+e.length,0),c=new Float32Array(l+i.length),s=[];let d=0;n.forEach((t,e)=>{const o=t.length/19;o>0&&s.push({first:d/19,count:o,opacity:Xt[e].opacity}),c.set(t,d),d+=t.length});const f=d/19;return c.set(i,d),{vertices:c,glowPasses:s,bodyFirst:f,bodyVertexCount:i.length/19,animated:a}},ie=(t,e,o)=>{const n=t.createShader(e);if(!n)throw new Error("无法创建电子围栏 WebGL shader。");if(t.shaderSource(n,o),t.compileShader(n),!t.getShaderParameter(n,t.COMPILE_STATUS)){const e=t.getShaderInfoLog(n)||"未知 shader 编译错误";throw t.deleteShader(n),new Error(`电子围栏 WebGL shader 编译失败:${e}`)}return n},re=(t,e,o)=>{const n=t.getUniformLocation(e,o);if(!n)throw new Error(`电子围栏 WebGL uniform 不存在:${o}`);return n};class ae{constructor(t,e){this.type="custom",this.renderingMode="3d",this.geometry={vertices:new Float32Array,glowPasses:[],bodyFirst:0,bodyVertexCount:0,animated:!1},this.visible=!0,this.id=t,this.animation=e}setGeometry(t){var e;this.geometry=t,this.uploadGeometry(),null==(e=this.map)||e.triggerRepaint()}setVisible(t){var e;this.visible=t,null==(e=this.map)||e.triggerRepaint()}onAdd(t,e){if(this.map=t,this.gl=e,this.program=(t=>{const e="undefined"!=typeof WebGL2RenderingContext&&t instanceof WebGL2RenderingContext,o=e?"#version 300 es\n precision highp float;\n in vec3 a_position;\n in vec3 a_normal;\n in float a_height_ratio;\n in float a_path_progress;\n in vec4 a_color;\n in vec3 a_flow_color;\n in float a_glow_strength;\n in float a_flow_width;\n in float a_flow_count;\n in float a_flow_line_style;\n uniform mat4 u_matrix;\n out vec3 v_normal;\n out float v_height_ratio;\n out float v_path_progress;\n out vec4 v_color;\n out vec3 v_flow_color;\n out float v_glow_strength;\n out float v_flow_width;\n out float v_flow_count;\n out float v_flow_line_style;\n void main() {\n gl_Position = u_matrix * vec4(a_position, 1.0);\n v_normal = a_normal;\n v_height_ratio = a_height_ratio;\n v_path_progress = a_path_progress;\n v_color = a_color;\n v_flow_color = a_flow_color;\n v_glow_strength = a_glow_strength;\n v_flow_width = a_flow_width;\n v_flow_count = a_flow_count;\n v_flow_line_style = a_flow_line_style;\n }\n ":"\n precision highp float;\n attribute vec3 a_position;\n attribute vec3 a_normal;\n attribute float a_height_ratio;\n attribute float a_path_progress;\n attribute vec4 a_color;\n attribute vec3 a_flow_color;\n attribute float a_glow_strength;\n attribute float a_flow_width;\n attribute float a_flow_count;\n attribute float a_flow_line_style;\n uniform mat4 u_matrix;\n varying vec3 v_normal;\n varying float v_height_ratio;\n varying float v_path_progress;\n varying vec4 v_color;\n varying vec3 v_flow_color;\n varying float v_glow_strength;\n varying float v_flow_width;\n varying float v_flow_count;\n varying float v_flow_line_style;\n void main() {\n gl_Position = u_matrix * vec4(a_position, 1.0);\n v_normal = a_normal;\n v_height_ratio = a_height_ratio;\n v_path_progress = a_path_progress;\n v_color = a_color;\n v_flow_color = a_flow_color;\n v_glow_strength = a_glow_strength;\n v_flow_width = a_flow_width;\n v_flow_count = a_flow_count;\n v_flow_line_style = a_flow_line_style;\n }\n ",n="\n precision highp float;\n uniform float u_time;\n uniform float u_speed;\n uniform float u_animation_enabled;\n uniform float u_glow_pass;\n uniform float u_glow_opacity;\n VARYING vec3 v_normal;\n VARYING float v_height_ratio;\n VARYING float v_path_progress;\n VARYING vec4 v_color;\n VARYING vec3 v_flow_color;\n VARYING float v_glow_strength;\n VARYING float v_flow_width;\n VARYING float v_flow_count;\n VARYING float v_flow_line_style;\n void main() {\n float bandCore = 0.0;\n float bandGlow = 0.0;\n float verticalFace = 1.0 - smoothstep(\n 0.82,\n 0.98,\n abs(normalize(v_normal).z)\n );\n\n if (\n u_animation_enabled > 0.5 &&\n v_flow_count > 0.5 &&\n v_flow_width > 0.0001\n ) {\n float count = max(v_flow_count, 1.0);\n float phase = fract(\n v_height_ratio * count + u_time * u_speed * count\n );\n float bandDistance = abs(phase - 0.5);\n float dashPhase = fract(\n v_path_progress * 36.0 - u_time * u_speed * 2.4\n );\n float dash = smoothstep(0.02, 0.1, dashPhase) *\n (1.0 - smoothstep(0.62, 0.74, dashPhase));\n float linePattern = v_flow_line_style > 0.5 ? dash : 1.0;\n\n bandCore = 1.0 - smoothstep(\n max(v_flow_width * 0.08, 0.001),\n max(v_flow_width * 0.42, 0.003),\n bandDistance\n );\n float glowDistance = bandDistance / max(v_flow_width, 0.001);\n bandGlow = exp(\n -glowDistance * glowDistance * 2.6\n );\n bandCore *= linePattern * verticalFace;\n bandGlow *= verticalFace;\n }\n\n if (u_glow_pass > 0.5) {\n float glowAlpha = clamp(\n (v_color.a * 0.003 + bandGlow * 0.085) *\n v_glow_strength * u_glow_opacity,\n 0.0,\n 0.14\n );\n OUTPUT_COLOR = vec4(v_color.rgb, glowAlpha);\n return;\n }\n\n float faceLight = 0.88 + 0.12 * abs(normalize(v_normal).z);\n vec3 bodyColor = v_color.rgb * faceLight;\n vec3 color = mix(bodyColor, v_flow_color, bandCore);\n float alpha = clamp(\n v_color.a + bandCore * 0.68,\n 0.0,\n 1.0\n );\n OUTPUT_COLOR = vec4(color, alpha);\n }\n ",i=(t,e,o)=>t.split(e).join(o),r=e?`#version 300 es\n ${i(i(n,"VARYING","in"),"OUTPUT_COLOR","fragmentColor").replace("precision highp float;","precision highp float;\n out vec4 fragmentColor;")}\n `:i(i(n,"VARYING","varying"),"OUTPUT_COLOR","gl_FragColor"),a=ie(t,t.VERTEX_SHADER,o),l=ie(t,t.FRAGMENT_SHADER,r),c=t.createProgram();if(!c)throw t.deleteShader(a),t.deleteShader(l),new Error("无法创建电子围栏 WebGL program。");if(t.attachShader(c,a),t.attachShader(c,l),t.linkProgram(c),t.deleteShader(a),t.deleteShader(l),!t.getProgramParameter(c,t.LINK_STATUS)){const e=t.getProgramInfoLog(c)||"未知 program 链接错误";throw t.deleteProgram(c),new Error(`电子围栏 WebGL program 链接失败:${e}`)}return c})(e),this.locations=((t,e)=>({position:t.getAttribLocation(e,"a_position"),normal:t.getAttribLocation(e,"a_normal"),heightRatio:t.getAttribLocation(e,"a_height_ratio"),pathProgress:t.getAttribLocation(e,"a_path_progress"),color:t.getAttribLocation(e,"a_color"),flowColor:t.getAttribLocation(e,"a_flow_color"),glowStrength:t.getAttribLocation(e,"a_glow_strength"),flowWidth:t.getAttribLocation(e,"a_flow_width"),flowCount:t.getAttribLocation(e,"a_flow_count"),flowLineStyle:t.getAttribLocation(e,"a_flow_line_style"),matrix:re(t,e,"u_matrix"),time:re(t,e,"u_time"),speed:re(t,e,"u_speed"),animationEnabled:re(t,e,"u_animation_enabled"),glowPass:re(t,e,"u_glow_pass"),glowOpacity:re(t,e,"u_glow_opacity")}))(e,this.program),this.buffer=e.createBuffer()||void 0,!this.buffer)throw new Error("无法创建电子围栏 WebGL 顶点缓冲。");this.uploadGeometry(e)}render(t,e){if(!(this.visible&&this.program&&this.buffer&&this.locations&&(this.geometry.glowPasses.length||this.geometry.bodyVertexCount)))return;const o=19*Float32Array.BYTES_PER_ELEMENT,n=(e,n,i)=>{t.enableVertexAttribArray(e),t.vertexAttribPointer(e,n,t.FLOAT,!1,o,i*Float32Array.BYTES_PER_ELEMENT)};t.useProgram(this.program),t.bindBuffer(t.ARRAY_BUFFER,this.buffer),n(this.locations.position,3,0),n(this.locations.normal,3,3),n(this.locations.heightRatio,1,6),n(this.locations.pathProgress,1,7),n(this.locations.color,4,8),n(this.locations.flowColor,3,12),n(this.locations.glowStrength,1,15),n(this.locations.flowWidth,1,16),n(this.locations.flowCount,1,17),n(this.locations.flowLineStyle,1,18),t.uniformMatrix4fv(this.locations.matrix,!1,e.defaultProjectionData.mainMatrix),t.uniform1f(this.locations.time,performance.now()/1e3),t.uniform1f(this.locations.speed,this.animation.speed),t.uniform1f(this.locations.animationEnabled,this.animation.enabled?1:0),t.enable(t.BLEND),t.enable(t.DEPTH_TEST),t.disable(t.CULL_FACE),t.depthMask(!1),this.geometry.glowPasses.length&&(t.blendFunc(t.SRC_ALPHA,t.ONE),t.uniform1f(this.locations.glowPass,1),this.geometry.glowPasses.forEach(e=>{t.uniform1f(this.locations.glowOpacity,e.opacity),t.drawArrays(t.TRIANGLES,e.first,e.count)})),this.geometry.bodyVertexCount&&(t.blendFuncSeparate(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA,t.ONE,t.ONE_MINUS_SRC_ALPHA),t.uniform1f(this.locations.glowPass,0),t.uniform1f(this.locations.glowOpacity,0),t.drawArrays(t.TRIANGLES,this.geometry.bodyFirst,this.geometry.bodyVertexCount)),t.depthMask(!0),t.bindBuffer(t.ARRAY_BUFFER,null)}onRemove(t,e){this.buffer&&e.deleteBuffer(this.buffer),this.program&&e.deleteProgram(this.program),this.map=void 0,this.gl=void 0,this.buffer=void 0,this.program=void 0,this.locations=void 0}uploadGeometry(t){const e=t||this.gl;e&&this.buffer&&(e.bindBuffer(e.ARRAY_BUFFER,this.buffer),e.bufferData(e.ARRAY_BUFFER,this.geometry.vertices,e.STATIC_DRAW),e.bindBuffer(e.ARRAY_BUFFER,null))}}const le=(t,e)=>t?"string"==typeof t&&m(t)?_(t,{token:e}):t:_("openfreemap-liberty");t.maplibregl=e,t.BASE_MAP_TYPES=y,t.OPENFREEMAP_STYLES=a,t.OPENFREEMAP_STYLE_BASE_URL=i,t.OPENFREEMAP_STYLE_TYPES=l,t.TDT_STYLE_TYPES=["tdt-image","tdt-image-label","tdt-mvt","tdt-mvt-label"],t.addBreachAlert=(t,e)=>{const o=e.id,n=`${o}-fence-source`,i=`${o}-fence-fill`,r=`${o}-fence-line`,a=`${o}-ripple-source`,l=`${o}-ripple-line`;let c,s,d,f={...e},h=!1,p=!1,u=!1,g=!1,y=0;const m=()=>f.fenceColor??"#1677ff",_=()=>f.fenceFillColor??m(),w=()=>f.fenceFillOpacity??.1,v=()=>f.fenceBorderWidth??2,b=()=>f.fenceBorderOpacity??.9,M=()=>f.fenceAlertColor??"#ff3b30",$=()=>f.rippleColor??M(),k=e=>{const o=t.getSource(a);o&&o.setData(e)},A=t=>{const e=Math.max(20,f.rippleRadius??800),o=Math.max(1,f.rippleCount??3),n=Math.max(400,f.rippleDuration??1500),i=Math.max(1,f.rippleLineWidth??3),r=performance.now(),a=l=>{k(((t,e,o,n,i,r)=>{const a=[];for(let l=0;l<o;l+=1){const c=(r/n+l/o)%1,s=c*e;s<1||a.push(W(P(t,s),{kind:"ring",opacity:.95*(1-c),width:i*(1-.3*c)}))}return N(a)})(t,e,o,n,i,l-r)),y=requestAnimationFrame(a)};y=requestAnimationFrame(a)},x=()=>{if(!u)return;const e=m(),o=_();t.getLayer(i)&&(t.setPaintProperty(i,"fill-color",o),t.setPaintProperty(i,"fill-opacity",w())),t.getLayer(r)&&(t.setPaintProperty(r,"line-color",e),t.setPaintProperty(r,"line-width",v()),t.setPaintProperty(r,"line-opacity",b()))},F=()=>{const e=f.tacticalColor??M(),o=Math.max(1,f.tacticalBorderWidth??4),n="viewport"===f.tacticalScope?12:0,i=Math.max(60,f.fenceFlashInterval??200),r=t.getContainer(),a=document.createElement("div");a.style.position="absolute",a.style.inset=`${n}px`,a.style.border=`${o}px solid ${e}`,a.style.boxShadow=`inset 0 0 ${6*o}px ${e}`,a.style.pointerEvents="none",a.style.zIndex="5",a.style.opacity="1",r.appendChild(a),d=a;let l=!0;s=setInterval(()=>{l=!l,a.style.opacity=l?"1":"0.15"},i)},C=()=>{const e=(t=>{if(!t)return[];if(Array.isArray(t))return[{type:"Polygon",coordinates:t}];switch(t.type){case"Polygon":return[t];case"MultiPolygon":return t.coordinates.map(t=>({type:"Polygon",coordinates:t}));case"Feature":{const e=t.geometry;return"Polygon"===(null==e?void 0:e.type)?[e]:"MultiPolygon"===(null==e?void 0:e.type)?e.coordinates.map(t=>({type:"Polygon",coordinates:t})):[]}case"FeatureCollection":{const e=[];for(const o of t.features){const t=o.geometry;"Polygon"===(null==t?void 0:t.type)?e.push(t):"MultiPolygon"===(null==t?void 0:t.type)&&e.push(...t.coordinates.map(t=>({type:"Polygon",coordinates:t})))}return e}default:return[]}})(f.fence);if(0===e.length)return;const o=N(e.map(t=>W(t,{kind:"fence"})));if(u){const e=t.getSource(n);e&&e.setData(o),x()}else t.getSource(n)?t.getSource(n).setData(o):t.addSource(n,{type:"geojson",data:o}),t.getLayer(i)||t.addLayer({id:i,type:"fill",source:n,filter:["==",["get","kind"],"fence"],paint:{"fill-color":_(),"fill-opacity":w()}},f.beforeId),t.getLayer(r)||t.addLayer({id:r,type:"line",source:n,filter:["==",["get","kind"],"fence"],paint:{"line-color":m(),"line-width":v(),"line-opacity":b()}},f.beforeId),u=!0,E(t,[i,r],!1!==f.visible)},S=()=>{p&&!h&&O()},O=()=>{if(!h)try{C(),t.getSource(a)||t.addSource(a,{type:"geojson",data:N([])}),t.getLayer(l)?t.getLayer(l)&&t.setPaintProperty(l,"line-color",$()):(t.addLayer({id:l,type:"line",source:a,filter:["==",["get","kind"],"ring"],paint:{"line-color":$(),"line-opacity":["coalesce",["get","opacity"],.9],"line-width":["coalesce",["get","width"],3]}},f.beforeId),E(t,[l],!1!==f.visible)),p=!1,t.off("styledata",S)}catch(e){if(!I(e))throw e;p||(p=!0,t.on("styledata",S))}},L=()=>{c&&(clearInterval(c),c=void 0),y&&(cancelAnimationFrame(y),y=0),k(N([])),s&&(clearInterval(s),s=void 0),d&&(d.remove(),d=void 0),x()};return O(),{id:o,update(t){h||(f={...f,...t,id:o},O())},show(){h||(f={...f,visible:!0},E(t,[i,r,l],!0))},hide(){h||(f={...f,visible:!1},E(t,[i,r,l],!1))},remove(){h||(h=!0,p&&(p=!1,t.off("styledata",S)),L(),q(t,l),q(t,r),q(t,i),G(t,a),G(t,n),u=!1)},trigger(e){if(h)return;g&&L();const o=e??f.center;g=!0,!1!==f.fenceFlash&&(()=>{if(!u)return;const e=M(),o=Math.max(60,f.fenceFlashInterval??200);let n=!0;t.getLayer(i)&&(t.setPaintProperty(i,"fill-color",e),t.setPaintProperty(i,"fill-opacity",.42)),t.getLayer(r)&&(t.setPaintProperty(r,"line-color",e),t.setPaintProperty(r,"line-opacity",1)),c=setInterval(()=>{n=!n;const e=n?.42:.08,o=n?1:.4;t.getLayer(i)&&t.setPaintProperty(i,"fill-opacity",e),t.getLayer(r)&&t.setPaintProperty(r,"line-opacity",o)},o)})(),!1!==f.ripple&&A(o),f.tacticalFlash&&F()},reset(){h||(L(),g=!1)},isActive:()=>g}},t.addBreathingCircle=(t,e)=>R(t,e,V),t.addCoordinatedCountermeasure=(t,e)=>R(t,e,_t),t.addCountermeasureBeam=(t,e)=>R(t,e,yt),t.addDefenceCircle=(t,e)=>R(t,e,ut),t.addDirectionalPulse=(t,e)=>R(t,e,lt),t.addNavigationSpoofing=(t,e)=>R(t,e,vt),t.addPulseMarker=(t,e)=>R(t,e,T),t.addRadarSweep=(t,e)=>R(t,e,ht),t.addRingPulseMarker=(t,e)=>R(t,e,z),t.addSectorScan=(t,e)=>R(t,e,rt),t.addStandardElectronicFenceLayer=(t,e)=>{Ft(e.id,e.defaults);const o=new At,n=`${e.id}-standard-source`,i=`${e.id}-standard-extrusion`,r=`${e.id}-standard-outline`,a=`${e.id}-standard-interaction`,l=[i,r,...!1===e.interactive?[]:[a]];let c=Jt(o,e),s=!1!==e.visible,d=!1;const f=()=>{if(!d)try{t.getSource(n)||t.addSource(n,{type:"geojson",data:c}),t.getLayer(i)||t.addLayer({id:i,type:"fill-extrusion",source:n,filter:["==",["get",Dt],"wall"],paint:{"fill-extrusion-color":["get",Vt],"fill-extrusion-opacity":1,"fill-extrusion-base":["get",Ut],"fill-extrusion-height":["get",Bt],"fill-extrusion-vertical-gradient":!0}},e.beforeId),t.getLayer(r)||t.addLayer({id:r,type:"line",source:n,filter:["==",["get",Dt],"boundary"],paint:{"line-color":["get",Yt],"line-width":["get",zt],"line-opacity":1}},e.beforeId),!1===e.interactive||t.getLayer(a)||t.addLayer({id:a,type:"fill",source:n,filter:["==",["get",Dt],"boundary"],paint:{"fill-color":"#000000","fill-opacity":0}},e.beforeId),jt(t,l,s)}catch(o){if(!Rt(o))throw o}},h=()=>{f()};t.on("styledata",h),f();const p=!1===e.interactive?()=>{}:It({map:t,instanceId:e.id,renderer:"standard",layerId:a,store:o});return Tt({id:e.id,renderer:"standard",store:o,refresh:()=>{c=Jt(o,e);const i=t.getSource(n);i?i.setData(c):f()},setPluginVisible(e){s=e,f(),jt(t,l,s)},destroy(){d=!0,t.off("styledata",h),p(),[...l].reverse().forEach(e=>{t.getLayer(e)&&t.removeLayer(e)}),t.getSource(n)&&t.removeSource(n)}})},t.addTargetLock=(t,o)=>{const n=o.id;let i,r={...o},a=!1;const l=document.createElement("div"),c=document.createElement("div"),s=Array.from({length:4},()=>document.createElement("div")),d=Array.from({length:4},()=>document.createElement("div"));l.dataset.effectId=n,l.setAttribute("aria-hidden","true"),l.style.position="absolute",l.style.pointerEvents="none",c.style.position="absolute",c.style.inset="0",l.appendChild(c),s.forEach(t=>{t.style.position="absolute",t.style.boxSizing="border-box",c.appendChild(t)}),d.forEach(t=>{t.style.position="absolute",l.appendChild(t)});const f=new e.Marker({element:l,anchor:"center"}).setLngLat(r.center).addTo(t),h=()=>{const t=r.color??"#ff3b30",e=Math.max(24,r.size??72),o=Math.max(1,r.lineWidth??2),n=Math.min(e/2,Math.max(2*o,r.cornerLength??18)),a=Math.max(2,r.crosshairLength??10),h=Math.max(0,r.crosshairGap??5);f.setLngLat(r.center),l.style.width=`${e}px`,l.style.height=`${e}px`,l.style.display=!1===r.visible?"none":"block",l.style.opacity=`${Math.min(1,Math.max(0,r.opacity??1))}`,s.forEach(t=>{t.style.width=`${n}px`,t.style.height=`${n}px`,t.style.border="0"}),Object.assign(s[0].style,{left:"0",top:"0",borderLeft:`${o}px solid ${t}`,borderTop:`${o}px solid ${t}`}),Object.assign(s[1].style,{right:"0",top:"0",borderRight:`${o}px solid ${t}`,borderTop:`${o}px solid ${t}`}),Object.assign(s[2].style,{right:"0",bottom:"0",borderRight:`${o}px solid ${t}`,borderBottom:`${o}px solid ${t}`}),Object.assign(s[3].style,{left:"0",bottom:"0",borderLeft:`${o}px solid ${t}`,borderBottom:`${o}px solid ${t}`}),d.forEach(e=>{e.style.display=!1===r.showCrosshair?"none":"block",e.style.background=t}),Object.assign(d[0].style,{width:`${o}px`,height:`${a}px`,left:"50%",bottom:`calc(50% + ${h}px)`,transform:"translateX(-50%)"}),Object.assign(d[1].style,{width:`${o}px`,height:`${a}px`,left:"50%",top:`calc(50% + ${h}px)`,transform:"translateX(-50%)"}),Object.assign(d[2].style,{width:`${a}px`,height:`${o}px`,right:`calc(50% + ${h}px)`,top:"50%",transform:"translateY(-50%)"}),Object.assign(d[3].style,{width:`${a}px`,height:`${o}px`,left:`calc(50% + ${h}px)`,top:"50%",transform:"translateY(-50%)"}),null==i||i.cancel(),i=void 0,c.style.transform="rotate(0deg)",!1!==r.rotate&&(i=c.animate([{transform:"rotate(0deg)"},{transform:"rotate(360deg)"}],{duration:Math.max(300,r.rotationDuration??2400),iterations:1/0}))};return h(),{id:n,update(t){a||(r={...r,...t,id:n},h())},show(){a||(r={...r,visible:!0},l.style.display="block")},hide(){a||(r={...r,visible:!1},l.style.display="none")},remove(){a||(a=!0,null==i||i.cancel(),i=void 0,f.remove())}}},t.addWebGLElectronicFenceLayer=(t,e)=>{Ft(e.id,e.defaults);const o=(t=>({enabled:(null==t?void 0:t.enabled)??!0,fps:Math.round(Gt((null==t?void 0:t.fps)??30,1,60)),speed:Math.max(0,(null==t?void 0:t.speed)??.35),scope:(null==t?void 0:t.scope)??"all"}))(e.animation),n=new At,i=`${e.id}-webgl`,r=`${e.id}-webgl-interaction-source`,a=`${e.id}-webgl-interaction`,l=new ae(i,o);let c=Et(n),s=ne(n,e,o),d=!1!==e.visible,f=!1,h=0,p=0;const u=()=>{h&&(cancelAnimationFrame(h),h=0)},g=e=>{!f&&d&&s.animated?(("undefined"==typeof document||!document.hidden)&&e-p>=1e3/o.fps&&(p=e,t.triggerRepaint()),h=requestAnimationFrame(g)):h=0},y=()=>{const e=o.enabled&&d&&s.animated&&!!t.getLayer(i);e&&!h?(p=0,h=requestAnimationFrame(g)):e||u()},m=()=>{if(!f)try{!1===e.interactive||t.getSource(r)||t.addSource(r,{type:"geojson",data:c}),t.getLayer(i)||t.addLayer(l,e.beforeId),!1===e.interactive||t.getLayer(a)||t.addLayer({id:a,type:"fill",source:r,paint:{"fill-color":"#000000","fill-opacity":0}},e.beforeId),l.setVisible(d),jt(t,!1===e.interactive?[]:[a],d),y()}catch(o){if(!Rt(o))throw o}},_=()=>{m()};l.setGeometry(s),t.on("styledata",_),m();const w=!1===e.interactive?()=>{}:It({map:t,instanceId:e.id,renderer:"webgl",layerId:a,store:n});return Tt({id:e.id,renderer:"webgl",store:n,refresh:()=>{s=ne(n,e,o),c=Et(n),l.setGeometry(s);const i=t.getSource(r);i&&i.setData(c),m(),y()},setPluginVisible(o){d=o,l.setVisible(d),m(),jt(t,!1===e.interactive?[]:[a],d),y()},destroy(){f=!0,u(),t.off("styledata",_),w(),t.getLayer(a)&&t.removeLayer(a),t.getLayer(i)&&t.removeLayer(i),t.getSource(r)&&t.removeSource(r)}})},t.createFenceCircle=(t,e,o)=>C(t,e,o),t.createMap=t=>{const{style:o,tdtToken:n,projection:i,...r}=t,a=new e.Map({...r,style:le(o,n)});return i&&a.on("style.load",()=>{a.setProjection({type:i})}),a},t.createTiandituImageStyle=u,t.createTiandituRasterSource=h,t.getBaseMapStyle=_,t.getMaplibreToolsConfig=n,t.getOpenFreeMapStyle=c,t.isBaseMapType=m,t.setBaseMap=(t,e,o={})=>{const{diff:n=!1,...i}=o;t.setStyle(_(e,i),{diff:n})},t.setMaplibreToolsConfig=t=>{Object.assign(o,t)},Object.defineProperty(t,Symbol.toStringTag,{value:"Module"})});
@@ -1,7 +1,7 @@
1
1
  import type { Map, StyleSpecification } from "maplibre-gl";
2
2
  import { type OpenFreeMapStyleType } from "./openfreemap";
3
3
  import { type TiandituStyleOptions } from "./tianditu";
4
- export type BaseMapType = OpenFreeMapStyleType | "tdt-image" | "tdt-image-label";
4
+ export type BaseMapType = OpenFreeMapStyleType | "tdt-image" | "tdt-image-label" | "tdt-mvt" | "tdt-mvt-label";
5
5
  export interface BaseMapOptions extends TiandituStyleOptions {
6
6
  /** 透传给 map.setStyle;false 会完整重载样式,true 会尝试差量更新。 */
7
7
  diff?: boolean;
@@ -11,6 +11,10 @@ export declare const BASE_MAP_TYPES: BaseMapType[];
11
11
  export declare const isBaseMapType: (type: string) => type is BaseMapType;
12
12
  /** 根据底图类型返回 MapLibre style。OpenFreeMap 返回 URL,天地图返回内联 style。 */
13
13
  export declare const getBaseMapStyle: (type?: BaseMapType, options?: TiandituStyleOptions) => string | StyleSpecification;
14
+ /**
15
+ * 切换内置底图。
16
+ * 注意:setStyle 会重建样式,业务图层/插件图层如需保留,应在 styledata/load 后自行恢复或使用对应控制器重建。
17
+ */
14
18
  export declare const setBaseMap: (map: Map, type: BaseMapType, options?: BaseMapOptions) => void;
15
19
  export * from "./openfreemap";
16
20
  export * from "./tianditu";
@@ -1,6 +1,6 @@
1
1
  import type { RasterSourceSpecification, StyleSpecification } from "maplibre-gl";
2
- /** 天地图图层类型:影像底图或影像注记。 */
3
- export type TiandituLayerType = "tdt-image" | "tdt-image-label";
2
+ /** 天地图图层类型:影像底图、影像注记、矢量底图、矢量注记。 */
3
+ export type TiandituLayerType = "tdt-image" | "tdt-image-label" | "tdt-mvt" | "tdt-mvt-label";
4
4
  export interface TiandituOptions {
5
5
  /** 天地图 token;不传时读取 setMaplibreToolsConfig 设置的全局 token。 */
6
6
  token?: string;
@@ -9,7 +9,10 @@ export interface TiandituStyleOptions extends TiandituOptions {
9
9
  /** 是否叠加注记图层,默认 true。 */
10
10
  label?: boolean;
11
11
  }
12
- export declare const TDT_STYLE_TYPES: readonly ["tdt-image", "tdt-image-label"];
13
- export declare const createTiandituRasterSource: (tileType: "img_w" | "cia_w", options?: TiandituOptions) => RasterSourceSpecification;
12
+ export declare const TDT_STYLE_TYPES: readonly ["tdt-image", "tdt-image-label", "tdt-mvt", "tdt-mvt-label"];
13
+ export declare const createTiandituRasterSource: (tileType: "img_w" | "cia_w" | "vec_w" | "cva_w", options?: TiandituOptions) => RasterSourceSpecification;
14
+ export declare const createTiandituMvtSource: (options?: TiandituOptions) => RasterSourceSpecification;
14
15
  /** 创建 MapLibre 可直接使用的天地图影像 style。 */
15
16
  export declare const createTiandituImageStyle: (options?: TiandituStyleOptions) => StyleSpecification;
17
+ /** 创建 MapLibre 可直接使用的天地图矢量 style。 */
18
+ export declare const createTiandituMvtStyle: (options?: TiandituStyleOptions) => StyleSpecification;
@@ -0,0 +1,76 @@
1
+ import type { Map as MaplibreMap } from "maplibre-gl";
2
+ import { type LngLatTuple } from "./geometry";
3
+ import type { ElectronicFenceController, ElectronicFenceDefaults, ElectronicFenceFeature, ElectronicFenceFeatureCollection, ElectronicFenceFeaturePatch, ElectronicFenceRendererType, ElectronicFenceStateStyles, ElectronicFenceStatus, ElectronicFenceVisualState } from "./electronic-fence-types";
4
+ export declare const FENCE_ID_PROPERTY = "__electronic_fence_id";
5
+ /** 两种渲染器共用的严格数据状态;不依赖具体渲染实现。 */
6
+ export declare class ElectronicFenceStore {
7
+ private features;
8
+ private states;
9
+ private activeIds;
10
+ private hiddenIds;
11
+ setData(data: ElectronicFenceFeatureCollection): void;
12
+ add(feature: ElectronicFenceFeature): string;
13
+ update(id: string, patch: ElectronicFenceFeaturePatch): void;
14
+ remove(id: string): void;
15
+ clear(): void;
16
+ setActive(id: string, active: boolean): void;
17
+ setState(id: string, state: ElectronicFenceStatus): void;
18
+ setVisible(id: string, visible: boolean): void;
19
+ isActive(id: string): boolean;
20
+ getState(id: string): ElectronicFenceStatus;
21
+ get(id: string): ElectronicFenceFeature | undefined;
22
+ values(): ElectronicFenceFeature[];
23
+ visibleValues(): ElectronicFenceFeature[];
24
+ private requireFeature;
25
+ }
26
+ export interface ResolvedFenceDimensions {
27
+ baseHeight: number;
28
+ height: number;
29
+ thickness: number;
30
+ }
31
+ export declare const validateFenceDefaults: (id: string, defaults: ElectronicFenceDefaults) => void;
32
+ export declare const resolveFenceDimensions: (defaults: ElectronicFenceDefaults) => ResolvedFenceDimensions;
33
+ export declare const resolveFenceVisualState: (status: ElectronicFenceStatus, active: boolean) => ElectronicFenceVisualState;
34
+ export declare const resolveFenceStyle: <Style extends object>(options: {
35
+ defaults: Record<ElectronicFenceVisualState, Style>;
36
+ overrides?: ElectronicFenceStateStyles<Style>;
37
+ state: ElectronicFenceVisualState;
38
+ }) => Style;
39
+ export interface ElectronicFenceSegment {
40
+ startLeft: LngLatTuple;
41
+ startRight: LngLatTuple;
42
+ endLeft: LngLatTuple;
43
+ endRight: LngLatTuple;
44
+ startProgress: number;
45
+ endProgress: number;
46
+ }
47
+ /** 将 Polygon 边界拆成互相略有重叠的窄矩形,适合两种渲染器共用。 */
48
+ export declare const createFenceSegments: (geometry: GeoJSON.Polygon, thickness: number) => ElectronicFenceSegment[];
49
+ export declare const createFenceWallMultiPolygon: (segments: ElectronicFenceSegment[]) => GeoJSON.MultiPolygon;
50
+ export type RgbaColor = [number, number, number, number];
51
+ /** WebGL 和标准图层共用的轻量颜色解析。 */
52
+ export declare const parseFenceColor: (value: string) => RgbaColor;
53
+ export declare const toFenceRgbaCss: (value: string, opacity?: number) => string;
54
+ export declare const clampFenceNumber: (value: number, min: number, max: number) => number;
55
+ export declare const createFenceInteractionData: (store: ElectronicFenceStore) => GeoJSON.FeatureCollection;
56
+ interface BindFenceInteractionsOptions {
57
+ map: MaplibreMap;
58
+ instanceId: string;
59
+ renderer: ElectronicFenceRendererType;
60
+ layerId: string;
61
+ store: ElectronicFenceStore;
62
+ }
63
+ /** 透明 MapLibre Fill Layer 负责两种渲染器一致的点击和悬停事件。 */
64
+ export declare const bindFenceInteractions: (options: BindFenceInteractionsOptions) => (() => void);
65
+ export declare const isStyleNotReadyError: (error: unknown) => boolean;
66
+ export declare const setFenceLayerVisibility: (map: MaplibreMap, layerIds: string[], visible: boolean) => void;
67
+ interface CreateElectronicFenceControllerOptions {
68
+ id: string;
69
+ renderer: ElectronicFenceRendererType;
70
+ store: ElectronicFenceStore;
71
+ refresh: () => void;
72
+ setPluginVisible: (visible: boolean) => void;
73
+ destroy: () => void;
74
+ }
75
+ export declare const createElectronicFenceController: (options: CreateElectronicFenceControllerOptions) => ElectronicFenceController;
76
+ export {};
@@ -0,0 +1,131 @@
1
+ import type { MapMouseEvent } from "maplibre-gl";
2
+ /** 电子围栏显式渲染状态。active 属于临时交互态。 */
3
+ export type ElectronicFenceStatus = "normal" | "warning" | "alarm" | "disabled";
4
+ /** 电子围栏当前实际使用的视觉状态。 */
5
+ export type ElectronicFenceVisualState = ElectronicFenceStatus | "active";
6
+ /** MapLibre 标准图层能够表达的公共样式。 */
7
+ export interface StandardElectronicFenceStyleOptions {
8
+ /** 围栏主体颜色。支持 #rgb、#rgba、#rrggbb、#rrggbbaa、rgb() 和 rgba()。 */
9
+ color: string;
10
+ /** 围栏主体透明度,范围 0-1。 */
11
+ opacity: number;
12
+ /** 地面边界线颜色。 */
13
+ outlineColor: string;
14
+ /** 地面边界线宽度,单位像素。 */
15
+ outlineWidth: number;
16
+ }
17
+ /** WebGL 高质量围栏在公共样式之上增加光晕和流光。 */
18
+ export interface WebGLElectronicFenceStyleOptions extends StandardElectronicFenceStyleOptions {
19
+ /** 与围栏主体同色的多层泛光强度;0 表示关闭。 */
20
+ glowStrength: number;
21
+ /** 水平流光的虚线核心颜色,默认白色。 */
22
+ flowColor: string;
23
+ /** 沿围栏高度同时向下移动的亮带数量;0 表示关闭,启用时限制为 1-8。 */
24
+ flowCount: number;
25
+ /** 流光核心线型;dashed 为流动虚线,solid 为连续实线。 */
26
+ flowLineStyle: "dashed" | "solid";
27
+ /** 单组泛光在高度方向的扩散比例,启用时限制为 0.01-0.49。 */
28
+ flowWidth: number;
29
+ }
30
+ /** 单个电子围栏的业务属性;渲染器只透传,不读取其中字段控制效果。 */
31
+ export interface ElectronicFenceProperties extends Record<string, unknown> {
32
+ /** 可选业务名称,仅作为业务数据透传。 */
33
+ name?: string;
34
+ }
35
+ /** 首版仅支持 Polygon;矩形和圆形应先转换为 Polygon。 */
36
+ export type ElectronicFenceFeature = GeoJSON.Feature<GeoJSON.Polygon, ElectronicFenceProperties> & {
37
+ /** 围栏必须使用稳定且唯一的字符串 id。 */
38
+ id: string;
39
+ };
40
+ export type ElectronicFenceFeatureCollection = GeoJSON.FeatureCollection<GeoJSON.Polygon, ElectronicFenceProperties>;
41
+ /** update() 对已有围栏的局部修改。geometry 传入时会整体替换。 */
42
+ export interface ElectronicFenceFeaturePatch {
43
+ geometry?: GeoJSON.Polygon;
44
+ properties?: Partial<ElectronicFenceProperties>;
45
+ }
46
+ /** 插件实例中所有围栏统一使用的尺寸,不读取 Feature properties 覆盖。 */
47
+ export interface ElectronicFenceDefaults {
48
+ /** 默认 0 米。 */
49
+ baseHeight?: number;
50
+ /** 默认围栏相对高度,必须大于 0。 */
51
+ height: number;
52
+ /** 围栏横向总宽度,单位米;默认 1,显式传入时必须大于 0。 */
53
+ thickness?: number;
54
+ }
55
+ /** 五种固定语义状态的样式插槽,具体颜色和参数由业务覆盖。 */
56
+ export interface ElectronicFenceStateStyles<Style> {
57
+ normal?: Partial<Style>;
58
+ active?: Partial<Style>;
59
+ warning?: Partial<Style>;
60
+ alarm?: Partial<Style>;
61
+ disabled?: Partial<Style>;
62
+ }
63
+ interface BaseElectronicFenceLayerOptions {
64
+ /** 插件实例 id;内部 Source 和 Layer id 会基于它派生。 */
65
+ id: string;
66
+ /** 将所有渲染图层插入到指定图层之前。 */
67
+ beforeId?: string;
68
+ /** 初始是否可见,默认 true。 */
69
+ visible?: boolean;
70
+ /** 所有围栏共用的默认尺寸。 */
71
+ defaults: ElectronicFenceDefaults;
72
+ /** 是否启用点击和悬停事件,默认 true。 */
73
+ interactive?: boolean;
74
+ }
75
+ /** MapLibre 内置图层版本的创建参数。 */
76
+ export interface StandardElectronicFenceLayerOptions extends BaseElectronicFenceLayerOptions {
77
+ styles?: ElectronicFenceStateStyles<StandardElectronicFenceStyleOptions>;
78
+ }
79
+ /** WebGL 流光动画配置。 */
80
+ export interface WebGLElectronicFenceAnimationOptions {
81
+ /** 是否播放流光,默认 true。 */
82
+ enabled?: boolean;
83
+ /** 目标刷新率,默认 30,内部限制在 1-60。 */
84
+ fps?: number;
85
+ /** 亮带每秒向下移动的围栏高度比例,默认 0.35;1 表示每秒从顶到底一次。 */
86
+ speed?: number;
87
+ /** all 播放全部;highlighted 只播放 active、warning 和 alarm。 */
88
+ scope?: "all" | "highlighted";
89
+ }
90
+ /** 原生 WebGL 高质量版本的创建参数。 */
91
+ export interface WebGLElectronicFenceLayerOptions extends BaseElectronicFenceLayerOptions {
92
+ styles?: ElectronicFenceStateStyles<WebGLElectronicFenceStyleOptions>;
93
+ animation?: WebGLElectronicFenceAnimationOptions;
94
+ }
95
+ export type ElectronicFenceRendererType = "standard" | "webgl";
96
+ /** 两种渲染器共同实现的严格数据 API。 */
97
+ export interface ElectronicFenceController {
98
+ readonly id: string;
99
+ readonly renderer: ElectronicFenceRendererType;
100
+ /** 全量替换围栏,并清空 renderer state、active 和 hidden 状态。 */
101
+ setData: (data: ElectronicFenceFeatureCollection) => void;
102
+ /** 严格新增;id 已存在时抛错。 */
103
+ add: (feature: ElectronicFenceFeature) => string;
104
+ /** 严格更新业务 Feature;id 不存在时抛错,不读取 properties 控制渲染。 */
105
+ update: (id: string, patch: ElectronicFenceFeaturePatch) => void;
106
+ /** 严格删除;id 不存在时抛错。 */
107
+ removeFeature: (id: string) => void;
108
+ /** 清空数据但保留图层和控制器。 */
109
+ clear: () => void;
110
+ /** 显式设置单围栏渲染状态,不修改业务 Feature。 */
111
+ setFeatureState: (id: string, state: ElectronicFenceStatus) => void;
112
+ /** 设置临时高亮态,不修改业务 Feature。 */
113
+ setFeatureActive: (id: string, active: boolean) => void;
114
+ /** 设置临时显隐,不删除业务 Feature。 */
115
+ setFeatureVisible: (id: string, visible: boolean) => void;
116
+ /** 显示整个插件。 */
117
+ show: () => void;
118
+ /** 隐藏整个插件;WebGL 版本会同时暂停动画。 */
119
+ hide: () => void;
120
+ /** 释放 Source、Layer、事件和 WebGL 资源;调用后控制器不可再用。 */
121
+ destroy: () => void;
122
+ }
123
+ /** fence.click / mouseenter / mouseleave 的事件载荷。 */
124
+ export interface ElectronicFenceInteractionEvent {
125
+ instanceId: string;
126
+ renderer: ElectronicFenceRendererType;
127
+ id: string;
128
+ feature: ElectronicFenceFeature;
129
+ originalEvent: MapMouseEvent;
130
+ }
131
+ export {};
@@ -1,4 +1,5 @@
1
1
  export type LngLatTuple = [number, number];
2
+ /** 将任意角度规整到 0-360 度。 */
2
3
  export declare const normalizeAngle: (angle: number) => number;
3
4
  /** 从中心点按距离和方位角推算目标点,单位米/度。 */
4
5
  export declare const getDestination: (center: LngLatTuple, distance: number, bearing: number) => LngLatTuple;
@@ -9,6 +10,7 @@ export declare const getBearing: (start: LngLatTuple, end: LngLatTuple) => numbe
9
10
  /** 创建圆形外环坐标,圆在 GeoJSON 中用多边形近似。 */
10
11
  export declare const createCircleCoordinates: (center: LngLatTuple, radius: number, segmentCount?: number) => LngLatTuple[];
11
12
  export declare const createCirclePolygon: (center: LngLatTuple, radius: number, segmentCount?: number) => GeoJSON.Polygon;
13
+ /** 创建圆形线,适合脉冲环、雷达距离环。 */
12
14
  export declare const createCircleLine: (center: LngLatTuple, radius: number, segmentCount?: number) => GeoJSON.LineString;
13
15
  /** 创建扇形面:中心点 + 弧线点 + 中心点。 */
14
16
  export declare const createSectorPolygon: (center: LngLatTuple, radius: number, startAngle: number, endAngle: number, segmentCount?: number) => GeoJSON.Polygon;
@@ -1,2 +1,5 @@
1
- export { addDirectionalPulse, addPulseMarker, addRingPulseMarker, addRadarSweep, addSectorScan, } from "./low-altitude";
2
- export type { DirectionalPulseOptions, MapEffectController, PulseMarkerOptions, RingPulseMarkerOptions, RadarSweepOptions, SectorScanOptions, } from "./low-altitude";
1
+ export { addBreachAlert, addBreathingCircle, addCountermeasureBeam, addCoordinatedCountermeasure, addDefenceCircle, addDirectionalPulse, addNavigationSpoofing, addPulseMarker, addRingPulseMarker, addRadarSweep, addSectorScan, addTargetLock, createFenceCircle, } from "./low-altitude";
2
+ export { addStandardElectronicFenceLayer } from "./standard-electronic-fence";
3
+ export { addWebGLElectronicFenceLayer } from "./webgl-electronic-fence";
4
+ export type { BreachAlertController, BreachAlertOptions, BreathingCircleOptions, CountermeasureBeamOptions, CoordinatedCountermeasureOptions, CoordinationLink, CoordinationLinkType, DefenceCircleOptions, DirectionalPulseOptions, FenceGeometry, MapEffectController, NavigationSpoofingOptions, PulseMarkerOptions, RingPulseMarkerOptions, RadarSweepOptions, SectorScanOptions, TargetLockOptions, } from "./low-altitude";
5
+ export type { ElectronicFenceController, ElectronicFenceDefaults, ElectronicFenceFeature, ElectronicFenceFeatureCollection, ElectronicFenceFeaturePatch, ElectronicFenceInteractionEvent, ElectronicFenceProperties, ElectronicFenceRendererType, ElectronicFenceStateStyles, ElectronicFenceStatus, ElectronicFenceVisualState, StandardElectronicFenceLayerOptions, StandardElectronicFenceStyleOptions, WebGLElectronicFenceAnimationOptions, WebGLElectronicFenceLayerOptions, WebGLElectronicFenceStyleOptions, } from "./electronic-fence-types";
@@ -0,0 +1,61 @@
1
+ import { type Map } from "maplibre-gl";
2
+ import { type LngLatTuple } from "../geometry";
3
+ import { type BaseEffectOptions, type MapEffectController } from "./shared";
4
+ export type FenceGeometry = GeoJSON.Polygon | GeoJSON.MultiPolygon | GeoJSON.Feature<GeoJSON.Polygon | GeoJSON.MultiPolygon> | GeoJSON.FeatureCollection | LngLatTuple[][];
5
+ export interface BreachAlertOptions extends BaseEffectOptions {
6
+ /** 接触点经纬度,作为涟漪中心。trigger 时可传入覆盖。 */
7
+ center: LngLatTuple;
8
+ /** 围栏几何。围栏闪烁作用对象。 */
9
+ fence?: FenceGeometry;
10
+ /** 围栏正常态颜色(蓝/绿),默认 #1677ff。 */
11
+ fenceColor?: string;
12
+ /** 围栏填充色,默认跟随 fenceColor。 */
13
+ fenceFillColor?: string;
14
+ /** 围栏填充透明度,默认 0.1。 */
15
+ fenceFillOpacity?: number;
16
+ /** 围栏边框宽度,默认 2。 */
17
+ fenceBorderWidth?: number;
18
+ /** 围栏边框透明度,默认 0.9。 */
19
+ fenceBorderOpacity?: number;
20
+ /** 是否启用围栏高频闪烁警报,默认 true。 */
21
+ fenceFlash?: boolean;
22
+ /** 警报态颜色,默认 #ff3b30。 */
23
+ fenceAlertColor?: string;
24
+ /** 闪烁半周期 ms(亮→暗→亮),默认 200(高频)。 */
25
+ fenceFlashInterval?: number;
26
+ /** 是否启用接触点涟漪,默认 true。 */
27
+ ripple?: boolean;
28
+ /** 涟漪颜色,默认跟随 fenceAlertColor。 */
29
+ rippleColor?: string;
30
+ /** 涟漪最大扩散半径,单位米,默认 800。 */
31
+ rippleRadius?: number;
32
+ /** 同时扩散的环数,默认 3。 */
33
+ rippleCount?: number;
34
+ /** 单波扩散周期 ms(一个环从中心扩散到最大半径的时长),默认 1500。涟漪循环播放直到 reset。 */
35
+ rippleDuration?: number;
36
+ /** 涟漪线宽,默认 3。 */
37
+ rippleLineWidth?: number;
38
+ /** 是否启用战术框闪烁,默认 false。 */
39
+ tacticalFlash?: boolean;
40
+ /** 战术框范围,默认 'fullscreen'。'viewport' 表示内缩聚焦框。 */
41
+ tacticalScope?: "fullscreen" | "viewport";
42
+ /** 战术框颜色,默认跟随 fenceAlertColor。 */
43
+ tacticalColor?: string;
44
+ /** 边框粗细 px,默认 4。 */
45
+ tacticalBorderWidth?: number;
46
+ }
47
+ /** addBreachAlert 返回的控制器。在 MapEffectController 基础上扩展事件触发能力。 */
48
+ export interface BreachAlertController extends MapEffectController<BreachAlertOptions> {
49
+ /** 触发一次预警。传入接触点会覆盖 center;若已在警报中,先 reset 再触发。 */
50
+ trigger: (point?: LngLatTuple) => void;
51
+ /** 立即停止当前预警:围栏恢复原色、涟漪消散、战术框停止。 */
52
+ reset: () => void;
53
+ /** 当前是否处于警报中。 */
54
+ isActive: () => boolean;
55
+ }
56
+ /** 构造圆形围栏几何。
57
+ * GeoJSON 不支持 Circle 类型,这里用多边形近似(默认 64 段),
58
+ * 与 edit 插件画圆输出的格式一致,可直接作为 fence 传入。 */
59
+ export declare const createFenceCircle: (center: LngLatTuple, radius: number, segmentCount?: number) => GeoJSON.Polygon;
60
+ /** 添加围栏闯入预警特效。 */
61
+ export declare const addBreachAlert: (map: Map, initialOptions: BreachAlertOptions) => BreachAlertController;
@@ -0,0 +1,5 @@
1
+ import { type Map } from "maplibre-gl";
2
+ import { type MapEffectController } from "./shared";
3
+ import type { BreathingCircleOptions } from "./types";
4
+ /** 添加呼吸圆特效。 */
5
+ export declare const addBreathingCircle: (map: Map, options: BreathingCircleOptions) => MapEffectController<BreathingCircleOptions>;
@@ -0,0 +1,5 @@
1
+ import { type Map } from "maplibre-gl";
2
+ import { type MapEffectController } from "./shared";
3
+ import type { CoordinatedCountermeasureOptions } from "./types";
4
+ /** 添加多设备协同反制链路。 */
5
+ export declare const addCoordinatedCountermeasure: (map: Map, options: CoordinatedCountermeasureOptions) => MapEffectController<CoordinatedCountermeasureOptions>;
@@ -0,0 +1,5 @@
1
+ import { type Map } from "maplibre-gl";
2
+ import { type MapEffectController } from "./shared";
3
+ import type { CountermeasureBeamOptions } from "./types";
4
+ /** 添加定向反制光束。 */
5
+ export declare const addCountermeasureBeam: (map: Map, options: CountermeasureBeamOptions) => MapEffectController<CountermeasureBeamOptions>;
@@ -0,0 +1,5 @@
1
+ import { type Map } from "maplibre-gl";
2
+ import { type MapEffectController } from "./shared";
3
+ import type { DefenceCircleOptions } from "./types";
4
+ /** 添加防御圆特效。 */
5
+ export declare const addDefenceCircle: (map: Map, options: DefenceCircleOptions) => MapEffectController<DefenceCircleOptions>;
@@ -0,0 +1,6 @@
1
+ import { type Map } from "maplibre-gl";
2
+ import { type MapEffectController } from "./shared";
3
+ import type { DirectionalPulseOptions } from "./types";
4
+ /** 判断雷达扫描是否启用 Canvas 渐变。 */
5
+ /** 添加定向脉冲特效。 */
6
+ export declare const addDirectionalPulse: (map: Map, options: DirectionalPulseOptions) => MapEffectController<DirectionalPulseOptions>;
@@ -0,0 +1,6 @@
1
+ import { type Map } from "maplibre-gl";
2
+ import { type MapEffectController } from "./shared";
3
+ import type { NavigationSpoofingOptions } from "./types";
4
+ /** 添加单点扩散脉冲特效。 */
5
+ /** 添加导航诱骗位置偏移效果。 */
6
+ export declare const addNavigationSpoofing: (map: Map, options: NavigationSpoofingOptions) => MapEffectController<NavigationSpoofingOptions>;
@@ -0,0 +1,5 @@
1
+ import { type Map } from "maplibre-gl";
2
+ import { type MapEffectController } from "./shared";
3
+ import type { PulseMarkerOptions } from "./types";
4
+ /** 添加单点扩散脉冲特效。 */
5
+ export declare const addPulseMarker: (map: Map, options: PulseMarkerOptions) => MapEffectController<PulseMarkerOptions>;
@@ -0,0 +1,5 @@
1
+ import { type Map } from "maplibre-gl";
2
+ import { type MapEffectController } from "./shared";
3
+ import type { RadarSweepOptions } from "./types";
4
+ /** 添加雷达扫描特效。 */
5
+ export declare const addRadarSweep: (map: Map, options: RadarSweepOptions) => MapEffectController<RadarSweepOptions>;
@@ -0,0 +1,5 @@
1
+ import { type Map } from "maplibre-gl";
2
+ import { type MapEffectController } from "./shared";
3
+ import type { RingPulseMarkerOptions } from "./types";
4
+ /** 添加多环脉冲特效。 */
5
+ export declare const addRingPulseMarker: (map: Map, options: RingPulseMarkerOptions) => MapEffectController<RingPulseMarkerOptions>;
@@ -0,0 +1,5 @@
1
+ import { type Map } from "maplibre-gl";
2
+ import { type MapEffectController } from "./shared";
3
+ import type { SectorScanOptions } from "./types";
4
+ /** 添加扇形扫描特效。 */
5
+ export declare const addSectorScan: (map: Map, options: SectorScanOptions) => MapEffectController<SectorScanOptions>;