@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/index.js
CHANGED
|
@@ -2721,16 +2721,16 @@ function validateTileflowWorldV1Tilejson(tilejson, schema = tileflowWorldV1Schem
|
|
|
2721
2721
|
}
|
|
2722
2722
|
return issues;
|
|
2723
2723
|
}
|
|
2724
|
-
function requireTilejsonLayer(layers,
|
|
2724
|
+
function requireTilejsonLayer(layers, id2, issues) {
|
|
2725
2725
|
const matches = layers.filter(
|
|
2726
|
-
(layer) => typeof layer === "object" && layer !== null && layer.id ===
|
|
2726
|
+
(layer) => typeof layer === "object" && layer !== null && layer.id === id2
|
|
2727
2727
|
);
|
|
2728
2728
|
if (matches.length === 0) {
|
|
2729
|
-
issues.push(`Tileflow World V1 requires ${
|
|
2729
|
+
issues.push(`Tileflow World V1 requires ${id2}.`);
|
|
2730
2730
|
return void 0;
|
|
2731
2731
|
}
|
|
2732
2732
|
if (matches.length !== 1) {
|
|
2733
|
-
issues.push(`Tileflow World V1 requires exactly one ${
|
|
2733
|
+
issues.push(`Tileflow World V1 requires exactly one ${id2} layer.`);
|
|
2734
2734
|
return void 0;
|
|
2735
2735
|
}
|
|
2736
2736
|
return matches[0];
|
|
@@ -3100,9 +3100,9 @@ function inferTileflowDataRequirements(style, options = {}) {
|
|
|
3100
3100
|
dynamicAccesses: [...dynamicAccesses].sort(compareCodeUnits),
|
|
3101
3101
|
schemaVersion: 1,
|
|
3102
3102
|
sourceId,
|
|
3103
|
-
sourceLayers: [...fieldsByLayer].sort(([left], [right]) => compareCodeUnits(left, right)).map(([
|
|
3103
|
+
sourceLayers: [...fieldsByLayer].sort(([left], [right]) => compareCodeUnits(left, right)).map(([id2, fields]) => ({
|
|
3104
3104
|
fields: [...fields].sort(([left], [right]) => compareCodeUnits(left, right)).map(([name, type]) => ({ name, ...type === void 0 ? {} : { type } })),
|
|
3105
|
-
id
|
|
3105
|
+
id: id2
|
|
3106
3106
|
}))
|
|
3107
3107
|
};
|
|
3108
3108
|
}
|
|
@@ -3479,6 +3479,47 @@ var tileflowLayerSlots = [
|
|
|
3479
3479
|
"vegetation",
|
|
3480
3480
|
"symbols"
|
|
3481
3481
|
];
|
|
3482
|
+
var tileflowLayerBands = [
|
|
3483
|
+
"land",
|
|
3484
|
+
"relief",
|
|
3485
|
+
"water",
|
|
3486
|
+
"roads",
|
|
3487
|
+
"boundaries",
|
|
3488
|
+
"buildings",
|
|
3489
|
+
"vegetation",
|
|
3490
|
+
"labels"
|
|
3491
|
+
];
|
|
3492
|
+
var bandSlots = {
|
|
3493
|
+
land: ["background", "land"],
|
|
3494
|
+
relief: ["terrain", "terrain"],
|
|
3495
|
+
water: ["hydro", "hydro"],
|
|
3496
|
+
roads: ["transport-areas", "transport-symbols"],
|
|
3497
|
+
boundaries: ["boundaries", "boundaries"],
|
|
3498
|
+
buildings: ["buildings", "buildings"],
|
|
3499
|
+
vegetation: ["vegetation", "vegetation"],
|
|
3500
|
+
labels: ["symbols", "symbols"]
|
|
3501
|
+
};
|
|
3502
|
+
var tileflowBandPlacements = tileflowLayerBands.flatMap(
|
|
3503
|
+
(band) => [`below-${band}`, `above-${band}`]
|
|
3504
|
+
);
|
|
3505
|
+
function tileflowBandPlacementSlot(placement) {
|
|
3506
|
+
const [side, band] = splitBandPlacement(placement);
|
|
3507
|
+
return bandSlots[band][side === "below" ? 0 : 1];
|
|
3508
|
+
}
|
|
3509
|
+
function tileflowBandPlacementIndex(slotRanks, placement) {
|
|
3510
|
+
const [side, band] = splitBandPlacement(placement);
|
|
3511
|
+
const [first, last] = bandSlots[band];
|
|
3512
|
+
const threshold = side === "below" ? tileflowLayerSlots.indexOf(first) : tileflowLayerSlots.indexOf(last) + 1;
|
|
3513
|
+
const index = slotRanks.findIndex((rank) => rank !== void 0 && rank >= threshold);
|
|
3514
|
+
return index < 0 ? slotRanks.length : index;
|
|
3515
|
+
}
|
|
3516
|
+
function splitBandPlacement(placement) {
|
|
3517
|
+
const separator = placement.indexOf("-");
|
|
3518
|
+
return [
|
|
3519
|
+
placement.slice(0, separator),
|
|
3520
|
+
placement.slice(separator + 1)
|
|
3521
|
+
];
|
|
3522
|
+
}
|
|
3482
3523
|
var tileflowSemanticTargetPattern = /^[a-z][a-z0-9-]*(?:\.[A-Za-z0-9_-]+)*$/u;
|
|
3483
3524
|
var tileflowRenderStackOperationNamePattern = /^[a-z][A-Za-z0-9_-]*$/u;
|
|
3484
3525
|
var tileflowCompilerMetadataKeys = Object.freeze({
|
|
@@ -3505,6 +3546,332 @@ function typographyTextStyle(typography) {
|
|
|
3505
3546
|
};
|
|
3506
3547
|
}
|
|
3507
3548
|
|
|
3549
|
+
// src/cartography/layer-style.ts
|
|
3550
|
+
import { Color as Color2 } from "@maplibre/maplibre-gl-style-spec";
|
|
3551
|
+
|
|
3552
|
+
// src/text-background.ts
|
|
3553
|
+
var tileflowLineBackgroundDefaults = Object.freeze({
|
|
3554
|
+
letterSpacing: 0,
|
|
3555
|
+
lineHeight: 1.2,
|
|
3556
|
+
padding: 0.33
|
|
3557
|
+
});
|
|
3558
|
+
var tileflowLineBackgroundLimits = Object.freeze({
|
|
3559
|
+
letterSpacing: Object.freeze({ max: 0.5, min: 0 }),
|
|
3560
|
+
lineHeight: Object.freeze({ max: 3, min: 0.8 }),
|
|
3561
|
+
padding: Object.freeze({ max: 1, min: 0 })
|
|
3562
|
+
});
|
|
3563
|
+
var tileflowLineBackgroundHaloRatio = 1 / 6;
|
|
3564
|
+
var STACK_PATTERN = /^(.+) lines-v1-t(\d{1,3})-l(\d{3,4})-p(\d{1,4})$/u;
|
|
3565
|
+
var SOURCE_PATTERN = /^[\p{L}\p{N} _.-]+$/u;
|
|
3566
|
+
var MAX_STACK_LENGTH = 256;
|
|
3567
|
+
var BORDER = 3;
|
|
3568
|
+
var TOP_OF_BITMAP = -20;
|
|
3569
|
+
var STRIP_CENTER = 0.5;
|
|
3570
|
+
var CELL_VALUE = 128;
|
|
3571
|
+
var CELL_EDGE = 64;
|
|
3572
|
+
var CELL_SLOPE = 64;
|
|
3573
|
+
var CELL_OVERLAP = 0.75;
|
|
3574
|
+
var MAX_GLYPH_SIDE = 255;
|
|
3575
|
+
function thousandths(value) {
|
|
3576
|
+
return Math.round(value * 1e3);
|
|
3577
|
+
}
|
|
3578
|
+
function normalizeTileflowLineBackgroundMetrics(metrics = {}) {
|
|
3579
|
+
const resolved = { ...tileflowLineBackgroundDefaults, ...metrics };
|
|
3580
|
+
const normalized = {};
|
|
3581
|
+
for (const key of ["letterSpacing", "lineHeight", "padding"]) {
|
|
3582
|
+
const value = resolved[key];
|
|
3583
|
+
const { max, min } = tileflowLineBackgroundLimits[key];
|
|
3584
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < min || value > max) {
|
|
3585
|
+
throw new RangeError(
|
|
3586
|
+
`Line-fitted text background ${key} must be a constant number from ${min} to ${max} ems.`
|
|
3587
|
+
);
|
|
3588
|
+
}
|
|
3589
|
+
normalized[key] = thousandths(value) / 1e3;
|
|
3590
|
+
}
|
|
3591
|
+
return normalized;
|
|
3592
|
+
}
|
|
3593
|
+
function createTileflowLineBackgroundFontStack(source, metrics = {}) {
|
|
3594
|
+
if (!SOURCE_PATTERN.test(source) || source !== source.trim()) {
|
|
3595
|
+
throw new TypeError(
|
|
3596
|
+
`Line-fitted text backgrounds need one exact font stack of letters, numbers, spaces, underscores, dots or hyphens; received "${source}".`
|
|
3597
|
+
);
|
|
3598
|
+
}
|
|
3599
|
+
if (parseTileflowLineBackgroundFontStack(source)) {
|
|
3600
|
+
throw new TypeError(`Font stack "${source}" is already a line-fitted background stack.`);
|
|
3601
|
+
}
|
|
3602
|
+
const { letterSpacing, lineHeight, padding } = normalizeTileflowLineBackgroundMetrics(metrics);
|
|
3603
|
+
const stack = `${source} lines-v1-t${thousandths(letterSpacing)}-l${thousandths(lineHeight)}-p${thousandths(padding)}`;
|
|
3604
|
+
if (stack.length > MAX_STACK_LENGTH) {
|
|
3605
|
+
throw new RangeError(
|
|
3606
|
+
`Line-fitted text background font stack exceeds ${MAX_STACK_LENGTH} characters.`
|
|
3607
|
+
);
|
|
3608
|
+
}
|
|
3609
|
+
return stack;
|
|
3610
|
+
}
|
|
3611
|
+
function parseTileflowLineBackgroundFontStack(stack) {
|
|
3612
|
+
const match2 = STACK_PATTERN.exec(stack);
|
|
3613
|
+
if (!match2 || stack.length > MAX_STACK_LENGTH || !SOURCE_PATTERN.test(match2[1]))
|
|
3614
|
+
return void 0;
|
|
3615
|
+
const metrics = {
|
|
3616
|
+
letterSpacing: Number(match2[2]) / 1e3,
|
|
3617
|
+
lineHeight: Number(match2[3]) / 1e3,
|
|
3618
|
+
padding: Number(match2[4]) / 1e3
|
|
3619
|
+
};
|
|
3620
|
+
try {
|
|
3621
|
+
const normalized = normalizeTileflowLineBackgroundMetrics(metrics);
|
|
3622
|
+
if (`lines-v1-t${thousandths(normalized.letterSpacing)}-l${thousandths(normalized.lineHeight)}-p${thousandths(normalized.padding)}` !== stack.slice(match2[1].length + 1)) {
|
|
3623
|
+
return void 0;
|
|
3624
|
+
}
|
|
3625
|
+
return { metrics: normalized, source: match2[1] };
|
|
3626
|
+
} catch {
|
|
3627
|
+
return void 0;
|
|
3628
|
+
}
|
|
3629
|
+
}
|
|
3630
|
+
function scaleTileflowTextSizeForLineBackground(size) {
|
|
3631
|
+
const ratio = tileflowLineBackgroundHaloRatio;
|
|
3632
|
+
const scale = (output) => typeof output === "number" ? output * ratio : ["*", ratio, output];
|
|
3633
|
+
if (size === void 0) return 16 * ratio;
|
|
3634
|
+
if (typeof size === "number") return size * ratio;
|
|
3635
|
+
if (Array.isArray(size) && size[0] === "interpolate" && isZoomInput(size[2])) {
|
|
3636
|
+
return size.map((entry, index) => index >= 4 && index % 2 === 0 ? scale(entry) : entry);
|
|
3637
|
+
}
|
|
3638
|
+
if (Array.isArray(size) && size[0] === "step" && isZoomInput(size[1])) {
|
|
3639
|
+
return size.map(
|
|
3640
|
+
(entry, index) => index === 2 || index >= 4 && index % 2 === 0 ? scale(entry) : entry
|
|
3641
|
+
);
|
|
3642
|
+
}
|
|
3643
|
+
return ["*", ratio, size];
|
|
3644
|
+
}
|
|
3645
|
+
function isZoomInput(value) {
|
|
3646
|
+
return Array.isArray(value) && value.length === 1 && value[0] === "zoom";
|
|
3647
|
+
}
|
|
3648
|
+
function deriveTileflowLineBackgroundGlyphs(range2, metrics = {}) {
|
|
3649
|
+
const normalized = normalizeTileflowLineBackgroundMetrics(metrics);
|
|
3650
|
+
const stacks = decodeGlyphStacks(range2);
|
|
3651
|
+
return encodeGlyphStacks(
|
|
3652
|
+
stacks.map((stack) => ({
|
|
3653
|
+
...stack,
|
|
3654
|
+
glyphs: stack.glyphs.map((glyph) => deriveGlyph(glyph, normalized))
|
|
3655
|
+
}))
|
|
3656
|
+
);
|
|
3657
|
+
}
|
|
3658
|
+
function deriveGlyph(glyph, metrics) {
|
|
3659
|
+
const letterSpacing = metrics.letterSpacing * 24;
|
|
3660
|
+
const padding = metrics.padding * 24;
|
|
3661
|
+
const height = metrics.lineHeight * 24;
|
|
3662
|
+
const cell = {
|
|
3663
|
+
x0: -letterSpacing / 2 - padding - CELL_OVERLAP,
|
|
3664
|
+
x1: glyph.advance + letterSpacing / 2 + padding + CELL_OVERLAP,
|
|
3665
|
+
y0: STRIP_CENTER - height / 2 - CELL_OVERLAP,
|
|
3666
|
+
y1: STRIP_CENTER + height / 2 + CELL_OVERLAP
|
|
3667
|
+
};
|
|
3668
|
+
const ramp = Math.ceil(CELL_EDGE / CELL_SLOPE) + 1;
|
|
3669
|
+
const hasBitmap = glyph.width > 0 && glyph.height > 0 && glyph.bitmap.length > 0;
|
|
3670
|
+
const sourceWidth = glyph.width + 2 * BORDER;
|
|
3671
|
+
const sourceHeight = glyph.height + 2 * BORDER;
|
|
3672
|
+
const sourceX = glyph.left - BORDER;
|
|
3673
|
+
const sourceY = TOP_OF_BITMAP - glyph.top;
|
|
3674
|
+
if (hasBitmap && glyph.bitmap.length !== sourceWidth * sourceHeight) {
|
|
3675
|
+
throw new RangeError(`Glyph ${glyph.id} has a bitmap that does not match its metrics.`);
|
|
3676
|
+
}
|
|
3677
|
+
let x0 = Math.floor(cell.x0 - ramp);
|
|
3678
|
+
let x1 = Math.ceil(cell.x1 + ramp);
|
|
3679
|
+
let y0 = Math.floor(cell.y0 - ramp);
|
|
3680
|
+
let y1 = Math.ceil(cell.y1 + ramp);
|
|
3681
|
+
if (hasBitmap) {
|
|
3682
|
+
x0 = Math.min(x0, sourceX);
|
|
3683
|
+
x1 = Math.max(x1, sourceX + sourceWidth);
|
|
3684
|
+
y0 = Math.min(y0, sourceY);
|
|
3685
|
+
y1 = Math.max(y1, sourceY + sourceHeight);
|
|
3686
|
+
}
|
|
3687
|
+
const width = x1 - x0;
|
|
3688
|
+
const rows = y1 - y0;
|
|
3689
|
+
if (width - 2 * BORDER > MAX_GLYPH_SIDE || rows - 2 * BORDER > MAX_GLYPH_SIDE) {
|
|
3690
|
+
throw new RangeError(`Glyph ${glyph.id} would exceed the derived glyph size limit.`);
|
|
3691
|
+
}
|
|
3692
|
+
const bitmap = new Uint8Array(width * rows);
|
|
3693
|
+
for (let row = 0; row < rows; row++) {
|
|
3694
|
+
const y = y0 + row + 0.5;
|
|
3695
|
+
for (let column = 0; column < width; column++) {
|
|
3696
|
+
const x = x0 + column + 0.5;
|
|
3697
|
+
const distance = Math.min(x - cell.x0, cell.x1 - x, y - cell.y0, cell.y1 - y);
|
|
3698
|
+
const background = Math.min(CELL_VALUE, Math.max(0, CELL_EDGE + CELL_SLOPE * distance));
|
|
3699
|
+
let letter = 0;
|
|
3700
|
+
if (hasBitmap) {
|
|
3701
|
+
const sourceColumn = x0 + column - sourceX;
|
|
3702
|
+
const sourceRow = y0 + row - sourceY;
|
|
3703
|
+
if (sourceColumn >= 0 && sourceColumn < sourceWidth && sourceRow >= 0 && sourceRow < sourceHeight) {
|
|
3704
|
+
letter = glyph.bitmap[sourceRow * sourceWidth + sourceColumn];
|
|
3705
|
+
}
|
|
3706
|
+
}
|
|
3707
|
+
bitmap[row * width + column] = Math.round(Math.max(letter, background));
|
|
3708
|
+
}
|
|
3709
|
+
}
|
|
3710
|
+
return {
|
|
3711
|
+
advance: glyph.advance,
|
|
3712
|
+
bitmap,
|
|
3713
|
+
height: rows - 2 * BORDER,
|
|
3714
|
+
id: glyph.id,
|
|
3715
|
+
left: x0 + BORDER,
|
|
3716
|
+
top: TOP_OF_BITMAP - y0,
|
|
3717
|
+
width: width - 2 * BORDER
|
|
3718
|
+
};
|
|
3719
|
+
}
|
|
3720
|
+
var GlyphReader = class {
|
|
3721
|
+
constructor(bytes) {
|
|
3722
|
+
this.bytes = bytes;
|
|
3723
|
+
}
|
|
3724
|
+
bytes;
|
|
3725
|
+
position = 0;
|
|
3726
|
+
fields(read) {
|
|
3727
|
+
while (this.position < this.bytes.length) {
|
|
3728
|
+
const key = this.varint();
|
|
3729
|
+
if (!read(Math.floor(key / 8), this)) this.skip(key % 8);
|
|
3730
|
+
}
|
|
3731
|
+
}
|
|
3732
|
+
varint() {
|
|
3733
|
+
let result = 0;
|
|
3734
|
+
let shift = 0;
|
|
3735
|
+
let byte;
|
|
3736
|
+
do {
|
|
3737
|
+
if (this.position >= this.bytes.length || shift > 49) {
|
|
3738
|
+
throw new RangeError("Invalid glyph PBF varint.");
|
|
3739
|
+
}
|
|
3740
|
+
byte = this.bytes[this.position++];
|
|
3741
|
+
result += (byte & 127) * 2 ** shift;
|
|
3742
|
+
shift += 7;
|
|
3743
|
+
} while (byte & 128);
|
|
3744
|
+
return result;
|
|
3745
|
+
}
|
|
3746
|
+
signed() {
|
|
3747
|
+
const value = this.varint();
|
|
3748
|
+
return value % 2 === 1 ? (value + 1) / -2 : value / 2;
|
|
3749
|
+
}
|
|
3750
|
+
message() {
|
|
3751
|
+
const length = this.varint();
|
|
3752
|
+
const end = this.position + length;
|
|
3753
|
+
if (end > this.bytes.length) throw new RangeError("Truncated glyph PBF field.");
|
|
3754
|
+
const value = this.bytes.subarray(this.position, end);
|
|
3755
|
+
this.position = end;
|
|
3756
|
+
return value;
|
|
3757
|
+
}
|
|
3758
|
+
skip(wire) {
|
|
3759
|
+
if (wire === 0) this.varint();
|
|
3760
|
+
else if (wire === 1) this.position += 8;
|
|
3761
|
+
else if (wire === 2) this.message();
|
|
3762
|
+
else if (wire === 5) this.position += 4;
|
|
3763
|
+
else throw new RangeError(`Unsupported glyph PBF wire type ${wire}.`);
|
|
3764
|
+
if (this.position > this.bytes.length) throw new RangeError("Truncated glyph PBF field.");
|
|
3765
|
+
}
|
|
3766
|
+
};
|
|
3767
|
+
function decodeGlyphStacks(bytes) {
|
|
3768
|
+
const stacks = [];
|
|
3769
|
+
const text = new TextDecoder();
|
|
3770
|
+
new GlyphReader(bytes).fields((tag, reader) => {
|
|
3771
|
+
if (tag !== 1) return false;
|
|
3772
|
+
const stack = { glyphs: [], name: "", range: "" };
|
|
3773
|
+
new GlyphReader(reader.message()).fields((stackTag, stackReader) => {
|
|
3774
|
+
if (stackTag === 1) stack.name = text.decode(stackReader.message());
|
|
3775
|
+
else if (stackTag === 2) stack.range = text.decode(stackReader.message());
|
|
3776
|
+
else if (stackTag === 3) stack.glyphs.push(decodeGlyph(stackReader.message()));
|
|
3777
|
+
else return false;
|
|
3778
|
+
return true;
|
|
3779
|
+
});
|
|
3780
|
+
stacks.push(stack);
|
|
3781
|
+
return true;
|
|
3782
|
+
});
|
|
3783
|
+
return stacks;
|
|
3784
|
+
}
|
|
3785
|
+
function decodeGlyph(bytes) {
|
|
3786
|
+
const glyph = {
|
|
3787
|
+
advance: 0,
|
|
3788
|
+
bitmap: new Uint8Array(0),
|
|
3789
|
+
height: 0,
|
|
3790
|
+
id: 0,
|
|
3791
|
+
left: 0,
|
|
3792
|
+
top: 0,
|
|
3793
|
+
width: 0
|
|
3794
|
+
};
|
|
3795
|
+
new GlyphReader(bytes).fields((tag, reader) => {
|
|
3796
|
+
if (tag === 1) glyph.id = reader.varint();
|
|
3797
|
+
else if (tag === 2) glyph.bitmap = reader.message().slice();
|
|
3798
|
+
else if (tag === 3) glyph.width = reader.varint();
|
|
3799
|
+
else if (tag === 4) glyph.height = reader.varint();
|
|
3800
|
+
else if (tag === 5) glyph.left = reader.signed();
|
|
3801
|
+
else if (tag === 6) glyph.top = reader.signed();
|
|
3802
|
+
else if (tag === 7) glyph.advance = reader.varint();
|
|
3803
|
+
else return false;
|
|
3804
|
+
return true;
|
|
3805
|
+
});
|
|
3806
|
+
return glyph;
|
|
3807
|
+
}
|
|
3808
|
+
var GlyphWriter = class {
|
|
3809
|
+
parts = [];
|
|
3810
|
+
length = 0;
|
|
3811
|
+
varint(value) {
|
|
3812
|
+
const bytes = [];
|
|
3813
|
+
let remaining = value;
|
|
3814
|
+
while (remaining >= 128) {
|
|
3815
|
+
bytes.push(remaining % 128 | 128);
|
|
3816
|
+
remaining = Math.floor(remaining / 128);
|
|
3817
|
+
}
|
|
3818
|
+
bytes.push(remaining);
|
|
3819
|
+
this.raw(Uint8Array.from(bytes));
|
|
3820
|
+
}
|
|
3821
|
+
signed(value) {
|
|
3822
|
+
this.varint(value < 0 ? -2 * value - 1 : 2 * value);
|
|
3823
|
+
}
|
|
3824
|
+
key(tag, wire) {
|
|
3825
|
+
this.varint(tag * 8 + wire);
|
|
3826
|
+
}
|
|
3827
|
+
message(tag, bytes) {
|
|
3828
|
+
this.key(tag, 2);
|
|
3829
|
+
this.varint(bytes.length);
|
|
3830
|
+
this.raw(bytes);
|
|
3831
|
+
}
|
|
3832
|
+
finish() {
|
|
3833
|
+
const output = new Uint8Array(this.length);
|
|
3834
|
+
let offset = 0;
|
|
3835
|
+
for (const part of this.parts) {
|
|
3836
|
+
output.set(part, offset);
|
|
3837
|
+
offset += part.length;
|
|
3838
|
+
}
|
|
3839
|
+
return output;
|
|
3840
|
+
}
|
|
3841
|
+
raw(bytes) {
|
|
3842
|
+
this.parts.push(bytes);
|
|
3843
|
+
this.length += bytes.length;
|
|
3844
|
+
}
|
|
3845
|
+
};
|
|
3846
|
+
function encodeGlyphStacks(stacks) {
|
|
3847
|
+
const text = new TextEncoder();
|
|
3848
|
+
const root = new GlyphWriter();
|
|
3849
|
+
for (const stack of stacks) {
|
|
3850
|
+
const writer = new GlyphWriter();
|
|
3851
|
+
writer.message(1, text.encode(stack.name));
|
|
3852
|
+
writer.message(2, text.encode(stack.range));
|
|
3853
|
+
for (const glyph of stack.glyphs) {
|
|
3854
|
+
const glyphWriter = new GlyphWriter();
|
|
3855
|
+
glyphWriter.key(1, 0);
|
|
3856
|
+
glyphWriter.varint(glyph.id);
|
|
3857
|
+
if (glyph.bitmap.length > 0) glyphWriter.message(2, glyph.bitmap);
|
|
3858
|
+
glyphWriter.key(3, 0);
|
|
3859
|
+
glyphWriter.varint(glyph.width);
|
|
3860
|
+
glyphWriter.key(4, 0);
|
|
3861
|
+
glyphWriter.varint(glyph.height);
|
|
3862
|
+
glyphWriter.key(5, 0);
|
|
3863
|
+
glyphWriter.signed(glyph.left);
|
|
3864
|
+
glyphWriter.key(6, 0);
|
|
3865
|
+
glyphWriter.signed(glyph.top);
|
|
3866
|
+
glyphWriter.key(7, 0);
|
|
3867
|
+
glyphWriter.varint(glyph.advance);
|
|
3868
|
+
writer.message(3, glyphWriter.finish());
|
|
3869
|
+
}
|
|
3870
|
+
root.message(1, writer.finish());
|
|
3871
|
+
}
|
|
3872
|
+
return root.finish();
|
|
3873
|
+
}
|
|
3874
|
+
|
|
3508
3875
|
// src/cartography/layer-style.ts
|
|
3509
3876
|
init_values();
|
|
3510
3877
|
function applyBackgroundStyle(layer, style) {
|
|
@@ -3584,8 +3951,52 @@ function applyTextStyle(layer, style) {
|
|
|
3584
3951
|
setPaint(paint, "text-halo-color", style.haloColor);
|
|
3585
3952
|
setPaint(paint, "text-halo-width", style.haloWidth);
|
|
3586
3953
|
setPaint(paint, "text-opacity", style.opacity);
|
|
3954
|
+
applyLineBackground(layer.id, layout, paint, style, backedFontStack(asRecord2(layer.layout)));
|
|
3587
3955
|
return applyLayerRange(withLayerParts(layer, layout, paint), style);
|
|
3588
3956
|
}
|
|
3957
|
+
function applyLineBackground(id2, layout, paint, style, previous) {
|
|
3958
|
+
const fonts = layout["text-font"];
|
|
3959
|
+
const single = Array.isArray(fonts) && fonts.length === 1 && typeof fonts[0] === "string";
|
|
3960
|
+
const current = backedFontStack(layout);
|
|
3961
|
+
const background = style.background;
|
|
3962
|
+
if (!background && !current && !previous) return;
|
|
3963
|
+
if (!single) {
|
|
3964
|
+
throw new Error(
|
|
3965
|
+
`Layer "${id2}" needs exactly one text font without fallbacks for a line-fitted background.`
|
|
3966
|
+
);
|
|
3967
|
+
}
|
|
3968
|
+
const padding = background?.padding === void 0 ? (current ?? previous)?.metrics.padding ?? tileflowLineBackgroundDefaults.padding : constantNumber(id2, toMapLibreStyleValue(background.padding), "background padding");
|
|
3969
|
+
const stack = createTileflowLineBackgroundFontStack(current?.source ?? fonts[0], {
|
|
3970
|
+
letterSpacing: constantNumber(id2, layout["text-letter-spacing"] ?? 0, "letterSpacing"),
|
|
3971
|
+
lineHeight: constantNumber(id2, layout["text-line-height"] ?? 1.2, "lineHeight"),
|
|
3972
|
+
padding
|
|
3973
|
+
});
|
|
3974
|
+
const { metrics } = parseTileflowLineBackgroundFontStack(stack);
|
|
3975
|
+
layout["text-font"] = [stack];
|
|
3976
|
+
layout["text-letter-spacing"] = metrics.letterSpacing;
|
|
3977
|
+
layout["text-line-height"] = metrics.lineHeight;
|
|
3978
|
+
if (background) {
|
|
3979
|
+
const color3 = toMapLibreStyleValue(background.color);
|
|
3980
|
+
if (typeof color3 === "string" && (Color2.parse(color3)?.a ?? 1) < 1) {
|
|
3981
|
+
throw new Error(
|
|
3982
|
+
`Layer "${id2}" needs an opaque line-fitted background colour; "${color3}" is translucent.`
|
|
3983
|
+
);
|
|
3984
|
+
}
|
|
3985
|
+
paint["text-halo-color"] = color3;
|
|
3986
|
+
}
|
|
3987
|
+
paint["text-halo-width"] = scaleTileflowTextSizeForLineBackground(layout["text-size"]);
|
|
3988
|
+
paint["text-halo-blur"] = 0;
|
|
3989
|
+
}
|
|
3990
|
+
function backedFontStack(layout) {
|
|
3991
|
+
const fonts = layout["text-font"];
|
|
3992
|
+
return Array.isArray(fonts) && fonts.length === 1 && typeof fonts[0] === "string" ? parseTileflowLineBackgroundFontStack(fonts[0]) : void 0;
|
|
3993
|
+
}
|
|
3994
|
+
function constantNumber(id2, value, property) {
|
|
3995
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
3996
|
+
throw new Error(
|
|
3997
|
+
`Layer "${id2}" uses a line-fitted text background, so its ${property} must be a constant number.`
|
|
3998
|
+
);
|
|
3999
|
+
}
|
|
3589
4000
|
function applyIconStyle(layer, style) {
|
|
3590
4001
|
const paint = { ...asRecord2(layer.paint) };
|
|
3591
4002
|
const layout = { ...asRecord2(layer.layout) };
|
|
@@ -3728,12 +4139,12 @@ function setLayout(layout, property, value) {
|
|
|
3728
4139
|
function invertPriority(value) {
|
|
3729
4140
|
const resolved = toMapLibreStyleValue(value);
|
|
3730
4141
|
if (typeof resolved === "number") return -resolved;
|
|
3731
|
-
if (Array.isArray(resolved) && resolved[0] === "interpolate" &&
|
|
4142
|
+
if (Array.isArray(resolved) && resolved[0] === "interpolate" && isZoomInput2(resolved[2])) {
|
|
3732
4143
|
return resolved.map(
|
|
3733
4144
|
(entry, index) => index >= 4 && index % 2 === 0 ? negateExpressionOutput(entry) : entry
|
|
3734
4145
|
);
|
|
3735
4146
|
}
|
|
3736
|
-
if (Array.isArray(resolved) && resolved[0] === "step" &&
|
|
4147
|
+
if (Array.isArray(resolved) && resolved[0] === "step" && isZoomInput2(resolved[1])) {
|
|
3737
4148
|
return resolved.map(
|
|
3738
4149
|
(entry, index) => index === 2 || index >= 4 && index % 2 === 0 ? negateExpressionOutput(entry) : entry
|
|
3739
4150
|
);
|
|
@@ -3746,7 +4157,7 @@ function resolvePriority(value, order) {
|
|
|
3746
4157
|
function negateExpressionOutput(value) {
|
|
3747
4158
|
return typeof value === "number" ? -value : ["*", -1, value];
|
|
3748
4159
|
}
|
|
3749
|
-
function
|
|
4160
|
+
function isZoomInput2(value) {
|
|
3750
4161
|
return Array.isArray(value) && value.length === 1 && value[0] === "zoom";
|
|
3751
4162
|
}
|
|
3752
4163
|
function asRecord2(value) {
|
|
@@ -3940,7 +4351,7 @@ function compileAeroways(request, context) {
|
|
|
3940
4351
|
["taxiway", config.taxiway, 10],
|
|
3941
4352
|
["runway", config.runway, 20]
|
|
3942
4353
|
]) {
|
|
3943
|
-
for (const [phase, style,
|
|
4354
|
+
for (const [phase, style, phaseOrder] of [
|
|
3944
4355
|
["shadow", target?.shadow, 0],
|
|
3945
4356
|
["casing", target?.casing, 1],
|
|
3946
4357
|
["fill", target?.fill, 2]
|
|
@@ -3962,7 +4373,7 @@ function compileAeroways(request, context) {
|
|
|
3962
4373
|
},
|
|
3963
4374
|
style
|
|
3964
4375
|
),
|
|
3965
|
-
localOrder: order +
|
|
4376
|
+
localOrder: order + phaseOrder,
|
|
3966
4377
|
owner: "aeroways",
|
|
3967
4378
|
slot: "aeroways",
|
|
3968
4379
|
target: `aeroways.${name}.${phase}`
|
|
@@ -4748,14 +5159,14 @@ function compileLabels(request, roadRequest, context) {
|
|
|
4748
5159
|
for (const placeClass of visiblePlaceClasses) {
|
|
4749
5160
|
const style = styles.places?.[placeClass];
|
|
4750
5161
|
if (!style || style.visible === false || style.text?.visible === false) continue;
|
|
4751
|
-
const
|
|
5162
|
+
const id2 = `tileflow-label-place-${placeClass}`;
|
|
4752
5163
|
result.push(
|
|
4753
5164
|
symbolContribution(
|
|
4754
5165
|
`labels.places.${placeClass}`,
|
|
4755
5166
|
(navigationPriority ? 1300 : 800) + order++,
|
|
4756
5167
|
applySymbolStyle(
|
|
4757
5168
|
{
|
|
4758
|
-
id,
|
|
5169
|
+
id: id2,
|
|
4759
5170
|
type: "symbol",
|
|
4760
5171
|
source,
|
|
4761
5172
|
"source-layer": schema.layers.place,
|
|
@@ -4780,14 +5191,14 @@ function compileLabels(request, roadRequest, context) {
|
|
|
4780
5191
|
for (const roadClass of orderedRoads) {
|
|
4781
5192
|
const style = styles.roads?.[roadClass];
|
|
4782
5193
|
if (!style || style.visible === false || style.text?.visible === false) continue;
|
|
4783
|
-
const
|
|
5194
|
+
const id2 = `tileflow-label-road-${roadClass}`;
|
|
4784
5195
|
result.push(
|
|
4785
5196
|
symbolContribution(
|
|
4786
5197
|
`labels.roads.${roadClass}`,
|
|
4787
5198
|
(navigationPriority ? 1200 : 200) + order++,
|
|
4788
5199
|
applySymbolStyle(
|
|
4789
5200
|
{
|
|
4790
|
-
id,
|
|
5201
|
+
id: id2,
|
|
4791
5202
|
type: "symbol",
|
|
4792
5203
|
source,
|
|
4793
5204
|
"source-layer": schema.layers.roadName,
|
|
@@ -4799,7 +5210,7 @@ function compileLabels(request, roadRequest, context) {
|
|
|
4799
5210
|
},
|
|
4800
5211
|
mergeTileflowDesign(style, { text: { field: field2 } })
|
|
4801
5212
|
),
|
|
4802
|
-
|
|
5213
|
+
"symbols",
|
|
4803
5214
|
{ group: "roads", kind: "road-label", member: roadClass }
|
|
4804
5215
|
)
|
|
4805
5216
|
);
|
|
@@ -4891,8 +5302,7 @@ function compileLabels(request, roadRequest, context) {
|
|
|
4891
5302
|
]
|
|
4892
5303
|
},
|
|
4893
5304
|
style
|
|
4894
|
-
)
|
|
4895
|
-
"transport-symbols"
|
|
5305
|
+
)
|
|
4896
5306
|
)
|
|
4897
5307
|
);
|
|
4898
5308
|
}
|
|
@@ -4930,8 +5340,7 @@ function compileLabels(request, roadRequest, context) {
|
|
|
4930
5340
|
])
|
|
4931
5341
|
}
|
|
4932
5342
|
})
|
|
4933
|
-
)
|
|
4934
|
-
"transport-symbols"
|
|
5343
|
+
)
|
|
4935
5344
|
)
|
|
4936
5345
|
);
|
|
4937
5346
|
}
|
|
@@ -7734,10 +8143,10 @@ function isExpressionOutput(value) {
|
|
|
7734
8143
|
}
|
|
7735
8144
|
function rewriteZoomOutputs(value, rewrite) {
|
|
7736
8145
|
if (!Array.isArray(value)) return rewrite(value);
|
|
7737
|
-
if (value[0] === "interpolate" &&
|
|
8146
|
+
if (value[0] === "interpolate" && isZoomInput3(value[2])) {
|
|
7738
8147
|
return value.map((entry, index) => index >= 4 && index % 2 === 0 ? rewrite(entry) : entry);
|
|
7739
8148
|
}
|
|
7740
|
-
if (value[0] === "step" &&
|
|
8149
|
+
if (value[0] === "step" && isZoomInput3(value[1])) {
|
|
7741
8150
|
return value.map(
|
|
7742
8151
|
(entry, index) => index === 2 || index >= 4 && index % 2 === 0 ? rewrite(entry) : entry
|
|
7743
8152
|
);
|
|
@@ -7747,7 +8156,7 @@ function rewriteZoomOutputs(value, rewrite) {
|
|
|
7747
8156
|
function expressionOutput(value) {
|
|
7748
8157
|
return Array.isArray(value) && typeof value[0] !== "string" ? ["literal", value] : value;
|
|
7749
8158
|
}
|
|
7750
|
-
function
|
|
8159
|
+
function isZoomInput3(value) {
|
|
7751
8160
|
return Array.isArray(value) && value.length === 1 && value[0] === "zoom";
|
|
7752
8161
|
}
|
|
7753
8162
|
function restrictedAccessFilter(field2) {
|
|
@@ -9164,7 +9573,7 @@ function insertTileflowOverlays(input) {
|
|
|
9164
9573
|
});
|
|
9165
9574
|
groups.set(overlay.placement, [...groups.get(overlay.placement) ?? [], ...layers2]);
|
|
9166
9575
|
identities[overlayId] = Object.freeze({
|
|
9167
|
-
layers: Object.freeze(overlay.layers.map(({ id }) =>
|
|
9576
|
+
layers: Object.freeze(overlay.layers.map(({ id: id2 }) => id2)),
|
|
9168
9577
|
placement: overlay.placement,
|
|
9169
9578
|
source: overlay.source
|
|
9170
9579
|
});
|
|
@@ -9201,22 +9610,13 @@ function cloneJson18(value) {
|
|
|
9201
9610
|
);
|
|
9202
9611
|
}
|
|
9203
9612
|
function tileflowOverlayInsertionIndex(layers, placement) {
|
|
9204
|
-
const
|
|
9205
|
-
|
|
9206
|
-
"below-roads": tileflowLayerSlots.indexOf("transport-areas"),
|
|
9207
|
-
"above-roads": tileflowLayerSlots.indexOf("boundaries"),
|
|
9208
|
-
"above-buildings": tileflowLayerSlots.indexOf("vegetation"),
|
|
9209
|
-
"below-labels": tileflowLayerSlots.indexOf("symbols"),
|
|
9210
|
-
"above-labels": Number.POSITIVE_INFINITY
|
|
9211
|
-
}[placement];
|
|
9212
|
-
if (!Number.isFinite(threshold)) return layers.length;
|
|
9213
|
-
const index = layers.findIndex((layer) => {
|
|
9214
|
-
const ranks = readTileflowCompilerProvenance(layer).map(
|
|
9613
|
+
const ranks = layers.map((layer) => {
|
|
9614
|
+
const slots = readTileflowCompilerProvenance(layer).map(
|
|
9215
9615
|
({ slot }) => tileflowLayerSlots.indexOf(slot)
|
|
9216
9616
|
);
|
|
9217
|
-
return
|
|
9617
|
+
return slots.length > 0 ? Math.min(...slots) : void 0;
|
|
9218
9618
|
});
|
|
9219
|
-
return
|
|
9619
|
+
return tileflowBandPlacementIndex(ranks, placement);
|
|
9220
9620
|
}
|
|
9221
9621
|
function compareCodeUnits4(left, right) {
|
|
9222
9622
|
return left < right ? -1 : left > right ? 1 : 0;
|
|
@@ -9228,7 +9628,7 @@ function isPlainRecord2(value) {
|
|
|
9228
9628
|
}
|
|
9229
9629
|
|
|
9230
9630
|
// src/resolved-map-schema.ts
|
|
9231
|
-
import { Color as
|
|
9631
|
+
import { Color as Color3 } from "@maplibre/maplibre-gl-style-spec";
|
|
9232
9632
|
import { z as z6 } from "zod";
|
|
9233
9633
|
|
|
9234
9634
|
// src/cartography/data-expression.ts
|
|
@@ -9247,6 +9647,9 @@ function literal(value) {
|
|
|
9247
9647
|
function zoom2() {
|
|
9248
9648
|
return make(["zoom"]);
|
|
9249
9649
|
}
|
|
9650
|
+
function id() {
|
|
9651
|
+
return make(["id"]);
|
|
9652
|
+
}
|
|
9250
9653
|
function coalesce(first, ...rest) {
|
|
9251
9654
|
if (rest.length === 0) throw new Error("expr.coalesce requires at least two values.");
|
|
9252
9655
|
validateOperandCount(1 + rest.length, "expr.coalesce");
|
|
@@ -9297,6 +9700,9 @@ function subtract(first, second) {
|
|
|
9297
9700
|
function divide(dividend, divisor) {
|
|
9298
9701
|
return make(["/", node(dividend), node(divisor)]);
|
|
9299
9702
|
}
|
|
9703
|
+
function modulo(dividend, divisor) {
|
|
9704
|
+
return make(["%", node(dividend), node(divisor)]);
|
|
9705
|
+
}
|
|
9300
9706
|
function multiply(first, second, ...rest) {
|
|
9301
9707
|
validateOperandCount(2 + rest.length, "expr.multiply");
|
|
9302
9708
|
return make(["*", node(first), node(second), ...rest.map(node)]);
|
|
@@ -9502,6 +9908,7 @@ function visitExpression(value, path, variables, issues) {
|
|
|
9502
9908
|
}
|
|
9503
9909
|
return;
|
|
9504
9910
|
}
|
|
9911
|
+
case "id":
|
|
9505
9912
|
case "zoom": {
|
|
9506
9913
|
exact(1);
|
|
9507
9914
|
return;
|
|
@@ -9551,6 +9958,7 @@ function visitExpression(value, path, variables, issues) {
|
|
|
9551
9958
|
}
|
|
9552
9959
|
case "-":
|
|
9553
9960
|
case "/":
|
|
9961
|
+
case "%":
|
|
9554
9962
|
case "!=":
|
|
9555
9963
|
case "<":
|
|
9556
9964
|
case "<=":
|
|
@@ -9775,6 +10183,7 @@ var expr = Object.freeze({
|
|
|
9775
10183
|
gt: (left, right) => compare(">", left, right),
|
|
9776
10184
|
gte: (left, right) => compare(">=", left, right),
|
|
9777
10185
|
has,
|
|
10186
|
+
id,
|
|
9778
10187
|
featureState,
|
|
9779
10188
|
interpolate: interpolate2,
|
|
9780
10189
|
let: letValue,
|
|
@@ -9784,6 +10193,7 @@ var expr = Object.freeze({
|
|
|
9784
10193
|
match,
|
|
9785
10194
|
max: maximum,
|
|
9786
10195
|
min: minimum,
|
|
10196
|
+
modulo,
|
|
9787
10197
|
multiply,
|
|
9788
10198
|
ne: (left, right) => compare("!=", left, right),
|
|
9789
10199
|
not,
|
|
@@ -9916,7 +10326,7 @@ function createTileflowLayerFamilyIR(contribution) {
|
|
|
9916
10326
|
function createTileflowLayerTemplateIR(layer, semanticKey) {
|
|
9917
10327
|
const {
|
|
9918
10328
|
filter,
|
|
9919
|
-
id,
|
|
10329
|
+
id: id2,
|
|
9920
10330
|
layout,
|
|
9921
10331
|
maxzoom,
|
|
9922
10332
|
metadata,
|
|
@@ -9927,7 +10337,7 @@ function createTileflowLayerTemplateIR(layer, semanticKey) {
|
|
|
9927
10337
|
type,
|
|
9928
10338
|
...properties
|
|
9929
10339
|
} = layer;
|
|
9930
|
-
if (typeof
|
|
10340
|
+
if (typeof id2 !== "string" || !id2.trim()) {
|
|
9931
10341
|
throw new TileflowDomainIRError(
|
|
9932
10342
|
"TILEFLOW_DOMAIN_IR_INVALID_KEY",
|
|
9933
10343
|
"Layer key must not be empty."
|
|
@@ -9942,7 +10352,7 @@ function createTileflowLayerTemplateIR(layer, semanticKey) {
|
|
|
9942
10352
|
if (typeof type !== "string" || !type.trim()) {
|
|
9943
10353
|
throw new TileflowDomainIRError(
|
|
9944
10354
|
"TILEFLOW_DOMAIN_IR_INVALID_RENDERER",
|
|
9945
|
-
`Layer family ${
|
|
10355
|
+
`Layer family ${id2} requires a renderer.`
|
|
9946
10356
|
);
|
|
9947
10357
|
}
|
|
9948
10358
|
const annotations = publicMetadata(metadata);
|
|
@@ -10224,13 +10634,6 @@ function isRecord5(value) {
|
|
|
10224
10634
|
}
|
|
10225
10635
|
|
|
10226
10636
|
// src/cartography/render-stack.ts
|
|
10227
|
-
var tileflowRenderStackPhases = [
|
|
10228
|
-
"underlay",
|
|
10229
|
-
"overlay",
|
|
10230
|
-
"postRelief",
|
|
10231
|
-
"annotation",
|
|
10232
|
-
"finish"
|
|
10233
|
-
];
|
|
10234
10637
|
var tileflowRenderStackRenderers = [
|
|
10235
10638
|
"background",
|
|
10236
10639
|
"circle",
|
|
@@ -10438,15 +10841,14 @@ var geometryTypes = {
|
|
|
10438
10841
|
point: "Point",
|
|
10439
10842
|
polygon: "Polygon"
|
|
10440
10843
|
};
|
|
10441
|
-
var phaseOrder = new Map(tileflowRenderStackPhases.map((phase, index) => [phase, index]));
|
|
10442
10844
|
function renderPass(input) {
|
|
10443
10845
|
assertOnlyKeys(
|
|
10444
10846
|
input,
|
|
10445
|
-
["
|
|
10847
|
+
["feature", "placement", "renderer", "requirements", "selector", "style"],
|
|
10446
10848
|
"renderPass"
|
|
10447
10849
|
);
|
|
10448
10850
|
requireRenderer(input.renderer);
|
|
10449
|
-
|
|
10851
|
+
requirePlacement(input.placement);
|
|
10450
10852
|
validateStyle(input.renderer, input.style);
|
|
10451
10853
|
if (input.renderer === "background" && ("feature" in input || "selector" in input)) {
|
|
10452
10854
|
throw renderStackError(
|
|
@@ -10461,11 +10863,10 @@ function renderPass(input) {
|
|
|
10461
10863
|
function refineRenderTarget(input) {
|
|
10462
10864
|
assertOnlyKeys(
|
|
10463
10865
|
input,
|
|
10464
|
-
["renderer", "requirements", "selector", "style", "target"],
|
|
10866
|
+
["placement", "renderer", "requirements", "selector", "style", "target"],
|
|
10465
10867
|
"refineRenderTarget"
|
|
10466
10868
|
);
|
|
10467
|
-
|
|
10468
|
-
validateStyle(input.renderer, input.style);
|
|
10869
|
+
validateRefinementShape(input);
|
|
10469
10870
|
if (input.renderer === "background" && "selector" in input) {
|
|
10470
10871
|
throw renderStackError(
|
|
10471
10872
|
"invalid-background-refinement",
|
|
@@ -10515,71 +10916,118 @@ function compileRenderSelector(selector, data) {
|
|
|
10515
10916
|
}
|
|
10516
10917
|
function applyCompiledRenderStacks(input, operations2) {
|
|
10517
10918
|
let layers = input.map(cloneJson21);
|
|
10518
|
-
const
|
|
10519
|
-
const layerOperations = operations2.filter(
|
|
10919
|
+
const passes = operations2.filter(
|
|
10520
10920
|
(operation) => operation.kind === "layer"
|
|
10521
10921
|
);
|
|
10522
|
-
const
|
|
10523
|
-
|
|
10524
|
-
(operation) => operation.requirements.some((requirement) => !activeOwners.has(requirement))
|
|
10525
|
-
).map((operation) => operation.target)
|
|
10922
|
+
const refinements = operations2.filter(
|
|
10923
|
+
(operation) => operation.kind === "refinement"
|
|
10526
10924
|
);
|
|
10527
|
-
|
|
10528
|
-
|
|
10925
|
+
requireUniqueCompiledLayers(layers, passes);
|
|
10926
|
+
const passTargets = new Set(passes.map(({ target }) => target));
|
|
10927
|
+
const knownTargets = /* @__PURE__ */ new Set([...layers.map(({ target }) => target), ...passTargets]);
|
|
10928
|
+
const activeOwners = new Set(layers.map(({ owner }) => owner));
|
|
10929
|
+
const drawn = /* @__PURE__ */ new Set();
|
|
10930
|
+
for (let changed = true; changed; ) {
|
|
10529
10931
|
changed = false;
|
|
10530
|
-
for (const
|
|
10531
|
-
if (
|
|
10532
|
-
|
|
10533
|
-
|
|
10534
|
-
|
|
10932
|
+
for (const pass of passes) {
|
|
10933
|
+
if (drawn.has(pass.target)) continue;
|
|
10934
|
+
const anchor = placementAnchor(pass.placement);
|
|
10935
|
+
if (pass.requirements.some((requirement) => !activeOwners.has(requirement))) continue;
|
|
10936
|
+
if (anchor !== void 0 && passTargets.has(anchor) && !drawn.has(anchor)) continue;
|
|
10937
|
+
drawn.add(pass.target);
|
|
10938
|
+
activeOwners.add(pass.owner);
|
|
10939
|
+
changed = true;
|
|
10940
|
+
}
|
|
10941
|
+
}
|
|
10942
|
+
const activeRefinements = refinements.filter(
|
|
10943
|
+
(refinement) => refinement.requirements.every((requirement) => activeOwners.has(requirement))
|
|
10944
|
+
).sort(compareCompiledOperations);
|
|
10945
|
+
for (const refinement of activeRefinements) {
|
|
10946
|
+
const index = findTargetIndex(layers, refinement.target);
|
|
10947
|
+
if (index < 0 && !passTargets.has(refinement.target)) {
|
|
10948
|
+
throw renderStackError(
|
|
10949
|
+
"unknown-refinement-target",
|
|
10950
|
+
`Render refinement targets unknown semantic contribution: ${refinement.target}.`
|
|
10951
|
+
);
|
|
10535
10952
|
}
|
|
10536
|
-
|
|
10537
|
-
const pending = layerOperations.filter((operation) => !suppressedTargets.has(operation.target)).sort(compareCompiledOperations);
|
|
10538
|
-
requireUniqueCompiledLayers(layers, pending);
|
|
10539
|
-
while (pending.length > 0) {
|
|
10540
|
-
const ready = pending.find((operation) => findTargetIndex(layers, operation.attachTo) >= 0);
|
|
10541
|
-
if (!ready) {
|
|
10953
|
+
if (refinement.placement !== void 0 && placementAnchor(refinement.placement) === refinement.target) {
|
|
10542
10954
|
throw renderStackError(
|
|
10543
10955
|
"unknown-or-circular-anchor",
|
|
10544
|
-
`Render
|
|
10956
|
+
`Render refinement ${refinement.target} cannot be placed beside itself.`
|
|
10545
10957
|
);
|
|
10546
10958
|
}
|
|
10547
|
-
const anchorTarget = ready.attachTo;
|
|
10548
|
-
const group = pending.filter((operation) => operation.attachTo === anchorTarget).sort(compareCompiledOperations);
|
|
10549
|
-
const anchorIndex = findTargetIndex(layers, anchorTarget);
|
|
10550
|
-
const anchor = layers[anchorIndex];
|
|
10551
|
-
const before = group.filter((operation) => operation.phase === "underlay").map((operation) => materializeRenderLayer(operation, anchor));
|
|
10552
|
-
const after = group.filter((operation) => operation.phase !== "underlay").map((operation) => materializeRenderLayer(operation, anchor));
|
|
10553
|
-
layers = [
|
|
10554
|
-
...layers.slice(0, anchorIndex),
|
|
10555
|
-
...before,
|
|
10556
|
-
anchor,
|
|
10557
|
-
...after,
|
|
10558
|
-
...layers.slice(anchorIndex + 1)
|
|
10559
|
-
];
|
|
10560
|
-
for (const operation of group) pending.splice(pending.indexOf(operation), 1);
|
|
10561
10959
|
}
|
|
10562
|
-
const
|
|
10563
|
-
|
|
10564
|
-
|
|
10565
|
-
(
|
|
10566
|
-
|
|
10567
|
-
|
|
10568
|
-
|
|
10569
|
-
|
|
10960
|
+
const isDrawn = (target) => !passTargets.has(target) || drawn.has(target);
|
|
10961
|
+
const pending = [
|
|
10962
|
+
...passes.filter(({ target }) => drawn.has(target)),
|
|
10963
|
+
...activeRefinements.filter(({ placement, target }) => {
|
|
10964
|
+
if (placement === void 0 || !isDrawn(target)) return false;
|
|
10965
|
+
const anchor = placementAnchor(placement);
|
|
10966
|
+
return anchor === void 0 || isDrawn(anchor);
|
|
10967
|
+
})
|
|
10968
|
+
].sort(compareCompiledOperations);
|
|
10969
|
+
for (const operation of pending) {
|
|
10970
|
+
const anchor = placementAnchor(operation.placement);
|
|
10971
|
+
if (anchor !== void 0 && !knownTargets.has(anchor)) {
|
|
10570
10972
|
throw renderStackError(
|
|
10571
|
-
"unknown-
|
|
10572
|
-
|
|
10973
|
+
"unknown-or-circular-anchor",
|
|
10974
|
+
`${operation.target} is placed beside unknown semantic target ${anchor}.`
|
|
10573
10975
|
);
|
|
10574
10976
|
}
|
|
10575
|
-
|
|
10576
|
-
|
|
10577
|
-
|
|
10977
|
+
}
|
|
10978
|
+
const lastPlaced = /* @__PURE__ */ new Map();
|
|
10979
|
+
const isMovePending = (target) => pending.some((operation) => operation.kind === "refinement" && operation.target === target);
|
|
10980
|
+
const isReady = (operation) => {
|
|
10981
|
+
if (operation.kind === "refinement" && findTargetIndex(layers, operation.target) < 0) {
|
|
10982
|
+
return false;
|
|
10983
|
+
}
|
|
10984
|
+
const anchor = placementAnchor(operation.placement);
|
|
10985
|
+
return anchor === void 0 || findTargetIndex(layers, anchor) >= 0 && !isMovePending(anchor);
|
|
10986
|
+
};
|
|
10987
|
+
while (pending.length > 0) {
|
|
10988
|
+
const first = pending.find(isReady);
|
|
10989
|
+
if (first === void 0) {
|
|
10578
10990
|
throw renderStackError(
|
|
10579
|
-
"
|
|
10580
|
-
`Render
|
|
10991
|
+
"unknown-or-circular-anchor",
|
|
10992
|
+
`Render operations are placed beside circular anchors: ${pending.map((operation) => `${operation.target}->${placementKey(operation.placement)}`).join(", ")}.`
|
|
10581
10993
|
);
|
|
10582
10994
|
}
|
|
10995
|
+
const key = placementKey(first.placement);
|
|
10996
|
+
const group = pending.filter(
|
|
10997
|
+
(operation) => placementKey(operation.placement) === key && isReady(operation)
|
|
10998
|
+
);
|
|
10999
|
+
for (const operation of group) pending.splice(pending.indexOf(operation), 1);
|
|
11000
|
+
const moved = /* @__PURE__ */ new Map();
|
|
11001
|
+
for (const operation of group) {
|
|
11002
|
+
if (operation.kind !== "refinement") continue;
|
|
11003
|
+
const index2 = findTargetIndex(layers, operation.target);
|
|
11004
|
+
moved.set(operation.target, requireRefinementOwner(layers[index2], operation));
|
|
11005
|
+
layers = [...layers.slice(0, index2), ...layers.slice(index2 + 1)];
|
|
11006
|
+
for (const [placed, target] of lastPlaced) {
|
|
11007
|
+
if (target === operation.target) lastPlaced.delete(placed);
|
|
11008
|
+
}
|
|
11009
|
+
}
|
|
11010
|
+
const placement = first.placement;
|
|
11011
|
+
const anchor = placementAnchor(placement);
|
|
11012
|
+
const anchorLayer = anchor === void 0 ? void 0 : layers[findTargetIndex(layers, anchor)];
|
|
11013
|
+
const slot = anchorLayer === void 0 ? tileflowBandPlacementSlot(placement) : requireSemanticSlot(anchorLayer, anchor);
|
|
11014
|
+
const block = group.map(
|
|
11015
|
+
(operation) => operation.kind === "layer" ? materializeRenderLayer(operation, anchorLayer, slot) : moveLayer(moved.get(operation.target), operation, slot, anchorLayer)
|
|
11016
|
+
);
|
|
11017
|
+
const previous = lastPlaced.get(key);
|
|
11018
|
+
const previousIndex = previous === void 0 ? -1 : findTargetIndex(layers, previous);
|
|
11019
|
+
const index = anchorLayer !== void 0 ? findTargetIndex(layers, anchor) + (key.startsWith("above:") ? 1 : 0) : previousIndex >= 0 ? previousIndex + 1 : tileflowBandPlacementIndex(
|
|
11020
|
+
layers.map((candidate) => tileflowLayerSlots.indexOf(candidate.slot)),
|
|
11021
|
+
placement
|
|
11022
|
+
);
|
|
11023
|
+
layers = [...layers.slice(0, index), ...block, ...layers.slice(index)];
|
|
11024
|
+
lastPlaced.set(key, block.at(-1).target);
|
|
11025
|
+
}
|
|
11026
|
+
for (const refinement of activeRefinements) {
|
|
11027
|
+
if (refinement.patch === void 0) continue;
|
|
11028
|
+
const index = findTargetIndex(layers, refinement.target);
|
|
11029
|
+
if (index < 0) continue;
|
|
11030
|
+
const previous = requireRefinementOwner(layers[index], refinement);
|
|
10583
11031
|
const expectedType = rendererLayerType(refinement.renderer);
|
|
10584
11032
|
if (previous.renderer !== expectedType) {
|
|
10585
11033
|
throw renderStackError(
|
|
@@ -10587,26 +11035,48 @@ function applyCompiledRenderStacks(input, operations2) {
|
|
|
10587
11035
|
`Render refinement ${refinement.target} expects ${expectedType}, found ${String(previous.renderer)}.`
|
|
10588
11036
|
);
|
|
10589
11037
|
}
|
|
10590
|
-
layers[index] = applyRefinement(previous, refinement);
|
|
11038
|
+
layers[index] = applyRefinement(previous, { ...refinement, patch: refinement.patch });
|
|
10591
11039
|
}
|
|
10592
11040
|
return layers;
|
|
10593
11041
|
}
|
|
11042
|
+
function requireRefinementOwner(layer, refinement) {
|
|
11043
|
+
if (layer.owner !== refinement.owner) {
|
|
11044
|
+
throw renderStackError(
|
|
11045
|
+
"refinement-owner-mismatch",
|
|
11046
|
+
`Render refinement ${refinement.target} belongs to ${layer.owner ?? "no owner"}, not ${refinement.owner}.`
|
|
11047
|
+
);
|
|
11048
|
+
}
|
|
11049
|
+
return layer;
|
|
11050
|
+
}
|
|
11051
|
+
function placementAnchor(placement) {
|
|
11052
|
+
if (placement === void 0 || typeof placement === "string") return void 0;
|
|
11053
|
+
return placement.above ?? placement.below;
|
|
11054
|
+
}
|
|
11055
|
+
function placementKey(placement) {
|
|
11056
|
+
if (typeof placement === "string") return placement;
|
|
11057
|
+
return placement.above === void 0 ? `below:${placement.below}` : `above:${placement.above}`;
|
|
11058
|
+
}
|
|
10594
11059
|
function compileOperation(owner, name, operation, order, data) {
|
|
10595
11060
|
requireOperationName(name);
|
|
10596
11061
|
if (operation.kind === "render-pass") {
|
|
10597
11062
|
validateRenderPassOperation(operation);
|
|
10598
11063
|
const requirements2 = normalizeRequirements(operation.requirements);
|
|
10599
|
-
|
|
11064
|
+
requirePlacementAnchor(owner, operation.placement, requirements2);
|
|
10600
11065
|
const target = `${owner}.render.${name}`;
|
|
10601
11066
|
requirePortableTarget(target, "generated render target");
|
|
11067
|
+
if (typeof operation.placement === "string" && operation.renderer !== "background" && operation.feature === void 0) {
|
|
11068
|
+
throw renderStackError(
|
|
11069
|
+
"missing-inherited-feature",
|
|
11070
|
+
`Render pass ${target} is placed at ${operation.placement} and must declare its feature.`
|
|
11071
|
+
);
|
|
11072
|
+
}
|
|
10602
11073
|
const template2 = compileRenderLayer(target, operation, data);
|
|
10603
11074
|
return {
|
|
10604
|
-
attachTo: operation.attachTo,
|
|
10605
11075
|
kind: "layer",
|
|
10606
11076
|
name,
|
|
10607
11077
|
order,
|
|
10608
11078
|
owner,
|
|
10609
|
-
|
|
11079
|
+
placement: cloneJson21(operation.placement),
|
|
10610
11080
|
renderer: operation.renderer,
|
|
10611
11081
|
requirements: requirements2,
|
|
10612
11082
|
target,
|
|
@@ -10616,6 +11086,21 @@ function compileOperation(owner, name, operation, order, data) {
|
|
|
10616
11086
|
validateRefinementOperation(operation);
|
|
10617
11087
|
requireOwnedTarget(owner, operation.target, "refinement target");
|
|
10618
11088
|
const requirements = normalizeRequirements(operation.requirements);
|
|
11089
|
+
if (operation.placement !== void 0) {
|
|
11090
|
+
requirePlacementAnchor(owner, operation.placement, requirements);
|
|
11091
|
+
}
|
|
11092
|
+
const placement = operation.placement === void 0 ? {} : { placement: cloneJson21(operation.placement) };
|
|
11093
|
+
if (operation.renderer === void 0) {
|
|
11094
|
+
return {
|
|
11095
|
+
kind: "refinement",
|
|
11096
|
+
name,
|
|
11097
|
+
order,
|
|
11098
|
+
owner,
|
|
11099
|
+
...placement,
|
|
11100
|
+
requirements,
|
|
11101
|
+
target: operation.target
|
|
11102
|
+
};
|
|
11103
|
+
}
|
|
10619
11104
|
const template = applyRendererStyle(
|
|
10620
11105
|
{ id: "tileflow-render-refinement-template", type: rendererLayerType(operation.renderer) },
|
|
10621
11106
|
operation.renderer,
|
|
@@ -10629,6 +11114,7 @@ function compileOperation(owner, name, operation, order, data) {
|
|
|
10629
11114
|
order,
|
|
10630
11115
|
owner,
|
|
10631
11116
|
patch,
|
|
11117
|
+
...placement,
|
|
10632
11118
|
renderer: operation.renderer,
|
|
10633
11119
|
requirements,
|
|
10634
11120
|
target: operation.target
|
|
@@ -10806,26 +11292,42 @@ function requireFieldBinding(fieldName, data) {
|
|
|
10806
11292
|
}
|
|
10807
11293
|
return field(fieldName);
|
|
10808
11294
|
}
|
|
10809
|
-
function materializeRenderLayer(operation, anchor) {
|
|
11295
|
+
function materializeRenderLayer(operation, anchor, slot) {
|
|
10810
11296
|
let template = cloneJson21(operation.template);
|
|
10811
11297
|
if (operation.renderer !== "background" && template.feature?.dataSource === void 0) {
|
|
10812
|
-
if (anchor
|
|
11298
|
+
if (anchor?.feature?.dataSource === void 0 || anchor.feature.dataLayer === void 0) {
|
|
10813
11299
|
throw renderStackError(
|
|
10814
11300
|
"missing-inherited-feature",
|
|
10815
|
-
`Render pass ${operation.target} has no feature and
|
|
11301
|
+
`Render pass ${operation.target} has no feature and ${placementKey(operation.placement)} provides no vector feature to inherit.`
|
|
10816
11302
|
);
|
|
10817
11303
|
}
|
|
10818
11304
|
template = { ...template, feature: cloneJson21(anchor.feature) };
|
|
10819
11305
|
}
|
|
10820
|
-
const slot = requireSemanticSlot(anchor, operation.attachTo);
|
|
10821
11306
|
return materializeTileflowLayerFamilyIR(template, {
|
|
10822
11307
|
operations: [{ kind: "pass", owner: operation.owner, target: operation.target }],
|
|
10823
|
-
order: anchor
|
|
11308
|
+
order: anchor?.order ?? 0,
|
|
10824
11309
|
owner: operation.owner,
|
|
10825
11310
|
slot,
|
|
10826
11311
|
target: operation.target
|
|
10827
11312
|
});
|
|
10828
11313
|
}
|
|
11314
|
+
function moveLayer(layer, refinement, slot, anchor) {
|
|
11315
|
+
return {
|
|
11316
|
+
...layer,
|
|
11317
|
+
order: anchor?.order ?? layer.order,
|
|
11318
|
+
origins: layer.origins.map(
|
|
11319
|
+
(origin) => origin.owner === refinement.owner && origin.target === refinement.target ? {
|
|
11320
|
+
...origin,
|
|
11321
|
+
operations: [
|
|
11322
|
+
...origin.operations,
|
|
11323
|
+
{ kind: "refinement", owner: refinement.owner, target: refinement.target }
|
|
11324
|
+
],
|
|
11325
|
+
slot
|
|
11326
|
+
} : origin
|
|
11327
|
+
),
|
|
11328
|
+
slot
|
|
11329
|
+
};
|
|
11330
|
+
}
|
|
10829
11331
|
function applyRefinement(previous, refinement) {
|
|
10830
11332
|
const patch = refinement.patch;
|
|
10831
11333
|
const operation = {
|
|
@@ -10841,7 +11343,8 @@ function applyRefinement(previous, refinement) {
|
|
|
10841
11343
|
...patch.range === void 0 ? {} : { range: { ...previous.range ?? {}, ...patch.range } },
|
|
10842
11344
|
...!Object.hasOwn(patch, "selector") ? {} : { selector: cloneJson21(patch.selector) },
|
|
10843
11345
|
origins: previous.origins.map(
|
|
10844
|
-
(origin) => origin.owner === refinement.owner && origin.target === refinement.target
|
|
11346
|
+
(origin) => origin.owner === refinement.owner && origin.target === refinement.target && // A move already recorded this refinement on the target.
|
|
11347
|
+
refinement.placement === void 0 ? { ...origin, operations: [...origin.operations, operation] } : origin
|
|
10845
11348
|
),
|
|
10846
11349
|
style: {
|
|
10847
11350
|
...previous.style,
|
|
@@ -10872,10 +11375,34 @@ function requireRenderer(value) {
|
|
|
10872
11375
|
throw renderStackError("invalid-renderer", `Unknown render-stack renderer: ${String(value)}.`);
|
|
10873
11376
|
}
|
|
10874
11377
|
}
|
|
10875
|
-
function
|
|
10876
|
-
if (
|
|
10877
|
-
|
|
11378
|
+
function requirePlacement(value) {
|
|
11379
|
+
if (typeof value === "string") {
|
|
11380
|
+
if (tileflowBandPlacements.includes(value)) return;
|
|
11381
|
+
} else if (isRecord6(value)) {
|
|
11382
|
+
const keys = Object.keys(value);
|
|
11383
|
+
if (keys.length === 1 && (keys[0] === "above" || keys[0] === "below")) {
|
|
11384
|
+
requirePortableTarget(value[keys[0]], "render placement target");
|
|
11385
|
+
return;
|
|
11386
|
+
}
|
|
11387
|
+
}
|
|
11388
|
+
throw renderStackError(
|
|
11389
|
+
"invalid-placement",
|
|
11390
|
+
`A render placement is a band edge (${tileflowBandPlacements.join(", ")}) or {above} / {below} one semantic target: ${JSON.stringify(value)}.`
|
|
11391
|
+
);
|
|
11392
|
+
}
|
|
11393
|
+
function validateRefinementShape(operation) {
|
|
11394
|
+
if (operation.placement !== void 0) requirePlacement(operation.placement);
|
|
11395
|
+
if (operation.renderer === void 0) {
|
|
11396
|
+
if (operation.placement === void 0 || "style" in operation || "selector" in operation) {
|
|
11397
|
+
throw renderStackError(
|
|
11398
|
+
"invalid-refinement",
|
|
11399
|
+
"A render refinement declares a renderer with its style, a placement, or both."
|
|
11400
|
+
);
|
|
11401
|
+
}
|
|
11402
|
+
return;
|
|
10878
11403
|
}
|
|
11404
|
+
requireRenderer(operation.renderer);
|
|
11405
|
+
validateStyle(operation.renderer, operation.style);
|
|
10879
11406
|
}
|
|
10880
11407
|
function validateStyle(renderer, style) {
|
|
10881
11408
|
if (!isRecord6(style)) {
|
|
@@ -10995,13 +11522,15 @@ function requireRenderStackEntries(stack) {
|
|
|
10995
11522
|
}
|
|
10996
11523
|
return entries;
|
|
10997
11524
|
}
|
|
10998
|
-
function
|
|
10999
|
-
|
|
11525
|
+
function requirePlacementAnchor(owner, placement, requirements) {
|
|
11526
|
+
requirePlacement(placement);
|
|
11527
|
+
const target = placementAnchor(placement);
|
|
11528
|
+
if (target === void 0) return;
|
|
11000
11529
|
const targetOwner = target.split(".")[0];
|
|
11001
11530
|
if (targetOwner !== owner && !requirements.includes(targetOwner)) {
|
|
11002
11531
|
throw renderStackError(
|
|
11003
11532
|
"cross-owner-attachment",
|
|
11004
|
-
`Render
|
|
11533
|
+
`Render operation owner ${owner} may be placed beside ${target} only with an explicit ${targetOwner} requirement.`
|
|
11005
11534
|
);
|
|
11006
11535
|
}
|
|
11007
11536
|
}
|
|
@@ -11048,18 +11577,16 @@ function requireUniqueCompiledLayers(layers, operations2) {
|
|
|
11048
11577
|
}
|
|
11049
11578
|
}
|
|
11050
11579
|
function compareCompiledOperations(left, right) {
|
|
11051
|
-
|
|
11052
|
-
const rightPhase = right.kind === "layer" ? phaseOrder.get(right.phase) : Number.MAX_SAFE_INTEGER;
|
|
11053
|
-
return leftPhase - rightPhase || left.order - right.order || compareCodeUnits6(left.owner, right.owner) || compareCodeUnits6(left.name, right.name);
|
|
11580
|
+
return left.order - right.order || compareCodeUnits6(left.owner, right.owner) || compareCodeUnits6(left.name, right.name);
|
|
11054
11581
|
}
|
|
11055
11582
|
function validateRenderPassOperation(operation) {
|
|
11056
11583
|
assertOnlyKeys(
|
|
11057
11584
|
operation,
|
|
11058
|
-
["
|
|
11585
|
+
["feature", "kind", "placement", "renderer", "requirements", "selector", "style"],
|
|
11059
11586
|
"render pass operation"
|
|
11060
11587
|
);
|
|
11061
11588
|
requireRenderer(operation.renderer);
|
|
11062
|
-
|
|
11589
|
+
requirePlacement(operation.placement);
|
|
11063
11590
|
validateStyle(operation.renderer, operation.style);
|
|
11064
11591
|
if (operation.renderer === "background" && ("feature" in operation || "selector" in operation)) {
|
|
11065
11592
|
throw renderStackError(
|
|
@@ -11071,11 +11598,10 @@ function validateRenderPassOperation(operation) {
|
|
|
11071
11598
|
function validateRefinementOperation(operation) {
|
|
11072
11599
|
assertOnlyKeys(
|
|
11073
11600
|
operation,
|
|
11074
|
-
["kind", "renderer", "requirements", "selector", "style", "target"],
|
|
11601
|
+
["kind", "placement", "renderer", "requirements", "selector", "style", "target"],
|
|
11075
11602
|
"render refinement operation"
|
|
11076
11603
|
);
|
|
11077
|
-
|
|
11078
|
-
validateStyle(operation.renderer, operation.style);
|
|
11604
|
+
validateRefinementShape(operation);
|
|
11079
11605
|
if (operation.renderer === "background" && "selector" in operation) {
|
|
11080
11606
|
throw renderStackError(
|
|
11081
11607
|
"invalid-background-refinement",
|
|
@@ -11725,6 +12251,11 @@ var textStyleSchema = z6.object({
|
|
|
11725
12251
|
"top-left",
|
|
11726
12252
|
"top-right"
|
|
11727
12253
|
]).optional(),
|
|
12254
|
+
background: z6.object({
|
|
12255
|
+
color: colorValueSchema,
|
|
12256
|
+
fit: z6.literal("lines"),
|
|
12257
|
+
padding: themeNumberValueSchema.optional()
|
|
12258
|
+
}).strict().optional(),
|
|
11728
12259
|
color: colorValueSchema.optional(),
|
|
11729
12260
|
fallbacks: moduleFontFallbacksSchema.optional(),
|
|
11730
12261
|
field: stringValueSchema.optional(),
|
|
@@ -11971,12 +12502,16 @@ var renderRequirementsSchema = z6.array(z6.enum(tileflowLayerDomains)).min(1).ma
|
|
|
11971
12502
|
seen.add(requirement);
|
|
11972
12503
|
}
|
|
11973
12504
|
});
|
|
12505
|
+
var renderPlacementSchema = z6.union([
|
|
12506
|
+
z6.enum(tileflowBandPlacements),
|
|
12507
|
+
z6.object({ above: renderTargetSchema }).strict(),
|
|
12508
|
+
z6.object({ below: renderTargetSchema }).strict()
|
|
12509
|
+
]);
|
|
11974
12510
|
var vectorRenderPassSchemas = tileflowRenderStackRenderers.filter((renderer) => renderer !== "background").map(
|
|
11975
12511
|
(renderer) => z6.object({
|
|
11976
|
-
attachTo: renderTargetSchema,
|
|
11977
12512
|
feature: z6.enum(tileflowSemanticLayerNames).optional(),
|
|
11978
12513
|
kind: z6.literal("render-pass"),
|
|
11979
|
-
|
|
12514
|
+
placement: renderPlacementSchema,
|
|
11980
12515
|
renderer: z6.literal(renderer),
|
|
11981
12516
|
requirements: renderRequirementsSchema.optional(),
|
|
11982
12517
|
selector: renderSelectorSchema.optional(),
|
|
@@ -11985,9 +12520,8 @@ var vectorRenderPassSchemas = tileflowRenderStackRenderers.filter((renderer) =>
|
|
|
11985
12520
|
);
|
|
11986
12521
|
var renderPassSchema = z6.discriminatedUnion("renderer", [
|
|
11987
12522
|
z6.object({
|
|
11988
|
-
attachTo: renderTargetSchema,
|
|
11989
12523
|
kind: z6.literal("render-pass"),
|
|
11990
|
-
|
|
12524
|
+
placement: renderPlacementSchema,
|
|
11991
12525
|
renderer: z6.literal("background"),
|
|
11992
12526
|
requirements: renderRequirementsSchema.optional(),
|
|
11993
12527
|
style: renderStyleSchemas.background
|
|
@@ -11997,6 +12531,7 @@ var renderPassSchema = z6.discriminatedUnion("renderer", [
|
|
|
11997
12531
|
var renderRefinementSchemas = tileflowRenderStackRenderers.map(
|
|
11998
12532
|
(renderer) => z6.object({
|
|
11999
12533
|
kind: z6.literal("refine-render-target"),
|
|
12534
|
+
placement: renderPlacementSchema.optional(),
|
|
12000
12535
|
requirements: renderRequirementsSchema.optional(),
|
|
12001
12536
|
renderer: z6.literal(renderer),
|
|
12002
12537
|
...renderer === "background" ? {} : { selector: renderSelectorSchema.optional() },
|
|
@@ -12004,7 +12539,17 @@ var renderRefinementSchemas = tileflowRenderStackRenderers.map(
|
|
|
12004
12539
|
target: renderTargetSchema
|
|
12005
12540
|
}).strict()
|
|
12006
12541
|
);
|
|
12007
|
-
var
|
|
12542
|
+
var renderPlacementRefinementSchema = z6.object({
|
|
12543
|
+
kind: z6.literal("refine-render-target"),
|
|
12544
|
+
placement: renderPlacementSchema,
|
|
12545
|
+
requirements: renderRequirementsSchema.optional(),
|
|
12546
|
+
target: renderTargetSchema
|
|
12547
|
+
}).strict();
|
|
12548
|
+
var renderStackOperationSchema = z6.union([
|
|
12549
|
+
renderPassSchema,
|
|
12550
|
+
...renderRefinementSchemas,
|
|
12551
|
+
renderPlacementRefinementSchema
|
|
12552
|
+
]);
|
|
12008
12553
|
var renderStackSchema = z6.record(renderStackOperationNameSchema, renderStackOperationSchema).superRefine((stack, context) => {
|
|
12009
12554
|
const size = Object.keys(stack).length;
|
|
12010
12555
|
if (size === 0) {
|
|
@@ -12846,7 +13391,7 @@ var terrainSchema = z6.union([
|
|
|
12846
13391
|
url: z6.string().trim().min(1).optional()
|
|
12847
13392
|
}).strict()
|
|
12848
13393
|
]);
|
|
12849
|
-
var atmosphereColorLiteralSchema = z6.string().refine((value) =>
|
|
13394
|
+
var atmosphereColorLiteralSchema = z6.string().refine((value) => Color3.parse(value)?.a === 1, "Expected an opaque color");
|
|
12850
13395
|
var atmosphereColorSchema = z6.union([
|
|
12851
13396
|
atmosphereColorLiteralSchema,
|
|
12852
13397
|
fixedStringSchema.extend({ value: atmosphereColorLiteralSchema }),
|
|
@@ -13343,7 +13888,7 @@ function cloneJson22(value) {
|
|
|
13343
13888
|
}
|
|
13344
13889
|
|
|
13345
13890
|
// src/icon-appearance.ts
|
|
13346
|
-
import { Color as
|
|
13891
|
+
import { Color as Color4 } from "@maplibre/maplibre-gl-style-spec";
|
|
13347
13892
|
import { z as z8 } from "zod";
|
|
13348
13893
|
|
|
13349
13894
|
// src/icon-layout.ts
|
|
@@ -13417,7 +13962,7 @@ function scaleTileflowIconLayout(layout, scale) {
|
|
|
13417
13962
|
}
|
|
13418
13963
|
|
|
13419
13964
|
// src/icon-appearance.ts
|
|
13420
|
-
var color2 = z8.string().max(128).refine((value) =>
|
|
13965
|
+
var color2 = z8.string().max(128).refine((value) => Color4.parse(value) !== void 0, "Expected a MapLibre color");
|
|
13421
13966
|
var tileflowIconAppearanceSchema = z8.object({
|
|
13422
13967
|
representation: z8.literal("sdf"),
|
|
13423
13968
|
defaults: z8.object({
|
|
@@ -13491,9 +14036,9 @@ function applyTileflowIconCapabilities(style, icons) {
|
|
|
13491
14036
|
if (!icons?.appearances || !Object.keys(icons.appearances).length) return;
|
|
13492
14037
|
const ids = [...icons.ids];
|
|
13493
14038
|
const appearances = icons.appearances;
|
|
13494
|
-
for (const [
|
|
13495
|
-
if (!ids.includes(
|
|
13496
|
-
throw new Error(`Icon capability metadata references unknown icon "${
|
|
14039
|
+
for (const [id2, appearance] of Object.entries(appearances)) {
|
|
14040
|
+
if (!ids.includes(id2))
|
|
14041
|
+
throw new Error(`Icon capability metadata references unknown icon "${id2}".`);
|
|
13497
14042
|
tileflowIconAppearanceSchema.parse(appearance);
|
|
13498
14043
|
}
|
|
13499
14044
|
for (const layer of style.layers) {
|
|
@@ -13504,7 +14049,7 @@ function applyTileflowIconCapabilities(style, icons) {
|
|
|
13504
14049
|
"background-pattern"
|
|
13505
14050
|
]) {
|
|
13506
14051
|
const pattern = record(layer.paint)[property];
|
|
13507
|
-
if (pattern !== void 0 && [...outputs(pattern, ids)].some((
|
|
14052
|
+
if (pattern !== void 0 && [...outputs(pattern, ids)].some((id2) => appearances[id2]?.representation === "sdf")) {
|
|
13508
14053
|
throw Object.assign(new Error(`Layer "${layer.id}" cannot use an SDF icon as a pattern.`), {
|
|
13509
14054
|
code: "TF_ICON_PATTERN_SDF",
|
|
13510
14055
|
path: `layers.${layer.id}.paint.${property}`,
|
|
@@ -13522,7 +14067,7 @@ function applyTileflowIconCapabilities(style, icons) {
|
|
|
13522
14067
|
});
|
|
13523
14068
|
}
|
|
13524
14069
|
const names = [...outputs(image, ids)];
|
|
13525
|
-
const sdf = names.filter((
|
|
14070
|
+
const sdf = names.filter((id2) => appearances[id2]?.representation === "sdf");
|
|
13526
14071
|
if (!sdf.length) continue;
|
|
13527
14072
|
if (sdf.length !== names.length) {
|
|
13528
14073
|
throw Object.assign(
|
|
@@ -13634,7 +14179,7 @@ function numericBounds(value) {
|
|
|
13634
14179
|
];
|
|
13635
14180
|
}
|
|
13636
14181
|
function defaultPaint(image, key, names, appearances, ids) {
|
|
13637
|
-
const values = names.map((
|
|
14182
|
+
const values = names.map((id2) => appearances[id2].defaults[key]);
|
|
13638
14183
|
if (new Set(values).size === 1) return values[0];
|
|
13639
14184
|
if (Array.isArray(image) && (image[0] === "step" || image[0] === "interpolate")) {
|
|
13640
14185
|
const copy = [...image];
|
|
@@ -13645,7 +14190,7 @@ function defaultPaint(image, key, names, appearances, ids) {
|
|
|
13645
14190
|
return [
|
|
13646
14191
|
"match",
|
|
13647
14192
|
["to-string", selection(image, ids)],
|
|
13648
|
-
...names.flatMap((
|
|
14193
|
+
...names.flatMap((id2, i) => [id2, values[i]]),
|
|
13649
14194
|
values[0]
|
|
13650
14195
|
];
|
|
13651
14196
|
}
|
|
@@ -13655,18 +14200,18 @@ var tileflowInteractionManifestMetadataKey = "tileflow:interaction-manifest";
|
|
|
13655
14200
|
var tileflowInteractionManifestVersion = 2;
|
|
13656
14201
|
function createTileflowInteractionManifest(layers, fields) {
|
|
13657
14202
|
const poiLayers = layers.flatMap((layer, priority) => {
|
|
13658
|
-
const
|
|
14203
|
+
const id2 = typeof layer.id === "string" ? layer.id : void 0;
|
|
13659
14204
|
const source = typeof layer.source === "string" ? layer.source : void 0;
|
|
13660
14205
|
const sourceLayer = typeof layer["source-layer"] === "string" ? layer["source-layer"] : void 0;
|
|
13661
14206
|
const target = semanticTarget(layer);
|
|
13662
|
-
if (!
|
|
14207
|
+
if (!id2 || !source || !sourceLayer || !target?.startsWith("poi.")) return [];
|
|
13663
14208
|
const parsed = parsePoiTarget(target);
|
|
13664
14209
|
if (!parsed) return [];
|
|
13665
14210
|
return [
|
|
13666
14211
|
{
|
|
13667
14212
|
...parsed,
|
|
13668
14213
|
anchor: "pointer-coordinate",
|
|
13669
|
-
layerId:
|
|
14214
|
+
layerId: id2,
|
|
13670
14215
|
priority,
|
|
13671
14216
|
source,
|
|
13672
14217
|
sourceLayer
|
|
@@ -13765,11 +14310,11 @@ function createTileflowOverlayPlacementManifest(layers) {
|
|
|
13765
14310
|
const anchors = Object.fromEntries(
|
|
13766
14311
|
tileflowOverlayPlacements.map((placement) => {
|
|
13767
14312
|
const index = tileflowOverlayInsertionIndex(layers, placement);
|
|
13768
|
-
const
|
|
13769
|
-
if (
|
|
14313
|
+
const id2 = index < layers.length ? layers[index]?.id : void 0;
|
|
14314
|
+
if (id2 !== void 0 && typeof id2 !== "string") {
|
|
13770
14315
|
throw new Error(`Tileflow overlay placement ${placement} resolved an invalid layer ID.`);
|
|
13771
14316
|
}
|
|
13772
|
-
return [placement,
|
|
14317
|
+
return [placement, id2 ?? null];
|
|
13773
14318
|
})
|
|
13774
14319
|
);
|
|
13775
14320
|
return {
|
|
@@ -15013,10 +15558,10 @@ function compileSemanticStyleInternal(input, options, inspect, onReport) {
|
|
|
15013
15558
|
function finalizeTileflowLayers(input) {
|
|
15014
15559
|
const ids = /* @__PURE__ */ new Set();
|
|
15015
15560
|
return input.map((layer, index) => {
|
|
15016
|
-
const
|
|
15017
|
-
if (!
|
|
15018
|
-
if (ids.has(
|
|
15019
|
-
ids.add(
|
|
15561
|
+
const id2 = typeof layer.id === "string" ? layer.id : "";
|
|
15562
|
+
if (!id2) throw new Error(`Compiled Tileflow layer at index ${index} has no ID.`);
|
|
15563
|
+
if (ids.has(id2)) throw new Error(`Duplicate compiled Tileflow layer ID: ${id2}`);
|
|
15564
|
+
ids.add(id2);
|
|
15020
15565
|
const minimum2 = layer.minzoom;
|
|
15021
15566
|
const maximum2 = layer.maxzoom;
|
|
15022
15567
|
for (const [name, value] of [
|
|
@@ -15025,11 +15570,11 @@ function finalizeTileflowLayers(input) {
|
|
|
15025
15570
|
]) {
|
|
15026
15571
|
if (value === void 0) continue;
|
|
15027
15572
|
if (typeof value !== "number" || !Number.isFinite(value) || value < 0 || value > 24) {
|
|
15028
|
-
throw new Error(`Compiled Tileflow layer ${
|
|
15573
|
+
throw new Error(`Compiled Tileflow layer ${id2} has invalid ${name}: ${String(value)}`);
|
|
15029
15574
|
}
|
|
15030
15575
|
}
|
|
15031
15576
|
if (typeof minimum2 === "number" && typeof maximum2 === "number" && minimum2 > maximum2) {
|
|
15032
|
-
throw new Error(`Compiled Tileflow layer ${
|
|
15577
|
+
throw new Error(`Compiled Tileflow layer ${id2} requires minzoom <= maxzoom.`);
|
|
15033
15578
|
}
|
|
15034
15579
|
const metadata = isRecord8(layer.metadata) ? { ...layer.metadata } : void 0;
|
|
15035
15580
|
if (metadata) {
|
|
@@ -15073,7 +15618,7 @@ function assertPreparedIconReferences(style, config, prepared) {
|
|
|
15073
15618
|
const references = collectStyleImageReferences(style);
|
|
15074
15619
|
if (references.size === 0) return;
|
|
15075
15620
|
const available = new Set(prepared?.icons?.ids ?? []);
|
|
15076
|
-
const missing = [...references].filter((
|
|
15621
|
+
const missing = [...references].filter((id2) => !available.has(id2)).sort();
|
|
15077
15622
|
if (missing.length === 0 && prepared?.icons?.sprite) return;
|
|
15078
15623
|
const authoring = config.icons?.length ? "Run the Node build so map.icons directories are prepared." : "Declare map.icons with directories containing those canonical filenames.";
|
|
15079
15624
|
throw new Error(
|
|
@@ -15177,7 +15722,8 @@ function assertGlyphFontStacks(style, config) {
|
|
|
15177
15722
|
const font = layout?.["text-font"];
|
|
15178
15723
|
if (!Array.isArray(font) || !font.every((entry) => typeof entry === "string")) continue;
|
|
15179
15724
|
const stack = font.join(",");
|
|
15180
|
-
|
|
15725
|
+
const source = parseTileflowLineBackgroundFontStack(stack)?.source ?? stack;
|
|
15726
|
+
if (stack && !declared.has(source)) missing.add(source);
|
|
15181
15727
|
}
|
|
15182
15728
|
if (missing.size > 0) {
|
|
15183
15729
|
throw new Error(
|
|
@@ -15200,6 +15746,15 @@ function assertTextAssets(style, config) {
|
|
|
15200
15746
|
}
|
|
15201
15747
|
if (textLayers.length === 0) return;
|
|
15202
15748
|
if (config.fonts !== void 0) {
|
|
15749
|
+
const backed = style.layers.find((layer) => {
|
|
15750
|
+
const font = isRecord8(layer.layout) ? layer.layout["text-font"] : void 0;
|
|
15751
|
+
return Array.isArray(font) && font.length === 1 && typeof font[0] === "string" && parseTileflowLineBackgroundFontStack(font[0]) !== void 0;
|
|
15752
|
+
});
|
|
15753
|
+
if (backed) {
|
|
15754
|
+
throw new Error(
|
|
15755
|
+
`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.`
|
|
15756
|
+
);
|
|
15757
|
+
}
|
|
15203
15758
|
if (config.fonts.length > 0) return;
|
|
15204
15759
|
throw new Error(
|
|
15205
15760
|
`Tileflow map "${config.id}" contains text but declares an empty fonts directory array.`
|
|
@@ -15416,10 +15971,10 @@ function resolveMap(map, options = {}) {
|
|
|
15416
15971
|
}
|
|
15417
15972
|
}
|
|
15418
15973
|
const leaf = lineage[0];
|
|
15419
|
-
const
|
|
15974
|
+
const id2 = parseMapId(leaf.id);
|
|
15420
15975
|
const resolved = {
|
|
15421
|
-
id,
|
|
15422
|
-
name: leaf.name ??
|
|
15976
|
+
id: id2,
|
|
15977
|
+
name: leaf.name ?? id2,
|
|
15423
15978
|
version: leaf.version,
|
|
15424
15979
|
...design,
|
|
15425
15980
|
...modules === void 0 ? {} : { modules }
|
|
@@ -15802,12 +16357,12 @@ function validateTileflowMap(input) {
|
|
|
15802
16357
|
}
|
|
15803
16358
|
|
|
15804
16359
|
// src/icon-preview.ts
|
|
15805
|
-
import { Color as
|
|
16360
|
+
import { Color as Color5 } from "@maplibre/maplibre-gl-style-spec";
|
|
15806
16361
|
function resolveTileflowIconPreviewPaint(appearance) {
|
|
15807
16362
|
return {
|
|
15808
16363
|
...appearance.defaults,
|
|
15809
|
-
color:
|
|
15810
|
-
haloColor:
|
|
16364
|
+
color: Color5.parse(appearance.defaults.color),
|
|
16365
|
+
haloColor: Color5.parse(appearance.defaults.haloColor)
|
|
15811
16366
|
};
|
|
15812
16367
|
}
|
|
15813
16368
|
function createTileflowIconPreviewRuntime() {
|
|
@@ -15928,13 +16483,13 @@ var operations = [
|
|
|
15928
16483
|
},
|
|
15929
16484
|
{
|
|
15930
16485
|
api: "withRenderStack(module, { name: renderPass(...) })",
|
|
15931
|
-
description: "Add an owner-local semantic pass
|
|
16486
|
+
description: "Add an owner-local semantic pass at a band edge or beside a semantic target.",
|
|
15932
16487
|
name: "render-pass",
|
|
15933
16488
|
scope: "render-stack"
|
|
15934
16489
|
},
|
|
15935
16490
|
{
|
|
15936
16491
|
api: "withRenderStack(module, { name: refineRenderTarget(...) })",
|
|
15937
|
-
description: "Refine an owner-local semantic target without a physical layer patch.",
|
|
16492
|
+
description: "Refine or move an owner-local semantic target without a physical layer patch.",
|
|
15938
16493
|
name: "refine-render-target",
|
|
15939
16494
|
scope: "render-stack"
|
|
15940
16495
|
}
|
|
@@ -16081,6 +16636,7 @@ var expressionBuilders = [
|
|
|
16081
16636
|
returns: "boolean",
|
|
16082
16637
|
serializedOperator: "has"
|
|
16083
16638
|
},
|
|
16639
|
+
{ arguments: [], name: "id", returns: "string | number | null", serializedOperator: "id" },
|
|
16084
16640
|
{
|
|
16085
16641
|
arguments: [
|
|
16086
16642
|
"interpolation: linear | exponential(base) | cubic-bezier(x1,y1,x2,y2)",
|
|
@@ -16137,6 +16693,12 @@ var expressionBuilders = [
|
|
|
16137
16693
|
returns: "number",
|
|
16138
16694
|
serializedOperator: "min"
|
|
16139
16695
|
},
|
|
16696
|
+
{
|
|
16697
|
+
arguments: ["dividend: number", "divisor: number"],
|
|
16698
|
+
name: "modulo",
|
|
16699
|
+
returns: "number",
|
|
16700
|
+
serializedOperator: "%"
|
|
16701
|
+
},
|
|
16140
16702
|
{
|
|
16141
16703
|
arguments: ["first: number", "second: number", "...rest: number[]"],
|
|
16142
16704
|
name: "multiply",
|
|
@@ -16286,7 +16848,10 @@ var tileflowAuthoringManifest = deepFreeze2({
|
|
|
16286
16848
|
geometries: [...tileflowRenderSelectorGeometries],
|
|
16287
16849
|
limits: tileflowRenderStackLimits,
|
|
16288
16850
|
operationNamePattern: tileflowRenderStackOperationNamePattern.source,
|
|
16289
|
-
|
|
16851
|
+
placements: {
|
|
16852
|
+
bands: [...tileflowBandPlacements],
|
|
16853
|
+
targets: ["{ above: target }", "{ below: target }"]
|
|
16854
|
+
},
|
|
16290
16855
|
renderers: [...tileflowRenderStackRenderers],
|
|
16291
16856
|
selectorKinds: [...tileflowRenderSelectorKinds],
|
|
16292
16857
|
targetPattern: tileflowSemanticTargetPattern.source
|
|
@@ -16984,6 +17549,30 @@ function validateTileflowRuntimeSource(source) {
|
|
|
16984
17549
|
function validateTileflowThemeSelection(value) {
|
|
16985
17550
|
return value === "system" || isTileflowThemeName(value);
|
|
16986
17551
|
}
|
|
17552
|
+
var tileflowThemeBlendLimits = Object.freeze({ maximumThemes: 8, minimumThemes: 2 });
|
|
17553
|
+
function validateTileflowThemeBlendSelection(value) {
|
|
17554
|
+
if (!value || typeof value !== "object") return false;
|
|
17555
|
+
const { position, themes } = value;
|
|
17556
|
+
return Array.isArray(themes) && themes.length >= tileflowThemeBlendLimits.minimumThemes && themes.length <= tileflowThemeBlendLimits.maximumThemes && themes.every((theme) => isTileflowThemeName(theme)) && typeof position === "number" && Number.isFinite(position) && position >= 0 && position <= themes.length - 1;
|
|
17557
|
+
}
|
|
17558
|
+
function nearestTileflowBlendTheme(blend) {
|
|
17559
|
+
const index = Math.min(blend.themes.length - 1, Math.max(0, Math.round(blend.position)));
|
|
17560
|
+
return blend.themes[index];
|
|
17561
|
+
}
|
|
17562
|
+
function resolveTileflowRuntimeThemeBlend(options) {
|
|
17563
|
+
if (!validateTileflowThemeBlendSelection(options.blend)) {
|
|
17564
|
+
throw new TypeError(
|
|
17565
|
+
"A Tileflow theme blend requires two to eight concrete themes and a position."
|
|
17566
|
+
);
|
|
17567
|
+
}
|
|
17568
|
+
return options.blend.themes.map(
|
|
17569
|
+
(theme) => resolveTileflowRuntimeStyle({
|
|
17570
|
+
manifestMap: options.manifestMap,
|
|
17571
|
+
source: options.source,
|
|
17572
|
+
theme
|
|
17573
|
+
})
|
|
17574
|
+
);
|
|
17575
|
+
}
|
|
16987
17576
|
function assertValidTileflowRuntimeSource(source) {
|
|
16988
17577
|
const validation = validateTileflowRuntimeSource(source);
|
|
16989
17578
|
if (!validation.ok) {
|
|
@@ -17936,7 +18525,7 @@ async function serializeTileflowIconsLockfile(input) {
|
|
|
17936
18525
|
import { z as z12 } from "zod";
|
|
17937
18526
|
var tileflowIconCompositionMaximumBytes = 1024 * 1024;
|
|
17938
18527
|
var idsSchema = z12.array(tileflowIconIdSchema).max(tileflowIconPackageLimits.maxIconCount).refine(
|
|
17939
|
-
(ids) => new Set(ids).size === ids.length && ids.every((
|
|
18528
|
+
(ids) => new Set(ids).size === ids.length && ids.every((id2, index) => index === 0 || compareCodeUnits11(ids[index - 1], id2) < 0),
|
|
17940
18529
|
"Icon exports must be unique and sorted by code unit"
|
|
17941
18530
|
);
|
|
17942
18531
|
var localContributorSchema = z12.object({ kind: z12.literal("local"), iconIds: idsSchema }).strict();
|
|
@@ -18031,7 +18620,7 @@ var tileflowIconCompositionSchema = z12.object({
|
|
|
18031
18620
|
teams.add(contributor.teamId);
|
|
18032
18621
|
teamSlugs.add(contributor.reference.split("/")[0]);
|
|
18033
18622
|
}
|
|
18034
|
-
for (const
|
|
18623
|
+
for (const id2 of contributor.iconIds) expected.set(id2, ordinal);
|
|
18035
18624
|
}
|
|
18036
18625
|
if (teams.size !== 1 || teamSlugs.size !== 1)
|
|
18037
18626
|
context.addIssue({
|
|
@@ -18123,12 +18712,14 @@ export {
|
|
|
18123
18712
|
createStyle,
|
|
18124
18713
|
createStyleResult,
|
|
18125
18714
|
createTileflowIconPreviewRuntime,
|
|
18715
|
+
createTileflowLineBackgroundFontStack,
|
|
18126
18716
|
createTileflowSessionController,
|
|
18127
18717
|
createTileflowSessionId,
|
|
18128
18718
|
defaultTileflowManifestUrl,
|
|
18129
18719
|
defaultTileflowRuntimeView,
|
|
18130
18720
|
defineMap,
|
|
18131
18721
|
defineTheme,
|
|
18722
|
+
deriveTileflowLineBackgroundGlyphs,
|
|
18132
18723
|
diffTileflowIconPackageManifests,
|
|
18133
18724
|
diffTileflowMaps,
|
|
18134
18725
|
disable,
|
|
@@ -18161,8 +18752,10 @@ export {
|
|
|
18161
18752
|
maplibreOverlay,
|
|
18162
18753
|
mergeTileflowAnalytics,
|
|
18163
18754
|
nautical,
|
|
18755
|
+
nearestTileflowBlendTheme,
|
|
18164
18756
|
normalizeTileflowCaptureId,
|
|
18165
18757
|
normalizeTileflowCaptureScene,
|
|
18758
|
+
normalizeTileflowLineBackgroundMetrics,
|
|
18166
18759
|
normalizeTileflowRuntimeCenter,
|
|
18167
18760
|
normalizeTileflowStaticImageSize,
|
|
18168
18761
|
normalizeTileflowUrl,
|
|
@@ -18172,6 +18765,7 @@ export {
|
|
|
18172
18765
|
parseTileflowIconComposition,
|
|
18173
18766
|
parseTileflowIconJson,
|
|
18174
18767
|
parseTileflowIconsLockfile,
|
|
18768
|
+
parseTileflowLineBackgroundFontStack,
|
|
18175
18769
|
parseTileflowMap,
|
|
18176
18770
|
parseTileflowRuntimeManifest,
|
|
18177
18771
|
poi,
|
|
@@ -18193,12 +18787,14 @@ export {
|
|
|
18193
18787
|
resolveTileflowMapMode,
|
|
18194
18788
|
resolveTileflowRuntimeStyle,
|
|
18195
18789
|
resolveTileflowRuntimeTheme,
|
|
18790
|
+
resolveTileflowRuntimeThemeBlend,
|
|
18196
18791
|
resolveTileflowRuntimeView,
|
|
18197
18792
|
resolveTileflowStaticImageUrl,
|
|
18198
18793
|
resolveTileflowTheme,
|
|
18199
18794
|
roads,
|
|
18200
18795
|
safeParseTileflowRuntimeManifest,
|
|
18201
18796
|
scaleTileflowIconLayout,
|
|
18797
|
+
scaleTileflowTextSizeForLineBackground,
|
|
18202
18798
|
serializeCanonicalJson,
|
|
18203
18799
|
serializeTileflowFontBundleManifest,
|
|
18204
18800
|
serializeTileflowIconPackageManifest,
|
|
@@ -18208,6 +18804,7 @@ export {
|
|
|
18208
18804
|
startTileflowSession,
|
|
18209
18805
|
tileflowAuthoringManifest,
|
|
18210
18806
|
tileflowAuthoringManifestSchemaVersion,
|
|
18807
|
+
tileflowBandPlacements,
|
|
18211
18808
|
tileflowBathymetryDemSourceId,
|
|
18212
18809
|
tileflowBathymetrySourceId,
|
|
18213
18810
|
tileflowBathymetryV1Schema,
|
|
@@ -18259,6 +18856,10 @@ export {
|
|
|
18259
18856
|
tileflowIconsLockfileName,
|
|
18260
18857
|
tileflowIconsLockfileSchema,
|
|
18261
18858
|
tileflowLandformClasses,
|
|
18859
|
+
tileflowLayerBands,
|
|
18860
|
+
tileflowLineBackgroundDefaults,
|
|
18861
|
+
tileflowLineBackgroundHaloRatio,
|
|
18862
|
+
tileflowLineBackgroundLimits,
|
|
18262
18863
|
tileflowLocalDirectoryMaximumLength,
|
|
18263
18864
|
tileflowLocalDirectoryMessage,
|
|
18264
18865
|
tileflowMapDefaultMaxDepth,
|
|
@@ -18275,7 +18876,6 @@ export {
|
|
|
18275
18876
|
tileflowRenderSelectorGeometries,
|
|
18276
18877
|
tileflowRenderSelectorKinds,
|
|
18277
18878
|
tileflowRenderStackLimits,
|
|
18278
|
-
tileflowRenderStackPhases,
|
|
18279
18879
|
tileflowRenderStackRenderers,
|
|
18280
18880
|
tileflowRenderedIconIdentitySchema,
|
|
18281
18881
|
tileflowRenderedIconManifestEntrySchema,
|
|
@@ -18286,6 +18886,7 @@ export {
|
|
|
18286
18886
|
tileflowSemanticDiffSchemaVersion,
|
|
18287
18887
|
tileflowStyleFontFaceLimits,
|
|
18288
18888
|
tileflowStyleFontFacesMetadataKey,
|
|
18889
|
+
tileflowThemeBlendLimits,
|
|
18289
18890
|
tileflowThemeLimits,
|
|
18290
18891
|
tileflowThemeNameSchema,
|
|
18291
18892
|
tileflowThemeTokenCategories,
|
|
@@ -18304,6 +18905,7 @@ export {
|
|
|
18304
18905
|
validateTileflowDataCompatibility,
|
|
18305
18906
|
validateTileflowMap,
|
|
18306
18907
|
validateTileflowRuntimeSource,
|
|
18908
|
+
validateTileflowThemeBlendSelection,
|
|
18307
18909
|
validateTileflowThemeSelection,
|
|
18308
18910
|
validateTileflowWorldV1Tilejson,
|
|
18309
18911
|
vectorTiles,
|