@tileflow/core 0.1.0-alpha.29 → 0.1.0-alpha.30
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/README.md +8 -1
- package/dist/browser.d.ts +66 -5
- package/dist/browser.js +1102 -39
- package/dist/build.d.ts +7 -7
- package/dist/build.js +485 -163
- package/dist/config-reference.json +1399 -1153
- package/dist/{icon-composition-BquPlPPI.d.ts → icon-composition-BiOTwrvD.d.ts} +12 -3
- package/dist/index.d.ts +105 -11
- package/dist/index.js +770 -168
- package/dist/{manifest-types-BZU4zbmI.d.ts → manifest-types-CTT2eLbp.d.ts} +42 -1
- package/dist/manifest.d.ts +2 -2
- package/dist/native.js +1 -0
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +28 -0
- package/docs/authoring-model.md +30 -3
- package/docs/data-is-separate-from-design.md +2 -1
- package/docs/shared-visual-primitives.md +61 -2
- package/docs/theme-transitions-and-blends.md +165 -0
- package/package.json +1 -1
package/dist/build.js
CHANGED
|
@@ -504,9 +504,9 @@ function inferTileflowDataRequirements(style, options = {}) {
|
|
|
504
504
|
dynamicAccesses: [...dynamicAccesses].sort(compareCodeUnits),
|
|
505
505
|
schemaVersion: 1,
|
|
506
506
|
sourceId,
|
|
507
|
-
sourceLayers: [...fieldsByLayer].sort(([left], [right]) => compareCodeUnits(left, right)).map(([
|
|
507
|
+
sourceLayers: [...fieldsByLayer].sort(([left], [right]) => compareCodeUnits(left, right)).map(([id2, fields]) => ({
|
|
508
508
|
fields: [...fields].sort(([left], [right]) => compareCodeUnits(left, right)).map(([name, type]) => ({ name, ...type === void 0 ? {} : { type } })),
|
|
509
|
-
id
|
|
509
|
+
id: id2
|
|
510
510
|
}))
|
|
511
511
|
};
|
|
512
512
|
}
|
|
@@ -880,6 +880,47 @@ var tileflowLayerSlots = [
|
|
|
880
880
|
"vegetation",
|
|
881
881
|
"symbols"
|
|
882
882
|
];
|
|
883
|
+
var tileflowLayerBands = [
|
|
884
|
+
"land",
|
|
885
|
+
"relief",
|
|
886
|
+
"water",
|
|
887
|
+
"roads",
|
|
888
|
+
"boundaries",
|
|
889
|
+
"buildings",
|
|
890
|
+
"vegetation",
|
|
891
|
+
"labels"
|
|
892
|
+
];
|
|
893
|
+
var bandSlots = {
|
|
894
|
+
land: ["background", "land"],
|
|
895
|
+
relief: ["terrain", "terrain"],
|
|
896
|
+
water: ["hydro", "hydro"],
|
|
897
|
+
roads: ["transport-areas", "transport-symbols"],
|
|
898
|
+
boundaries: ["boundaries", "boundaries"],
|
|
899
|
+
buildings: ["buildings", "buildings"],
|
|
900
|
+
vegetation: ["vegetation", "vegetation"],
|
|
901
|
+
labels: ["symbols", "symbols"]
|
|
902
|
+
};
|
|
903
|
+
var tileflowBandPlacements = tileflowLayerBands.flatMap(
|
|
904
|
+
(band) => [`below-${band}`, `above-${band}`]
|
|
905
|
+
);
|
|
906
|
+
function tileflowBandPlacementSlot(placement) {
|
|
907
|
+
const [side, band] = splitBandPlacement(placement);
|
|
908
|
+
return bandSlots[band][side === "below" ? 0 : 1];
|
|
909
|
+
}
|
|
910
|
+
function tileflowBandPlacementIndex(slotRanks, placement) {
|
|
911
|
+
const [side, band] = splitBandPlacement(placement);
|
|
912
|
+
const [first, last] = bandSlots[band];
|
|
913
|
+
const threshold = side === "below" ? tileflowLayerSlots.indexOf(first) : tileflowLayerSlots.indexOf(last) + 1;
|
|
914
|
+
const index = slotRanks.findIndex((rank) => rank !== void 0 && rank >= threshold);
|
|
915
|
+
return index < 0 ? slotRanks.length : index;
|
|
916
|
+
}
|
|
917
|
+
function splitBandPlacement(placement) {
|
|
918
|
+
const separator = placement.indexOf("-");
|
|
919
|
+
return [
|
|
920
|
+
placement.slice(0, separator),
|
|
921
|
+
placement.slice(separator + 1)
|
|
922
|
+
];
|
|
923
|
+
}
|
|
883
924
|
var tileflowSemanticTargetPattern = /^[a-z][a-z0-9-]*(?:\.[A-Za-z0-9_-]+)*$/u;
|
|
884
925
|
var tileflowRenderStackOperationNamePattern = /^[a-z][A-Za-z0-9_-]*$/u;
|
|
885
926
|
var tileflowCompilerMetadataKeys = Object.freeze({
|
|
@@ -906,6 +947,98 @@ function typographyTextStyle(typography) {
|
|
|
906
947
|
};
|
|
907
948
|
}
|
|
908
949
|
|
|
950
|
+
// src/cartography/layer-style.ts
|
|
951
|
+
import { Color as Color2 } from "@maplibre/maplibre-gl-style-spec";
|
|
952
|
+
|
|
953
|
+
// src/text-background.ts
|
|
954
|
+
var tileflowLineBackgroundDefaults = Object.freeze({
|
|
955
|
+
letterSpacing: 0,
|
|
956
|
+
lineHeight: 1.2,
|
|
957
|
+
padding: 0.33
|
|
958
|
+
});
|
|
959
|
+
var tileflowLineBackgroundLimits = Object.freeze({
|
|
960
|
+
letterSpacing: Object.freeze({ max: 0.5, min: 0 }),
|
|
961
|
+
lineHeight: Object.freeze({ max: 3, min: 0.8 }),
|
|
962
|
+
padding: Object.freeze({ max: 1, min: 0 })
|
|
963
|
+
});
|
|
964
|
+
var tileflowLineBackgroundHaloRatio = 1 / 6;
|
|
965
|
+
var STACK_PATTERN = /^(.+) lines-v1-t(\d{1,3})-l(\d{3,4})-p(\d{1,4})$/u;
|
|
966
|
+
var SOURCE_PATTERN = /^[\p{L}\p{N} _.-]+$/u;
|
|
967
|
+
var MAX_STACK_LENGTH = 256;
|
|
968
|
+
function thousandths(value) {
|
|
969
|
+
return Math.round(value * 1e3);
|
|
970
|
+
}
|
|
971
|
+
function normalizeTileflowLineBackgroundMetrics(metrics = {}) {
|
|
972
|
+
const resolved = { ...tileflowLineBackgroundDefaults, ...metrics };
|
|
973
|
+
const normalized = {};
|
|
974
|
+
for (const key of ["letterSpacing", "lineHeight", "padding"]) {
|
|
975
|
+
const value = resolved[key];
|
|
976
|
+
const { max, min } = tileflowLineBackgroundLimits[key];
|
|
977
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < min || value > max) {
|
|
978
|
+
throw new RangeError(
|
|
979
|
+
`Line-fitted text background ${key} must be a constant number from ${min} to ${max} ems.`
|
|
980
|
+
);
|
|
981
|
+
}
|
|
982
|
+
normalized[key] = thousandths(value) / 1e3;
|
|
983
|
+
}
|
|
984
|
+
return normalized;
|
|
985
|
+
}
|
|
986
|
+
function createTileflowLineBackgroundFontStack(source, metrics = {}) {
|
|
987
|
+
if (!SOURCE_PATTERN.test(source) || source !== source.trim()) {
|
|
988
|
+
throw new TypeError(
|
|
989
|
+
`Line-fitted text backgrounds need one exact font stack of letters, numbers, spaces, underscores, dots or hyphens; received "${source}".`
|
|
990
|
+
);
|
|
991
|
+
}
|
|
992
|
+
if (parseTileflowLineBackgroundFontStack(source)) {
|
|
993
|
+
throw new TypeError(`Font stack "${source}" is already a line-fitted background stack.`);
|
|
994
|
+
}
|
|
995
|
+
const { letterSpacing, lineHeight, padding } = normalizeTileflowLineBackgroundMetrics(metrics);
|
|
996
|
+
const stack = `${source} lines-v1-t${thousandths(letterSpacing)}-l${thousandths(lineHeight)}-p${thousandths(padding)}`;
|
|
997
|
+
if (stack.length > MAX_STACK_LENGTH) {
|
|
998
|
+
throw new RangeError(
|
|
999
|
+
`Line-fitted text background font stack exceeds ${MAX_STACK_LENGTH} characters.`
|
|
1000
|
+
);
|
|
1001
|
+
}
|
|
1002
|
+
return stack;
|
|
1003
|
+
}
|
|
1004
|
+
function parseTileflowLineBackgroundFontStack(stack) {
|
|
1005
|
+
const match2 = STACK_PATTERN.exec(stack);
|
|
1006
|
+
if (!match2 || stack.length > MAX_STACK_LENGTH || !SOURCE_PATTERN.test(match2[1]))
|
|
1007
|
+
return void 0;
|
|
1008
|
+
const metrics = {
|
|
1009
|
+
letterSpacing: Number(match2[2]) / 1e3,
|
|
1010
|
+
lineHeight: Number(match2[3]) / 1e3,
|
|
1011
|
+
padding: Number(match2[4]) / 1e3
|
|
1012
|
+
};
|
|
1013
|
+
try {
|
|
1014
|
+
const normalized = normalizeTileflowLineBackgroundMetrics(metrics);
|
|
1015
|
+
if (`lines-v1-t${thousandths(normalized.letterSpacing)}-l${thousandths(normalized.lineHeight)}-p${thousandths(normalized.padding)}` !== stack.slice(match2[1].length + 1)) {
|
|
1016
|
+
return void 0;
|
|
1017
|
+
}
|
|
1018
|
+
return { metrics: normalized, source: match2[1] };
|
|
1019
|
+
} catch {
|
|
1020
|
+
return void 0;
|
|
1021
|
+
}
|
|
1022
|
+
}
|
|
1023
|
+
function scaleTileflowTextSizeForLineBackground(size) {
|
|
1024
|
+
const ratio = tileflowLineBackgroundHaloRatio;
|
|
1025
|
+
const scale = (output) => typeof output === "number" ? output * ratio : ["*", ratio, output];
|
|
1026
|
+
if (size === void 0) return 16 * ratio;
|
|
1027
|
+
if (typeof size === "number") return size * ratio;
|
|
1028
|
+
if (Array.isArray(size) && size[0] === "interpolate" && isZoomInput(size[2])) {
|
|
1029
|
+
return size.map((entry, index) => index >= 4 && index % 2 === 0 ? scale(entry) : entry);
|
|
1030
|
+
}
|
|
1031
|
+
if (Array.isArray(size) && size[0] === "step" && isZoomInput(size[1])) {
|
|
1032
|
+
return size.map(
|
|
1033
|
+
(entry, index) => index === 2 || index >= 4 && index % 2 === 0 ? scale(entry) : entry
|
|
1034
|
+
);
|
|
1035
|
+
}
|
|
1036
|
+
return ["*", ratio, size];
|
|
1037
|
+
}
|
|
1038
|
+
function isZoomInput(value) {
|
|
1039
|
+
return Array.isArray(value) && value.length === 1 && value[0] === "zoom";
|
|
1040
|
+
}
|
|
1041
|
+
|
|
909
1042
|
// src/cartography/expression-operators.ts
|
|
910
1043
|
var mapLibreExpressionOperators = /* @__PURE__ */ new Set([
|
|
911
1044
|
"!",
|
|
@@ -1216,8 +1349,52 @@ function applyTextStyle(layer, style) {
|
|
|
1216
1349
|
setPaint(paint, "text-halo-color", style.haloColor);
|
|
1217
1350
|
setPaint(paint, "text-halo-width", style.haloWidth);
|
|
1218
1351
|
setPaint(paint, "text-opacity", style.opacity);
|
|
1352
|
+
applyLineBackground(layer.id, layout, paint, style, backedFontStack(asRecord(layer.layout)));
|
|
1219
1353
|
return applyLayerRange(withLayerParts(layer, layout, paint), style);
|
|
1220
1354
|
}
|
|
1355
|
+
function applyLineBackground(id2, layout, paint, style, previous) {
|
|
1356
|
+
const fonts = layout["text-font"];
|
|
1357
|
+
const single = Array.isArray(fonts) && fonts.length === 1 && typeof fonts[0] === "string";
|
|
1358
|
+
const current = backedFontStack(layout);
|
|
1359
|
+
const background = style.background;
|
|
1360
|
+
if (!background && !current && !previous) return;
|
|
1361
|
+
if (!single) {
|
|
1362
|
+
throw new Error(
|
|
1363
|
+
`Layer "${id2}" needs exactly one text font without fallbacks for a line-fitted background.`
|
|
1364
|
+
);
|
|
1365
|
+
}
|
|
1366
|
+
const padding = background?.padding === void 0 ? (current ?? previous)?.metrics.padding ?? tileflowLineBackgroundDefaults.padding : constantNumber(id2, toMapLibreStyleValue(background.padding), "background padding");
|
|
1367
|
+
const stack = createTileflowLineBackgroundFontStack(current?.source ?? fonts[0], {
|
|
1368
|
+
letterSpacing: constantNumber(id2, layout["text-letter-spacing"] ?? 0, "letterSpacing"),
|
|
1369
|
+
lineHeight: constantNumber(id2, layout["text-line-height"] ?? 1.2, "lineHeight"),
|
|
1370
|
+
padding
|
|
1371
|
+
});
|
|
1372
|
+
const { metrics } = parseTileflowLineBackgroundFontStack(stack);
|
|
1373
|
+
layout["text-font"] = [stack];
|
|
1374
|
+
layout["text-letter-spacing"] = metrics.letterSpacing;
|
|
1375
|
+
layout["text-line-height"] = metrics.lineHeight;
|
|
1376
|
+
if (background) {
|
|
1377
|
+
const color2 = toMapLibreStyleValue(background.color);
|
|
1378
|
+
if (typeof color2 === "string" && (Color2.parse(color2)?.a ?? 1) < 1) {
|
|
1379
|
+
throw new Error(
|
|
1380
|
+
`Layer "${id2}" needs an opaque line-fitted background colour; "${color2}" is translucent.`
|
|
1381
|
+
);
|
|
1382
|
+
}
|
|
1383
|
+
paint["text-halo-color"] = color2;
|
|
1384
|
+
}
|
|
1385
|
+
paint["text-halo-width"] = scaleTileflowTextSizeForLineBackground(layout["text-size"]);
|
|
1386
|
+
paint["text-halo-blur"] = 0;
|
|
1387
|
+
}
|
|
1388
|
+
function backedFontStack(layout) {
|
|
1389
|
+
const fonts = layout["text-font"];
|
|
1390
|
+
return Array.isArray(fonts) && fonts.length === 1 && typeof fonts[0] === "string" ? parseTileflowLineBackgroundFontStack(fonts[0]) : void 0;
|
|
1391
|
+
}
|
|
1392
|
+
function constantNumber(id2, value, property) {
|
|
1393
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
1394
|
+
throw new Error(
|
|
1395
|
+
`Layer "${id2}" uses a line-fitted text background, so its ${property} must be a constant number.`
|
|
1396
|
+
);
|
|
1397
|
+
}
|
|
1221
1398
|
function applyIconStyle(layer, style) {
|
|
1222
1399
|
const paint = { ...asRecord(layer.paint) };
|
|
1223
1400
|
const layout = { ...asRecord(layer.layout) };
|
|
@@ -1360,12 +1537,12 @@ function setLayout(layout, property, value) {
|
|
|
1360
1537
|
function invertPriority(value) {
|
|
1361
1538
|
const resolved = toMapLibreStyleValue(value);
|
|
1362
1539
|
if (typeof resolved === "number") return -resolved;
|
|
1363
|
-
if (Array.isArray(resolved) && resolved[0] === "interpolate" &&
|
|
1540
|
+
if (Array.isArray(resolved) && resolved[0] === "interpolate" && isZoomInput2(resolved[2])) {
|
|
1364
1541
|
return resolved.map(
|
|
1365
1542
|
(entry, index) => index >= 4 && index % 2 === 0 ? negateExpressionOutput(entry) : entry
|
|
1366
1543
|
);
|
|
1367
1544
|
}
|
|
1368
|
-
if (Array.isArray(resolved) && resolved[0] === "step" &&
|
|
1545
|
+
if (Array.isArray(resolved) && resolved[0] === "step" && isZoomInput2(resolved[1])) {
|
|
1369
1546
|
return resolved.map(
|
|
1370
1547
|
(entry, index) => index === 2 || index >= 4 && index % 2 === 0 ? negateExpressionOutput(entry) : entry
|
|
1371
1548
|
);
|
|
@@ -1378,7 +1555,7 @@ function resolvePriority(value, order) {
|
|
|
1378
1555
|
function negateExpressionOutput(value) {
|
|
1379
1556
|
return typeof value === "number" ? -value : ["*", -1, value];
|
|
1380
1557
|
}
|
|
1381
|
-
function
|
|
1558
|
+
function isZoomInput2(value) {
|
|
1382
1559
|
return Array.isArray(value) && value.length === 1 && value[0] === "zoom";
|
|
1383
1560
|
}
|
|
1384
1561
|
function asRecord(value) {
|
|
@@ -1569,7 +1746,7 @@ function compileAeroways(request, context) {
|
|
|
1569
1746
|
["taxiway", config.taxiway, 10],
|
|
1570
1747
|
["runway", config.runway, 20]
|
|
1571
1748
|
]) {
|
|
1572
|
-
for (const [phase, style,
|
|
1749
|
+
for (const [phase, style, phaseOrder] of [
|
|
1573
1750
|
["shadow", target?.shadow, 0],
|
|
1574
1751
|
["casing", target?.casing, 1],
|
|
1575
1752
|
["fill", target?.fill, 2]
|
|
@@ -1591,7 +1768,7 @@ function compileAeroways(request, context) {
|
|
|
1591
1768
|
},
|
|
1592
1769
|
style
|
|
1593
1770
|
),
|
|
1594
|
-
localOrder: order +
|
|
1771
|
+
localOrder: order + phaseOrder,
|
|
1595
1772
|
owner: "aeroways",
|
|
1596
1773
|
slot: "aeroways",
|
|
1597
1774
|
target: `aeroways.${name}.${phase}`
|
|
@@ -2373,14 +2550,14 @@ function compileLabels(request, roadRequest, context) {
|
|
|
2373
2550
|
for (const placeClass of visiblePlaceClasses) {
|
|
2374
2551
|
const style = styles.places?.[placeClass];
|
|
2375
2552
|
if (!style || style.visible === false || style.text?.visible === false) continue;
|
|
2376
|
-
const
|
|
2553
|
+
const id2 = `tileflow-label-place-${placeClass}`;
|
|
2377
2554
|
result.push(
|
|
2378
2555
|
symbolContribution(
|
|
2379
2556
|
`labels.places.${placeClass}`,
|
|
2380
2557
|
(navigationPriority ? 1300 : 800) + order++,
|
|
2381
2558
|
applySymbolStyle(
|
|
2382
2559
|
{
|
|
2383
|
-
id,
|
|
2560
|
+
id: id2,
|
|
2384
2561
|
type: "symbol",
|
|
2385
2562
|
source,
|
|
2386
2563
|
"source-layer": schema.layers.place,
|
|
@@ -2405,14 +2582,14 @@ function compileLabels(request, roadRequest, context) {
|
|
|
2405
2582
|
for (const roadClass of orderedRoads) {
|
|
2406
2583
|
const style = styles.roads?.[roadClass];
|
|
2407
2584
|
if (!style || style.visible === false || style.text?.visible === false) continue;
|
|
2408
|
-
const
|
|
2585
|
+
const id2 = `tileflow-label-road-${roadClass}`;
|
|
2409
2586
|
result.push(
|
|
2410
2587
|
symbolContribution(
|
|
2411
2588
|
`labels.roads.${roadClass}`,
|
|
2412
2589
|
(navigationPriority ? 1200 : 200) + order++,
|
|
2413
2590
|
applySymbolStyle(
|
|
2414
2591
|
{
|
|
2415
|
-
id,
|
|
2592
|
+
id: id2,
|
|
2416
2593
|
type: "symbol",
|
|
2417
2594
|
source,
|
|
2418
2595
|
"source-layer": schema.layers.roadName,
|
|
@@ -2424,7 +2601,7 @@ function compileLabels(request, roadRequest, context) {
|
|
|
2424
2601
|
},
|
|
2425
2602
|
mergeTileflowDesign(style, { text: { field: field2 } })
|
|
2426
2603
|
),
|
|
2427
|
-
|
|
2604
|
+
"symbols",
|
|
2428
2605
|
{ group: "roads", kind: "road-label", member: roadClass }
|
|
2429
2606
|
)
|
|
2430
2607
|
);
|
|
@@ -2516,8 +2693,7 @@ function compileLabels(request, roadRequest, context) {
|
|
|
2516
2693
|
]
|
|
2517
2694
|
},
|
|
2518
2695
|
style
|
|
2519
|
-
)
|
|
2520
|
-
"transport-symbols"
|
|
2696
|
+
)
|
|
2521
2697
|
)
|
|
2522
2698
|
);
|
|
2523
2699
|
}
|
|
@@ -2555,8 +2731,7 @@ function compileLabels(request, roadRequest, context) {
|
|
|
2555
2731
|
])
|
|
2556
2732
|
}
|
|
2557
2733
|
})
|
|
2558
|
-
)
|
|
2559
|
-
"transport-symbols"
|
|
2734
|
+
)
|
|
2560
2735
|
)
|
|
2561
2736
|
);
|
|
2562
2737
|
}
|
|
@@ -6608,10 +6783,10 @@ function isExpressionOutput(value) {
|
|
|
6608
6783
|
}
|
|
6609
6784
|
function rewriteZoomOutputs(value, rewrite) {
|
|
6610
6785
|
if (!Array.isArray(value)) return rewrite(value);
|
|
6611
|
-
if (value[0] === "interpolate" &&
|
|
6786
|
+
if (value[0] === "interpolate" && isZoomInput3(value[2])) {
|
|
6612
6787
|
return value.map((entry, index) => index >= 4 && index % 2 === 0 ? rewrite(entry) : entry);
|
|
6613
6788
|
}
|
|
6614
|
-
if (value[0] === "step" &&
|
|
6789
|
+
if (value[0] === "step" && isZoomInput3(value[1])) {
|
|
6615
6790
|
return value.map(
|
|
6616
6791
|
(entry, index) => index === 2 || index >= 4 && index % 2 === 0 ? rewrite(entry) : entry
|
|
6617
6792
|
);
|
|
@@ -6621,7 +6796,7 @@ function rewriteZoomOutputs(value, rewrite) {
|
|
|
6621
6796
|
function expressionOutput(value) {
|
|
6622
6797
|
return Array.isArray(value) && typeof value[0] !== "string" ? ["literal", value] : value;
|
|
6623
6798
|
}
|
|
6624
|
-
function
|
|
6799
|
+
function isZoomInput3(value) {
|
|
6625
6800
|
return Array.isArray(value) && value.length === 1 && value[0] === "zoom";
|
|
6626
6801
|
}
|
|
6627
6802
|
function restrictedAccessFilter(field2) {
|
|
@@ -8048,7 +8223,7 @@ function insertTileflowOverlays(input) {
|
|
|
8048
8223
|
});
|
|
8049
8224
|
groups.set(overlay.placement, [...groups.get(overlay.placement) ?? [], ...layers2]);
|
|
8050
8225
|
identities[overlayId] = Object.freeze({
|
|
8051
|
-
layers: Object.freeze(overlay.layers.map(({ id }) =>
|
|
8226
|
+
layers: Object.freeze(overlay.layers.map(({ id: id2 }) => id2)),
|
|
8052
8227
|
placement: overlay.placement,
|
|
8053
8228
|
source: overlay.source
|
|
8054
8229
|
});
|
|
@@ -8085,22 +8260,13 @@ function cloneJson18(value) {
|
|
|
8085
8260
|
);
|
|
8086
8261
|
}
|
|
8087
8262
|
function tileflowOverlayInsertionIndex(layers, placement) {
|
|
8088
|
-
const
|
|
8089
|
-
|
|
8090
|
-
"below-roads": tileflowLayerSlots.indexOf("transport-areas"),
|
|
8091
|
-
"above-roads": tileflowLayerSlots.indexOf("boundaries"),
|
|
8092
|
-
"above-buildings": tileflowLayerSlots.indexOf("vegetation"),
|
|
8093
|
-
"below-labels": tileflowLayerSlots.indexOf("symbols"),
|
|
8094
|
-
"above-labels": Number.POSITIVE_INFINITY
|
|
8095
|
-
}[placement];
|
|
8096
|
-
if (!Number.isFinite(threshold)) return layers.length;
|
|
8097
|
-
const index = layers.findIndex((layer) => {
|
|
8098
|
-
const ranks = readTileflowCompilerProvenance(layer).map(
|
|
8263
|
+
const ranks = layers.map((layer) => {
|
|
8264
|
+
const slots = readTileflowCompilerProvenance(layer).map(
|
|
8099
8265
|
({ slot }) => tileflowLayerSlots.indexOf(slot)
|
|
8100
8266
|
);
|
|
8101
|
-
return
|
|
8267
|
+
return slots.length > 0 ? Math.min(...slots) : void 0;
|
|
8102
8268
|
});
|
|
8103
|
-
return
|
|
8269
|
+
return tileflowBandPlacementIndex(ranks, placement);
|
|
8104
8270
|
}
|
|
8105
8271
|
function compareCodeUnits4(left, right) {
|
|
8106
8272
|
return left < right ? -1 : left > right ? 1 : 0;
|
|
@@ -8112,7 +8278,7 @@ function isPlainRecord2(value) {
|
|
|
8112
8278
|
}
|
|
8113
8279
|
|
|
8114
8280
|
// src/resolved-map-schema.ts
|
|
8115
|
-
import { Color as
|
|
8281
|
+
import { Color as Color3 } from "@maplibre/maplibre-gl-style-spec";
|
|
8116
8282
|
import { z as z5 } from "zod";
|
|
8117
8283
|
|
|
8118
8284
|
// src/cartography/data-expression.ts
|
|
@@ -8130,6 +8296,9 @@ function literal(value) {
|
|
|
8130
8296
|
function zoom2() {
|
|
8131
8297
|
return make(["zoom"]);
|
|
8132
8298
|
}
|
|
8299
|
+
function id() {
|
|
8300
|
+
return make(["id"]);
|
|
8301
|
+
}
|
|
8133
8302
|
function coalesce(first, ...rest) {
|
|
8134
8303
|
if (rest.length === 0) throw new Error("expr.coalesce requires at least two values.");
|
|
8135
8304
|
validateOperandCount(1 + rest.length, "expr.coalesce");
|
|
@@ -8180,6 +8349,9 @@ function subtract(first, second) {
|
|
|
8180
8349
|
function divide(dividend, divisor) {
|
|
8181
8350
|
return make(["/", node(dividend), node(divisor)]);
|
|
8182
8351
|
}
|
|
8352
|
+
function modulo(dividend, divisor) {
|
|
8353
|
+
return make(["%", node(dividend), node(divisor)]);
|
|
8354
|
+
}
|
|
8183
8355
|
function multiply(first, second, ...rest) {
|
|
8184
8356
|
validateOperandCount(2 + rest.length, "expr.multiply");
|
|
8185
8357
|
return make(["*", node(first), node(second), ...rest.map(node)]);
|
|
@@ -8385,6 +8557,7 @@ function visitExpression(value, path, variables, issues) {
|
|
|
8385
8557
|
}
|
|
8386
8558
|
return;
|
|
8387
8559
|
}
|
|
8560
|
+
case "id":
|
|
8388
8561
|
case "zoom": {
|
|
8389
8562
|
exact(1);
|
|
8390
8563
|
return;
|
|
@@ -8434,6 +8607,7 @@ function visitExpression(value, path, variables, issues) {
|
|
|
8434
8607
|
}
|
|
8435
8608
|
case "-":
|
|
8436
8609
|
case "/":
|
|
8610
|
+
case "%":
|
|
8437
8611
|
case "!=":
|
|
8438
8612
|
case "<":
|
|
8439
8613
|
case "<=":
|
|
@@ -8658,6 +8832,7 @@ var expr = Object.freeze({
|
|
|
8658
8832
|
gt: (left, right) => compare(">", left, right),
|
|
8659
8833
|
gte: (left, right) => compare(">=", left, right),
|
|
8660
8834
|
has,
|
|
8835
|
+
id,
|
|
8661
8836
|
featureState,
|
|
8662
8837
|
interpolate: interpolate2,
|
|
8663
8838
|
let: letValue,
|
|
@@ -8667,6 +8842,7 @@ var expr = Object.freeze({
|
|
|
8667
8842
|
match,
|
|
8668
8843
|
max: maximum,
|
|
8669
8844
|
min: minimum,
|
|
8845
|
+
modulo,
|
|
8670
8846
|
multiply,
|
|
8671
8847
|
ne: (left, right) => compare("!=", left, right),
|
|
8672
8848
|
not,
|
|
@@ -8799,7 +8975,7 @@ function createTileflowLayerFamilyIR(contribution) {
|
|
|
8799
8975
|
function createTileflowLayerTemplateIR(layer, semanticKey) {
|
|
8800
8976
|
const {
|
|
8801
8977
|
filter,
|
|
8802
|
-
id,
|
|
8978
|
+
id: id2,
|
|
8803
8979
|
layout,
|
|
8804
8980
|
maxzoom,
|
|
8805
8981
|
metadata,
|
|
@@ -8810,7 +8986,7 @@ function createTileflowLayerTemplateIR(layer, semanticKey) {
|
|
|
8810
8986
|
type,
|
|
8811
8987
|
...properties2
|
|
8812
8988
|
} = layer;
|
|
8813
|
-
if (typeof
|
|
8989
|
+
if (typeof id2 !== "string" || !id2.trim()) {
|
|
8814
8990
|
throw new TileflowDomainIRError(
|
|
8815
8991
|
"TILEFLOW_DOMAIN_IR_INVALID_KEY",
|
|
8816
8992
|
"Layer key must not be empty."
|
|
@@ -8825,7 +9001,7 @@ function createTileflowLayerTemplateIR(layer, semanticKey) {
|
|
|
8825
9001
|
if (typeof type !== "string" || !type.trim()) {
|
|
8826
9002
|
throw new TileflowDomainIRError(
|
|
8827
9003
|
"TILEFLOW_DOMAIN_IR_INVALID_RENDERER",
|
|
8828
|
-
`Layer family ${
|
|
9004
|
+
`Layer family ${id2} requires a renderer.`
|
|
8829
9005
|
);
|
|
8830
9006
|
}
|
|
8831
9007
|
const annotations = publicMetadata(metadata);
|
|
@@ -9107,13 +9283,6 @@ function isRecord5(value) {
|
|
|
9107
9283
|
}
|
|
9108
9284
|
|
|
9109
9285
|
// src/cartography/render-stack.ts
|
|
9110
|
-
var tileflowRenderStackPhases = [
|
|
9111
|
-
"underlay",
|
|
9112
|
-
"overlay",
|
|
9113
|
-
"postRelief",
|
|
9114
|
-
"annotation",
|
|
9115
|
-
"finish"
|
|
9116
|
-
];
|
|
9117
9286
|
var tileflowRenderStackRenderers = [
|
|
9118
9287
|
"background",
|
|
9119
9288
|
"circle",
|
|
@@ -9309,7 +9478,6 @@ var geometryTypes = {
|
|
|
9309
9478
|
point: "Point",
|
|
9310
9479
|
polygon: "Polygon"
|
|
9311
9480
|
};
|
|
9312
|
-
var phaseOrder = new Map(tileflowRenderStackPhases.map((phase, index) => [phase, index]));
|
|
9313
9481
|
function compileRenderStack(module, data) {
|
|
9314
9482
|
if (!tileflowLayerDomains.includes(module.type)) {
|
|
9315
9483
|
throw renderStackError("invalid-owner", `Unknown render-stack owner: ${String(module.type)}.`);
|
|
@@ -9327,71 +9495,118 @@ function compileRenderSelector(selector, data) {
|
|
|
9327
9495
|
}
|
|
9328
9496
|
function applyCompiledRenderStacks(input, operations) {
|
|
9329
9497
|
let layers = input.map(cloneJson21);
|
|
9330
|
-
const
|
|
9331
|
-
const layerOperations = operations.filter(
|
|
9498
|
+
const passes = operations.filter(
|
|
9332
9499
|
(operation) => operation.kind === "layer"
|
|
9333
9500
|
);
|
|
9334
|
-
const
|
|
9335
|
-
|
|
9336
|
-
(operation) => operation.requirements.some((requirement) => !activeOwners.has(requirement))
|
|
9337
|
-
).map((operation) => operation.target)
|
|
9501
|
+
const refinements = operations.filter(
|
|
9502
|
+
(operation) => operation.kind === "refinement"
|
|
9338
9503
|
);
|
|
9339
|
-
|
|
9340
|
-
|
|
9504
|
+
requireUniqueCompiledLayers(layers, passes);
|
|
9505
|
+
const passTargets = new Set(passes.map(({ target }) => target));
|
|
9506
|
+
const knownTargets = /* @__PURE__ */ new Set([...layers.map(({ target }) => target), ...passTargets]);
|
|
9507
|
+
const activeOwners = new Set(layers.map(({ owner }) => owner));
|
|
9508
|
+
const drawn = /* @__PURE__ */ new Set();
|
|
9509
|
+
for (let changed = true; changed; ) {
|
|
9341
9510
|
changed = false;
|
|
9342
|
-
for (const
|
|
9343
|
-
if (
|
|
9344
|
-
|
|
9345
|
-
|
|
9346
|
-
|
|
9511
|
+
for (const pass of passes) {
|
|
9512
|
+
if (drawn.has(pass.target)) continue;
|
|
9513
|
+
const anchor = placementAnchor(pass.placement);
|
|
9514
|
+
if (pass.requirements.some((requirement) => !activeOwners.has(requirement))) continue;
|
|
9515
|
+
if (anchor !== void 0 && passTargets.has(anchor) && !drawn.has(anchor)) continue;
|
|
9516
|
+
drawn.add(pass.target);
|
|
9517
|
+
activeOwners.add(pass.owner);
|
|
9518
|
+
changed = true;
|
|
9519
|
+
}
|
|
9520
|
+
}
|
|
9521
|
+
const activeRefinements = refinements.filter(
|
|
9522
|
+
(refinement) => refinement.requirements.every((requirement) => activeOwners.has(requirement))
|
|
9523
|
+
).sort(compareCompiledOperations);
|
|
9524
|
+
for (const refinement of activeRefinements) {
|
|
9525
|
+
const index = findTargetIndex(layers, refinement.target);
|
|
9526
|
+
if (index < 0 && !passTargets.has(refinement.target)) {
|
|
9527
|
+
throw renderStackError(
|
|
9528
|
+
"unknown-refinement-target",
|
|
9529
|
+
`Render refinement targets unknown semantic contribution: ${refinement.target}.`
|
|
9530
|
+
);
|
|
9347
9531
|
}
|
|
9348
|
-
|
|
9349
|
-
const pending = layerOperations.filter((operation) => !suppressedTargets.has(operation.target)).sort(compareCompiledOperations);
|
|
9350
|
-
requireUniqueCompiledLayers(layers, pending);
|
|
9351
|
-
while (pending.length > 0) {
|
|
9352
|
-
const ready = pending.find((operation) => findTargetIndex(layers, operation.attachTo) >= 0);
|
|
9353
|
-
if (!ready) {
|
|
9532
|
+
if (refinement.placement !== void 0 && placementAnchor(refinement.placement) === refinement.target) {
|
|
9354
9533
|
throw renderStackError(
|
|
9355
9534
|
"unknown-or-circular-anchor",
|
|
9356
|
-
`Render
|
|
9535
|
+
`Render refinement ${refinement.target} cannot be placed beside itself.`
|
|
9357
9536
|
);
|
|
9358
9537
|
}
|
|
9359
|
-
const anchorTarget = ready.attachTo;
|
|
9360
|
-
const group = pending.filter((operation) => operation.attachTo === anchorTarget).sort(compareCompiledOperations);
|
|
9361
|
-
const anchorIndex = findTargetIndex(layers, anchorTarget);
|
|
9362
|
-
const anchor = layers[anchorIndex];
|
|
9363
|
-
const before = group.filter((operation) => operation.phase === "underlay").map((operation) => materializeRenderLayer(operation, anchor));
|
|
9364
|
-
const after = group.filter((operation) => operation.phase !== "underlay").map((operation) => materializeRenderLayer(operation, anchor));
|
|
9365
|
-
layers = [
|
|
9366
|
-
...layers.slice(0, anchorIndex),
|
|
9367
|
-
...before,
|
|
9368
|
-
anchor,
|
|
9369
|
-
...after,
|
|
9370
|
-
...layers.slice(anchorIndex + 1)
|
|
9371
|
-
];
|
|
9372
|
-
for (const operation of group) pending.splice(pending.indexOf(operation), 1);
|
|
9373
9538
|
}
|
|
9374
|
-
const
|
|
9375
|
-
|
|
9376
|
-
|
|
9377
|
-
(
|
|
9378
|
-
|
|
9379
|
-
|
|
9380
|
-
|
|
9381
|
-
|
|
9539
|
+
const isDrawn = (target) => !passTargets.has(target) || drawn.has(target);
|
|
9540
|
+
const pending = [
|
|
9541
|
+
...passes.filter(({ target }) => drawn.has(target)),
|
|
9542
|
+
...activeRefinements.filter(({ placement, target }) => {
|
|
9543
|
+
if (placement === void 0 || !isDrawn(target)) return false;
|
|
9544
|
+
const anchor = placementAnchor(placement);
|
|
9545
|
+
return anchor === void 0 || isDrawn(anchor);
|
|
9546
|
+
})
|
|
9547
|
+
].sort(compareCompiledOperations);
|
|
9548
|
+
for (const operation of pending) {
|
|
9549
|
+
const anchor = placementAnchor(operation.placement);
|
|
9550
|
+
if (anchor !== void 0 && !knownTargets.has(anchor)) {
|
|
9382
9551
|
throw renderStackError(
|
|
9383
|
-
"unknown-
|
|
9384
|
-
|
|
9552
|
+
"unknown-or-circular-anchor",
|
|
9553
|
+
`${operation.target} is placed beside unknown semantic target ${anchor}.`
|
|
9385
9554
|
);
|
|
9386
9555
|
}
|
|
9387
|
-
|
|
9388
|
-
|
|
9389
|
-
|
|
9556
|
+
}
|
|
9557
|
+
const lastPlaced = /* @__PURE__ */ new Map();
|
|
9558
|
+
const isMovePending = (target) => pending.some((operation) => operation.kind === "refinement" && operation.target === target);
|
|
9559
|
+
const isReady = (operation) => {
|
|
9560
|
+
if (operation.kind === "refinement" && findTargetIndex(layers, operation.target) < 0) {
|
|
9561
|
+
return false;
|
|
9562
|
+
}
|
|
9563
|
+
const anchor = placementAnchor(operation.placement);
|
|
9564
|
+
return anchor === void 0 || findTargetIndex(layers, anchor) >= 0 && !isMovePending(anchor);
|
|
9565
|
+
};
|
|
9566
|
+
while (pending.length > 0) {
|
|
9567
|
+
const first = pending.find(isReady);
|
|
9568
|
+
if (first === void 0) {
|
|
9390
9569
|
throw renderStackError(
|
|
9391
|
-
"
|
|
9392
|
-
`Render
|
|
9570
|
+
"unknown-or-circular-anchor",
|
|
9571
|
+
`Render operations are placed beside circular anchors: ${pending.map((operation) => `${operation.target}->${placementKey(operation.placement)}`).join(", ")}.`
|
|
9393
9572
|
);
|
|
9394
9573
|
}
|
|
9574
|
+
const key = placementKey(first.placement);
|
|
9575
|
+
const group = pending.filter(
|
|
9576
|
+
(operation) => placementKey(operation.placement) === key && isReady(operation)
|
|
9577
|
+
);
|
|
9578
|
+
for (const operation of group) pending.splice(pending.indexOf(operation), 1);
|
|
9579
|
+
const moved = /* @__PURE__ */ new Map();
|
|
9580
|
+
for (const operation of group) {
|
|
9581
|
+
if (operation.kind !== "refinement") continue;
|
|
9582
|
+
const index2 = findTargetIndex(layers, operation.target);
|
|
9583
|
+
moved.set(operation.target, requireRefinementOwner(layers[index2], operation));
|
|
9584
|
+
layers = [...layers.slice(0, index2), ...layers.slice(index2 + 1)];
|
|
9585
|
+
for (const [placed, target] of lastPlaced) {
|
|
9586
|
+
if (target === operation.target) lastPlaced.delete(placed);
|
|
9587
|
+
}
|
|
9588
|
+
}
|
|
9589
|
+
const placement = first.placement;
|
|
9590
|
+
const anchor = placementAnchor(placement);
|
|
9591
|
+
const anchorLayer = anchor === void 0 ? void 0 : layers[findTargetIndex(layers, anchor)];
|
|
9592
|
+
const slot = anchorLayer === void 0 ? tileflowBandPlacementSlot(placement) : requireSemanticSlot(anchorLayer, anchor);
|
|
9593
|
+
const block = group.map(
|
|
9594
|
+
(operation) => operation.kind === "layer" ? materializeRenderLayer(operation, anchorLayer, slot) : moveLayer(moved.get(operation.target), operation, slot, anchorLayer)
|
|
9595
|
+
);
|
|
9596
|
+
const previous = lastPlaced.get(key);
|
|
9597
|
+
const previousIndex = previous === void 0 ? -1 : findTargetIndex(layers, previous);
|
|
9598
|
+
const index = anchorLayer !== void 0 ? findTargetIndex(layers, anchor) + (key.startsWith("above:") ? 1 : 0) : previousIndex >= 0 ? previousIndex + 1 : tileflowBandPlacementIndex(
|
|
9599
|
+
layers.map((candidate) => tileflowLayerSlots.indexOf(candidate.slot)),
|
|
9600
|
+
placement
|
|
9601
|
+
);
|
|
9602
|
+
layers = [...layers.slice(0, index), ...block, ...layers.slice(index)];
|
|
9603
|
+
lastPlaced.set(key, block.at(-1).target);
|
|
9604
|
+
}
|
|
9605
|
+
for (const refinement of activeRefinements) {
|
|
9606
|
+
if (refinement.patch === void 0) continue;
|
|
9607
|
+
const index = findTargetIndex(layers, refinement.target);
|
|
9608
|
+
if (index < 0) continue;
|
|
9609
|
+
const previous = requireRefinementOwner(layers[index], refinement);
|
|
9395
9610
|
const expectedType = rendererLayerType(refinement.renderer);
|
|
9396
9611
|
if (previous.renderer !== expectedType) {
|
|
9397
9612
|
throw renderStackError(
|
|
@@ -9399,26 +9614,48 @@ function applyCompiledRenderStacks(input, operations) {
|
|
|
9399
9614
|
`Render refinement ${refinement.target} expects ${expectedType}, found ${String(previous.renderer)}.`
|
|
9400
9615
|
);
|
|
9401
9616
|
}
|
|
9402
|
-
layers[index] = applyRefinement(previous, refinement);
|
|
9617
|
+
layers[index] = applyRefinement(previous, { ...refinement, patch: refinement.patch });
|
|
9403
9618
|
}
|
|
9404
9619
|
return layers;
|
|
9405
9620
|
}
|
|
9621
|
+
function requireRefinementOwner(layer, refinement) {
|
|
9622
|
+
if (layer.owner !== refinement.owner) {
|
|
9623
|
+
throw renderStackError(
|
|
9624
|
+
"refinement-owner-mismatch",
|
|
9625
|
+
`Render refinement ${refinement.target} belongs to ${layer.owner ?? "no owner"}, not ${refinement.owner}.`
|
|
9626
|
+
);
|
|
9627
|
+
}
|
|
9628
|
+
return layer;
|
|
9629
|
+
}
|
|
9630
|
+
function placementAnchor(placement) {
|
|
9631
|
+
if (placement === void 0 || typeof placement === "string") return void 0;
|
|
9632
|
+
return placement.above ?? placement.below;
|
|
9633
|
+
}
|
|
9634
|
+
function placementKey(placement) {
|
|
9635
|
+
if (typeof placement === "string") return placement;
|
|
9636
|
+
return placement.above === void 0 ? `below:${placement.below}` : `above:${placement.above}`;
|
|
9637
|
+
}
|
|
9406
9638
|
function compileOperation(owner, name, operation, order, data) {
|
|
9407
9639
|
requireOperationName(name);
|
|
9408
9640
|
if (operation.kind === "render-pass") {
|
|
9409
9641
|
validateRenderPassOperation(operation);
|
|
9410
9642
|
const requirements2 = normalizeRequirements(operation.requirements);
|
|
9411
|
-
|
|
9643
|
+
requirePlacementAnchor(owner, operation.placement, requirements2);
|
|
9412
9644
|
const target = `${owner}.render.${name}`;
|
|
9413
9645
|
requirePortableTarget(target, "generated render target");
|
|
9646
|
+
if (typeof operation.placement === "string" && operation.renderer !== "background" && operation.feature === void 0) {
|
|
9647
|
+
throw renderStackError(
|
|
9648
|
+
"missing-inherited-feature",
|
|
9649
|
+
`Render pass ${target} is placed at ${operation.placement} and must declare its feature.`
|
|
9650
|
+
);
|
|
9651
|
+
}
|
|
9414
9652
|
const template2 = compileRenderLayer(target, operation, data);
|
|
9415
9653
|
return {
|
|
9416
|
-
attachTo: operation.attachTo,
|
|
9417
9654
|
kind: "layer",
|
|
9418
9655
|
name,
|
|
9419
9656
|
order,
|
|
9420
9657
|
owner,
|
|
9421
|
-
|
|
9658
|
+
placement: cloneJson21(operation.placement),
|
|
9422
9659
|
renderer: operation.renderer,
|
|
9423
9660
|
requirements: requirements2,
|
|
9424
9661
|
target,
|
|
@@ -9428,6 +9665,21 @@ function compileOperation(owner, name, operation, order, data) {
|
|
|
9428
9665
|
validateRefinementOperation(operation);
|
|
9429
9666
|
requireOwnedTarget(owner, operation.target, "refinement target");
|
|
9430
9667
|
const requirements = normalizeRequirements(operation.requirements);
|
|
9668
|
+
if (operation.placement !== void 0) {
|
|
9669
|
+
requirePlacementAnchor(owner, operation.placement, requirements);
|
|
9670
|
+
}
|
|
9671
|
+
const placement = operation.placement === void 0 ? {} : { placement: cloneJson21(operation.placement) };
|
|
9672
|
+
if (operation.renderer === void 0) {
|
|
9673
|
+
return {
|
|
9674
|
+
kind: "refinement",
|
|
9675
|
+
name,
|
|
9676
|
+
order,
|
|
9677
|
+
owner,
|
|
9678
|
+
...placement,
|
|
9679
|
+
requirements,
|
|
9680
|
+
target: operation.target
|
|
9681
|
+
};
|
|
9682
|
+
}
|
|
9431
9683
|
const template = applyRendererStyle(
|
|
9432
9684
|
{ id: "tileflow-render-refinement-template", type: rendererLayerType(operation.renderer) },
|
|
9433
9685
|
operation.renderer,
|
|
@@ -9441,6 +9693,7 @@ function compileOperation(owner, name, operation, order, data) {
|
|
|
9441
9693
|
order,
|
|
9442
9694
|
owner,
|
|
9443
9695
|
patch,
|
|
9696
|
+
...placement,
|
|
9444
9697
|
renderer: operation.renderer,
|
|
9445
9698
|
requirements,
|
|
9446
9699
|
target: operation.target
|
|
@@ -9618,26 +9871,42 @@ function requireFieldBinding(fieldName, data) {
|
|
|
9618
9871
|
}
|
|
9619
9872
|
return field(fieldName);
|
|
9620
9873
|
}
|
|
9621
|
-
function materializeRenderLayer(operation, anchor) {
|
|
9874
|
+
function materializeRenderLayer(operation, anchor, slot) {
|
|
9622
9875
|
let template = cloneJson21(operation.template);
|
|
9623
9876
|
if (operation.renderer !== "background" && template.feature?.dataSource === void 0) {
|
|
9624
|
-
if (anchor
|
|
9877
|
+
if (anchor?.feature?.dataSource === void 0 || anchor.feature.dataLayer === void 0) {
|
|
9625
9878
|
throw renderStackError(
|
|
9626
9879
|
"missing-inherited-feature",
|
|
9627
|
-
`Render pass ${operation.target} has no feature and
|
|
9880
|
+
`Render pass ${operation.target} has no feature and ${placementKey(operation.placement)} provides no vector feature to inherit.`
|
|
9628
9881
|
);
|
|
9629
9882
|
}
|
|
9630
9883
|
template = { ...template, feature: cloneJson21(anchor.feature) };
|
|
9631
9884
|
}
|
|
9632
|
-
const slot = requireSemanticSlot(anchor, operation.attachTo);
|
|
9633
9885
|
return materializeTileflowLayerFamilyIR(template, {
|
|
9634
9886
|
operations: [{ kind: "pass", owner: operation.owner, target: operation.target }],
|
|
9635
|
-
order: anchor
|
|
9887
|
+
order: anchor?.order ?? 0,
|
|
9636
9888
|
owner: operation.owner,
|
|
9637
9889
|
slot,
|
|
9638
9890
|
target: operation.target
|
|
9639
9891
|
});
|
|
9640
9892
|
}
|
|
9893
|
+
function moveLayer(layer, refinement, slot, anchor) {
|
|
9894
|
+
return {
|
|
9895
|
+
...layer,
|
|
9896
|
+
order: anchor?.order ?? layer.order,
|
|
9897
|
+
origins: layer.origins.map(
|
|
9898
|
+
(origin) => origin.owner === refinement.owner && origin.target === refinement.target ? {
|
|
9899
|
+
...origin,
|
|
9900
|
+
operations: [
|
|
9901
|
+
...origin.operations,
|
|
9902
|
+
{ kind: "refinement", owner: refinement.owner, target: refinement.target }
|
|
9903
|
+
],
|
|
9904
|
+
slot
|
|
9905
|
+
} : origin
|
|
9906
|
+
),
|
|
9907
|
+
slot
|
|
9908
|
+
};
|
|
9909
|
+
}
|
|
9641
9910
|
function applyRefinement(previous, refinement) {
|
|
9642
9911
|
const patch = refinement.patch;
|
|
9643
9912
|
const operation = {
|
|
@@ -9653,7 +9922,8 @@ function applyRefinement(previous, refinement) {
|
|
|
9653
9922
|
...patch.range === void 0 ? {} : { range: { ...previous.range ?? {}, ...patch.range } },
|
|
9654
9923
|
...!Object.hasOwn(patch, "selector") ? {} : { selector: cloneJson21(patch.selector) },
|
|
9655
9924
|
origins: previous.origins.map(
|
|
9656
|
-
(origin) => origin.owner === refinement.owner && origin.target === refinement.target
|
|
9925
|
+
(origin) => origin.owner === refinement.owner && origin.target === refinement.target && // A move already recorded this refinement on the target.
|
|
9926
|
+
refinement.placement === void 0 ? { ...origin, operations: [...origin.operations, operation] } : origin
|
|
9657
9927
|
),
|
|
9658
9928
|
style: {
|
|
9659
9929
|
...previous.style,
|
|
@@ -9684,10 +9954,34 @@ function requireRenderer(value) {
|
|
|
9684
9954
|
throw renderStackError("invalid-renderer", `Unknown render-stack renderer: ${String(value)}.`);
|
|
9685
9955
|
}
|
|
9686
9956
|
}
|
|
9687
|
-
function
|
|
9688
|
-
if (
|
|
9689
|
-
|
|
9957
|
+
function requirePlacement(value) {
|
|
9958
|
+
if (typeof value === "string") {
|
|
9959
|
+
if (tileflowBandPlacements.includes(value)) return;
|
|
9960
|
+
} else if (isRecord6(value)) {
|
|
9961
|
+
const keys = Object.keys(value);
|
|
9962
|
+
if (keys.length === 1 && (keys[0] === "above" || keys[0] === "below")) {
|
|
9963
|
+
requirePortableTarget(value[keys[0]], "render placement target");
|
|
9964
|
+
return;
|
|
9965
|
+
}
|
|
9966
|
+
}
|
|
9967
|
+
throw renderStackError(
|
|
9968
|
+
"invalid-placement",
|
|
9969
|
+
`A render placement is a band edge (${tileflowBandPlacements.join(", ")}) or {above} / {below} one semantic target: ${JSON.stringify(value)}.`
|
|
9970
|
+
);
|
|
9971
|
+
}
|
|
9972
|
+
function validateRefinementShape(operation) {
|
|
9973
|
+
if (operation.placement !== void 0) requirePlacement(operation.placement);
|
|
9974
|
+
if (operation.renderer === void 0) {
|
|
9975
|
+
if (operation.placement === void 0 || "style" in operation || "selector" in operation) {
|
|
9976
|
+
throw renderStackError(
|
|
9977
|
+
"invalid-refinement",
|
|
9978
|
+
"A render refinement declares a renderer with its style, a placement, or both."
|
|
9979
|
+
);
|
|
9980
|
+
}
|
|
9981
|
+
return;
|
|
9690
9982
|
}
|
|
9983
|
+
requireRenderer(operation.renderer);
|
|
9984
|
+
validateStyle(operation.renderer, operation.style);
|
|
9691
9985
|
}
|
|
9692
9986
|
function validateStyle(renderer, style) {
|
|
9693
9987
|
if (!isRecord6(style)) {
|
|
@@ -9807,13 +10101,15 @@ function requireRenderStackEntries(stack) {
|
|
|
9807
10101
|
}
|
|
9808
10102
|
return entries;
|
|
9809
10103
|
}
|
|
9810
|
-
function
|
|
9811
|
-
|
|
10104
|
+
function requirePlacementAnchor(owner, placement, requirements) {
|
|
10105
|
+
requirePlacement(placement);
|
|
10106
|
+
const target = placementAnchor(placement);
|
|
10107
|
+
if (target === void 0) return;
|
|
9812
10108
|
const targetOwner = target.split(".")[0];
|
|
9813
10109
|
if (targetOwner !== owner && !requirements.includes(targetOwner)) {
|
|
9814
10110
|
throw renderStackError(
|
|
9815
10111
|
"cross-owner-attachment",
|
|
9816
|
-
`Render
|
|
10112
|
+
`Render operation owner ${owner} may be placed beside ${target} only with an explicit ${targetOwner} requirement.`
|
|
9817
10113
|
);
|
|
9818
10114
|
}
|
|
9819
10115
|
}
|
|
@@ -9860,18 +10156,16 @@ function requireUniqueCompiledLayers(layers, operations) {
|
|
|
9860
10156
|
}
|
|
9861
10157
|
}
|
|
9862
10158
|
function compareCompiledOperations(left, right) {
|
|
9863
|
-
|
|
9864
|
-
const rightPhase = right.kind === "layer" ? phaseOrder.get(right.phase) : Number.MAX_SAFE_INTEGER;
|
|
9865
|
-
return leftPhase - rightPhase || left.order - right.order || compareCodeUnits6(left.owner, right.owner) || compareCodeUnits6(left.name, right.name);
|
|
10159
|
+
return left.order - right.order || compareCodeUnits6(left.owner, right.owner) || compareCodeUnits6(left.name, right.name);
|
|
9866
10160
|
}
|
|
9867
10161
|
function validateRenderPassOperation(operation) {
|
|
9868
10162
|
assertOnlyKeys(
|
|
9869
10163
|
operation,
|
|
9870
|
-
["
|
|
10164
|
+
["feature", "kind", "placement", "renderer", "requirements", "selector", "style"],
|
|
9871
10165
|
"render pass operation"
|
|
9872
10166
|
);
|
|
9873
10167
|
requireRenderer(operation.renderer);
|
|
9874
|
-
|
|
10168
|
+
requirePlacement(operation.placement);
|
|
9875
10169
|
validateStyle(operation.renderer, operation.style);
|
|
9876
10170
|
if (operation.renderer === "background" && ("feature" in operation || "selector" in operation)) {
|
|
9877
10171
|
throw renderStackError(
|
|
@@ -9883,11 +10177,10 @@ function validateRenderPassOperation(operation) {
|
|
|
9883
10177
|
function validateRefinementOperation(operation) {
|
|
9884
10178
|
assertOnlyKeys(
|
|
9885
10179
|
operation,
|
|
9886
|
-
["kind", "renderer", "requirements", "selector", "style", "target"],
|
|
10180
|
+
["kind", "placement", "renderer", "requirements", "selector", "style", "target"],
|
|
9887
10181
|
"render refinement operation"
|
|
9888
10182
|
);
|
|
9889
|
-
|
|
9890
|
-
validateStyle(operation.renderer, operation.style);
|
|
10183
|
+
validateRefinementShape(operation);
|
|
9891
10184
|
if (operation.renderer === "background" && "selector" in operation) {
|
|
9892
10185
|
throw renderStackError(
|
|
9893
10186
|
"invalid-background-refinement",
|
|
@@ -10522,6 +10815,11 @@ var textStyleSchema = z5.object({
|
|
|
10522
10815
|
"top-left",
|
|
10523
10816
|
"top-right"
|
|
10524
10817
|
]).optional(),
|
|
10818
|
+
background: z5.object({
|
|
10819
|
+
color: colorValueSchema,
|
|
10820
|
+
fit: z5.literal("lines"),
|
|
10821
|
+
padding: themeNumberValueSchema.optional()
|
|
10822
|
+
}).strict().optional(),
|
|
10525
10823
|
color: colorValueSchema.optional(),
|
|
10526
10824
|
fallbacks: moduleFontFallbacksSchema.optional(),
|
|
10527
10825
|
field: stringValueSchema.optional(),
|
|
@@ -10768,12 +11066,16 @@ var renderRequirementsSchema = z5.array(z5.enum(tileflowLayerDomains)).min(1).ma
|
|
|
10768
11066
|
seen.add(requirement);
|
|
10769
11067
|
}
|
|
10770
11068
|
});
|
|
11069
|
+
var renderPlacementSchema = z5.union([
|
|
11070
|
+
z5.enum(tileflowBandPlacements),
|
|
11071
|
+
z5.object({ above: renderTargetSchema }).strict(),
|
|
11072
|
+
z5.object({ below: renderTargetSchema }).strict()
|
|
11073
|
+
]);
|
|
10771
11074
|
var vectorRenderPassSchemas = tileflowRenderStackRenderers.filter((renderer) => renderer !== "background").map(
|
|
10772
11075
|
(renderer) => z5.object({
|
|
10773
|
-
attachTo: renderTargetSchema,
|
|
10774
11076
|
feature: z5.enum(tileflowSemanticLayerNames).optional(),
|
|
10775
11077
|
kind: z5.literal("render-pass"),
|
|
10776
|
-
|
|
11078
|
+
placement: renderPlacementSchema,
|
|
10777
11079
|
renderer: z5.literal(renderer),
|
|
10778
11080
|
requirements: renderRequirementsSchema.optional(),
|
|
10779
11081
|
selector: renderSelectorSchema.optional(),
|
|
@@ -10782,9 +11084,8 @@ var vectorRenderPassSchemas = tileflowRenderStackRenderers.filter((renderer) =>
|
|
|
10782
11084
|
);
|
|
10783
11085
|
var renderPassSchema = z5.discriminatedUnion("renderer", [
|
|
10784
11086
|
z5.object({
|
|
10785
|
-
attachTo: renderTargetSchema,
|
|
10786
11087
|
kind: z5.literal("render-pass"),
|
|
10787
|
-
|
|
11088
|
+
placement: renderPlacementSchema,
|
|
10788
11089
|
renderer: z5.literal("background"),
|
|
10789
11090
|
requirements: renderRequirementsSchema.optional(),
|
|
10790
11091
|
style: renderStyleSchemas.background
|
|
@@ -10794,6 +11095,7 @@ var renderPassSchema = z5.discriminatedUnion("renderer", [
|
|
|
10794
11095
|
var renderRefinementSchemas = tileflowRenderStackRenderers.map(
|
|
10795
11096
|
(renderer) => z5.object({
|
|
10796
11097
|
kind: z5.literal("refine-render-target"),
|
|
11098
|
+
placement: renderPlacementSchema.optional(),
|
|
10797
11099
|
requirements: renderRequirementsSchema.optional(),
|
|
10798
11100
|
renderer: z5.literal(renderer),
|
|
10799
11101
|
...renderer === "background" ? {} : { selector: renderSelectorSchema.optional() },
|
|
@@ -10801,7 +11103,17 @@ var renderRefinementSchemas = tileflowRenderStackRenderers.map(
|
|
|
10801
11103
|
target: renderTargetSchema
|
|
10802
11104
|
}).strict()
|
|
10803
11105
|
);
|
|
10804
|
-
var
|
|
11106
|
+
var renderPlacementRefinementSchema = z5.object({
|
|
11107
|
+
kind: z5.literal("refine-render-target"),
|
|
11108
|
+
placement: renderPlacementSchema,
|
|
11109
|
+
requirements: renderRequirementsSchema.optional(),
|
|
11110
|
+
target: renderTargetSchema
|
|
11111
|
+
}).strict();
|
|
11112
|
+
var renderStackOperationSchema = z5.union([
|
|
11113
|
+
renderPassSchema,
|
|
11114
|
+
...renderRefinementSchemas,
|
|
11115
|
+
renderPlacementRefinementSchema
|
|
11116
|
+
]);
|
|
10805
11117
|
var renderStackSchema = z5.record(renderStackOperationNameSchema, renderStackOperationSchema).superRefine((stack, context) => {
|
|
10806
11118
|
const size = Object.keys(stack).length;
|
|
10807
11119
|
if (size === 0) {
|
|
@@ -11643,7 +11955,7 @@ var terrainSchema = z5.union([
|
|
|
11643
11955
|
url: z5.string().trim().min(1).optional()
|
|
11644
11956
|
}).strict()
|
|
11645
11957
|
]);
|
|
11646
|
-
var atmosphereColorLiteralSchema = z5.string().refine((value) =>
|
|
11958
|
+
var atmosphereColorLiteralSchema = z5.string().refine((value) => Color3.parse(value)?.a === 1, "Expected an opaque color");
|
|
11647
11959
|
var atmosphereColorSchema = z5.union([
|
|
11648
11960
|
atmosphereColorLiteralSchema,
|
|
11649
11961
|
fixedStringSchema.extend({ value: atmosphereColorLiteralSchema }),
|
|
@@ -12166,7 +12478,7 @@ function cloneJson22(value) {
|
|
|
12166
12478
|
}
|
|
12167
12479
|
|
|
12168
12480
|
// src/icon-appearance.ts
|
|
12169
|
-
import { Color as
|
|
12481
|
+
import { Color as Color4 } from "@maplibre/maplibre-gl-style-spec";
|
|
12170
12482
|
import { z as z7 } from "zod";
|
|
12171
12483
|
|
|
12172
12484
|
// src/icon-layout.ts
|
|
@@ -12224,7 +12536,7 @@ function assertTileflowIconLayoutBounds(layout, width, height) {
|
|
|
12224
12536
|
}
|
|
12225
12537
|
|
|
12226
12538
|
// src/icon-appearance.ts
|
|
12227
|
-
var color = z7.string().max(128).refine((value) =>
|
|
12539
|
+
var color = z7.string().max(128).refine((value) => Color4.parse(value) !== void 0, "Expected a MapLibre color");
|
|
12228
12540
|
var tileflowIconAppearanceSchema = z7.object({
|
|
12229
12541
|
representation: z7.literal("sdf"),
|
|
12230
12542
|
defaults: z7.object({
|
|
@@ -12257,9 +12569,9 @@ function applyTileflowIconCapabilities(style, icons) {
|
|
|
12257
12569
|
if (!icons?.appearances || !Object.keys(icons.appearances).length) return;
|
|
12258
12570
|
const ids = [...icons.ids];
|
|
12259
12571
|
const appearances = icons.appearances;
|
|
12260
|
-
for (const [
|
|
12261
|
-
if (!ids.includes(
|
|
12262
|
-
throw new Error(`Icon capability metadata references unknown icon "${
|
|
12572
|
+
for (const [id2, appearance] of Object.entries(appearances)) {
|
|
12573
|
+
if (!ids.includes(id2))
|
|
12574
|
+
throw new Error(`Icon capability metadata references unknown icon "${id2}".`);
|
|
12263
12575
|
tileflowIconAppearanceSchema.parse(appearance);
|
|
12264
12576
|
}
|
|
12265
12577
|
for (const layer of style.layers) {
|
|
@@ -12270,7 +12582,7 @@ function applyTileflowIconCapabilities(style, icons) {
|
|
|
12270
12582
|
"background-pattern"
|
|
12271
12583
|
]) {
|
|
12272
12584
|
const pattern = record(layer.paint)[property];
|
|
12273
|
-
if (pattern !== void 0 && [...outputs(pattern, ids)].some((
|
|
12585
|
+
if (pattern !== void 0 && [...outputs(pattern, ids)].some((id2) => appearances[id2]?.representation === "sdf")) {
|
|
12274
12586
|
throw Object.assign(new Error(`Layer "${layer.id}" cannot use an SDF icon as a pattern.`), {
|
|
12275
12587
|
code: "TF_ICON_PATTERN_SDF",
|
|
12276
12588
|
path: `layers.${layer.id}.paint.${property}`,
|
|
@@ -12288,7 +12600,7 @@ function applyTileflowIconCapabilities(style, icons) {
|
|
|
12288
12600
|
});
|
|
12289
12601
|
}
|
|
12290
12602
|
const names = [...outputs(image, ids)];
|
|
12291
|
-
const sdf = names.filter((
|
|
12603
|
+
const sdf = names.filter((id2) => appearances[id2]?.representation === "sdf");
|
|
12292
12604
|
if (!sdf.length) continue;
|
|
12293
12605
|
if (sdf.length !== names.length) {
|
|
12294
12606
|
throw Object.assign(
|
|
@@ -12400,7 +12712,7 @@ function numericBounds(value) {
|
|
|
12400
12712
|
];
|
|
12401
12713
|
}
|
|
12402
12714
|
function defaultPaint(image, key, names, appearances, ids) {
|
|
12403
|
-
const values = names.map((
|
|
12715
|
+
const values = names.map((id2) => appearances[id2].defaults[key]);
|
|
12404
12716
|
if (new Set(values).size === 1) return values[0];
|
|
12405
12717
|
if (Array.isArray(image) && (image[0] === "step" || image[0] === "interpolate")) {
|
|
12406
12718
|
const copy = [...image];
|
|
@@ -12411,7 +12723,7 @@ function defaultPaint(image, key, names, appearances, ids) {
|
|
|
12411
12723
|
return [
|
|
12412
12724
|
"match",
|
|
12413
12725
|
["to-string", selection(image, ids)],
|
|
12414
|
-
...names.flatMap((
|
|
12726
|
+
...names.flatMap((id2, i) => [id2, values[i]]),
|
|
12415
12727
|
values[0]
|
|
12416
12728
|
];
|
|
12417
12729
|
}
|
|
@@ -12421,18 +12733,18 @@ var tileflowInteractionManifestMetadataKey = "tileflow:interaction-manifest";
|
|
|
12421
12733
|
var tileflowInteractionManifestVersion = 2;
|
|
12422
12734
|
function createTileflowInteractionManifest(layers, fields) {
|
|
12423
12735
|
const poiLayers = layers.flatMap((layer, priority) => {
|
|
12424
|
-
const
|
|
12736
|
+
const id2 = typeof layer.id === "string" ? layer.id : void 0;
|
|
12425
12737
|
const source = typeof layer.source === "string" ? layer.source : void 0;
|
|
12426
12738
|
const sourceLayer = typeof layer["source-layer"] === "string" ? layer["source-layer"] : void 0;
|
|
12427
12739
|
const target = semanticTarget(layer);
|
|
12428
|
-
if (!
|
|
12740
|
+
if (!id2 || !source || !sourceLayer || !target?.startsWith("poi.")) return [];
|
|
12429
12741
|
const parsed = parsePoiTarget(target);
|
|
12430
12742
|
if (!parsed) return [];
|
|
12431
12743
|
return [
|
|
12432
12744
|
{
|
|
12433
12745
|
...parsed,
|
|
12434
12746
|
anchor: "pointer-coordinate",
|
|
12435
|
-
layerId:
|
|
12747
|
+
layerId: id2,
|
|
12436
12748
|
priority,
|
|
12437
12749
|
source,
|
|
12438
12750
|
sourceLayer
|
|
@@ -12531,11 +12843,11 @@ function createTileflowOverlayPlacementManifest(layers) {
|
|
|
12531
12843
|
const anchors = Object.fromEntries(
|
|
12532
12844
|
tileflowOverlayPlacements.map((placement) => {
|
|
12533
12845
|
const index = tileflowOverlayInsertionIndex(layers, placement);
|
|
12534
|
-
const
|
|
12535
|
-
if (
|
|
12846
|
+
const id2 = index < layers.length ? layers[index]?.id : void 0;
|
|
12847
|
+
if (id2 !== void 0 && typeof id2 !== "string") {
|
|
12536
12848
|
throw new Error(`Tileflow overlay placement ${placement} resolved an invalid layer ID.`);
|
|
12537
12849
|
}
|
|
12538
|
-
return [placement,
|
|
12850
|
+
return [placement, id2 ?? null];
|
|
12539
12851
|
})
|
|
12540
12852
|
);
|
|
12541
12853
|
return {
|
|
@@ -13759,10 +14071,10 @@ function compileSemanticStyleInternal(input, options, inspect, onReport) {
|
|
|
13759
14071
|
function finalizeTileflowLayers(input) {
|
|
13760
14072
|
const ids = /* @__PURE__ */ new Set();
|
|
13761
14073
|
return input.map((layer, index) => {
|
|
13762
|
-
const
|
|
13763
|
-
if (!
|
|
13764
|
-
if (ids.has(
|
|
13765
|
-
ids.add(
|
|
14074
|
+
const id2 = typeof layer.id === "string" ? layer.id : "";
|
|
14075
|
+
if (!id2) throw new Error(`Compiled Tileflow layer at index ${index} has no ID.`);
|
|
14076
|
+
if (ids.has(id2)) throw new Error(`Duplicate compiled Tileflow layer ID: ${id2}`);
|
|
14077
|
+
ids.add(id2);
|
|
13766
14078
|
const minimum2 = layer.minzoom;
|
|
13767
14079
|
const maximum2 = layer.maxzoom;
|
|
13768
14080
|
for (const [name, value] of [
|
|
@@ -13771,11 +14083,11 @@ function finalizeTileflowLayers(input) {
|
|
|
13771
14083
|
]) {
|
|
13772
14084
|
if (value === void 0) continue;
|
|
13773
14085
|
if (typeof value !== "number" || !Number.isFinite(value) || value < 0 || value > 24) {
|
|
13774
|
-
throw new Error(`Compiled Tileflow layer ${
|
|
14086
|
+
throw new Error(`Compiled Tileflow layer ${id2} has invalid ${name}: ${String(value)}`);
|
|
13775
14087
|
}
|
|
13776
14088
|
}
|
|
13777
14089
|
if (typeof minimum2 === "number" && typeof maximum2 === "number" && minimum2 > maximum2) {
|
|
13778
|
-
throw new Error(`Compiled Tileflow layer ${
|
|
14090
|
+
throw new Error(`Compiled Tileflow layer ${id2} requires minzoom <= maxzoom.`);
|
|
13779
14091
|
}
|
|
13780
14092
|
const metadata = isRecord8(layer.metadata) ? { ...layer.metadata } : void 0;
|
|
13781
14093
|
if (metadata) {
|
|
@@ -13819,7 +14131,7 @@ function assertPreparedIconReferences(style, config, prepared) {
|
|
|
13819
14131
|
const references = collectStyleImageReferences(style);
|
|
13820
14132
|
if (references.size === 0) return;
|
|
13821
14133
|
const available = new Set(prepared?.icons?.ids ?? []);
|
|
13822
|
-
const missing = [...references].filter((
|
|
14134
|
+
const missing = [...references].filter((id2) => !available.has(id2)).sort();
|
|
13823
14135
|
if (missing.length === 0 && prepared?.icons?.sprite) return;
|
|
13824
14136
|
const authoring = config.icons?.length ? "Run the Node build so map.icons directories are prepared." : "Declare map.icons with directories containing those canonical filenames.";
|
|
13825
14137
|
throw new Error(
|
|
@@ -13923,7 +14235,8 @@ function assertGlyphFontStacks(style, config) {
|
|
|
13923
14235
|
const font = layout?.["text-font"];
|
|
13924
14236
|
if (!Array.isArray(font) || !font.every((entry) => typeof entry === "string")) continue;
|
|
13925
14237
|
const stack = font.join(",");
|
|
13926
|
-
|
|
14238
|
+
const source = parseTileflowLineBackgroundFontStack(stack)?.source ?? stack;
|
|
14239
|
+
if (stack && !declared.has(source)) missing.add(source);
|
|
13927
14240
|
}
|
|
13928
14241
|
if (missing.size > 0) {
|
|
13929
14242
|
throw new Error(
|
|
@@ -13946,6 +14259,15 @@ function assertTextAssets(style, config) {
|
|
|
13946
14259
|
}
|
|
13947
14260
|
if (textLayers.length === 0) return;
|
|
13948
14261
|
if (config.fonts !== void 0) {
|
|
14262
|
+
const backed = style.layers.find((layer) => {
|
|
14263
|
+
const font = isRecord8(layer.layout) ? layer.layout["text-font"] : void 0;
|
|
14264
|
+
return Array.isArray(font) && font.length === 1 && typeof font[0] === "string" && parseTileflowLineBackgroundFontStack(font[0]) !== void 0;
|
|
14265
|
+
});
|
|
14266
|
+
if (backed) {
|
|
14267
|
+
throw new Error(
|
|
14268
|
+
`Tileflow map "${config.id}" layer "${String(backed.id)}" uses a line-fitted text background, which needs a glyphs provider; browser-rendered fonts cannot draw its cells.`
|
|
14269
|
+
);
|
|
14270
|
+
}
|
|
13949
14271
|
if (config.fonts.length > 0) return;
|
|
13950
14272
|
throw new Error(
|
|
13951
14273
|
`Tileflow map "${config.id}" contains text but declares an empty fonts directory array.`
|
|
@@ -14525,10 +14847,10 @@ function resolveMap(map, options = {}) {
|
|
|
14525
14847
|
}
|
|
14526
14848
|
}
|
|
14527
14849
|
const leaf = lineage[0];
|
|
14528
|
-
const
|
|
14850
|
+
const id2 = parseMapId(leaf.id);
|
|
14529
14851
|
const resolved = {
|
|
14530
|
-
id,
|
|
14531
|
-
name: leaf.name ??
|
|
14852
|
+
id: id2,
|
|
14853
|
+
name: leaf.name ?? id2,
|
|
14532
14854
|
version: leaf.version,
|
|
14533
14855
|
...design,
|
|
14534
14856
|
...modules === void 0 ? {} : { modules }
|
|
@@ -15036,7 +15358,7 @@ function containsControlCharacter(value) {
|
|
|
15036
15358
|
// src/icon-composition.ts
|
|
15037
15359
|
var tileflowIconCompositionMaximumBytes = 1024 * 1024;
|
|
15038
15360
|
var idsSchema = z10.array(tileflowIconIdSchema).max(tileflowIconPackageLimits.maxIconCount).refine(
|
|
15039
|
-
(ids) => new Set(ids).size === ids.length && ids.every((
|
|
15361
|
+
(ids) => new Set(ids).size === ids.length && ids.every((id2, index) => index === 0 || compareCodeUnits8(ids[index - 1], id2) < 0),
|
|
15040
15362
|
"Icon exports must be unique and sorted by code unit"
|
|
15041
15363
|
);
|
|
15042
15364
|
var localContributorSchema = z10.object({ kind: z10.literal("local"), iconIds: idsSchema }).strict();
|
|
@@ -15131,7 +15453,7 @@ var tileflowIconCompositionSchema = z10.object({
|
|
|
15131
15453
|
teams.add(contributor.teamId);
|
|
15132
15454
|
teamSlugs.add(contributor.reference.split("/")[0]);
|
|
15133
15455
|
}
|
|
15134
|
-
for (const
|
|
15456
|
+
for (const id2 of contributor.iconIds) expected.set(id2, ordinal);
|
|
15135
15457
|
}
|
|
15136
15458
|
if (teams.size !== 1 || teamSlugs.size !== 1)
|
|
15137
15459
|
context.addIssue({
|
|
@@ -24375,9 +24697,9 @@ function validateNativeStyle(input, options, stage) {
|
|
|
24375
24697
|
if (Object.keys(sources).length > tileflowNativeProfileLimits.maximumSources) {
|
|
24376
24698
|
add2("NATIVE_UNSUPPORTED_SOURCE", "/sources");
|
|
24377
24699
|
}
|
|
24378
|
-
for (const
|
|
24379
|
-
const source = sources[
|
|
24380
|
-
const path = nativePointer("/sources",
|
|
24700
|
+
for (const id2 of Object.keys(sources).sort().slice(0, tileflowNativeProfileLimits.maximumSources)) {
|
|
24701
|
+
const source = sources[id2];
|
|
24702
|
+
const path = nativePointer("/sources", id2);
|
|
24381
24703
|
if (!record2(source) || typeof source.type !== "string" || !sourceKinds.has(source.type)) {
|
|
24382
24704
|
add2("NATIVE_UNSUPPORTED_SOURCE", path);
|
|
24383
24705
|
continue;
|
|
@@ -24672,8 +24994,8 @@ var teamSourcesSchema = z14.record(
|
|
|
24672
24994
|
const entries = Object.entries(sources);
|
|
24673
24995
|
const tilesets = /* @__PURE__ */ new Set();
|
|
24674
24996
|
if (entries.length > 16) context.addIssue({ code: "custom", message: "Too many Team sources" });
|
|
24675
|
-
for (const [
|
|
24676
|
-
if (
|
|
24997
|
+
for (const [id2, value] of entries) {
|
|
24998
|
+
if (id2 === "tileflow" || id2.startsWith("tileflow-") || ["world", "terrain"].includes(value.tileset) || tilesets.has(value.tileset))
|
|
24677
24999
|
context.addIssue({ code: "custom", message: "Invalid logical Team source binding" });
|
|
24678
25000
|
tilesets.add(value.tileset);
|
|
24679
25001
|
}
|
|
@@ -24784,11 +25106,11 @@ async function parseTileflowRendererDeploymentArtifact(input) {
|
|
|
24784
25106
|
function nativeValidationStyle(style, bindings) {
|
|
24785
25107
|
const copy = JSON.parse(serializeCanonicalJson(style));
|
|
24786
25108
|
const sources = object(copy.sources);
|
|
24787
|
-
for (const [
|
|
24788
|
-
const source = object(sources?.[
|
|
24789
|
-
if (!source || source.type !== binding.type || source.url !== `tileflow://hosted-sources/${
|
|
25109
|
+
for (const [id2, binding] of Object.entries(bindings)) {
|
|
25110
|
+
const source = object(sources?.[id2]);
|
|
25111
|
+
if (!source || source.type !== binding.type || source.url !== `tileflow://hosted-sources/${id2}` || source.tiles !== void 0)
|
|
24790
25112
|
throw new Error();
|
|
24791
|
-
source.url = `https://artifacts.invalid/tiles/${
|
|
25113
|
+
source.url = `https://artifacts.invalid/tiles/${id2}/tiles.json`;
|
|
24792
25114
|
}
|
|
24793
25115
|
return copy;
|
|
24794
25116
|
}
|
|
@@ -24942,7 +25264,7 @@ function createStyleFromCatalog(catalog, mapName, options = {}) {
|
|
|
24942
25264
|
};
|
|
24943
25265
|
return compileSemanticStyle(resolved, {
|
|
24944
25266
|
...options,
|
|
24945
|
-
map: { ...metadata, lineage: metadata.lineage.map(({ id }) =>
|
|
25267
|
+
map: { ...metadata, lineage: metadata.lineage.map(({ id: id2 }) => id2) }
|
|
24946
25268
|
});
|
|
24947
25269
|
}
|
|
24948
25270
|
function createStyleFromCatalogWithInspection(catalog, mapName, options = {}) {
|
|
@@ -24957,7 +25279,7 @@ function createStyleFromCatalogWithInspection(catalog, mapName, options = {}) {
|
|
|
24957
25279
|
};
|
|
24958
25280
|
return compileSemanticStyleWithInspection(resolved, {
|
|
24959
25281
|
...options,
|
|
24960
|
-
map: { ...metadata, lineage: metadata.lineage.map(({ id }) =>
|
|
25282
|
+
map: { ...metadata, lineage: metadata.lineage.map(({ id: id2 }) => id2) }
|
|
24961
25283
|
});
|
|
24962
25284
|
}
|
|
24963
25285
|
function createStylesFromCatalog(catalog, options = {}) {
|