@chrtco/sdk 0.10.47 → 0.10.48

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
@@ -44,6 +44,12 @@ __export(index_exports, {
44
44
  CHART_BAND_CODES: () => CHART_BAND_CODES,
45
45
  CHART_CASCADE_CODES: () => CHART_CASCADE_CODES,
46
46
  CHART_SECTIONS: () => CHART_SECTIONS,
47
+ CHART_SOUNDINGS_RULE: () => CHART_SOUNDINGS_RULE,
48
+ CHART_SYMBOL_SCALE: () => CHART_SYMBOL_SCALE,
49
+ CHART_SYMBOL_SIZES: () => CHART_SYMBOL_SIZES,
50
+ CHART_SYMBOL_SIZE_LABELS: () => CHART_SYMBOL_SIZE_LABELS,
51
+ CHART_SYMBOL_SIZE_REACH: () => CHART_SYMBOL_SIZE_REACH,
52
+ CHART_SYMBOL_SIZE_WIRE: () => CHART_SYMBOL_SIZE_WIRE,
47
53
  CHRTRASTER_REF_CROPS: () => CHRTRASTER_REF_CROPS,
48
54
  CHRTRASTER_SVGS: () => CHRTRASTER_SVGS,
49
55
  CHRT_ATON_COLORS: () => CHRT_ATON_COLORS,
@@ -57,7 +63,6 @@ __export(index_exports, {
57
63
  ChrtError: () => ChrtError,
58
64
  DEFAULT_CLICK_TOLERANCE: () => DEFAULT_CLICK_TOLERANCE,
59
65
  DEFAULT_CUSTOM_STYLE_CONFIG: () => DEFAULT_CUSTOM_STYLE_CONFIG,
60
- DEFAULT_DEPTH_LABEL_SIZE: () => DEFAULT_DEPTH_LABEL_SIZE,
61
66
  DEFAULT_INSPECT_CLASS_RANK: () => DEFAULT_INSPECT_CLASS_RANK,
62
67
  DEFAULT_LABEL_SETTINGS: () => DEFAULT_LABEL_SETTINGS,
63
68
  DEFAULT_NAV_AID_SETTINGS: () => DEFAULT_NAV_AID_SETTINGS,
@@ -69,14 +74,14 @@ __export(index_exports, {
69
74
  DEFAULT_WATER_BODY_SETTINGS: () => DEFAULT_WATER_BODY_SETTINGS,
70
75
  DEPARE_FILL_BRANCH_TOKENS: () => DEPARE_FILL_BRANCH_TOKENS,
71
76
  DEPARE_FILL_FALLBACK_TOKEN: () => DEPARE_FILL_FALLBACK_TOKEN,
72
- DEPTH_LABEL_CLASSES: () => DEPTH_LABEL_CLASSES,
73
- DEPTH_LABEL_SIZES: () => DEPTH_LABEL_SIZES,
77
+ DEPTH_FIGURE_CLASSES: () => DEPTH_FIGURE_CLASSES,
74
78
  DRAPEABLE_LAYER_TYPES: () => DRAPEABLE_LAYER_TYPES,
75
79
  EINK_COLOR_TABLES: () => EINK_COLOR_TABLES,
76
80
  EINK_DANGER_PATTERN: () => EINK_DANGER_PATTERN,
77
81
  EINK_DOTS_PATTERN: () => EINK_DOTS_PATTERN,
78
82
  EINK_HATCH_PATTERN: () => EINK_HATCH_PATTERN,
79
83
  EINK_MONO_GREYS: () => EINK_MONO_GREYS,
84
+ HAZARD_LABEL_PRIORITY: () => HAZARD_LABEL_PRIORITY,
80
85
  INSPECT_CLASS_RANK: () => INSPECT_CLASS_RANK,
81
86
  INSPECT_RANK_DEVIATIONS: () => INSPECT_RANK_DEVIATIONS,
82
87
  InteractClient: () => InteractClient,
@@ -92,7 +97,8 @@ __export(index_exports, {
92
97
  LAND_ATTRIBUTION: () => LAND_ATTRIBUTION,
93
98
  LAND_BUILD_MAXZOOM: () => LAND_BUILD_MAXZOOM,
94
99
  LAND_REGION: () => LAND_REGION,
95
- LARGE_SOUNDING_PADDING_PX: () => LARGE_SOUNDING_PADDING_PX,
100
+ LAND_TEXT_CLASSES: () => LAND_TEXT_CLASSES,
101
+ MAPLIBRE_DEFAULT_TEXT_PADDING_PX: () => MAPLIBRE_DEFAULT_TEXT_PADDING_PX,
96
102
  NAUTICAL_SYMBOLS: () => NAUTICAL_SYMBOLS,
97
103
  NAV_AID_LAYER_GROUPS: () => NAV_AID_LAYER_GROUPS,
98
104
  NAV_AID_QUERY_LAYERS: () => NAV_AID_QUERY_LAYERS,
@@ -101,6 +107,7 @@ __export(index_exports, {
101
107
  NON_SOLAS_DISCLAIMER: () => NON_SOLAS_DISCLAIMER,
102
108
  NON_SOLAS_DISCLAIMER_SHORT: () => NON_SOLAS_DISCLAIMER_SHORT,
103
109
  OPAQUE_SPLIT_OF: () => OPAQUE_SPLIT_OF,
110
+ OUTRANK_LABELS: () => OUTRANK_LABELS,
104
111
  OfflineError: () => OfflineError,
105
112
  OfflineStyleError: () => OfflineStyleError,
106
113
  PLACENAME_LAND_CLASSES: () => PLACENAME_LAND_CLASSES,
@@ -135,9 +142,14 @@ __export(index_exports, {
135
142
  S52_LOOKUP: () => S52_LOOKUP,
136
143
  S52_NIGHT: () => S52_NIGHT,
137
144
  S52_PATTERN_SPRITE_PREFIX: () => S52_PATTERN_SPRITE_PREFIX,
145
+ SERVED_FONT_STACKS: () => SERVED_FONT_STACKS,
146
+ SERVED_SOUNDING_PADDING_PX: () => SERVED_SOUNDING_PADDING_PX,
138
147
  SIGPER_TOLERANCE_SECONDS: () => SIGPER_TOLERANCE_SECONDS,
139
148
  SIGSEQ_MAX_TERMS: () => SIGSEQ_MAX_TERMS,
140
149
  SOUNDING_LAYERS: () => SOUNDING_LAYERS,
150
+ SOUNDING_PADDING_PER_FACTOR: () => SOUNDING_PADDING_PER_FACTOR,
151
+ STANDARD_CHART_SYMBOL_SCALES: () => STANDARD_CHART_SYMBOL_SCALES,
152
+ SYMBOL_ANNOTATION_TEXT_CLASSES: () => SYMBOL_ANNOTATION_TEXT_CLASSES,
141
153
  SYMBOL_FAMILIES: () => SYMBOL_FAMILIES,
142
154
  SYMBOL_FAMILY_META: () => SYMBOL_FAMILY_META,
143
155
  SYMBOL_GROUPS: () => SYMBOL_GROUPS,
@@ -145,12 +157,14 @@ __export(index_exports, {
145
157
  TileAuth: () => TileAuth,
146
158
  TileTokenError: () => TileTokenError,
147
159
  WATER_BODY_LAYER_GROUPS: () => WATER_BODY_LAYER_GROUPS,
160
+ WATER_TEXT_CLASSES: () => WATER_TEXT_CLASSES,
148
161
  WeatherEndpoint: () => WeatherEndpoint,
149
162
  applyBaseBundle: () => applyBaseBundle,
163
+ applyChartSymbolScales: () => applyChartSymbolScales,
164
+ applyChartSymbolScalesToLayer: () => applyChartSymbolScalesToLayer,
150
165
  applyChrtSymbolSet: () => applyChrtSymbolSet,
151
166
  applyColorTheme: () => applyColorTheme,
152
167
  applyCustomStyleSettings: () => applyCustomStyleSettings,
153
- applyDepthLabelSize: () => applyDepthLabelSize,
154
168
  applyEinkPortrayal: () => applyEinkPortrayal,
155
169
  applyRasterSymbolSet: () => applyRasterSymbolSet,
156
170
  applyS101SymbolSet: () => applyS101SymbolSet,
@@ -177,19 +191,24 @@ __export(index_exports, {
177
191
  capLuminance: () => capLuminance,
178
192
  cellBandCharacters: () => cellBandCharacters,
179
193
  cellBandMatch: () => cellBandMatch,
194
+ chartSymbolSizingCensus: () => chartSymbolSizingCensus,
180
195
  chrtAtonTintExpression: () => chrtAtonTintExpression,
181
196
  chrtHouseColor: () => chrtHouseColor,
182
197
  chrtLightTintExpression: () => chrtLightTintExpression,
198
+ clampChartSymbolScale: () => clampChartSymbolScale,
183
199
  collectCandidates: () => collectCandidates,
184
200
  collectClickCandidates: () => collectClickCandidates,
185
201
  combineWithBandFilter: () => combineWithBandFilter,
202
+ contourValueFactor: () => contourValueFactor,
186
203
  contrastRatio: () => contrastRatio,
187
204
  daymarkColor: () => daymarkColor,
188
205
  decimateFeatures: () => decimateFeatures,
189
206
  decodeAreaFeatureProps: () => decodeAreaFeatureProps,
190
207
  decodeBridgeProps: () => decodeBridgeProps,
191
208
  decodeCandidate: () => decodeCandidate,
209
+ decodeChartSymbolScale: () => decodeChartSymbolScale,
192
210
  decodeNavAidProps: () => decodeNavAidProps,
211
+ demotedBelowSoundings: () => demotedBelowSoundings,
193
212
  depareColor: () => depareColor,
194
213
  depareFillExpression: () => depareFillExpression,
195
214
  depthAreaClassLayerId: () => depthAreaClassLayerId,
@@ -199,6 +218,7 @@ __export(index_exports, {
199
218
  drapedFirst: () => drapedFirst,
200
219
  extractNavAidDesignation: () => extractNavAidDesignation,
201
220
  featureIdentity: () => featureIdentity,
221
+ fromZoom: () => fromZoom,
202
222
  generateCustomStyle: () => generateCustomStyle,
203
223
  generateSpriteManifest: () => generateSpriteManifest,
204
224
  generateSpriteSheet: () => generateSpriteSheet,
@@ -226,9 +246,11 @@ __export(index_exports, {
226
246
  getThemedS101Svg: () => getThemedS101Svg,
227
247
  getThemedS52Svg: () => getThemedS52Svg,
228
248
  getTopmarkMeaning: () => getTopmarkMeaning,
249
+ haloFactor: () => haloFactor,
229
250
  hazardColor: () => hazardColor,
230
251
  hazardFillExpression: () => hazardFillExpression,
231
252
  iconExpressionForFamily: () => iconExpressionForFamily,
253
+ iconSliderFor: () => iconSliderFor,
232
254
  isDepthAreaClassLayerId: () => isDepthAreaClassLayerId,
233
255
  isDrapeable: () => isDrapeable,
234
256
  isEinkColorTable: () => isEinkColorTable,
@@ -240,6 +262,7 @@ __export(index_exports, {
240
262
  isSoundingLayerVisible: () => isSoundingLayerVisible,
241
263
  isVisibleInMode: () => isVisibleInMode,
242
264
  isWaterBodyLayerVisible: () => isWaterBodyLayerVisible,
265
+ keptAboveSoundings: () => keptAboveSoundings,
243
266
  labelSortKey: () => labelSortKey,
244
267
  lampRhythmColour: () => lampRhythmColour,
245
268
  lampRhythmOpacity: () => lampRhythmOpacity,
@@ -252,7 +275,6 @@ __export(index_exports, {
252
275
  normalizeTheme: () => normalizeTheme,
253
276
  opaqueSplitBaseOf: () => opaqueSplitBaseOf,
254
277
  paginate: () => paginate,
255
- parseDepthLabelSize: () => parseDepthLabelSize,
256
278
  parseListCodes: () => parseListCodes,
257
279
  parseSigseqTerms: () => parseSigseqTerms,
258
280
  parseSymbolFamily: () => parseSymbolFamily,
@@ -275,12 +297,19 @@ __export(index_exports, {
275
297
  safetyContourValues: () => safetyContourValues,
276
298
  sanitizeCustomStyleConfig: () => sanitizeCustomStyleConfig,
277
299
  scaleLinearLight: () => scaleLinearLight,
300
+ scaleSizeExpression: () => scaleSizeExpression,
278
301
  scaleSizeValue: () => scaleSizeValue,
279
302
  scaminToMinZoom: () => scaminToMinZoom,
280
303
  sectorLimitToArcBearing: () => sectorLimitToArcBearing,
304
+ semiboldFontStack: () => semiboldFontStack,
305
+ snapChartSymbolScale: () => snapChartSymbolScale,
306
+ soundingPadding: () => soundingPadding,
307
+ soundingPaddingValue: () => soundingPaddingValue,
281
308
  splitOpaqueDepthAreas: () => splitOpaqueDepthAreas,
309
+ stepChartSymbolScale: () => stepChartSymbolScale,
282
310
  styleModeBand: () => styleModeBand,
283
311
  terrainStackCount: () => terrainStackCount,
312
+ textSliderFor: () => textSliderFor,
284
313
  themeChrtGlyph: () => themeChrtGlyph,
285
314
  tileTemplate: () => tileTemplate,
286
315
  uncoveredSectorArcs: () => uncoveredSectorArcs,
@@ -25683,7 +25712,23 @@ function getLabelConfig(layerName, opts = {}) {
25683
25712
  "text-variable-anchor": ["top-left", "bottom-left", "top-right", "bottom-right"],
25684
25713
  "text-radial-offset": 0.9,
25685
25714
  "text-justify": "auto",
25686
- "text-allow-overlap": false,
25715
+ // ⚠ A DANGER DEPTH IS NEVER DROPPED (owner, 2026-10-06). Before,
25716
+ // a callout with no free corner was culled and the rock, wreck or
25717
+ // obstruction drew with no depth beside it: 15 of 136 at Boston
25718
+ // z12.3. ALLOW-OVERLAP ONLY, and that is the whole point:
25719
+ // - the variable anchors still fan out first — MapLibre 5.24
25720
+ // tries every corner without overlap and overlaps, at the
25721
+ // first corner, only when none is free (`placement.ts`,
25722
+ // `placementPasses`), so only the callouts that used to vanish
25723
+ // draw over something;
25724
+ // - `text-ignore-placement` stays false, so a callout keeps its
25725
+ // collision space and blocks what it blocked before. Ignoring
25726
+ // placement as well freed that space for buoy and place names,
25727
+ // which then pushed shallow soundings off: 11 shoals uncovered
25728
+ // at z12.3 on the bench. This form: 0.
25729
+ // The census and its numbers: `scripts/chart-bench/
25730
+ // danger-depth-census.ts` and `.chrt/standards/s-52.md` §8a.
25731
+ "text-allow-overlap": true,
25687
25732
  "text-optional": true,
25688
25733
  "text-padding": 2,
25689
25734
  "symbol-sort-key": labelSortKey(100, ["*", 10, valsou])
@@ -28969,65 +29014,364 @@ function iconExpressionForFamily(objectClass2, family) {
28969
29014
  }
28970
29015
  }
28971
29016
 
28972
- // src/atlas/depth-label-size.ts
28973
- var DEPTH_LABEL_SIZES = ["standard", "large"];
28974
- var DEFAULT_DEPTH_LABEL_SIZE = "standard";
28975
- function parseDepthLabelSize(raw) {
28976
- if (!raw) return null;
28977
- const lower = raw.toLowerCase();
28978
- return DEPTH_LABEL_SIZES.find((s) => s === lower) ?? null;
28979
- }
28980
- var DEPTH_LABEL_CLASSES = /* @__PURE__ */ new Set([
28981
- "SOUNDG",
28982
- "DEPCNT",
28983
- "UWTROC",
28984
- "OBSTRN",
28985
- "WRECKS"
28986
- ]);
28987
- var SEMIBOLD = ["Open Sans Semibold"];
28988
- var HAZARD_DEPTH = {
28989
- textSize: ["interpolate", ["linear"], ["zoom"], 12, 12, 16, 15],
28990
- haloWidth: 1.4,
28991
- font: SEMIBOLD
29017
+ // src/atlas/chart-symbol-sizing.ts
29018
+ var CHART_SYMBOL_SIZES = ["landLabels", "waterLabels", "depthNumbers", "waypoints", "chartIcons"];
29019
+ var CHART_SYMBOL_SIZE_WIRE = {
29020
+ landLabels: "chart.landLabelScale",
29021
+ waterLabels: "chart.waterLabelScale",
29022
+ /** Proposed for CHRTKit; aligned with sail's ChartSymbolSizing before release. */
29023
+ depthNumbers: "chart.depthNumberScale",
29024
+ waypoints: "chart.waypointScale",
29025
+ chartIcons: "chart.chartIconScale"
28992
29026
  };
28993
- var LARGE = {
28994
- // Standard: 7 / 8 / 10 / 12 at z8 / 11 / 14 / 16, halo 1.0, Semibold.
28995
- SOUNDG: {
28996
- textSize: ["interpolate", ["linear"], ["zoom"], 8, 10, 11, 11, 14, 14, 16, 17],
28997
- haloWidth: 1.2,
28998
- font: SEMIBOLD
28999
- },
29000
- // Standard: 8 / 10 at z10 / 14, halo 1.2, Regular.
29001
- //
29002
- // ⚠ ~1.2x, NOT 1.4x, AND SEMIBOLD CARRIES THE REST. A contour value rides
29003
- // its line (`symbol-placement: line`) and needs a straight-enough run to fit;
29004
- // it also shares rank 300 with the soundings, which place first. At 1.4x the
29005
- // Boston harbour view kept 15 of Standard's 20 contour labels; at 1.2x, 18.
29006
- DEPCNT: {
29007
- textSize: ["interpolate", ["linear"], ["zoom"], 10, 10, 14, 12],
29008
- haloWidth: 1.2,
29009
- font: SEMIBOLD
29010
- },
29011
- UWTROC: HAZARD_DEPTH,
29012
- OBSTRN: HAZARD_DEPTH,
29013
- WRECKS: HAZARD_DEPTH
29027
+ var CHART_SYMBOL_SIZE_LABELS = {
29028
+ landLabels: "Land labels",
29029
+ waterLabels: "Water labels",
29030
+ depthNumbers: "Depth numbers",
29031
+ waypoints: "Waypoints",
29032
+ chartIcons: "Chart icons"
29014
29033
  };
29015
- var LARGE_SOUNDING_PADDING_PX = 3.5;
29016
- function applyDepthLabelSize(objectClass2, layer, size) {
29017
- if (size !== "large") return layer;
29018
- const large = LARGE[objectClass2];
29019
- if (large === void 0) return layer;
29020
- const layout = {
29021
- ...layer.layout ?? {},
29022
- "text-size": large.textSize,
29023
- "text-font": [...large.font]
29024
- };
29025
- if (objectClass2 === "SOUNDG") layout["text-padding"] = LARGE_SOUNDING_PADDING_PX;
29026
- return {
29027
- ...layer,
29028
- layout,
29029
- paint: { ...layer.paint, "text-halo-width": large.haloWidth }
29030
- };
29034
+ var CHART_SYMBOL_SIZE_REACH = {
29035
+ landLabels: "Towns, landmarks, buildings and land areas.",
29036
+ waterLabels: "Sea, channel, lake and river names, and clearances.",
29037
+ depthNumbers: "Soundings, contour values, and the depths beside rocks, wrecks and obstructions.",
29038
+ waypoints: "Your waypoints and route marks, and how far a tap reaches them.",
29039
+ chartIcons: "Buoys, beacons, lights, wrecks, rocks and their names."
29040
+ };
29041
+ var CHART_SYMBOL_SCALE = {
29042
+ min: 50,
29043
+ max: 200,
29044
+ standard: 100,
29045
+ /** The − / + step. */
29046
+ buttonStep: 10,
29047
+ /** The slider's snap. */
29048
+ sliderStep: 5
29049
+ };
29050
+ var STANDARD_CHART_SYMBOL_SCALES = {
29051
+ landLabels: 100,
29052
+ waterLabels: 100,
29053
+ depthNumbers: 100,
29054
+ waypoints: 100,
29055
+ chartIcons: 100
29056
+ };
29057
+ function clampChartSymbolScale(percent) {
29058
+ if (!Number.isFinite(percent)) return CHART_SYMBOL_SCALE.standard;
29059
+ return Math.min(Math.max(Math.round(percent), CHART_SYMBOL_SCALE.min), CHART_SYMBOL_SCALE.max);
29060
+ }
29061
+ function snapChartSymbolScale(value) {
29062
+ if (!Number.isFinite(value)) return CHART_SYMBOL_SCALE.standard;
29063
+ const step = CHART_SYMBOL_SCALE.sliderStep;
29064
+ return clampChartSymbolScale(Math.round(value / step) * step);
29065
+ }
29066
+ function stepChartSymbolScale(percent, presses) {
29067
+ return clampChartSymbolScale(percent + presses * CHART_SYMBOL_SCALE.buttonStep);
29068
+ }
29069
+ function decodeChartSymbolScale(raw) {
29070
+ if (typeof raw === "number") return Number.isFinite(raw) ? clampChartSymbolScale(raw) : null;
29071
+ if (typeof raw === "string" && /^\s*-?\d+(\.\d+)?\s*$/.test(raw)) return clampChartSymbolScale(Number(raw));
29072
+ return null;
29073
+ }
29074
+ var LAND_TEXT_CLASSES = /* @__PURE__ */ new Set([
29075
+ "BUAARE",
29076
+ "LNDARE",
29077
+ "LNDRGN",
29078
+ "AIRARE",
29079
+ "PRDARE",
29080
+ "LNDMRK",
29081
+ "BUISGL",
29082
+ "SLCONS",
29083
+ "HRBFAC",
29084
+ "BRIDGE"
29085
+ ]);
29086
+ var WATER_TEXT_CLASSES = /* @__PURE__ */ new Set([
29087
+ "SEAARE",
29088
+ "DRGNOTE",
29089
+ "SBDARE",
29090
+ "WEDKLP",
29091
+ "ACHARE",
29092
+ "LAKARE",
29093
+ "RIVERS",
29094
+ "CANALS",
29095
+ "CBLOHD",
29096
+ "PIPOHD"
29097
+ ]);
29098
+ var SYMBOL_ANNOTATION_TEXT_CLASSES = /* @__PURE__ */ new Set([
29099
+ "LIGHTS",
29100
+ "FOGSIG",
29101
+ "BOYCAR",
29102
+ "BOYINB",
29103
+ "BOYISD",
29104
+ "BOYLAT",
29105
+ "BOYSAW",
29106
+ "BOYSPP",
29107
+ "BCNCAR",
29108
+ "BCNISD",
29109
+ "BCNLAT",
29110
+ "BCNSAW",
29111
+ "BCNSPP",
29112
+ "MORFAC",
29113
+ "PILPNT"
29114
+ ]);
29115
+ var BASEMAP_LAND_TEXT = /* @__PURE__ */ new Set([
29116
+ "CHRT_LAND/land_town",
29117
+ "CHRT_LAND/land_summit",
29118
+ "CHRT_LAND/land_poi",
29119
+ "CHRT_BASE/state_label"
29120
+ ]);
29121
+ var BASEMAP_WATER_TEXT = /* @__PURE__ */ new Set([
29122
+ "CHRT_BASE/inland_water_label",
29123
+ "CHRT_BASE/inland_water_label_detail"
29124
+ ]);
29125
+ var BASEMAP_SOURCES = /* @__PURE__ */ new Set(["CHRT_LAND", "CHRT_BASE"]);
29126
+ var HAZARD_LABEL_PRIORITY = 100;
29127
+ var DEPTH_FIGURE_CLASSES = /* @__PURE__ */ new Set(["SOUNDG", "DEPCNT", "UWTROC", "OBSTRN", "WRECKS"]);
29128
+ function contourValueFactor(depthNumbersFactor) {
29129
+ return 1 + (depthNumbersFactor - 1) / 2;
29130
+ }
29131
+ var SERVED_FONT_STACKS = ["Open Sans Regular", "Open Sans Italic", "Open Sans Semibold"];
29132
+ function semiboldFontStack(font) {
29133
+ if (!Array.isArray(font) || !font.every((face) => typeof face === "string")) return font;
29134
+ return font.map((face) => {
29135
+ const semibold = face.replace(/ Regular$/, " Semibold");
29136
+ return SERVED_FONT_STACKS.includes(semibold) ? semibold : face;
29137
+ });
29138
+ }
29139
+ function factsOf(layer) {
29140
+ const l = layer;
29141
+ const source = typeof l.source === "string" ? l.source : void 0;
29142
+ const sourceLayer = typeof l["source-layer"] === "string" ? l["source-layer"] : void 0;
29143
+ const meta = l.metadata ?? {};
29144
+ const isBasemap = source !== void 0 && BASEMAP_SOURCES.has(source);
29145
+ const cls = meta["s52:objectClass"];
29146
+ const objectClass2 = isBasemap ? void 0 : (typeof cls === "string" ? cls : sourceLayer)?.toUpperCase();
29147
+ const p = meta["chrt:labelPriority"];
29148
+ return { source, sourceLayer, objectClass: objectClass2, labelPriority: typeof p === "number" ? p : void 0 };
29149
+ }
29150
+ function textSliderFor(layer) {
29151
+ const f = factsOf(layer);
29152
+ if (f.source !== void 0 && BASEMAP_SOURCES.has(f.source)) {
29153
+ const key = `${f.source}/${f.sourceLayer ?? ""}`;
29154
+ if (BASEMAP_LAND_TEXT.has(key)) return "landLabels";
29155
+ if (BASEMAP_WATER_TEXT.has(key)) return "waterLabels";
29156
+ return null;
29157
+ }
29158
+ const cls = f.objectClass;
29159
+ if (cls === void 0) return null;
29160
+ if (DEPTH_FIGURE_CLASSES.has(cls)) return "depthNumbers";
29161
+ if (LAND_TEXT_CLASSES.has(cls)) return "landLabels";
29162
+ if (WATER_TEXT_CLASSES.has(cls)) return "waterLabels";
29163
+ if (SYMBOL_ANNOTATION_TEXT_CLASSES.has(cls)) return "chartIcons";
29164
+ return null;
29165
+ }
29166
+ function iconSliderFor(layer) {
29167
+ const f = factsOf(layer);
29168
+ if (f.source !== void 0 && BASEMAP_SOURCES.has(f.source)) return null;
29169
+ return f.objectClass === void 0 ? null : "chartIcons";
29170
+ }
29171
+ function mentionsZoom(v) {
29172
+ if (Array.isArray(v)) {
29173
+ if (v.length === 1 && v[0] === "zoom") return true;
29174
+ return v.some(mentionsZoom);
29175
+ }
29176
+ if (v !== null && typeof v === "object") return Object.values(v).some(mentionsZoom);
29177
+ return false;
29178
+ }
29179
+ function scaledOutput(v, factor) {
29180
+ return typeof v === "number" ? round(v * factor) : ["*", v, factor];
29181
+ }
29182
+ function round(n) {
29183
+ return Math.round(n * 1e3) / 1e3;
29184
+ }
29185
+ function scaleSizeExpression(value, factor, fallback) {
29186
+ if (!Number.isFinite(factor) || factor <= 0) return null;
29187
+ if (value === void 0) return round(fallback * factor);
29188
+ if (factor === 1) return value;
29189
+ if (typeof value === "number") return round(value * factor);
29190
+ if (Array.isArray(value)) {
29191
+ const op = value[0];
29192
+ if (typeof op !== "string") return null;
29193
+ if (op === "interpolate" || op === "interpolate-hcl" || op === "interpolate-lab") {
29194
+ if (value.length < 5 || value.length % 2 !== 1) return null;
29195
+ const out = [...value];
29196
+ for (let i = 4; i < out.length; i += 2) out[i] = scaledOutput(out[i], factor);
29197
+ return out;
29198
+ }
29199
+ if (op === "step") {
29200
+ if (value.length < 3 || value.length % 2 !== 1) return null;
29201
+ const out = [...value];
29202
+ for (let i = 2; i < out.length; i += 2) out[i] = scaledOutput(out[i], factor);
29203
+ return out;
29204
+ }
29205
+ return mentionsZoom(value) ? null : ["*", value, factor];
29206
+ }
29207
+ if (value !== null && typeof value === "object") {
29208
+ const stops = value.stops;
29209
+ if (!Array.isArray(stops)) return null;
29210
+ const outStops = [];
29211
+ for (const stop of stops) {
29212
+ if (!Array.isArray(stop) || stop.length !== 2 || typeof stop[1] !== "number") return null;
29213
+ outStops.push([stop[0], round(stop[1] * factor)]);
29214
+ }
29215
+ return { ...value, stops: outStops };
29216
+ }
29217
+ return null;
29218
+ }
29219
+ function haloFactor(factor) {
29220
+ return factor > 1 ? 1 + (factor - 1) / 2 : 1;
29221
+ }
29222
+ var SERVED_SOUNDING_PADDING_PX = 6;
29223
+ var SOUNDING_PADDING_PER_FACTOR = 6.25;
29224
+ function soundingPadding(factor, served = SERVED_SOUNDING_PADDING_PX) {
29225
+ if (factor <= 1) return served;
29226
+ return round(Math.max(0, served - SOUNDING_PADDING_PER_FACTOR * (factor - 1)));
29227
+ }
29228
+ var MAPLIBRE_DEFAULT_TEXT_PADDING_PX = 2;
29229
+ function soundingPaddingValue(served, factor) {
29230
+ if (factor <= 1) return served;
29231
+ if (served === void 0) return soundingPadding(factor, MAPLIBRE_DEFAULT_TEXT_PADDING_PX);
29232
+ if (typeof served === "number") return soundingPadding(factor, served);
29233
+ if (!Array.isArray(served) || typeof served[0] !== "string") return served;
29234
+ const first = served[0] === "interpolate" ? 4 : served[0] === "step" ? 2 : null;
29235
+ if (first === null) return served;
29236
+ const out = [...served];
29237
+ for (let i = first; i < out.length; i += 2) {
29238
+ if (typeof out[i] !== "number") return served;
29239
+ out[i] = soundingPadding(factor, out[i]);
29240
+ }
29241
+ return out;
29242
+ }
29243
+ function factorOf(scales, size) {
29244
+ return clampChartSymbolScale(scales[size]) / 100;
29245
+ }
29246
+ var OUTRANK_LABELS = { kind: "outrankLabels" };
29247
+ var CHART_SOUNDINGS_RULE = { kind: "zoomSplit", harbourFrom: 14 };
29248
+ var KEPT_ABOVE_SOUNDINGS_CLASSES = /* @__PURE__ */ new Set(["SEAARE", "LNDARE", "LNDRGN"]);
29249
+ function keptAboveSoundings(layer, splittingLights = false) {
29250
+ const facts = factsOf(layer);
29251
+ if (splittingLights && facts.objectClass === "LIGHTS") return false;
29252
+ if (facts.labelPriority === HAZARD_LABEL_PRIORITY) return true;
29253
+ if (facts.source !== void 0 && BASEMAP_SOURCES.has(facts.source)) return true;
29254
+ return KEPT_ABOVE_SOUNDINGS_CLASSES.has(facts.objectClass ?? "");
29255
+ }
29256
+ function fromZoom(z, value) {
29257
+ return ["step", ["zoom"], value ?? false, z, true];
29258
+ }
29259
+ function labelSlidersOffStandard(scales) {
29260
+ return ["landLabels", "waterLabels", "depthNumbers", "chartIcons"].some((s) => clampChartSymbolScale(scales[s]) !== 100);
29261
+ }
29262
+ function applyChartSymbolScalesToLayer(layer, scales, yieldText = false) {
29263
+ if (layer.type !== "symbol") return layer;
29264
+ const layout = layer.layout ?? {};
29265
+ const hasText = layout["text-field"] !== void 0;
29266
+ const hasIcon = layout["icon-image"] !== void 0;
29267
+ if (!hasText && !hasIcon) return layer;
29268
+ const facts = factsOf(layer);
29269
+ const nextLayout = { ...layout };
29270
+ let nextPaint = null;
29271
+ let touched = false;
29272
+ if (hasText) {
29273
+ const slider = textSliderFor(layer);
29274
+ const isDepthFigure = slider === "depthNumbers";
29275
+ const sliderFactor = slider === null ? 1 : factorOf(scales, slider);
29276
+ const f = isDepthFigure && facts.objectClass === "DEPCNT" ? contourValueFactor(sliderFactor) : sliderFactor;
29277
+ const size = f === 1 ? null : scaleSizeExpression(layout["text-size"], f, 16);
29278
+ if (size !== null) {
29279
+ touched = true;
29280
+ nextLayout["text-size"] = size;
29281
+ if (f > 1) {
29282
+ if (isDepthFigure) {
29283
+ const semibold = semiboldFontStack(layout["text-font"]);
29284
+ if (JSON.stringify(semibold) !== JSON.stringify(layout["text-font"])) nextLayout["text-font"] = semibold;
29285
+ if (facts.objectClass === "SOUNDG") {
29286
+ const padding = soundingPaddingValue(layout["text-padding"], f);
29287
+ if (padding !== void 0) nextLayout["text-padding"] = padding;
29288
+ } else if (facts.labelPriority === HAZARD_LABEL_PRIORITY) {
29289
+ nextLayout["text-ignore-placement"] = true;
29290
+ nextLayout["text-allow-overlap"] = true;
29291
+ }
29292
+ } else {
29293
+ nextLayout["text-ignore-placement"] = true;
29294
+ if (facts.labelPriority === HAZARD_LABEL_PRIORITY) nextLayout["text-allow-overlap"] = true;
29295
+ }
29296
+ const halo = layer.paint?.["text-halo-width"];
29297
+ if (isDepthFigure && halo !== void 0) {
29298
+ const wider = scaleSizeExpression(halo, haloFactor(sliderFactor), 0);
29299
+ if (wider !== null) nextPaint = { ...layer.paint ?? {}, "text-halo-width": wider };
29300
+ }
29301
+ }
29302
+ }
29303
+ if (yieldText && facts.objectClass !== "SOUNDG") {
29304
+ touched = true;
29305
+ nextLayout["text-ignore-placement"] = true;
29306
+ }
29307
+ }
29308
+ if (hasIcon) {
29309
+ const slider = iconSliderFor(layer);
29310
+ const f = slider === null ? 1 : factorOf(scales, slider);
29311
+ const size = f === 1 ? null : scaleSizeExpression(layout["icon-size"], f, 1);
29312
+ if (size !== null) {
29313
+ touched = true;
29314
+ nextLayout["icon-size"] = size;
29315
+ if (f > 1) nextLayout["icon-ignore-placement"] = true;
29316
+ }
29317
+ }
29318
+ if (!touched) return layer;
29319
+ return { ...layer, layout: nextLayout, ...nextPaint ? { paint: nextPaint } : {} };
29320
+ }
29321
+ var isSoundingText = (l) => l.type === "symbol" && l.layout?.["text-field"] !== void 0 && factsOf(l).objectClass === "SOUNDG";
29322
+ function applyChartSymbolScales(layers, scales, rule = CHART_SOUNDINGS_RULE) {
29323
+ if (scales === void 0 || ["landLabels", "waterLabels", "depthNumbers", "chartIcons"].every((s) => clampChartSymbolScale(scales[s]) === 100)) {
29324
+ return layers;
29325
+ }
29326
+ const outrank = labelSlidersOffStandard(scales);
29327
+ const soundingsAt = layers.findIndex(isSoundingText);
29328
+ const split = rule.kind === "zoomSplit" ? rule : null;
29329
+ const demoted = [];
29330
+ const kept = [];
29331
+ layers.forEach((l, i) => {
29332
+ const above = outrank && soundingsAt !== -1 && i > soundingsAt;
29333
+ const hasText = l.type === "symbol" && l.layout?.["text-field"] !== void 0;
29334
+ if (split !== null && above && hasText && !isSoundingText(l) && !keptAboveSoundings(l, split.splitLights === true)) {
29335
+ const own = applyChartSymbolScalesToLayer(l, scales, false);
29336
+ const layout = own.layout ?? {};
29337
+ demoted.push({
29338
+ ...own,
29339
+ layout: {
29340
+ ...layout,
29341
+ "text-allow-overlap": fromZoom(split.harbourFrom, layout["text-allow-overlap"]),
29342
+ "text-ignore-placement": fromZoom(split.harbourFrom, layout["text-ignore-placement"])
29343
+ }
29344
+ });
29345
+ return;
29346
+ }
29347
+ kept.push(applyChartSymbolScalesToLayer(l, scales, above));
29348
+ });
29349
+ if (demoted.length === 0) return kept;
29350
+ const at = kept.findIndex(isSoundingText);
29351
+ return [...kept.slice(0, at), ...demoted, ...kept.slice(at)];
29352
+ }
29353
+ function demotedBelowSoundings(layers, scales, rule = CHART_SOUNDINGS_RULE) {
29354
+ if (scales === void 0 || rule.kind !== "zoomSplit" || !labelSlidersOffStandard(scales)) return [];
29355
+ const soundingsAt = layers.findIndex(isSoundingText);
29356
+ if (soundingsAt === -1) return [];
29357
+ return layers.filter((l, i) => i > soundingsAt && l.type === "symbol" && l.layout?.["text-field"] !== void 0 && !isSoundingText(l) && !keptAboveSoundings(l, rule.splitLights === true)).map((l) => l.id);
29358
+ }
29359
+ function chartSymbolSizingCensus(layers) {
29360
+ const unclassified = [];
29361
+ const unscalable = [];
29362
+ for (const l of layers) {
29363
+ if (l.type !== "symbol") continue;
29364
+ const layout = l.layout ?? {};
29365
+ if (layout["text-field"] !== void 0) {
29366
+ if (textSliderFor(l) === null) unclassified.push(`${l.id} text`);
29367
+ else if (scaleSizeExpression(layout["text-size"], 2, 16) === null) unscalable.push(`${l.id} text`);
29368
+ }
29369
+ if (layout["icon-image"] !== void 0) {
29370
+ if (iconSliderFor(l) === null) unclassified.push(`${l.id} icon`);
29371
+ else if (scaleSizeExpression(layout["icon-size"], 2, 1) === null) unscalable.push(`${l.id} icon`);
29372
+ }
29373
+ }
29374
+ return { unclassified, unscalable };
29031
29375
  }
29032
29376
 
29033
29377
  // src/atlas/base-bundle.ts
@@ -30370,7 +30714,7 @@ function buildLabelLayer2(objectClass2, ct, sourceId = DEFAULT_REGION, depthUnit
30370
30714
  if (getLabelBehavior(objectClass2) === "orientation-cross-band") {
30371
30715
  layer.filter = LABEL_ANCHOR_FILTER;
30372
30716
  }
30373
- return applyDepthLabelSize(objectClass2, layer, labelOpts.depthLabelSize);
30717
+ return layer;
30374
30718
  }
30375
30719
  function getGeomTypesForClass(objectClass2, defaultType) {
30376
30720
  if (SYMBOL_MAP[objectClass2] && defaultType === "symbol") {
@@ -31525,8 +31869,7 @@ function generateStyle(palette = "DAY", opts = {}) {
31525
31869
  label: buildLabelLayer2(objectClass2, palette, sourceId, opts.depthUnits ?? "meters", {
31526
31870
  safetyContour: opts.safetyContour,
31527
31871
  twoShadeSoundings: opts.twoShadeSoundings,
31528
- soundingFontWeight: opts.soundingFontWeight,
31529
- depthLabelSize: opts.depthLabelSize
31872
+ soundingFontWeight: opts.soundingFontWeight
31530
31873
  })
31531
31874
  });
31532
31875
  }
@@ -31951,7 +32294,9 @@ function generateStyle(palette = "DAY", opts = {}) {
31951
32294
  layers: finalLayers
31952
32295
  };
31953
32296
  const familyStyle = symbolSet === "s101" ? applyS101SymbolSet(style) : symbolSet === "chrt" ? applyChrtSymbolSet(style, palette) : symbolSet === "raster" ? applyRasterSymbolSet(style) : style;
31954
- return applyEinkPortrayal(familyStyle, palette, { safetyContour: opts.safetyContour });
32297
+ const portrayed = applyEinkPortrayal(familyStyle, palette, { safetyContour: opts.safetyContour });
32298
+ const sized = applyChartSymbolScales(portrayed.layers, opts.symbolScales, opts.soundingsRule);
32299
+ return sized === portrayed.layers ? portrayed : { ...portrayed, layers: sized };
31955
32300
  }
31956
32301
  function generateStyleJSON(palette = "DAY", opts = {}) {
31957
32302
  return JSON.stringify(generateStyle(palette, opts), null, 2);
@@ -32858,6 +33203,12 @@ var Chrt = class {
32858
33203
  CHART_BAND_CODES,
32859
33204
  CHART_CASCADE_CODES,
32860
33205
  CHART_SECTIONS,
33206
+ CHART_SOUNDINGS_RULE,
33207
+ CHART_SYMBOL_SCALE,
33208
+ CHART_SYMBOL_SIZES,
33209
+ CHART_SYMBOL_SIZE_LABELS,
33210
+ CHART_SYMBOL_SIZE_REACH,
33211
+ CHART_SYMBOL_SIZE_WIRE,
32861
33212
  CHRTRASTER_REF_CROPS,
32862
33213
  CHRTRASTER_SVGS,
32863
33214
  CHRT_ATON_COLORS,
@@ -32871,7 +33222,6 @@ var Chrt = class {
32871
33222
  ChrtError,
32872
33223
  DEFAULT_CLICK_TOLERANCE,
32873
33224
  DEFAULT_CUSTOM_STYLE_CONFIG,
32874
- DEFAULT_DEPTH_LABEL_SIZE,
32875
33225
  DEFAULT_INSPECT_CLASS_RANK,
32876
33226
  DEFAULT_LABEL_SETTINGS,
32877
33227
  DEFAULT_NAV_AID_SETTINGS,
@@ -32883,14 +33233,14 @@ var Chrt = class {
32883
33233
  DEFAULT_WATER_BODY_SETTINGS,
32884
33234
  DEPARE_FILL_BRANCH_TOKENS,
32885
33235
  DEPARE_FILL_FALLBACK_TOKEN,
32886
- DEPTH_LABEL_CLASSES,
32887
- DEPTH_LABEL_SIZES,
33236
+ DEPTH_FIGURE_CLASSES,
32888
33237
  DRAPEABLE_LAYER_TYPES,
32889
33238
  EINK_COLOR_TABLES,
32890
33239
  EINK_DANGER_PATTERN,
32891
33240
  EINK_DOTS_PATTERN,
32892
33241
  EINK_HATCH_PATTERN,
32893
33242
  EINK_MONO_GREYS,
33243
+ HAZARD_LABEL_PRIORITY,
32894
33244
  INSPECT_CLASS_RANK,
32895
33245
  INSPECT_RANK_DEVIATIONS,
32896
33246
  InteractClient,
@@ -32906,7 +33256,8 @@ var Chrt = class {
32906
33256
  LAND_ATTRIBUTION,
32907
33257
  LAND_BUILD_MAXZOOM,
32908
33258
  LAND_REGION,
32909
- LARGE_SOUNDING_PADDING_PX,
33259
+ LAND_TEXT_CLASSES,
33260
+ MAPLIBRE_DEFAULT_TEXT_PADDING_PX,
32910
33261
  NAUTICAL_SYMBOLS,
32911
33262
  NAV_AID_LAYER_GROUPS,
32912
33263
  NAV_AID_QUERY_LAYERS,
@@ -32915,6 +33266,7 @@ var Chrt = class {
32915
33266
  NON_SOLAS_DISCLAIMER,
32916
33267
  NON_SOLAS_DISCLAIMER_SHORT,
32917
33268
  OPAQUE_SPLIT_OF,
33269
+ OUTRANK_LABELS,
32918
33270
  OfflineError,
32919
33271
  OfflineStyleError,
32920
33272
  PLACENAME_LAND_CLASSES,
@@ -32949,9 +33301,14 @@ var Chrt = class {
32949
33301
  S52_LOOKUP,
32950
33302
  S52_NIGHT,
32951
33303
  S52_PATTERN_SPRITE_PREFIX,
33304
+ SERVED_FONT_STACKS,
33305
+ SERVED_SOUNDING_PADDING_PX,
32952
33306
  SIGPER_TOLERANCE_SECONDS,
32953
33307
  SIGSEQ_MAX_TERMS,
32954
33308
  SOUNDING_LAYERS,
33309
+ SOUNDING_PADDING_PER_FACTOR,
33310
+ STANDARD_CHART_SYMBOL_SCALES,
33311
+ SYMBOL_ANNOTATION_TEXT_CLASSES,
32955
33312
  SYMBOL_FAMILIES,
32956
33313
  SYMBOL_FAMILY_META,
32957
33314
  SYMBOL_GROUPS,
@@ -32959,12 +33316,14 @@ var Chrt = class {
32959
33316
  TileAuth,
32960
33317
  TileTokenError,
32961
33318
  WATER_BODY_LAYER_GROUPS,
33319
+ WATER_TEXT_CLASSES,
32962
33320
  WeatherEndpoint,
32963
33321
  applyBaseBundle,
33322
+ applyChartSymbolScales,
33323
+ applyChartSymbolScalesToLayer,
32964
33324
  applyChrtSymbolSet,
32965
33325
  applyColorTheme,
32966
33326
  applyCustomStyleSettings,
32967
- applyDepthLabelSize,
32968
33327
  applyEinkPortrayal,
32969
33328
  applyRasterSymbolSet,
32970
33329
  applyS101SymbolSet,
@@ -32991,19 +33350,24 @@ var Chrt = class {
32991
33350
  capLuminance,
32992
33351
  cellBandCharacters,
32993
33352
  cellBandMatch,
33353
+ chartSymbolSizingCensus,
32994
33354
  chrtAtonTintExpression,
32995
33355
  chrtHouseColor,
32996
33356
  chrtLightTintExpression,
33357
+ clampChartSymbolScale,
32997
33358
  collectCandidates,
32998
33359
  collectClickCandidates,
32999
33360
  combineWithBandFilter,
33361
+ contourValueFactor,
33000
33362
  contrastRatio,
33001
33363
  daymarkColor,
33002
33364
  decimateFeatures,
33003
33365
  decodeAreaFeatureProps,
33004
33366
  decodeBridgeProps,
33005
33367
  decodeCandidate,
33368
+ decodeChartSymbolScale,
33006
33369
  decodeNavAidProps,
33370
+ demotedBelowSoundings,
33007
33371
  depareColor,
33008
33372
  depareFillExpression,
33009
33373
  depthAreaClassLayerId,
@@ -33013,6 +33377,7 @@ var Chrt = class {
33013
33377
  drapedFirst,
33014
33378
  extractNavAidDesignation,
33015
33379
  featureIdentity,
33380
+ fromZoom,
33016
33381
  generateCustomStyle,
33017
33382
  generateSpriteManifest,
33018
33383
  generateSpriteSheet,
@@ -33040,9 +33405,11 @@ var Chrt = class {
33040
33405
  getThemedS101Svg,
33041
33406
  getThemedS52Svg,
33042
33407
  getTopmarkMeaning,
33408
+ haloFactor,
33043
33409
  hazardColor,
33044
33410
  hazardFillExpression,
33045
33411
  iconExpressionForFamily,
33412
+ iconSliderFor,
33046
33413
  isDepthAreaClassLayerId,
33047
33414
  isDrapeable,
33048
33415
  isEinkColorTable,
@@ -33054,6 +33421,7 @@ var Chrt = class {
33054
33421
  isSoundingLayerVisible,
33055
33422
  isVisibleInMode,
33056
33423
  isWaterBodyLayerVisible,
33424
+ keptAboveSoundings,
33057
33425
  labelSortKey,
33058
33426
  lampRhythmColour,
33059
33427
  lampRhythmOpacity,
@@ -33066,7 +33434,6 @@ var Chrt = class {
33066
33434
  normalizeTheme,
33067
33435
  opaqueSplitBaseOf,
33068
33436
  paginate,
33069
- parseDepthLabelSize,
33070
33437
  parseListCodes,
33071
33438
  parseSigseqTerms,
33072
33439
  parseSymbolFamily,
@@ -33089,12 +33456,19 @@ var Chrt = class {
33089
33456
  safetyContourValues,
33090
33457
  sanitizeCustomStyleConfig,
33091
33458
  scaleLinearLight,
33459
+ scaleSizeExpression,
33092
33460
  scaleSizeValue,
33093
33461
  scaminToMinZoom,
33094
33462
  sectorLimitToArcBearing,
33463
+ semiboldFontStack,
33464
+ snapChartSymbolScale,
33465
+ soundingPadding,
33466
+ soundingPaddingValue,
33095
33467
  splitOpaqueDepthAreas,
33468
+ stepChartSymbolScale,
33096
33469
  styleModeBand,
33097
33470
  terrainStackCount,
33471
+ textSliderFor,
33098
33472
  themeChrtGlyph,
33099
33473
  tileTemplate,
33100
33474
  uncoveredSectorArcs,