@chrtco/sdk 0.10.42 → 0.10.43

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.js CHANGED
@@ -2228,6 +2228,22 @@ var S52_NIGHT = {
2228
2228
  CHBRN: "#382410",
2229
2229
  CHGRF: "#2a2a22",
2230
2230
  CHGRD: "#1e1e18",
2231
+ // The NIGHT ink — linework, symbol outlines, navigation text, the shoal
2232
+ // soundings (SNDG2 below). Light warm on dark water: a deliberate deviation
2233
+ // from the spec's near-black (#1f2223), so a NIGHT chart is legible on a
2234
+ // screen nobody has dimmed. It is the brightest thing NIGHT draws on purpose,
2235
+ // and `night-luminance.test.ts` holds everything else under its muted level.
2236
+ //
2237
+ // ⚠ RED NIGHT DOES NOT DIM IT, AND THAT WAS DECIDED, NOT MISSED (2026-10-01).
2238
+ // Red night composes this same NIGHT chart with red chrome, as iOS does
2239
+ // (ContentView `effectiveChartTheme`). Dimming the ink for red night alone
2240
+ // would (1) drop SNDG2 out of the deeper soundings' legibility window — SNDG1
2241
+ // is pinned to 43% of this light by `sounding-legibility.test.ts` — and the
2242
+ // owner's red-night report of 2026-09-30 asked for MORE sounding legibility,
2243
+ // not less; and (2) dim the hazard outlines (OBSTRN, WRECKS) and coastline
2244
+ // that a night chart must keep. What red night was missing was everything
2245
+ // that did NOT follow this palette: labels, house marks, hatches, sector
2246
+ // bearings. Those follow it now.
2231
2247
  CHBLK: "#c8aa78",
2232
2248
  CSTLN: "#c8aa78",
2233
2249
  OUTLW: "#c8aa78",
@@ -4972,6 +4988,45 @@ var InteractClient = class {
4972
4988
  }
4973
4989
  };
4974
4990
 
4991
+ // src/atlas/palette-light.ts
4992
+ var HEX6 = /^#?([0-9a-f]{6})$/i;
4993
+ function channels(hex) {
4994
+ const m = HEX6.exec(hex);
4995
+ if (!m) throw new Error(`palette-light: "${hex}" is not a #rrggbb colour`);
4996
+ const h = m[1];
4997
+ return [0, 2, 4].map((i) => parseInt(h.slice(i, i + 2), 16));
4998
+ }
4999
+ function toLinear(c) {
5000
+ const v = c / 255;
5001
+ return v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4;
5002
+ }
5003
+ function toEncoded(v) {
5004
+ const c = v <= 31308e-7 ? v * 12.92 : 1.055 * v ** (1 / 2.4) - 0.055;
5005
+ return Math.round(Math.min(1, Math.max(0, c)) * 255);
5006
+ }
5007
+ function hex2(n) {
5008
+ return n.toString(16).padStart(2, "0");
5009
+ }
5010
+ function relativeLuminance(hex) {
5011
+ const [r, g2, b] = channels(hex).map(toLinear);
5012
+ return 0.2126 * r + 0.7152 * g2 + 0.0722 * b;
5013
+ }
5014
+ function contrastRatio(a, b) {
5015
+ const [hi, lo] = [relativeLuminance(a), relativeLuminance(b)].sort((x, y) => y - x);
5016
+ return (hi + 0.05) / (lo + 0.05);
5017
+ }
5018
+ function scaleLinearLight(hex, factor) {
5019
+ const [r, g2, b] = channels(hex).map((c) => toEncoded(toLinear(c) * factor));
5020
+ return `#${hex2(r)}${hex2(g2)}${hex2(b)}`;
5021
+ }
5022
+ function capLuminance(hex, ceiling) {
5023
+ const l = relativeLuminance(hex);
5024
+ if (l <= ceiling) return scaleLinearLight(hex, 1);
5025
+ return scaleLinearLight(hex, ceiling / l);
5026
+ }
5027
+ var NIGHT_INK = S52_NIGHT.CHBLK;
5028
+ var NIGHT_MUTED_INK = scaleLinearLight(S52_NIGHT.CHBLK, 0.43);
5029
+
4975
5030
  // src/atlas/s52-linestyles-generated.ts
4976
5031
  var S52_LINESTYLES = {
4977
5032
  ACHARE51: {
@@ -22782,14 +22837,60 @@ var NATQUA_ABBR = [
22782
22837
  // hard
22783
22838
  ];
22784
22839
  var DARK_BG = "#1a1d23";
22785
- var NAV_HALO = {
22786
- WHITE: { bright: "#ffffff", night: "#b8b0a0" },
22787
- CREAM: { bright: "#fdf0b0", night: "#a89868" },
22788
- YELLOW: { bright: "#eab308", night: "#806020" },
22789
- BLUE: { bright: "#b0c8e8", night: "#7088a0" }
22840
+ var NIGHT_MUTED = NIGHT_MUTED_INK;
22841
+ var NIGHT_KNOCKOUT = resolveColor("UIBCK", "NIGHT");
22842
+ var LABEL_TINT = {
22843
+ WATER: { day: "#9ec1d8", night: "muted" },
22844
+ // halo — lakes, rivers, canals
22845
+ WATER_DEEP: { day: "#8fb8d0", night: "muted" },
22846
+ // halo — sea areas, water place names
22847
+ LAND_REGION: { day: "#e8d8b8", night: "muted" },
22848
+ // halo — land regions, land place names
22849
+ LAND_NATURAL: { day: "#e0d8c8", night: "muted" },
22850
+ // halo — islands
22851
+ CITY: { day: "#f1e7d2", night: "muted" },
22852
+ // halo — built-up areas
22853
+ AIRPORT: { day: "#d4c9b0", night: "muted" },
22854
+ // halo — airports, landmarks, harbour facilities
22855
+ STRUCTURE: { day: "#bfa88a", night: "muted" },
22856
+ // glyph — bridges, shoreline constructions
22857
+ STRUCTURE_LIGHT: { day: "#c8c0b0", night: "muted" },
22858
+ // glyph — piles, moorings; halo — single buildings
22859
+ SOUNDING: { day: "#c8c8c8", night: "muted" },
22860
+ // halo — seabed, contour values; glyph — variation
22861
+ MAGENTA: { day: "#c545c3", night: "hue" },
22862
+ // glyph — production areas, overhead cables
22863
+ PIPELINE: { day: "#7fbf3f", night: "hue" },
22864
+ // glyph — overhead pipelines
22865
+ KELP: { day: "#3f8a34", night: "hue" },
22866
+ // halo — weed / kelp
22867
+ NAV_WHITE: { day: "#ffffff", night: "ink" },
22868
+ // halo — lateral, isolated danger, safe water
22869
+ NAV_CREAM: { day: "#fdf0b0", night: "ink" },
22870
+ // halo — cardinals, light characteristics
22871
+ NAV_YELLOW: { day: "#eab308", night: "hue" },
22872
+ // halo — special-purpose marks
22873
+ NAV_BLUE: { day: "#b0c8e8", night: "muted" }
22874
+ // halo — fog signals
22790
22875
  };
22791
- function navHalo(palette, ct) {
22792
- return ct === "NIGHT" ? NAV_HALO[palette].night : NAV_HALO[palette].bright;
22876
+ function tintFor(tint, ct) {
22877
+ const day = LABEL_TINT[tint].day;
22878
+ if (ct === "DAY") return day;
22879
+ return capLuminance(day, relativeLuminance(resolveColor("CHBLK", ct)));
22880
+ }
22881
+ function nightText(tint) {
22882
+ const role = LABEL_TINT[tint].night;
22883
+ if (role === "ink") return NIGHT_INK;
22884
+ if (role === "muted") return NIGHT_MUTED;
22885
+ return capLuminance(LABEL_TINT[tint].day, relativeLuminance(NIGHT_MUTED));
22886
+ }
22887
+ function onHalo(tint, ct) {
22888
+ if (ct === "NIGHT") return { textColor: nightText(tint), textHaloColor: NIGHT_KNOCKOUT };
22889
+ return { textColor: DARK_BG, textHaloColor: tintFor(tint, ct) };
22890
+ }
22891
+ function onKnockout(tint, ct) {
22892
+ if (ct === "NIGHT") return { textColor: nightText(tint), textHaloColor: NIGHT_KNOCKOUT };
22893
+ return { textColor: tintFor(tint, ct), textHaloColor: DARK_BG };
22793
22894
  }
22794
22895
  var NAV_AID_LABEL_TEXT_SIZE = [
22795
22896
  "interpolate",
@@ -23071,21 +23172,6 @@ function buildAirportTierExpression() {
23071
23172
  2
23072
23173
  ];
23073
23174
  }
23074
- var COLOR = {
23075
- WATER: "#9ec1d8",
23076
- WATER_DEEP: "#8fb8d0",
23077
- LAND_REGION: "#e8d8b8",
23078
- LAND_NATURAL: "#e0d8c8",
23079
- CITY: "#f1e7d2",
23080
- AIRPORT: "#d4c9b0",
23081
- STRUCTURE: "#bfa88a",
23082
- STRUCTURE_LIGHT: "#c8c0b0",
23083
- SOUNDING: "#c8c8c8",
23084
- NAV_NUMBER: "#ffffff",
23085
- NAV_CARDINAL: "#fdf0b0",
23086
- NAV_SPECIAL: "#eab308",
23087
- LIGHT: "#fdf0b0"
23088
- };
23089
23175
  var ORIENTATION_BAND_SORT_KEY = [
23090
23176
  "to-number",
23091
23177
  ["slice", ["coalesce", ["get", "_cell_id"], "??9???"], 2, 3],
@@ -23430,8 +23516,7 @@ function getLabelConfig(layerName, opts = {}) {
23430
23516
  [13, [11.5, 11.5]],
23431
23517
  [16, [10.5, 11.5]]
23432
23518
  ]),
23433
- textColor: DARK_BG,
23434
- textHaloColor: COLOR.LAND_REGION,
23519
+ ...onHalo("LAND_REGION", ct),
23435
23520
  // Land halo, not the shared taper — see LAND_HALO_WIDTH.
23436
23521
  textHaloWidth: LAND_HALO_WIDTH,
23437
23522
  textOffset: [0, 0],
@@ -23445,8 +23530,7 @@ function getLabelConfig(layerName, opts = {}) {
23445
23530
  type: "symbol",
23446
23531
  textField: buildLandmarkLabelExpression(),
23447
23532
  textSize: 9,
23448
- textColor: DARK_BG,
23449
- textHaloColor: "#d4c9b0",
23533
+ ...onHalo("AIRPORT", ct),
23450
23534
  textHaloWidth: 1.5,
23451
23535
  textOffset: [0, 0],
23452
23536
  minzoom: 9,
@@ -23466,8 +23550,7 @@ function getLabelConfig(layerName, opts = {}) {
23466
23550
  type: "symbol",
23467
23551
  textField: buildHarbourFacilityLabelExpression(),
23468
23552
  textSize: 9,
23469
- textColor: DARK_BG,
23470
- textHaloColor: "#d4c9b0",
23553
+ ...onHalo("AIRPORT", ct),
23471
23554
  textHaloWidth: 1.5,
23472
23555
  textOffset: [0, 0],
23473
23556
  minzoom: 12,
@@ -23484,8 +23567,7 @@ function getLabelConfig(layerName, opts = {}) {
23484
23567
  textField: ["coalesce", ["get", "_navAidLabel"], OBJNAM_TEXT],
23485
23568
  textSize: NAV_AID_LABEL_TEXT_SIZE,
23486
23569
  textFont: NAV_AID_LABEL_FONT,
23487
- textColor: DARK_BG,
23488
- textHaloColor: navHalo("WHITE", ct),
23570
+ ...onHalo("NAV_WHITE", ct),
23489
23571
  textHaloWidth: 1.5,
23490
23572
  textOffset: [0, 1.5],
23491
23573
  minzoom: 10,
@@ -23497,8 +23579,7 @@ function getLabelConfig(layerName, opts = {}) {
23497
23579
  textField: ["coalesce", ["get", "_navAidLabel"], OBJNAM_TEXT],
23498
23580
  textSize: NAV_AID_LABEL_TEXT_SIZE,
23499
23581
  textFont: NAV_AID_LABEL_FONT,
23500
- textColor: DARK_BG,
23501
- textHaloColor: navHalo("WHITE", ct),
23582
+ ...onHalo("NAV_WHITE", ct),
23502
23583
  textHaloWidth: 1.5,
23503
23584
  textOffset: [0, 1.5],
23504
23585
  minzoom: 10,
@@ -23511,8 +23592,7 @@ function getLabelConfig(layerName, opts = {}) {
23511
23592
  textField: ["coalesce", ["get", "_navAidLabel"], OBJNAM_TEXT],
23512
23593
  textSize: NAV_AID_LABEL_TEXT_SIZE,
23513
23594
  textFont: NAV_AID_LABEL_FONT,
23514
- textColor: DARK_BG,
23515
- textHaloColor: navHalo("CREAM", ct),
23595
+ ...onHalo("NAV_CREAM", ct),
23516
23596
  textHaloWidth: 1.5,
23517
23597
  textOffset: [0, 1.5],
23518
23598
  minzoom: 10,
@@ -23525,8 +23605,7 @@ function getLabelConfig(layerName, opts = {}) {
23525
23605
  textField: ["coalesce", ["get", "_navAidLabel"], OBJNAM_TEXT],
23526
23606
  textSize: NAV_AID_LABEL_TEXT_SIZE,
23527
23607
  textFont: NAV_AID_LABEL_FONT,
23528
- textColor: DARK_BG,
23529
- textHaloColor: navHalo("YELLOW", ct),
23608
+ ...onHalo("NAV_YELLOW", ct),
23530
23609
  textHaloWidth: 1.5,
23531
23610
  textOffset: [0, 1.5],
23532
23611
  minzoom: 10,
@@ -23539,8 +23618,7 @@ function getLabelConfig(layerName, opts = {}) {
23539
23618
  textField: ["coalesce", ["get", "_navAidLabel"], OBJNAM_TEXT],
23540
23619
  textSize: NAV_AID_LABEL_TEXT_SIZE,
23541
23620
  textFont: NAV_AID_LABEL_FONT,
23542
- textColor: DARK_BG,
23543
- textHaloColor: navHalo("WHITE", ct),
23621
+ ...onHalo("NAV_WHITE", ct),
23544
23622
  textHaloWidth: 1.5,
23545
23623
  textOffset: [0, 1.5],
23546
23624
  minzoom: 10,
@@ -23552,8 +23630,7 @@ function getLabelConfig(layerName, opts = {}) {
23552
23630
  textField: ["get", "_lightLabel"],
23553
23631
  textSize: NAV_AID_LABEL_TEXT_SIZE,
23554
23632
  textFont: NAV_AID_LABEL_FONT,
23555
- textColor: DARK_BG,
23556
- textHaloColor: navHalo("CREAM", ct),
23633
+ ...onHalo("NAV_CREAM", ct),
23557
23634
  textHaloWidth: 1.5,
23558
23635
  textOffset: [2, 0],
23559
23636
  minzoom: 9,
@@ -23577,8 +23654,7 @@ function getLabelConfig(layerName, opts = {}) {
23577
23654
  textField: catfogExpr,
23578
23655
  textSize: NAV_AID_LABEL_TEXT_SIZE,
23579
23656
  textFont: NAV_AID_LABEL_FONT,
23580
- textColor: DARK_BG,
23581
- textHaloColor: navHalo("BLUE", ct),
23657
+ ...onHalo("NAV_BLUE", ct),
23582
23658
  textHaloWidth: 1.5,
23583
23659
  textOffset: [2, 1.2],
23584
23660
  minzoom: 11,
@@ -23653,8 +23729,7 @@ function getLabelConfig(layerName, opts = {}) {
23653
23729
  [13, [0, 0, 13, 10, 11]],
23654
23730
  [16, [0, 0, 12, 11, 10]]
23655
23731
  ]),
23656
- textColor: DARK_BG,
23657
- textHaloColor: COLOR.WATER_DEEP,
23732
+ ...onHalo("WATER_DEEP", ct),
23658
23733
  textHaloWidth: ORIENTATION_HALO_WIDTH,
23659
23734
  textOffset: [0, 0],
23660
23735
  textFont: ["Open Sans Italic"],
@@ -23724,8 +23799,7 @@ function getLabelConfig(layerName, opts = {}) {
23724
23799
  [13, [10, 11]],
23725
23800
  [16, [9, 10]]
23726
23801
  ]),
23727
- textColor: DARK_BG,
23728
- textHaloColor: COLOR.WATER,
23802
+ ...onHalo("WATER", ct),
23729
23803
  textHaloWidth: ORIENTATION_HALO_WIDTH,
23730
23804
  textOffset: [0, 0],
23731
23805
  textFont: ["Open Sans Italic"],
@@ -23745,8 +23819,7 @@ function getLabelConfig(layerName, opts = {}) {
23745
23819
  [13, [10, 10]],
23746
23820
  [16, [9, 10]]
23747
23821
  ]),
23748
- textColor: DARK_BG,
23749
- textHaloColor: COLOR.WATER,
23822
+ ...onHalo("WATER", ct),
23750
23823
  textHaloWidth: ORIENTATION_HALO_WIDTH,
23751
23824
  textOffset: [0, 0],
23752
23825
  textFont: ["Open Sans Italic"],
@@ -23769,8 +23842,7 @@ function getLabelConfig(layerName, opts = {}) {
23769
23842
  16,
23770
23843
  9
23771
23844
  ],
23772
- textColor: DARK_BG,
23773
- textHaloColor: COLOR.WATER,
23845
+ ...onHalo("WATER", ct),
23774
23846
  textHaloWidth: ORIENTATION_HALO_WIDTH,
23775
23847
  textOffset: [0, 0],
23776
23848
  textFont: ["Open Sans Italic"],
@@ -23799,8 +23871,7 @@ function getLabelConfig(layerName, opts = {}) {
23799
23871
  [13, [11.5, 11.5]],
23800
23872
  [16, [10.5, 11.5]]
23801
23873
  ]),
23802
- textColor: DARK_BG,
23803
- textHaloColor: COLOR.LAND_NATURAL,
23874
+ ...onHalo("LAND_NATURAL", ct),
23804
23875
  // Land halo, not the shared taper — see LAND_HALO_WIDTH.
23805
23876
  textHaloWidth: LAND_HALO_WIDTH,
23806
23877
  textOffset: [0, 0],
@@ -23823,8 +23894,7 @@ function getLabelConfig(layerName, opts = {}) {
23823
23894
  [13, [10, 11, 12]],
23824
23895
  [16, [10, 10, 11]]
23825
23896
  ]),
23826
- textColor: DARK_BG,
23827
- textHaloColor: COLOR.CITY,
23897
+ ...onHalo("CITY", ct),
23828
23898
  textHaloWidth: ORIENTATION_HALO_WIDTH,
23829
23899
  textOffset: [0, 0],
23830
23900
  textFont: ["Open Sans Regular"],
@@ -23839,8 +23909,7 @@ function getLabelConfig(layerName, opts = {}) {
23839
23909
  type: "symbol",
23840
23910
  textField: OBJNAM_TEXT,
23841
23911
  textSize: 9,
23842
- textColor: "#bfa88a",
23843
- textHaloColor: DARK_BG,
23912
+ ...onKnockout("STRUCTURE", ct),
23844
23913
  textHaloWidth: 1.5,
23845
23914
  textOffset: [0, 0],
23846
23915
  minzoom: 12,
@@ -23858,8 +23927,7 @@ function getLabelConfig(layerName, opts = {}) {
23858
23927
  type: "symbol",
23859
23928
  textField: OBJNAM_TEXT,
23860
23929
  textSize: 8,
23861
- textColor: "#c8c0b0",
23862
- textHaloColor: DARK_BG,
23930
+ ...onKnockout("STRUCTURE_LIGHT", ct),
23863
23931
  textHaloWidth: 1.2,
23864
23932
  textOffset: [0, 1.2],
23865
23933
  minzoom: 13
@@ -23869,8 +23937,7 @@ function getLabelConfig(layerName, opts = {}) {
23869
23937
  type: "symbol",
23870
23938
  textField: OBJNAM_TEXT,
23871
23939
  textSize: 8,
23872
- textColor: "#c8c0b0",
23873
- textHaloColor: DARK_BG,
23940
+ ...onKnockout("STRUCTURE_LIGHT", ct),
23874
23941
  textHaloWidth: 1.2,
23875
23942
  textOffset: [0, 1.2],
23876
23943
  minzoom: 13
@@ -23880,8 +23947,7 @@ function getLabelConfig(layerName, opts = {}) {
23880
23947
  type: "symbol",
23881
23948
  textField: OBJNAM_TEXT,
23882
23949
  textSize: 8,
23883
- textColor: "#bfa88a",
23884
- textHaloColor: DARK_BG,
23950
+ ...onKnockout("STRUCTURE", ct),
23885
23951
  textHaloWidth: 1.2,
23886
23952
  textOffset: [0, 1],
23887
23953
  minzoom: 13,
@@ -23895,8 +23961,7 @@ function getLabelConfig(layerName, opts = {}) {
23895
23961
  type: "symbol",
23896
23962
  textField: OBJNAM_TEXT,
23897
23963
  textSize: 8,
23898
- textColor: DARK_BG,
23899
- textHaloColor: "#c8c0b0",
23964
+ ...onHalo("STRUCTURE_LIGHT", ct),
23900
23965
  textHaloWidth: 1.2,
23901
23966
  textOffset: [0, 1.2],
23902
23967
  minzoom: 14,
@@ -23917,8 +23982,7 @@ function getLabelConfig(layerName, opts = {}) {
23917
23982
  [13, [10, 10]],
23918
23983
  [16, [9, 9]]
23919
23984
  ]),
23920
- textColor: DARK_BG,
23921
- textHaloColor: COLOR.AIRPORT,
23985
+ ...onHalo("AIRPORT", ct),
23922
23986
  textHaloWidth: ORIENTATION_HALO_WIDTH,
23923
23987
  textOffset: [0, 0],
23924
23988
  textFont: ["Open Sans Regular"],
@@ -23939,8 +24003,7 @@ function getLabelConfig(layerName, opts = {}) {
23939
24003
  16,
23940
24004
  11
23941
24005
  ],
23942
- textColor: DARK_BG,
23943
- textHaloColor: COLOR.SOUNDING,
24006
+ ...onHalo("SOUNDING", ct),
23944
24007
  textHaloWidth: 1,
23945
24008
  textOffset: [0, 0],
23946
24009
  textFont: ["Open Sans Italic"],
@@ -23974,8 +24037,7 @@ function getLabelConfig(layerName, opts = {}) {
23974
24037
  14,
23975
24038
  11
23976
24039
  ],
23977
- textColor: COLOR.SOUNDING,
23978
- textHaloColor: DARK_BG,
24040
+ ...onKnockout("SOUNDING", ct),
23979
24041
  textHaloWidth: 1,
23980
24042
  textOffset: [0, 0],
23981
24043
  textFont: ["Open Sans Italic"],
@@ -24005,8 +24067,7 @@ function getLabelConfig(layerName, opts = {}) {
24005
24067
  16,
24006
24068
  8
24007
24069
  ],
24008
- textColor: "#c545c3",
24009
- textHaloColor: DARK_BG,
24070
+ ...onKnockout("MAGENTA", ct),
24010
24071
  textHaloWidth: ORIENTATION_HALO_WIDTH,
24011
24072
  textOffset: [0, 0],
24012
24073
  textFont: ["Open Sans Italic"],
@@ -24026,8 +24087,7 @@ function getLabelConfig(layerName, opts = {}) {
24026
24087
  16,
24027
24088
  11
24028
24089
  ],
24029
- textColor: DARK_BG,
24030
- textHaloColor: "#3f8a34",
24090
+ ...onHalo("KELP", ct),
24031
24091
  textHaloWidth: 1,
24032
24092
  textOffset: [0, 0],
24033
24093
  textFont: ["Open Sans Italic"],
@@ -24119,8 +24179,7 @@ function getLabelConfig(layerName, opts = {}) {
24119
24179
  17,
24120
24180
  11
24121
24181
  ],
24122
- textColor: isCBL ? "#c545c3" : "#7fbf3f",
24123
- textHaloColor: DARK_BG,
24182
+ ...onKnockout(isCBL ? "MAGENTA" : "PIPELINE", ct),
24124
24183
  textHaloWidth: 1.4,
24125
24184
  textOffset: [0, 0],
24126
24185
  textFont: ["Open Sans Regular"],
@@ -24155,8 +24214,7 @@ function getLabelConfig(layerName, opts = {}) {
24155
24214
  14,
24156
24215
  10
24157
24216
  ],
24158
- textColor: DARK_BG,
24159
- textHaloColor: "#c8c8c8",
24217
+ ...onHalo("SOUNDING", ct),
24160
24218
  textHaloWidth: 1.2,
24161
24219
  textOffset: [0, 0],
24162
24220
  textFont: ["Open Sans Regular"],
@@ -24461,9 +24519,9 @@ var PLACENAME_LAND_SIZE_STOPS = [
24461
24519
  [13, [0, 0, 10, 11, 10, 11, 10, 10, 10, 10]],
24462
24520
  [16, [0, 0, 10, 10, 9, 10, 9, 9, 9, 9]]
24463
24521
  ];
24464
- function buildPlaceNameLayers(sourceId) {
24522
+ function buildPlaceNameLayers(sourceId, ct = "DAY") {
24465
24523
  const sortKey = ["to-number", ["coalesce", ["get", "rank"], 9999999]];
24466
- const make = (idSuffix, classes, font, haloColor, letterSpacing, stops) => ({
24524
+ const make = (idSuffix, classes, font, tint, letterSpacing, stops) => ({
24467
24525
  id: `chrt-placename-${idSuffix}`,
24468
24526
  type: "symbol",
24469
24527
  source: sourceId,
@@ -24491,8 +24549,8 @@ function buildPlaceNameLayers(sourceId) {
24491
24549
  "symbol-sort-key": sortKey
24492
24550
  },
24493
24551
  paint: {
24494
- "text-color": DARK_BG,
24495
- "text-halo-color": haloColor,
24552
+ "text-color": onHalo(tint, ct).textColor,
24553
+ "text-halo-color": onHalo(tint, ct).textHaloColor,
24496
24554
  "text-halo-width": ORIENTATION_HALO_WIDTH,
24497
24555
  "text-opacity": PLACENAME_TEXT_OPACITY
24498
24556
  },
@@ -24502,8 +24560,8 @@ function buildPlaceNameLayers(sourceId) {
24502
24560
  }
24503
24561
  });
24504
24562
  return [
24505
- make("water", PLACENAME_WATER_CLASSES, ["Open Sans Italic"], COLOR.WATER_DEEP, 0.05, PLACENAME_WATER_SIZE_STOPS),
24506
- make("land", PLACENAME_LAND_CLASSES, ["Open Sans Regular"], COLOR.LAND_REGION, 0.02, PLACENAME_LAND_SIZE_STOPS)
24563
+ make("water", PLACENAME_WATER_CLASSES, ["Open Sans Italic"], "WATER_DEEP", 0.05, PLACENAME_WATER_SIZE_STOPS),
24564
+ make("land", PLACENAME_LAND_CLASSES, ["Open Sans Regular"], "LAND_REGION", 0.02, PLACENAME_LAND_SIZE_STOPS)
24507
24565
  ];
24508
24566
  }
24509
24567
  var DRGNOTE_SOURCE_LAYER = "DRGNOTE";
@@ -27227,37 +27285,58 @@ var CHRT_ATON_COLORS = {
27227
27285
  // pink (magenta-ish)
27228
27286
  };
27229
27287
  var CHRT_UNKNOWN_TINT = "#8B9298";
27230
- function chrtAtonTintExpression() {
27288
+ var HOUSE_BLACK = "#101418";
27289
+ function chrtHouseColor(dayHex, palette = "DAY") {
27290
+ if (palette === "DAY") return dayHex;
27291
+ const isBlack = dayHex.toLowerCase() === HOUSE_BLACK.toLowerCase();
27292
+ if (palette === "DUSK") {
27293
+ return isBlack ? dayHex : capLuminance(dayHex, relativeLuminance(resolveColor("CHBLK", "DUSK")));
27294
+ }
27295
+ return isBlack ? NIGHT_INK : capLuminance(dayHex, relativeLuminance(NIGHT_MUTED_INK));
27296
+ }
27297
+ function themeChrtGlyph(svg3, palette = "DAY") {
27298
+ if (palette === "DAY") return svg3;
27299
+ return svg3.replace(
27300
+ /(fill|stroke)="(#[0-9a-fA-F]{3}|#[0-9a-fA-F]{6})"/g,
27301
+ (_m, attr, hex) => {
27302
+ const six = hex.length === 4 ? `#${hex[1]}${hex[1]}${hex[2]}${hex[2]}${hex[3]}${hex[3]}` : hex;
27303
+ return `${attr}="${chrtHouseColor(six, palette)}"`;
27304
+ }
27305
+ );
27306
+ }
27307
+ function chrtAtonTintExpression(palette = "DAY") {
27308
+ const c = (code) => chrtHouseColor(CHRT_ATON_COLORS[code], palette);
27231
27309
  return colourCodeCase(
27232
27310
  [
27233
- ["3", CHRT_ATON_COLORS["3"]],
27234
- ["4", CHRT_ATON_COLORS["4"]],
27235
- ["6", CHRT_ATON_COLORS["6"]],
27236
- ["11", CHRT_ATON_COLORS["11"]],
27237
- ["9", CHRT_ATON_COLORS["9"]],
27238
- ["5", CHRT_ATON_COLORS["5"]],
27239
- ["1", CHRT_ATON_COLORS["1"]],
27240
- ["2", CHRT_ATON_COLORS["2"]],
27241
- ["8", CHRT_ATON_COLORS["8"]],
27242
- ["10", CHRT_ATON_COLORS["10"]],
27243
- ["12", CHRT_ATON_COLORS["12"]],
27244
- ["7", CHRT_ATON_COLORS["7"]]
27311
+ ["3", c("3")],
27312
+ ["4", c("4")],
27313
+ ["6", c("6")],
27314
+ ["11", c("11")],
27315
+ ["9", c("9")],
27316
+ ["5", c("5")],
27317
+ ["1", c("1")],
27318
+ ["2", c("2")],
27319
+ ["8", c("8")],
27320
+ ["10", c("10")],
27321
+ ["12", c("12")],
27322
+ ["7", c("7")]
27245
27323
  ],
27246
- CHRT_UNKNOWN_TINT
27324
+ chrtHouseColor(CHRT_UNKNOWN_TINT, palette)
27247
27325
  );
27248
27326
  }
27249
- function chrtLightTintExpression() {
27327
+ function chrtLightTintExpression(palette = "DAY") {
27328
+ const c = (code) => chrtHouseColor(CHRT_ATON_COLORS[code], palette);
27250
27329
  return colourCodeCase(
27251
27330
  [
27252
- ["3", CHRT_ATON_COLORS["3"]],
27253
- ["4", CHRT_ATON_COLORS["4"]],
27254
- ["6", CHRT_ATON_COLORS["6"]],
27255
- ["11", CHRT_ATON_COLORS["11"]],
27256
- ["9", CHRT_ATON_COLORS["9"]],
27257
- ["5", CHRT_ATON_COLORS["5"]],
27258
- ["1", CHRT_ATON_COLORS["1"]]
27331
+ ["3", c("3")],
27332
+ ["4", c("4")],
27333
+ ["6", c("6")],
27334
+ ["11", c("11")],
27335
+ ["9", c("9")],
27336
+ ["5", c("5")],
27337
+ ["1", c("1")]
27259
27338
  ],
27260
- CHRT_ATON_COLORS["1"]
27339
+ c("1")
27261
27340
  );
27262
27341
  }
27263
27342
  function scalar(attr) {
@@ -27359,7 +27438,7 @@ var TINTED_CLASSES = /* @__PURE__ */ new Set([
27359
27438
  "BCNSPP",
27360
27439
  "DAYMAR"
27361
27440
  ]);
27362
- var CHRT_HALO = { color: "#101418", width: 1 };
27441
+ var CHRT_HALO = { color: HOUSE_BLACK, width: 1 };
27363
27442
  var CHRT_LINE_DASH = {
27364
27443
  CBLSUB: { color: "CHMGD", width: 0.8, dash: [6, 3] },
27365
27444
  PIPSOL: { color: "PIPLN", width: 0.8, dash: [6, 3] }
@@ -27387,11 +27466,11 @@ function applyChrtSymbolSet(style, palette = "DAY") {
27387
27466
  layout["icon-image"] = CHRT_ICON_EXPRESSIONS[objectClass]();
27388
27467
  const paint = layer.paint ?? {};
27389
27468
  if (TINTED_CLASSES.has(objectClass)) {
27390
- paint["icon-color"] = chrtAtonTintExpression();
27469
+ paint["icon-color"] = chrtAtonTintExpression(palette);
27391
27470
  paint["icon-halo-color"] = CHRT_HALO.color;
27392
27471
  paint["icon-halo-width"] = CHRT_HALO.width;
27393
27472
  } else if (objectClass === "LIGHTS") {
27394
- paint["icon-color"] = chrtLightTintExpression();
27473
+ paint["icon-color"] = chrtLightTintExpression(palette);
27395
27474
  paint["icon-halo-color"] = CHRT_HALO.color;
27396
27475
  paint["icon-halo-width"] = CHRT_HALO.width;
27397
27476
  }
@@ -30543,7 +30622,7 @@ function generateStyle(palette = "DAY", opts = {}) {
30543
30622
  )
30544
30623
  );
30545
30624
  if (opts.labels === "placename") {
30546
- labelLayers.push(...buildPlaceNameLayers(sourceId));
30625
+ labelLayers.push(...buildPlaceNameLayers(sourceId, palette));
30547
30626
  }
30548
30627
  for (const { label } of chartLabelBundles) {
30549
30628
  if (bandFan === "collapsed") {
@@ -30633,7 +30712,7 @@ function generateStyle(palette = "DAY", opts = {}) {
30633
30712
  }
30634
30713
  }
30635
30714
  if (opts.labels === "placename") {
30636
- labelLayers.push(...buildPlaceNameLayers(sourceId));
30715
+ labelLayers.push(...buildPlaceNameLayers(sourceId, palette));
30637
30716
  } else {
30638
30717
  for (const { objectClass, label } of bundles) {
30639
30718
  if (!label) continue;
@@ -31805,6 +31884,8 @@ export {
31805
31884
  NAUTICAL_SYMBOLS,
31806
31885
  NAV_AID_LAYER_GROUPS,
31807
31886
  NAV_AID_QUERY_LAYERS,
31887
+ NIGHT_INK,
31888
+ NIGHT_MUTED_INK,
31808
31889
  NON_SOLAS_DISCLAIMER,
31809
31890
  NON_SOLAS_DISCLAIMER_SHORT,
31810
31891
  OfflineError,
@@ -31875,13 +31956,16 @@ export {
31875
31956
  buildSectorsFromFeatures,
31876
31957
  buildSources,
31877
31958
  candidateRank,
31959
+ capLuminance,
31878
31960
  cellBandCharacters,
31879
31961
  cellBandMatch,
31880
31962
  chrtAtonTintExpression,
31963
+ chrtHouseColor,
31881
31964
  chrtLightTintExpression,
31882
31965
  collectCandidates,
31883
31966
  collectClickCandidates,
31884
31967
  combineWithBandFilter,
31968
+ contrastRatio,
31885
31969
  daymarkColor,
31886
31970
  decimateFeatures,
31887
31971
  decodeAreaFeatureProps,
@@ -31953,6 +32037,7 @@ export {
31953
32037
  preprocessSoundings,
31954
32038
  preprocessWaterBodies,
31955
32039
  rasterAtonIconExpression,
32040
+ relativeLuminance,
31956
32041
  resolveColor,
31957
32042
  resolveCustomTheme,
31958
32043
  resolveRasterImage,
@@ -31962,11 +32047,13 @@ export {
31962
32047
  rhythmProperties,
31963
32048
  s101ArtworkProvenance,
31964
32049
  sanitizeCustomStyleConfig,
32050
+ scaleLinearLight,
31965
32051
  scaleSizeValue,
31966
32052
  scaminToMinZoom,
31967
32053
  sectorLimitToArcBearing,
31968
32054
  styleModeBand,
31969
32055
  terrainStackCount,
32056
+ themeChrtGlyph,
31970
32057
  tileTemplate,
31971
32058
  uncoveredSectorArcs,
31972
32059
  withinBboxFilter,