@chrtco/sdk 0.7.4 → 0.7.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -6463,30 +6463,141 @@ function buildSeabedLabelExpression() {
6463
6463
  const natsurJoined = ["slice", natsurParts, 1];
6464
6464
  return ["concat", natquaPrefix, natsurJoined];
6465
6465
  }
6466
+ function underseaFeatureNameMatch(objnam) {
6467
+ const terms = [
6468
+ "Canyon",
6469
+ "Seamount",
6470
+ "Ridge",
6471
+ "Basin",
6472
+ "Swell",
6473
+ "Knoll",
6474
+ "Shoal",
6475
+ "Ledge",
6476
+ "Bank",
6477
+ "Valley",
6478
+ "Spur",
6479
+ "Escarpment"
6480
+ ];
6481
+ return ["any", ...terms.map((t) => [">=", ["index-of", t, objnam], 0])];
6482
+ }
6483
+ var CATSEA_RELIEF_CODES = [
6484
+ 2,
6485
+ // gat
6486
+ 3,
6487
+ // bank
6488
+ 4,
6489
+ // deep
6490
+ 6,
6491
+ // trench
6492
+ 7,
6493
+ // basin
6494
+ 8,
6495
+ // mud flats
6496
+ 9,
6497
+ // reef
6498
+ 10,
6499
+ // ledge
6500
+ 11,
6501
+ // canyon
6502
+ 13,
6503
+ // shoal
6504
+ 14,
6505
+ // knoll
6506
+ 15,
6507
+ // ridge
6508
+ 16,
6509
+ // seamount
6510
+ 17,
6511
+ // pinnacle
6512
+ 18,
6513
+ // abyssal plain
6514
+ 19,
6515
+ // plateau
6516
+ 20,
6517
+ // spur
6518
+ 21,
6519
+ // shelf
6520
+ 22,
6521
+ // trough
6522
+ 23,
6523
+ // saddle
6524
+ 24,
6525
+ // abyssal hills
6526
+ 25,
6527
+ // apron
6528
+ 26,
6529
+ // archipelagic apron
6530
+ 27,
6531
+ // borderland
6532
+ 28,
6533
+ // continental margin
6534
+ 29,
6535
+ // continental rise
6536
+ 30,
6537
+ // escarpment
6538
+ 31,
6539
+ // fan
6540
+ 32,
6541
+ // fracture zone
6542
+ 33,
6543
+ // gap
6544
+ 34,
6545
+ // guyot
6546
+ 35,
6547
+ // hill
6548
+ 36,
6549
+ // hole
6550
+ 37,
6551
+ // hollow
6552
+ 39,
6553
+ // levee
6554
+ 40,
6555
+ // median valley
6556
+ 41,
6557
+ // moat
6558
+ 42,
6559
+ // mountains
6560
+ 43,
6561
+ // peak
6562
+ 44,
6563
+ // province
6564
+ 45,
6565
+ // rise
6566
+ 47,
6567
+ // seamount chain
6568
+ 48,
6569
+ // shelf-edge
6570
+ 49,
6571
+ // sill
6572
+ 50,
6573
+ // slope
6574
+ 51,
6575
+ // terrace
6576
+ 52
6577
+ // valley
6578
+ ];
6466
6579
  function buildSeaAreaTierExpression() {
6467
- const catsea = ["coalesce", ["get", "CATSEA"], ["get", "catsea"], 0];
6580
+ const catsea = ["to-number", ["coalesce", ["get", "CATSEA"], ["get", "catsea"], 0]];
6468
6581
  const objnam = ["coalesce", ["get", "OBJNAM"], ""];
6469
6582
  return [
6470
6583
  "case",
6471
- // Tier 1 — Ocean (CATSEA=31 OR OBJNAM contains "Ocean", excluding
6472
- // anchorage-area-style compound names which we filter on later).
6473
- ["==", ["to-number", catsea], 31],
6474
- 1,
6475
- ["any", ["==", ["to-number", catsea], 29], ["==", ["to-number", catsea], 30]],
6476
- 2,
6477
- [
6478
- "any",
6479
- ["==", ["to-number", catsea], 4],
6480
- ["==", ["to-number", catsea], 11],
6481
- ["==", ["to-number", catsea], 27],
6482
- ["==", ["to-number", catsea], 28]
6483
- ],
6484
- 3,
6485
- // Tier 4 — Anchorage detail (must be checked before OBJNAM-substring
6486
- // promotion so "Boston Harbor, MA …" anchorages don't bubble up).
6584
+ // Tier 4 — Anchorage detail (before all promotions so "Boston Harbor,
6585
+ // MA …" anchorage compound names don't bubble up).
6487
6586
  [">=", ["index-of", "Anchorage Area", objnam], 0],
6488
6587
  4,
6489
- // OBJNAM-substring promotion shims (run AFTER tier 4 demotion):
6588
+ // Tier 5 — undersea relief, by authoritative CATSEA code first
6589
+ // (Georges Bank=3, Georges Shoal=13, …), then by name for
6590
+ // uncategorised features. Before promotion shims; see
6591
+ // underseaFeatureNameMatch.
6592
+ ["match", catsea, CATSEA_RELIEF_CODES, true, false],
6593
+ 5,
6594
+ underseaFeatureNameMatch(objnam),
6595
+ 5,
6596
+ // Tier 3 by authoritative CATSEA: bay / narrows.
6597
+ ["match", catsea, [5, 12], true, false],
6598
+ 3,
6599
+ // OBJNAM promotion shims (CATSEA has no ocean/sea/gulf/sound/strait
6600
+ // codes, so names are the only signal for the headline tiers):
6490
6601
  [">=", ["index-of", "Atlantic Ocean", objnam], 0],
6491
6602
  1,
6492
6603
  [">=", ["index-of", "Pacific Ocean", objnam], 0],
@@ -6495,9 +6606,6 @@ function buildSeaAreaTierExpression() {
6495
6606
  1,
6496
6607
  [">=", ["index-of", "Gulf of", objnam], 0],
6497
6608
  2,
6498
- // Bay/Sound/Sea/Strait/Channel as a tier-3 shim (matches "Massachusetts
6499
- // Bay", "Buzzards Bay", "Long Island Sound", "Block Island Sound",
6500
- // "Vineyard Sound", "Cape Cod Bay", etc. without needing CATSEA).
6501
6609
  [">=", ["index-of", " Bay", objnam], 0],
6502
6610
  3,
6503
6611
  [">=", ["index-of", " Sound", objnam], 0],
@@ -6531,6 +6639,11 @@ function buildLandRegionTierExpression() {
6531
6639
  const nameLen = ["length", objnam];
6532
6640
  return [
6533
6641
  "case",
6642
+ // NOAA also encodes undersea relief names (e.g. "Block Canyon", 12
6643
+ // chars, no comma) as LNDRGN — without this demotion they'd qualify
6644
+ // as tier-1 "major region" and paint at overview zoom.
6645
+ underseaFeatureNameMatch(objnam),
6646
+ 2,
6534
6647
  ["all", ["<=", nameLen, 12], ["==", ["index-of", ",", objnam], -1]],
6535
6648
  1,
6536
6649
  2
@@ -6612,6 +6725,36 @@ function orientationLabelLayout(extras = {}) {
6612
6725
  ...extras
6613
6726
  };
6614
6727
  }
6728
+ function tieredSizeCurve(tierExpr, stops) {
6729
+ const withHolds = [];
6730
+ for (let i = 0; i < stops.length; i++) {
6731
+ if (i > 0) {
6732
+ const [pz, pv] = stops[i - 1];
6733
+ const [nz, nv] = stops[i];
6734
+ if (pv.some((v, t) => v === 0 && nv[t] > 0)) {
6735
+ const hz = Math.round((nz - 0.2) * 10) / 10;
6736
+ if (hz > pz) {
6737
+ const f = (hz - pz) / (nz - pz);
6738
+ withHolds.push([
6739
+ hz,
6740
+ pv.map(
6741
+ (v, t) => v === 0 && nv[t] > 0 ? 0 : Math.round((v + (nv[t] - v) * f) * 10) / 10
6742
+ )
6743
+ ]);
6744
+ }
6745
+ }
6746
+ }
6747
+ withHolds.push(stops[i]);
6748
+ }
6749
+ const expr = ["interpolate", ["linear"], ["zoom"]];
6750
+ for (const [z, vals] of withHolds) {
6751
+ const m = ["match", tierExpr];
6752
+ for (let t = 0; t < vals.length - 1; t++) m.push(t + 1, vals[t]);
6753
+ m.push(vals[vals.length - 1]);
6754
+ expr.push(z, m);
6755
+ }
6756
+ return expr;
6757
+ }
6615
6758
  var ORIENTATION_HALO_WIDTH = [
6616
6759
  "interpolate",
6617
6760
  ["linear"],
@@ -6741,35 +6884,23 @@ function getLabelConfig(layerName, opts = {}) {
6741
6884
  }
6742
6885
  case "LNDRGN": {
6743
6886
  const tierExpr = buildLandRegionTierExpression();
6744
- const sizeAt = (t1, t2) => [
6745
- "match",
6746
- tierExpr,
6747
- 1,
6748
- t1,
6749
- 2,
6750
- t2,
6751
- t2
6752
- ];
6753
6887
  return {
6754
6888
  type: "symbol",
6755
6889
  textField: ["get", "OBJNAM"],
6756
- textSize: [
6757
- "interpolate",
6758
- ["linear"],
6759
- ["zoom"],
6760
- 5,
6761
- sizeAt(9, 0),
6762
- 7,
6763
- sizeAt(11, 0),
6764
- 9,
6765
- sizeAt(12, 0),
6766
- 11,
6767
- sizeAt(12, 9),
6768
- 13,
6769
- sizeAt(11, 11),
6770
- 16,
6771
- sizeAt(10, 10)
6772
- ],
6890
+ // Tier-1 entry moved from z5 to z7: undersea-relief names without a
6891
+ // generic keyword ("Three Dory", "Outer Fall") can't be demoted by
6892
+ // pattern, so the overview/general bands stay clean by holding ALL
6893
+ // LNDRGN labels until coastal zoom. The Carto basemap already labels
6894
+ // major land regions at z5-z6. Columns: t1 major region, t2 local
6895
+ // point (also the default).
6896
+ textSize: tieredSizeCurve(tierExpr, [
6897
+ [5, [0, 0]],
6898
+ [7, [11, 0]],
6899
+ [9, [12, 0]],
6900
+ [11, [12, 9]],
6901
+ [13, [11, 11]],
6902
+ [16, [10, 10]]
6903
+ ]),
6773
6904
  textColor: DARK_BG,
6774
6905
  textHaloColor: COLOR.LAND_REGION,
6775
6906
  textHaloWidth: ORIENTATION_HALO_WIDTH,
@@ -6909,19 +7040,6 @@ function getLabelConfig(layerName, opts = {}) {
6909
7040
  }
6910
7041
  case "SEAARE": {
6911
7042
  const tierExpr = buildSeaAreaTierExpression();
6912
- const sizeAt = (t1, t2, t3, t4, def) => [
6913
- "match",
6914
- tierExpr,
6915
- 1,
6916
- t1,
6917
- 2,
6918
- t2,
6919
- 3,
6920
- t3,
6921
- 4,
6922
- t4,
6923
- def
6924
- ];
6925
7043
  return {
6926
7044
  type: "symbol",
6927
7045
  textField: ["get", "OBJNAM"],
@@ -6930,26 +7048,17 @@ function getLabelConfig(layerName, opts = {}) {
6930
7048
  // it floods the overview with hundreds of small italic labels that
6931
7049
  // crowd out the headline Ocean/Sea/Gulf names. It becomes visible only
6932
7050
  // at approach scale (z9) when the user has zoomed in enough that
6933
- // individual banks are useful context.
6934
- textSize: [
6935
- "interpolate",
6936
- ["linear"],
6937
- ["zoom"],
6938
- 3,
6939
- sizeAt(14, 8, 0, 0, 0),
6940
- 5,
6941
- sizeAt(16, 13, 9, 0, 0),
6942
- 7,
6943
- sizeAt(14, 14, 12, 0, 0),
6944
- 9,
6945
- sizeAt(12, 13, 14, 0, 9),
6946
- 11,
6947
- sizeAt(10, 12, 13, 0, 11),
6948
- 13,
6949
- sizeAt(9, 11, 12, 10, 11),
6950
- 16,
6951
- sizeAt(9, 10, 11, 11, 10)
6952
- ],
7051
+ // individual banks are useful context. Columns: t1 ocean, t2 sea/gulf,
7052
+ // t3 bay/sound, t4 anchorage, default.
7053
+ textSize: tieredSizeCurve(tierExpr, [
7054
+ [3, [14, 8, 0, 0, 0]],
7055
+ [5, [16, 13, 9, 0, 0]],
7056
+ [7, [14, 14, 12, 0, 0]],
7057
+ [9, [12, 13, 14, 0, 9]],
7058
+ [11, [10, 12, 13, 0, 11]],
7059
+ [13, [9, 11, 12, 10, 11]],
7060
+ [16, [9, 10, 11, 11, 10]]
7061
+ ]),
6953
7062
  textColor: DARK_BG,
6954
7063
  textHaloColor: COLOR.WATER_DEEP,
6955
7064
  textHaloWidth: ORIENTATION_HALO_WIDTH,
@@ -6958,39 +7067,38 @@ function getLabelConfig(layerName, opts = {}) {
6958
7067
  minzoom: 5,
6959
7068
  layout: orientationLabelLayout({
6960
7069
  "text-letter-spacing": 0.15,
6961
- "text-max-width": 9
7070
+ "text-max-width": 9,
7071
+ // SEAARE is always-paint, unlike the other orientation classes.
7072
+ // MapLibre places symbols topmost-layer-first, so with
7073
+ // allow-overlap:false the dense sounding field (drawn above)
7074
+ // collision-starves big-water names — observed on staging at z8:
7075
+ // only 2 SEAARE labels survived viewport-wide, with Cape Cod Bay
7076
+ // and Gulf of Maine dropped entirely. Always-paint is safe for
7077
+ // this class because (a) the dominance composition in
7078
+ // fanOrientationLabelByCellBand suppresses cross-band duplicate
7079
+ // copies, and (b) tier sizing zeroes relief/anchorage names at
7080
+ // the zooms where density is a problem. Rivers/lakes/land keep
7081
+ // collision-dedup — their within-band multi-polygon stacking was
7082
+ // the original complaint, and they lack big-water headline value.
7083
+ "text-allow-overlap": true,
7084
+ "text-ignore-placement": true,
7085
+ "text-optional": false,
7086
+ "text-padding": 2
6962
7087
  })
6963
7088
  };
6964
7089
  }
6965
7090
  case "LAKARE": {
6966
7091
  const tierExpr = buildLakeTierExpression();
6967
- const sizeAt = (t1, t2) => [
6968
- "match",
6969
- tierExpr,
6970
- 1,
6971
- t1,
6972
- 2,
6973
- t2,
6974
- t2
6975
- ];
6976
7092
  return {
6977
7093
  type: "symbol",
6978
7094
  textField: ["get", "OBJNAM"],
6979
- textSize: [
6980
- "interpolate",
6981
- ["linear"],
6982
- ["zoom"],
6983
- 7,
6984
- sizeAt(9, 0),
6985
- 9,
6986
- sizeAt(11, 0),
6987
- 11,
6988
- sizeAt(11, 9),
6989
- 13,
6990
- sizeAt(10, 11),
6991
- 16,
6992
- sizeAt(9, 10)
6993
- ],
7095
+ textSize: tieredSizeCurve(tierExpr, [
7096
+ [7, [9, 0]],
7097
+ [9, [11, 0]],
7098
+ [11, [11, 9]],
7099
+ [13, [10, 11]],
7100
+ [16, [9, 10]]
7101
+ ]),
6994
7102
  textColor: DARK_BG,
6995
7103
  textHaloColor: COLOR.WATER,
6996
7104
  textHaloWidth: ORIENTATION_HALO_WIDTH,
@@ -7002,33 +7110,16 @@ function getLabelConfig(layerName, opts = {}) {
7002
7110
  }
7003
7111
  case "RIVERS": {
7004
7112
  const tierExpr = buildRiverTierExpression();
7005
- const sizeAt = (t1, t2) => [
7006
- "match",
7007
- tierExpr,
7008
- 1,
7009
- t1,
7010
- 2,
7011
- t2,
7012
- t2
7013
- ];
7014
7113
  return {
7015
7114
  type: "symbol",
7016
7115
  textField: ["get", "OBJNAM"],
7017
- textSize: [
7018
- "interpolate",
7019
- ["linear"],
7020
- ["zoom"],
7021
- 7,
7022
- sizeAt(9, 0),
7023
- 9,
7024
- sizeAt(11, 0),
7025
- 11,
7026
- sizeAt(11, 9),
7027
- 13,
7028
- sizeAt(10, 10),
7029
- 16,
7030
- sizeAt(9, 10)
7031
- ],
7116
+ textSize: tieredSizeCurve(tierExpr, [
7117
+ [7, [9, 0]],
7118
+ [9, [11, 0]],
7119
+ [11, [11, 9]],
7120
+ [13, [10, 10]],
7121
+ [16, [9, 10]]
7122
+ ]),
7032
7123
  textColor: DARK_BG,
7033
7124
  textHaloColor: COLOR.WATER,
7034
7125
  textHaloWidth: ORIENTATION_HALO_WIDTH,
@@ -7063,35 +7154,17 @@ function getLabelConfig(layerName, opts = {}) {
7063
7154
  };
7064
7155
  case "LNDARE": {
7065
7156
  const tierExpr = buildLandAreaTierExpression();
7066
- const sizeAt = (t1, t2) => [
7067
- "match",
7068
- tierExpr,
7069
- 1,
7070
- t1,
7071
- 2,
7072
- t2,
7073
- t2
7074
- ];
7075
7157
  return {
7076
7158
  type: "symbol",
7077
7159
  textField: ["get", "OBJNAM"],
7078
- textSize: [
7079
- "interpolate",
7080
- ["linear"],
7081
- ["zoom"],
7082
- 5,
7083
- sizeAt(8, 0),
7084
- 7,
7085
- sizeAt(10, 0),
7086
- 9,
7087
- sizeAt(11, 0),
7088
- 11,
7089
- sizeAt(11, 9),
7090
- 13,
7091
- sizeAt(10, 10),
7092
- 16,
7093
- sizeAt(9, 10)
7094
- ],
7160
+ textSize: tieredSizeCurve(tierExpr, [
7161
+ [5, [8, 0]],
7162
+ [7, [10, 0]],
7163
+ [9, [11, 0]],
7164
+ [11, [11, 9]],
7165
+ [13, [10, 10]],
7166
+ [16, [9, 10]]
7167
+ ]),
7095
7168
  textColor: DARK_BG,
7096
7169
  textHaloColor: COLOR.LAND_NATURAL,
7097
7170
  textHaloWidth: ORIENTATION_HALO_WIDTH,
@@ -7103,39 +7176,18 @@ function getLabelConfig(layerName, opts = {}) {
7103
7176
  }
7104
7177
  case "BUAARE": {
7105
7178
  const tierExpr = buildBuiltUpAreaTierExpression();
7106
- const sizeAt = (t1, t2, t3) => [
7107
- "match",
7108
- tierExpr,
7109
- 1,
7110
- t1,
7111
- 2,
7112
- t2,
7113
- 3,
7114
- t3,
7115
- t3
7116
- ];
7117
7179
  return {
7118
7180
  type: "symbol",
7119
7181
  textField: ["get", "OBJNAM"],
7120
- textSize: [
7121
- "interpolate",
7122
- ["linear"],
7123
- ["zoom"],
7124
- 3,
7125
- sizeAt(11, 0, 0),
7126
- 5,
7127
- sizeAt(13, 0, 0),
7128
- 7,
7129
- sizeAt(13, 9, 0),
7130
- 9,
7131
- sizeAt(12, 12, 0),
7132
- 11,
7133
- sizeAt(11, 12, 10),
7134
- 13,
7135
- sizeAt(10, 11, 12),
7136
- 16,
7137
- sizeAt(10, 10, 11)
7138
- ],
7182
+ textSize: tieredSizeCurve(tierExpr, [
7183
+ [3, [11, 0, 0]],
7184
+ [5, [13, 0, 0]],
7185
+ [7, [13, 9, 0]],
7186
+ [9, [12, 12, 0]],
7187
+ [11, [11, 12, 10]],
7188
+ [13, [10, 11, 12]],
7189
+ [16, [10, 10, 11]]
7190
+ ]),
7139
7191
  textColor: DARK_BG,
7140
7192
  textHaloColor: COLOR.CITY,
7141
7193
  textHaloWidth: ORIENTATION_HALO_WIDTH,
@@ -7216,33 +7268,16 @@ function getLabelConfig(layerName, opts = {}) {
7216
7268
  };
7217
7269
  case "AIRARE": {
7218
7270
  const tierExpr = buildAirportTierExpression();
7219
- const sizeAt = (t1, t2) => [
7220
- "match",
7221
- tierExpr,
7222
- 1,
7223
- t1,
7224
- 2,
7225
- t2,
7226
- t2
7227
- ];
7228
7271
  return {
7229
7272
  type: "symbol",
7230
7273
  textField: ["get", "OBJNAM"],
7231
- textSize: [
7232
- "interpolate",
7233
- ["linear"],
7234
- ["zoom"],
7235
- 7,
7236
- sizeAt(9, 0),
7237
- 9,
7238
- sizeAt(11, 0),
7239
- 11,
7240
- sizeAt(11, 9),
7241
- 13,
7242
- sizeAt(10, 10),
7243
- 16,
7244
- sizeAt(9, 9)
7245
- ],
7274
+ textSize: tieredSizeCurve(tierExpr, [
7275
+ [7, [9, 0]],
7276
+ [9, [11, 0]],
7277
+ [11, [11, 9]],
7278
+ [13, [10, 10]],
7279
+ [16, [9, 9]]
7280
+ ]),
7246
7281
  textColor: DARK_BG,
7247
7282
  textHaloColor: COLOR.AIRPORT,
7248
7283
  textHaloWidth: ORIENTATION_HALO_WIDTH,
@@ -10514,7 +10549,10 @@ function buildLayersForClass(objectClass, ct, sourceId = DEFAULT_REGION) {
10514
10549
  }
10515
10550
  if (objectClass === "TUNNEL" && resolved.type === "line") {
10516
10551
  layers.push({
10517
- id: `s52-TUNNEL-line`,
10552
+ // NOT `s52-TUNNEL-line` — that id is already taken by the main layer
10553
+ // (`s52-${objectClass}-${resolved.type}`), and duplicate layer ids
10554
+ // are a Mapbox style-spec violation (caught by style-integrity.test).
10555
+ id: `s52-TUNNEL-linestring`,
10518
10556
  type: "line",
10519
10557
  source: sourceId,
10520
10558
  "source-layer": "TUNNEL",
@@ -10888,24 +10926,37 @@ function fanOrientationLabelByCellBand(label) {
10888
10926
  const curve = CELL_BAND_OPACITY_CURVE[code];
10889
10927
  const opacityExpr = ["interpolate", ["linear"], ["zoom"]];
10890
10928
  for (const [z, o] of curve) opacityExpr.push(z, o);
10891
- const variant = {
10892
- ...label,
10893
- id: `${label.id}-cell${code}`,
10894
- filter: combineWithBandFilter(
10895
- label.filter,
10896
- ["==", cellBandExpr, code]
10897
- ),
10898
- minzoom: Math.max(
10899
- label.minzoom ?? range.minzoom,
10900
- range.minzoom
10901
- ),
10902
- paint: {
10903
- ...label.paint ?? {},
10904
- "text-opacity": opacityExpr
10905
- }
10929
+ const cellFiltered = combineWithBandFilter(
10930
+ label.filter,
10931
+ ["==", cellBandExpr, code]
10932
+ );
10933
+ const minzoom = Math.max(
10934
+ label.minzoom ?? range.minzoom,
10935
+ range.minzoom
10936
+ );
10937
+ const paint = {
10938
+ ...label.paint ?? {},
10939
+ "text-opacity": opacityExpr
10906
10940
  };
10907
- delete variant.maxzoom;
10908
- variants.push(variant);
10941
+ variants.push({
10942
+ ...label,
10943
+ id: `${label.id}-cell${code}-notdom`,
10944
+ filter: combineWithBandFilter(cellFiltered, NOT_DOMINATED_FILTER),
10945
+ minzoom,
10946
+ paint
10947
+ });
10948
+ for (const D of BAND_DRAW_ORDER) {
10949
+ const dom = BAND_PRIORITY_RANGES[D];
10950
+ if (dom.minzoom <= minzoom) continue;
10951
+ variants.push({
10952
+ ...label,
10953
+ id: `${label.id}-cell${code}-domBy${D}`,
10954
+ filter: combineWithBandFilter(cellFiltered, dominatedByMinFilter(D)),
10955
+ minzoom,
10956
+ maxzoom: dom.minzoom,
10957
+ paint
10958
+ });
10959
+ }
10909
10960
  }
10910
10961
  return variants;
10911
10962
  }