@diagrammo/dgmo 0.20.2 → 0.21.0

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/internal.cjs CHANGED
@@ -857,13 +857,9 @@ var init_reserved_key_registry = __esm({
857
857
  "icon"
858
858
  ]);
859
859
  MAP_REGISTRY = staticRegistry([
860
- "score",
860
+ "value",
861
861
  "label",
862
- "size",
863
- "description",
864
- "weight",
865
- "style",
866
- "date"
862
+ "style"
867
863
  ]);
868
864
  ORG_REGISTRY = staticRegistry([
869
865
  "color",
@@ -15828,7 +15824,8 @@ function parseMap(content) {
15828
15824
  continue;
15829
15825
  }
15830
15826
  if (open.route && indent > open.route.indent) {
15831
- open.route.route.stops.push(parseStop(trimmed, lineNumber));
15827
+ const leg = parseLeg(trimmed, lineNumber, open.route.route.style);
15828
+ open.route.route.legs.push(leg);
15832
15829
  continue;
15833
15830
  }
15834
15831
  if (open.poi && indent > open.poi.indent) {
@@ -15859,6 +15856,10 @@ function parseMap(content) {
15859
15856
  handleTag(trimmed, lineNumber);
15860
15857
  continue;
15861
15858
  }
15859
+ if ((firstWord === "muted" || firstWord === "natural") && trimmed === firstWord) {
15860
+ handleDirective(firstWord, "", lineNumber);
15861
+ continue;
15862
+ }
15862
15863
  if (DIRECTIVE_SET.has(firstWord) && !trimmed.slice(firstWord.length).trimStart().startsWith(":")) {
15863
15864
  handleDirective(
15864
15865
  firstWord,
@@ -15923,13 +15924,17 @@ function parseMap(content) {
15923
15924
  );
15924
15925
  d.projection = value;
15925
15926
  break;
15926
- case "metric":
15927
- dup(d.metric);
15928
- d.metric = value;
15927
+ case "region-metric":
15928
+ dup(d.regionMetric);
15929
+ d.regionMetric = value;
15930
+ break;
15931
+ case "poi-metric":
15932
+ dup(d.poiMetric);
15933
+ d.poiMetric = value;
15929
15934
  break;
15930
- case "size-metric":
15931
- dup(d.sizeMetric);
15932
- d.sizeMetric = value;
15935
+ case "flow-metric":
15936
+ dup(d.flowMetric);
15937
+ d.flowMetric = value;
15933
15938
  break;
15934
15939
  case "scale":
15935
15940
  dup(d.scale);
@@ -15971,6 +15976,15 @@ function parseMap(content) {
15971
15976
  case "no-legend":
15972
15977
  d.noLegend = true;
15973
15978
  break;
15979
+ case "muted":
15980
+ case "natural":
15981
+ if (d.basemapStyle !== void 0 && d.basemapStyle !== key)
15982
+ pushWarning(
15983
+ line12,
15984
+ `Conflicting basemap dress \u2014 "${d.basemapStyle}" then "${key}"; last wins.`
15985
+ );
15986
+ d.basemapStyle = key;
15987
+ break;
15974
15988
  case "subtitle":
15975
15989
  dup(d.subtitle);
15976
15990
  d.subtitle = value;
@@ -16048,14 +16062,14 @@ function parseMap(content) {
16048
16062
  line12
16049
16063
  );
16050
16064
  const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
16051
- let scoreNum;
16052
- const score = meta["score"];
16053
- if (score !== void 0) {
16054
- delete meta["score"];
16055
- scoreNum = Number(score);
16056
- if (!Number.isFinite(scoreNum)) {
16057
- pushError(line12, `score must be a number (got "${score}").`);
16058
- scoreNum = void 0;
16065
+ let valueNum;
16066
+ const value = meta["value"];
16067
+ if (value !== void 0) {
16068
+ delete meta["value"];
16069
+ valueNum = Number(value);
16070
+ if (!Number.isFinite(valueNum)) {
16071
+ pushError(line12, `value must be a number (got "${value}").`);
16072
+ valueNum = void 0;
16059
16073
  }
16060
16074
  }
16061
16075
  let regionName = split.name;
@@ -16073,7 +16087,7 @@ function parseMap(content) {
16073
16087
  lineNumber: line12
16074
16088
  };
16075
16089
  if (regionScope !== void 0) region.scope = regionScope;
16076
- if (scoreNum !== void 0) region.score = scoreNum;
16090
+ if (valueNum !== void 0) region.value = valueNum;
16077
16091
  regions.push(region);
16078
16092
  }
16079
16093
  function handlePoi(rest, line12, indent) {
@@ -16102,24 +16116,76 @@ function parseMap(content) {
16102
16116
  open.poi = { poi, indent };
16103
16117
  }
16104
16118
  function handleRoute(rest, line12, indent) {
16105
- const meta = rest ? splitNameAndMeta(rest, registry(), aliasMap).meta : {};
16106
- const route = { stops: [], meta, lineNumber: line12 };
16119
+ const split = rest ? splitNameAndMeta(
16120
+ rest,
16121
+ registry(),
16122
+ aliasMap,
16123
+ void 0,
16124
+ diagnostics,
16125
+ line12
16126
+ ) : { name: "", meta: {}, alias: void 0 };
16127
+ const pos = parsePos(split.name, line12);
16128
+ if (!pos || pos.kind === "name" && !pos.name) {
16129
+ pushError(
16130
+ line12,
16131
+ "route requires an origin: `route <origin> [style: arc]`."
16132
+ );
16133
+ return;
16134
+ }
16135
+ const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
16136
+ const originLabel = meta["label"];
16137
+ const originValue = meta["value"];
16138
+ const style = meta["style"] === "arc" ? "arc" : "straight";
16139
+ const route = {
16140
+ origin: pos,
16141
+ ...split.alias !== void 0 && { originAlias: split.alias },
16142
+ ...originLabel !== void 0 && { originLabel },
16143
+ ...originValue !== void 0 && { originValue },
16144
+ originTags: tags,
16145
+ style,
16146
+ legs: [],
16147
+ lineNumber: line12
16148
+ };
16107
16149
  routes.push(route);
16108
16150
  open.route = { route, indent };
16109
16151
  }
16110
- function parseStop(trimmed, line12) {
16111
- const split = splitNameAndMeta(trimmed, registry(), aliasMap);
16112
- const ref = parsePos(split.name, line12) ?? {
16152
+ function parseLeg(trimmed, line12, headerStyle) {
16153
+ let arrowStyle = "straight";
16154
+ let label;
16155
+ let rest = trimmed;
16156
+ const m = trimmed.match(LEG_ARROW_RE);
16157
+ if (m) {
16158
+ const arr = classifyArrow(m[1], line12);
16159
+ arrowStyle = arr.style;
16160
+ label = arr.label;
16161
+ rest = m[2];
16162
+ }
16163
+ const split = splitNameAndMeta(
16164
+ rest,
16165
+ registry(),
16166
+ aliasMap,
16167
+ void 0,
16168
+ diagnostics,
16169
+ line12
16170
+ );
16171
+ const pos = parsePos(split.name, line12) ?? {
16113
16172
  kind: "name",
16114
16173
  name: split.name
16115
16174
  };
16116
- const stop = {
16117
- ref,
16118
- meta: split.meta,
16175
+ const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
16176
+ const value = meta["value"];
16177
+ const destLabel = meta["label"];
16178
+ const style = arrowStyle === "arc" || headerStyle === "arc" ? "arc" : "straight";
16179
+ return {
16180
+ ...label !== void 0 && { label },
16181
+ style,
16182
+ ...value !== void 0 && { value },
16183
+ dest: pos,
16184
+ ...split.alias !== void 0 && { destAlias: split.alias },
16185
+ ...destLabel !== void 0 && { destLabel },
16186
+ destTags: tags,
16119
16187
  lineNumber: line12
16120
16188
  };
16121
- if (split.alias) stop.alias = split.alias;
16122
- return stop;
16123
16189
  }
16124
16190
  function handleEdges(trimmed, line12) {
16125
16191
  const parts = trimmed.split(ARROW_SPLIT);
@@ -16221,7 +16287,7 @@ function partitionMeta(meta, tagGroupNames) {
16221
16287
  function poiName(pos) {
16222
16288
  return pos.kind === "name" ? pos.name : void 0;
16223
16289
  }
16224
- var COORD_RE, NUMERIC_LEAD_RE, SCOPE_RE, ARROW_SPLIT, HUB_RE, AT_RE, DIRECTIVE_SET;
16290
+ var COORD_RE, NUMERIC_LEAD_RE, SCOPE_RE, ARROW_SPLIT, HUB_RE, LEG_ARROW_RE, AT_RE, DIRECTIVE_SET;
16225
16291
  var init_parser12 = __esm({
16226
16292
  "src/map/parser.ts"() {
16227
16293
  "use strict";
@@ -16235,12 +16301,14 @@ var init_parser12 = __esm({
16235
16301
  SCOPE_RE = /^[A-Z]{2}(?:-[A-Z0-9]{1,3})?$/;
16236
16302
  ARROW_SPLIT = /\s+(-[^>]*?->|->|~[^>]*?~>|~>|--)\s+/;
16237
16303
  HUB_RE = /^(->|~>)\s+(.+)$/;
16304
+ LEG_ARROW_RE = /^(-[^>]*?->|->|~[^>]*?~>|~>|--)\s+(.+)$/;
16238
16305
  AT_RE = /(^|[\s,])at\s*:/i;
16239
16306
  DIRECTIVE_SET = /* @__PURE__ */ new Set([
16240
16307
  "region",
16241
16308
  "projection",
16242
- "metric",
16243
- "size-metric",
16309
+ "region-metric",
16310
+ "poi-metric",
16311
+ "flow-metric",
16244
16312
  "scale",
16245
16313
  "region-labels",
16246
16314
  "poi-labels",
@@ -45838,6 +45906,11 @@ var resolver_exports = {};
45838
45906
  __export(resolver_exports, {
45839
45907
  resolveMap: () => resolveMap
45840
45908
  });
45909
+ function usStateFromBareScope(scope) {
45910
+ if (!scope) return null;
45911
+ const up = scope.toUpperCase();
45912
+ return US_STATE_POSTAL.has(up) ? `US-${up}` : null;
45913
+ }
45841
45914
  function looksUS(lat, lon) {
45842
45915
  if (lat < 15 || lat > 72) return false;
45843
45916
  return lon >= -180 && lon <= -64 || lon >= 172;
@@ -45887,9 +45960,9 @@ function resolveMap(parsed, data) {
45887
45960
  const f = fold(r.name);
45888
45961
  return usStateIndex.has(f) && !countryIndex.has(f);
45889
45962
  }) || parsed.regions.some(
45890
- (r) => r.scope === "US" || r.scope?.startsWith("US-")
45963
+ (r) => r.scope === "US" || r.scope?.startsWith("US-") || usStateFromBareScope(r.scope) !== null
45891
45964
  ) || parsed.pois.some(
45892
- (p) => p.pos.kind === "name" && p.pos.scope?.startsWith("US-")
45965
+ (p) => p.pos.kind === "name" && (p.pos.scope?.startsWith("US-") || usStateFromBareScope(p.pos.scope) !== null)
45893
45966
  );
45894
45967
  const regions = [];
45895
45968
  const seenRegion = /* @__PURE__ */ new Map();
@@ -45956,7 +46029,7 @@ function resolveMap(parsed, data) {
45956
46029
  iso: chosen.id,
45957
46030
  name: chosen.name,
45958
46031
  layer: chosen.layer,
45959
- ...r.score !== void 0 && { score: r.score },
46032
+ ...r.value !== void 0 && { value: r.value },
45960
46033
  tags: r.tags,
45961
46034
  meta: r.meta,
45962
46035
  lineNumber: r.lineNumber
@@ -46014,9 +46087,10 @@ function resolveMap(parsed, data) {
46014
46087
  let cands = idxs.map((i) => data.gazetteer.cities[i]);
46015
46088
  const scopeUse = scope ?? scopeHint;
46016
46089
  if (scopeUse) {
46017
- const isSub = /^[A-Za-z]{2}-/.test(scopeUse);
46090
+ const bareState = usStateFromBareScope(scopeUse);
46091
+ const subScope = /^[A-Za-z]{2}-/.test(scopeUse) ? scopeUse : bareState;
46018
46092
  const filtered = cands.filter(
46019
- (c2) => isSub ? c2[5] === scopeUse : c2[2] === scopeUse
46093
+ (c2) => subScope ? c2[5] === subScope : c2[2] === scopeUse
46020
46094
  );
46021
46095
  if (filtered.length) cands = filtered;
46022
46096
  else if (scope) {
@@ -46145,33 +46219,89 @@ function resolveMap(parsed, data) {
46145
46219
  lineNumber: e.lineNumber
46146
46220
  });
46147
46221
  }
46148
- const routes = [];
46149
- for (const rt of parsed.routes) {
46150
- const stopIds = [];
46151
- for (const stop of rt.stops) {
46152
- let id;
46153
- if (stop.ref.kind === "coords") {
46154
- id = stop.alias ? fold(stop.alias) : `@${stop.ref.lat},${stop.ref.lon}`;
46155
- if (!looksUS(stop.ref.lat, stop.ref.lon)) anyNonUsPoi = true;
46156
- if (!registry.has(id)) {
46157
- const poi = {
46222
+ const resolveStop = (pos, alias, label, tags, sizeValue, line12) => {
46223
+ const meta = sizeValue !== void 0 ? { value: sizeValue } : {};
46224
+ if (pos.kind === "coords") {
46225
+ const id = alias ? fold(alias) : `@${pos.lat},${pos.lon}`;
46226
+ if (!looksUS(pos.lat, pos.lon)) anyNonUsPoi = true;
46227
+ if (!registry.has(id)) {
46228
+ registerPoi(
46229
+ id,
46230
+ {
46158
46231
  id,
46159
- ...stop.alias !== void 0 && { name: stop.alias },
46160
- lat: stop.ref.lat,
46161
- lon: stop.ref.lon,
46162
- tags: {},
46163
- meta: stop.meta,
46164
- lineNumber: stop.lineNumber,
46165
- implicit: true
46166
- };
46167
- registerPoi(id, poi, stop.lineNumber);
46168
- }
46169
- } else {
46170
- id = stop.alias && registry.has(fold(stop.alias)) ? fold(stop.alias) : resolveEndpoint2(stop.ref.name, stop.lineNumber);
46232
+ ...alias !== void 0 && { name: alias },
46233
+ lat: pos.lat,
46234
+ lon: pos.lon,
46235
+ ...label !== void 0 && { label },
46236
+ tags,
46237
+ meta,
46238
+ lineNumber: line12
46239
+ },
46240
+ line12
46241
+ );
46171
46242
  }
46172
- if (id) stopIds.push(id);
46243
+ return id;
46244
+ }
46245
+ const f = fold(pos.name);
46246
+ if (registry.has(f)) return f;
46247
+ const aliased = declaredByName.get(f);
46248
+ if (aliased) return aliased;
46249
+ const got = lookupName(pos.name, pos.scope, line12, inferredCountry, true);
46250
+ if (got.kind !== "ok") return null;
46251
+ noteCountry(got.iso);
46252
+ registerPoi(
46253
+ f,
46254
+ {
46255
+ id: f,
46256
+ name: pos.name,
46257
+ lat: got.lat,
46258
+ lon: got.lon,
46259
+ ...label !== void 0 && { label },
46260
+ tags,
46261
+ meta,
46262
+ lineNumber: line12
46263
+ },
46264
+ line12
46265
+ );
46266
+ return f;
46267
+ };
46268
+ const routes = [];
46269
+ for (const rt of parsed.routes) {
46270
+ const originId = resolveStop(
46271
+ rt.origin,
46272
+ rt.originAlias,
46273
+ rt.originLabel,
46274
+ rt.originTags,
46275
+ rt.originValue,
46276
+ rt.lineNumber
46277
+ );
46278
+ if (!originId) continue;
46279
+ const stopIds = [originId];
46280
+ const legs = [];
46281
+ let prevId = originId;
46282
+ for (const leg of rt.legs) {
46283
+ const destId = resolveStop(
46284
+ leg.dest,
46285
+ leg.destAlias,
46286
+ leg.destLabel,
46287
+ leg.destTags,
46288
+ void 0,
46289
+ // a leg's `value:` is leg thickness, not the dest's size
46290
+ leg.lineNumber
46291
+ );
46292
+ if (!destId) continue;
46293
+ legs.push({
46294
+ fromId: prevId,
46295
+ toId: destId,
46296
+ ...leg.label !== void 0 && { label: leg.label },
46297
+ style: leg.style,
46298
+ ...leg.value !== void 0 && { value: leg.value },
46299
+ lineNumber: leg.lineNumber
46300
+ });
46301
+ if (!stopIds.includes(destId)) stopIds.push(destId);
46302
+ prevId = destId;
46173
46303
  }
46174
- routes.push({ stopIds, meta: rt.meta, lineNumber: rt.lineNumber });
46304
+ routes.push({ stopIds, legs, lineNumber: rt.lineNumber });
46175
46305
  }
46176
46306
  const subdivisions = [];
46177
46307
  if (usSubdivisionReferenced || parsed.directives.region === "us-states")
@@ -46263,7 +46393,7 @@ function firstError(diags) {
46263
46393
  const e = diags.find((d) => d.severity === "error");
46264
46394
  return e ? formatDgmoError(e) : null;
46265
46395
  }
46266
- var WORLD_SPAN, MERCATOR_MAX_SPAN, PAD_FRACTION, WORLD_LAT_SOUTH, WORLD_LAT_NORTH, REGION_ALIASES;
46396
+ var WORLD_SPAN, MERCATOR_MAX_SPAN, PAD_FRACTION, WORLD_LAT_SOUTH, WORLD_LAT_NORTH, REGION_ALIASES, US_STATE_POSTAL;
46267
46397
  var init_resolver2 = __esm({
46268
46398
  "src/map/resolver.ts"() {
46269
46399
  "use strict";
@@ -46295,6 +46425,59 @@ var init_resolver2 = __esm({
46295
46425
  "north macedonia": "macedonia",
46296
46426
  "czech republic": "czechia"
46297
46427
  };
46428
+ US_STATE_POSTAL = /* @__PURE__ */ new Set([
46429
+ "AL",
46430
+ "AK",
46431
+ "AZ",
46432
+ "AR",
46433
+ "CA",
46434
+ "CO",
46435
+ "CT",
46436
+ "DE",
46437
+ "FL",
46438
+ "GA",
46439
+ "HI",
46440
+ "ID",
46441
+ "IL",
46442
+ "IN",
46443
+ "IA",
46444
+ "KS",
46445
+ "KY",
46446
+ "LA",
46447
+ "ME",
46448
+ "MD",
46449
+ "MA",
46450
+ "MI",
46451
+ "MN",
46452
+ "MS",
46453
+ "MO",
46454
+ "MT",
46455
+ "NE",
46456
+ "NV",
46457
+ "NH",
46458
+ "NJ",
46459
+ "NM",
46460
+ "NY",
46461
+ "NC",
46462
+ "ND",
46463
+ "OH",
46464
+ "OK",
46465
+ "OR",
46466
+ "PA",
46467
+ "RI",
46468
+ "SC",
46469
+ "SD",
46470
+ "TN",
46471
+ "TX",
46472
+ "UT",
46473
+ "VT",
46474
+ "VA",
46475
+ "WA",
46476
+ "WV",
46477
+ "WI",
46478
+ "WY",
46479
+ "DC"
46480
+ ]);
46298
46481
  }
46299
46482
  });
46300
46483
 
@@ -46433,10 +46616,18 @@ function projectionFor(family) {
46433
46616
  return (0, import_d3_geo2.geoEquirectangular)();
46434
46617
  }
46435
46618
  }
46436
- function mapBackgroundColor(palette) {
46619
+ function mapBackgroundColor(palette, isDark = false, dataActive = false) {
46620
+ if (dataActive)
46621
+ return mix(
46622
+ palette.colors.gray,
46623
+ palette.bg,
46624
+ isDark ? MUTED_WATER_DARK : MUTED_WATER_LIGHT
46625
+ );
46437
46626
  return mix(palette.colors.blue, palette.bg, WATER_TINT);
46438
46627
  }
46439
- function mapNeutralLandColor(palette, isDark) {
46628
+ function mapNeutralLandColor(palette, isDark, dataActive = false) {
46629
+ if (dataActive)
46630
+ return isDark ? mix(palette.colors.gray, palette.bg, MUTED_LAND_DARK) : palette.bg;
46440
46631
  return mix(
46441
46632
  palette.colors.green,
46442
46633
  palette.bg,
@@ -46462,28 +46653,19 @@ function layoutMap(resolved, data, size, opts) {
46462
46653
  }
46463
46654
  }
46464
46655
  const usLayer = wantsUsStates ? decodeLayer(data.usStates) : null;
46465
- const landTint = isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT;
46466
- const neutralFill = mix(palette.colors.green, palette.bg, landTint);
46467
- const water = mapBackgroundColor(palette);
46468
46656
  const usContext = usLayer !== null;
46469
- const foreignFill = mix(
46470
- palette.colors.gray,
46471
- palette.bg,
46472
- isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
46473
- );
46474
46657
  const regionStroke = isDark ? mix(palette.bg, palette.text, 78) : mix(palette.text, palette.bg, 78);
46475
- const scores = resolved.regions.filter((r) => r.score !== void 0).map((r) => r.score);
46658
+ const values = resolved.regions.filter((r) => r.value !== void 0).map((r) => r.value);
46476
46659
  const scaleOverride = resolved.directives.scale;
46477
- const rampMin = scaleOverride ? scaleOverride.min : Math.min(...scores);
46478
- const rampMax = scaleOverride ? scaleOverride.max : Math.max(...scores);
46660
+ const rampMin = scaleOverride ? scaleOverride.min : Math.min(...values);
46661
+ const rampMax = scaleOverride ? scaleOverride.max : Math.max(...values);
46479
46662
  const rampHue = palette.colors.red;
46480
- const hasRamp = scores.length > 0;
46481
- const SCORE_NAME = hasRamp ? resolved.directives.metric?.trim() || "Score" : null;
46663
+ const hasRamp = values.length > 0;
46664
+ const VALUE_NAME = hasRamp ? resolved.directives.regionMetric?.trim() || "Value" : null;
46482
46665
  const matchColorGroup = (v) => {
46483
46666
  const lv = v.trim().toLowerCase();
46484
46667
  if (lv === "none") return null;
46485
- if (SCORE_NAME && (lv === "score" || lv === SCORE_NAME.toLowerCase()))
46486
- return SCORE_NAME;
46668
+ if (lv === VALUE_NAME?.toLowerCase()) return VALUE_NAME;
46487
46669
  const tg = resolved.tagGroups.find((g) => g.name.toLowerCase() === lv);
46488
46670
  return tg ? tg.name : v;
46489
46671
  };
@@ -46494,11 +46676,19 @@ function layoutMap(resolved, data, size, opts) {
46494
46676
  } else if (resolved.directives.activeTag !== void 0) {
46495
46677
  activeGroup = matchColorGroup(resolved.directives.activeTag);
46496
46678
  } else {
46497
- activeGroup = SCORE_NAME ?? (resolved.tagGroups.length > 0 ? resolved.tagGroups[0].name : null);
46679
+ activeGroup = VALUE_NAME ?? (resolved.tagGroups.length > 0 ? resolved.tagGroups[0].name : null);
46498
46680
  }
46499
- const activeIsScore = SCORE_NAME !== null && activeGroup === SCORE_NAME;
46681
+ const activeIsScore = VALUE_NAME !== null && activeGroup === VALUE_NAME;
46682
+ const mutedBasemap = resolved.directives.basemapStyle === "muted" ? true : resolved.directives.basemapStyle === "natural" ? false : activeGroup !== null;
46683
+ const neutralFill = mapNeutralLandColor(palette, isDark, mutedBasemap);
46684
+ const water = mapBackgroundColor(palette, isDark, mutedBasemap);
46685
+ const foreignFill = mix(
46686
+ palette.colors.gray,
46687
+ palette.bg,
46688
+ mutedBasemap ? isDark ? MUTED_FOREIGN_DARK : MUTED_FOREIGN_LIGHT : isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
46689
+ );
46500
46690
  const rampBase = isDark ? mix(palette.surface, palette.text, 28) : palette.bg;
46501
- const fillForScore = (s) => {
46691
+ const fillForValue = (s) => {
46502
46692
  const t = rampMax > rampMin ? (s - rampMin) / (rampMax - rampMin) : 1;
46503
46693
  const pct = RAMP_FLOOR + Math.max(0, Math.min(1, t)) * (100 - RAMP_FLOOR);
46504
46694
  return mix(rampHue, rampBase, pct);
@@ -46523,7 +46713,7 @@ function layoutMap(resolved, data, size, opts) {
46523
46713
  };
46524
46714
  const regionFill = (r) => {
46525
46715
  if (activeIsScore) {
46526
- return r.score !== void 0 ? fillForScore(r.score) : neutralFill;
46716
+ return r.value !== void 0 ? fillForValue(r.value) : neutralFill;
46527
46717
  }
46528
46718
  return tagFill(r.tags, activeGroup) ?? neutralFill;
46529
46719
  };
@@ -46735,7 +46925,7 @@ function layoutMap(resolved, data, size, opts) {
46735
46925
  stroke: regionStroke,
46736
46926
  lineNumber,
46737
46927
  layer: "us-state",
46738
- ...r?.score !== void 0 && { score: r.score },
46928
+ ...r?.value !== void 0 && { value: r.value },
46739
46929
  ...r && Object.keys(r.tags).length > 0 && { tags: r.tags }
46740
46930
  });
46741
46931
  const ctr = (0, import_d3_geo2.geoPath)(proj).centroid(f);
@@ -46851,6 +47041,8 @@ function layoutMap(resolved, data, size, opts) {
46851
47041
  if (layerKind === "us-state" && usContext && INSET_STATES.has(iso))
46852
47042
  continue;
46853
47043
  if (layerKind === "country" && usContext && iso === "US") continue;
47044
+ if (layerKind === "country" && iso === "AQ" && !regionById.has("AQ"))
47045
+ continue;
46854
47046
  const r = regionById.get(iso);
46855
47047
  const viewF = shouldCull ? cullFeatureToView(f) : dropFrameFillers(f);
46856
47048
  if (!viewF) continue;
@@ -46876,7 +47068,7 @@ function layoutMap(resolved, data, size, opts) {
46876
47068
  lineNumber,
46877
47069
  layer,
46878
47070
  ...label !== void 0 && { label },
46879
- ...isThisLayer && r.score !== void 0 && { score: r.score },
47071
+ ...isThisLayer && r.value !== void 0 && { value: r.value },
46880
47072
  ...isThisLayer && Object.keys(r.tags).length > 0 && { tags: r.tags }
46881
47073
  });
46882
47074
  }
@@ -46911,11 +47103,11 @@ function layoutMap(resolved, data, size, opts) {
46911
47103
  rivers.push({ d, color: riverColor, width: RIVER_WIDTH });
46912
47104
  }
46913
47105
  }
46914
- const sizeVals = resolved.pois.map((p) => Number(p.meta["size"])).filter((n) => Number.isFinite(n) && n > 0);
47106
+ const sizeVals = resolved.pois.map((p) => Number(p.meta["value"])).filter((n) => Number.isFinite(n) && n > 0);
46915
47107
  const sizeMin = sizeVals.length ? Math.min(...sizeVals) : 0;
46916
47108
  const sizeMax = sizeVals.length ? Math.max(...sizeVals) : 0;
46917
47109
  const radiusFor = (p) => {
46918
- const v = Number(p.meta["size"]);
47110
+ const v = Number(p.meta["value"]);
46919
47111
  if (!Number.isFinite(v) || v <= 0 || sizeMax <= 0) return R_DEFAULT;
46920
47112
  const t = sizeMax > sizeMin ? (Math.sqrt(v) - Math.sqrt(sizeMin)) / (Math.sqrt(sizeMax) - Math.sqrt(sizeMin)) : 1;
46921
47113
  return R_MIN + Math.max(0, Math.min(1, t)) * (R_MAX - R_MIN);
@@ -46982,7 +47174,8 @@ function layoutMap(resolved, data, size, opts) {
46982
47174
  lineNumber: e.p.lineNumber,
46983
47175
  implicit: !!e.p.implicit,
46984
47176
  isOrigin: originIds.has(e.p.id),
46985
- ...num !== void 0 && { routeNumber: num }
47177
+ ...num !== void 0 && { routeNumber: num },
47178
+ ...Object.keys(e.p.tags).length > 0 && { tags: e.p.tags }
46986
47179
  });
46987
47180
  });
46988
47181
  }
@@ -47018,26 +47211,40 @@ function layoutMap(resolved, data, size, opts) {
47018
47211
  const by = b.cy - (b.cy - py) / tb * trimB;
47019
47212
  return `M${ax},${ay}Q${px},${py} ${bx},${by}`;
47020
47213
  };
47214
+ const routeLegVals = resolved.routes.flatMap((rt) => rt.legs).map((l) => Number(l.value)).filter((n) => Number.isFinite(n) && n > 0);
47215
+ const rlMin = routeLegVals.length ? Math.min(...routeLegVals) : 0;
47216
+ const rlMax = routeLegVals.length ? Math.max(...routeLegVals) : 0;
47217
+ const routeWidthFor = (v) => {
47218
+ if (!Number.isFinite(v) || v <= 0 || rlMax <= 0) return W_MIN;
47219
+ const t = rlMax > rlMin ? (v - rlMin) / (rlMax - rlMin) : 1;
47220
+ return W_MIN + t * (W_MAX - W_MIN);
47221
+ };
47021
47222
  for (const rt of resolved.routes) {
47022
- const curved = rt.meta["style"] === "arc";
47023
- for (let i = 1; i < rt.stopIds.length; i++) {
47024
- const a = poiScreen.get(rt.stopIds[i - 1]);
47025
- const b = poiScreen.get(rt.stopIds[i]);
47223
+ for (const leg of rt.legs) {
47224
+ const a = poiScreen.get(leg.fromId);
47225
+ const b = poiScreen.get(leg.toId);
47026
47226
  if (!a || !b) continue;
47227
+ const mx = (a.cx + b.cx) / 2;
47228
+ const my = (a.cy + b.cy) / 2;
47027
47229
  legs.push({
47028
- d: legPath(a, b, curved, 0),
47029
- width: W_MIN,
47230
+ d: legPath(a, b, leg.style === "arc", 0),
47231
+ width: routeWidthFor(Number(leg.value)),
47030
47232
  color: mix(palette.text, palette.bg, 72),
47031
47233
  arrow: true,
47032
- lineNumber: rt.lineNumber
47234
+ lineNumber: leg.lineNumber,
47235
+ ...leg.label !== void 0 && {
47236
+ label: leg.label,
47237
+ labelX: mx,
47238
+ labelY: my - 4
47239
+ }
47033
47240
  });
47034
47241
  }
47035
47242
  }
47036
- const weightVals = resolved.edges.map((e) => Number(e.meta["weight"])).filter((n) => Number.isFinite(n) && n > 0);
47243
+ const weightVals = resolved.edges.map((e) => Number(e.meta["value"])).filter((n) => Number.isFinite(n) && n > 0);
47037
47244
  const wMin = weightVals.length ? Math.min(...weightVals) : 0;
47038
47245
  const wMax = weightVals.length ? Math.max(...weightVals) : 0;
47039
47246
  const widthFor = (e) => {
47040
- const v = Number(e.meta["weight"]);
47247
+ const v = Number(e.meta["value"]);
47041
47248
  if (!Number.isFinite(v) || v <= 0 || wMax <= 0) return W_MIN;
47042
47249
  const t = wMax > wMin ? (v - wMin) / (wMax - wMin) : 1;
47043
47250
  return W_MIN + t * (W_MAX - W_MIN);
@@ -47300,8 +47507,8 @@ function layoutMap(resolved, data, size, opts) {
47300
47507
  activeGroup,
47301
47508
  ...hasRamp && {
47302
47509
  ramp: {
47303
- ...resolved.directives.metric !== void 0 && {
47304
- metric: resolved.directives.metric
47510
+ ...resolved.directives.regionMetric !== void 0 && {
47511
+ metric: resolved.directives.regionMetric
47305
47512
  },
47306
47513
  min: rampMin,
47307
47514
  max: rampMax,
@@ -47329,7 +47536,7 @@ function layoutMap(resolved, data, size, opts) {
47329
47536
  insetRegions
47330
47537
  };
47331
47538
  }
47332
- var import_d3_geo2, import_topojson_client2, FIT_PAD, RAMP_FLOOR, R_DEFAULT, R_MIN, R_MAX, W_MIN, W_MAX, FONT, COLO_EPS, LAND_TINT_LIGHT, LAND_TINT_DARK, TAG_TINT_LIGHT, TAG_TINT_DARK, WATER_TINT, RIVER_WIDTH, FOREIGN_TINT_LIGHT, FOREIGN_TINT_DARK, COLO_R, GOLDEN_ANGLE, FAN_STEP, ARC_CURVE_FRAC, usConusProjection, alaskaProjection, hawaiiProjection, INSET_STATES, US_NON_CONUS;
47539
+ var import_d3_geo2, import_topojson_client2, FIT_PAD, RAMP_FLOOR, R_DEFAULT, R_MIN, R_MAX, W_MIN, W_MAX, FONT, COLO_EPS, LAND_TINT_LIGHT, LAND_TINT_DARK, TAG_TINT_LIGHT, TAG_TINT_DARK, WATER_TINT, RIVER_WIDTH, FOREIGN_TINT_LIGHT, FOREIGN_TINT_DARK, MUTED_WATER_LIGHT, MUTED_WATER_DARK, MUTED_FOREIGN_LIGHT, MUTED_FOREIGN_DARK, MUTED_LAND_DARK, COLO_R, GOLDEN_ANGLE, FAN_STEP, ARC_CURVE_FRAC, usConusProjection, alaskaProjection, hawaiiProjection, INSET_STATES, US_NON_CONUS;
47333
47540
  var init_layout15 = __esm({
47334
47541
  "src/map/layout.ts"() {
47335
47542
  "use strict";
@@ -47356,6 +47563,11 @@ var init_layout15 = __esm({
47356
47563
  RIVER_WIDTH = 1.3;
47357
47564
  FOREIGN_TINT_LIGHT = 30;
47358
47565
  FOREIGN_TINT_DARK = 62;
47566
+ MUTED_WATER_LIGHT = 14;
47567
+ MUTED_WATER_DARK = 10;
47568
+ MUTED_FOREIGN_LIGHT = 28;
47569
+ MUTED_FOREIGN_DARK = 16;
47570
+ MUTED_LAND_DARK = 24;
47359
47571
  COLO_R = 9;
47360
47572
  GOLDEN_ANGLE = 2.399963229728653;
47361
47573
  FAN_STEP = 16;
@@ -47409,7 +47621,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
47409
47621
  const p = g.append("path").attr("d", r.d).attr("fill", r.fill).attr("stroke", r.stroke).attr("stroke-width", strokeWidth);
47410
47622
  if (r.layer !== "base") {
47411
47623
  p.classed("dgmo-map-region", true).attr("data-region", r.id);
47412
- if (r.score !== void 0) p.attr("data-score", r.score);
47624
+ if (r.value !== void 0) p.attr("data-value", r.value);
47413
47625
  if (r.tags) {
47414
47626
  for (const [group, value] of Object.entries(r.tags)) {
47415
47627
  p.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
@@ -47470,6 +47682,11 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
47470
47682
  gPois.append("circle").attr("cx", poi.cx).attr("cy", poi.cy).attr("r", poi.r + 3).attr("fill", "none").attr("stroke", poi.stroke).attr("stroke-width", 1.5);
47471
47683
  }
47472
47684
  const c = gPois.append("circle").attr("cx", poi.cx).attr("cy", poi.cy).attr("r", poi.r).attr("fill", poi.fill).attr("stroke", poi.stroke).attr("stroke-width", 1).attr("data-line-number", poi.lineNumber).attr("data-poi", poi.id);
47685
+ if (poi.tags) {
47686
+ for (const [group, value] of Object.entries(poi.tags)) {
47687
+ c.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
47688
+ }
47689
+ }
47473
47690
  if (onClickItem) {
47474
47691
  c.style("cursor", "pointer").on(
47475
47692
  "click",
@@ -47519,7 +47736,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
47519
47736
  const legendG = svg.append("g").attr("class", "dgmo-map-legend").attr("transform", `translate(0, ${legendY})`);
47520
47737
  const ramp = layout.legend.ramp;
47521
47738
  const scoreGroup = ramp ? {
47522
- name: ramp.metric?.trim() || "Score",
47739
+ name: ramp.metric?.trim() || "Value",
47523
47740
  entries: [],
47524
47741
  gradient: {
47525
47742
  min: ramp.min,
@@ -58467,7 +58684,7 @@ var COMPLETION_REGISTRY = /* @__PURE__ */ new Map([
58467
58684
  [
58468
58685
  "map",
58469
58686
  // Geographic map directives (§24B.2/.7). `poi`/`route` are content
58470
- // keywords, not directives; metadata keys (score/size/label) live in the
58687
+ // keywords, not directives; metadata keys (value/label/style) live in the
58471
58688
  // reserved-key registry.
58472
58689
  withGlobals({
58473
58690
  region: {
@@ -58478,9 +58695,14 @@ var COMPLETION_REGISTRY = /* @__PURE__ */ new Map([
58478
58695
  description: "Override the auto projection",
58479
58696
  values: ["equirectangular", "natural-earth", "albers-usa", "mercator"]
58480
58697
  },
58481
- metric: { description: "Label for the region score ramp" },
58482
- "size-metric": { description: "Label for the POI size channel" },
58483
- scale: { description: "Override score ramp anchors: scale <min> <max>" },
58698
+ "region-metric": { description: "Label for the region value ramp" },
58699
+ "poi-metric": {
58700
+ description: "Label for the POI value (marker size) channel"
58701
+ },
58702
+ "flow-metric": {
58703
+ description: "Label for the edge/leg value (thickness) channel"
58704
+ },
58705
+ scale: { description: "Override value ramp anchors: scale <min> <max>" },
58484
58706
  "region-labels": {
58485
58707
  description: "Subdivision name labels",
58486
58708
  values: ["full", "abbrev", "off"]