@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/index.cjs CHANGED
@@ -835,13 +835,9 @@ var init_reserved_key_registry = __esm({
835
835
  "icon"
836
836
  ]);
837
837
  MAP_REGISTRY = staticRegistry([
838
- "score",
838
+ "value",
839
839
  "label",
840
- "size",
841
- "description",
842
- "weight",
843
- "style",
844
- "date"
840
+ "style"
845
841
  ]);
846
842
  ORG_REGISTRY = staticRegistry([
847
843
  "color",
@@ -15854,7 +15850,8 @@ function parseMap(content) {
15854
15850
  continue;
15855
15851
  }
15856
15852
  if (open.route && indent > open.route.indent) {
15857
- open.route.route.stops.push(parseStop(trimmed, lineNumber));
15853
+ const leg = parseLeg(trimmed, lineNumber, open.route.route.style);
15854
+ open.route.route.legs.push(leg);
15858
15855
  continue;
15859
15856
  }
15860
15857
  if (open.poi && indent > open.poi.indent) {
@@ -15885,6 +15882,10 @@ function parseMap(content) {
15885
15882
  handleTag(trimmed, lineNumber);
15886
15883
  continue;
15887
15884
  }
15885
+ if ((firstWord === "muted" || firstWord === "natural") && trimmed === firstWord) {
15886
+ handleDirective(firstWord, "", lineNumber);
15887
+ continue;
15888
+ }
15888
15889
  if (DIRECTIVE_SET.has(firstWord) && !trimmed.slice(firstWord.length).trimStart().startsWith(":")) {
15889
15890
  handleDirective(
15890
15891
  firstWord,
@@ -15949,13 +15950,17 @@ function parseMap(content) {
15949
15950
  );
15950
15951
  d.projection = value;
15951
15952
  break;
15952
- case "metric":
15953
- dup(d.metric);
15954
- d.metric = value;
15953
+ case "region-metric":
15954
+ dup(d.regionMetric);
15955
+ d.regionMetric = value;
15956
+ break;
15957
+ case "poi-metric":
15958
+ dup(d.poiMetric);
15959
+ d.poiMetric = value;
15955
15960
  break;
15956
- case "size-metric":
15957
- dup(d.sizeMetric);
15958
- d.sizeMetric = value;
15961
+ case "flow-metric":
15962
+ dup(d.flowMetric);
15963
+ d.flowMetric = value;
15959
15964
  break;
15960
15965
  case "scale":
15961
15966
  dup(d.scale);
@@ -15997,6 +16002,15 @@ function parseMap(content) {
15997
16002
  case "no-legend":
15998
16003
  d.noLegend = true;
15999
16004
  break;
16005
+ case "muted":
16006
+ case "natural":
16007
+ if (d.basemapStyle !== void 0 && d.basemapStyle !== key)
16008
+ pushWarning(
16009
+ line12,
16010
+ `Conflicting basemap dress \u2014 "${d.basemapStyle}" then "${key}"; last wins.`
16011
+ );
16012
+ d.basemapStyle = key;
16013
+ break;
16000
16014
  case "subtitle":
16001
16015
  dup(d.subtitle);
16002
16016
  d.subtitle = value;
@@ -16074,14 +16088,14 @@ function parseMap(content) {
16074
16088
  line12
16075
16089
  );
16076
16090
  const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
16077
- let scoreNum;
16078
- const score = meta["score"];
16079
- if (score !== void 0) {
16080
- delete meta["score"];
16081
- scoreNum = Number(score);
16082
- if (!Number.isFinite(scoreNum)) {
16083
- pushError(line12, `score must be a number (got "${score}").`);
16084
- scoreNum = void 0;
16091
+ let valueNum;
16092
+ const value = meta["value"];
16093
+ if (value !== void 0) {
16094
+ delete meta["value"];
16095
+ valueNum = Number(value);
16096
+ if (!Number.isFinite(valueNum)) {
16097
+ pushError(line12, `value must be a number (got "${value}").`);
16098
+ valueNum = void 0;
16085
16099
  }
16086
16100
  }
16087
16101
  let regionName = split.name;
@@ -16099,7 +16113,7 @@ function parseMap(content) {
16099
16113
  lineNumber: line12
16100
16114
  };
16101
16115
  if (regionScope !== void 0) region.scope = regionScope;
16102
- if (scoreNum !== void 0) region.score = scoreNum;
16116
+ if (valueNum !== void 0) region.value = valueNum;
16103
16117
  regions.push(region);
16104
16118
  }
16105
16119
  function handlePoi(rest, line12, indent) {
@@ -16128,24 +16142,76 @@ function parseMap(content) {
16128
16142
  open.poi = { poi, indent };
16129
16143
  }
16130
16144
  function handleRoute(rest, line12, indent) {
16131
- const meta = rest ? splitNameAndMeta(rest, registry(), aliasMap).meta : {};
16132
- const route = { stops: [], meta, lineNumber: line12 };
16145
+ const split = rest ? splitNameAndMeta(
16146
+ rest,
16147
+ registry(),
16148
+ aliasMap,
16149
+ void 0,
16150
+ diagnostics,
16151
+ line12
16152
+ ) : { name: "", meta: {}, alias: void 0 };
16153
+ const pos = parsePos(split.name, line12);
16154
+ if (!pos || pos.kind === "name" && !pos.name) {
16155
+ pushError(
16156
+ line12,
16157
+ "route requires an origin: `route <origin> [style: arc]`."
16158
+ );
16159
+ return;
16160
+ }
16161
+ const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
16162
+ const originLabel = meta["label"];
16163
+ const originValue = meta["value"];
16164
+ const style = meta["style"] === "arc" ? "arc" : "straight";
16165
+ const route = {
16166
+ origin: pos,
16167
+ ...split.alias !== void 0 && { originAlias: split.alias },
16168
+ ...originLabel !== void 0 && { originLabel },
16169
+ ...originValue !== void 0 && { originValue },
16170
+ originTags: tags,
16171
+ style,
16172
+ legs: [],
16173
+ lineNumber: line12
16174
+ };
16133
16175
  routes.push(route);
16134
16176
  open.route = { route, indent };
16135
16177
  }
16136
- function parseStop(trimmed, line12) {
16137
- const split = splitNameAndMeta(trimmed, registry(), aliasMap);
16138
- const ref = parsePos(split.name, line12) ?? {
16178
+ function parseLeg(trimmed, line12, headerStyle) {
16179
+ let arrowStyle = "straight";
16180
+ let label;
16181
+ let rest = trimmed;
16182
+ const m = trimmed.match(LEG_ARROW_RE);
16183
+ if (m) {
16184
+ const arr = classifyArrow(m[1], line12);
16185
+ arrowStyle = arr.style;
16186
+ label = arr.label;
16187
+ rest = m[2];
16188
+ }
16189
+ const split = splitNameAndMeta(
16190
+ rest,
16191
+ registry(),
16192
+ aliasMap,
16193
+ void 0,
16194
+ diagnostics,
16195
+ line12
16196
+ );
16197
+ const pos = parsePos(split.name, line12) ?? {
16139
16198
  kind: "name",
16140
16199
  name: split.name
16141
16200
  };
16142
- const stop = {
16143
- ref,
16144
- meta: split.meta,
16201
+ const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
16202
+ const value = meta["value"];
16203
+ const destLabel = meta["label"];
16204
+ const style = arrowStyle === "arc" || headerStyle === "arc" ? "arc" : "straight";
16205
+ return {
16206
+ ...label !== void 0 && { label },
16207
+ style,
16208
+ ...value !== void 0 && { value },
16209
+ dest: pos,
16210
+ ...split.alias !== void 0 && { destAlias: split.alias },
16211
+ ...destLabel !== void 0 && { destLabel },
16212
+ destTags: tags,
16145
16213
  lineNumber: line12
16146
16214
  };
16147
- if (split.alias) stop.alias = split.alias;
16148
- return stop;
16149
16215
  }
16150
16216
  function handleEdges(trimmed, line12) {
16151
16217
  const parts = trimmed.split(ARROW_SPLIT);
@@ -16247,7 +16313,7 @@ function partitionMeta(meta, tagGroupNames) {
16247
16313
  function poiName(pos) {
16248
16314
  return pos.kind === "name" ? pos.name : void 0;
16249
16315
  }
16250
- var COORD_RE, NUMERIC_LEAD_RE, SCOPE_RE, ARROW_SPLIT, HUB_RE, AT_RE, DIRECTIVE_SET;
16316
+ var COORD_RE, NUMERIC_LEAD_RE, SCOPE_RE, ARROW_SPLIT, HUB_RE, LEG_ARROW_RE, AT_RE, DIRECTIVE_SET;
16251
16317
  var init_parser12 = __esm({
16252
16318
  "src/map/parser.ts"() {
16253
16319
  "use strict";
@@ -16261,12 +16327,14 @@ var init_parser12 = __esm({
16261
16327
  SCOPE_RE = /^[A-Z]{2}(?:-[A-Z0-9]{1,3})?$/;
16262
16328
  ARROW_SPLIT = /\s+(-[^>]*?->|->|~[^>]*?~>|~>|--)\s+/;
16263
16329
  HUB_RE = /^(->|~>)\s+(.+)$/;
16330
+ LEG_ARROW_RE = /^(-[^>]*?->|->|~[^>]*?~>|~>|--)\s+(.+)$/;
16264
16331
  AT_RE = /(^|[\s,])at\s*:/i;
16265
16332
  DIRECTIVE_SET = /* @__PURE__ */ new Set([
16266
16333
  "region",
16267
16334
  "projection",
16268
- "metric",
16269
- "size-metric",
16335
+ "region-metric",
16336
+ "poi-metric",
16337
+ "flow-metric",
16270
16338
  "scale",
16271
16339
  "region-labels",
16272
16340
  "poi-labels",
@@ -45551,6 +45619,11 @@ var resolver_exports = {};
45551
45619
  __export(resolver_exports, {
45552
45620
  resolveMap: () => resolveMap
45553
45621
  });
45622
+ function usStateFromBareScope(scope) {
45623
+ if (!scope) return null;
45624
+ const up = scope.toUpperCase();
45625
+ return US_STATE_POSTAL.has(up) ? `US-${up}` : null;
45626
+ }
45554
45627
  function looksUS(lat, lon) {
45555
45628
  if (lat < 15 || lat > 72) return false;
45556
45629
  return lon >= -180 && lon <= -64 || lon >= 172;
@@ -45600,9 +45673,9 @@ function resolveMap(parsed, data) {
45600
45673
  const f = fold(r.name);
45601
45674
  return usStateIndex.has(f) && !countryIndex.has(f);
45602
45675
  }) || parsed.regions.some(
45603
- (r) => r.scope === "US" || r.scope?.startsWith("US-")
45676
+ (r) => r.scope === "US" || r.scope?.startsWith("US-") || usStateFromBareScope(r.scope) !== null
45604
45677
  ) || parsed.pois.some(
45605
- (p) => p.pos.kind === "name" && p.pos.scope?.startsWith("US-")
45678
+ (p) => p.pos.kind === "name" && (p.pos.scope?.startsWith("US-") || usStateFromBareScope(p.pos.scope) !== null)
45606
45679
  );
45607
45680
  const regions = [];
45608
45681
  const seenRegion = /* @__PURE__ */ new Map();
@@ -45669,7 +45742,7 @@ function resolveMap(parsed, data) {
45669
45742
  iso: chosen.id,
45670
45743
  name: chosen.name,
45671
45744
  layer: chosen.layer,
45672
- ...r.score !== void 0 && { score: r.score },
45745
+ ...r.value !== void 0 && { value: r.value },
45673
45746
  tags: r.tags,
45674
45747
  meta: r.meta,
45675
45748
  lineNumber: r.lineNumber
@@ -45727,9 +45800,10 @@ function resolveMap(parsed, data) {
45727
45800
  let cands = idxs.map((i) => data.gazetteer.cities[i]);
45728
45801
  const scopeUse = scope ?? scopeHint;
45729
45802
  if (scopeUse) {
45730
- const isSub = /^[A-Za-z]{2}-/.test(scopeUse);
45803
+ const bareState = usStateFromBareScope(scopeUse);
45804
+ const subScope = /^[A-Za-z]{2}-/.test(scopeUse) ? scopeUse : bareState;
45731
45805
  const filtered = cands.filter(
45732
- (c2) => isSub ? c2[5] === scopeUse : c2[2] === scopeUse
45806
+ (c2) => subScope ? c2[5] === subScope : c2[2] === scopeUse
45733
45807
  );
45734
45808
  if (filtered.length) cands = filtered;
45735
45809
  else if (scope) {
@@ -45858,33 +45932,89 @@ function resolveMap(parsed, data) {
45858
45932
  lineNumber: e.lineNumber
45859
45933
  });
45860
45934
  }
45861
- const routes = [];
45862
- for (const rt of parsed.routes) {
45863
- const stopIds = [];
45864
- for (const stop of rt.stops) {
45865
- let id;
45866
- if (stop.ref.kind === "coords") {
45867
- id = stop.alias ? fold(stop.alias) : `@${stop.ref.lat},${stop.ref.lon}`;
45868
- if (!looksUS(stop.ref.lat, stop.ref.lon)) anyNonUsPoi = true;
45869
- if (!registry.has(id)) {
45870
- const poi = {
45935
+ const resolveStop = (pos, alias, label, tags, sizeValue, line12) => {
45936
+ const meta = sizeValue !== void 0 ? { value: sizeValue } : {};
45937
+ if (pos.kind === "coords") {
45938
+ const id = alias ? fold(alias) : `@${pos.lat},${pos.lon}`;
45939
+ if (!looksUS(pos.lat, pos.lon)) anyNonUsPoi = true;
45940
+ if (!registry.has(id)) {
45941
+ registerPoi(
45942
+ id,
45943
+ {
45871
45944
  id,
45872
- ...stop.alias !== void 0 && { name: stop.alias },
45873
- lat: stop.ref.lat,
45874
- lon: stop.ref.lon,
45875
- tags: {},
45876
- meta: stop.meta,
45877
- lineNumber: stop.lineNumber,
45878
- implicit: true
45879
- };
45880
- registerPoi(id, poi, stop.lineNumber);
45881
- }
45882
- } else {
45883
- id = stop.alias && registry.has(fold(stop.alias)) ? fold(stop.alias) : resolveEndpoint2(stop.ref.name, stop.lineNumber);
45945
+ ...alias !== void 0 && { name: alias },
45946
+ lat: pos.lat,
45947
+ lon: pos.lon,
45948
+ ...label !== void 0 && { label },
45949
+ tags,
45950
+ meta,
45951
+ lineNumber: line12
45952
+ },
45953
+ line12
45954
+ );
45884
45955
  }
45885
- if (id) stopIds.push(id);
45956
+ return id;
45957
+ }
45958
+ const f = fold(pos.name);
45959
+ if (registry.has(f)) return f;
45960
+ const aliased = declaredByName.get(f);
45961
+ if (aliased) return aliased;
45962
+ const got = lookupName(pos.name, pos.scope, line12, inferredCountry, true);
45963
+ if (got.kind !== "ok") return null;
45964
+ noteCountry(got.iso);
45965
+ registerPoi(
45966
+ f,
45967
+ {
45968
+ id: f,
45969
+ name: pos.name,
45970
+ lat: got.lat,
45971
+ lon: got.lon,
45972
+ ...label !== void 0 && { label },
45973
+ tags,
45974
+ meta,
45975
+ lineNumber: line12
45976
+ },
45977
+ line12
45978
+ );
45979
+ return f;
45980
+ };
45981
+ const routes = [];
45982
+ for (const rt of parsed.routes) {
45983
+ const originId = resolveStop(
45984
+ rt.origin,
45985
+ rt.originAlias,
45986
+ rt.originLabel,
45987
+ rt.originTags,
45988
+ rt.originValue,
45989
+ rt.lineNumber
45990
+ );
45991
+ if (!originId) continue;
45992
+ const stopIds = [originId];
45993
+ const legs = [];
45994
+ let prevId = originId;
45995
+ for (const leg of rt.legs) {
45996
+ const destId = resolveStop(
45997
+ leg.dest,
45998
+ leg.destAlias,
45999
+ leg.destLabel,
46000
+ leg.destTags,
46001
+ void 0,
46002
+ // a leg's `value:` is leg thickness, not the dest's size
46003
+ leg.lineNumber
46004
+ );
46005
+ if (!destId) continue;
46006
+ legs.push({
46007
+ fromId: prevId,
46008
+ toId: destId,
46009
+ ...leg.label !== void 0 && { label: leg.label },
46010
+ style: leg.style,
46011
+ ...leg.value !== void 0 && { value: leg.value },
46012
+ lineNumber: leg.lineNumber
46013
+ });
46014
+ if (!stopIds.includes(destId)) stopIds.push(destId);
46015
+ prevId = destId;
45886
46016
  }
45887
- routes.push({ stopIds, meta: rt.meta, lineNumber: rt.lineNumber });
46017
+ routes.push({ stopIds, legs, lineNumber: rt.lineNumber });
45888
46018
  }
45889
46019
  const subdivisions = [];
45890
46020
  if (usSubdivisionReferenced || parsed.directives.region === "us-states")
@@ -45976,7 +46106,7 @@ function firstError(diags) {
45976
46106
  const e = diags.find((d) => d.severity === "error");
45977
46107
  return e ? formatDgmoError(e) : null;
45978
46108
  }
45979
- var WORLD_SPAN, MERCATOR_MAX_SPAN, PAD_FRACTION, WORLD_LAT_SOUTH, WORLD_LAT_NORTH, REGION_ALIASES;
46109
+ var WORLD_SPAN, MERCATOR_MAX_SPAN, PAD_FRACTION, WORLD_LAT_SOUTH, WORLD_LAT_NORTH, REGION_ALIASES, US_STATE_POSTAL;
45980
46110
  var init_resolver2 = __esm({
45981
46111
  "src/map/resolver.ts"() {
45982
46112
  "use strict";
@@ -46008,6 +46138,59 @@ var init_resolver2 = __esm({
46008
46138
  "north macedonia": "macedonia",
46009
46139
  "czech republic": "czechia"
46010
46140
  };
46141
+ US_STATE_POSTAL = /* @__PURE__ */ new Set([
46142
+ "AL",
46143
+ "AK",
46144
+ "AZ",
46145
+ "AR",
46146
+ "CA",
46147
+ "CO",
46148
+ "CT",
46149
+ "DE",
46150
+ "FL",
46151
+ "GA",
46152
+ "HI",
46153
+ "ID",
46154
+ "IL",
46155
+ "IN",
46156
+ "IA",
46157
+ "KS",
46158
+ "KY",
46159
+ "LA",
46160
+ "ME",
46161
+ "MD",
46162
+ "MA",
46163
+ "MI",
46164
+ "MN",
46165
+ "MS",
46166
+ "MO",
46167
+ "MT",
46168
+ "NE",
46169
+ "NV",
46170
+ "NH",
46171
+ "NJ",
46172
+ "NM",
46173
+ "NY",
46174
+ "NC",
46175
+ "ND",
46176
+ "OH",
46177
+ "OK",
46178
+ "OR",
46179
+ "PA",
46180
+ "RI",
46181
+ "SC",
46182
+ "SD",
46183
+ "TN",
46184
+ "TX",
46185
+ "UT",
46186
+ "VT",
46187
+ "VA",
46188
+ "WA",
46189
+ "WV",
46190
+ "WI",
46191
+ "WY",
46192
+ "DC"
46193
+ ]);
46011
46194
  }
46012
46195
  });
46013
46196
 
@@ -46146,9 +46329,24 @@ function projectionFor(family) {
46146
46329
  return (0, import_d3_geo2.geoEquirectangular)();
46147
46330
  }
46148
46331
  }
46149
- function mapBackgroundColor(palette) {
46332
+ function mapBackgroundColor(palette, isDark = false, dataActive = false) {
46333
+ if (dataActive)
46334
+ return mix(
46335
+ palette.colors.gray,
46336
+ palette.bg,
46337
+ isDark ? MUTED_WATER_DARK : MUTED_WATER_LIGHT
46338
+ );
46150
46339
  return mix(palette.colors.blue, palette.bg, WATER_TINT);
46151
46340
  }
46341
+ function mapNeutralLandColor(palette, isDark, dataActive = false) {
46342
+ if (dataActive)
46343
+ return isDark ? mix(palette.colors.gray, palette.bg, MUTED_LAND_DARK) : palette.bg;
46344
+ return mix(
46345
+ palette.colors.green,
46346
+ palette.bg,
46347
+ isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT
46348
+ );
46349
+ }
46152
46350
  function layoutMap(resolved, data, size, opts) {
46153
46351
  const { palette, isDark } = opts;
46154
46352
  const { width, height } = size;
@@ -46168,28 +46366,19 @@ function layoutMap(resolved, data, size, opts) {
46168
46366
  }
46169
46367
  }
46170
46368
  const usLayer = wantsUsStates ? decodeLayer(data.usStates) : null;
46171
- const landTint = isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT;
46172
- const neutralFill = mix(palette.colors.green, palette.bg, landTint);
46173
- const water = mapBackgroundColor(palette);
46174
46369
  const usContext = usLayer !== null;
46175
- const foreignFill = mix(
46176
- palette.colors.gray,
46177
- palette.bg,
46178
- isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
46179
- );
46180
46370
  const regionStroke = isDark ? mix(palette.bg, palette.text, 78) : mix(palette.text, palette.bg, 78);
46181
- const scores = resolved.regions.filter((r) => r.score !== void 0).map((r) => r.score);
46371
+ const values = resolved.regions.filter((r) => r.value !== void 0).map((r) => r.value);
46182
46372
  const scaleOverride = resolved.directives.scale;
46183
- const rampMin = scaleOverride ? scaleOverride.min : Math.min(...scores);
46184
- const rampMax = scaleOverride ? scaleOverride.max : Math.max(...scores);
46373
+ const rampMin = scaleOverride ? scaleOverride.min : Math.min(...values);
46374
+ const rampMax = scaleOverride ? scaleOverride.max : Math.max(...values);
46185
46375
  const rampHue = palette.colors.red;
46186
- const hasRamp = scores.length > 0;
46187
- const SCORE_NAME = hasRamp ? resolved.directives.metric?.trim() || "Score" : null;
46376
+ const hasRamp = values.length > 0;
46377
+ const VALUE_NAME = hasRamp ? resolved.directives.regionMetric?.trim() || "Value" : null;
46188
46378
  const matchColorGroup = (v) => {
46189
46379
  const lv = v.trim().toLowerCase();
46190
46380
  if (lv === "none") return null;
46191
- if (SCORE_NAME && (lv === "score" || lv === SCORE_NAME.toLowerCase()))
46192
- return SCORE_NAME;
46381
+ if (lv === VALUE_NAME?.toLowerCase()) return VALUE_NAME;
46193
46382
  const tg = resolved.tagGroups.find((g) => g.name.toLowerCase() === lv);
46194
46383
  return tg ? tg.name : v;
46195
46384
  };
@@ -46200,11 +46389,19 @@ function layoutMap(resolved, data, size, opts) {
46200
46389
  } else if (resolved.directives.activeTag !== void 0) {
46201
46390
  activeGroup = matchColorGroup(resolved.directives.activeTag);
46202
46391
  } else {
46203
- activeGroup = SCORE_NAME ?? (resolved.tagGroups.length > 0 ? resolved.tagGroups[0].name : null);
46392
+ activeGroup = VALUE_NAME ?? (resolved.tagGroups.length > 0 ? resolved.tagGroups[0].name : null);
46204
46393
  }
46205
- const activeIsScore = SCORE_NAME !== null && activeGroup === SCORE_NAME;
46394
+ const activeIsScore = VALUE_NAME !== null && activeGroup === VALUE_NAME;
46395
+ const mutedBasemap = resolved.directives.basemapStyle === "muted" ? true : resolved.directives.basemapStyle === "natural" ? false : activeGroup !== null;
46396
+ const neutralFill = mapNeutralLandColor(palette, isDark, mutedBasemap);
46397
+ const water = mapBackgroundColor(palette, isDark, mutedBasemap);
46398
+ const foreignFill = mix(
46399
+ palette.colors.gray,
46400
+ palette.bg,
46401
+ mutedBasemap ? isDark ? MUTED_FOREIGN_DARK : MUTED_FOREIGN_LIGHT : isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
46402
+ );
46206
46403
  const rampBase = isDark ? mix(palette.surface, palette.text, 28) : palette.bg;
46207
- const fillForScore = (s) => {
46404
+ const fillForValue = (s) => {
46208
46405
  const t = rampMax > rampMin ? (s - rampMin) / (rampMax - rampMin) : 1;
46209
46406
  const pct = RAMP_FLOOR + Math.max(0, Math.min(1, t)) * (100 - RAMP_FLOOR);
46210
46407
  return mix(rampHue, rampBase, pct);
@@ -46229,7 +46426,7 @@ function layoutMap(resolved, data, size, opts) {
46229
46426
  };
46230
46427
  const regionFill = (r) => {
46231
46428
  if (activeIsScore) {
46232
- return r.score !== void 0 ? fillForScore(r.score) : neutralFill;
46429
+ return r.value !== void 0 ? fillForValue(r.value) : neutralFill;
46233
46430
  }
46234
46431
  return tagFill(r.tags, activeGroup) ?? neutralFill;
46235
46432
  };
@@ -46441,7 +46638,7 @@ function layoutMap(resolved, data, size, opts) {
46441
46638
  stroke: regionStroke,
46442
46639
  lineNumber,
46443
46640
  layer: "us-state",
46444
- ...r?.score !== void 0 && { score: r.score },
46641
+ ...r?.value !== void 0 && { value: r.value },
46445
46642
  ...r && Object.keys(r.tags).length > 0 && { tags: r.tags }
46446
46643
  });
46447
46644
  const ctr = (0, import_d3_geo2.geoPath)(proj).centroid(f);
@@ -46557,6 +46754,8 @@ function layoutMap(resolved, data, size, opts) {
46557
46754
  if (layerKind === "us-state" && usContext && INSET_STATES.has(iso))
46558
46755
  continue;
46559
46756
  if (layerKind === "country" && usContext && iso === "US") continue;
46757
+ if (layerKind === "country" && iso === "AQ" && !regionById.has("AQ"))
46758
+ continue;
46560
46759
  const r = regionById.get(iso);
46561
46760
  const viewF = shouldCull ? cullFeatureToView(f) : dropFrameFillers(f);
46562
46761
  if (!viewF) continue;
@@ -46582,7 +46781,7 @@ function layoutMap(resolved, data, size, opts) {
46582
46781
  lineNumber,
46583
46782
  layer,
46584
46783
  ...label !== void 0 && { label },
46585
- ...isThisLayer && r.score !== void 0 && { score: r.score },
46784
+ ...isThisLayer && r.value !== void 0 && { value: r.value },
46586
46785
  ...isThisLayer && Object.keys(r.tags).length > 0 && { tags: r.tags }
46587
46786
  });
46588
46787
  }
@@ -46617,11 +46816,11 @@ function layoutMap(resolved, data, size, opts) {
46617
46816
  rivers.push({ d, color: riverColor, width: RIVER_WIDTH });
46618
46817
  }
46619
46818
  }
46620
- const sizeVals = resolved.pois.map((p) => Number(p.meta["size"])).filter((n) => Number.isFinite(n) && n > 0);
46819
+ const sizeVals = resolved.pois.map((p) => Number(p.meta["value"])).filter((n) => Number.isFinite(n) && n > 0);
46621
46820
  const sizeMin = sizeVals.length ? Math.min(...sizeVals) : 0;
46622
46821
  const sizeMax = sizeVals.length ? Math.max(...sizeVals) : 0;
46623
46822
  const radiusFor = (p) => {
46624
- const v = Number(p.meta["size"]);
46823
+ const v = Number(p.meta["value"]);
46625
46824
  if (!Number.isFinite(v) || v <= 0 || sizeMax <= 0) return R_DEFAULT;
46626
46825
  const t = sizeMax > sizeMin ? (Math.sqrt(v) - Math.sqrt(sizeMin)) / (Math.sqrt(sizeMax) - Math.sqrt(sizeMin)) : 1;
46627
46826
  return R_MIN + Math.max(0, Math.min(1, t)) * (R_MAX - R_MIN);
@@ -46688,7 +46887,8 @@ function layoutMap(resolved, data, size, opts) {
46688
46887
  lineNumber: e.p.lineNumber,
46689
46888
  implicit: !!e.p.implicit,
46690
46889
  isOrigin: originIds.has(e.p.id),
46691
- ...num !== void 0 && { routeNumber: num }
46890
+ ...num !== void 0 && { routeNumber: num },
46891
+ ...Object.keys(e.p.tags).length > 0 && { tags: e.p.tags }
46692
46892
  });
46693
46893
  });
46694
46894
  }
@@ -46724,26 +46924,40 @@ function layoutMap(resolved, data, size, opts) {
46724
46924
  const by = b.cy - (b.cy - py) / tb * trimB;
46725
46925
  return `M${ax},${ay}Q${px},${py} ${bx},${by}`;
46726
46926
  };
46927
+ const routeLegVals = resolved.routes.flatMap((rt) => rt.legs).map((l) => Number(l.value)).filter((n) => Number.isFinite(n) && n > 0);
46928
+ const rlMin = routeLegVals.length ? Math.min(...routeLegVals) : 0;
46929
+ const rlMax = routeLegVals.length ? Math.max(...routeLegVals) : 0;
46930
+ const routeWidthFor = (v) => {
46931
+ if (!Number.isFinite(v) || v <= 0 || rlMax <= 0) return W_MIN;
46932
+ const t = rlMax > rlMin ? (v - rlMin) / (rlMax - rlMin) : 1;
46933
+ return W_MIN + t * (W_MAX - W_MIN);
46934
+ };
46727
46935
  for (const rt of resolved.routes) {
46728
- const curved = rt.meta["style"] === "arc";
46729
- for (let i = 1; i < rt.stopIds.length; i++) {
46730
- const a = poiScreen.get(rt.stopIds[i - 1]);
46731
- const b = poiScreen.get(rt.stopIds[i]);
46936
+ for (const leg of rt.legs) {
46937
+ const a = poiScreen.get(leg.fromId);
46938
+ const b = poiScreen.get(leg.toId);
46732
46939
  if (!a || !b) continue;
46940
+ const mx = (a.cx + b.cx) / 2;
46941
+ const my = (a.cy + b.cy) / 2;
46733
46942
  legs.push({
46734
- d: legPath(a, b, curved, 0),
46735
- width: W_MIN,
46943
+ d: legPath(a, b, leg.style === "arc", 0),
46944
+ width: routeWidthFor(Number(leg.value)),
46736
46945
  color: mix(palette.text, palette.bg, 72),
46737
46946
  arrow: true,
46738
- lineNumber: rt.lineNumber
46947
+ lineNumber: leg.lineNumber,
46948
+ ...leg.label !== void 0 && {
46949
+ label: leg.label,
46950
+ labelX: mx,
46951
+ labelY: my - 4
46952
+ }
46739
46953
  });
46740
46954
  }
46741
46955
  }
46742
- const weightVals = resolved.edges.map((e) => Number(e.meta["weight"])).filter((n) => Number.isFinite(n) && n > 0);
46956
+ const weightVals = resolved.edges.map((e) => Number(e.meta["value"])).filter((n) => Number.isFinite(n) && n > 0);
46743
46957
  const wMin = weightVals.length ? Math.min(...weightVals) : 0;
46744
46958
  const wMax = weightVals.length ? Math.max(...weightVals) : 0;
46745
46959
  const widthFor = (e) => {
46746
- const v = Number(e.meta["weight"]);
46960
+ const v = Number(e.meta["value"]);
46747
46961
  if (!Number.isFinite(v) || v <= 0 || wMax <= 0) return W_MIN;
46748
46962
  const t = wMax > wMin ? (v - wMin) / (wMax - wMin) : 1;
46749
46963
  return W_MIN + t * (W_MAX - W_MIN);
@@ -47006,8 +47220,8 @@ function layoutMap(resolved, data, size, opts) {
47006
47220
  activeGroup,
47007
47221
  ...hasRamp && {
47008
47222
  ramp: {
47009
- ...resolved.directives.metric !== void 0 && {
47010
- metric: resolved.directives.metric
47223
+ ...resolved.directives.regionMetric !== void 0 && {
47224
+ metric: resolved.directives.regionMetric
47011
47225
  },
47012
47226
  min: rampMin,
47013
47227
  max: rampMax,
@@ -47035,7 +47249,7 @@ function layoutMap(resolved, data, size, opts) {
47035
47249
  insetRegions
47036
47250
  };
47037
47251
  }
47038
- 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;
47252
+ 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;
47039
47253
  var init_layout15 = __esm({
47040
47254
  "src/map/layout.ts"() {
47041
47255
  "use strict";
@@ -47062,6 +47276,11 @@ var init_layout15 = __esm({
47062
47276
  RIVER_WIDTH = 1.3;
47063
47277
  FOREIGN_TINT_LIGHT = 30;
47064
47278
  FOREIGN_TINT_DARK = 62;
47279
+ MUTED_WATER_LIGHT = 14;
47280
+ MUTED_WATER_DARK = 10;
47281
+ MUTED_FOREIGN_LIGHT = 28;
47282
+ MUTED_FOREIGN_DARK = 16;
47283
+ MUTED_LAND_DARK = 24;
47065
47284
  COLO_R = 9;
47066
47285
  GOLDEN_ANGLE = 2.399963229728653;
47067
47286
  FAN_STEP = 16;
@@ -47115,7 +47334,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
47115
47334
  const p = g.append("path").attr("d", r.d).attr("fill", r.fill).attr("stroke", r.stroke).attr("stroke-width", strokeWidth);
47116
47335
  if (r.layer !== "base") {
47117
47336
  p.classed("dgmo-map-region", true).attr("data-region", r.id);
47118
- if (r.score !== void 0) p.attr("data-score", r.score);
47337
+ if (r.value !== void 0) p.attr("data-value", r.value);
47119
47338
  if (r.tags) {
47120
47339
  for (const [group, value] of Object.entries(r.tags)) {
47121
47340
  p.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
@@ -47176,6 +47395,11 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
47176
47395
  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);
47177
47396
  }
47178
47397
  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);
47398
+ if (poi.tags) {
47399
+ for (const [group, value] of Object.entries(poi.tags)) {
47400
+ c.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
47401
+ }
47402
+ }
47179
47403
  if (onClickItem) {
47180
47404
  c.style("cursor", "pointer").on(
47181
47405
  "click",
@@ -47225,7 +47449,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
47225
47449
  const legendG = svg.append("g").attr("class", "dgmo-map-legend").attr("transform", `translate(0, ${legendY})`);
47226
47450
  const ramp = layout.legend.ramp;
47227
47451
  const scoreGroup = ramp ? {
47228
- name: ramp.metric?.trim() || "Score",
47452
+ name: ramp.metric?.trim() || "Value",
47229
47453
  entries: [],
47230
47454
  gradient: {
47231
47455
  min: ramp.min,