@tileflow/core 0.1.0-alpha.39 → 0.1.0-alpha.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/3d.js CHANGED
@@ -501,6 +501,50 @@ function record(value) {
501
501
  return typeof value === "object" && value !== null && !Array.isArray(value);
502
502
  }
503
503
 
504
+ // src/buildings-3d-surfaces.ts
505
+ function readTileflowBuildingSurfaces(value) {
506
+ if (!record2(value)) return void 0;
507
+ const number = (value2, min, max2, fallback) => typeof value2 === "number" && Number.isFinite(value2) && value2 >= min && value2 <= max2 ? value2 : fallback;
508
+ const result = {};
509
+ if (record2(value.walls) && value.walls.kind === "brick") {
510
+ const size = Array.isArray(value.walls.size) ? value.walls.size : [];
511
+ const width = number(size[0], 0.5, 100, 6);
512
+ const height = number(size[1], 0.5, 100, 3);
513
+ result.walls = {
514
+ kind: "brick",
515
+ size: [width, height],
516
+ jointWidth: Math.min(
517
+ number(value.walls.jointWidth, 0.01, 2, 0.12),
518
+ Math.min(width, height) * 0.25
519
+ ),
520
+ contrast: number(value.walls.contrast, 0, 1, 0.2)
521
+ };
522
+ }
523
+ if (record2(value.roof) && value.roof.kind === "tiles") {
524
+ const size = number(value.roof.size, 0.5, 100, 8);
525
+ result.roof = {
526
+ kind: "tiles",
527
+ size,
528
+ jointWidth: Math.min(number(value.roof.jointWidth, 0.01, 2, 0.12), size * 0.25),
529
+ contrast: number(value.roof.contrast, 0, 1, 0.1)
530
+ };
531
+ }
532
+ if (record2(value.cornice))
533
+ result.cornice = {
534
+ height: number(value.cornice.height, 0.05, 5, 0.6),
535
+ contrast: number(value.cornice.contrast, 0, 1, 0.2)
536
+ };
537
+ return Object.keys(result).length ? result : void 0;
538
+ }
539
+ function tileflowBuildingSurfaceTile(x3, y2, zoom, size) {
540
+ const span = 4007501668557849e-8 / 2 ** zoom;
541
+ const phase = (value) => (value % size + size) % size;
542
+ return [phase(x3 * span), phase(y2 * span), span / 8192];
543
+ }
544
+ function record2(value) {
545
+ return value !== null && typeof value === "object" && !Array.isArray(value);
546
+ }
547
+
504
548
  // src/buildings-3d-design.ts
505
549
  var tileflowBuildingsMetadataKey = "tileflow:buildings";
506
550
  var tileflowDefaultBuildings3DDesign = Object.freeze({
@@ -528,6 +572,7 @@ function readTileflowBuildings3D(metadata) {
528
572
  if (typeof color !== "string" && !Array.isArray(color)) return void 0;
529
573
  const within = (number, high, fallback) => typeof number === "number" && number >= 0 && number <= high ? number : fallback;
530
574
  const defaults = tileflowDefaultBuildings3DDesign;
575
+ const surfaces = readTileflowBuildingSurfaces(value.surfaces);
531
576
  const floodLight = readBuildingFloodLight(value.floodLight);
532
577
  const modelLighting = readModelRoleLighting(value.modelLighting);
533
578
  return {
@@ -547,6 +592,7 @@ function readTileflowBuildings3D(metadata) {
547
592
  ...floodLight ? { floodLight } : {},
548
593
  ...modelLighting ? { modelLighting } : {},
549
594
  windows: value.windows === true,
595
+ ...surfaces ? { surfaces } : {},
550
596
  ...readTileflowBuildingsEntrance(value.entrance),
551
597
  shadows: typeof value.shadows === "boolean" ? value.shadows : defaults.shadows,
552
598
  occlusion: typeof value.occlusion === "boolean" ? value.occlusion : defaults.occlusion,
@@ -2519,7 +2565,9 @@ uniform vec2 u_palette_rows; // rows per theme; texels per row
2519
2565
  uniform vec2 u_palette_themes; // the themes either side of the blend position
2520
2566
  uniform float u_palette_mix;
2521
2567
  uniform float u_variation; // how far buildings' brightness strays from their colour, either way
2568
+ uniform vec3 u_surface_tile; // repeating projected-metre phase and metres per tile unit
2522
2569
  ${growth}
2570
+ out vec2 v_surface;
2523
2571
  out vec3 v_colour;
2524
2572
  out float v_base;
2525
2573
  out vec3 v_facade; // metres along the wall, metres up as built, the building's top
@@ -2564,6 +2612,7 @@ void main() {
2564
2612
  // Neighbours of one colour stay apart: each building a little lighter or darker than its colour.
2565
2613
  v_colour *= 1.0 + (a_wave.x - 0.5) * 2.0 * u_variation;
2566
2614
  v_base = base;
2615
+ v_surface = a_pos * u_surface_tile.z + u_surface_tile.xy;
2567
2616
  v_edge = wall > 0.5 ? vec3(a_edge.x, 0.0, 0.0) : vec3(equal(vec3(a_edge.x), vec3(0.0, 1.0, 2.0)));
2568
2617
  v_outline = a_edge.y;
2569
2618
  v_facade = vec3(a_along * 0.1, own, top);
@@ -2574,6 +2623,10 @@ var tileflowBuildingFragment = `#version 300 es
2574
2623
  precision highp float;
2575
2624
  in vec3 v_colour;
2576
2625
  in float v_base;
2626
+ in vec2 v_surface;
2627
+ uniform vec4 u_surface_walls; // width, course height, joint width, contrast
2628
+ uniform vec3 u_surface_roof; // square size, joint width, contrast
2629
+ uniform vec2 u_surface_cornice; // band height, contrast
2577
2630
  uniform vec3 u_style_light_position;
2578
2631
  uniform vec3 u_style_light_colour;
2579
2632
  uniform float u_style_light_intensity;
@@ -2678,6 +2731,62 @@ float edgeOf() {
2678
2731
  return 1.0 - smoothstep(u_edge_width - 0.75, u_edge_width + 0.25, near);
2679
2732
  }
2680
2733
 
2734
+ // A filtered joint between large, softly shaded blocks. Derivatives are taken before the
2735
+ // stagger/periodic wrap, so row boundaries do not create false level-of-detail transitions.
2736
+ float surfaceBlocks(vec2 position, vec2 size, float joint, float contrast, float stagger) {
2737
+ vec2 footprint = max(fwidth(position), vec2(0.0001));
2738
+ float visible = smoothstep(2.0, 7.0, min(size.x / footprint.x, size.y / footprint.y));
2739
+ vec2 uv = position / size;
2740
+ uv.x += mod(floor(uv.y), 2.0) * stagger;
2741
+ vec2 cell = fract(uv) * size;
2742
+ vec2 distance = min(cell, size - cell);
2743
+ vec2 aa = footprint * 0.65;
2744
+ vec2 seam = 1.0 - smoothstep(vec2(joint * 0.5) - aa, vec2(joint * 0.5) + aa, distance);
2745
+ float groove = max(seam.x, seam.y);
2746
+ // A quiet bevel on the upper and left edges makes the painted blocks catch light.
2747
+ vec2 bevel = (1.0 - smoothstep(vec2(joint), vec2(joint + 0.35) + aa, cell)) * (1.0 - seam);
2748
+ return 1.0 + contrast * visible * (max(bevel.x, bevel.y) * 0.3 - groove * 0.65);
2749
+ }
2750
+
2751
+ // Distance to the actual roof outline in the roof's projected-metre plane. The triangle's
2752
+ // barycentric gradient ignores internal triangulation and tile cuts, including around patios.
2753
+ float roofOutlineDistance() {
2754
+ vec2 dx = dFdx(v_surface), dy = dFdy(v_surface);
2755
+ float determinant = dx.x * dy.y - dx.y * dy.x;
2756
+ if (abs(determinant) < 1e-10) return 1e6;
2757
+ vec3 bx = dFdx(v_edge), by = dFdy(v_edge);
2758
+ vec3 gx = (bx * dy.y - by * dx.y) / determinant;
2759
+ vec3 gy = (by * dx.x - bx * dy.x) / determinant;
2760
+ vec3 distance = v_edge / max(sqrt(gx * gx + gy * gy), vec3(1e-7));
2761
+ int sides = int(v_outline + 0.5);
2762
+ float nearest = 1e6;
2763
+ if ((sides & 1) != 0) nearest = min(nearest, distance.x);
2764
+ if ((sides & 2) != 0) nearest = min(nearest, distance.y);
2765
+ if ((sides & 4) != 0) nearest = min(nearest, distance.z);
2766
+ return nearest;
2767
+ }
2768
+
2769
+ vec3 surfaceColour() {
2770
+ vec3 colour = v_colour;
2771
+ bool wall = v_building.z > 0.5;
2772
+ float pattern = 1.0;
2773
+ if (wall && u_surface_walls.w > 0.0)
2774
+ pattern = surfaceBlocks(v_facade.xy, u_surface_walls.xy, u_surface_walls.z, u_surface_walls.w, 0.5);
2775
+ if (!wall && u_surface_roof.z > 0.0)
2776
+ pattern = surfaceBlocks(v_surface, vec2(u_surface_roof.x), u_surface_roof.y, u_surface_roof.z, 0.0);
2777
+ float band = 0.0, seam = 0.0;
2778
+ if (u_surface_cornice.y > 0.0) {
2779
+ float distance = wall ? v_facade.z - v_facade.y : roofOutlineDistance();
2780
+ float width = wall ? min(u_surface_cornice.x, (v_facade.z - v_base) * 0.2) : u_surface_cornice.x;
2781
+ float pixel = max(fwidth(distance), 0.001);
2782
+ float visible = smoothstep(0.4, 1.5, width / pixel);
2783
+ band = (1.0 - smoothstep(width - pixel * 0.5, width + pixel * 0.5, distance)) * visible;
2784
+ seam = (1.0 - smoothstep(0.0, pixel + width * 0.15, abs(distance - width))) * visible;
2785
+ }
2786
+ colour *= mix(pattern, 1.0, band) * (1.0 - seam * u_surface_cornice.y * 0.25);
2787
+ return mix(colour, mix(colour, vec3(1.0), u_surface_cornice.y * 0.45), band);
2788
+ }
2789
+
2681
2790
  void main() {
2682
2791
  vec3 normal = normalize(v_normal);
2683
2792
  // A narrow lighting transition softens the roof/wall junction without moving the roof
@@ -2688,8 +2797,9 @@ void main() {
2688
2797
  normal = normalize(mix(normal, vec3(0.0, 0.0, 1.0), rim));
2689
2798
  }
2690
2799
  float lit = dot(normal, u_sun_dir) > 0.0 ? visibility(v_shadow, 0.3) : 0.0;
2691
- vec3 colour = mix(styleColour(v_colour, normal) * (1.0 - u_shadow * (1.0 - lit)),
2692
- v_colour * shade(normal, lit), u_sun_lighting);
2800
+ vec3 surface = surfaceColour();
2801
+ vec3 colour = mix(styleColour(surface, normal) * (1.0 - u_shadow * (1.0 - lit)),
2802
+ surface * shade(normal, lit), u_sun_lighting);
2693
2803
  colour *= facadeShade();
2694
2804
  // Roof outlines and outer corners catch the light, so where one building ends and the next starts
2695
2805
  // stays legible, at night most of all.
@@ -3781,6 +3891,8 @@ function readTileflowVegetation3D(metadata) {
3781
3891
  colors: { bark: colors.bark, broadleaf, conifer, palm, hedge },
3782
3892
  heightScale: scale(heightScale),
3783
3893
  crownScale: scale(crownScale),
3894
+ minimumHeight: typeof value.minimumHeight === "number" && Number.isFinite(value.minimumHeight) ? clamp(value.minimumHeight, [0, 20]) : 0,
3895
+ materialVariation: typeof value.materialVariation === "number" && Number.isFinite(value.materialVariation) ? clamp(value.materialVariation, [0, 1]) : 0,
3784
3896
  forms,
3785
3897
  models,
3786
3898
  finish,
@@ -4070,7 +4182,7 @@ function browserWorker() {
4070
4182
  if (typeof Worker === "undefined" || false)
4071
4183
  return;
4072
4184
  const url = URL.createObjectURL(
4073
- new Blob(['"use strict";(()=>{var Be=new Set,ln=!1;function Pe(e,n,t=2){let i=n&&n.length,o=i?n[0]*t:e.length;Be.size&&Be.clear();let r=zn(e,0,o,t,!0),s=[];if(!r||r.next===r.prev)return s;let a=0,l=0,u=0;if(i&&(r=xt(e,n,r,t)),e.length>80*t){a=e[0],l=e[1];let c=a,f=l;for(let d=t;d<o;d+=t){let g=e[d],m=e[d+1];g<a&&(a=g),m<l&&(l=m),g>c&&(c=g),m>f&&(f=m)}u=Math.max(c-a,f-l),u=u!==0?32767/u:0}return un(r,s,a,l,u),s}function zn(e,n,t,i,o){let r=null;if(o===Ut(e,n,t,i)>0)for(let s=n;s<t;s+=i)r=In(s/i|0,e[s],e[s+1],r);else for(let s=t-i;s>=n;s-=i)r=In(s/i|0,e[s],e[s+1],r);return r&&Oe(r,r.next)&&(Ce(r),r=r.next),r}function ge(e,n=e){let t=n===e,i=e,o;do o=!1,i!==i.next&&(Be.size===0||!Be.has(i))&&(Oe(i,i.next)||Q(i.prev,i,i.next)===0)?((t||i===n)&&(n=i.prev),ln=!0,Ce(i),i=i.prev,o=!0):(t||i!==n)&&(i=i.next,o=!t);while(o||i!==n);return n}function un(e,n,t,i,o){o&&At(e,t,i,o);let r=e,s=!1;for(;e.prev!==e.next;){let a=e.prev,l=e.next;if(Q(a,e,l)<0&&(o?bt(e,t,i,o):yt(e))){n.push(a.i,e.i,l.i),Ce(e),e=l,r=l;continue}if(e=l,e===r){if(ln=!1,e=ge(e),ln){r=e;continue}if(!s){e=gt(e,n),r=e,s=!0;continue}wt(e,n,t,i,o);break}}}function yt(e){let n=e.prev,t=e,i=e.next,o=n.x,r=t.x,s=i.x,a=n.y,l=t.y,u=i.y,c=Math.min(o,r,s),f=Math.min(a,l,u),d=Math.max(o,r,s),g=Math.max(a,l,u),m=i.next;for(;m!==n;){if(m.x>=c&&m.x<=d&&m.y>=f&&m.y<=g&&!(o===m.x&&a===m.y)&&Ke(o,a,r,l,s,u,m.x,m.y)&&Q(m.prev,m,m.next)>=0)return!1;m=m.next}return!0}function bt(e,n,t,i){let o=e.prev,r=e,s=e.next,a=o.x,l=r.x,u=s.x,c=o.y,f=r.y,d=s.y,g=Math.min(a,l,u),m=Math.min(c,f,d),p=Math.max(a,l,u),h=Math.max(c,f,d),_=mn(g,m,n,t,i),A=mn(p,h,n,t,i),k=e.prevZ;for(;k&&k.z>=_;){if(k.x>=g&&k.x<=p&&k.y>=m&&k.y<=h&&k!==s&&!(a===k.x&&c===k.y)&&Ke(a,c,l,f,u,d,k.x,k.y)&&Q(k.prev,k,k.next)>=0)return!1;k=k.prevZ}let M=e.nextZ;for(;M&&M.z<=A;){if(M.x>=g&&M.x<=p&&M.y>=m&&M.y<=h&&M!==s&&!(a===M.x&&c===M.y)&&Ke(a,c,l,f,u,d,M.x,M.y)&&Q(M.prev,M,M.next)>=0)return!1;M=M.nextZ}return!0}function gt(e,n){let t=e,i=!1;do{let o=t.prev,r=t.next.next;Nn(o,t,t.next,r,!1)&&Ue(o,r)&&Ue(r,o)&&(n.push(o.i,t.i,r.i),Ce(t),Ce(t.next),t=e=r,i=!0),t=t.next}while(t!==e);return i?ge(t):t}function wt(e,n,t,i,o){let r=e;do{let s=r.next.next;for(;s!==r.prev;){if(r.i!==s.i&&Lt(r,s)){let a=Vn(r,s);r=ge(r,r.next),a=ge(a,a.next),un(r,n,t,i,o),un(a,n,t,i,o);return}s=s.next}r=r.next}while(r!==e)}var cn=!1;function xt(e,n,t,i){let o=[];for(let r=0,s=n.length;r<s;r++){let a=n[r]*i,l=r<s-1?n[r+1]*i:e.length,u=zn(e,a,l,i,!1);u===u.next&&Be.add(u),o.push(St(u))}o.sort(Tt),kt(e.length/i,n.length),Dn(t,t),cn=!0;for(let r=0;r<o.length;r++)t=Mt(o[r],t);return cn=!1,ge(t)}function Tt(e,n){return e.x-n.x||e.y-n.y||(e.next.y-e.y)/(e.next.x-e.x)-(n.next.y-n.y)/(n.next.x-n.x)}function Mt(e,n){let t=Rt(e,n);if(!t)return n;let i=Vn(t,e),o=i.next;return Dn(t,o.next),ge(i,i.next),ge(t,t.next)}var jn=16,X=new Float64Array(0),Je=0,fn=[],dn=[];function kt(e,n){let t=Math.ceil((e+2*n)/jn)+n+2;X.length<t*4&&(X=new Float64Array(t*4)),Je=0}function Dn(e,n){let t=e;do{let i=Je++;fn[i]=t;let o=t.x,r=t.y,s=t.x,a=t.y,l=0;do{let c=t.next;t.z=i,c.x<o&&(o=c.x),c.x>s&&(s=c.x),c.y<r&&(r=c.y),c.y>a&&(a=c.y),t=c}while(++l<jn&&t!==n);dn[i]=t;let u=i*4;X[u]=o,X[u+1]=r,X[u+2]=s,X[u+3]=a}while(t!==n)}function vt(e,n){let t=e.z*4;n.x<X[t]&&(X[t]=n.x),n.y<X[t+1]&&(X[t+1]=n.y),n.x>X[t+2]&&(X[t+2]=n.x),n.y>X[t+3]&&(X[t+3]=n.y)}function Pn(e){let n=dn[e];for(;n.prev.next!==n;)n=n.next;return dn[e]=n,n}function En(e){let n=fn[e];for(;n.prev.next!==n;)n=n.next;return fn[e]=n,n}function Rt(e,n){let t=n,i=e.x,o=e.y,r=-1/0,s;if(Oe(e,t))return t;for(let d=0,g=0;d<Je;d++,g+=4){if(o<X[g+1]||o>X[g+3]||X[g]>i||X[g+2]<=r)continue;let m=Pn(d);t=En(d);do{if(t.prev.next===t){if(Oe(e,t.next))return t.next;if(o<=t.y&&o>=t.next.y&&t.next.y!==t.y){let p=t.x+(o-t.y)*(t.next.x-t.x)/(t.next.y-t.y);if(p<=i&&p>r&&(r=p,s=t.x<t.next.x?t:t.next,p===i))return s}}t=t.next}while(t!==m)}if(!s)return null;let a=s.x,l=s.y,u=Math.min(o,l),c=Math.max(o,l),f=1/0;for(let d=0,g=0;d<Je;d++,g+=4){if(X[g+2]<a||X[g]>i||X[g+3]<u||X[g+1]>c)continue;let m=Pn(d);t=En(d);do{if(t.prev.next===t&&i>=t.x&&t.x>=a&&i!==t.x&&Ke(o<l?i:r,o,a,l,o<l?r:i,o,t.x,t.y)){let p=Math.abs(o-t.y)/(i-t.x);(Ue(t,e)||t.y===o&&t.next.y===o&&t.next.x>i)&&(p<f||p===f&&(t.x>s.x||t.x===s.x&&_t(s,t)))&&(s=t,f=p)}t=t.next}while(t!==m)}return s}function _t(e,n){return Q(e.prev,e,n.prev)<0&&Q(n.next,e,e.next)<0}var ie=[],ve=[],be=new Uint32Array(0),Se=new Uint32Array(0),Le=new Uint32Array(256);function At(e,n,t,i){let o=e,r=0;do o.z=mn(o.x,o.y,n,t,i),ie[r++]=o,o=o.next;while(o!==e);Ft(r);let s=null;for(let a=0;a<r;a++){let l=ie[a];l.prevZ=s,s&&(s.nextZ=l),s=l}s.nextZ=null,ie.fill(null,0,r),ve.fill(null,0,r)}function Ft(e){if(e<=32){for(let n=1;n<e;n++){let t=ie[n],i=t.z,o=n-1;for(;o>=0&&ie[o].z>i;)ie[o+1]=ie[o],o--;ie[o+1]=t}return}be.length<e&&(be=new Uint32Array(e),Se=new Uint32Array(e),ve=new Array(e));for(let n=0;n<e;n++)be[n]=ie[n].z;Xe(e,ie,be,ve,Se,0),Xe(e,ve,Se,ie,be,8),Xe(e,ie,be,ve,Se,16),Xe(e,ve,Se,ie,be,24)}function Xe(e,n,t,i,o,r){Le.fill(0);for(let a=0;a<e;a++)Le[t[a]>>>r&255]++;let s=0;for(let a=0;a<256;a++){let l=Le[a];Le[a]=s,s+=l}for(let a=0;a<e;a++){let l=t[a],u=Le[l>>>r&255]++;i[u]=n[a],o[u]=l}}function mn(e,n,t,i,o){return e=(e-t)*o|0,n=(n-i)*o|0,e=(e|e<<8)&16711935,e=(e|e<<4)&252645135,e=(e|e<<2)&858993459,e=(e|e<<1)&1431655765,n=(n|n<<8)&16711935,n=(n|n<<4)&252645135,n=(n|n<<2)&858993459,n=(n|n<<1)&1431655765,e|n<<1}function St(e){let n=e,t=e;do(n.x<t.x||n.x===t.x&&n.y<t.y)&&(t=n),n=n.next;while(n!==e);return t}function Ke(e,n,t,i,o,r,s,a){return(o-s)*(n-a)>=(e-s)*(r-a)&&(e-s)*(i-a)>=(t-s)*(n-a)&&(t-s)*(r-a)>=(o-s)*(i-a)}function Lt(e,n){let t=Oe(e,n)&&Q(e.prev,e,e.next)>0&&Q(n.prev,n,n.next)>0;return e.next.i!==n.i&&(t||Ue(e,n)&&Ue(n,e)&&(Q(e.prev,e,n.prev)!==0||Q(e,n.prev,n)!==0))&&!Bt(e,n)&&(t||Ot(e,n))}function Q(e,n,t){return(n.y-e.y)*(t.x-n.x)-(n.x-e.x)*(t.y-n.y)}function Oe(e,n){return e.x===n.x&&e.y===n.y}function Nn(e,n,t,i,o=!0){let r=Q(e,n,t),s=Q(e,n,i),a=Q(t,i,e),l=Q(t,i,n);return(r>0&&s<0||r<0&&s>0)&&(a>0&&l<0||a<0&&l>0)?!0:o?!!(r===0&&Ye(e,t,n)||s===0&&Ye(e,i,n)||a===0&&Ye(t,e,i)||l===0&&Ye(t,n,i)):!1}function Ye(e,n,t){return n.x<=Math.max(e.x,t.x)&&n.x>=Math.min(e.x,t.x)&&n.y<=Math.max(e.y,t.y)&&n.y>=Math.min(e.y,t.y)}function Bt(e,n){let t=Math.min(e.x,n.x),i=Math.max(e.x,n.x),o=Math.min(e.y,n.y),r=Math.max(e.y,n.y),s=e;do{let a=s.next;if(s.x>i&&a.x>i||s.x<t&&a.x<t||s.y>r&&a.y>r||s.y<o&&a.y<o){s=a;continue}if(s.i!==e.i&&a.i!==e.i&&s.i!==n.i&&a.i!==n.i&&Nn(s,a,e,n))return!0;s=a}while(s!==e);return!1}function Ue(e,n){return Q(e.prev,e,e.next)<0?Q(e,n,e.next)>=0&&Q(e,e.prev,n)>=0:Q(e,n,e.prev)<0||Q(e,e.next,n)<0}function Ot(e,n){let t=e,i=!1,o=(e.x+n.x)/2,r=(e.y+n.y)/2;do{let s=t.next;t.y>r!=s.y>r&&o<(s.x-t.x)*(r-t.y)/(s.y-t.y)+t.x&&(i=!i),t=s}while(t!==e);return i}function Vn(e,n){let t=hn(e.i,e.x,e.y),i=hn(n.i,n.x,n.y),o=e.next,r=n.prev;return e.next=n,n.prev=e,t.next=o,o.prev=t,i.next=t,t.prev=i,r.next=i,i.prev=r,i}function In(e,n,t,i){let o=hn(e,n,t);return i?(o.next=i.next,o.prev=i,i.next.prev=o,i.next=o):(o.prev=o,o.next=o),o}function Ce(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ),cn&&vt(e.prev,e.next)}function hn(e,n,t){return{i:e,x:n,y:t,prev:null,next:null,z:0,prevZ:null,nextZ:null}}function Ut(e,n,t,i){let o=0;for(let r=n,s=t-i;r<t;r+=i)o+=(e[s]-e[r])*(e[r+1]+e[s+1]),s=r;return o}var Ct=.7,Pt=Math.tan(Math.PI/6),Et=Math.tan(35*Math.PI/180),It=Math.tan(Math.PI/18),Ee=.65,Ie=.4;function Zn(e,n,t,i,o,r,s){let a=String(t.roof_shape??"");if(!a||a==="flat"||a==="sawtooth"||Vt(e,s))return;let l=Dt(e);if(!l||Math.abs(pn(e))<Ct*4*l.halfU*l.halfV)return;let u=l.u,c=l.v,f=l.halfU*r,d=l.halfV*r;f<d&&([u,c,f,d]=[c,u,d,f]);let g=Gn(t.roof_direction),m=g===void 0?void 0:[Math.sin(g*Math.PI/180),-Math.cos(g*Math.PI/180)];(m!==void 0?Math.abs(m[0]*u[0]+m[1]*u[1])>Math.abs(m[0]*c[0]+m[1]*c[1]):t.roof_orientation==="across")&&a!=="skillion"&&([u,c,f,d]=[c,u,d,f]);let h=jt(a,f,d,m&&[$n(m,u),$n(m,c)]);if(!h)return;let _=Math.max(0,o-i),A=Gn(t.roof_height),k,M;if(A!==void 0&&A>0)M=o,k=Math.max(i+Math.min(2,_/2),o-A);else{let y=Math.min(zt(a,d),_*.6,30);t.height_source==="height"?(M=o,k=o-y):(k=o,M=o+y)}let B=M-k;if(!(B>=.3))return;let[U,E]=l.centre,C=(y,b)=>{let x=(y-U)*r,T=(b-E)*r;return[x*u[0]+T*u[1],x*c[0]+T*c[1]]},I=(y,b)=>[U+(y*u[0]+b*c[0])/r,E+(y*u[1]+b*c[1])/r],N=(y,b)=>{let x=1/0;for(let[T,F,v]of h)x=Math.min(x,T*y+F*b+v);return Math.max(0,x)},K=(y,b)=>k+B*N(...C(y,b)),$=[];for(let y=0;y+1<n.length;y+=2)$.push(...C(n[y],n[y+1]));pn($)<0&&Ht($);let D=1.01,Y=[-f*D,-d*D,f*D,-d*D,f*D,d*D,-f*D,d*D],w=[];for(let[y,b]of h.entries()){let x=Y;for(let[P,Z]of h.entries()){if(P===y)continue;let j=b[0]-Z[0],G=b[1]-Z[1],W=b[2]-Z[2];if(Math.abs(j)+Math.abs(G)+Math.abs(W)<1e-9){P<y&&(x=[]);continue}if(x=Hn(x,j,G,W),x.length<6)break}if(x.length<6)continue;let T=$,F=x.length/2;for(let P=0;P<F&&T.length>=6;P+=1){let[Z,j]=[x[P*2],x[P*2+1]],[G,W]=[x[(P+1)%F*2],x[(P+1)%F*2+1]];T=Hn(T,W-j,Z-G,-(W-j)*Z-(Z-G)*j)}if(T.length<6||Math.abs(pn(T))<1e-6)continue;let v=[];for(let P=0;P<T.length;P+=2)v.push(...I(T[P],T[P+1]));let L=Pe(v);if(L.length===0)continue;let O=B*b[0],V=B*b[1],R=O*u[0]+V*c[0],S=O*u[1]+V*c[1],z=Math.hypot(R,S,1);w.push({ring:v,triangles:L,normal:[-R/z,-S/z]})}if(w.length!==0)return{eaves:k,ridge:M,faces:w,heightAt:K,breaks(y,b,x,T){let[F,v]=C(y,b),[L,O]=C(x,T),V=[];for(let R=0;R<h.length;R+=1)for(let S=R+1;S<h.length;S+=1){let z=(ae,H)=>(h[R][0]-h[S][0])*ae+(h[R][1]-h[S][1])*H+(h[R][2]-h[S][2]),P=z(F,v),Z=z(L,O);if(P===Z||P*Z>0)continue;let j=P/(P-Z);if(j<=1e-4||j>=1-1e-4)continue;let G=F+(L-F)*j,W=v+(O-v)*j;h[R][0]*G+h[R][1]*W+h[R][2]<=N(G,W)+1e-6&&V.push(j)}return[...new Set(V.map(R=>Math.round(R*1e6)/1e6))].sort((R,S)=>R-S)}}}function zt(e,n){switch(e){case"skillion":return 2*n*It;case"pyramidal":return n*Et;case"gambrel":case"mansard":return n*.8;case"dome":case"onion":case"round":return n;default:return n*Pt}}function jt(e,n,t,i){let o=n,r=t,s=[[0,-1/r,1],[0,1/r,1]],a=u=>u.flatMap(c=>[1,-1].flatMap(f=>{let d=c==="v"?r:o,g=Ee/(Ie*r)*f,m=(1-Ee)/((1-Ie)*r)*f,p=h=>c==="v"?[0,-h]:[-h,0];return[[...p(g),Ee/(Ie*r)*d],[...p(m),Ee+(1-Ee)/((1-Ie)*r)*(d-Ie*r)]]})),l=[.99,.8,.5,.2];switch(e){case"gabled":return s;case"saltbox":{let u=r/3;return[[0,-1/(r-u),1+u/(r-u)],[0,1/(r+u),1-u/(r+u)]]}case"hipped":return[...s,[-1/r,0,o/r],[1/r,0,o/r]];case"half_hipped":return[...s,[-1/r,0,.5+o/r],[1/r,0,.5+o/r]];case"pyramidal":return[...s,[-1/o,0,1],[1/o,0,1]];case"gambrel":return a(["v"]);case"mansard":return a(["v","u"]);case"skillion":{let[u,c]=i??[0,1],f=Math.abs(u)*o+Math.abs(c)*r;return f>0?[[-u/(2*f),-c/(2*f),.5]]:void 0}case"round":return[[0,0,1],...l.flatMap(u=>{let c=Math.sqrt(1-u*u);return[1,-1].map(f=>[0,-f*u/(r*c),1/c])})];case"dome":case"onion":return[[0,0,1],...l.flatMap(u=>{let c=Math.sqrt(1-u*u);return Array.from({length:12},(f,d)=>{let g=d*Math.PI/6;return[-u*Math.cos(g)/(o*c),-u*Math.sin(g)/(r*c),1/c]})})];default:return}}function Hn(e,n,t,i){let o=e.length/2,r=[];for(let s=0;s<o;s+=1){let a=e[s*2],l=e[s*2+1],u=e[(s+1)%o*2],c=e[(s+1)%o*2+1],f=n*a+t*l+i,d=n*u+t*c+i;if(f<=0&&r.push(a,l),f<0&&d>0||f>0&&d<0){let g=f/(f-d);r.push(a+(u-a)*g,l+(c-l)*g)}}return r}function Dt(e){let n=Nt(e);if(n.length<3)return;let t,i=1/0;for(let o=0;o<n.length;o+=1){let[r,s]=n[o],[a,l]=n[(o+1)%n.length],u=Math.hypot(a-r,l-s);if(u===0)continue;let c=[(a-r)/u,(l-s)/u],f=[-c[1],c[0]],[d,g,m,p]=[1/0,-1/0,1/0,-1/0];for(let[_,A]of n){let k=_*c[0]+A*c[1],M=_*f[0]+A*f[1];d=Math.min(d,k),g=Math.max(g,k),m=Math.min(m,M),p=Math.max(p,M)}let h=(g-d)*(p-m);if(h<i){i=h;let _=(d+g)/2,A=(m+p)/2;t={centre:[_*c[0]+A*f[0],_*c[1]+A*f[1]],u:c,v:f,halfU:(g-d)/2,halfV:(p-m)/2}}}return t&&t.halfU>0&&t.halfV>0?t:void 0}function Nt(e){let n=[];for(let r=0;r+1<e.length;r+=2)n.push([e[r],e[r+1]]);n.sort((r,s)=>r[0]-s[0]||r[1]-s[1]);let t=(r,s,a)=>(s[0]-r[0])*(a[1]-r[1])-(s[1]-r[1])*(a[0]-r[0]),i=[];for(let r of n){for(;i.length>=2&&t(i.at(-2),i.at(-1),r)<=0;)i.pop();i.push(r)}let o=[];for(let r of n.reverse()){for(;o.length>=2&&t(o.at(-2),o.at(-1),r)<=0;)o.pop();o.push(r)}return[...i.slice(0,-1),...o.slice(0,-1)]}function Vt(e,n){let[t,i,o,r]=[1/0,-1/0,1/0,-1/0];for(let a=0;a+1<e.length;a+=2)t=Math.min(t,e[a]),i=Math.max(i,e[a]),o=Math.min(o,e[a+1]),r=Math.max(r,e[a+1]);let s=e.length/2;for(let a=0;a<s;a+=1){let l=e[a*2],u=e[a*2+1],c=e[(a+1)%s*2],f=e[(a+1)%s*2+1];if(t<0&&l===t&&c===t||i>n&&l===i&&c===i||o<0&&u===o&&f===o||r>n&&u===r&&f===r)return!0}return!1}function pn(e){let n=0,t=e.length/2;for(let i=0;i<t;i+=1){let o=(i+1)%t;n+=e[i*2]*e[o*2+1]-e[o*2]*e[i*2+1]}return n/2}function Ht(e){let n=[];for(let t=0;t<e.length;t+=2)n.push([e[t],e[t+1]]);n.reverse(),e.splice(0,e.length,...n.flat())}function $n(e,n){return e[0]*n[0]+e[1]*n[1]}function Gn(e){let n=typeof e=="string"?Number(e):e;return typeof n=="number"&&Number.isFinite(n)?n:void 0}var jr=Object.freeze({surface:0,secondary:1,glass:2,accent:3,roof:4}),Dr=Object.freeze({unclassified:0,wall:1,door:2,roof:3,window:4,lamp:5,logo:6}),Nr=Object.freeze([1,1,4,1,3]),Vr=Object.freeze({levels:3,vertices:2e5,triangles:2e5,footprintPoints:4096,radius:2e3,height:1e3,models:512,bytes:16*1024*1024});function yn(e,n,t){for(let i of e){let o=!1;for(let r=0,s=i.length-2;r<i.length;s=r,r+=2){let a=i[r],l=i[r+1],u=i[s],c=i[s+1];l>t!=c>t&&n<(u-a)*(t-l)/(c-l)+a&&(o=!o)}if(o)return!0}return!1}function Yn(e,n,t){for(let i of n){let[o,r,s,a]=Xn(i);for(let l of e){let[u,c,f,d]=Xn(l);if(!(u>s-t||f<o+t||c>a-t||d<r+t)&&(Wn(l,i,t)||Wn(i,l,t)))return!0}}return!1}function Wn(e,n,t){let i=(o,r)=>yn([n],o,r)&&Gt(n,o,r)>t;for(let o=0;o+1<e.length;o+=2)if(i(e[o],e[o+1]))return!0;for(let o=0,r=e.length-2;o<e.length;r=o,o+=2){let[s,a,l,u]=[e[r],e[r+1],e[o],e[o+1]],c=[0,1];for(let f=0,d=n.length-2;f<n.length;d=f,f+=2){let g=$t(s,a,l,u,n[d],n[d+1],n[f],n[f+1]);g!==void 0&&c.push(g)}if(c.length!==2){c.sort((f,d)=>f-d);for(let f=1;f<c.length;f+=1){let d=(c[f-1]+c[f])/2;if(i(s+(l-s)*d,a+(u-a)*d))return!0}}}return!1}function $t(e,n,t,i,o,r,s,a){let l=t-e,u=i-n,c=s-o,f=a-r,d=l*f-u*c;if(d===0)return;let g=((o-e)*f-(r-n)*c)/d,m=((o-e)*u-(r-n)*l)/d;return g>0&&g<1&&m>=0&&m<=1?g:void 0}function Gt(e,n,t){let i=1/0;for(let o=0,r=e.length-2;o<e.length;r=o,o+=2){let[s,a,l,u]=[e[r],e[r+1],e[o],e[o+1]],c=(l-s)**2+(u-a)**2,f=c>0?Math.max(0,Math.min(1,((n-s)*(l-s)+(t-a)*(u-a))/c)):0;i=Math.min(i,Math.hypot(n-(s+(l-s)*f),t-(a+(u-a)*f)))}return i}function Xn(e){let[n,t,i,o]=[1/0,1/0,-1/0,-1/0];for(let r=0;r+1<e.length;r+=2)n=Math.min(n,e[r]),i=Math.max(i,e[r]),t=Math.min(t,e[r+1]),o=Math.max(o,e[r+1]);return[n,t,i,o]}var ue=8192,pe=28,Zt={commercial:1,active:2,destination:3},Wt={residential:1,...Object.fromEntries(["civic","commercial","education","entertainment","medical","transportation"].map(e=>[e,2])),...Object.fromEntries(["agricultural","industrial","military","outbuilding","religious","service"].map(e=>[e,3]))},Xt={dining:1,entertainment:2,nightlife:3},bn={...Object.fromEntries(["alcoholic_beverage_venue","bar","beer","biergarten","brewery","casino","cocktail_bar","dance_club","karaoke","lounge","music_venue","night_club","nightclub","pub","wine_bar"].map(e=>[e,3])),...Object.fromEntries(["arts_centre","bowling_alley","cinema","comedy_club","concert_hall","movie_theater","opera","performing_arts_venue","theater","theatre","theatre_venue"].map(e=>[e,2])),...Object.fromEntries(["casual_eatery","fast_food","fast_food_restaurant","food_court","restaurant"].map(e=>[e,1]))},Yt=6,Jt=.5,Kt=.5;function Kn(e,n){let t=ue/e.extent,i=n.tileMetres/ue,o=n.defaultHeight??5,r=Number.isFinite(n.edgeRadius)?Math.max(0,Math.min(1,n.edgeRadius))/i:0,s=new wn,a=new Qe,l=new Qe,u=[],c=[],f=0,d=nr(e,n);for(let[M,B]of e.features.entries()){if(B.type!=="Polygon"||u.length>=65535)continue;let U=B.properties,E=U.hide_3d;if(E===!0||E===1||E==="1"||E==="true")continue;let C=Math.min(6e3,Jn(U.render_height)??o),I=Math.min(C,Jn(U.render_min_height)??0),N=Zt[String(U.building_tone??"")]??0,K=Wt[String(U.class??"")]??0,$=d.get(M)??0,D=u.length,Y=!1;for(let w of tr(B.geometry,t)){let y=w.map(or).filter(S=>S.length>=6);if(y.length===0||qe(y[0])===0)continue;let[b,x]=rr(y[0]);if(n.masks?.length&&(yn(n.masks,b,x)||Yn(y,n.masks,Kt/i)))continue;let T={cell:Math.min(7,Math.max(0,Math.floor(x/1024)))*8+Math.min(7,Math.max(0,Math.floor(b/1024))),bounds:[1/0,1/0,-1/0,-1/0,C+.1],roofsFrom:a.length,roofsCount:0,wallsFrom:l.length,wallsCount:0};for(let S of y)for(let z=0;z<S.length;z+=2)T.bounds[0]=Math.min(T.bounds[0],S[z]-1),T.bounds[1]=Math.min(T.bounds[1],S[z+1]-1),T.bounds[2]=Math.max(T.bounds[2],S[z]+1),T.bounds[3]=Math.max(T.bounds[3],S[z+1]+1);Y=!0,f=Math.max(f,C);let F=Number.isSafeInteger(B.id),v=gn(F?B.id*.0731:b*.0731+x*.19137+D*1.618),L=!F&&y[0].some(S=>S<=0||S>=ue)?gn(C*7.31+I*3.17+N):v,O={base:I,top:C,jitter:L,seed:v,tone:N,group:K,use:$,cx:b,cy:x,index:D},V=y.map((S,z)=>er(S,z,r,n.cornerAngle));y=V.map(({ring:S})=>S);let R=w.length===1&&y.length===1?Zn(w[0],y[0],U,I,C,i,ue):void 0;R?(f=Math.max(f,R.ridge),T.bounds[4]=Math.max(T.bounds[4],R.ridge+.1),qt(R,O,s,a)):Qt(y,O,s,a);for(let[S,z]of y.entries()){let P=qe(z)>0,Z=S===0?P?-1:1:P?1:-1,j=z.length/2,G=H=>{let J=(H%j+j)%j;return[z[J*2],z[J*2+1]]},W=H=>{let[J,re]=G(H-1),[ne,te]=G(H),[le,de]=G(H+1);if(we(J,re,ne,te)||we(ne,te,le,de))return!1;let me=Math.hypot(ne-J,te-re),ce=Math.hypot(le-ne,de-te);if(!me||!ce)return!1;let je=-(te-re)/me*Z,De=(ne-J)/me*Z;return(je*(le-ne)+De*(de-te))/ce>Jt},se=(H,J)=>R?R.heightAt(H,J):C,ae=0;for(let H=0;H<j;H+=1){let[J,re]=G(H),[ne,te]=G(H+1),le=Math.hypot(ne-J,te-re);if(le===0||we(J,re,ne,te))continue;let de=-(te-re)/le*Z,me=(ne-J)/le*Z,ce=V[S].normals[H]??[de,me],je=V[S].normals[(H+1)%j]??[de,me],De=oe=>{let _e=ce[0]+(je[0]-ce[0])*oe,Ae=ce[1]+(je[1]-ce[1])*oe,ye=Math.hypot(_e,Ae)||1;return[_e/ye,Ae/ye]},he=[0,...R?R.breaks(J,re,ne,te):[],1];for(let oe=0;oe+1<he.length;oe+=1){let _e=oe===0,Ae=oe+2===he.length,ye=J+(ne-J)*he[oe],Ne=re+(te-re)*he[oe],Ve=J+(ne-J)*he[oe+1],He=re+(te-re)*he[oe+1],Fe=Math.hypot(Ve-ye,He-Ne)/ue*n.tileMetres,$e=(_e&&W(H)?1:0)|(Ae&&W(H+1)?2:0)|(S>0?4:0),Ge=(_e&&xn(J,re)?1:0)|(Ae&&xn(ne,te)?2:0),an=ae+Fe,Ze=De(he[oe]),We=De(he[oe+1]),Un=se(ye,Ne),Cn=se(Ve,He),ke=s.write(O,ye,Ne,0,Ze[0],Ze[1],1,ae,$e,Fe,0,Ge,Un);s.write(O,Ve,He,0,We[0],We[1],1,an,$e,Fe,1,Ge,Cn),s.write(O,ye,Ne,1,Ze[0],Ze[1],1,ae,$e,Fe,0,Ge,Un),s.write(O,Ve,He,1,We[0],We[1],1,an,$e,Fe,1,Ge,Cn),l.push(ke,ke+1,ke+2,ke+1,ke+3,ke+2),ae=an}}}T.roofsCount=a.length-T.roofsFrom,T.wallsCount=l.length-T.wallsFrom,c.push(T)}Y&&u.push(U)}if(s.count===0)return;let g=new Uint32Array(a.length+l.length),m=[],p=0,h=a.length,_=a.values(),A=l.values();c.sort((M,B)=>M.cell-B.cell);let k=-1;for(let M of c){M.cell!==k&&(k=M.cell,m.push({bounds:[...M.bounds],roofsFrom:p,roofsCount:0,wallsFrom:h,wallsCount:0}));let B=m.at(-1);for(let U=0;U<5;U+=1)B.bounds[U]=U<2?Math.min(B.bounds[U],M.bounds[U]):Math.max(B.bounds[U],M.bounds[U]);g.set(_.subarray(M.roofsFrom,M.roofsFrom+M.roofsCount),p),g.set(A.subarray(M.wallsFrom,M.wallsFrom+M.wallsCount),h),p+=M.roofsCount,h+=M.wallsCount,B.roofsCount+=M.roofsCount,B.wallsCount+=M.wallsCount}return{groups:m,vertices:s.bytes(),indices:g,wallsFrom:a.length,top:f,features:u}}function Qt(e,n,t,i){let o=[],r=[];for(let l of e)r.push(o.length/2),o.push(...l);r.push(o.length/2);let s=(l,u)=>{let c=r.findIndex((p,h)=>l>=p&&l<r[h+1]),[f,d]=[r[c],r[c+1]-1];if(u<f||u>d)return!1;let[g,m]=l<u?[l,u]:[u,l];return m-g!==1&&!(g===f&&m===d)?!1:!we(o[l*2],o[l*2+1],o[u*2],o[u*2+1])},a=Pe(o,r.slice(1,-1),2);for(let l=0;l+2<a.length;l+=3){let u=[a[l],a[l+1],a[l+2]],c=0;for(let f=0;f<3;f+=1)s(u[(f+1)%3],u[(f+2)%3])&&(c|=1<<f);for(let[f,d]of u.entries())i.push(t.write(n,o[d*2],o[d*2+1],1,0,0,0,0,0,0,f,c))}}function qt(e,n,t,i){for(let o of e.faces){let r=o.ring,s=r.length/2,a=(l,u)=>{let[c,f]=l<u?[l,u]:[u,l];return f-c!==1&&!(c===0&&f===s-1)?!1:!we(r[l*2],r[l*2+1],r[u*2],r[u*2+1])};for(let l=0;l+2<o.triangles.length;l+=3){let u=[o.triangles[l],o.triangles[l+1],o.triangles[l+2]],c=0;for(let f=0;f<3;f+=1)a(u[(f+1)%3],u[(f+2)%3])&&(c|=1<<f);for(let[f,d]of u.entries()){let g=r[d*2],m=r[d*2+1];i.push(t.write(n,g,m,1,o.normal[0],o.normal[1],0,0,0,0,f,c,e.heightAt(g,m)))}}}}function er(e,n,t,i=Math.PI/6){if(t<1)return{ring:e,normals:[]};let o=e.length/2,r=qe(e)>0,s=n===0?r?-1:1:r?1:-1,a=[],l=[],u=(c,f,d)=>{c=Re(c),f=Re(f),!(a.at(-2)===c&&a.at(-1)===f)&&(a.push(c,f),l.push(d))};for(let c=0;c<o;c+=1){let f=(c+o-1)%o,d=(c+1)%o,[g,m]=[e[f*2],e[f*2+1]],[p,h]=[e[c*2],e[c*2+1]],[_,A]=[e[d*2],e[d*2+1]],k=Math.hypot(p-g,h-m),M=Math.hypot(_-p,A-h);if(!k||!M||xn(p,h)||we(g,m,p,h)||we(p,h,_,A)){u(p,h);continue}let[B,U]=[(p-g)/k,(h-m)/k],[E,C]=[(_-p)/M,(A-h)/M],I=Math.atan2(B*C-U*E,B*E+U*C);if(I*s>=-.08||Math.abs(I)>Math.PI*.85){u(p,h);continue}let N=Math.tan(Math.abs(I)/2),K=Math.min(t*N,k*.2,M*.2),$=K/N;if($<1){u(p,h);continue}let[D,Y]=[-U*s,B*s],[w,y]=[p-B*K-D*$,h-U*K-Y*$],b=Math.atan2(Y,D),x=Math.max(i<=Math.PI/6?2:1,Math.ceil(Math.abs(I)/Math.max(Math.PI/6,Math.min(Math.PI/3,i))));for(let T=0;T<=x;T+=1){let F=b+I*T/x,v=[Math.cos(F),Math.sin(F)];u(w+v[0]*$,y+v[1]*$,v)}}return a[0]===a.at(-2)&&a[1]===a.at(-1)&&(a.splice(-2),l.pop()),a.length>=6?{ring:a,normals:l}:{ring:e,normals:[]}}var wn=class{#e=new ArrayBuffer(4096*pe);#n=new DataView(this.#e);count=0;write(n,t,i,o,r,s,a,l,u,c,f=0,d=0,g=n.top){let m=pe;if((this.count+1)*m>this.#e.byteLength){let _=new ArrayBuffer(this.#e.byteLength*2);new Uint8Array(_).set(new Uint8Array(this.#e)),this.#e=_,this.#n=new DataView(_)}let p=this.#n,h=this.count*m;return p.setUint16(h,Re(t),!0),p.setUint16(h+2,Re(i),!0),p.setUint16(h+4,Math.min(65535,Math.round(n.base*10)),!0),p.setUint16(h+6,Math.min(65535,Math.max(0,Math.round(g*10))),!0),p.setInt8(h+8,Math.round(r*127)),p.setInt8(h+9,Math.round(s*127)),p.setUint8(h+10,o),p.setUint8(h+11,a),p.setUint16(h+12,Math.round(l*10)%65536,!0),p.setUint8(h+14,Math.round(n.jitter*255)),p.setUint8(h+15,Math.round(n.seed*255)),p.setUint16(h+16,Re(n.cx),!0),p.setUint16(h+18,Re(n.cy),!0),p.setUint8(h+20,n.tone+4*n.group),p.setUint8(h+21,n.use),p.setUint8(h+22,u),p.setUint8(h+23,Math.min(255,Math.round(c))),p.setUint16(h+24,n.index,!0),p.setUint8(h+26,f),p.setUint8(h+27,d),this.count+=1,this.count-1}bytes(){return new Uint8Array(this.#e.slice(0,this.count*pe))}},Qe=class{#e=new Uint32Array(8192);length=0;push(...n){if(this.length+n.length>this.#e.length){let t=new Uint32Array(Math.max(this.length+n.length,this.#e.length*2));t.set(this.#e),this.#e=t}for(let t of n)this.#e[this.length++]=t}values(){return this.#e.subarray(0,this.length)}};function nr(e,n){let t=new Map;if(e.features.some(a=>a.properties.night_use!==void 0)){for(let[a,l]of e.features.entries()){let u=Xt[String(l.properties.night_use??"")];u&&t.set(a,u)}return t}let i=n.places;if(!i||i.features.length===0)return t;let o=Yt/n.tileMetres*e.extent,r=[];for(let[a,l]of e.features.entries()){if(l.type!=="Polygon")continue;let u=l.properties.hide_3d;if(u===!0||u===1||u==="1"||u==="true")continue;let c=[1/0,1/0,-1/0,-1/0];for(let f of l.geometry)for(let d=0;d+1<f.length;d+=2)c[0]=Math.min(c[0],f[d]),c[1]=Math.min(c[1],f[d+1]),c[2]=Math.max(c[2],f[d]),c[3]=Math.max(c[3],f[d+1]);r.push({index:a,rings:l.geometry,box:c})}let s=e.extent/i.extent;for(let a of i.features){if(a.type!=="Point")continue;let l=a.properties,u=bn[String(l.type??"")]??bn[String(l.subclass??"")]??bn[String(l.class??"")];if(u)for(let c of a.geometry)for(let f=0;f+1<c.length;f+=2){let d=c[f]*s,g=c[f+1]*s,m,p,h=o;for(let A of r){let[k,M,B,U]=A.box;if(d<k-o||d>B+o||g<M-o||g>U+o)continue;let E=!1;for(let C of A.rings)for(let I=0,N=C.length-2;I+1<C.length;N=I,I+=2){let K=C[N],$=C[N+1],D=C[I],Y=C[I+1];Y>g!=$>g&&d<(K-D)*(g-Y)/($-Y)+D&&(E=!E);let w=D-K,y=Y-$,b=w*w+y*y,x=b?Math.min(1,Math.max(0,((d-K)*w+(g-$)*y)/b)):0,T=Math.hypot(d-K-x*w,g-$-x*y);T<h&&(h=T,p=A.index)}if(E){m=A.index;break}}let _=m??p;_!==void 0&&t.set(_,Math.max(t.get(_)??0,u))}}return t}function Re(e){return Math.min(ue,Math.max(0,Math.round(e)))}function Jn(e){let n=Number(e);return Number.isFinite(n)&&n>0?n:void 0}function tr(e,n){let t=[],i;for(let o of e){let r=[];for(let a=0;a+1<o.length;a+=2){let l=o[a]*n,u=o[a+1]*n;r.length&&l===r.at(-2)&&u===r.at(-1)||r.push(l,u)}if(r.length>=6&&r[0]===r.at(-2)&&r[1]===r.at(-1)&&(r.length-=2),r.length<6)continue;let s=Math.sign(qe(r));s&&(i??=s,s===i||t.length===0?t.push([r]):t.at(-1).push(r))}return t}function qe(e){let n=0,t=e.length/2;for(let i=0;i<t;i+=1){let o=(i+1)%t;n+=e[i*2]*e[o*2+1]-e[o*2]*e[i*2+1]}return n}function rr(e){let n=0,t=0,i=e.length/2;for(let o=0;o<i;o+=1)n+=e[o*2],t+=e[o*2+1];return[n/i,t/i]}function xn(e,n){return e<=0||n<=0||e>=ue||n>=ue}function we(e,n,t,i){let o=ue;return e<=0&&t<=0||e>=o&&t>=o||n<=0&&i<=0||n>=o&&i>=o}function or(e){let n=ue,t=[...e],i=[[0,0,o=>o>=0],[0,n,o=>o<=n],[1,0,o=>o>=0],[1,n,o=>o<=n]];for(let[o,r,s]of i){let a=[],l=t.length/2;for(let u=0;u<l;u+=1){let c=[t[u*2],t[u*2+1]],f=[t[(u+1)%l*2],t[(u+1)%l*2+1]],d=s(c[o]),g=s(f[o]);if(d&&a.push(c[0],c[1]),d!==g){let m=(r-c[o])/(f[o]-c[o]);a.push(c[0]+(f[0]-c[0])*m,c[1]+(f[1]-c[1])*m)}}if(t=a,t.length<6)return[]}return t}function gn(e){let n=Math.sin(e*12.9898+78.233)*43758.5453;return n-Math.floor(n)}var Qn=`\nin float v_haze_depth;\nuniform vec3 u_haze_colour;\nuniform vec3 u_haze; // strength; the view depths where the haze starts and is complete\n\nfloat hazeOf() {\n return u_haze.x > 0.0 ? u_haze.x * smoothstep(u_haze.y, u_haze.z, v_haze_depth) : 0.0;\n}\n\nvec3 hazed(vec3 colour) {\n return mix(colour, u_haze_colour, hazeOf());\n}`;function qn(e){let n=(e.indices.length-e.wallsFrom)/6,t=new Uint8Array(n*16);for(let i=0;i<n;i+=1){let o=e.wallsFrom+i*6,r=e.indices[o]*pe,s=e.indices[o+1]*pe;t.set(e.vertices.subarray(r,r+4),i*16),t.set(e.vertices.subarray(s,s+4),i*16+4),t.set(e.vertices.subarray(r+4,r+8),i*16+8),t[i*16+12]=e.vertices[r+14],t[i*16+13]=e.vertices[r+27]}return t}var Kr=`#version 300 es\nprecision highp float;\nuniform highp sampler2D u_contact;\n${Qn}\nout vec4 fragColor;\nvoid main() {\n float shade = mix(texelFetch(u_contact, ivec2(gl_FragCoord.xy), 0).r, 1.0, hazeOf());\n fragColor = vec4(vec3(shade), 1.0);\n}`;function et(e){let n=e.vertices.length/pe;return{mesh:{...e.groups?{groups:e.groups}:{},wallsFrom:e.wallsFrom,top:e.top,features:e.features,vertexCount:n,indexCount:e.indices.length},data:{vertices:e.vertices,indices:n<=65536?Uint16Array.from(e.indices):e.indices,contact:qn(e)}}}function nt({data:e}){return[e.vertices.buffer,e.indices.buffer,e.contact.buffer]}function Tn(e){let n=ir(e);return n?[Math.min(1,Math.max(0,n[0]/255)),Math.min(1,Math.max(0,n[1]/255)),Math.min(1,Math.max(0,n[2]/255)),Math.min(1,Math.max(0,n[3]))]:null}function ir(e){let n=e.trim().toLowerCase(),t=/^#([\\da-f]{3,8})$/u.exec(n)?.[1];if(t&&[3,4,6,8].includes(t.length)){let _=(t.length<=4?[...t].map(A=>A+A).join(""):t).match(/../gu).map(A=>Number.parseInt(A,16));return[_[0],_[1],_[2],_.length>3?_[3]/255:1]}let i=/^(rgba?|hsla?)\\(([^)]+)\\)$/u.exec(n);if(!i)return null;let o=i[2].split(/[\\s,/]+/u).filter(Boolean);if(o.length<3||o.length>4)return null;let r=o[3]===void 0?1:en(o[3],1);if(i[1].startsWith("rgb")){let[h,_,A]=o.slice(0,3).map(k=>en(k,255));return[h,_,A,r].some(k=>k===null)?null:[h,_,A,r]}let s=Number.parseFloat(o[0]),a=en(o[1],1),l=en(o[2],1);if(!Number.isFinite(s)||a===null||l===null||r===null)return null;let u=(1-Math.abs(2*l-1))*a,c=(s%360+360)%360/60,f=u*(1-Math.abs(c%2-1)),[d,g,m]=c<1?[u,f,0]:c<2?[f,u,0]:c<3?[0,u,f]:c<4?[0,f,u]:c<5?[f,0,u]:[u,0,f],p=l-u/2;return[(d+p)*255,(g+p)*255,(m+p)*255,r]}function en(e,n){let t=e.endsWith("%"),i=Number.parseFloat(e);return Number.isFinite(i)?t?i/100*n:i:null}var fe=8192,Mn=12,sr={primary:{spacing:30,kerb:10},secondary:{spacing:32,kerb:8.5},tertiary:{spacing:34,kerb:7},minor:{spacing:36,kerb:5.5},pedestrian:{spacing:26,kerb:3}},ar={motorway:{spacing:45,kerb:14},trunk:{spacing:40,kerb:12},service:{spacing:38,kerb:4},path:{spacing:28,kerb:1.5},track:{spacing:40,kerb:2.5}},lr={spacing:30,kerb:0},ur=12,cr=18,fr=9,dr={sodium:"#ffa64d",high_pressure_sodium:"#ffa64d",low_pressure_sodium:"#ff9326",led:"#fff1db",mercury:"#e3ecff",metal_halide:"#f4f4ff",fluorescent:"#eef9ff",electric:"#ffd59a",incandescent:"#ffd59a",halogen:"#ffe3b0",gas:"#ffd28a",gaslight:"#ffd28a"},mr={orange:"#ffa64d",yellow:"#ffd27a",warm_white:"#ffe2b8",white:"#fff4e6",cool_white:"#eef4ff",neutral_white:"#fff8f0",blue:"#b8d0ff",green:"#c4ffd0",red:"#ff9a8a"},hr=new Set(["wall","wall_mounted","wall_bracket"]),pr=new Set(["suspended","cable","catenary","wire"]);function it(e,n){let t=n.estimate??"lit",i=new vn,o=new nn(cr),r=new nn(fr),s=e.streetFurniture;if(s){let m=fe/s.extent;for(let p of s.features){let h=p.properties;if(p.type!=="Point"||h.subclass!=="street_lamp")continue;let _=yr(h),A=br(h),k=Math.max(1,Math.min(4,Number(h.light_count)||1)),M=Math.min(24,Math.max(5,_*1.7*(k>1?1.15:1)));for(let B of p.geometry)for(let U=0;U+1<B.length;U+=2){let E=B[U]*m,C=B[U+1]*m;if(!rt(E,C))continue;i.write(E,C,_,M,!0,A);let I=ot(E,C,n.tileMetres);o.add(...I),r.add(...I)}}}let a=i.count;if(t==="none")return i.done(a);let l=e.transportation,u=0;if(l){let m=n.tileMetres/l.extent;for(let p of l.features)if(!(p.type!=="LineString"||!tt(p.properties,"streets")))for(let h of p.geometry)u+=gr(h,l.extent)*m}let c=u>0&&a/(u/1e3)>=ur,f=t==="streets"&&!c?"streets":"lit",d=(m,p,h,_)=>{let A=fe/m.extent,k=[];for(let N=0;N+1<p.length;N+=2)k.push(p[N]*A,p[N+1]*A);let M=n.tileMetres/fe,B=h.kerb*.45/M,U=Rn(k[0]*.013+k[1]*.029+_)*h.spacing,E=0,C=U,I=Rn(k[0]+k[1]*3.1)<.5?1:-1;for(let N=2;N<k.length;N+=2){let K=k[N-2],$=k[N-1],D=k[N],Y=k[N+1],w=Math.hypot(D-K,Y-$)*M;if(w!==0){for(;C<=E+w;){let y=(C-E)/w,b=-(Y-$)/(w/M)*I,x=(D-K)/(w/M)*I,T=K+(D-K)*y+b*B,F=$+(Y-$)*y+x*B;if(C+=h.kerb>0?h.spacing/2:h.spacing,h.kerb>0&&(I=-I),!rt(T,F))continue;let v=ot(T,F,n.tileMetres);o.near(...v)||r.near(...v)||(r.add(...v),i.write(T,F,7,15,!1))}E+=w}}};if(l)for(let m of l.features){if(m.type!=="LineString")continue;let p=tt(m.properties,f);if(p)for(let h of m.geometry)d(l,h,p,1)}let g=e.sidewalks;if(g){for(let m of g.features)if(!(m.type==="Point"||!kn(m.properties.lit)))for(let p of m.geometry)d(g,p,lr,2)}return i.done(a)}function tt(e,n){if(e.brunnel==="tunnel"||e.covered===!0)return;let t=e.lit;if(t===!1||t==="no")return;let i=String(e.class??""),o=String(e.subclass??""),r=i==="path"&&(o==="pedestrian"||o==="living_street")?"pedestrian":i,s=sr[r];if(s&&(n==="streets"||kn(t)))return s;let a=ar[r];if(a&&kn(t))return a}function kn(e){return e===!0||e==="yes"||e===1||e==="1"||e==="true"}function yr(e){let n=Number(e.height);if(Number.isFinite(n)&&n>=.5&&n<=40)return n;let t=String(e.lamp_mount??"").toLowerCase();return hr.has(t)?4.5:pr.has(t)?7.5:7}function br(e){let n=e.light_colour??e["light:colour"];if(typeof n=="string"&&n){let r=n.toLowerCase().replaceAll(" ","_"),s=Tn(mr[r]??n);if(s)return[s[0],s[1],s[2]]}let t=String(e.lamp_type??"").toLowerCase().replaceAll("-","_").replaceAll(" ","_"),i=dr[t];if(!i)return;let o=Tn(i);return[o[0],o[1],o[2]]}function rt(e,n){return e>=0&&n>=0&&e<fe&&n<fe}function ot(e,n,t){return[e/fe*t,n/fe*t]}function gr(e,n){let t=0;for(let i=2;i+1<e.length;i+=2){let o=(e[i-2]+e[i])/2,r=(e[i-1]+e[i+1])/2;o<0||r<0||o>=n||r>=n||(t+=Math.hypot(e[i]-e[i-2],e[i+1]-e[i-1]))}return t}var nn=class{constructor(n){this.size=n}size;#e=new Map;add(n,t){let i=`${Math.floor(n/this.size)}/${Math.floor(t/this.size)}`,o=this.#e.get(i);o?o.push([n,t]):this.#e.set(i,[[n,t]])}near(n,t){let i=Math.floor(n/this.size),o=Math.floor(t/this.size);for(let r=-1;r<=1;r+=1)for(let s=-1;s<=1;s+=1)for(let[a,l]of this.#e.get(`${i+r}/${o+s}`)??[])if(Math.hypot(a-n,l-t)<this.size)return!0;return!1}},vn=class{#e=new ArrayBuffer(256*Mn);#n=new DataView(this.#e);count=0;write(n,t,i,o,r,s){let a=Mn;if((this.count+1)*a>this.#e.byteLength){let c=new ArrayBuffer(this.#e.byteLength*2);new Uint8Array(c).set(new Uint8Array(this.#e)),this.#e=c,this.#n=new DataView(c)}let l=this.#n,u=this.count*a;l.setUint16(u,Math.min(fe,Math.max(0,Math.round(n))),!0),l.setUint16(u+2,Math.min(fe,Math.max(0,Math.round(t))),!0),l.setUint16(u+4,Math.min(65535,Math.round(i*10)),!0),l.setUint8(u+6,Math.min(255,Math.round(o))),l.setUint8(u+7,(r?1:0)|(s?2:0)),l.setUint8(u+8,Math.round((s?.[0]??0)*255)),l.setUint8(u+9,Math.round((s?.[1]??0)*255)),l.setUint8(u+10,Math.round((s?.[2]??0)*255)),l.setUint8(u+11,Math.round(Rn(n*.0731+t*.19137)*255)),this.count+=1}done(n){if(this.count!==0)return{lamps:new Uint8Array(this.#e.slice(0,this.count*Mn)),mapped:n,estimated:this.count-n}}};function Rn(e){let n=Math.sin(e*12.9898+78.233)*43758.5453;return n-Math.floor(n)}var oo=Object.freeze({source:"tileflow",layers:Object.freeze({streetFurniture:"street_furniture",transportation:"transportation",sidewalk:"sidewalk"}),estimate:"lit",color:"#ffcf8f",intensity:1});var Me=["round","open","tall","conifer","columnar","palm"];var ut=Object.freeze({height:"height",diameterCrown:"diameter_crown",circumference:"circumference",genus:"genus",species:"species",leafType:"leaf_type",taxon:"taxon",canopyRank:"rank",canopyClearance:"clearance_px_z15",canopyCover:"cover_pct",canopyHeight:"height_m",subclass:"subclass",hedge:"hedge"}),Sn=Object.freeze({round:1,open:1,tall:1}),tn=16,q=8192,rn=16,st={round:{height:[6,12],crown:[.66,.9]},open:{height:[5,10],crown:[.8,1.05]},tall:{height:[9,17],crown:[.48,.68]},conifer:{height:[7,16],crown:[.46,.66]},columnar:{height:[9,18],crown:[.22,.36]},palm:{height:[12,20],crown:[.42,.55]}};var on=[2,45],_n=[1,25],wr=1.2,xr=1.5,Tr=1.3,Mr=1,kr=[.3,10],vr=new Set(["acoelorrhaphe","adonidia","archontophoenix","areca","arecastrum","bismarckia","brahea","butia","caryota","chamaedorea","chamaerops","coccothrinax","cocos","dypsis","elaeis","howea","jubaea","licuala","livistona","phoenix","pritchardia","ptychosperma","rhapis","roystonea","sabal","serenoa","syagrus","thrinax","trachycarpus","veitchia","washingtonia","wodyetia"]),Rr=new Set(["cupressus","calocedrus","thuja"]),_r=new Set(["abies","araucaria","cedrus","cryptomeria","juniperus","larix","metasequoia","picea","pinus","pseudotsuga","sequoia","sequoiadendron","taxodium","taxus","tsuga"]),at=Object.freeze({...Object.fromEntries(["acacia","albizia","arbutus","bursera","ceratonia","delonix","ficus","gleditsia","jacaranda","olea","quercus","robinia","schinus","sophora","styphnolobium","tamarix"].map(e=>[e,"open"])),...Object.fromEntries(["betula","celtis","fraxinus","ginkgo","liquidambar","liriodendron","magnolia","platanus","populus","pyrus","ulmus","zelkova"].map(e=>[e,"tall"])),...Object.fromEntries(["acer","aesculus","carpinus","castanea","catalpa","cercis","citrus","fagus","lagerstroemia","malus","melia","morus","prunus","sorbus","tilia"].map(e=>[e,"round"]))});function lt(e,n={}){let t={...ut,...n},i=String(e[t.leafType]??"").toLowerCase(),o=String(e[t.taxon]??"").toLowerCase(),r=An(e[t.genus])??An(e[t.species])??(o.endsWith("aceae")?void 0:An(e[t.taxon]));if(i.includes("palm")||o.includes("arecaceae")||r&&vr.has(r))return"palm";if(o.includes("cupressaceae")&&!r||o.includes("pinaceae"))return"conifer";if(r&&Rr.has(r))return"columnar";if(i.includes("needle")||r&&_r.has(r))return"conifer";if(r&&at[r])return at[r];if(i.includes("broad"))return"broadleaf"}function An(e){return typeof e!="string"?void 0:e.trim().split(/\\s+/u)[0]?.toLowerCase()||void 0}function ct(e,n){let t={...ut,...n.fields},i=n.unknownForms??Sn,o=n.regions??[],{tile:r,tileMetres:s}=n,a=s/2**(15-r.z)/512,l=[],u=0,c=0,f=(w,y)=>{if(o.length===0)return i;let[b,x]=Fr(r,w/q,y/q);for(let T of o){let[F,v,L,O]=T.bounds;if(x>=v&&x<=O&&(F<=L?b>=F&&b<=L:b>=F||b<=L))return T.unknownForms}return i},d=(w,y,b,x)=>{let T=st[w],F=Fn(T.crown,ee(y,2)),v=b,L=x;return v===void 0&&L===void 0&&(v=Fn(T.height,ee(y,1))),v===void 0&&(v=L/F),L===void 0&&(L=v*F),{height:Te(v,on),crown:Te(L,_n)}},g=(w,y,b,x,T,F)=>{let v=ze(r.x*q+w,r.y*q+y,7),L=b===void 0?sn(f(w,y),ee(v,3)):b==="broadleaf"?sn(Ar(f(w,y)),ee(v,3)):b,O=x===void 0&&T===void 0&&F!==void 0?d(L,v,Fn(st[L].height,Te(F/3,[0,1]))):d(L,v,x,T);l.push({x:w,y,...O,turn:ee(v,4),shade:ee(v,5),form:Me.indexOf(L),rank:Math.floor(ee(v,6)*rn),seed:ee(v,7),canopy:0}),u+=1},m=e.trees;if(m){let w=q/m.extent;for(let y of m.features){if(y.type!=="Point")continue;let b=y.properties,x=lt(b,t),T=xe(b[t.height],on),F=xe(b[t.diameterCrown],_n),v=xe(b[t.circumference],[.1,12]);for(let L of y.geometry)for(let O=0;O+1<L.length;O+=2){let V=L[O],R=L[O+1];V<0||R<0||V>=m.extent||R>=m.extent||g(V*w,R*w,x,T,F,v)}}}let p=e.trees;if(p){let w=q/p.extent,y=(n.rowSpacing??8)/(s/p.extent);for(let b of p.features){if(b.type!=="LineString")continue;let x=b.properties,T=lt(x,t),F=xe(x[t.height],on),v=xe(x[t.diameterCrown],_n);for(let L of b.geometry){let O=y/2,V=0;for(let R=0;R+3<L.length;R+=2){let[S,z,P,Z]=[L[R],L[R+1],L[R+2],L[R+3]],j=Math.hypot(P-S,Z-z);for(;O<=V+j;){let G=j>0?(O-V)/j:0,W=S+(P-S)*G,se=z+(Z-z)*G;W>=0&&se>=0&&W<p.extent&&se<p.extent&&g(W*w,se*w,T,F,v,void 0),O+=y}V+=j}}}}let h=e.canopy;if(h){let w=q/h.extent;for(let y of h.features){if(y.type!=="Point")continue;let b=y.properties,x=Te(Math.floor(Number(b[t.canopyRank]??8)),[0,rn-1]),T=Math.max(4,Number(b[t.canopyClearance]??8))*a,F=Number(b[t.canopyCover]??30),v=F>=60?3:F>=30?2:1;for(let L of y.geometry)for(let O=0;O+1<L.length;O+=2){let V=L[O],R=L[O+1];if(V<0||R<0||V>=h.extent||R>=h.extent)continue;let S=V*w,z=R*w,P=ze(r.x*q+S,r.y*q+z,11),Z=f(S,z),j=xe(b[t.canopyHeight],on),G=Te(Math.min(T*(v===1?1.3:.95),11)*(.85+ee(P,1)*.25),[3,12]),W=Math.max(0,Math.min(G*.5,T-G/2)),se=ee(P,2)*Math.PI*2;for(let ae=0;ae<v;ae+=1){let H=ze(P,ae,13),J=se+ae*Math.PI*2/v,re=v===1?W*.3*ee(H,1):W,ne=S+Math.cos(J)*re/(s/q),te=z+Math.sin(J)*re/(s/q);if(ne<0||te<0||ne>=q||te>=q)continue;let le=sn(Z,ee(H,3)),de=G*(.85+ee(H,2)*.3),me=j===void 0?void 0:j*(.85+ee(H,6)*.25),ce=d(le,H,me,le==="palm"?void 0:de);l.push({x:ne,y:te,...ce,turn:ee(H,4),shade:ee(H,5),form:Me.indexOf(le),rank:x,seed:ee(H,7),canopy:1}),c+=1}}}}let _=[],A=e.hedges;if(A){let w=q/A.extent,y=wr/(s/A.extent);for(let b of A.features){if(b.type==="Point"||b.properties[t.subclass]!=="hedge")continue;let x=b.properties[t.hedge]==="hedge_bank"?Mr:0,T=(xe(b.properties[t.height],kr)??Tr)+x;for(let F of b.geometry){let v=y/2,L=0;for(let O=0;O+3<F.length;O+=2){let[V,R,S,z]=[F[O],F[O+1],F[O+2],F[O+3]],P=Math.hypot(S-V,z-R),Z=(Math.atan2(R-z,S-V)/(Math.PI*2)+1)%1;for(;v<=L+P;){let j=P>0?(v-L)/P:0,G=V+(S-V)*j,W=R+(z-R)*j;if(G>=0&&W>=0&&G<A.extent&&W<A.extent){let se=ze(r.x*q+G*w,r.y*q+W*w,17);_.push({x:G*w,y:W*w,height:T,turn:Z,shade:ee(se,5),seed:ee(se,7)})}v+=y}L+=P}}}}let k=w=>Te(Math.floor(n.variants?.[Me[w]]??1),[1,4]),M=w=>Math.min(k(w.form)-1,Math.floor(ee(Math.floor(w.seed*256),9)*k(w.form))),B=l.map(M),U=l.map((w,y)=>y);U.sort((w,y)=>l[w].form-l[y].form||B[w]-B[y]||l[w].rank-l[y].rank);let E=new Uint8Array(l.length*tn),C=new DataView(E.buffer),I=0,N=()=>({start:0,count:0,upTo:new Array(rn).fill(0)}),K=Object.fromEntries(Me.map((w,y)=>[w,{...N(),variants:Array.from({length:k(y)},N)}])),$=(w,y,b)=>{w.count===0&&(w.start=y),w.count+=1;for(let x=b;x<rn;x+=1)w.upTo[x]+=1};U.forEach((w,y)=>{let b=l[w],x=y*tn;C.setUint16(x,Math.min(q-1,Math.round(b.x)),!0),C.setUint16(x+2,Math.min(q-1,Math.round(b.y)),!0),C.setUint16(x+4,Math.round(b.height*10),!0),C.setUint16(x+6,Math.round(b.crown*10),!0),E[x+8]=Math.floor(b.turn*256)&255,E[x+9]=Math.floor(b.shade*256)&255,E[x+10]=b.form,E[x+11]=b.rank,E[x+12]=Math.floor(b.seed*256)&255,E[x+13]=b.canopy,E[x+14]=B[w],I=Math.max(I,b.height);let T=K[Me[b.form]];$(T,y,b.rank),$(T.variants[B[w]],y,b.rank)});let D=new Uint8Array(_.length*tn),Y=new DataView(D.buffer);return _.forEach((w,y)=>{let b=y*tn;Y.setUint16(b,Math.min(q-1,Math.round(w.x)),!0),Y.setUint16(b+2,Math.min(q-1,Math.round(w.y)),!0),Y.setUint16(b+4,Math.round(w.height*10),!0),Y.setUint16(b+6,Math.round(xr*10),!0),D[b+8]=Math.round(w.turn*256)&255,D[b+9]=Math.floor(w.shade*256)&255,D[b+12]=Math.floor(w.seed*256)&255,I=Math.max(I,w.height)}),{trees:E,forms:K,hedges:D,tallest:I,mapped:u,canopy:c}}function Ar(e){let n={round:e.round??0,open:e.open??0,tall:e.tall??0};return n.round+n.open+n.tall>0?n:Sn}function sn(e,n){let t=0;for(let o of Me)t+=Math.max(0,e[o]??0);if(t<=0)return sn(Sn,n);let i=n*t;for(let o of Me){let r=Math.max(0,e[o]??0);if(i<r)return o;i-=r}return"round"}function xe(e,n){let t=typeof e=="number"?e:typeof e=="string"?Number.parseFloat(e):NaN;return Number.isFinite(t)&&t>0?Te(t,n):void 0}function Te(e,[n,t]){return Math.min(t,Math.max(n,e))}function Fn([e,n],t){return e+(n-e)*t}function Fr(e,n,t){let i=2**e.z,o=(e.x+n)/i*360-180,r=Math.atan(Math.sinh(Math.PI*(1-2*(e.y+t)/i)))*180/Math.PI;return[o,r]}function ze(e,n,t){let i=(Math.imul(Math.floor(e)|0,668265261)^Math.imul(Math.floor(n)|0,374761393)^Math.imul(t,2654435761))>>>0;return i=Math.imul(i^i>>>15,2246822507)>>>0,i=Math.imul(i^i>>>13,3266489909)>>>0,(i^i>>>16)>>>0}function ee(e,n){return ze(e,n,20973)/4294967296}var Sr=[void 0,"Point","LineString","Polygon"];function ft(e,n={}){let t=n.layers?new Set(n.layers):void 0,i={},o=new Bn(e,0,e.length);for(;o.more();){let[r,s]=o.tag();if(r!==3){o.skip(s);continue}let a=o.message(),l=Lr(a,t);l&&!(l.name in i)&&(i[l.name]=l.layer)}return i}function Lr(e,n){let t,i=4096,o=[],r=[],s=[];for(;e.more();){let[a,l]=e.tag();if(a===1?t=e.string():a===2?s.push(e.message()):a===3?o.push(e.string()):a===4?r.push(Ur(e.message())):a===5?i=e.varint():e.skip(l),t!==void 0&&n&&!n.has(t))return}if(!(t===void 0||n&&!n.has(t)))return{name:t,layer:Object.freeze({extent:i,features:Object.freeze(s.flatMap(a=>{let l=Br(a,o,r);return l?[l]:[]}))})}}function Br(e,n,t){let i,o,r={},s=[];for(;e.more();){let[a,l]=e.tag();if(a===1)i=e.varint();else if(a===2){let u=e.packed();for(let c=0;c+1<u.length;c+=2){let f=n[u[c]],d=t[u[c+1]];f!==void 0&&d!==void 0&&(r[f]=d)}}else a===3?o=Sr[e.varint()]:a===4?s=e.packed():e.skip(l)}if(o)return Object.freeze({...i===void 0?{}:{id:i},type:o,properties:Object.freeze(r),geometry:Object.freeze(Or(s,o))})}function Or(e,n){let t=[],i,o=0,r=0,s=0;for(;s<e.length;){let a=e[s++],l=a&7,u=a>>>3;if(l===7){i&&i.length>=2&&i.push(i[0],i[1]);continue}if(l!==1&&l!==2)throw new Error(`Unknown geometry command ${l} in vector tile.`);if(s+u*2>e.length)throw new Error("Truncated vector tile geometry.");for(let c=0;c<u;c+=1){if(o+=Ln(e[s++]),r+=Ln(e[s++]),l===1&&(n!=="Point"||c===0)&&t.push(i=[]),!i)throw new Error("Vector tile geometry draws a line before moving to its start.");i.push(o,r)}}return t}var Ln=e=>e%2===1?-(e+1)/2:e/2;function Ur(e){let n="";for(;e.more();){let[t,i]=e.tag();t===1?n=e.string():t===2?n=e.float():t===3?n=e.double():t===4?n=e.varint(!0):t===5?n=e.varint():t===6?n=Ln(e.varint()):t===7?n=e.varint()!==0:e.skip(i)}return n}var Cr=new TextDecoder,Bn=class e{constructor(n,t,i){this.bytes=n;this.end=i;this.position=t,this.view=new DataView(n.buffer,n.byteOffset,n.byteLength)}bytes;end;position;view;more(){return this.position<this.end}tag(){let n=this.varint();return[Math.floor(n/8),n&7]}varint(n=!1){let t=0,i=0;for(let o=0;o<10;o+=1){if(this.position>=this.end)throw new Error("Truncated vector tile.");let r=this.bytes[this.position++];if(o<4?t|=(r&127)<<o*7:o===4?(t|=(r&15)<<28,i=(r&112)>>4):o<9?i|=(r&127)<<(o-5)*7+3:i|=(r&1)<<31,r<128)return n?i*4294967296+(t>>>0):(i>>>0)*4294967296+(t>>>0)}throw new Error("Invalid varint in vector tile.")}span(){let n=this.varint(),t=this.position;if(t+n>this.end)throw new Error("Truncated vector tile.");return this.position=t+n,[t,t+n]}message(){let[n,t]=this.span();return new e(this.bytes,n,t)}string(){let[n,t]=this.span();return Cr.decode(this.bytes.subarray(n,t))}packed(){let[n,t]=this.span(),i=new e(this.bytes,n,t),o=[];for(;i.more();)o.push(i.varint());return o}float(){if(this.position+4>this.end)throw new Error("Truncated vector tile.");let n=this.view.getFloat32(this.position,!0);return this.position+=4,n}double(){if(this.position+8>this.end)throw new Error("Truncated vector tile.");let n=this.view.getFloat64(this.position,!0);return this.position+=8,n}skip(n){if(n===0)this.varint();else if(n===1)this.position+=8;else if(n===2)this.span();else if(n===5)this.position+=4;else throw new Error(`Unsupported protocol buffer wire type ${n} in vector tile.`);if(this.position>this.end)throw new Error("Truncated vector tile.")}};function dt(e){return Object.values(e.layers).filter(n=>typeof n=="string")}function mt(e,n){if(e.kind==="buildings"){let r=n(e.layers.building);if(!r)return;let s=n(e.layers.places),a=Kn(r,{...e.options,...s?{places:s}:{}});return a&&et(a)}if(e.kind==="trees"){let r=n(e.layers.tree),s=n(e.layers.canopy),a=n(e.layers.hedge);if(!r&&!s&&!a)return;let l=ct({...r?{trees:r}:{},...s?{canopy:s}:{},...a?{hedges:a}:{}},e.options);return l.trees.length>0||l.hedges.length>0?l:void 0}let t=n(e.layers.streetFurniture),i=n(e.layers.transportation),o=n(e.layers.sidewalk);return it({...t?{streetFurniture:t}:{},...i?{transportation:i}:{},...o?{sidewalks:o}:{}},e.options)}function ht(e,n){if(!n)return[];if(e==="buildings")return nt(n);if(e==="trees"){let{trees:t,hedges:i}=n;return[t.buffer,i.buffer].filter((o,r,s)=>s.indexOf(o)===r)}return[n.lamps.buffer]}function pt(e=16){let n=new Map;return{read(t,i,o){let r=n.get(t);for(n.delete(t),r??={bytes:i,layers:new Map},n.set(t,r);n.size>e;)n.delete(n.keys().next().value);let s=o.filter(l=>!r.layers.has(l));if(s.length>0){let l=ft(r.bytes,{layers:s});for(let u of s)r.layers.set(u,l[u])}let a=r.layers;return l=>l===void 0?void 0:a.get(l)}}}var On=globalThis,Pr=pt();On.onmessage=({data:{url:e,bytes:n,task:t}})=>{try{let i=mt(t,Pr.read(e,n,dt(t)));On.postMessage({result:i},ht(t.kind,i))}catch(i){On.postMessage({error:String(i)})}};})();\n'], { type: "text/javascript" })
4185
+ new Blob(['"use strict";(()=>{var Be=new Set,ln=!1;function Pe(e,n,t=2){let i=n&&n.length,o=i?n[0]*t:e.length;Be.size&&Be.clear();let r=zn(e,0,o,t,!0),s=[];if(!r||r.next===r.prev)return s;let a=0,l=0,u=0;if(i&&(r=xt(e,n,r,t)),e.length>80*t){a=e[0],l=e[1];let c=a,f=l;for(let d=t;d<o;d+=t){let g=e[d],m=e[d+1];g<a&&(a=g),m<l&&(l=m),g>c&&(c=g),m>f&&(f=m)}u=Math.max(c-a,f-l),u=u!==0?32767/u:0}return un(r,s,a,l,u),s}function zn(e,n,t,i,o){let r=null;if(o===Ut(e,n,t,i)>0)for(let s=n;s<t;s+=i)r=In(s/i|0,e[s],e[s+1],r);else for(let s=t-i;s>=n;s-=i)r=In(s/i|0,e[s],e[s+1],r);return r&&Oe(r,r.next)&&(Ce(r),r=r.next),r}function ge(e,n=e){let t=n===e,i=e,o;do o=!1,i!==i.next&&(Be.size===0||!Be.has(i))&&(Oe(i,i.next)||Q(i.prev,i,i.next)===0)?((t||i===n)&&(n=i.prev),ln=!0,Ce(i),i=i.prev,o=!0):(t||i!==n)&&(i=i.next,o=!t);while(o||i!==n);return n}function un(e,n,t,i,o){o&&Ft(e,t,i,o);let r=e,s=!1;for(;e.prev!==e.next;){let a=e.prev,l=e.next;if(Q(a,e,l)<0&&(o?bt(e,t,i,o):yt(e))){n.push(a.i,e.i,l.i),Ce(e),e=l,r=l;continue}if(e=l,e===r){if(ln=!1,e=ge(e),ln){r=e;continue}if(!s){e=gt(e,n),r=e,s=!0;continue}wt(e,n,t,i,o);break}}}function yt(e){let n=e.prev,t=e,i=e.next,o=n.x,r=t.x,s=i.x,a=n.y,l=t.y,u=i.y,c=Math.min(o,r,s),f=Math.min(a,l,u),d=Math.max(o,r,s),g=Math.max(a,l,u),m=i.next;for(;m!==n;){if(m.x>=c&&m.x<=d&&m.y>=f&&m.y<=g&&!(o===m.x&&a===m.y)&&Ke(o,a,r,l,s,u,m.x,m.y)&&Q(m.prev,m,m.next)>=0)return!1;m=m.next}return!0}function bt(e,n,t,i){let o=e.prev,r=e,s=e.next,a=o.x,l=r.x,u=s.x,c=o.y,f=r.y,d=s.y,g=Math.min(a,l,u),m=Math.min(c,f,d),p=Math.max(a,l,u),h=Math.max(c,f,d),_=mn(g,m,n,t,i),F=mn(p,h,n,t,i),k=e.prevZ;for(;k&&k.z>=_;){if(k.x>=g&&k.x<=p&&k.y>=m&&k.y<=h&&k!==s&&!(a===k.x&&c===k.y)&&Ke(a,c,l,f,u,d,k.x,k.y)&&Q(k.prev,k,k.next)>=0)return!1;k=k.prevZ}let M=e.nextZ;for(;M&&M.z<=F;){if(M.x>=g&&M.x<=p&&M.y>=m&&M.y<=h&&M!==s&&!(a===M.x&&c===M.y)&&Ke(a,c,l,f,u,d,M.x,M.y)&&Q(M.prev,M,M.next)>=0)return!1;M=M.nextZ}return!0}function gt(e,n){let t=e,i=!1;do{let o=t.prev,r=t.next.next;Nn(o,t,t.next,r,!1)&&Ue(o,r)&&Ue(r,o)&&(n.push(o.i,t.i,r.i),Ce(t),Ce(t.next),t=e=r,i=!0),t=t.next}while(t!==e);return i?ge(t):t}function wt(e,n,t,i,o){let r=e;do{let s=r.next.next;for(;s!==r.prev;){if(r.i!==s.i&&Lt(r,s)){let a=Vn(r,s);r=ge(r,r.next),a=ge(a,a.next),un(r,n,t,i,o),un(a,n,t,i,o);return}s=s.next}r=r.next}while(r!==e)}var cn=!1;function xt(e,n,t,i){let o=[];for(let r=0,s=n.length;r<s;r++){let a=n[r]*i,l=r<s-1?n[r+1]*i:e.length,u=zn(e,a,l,i,!1);u===u.next&&Be.add(u),o.push(St(u))}o.sort(Tt),kt(e.length/i,n.length),Dn(t,t),cn=!0;for(let r=0;r<o.length;r++)t=Mt(o[r],t);return cn=!1,ge(t)}function Tt(e,n){return e.x-n.x||e.y-n.y||(e.next.y-e.y)/(e.next.x-e.x)-(n.next.y-n.y)/(n.next.x-n.x)}function Mt(e,n){let t=Rt(e,n);if(!t)return n;let i=Vn(t,e),o=i.next;return Dn(t,o.next),ge(i,i.next),ge(t,t.next)}var jn=16,X=new Float64Array(0),Je=0,fn=[],dn=[];function kt(e,n){let t=Math.ceil((e+2*n)/jn)+n+2;X.length<t*4&&(X=new Float64Array(t*4)),Je=0}function Dn(e,n){let t=e;do{let i=Je++;fn[i]=t;let o=t.x,r=t.y,s=t.x,a=t.y,l=0;do{let c=t.next;t.z=i,c.x<o&&(o=c.x),c.x>s&&(s=c.x),c.y<r&&(r=c.y),c.y>a&&(a=c.y),t=c}while(++l<jn&&t!==n);dn[i]=t;let u=i*4;X[u]=o,X[u+1]=r,X[u+2]=s,X[u+3]=a}while(t!==n)}function vt(e,n){let t=e.z*4;n.x<X[t]&&(X[t]=n.x),n.y<X[t+1]&&(X[t+1]=n.y),n.x>X[t+2]&&(X[t+2]=n.x),n.y>X[t+3]&&(X[t+3]=n.y)}function Pn(e){let n=dn[e];for(;n.prev.next!==n;)n=n.next;return dn[e]=n,n}function En(e){let n=fn[e];for(;n.prev.next!==n;)n=n.next;return fn[e]=n,n}function Rt(e,n){let t=n,i=e.x,o=e.y,r=-1/0,s;if(Oe(e,t))return t;for(let d=0,g=0;d<Je;d++,g+=4){if(o<X[g+1]||o>X[g+3]||X[g]>i||X[g+2]<=r)continue;let m=Pn(d);t=En(d);do{if(t.prev.next===t){if(Oe(e,t.next))return t.next;if(o<=t.y&&o>=t.next.y&&t.next.y!==t.y){let p=t.x+(o-t.y)*(t.next.x-t.x)/(t.next.y-t.y);if(p<=i&&p>r&&(r=p,s=t.x<t.next.x?t:t.next,p===i))return s}}t=t.next}while(t!==m)}if(!s)return null;let a=s.x,l=s.y,u=Math.min(o,l),c=Math.max(o,l),f=1/0;for(let d=0,g=0;d<Je;d++,g+=4){if(X[g+2]<a||X[g]>i||X[g+3]<u||X[g+1]>c)continue;let m=Pn(d);t=En(d);do{if(t.prev.next===t&&i>=t.x&&t.x>=a&&i!==t.x&&Ke(o<l?i:r,o,a,l,o<l?r:i,o,t.x,t.y)){let p=Math.abs(o-t.y)/(i-t.x);(Ue(t,e)||t.y===o&&t.next.y===o&&t.next.x>i)&&(p<f||p===f&&(t.x>s.x||t.x===s.x&&_t(s,t)))&&(s=t,f=p)}t=t.next}while(t!==m)}return s}function _t(e,n){return Q(e.prev,e,n.prev)<0&&Q(n.next,e,e.next)<0}var ie=[],ve=[],be=new Uint32Array(0),Se=new Uint32Array(0),Le=new Uint32Array(256);function Ft(e,n,t,i){let o=e,r=0;do o.z=mn(o.x,o.y,n,t,i),ie[r++]=o,o=o.next;while(o!==e);At(r);let s=null;for(let a=0;a<r;a++){let l=ie[a];l.prevZ=s,s&&(s.nextZ=l),s=l}s.nextZ=null,ie.fill(null,0,r),ve.fill(null,0,r)}function At(e){if(e<=32){for(let n=1;n<e;n++){let t=ie[n],i=t.z,o=n-1;for(;o>=0&&ie[o].z>i;)ie[o+1]=ie[o],o--;ie[o+1]=t}return}be.length<e&&(be=new Uint32Array(e),Se=new Uint32Array(e),ve=new Array(e));for(let n=0;n<e;n++)be[n]=ie[n].z;Xe(e,ie,be,ve,Se,0),Xe(e,ve,Se,ie,be,8),Xe(e,ie,be,ve,Se,16),Xe(e,ve,Se,ie,be,24)}function Xe(e,n,t,i,o,r){Le.fill(0);for(let a=0;a<e;a++)Le[t[a]>>>r&255]++;let s=0;for(let a=0;a<256;a++){let l=Le[a];Le[a]=s,s+=l}for(let a=0;a<e;a++){let l=t[a],u=Le[l>>>r&255]++;i[u]=n[a],o[u]=l}}function mn(e,n,t,i,o){return e=(e-t)*o|0,n=(n-i)*o|0,e=(e|e<<8)&16711935,e=(e|e<<4)&252645135,e=(e|e<<2)&858993459,e=(e|e<<1)&1431655765,n=(n|n<<8)&16711935,n=(n|n<<4)&252645135,n=(n|n<<2)&858993459,n=(n|n<<1)&1431655765,e|n<<1}function St(e){let n=e,t=e;do(n.x<t.x||n.x===t.x&&n.y<t.y)&&(t=n),n=n.next;while(n!==e);return t}function Ke(e,n,t,i,o,r,s,a){return(o-s)*(n-a)>=(e-s)*(r-a)&&(e-s)*(i-a)>=(t-s)*(n-a)&&(t-s)*(r-a)>=(o-s)*(i-a)}function Lt(e,n){let t=Oe(e,n)&&Q(e.prev,e,e.next)>0&&Q(n.prev,n,n.next)>0;return e.next.i!==n.i&&(t||Ue(e,n)&&Ue(n,e)&&(Q(e.prev,e,n.prev)!==0||Q(e,n.prev,n)!==0))&&!Bt(e,n)&&(t||Ot(e,n))}function Q(e,n,t){return(n.y-e.y)*(t.x-n.x)-(n.x-e.x)*(t.y-n.y)}function Oe(e,n){return e.x===n.x&&e.y===n.y}function Nn(e,n,t,i,o=!0){let r=Q(e,n,t),s=Q(e,n,i),a=Q(t,i,e),l=Q(t,i,n);return(r>0&&s<0||r<0&&s>0)&&(a>0&&l<0||a<0&&l>0)?!0:o?!!(r===0&&Ye(e,t,n)||s===0&&Ye(e,i,n)||a===0&&Ye(t,e,i)||l===0&&Ye(t,n,i)):!1}function Ye(e,n,t){return n.x<=Math.max(e.x,t.x)&&n.x>=Math.min(e.x,t.x)&&n.y<=Math.max(e.y,t.y)&&n.y>=Math.min(e.y,t.y)}function Bt(e,n){let t=Math.min(e.x,n.x),i=Math.max(e.x,n.x),o=Math.min(e.y,n.y),r=Math.max(e.y,n.y),s=e;do{let a=s.next;if(s.x>i&&a.x>i||s.x<t&&a.x<t||s.y>r&&a.y>r||s.y<o&&a.y<o){s=a;continue}if(s.i!==e.i&&a.i!==e.i&&s.i!==n.i&&a.i!==n.i&&Nn(s,a,e,n))return!0;s=a}while(s!==e);return!1}function Ue(e,n){return Q(e.prev,e,e.next)<0?Q(e,n,e.next)>=0&&Q(e,e.prev,n)>=0:Q(e,n,e.prev)<0||Q(e,e.next,n)<0}function Ot(e,n){let t=e,i=!1,o=(e.x+n.x)/2,r=(e.y+n.y)/2;do{let s=t.next;t.y>r!=s.y>r&&o<(s.x-t.x)*(r-t.y)/(s.y-t.y)+t.x&&(i=!i),t=s}while(t!==e);return i}function Vn(e,n){let t=hn(e.i,e.x,e.y),i=hn(n.i,n.x,n.y),o=e.next,r=n.prev;return e.next=n,n.prev=e,t.next=o,o.prev=t,i.next=t,t.prev=i,r.next=i,i.prev=r,i}function In(e,n,t,i){let o=hn(e,n,t);return i?(o.next=i.next,o.prev=i,i.next.prev=o,i.next=o):(o.prev=o,o.next=o),o}function Ce(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ),cn&&vt(e.prev,e.next)}function hn(e,n,t){return{i:e,x:n,y:t,prev:null,next:null,z:0,prevZ:null,nextZ:null}}function Ut(e,n,t,i){let o=0;for(let r=n,s=t-i;r<t;r+=i)o+=(e[s]-e[r])*(e[r+1]+e[s+1]),s=r;return o}var Ct=.7,Pt=Math.tan(Math.PI/6),Et=Math.tan(35*Math.PI/180),It=Math.tan(Math.PI/18),Ee=.65,Ie=.4;function Zn(e,n,t,i,o,r,s){let a=String(t.roof_shape??"");if(!a||a==="flat"||a==="sawtooth"||Vt(e,s))return;let l=Dt(e);if(!l||Math.abs(pn(e))<Ct*4*l.halfU*l.halfV)return;let u=l.u,c=l.v,f=l.halfU*r,d=l.halfV*r;f<d&&([u,c,f,d]=[c,u,d,f]);let g=Gn(t.roof_direction),m=g===void 0?void 0:[Math.sin(g*Math.PI/180),-Math.cos(g*Math.PI/180)];(m!==void 0?Math.abs(m[0]*u[0]+m[1]*u[1])>Math.abs(m[0]*c[0]+m[1]*c[1]):t.roof_orientation==="across")&&a!=="skillion"&&([u,c,f,d]=[c,u,d,f]);let h=jt(a,f,d,m&&[$n(m,u),$n(m,c)]);if(!h)return;let _=Math.max(0,o-i),F=Gn(t.roof_height),k,M;if(F!==void 0&&F>0)M=o,k=Math.max(i+Math.min(2,_/2),o-F);else{let y=Math.min(zt(a,d),_*.6,30);t.height_source==="height"?(M=o,k=o-y):(k=o,M=o+y)}let B=M-k;if(!(B>=.3))return;let[U,E]=l.centre,C=(y,b)=>{let x=(y-U)*r,T=(b-E)*r;return[x*u[0]+T*u[1],x*c[0]+T*c[1]]},I=(y,b)=>[U+(y*u[0]+b*c[0])/r,E+(y*u[1]+b*c[1])/r],N=(y,b)=>{let x=1/0;for(let[T,A,v]of h)x=Math.min(x,T*y+A*b+v);return Math.max(0,x)},K=(y,b)=>k+B*N(...C(y,b)),$=[];for(let y=0;y+1<n.length;y+=2)$.push(...C(n[y],n[y+1]));pn($)<0&&Ht($);let D=1.01,Y=[-f*D,-d*D,f*D,-d*D,f*D,d*D,-f*D,d*D],w=[];for(let[y,b]of h.entries()){let x=Y;for(let[P,Z]of h.entries()){if(P===y)continue;let j=b[0]-Z[0],G=b[1]-Z[1],W=b[2]-Z[2];if(Math.abs(j)+Math.abs(G)+Math.abs(W)<1e-9){P<y&&(x=[]);continue}if(x=Hn(x,j,G,W),x.length<6)break}if(x.length<6)continue;let T=$,A=x.length/2;for(let P=0;P<A&&T.length>=6;P+=1){let[Z,j]=[x[P*2],x[P*2+1]],[G,W]=[x[(P+1)%A*2],x[(P+1)%A*2+1]];T=Hn(T,W-j,Z-G,-(W-j)*Z-(Z-G)*j)}if(T.length<6||Math.abs(pn(T))<1e-6)continue;let v=[];for(let P=0;P<T.length;P+=2)v.push(...I(T[P],T[P+1]));let L=Pe(v);if(L.length===0)continue;let O=B*b[0],V=B*b[1],R=O*u[0]+V*c[0],S=O*u[1]+V*c[1],z=Math.hypot(R,S,1);w.push({ring:v,triangles:L,normal:[-R/z,-S/z]})}if(w.length!==0)return{eaves:k,ridge:M,faces:w,heightAt:K,breaks(y,b,x,T){let[A,v]=C(y,b),[L,O]=C(x,T),V=[];for(let R=0;R<h.length;R+=1)for(let S=R+1;S<h.length;S+=1){let z=(ae,H)=>(h[R][0]-h[S][0])*ae+(h[R][1]-h[S][1])*H+(h[R][2]-h[S][2]),P=z(A,v),Z=z(L,O);if(P===Z||P*Z>0)continue;let j=P/(P-Z);if(j<=1e-4||j>=1-1e-4)continue;let G=A+(L-A)*j,W=v+(O-v)*j;h[R][0]*G+h[R][1]*W+h[R][2]<=N(G,W)+1e-6&&V.push(j)}return[...new Set(V.map(R=>Math.round(R*1e6)/1e6))].sort((R,S)=>R-S)}}}function zt(e,n){switch(e){case"skillion":return 2*n*It;case"pyramidal":return n*Et;case"gambrel":case"mansard":return n*.8;case"dome":case"onion":case"round":return n;default:return n*Pt}}function jt(e,n,t,i){let o=n,r=t,s=[[0,-1/r,1],[0,1/r,1]],a=u=>u.flatMap(c=>[1,-1].flatMap(f=>{let d=c==="v"?r:o,g=Ee/(Ie*r)*f,m=(1-Ee)/((1-Ie)*r)*f,p=h=>c==="v"?[0,-h]:[-h,0];return[[...p(g),Ee/(Ie*r)*d],[...p(m),Ee+(1-Ee)/((1-Ie)*r)*(d-Ie*r)]]})),l=[.99,.8,.5,.2];switch(e){case"gabled":return s;case"saltbox":{let u=r/3;return[[0,-1/(r-u),1+u/(r-u)],[0,1/(r+u),1-u/(r+u)]]}case"hipped":return[...s,[-1/r,0,o/r],[1/r,0,o/r]];case"half_hipped":return[...s,[-1/r,0,.5+o/r],[1/r,0,.5+o/r]];case"pyramidal":return[...s,[-1/o,0,1],[1/o,0,1]];case"gambrel":return a(["v"]);case"mansard":return a(["v","u"]);case"skillion":{let[u,c]=i??[0,1],f=Math.abs(u)*o+Math.abs(c)*r;return f>0?[[-u/(2*f),-c/(2*f),.5]]:void 0}case"round":return[[0,0,1],...l.flatMap(u=>{let c=Math.sqrt(1-u*u);return[1,-1].map(f=>[0,-f*u/(r*c),1/c])})];case"dome":case"onion":return[[0,0,1],...l.flatMap(u=>{let c=Math.sqrt(1-u*u);return Array.from({length:12},(f,d)=>{let g=d*Math.PI/6;return[-u*Math.cos(g)/(o*c),-u*Math.sin(g)/(r*c),1/c]})})];default:return}}function Hn(e,n,t,i){let o=e.length/2,r=[];for(let s=0;s<o;s+=1){let a=e[s*2],l=e[s*2+1],u=e[(s+1)%o*2],c=e[(s+1)%o*2+1],f=n*a+t*l+i,d=n*u+t*c+i;if(f<=0&&r.push(a,l),f<0&&d>0||f>0&&d<0){let g=f/(f-d);r.push(a+(u-a)*g,l+(c-l)*g)}}return r}function Dt(e){let n=Nt(e);if(n.length<3)return;let t,i=1/0;for(let o=0;o<n.length;o+=1){let[r,s]=n[o],[a,l]=n[(o+1)%n.length],u=Math.hypot(a-r,l-s);if(u===0)continue;let c=[(a-r)/u,(l-s)/u],f=[-c[1],c[0]],[d,g,m,p]=[1/0,-1/0,1/0,-1/0];for(let[_,F]of n){let k=_*c[0]+F*c[1],M=_*f[0]+F*f[1];d=Math.min(d,k),g=Math.max(g,k),m=Math.min(m,M),p=Math.max(p,M)}let h=(g-d)*(p-m);if(h<i){i=h;let _=(d+g)/2,F=(m+p)/2;t={centre:[_*c[0]+F*f[0],_*c[1]+F*f[1]],u:c,v:f,halfU:(g-d)/2,halfV:(p-m)/2}}}return t&&t.halfU>0&&t.halfV>0?t:void 0}function Nt(e){let n=[];for(let r=0;r+1<e.length;r+=2)n.push([e[r],e[r+1]]);n.sort((r,s)=>r[0]-s[0]||r[1]-s[1]);let t=(r,s,a)=>(s[0]-r[0])*(a[1]-r[1])-(s[1]-r[1])*(a[0]-r[0]),i=[];for(let r of n){for(;i.length>=2&&t(i.at(-2),i.at(-1),r)<=0;)i.pop();i.push(r)}let o=[];for(let r of n.reverse()){for(;o.length>=2&&t(o.at(-2),o.at(-1),r)<=0;)o.pop();o.push(r)}return[...i.slice(0,-1),...o.slice(0,-1)]}function Vt(e,n){let[t,i,o,r]=[1/0,-1/0,1/0,-1/0];for(let a=0;a+1<e.length;a+=2)t=Math.min(t,e[a]),i=Math.max(i,e[a]),o=Math.min(o,e[a+1]),r=Math.max(r,e[a+1]);let s=e.length/2;for(let a=0;a<s;a+=1){let l=e[a*2],u=e[a*2+1],c=e[(a+1)%s*2],f=e[(a+1)%s*2+1];if(t<0&&l===t&&c===t||i>n&&l===i&&c===i||o<0&&u===o&&f===o||r>n&&u===r&&f===r)return!0}return!1}function pn(e){let n=0,t=e.length/2;for(let i=0;i<t;i+=1){let o=(i+1)%t;n+=e[i*2]*e[o*2+1]-e[o*2]*e[i*2+1]}return n/2}function Ht(e){let n=[];for(let t=0;t<e.length;t+=2)n.push([e[t],e[t+1]]);n.reverse(),e.splice(0,e.length,...n.flat())}function $n(e,n){return e[0]*n[0]+e[1]*n[1]}function Gn(e){let n=typeof e=="string"?Number(e):e;return typeof n=="number"&&Number.isFinite(n)?n:void 0}var jr=Object.freeze({surface:0,secondary:1,glass:2,accent:3,roof:4}),Dr=Object.freeze({unclassified:0,wall:1,door:2,roof:3,window:4,lamp:5,logo:6}),Nr=Object.freeze([1,1,4,1,3]),Vr=Object.freeze({levels:3,vertices:2e5,triangles:2e5,footprintPoints:4096,radius:2e3,height:1e3,models:512,bytes:16*1024*1024});function yn(e,n,t){for(let i of e){let o=!1;for(let r=0,s=i.length-2;r<i.length;s=r,r+=2){let a=i[r],l=i[r+1],u=i[s],c=i[s+1];l>t!=c>t&&n<(u-a)*(t-l)/(c-l)+a&&(o=!o)}if(o)return!0}return!1}function Yn(e,n,t){for(let i of n){let[o,r,s,a]=Xn(i);for(let l of e){let[u,c,f,d]=Xn(l);if(!(u>s-t||f<o+t||c>a-t||d<r+t)&&(Wn(l,i,t)||Wn(i,l,t)))return!0}}return!1}function Wn(e,n,t){let i=(o,r)=>yn([n],o,r)&&Gt(n,o,r)>t;for(let o=0;o+1<e.length;o+=2)if(i(e[o],e[o+1]))return!0;for(let o=0,r=e.length-2;o<e.length;r=o,o+=2){let[s,a,l,u]=[e[r],e[r+1],e[o],e[o+1]],c=[0,1];for(let f=0,d=n.length-2;f<n.length;d=f,f+=2){let g=$t(s,a,l,u,n[d],n[d+1],n[f],n[f+1]);g!==void 0&&c.push(g)}if(c.length!==2){c.sort((f,d)=>f-d);for(let f=1;f<c.length;f+=1){let d=(c[f-1]+c[f])/2;if(i(s+(l-s)*d,a+(u-a)*d))return!0}}}return!1}function $t(e,n,t,i,o,r,s,a){let l=t-e,u=i-n,c=s-o,f=a-r,d=l*f-u*c;if(d===0)return;let g=((o-e)*f-(r-n)*c)/d,m=((o-e)*u-(r-n)*l)/d;return g>0&&g<1&&m>=0&&m<=1?g:void 0}function Gt(e,n,t){let i=1/0;for(let o=0,r=e.length-2;o<e.length;r=o,o+=2){let[s,a,l,u]=[e[r],e[r+1],e[o],e[o+1]],c=(l-s)**2+(u-a)**2,f=c>0?Math.max(0,Math.min(1,((n-s)*(l-s)+(t-a)*(u-a))/c)):0;i=Math.min(i,Math.hypot(n-(s+(l-s)*f),t-(a+(u-a)*f)))}return i}function Xn(e){let[n,t,i,o]=[1/0,1/0,-1/0,-1/0];for(let r=0;r+1<e.length;r+=2)n=Math.min(n,e[r]),i=Math.max(i,e[r]),t=Math.min(t,e[r+1]),o=Math.max(o,e[r+1]);return[n,t,i,o]}var ue=8192,pe=28,Zt={commercial:1,active:2,destination:3},Wt={residential:1,...Object.fromEntries(["civic","commercial","education","entertainment","medical","transportation"].map(e=>[e,2])),...Object.fromEntries(["agricultural","industrial","military","outbuilding","religious","service"].map(e=>[e,3]))},Xt={dining:1,entertainment:2,nightlife:3},bn={...Object.fromEntries(["alcoholic_beverage_venue","bar","beer","biergarten","brewery","casino","cocktail_bar","dance_club","karaoke","lounge","music_venue","night_club","nightclub","pub","wine_bar"].map(e=>[e,3])),...Object.fromEntries(["arts_centre","bowling_alley","cinema","comedy_club","concert_hall","movie_theater","opera","performing_arts_venue","theater","theatre","theatre_venue"].map(e=>[e,2])),...Object.fromEntries(["casual_eatery","fast_food","fast_food_restaurant","food_court","restaurant"].map(e=>[e,1]))},Yt=6,Jt=.5,Kt=.5;function Kn(e,n){let t=ue/e.extent,i=n.tileMetres/ue,o=n.defaultHeight??5,r=Number.isFinite(n.edgeRadius)?Math.max(0,Math.min(1,n.edgeRadius))/i:0,s=new wn,a=new Qe,l=new Qe,u=[],c=[],f=0,d=nr(e,n);for(let[M,B]of e.features.entries()){if(B.type!=="Polygon"||u.length>=65535)continue;let U=B.properties,E=U.hide_3d;if(E===!0||E===1||E==="1"||E==="true")continue;let C=Math.min(6e3,Jn(U.render_height)??o),I=Math.min(C,Jn(U.render_min_height)??0),N=Zt[String(U.building_tone??"")]??0,K=Wt[String(U.class??"")]??0,$=d.get(M)??0,D=u.length,Y=!1;for(let w of tr(B.geometry,t)){let y=w.map(or).filter(S=>S.length>=6);if(y.length===0||qe(y[0])===0)continue;let[b,x]=rr(y[0]);if(n.masks?.length&&(yn(n.masks,b,x)||Yn(y,n.masks,Kt/i)))continue;let T={cell:Math.min(7,Math.max(0,Math.floor(x/1024)))*8+Math.min(7,Math.max(0,Math.floor(b/1024))),bounds:[1/0,1/0,-1/0,-1/0,C+.1],roofsFrom:a.length,roofsCount:0,wallsFrom:l.length,wallsCount:0};for(let S of y)for(let z=0;z<S.length;z+=2)T.bounds[0]=Math.min(T.bounds[0],S[z]-1),T.bounds[1]=Math.min(T.bounds[1],S[z+1]-1),T.bounds[2]=Math.max(T.bounds[2],S[z]+1),T.bounds[3]=Math.max(T.bounds[3],S[z+1]+1);Y=!0,f=Math.max(f,C);let A=Number.isSafeInteger(B.id),v=gn(A?B.id*.0731:b*.0731+x*.19137+D*1.618),L=!A&&y[0].some(S=>S<=0||S>=ue)?gn(C*7.31+I*3.17+N):v,O={base:I,top:C,jitter:L,seed:v,tone:N,group:K,use:$,cx:b,cy:x,index:D},V=y.map((S,z)=>er(S,z,r,n.cornerAngle));y=V.map(({ring:S})=>S);let R=w.length===1&&y.length===1?Zn(w[0],y[0],U,I,C,i,ue):void 0;R?(f=Math.max(f,R.ridge),T.bounds[4]=Math.max(T.bounds[4],R.ridge+.1),qt(R,O,s,a)):Qt(y,O,s,a);for(let[S,z]of y.entries()){let P=qe(z)>0,Z=S===0?P?-1:1:P?1:-1,j=z.length/2,G=H=>{let J=(H%j+j)%j;return[z[J*2],z[J*2+1]]},W=H=>{let[J,re]=G(H-1),[ne,te]=G(H),[le,de]=G(H+1);if(we(J,re,ne,te)||we(ne,te,le,de))return!1;let me=Math.hypot(ne-J,te-re),ce=Math.hypot(le-ne,de-te);if(!me||!ce)return!1;let je=-(te-re)/me*Z,De=(ne-J)/me*Z;return(je*(le-ne)+De*(de-te))/ce>Jt},se=(H,J)=>R?R.heightAt(H,J):C,ae=0;for(let H=0;H<j;H+=1){let[J,re]=G(H),[ne,te]=G(H+1),le=Math.hypot(ne-J,te-re);if(le===0||we(J,re,ne,te))continue;let de=-(te-re)/le*Z,me=(ne-J)/le*Z,ce=V[S].normals[H]??[de,me],je=V[S].normals[(H+1)%j]??[de,me],De=oe=>{let _e=ce[0]+(je[0]-ce[0])*oe,Fe=ce[1]+(je[1]-ce[1])*oe,ye=Math.hypot(_e,Fe)||1;return[_e/ye,Fe/ye]},he=[0,...R?R.breaks(J,re,ne,te):[],1];for(let oe=0;oe+1<he.length;oe+=1){let _e=oe===0,Fe=oe+2===he.length,ye=J+(ne-J)*he[oe],Ne=re+(te-re)*he[oe],Ve=J+(ne-J)*he[oe+1],He=re+(te-re)*he[oe+1],Ae=Math.hypot(Ve-ye,He-Ne)/ue*n.tileMetres,$e=(_e&&W(H)?1:0)|(Fe&&W(H+1)?2:0)|(S>0?4:0),Ge=(_e&&xn(J,re)?1:0)|(Fe&&xn(ne,te)?2:0),an=ae+Ae,Ze=De(he[oe]),We=De(he[oe+1]),Un=se(ye,Ne),Cn=se(Ve,He),ke=s.write(O,ye,Ne,0,Ze[0],Ze[1],1,ae,$e,Ae,0,Ge,Un);s.write(O,Ve,He,0,We[0],We[1],1,an,$e,Ae,1,Ge,Cn),s.write(O,ye,Ne,1,Ze[0],Ze[1],1,ae,$e,Ae,0,Ge,Un),s.write(O,Ve,He,1,We[0],We[1],1,an,$e,Ae,1,Ge,Cn),l.push(ke,ke+1,ke+2,ke+1,ke+3,ke+2),ae=an}}}T.roofsCount=a.length-T.roofsFrom,T.wallsCount=l.length-T.wallsFrom,c.push(T)}Y&&u.push(U)}if(s.count===0)return;let g=new Uint32Array(a.length+l.length),m=[],p=0,h=a.length,_=a.values(),F=l.values();c.sort((M,B)=>M.cell-B.cell);let k=-1;for(let M of c){M.cell!==k&&(k=M.cell,m.push({bounds:[...M.bounds],roofsFrom:p,roofsCount:0,wallsFrom:h,wallsCount:0}));let B=m.at(-1);for(let U=0;U<5;U+=1)B.bounds[U]=U<2?Math.min(B.bounds[U],M.bounds[U]):Math.max(B.bounds[U],M.bounds[U]);g.set(_.subarray(M.roofsFrom,M.roofsFrom+M.roofsCount),p),g.set(F.subarray(M.wallsFrom,M.wallsFrom+M.wallsCount),h),p+=M.roofsCount,h+=M.wallsCount,B.roofsCount+=M.roofsCount,B.wallsCount+=M.wallsCount}return{groups:m,vertices:s.bytes(),indices:g,wallsFrom:a.length,top:f,features:u}}function Qt(e,n,t,i){let o=[],r=[];for(let l of e)r.push(o.length/2),o.push(...l);r.push(o.length/2);let s=(l,u)=>{let c=r.findIndex((p,h)=>l>=p&&l<r[h+1]),[f,d]=[r[c],r[c+1]-1];if(u<f||u>d)return!1;let[g,m]=l<u?[l,u]:[u,l];return m-g!==1&&!(g===f&&m===d)?!1:!we(o[l*2],o[l*2+1],o[u*2],o[u*2+1])},a=Pe(o,r.slice(1,-1),2);for(let l=0;l+2<a.length;l+=3){let u=[a[l],a[l+1],a[l+2]],c=0;for(let f=0;f<3;f+=1)s(u[(f+1)%3],u[(f+2)%3])&&(c|=1<<f);for(let[f,d]of u.entries())i.push(t.write(n,o[d*2],o[d*2+1],1,0,0,0,0,0,0,f,c))}}function qt(e,n,t,i){for(let o of e.faces){let r=o.ring,s=r.length/2,a=(l,u)=>{let[c,f]=l<u?[l,u]:[u,l];return f-c!==1&&!(c===0&&f===s-1)?!1:!we(r[l*2],r[l*2+1],r[u*2],r[u*2+1])};for(let l=0;l+2<o.triangles.length;l+=3){let u=[o.triangles[l],o.triangles[l+1],o.triangles[l+2]],c=0;for(let f=0;f<3;f+=1)a(u[(f+1)%3],u[(f+2)%3])&&(c|=1<<f);for(let[f,d]of u.entries()){let g=r[d*2],m=r[d*2+1];i.push(t.write(n,g,m,1,o.normal[0],o.normal[1],0,0,0,0,f,c,e.heightAt(g,m)))}}}}function er(e,n,t,i=Math.PI/6){if(t<1)return{ring:e,normals:[]};let o=e.length/2,r=qe(e)>0,s=n===0?r?-1:1:r?1:-1,a=[],l=[],u=(c,f,d)=>{c=Re(c),f=Re(f),!(a.at(-2)===c&&a.at(-1)===f)&&(a.push(c,f),l.push(d))};for(let c=0;c<o;c+=1){let f=(c+o-1)%o,d=(c+1)%o,[g,m]=[e[f*2],e[f*2+1]],[p,h]=[e[c*2],e[c*2+1]],[_,F]=[e[d*2],e[d*2+1]],k=Math.hypot(p-g,h-m),M=Math.hypot(_-p,F-h);if(!k||!M||xn(p,h)||we(g,m,p,h)||we(p,h,_,F)){u(p,h);continue}let[B,U]=[(p-g)/k,(h-m)/k],[E,C]=[(_-p)/M,(F-h)/M],I=Math.atan2(B*C-U*E,B*E+U*C);if(I*s>=-.08||Math.abs(I)>Math.PI*.85){u(p,h);continue}let N=Math.tan(Math.abs(I)/2),K=Math.min(t*N,k*.2,M*.2),$=K/N;if($<1){u(p,h);continue}let[D,Y]=[-U*s,B*s],[w,y]=[p-B*K-D*$,h-U*K-Y*$],b=Math.atan2(Y,D),x=Math.max(i<=Math.PI/6?2:1,Math.ceil(Math.abs(I)/Math.max(Math.PI/6,Math.min(Math.PI/3,i))));for(let T=0;T<=x;T+=1){let A=b+I*T/x,v=[Math.cos(A),Math.sin(A)];u(w+v[0]*$,y+v[1]*$,v)}}return a[0]===a.at(-2)&&a[1]===a.at(-1)&&(a.splice(-2),l.pop()),a.length>=6?{ring:a,normals:l}:{ring:e,normals:[]}}var wn=class{#e=new ArrayBuffer(4096*pe);#n=new DataView(this.#e);count=0;write(n,t,i,o,r,s,a,l,u,c,f=0,d=0,g=n.top){let m=pe;if((this.count+1)*m>this.#e.byteLength){let _=new ArrayBuffer(this.#e.byteLength*2);new Uint8Array(_).set(new Uint8Array(this.#e)),this.#e=_,this.#n=new DataView(_)}let p=this.#n,h=this.count*m;return p.setUint16(h,Re(t),!0),p.setUint16(h+2,Re(i),!0),p.setUint16(h+4,Math.min(65535,Math.round(n.base*10)),!0),p.setUint16(h+6,Math.min(65535,Math.max(0,Math.round(g*10))),!0),p.setInt8(h+8,Math.round(r*127)),p.setInt8(h+9,Math.round(s*127)),p.setUint8(h+10,o),p.setUint8(h+11,a),p.setUint16(h+12,Math.round(l*10)%65536,!0),p.setUint8(h+14,Math.round(n.jitter*255)),p.setUint8(h+15,Math.round(n.seed*255)),p.setUint16(h+16,Re(n.cx),!0),p.setUint16(h+18,Re(n.cy),!0),p.setUint8(h+20,n.tone+4*n.group),p.setUint8(h+21,n.use),p.setUint8(h+22,u),p.setUint8(h+23,Math.min(255,Math.round(c))),p.setUint16(h+24,n.index,!0),p.setUint8(h+26,f),p.setUint8(h+27,d),this.count+=1,this.count-1}bytes(){return new Uint8Array(this.#e.slice(0,this.count*pe))}},Qe=class{#e=new Uint32Array(8192);length=0;push(...n){if(this.length+n.length>this.#e.length){let t=new Uint32Array(Math.max(this.length+n.length,this.#e.length*2));t.set(this.#e),this.#e=t}for(let t of n)this.#e[this.length++]=t}values(){return this.#e.subarray(0,this.length)}};function nr(e,n){let t=new Map;if(e.features.some(a=>a.properties.night_use!==void 0)){for(let[a,l]of e.features.entries()){let u=Xt[String(l.properties.night_use??"")];u&&t.set(a,u)}return t}let i=n.places;if(!i||i.features.length===0)return t;let o=Yt/n.tileMetres*e.extent,r=[];for(let[a,l]of e.features.entries()){if(l.type!=="Polygon")continue;let u=l.properties.hide_3d;if(u===!0||u===1||u==="1"||u==="true")continue;let c=[1/0,1/0,-1/0,-1/0];for(let f of l.geometry)for(let d=0;d+1<f.length;d+=2)c[0]=Math.min(c[0],f[d]),c[1]=Math.min(c[1],f[d+1]),c[2]=Math.max(c[2],f[d]),c[3]=Math.max(c[3],f[d+1]);r.push({index:a,rings:l.geometry,box:c})}let s=e.extent/i.extent;for(let a of i.features){if(a.type!=="Point")continue;let l=a.properties,u=bn[String(l.type??"")]??bn[String(l.subclass??"")]??bn[String(l.class??"")];if(u)for(let c of a.geometry)for(let f=0;f+1<c.length;f+=2){let d=c[f]*s,g=c[f+1]*s,m,p,h=o;for(let F of r){let[k,M,B,U]=F.box;if(d<k-o||d>B+o||g<M-o||g>U+o)continue;let E=!1;for(let C of F.rings)for(let I=0,N=C.length-2;I+1<C.length;N=I,I+=2){let K=C[N],$=C[N+1],D=C[I],Y=C[I+1];Y>g!=$>g&&d<(K-D)*(g-Y)/($-Y)+D&&(E=!E);let w=D-K,y=Y-$,b=w*w+y*y,x=b?Math.min(1,Math.max(0,((d-K)*w+(g-$)*y)/b)):0,T=Math.hypot(d-K-x*w,g-$-x*y);T<h&&(h=T,p=F.index)}if(E){m=F.index;break}}let _=m??p;_!==void 0&&t.set(_,Math.max(t.get(_)??0,u))}}return t}function Re(e){return Math.min(ue,Math.max(0,Math.round(e)))}function Jn(e){let n=Number(e);return Number.isFinite(n)&&n>0?n:void 0}function tr(e,n){let t=[],i;for(let o of e){let r=[];for(let a=0;a+1<o.length;a+=2){let l=o[a]*n,u=o[a+1]*n;r.length&&l===r.at(-2)&&u===r.at(-1)||r.push(l,u)}if(r.length>=6&&r[0]===r.at(-2)&&r[1]===r.at(-1)&&(r.length-=2),r.length<6)continue;let s=Math.sign(qe(r));s&&(i??=s,s===i||t.length===0?t.push([r]):t.at(-1).push(r))}return t}function qe(e){let n=0,t=e.length/2;for(let i=0;i<t;i+=1){let o=(i+1)%t;n+=e[i*2]*e[o*2+1]-e[o*2]*e[i*2+1]}return n}function rr(e){let n=0,t=0,i=e.length/2;for(let o=0;o<i;o+=1)n+=e[o*2],t+=e[o*2+1];return[n/i,t/i]}function xn(e,n){return e<=0||n<=0||e>=ue||n>=ue}function we(e,n,t,i){let o=ue;return e<=0&&t<=0||e>=o&&t>=o||n<=0&&i<=0||n>=o&&i>=o}function or(e){let n=ue,t=[...e],i=[[0,0,o=>o>=0],[0,n,o=>o<=n],[1,0,o=>o>=0],[1,n,o=>o<=n]];for(let[o,r,s]of i){let a=[],l=t.length/2;for(let u=0;u<l;u+=1){let c=[t[u*2],t[u*2+1]],f=[t[(u+1)%l*2],t[(u+1)%l*2+1]],d=s(c[o]),g=s(f[o]);if(d&&a.push(c[0],c[1]),d!==g){let m=(r-c[o])/(f[o]-c[o]);a.push(c[0]+(f[0]-c[0])*m,c[1]+(f[1]-c[1])*m)}}if(t=a,t.length<6)return[]}return t}function gn(e){let n=Math.sin(e*12.9898+78.233)*43758.5453;return n-Math.floor(n)}var Qn=`\nin float v_haze_depth;\nuniform vec3 u_haze_colour;\nuniform vec3 u_haze; // strength; the view depths where the haze starts and is complete\n\nfloat hazeOf() {\n return u_haze.x > 0.0 ? u_haze.x * smoothstep(u_haze.y, u_haze.z, v_haze_depth) : 0.0;\n}\n\nvec3 hazed(vec3 colour) {\n return mix(colour, u_haze_colour, hazeOf());\n}`;function qn(e){let n=(e.indices.length-e.wallsFrom)/6,t=new Uint8Array(n*16);for(let i=0;i<n;i+=1){let o=e.wallsFrom+i*6,r=e.indices[o]*pe,s=e.indices[o+1]*pe;t.set(e.vertices.subarray(r,r+4),i*16),t.set(e.vertices.subarray(s,s+4),i*16+4),t.set(e.vertices.subarray(r+4,r+8),i*16+8),t[i*16+12]=e.vertices[r+14],t[i*16+13]=e.vertices[r+27]}return t}var Kr=`#version 300 es\nprecision highp float;\nuniform highp sampler2D u_contact;\n${Qn}\nout vec4 fragColor;\nvoid main() {\n float shade = mix(texelFetch(u_contact, ivec2(gl_FragCoord.xy), 0).r, 1.0, hazeOf());\n fragColor = vec4(vec3(shade), 1.0);\n}`;function et(e){let n=e.vertices.length/pe;return{mesh:{...e.groups?{groups:e.groups}:{},wallsFrom:e.wallsFrom,top:e.top,features:e.features,vertexCount:n,indexCount:e.indices.length},data:{vertices:e.vertices,indices:n<=65536?Uint16Array.from(e.indices):e.indices,contact:qn(e)}}}function nt({data:e}){return[e.vertices.buffer,e.indices.buffer,e.contact.buffer]}function Tn(e){let n=ir(e);return n?[Math.min(1,Math.max(0,n[0]/255)),Math.min(1,Math.max(0,n[1]/255)),Math.min(1,Math.max(0,n[2]/255)),Math.min(1,Math.max(0,n[3]))]:null}function ir(e){let n=e.trim().toLowerCase(),t=/^#([\\da-f]{3,8})$/u.exec(n)?.[1];if(t&&[3,4,6,8].includes(t.length)){let _=(t.length<=4?[...t].map(F=>F+F).join(""):t).match(/../gu).map(F=>Number.parseInt(F,16));return[_[0],_[1],_[2],_.length>3?_[3]/255:1]}let i=/^(rgba?|hsla?)\\(([^)]+)\\)$/u.exec(n);if(!i)return null;let o=i[2].split(/[\\s,/]+/u).filter(Boolean);if(o.length<3||o.length>4)return null;let r=o[3]===void 0?1:en(o[3],1);if(i[1].startsWith("rgb")){let[h,_,F]=o.slice(0,3).map(k=>en(k,255));return[h,_,F,r].some(k=>k===null)?null:[h,_,F,r]}let s=Number.parseFloat(o[0]),a=en(o[1],1),l=en(o[2],1);if(!Number.isFinite(s)||a===null||l===null||r===null)return null;let u=(1-Math.abs(2*l-1))*a,c=(s%360+360)%360/60,f=u*(1-Math.abs(c%2-1)),[d,g,m]=c<1?[u,f,0]:c<2?[f,u,0]:c<3?[0,u,f]:c<4?[0,f,u]:c<5?[f,0,u]:[u,0,f],p=l-u/2;return[(d+p)*255,(g+p)*255,(m+p)*255,r]}function en(e,n){let t=e.endsWith("%"),i=Number.parseFloat(e);return Number.isFinite(i)?t?i/100*n:i:null}var fe=8192,Mn=12,sr={primary:{spacing:30,kerb:10},secondary:{spacing:32,kerb:8.5},tertiary:{spacing:34,kerb:7},minor:{spacing:36,kerb:5.5},pedestrian:{spacing:26,kerb:3}},ar={motorway:{spacing:45,kerb:14},trunk:{spacing:40,kerb:12},service:{spacing:38,kerb:4},path:{spacing:28,kerb:1.5},track:{spacing:40,kerb:2.5}},lr={spacing:30,kerb:0},ur=12,cr=18,fr=9,dr={sodium:"#ffa64d",high_pressure_sodium:"#ffa64d",low_pressure_sodium:"#ff9326",led:"#fff1db",mercury:"#e3ecff",metal_halide:"#f4f4ff",fluorescent:"#eef9ff",electric:"#ffd59a",incandescent:"#ffd59a",halogen:"#ffe3b0",gas:"#ffd28a",gaslight:"#ffd28a"},mr={orange:"#ffa64d",yellow:"#ffd27a",warm_white:"#ffe2b8",white:"#fff4e6",cool_white:"#eef4ff",neutral_white:"#fff8f0",blue:"#b8d0ff",green:"#c4ffd0",red:"#ff9a8a"},hr=new Set(["wall","wall_mounted","wall_bracket"]),pr=new Set(["suspended","cable","catenary","wire"]);function it(e,n){let t=n.estimate??"lit",i=new vn,o=new nn(cr),r=new nn(fr),s=e.streetFurniture;if(s){let m=fe/s.extent;for(let p of s.features){let h=p.properties;if(p.type!=="Point"||h.subclass!=="street_lamp")continue;let _=yr(h),F=br(h),k=Math.max(1,Math.min(4,Number(h.light_count)||1)),M=Math.min(24,Math.max(5,_*1.7*(k>1?1.15:1)));for(let B of p.geometry)for(let U=0;U+1<B.length;U+=2){let E=B[U]*m,C=B[U+1]*m;if(!rt(E,C))continue;i.write(E,C,_,M,!0,F);let I=ot(E,C,n.tileMetres);o.add(...I),r.add(...I)}}}let a=i.count;if(t==="none")return i.done(a);let l=e.transportation,u=0;if(l){let m=n.tileMetres/l.extent;for(let p of l.features)if(!(p.type!=="LineString"||!tt(p.properties,"streets")))for(let h of p.geometry)u+=gr(h,l.extent)*m}let c=u>0&&a/(u/1e3)>=ur,f=t==="streets"&&!c?"streets":"lit",d=(m,p,h,_)=>{let F=fe/m.extent,k=[];for(let N=0;N+1<p.length;N+=2)k.push(p[N]*F,p[N+1]*F);let M=n.tileMetres/fe,B=h.kerb*.45/M,U=Rn(k[0]*.013+k[1]*.029+_)*h.spacing,E=0,C=U,I=Rn(k[0]+k[1]*3.1)<.5?1:-1;for(let N=2;N<k.length;N+=2){let K=k[N-2],$=k[N-1],D=k[N],Y=k[N+1],w=Math.hypot(D-K,Y-$)*M;if(w!==0){for(;C<=E+w;){let y=(C-E)/w,b=-(Y-$)/(w/M)*I,x=(D-K)/(w/M)*I,T=K+(D-K)*y+b*B,A=$+(Y-$)*y+x*B;if(C+=h.kerb>0?h.spacing/2:h.spacing,h.kerb>0&&(I=-I),!rt(T,A))continue;let v=ot(T,A,n.tileMetres);o.near(...v)||r.near(...v)||(r.add(...v),i.write(T,A,7,15,!1))}E+=w}}};if(l)for(let m of l.features){if(m.type!=="LineString")continue;let p=tt(m.properties,f);if(p)for(let h of m.geometry)d(l,h,p,1)}let g=e.sidewalks;if(g){for(let m of g.features)if(!(m.type==="Point"||!kn(m.properties.lit)))for(let p of m.geometry)d(g,p,lr,2)}return i.done(a)}function tt(e,n){if(e.brunnel==="tunnel"||e.covered===!0)return;let t=e.lit;if(t===!1||t==="no")return;let i=String(e.class??""),o=String(e.subclass??""),r=i==="path"&&(o==="pedestrian"||o==="living_street")?"pedestrian":i,s=sr[r];if(s&&(n==="streets"||kn(t)))return s;let a=ar[r];if(a&&kn(t))return a}function kn(e){return e===!0||e==="yes"||e===1||e==="1"||e==="true"}function yr(e){let n=Number(e.height);if(Number.isFinite(n)&&n>=.5&&n<=40)return n;let t=String(e.lamp_mount??"").toLowerCase();return hr.has(t)?4.5:pr.has(t)?7.5:7}function br(e){let n=e.light_colour??e["light:colour"];if(typeof n=="string"&&n){let r=n.toLowerCase().replaceAll(" ","_"),s=Tn(mr[r]??n);if(s)return[s[0],s[1],s[2]]}let t=String(e.lamp_type??"").toLowerCase().replaceAll("-","_").replaceAll(" ","_"),i=dr[t];if(!i)return;let o=Tn(i);return[o[0],o[1],o[2]]}function rt(e,n){return e>=0&&n>=0&&e<fe&&n<fe}function ot(e,n,t){return[e/fe*t,n/fe*t]}function gr(e,n){let t=0;for(let i=2;i+1<e.length;i+=2){let o=(e[i-2]+e[i])/2,r=(e[i-1]+e[i+1])/2;o<0||r<0||o>=n||r>=n||(t+=Math.hypot(e[i]-e[i-2],e[i+1]-e[i-1]))}return t}var nn=class{constructor(n){this.size=n}size;#e=new Map;add(n,t){let i=`${Math.floor(n/this.size)}/${Math.floor(t/this.size)}`,o=this.#e.get(i);o?o.push([n,t]):this.#e.set(i,[[n,t]])}near(n,t){let i=Math.floor(n/this.size),o=Math.floor(t/this.size);for(let r=-1;r<=1;r+=1)for(let s=-1;s<=1;s+=1)for(let[a,l]of this.#e.get(`${i+r}/${o+s}`)??[])if(Math.hypot(a-n,l-t)<this.size)return!0;return!1}},vn=class{#e=new ArrayBuffer(256*Mn);#n=new DataView(this.#e);count=0;write(n,t,i,o,r,s){let a=Mn;if((this.count+1)*a>this.#e.byteLength){let c=new ArrayBuffer(this.#e.byteLength*2);new Uint8Array(c).set(new Uint8Array(this.#e)),this.#e=c,this.#n=new DataView(c)}let l=this.#n,u=this.count*a;l.setUint16(u,Math.min(fe,Math.max(0,Math.round(n))),!0),l.setUint16(u+2,Math.min(fe,Math.max(0,Math.round(t))),!0),l.setUint16(u+4,Math.min(65535,Math.round(i*10)),!0),l.setUint8(u+6,Math.min(255,Math.round(o))),l.setUint8(u+7,(r?1:0)|(s?2:0)),l.setUint8(u+8,Math.round((s?.[0]??0)*255)),l.setUint8(u+9,Math.round((s?.[1]??0)*255)),l.setUint8(u+10,Math.round((s?.[2]??0)*255)),l.setUint8(u+11,Math.round(Rn(n*.0731+t*.19137)*255)),this.count+=1}done(n){if(this.count!==0)return{lamps:new Uint8Array(this.#e.slice(0,this.count*Mn)),mapped:n,estimated:this.count-n}}};function Rn(e){let n=Math.sin(e*12.9898+78.233)*43758.5453;return n-Math.floor(n)}var oo=Object.freeze({source:"tileflow",layers:Object.freeze({streetFurniture:"street_furniture",transportation:"transportation",sidewalk:"sidewalk"}),estimate:"lit",color:"#ffcf8f",intensity:1});var Me=["round","open","tall","conifer","columnar","palm"];var ut=Object.freeze({height:"height",diameterCrown:"diameter_crown",circumference:"circumference",genus:"genus",species:"species",leafType:"leaf_type",taxon:"taxon",canopyRank:"rank",canopyClearance:"clearance_px_z15",canopyCover:"cover_pct",canopyHeight:"height_m",subclass:"subclass",hedge:"hedge"}),Sn=Object.freeze({round:1,open:1,tall:1}),tn=16,q=8192,rn=16,st={round:{height:[6,12],crown:[.66,.9]},open:{height:[5,10],crown:[.8,1.05]},tall:{height:[9,17],crown:[.48,.68]},conifer:{height:[7,16],crown:[.46,.66]},columnar:{height:[9,18],crown:[.22,.36]},palm:{height:[12,20],crown:[.42,.55]}};var on=[2,45],_n=[1,25],wr=1.2,xr=1.5,Tr=1.3,Mr=1,kr=[.3,10],vr=new Set(["acoelorrhaphe","adonidia","archontophoenix","areca","arecastrum","bismarckia","brahea","butia","caryota","chamaedorea","chamaerops","coccothrinax","cocos","dypsis","elaeis","howea","jubaea","licuala","livistona","phoenix","pritchardia","ptychosperma","rhapis","roystonea","sabal","serenoa","syagrus","thrinax","trachycarpus","veitchia","washingtonia","wodyetia"]),Rr=new Set(["cupressus","calocedrus","thuja"]),_r=new Set(["abies","araucaria","cedrus","cryptomeria","juniperus","larix","metasequoia","picea","pinus","pseudotsuga","sequoia","sequoiadendron","taxodium","taxus","tsuga"]),at=Object.freeze({...Object.fromEntries(["acacia","albizia","arbutus","bursera","ceratonia","delonix","ficus","gleditsia","jacaranda","olea","quercus","robinia","schinus","sophora","styphnolobium","tamarix"].map(e=>[e,"open"])),...Object.fromEntries(["betula","celtis","fraxinus","ginkgo","liquidambar","liriodendron","magnolia","platanus","populus","pyrus","ulmus","zelkova"].map(e=>[e,"tall"])),...Object.fromEntries(["acer","aesculus","carpinus","castanea","catalpa","cercis","citrus","fagus","lagerstroemia","malus","melia","morus","prunus","sorbus","tilia"].map(e=>[e,"round"]))});function lt(e,n={}){let t={...ut,...n},i=String(e[t.leafType]??"").toLowerCase(),o=String(e[t.taxon]??"").toLowerCase(),r=Fn(e[t.genus])??Fn(e[t.species])??(o.endsWith("aceae")?void 0:Fn(e[t.taxon]));if(i.includes("palm")||o.includes("arecaceae")||r&&vr.has(r))return"palm";if(o.includes("cupressaceae")&&!r||o.includes("pinaceae"))return"conifer";if(r&&Rr.has(r))return"columnar";if(i.includes("needle")||r&&_r.has(r))return"conifer";if(r&&at[r])return at[r];if(i.includes("broad"))return"broadleaf"}function Fn(e){return typeof e!="string"?void 0:e.trim().split(/\\s+/u)[0]?.toLowerCase()||void 0}function ct(e,n){let t={...ut,...n.fields},i=n.unknownForms??Sn,o=n.regions??[],{tile:r,tileMetres:s}=n,a=s/2**(15-r.z)/512,l=[],u=0,c=0,f=(w,y)=>{if(o.length===0)return i;let[b,x]=Ar(r,w/q,y/q);for(let T of o){let[A,v,L,O]=T.bounds;if(x>=v&&x<=O&&(A<=L?b>=A&&b<=L:b>=A||b<=L))return T.unknownForms}return i},d=(w,y,b,x)=>{let T=st[w],A=An(T.crown,ee(y,2)),v=b,L=x;return v===void 0&&L===void 0&&(v=An(T.height,ee(y,1))),v===void 0&&(v=L/A),L===void 0&&(L=v*A),{height:Te(v,on),crown:Te(L,_n)}},g=(w,y,b,x,T,A)=>{let v=ze(r.x*q+w,r.y*q+y,7),L=b===void 0?sn(f(w,y),ee(v,3)):b==="broadleaf"?sn(Fr(f(w,y)),ee(v,3)):b,O=x===void 0&&T===void 0&&A!==void 0?d(L,v,An(st[L].height,Te(A/3,[0,1]))):d(L,v,x,T);l.push({x:w,y,...O,turn:ee(v,4),shade:ee(v,5),form:Me.indexOf(L),rank:Math.floor(ee(v,6)*rn),seed:ee(v,7),canopy:0}),u+=1},m=e.trees;if(m){let w=q/m.extent;for(let y of m.features){if(y.type!=="Point")continue;let b=y.properties,x=lt(b,t),T=xe(b[t.height],on),A=xe(b[t.diameterCrown],_n),v=xe(b[t.circumference],[.1,12]);for(let L of y.geometry)for(let O=0;O+1<L.length;O+=2){let V=L[O],R=L[O+1];V<0||R<0||V>=m.extent||R>=m.extent||g(V*w,R*w,x,T,A,v)}}}let p=e.trees;if(p){let w=q/p.extent,y=(n.rowSpacing??8)/(s/p.extent);for(let b of p.features){if(b.type!=="LineString")continue;let x=b.properties,T=lt(x,t),A=xe(x[t.height],on),v=xe(x[t.diameterCrown],_n);for(let L of b.geometry){let O=y/2,V=0;for(let R=0;R+3<L.length;R+=2){let[S,z,P,Z]=[L[R],L[R+1],L[R+2],L[R+3]],j=Math.hypot(P-S,Z-z);for(;O<=V+j;){let G=j>0?(O-V)/j:0,W=S+(P-S)*G,se=z+(Z-z)*G;W>=0&&se>=0&&W<p.extent&&se<p.extent&&g(W*w,se*w,T,A,v,void 0),O+=y}V+=j}}}}let h=e.canopy;if(h){let w=q/h.extent;for(let y of h.features){if(y.type!=="Point")continue;let b=y.properties,x=Te(Math.floor(Number(b[t.canopyRank]??8)),[0,rn-1]),T=Math.max(4,Number(b[t.canopyClearance]??8))*a,A=Number(b[t.canopyCover]??30),v=A>=60?3:A>=30?2:1;for(let L of y.geometry)for(let O=0;O+1<L.length;O+=2){let V=L[O],R=L[O+1];if(V<0||R<0||V>=h.extent||R>=h.extent)continue;let S=V*w,z=R*w,P=ze(r.x*q+S,r.y*q+z,11),Z=f(S,z),j=xe(b[t.canopyHeight],on),G=Te(Math.min(T*(v===1?1.3:.95),11)*(.85+ee(P,1)*.25),[3,12]),W=Math.max(0,Math.min(G*.5,T-G/2)),se=ee(P,2)*Math.PI*2;for(let ae=0;ae<v;ae+=1){let H=ze(P,ae,13),J=se+ae*Math.PI*2/v,re=v===1?W*.3*ee(H,1):W,ne=S+Math.cos(J)*re/(s/q),te=z+Math.sin(J)*re/(s/q);if(ne<0||te<0||ne>=q||te>=q)continue;let le=sn(Z,ee(H,3)),de=G*(.85+ee(H,2)*.3),me=j===void 0?void 0:j*(.85+ee(H,6)*.25),ce=d(le,H,me,le==="palm"?void 0:de);l.push({x:ne,y:te,...ce,turn:ee(H,4),shade:ee(H,5),form:Me.indexOf(le),rank:x,seed:ee(H,7),canopy:1}),c+=1}}}}let _=[],F=e.hedges;if(F){let w=q/F.extent,y=wr/(s/F.extent);for(let b of F.features){if(b.type==="Point"||b.properties[t.subclass]!=="hedge")continue;let x=b.properties[t.hedge]==="hedge_bank"?Mr:0,T=(xe(b.properties[t.height],kr)??Tr)+x;for(let A of b.geometry){let v=y/2,L=0;for(let O=0;O+3<A.length;O+=2){let[V,R,S,z]=[A[O],A[O+1],A[O+2],A[O+3]],P=Math.hypot(S-V,z-R),Z=(Math.atan2(R-z,S-V)/(Math.PI*2)+1)%1;for(;v<=L+P;){let j=P>0?(v-L)/P:0,G=V+(S-V)*j,W=R+(z-R)*j;if(G>=0&&W>=0&&G<F.extent&&W<F.extent){let se=ze(r.x*q+G*w,r.y*q+W*w,17);_.push({x:G*w,y:W*w,height:T,turn:Z,shade:ee(se,5),seed:ee(se,7)})}v+=y}L+=P}}}}let k=w=>Te(Math.floor(n.variants?.[Me[w]]??1),[1,4]),M=w=>Math.min(k(w.form)-1,Math.floor(ee(Math.floor(w.seed*256),9)*k(w.form))),B=l.map(M),U=l.map((w,y)=>y);U.sort((w,y)=>l[w].form-l[y].form||B[w]-B[y]||l[w].rank-l[y].rank);let E=new Uint8Array(l.length*tn),C=new DataView(E.buffer),I=0,N=()=>({start:0,count:0,upTo:new Array(rn).fill(0)}),K=Object.fromEntries(Me.map((w,y)=>[w,{...N(),variants:Array.from({length:k(y)},N)}])),$=(w,y,b)=>{w.count===0&&(w.start=y),w.count+=1;for(let x=b;x<rn;x+=1)w.upTo[x]+=1};U.forEach((w,y)=>{let b=l[w],x=y*tn;C.setUint16(x,Math.min(q-1,Math.round(b.x)),!0),C.setUint16(x+2,Math.min(q-1,Math.round(b.y)),!0),C.setUint16(x+4,Math.round(b.height*10),!0),C.setUint16(x+6,Math.round(b.crown*10),!0),E[x+8]=Math.floor(b.turn*256)&255,E[x+9]=Math.floor(b.shade*256)&255,E[x+10]=b.form,E[x+11]=b.rank,E[x+12]=Math.floor(b.seed*256)&255,E[x+13]=b.canopy,E[x+14]=B[w],I=Math.max(I,b.height);let T=K[Me[b.form]];$(T,y,b.rank),$(T.variants[B[w]],y,b.rank)});let D=new Uint8Array(_.length*tn),Y=new DataView(D.buffer);return _.forEach((w,y)=>{let b=y*tn;Y.setUint16(b,Math.min(q-1,Math.round(w.x)),!0),Y.setUint16(b+2,Math.min(q-1,Math.round(w.y)),!0),Y.setUint16(b+4,Math.round(w.height*10),!0),Y.setUint16(b+6,Math.round(xr*10),!0),D[b+8]=Math.round(w.turn*256)&255,D[b+9]=Math.floor(w.shade*256)&255,D[b+12]=Math.floor(w.seed*256)&255,I=Math.max(I,w.height)}),{trees:E,forms:K,hedges:D,tallest:I,mapped:u,canopy:c}}function Fr(e){let n={round:e.round??0,open:e.open??0,tall:e.tall??0};return n.round+n.open+n.tall>0?n:Sn}function sn(e,n){let t=0;for(let o of Me)t+=Math.max(0,e[o]??0);if(t<=0)return sn(Sn,n);let i=n*t;for(let o of Me){let r=Math.max(0,e[o]??0);if(i<r)return o;i-=r}return"round"}function xe(e,n){let t=typeof e=="number"?e:typeof e=="string"?Number.parseFloat(e):NaN;return Number.isFinite(t)&&t>0?Te(t,n):void 0}function Te(e,[n,t]){return Math.min(t,Math.max(n,e))}function An([e,n],t){return e+(n-e)*t}function Ar(e,n,t){let i=2**e.z,o=(e.x+n)/i*360-180,r=Math.atan(Math.sinh(Math.PI*(1-2*(e.y+t)/i)))*180/Math.PI;return[o,r]}function ze(e,n,t){let i=(Math.imul(Math.floor(e)|0,668265261)^Math.imul(Math.floor(n)|0,374761393)^Math.imul(t,2654435761))>>>0;return i=Math.imul(i^i>>>15,2246822507)>>>0,i=Math.imul(i^i>>>13,3266489909)>>>0,(i^i>>>16)>>>0}function ee(e,n){return ze(e,n,20973)/4294967296}var Sr=[void 0,"Point","LineString","Polygon"];function ft(e,n={}){let t=n.layers?new Set(n.layers):void 0,i={},o=new Bn(e,0,e.length);for(;o.more();){let[r,s]=o.tag();if(r!==3){o.skip(s);continue}let a=o.message(),l=Lr(a,t);l&&!(l.name in i)&&(i[l.name]=l.layer)}return i}function Lr(e,n){let t,i=4096,o=[],r=[],s=[];for(;e.more();){let[a,l]=e.tag();if(a===1?t=e.string():a===2?s.push(e.message()):a===3?o.push(e.string()):a===4?r.push(Ur(e.message())):a===5?i=e.varint():e.skip(l),t!==void 0&&n&&!n.has(t))return}if(!(t===void 0||n&&!n.has(t)))return{name:t,layer:Object.freeze({extent:i,features:Object.freeze(s.flatMap(a=>{let l=Br(a,o,r);return l?[l]:[]}))})}}function Br(e,n,t){let i,o,r={},s=[];for(;e.more();){let[a,l]=e.tag();if(a===1)i=e.varint();else if(a===2){let u=e.packed();for(let c=0;c+1<u.length;c+=2){let f=n[u[c]],d=t[u[c+1]];f!==void 0&&d!==void 0&&(r[f]=d)}}else a===3?o=Sr[e.varint()]:a===4?s=e.packed():e.skip(l)}if(o)return Object.freeze({...i===void 0?{}:{id:i},type:o,properties:Object.freeze(r),geometry:Object.freeze(Or(s,o))})}function Or(e,n){let t=[],i,o=0,r=0,s=0;for(;s<e.length;){let a=e[s++],l=a&7,u=a>>>3;if(l===7){i&&i.length>=2&&i.push(i[0],i[1]);continue}if(l!==1&&l!==2)throw new Error(`Unknown geometry command ${l} in vector tile.`);if(s+u*2>e.length)throw new Error("Truncated vector tile geometry.");for(let c=0;c<u;c+=1){if(o+=Ln(e[s++]),r+=Ln(e[s++]),l===1&&(n!=="Point"||c===0)&&t.push(i=[]),!i)throw new Error("Vector tile geometry draws a line before moving to its start.");i.push(o,r)}}return t}var Ln=e=>e%2===1?-(e+1)/2:e/2;function Ur(e){let n="";for(;e.more();){let[t,i]=e.tag();t===1?n=e.string():t===2?n=e.float():t===3?n=e.double():t===4?n=e.varint(!0):t===5?n=e.varint():t===6?n=Ln(e.varint()):t===7?n=e.varint()!==0:e.skip(i)}return n}var Cr=new TextDecoder,Bn=class e{constructor(n,t,i){this.bytes=n;this.end=i;this.position=t,this.view=new DataView(n.buffer,n.byteOffset,n.byteLength)}bytes;end;position;view;more(){return this.position<this.end}tag(){let n=this.varint();return[Math.floor(n/8),n&7]}varint(n=!1){let t=0,i=0;for(let o=0;o<10;o+=1){if(this.position>=this.end)throw new Error("Truncated vector tile.");let r=this.bytes[this.position++];if(o<4?t|=(r&127)<<o*7:o===4?(t|=(r&15)<<28,i=(r&112)>>4):o<9?i|=(r&127)<<(o-5)*7+3:i|=(r&1)<<31,r<128)return n?i*4294967296+(t>>>0):(i>>>0)*4294967296+(t>>>0)}throw new Error("Invalid varint in vector tile.")}span(){let n=this.varint(),t=this.position;if(t+n>this.end)throw new Error("Truncated vector tile.");return this.position=t+n,[t,t+n]}message(){let[n,t]=this.span();return new e(this.bytes,n,t)}string(){let[n,t]=this.span();return Cr.decode(this.bytes.subarray(n,t))}packed(){let[n,t]=this.span(),i=new e(this.bytes,n,t),o=[];for(;i.more();)o.push(i.varint());return o}float(){if(this.position+4>this.end)throw new Error("Truncated vector tile.");let n=this.view.getFloat32(this.position,!0);return this.position+=4,n}double(){if(this.position+8>this.end)throw new Error("Truncated vector tile.");let n=this.view.getFloat64(this.position,!0);return this.position+=8,n}skip(n){if(n===0)this.varint();else if(n===1)this.position+=8;else if(n===2)this.span();else if(n===5)this.position+=4;else throw new Error(`Unsupported protocol buffer wire type ${n} in vector tile.`);if(this.position>this.end)throw new Error("Truncated vector tile.")}};function dt(e){return Object.values(e.layers).filter(n=>typeof n=="string")}function mt(e,n){if(e.kind==="buildings"){let r=n(e.layers.building);if(!r)return;let s=n(e.layers.places),a=Kn(r,{...e.options,...s?{places:s}:{}});return a&&et(a)}if(e.kind==="trees"){let r=n(e.layers.tree),s=n(e.layers.canopy),a=n(e.layers.hedge);if(!r&&!s&&!a)return;let l=ct({...r?{trees:r}:{},...s?{canopy:s}:{},...a?{hedges:a}:{}},e.options);return l.trees.length>0||l.hedges.length>0?l:void 0}let t=n(e.layers.streetFurniture),i=n(e.layers.transportation),o=n(e.layers.sidewalk);return it({...t?{streetFurniture:t}:{},...i?{transportation:i}:{},...o?{sidewalks:o}:{}},e.options)}function ht(e,n){if(!n)return[];if(e==="buildings")return nt(n);if(e==="trees"){let{trees:t,hedges:i}=n;return[t.buffer,i.buffer].filter((o,r,s)=>s.indexOf(o)===r)}return[n.lamps.buffer]}function pt(e=16){let n=new Map;return{read(t,i,o){let r=n.get(t);for(n.delete(t),r??={bytes:i,layers:new Map},n.set(t,r);n.size>e;)n.delete(n.keys().next().value);let s=o.filter(l=>!r.layers.has(l));if(s.length>0){let l=ft(r.bytes,{layers:s});for(let u of s)r.layers.set(u,l[u])}let a=r.layers;return l=>l===void 0?void 0:a.get(l)}}}var On=globalThis,Pr=pt();On.onmessage=({data:{url:e,bytes:n,task:t}})=>{try{let i=mt(t,Pr.read(e,n,dt(t)));On.postMessage({result:i},ht(t.kind,i))}catch(i){On.postMessage({error:String(i)})}};})();\n'], { type: "text/javascript" })
4074
4186
  );
4075
4187
  try {
4076
4188
  return new Worker(url, { name: "tileflow-tiles" });
@@ -9146,6 +9258,7 @@ function createTileflowBuildings3D(options) {
9146
9258
  const nightLight2 = mixed2((entry) => entry.nightLight);
9147
9259
  const architectural = floodLightNow();
9148
9260
  const edges = mixed2((entry) => entry.edges);
9261
+ const surfaces = design().surfaces;
9149
9262
  const { occlusion: occlusionOn, windows: windowsOn } = design();
9150
9263
  const now = performance.now();
9151
9264
  const appearing = standing.filter((entry) => appearanceOf(entry, now) < 1);
@@ -9171,6 +9284,24 @@ function createTileflowBuildings3D(options) {
9171
9284
  context.uniform1f(u.u_corner, tileflowBuildingOcclusion.corner);
9172
9285
  context.uniform1f(u.u_night, light.night);
9173
9286
  context.uniform1f(u.u_windows, windowsOn ? 1 : 0);
9287
+ context.uniform4f(
9288
+ u.u_surface_walls,
9289
+ surfaces?.walls?.size[0] ?? 6,
9290
+ surfaces?.walls?.size[1] ?? 3,
9291
+ surfaces?.walls?.jointWidth ?? 0.12,
9292
+ mixed2((entry) => entry.surfaces?.walls?.contrast ?? 0)
9293
+ );
9294
+ context.uniform3f(
9295
+ u.u_surface_roof,
9296
+ surfaces?.roof?.size ?? 8,
9297
+ surfaces?.roof?.jointWidth ?? 0.12,
9298
+ mixed2((entry) => entry.surfaces?.roof?.contrast ?? 0)
9299
+ );
9300
+ context.uniform2f(
9301
+ u.u_surface_cornice,
9302
+ surfaces?.cornice?.height ?? 0.6,
9303
+ mixed2((entry) => entry.surfaces?.cornice?.contrast ?? 0)
9304
+ );
9174
9305
  context.uniform1f(u.u_flood, light.night * nightLight2);
9175
9306
  context.uniform3fv(u.u_flood_colour, flood.colour);
9176
9307
  context.uniform1f(u.u_architectural_intensity, architectural.intensity);
@@ -9213,6 +9344,10 @@ function createTileflowBuildings3D(options) {
9213
9344
  if (!ranges.length) continue;
9214
9345
  project(context, buildings, args, x3, y2);
9215
9346
  context.uniform2f(u.u_offset, ...placed2(x3, y2).offset);
9347
+ context.uniform3f(
9348
+ u.u_surface_tile,
9349
+ ...tileflowBuildingSurfaceTile(x3, y2, camera.zoom, surfaces?.roof?.size ?? 8)
9350
+ );
9216
9351
  context.uniform4f(u.u_ring ?? null, ...ringIn(x3, y2));
9217
9352
  context.uniform2f(u.u_ring_ahead ?? null, ...ahead);
9218
9353
  const palette = themes ? paletteOf(context, entry, themes.themes) : void 0;
@@ -10209,6 +10344,14 @@ void main() {
10209
10344
  fragColor = vec4(v_light * (exp(-d * 5.0) * 1.1 + exp(-d * 1.5) * 0.25) * (1.0 - d), 0.0);
10210
10345
  }`;
10211
10346
 
10347
+ // src/cartography/label-placement.ts
10348
+ var roadLabelPlacementKey = "tileflow:road-label-placement";
10349
+ var groundRoadLabelMetadata = { [roadLabelPlacementKey]: { version: 1, mode: "ground" } };
10350
+ function isGroundRoadLabel(layer) {
10351
+ const policy = layer.metadata?.[roadLabelPlacementKey];
10352
+ return policy?.version === 1 && policy.mode === "ground";
10353
+ }
10354
+
10212
10355
  // src/trees-3d-mesh.ts
10213
10356
  var tileflowTreeVertexBytes = 24;
10214
10357
  var tileflowTreeParts = { bark: 0, leaves: 1, fronds: 2, stem: 3 };
@@ -10886,6 +11029,7 @@ var placement2 = `
10886
11029
  uniform float u_scale;
10887
11030
  uniform float u_metres; // metres per tile unit
10888
11031
  uniform vec2 u_offset; // this tile's corner from the scene's origin, in tile units
11032
+ uniform float u_minimum_height; // optional visual height floor, in metres
10889
11033
  uniform vec2 u_size_scale; // the map's height and crown scales, for this form
10890
11034
  uniform float u_round; // how far normals turn from the facets to the round shape, by finish
10891
11035
 
@@ -10901,17 +11045,20 @@ vec2 turned(vec2 v) {
10901
11045
  return vec2(v.x * c - v.y * s, v.x * s + v.y * c);
10902
11046
  }
10903
11047
 
11048
+ vec2 displaySize() {
11049
+ vec2 size = a_tree_size * 0.1 * u_size_scale;
11050
+ return size * max(1.0, u_minimum_height / max(size.x, 0.001));
11051
+ }
11052
+
10904
11053
  vec3 standing(float growth) {
10905
- float height = a_tree_size.x * 0.1 * u_size_scale.x;
10906
- float crown = a_tree_size.y * 0.1 * u_size_scale.y;
10907
- return vec3(turned(a_vertex.xy * crown), a_vertex.z * height) * growth;
11054
+ vec2 size = displaySize();
11055
+ return vec3(turned(a_vertex.xy * size.y), a_vertex.z * size.x) * growth;
10908
11056
  }
10909
11057
 
10910
11058
  vec3 normalOf() {
10911
- float height = max(a_tree_size.x * 0.1 * u_size_scale.x, 0.1);
10912
- float crown = max(a_tree_size.y * 0.1 * u_size_scale.y, 0.1);
11059
+ vec2 size = max(displaySize(), vec2(0.1));
10913
11060
  vec3 blended = normalize(mix(a_normal, a_round, u_round));
10914
- vec3 n = normalize(vec3(blended.xy / crown, blended.z / height));
11061
+ vec3 n = normalize(vec3(blended.xy / size.y, blended.z / size.x));
10915
11062
  return vec3(turned(n.xy), n.z);
10916
11063
  }
10917
11064
 
@@ -11001,6 +11148,7 @@ uniform float u_night;
11001
11148
  uniform float u_fade; // how far the layer has faded in, from 0 to 1
11002
11149
  uniform float u_toon; // 1 for light in bands, as a drawing has it
11003
11150
  uniform vec3 u_bark;
11151
+ uniform float u_material_variation;
11004
11152
  uniform vec3 u_leaves[4]; // the form's colours, sunlit
11005
11153
  uniform float u_leaf_count;
11006
11154
  out vec4 fragColor;
@@ -11011,7 +11159,7 @@ ${treeDither}
11011
11159
 
11012
11160
  vec3 leafColour() {
11013
11161
  float count = max(u_leaf_count, 1.0);
11014
- float at = v_shade * (count - 1.0);
11162
+ float at = clamp(v_shade + v_look.y * 0.45 * u_material_variation, 0.0, 1.0) * (count - 1.0);
11015
11163
  int low = int(floor(at));
11016
11164
  int high = min(low + 1, int(count) - 1);
11017
11165
  vec3 a = u_leaves[0];
@@ -11033,7 +11181,7 @@ void main() {
11033
11181
  // A palm's stem is paler than bark, ringed light and dark by its leaf scars.
11034
11182
  vec3 base = stem
11035
11183
  ? min(u_bark * 1.45 + 0.06, vec3(1.0)) * (1.0 + v_look.y * 0.12)
11036
- : bark ? u_bark : leafColour() * (1.0 + v_look.y * 0.09);
11184
+ : bark ? u_bark * (1.0 + ((v_shade - 0.5) * 0.32 + v_look.y * 0.08) * u_material_variation) : leafColour() * (1.0 + v_look.y * 0.09);
11037
11185
  float facing = dot(normal, u_sun_dir);
11038
11186
  // Leaves let light round and through them: wrapped light on the lit side, a glow against a low sun.
11039
11187
  float direct = bark ? max(facing, 0.0) : fronds ? abs(facing) * 0.85 : max((facing + 0.35) / 1.35, 0.0);
@@ -11441,6 +11589,7 @@ function createTileflowTrees3D(options) {
11441
11589
  palm: slots(theme?.colors.palm ?? ["#7fa45f"]),
11442
11590
  hedge: slots(theme?.colors.hedge ?? ["#5f8a55"]),
11443
11591
  size: [[theme?.heightScale ?? 1, theme?.crownScale ?? 1, 0]],
11592
+ materials: [[theme?.minimumHeight ?? 0, theme?.materialVariation ?? 0, 0]],
11444
11593
  forms: tileflowTreeForms.map((form) => [
11445
11594
  theme?.forms[form]?.heightScale ?? 1,
11446
11595
  theme?.forms[form]?.crownScale ?? 1,
@@ -11460,6 +11609,8 @@ function createTileflowTrees3D(options) {
11460
11609
  palm: mixList(x3.palm, y2.palm),
11461
11610
  hedge: mixList(x3.hedge, y2.hedge),
11462
11611
  size,
11612
+ minimumHeight: mixList(x3.materials, y2.materials)[0][0],
11613
+ materialVariation: mixList(x3.materials, y2.materials)[0][1],
11463
11614
  /** Each form's height and crown scale: the map's times the form's own. */
11464
11615
  sizes: Object.fromEntries(
11465
11616
  tileflowTreeForms.map((form, index) => [
@@ -11507,11 +11658,11 @@ function createTileflowTrees3D(options) {
11507
11658
  return {
11508
11659
  zoom: preferredZoom3,
11509
11660
  tiles: [left, top, right, bottom],
11510
- tallest: tallest * shown * size[0]
11661
+ tallest: Math.max(tallest * size[0], colours().minimumHeight) * shown
11511
11662
  };
11512
11663
  },
11513
11664
  // Camera-dependent density, detail and fading also change the trees casting shadows.
11514
- key: () => `trees:${map.isMoving?.() ? view().movingKey : view().key}:${fadeIn().toFixed(4)}:${visibleScale().toFixed(4)}:${generation}:${programs.depth ? 1 : 0}:${Object.values(
11665
+ key: () => `trees:${colours().minimumHeight.toFixed(3)}:${map.isMoving?.() ? view().movingKey : view().key}:${fadeIn().toFixed(4)}:${visibleScale().toFixed(4)}:${generation}:${programs.depth ? 1 : 0}:${Object.values(
11515
11666
  colours().sizes
11516
11667
  ).flat().map((value) => value.toFixed(3)).join()}:${drawn().map(({ x: x3, y: y2 }) => `${x3}/${y2}`).join(";")}`,
11517
11668
  drawDepth(context, frame) {
@@ -11523,12 +11674,14 @@ function createTileflowTrees3D(options) {
11523
11674
  context.uniform1f(u.u_metres, frame.metres);
11524
11675
  context.uniformMatrix4fv(u.u_light_matrix, false, frame.light.matrix);
11525
11676
  const sizes = colours().sizes;
11677
+ const minimumHeight = colours().minimumHeight;
11526
11678
  const camera = view();
11527
11679
  context.uniform1f(u.u_fade, 1);
11528
11680
  context.uniform2fv(u.u_reach, [...camera.reach]);
11529
11681
  for (const { x: x3, y: y2, set, value } of drawn()) {
11530
11682
  const selection = camera.tile(x3, y2);
11531
11683
  if (!selection) continue;
11684
+ context.uniform1f(u.u_minimum_height, minimumHeight);
11532
11685
  context.uniform2f(u.u_offset, ...frame.offsetOf({ x: x3, y: y2 }, set.zoom));
11533
11686
  context.uniform2f(
11534
11687
  u.u_centre,
@@ -11546,6 +11699,7 @@ function createTileflowTrees3D(options) {
11546
11699
  });
11547
11700
  const hedge = value.gl.hedge;
11548
11701
  if (hedge) {
11702
+ context.uniform1f(u.u_minimum_height, 0);
11549
11703
  context.uniform2f(u.u_size_scale, 1, 1);
11550
11704
  context.bindVertexArray(hedge.vao);
11551
11705
  context.drawArraysInstanced(
@@ -11592,6 +11746,7 @@ function createTileflowTrees3D(options) {
11592
11746
  context.uniform1f(u.u_scale, visibleScale());
11593
11747
  context.uniform1f(u.u_metres, metres);
11594
11748
  context.uniform1f(u.u_round, finishes[palette2.finish].round);
11749
+ context.uniform1f(u.u_material_variation, palette2.materialVariation);
11595
11750
  context.uniform1f(u.u_toon, palette2.finish === "toon" ? 1 : 0);
11596
11751
  context.uniform3fv(u.u_sun_dir, [...light.direction]);
11597
11752
  context.uniform3fv(u.u_shadow_dir, light.shadowDirection);
@@ -11628,21 +11783,41 @@ function createTileflowTrees3D(options) {
11628
11783
  palette2.sizes[form][0],
11629
11784
  palette2.sizes[form][1] * drawing.crown
11630
11785
  ];
11786
+ context.uniform1f(u.u_minimum_height, palette2.minimumHeight);
11631
11787
  context.uniform2f(u.u_size_scale, ...size);
11632
11788
  context.bindVertexArray(drawing.vao);
11633
11789
  context.drawArraysInstanced(context.TRIANGLES, 0, drawing.count, instances);
11634
11790
  count += instances;
11635
- draws.push({ x: x3, y: y2, offset, leaves, size, instances, drawing });
11791
+ draws.push({
11792
+ x: x3,
11793
+ y: y2,
11794
+ offset,
11795
+ leaves,
11796
+ size,
11797
+ minimumHeight: palette2.minimumHeight,
11798
+ instances,
11799
+ drawing
11800
+ });
11636
11801
  });
11637
11802
  }
11638
11803
  const hedge = value.gl.hedge;
11639
11804
  if (hedge) {
11640
11805
  const instances = value.placement.hedges.length / tileflowTreeBytes;
11641
11806
  context.uniform3fv(u.u_leaves, palette2.hedge.flat());
11807
+ context.uniform1f(u.u_minimum_height, 0);
11642
11808
  context.uniform2f(u.u_size_scale, 1, 1);
11643
11809
  context.bindVertexArray(hedge.vao);
11644
11810
  context.drawArraysInstanced(context.TRIANGLES, 0, hedge.count, instances);
11645
- draws.push({ x: x3, y: y2, offset, leaves: palette2.hedge, size: [1, 1], instances, drawing: hedge });
11811
+ draws.push({
11812
+ x: x3,
11813
+ y: y2,
11814
+ offset,
11815
+ leaves: palette2.hedge,
11816
+ size: [1, 1],
11817
+ minimumHeight: 0,
11818
+ instances,
11819
+ drawing: hedge
11820
+ });
11646
11821
  }
11647
11822
  }
11648
11823
  drawnLast = count;
@@ -11680,6 +11855,7 @@ function createTileflowTrees3D(options) {
11680
11855
  (channel) => palette2.edgeColor[channel] * own + draw2.leaves[0][channel] * 0.4 * (1 - own)
11681
11856
  )
11682
11857
  );
11858
+ context.uniform1f(e.u_minimum_height, draw2.minimumHeight);
11683
11859
  context.uniform2f(e.u_size_scale, ...draw2.size);
11684
11860
  context.bindVertexArray(draw2.drawing.vao);
11685
11861
  context.drawArraysInstanced(context.TRIANGLES, 0, draw2.drawing.count, draw2.instances);
@@ -11844,6 +12020,7 @@ ${shaderData.define}`;
11844
12020
  }
11845
12021
  const layer = {
11846
12022
  id: tileflowTrees3DLayerId,
12023
+ metadata: { "tileflow:scene-kind": "vegetation" },
11847
12024
  type: "custom",
11848
12025
  renderingMode: "3d",
11849
12026
  onAdd(_2, context) {
@@ -11934,8 +12111,14 @@ ${args.shaderData.define}`;
11934
12111
  }
11935
12112
  function beforeId() {
11936
12113
  if (options.beforeId) return map.getLayer(options.beforeId) ? options.beforeId : void 0;
11937
- if (map.getLayer(streetLightsLayerId2)) return streetLightsLayerId2;
11938
12114
  const style = map.getStyle();
12115
+ if (style?.layers?.some(isGroundRoadLabel)) {
12116
+ const boundary = style.layers.find(
12117
+ (entry) => isGroundRoadLabel(entry) || entry.type === "fill-extrusion"
12118
+ );
12119
+ if (boundary) return boundary.id;
12120
+ }
12121
+ if (map.getLayer(streetLightsLayerId2)) return streetLightsLayerId2;
11939
12122
  const anchors = style?.metadata?.["tileflow:overlay-placement-manifest"]?.anchors;
11940
12123
  const anchor = anchors?.["above-buildings"];
11941
12124
  if (typeof anchor === "string" && map.getLayer(anchor)) return anchor;