@tileflow/core 0.1.0-alpha.38 → 0.1.0-alpha.39
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 +9 -9
- package/dist/{3d-D9c3i78O.d.ts → 3d-BkaJjwfk.d.ts} +3 -0
- package/dist/3d.d.ts +1 -1
- package/dist/3d.js +325 -76
- package/dist/browser.d.ts +341 -12
- package/dist/browser.js +9412 -7855
- package/dist/build.d.ts +4 -3
- package/dist/build.js +854 -117
- package/dist/capture.js +4 -1
- package/dist/config-reference.json +417 -159
- package/dist/{icon-composition-Br4Bd2bY.d.ts → icon-composition-Ivgoxz8d.d.ts} +156 -5
- package/dist/index.d.ts +165 -5
- package/dist/index.js +1508 -260
- package/dist/{manifest-types-jrBdBrES.d.ts → manifest-types-DRy2980g.d.ts} +5 -2
- package/dist/manifest.d.ts +2 -2
- package/dist/manifest.js +4 -1
- package/dist/native-profile.d.ts +4 -0
- package/dist/native-profile.js +2 -0
- package/dist/native.js +11 -1
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +11 -1
- package/dist/worker/camera-tile-worker.global.js +20 -1
- package/docs/globe-atmosphere.md +3 -0
- package/docs/native-artifact-profile.md +2 -2
- package/docs/nautical-marks.md +147 -39
- package/docs/public-api-and-browser-subpath.md +3 -2
- package/docs/street-sky.md +153 -0
- package/docs/sun-and-light.md +4 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13,6 +13,114 @@ var __export = (target, all2) => {
|
|
|
13
13
|
__defProp(target, name, { get: all2[name], enumerable: true });
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
+
// src/theme-blend.ts
|
|
17
|
+
function mixTileflowColours(from, to, t) {
|
|
18
|
+
const a = oklab(from);
|
|
19
|
+
const b = oklab(to);
|
|
20
|
+
if (!a || !b) return void 0;
|
|
21
|
+
return colourFromOklab(a.map((value, channel) => value + (b[channel] - value) * t));
|
|
22
|
+
}
|
|
23
|
+
function oklab(colour) {
|
|
24
|
+
const cached = oklabCache.get(colour);
|
|
25
|
+
if (cached !== void 0) return cached;
|
|
26
|
+
const rgba = parseColour(colour);
|
|
27
|
+
let result = null;
|
|
28
|
+
if (rgba) {
|
|
29
|
+
const [r, g, b] = rgba.slice(0, 3).map((channel) => {
|
|
30
|
+
const value = channel / 255;
|
|
31
|
+
return value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;
|
|
32
|
+
});
|
|
33
|
+
const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);
|
|
34
|
+
const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);
|
|
35
|
+
const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);
|
|
36
|
+
result = [
|
|
37
|
+
0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,
|
|
38
|
+
1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,
|
|
39
|
+
0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,
|
|
40
|
+
rgba[3]
|
|
41
|
+
];
|
|
42
|
+
}
|
|
43
|
+
if (oklabCache.size > 4096) oklabCache.clear();
|
|
44
|
+
oklabCache.set(colour, result);
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
47
|
+
function colourFromOklab([lightness, a, b, alpha2]) {
|
|
48
|
+
const l = (lightness + 0.3963377774 * a + 0.2158037573 * b) ** 3;
|
|
49
|
+
const m = (lightness - 0.1055613458 * a - 0.0638541728 * b) ** 3;
|
|
50
|
+
const s = (lightness - 0.0894841775 * a - 1.291485548 * b) ** 3;
|
|
51
|
+
const [red, green, blue] = [
|
|
52
|
+
4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
|
|
53
|
+
-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
|
|
54
|
+
-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s
|
|
55
|
+
].map((value) => {
|
|
56
|
+
const clamped = Math.min(1, Math.max(0, value));
|
|
57
|
+
const encoded = clamped <= 31308e-7 ? clamped * 12.92 : 1.055 * clamped ** (1 / 2.4) - 0.055;
|
|
58
|
+
return Math.round(encoded * 255);
|
|
59
|
+
});
|
|
60
|
+
return `rgba(${red}, ${green}, ${blue}, ${Number(alpha2.toFixed(3))})`;
|
|
61
|
+
}
|
|
62
|
+
function tileflowColourChannels(colour) {
|
|
63
|
+
const rgba = parseColour(colour);
|
|
64
|
+
if (!rgba) return null;
|
|
65
|
+
return [
|
|
66
|
+
Math.min(1, Math.max(0, rgba[0] / 255)),
|
|
67
|
+
Math.min(1, Math.max(0, rgba[1] / 255)),
|
|
68
|
+
Math.min(1, Math.max(0, rgba[2] / 255)),
|
|
69
|
+
Math.min(1, Math.max(0, rgba[3]))
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
function parseColour(colour) {
|
|
73
|
+
const text = colour.trim().toLowerCase();
|
|
74
|
+
const hex = /^#([\da-f]{3,8})$/u.exec(text)?.[1];
|
|
75
|
+
if (hex && [3, 4, 6, 8].includes(hex.length)) {
|
|
76
|
+
const full = hex.length <= 4 ? [...hex].map((digit) => digit + digit).join("") : hex;
|
|
77
|
+
const channels = full.match(/../gu).map((pair) => Number.parseInt(pair, 16));
|
|
78
|
+
return [channels[0], channels[1], channels[2], channels.length > 3 ? channels[3] / 255 : 1];
|
|
79
|
+
}
|
|
80
|
+
const functional = /^(rgba?|hsla?)\(([^)]+)\)$/u.exec(text);
|
|
81
|
+
if (!functional) return null;
|
|
82
|
+
const parts = functional[2].split(/[\s,/]+/u).filter(Boolean);
|
|
83
|
+
if (parts.length < 3 || parts.length > 4) return null;
|
|
84
|
+
const alpha2 = parts[3] === void 0 ? 1 : parseUnit(parts[3], 1);
|
|
85
|
+
if (functional[1].startsWith("rgb")) {
|
|
86
|
+
const [r, g, b] = parts.slice(0, 3).map((part) => parseUnit(part, 255));
|
|
87
|
+
if ([r, g, b, alpha2].some((value) => value === null)) return null;
|
|
88
|
+
return [r, g, b, alpha2];
|
|
89
|
+
}
|
|
90
|
+
const hue = Number.parseFloat(parts[0]);
|
|
91
|
+
const saturation = parseUnit(parts[1], 1);
|
|
92
|
+
const light = parseUnit(parts[2], 1);
|
|
93
|
+
if (!Number.isFinite(hue) || saturation === null || light === null || alpha2 === null) return null;
|
|
94
|
+
const chroma = (1 - Math.abs(2 * light - 1)) * saturation;
|
|
95
|
+
const sector = (hue % 360 + 360) % 360 / 60;
|
|
96
|
+
const x = chroma * (1 - Math.abs(sector % 2 - 1));
|
|
97
|
+
const [r1, g1, b1] = sector < 1 ? [chroma, x, 0] : sector < 2 ? [x, chroma, 0] : sector < 3 ? [0, chroma, x] : sector < 4 ? [0, x, chroma] : sector < 5 ? [x, 0, chroma] : [chroma, 0, x];
|
|
98
|
+
const offset = light - chroma / 2;
|
|
99
|
+
return [(r1 + offset) * 255, (g1 + offset) * 255, (b1 + offset) * 255, alpha2];
|
|
100
|
+
}
|
|
101
|
+
function parseUnit(part, scale) {
|
|
102
|
+
const percentage = part.endsWith("%");
|
|
103
|
+
const value = Number.parseFloat(part);
|
|
104
|
+
if (!Number.isFinite(value)) return null;
|
|
105
|
+
return percentage ? value / 100 * scale : value;
|
|
106
|
+
}
|
|
107
|
+
var oklabCache;
|
|
108
|
+
var init_theme_blend = __esm({
|
|
109
|
+
"src/theme-blend.ts"() {
|
|
110
|
+
"use strict";
|
|
111
|
+
oklabCache = /* @__PURE__ */ new Map();
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// src/camera-limits.ts
|
|
116
|
+
var tileflowMaxPitch;
|
|
117
|
+
var init_camera_limits = __esm({
|
|
118
|
+
"src/camera-limits.ts"() {
|
|
119
|
+
"use strict";
|
|
120
|
+
tileflowMaxPitch = 85;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
|
|
16
124
|
// src/native-zod-object.ts
|
|
17
125
|
import { z } from "zod";
|
|
18
126
|
function strictNativeObject(shape) {
|
|
@@ -483,105 +591,6 @@ var init_operations = __esm({
|
|
|
483
591
|
}
|
|
484
592
|
});
|
|
485
593
|
|
|
486
|
-
// src/theme-blend.ts
|
|
487
|
-
function mixTileflowColours(from, to, t) {
|
|
488
|
-
const a = oklab(from);
|
|
489
|
-
const b = oklab(to);
|
|
490
|
-
if (!a || !b) return void 0;
|
|
491
|
-
return colourFromOklab(a.map((value, channel) => value + (b[channel] - value) * t));
|
|
492
|
-
}
|
|
493
|
-
function oklab(colour) {
|
|
494
|
-
const cached = oklabCache.get(colour);
|
|
495
|
-
if (cached !== void 0) return cached;
|
|
496
|
-
const rgba = parseColour(colour);
|
|
497
|
-
let result = null;
|
|
498
|
-
if (rgba) {
|
|
499
|
-
const [r, g, b] = rgba.slice(0, 3).map((channel) => {
|
|
500
|
-
const value = channel / 255;
|
|
501
|
-
return value <= 0.04045 ? value / 12.92 : ((value + 0.055) / 1.055) ** 2.4;
|
|
502
|
-
});
|
|
503
|
-
const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);
|
|
504
|
-
const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);
|
|
505
|
-
const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);
|
|
506
|
-
result = [
|
|
507
|
-
0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,
|
|
508
|
-
1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,
|
|
509
|
-
0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,
|
|
510
|
-
rgba[3]
|
|
511
|
-
];
|
|
512
|
-
}
|
|
513
|
-
if (oklabCache.size > 4096) oklabCache.clear();
|
|
514
|
-
oklabCache.set(colour, result);
|
|
515
|
-
return result;
|
|
516
|
-
}
|
|
517
|
-
function colourFromOklab([lightness, a, b, alpha2]) {
|
|
518
|
-
const l = (lightness + 0.3963377774 * a + 0.2158037573 * b) ** 3;
|
|
519
|
-
const m = (lightness - 0.1055613458 * a - 0.0638541728 * b) ** 3;
|
|
520
|
-
const s = (lightness - 0.0894841775 * a - 1.291485548 * b) ** 3;
|
|
521
|
-
const [red, green, blue] = [
|
|
522
|
-
4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
|
|
523
|
-
-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
|
|
524
|
-
-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s
|
|
525
|
-
].map((value) => {
|
|
526
|
-
const clamped = Math.min(1, Math.max(0, value));
|
|
527
|
-
const encoded = clamped <= 31308e-7 ? clamped * 12.92 : 1.055 * clamped ** (1 / 2.4) - 0.055;
|
|
528
|
-
return Math.round(encoded * 255);
|
|
529
|
-
});
|
|
530
|
-
return `rgba(${red}, ${green}, ${blue}, ${Number(alpha2.toFixed(3))})`;
|
|
531
|
-
}
|
|
532
|
-
function tileflowColourChannels(colour) {
|
|
533
|
-
const rgba = parseColour(colour);
|
|
534
|
-
if (!rgba) return null;
|
|
535
|
-
return [
|
|
536
|
-
Math.min(1, Math.max(0, rgba[0] / 255)),
|
|
537
|
-
Math.min(1, Math.max(0, rgba[1] / 255)),
|
|
538
|
-
Math.min(1, Math.max(0, rgba[2] / 255)),
|
|
539
|
-
Math.min(1, Math.max(0, rgba[3]))
|
|
540
|
-
];
|
|
541
|
-
}
|
|
542
|
-
function parseColour(colour) {
|
|
543
|
-
const text = colour.trim().toLowerCase();
|
|
544
|
-
const hex = /^#([\da-f]{3,8})$/u.exec(text)?.[1];
|
|
545
|
-
if (hex && [3, 4, 6, 8].includes(hex.length)) {
|
|
546
|
-
const full = hex.length <= 4 ? [...hex].map((digit) => digit + digit).join("") : hex;
|
|
547
|
-
const channels = full.match(/../gu).map((pair) => Number.parseInt(pair, 16));
|
|
548
|
-
return [channels[0], channels[1], channels[2], channels.length > 3 ? channels[3] / 255 : 1];
|
|
549
|
-
}
|
|
550
|
-
const functional = /^(rgba?|hsla?)\(([^)]+)\)$/u.exec(text);
|
|
551
|
-
if (!functional) return null;
|
|
552
|
-
const parts = functional[2].split(/[\s,/]+/u).filter(Boolean);
|
|
553
|
-
if (parts.length < 3 || parts.length > 4) return null;
|
|
554
|
-
const alpha2 = parts[3] === void 0 ? 1 : parseUnit(parts[3], 1);
|
|
555
|
-
if (functional[1].startsWith("rgb")) {
|
|
556
|
-
const [r, g, b] = parts.slice(0, 3).map((part) => parseUnit(part, 255));
|
|
557
|
-
if ([r, g, b, alpha2].some((value) => value === null)) return null;
|
|
558
|
-
return [r, g, b, alpha2];
|
|
559
|
-
}
|
|
560
|
-
const hue = Number.parseFloat(parts[0]);
|
|
561
|
-
const saturation = parseUnit(parts[1], 1);
|
|
562
|
-
const light = parseUnit(parts[2], 1);
|
|
563
|
-
if (!Number.isFinite(hue) || saturation === null || light === null || alpha2 === null) return null;
|
|
564
|
-
const chroma = (1 - Math.abs(2 * light - 1)) * saturation;
|
|
565
|
-
const sector = (hue % 360 + 360) % 360 / 60;
|
|
566
|
-
const x = chroma * (1 - Math.abs(sector % 2 - 1));
|
|
567
|
-
const [r1, g1, b1] = sector < 1 ? [chroma, x, 0] : sector < 2 ? [x, chroma, 0] : sector < 3 ? [0, chroma, x] : sector < 4 ? [0, x, chroma] : sector < 5 ? [x, 0, chroma] : [chroma, 0, x];
|
|
568
|
-
const offset = light - chroma / 2;
|
|
569
|
-
return [(r1 + offset) * 255, (g1 + offset) * 255, (b1 + offset) * 255, alpha2];
|
|
570
|
-
}
|
|
571
|
-
function parseUnit(part, scale) {
|
|
572
|
-
const percentage = part.endsWith("%");
|
|
573
|
-
const value = Number.parseFloat(part);
|
|
574
|
-
if (!Number.isFinite(value)) return null;
|
|
575
|
-
return percentage ? value / 100 * scale : value;
|
|
576
|
-
}
|
|
577
|
-
var oklabCache;
|
|
578
|
-
var init_theme_blend = __esm({
|
|
579
|
-
"src/theme-blend.ts"() {
|
|
580
|
-
"use strict";
|
|
581
|
-
oklabCache = /* @__PURE__ */ new Map();
|
|
582
|
-
}
|
|
583
|
-
});
|
|
584
|
-
|
|
585
594
|
// src/sun.ts
|
|
586
595
|
function normalizeTileflowAzimuth(azimuth) {
|
|
587
596
|
const turned = azimuth % 360;
|
|
@@ -705,9 +714,9 @@ function tileflowSunMetadata(preset) {
|
|
|
705
714
|
return Object.freeze({ version: 1, ...preset });
|
|
706
715
|
}
|
|
707
716
|
function readTileflowSunPreset(metadata) {
|
|
708
|
-
if (!
|
|
717
|
+
if (!isRecord5(metadata)) return void 0;
|
|
709
718
|
const value = metadata[tileflowSunMetadataKey];
|
|
710
|
-
if (!
|
|
719
|
+
if (!isRecord5(value) || value.version !== 1 || !isRecord5(value.ambient)) return void 0;
|
|
711
720
|
const { azimuth, altitude, color: color3, intensity, shadowIntensity } = value;
|
|
712
721
|
const ambient = value.ambient;
|
|
713
722
|
if (!isFiniteNumber(azimuth) || !isFiniteNumber(altitude) || !isUnit(intensity) || !isUnit(shadowIntensity) || !isUnit(ambient.intensity) || !isColour(color3) || !isColour(ambient.color))
|
|
@@ -724,7 +733,7 @@ function readTileflowSunPreset(metadata) {
|
|
|
724
733
|
function tileflowStyleSunPreset(style) {
|
|
725
734
|
const published = readTileflowSunPreset(style?.metadata);
|
|
726
735
|
if (published) return published;
|
|
727
|
-
const light =
|
|
736
|
+
const light = isRecord5(style?.light) ? style.light : void 0;
|
|
728
737
|
const position = light?.position;
|
|
729
738
|
if (!position) return tileflowDefaultSunPreset;
|
|
730
739
|
return Object.freeze({
|
|
@@ -762,7 +771,7 @@ function smoothstep2(from, to, value) {
|
|
|
762
771
|
function clamp01(value) {
|
|
763
772
|
return Math.min(1, Math.max(0, Number.isFinite(value) ? value : 0));
|
|
764
773
|
}
|
|
765
|
-
function
|
|
774
|
+
function isRecord5(value) {
|
|
766
775
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
767
776
|
}
|
|
768
777
|
function isFiniteNumber(value) {
|
|
@@ -881,6 +890,7 @@ var init_visual_semantics = __esm({
|
|
|
881
890
|
"colorMix",
|
|
882
891
|
"metallic",
|
|
883
892
|
"roughness",
|
|
893
|
+
"horizonBlend",
|
|
884
894
|
"hue",
|
|
885
895
|
"saturation",
|
|
886
896
|
"lightness",
|
|
@@ -908,6 +918,7 @@ var init_visual_semantics = __esm({
|
|
|
908
918
|
"roundLimit",
|
|
909
919
|
"size",
|
|
910
920
|
"spacing",
|
|
921
|
+
"starIntensity",
|
|
911
922
|
"strokeOpacity",
|
|
912
923
|
"strokeWidth",
|
|
913
924
|
"textFitPadding",
|
|
@@ -1078,7 +1089,7 @@ function auditTileflowThemeValues(value, path = "value", context = inferAuditCon
|
|
|
1078
1089
|
return diagnostics.sort(compareAuditDiagnostics);
|
|
1079
1090
|
}
|
|
1080
1091
|
function auditTileflowMapThemeValues(map) {
|
|
1081
|
-
const modules =
|
|
1092
|
+
const modules = isRecord6(map.modules) ? map.modules : void 0;
|
|
1082
1093
|
const moduleDiagnostics = modules ? Object.keys(modules).sort(compareCodeUnits2).flatMap(
|
|
1083
1094
|
(owner) => auditTileflowThemeValues(modules[owner], `modules.${owner}`, {
|
|
1084
1095
|
owner,
|
|
@@ -1185,7 +1196,7 @@ function isThemePrimitiveForCategory(value, category) {
|
|
|
1185
1196
|
return category === "number" ? typeof value === "number" && Number.isFinite(value) || Array.isArray(value) && value.every((entry) => typeof entry === "number" && Number.isFinite(entry)) : typeof value === "string" && value.length > 0;
|
|
1186
1197
|
}
|
|
1187
1198
|
function isThemeValueCandidate(value) {
|
|
1188
|
-
return
|
|
1199
|
+
return isRecord6(value) && (value.kind === "theme-token" || value.kind === "theme-fixed" || value.kind === "theme-color");
|
|
1189
1200
|
}
|
|
1190
1201
|
function visitAuditableValue(value, path, category, state, intentRequired = false) {
|
|
1191
1202
|
if (isThemeStructuralPath(path)) category = void 0;
|
|
@@ -1201,7 +1212,7 @@ function visitAuditableValue(value, path, category, state, intentRequired = fals
|
|
|
1201
1212
|
visitAuditableArray(value, path, category, state, false, intentRequired);
|
|
1202
1213
|
return;
|
|
1203
1214
|
}
|
|
1204
|
-
if (!
|
|
1215
|
+
if (!isRecord6(value)) return;
|
|
1205
1216
|
if (value.kind === "expression" && Array.isArray(value.value)) {
|
|
1206
1217
|
visitAuditableArray(value.value, `${path}.value`, category, state, true, intentRequired);
|
|
1207
1218
|
return;
|
|
@@ -1590,7 +1601,7 @@ function assertThemeLighting(value, path, allowReset = false) {
|
|
|
1590
1601
|
}
|
|
1591
1602
|
}
|
|
1592
1603
|
function assertThemeCategoryValue(value, expectedCategory, path) {
|
|
1593
|
-
if (!
|
|
1604
|
+
if (!isRecord6(value)) {
|
|
1594
1605
|
assertTokenPrimitive(expectedCategory, value, path);
|
|
1595
1606
|
return;
|
|
1596
1607
|
}
|
|
@@ -1955,11 +1966,11 @@ function cloneJson14(value) {
|
|
|
1955
1966
|
if (serialized === void 0) throw new Error("Tileflow themes must be JSON-serializable.");
|
|
1956
1967
|
return JSON.parse(serialized);
|
|
1957
1968
|
}
|
|
1958
|
-
function
|
|
1969
|
+
function isRecord6(value) {
|
|
1959
1970
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
1960
1971
|
}
|
|
1961
1972
|
function isPlainRecord2(value) {
|
|
1962
|
-
if (!
|
|
1973
|
+
if (!isRecord6(value)) return false;
|
|
1963
1974
|
const prototype = Object.getPrototypeOf(value);
|
|
1964
1975
|
return prototype === Object.prototype || prototype === null;
|
|
1965
1976
|
}
|
|
@@ -2074,7 +2085,7 @@ var init_model = __esm({
|
|
|
2074
2085
|
if (Array.isArray(value)) {
|
|
2075
2086
|
return value.map((entry, index) => this.resolveTree(entry, `${path}[${index}]`, category));
|
|
2076
2087
|
}
|
|
2077
|
-
if (!
|
|
2088
|
+
if (!isRecord6(value)) return value;
|
|
2078
2089
|
if (value.kind === "expression" && Array.isArray(value.value)) {
|
|
2079
2090
|
return {
|
|
2080
2091
|
...value,
|
|
@@ -2333,13 +2344,14 @@ function createTileflowRuntimeViewSchema(operations2) {
|
|
|
2333
2344
|
center: operations2.optional(
|
|
2334
2345
|
operations2.tuplePair(operations2.number(-180, 180), operations2.number(-90, 90))
|
|
2335
2346
|
),
|
|
2336
|
-
pitch: operations2.optional(operations2.number(0,
|
|
2347
|
+
pitch: operations2.optional(operations2.number(0, tileflowMaxPitch)),
|
|
2337
2348
|
zoom: operations2.optional(operations2.number(0, 24))
|
|
2338
2349
|
});
|
|
2339
2350
|
}
|
|
2340
2351
|
var init_runtime_view_schema = __esm({
|
|
2341
2352
|
"src/runtime-view-schema.ts"() {
|
|
2342
2353
|
"use strict";
|
|
2354
|
+
init_camera_limits();
|
|
2343
2355
|
}
|
|
2344
2356
|
});
|
|
2345
2357
|
|
|
@@ -2909,8 +2921,68 @@ var init_meshopt_decoder = __esm({
|
|
|
2909
2921
|
}
|
|
2910
2922
|
});
|
|
2911
2923
|
|
|
2924
|
+
// src/sky.ts
|
|
2925
|
+
init_theme_blend();
|
|
2926
|
+
var tileflowSkyMetadataKey = "tileflow:sky";
|
|
2927
|
+
var hexColour = /^#[0-9a-f]{6}$/iu;
|
|
2928
|
+
var unit = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 1;
|
|
2929
|
+
function readColours(value) {
|
|
2930
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
2931
|
+
const record3 = value;
|
|
2932
|
+
if (Object.keys(record3).length !== 4) return void 0;
|
|
2933
|
+
const { color: color3, horizonColor, horizonBlend, glowColor } = record3;
|
|
2934
|
+
if (typeof color3 !== "string" || !hexColour.test(color3) || typeof horizonColor !== "string" || !hexColour.test(horizonColor) || typeof glowColor !== "string" || !hexColour.test(glowColor) || !unit(horizonBlend))
|
|
2935
|
+
return void 0;
|
|
2936
|
+
return { color: color3, horizonColor, horizonBlend, glowColor };
|
|
2937
|
+
}
|
|
2938
|
+
function readTileflowSky(value) {
|
|
2939
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
2940
|
+
const record3 = value;
|
|
2941
|
+
const keys = Object.keys(record3);
|
|
2942
|
+
if (record3.version !== 1 || keys.length !== (record3.timesOfDay === void 0 ? 3 : 4))
|
|
2943
|
+
return void 0;
|
|
2944
|
+
const { starIntensity, glowColor, timesOfDay } = record3;
|
|
2945
|
+
if (!unit(starIntensity) || typeof glowColor !== "string" || !hexColour.test(glowColor))
|
|
2946
|
+
return void 0;
|
|
2947
|
+
if (timesOfDay === void 0) return { version: 1, starIntensity, glowColor };
|
|
2948
|
+
if (!timesOfDay || typeof timesOfDay !== "object" || Array.isArray(timesOfDay)) return void 0;
|
|
2949
|
+
const times = timesOfDay;
|
|
2950
|
+
if (Object.keys(times).length !== 4) return void 0;
|
|
2951
|
+
const day = readColours(times.day);
|
|
2952
|
+
const dawn = readColours(times.dawn);
|
|
2953
|
+
const dusk = readColours(times.dusk);
|
|
2954
|
+
const night = readColours(times.night);
|
|
2955
|
+
if (!day || !dawn || !dusk || !night) return void 0;
|
|
2956
|
+
return { version: 1, starIntensity, glowColor, timesOfDay: { day, dawn, dusk, night } };
|
|
2957
|
+
}
|
|
2958
|
+
var smooth = (from, to, value) => {
|
|
2959
|
+
const t = Math.min(1, Math.max(0, (value - from) / (to - from)));
|
|
2960
|
+
return t * t * (3 - 2 * t);
|
|
2961
|
+
};
|
|
2962
|
+
function mixColours(from, to, t) {
|
|
2963
|
+
if (t <= 0) return from;
|
|
2964
|
+
if (t >= 1) return to;
|
|
2965
|
+
return {
|
|
2966
|
+
color: mixTileflowColours(from.color, to.color, t) ?? to.color,
|
|
2967
|
+
horizonColor: mixTileflowColours(from.horizonColor, to.horizonColor, t) ?? to.horizonColor,
|
|
2968
|
+
horizonBlend: from.horizonBlend + (to.horizonBlend - from.horizonBlend) * t,
|
|
2969
|
+
glowColor: mixTileflowColours(from.glowColor, to.glowColor, t) ?? to.glowColor
|
|
2970
|
+
};
|
|
2971
|
+
}
|
|
2972
|
+
function tileflowSkyAtSun(times, sun) {
|
|
2973
|
+
const azimuth = (sun.azimuth % 360 + 360) % 360;
|
|
2974
|
+
const twilight = azimuth < 180 ? times.dawn : times.dusk;
|
|
2975
|
+
if (sun.altitude >= 2) return mixColours(twilight, times.day, smooth(2, 14, sun.altitude));
|
|
2976
|
+
if (sun.altitude >= -2) return twilight;
|
|
2977
|
+
return mixColours(times.night, twilight, smooth(-10, -2, sun.altitude));
|
|
2978
|
+
}
|
|
2979
|
+
|
|
2980
|
+
// src/index.ts
|
|
2981
|
+
init_camera_limits();
|
|
2982
|
+
|
|
2912
2983
|
// src/capture-scene.ts
|
|
2913
2984
|
init_portable_identity();
|
|
2985
|
+
init_camera_limits();
|
|
2914
2986
|
import { z as z3 } from "zod";
|
|
2915
2987
|
var tileflowCaptureSceneSchemaVersion = 1;
|
|
2916
2988
|
var tileflowCaptureSceneLimits = Object.freeze({
|
|
@@ -2918,7 +2990,7 @@ var tileflowCaptureSceneLimits = Object.freeze({
|
|
|
2918
2990
|
boundsPadding: { maximum: 1024, minimum: 0 },
|
|
2919
2991
|
captureIdLength: tileflowPortableIdMaximumLength,
|
|
2920
2992
|
maximumPhysicalPixels: 16777216,
|
|
2921
|
-
pitch: { maximum:
|
|
2993
|
+
pitch: { maximum: tileflowMaxPitch, minimum: 0 },
|
|
2922
2994
|
selectorLength: 256,
|
|
2923
2995
|
viewport: { maximum: 4096, minimum: 64 },
|
|
2924
2996
|
zoom: { maximum: 24, minimum: 0 }
|
|
@@ -3402,14 +3474,7 @@ var defaults = {
|
|
|
3402
3474
|
function resolveTileflowAtmosphere(value) {
|
|
3403
3475
|
if (!value) return void 0;
|
|
3404
3476
|
const options = { ...defaults, ...value === true ? {} : value };
|
|
3405
|
-
const normalize2 = (input) =>
|
|
3406
|
-
const color3 = typeof input === "string" ? Color.parse(input) : void 0;
|
|
3407
|
-
if (!color3 || color3.a !== 1)
|
|
3408
|
-
throw new Error("Atmosphere colors must resolve to opaque colors.");
|
|
3409
|
-
return `#${[color3.r, color3.g, color3.b].map(
|
|
3410
|
-
(channel) => Math.round(channel * 255).toString(16).padStart(2, "0")
|
|
3411
|
-
).join("")}`;
|
|
3412
|
-
};
|
|
3477
|
+
const normalize2 = (input) => opaqueHex(input, "Atmosphere colors");
|
|
3413
3478
|
return {
|
|
3414
3479
|
...options,
|
|
3415
3480
|
skyColor: normalize2(options.skyColor),
|
|
@@ -3418,6 +3483,13 @@ function resolveTileflowAtmosphere(value) {
|
|
|
3418
3483
|
spaceColor: normalize2(options.spaceColor)
|
|
3419
3484
|
};
|
|
3420
3485
|
}
|
|
3486
|
+
function opaqueHex(input, subject) {
|
|
3487
|
+
const color3 = typeof input === "string" ? Color.parse(input) : void 0;
|
|
3488
|
+
if (!color3 || color3.a !== 1) throw new Error(`${subject} must resolve to opaque colors.`);
|
|
3489
|
+
return `#${[color3.r, color3.g, color3.b].map(
|
|
3490
|
+
(channel) => Math.round(channel * 255).toString(16).padStart(2, "0")
|
|
3491
|
+
).join("")}`;
|
|
3492
|
+
}
|
|
3421
3493
|
function compileTileflowSky(options) {
|
|
3422
3494
|
return {
|
|
3423
3495
|
"sky-color": options.skyColor,
|
|
@@ -3429,6 +3501,41 @@ function compileTileflowSky(options) {
|
|
|
3429
3501
|
"atmosphere-blend": ["interpolate", ["linear"], ["zoom"], 0, 0.55, 3, 0.45, 5, 0.2, 7, 0]
|
|
3430
3502
|
};
|
|
3431
3503
|
}
|
|
3504
|
+
var skyDefaults = {
|
|
3505
|
+
color: "#5c9ce6",
|
|
3506
|
+
horizonColor: "#dcebf7",
|
|
3507
|
+
horizonBlend: 0.6,
|
|
3508
|
+
glowColor: "#ffc68a",
|
|
3509
|
+
starIntensity: 0.6
|
|
3510
|
+
};
|
|
3511
|
+
function resolveTileflowSky(value) {
|
|
3512
|
+
if (!value) return void 0;
|
|
3513
|
+
const options = { ...skyDefaults, ...value === true ? {} : value };
|
|
3514
|
+
const unit2 = (input, name) => {
|
|
3515
|
+
if (typeof input !== "number" || !Number.isFinite(input) || input < 0 || input > 1)
|
|
3516
|
+
throw new Error(`Sky ${name} must resolve to a number from 0 to 1.`);
|
|
3517
|
+
return input;
|
|
3518
|
+
};
|
|
3519
|
+
return {
|
|
3520
|
+
color: opaqueHex(options.color, "Sky colors"),
|
|
3521
|
+
horizonColor: opaqueHex(options.horizonColor, "Sky colors"),
|
|
3522
|
+
horizonBlend: unit2(options.horizonBlend, "horizonBlend"),
|
|
3523
|
+
glowColor: opaqueHex(options.glowColor, "Sky colors"),
|
|
3524
|
+
starIntensity: unit2(options.starIntensity, "starIntensity")
|
|
3525
|
+
};
|
|
3526
|
+
}
|
|
3527
|
+
function compileTileflowStreetSky(options) {
|
|
3528
|
+
return {
|
|
3529
|
+
"sky-color": options.color,
|
|
3530
|
+
"horizon-color": options.horizonColor,
|
|
3531
|
+
// MapLibre fogs only 3D terrain; the haze matches the horizon so terrain meets the sky.
|
|
3532
|
+
"fog-color": options.horizonColor,
|
|
3533
|
+
"sky-horizon-blend": options.horizonBlend,
|
|
3534
|
+
"horizon-fog-blend": 0.6,
|
|
3535
|
+
"fog-ground-blend": 0.75,
|
|
3536
|
+
"atmosphere-blend": ["interpolate", ["linear"], ["zoom"], 0, 0.55, 3, 0.45, 5, 0.2, 7, 0]
|
|
3537
|
+
};
|
|
3538
|
+
}
|
|
3432
3539
|
|
|
3433
3540
|
// src/models-3d-model.ts
|
|
3434
3541
|
var tileflowModelParts = Object.freeze({
|
|
@@ -7313,12 +7420,46 @@ var tileflowNauticalImageRoles = Object.freeze({
|
|
|
7313
7420
|
port: "nautical.buoy.port",
|
|
7314
7421
|
starboard: "nautical.buoy.starboard"
|
|
7315
7422
|
}),
|
|
7316
|
-
|
|
7423
|
+
distanceMarks: Object.freeze({ default: "nautical.distance-mark" }),
|
|
7424
|
+
/**
|
|
7425
|
+
* A facility that lists several categories shows the first of `tileflowNauticalFacilityIcons`
|
|
7426
|
+
* it lists; facilities without a variant token fall back to `nautical.facility`.
|
|
7427
|
+
*/
|
|
7428
|
+
facilities: Object.freeze({
|
|
7429
|
+
"boat-hoist": "nautical.facility.boat-hoist",
|
|
7430
|
+
boatyard: "nautical.facility.boatyard",
|
|
7431
|
+
default: "nautical.facility",
|
|
7432
|
+
"fuel-station": "nautical.facility.fuel-station",
|
|
7433
|
+
"pump-out": "nautical.facility.pump-out",
|
|
7434
|
+
slipway: "nautical.facility.slipway",
|
|
7435
|
+
"visitor-berth": "nautical.facility.visitor-berth",
|
|
7436
|
+
"water-tap": "nautical.facility.water-tap"
|
|
7437
|
+
}),
|
|
7438
|
+
/** Harbours whose `subclass` lists a marina use `nautical.marina` when the theme declares it. */
|
|
7439
|
+
harbours: Object.freeze({ default: "nautical.harbour", marina: "nautical.marina" }),
|
|
7317
7440
|
lighthouses: Object.freeze({ default: "nautical.lighthouse" }),
|
|
7318
7441
|
lights: Object.freeze({ default: "nautical.light" }),
|
|
7442
|
+
/** Notice boards by function; a board without a variant token uses `nautical.notice`. */
|
|
7443
|
+
notices: Object.freeze({
|
|
7444
|
+
default: "nautical.notice",
|
|
7445
|
+
information: "nautical.notice.information",
|
|
7446
|
+
prohibition: "nautical.notice.prohibition",
|
|
7447
|
+
recommendation: "nautical.notice.recommendation",
|
|
7448
|
+
regulation: "nautical.notice.regulation",
|
|
7449
|
+
restriction: "nautical.notice.restriction"
|
|
7450
|
+
}),
|
|
7319
7451
|
ports: Object.freeze({ default: "nautical.port" }),
|
|
7320
7452
|
wrecks: Object.freeze({ default: "nautical.wreck" })
|
|
7321
7453
|
});
|
|
7454
|
+
var tileflowNauticalFacilityIcons = Object.freeze([
|
|
7455
|
+
"fuel-station",
|
|
7456
|
+
"slipway",
|
|
7457
|
+
"boat-hoist",
|
|
7458
|
+
"pump-out",
|
|
7459
|
+
"water-tap",
|
|
7460
|
+
"visitor-berth",
|
|
7461
|
+
"boatyard"
|
|
7462
|
+
]);
|
|
7322
7463
|
var tileflowNauticalNotice = Object.freeze({
|
|
7323
7464
|
id: "nautical-not-for-navigation",
|
|
7324
7465
|
text: "Not for navigation"
|
|
@@ -7380,10 +7521,15 @@ var tileflowNauticalV1Schema = Object.freeze({
|
|
|
7380
7521
|
country: "country",
|
|
7381
7522
|
coverage: "coverage",
|
|
7382
7523
|
depth: "depth",
|
|
7524
|
+
distance: "distance",
|
|
7525
|
+
distanceUnit: "distance_unit",
|
|
7383
7526
|
edition: "edition",
|
|
7384
7527
|
families: "families",
|
|
7385
7528
|
group: "group",
|
|
7386
7529
|
heightM: "height_m",
|
|
7530
|
+
horizontalClearance: "horizontal_clearance",
|
|
7531
|
+
impact: "impact",
|
|
7532
|
+
information: "information",
|
|
7387
7533
|
label: "label",
|
|
7388
7534
|
licence: "licence",
|
|
7389
7535
|
lit: "lit",
|
|
@@ -7401,6 +7547,7 @@ var tileflowNauticalV1Schema = Object.freeze({
|
|
|
7401
7547
|
scale: "scale",
|
|
7402
7548
|
sectorEnd: "sector_end",
|
|
7403
7549
|
sectorStart: "sector_start",
|
|
7550
|
+
sequence: "sequence",
|
|
7404
7551
|
shape: "shape",
|
|
7405
7552
|
size: "size",
|
|
7406
7553
|
subclass: "subclass",
|
|
@@ -7408,6 +7555,10 @@ var tileflowNauticalV1Schema = Object.freeze({
|
|
|
7408
7555
|
topmark: "topmark",
|
|
7409
7556
|
unlocode: "unlocode",
|
|
7410
7557
|
update: "update",
|
|
7558
|
+
verticalClearance: "vertical_clearance",
|
|
7559
|
+
verticalClearanceClosed: "vertical_clearance_closed",
|
|
7560
|
+
verticalClearanceOpen: "vertical_clearance_open",
|
|
7561
|
+
verticalClearanceSafe: "vertical_clearance_safe",
|
|
7411
7562
|
waterLevel: "water_level"
|
|
7412
7563
|
}),
|
|
7413
7564
|
geometryTypes: Object.freeze({
|
|
@@ -7431,6 +7582,16 @@ var tileflowNauticalV1Schema = Object.freeze({
|
|
|
7431
7582
|
wrecks: "wreck"
|
|
7432
7583
|
}),
|
|
7433
7584
|
product: "nautical-v1",
|
|
7585
|
+
/**
|
|
7586
|
+
* Known `provider` values and the `class` of their `coverage` cells. The source's TileJSON owns
|
|
7587
|
+
* each provider's credit; the module never adds attribution.
|
|
7588
|
+
*/
|
|
7589
|
+
providers: Object.freeze({
|
|
7590
|
+
"nga-list-of-lights": "list",
|
|
7591
|
+
"noaa-office-of-coast-survey": "chart",
|
|
7592
|
+
openstreetmap: "community",
|
|
7593
|
+
"usace-ienc": "chart"
|
|
7594
|
+
}),
|
|
7434
7595
|
schemaVersion: 1
|
|
7435
7596
|
});
|
|
7436
7597
|
var tileflowBathymetryNameLayerLimits = Object.freeze({ maxZoomRanges: 128 });
|
|
@@ -7518,8 +7679,11 @@ function resolveBathymetryRelief(style, apiBaseUrl) {
|
|
|
7518
7679
|
style: cloneJson12(style)
|
|
7519
7680
|
};
|
|
7520
7681
|
}
|
|
7682
|
+
var tileflowNauticalPromoteId = Object.freeze({
|
|
7683
|
+
[tileflowNauticalV1Schema.layers.lights]: tileflowNauticalV1Schema.fields.provenance
|
|
7684
|
+
});
|
|
7521
7685
|
function resolveNauticalSource(config, apiBaseUrl) {
|
|
7522
|
-
|
|
7686
|
+
const resolved = resolveMarineSource({
|
|
7523
7687
|
config,
|
|
7524
7688
|
defaultPath: "/tiles/nautical/tiles.json",
|
|
7525
7689
|
defaultSourceId: tileflowNauticalSourceId,
|
|
@@ -7527,6 +7691,7 @@ function resolveNauticalSource(config, apiBaseUrl) {
|
|
|
7527
7691
|
product: tileflowNauticalV1Schema.product,
|
|
7528
7692
|
apiBaseUrl
|
|
7529
7693
|
});
|
|
7694
|
+
return { ...resolved, source: { ...resolved.source, promoteId: { ...tileflowNauticalPromoteId } } };
|
|
7530
7695
|
}
|
|
7531
7696
|
function resolveMarineSource(options) {
|
|
7532
7697
|
const sourceId = validateSourceId(options.config.sourceId ?? options.defaultSourceId);
|
|
@@ -7588,6 +7753,85 @@ function cloneJson12(value) {
|
|
|
7588
7753
|
return JSON.parse(JSON.stringify(value));
|
|
7589
7754
|
}
|
|
7590
7755
|
|
|
7756
|
+
// src/nautical-lights.ts
|
|
7757
|
+
var tileflowNauticalLightsMetadataKey = "tileflow:nautical-lights";
|
|
7758
|
+
var tileflowNauticalLightStates = Object.freeze({
|
|
7759
|
+
/** Index of the colour shown, into the light's comma-separated `color` list. */
|
|
7760
|
+
colour: "tileflowLightColour",
|
|
7761
|
+
/** `1` while the light shines, `0` while it is eclipsed, in between for a fixed part. */
|
|
7762
|
+
intensity: "tileflowLightIntensity"
|
|
7763
|
+
});
|
|
7764
|
+
var tileflowNauticalLightEclipseOpacity = 0.15;
|
|
7765
|
+
var tileflowNauticalLightsLimits = Object.freeze({ maxLayers: 16 });
|
|
7766
|
+
var identifierPattern = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/u;
|
|
7767
|
+
var layerIdPattern = /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,127}$/u;
|
|
7768
|
+
function readTileflowNauticalLights(metadata) {
|
|
7769
|
+
if (!isRecord4(metadata)) return void 0;
|
|
7770
|
+
const value = metadata[tileflowNauticalLightsMetadataKey];
|
|
7771
|
+
if (!isRecord4(value) || value.version !== 1) return void 0;
|
|
7772
|
+
const { layers: layers2, source, sourceLayer } = value;
|
|
7773
|
+
if (typeof source !== "string" || !identifierPattern.test(source)) return void 0;
|
|
7774
|
+
if (typeof sourceLayer !== "string" || !identifierPattern.test(sourceLayer)) return void 0;
|
|
7775
|
+
if (!Array.isArray(layers2) || layers2.length === 0 || layers2.length > tileflowNauticalLightsLimits.maxLayers || !layers2.every((layer) => typeof layer === "string" && layerIdPattern.test(layer)) || new Set(layers2).size !== layers2.length) {
|
|
7776
|
+
return void 0;
|
|
7777
|
+
}
|
|
7778
|
+
return Object.freeze({
|
|
7779
|
+
layers: Object.freeze([...layers2]),
|
|
7780
|
+
source,
|
|
7781
|
+
sourceLayer,
|
|
7782
|
+
version: 1
|
|
7783
|
+
});
|
|
7784
|
+
}
|
|
7785
|
+
function declareTileflowNauticalLights(layers2, sourceId, sourceLayer) {
|
|
7786
|
+
if (!sourceId) return void 0;
|
|
7787
|
+
const ids = layers2.filter(
|
|
7788
|
+
(layer) => layer.source === sourceId && layer["source-layer"] === sourceLayer && readsLightState(layer.paint)
|
|
7789
|
+
).map(({ id: id2 }) => id2).filter((id2) => typeof id2 === "string").slice(0, tileflowNauticalLightsLimits.maxLayers);
|
|
7790
|
+
if (ids.length === 0) return void 0;
|
|
7791
|
+
return { layers: ids, source: sourceId, sourceLayer, version: 1 };
|
|
7792
|
+
}
|
|
7793
|
+
function steadyTileflowNauticalLights(style) {
|
|
7794
|
+
const declaration = isRecord4(style.metadata) ? readTileflowNauticalLights(style.metadata) : void 0;
|
|
7795
|
+
const hasKey = isRecord4(style.metadata) && tileflowNauticalLightsMetadataKey in style.metadata;
|
|
7796
|
+
if (!declaration && !hasKey) return style;
|
|
7797
|
+
const metadata = { ...style.metadata };
|
|
7798
|
+
delete metadata[tileflowNauticalLightsMetadataKey];
|
|
7799
|
+
const layers2 = Array.isArray(style.layers) ? style.layers.map(
|
|
7800
|
+
(layer) => isRecord4(layer) && isRecord4(layer.paint) && readsLightState(layer.paint) ? { ...layer, paint: steady(layer.paint) } : layer
|
|
7801
|
+
) : style.layers;
|
|
7802
|
+
return { ...style, layers: layers2, metadata };
|
|
7803
|
+
}
|
|
7804
|
+
function tileflowNauticalLightStateRead(state, steadyValue) {
|
|
7805
|
+
return ["number", ["feature-state", tileflowNauticalLightStates[state]], steadyValue];
|
|
7806
|
+
}
|
|
7807
|
+
var stateKeys = new Set(Object.values(tileflowNauticalLightStates));
|
|
7808
|
+
function readsLightState(value) {
|
|
7809
|
+
if (!Array.isArray(value)) {
|
|
7810
|
+
return isRecord4(value) ? Object.values(value).some(readsLightState) : false;
|
|
7811
|
+
}
|
|
7812
|
+
if (value[0] === "literal") return false;
|
|
7813
|
+
if (value[0] === "feature-state" && typeof value[1] === "string" && stateKeys.has(value[1])) {
|
|
7814
|
+
return true;
|
|
7815
|
+
}
|
|
7816
|
+
return value.some(readsLightState);
|
|
7817
|
+
}
|
|
7818
|
+
function steady(value) {
|
|
7819
|
+
if (Array.isArray(value)) {
|
|
7820
|
+
if (value[0] === "literal") return value;
|
|
7821
|
+
if (value[0] === "number" && value.length === 3 && Array.isArray(value[1]) && value[1][0] === "feature-state" && typeof value[1][1] === "string" && stateKeys.has(value[1][1])) {
|
|
7822
|
+
return value[2];
|
|
7823
|
+
}
|
|
7824
|
+
return value.map(steady);
|
|
7825
|
+
}
|
|
7826
|
+
if (isRecord4(value)) {
|
|
7827
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, steady(entry)]));
|
|
7828
|
+
}
|
|
7829
|
+
return value;
|
|
7830
|
+
}
|
|
7831
|
+
function isRecord4(value) {
|
|
7832
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
7833
|
+
}
|
|
7834
|
+
|
|
7591
7835
|
// src/modules/nautical/compiler.ts
|
|
7592
7836
|
var { fields, layers } = tileflowNauticalV1Schema;
|
|
7593
7837
|
var markColours = Object.freeze({
|
|
@@ -7630,6 +7874,24 @@ var operationalAreaClasses = [
|
|
|
7630
7874
|
var routeClasses = ["route", "traffic-separation"];
|
|
7631
7875
|
var cableClasses = ["cable", "cable-area", "pipeline", "pipeline-area"];
|
|
7632
7876
|
var portSizes = ["large", "medium", "small", "very-small"];
|
|
7877
|
+
var ownAreaClasses = ["berth", "bridge", "facility", "harbour"];
|
|
7878
|
+
var ownAidClasses = ["distance-mark", "notice"];
|
|
7879
|
+
var marinaSubclasses = ["marina", "marina-no-facilities"];
|
|
7880
|
+
var noticeFunctionColours = Object.freeze({
|
|
7881
|
+
information: markColours.blue,
|
|
7882
|
+
prohibition: markColours.red,
|
|
7883
|
+
recommendation: markColours.green,
|
|
7884
|
+
regulation: markColours.red,
|
|
7885
|
+
restriction: markColours.red
|
|
7886
|
+
});
|
|
7887
|
+
var distanceUnits = Object.freeze({
|
|
7888
|
+
hectometres: "hm",
|
|
7889
|
+
kilometres: "km",
|
|
7890
|
+
metres: "m",
|
|
7891
|
+
"nautical-miles": "NM",
|
|
7892
|
+
"statute-miles": "mi"
|
|
7893
|
+
});
|
|
7894
|
+
var maxAlternatingColours = 3;
|
|
7633
7895
|
function compileNautical(request, context) {
|
|
7634
7896
|
const nauticalSource = context.marine?.nautical;
|
|
7635
7897
|
if (!nauticalSource || request?.enabled === false) return [];
|
|
@@ -7660,10 +7922,30 @@ function compileNautical(request, context) {
|
|
|
7660
7922
|
const belowLabel = { anchor: "top", offset: [0, 0.75], optional: true };
|
|
7661
7923
|
const markColour = expression(colourMatch(firstColour(fields.color), markColours, ink));
|
|
7662
7924
|
const markStroke = expression(colourMatch(secondColour(fields.color), markColours, ink));
|
|
7925
|
+
const animateLights = request?.animateLights !== false;
|
|
7663
7926
|
const flareColour = expression(
|
|
7664
|
-
colourMatch(
|
|
7927
|
+
colourMatch(
|
|
7928
|
+
animateLights ? nthColour(fields.color, tileflowNauticalLightStateRead("colour", 0)) : firstColour(fields.color),
|
|
7929
|
+
lightColours,
|
|
7930
|
+
lightColours.white
|
|
7931
|
+
)
|
|
7665
7932
|
);
|
|
7666
7933
|
const iconPaint = { color: markColour, haloColor: ink, haloWidth: 1 };
|
|
7934
|
+
const noticeColours = [
|
|
7935
|
+
"match",
|
|
7936
|
+
["get", fields.subclass],
|
|
7937
|
+
...Object.entries(noticeFunctionColours).flat(),
|
|
7938
|
+
ink
|
|
7939
|
+
];
|
|
7940
|
+
const noticeColour = expression(noticeColours);
|
|
7941
|
+
const distanceOpacity = (installed, notInstalled) => expression([
|
|
7942
|
+
"match",
|
|
7943
|
+
["get", fields.category],
|
|
7944
|
+
"not-installed",
|
|
7945
|
+
notInstalled,
|
|
7946
|
+
installed
|
|
7947
|
+
]);
|
|
7948
|
+
const isGuestBerth = listIncludes(fields.subclass, "guest");
|
|
7667
7949
|
const defaults4 = {
|
|
7668
7950
|
type: "nautical",
|
|
7669
7951
|
enabled: true,
|
|
@@ -7754,6 +8036,60 @@ function compileNautical(request, context) {
|
|
|
7754
8036
|
[14, 1.3]
|
|
7755
8037
|
])
|
|
7756
8038
|
},
|
|
8039
|
+
harbourAreas: {
|
|
8040
|
+
fill: { color: ink, minZoom: 10, opacity: 0.05 },
|
|
8041
|
+
outline: {
|
|
8042
|
+
color: ink,
|
|
8043
|
+
minZoom: 10,
|
|
8044
|
+
opacity: zoom.linear([
|
|
8045
|
+
[10, 0.35],
|
|
8046
|
+
[14, 0.6]
|
|
8047
|
+
]),
|
|
8048
|
+
width: zoom.linear([
|
|
8049
|
+
[10, 0.5],
|
|
8050
|
+
[16, 1]
|
|
8051
|
+
])
|
|
8052
|
+
}
|
|
8053
|
+
},
|
|
8054
|
+
berths: {
|
|
8055
|
+
fill: { color: ink, minZoom: 13, opacity: 0.06 },
|
|
8056
|
+
outline: {
|
|
8057
|
+
color: ink,
|
|
8058
|
+
minZoom: 13,
|
|
8059
|
+
opacity: expression(["case", isGuestBerth, 0.95, 0.5]),
|
|
8060
|
+
width: expression([
|
|
8061
|
+
"interpolate",
|
|
8062
|
+
["linear"],
|
|
8063
|
+
["zoom"],
|
|
8064
|
+
13,
|
|
8065
|
+
["case", isGuestBerth, 1.2, 0.6],
|
|
8066
|
+
16,
|
|
8067
|
+
["case", isGuestBerth, 2.4, 1.2]
|
|
8068
|
+
])
|
|
8069
|
+
}
|
|
8070
|
+
},
|
|
8071
|
+
bridges: {
|
|
8072
|
+
fill: { color: colors.land, minZoom: 12, opacity: 0.9 },
|
|
8073
|
+
outline: {
|
|
8074
|
+
color: ink,
|
|
8075
|
+
minZoom: 12,
|
|
8076
|
+
opacity: 0.85,
|
|
8077
|
+
width: zoom.linear([
|
|
8078
|
+
[12, 0.8],
|
|
8079
|
+
[16, 1.8]
|
|
8080
|
+
])
|
|
8081
|
+
}
|
|
8082
|
+
},
|
|
8083
|
+
overheadCables: {
|
|
8084
|
+
color: accent,
|
|
8085
|
+
dash: [6, 2, 1, 2],
|
|
8086
|
+
minZoom: 10,
|
|
8087
|
+
opacity: 0.75,
|
|
8088
|
+
width: zoom.linear([
|
|
8089
|
+
[10, 0.7],
|
|
8090
|
+
[16, 1.3]
|
|
8091
|
+
])
|
|
8092
|
+
},
|
|
7757
8093
|
hazardAreas: {
|
|
7758
8094
|
fill: { color: accent, minZoom: 10, opacity: 0.08 },
|
|
7759
8095
|
outline: { color: accent, dash: [1, 1], minZoom: 10, opacity: 0.7, width: 0.8 }
|
|
@@ -7863,6 +8199,7 @@ function compileNautical(request, context) {
|
|
|
7863
8199
|
harbours: {
|
|
7864
8200
|
minZoom: 11,
|
|
7865
8201
|
placement: "point",
|
|
8202
|
+
...rankPriority,
|
|
7866
8203
|
...images.harbours ? {
|
|
7867
8204
|
icon: {
|
|
7868
8205
|
color: ink,
|
|
@@ -7893,18 +8230,159 @@ function compileNautical(request, context) {
|
|
|
7893
8230
|
...rankPriority,
|
|
7894
8231
|
...images.aids ? {
|
|
7895
8232
|
icon: {
|
|
7896
|
-
...iconPaint,
|
|
7897
|
-
image: images.aids,
|
|
8233
|
+
...iconPaint,
|
|
8234
|
+
image: images.aids,
|
|
8235
|
+
size: zoom.linear([
|
|
8236
|
+
[11, 0.8],
|
|
8237
|
+
[16, 1.2]
|
|
8238
|
+
])
|
|
8239
|
+
}
|
|
8240
|
+
} : {
|
|
8241
|
+
marker: {
|
|
8242
|
+
color: halo,
|
|
8243
|
+
radius: zoom.linear([
|
|
8244
|
+
[11, 1.8],
|
|
8245
|
+
[16, 3]
|
|
8246
|
+
]),
|
|
8247
|
+
strokeColor: ink,
|
|
8248
|
+
strokeWidth: 1
|
|
8249
|
+
}
|
|
8250
|
+
},
|
|
8251
|
+
text: { ...markText, ...sideLabel, field: nameFrom(15), padding: 3, size: 9 }
|
|
8252
|
+
},
|
|
8253
|
+
notices: {
|
|
8254
|
+
minZoom: 12,
|
|
8255
|
+
placement: "point",
|
|
8256
|
+
...rankPriority,
|
|
8257
|
+
...images.notices ? {
|
|
8258
|
+
icon: {
|
|
8259
|
+
color: noticeColour,
|
|
8260
|
+
haloColor: halo,
|
|
8261
|
+
haloWidth: 1,
|
|
8262
|
+
image: images.notices,
|
|
8263
|
+
padding: 1,
|
|
8264
|
+
size: zoom.linear([
|
|
8265
|
+
[12, 0.8],
|
|
8266
|
+
[16, 1.2]
|
|
8267
|
+
])
|
|
8268
|
+
}
|
|
8269
|
+
} : {
|
|
8270
|
+
marker: {
|
|
8271
|
+
color: expression([
|
|
8272
|
+
"match",
|
|
8273
|
+
["get", fields.subclass],
|
|
8274
|
+
["prohibition", "recommendation", "information"],
|
|
8275
|
+
noticeColours,
|
|
8276
|
+
halo
|
|
8277
|
+
]),
|
|
8278
|
+
radius: zoom.linear([
|
|
8279
|
+
[12, 1.8],
|
|
8280
|
+
[16, 3.2]
|
|
8281
|
+
]),
|
|
8282
|
+
strokeColor: expression([
|
|
8283
|
+
"match",
|
|
8284
|
+
["get", fields.subclass],
|
|
8285
|
+
["prohibition", "recommendation", "information"],
|
|
8286
|
+
halo,
|
|
8287
|
+
noticeColours
|
|
8288
|
+
]),
|
|
8289
|
+
strokeWidth: 1
|
|
8290
|
+
}
|
|
8291
|
+
},
|
|
8292
|
+
text: {
|
|
8293
|
+
...markText,
|
|
8294
|
+
...sideLabel,
|
|
8295
|
+
field: expression([
|
|
8296
|
+
"step",
|
|
8297
|
+
["zoom"],
|
|
8298
|
+
"",
|
|
8299
|
+
14,
|
|
8300
|
+
["to-string", ["coalesce", ["get", fields.information], ""]]
|
|
8301
|
+
]),
|
|
8302
|
+
padding: 2,
|
|
8303
|
+
size: 9
|
|
8304
|
+
}
|
|
8305
|
+
},
|
|
8306
|
+
distanceMarks: {
|
|
8307
|
+
minZoom: 11,
|
|
8308
|
+
placement: "point",
|
|
8309
|
+
...rankPriority,
|
|
8310
|
+
...images.distanceMarks ? {
|
|
8311
|
+
icon: {
|
|
8312
|
+
color: ink,
|
|
8313
|
+
haloColor: halo,
|
|
8314
|
+
haloWidth: 1,
|
|
8315
|
+
image: images.distanceMarks,
|
|
8316
|
+
opacity: distanceOpacity(1, 0.6),
|
|
8317
|
+
size: zoom.linear([
|
|
8318
|
+
[11, 0.7],
|
|
8319
|
+
[16, 1]
|
|
8320
|
+
])
|
|
8321
|
+
}
|
|
8322
|
+
} : {
|
|
8323
|
+
marker: {
|
|
8324
|
+
color: ink,
|
|
8325
|
+
opacity: distanceOpacity(1, 0.6),
|
|
8326
|
+
radius: zoom.linear([
|
|
8327
|
+
[11, 1.2],
|
|
8328
|
+
[16, 2.2]
|
|
8329
|
+
]),
|
|
8330
|
+
strokeColor: halo,
|
|
8331
|
+
strokeWidth: 0.8
|
|
8332
|
+
}
|
|
8333
|
+
},
|
|
8334
|
+
text: {
|
|
8335
|
+
...markText,
|
|
8336
|
+
...sideLabel,
|
|
8337
|
+
field: expression([
|
|
8338
|
+
"step",
|
|
8339
|
+
["zoom"],
|
|
8340
|
+
"",
|
|
8341
|
+
13,
|
|
8342
|
+
[
|
|
8343
|
+
"case",
|
|
8344
|
+
["has", fields.distance],
|
|
8345
|
+
[
|
|
8346
|
+
"concat",
|
|
8347
|
+
["to-string", ["get", fields.distance]],
|
|
8348
|
+
[
|
|
8349
|
+
"match",
|
|
8350
|
+
["get", fields.distanceUnit],
|
|
8351
|
+
...Object.entries(distanceUnits).flatMap(([unit2, label]) => [unit2, ` ${label}`]),
|
|
8352
|
+
""
|
|
8353
|
+
]
|
|
8354
|
+
],
|
|
8355
|
+
""
|
|
8356
|
+
]
|
|
8357
|
+
]),
|
|
8358
|
+
opacity: distanceOpacity(1, 0.75),
|
|
8359
|
+
padding: 2,
|
|
8360
|
+
size: zoom.linear([
|
|
8361
|
+
[13, 8.5],
|
|
8362
|
+
[16, 10]
|
|
8363
|
+
])
|
|
8364
|
+
}
|
|
8365
|
+
},
|
|
8366
|
+
facilities: {
|
|
8367
|
+
minZoom: 13,
|
|
8368
|
+
placement: "point",
|
|
8369
|
+
...images.facilities ? {
|
|
8370
|
+
icon: {
|
|
8371
|
+
color: ink,
|
|
8372
|
+
haloColor: halo,
|
|
8373
|
+
haloWidth: 1,
|
|
8374
|
+
image: images.facilities,
|
|
8375
|
+
padding: 1,
|
|
7898
8376
|
size: zoom.linear([
|
|
7899
|
-
[
|
|
7900
|
-
[16, 1.
|
|
8377
|
+
[13, 0.8],
|
|
8378
|
+
[16, 1.15]
|
|
7901
8379
|
])
|
|
7902
8380
|
}
|
|
7903
8381
|
} : {
|
|
7904
8382
|
marker: {
|
|
7905
8383
|
color: halo,
|
|
7906
8384
|
radius: zoom.linear([
|
|
7907
|
-
[
|
|
8385
|
+
[13, 1.8],
|
|
7908
8386
|
[16, 3]
|
|
7909
8387
|
]),
|
|
7910
8388
|
strokeColor: ink,
|
|
@@ -8095,6 +8573,32 @@ function compileNautical(request, context) {
|
|
|
8095
8573
|
}
|
|
8096
8574
|
},
|
|
8097
8575
|
labels: {
|
|
8576
|
+
bridges: {
|
|
8577
|
+
minZoom: 13,
|
|
8578
|
+
placement: "point",
|
|
8579
|
+
text: {
|
|
8580
|
+
...markText,
|
|
8581
|
+
field: expression(bridgeClearance()),
|
|
8582
|
+
padding: 2,
|
|
8583
|
+
size: zoom.linear([
|
|
8584
|
+
[13, 8.5],
|
|
8585
|
+
[16, 10]
|
|
8586
|
+
])
|
|
8587
|
+
}
|
|
8588
|
+
},
|
|
8589
|
+
overheadCables: {
|
|
8590
|
+
minZoom: 12,
|
|
8591
|
+
placement: "point",
|
|
8592
|
+
spacing: 360,
|
|
8593
|
+
text: {
|
|
8594
|
+
...markText,
|
|
8595
|
+
color: accent,
|
|
8596
|
+
field: expression(cableClearance()),
|
|
8597
|
+
maxAngle: 30,
|
|
8598
|
+
padding: 2,
|
|
8599
|
+
size: 8.5
|
|
8600
|
+
}
|
|
8601
|
+
},
|
|
8098
8602
|
coverage: {
|
|
8099
8603
|
maxZoom: 9,
|
|
8100
8604
|
minZoom: 4,
|
|
@@ -8144,6 +8648,7 @@ function compileNautical(request, context) {
|
|
|
8144
8648
|
const source = nauticalSource.sourceId;
|
|
8145
8649
|
const contributions = [];
|
|
8146
8650
|
const add2 = (options) => appendNauticalLayer(contributions, { ...options, source });
|
|
8651
|
+
const ofClass = (value) => ["==", ["get", fields.class], value];
|
|
8147
8652
|
add2({
|
|
8148
8653
|
// Only coverage that speaks for every family; lists of lights alone would double the tint.
|
|
8149
8654
|
filter: ["all", polygons, ["in", layers.aids, ["coalesce", ["get", fields.families], ""]]],
|
|
@@ -8154,13 +8659,30 @@ function compileNautical(request, context) {
|
|
|
8154
8659
|
target: "nautical.coverage"
|
|
8155
8660
|
});
|
|
8156
8661
|
add2({
|
|
8157
|
-
filter: polygons,
|
|
8662
|
+
filter: ["all", polygons, ["match", ["get", fields.class], [...ownAreaClasses], false, true]],
|
|
8158
8663
|
id: "tileflow-nautical-navigation-areas",
|
|
8159
8664
|
localOrder: 390,
|
|
8160
8665
|
sourceLayer: layers.navigationAreas,
|
|
8161
8666
|
style: config.navigationAreas,
|
|
8162
8667
|
target: "nautical.navigationAreas"
|
|
8163
8668
|
});
|
|
8669
|
+
add2({
|
|
8670
|
+
filter: ["all", polygons, ofClass("harbour")],
|
|
8671
|
+
id: "tileflow-nautical-harbour-areas",
|
|
8672
|
+
localOrder: 392,
|
|
8673
|
+
sourceLayer: layers.navigationAreas,
|
|
8674
|
+
style: config.harbourAreas,
|
|
8675
|
+
target: "nautical.harbourAreas"
|
|
8676
|
+
});
|
|
8677
|
+
add2({
|
|
8678
|
+
filter: ["all", polygons, ofClass("berth")],
|
|
8679
|
+
id: "tileflow-nautical-berths",
|
|
8680
|
+
localOrder: 394,
|
|
8681
|
+
outlineFilter: ["all", linesOrPolygons, ofClass("berth")],
|
|
8682
|
+
sourceLayer: layers.navigationAreas,
|
|
8683
|
+
style: config.berths,
|
|
8684
|
+
target: "nautical.berths"
|
|
8685
|
+
});
|
|
8164
8686
|
add2({
|
|
8165
8687
|
filter: polygons,
|
|
8166
8688
|
id: "tileflow-nautical-reefs",
|
|
@@ -8187,11 +8709,20 @@ function compileNautical(request, context) {
|
|
|
8187
8709
|
style: config.routes,
|
|
8188
8710
|
target: "nautical.routes"
|
|
8189
8711
|
});
|
|
8712
|
+
add2({
|
|
8713
|
+
filter: linesOf(["overhead-cable"]),
|
|
8714
|
+
id: "tileflow-nautical-overhead-cables",
|
|
8715
|
+
line: true,
|
|
8716
|
+
localOrder: 408,
|
|
8717
|
+
sourceLayer: layers.navigationAreas,
|
|
8718
|
+
style: config.overheadCables,
|
|
8719
|
+
target: "nautical.overheadCables"
|
|
8720
|
+
});
|
|
8190
8721
|
add2({
|
|
8191
8722
|
filter: polygons,
|
|
8192
8723
|
id: "tileflow-nautical-hazard-areas",
|
|
8193
8724
|
localOrder: 410,
|
|
8194
|
-
outlineFilter:
|
|
8725
|
+
outlineFilter: linesOrPolygons,
|
|
8195
8726
|
sourceLayer: layers.hazards,
|
|
8196
8727
|
style: config.hazardAreas,
|
|
8197
8728
|
target: "nautical.hazardAreas"
|
|
@@ -8204,15 +8735,42 @@ function compileNautical(request, context) {
|
|
|
8204
8735
|
style: config.wreckAreas,
|
|
8205
8736
|
target: "nautical.wreckAreas"
|
|
8206
8737
|
});
|
|
8207
|
-
|
|
8208
|
-
|
|
8209
|
-
["
|
|
8210
|
-
|
|
8211
|
-
|
|
8212
|
-
["
|
|
8738
|
+
add2({
|
|
8739
|
+
// Bridges draw over the water and the areas below them.
|
|
8740
|
+
filter: ["all", polygons, ofClass("bridge")],
|
|
8741
|
+
id: "tileflow-nautical-bridges",
|
|
8742
|
+
localOrder: 424,
|
|
8743
|
+
outlineFilter: ["all", linesOrPolygons, ofClass("bridge")],
|
|
8744
|
+
sourceLayer: layers.navigationAreas,
|
|
8745
|
+
style: config.bridges,
|
|
8746
|
+
target: "nautical.bridges"
|
|
8747
|
+
});
|
|
8748
|
+
for (const [key, id2, sourceLayer, localOrder, filter] of [
|
|
8749
|
+
[
|
|
8750
|
+
"coverage",
|
|
8751
|
+
"tileflow-nautical-coverage-labels",
|
|
8752
|
+
layers.coverage,
|
|
8753
|
+
560,
|
|
8754
|
+
["has", fields.provider]
|
|
8755
|
+
],
|
|
8756
|
+
[
|
|
8757
|
+
"navigationAreas",
|
|
8758
|
+
"tileflow-nautical-navigation-area-labels",
|
|
8759
|
+
layers.navigationAreas,
|
|
8760
|
+
562,
|
|
8761
|
+
// Harbours, facilities and bridges carry their own symbols and labels.
|
|
8762
|
+
[
|
|
8763
|
+
"all",
|
|
8764
|
+
["has", fields.name],
|
|
8765
|
+
["match", ["get", fields.class], ["bridge", "facility", "harbour"], false, true]
|
|
8766
|
+
]
|
|
8767
|
+
],
|
|
8768
|
+
["reefs", "tileflow-nautical-reef-labels", layers.reefs, 564, ["has", fields.name]],
|
|
8769
|
+
["hazards", "tileflow-nautical-hazard-area-labels", layers.hazards, 566, ["has", fields.name]],
|
|
8770
|
+
["wrecks", "tileflow-nautical-wreck-area-labels", layers.wrecks, 568, ["has", fields.name]]
|
|
8213
8771
|
]) {
|
|
8214
8772
|
add2({
|
|
8215
|
-
filter: ["all", polygons,
|
|
8773
|
+
filter: ["all", polygons, filter],
|
|
8216
8774
|
id: id2,
|
|
8217
8775
|
localOrder,
|
|
8218
8776
|
sourceLayer,
|
|
@@ -8220,6 +8778,37 @@ function compileNautical(request, context) {
|
|
|
8220
8778
|
target: `nautical.labels.${key}`
|
|
8221
8779
|
});
|
|
8222
8780
|
}
|
|
8781
|
+
add2({
|
|
8782
|
+
filter: [
|
|
8783
|
+
"all",
|
|
8784
|
+
ofClass("bridge"),
|
|
8785
|
+
[
|
|
8786
|
+
"any",
|
|
8787
|
+
["has", fields.verticalClearance],
|
|
8788
|
+
["has", fields.verticalClearanceClosed],
|
|
8789
|
+
["has", fields.verticalClearanceOpen]
|
|
8790
|
+
]
|
|
8791
|
+
],
|
|
8792
|
+
id: "tileflow-nautical-bridge-labels",
|
|
8793
|
+
lines: { localOrder: 557, placement: "line-center" },
|
|
8794
|
+
localOrder: 556,
|
|
8795
|
+
sourceLayer: layers.navigationAreas,
|
|
8796
|
+
style: config.labels?.bridges,
|
|
8797
|
+
target: "nautical.labels.bridges"
|
|
8798
|
+
});
|
|
8799
|
+
add2({
|
|
8800
|
+
filter: [
|
|
8801
|
+
"all",
|
|
8802
|
+
ofClass("overhead-cable"),
|
|
8803
|
+
["any", ["has", fields.verticalClearanceSafe], ["has", fields.verticalClearance]]
|
|
8804
|
+
],
|
|
8805
|
+
id: "tileflow-nautical-overhead-cable-labels",
|
|
8806
|
+
lines: { localOrder: 559, placement: "line" },
|
|
8807
|
+
localOrder: 558,
|
|
8808
|
+
sourceLayer: layers.navigationAreas,
|
|
8809
|
+
style: config.labels?.overheadCables,
|
|
8810
|
+
target: "nautical.labels.overheadCables"
|
|
8811
|
+
});
|
|
8223
8812
|
add2({
|
|
8224
8813
|
filter: ["all", points, ["has", fields.depth]],
|
|
8225
8814
|
id: "tileflow-nautical-soundings",
|
|
@@ -8238,6 +8827,16 @@ function compileNautical(request, context) {
|
|
|
8238
8827
|
symbolFilter: ["==", ["get", fields.class], "rock"],
|
|
8239
8828
|
target: "nautical.hazards"
|
|
8240
8829
|
});
|
|
8830
|
+
add2({
|
|
8831
|
+
filter: ofClass("facility"),
|
|
8832
|
+
id: "tileflow-nautical-facilities",
|
|
8833
|
+
lines: { localOrder: 580, placement: "line-center" },
|
|
8834
|
+
localOrder: 576,
|
|
8835
|
+
markerFilter: points,
|
|
8836
|
+
sourceLayer: layers.navigationAreas,
|
|
8837
|
+
style: config.facilities,
|
|
8838
|
+
target: "nautical.facilities"
|
|
8839
|
+
});
|
|
8241
8840
|
add2({
|
|
8242
8841
|
filter: points,
|
|
8243
8842
|
id: "tileflow-nautical-wrecks",
|
|
@@ -8247,13 +8846,23 @@ function compileNautical(request, context) {
|
|
|
8247
8846
|
target: "nautical.wrecks"
|
|
8248
8847
|
});
|
|
8249
8848
|
add2({
|
|
8250
|
-
|
|
8849
|
+
// Harbour polygons, such as marinas, carry their symbol and name at their centre.
|
|
8850
|
+
filter: ["all", pointsOrPolygons, ofClass("harbour")],
|
|
8251
8851
|
id: "tileflow-nautical-harbours",
|
|
8252
8852
|
localOrder: 582,
|
|
8853
|
+
markerFilter: points,
|
|
8253
8854
|
sourceLayer: layers.navigationAreas,
|
|
8254
8855
|
style: config.harbours,
|
|
8255
8856
|
target: "nautical.harbours"
|
|
8256
8857
|
});
|
|
8858
|
+
add2({
|
|
8859
|
+
filter: ["all", points, ofClass("distance-mark")],
|
|
8860
|
+
id: "tileflow-nautical-distance-marks",
|
|
8861
|
+
localOrder: 584,
|
|
8862
|
+
sourceLayer: layers.aids,
|
|
8863
|
+
style: config.distanceMarks,
|
|
8864
|
+
target: "nautical.distanceMarks"
|
|
8865
|
+
});
|
|
8257
8866
|
add2({
|
|
8258
8867
|
filter: [
|
|
8259
8868
|
"all",
|
|
@@ -8261,7 +8870,7 @@ function compileNautical(request, context) {
|
|
|
8261
8870
|
[
|
|
8262
8871
|
"match",
|
|
8263
8872
|
["get", fields.class],
|
|
8264
|
-
[...floatingAidClasses, ...fixedAidClasses, "lighthouse"],
|
|
8873
|
+
[...floatingAidClasses, ...fixedAidClasses, ...ownAidClasses, "lighthouse"],
|
|
8265
8874
|
false,
|
|
8266
8875
|
true
|
|
8267
8876
|
]
|
|
@@ -8272,6 +8881,14 @@ function compileNautical(request, context) {
|
|
|
8272
8881
|
style: config.aids,
|
|
8273
8882
|
target: "nautical.aids"
|
|
8274
8883
|
});
|
|
8884
|
+
add2({
|
|
8885
|
+
filter: ["all", points, ofClass("notice")],
|
|
8886
|
+
id: "tileflow-nautical-notices",
|
|
8887
|
+
localOrder: 588,
|
|
8888
|
+
sourceLayer: layers.aids,
|
|
8889
|
+
style: config.notices,
|
|
8890
|
+
target: "nautical.notices"
|
|
8891
|
+
});
|
|
8275
8892
|
add2({
|
|
8276
8893
|
filter: ["all", points, ["match", ["get", fields.class], [...fixedAidClasses], true, false]],
|
|
8277
8894
|
id: "tileflow-nautical-beacons",
|
|
@@ -8282,6 +8899,7 @@ function compileNautical(request, context) {
|
|
|
8282
8899
|
});
|
|
8283
8900
|
add2({
|
|
8284
8901
|
filter: points,
|
|
8902
|
+
flash: animateLights,
|
|
8285
8903
|
id: "tileflow-nautical-lights",
|
|
8286
8904
|
localOrder: 594,
|
|
8287
8905
|
sourceLayer: layers.lights,
|
|
@@ -8297,7 +8915,7 @@ function compileNautical(request, context) {
|
|
|
8297
8915
|
target: "nautical.buoys"
|
|
8298
8916
|
});
|
|
8299
8917
|
add2({
|
|
8300
|
-
filter: ["all", points,
|
|
8918
|
+
filter: ["all", points, ofClass("lighthouse")],
|
|
8301
8919
|
id: "tileflow-nautical-lighthouses",
|
|
8302
8920
|
localOrder: 602,
|
|
8303
8921
|
sourceLayer: layers.aids,
|
|
@@ -8305,7 +8923,7 @@ function compileNautical(request, context) {
|
|
|
8305
8923
|
target: "nautical.lighthouses"
|
|
8306
8924
|
});
|
|
8307
8925
|
add2({
|
|
8308
|
-
filter: ["all", points,
|
|
8926
|
+
filter: ["all", points, ofClass("port")],
|
|
8309
8927
|
id: "tileflow-nautical-ports",
|
|
8310
8928
|
localOrder: 606,
|
|
8311
8929
|
sourceLayer: layers.navigationAreas,
|
|
@@ -8316,12 +8934,14 @@ function compileNautical(request, context) {
|
|
|
8316
8934
|
}
|
|
8317
8935
|
var points = ["==", ["geometry-type"], "Point"];
|
|
8318
8936
|
var polygons = ["==", ["geometry-type"], "Polygon"];
|
|
8937
|
+
var lines = ["==", ["geometry-type"], "LineString"];
|
|
8938
|
+
var pointsOrPolygons = ["match", ["geometry-type"], ["Point", "Polygon"], true, false];
|
|
8939
|
+
var linesOrPolygons = ["match", ["geometry-type"], ["LineString", "Polygon"], true, false];
|
|
8319
8940
|
function linesOf(classes) {
|
|
8320
|
-
return [
|
|
8321
|
-
|
|
8322
|
-
|
|
8323
|
-
|
|
8324
|
-
];
|
|
8941
|
+
return ["all", lines, ["match", ["get", fields.class], [...classes], true, false]];
|
|
8942
|
+
}
|
|
8943
|
+
function listIncludes(field2, item) {
|
|
8944
|
+
return ["in", `,${item},`, ["concat", ",", ["to-string", ["coalesce", ["get", field2], ""]], ","]];
|
|
8325
8945
|
}
|
|
8326
8946
|
var fromFeatureMinZoom = [">=", ["zoom"], ["to-number", ["get", fields.minZoom], 0]];
|
|
8327
8947
|
function appendNauticalLayer(contributions, options) {
|
|
@@ -8378,24 +8998,25 @@ function appendNauticalLayer(contributions, options) {
|
|
|
8378
8998
|
if (point.visible === false) return;
|
|
8379
8999
|
const isLabel = options.target.startsWith("nautical.labels.");
|
|
8380
9000
|
if (!isLabel && point.marker && point.marker.visible !== false) {
|
|
9001
|
+
const marker = applyCircleStyle(
|
|
9002
|
+
base(
|
|
9003
|
+
`${options.id}-marker`,
|
|
9004
|
+
"circle",
|
|
9005
|
+
options.markerFilter ? ["all", options.filter, options.markerFilter] : options.filter
|
|
9006
|
+
),
|
|
9007
|
+
mergeTileflowDesign(
|
|
9008
|
+
{
|
|
9009
|
+
...point.maxZoom === void 0 ? {} : { maxZoom: point.maxZoom },
|
|
9010
|
+
...point.minZoom === void 0 ? {} : { minZoom: point.minZoom }
|
|
9011
|
+
},
|
|
9012
|
+
point.marker
|
|
9013
|
+
)
|
|
9014
|
+
);
|
|
8381
9015
|
contributions.push(
|
|
8382
9016
|
nauticalContribution(
|
|
8383
9017
|
`${options.target}.marker`,
|
|
8384
9018
|
options.localOrder,
|
|
8385
|
-
|
|
8386
|
-
base(
|
|
8387
|
-
`${options.id}-marker`,
|
|
8388
|
-
"circle",
|
|
8389
|
-
options.markerFilter ? ["all", options.filter, options.markerFilter] : options.filter
|
|
8390
|
-
),
|
|
8391
|
-
mergeTileflowDesign(
|
|
8392
|
-
{
|
|
8393
|
-
...point.maxZoom === void 0 ? {} : { maxZoom: point.maxZoom },
|
|
8394
|
-
...point.minZoom === void 0 ? {} : { minZoom: point.minZoom }
|
|
8395
|
-
},
|
|
8396
|
-
point.marker
|
|
8397
|
-
)
|
|
8398
|
-
),
|
|
9019
|
+
options.flash ? flashing(marker, ["circle-opacity", "circle-stroke-opacity"]) : marker,
|
|
8399
9020
|
"symbols"
|
|
8400
9021
|
)
|
|
8401
9022
|
);
|
|
@@ -8403,21 +9024,79 @@ function appendNauticalLayer(contributions, options) {
|
|
|
8403
9024
|
const hasText = Boolean(point.text && point.text.visible !== false);
|
|
8404
9025
|
const hasIcon = Boolean(point.icon && point.icon.visible !== false);
|
|
8405
9026
|
if (!hasText && !hasIcon) return;
|
|
9027
|
+
const symbolFilter = [
|
|
9028
|
+
options.filter,
|
|
9029
|
+
...options.symbolFilter ? [options.symbolFilter] : [],
|
|
9030
|
+
...options.lines ? [["!=", ["geometry-type"], "LineString"]] : []
|
|
9031
|
+
];
|
|
9032
|
+
const symbol = applySymbolStyle(
|
|
9033
|
+
base(
|
|
9034
|
+
options.id,
|
|
9035
|
+
"symbol",
|
|
9036
|
+
symbolFilter.length === 1 ? symbolFilter[0] : ["all", ...symbolFilter]
|
|
9037
|
+
),
|
|
9038
|
+
withoutMarker(point)
|
|
9039
|
+
);
|
|
8406
9040
|
contributions.push(
|
|
8407
9041
|
nauticalContribution(
|
|
8408
9042
|
isLabel ? options.target : `${options.target}.symbol`,
|
|
8409
9043
|
options.localOrder + (isLabel ? 0 : 1),
|
|
8410
|
-
|
|
8411
|
-
base(
|
|
8412
|
-
options.id,
|
|
8413
|
-
"symbol",
|
|
8414
|
-
options.symbolFilter ? ["all", options.filter, options.symbolFilter] : options.filter
|
|
8415
|
-
),
|
|
8416
|
-
withoutMarker(point)
|
|
8417
|
-
),
|
|
9044
|
+
options.flash && hasIcon ? flashing(symbol, ["icon-opacity"]) : symbol,
|
|
8418
9045
|
"symbols"
|
|
8419
9046
|
)
|
|
8420
9047
|
);
|
|
9048
|
+
if (options.lines) {
|
|
9049
|
+
contributions.push(
|
|
9050
|
+
nauticalContribution(
|
|
9051
|
+
`${options.target}.lines`,
|
|
9052
|
+
options.lines.localOrder,
|
|
9053
|
+
applySymbolStyle(
|
|
9054
|
+
base(`${options.id}-lines`, "symbol", [
|
|
9055
|
+
"all",
|
|
9056
|
+
options.filter,
|
|
9057
|
+
...options.symbolFilter ? [options.symbolFilter] : [],
|
|
9058
|
+
lines
|
|
9059
|
+
]),
|
|
9060
|
+
{ ...withoutMarker(point), placement: options.lines.placement }
|
|
9061
|
+
),
|
|
9062
|
+
"symbols"
|
|
9063
|
+
)
|
|
9064
|
+
);
|
|
9065
|
+
}
|
|
9066
|
+
}
|
|
9067
|
+
function flashing(layer, properties) {
|
|
9068
|
+
const paint = { ...layer.paint ?? {} };
|
|
9069
|
+
const factor = [
|
|
9070
|
+
"interpolate",
|
|
9071
|
+
["linear"],
|
|
9072
|
+
tileflowNauticalLightStateRead("intensity", 1),
|
|
9073
|
+
0,
|
|
9074
|
+
tileflowNauticalLightEclipseOpacity,
|
|
9075
|
+
1,
|
|
9076
|
+
1
|
|
9077
|
+
];
|
|
9078
|
+
for (const property of properties) {
|
|
9079
|
+
const value = paint[property];
|
|
9080
|
+
if (property !== "circle-opacity" && property !== "icon-opacity" && value === void 0) {
|
|
9081
|
+
continue;
|
|
9082
|
+
}
|
|
9083
|
+
paint[property] = scaleOutputs(value ?? 1, factor);
|
|
9084
|
+
}
|
|
9085
|
+
return { ...layer, paint };
|
|
9086
|
+
}
|
|
9087
|
+
function scaleOutputs(value, factor) {
|
|
9088
|
+
if (Array.isArray(value) && isZoomCurve(value)) {
|
|
9089
|
+
const firstOutput = value[0] === "step" ? 2 : 4;
|
|
9090
|
+
return value.map(
|
|
9091
|
+
(entry, index) => index >= firstOutput && (index - firstOutput) % 2 === 0 ? ["*", entry, factor] : entry
|
|
9092
|
+
);
|
|
9093
|
+
}
|
|
9094
|
+
return ["*", value, factor];
|
|
9095
|
+
}
|
|
9096
|
+
function isZoomCurve(value) {
|
|
9097
|
+
const isZoom3 = (input) => Array.isArray(input) && input[0] === "zoom";
|
|
9098
|
+
if (value[0] === "step") return isZoom3(value[1]);
|
|
9099
|
+
return (value[0] === "interpolate" || value[0] === "interpolate-hcl" || value[0] === "interpolate-lab") && isZoom3(value[2]);
|
|
8421
9100
|
}
|
|
8422
9101
|
function withoutMarker(style) {
|
|
8423
9102
|
const result = { ...style };
|
|
@@ -8454,8 +9133,96 @@ function themedImages(context) {
|
|
|
8454
9133
|
]
|
|
8455
9134
|
]);
|
|
8456
9135
|
}
|
|
9136
|
+
const notice = images.notices;
|
|
9137
|
+
if (typeof notice === "string") {
|
|
9138
|
+
const variants = ["information", "prohibition", "recommendation", "regulation", "restriction"].flatMap((role) => [role, context.images[roles.notices[role]] ?? notice]);
|
|
9139
|
+
images.notices = expression(["match", ["get", fields.subclass], ...variants, notice]);
|
|
9140
|
+
}
|
|
9141
|
+
const facility = images.facilities;
|
|
9142
|
+
if (typeof facility === "string") {
|
|
9143
|
+
const cases = tileflowNauticalFacilityIcons.flatMap((category) => {
|
|
9144
|
+
const image = context.images[roles.facilities[category]];
|
|
9145
|
+
if (!image || image === facility) return [];
|
|
9146
|
+
const categories = category === "visitor-berth" ? ["visitor-berth", "visitors-mooring"] : [category];
|
|
9147
|
+
return [["any", ...categories.map((name) => listIncludes(fields.subclass, name))], image];
|
|
9148
|
+
});
|
|
9149
|
+
if (cases.length > 0) images.facilities = expression(["case", ...cases, facility]);
|
|
9150
|
+
}
|
|
9151
|
+
const harbour = images.harbours;
|
|
9152
|
+
const marina = context.images[roles.harbours.marina];
|
|
9153
|
+
if (typeof harbour === "string" && marina && marina !== harbour) {
|
|
9154
|
+
images.harbours = expression([
|
|
9155
|
+
"case",
|
|
9156
|
+
["any", ...marinaSubclasses.map((name) => listIncludes(fields.subclass, name))],
|
|
9157
|
+
marina,
|
|
9158
|
+
harbour
|
|
9159
|
+
]);
|
|
9160
|
+
}
|
|
8457
9161
|
return images;
|
|
8458
9162
|
}
|
|
9163
|
+
function bridgeClearance() {
|
|
9164
|
+
const metres = (field2) => ["concat", ["to-string", ["get", field2]], " m"];
|
|
9165
|
+
const closed = fields.verticalClearanceClosed;
|
|
9166
|
+
const open = fields.verticalClearanceOpen;
|
|
9167
|
+
return [
|
|
9168
|
+
"case",
|
|
9169
|
+
["any", ["has", closed], ["has", open]],
|
|
9170
|
+
[
|
|
9171
|
+
"concat",
|
|
9172
|
+
["case", ["has", closed], ["concat", "closed ", metres(closed)], ""],
|
|
9173
|
+
["case", ["all", ["has", closed], ["has", open]], " \xB7 ", ""],
|
|
9174
|
+
["case", ["has", open], ["concat", "open ", metres(open)], ""]
|
|
9175
|
+
],
|
|
9176
|
+
["has", fields.verticalClearance],
|
|
9177
|
+
["concat", "clearance ", metres(fields.verticalClearance)],
|
|
9178
|
+
""
|
|
9179
|
+
];
|
|
9180
|
+
}
|
|
9181
|
+
function cableClearance() {
|
|
9182
|
+
return [
|
|
9183
|
+
"case",
|
|
9184
|
+
["has", fields.verticalClearanceSafe],
|
|
9185
|
+
["concat", "safe clearance ", ["to-string", ["get", fields.verticalClearanceSafe]], " m"],
|
|
9186
|
+
["has", fields.verticalClearance],
|
|
9187
|
+
["concat", "clearance ", ["to-string", ["get", fields.verticalClearance]], " m"],
|
|
9188
|
+
""
|
|
9189
|
+
];
|
|
9190
|
+
}
|
|
9191
|
+
function nthColour(field2, index) {
|
|
9192
|
+
const list = ["var", "nauticalColours"];
|
|
9193
|
+
const cases = [];
|
|
9194
|
+
for (let position = 1; position < maxAlternatingColours; position += 1) {
|
|
9195
|
+
cases.push(["==", ["var", "nauticalColourIndex"], position], nthName(list, position));
|
|
9196
|
+
}
|
|
9197
|
+
return [
|
|
9198
|
+
"let",
|
|
9199
|
+
"nauticalColours",
|
|
9200
|
+
["to-string", ["coalesce", ["get", field2], ""]],
|
|
9201
|
+
"nauticalColourIndex",
|
|
9202
|
+
index,
|
|
9203
|
+
["case", ...cases, leadingName(list)]
|
|
9204
|
+
];
|
|
9205
|
+
}
|
|
9206
|
+
function nthName(list, position) {
|
|
9207
|
+
if (position === 0) return leadingName(list);
|
|
9208
|
+
const rest = `nauticalRest${position}`;
|
|
9209
|
+
return [
|
|
9210
|
+
"let",
|
|
9211
|
+
rest,
|
|
9212
|
+
[
|
|
9213
|
+
"let",
|
|
9214
|
+
"nauticalComma",
|
|
9215
|
+
["index-of", ",", list],
|
|
9216
|
+
[
|
|
9217
|
+
"case",
|
|
9218
|
+
["<", ["var", "nauticalComma"], 0],
|
|
9219
|
+
"",
|
|
9220
|
+
["slice", list, ["+", ["var", "nauticalComma"], 1]]
|
|
9221
|
+
]
|
|
9222
|
+
],
|
|
9223
|
+
nthName(["var", rest], position - 1)
|
|
9224
|
+
];
|
|
9225
|
+
}
|
|
8459
9226
|
function firstColour(field2) {
|
|
8460
9227
|
return [
|
|
8461
9228
|
"let",
|
|
@@ -9928,7 +10695,7 @@ function phaseVisibility(surfaces, phase, fields2) {
|
|
|
9928
10695
|
function zoomLevels(values) {
|
|
9929
10696
|
const levels = new Set(Array.from({ length: 10 }, (_, index) => index + 15));
|
|
9930
10697
|
for (const value of values) {
|
|
9931
|
-
if (!
|
|
10698
|
+
if (!isZoomCurve2(value)) continue;
|
|
9932
10699
|
for (let index = 3; index < value.length - 1; index += 2) {
|
|
9933
10700
|
const level = value[index];
|
|
9934
10701
|
if (level < 15 || level > 24) continue;
|
|
@@ -9986,7 +10753,7 @@ function interpolationFactor2(interpolation, distance, span) {
|
|
|
9986
10753
|
const logarithm = Math.log(interpolation[1]);
|
|
9987
10754
|
return Math.expm1(logarithm * distance) / Math.expm1(logarithm * span);
|
|
9988
10755
|
}
|
|
9989
|
-
function
|
|
10756
|
+
function isZoomCurve2(value) {
|
|
9990
10757
|
return Array.isArray(value) && (value[0] === "interpolate" && isZoom(value[2]) || value[0] === "step" && isZoom(value[1]));
|
|
9991
10758
|
}
|
|
9992
10759
|
function isZoom(value) {
|
|
@@ -9995,7 +10762,7 @@ function isZoom(value) {
|
|
|
9995
10762
|
function atZoom(value, level) {
|
|
9996
10763
|
if (!Array.isArray(value) || value[0] === "literal") return value;
|
|
9997
10764
|
if (isZoom(value)) return level;
|
|
9998
|
-
if (!
|
|
10765
|
+
if (!isZoomCurve2(value)) return value.map((entry) => atZoom(entry, level));
|
|
9999
10766
|
const stops = [];
|
|
10000
10767
|
for (let index = 3; index < value.length - 1; index += 2) {
|
|
10001
10768
|
stops.push({ level: value[index], value: value[index + 1] });
|
|
@@ -10021,7 +10788,7 @@ function foldConstants(value) {
|
|
|
10021
10788
|
const [operator, ...operands] = folded;
|
|
10022
10789
|
if (!operands.length || !operands.every((operand) => typeof operand === "number")) return folded;
|
|
10023
10790
|
const numbers = operands;
|
|
10024
|
-
const result = operator === "*" ? numbers.reduce((product, number) => product * number, 1) : operator === "+" ? numbers.reduce((
|
|
10791
|
+
const result = operator === "*" ? numbers.reduce((product, number) => product * number, 1) : operator === "+" ? numbers.reduce((sum2, number) => sum2 + number, 0) : operator === "-" ? numbers.length === 1 ? -numbers[0] : numbers[0] - numbers[1] : operator === "/" && numbers.length === 2 ? numbers[0] / numbers[1] : operator === "max" ? Math.max(...numbers) : operator === "min" ? Math.min(...numbers) : void 0;
|
|
10025
10792
|
return result !== void 0 && Number.isFinite(result) ? result : folded;
|
|
10026
10793
|
}
|
|
10027
10794
|
function interpolated(lower, upper, at) {
|
|
@@ -11321,13 +12088,13 @@ function tileflowVegetationMetadata(vegetation2) {
|
|
|
11321
12088
|
return { version: 1, ...vegetation2 };
|
|
11322
12089
|
}
|
|
11323
12090
|
function readTileflowVegetation3D(metadata) {
|
|
11324
|
-
if (!
|
|
12091
|
+
if (!isRecord7(metadata)) return void 0;
|
|
11325
12092
|
const value = metadata[tileflowVegetationMetadataKey];
|
|
11326
|
-
if (!
|
|
12093
|
+
if (!isRecord7(value) || value.version !== 1) return void 0;
|
|
11327
12094
|
const { source, layers: layers2, fields: fields2, colors, heightScale, crownScale, unknownForms, regions: regions2 } = value;
|
|
11328
|
-
if (typeof source !== "string" || !
|
|
12095
|
+
if (typeof source !== "string" || !isRecord7(layers2) || typeof layers2.tree !== "string")
|
|
11329
12096
|
return void 0;
|
|
11330
|
-
if (!
|
|
12097
|
+
if (!isRecord7(fields2) || !isRecord7(colors) || typeof colors.bark !== "string") return void 0;
|
|
11331
12098
|
const palette = (list) => Array.isArray(list) && list.length > 0 && list.every((entry) => typeof entry === "string") ? list : void 0;
|
|
11332
12099
|
const broadleaf = palette(colors.broadleaf);
|
|
11333
12100
|
const conifer = palette(colors.conifer);
|
|
@@ -11337,18 +12104,18 @@ function readTileflowVegetation3D(metadata) {
|
|
|
11337
12104
|
const scale = (number) => typeof number === "number" && number > 0 && number <= 10 ? number : 1;
|
|
11338
12105
|
const mix2 = tileflowTreeFormMixProblem(unknownForms) === void 0 ? unknownForms : void 0;
|
|
11339
12106
|
const models = Object.fromEntries(
|
|
11340
|
-
Object.entries(
|
|
11341
|
-
([id2, model]) => tileflowTreeModelIdPattern.test(id2) &&
|
|
12107
|
+
Object.entries(isRecord7(value.models) ? value.models : {}).filter(
|
|
12108
|
+
([id2, model]) => tileflowTreeModelIdPattern.test(id2) && isRecord7(model) && typeof model.near === "string" && (model.far === void 0 || typeof model.far === "string")
|
|
11342
12109
|
).slice(0, 16).map(([id2, model]) => {
|
|
11343
12110
|
const { near, far } = model;
|
|
11344
12111
|
return [id2, far === void 0 ? { near } : { near, far }];
|
|
11345
12112
|
})
|
|
11346
12113
|
);
|
|
11347
|
-
const ownScales =
|
|
12114
|
+
const ownScales = isRecord7(value.forms) ? value.forms : {};
|
|
11348
12115
|
const forms = Object.fromEntries(
|
|
11349
12116
|
tileflowTreeForms.flatMap((form) => {
|
|
11350
12117
|
const own = ownScales[form];
|
|
11351
|
-
if (!
|
|
12118
|
+
if (!isRecord7(own)) return [];
|
|
11352
12119
|
const drawn = Array.isArray(own.models) ? [...new Set(own.models)].filter((id2) => typeof id2 === "string" && id2 in models).slice(0, 4) : [];
|
|
11353
12120
|
return [
|
|
11354
12121
|
[
|
|
@@ -11362,10 +12129,10 @@ function readTileflowVegetation3D(metadata) {
|
|
|
11362
12129
|
];
|
|
11363
12130
|
})
|
|
11364
12131
|
);
|
|
11365
|
-
const
|
|
12132
|
+
const finish2 = tileflowTreeFinishes.find((name) => name === value.finish) ?? "faceted";
|
|
11366
12133
|
const edges = typeof value.edges === "number" && value.edges >= 0 && value.edges <= 1 ? value.edges : 0;
|
|
11367
12134
|
const zones = Array.isArray(regions2) ? regions2.filter(
|
|
11368
|
-
(region) =>
|
|
12135
|
+
(region) => isRecord7(region) && tileflowTreeRegionProblem(region) === void 0
|
|
11369
12136
|
) : [];
|
|
11370
12137
|
const named = Object.fromEntries(
|
|
11371
12138
|
Object.entries(tileflowWorldTreeFields).map(([key, fallback]) => [
|
|
@@ -11386,7 +12153,7 @@ function readTileflowVegetation3D(metadata) {
|
|
|
11386
12153
|
crownScale: scale(crownScale),
|
|
11387
12154
|
forms,
|
|
11388
12155
|
models,
|
|
11389
|
-
finish,
|
|
12156
|
+
finish: finish2,
|
|
11390
12157
|
edges,
|
|
11391
12158
|
...typeof value.edgeColor === "string" ? { edgeColor: value.edgeColor } : {},
|
|
11392
12159
|
unknownForms: mix2 ?? tileflowDefaultUnknownTreeForms,
|
|
@@ -11395,7 +12162,7 @@ function readTileflowVegetation3D(metadata) {
|
|
|
11395
12162
|
};
|
|
11396
12163
|
}
|
|
11397
12164
|
function tileflowTreeRegionProblem(region) {
|
|
11398
|
-
if (!
|
|
12165
|
+
if (!isRecord7(region)) return "a region is an object with bounds and unknownForms";
|
|
11399
12166
|
const bounds = region.bounds;
|
|
11400
12167
|
if (!Array.isArray(bounds) || bounds.length !== 4 || !bounds.every((value) => typeof value === "number" && Number.isFinite(value)))
|
|
11401
12168
|
return "bounds are [west, south, east, north] in degrees";
|
|
@@ -11406,7 +12173,7 @@ function tileflowTreeRegionProblem(region) {
|
|
|
11406
12173
|
const mix2 = tileflowTreeFormMixProblem(region.unknownForms);
|
|
11407
12174
|
return mix2 ? `unknownForms: ${mix2}` : void 0;
|
|
11408
12175
|
}
|
|
11409
|
-
function
|
|
12176
|
+
function isRecord7(value) {
|
|
11410
12177
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11411
12178
|
}
|
|
11412
12179
|
|
|
@@ -13105,9 +13872,9 @@ var tileflowNoticeLimits = Object.freeze({
|
|
|
13105
13872
|
maxSources: 16,
|
|
13106
13873
|
maxTextLength: 120
|
|
13107
13874
|
});
|
|
13108
|
-
var
|
|
13875
|
+
var identifierPattern2 = /^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$/u;
|
|
13109
13876
|
function readTileflowNotices(metadata) {
|
|
13110
|
-
if (!
|
|
13877
|
+
if (!isRecord8(metadata)) return [];
|
|
13111
13878
|
const value = metadata[tileflowNoticesMetadataKey];
|
|
13112
13879
|
if (!Array.isArray(value)) return [];
|
|
13113
13880
|
const notices = [];
|
|
@@ -13121,18 +13888,18 @@ function readTileflowNotices(metadata) {
|
|
|
13121
13888
|
return Object.freeze(notices);
|
|
13122
13889
|
}
|
|
13123
13890
|
function readNotice(value) {
|
|
13124
|
-
if (!
|
|
13891
|
+
if (!isRecord8(value)) return void 0;
|
|
13125
13892
|
const { id: id2, sources, text } = value;
|
|
13126
|
-
if (typeof id2 !== "string" || !
|
|
13893
|
+
if (typeof id2 !== "string" || !identifierPattern2.test(id2)) return void 0;
|
|
13127
13894
|
if (typeof text !== "string" || text.trim() !== text || !text || text.length > tileflowNoticeLimits.maxTextLength || /\p{Cc}/u.test(text)) {
|
|
13128
13895
|
return void 0;
|
|
13129
13896
|
}
|
|
13130
|
-
if (!Array.isArray(sources) || sources.length > tileflowNoticeLimits.maxSources || !sources.every((source) => typeof source === "string" &&
|
|
13897
|
+
if (!Array.isArray(sources) || sources.length > tileflowNoticeLimits.maxSources || !sources.every((source) => typeof source === "string" && identifierPattern2.test(source))) {
|
|
13131
13898
|
return void 0;
|
|
13132
13899
|
}
|
|
13133
13900
|
return Object.freeze({ id: id2, sources: Object.freeze([...sources]), text });
|
|
13134
13901
|
}
|
|
13135
|
-
function
|
|
13902
|
+
function isRecord8(value) {
|
|
13136
13903
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
13137
13904
|
}
|
|
13138
13905
|
|
|
@@ -13809,21 +14576,21 @@ function bindSemanticValue(value, schema, sourceId) {
|
|
|
13809
14576
|
}
|
|
13810
14577
|
if (isDataSourceReference(value)) return sourceId;
|
|
13811
14578
|
if (Array.isArray(value)) return value.map((item) => bindSemanticValue(item, schema, sourceId));
|
|
13812
|
-
if (!
|
|
14579
|
+
if (!isRecord9(value)) return value;
|
|
13813
14580
|
return Object.fromEntries(
|
|
13814
14581
|
Object.entries(value).map(([key, item]) => [key, bindSemanticValue(item, schema, sourceId)])
|
|
13815
14582
|
);
|
|
13816
14583
|
}
|
|
13817
14584
|
function isDataFieldReference2(value) {
|
|
13818
|
-
return
|
|
14585
|
+
return isRecord9(value) && value.kind === "tileflow-data-field" && typeof value.name === "string";
|
|
13819
14586
|
}
|
|
13820
14587
|
function isDataLayerReference(value) {
|
|
13821
|
-
return
|
|
14588
|
+
return isRecord9(value) && value.kind === "tileflow-data-layer" && typeof value.name === "string";
|
|
13822
14589
|
}
|
|
13823
14590
|
function isDataSourceReference(value) {
|
|
13824
|
-
return
|
|
14591
|
+
return isRecord9(value) && value.kind === "tileflow-data-source" && value.name === "primary";
|
|
13825
14592
|
}
|
|
13826
|
-
function
|
|
14593
|
+
function isRecord9(value) {
|
|
13827
14594
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
13828
14595
|
}
|
|
13829
14596
|
function compareCodeUnits5(left, right) {
|
|
@@ -13927,8 +14694,8 @@ function createTileflowLayerTemplateIR(layer, semanticKey) {
|
|
|
13927
14694
|
renderer: type,
|
|
13928
14695
|
...filter === void 0 ? {} : { selector: cloneJson20(filter) },
|
|
13929
14696
|
style: Object.freeze({
|
|
13930
|
-
...
|
|
13931
|
-
...
|
|
14697
|
+
...isRecord10(layout) ? { placement: Object.freeze(cloneJson20(layout)) } : {},
|
|
14698
|
+
...isRecord10(paint) ? { appearance: Object.freeze(cloneJson20(paint)) } : {}
|
|
13932
14699
|
})
|
|
13933
14700
|
});
|
|
13934
14701
|
}
|
|
@@ -14120,20 +14887,29 @@ var exactPhysicalLayerIds = Object.freeze({
|
|
|
14120
14887
|
var nauticalPhysicalBases = Object.freeze({
|
|
14121
14888
|
"nautical.aids": "tileflow-nautical-aids",
|
|
14122
14889
|
"nautical.beacons": "tileflow-nautical-beacons",
|
|
14890
|
+
"nautical.berths": "tileflow-nautical-berths",
|
|
14891
|
+
"nautical.bridges": "tileflow-nautical-bridges",
|
|
14123
14892
|
"nautical.buoys": "tileflow-nautical-buoys",
|
|
14124
14893
|
"nautical.cables": "tileflow-nautical-cables",
|
|
14125
14894
|
"nautical.coverage": "tileflow-nautical-coverage",
|
|
14895
|
+
"nautical.distanceMarks": "tileflow-nautical-distance-marks",
|
|
14896
|
+
"nautical.facilities": "tileflow-nautical-facilities",
|
|
14897
|
+
"nautical.harbourAreas": "tileflow-nautical-harbour-areas",
|
|
14126
14898
|
"nautical.harbours": "tileflow-nautical-harbours",
|
|
14127
14899
|
"nautical.hazardAreas": "tileflow-nautical-hazard-areas",
|
|
14128
14900
|
"nautical.hazards": "tileflow-nautical-hazards",
|
|
14901
|
+
"nautical.labels.bridges": "tileflow-nautical-bridge-labels",
|
|
14129
14902
|
"nautical.labels.coverage": "tileflow-nautical-coverage-labels",
|
|
14130
14903
|
"nautical.labels.hazards": "tileflow-nautical-hazard-area-labels",
|
|
14131
14904
|
"nautical.labels.navigationAreas": "tileflow-nautical-navigation-area-labels",
|
|
14905
|
+
"nautical.labels.overheadCables": "tileflow-nautical-overhead-cable-labels",
|
|
14132
14906
|
"nautical.labels.reefs": "tileflow-nautical-reef-labels",
|
|
14133
14907
|
"nautical.labels.wrecks": "tileflow-nautical-wreck-area-labels",
|
|
14134
14908
|
"nautical.lighthouses": "tileflow-nautical-lighthouses",
|
|
14135
14909
|
"nautical.lights": "tileflow-nautical-lights",
|
|
14136
14910
|
"nautical.navigationAreas": "tileflow-nautical-navigation-areas",
|
|
14911
|
+
"nautical.notices": "tileflow-nautical-notices",
|
|
14912
|
+
"nautical.overheadCables": "tileflow-nautical-overhead-cables",
|
|
14137
14913
|
"nautical.ports": "tileflow-nautical-ports",
|
|
14138
14914
|
"nautical.reefs": "tileflow-nautical-reefs",
|
|
14139
14915
|
"nautical.routes": "tileflow-nautical-routes",
|
|
@@ -14144,7 +14920,9 @@ var nauticalPhysicalBases = Object.freeze({
|
|
|
14144
14920
|
function nauticalPhysicalLayerId(semanticKey) {
|
|
14145
14921
|
const direct = nauticalPhysicalBases[semanticKey];
|
|
14146
14922
|
if (direct) return direct;
|
|
14147
|
-
const match3 = /^(nautical\.[A-Za-z0-9_.-]+)\.(fill|outline|marker|symbol)$/u.exec(
|
|
14923
|
+
const match3 = /^(nautical\.[A-Za-z0-9_.-]+)\.(fill|outline|marker|symbol|lines)$/u.exec(
|
|
14924
|
+
semanticKey
|
|
14925
|
+
);
|
|
14148
14926
|
if (!match3) return void 0;
|
|
14149
14927
|
const base = nauticalPhysicalBases[match3[1]];
|
|
14150
14928
|
if (!base) return void 0;
|
|
@@ -14188,21 +14966,21 @@ function visitReferences(value, counts, visited = /* @__PURE__ */ new WeakSet())
|
|
|
14188
14966
|
}
|
|
14189
14967
|
}
|
|
14190
14968
|
function isSemanticFieldReference(value) {
|
|
14191
|
-
return
|
|
14969
|
+
return isRecord10(value) && value.kind === "tileflow-data-field";
|
|
14192
14970
|
}
|
|
14193
14971
|
function isSemanticLayerReference(value) {
|
|
14194
|
-
return
|
|
14972
|
+
return isRecord10(value) && value.kind === "tileflow-data-layer";
|
|
14195
14973
|
}
|
|
14196
14974
|
function isSemanticSourceReference(value) {
|
|
14197
|
-
return
|
|
14975
|
+
return isRecord10(value) && value.kind === "tileflow-data-source";
|
|
14198
14976
|
}
|
|
14199
14977
|
function cloneJson20(value) {
|
|
14200
14978
|
return JSON.parse(JSON.stringify(value));
|
|
14201
14979
|
}
|
|
14202
14980
|
function asRecord5(value) {
|
|
14203
|
-
return
|
|
14981
|
+
return isRecord10(value) ? value : {};
|
|
14204
14982
|
}
|
|
14205
|
-
function
|
|
14983
|
+
function isRecord10(value) {
|
|
14206
14984
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
14207
14985
|
}
|
|
14208
14986
|
|
|
@@ -14266,7 +15044,7 @@ function validateTileflowRenderSelectorConstraints(input) {
|
|
|
14266
15044
|
};
|
|
14267
15045
|
while (pending.length > 0) {
|
|
14268
15046
|
const current = pending.pop();
|
|
14269
|
-
if (!
|
|
15047
|
+
if (!isRecord11(current.selector) || typeof current.selector.kind !== "string") {
|
|
14270
15048
|
addIssue(
|
|
14271
15049
|
"invalid-selector",
|
|
14272
15050
|
"a render selector must be a semantic selector node",
|
|
@@ -14327,7 +15105,7 @@ function validateTileflowRenderSelectorConstraints(input) {
|
|
|
14327
15105
|
}
|
|
14328
15106
|
for (const [index, branch] of current.selector.branches.entries()) {
|
|
14329
15107
|
const branchPath = [...branchesPath, index];
|
|
14330
|
-
if (!
|
|
15108
|
+
if (!isRecord11(branch)) {
|
|
14331
15109
|
addIssue("invalid-selector", "match selector branch must be an object", branchPath);
|
|
14332
15110
|
continue;
|
|
14333
15111
|
}
|
|
@@ -14358,14 +15136,14 @@ function validateTileflowRenderSelectorConstraints(input) {
|
|
|
14358
15136
|
for (let index = current.selector.stops.length - 1; index >= 0; index -= 1) {
|
|
14359
15137
|
const stop = current.selector.stops[index];
|
|
14360
15138
|
const stopPath = [...stopsPath, index];
|
|
14361
|
-
if (!
|
|
15139
|
+
if (!isRecord11(stop)) {
|
|
14362
15140
|
addIssue("invalid-selector", "step selector stop must be an object", stopPath);
|
|
14363
15141
|
continue;
|
|
14364
15142
|
}
|
|
14365
15143
|
pushChild(stop.selector, current.depth + 1, [...stopPath, "selector"]);
|
|
14366
15144
|
}
|
|
14367
15145
|
for (const [index, stop] of current.selector.stops.entries()) {
|
|
14368
|
-
if (!
|
|
15146
|
+
if (!isRecord11(stop)) continue;
|
|
14369
15147
|
const zoom3 = stop.zoom;
|
|
14370
15148
|
const zoomPath = [...stopsPath, index, "zoom"];
|
|
14371
15149
|
if (typeof zoom3 !== "number" || !Number.isFinite(zoom3) || zoom3 < 0 || zoom3 > 24) {
|
|
@@ -14750,7 +15528,7 @@ function applyRendererStyle(layer, renderer, style) {
|
|
|
14750
15528
|
};
|
|
14751
15529
|
}
|
|
14752
15530
|
function lowerSelector(selector, data) {
|
|
14753
|
-
if (!
|
|
15531
|
+
if (!isRecord11(selector) || typeof selector.kind !== "string") {
|
|
14754
15532
|
throw renderStackError(
|
|
14755
15533
|
"invalid-selector",
|
|
14756
15534
|
"A render selector must be a semantic selector node."
|
|
@@ -14953,7 +15731,7 @@ function requireRenderer(value) {
|
|
|
14953
15731
|
function requirePlacement(value) {
|
|
14954
15732
|
if (typeof value === "string") {
|
|
14955
15733
|
if (tileflowBandPlacements.includes(value)) return;
|
|
14956
|
-
} else if (
|
|
15734
|
+
} else if (isRecord11(value)) {
|
|
14957
15735
|
const keys = Object.keys(value);
|
|
14958
15736
|
if (keys.length === 1 && (keys[0] === "above" || keys[0] === "below")) {
|
|
14959
15737
|
requirePortableTarget(value[keys[0]], "render placement target");
|
|
@@ -14980,7 +15758,7 @@ function validateRefinementShape(operation) {
|
|
|
14980
15758
|
validateStyle(operation.renderer, operation.style);
|
|
14981
15759
|
}
|
|
14982
15760
|
function validateStyle(renderer, style) {
|
|
14983
|
-
if (!
|
|
15761
|
+
if (!isRecord11(style)) {
|
|
14984
15762
|
throw renderStackError(
|
|
14985
15763
|
"invalid-style",
|
|
14986
15764
|
`A ${renderer} render operation requires a style object.`
|
|
@@ -15082,7 +15860,7 @@ function normalizeRequirements(requirements) {
|
|
|
15082
15860
|
return [...requirements];
|
|
15083
15861
|
}
|
|
15084
15862
|
function requireRenderStackEntries(stack) {
|
|
15085
|
-
if (!
|
|
15863
|
+
if (!isRecord11(stack)) {
|
|
15086
15864
|
throw renderStackError("invalid-stack", "A render stack must be a named operation record.");
|
|
15087
15865
|
}
|
|
15088
15866
|
const entries = Object.entries(stack);
|
|
@@ -15232,9 +16010,9 @@ function cloneJson21(value) {
|
|
|
15232
16010
|
return JSON.parse(JSON.stringify(value));
|
|
15233
16011
|
}
|
|
15234
16012
|
function asRecord6(value) {
|
|
15235
|
-
return
|
|
16013
|
+
return isRecord11(value) ? value : {};
|
|
15236
16014
|
}
|
|
15237
|
-
function
|
|
16015
|
+
function isRecord11(value) {
|
|
15238
16016
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
15239
16017
|
}
|
|
15240
16018
|
|
|
@@ -15450,6 +16228,7 @@ function isLoopbackHostname(hostname) {
|
|
|
15450
16228
|
// src/resolved-map-schema.ts
|
|
15451
16229
|
init_time_of_day();
|
|
15452
16230
|
init_time_of_day_schema();
|
|
16231
|
+
init_camera_limits();
|
|
15453
16232
|
var TileflowResolvedMapValidationError = class extends Error {
|
|
15454
16233
|
code = "CONFIG_INVALID";
|
|
15455
16234
|
messages;
|
|
@@ -16607,24 +17386,34 @@ var poiModuleSchema = z7.object({
|
|
|
16607
17386
|
var nauticalModuleSchema = z7.object({
|
|
16608
17387
|
type: z7.literal("nautical"),
|
|
16609
17388
|
aids: markerSymbolStyleSchema.optional(),
|
|
17389
|
+
animateLights: z7.boolean().optional(),
|
|
16610
17390
|
beacons: markerSymbolStyleSchema.optional(),
|
|
17391
|
+
berths: areaStyleSchema.optional(),
|
|
17392
|
+
bridges: areaStyleSchema.optional(),
|
|
16611
17393
|
buoys: markerSymbolStyleSchema.optional(),
|
|
16612
17394
|
cables: lineStyleSchema.optional(),
|
|
16613
17395
|
coverage: areaStyleSchema.optional(),
|
|
17396
|
+
distanceMarks: markerSymbolStyleSchema.optional(),
|
|
16614
17397
|
enabled: z7.boolean().optional(),
|
|
17398
|
+
facilities: markerSymbolStyleSchema.optional(),
|
|
17399
|
+
harbourAreas: areaStyleSchema.optional(),
|
|
16615
17400
|
harbours: markerSymbolStyleSchema.optional(),
|
|
16616
17401
|
hazardAreas: areaStyleSchema.optional(),
|
|
16617
17402
|
hazards: markerSymbolStyleSchema.optional(),
|
|
16618
17403
|
labels: z7.object({
|
|
17404
|
+
bridges: symbolStyleSchema.optional(),
|
|
16619
17405
|
coverage: symbolStyleSchema.optional(),
|
|
16620
17406
|
hazards: symbolStyleSchema.optional(),
|
|
16621
17407
|
navigationAreas: symbolStyleSchema.optional(),
|
|
17408
|
+
overheadCables: symbolStyleSchema.optional(),
|
|
16622
17409
|
reefs: symbolStyleSchema.optional(),
|
|
16623
17410
|
wrecks: symbolStyleSchema.optional()
|
|
16624
17411
|
}).strict().optional(),
|
|
16625
17412
|
lighthouses: markerSymbolStyleSchema.optional(),
|
|
16626
17413
|
lights: markerSymbolStyleSchema.optional(),
|
|
16627
17414
|
navigationAreas: areaStyleSchema.optional(),
|
|
17415
|
+
notices: markerSymbolStyleSchema.optional(),
|
|
17416
|
+
overheadCables: lineStyleSchema.optional(),
|
|
16628
17417
|
ports: markerSymbolStyleSchema.optional(),
|
|
16629
17418
|
reefs: areaStyleSchema.optional(),
|
|
16630
17419
|
renderStack: renderStackSchema.optional(),
|
|
@@ -17157,7 +17946,7 @@ var terrainContoursSchema = z7.object({
|
|
|
17157
17946
|
demUrl: z7.string().min(1).max(2048).refine(
|
|
17158
17947
|
isSafeTileflowDemUrlTemplate,
|
|
17159
17948
|
"Expected a safe HTTP(S) DEM URL template containing {z}, {x}, and {y}"
|
|
17160
|
-
),
|
|
17949
|
+
).optional(),
|
|
17161
17950
|
index: terrainContourLineSchema.optional(),
|
|
17162
17951
|
labels: terrainContourLabelSchema.optional(),
|
|
17163
17952
|
maxZoom: z7.number().int().min(0).max(24).optional(),
|
|
@@ -17281,10 +18070,25 @@ var atmosphereSchema = z7.union([
|
|
|
17281
18070
|
starParallax: z7.number().finite().min(0).max(1).optional()
|
|
17282
18071
|
}).strict()
|
|
17283
18072
|
]);
|
|
18073
|
+
var skyNumberSchema = z7.union([
|
|
18074
|
+
z7.number().finite().min(0).max(1),
|
|
18075
|
+
fixedNumberSchema.extend({ value: z7.number().finite().min(0).max(1) }),
|
|
18076
|
+
themeNumberReferenceSchema
|
|
18077
|
+
]);
|
|
18078
|
+
var skySchema = z7.union([
|
|
18079
|
+
z7.boolean(),
|
|
18080
|
+
z7.object({
|
|
18081
|
+
color: atmosphereColorSchema.optional(),
|
|
18082
|
+
horizonColor: atmosphereColorSchema.optional(),
|
|
18083
|
+
horizonBlend: skyNumberSchema.optional(),
|
|
18084
|
+
glowColor: atmosphereColorSchema.optional(),
|
|
18085
|
+
starIntensity: skyNumberSchema.optional()
|
|
18086
|
+
}).strict()
|
|
18087
|
+
]);
|
|
17284
18088
|
var viewSchema = z7.object({
|
|
17285
18089
|
bearing: z7.number().finite().min(-180).max(180).optional(),
|
|
17286
18090
|
center: z7.tuple([z7.number().finite().min(-180).max(180), z7.number().finite().min(-90).max(90)]).optional(),
|
|
17287
|
-
pitch: z7.number().finite().min(0).max(
|
|
18091
|
+
pitch: z7.number().finite().min(0).max(tileflowMaxPitch).optional(),
|
|
17288
18092
|
zoom: zoomNumberSchema.optional()
|
|
17289
18093
|
}).strict();
|
|
17290
18094
|
var themesSchema = z7.record(tileflowThemeNameSchema, tileflowThemeSchema).superRefine((themes, context) => {
|
|
@@ -17327,6 +18131,7 @@ var resolvedTileflowMapSchema = z7.object({
|
|
|
17327
18131
|
name: z7.string().trim().min(1),
|
|
17328
18132
|
overlays: overlaysSchema.optional(),
|
|
17329
18133
|
projection: z7.enum(["globe", "mercator"]).optional(),
|
|
18134
|
+
sky: skySchema.optional(),
|
|
17330
18135
|
sources: hostedSourcesSchema.optional(),
|
|
17331
18136
|
systemThemes: systemThemesSchema.optional(),
|
|
17332
18137
|
terrain: terrainSchema.optional(),
|
|
@@ -17640,7 +18445,7 @@ function resolveTerrain(terrain, apiBaseUrl) {
|
|
|
17640
18445
|
const mode = terrainConfig.mode ?? "hillshade";
|
|
17641
18446
|
const encoding = terrainConfig.encoding ?? "terrarium";
|
|
17642
18447
|
const raster = mode === "none" ? void 0 : resolveRaster(terrainConfig, apiBaseUrl, encoding);
|
|
17643
|
-
const contours = terrainConfig.contours ? resolveContours(terrainConfig.contours, encoding, terrainConfig.attribution) : void 0;
|
|
18448
|
+
const contours = terrainConfig.contours ? resolveContours(terrainConfig.contours, encoding, terrainConfig.attribution, apiBaseUrl) : void 0;
|
|
17644
18449
|
if (!raster && !contours) return void 0;
|
|
17645
18450
|
return {
|
|
17646
18451
|
...contours ? { contours } : {},
|
|
@@ -17772,7 +18577,7 @@ function resolveRaster(terrain, apiBaseUrl, encoding) {
|
|
|
17772
18577
|
}
|
|
17773
18578
|
};
|
|
17774
18579
|
}
|
|
17775
|
-
function resolveContours(contours, encoding, attribution) {
|
|
18580
|
+
function resolveContours(contours, encoding, attribution, apiBaseUrl) {
|
|
17776
18581
|
const thresholdZooms = Object.keys(contours.thresholds).map(Number);
|
|
17777
18582
|
const minimumZoom2 = contours.minZoom ?? Math.min(...thresholdZooms);
|
|
17778
18583
|
const maximumZoom2 = contours.maxZoom ?? Math.max(...thresholdZooms);
|
|
@@ -17780,7 +18585,7 @@ function resolveContours(contours, encoding, attribution) {
|
|
|
17780
18585
|
const tiles = [
|
|
17781
18586
|
createTileflowContourProtocolUrl({
|
|
17782
18587
|
demMaxzoom: contours.demMaxZoom,
|
|
17783
|
-
demUrl: contours.demUrl
|
|
18588
|
+
demUrl: contours.demUrl ?? `${apiBaseUrl}/tiles/terrain/{z}/{x}/{y}.webp`,
|
|
17784
18589
|
encoding,
|
|
17785
18590
|
maxzoom: maximumZoom2,
|
|
17786
18591
|
multiplier: contours.multiplier ?? 1,
|
|
@@ -18438,11 +19243,11 @@ function isTileflowPoiCategory(value) {
|
|
|
18438
19243
|
return typeof value === "string" && tileflowPoiCategories.includes(value);
|
|
18439
19244
|
}
|
|
18440
19245
|
function semanticTarget(layer) {
|
|
18441
|
-
if (!
|
|
19246
|
+
if (!isRecord12(layer.metadata)) return void 0;
|
|
18442
19247
|
const value = layer.metadata[tileflowCompilerMetadataKeys.target];
|
|
18443
19248
|
return typeof value === "string" ? value : void 0;
|
|
18444
19249
|
}
|
|
18445
|
-
function
|
|
19250
|
+
function isRecord12(value) {
|
|
18446
19251
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
18447
19252
|
}
|
|
18448
19253
|
function isSafeArtifactName(value) {
|
|
@@ -18886,8 +19691,8 @@ function consolidateFillFamily(layers2, group, mergedId) {
|
|
|
18886
19691
|
}
|
|
18887
19692
|
const replacements = /* @__PURE__ */ new Map();
|
|
18888
19693
|
let suffix = 0;
|
|
18889
|
-
for (const
|
|
18890
|
-
for (const group2 of contiguousRuns(
|
|
19694
|
+
for (const grouped2 of groups.values()) {
|
|
19695
|
+
for (const group2 of contiguousRuns(grouped2)) {
|
|
18891
19696
|
if (group2.length < 2) continue;
|
|
18892
19697
|
const first = group2[0].layer;
|
|
18893
19698
|
if (!group2.every(({ layer }) => sameTopLevelProperties(layer, first))) continue;
|
|
@@ -19342,7 +20147,7 @@ var colourSources = [
|
|
|
19342
20147
|
["tileflow-buildings-fill", "fill-color"]
|
|
19343
20148
|
];
|
|
19344
20149
|
function tileflowBuildings3DDesignOf(module, context, layers2, buildingModels, tileflowLandmarks) {
|
|
19345
|
-
const config =
|
|
20150
|
+
const config = isRecord13(module) ? module : {};
|
|
19346
20151
|
if (config.enabled === false) return void 0;
|
|
19347
20152
|
const style = config.threeDimensional ?? {};
|
|
19348
20153
|
const defaults4 = tileflowDefaultBuildings3DDesign;
|
|
@@ -19375,7 +20180,7 @@ function tileflowBuildings3DDesignOf(module, context, layers2, buildingModels, t
|
|
|
19375
20180
|
edgeRadius: number(style.edgeRadius, defaults4.edgeRadius),
|
|
19376
20181
|
...typeof edgeColor === "string" ? { edgeColor } : {},
|
|
19377
20182
|
nightLight: number(style.nightLight, 0),
|
|
19378
|
-
...
|
|
20183
|
+
...isRecord13(style.floodLight) ? {
|
|
19379
20184
|
floodLight: readBuildingFloodLight({
|
|
19380
20185
|
...style.floodLight,
|
|
19381
20186
|
intensity: number(style.floodLight.intensity, 0),
|
|
@@ -19383,10 +20188,10 @@ function tileflowBuildings3DDesignOf(module, context, layers2, buildingModels, t
|
|
|
19383
20188
|
color: style.floodLight.color === void 0 ? void 0 : toMapLibreStyleValue(style.floodLight.color)
|
|
19384
20189
|
})
|
|
19385
20190
|
} : {},
|
|
19386
|
-
...
|
|
20191
|
+
...isRecord13(style.modelLighting) ? {
|
|
19387
20192
|
modelLighting: readModelRoleLighting(
|
|
19388
20193
|
Object.fromEntries(
|
|
19389
|
-
Object.entries(style.modelLighting).filter(([, entry]) =>
|
|
20194
|
+
Object.entries(style.modelLighting).filter(([, entry]) => isRecord13(entry)).map(([role, entry]) => {
|
|
19390
20195
|
const own = entry;
|
|
19391
20196
|
return [
|
|
19392
20197
|
role,
|
|
@@ -19397,7 +20202,7 @@ function tileflowBuildings3DDesignOf(module, context, layers2, buildingModels, t
|
|
|
19397
20202
|
["emissiveVariation", "colorMix", "metallic", "roughness"].filter((key) => own[key] !== void 0).map((key) => [key, number(own[key], 0)])
|
|
19398
20203
|
),
|
|
19399
20204
|
...Array.isArray(own.emissiveHeight) ? { emissiveHeight: own.emissiveHeight.map((v) => number(v, 0)) } : {},
|
|
19400
|
-
...
|
|
20205
|
+
...isRecord13(own.colorVariation) ? {
|
|
19401
20206
|
colorVariation: {
|
|
19402
20207
|
...own.colorVariation,
|
|
19403
20208
|
...Object.fromEntries(
|
|
@@ -19430,7 +20235,7 @@ function tileflowBuildings3DDesignOf(module, context, layers2, buildingModels, t
|
|
|
19430
20235
|
}
|
|
19431
20236
|
function landmarksOf2(value, tileflowLandmarks) {
|
|
19432
20237
|
if (value === false) return {};
|
|
19433
|
-
if (
|
|
20238
|
+
if (isRecord13(value) && typeof value.url === "string") return { landmarks: { url: value.url } };
|
|
19434
20239
|
return tileflowLandmarks ? { landmarks: { url: tileflowLandmarks } } : {};
|
|
19435
20240
|
}
|
|
19436
20241
|
function placedModels(value, served) {
|
|
@@ -19457,7 +20262,7 @@ function placedModels(value, served) {
|
|
|
19457
20262
|
};
|
|
19458
20263
|
}
|
|
19459
20264
|
function modelColours(value) {
|
|
19460
|
-
if (!
|
|
20265
|
+
if (!isRecord13(value)) return {};
|
|
19461
20266
|
const colours = {};
|
|
19462
20267
|
for (const [part, colour] of Object.entries(value)) {
|
|
19463
20268
|
const resolved = colour === void 0 ? void 0 : toMapLibreStyleValue(colour);
|
|
@@ -19466,7 +20271,7 @@ function modelColours(value) {
|
|
|
19466
20271
|
return Object.keys(colours).length > 0 ? { modelColors: colours } : {};
|
|
19467
20272
|
}
|
|
19468
20273
|
function tileflowStreetLightsDesignOf(module, context) {
|
|
19469
|
-
const config =
|
|
20274
|
+
const config = isRecord13(module) ? module : {};
|
|
19470
20275
|
const layers2 = context.data.schema.layers;
|
|
19471
20276
|
const style = config.streetLights ?? {};
|
|
19472
20277
|
if (config.enabled === false || style.enabled !== true || !layers2.streetFurniture)
|
|
@@ -19486,7 +20291,7 @@ function tileflowStreetLightsDesignOf(module, context) {
|
|
|
19486
20291
|
intensity: typeof intensity === "number" ? intensity : 1
|
|
19487
20292
|
};
|
|
19488
20293
|
}
|
|
19489
|
-
function
|
|
20294
|
+
function isRecord13(value) {
|
|
19490
20295
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19491
20296
|
}
|
|
19492
20297
|
|
|
@@ -19677,7 +20482,7 @@ function compileSemanticStyleInternal(input, options, inspect, onReport) {
|
|
|
19677
20482
|
)
|
|
19678
20483
|
);
|
|
19679
20484
|
const renderStackModules = Object.values(modules).filter(
|
|
19680
|
-
(module) =>
|
|
20485
|
+
(module) => isRecord14(module) && module.enabled !== false && "renderStack" in module && isRecord14(module.renderStack)
|
|
19681
20486
|
);
|
|
19682
20487
|
const renderOperations = runCompilationPhase(
|
|
19683
20488
|
"render-stack",
|
|
@@ -19923,9 +20728,15 @@ function compileSemanticStyleInternal(input, options, inspect, onReport) {
|
|
|
19923
20728
|
layer.layout = { ...layer.layout, visibility: "none" };
|
|
19924
20729
|
}
|
|
19925
20730
|
const atmosphere = resolveTileflowAtmosphere(config.atmosphere);
|
|
20731
|
+
const sky = resolveTileflowSky(config.sky);
|
|
19926
20732
|
const notices = compiledNotices(layers2, marine);
|
|
20733
|
+
const nauticalLights = declareTileflowNauticalLights(
|
|
20734
|
+
layers2,
|
|
20735
|
+
marine?.nautical?.sourceId,
|
|
20736
|
+
tileflowNauticalV1Schema.layers.lights
|
|
20737
|
+
);
|
|
19927
20738
|
const style = {
|
|
19928
|
-
...atmosphere ? { sky: compileTileflowSky(atmosphere) } : {},
|
|
20739
|
+
...sky ? { sky: compileTileflowStreetSky(sky) } : atmosphere ? { sky: compileTileflowSky(atmosphere) } : {},
|
|
19929
20740
|
version: 8,
|
|
19930
20741
|
name: config.name ?? "Streets",
|
|
19931
20742
|
...glyphs ? { glyphs } : {},
|
|
@@ -19944,6 +20755,7 @@ function compileSemanticStyleInternal(input, options, inspect, onReport) {
|
|
|
19944
20755
|
...mapMetadata.lineage && mapMetadata.lineage.length > 1 ? { "tileflow:extends": mapMetadata.lineage.slice(1) } : {}
|
|
19945
20756
|
} : {},
|
|
19946
20757
|
...atmosphere ? { [tileflowAtmosphereMetadataKey]: { version: 1, ...atmosphere } } : {},
|
|
20758
|
+
...sky ? { [tileflowSkyMetadataKey]: skyMetadata(input, selected.name, sky) } : {},
|
|
19947
20759
|
"tileflow:theme": selected.name,
|
|
19948
20760
|
"tileflow:colorScheme": resolvedTheme.colorScheme,
|
|
19949
20761
|
[tileflowRouteMetadataKey]: tileflowRouteMetadata(resolveTileflowRouteInks(resolvedTheme)),
|
|
@@ -19972,9 +20784,10 @@ function compileSemanticStyleInternal(input, options, inspect, onReport) {
|
|
|
19972
20784
|
"tileflow:sourceRequirements": sourceRequirements,
|
|
19973
20785
|
...interactionManifest ? { [tileflowInteractionManifestMetadataKey]: interactionManifest } : {},
|
|
19974
20786
|
[tileflowOverlayPlacementManifestMetadataKey]: overlayPlacementManifest,
|
|
19975
|
-
"tileflow:modules": Object.entries(modules).filter(([, module]) => !
|
|
20787
|
+
"tileflow:modules": Object.entries(modules).filter(([, module]) => !isRecord14(module) || module.enabled !== false).map(([name]) => name).sort(),
|
|
19976
20788
|
...config.view ? { "tileflow:view": config.view } : {},
|
|
19977
|
-
...notices.length > 0 ? { [tileflowNoticesMetadataKey]: notices } : {}
|
|
20789
|
+
...notices.length > 0 ? { [tileflowNoticesMetadataKey]: notices } : {},
|
|
20790
|
+
...nauticalLights ? { [tileflowNauticalLightsMetadataKey]: nauticalLights } : {}
|
|
19978
20791
|
}
|
|
19979
20792
|
};
|
|
19980
20793
|
const report = {
|
|
@@ -20034,7 +20847,7 @@ function finalizeTileflowLayers(input) {
|
|
|
20034
20847
|
if (typeof minimum2 === "number" && typeof maximum2 === "number" && minimum2 > maximum2) {
|
|
20035
20848
|
throw new Error(`Compiled Tileflow layer ${id2} requires minzoom <= maxzoom.`);
|
|
20036
20849
|
}
|
|
20037
|
-
const metadata =
|
|
20850
|
+
const metadata = isRecord14(layer.metadata) ? { ...layer.metadata } : void 0;
|
|
20038
20851
|
if (metadata) {
|
|
20039
20852
|
const owner = metadata[tileflowCompilerMetadataKeys.owner];
|
|
20040
20853
|
delete metadata[tileflowCompilerProvenanceMetadataKey];
|
|
@@ -20068,7 +20881,7 @@ function assertMapLibreStyle(style, mapId) {
|
|
|
20068
20881
|
}
|
|
20069
20882
|
);
|
|
20070
20883
|
}
|
|
20071
|
-
function
|
|
20884
|
+
function isRecord14(value) {
|
|
20072
20885
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
20073
20886
|
}
|
|
20074
20887
|
function compiledNotices(layers2, marine) {
|
|
@@ -20113,8 +20926,8 @@ function assertPreparedIconReferences(style, config, prepared) {
|
|
|
20113
20926
|
function collectStyleImageReferences(style) {
|
|
20114
20927
|
const result = /* @__PURE__ */ new Set();
|
|
20115
20928
|
for (const layer of style.layers) {
|
|
20116
|
-
const layout =
|
|
20117
|
-
const paint =
|
|
20929
|
+
const layout = isRecord14(layer.layout) ? layer.layout : {};
|
|
20930
|
+
const paint = isRecord14(layer.paint) ? layer.paint : {};
|
|
20118
20931
|
const layerId = typeof layer.id === "string" ? layer.id : "<unknown>";
|
|
20119
20932
|
for (const [property, value] of [
|
|
20120
20933
|
["icon-image", layout["icon-image"]],
|
|
@@ -20203,7 +21016,7 @@ function assertGlyphFontStacks(style, config) {
|
|
|
20203
21016
|
const declared = new Set(config.glyphs.fontStacks);
|
|
20204
21017
|
const missing = /* @__PURE__ */ new Set();
|
|
20205
21018
|
for (const layer of style.layers) {
|
|
20206
|
-
const layout =
|
|
21019
|
+
const layout = isRecord14(layer.layout) ? layer.layout : void 0;
|
|
20207
21020
|
const font = layout?.["text-font"];
|
|
20208
21021
|
if (!Array.isArray(font) || !font.every((entry) => typeof entry === "string")) continue;
|
|
20209
21022
|
const stack = font.join(",");
|
|
@@ -20219,7 +21032,7 @@ function assertGlyphFontStacks(style, config) {
|
|
|
20219
21032
|
function assertTextAssets(style, config) {
|
|
20220
21033
|
const textLayers = [];
|
|
20221
21034
|
for (const layer of style.layers) {
|
|
20222
|
-
const layout =
|
|
21035
|
+
const layout = isRecord14(layer.layout) ? layer.layout : void 0;
|
|
20223
21036
|
if (layout?.["text-field"] === void 0) continue;
|
|
20224
21037
|
textLayers.push(typeof layer.id === "string" ? layer.id : "<unknown>");
|
|
20225
21038
|
const font = layout["text-font"];
|
|
@@ -20232,7 +21045,7 @@ function assertTextAssets(style, config) {
|
|
|
20232
21045
|
if (textLayers.length === 0) return;
|
|
20233
21046
|
if (config.fonts !== void 0) {
|
|
20234
21047
|
const backed = style.layers.find((layer) => {
|
|
20235
|
-
const font =
|
|
21048
|
+
const font = isRecord14(layer.layout) ? layer.layout["text-font"] : void 0;
|
|
20236
21049
|
return Array.isArray(font) && font.length === 1 && typeof font[0] === "string" && parseTileflowLineBackgroundFontStack(font[0]) !== void 0;
|
|
20237
21050
|
});
|
|
20238
21051
|
if (backed) {
|
|
@@ -20258,7 +21071,7 @@ function runCompilationPhase(phase, operation) {
|
|
|
20258
21071
|
}
|
|
20259
21072
|
}
|
|
20260
21073
|
function withCompilationPhase(error, phase) {
|
|
20261
|
-
const record3 =
|
|
21074
|
+
const record3 = isRecord14(error) ? error : {};
|
|
20262
21075
|
if (typeof record3.phase === "string") return error;
|
|
20263
21076
|
if (error instanceof Error && Object.isExtensible(error)) {
|
|
20264
21077
|
Object.defineProperty(error, "phase", { configurable: true, enumerable: true, value: phase });
|
|
@@ -20289,6 +21102,35 @@ function compareCodeUnits7(left, right) {
|
|
|
20289
21102
|
function semanticReportKey(...parts) {
|
|
20290
21103
|
return parts.join("\0");
|
|
20291
21104
|
}
|
|
21105
|
+
function skyMetadata(input, themeName, sky) {
|
|
21106
|
+
const family = Object.values(input.timeOfDay ?? {}).find(
|
|
21107
|
+
(moments) => Object.values(moments).includes(themeName)
|
|
21108
|
+
);
|
|
21109
|
+
const colours = (name) => {
|
|
21110
|
+
const theme = name === void 0 ? void 0 : input.themes[name];
|
|
21111
|
+
if (!theme) return void 0;
|
|
21112
|
+
const resolved = resolveTileflowSky(
|
|
21113
|
+
resolveThemeValues({ sky: input.sky }, theme, `map.${input.id}.themes.${name}`).sky
|
|
21114
|
+
);
|
|
21115
|
+
return resolved ? {
|
|
21116
|
+
color: resolved.color,
|
|
21117
|
+
horizonColor: resolved.horizonColor,
|
|
21118
|
+
horizonBlend: resolved.horizonBlend,
|
|
21119
|
+
glowColor: resolved.glowColor
|
|
21120
|
+
} : void 0;
|
|
21121
|
+
};
|
|
21122
|
+
const day = colours(family?.day);
|
|
21123
|
+
const night = colours(family?.night);
|
|
21124
|
+
const dawn = colours(family?.dawn);
|
|
21125
|
+
const dusk = colours(family?.dusk);
|
|
21126
|
+
const timesOfDay = day && night && (dawn ?? dusk) ? { day, night, dawn: dawn ?? dusk, dusk: dusk ?? dawn } : void 0;
|
|
21127
|
+
return {
|
|
21128
|
+
version: 1,
|
|
21129
|
+
starIntensity: sky.starIntensity,
|
|
21130
|
+
glowColor: sky.glowColor,
|
|
21131
|
+
...timesOfDay ? { timesOfDay } : {}
|
|
21132
|
+
};
|
|
21133
|
+
}
|
|
20292
21134
|
|
|
20293
21135
|
// src/maps/define.ts
|
|
20294
21136
|
function defineMap(map) {
|
|
@@ -20331,6 +21173,7 @@ var tileflowMapMergeStrategies = {
|
|
|
20331
21173
|
projection: "atomic",
|
|
20332
21174
|
scenes: "leaf",
|
|
20333
21175
|
shots: "leaf",
|
|
21176
|
+
sky: "atomic",
|
|
20334
21177
|
sources: "keyed-resources",
|
|
20335
21178
|
systemThemes: "atomic",
|
|
20336
21179
|
terrain: "atomic",
|
|
@@ -20677,11 +21520,11 @@ function cloneDesign(value) {
|
|
|
20677
21520
|
function describeMap(value) {
|
|
20678
21521
|
return typeof value.id === "string" && value.id ? value.id : "<anonymous>";
|
|
20679
21522
|
}
|
|
20680
|
-
function
|
|
21523
|
+
function isRecord15(value) {
|
|
20681
21524
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
20682
21525
|
}
|
|
20683
21526
|
function isPlainRecord4(value) {
|
|
20684
|
-
if (!
|
|
21527
|
+
if (!isRecord15(value)) return false;
|
|
20685
21528
|
const prototype = Object.getPrototypeOf(value);
|
|
20686
21529
|
return prototype === Object.prototype || prototype === null;
|
|
20687
21530
|
}
|
|
@@ -21451,7 +22294,7 @@ function semanticDesign(map) {
|
|
|
21451
22294
|
}
|
|
21452
22295
|
function compareValues(before, after, path, output) {
|
|
21453
22296
|
if (Object.is(before, after)) return;
|
|
21454
|
-
if (
|
|
22297
|
+
if (isRecord16(before) && isRecord16(after)) {
|
|
21455
22298
|
const keys = [.../* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(after)])].sort(
|
|
21456
22299
|
compareCodeUnits9
|
|
21457
22300
|
);
|
|
@@ -21493,7 +22336,7 @@ function toSemanticValue(value, path) {
|
|
|
21493
22336
|
}
|
|
21494
22337
|
throw new TypeError(`Tileflow semantic value at ${path || "/"} is not JSON-serializable.`);
|
|
21495
22338
|
}
|
|
21496
|
-
function
|
|
22339
|
+
function isRecord16(value) {
|
|
21497
22340
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
21498
22341
|
}
|
|
21499
22342
|
function isUnknownRecord(value) {
|
|
@@ -21506,7 +22349,7 @@ function deepEqual(left, right) {
|
|
|
21506
22349
|
if (Array.isArray(left) || Array.isArray(right)) {
|
|
21507
22350
|
return Array.isArray(left) && Array.isArray(right) && left.length === right.length && left.every((value, index) => deepEqual(value, right[index]));
|
|
21508
22351
|
}
|
|
21509
|
-
if (!
|
|
22352
|
+
if (!isRecord16(left) || !isRecord16(right)) return false;
|
|
21510
22353
|
const leftKeys = Object.keys(left).sort(compareCodeUnits9);
|
|
21511
22354
|
const rightKeys = Object.keys(right).sort(compareCodeUnits9);
|
|
21512
22355
|
return leftKeys.length === rightKeys.length && leftKeys.every((key, index) => key === rightKeys[index] && deepEqual(left[key], right[key]));
|
|
@@ -21813,6 +22656,394 @@ function isClassTier(value) {
|
|
|
21813
22656
|
return tileflowBoundaryClassTiers.includes(value);
|
|
21814
22657
|
}
|
|
21815
22658
|
|
|
22659
|
+
// src/nautical-light-rhythm.ts
|
|
22660
|
+
var tileflowLightRhythmConventions = Object.freeze({
|
|
22661
|
+
cardinalPeriods: Object.freeze({
|
|
22662
|
+
Q: Object.freeze({ 3: 10, 6: 15, 9: 15 }),
|
|
22663
|
+
"Q+LFl": 15,
|
|
22664
|
+
VQ: Object.freeze({ 3: 5, 6: 10, 9: 10 }),
|
|
22665
|
+
"VQ+LFl": 10
|
|
22666
|
+
}),
|
|
22667
|
+
fixedIntensity: 0.5,
|
|
22668
|
+
flash: 1,
|
|
22669
|
+
flashShare: 0.3,
|
|
22670
|
+
interruptedShare: 0.6,
|
|
22671
|
+
longFlash: 2,
|
|
22672
|
+
morseUnit: 0.5,
|
|
22673
|
+
occultingShare: 0.25,
|
|
22674
|
+
quickCycle: Object.freeze({ Q: 1, UQ: 0.25, VQ: 0.5 }),
|
|
22675
|
+
quickDuty: 0.3
|
|
22676
|
+
});
|
|
22677
|
+
var tileflowLightRhythmLimits = Object.freeze({
|
|
22678
|
+
maxPeriod: 600,
|
|
22679
|
+
maxPhases: 256,
|
|
22680
|
+
maxSequenceLength: 512,
|
|
22681
|
+
minPhase: 0.05
|
|
22682
|
+
});
|
|
22683
|
+
var conventions = tileflowLightRhythmConventions;
|
|
22684
|
+
var limits = tileflowLightRhythmLimits;
|
|
22685
|
+
var lit = 1;
|
|
22686
|
+
var eclipsed = 0;
|
|
22687
|
+
var morse = Object.freeze({
|
|
22688
|
+
A: ".-",
|
|
22689
|
+
B: "-...",
|
|
22690
|
+
C: "-.-.",
|
|
22691
|
+
D: "-..",
|
|
22692
|
+
E: ".",
|
|
22693
|
+
F: "..-.",
|
|
22694
|
+
G: "--.",
|
|
22695
|
+
H: "....",
|
|
22696
|
+
I: "..",
|
|
22697
|
+
J: ".---",
|
|
22698
|
+
K: "-.-",
|
|
22699
|
+
L: ".-..",
|
|
22700
|
+
M: "--",
|
|
22701
|
+
N: "-.",
|
|
22702
|
+
O: "---",
|
|
22703
|
+
P: ".--.",
|
|
22704
|
+
Q: "--.-",
|
|
22705
|
+
R: ".-.",
|
|
22706
|
+
S: "...",
|
|
22707
|
+
T: "-",
|
|
22708
|
+
U: "..-",
|
|
22709
|
+
V: "...-",
|
|
22710
|
+
W: ".--",
|
|
22711
|
+
X: "-..-",
|
|
22712
|
+
Y: "-.--",
|
|
22713
|
+
Z: "--..",
|
|
22714
|
+
0: "-----",
|
|
22715
|
+
1: ".----",
|
|
22716
|
+
2: "..---",
|
|
22717
|
+
3: "...--",
|
|
22718
|
+
4: "....-",
|
|
22719
|
+
5: ".....",
|
|
22720
|
+
6: "-....",
|
|
22721
|
+
7: "--...",
|
|
22722
|
+
8: "---..",
|
|
22723
|
+
9: "----."
|
|
22724
|
+
});
|
|
22725
|
+
function tileflowLightRhythm(light) {
|
|
22726
|
+
const character = typeof light.character === "string" ? light.character.trim() : "";
|
|
22727
|
+
const alternating = /^Al(?:\.|$)/u.test(character);
|
|
22728
|
+
const base = alternating ? character.slice(3) : character;
|
|
22729
|
+
const fixedPart = base === "FFl" || base === "F+LFl";
|
|
22730
|
+
const period = positiveNumber(light.period_s);
|
|
22731
|
+
const colours = colourCount(light.color);
|
|
22732
|
+
let phases = parseSequence(light.sequence, fixedPart);
|
|
22733
|
+
if (!phases) {
|
|
22734
|
+
phases = alternating && (base === "" || base === "F") ? alternatingFixed(colours, period) : derivePhases(base, groupText(light.group), period);
|
|
22735
|
+
}
|
|
22736
|
+
if (!phases) return void 0;
|
|
22737
|
+
if (alternating && colours > 1) phases = alternateColours(phases, colours);
|
|
22738
|
+
return finish(phases);
|
|
22739
|
+
}
|
|
22740
|
+
function tileflowLightStateAt(rhythm, seconds) {
|
|
22741
|
+
const periodMs = Math.round(rhythm.period * 1e3);
|
|
22742
|
+
const timeMs = Number.isFinite(seconds) ? Math.floor(seconds * 1e3) : 0;
|
|
22743
|
+
const offset = (timeMs % periodMs + periodMs) % periodMs;
|
|
22744
|
+
let end = 0;
|
|
22745
|
+
for (const phase of rhythm.phases) {
|
|
22746
|
+
end += Math.round(phase.duration * 1e3);
|
|
22747
|
+
if (offset < end) {
|
|
22748
|
+
return { colour: phase.colour, intensity: phase.intensity, remaining: (end - offset) / 1e3 };
|
|
22749
|
+
}
|
|
22750
|
+
}
|
|
22751
|
+
const first = rhythm.phases[0];
|
|
22752
|
+
return { colour: first.colour, intensity: first.intensity, remaining: first.duration };
|
|
22753
|
+
}
|
|
22754
|
+
function parseSequence(value, fixedPart) {
|
|
22755
|
+
if (typeof value !== "string") return void 0;
|
|
22756
|
+
const text = value.trim();
|
|
22757
|
+
if (!text || text.length > limits.maxSequenceLength) return void 0;
|
|
22758
|
+
const phases = [];
|
|
22759
|
+
for (const token2 of text.split("+")) {
|
|
22760
|
+
const match3 = /^\s*(\()?\s*(\d+(?:\.\d+)?|\.\d+)\s*(\))?\s*$/u.exec(token2);
|
|
22761
|
+
if (!match3 || Boolean(match3[1]) !== Boolean(match3[3])) return void 0;
|
|
22762
|
+
const duration = Number(match3[2]);
|
|
22763
|
+
if (!(duration > 0)) return void 0;
|
|
22764
|
+
const intensity = match3[1] ? fixedPart ? conventions.fixedIntensity : eclipsed : lit;
|
|
22765
|
+
phases.push({ colour: 0, duration, intensity });
|
|
22766
|
+
}
|
|
22767
|
+
if (!phases.some(({ intensity }) => intensity === lit)) return void 0;
|
|
22768
|
+
if (!phases.some(({ intensity }) => intensity !== lit)) return void 0;
|
|
22769
|
+
return phases;
|
|
22770
|
+
}
|
|
22771
|
+
function derivePhases(character, group, period) {
|
|
22772
|
+
switch (character) {
|
|
22773
|
+
case "Fl":
|
|
22774
|
+
return grouped(
|
|
22775
|
+
groupCounts(group),
|
|
22776
|
+
period,
|
|
22777
|
+
flashOf(groupCounts(group), period),
|
|
22778
|
+
lit,
|
|
22779
|
+
eclipsed
|
|
22780
|
+
);
|
|
22781
|
+
case "LFl":
|
|
22782
|
+
return grouped(
|
|
22783
|
+
groupCounts(group),
|
|
22784
|
+
period,
|
|
22785
|
+
longFlashOf(groupCounts(group), period),
|
|
22786
|
+
lit,
|
|
22787
|
+
eclipsed
|
|
22788
|
+
);
|
|
22789
|
+
case "FFl":
|
|
22790
|
+
return grouped(
|
|
22791
|
+
groupCounts(group),
|
|
22792
|
+
period,
|
|
22793
|
+
flashOf(groupCounts(group), period),
|
|
22794
|
+
lit,
|
|
22795
|
+
conventions.fixedIntensity
|
|
22796
|
+
);
|
|
22797
|
+
case "F+LFl":
|
|
22798
|
+
return grouped(
|
|
22799
|
+
groupCounts(group),
|
|
22800
|
+
period,
|
|
22801
|
+
longFlashOf(groupCounts(group), period),
|
|
22802
|
+
lit,
|
|
22803
|
+
conventions.fixedIntensity
|
|
22804
|
+
);
|
|
22805
|
+
case "Oc":
|
|
22806
|
+
case "Oc+Fl": {
|
|
22807
|
+
const counts = groupCounts(group);
|
|
22808
|
+
if (!counts || !period) return void 0;
|
|
22809
|
+
const eclipse = conventions.occultingShare * period / sum(counts);
|
|
22810
|
+
return grouped(counts, period, eclipse, eclipsed, lit);
|
|
22811
|
+
}
|
|
22812
|
+
case "Iso":
|
|
22813
|
+
return period ? [
|
|
22814
|
+
{ colour: 0, duration: period / 2, intensity: lit },
|
|
22815
|
+
{ colour: 0, duration: period / 2, intensity: eclipsed }
|
|
22816
|
+
] : void 0;
|
|
22817
|
+
case "Q":
|
|
22818
|
+
case "VQ":
|
|
22819
|
+
case "UQ":
|
|
22820
|
+
return quick(character, group, period);
|
|
22821
|
+
case "IQ":
|
|
22822
|
+
case "IVQ":
|
|
22823
|
+
case "IUQ":
|
|
22824
|
+
return interruptedQuick(character.slice(1), period);
|
|
22825
|
+
case "Mo":
|
|
22826
|
+
return morseCode(group, period);
|
|
22827
|
+
case "Q+LFl":
|
|
22828
|
+
case "VQ+LFl":
|
|
22829
|
+
case "UQ+LFl":
|
|
22830
|
+
case "Fl+LFl":
|
|
22831
|
+
return withLongFlash(character, group, period);
|
|
22832
|
+
default:
|
|
22833
|
+
return void 0;
|
|
22834
|
+
}
|
|
22835
|
+
}
|
|
22836
|
+
function grouped(counts, period, pulse, pulseIntensity, gapIntensity) {
|
|
22837
|
+
if (!counts || !period || !pulse || !(pulse >= limits.minPhase)) return void 0;
|
|
22838
|
+
const pulses = sum(counts);
|
|
22839
|
+
const groups = counts.length;
|
|
22840
|
+
const free = period - pulses * pulse;
|
|
22841
|
+
const units = pulses - groups + 2 * (groups - 1) + 3;
|
|
22842
|
+
const gap = Math.min(2 * pulse, free / units);
|
|
22843
|
+
if (!(gap >= limits.minPhase)) return void 0;
|
|
22844
|
+
const phases = [];
|
|
22845
|
+
counts.forEach((count, index) => {
|
|
22846
|
+
for (let pulseIndex = 0; pulseIndex < count; pulseIndex += 1) {
|
|
22847
|
+
phases.push({ colour: 0, duration: pulse, intensity: pulseIntensity });
|
|
22848
|
+
if (pulseIndex < count - 1) {
|
|
22849
|
+
phases.push({ colour: 0, duration: gap, intensity: gapIntensity });
|
|
22850
|
+
}
|
|
22851
|
+
}
|
|
22852
|
+
if (index < groups - 1) phases.push({ colour: 0, duration: 2 * gap, intensity: gapIntensity });
|
|
22853
|
+
});
|
|
22854
|
+
const used = phases.reduce((total, phase) => total + phase.duration, 0);
|
|
22855
|
+
phases.push({ colour: 0, duration: period - used, intensity: gapIntensity });
|
|
22856
|
+
return phases;
|
|
22857
|
+
}
|
|
22858
|
+
function quick(character, group, period) {
|
|
22859
|
+
const cycle = conventions.quickCycle[character];
|
|
22860
|
+
const flash = cycle * conventions.quickDuty;
|
|
22861
|
+
if (group === "") {
|
|
22862
|
+
return [
|
|
22863
|
+
{ colour: 0, duration: flash, intensity: lit },
|
|
22864
|
+
{ colour: 0, duration: cycle - flash, intensity: eclipsed }
|
|
22865
|
+
];
|
|
22866
|
+
}
|
|
22867
|
+
const counts = groupCounts(group);
|
|
22868
|
+
if (!counts) return void 0;
|
|
22869
|
+
const count = sum(counts);
|
|
22870
|
+
const cardinal = conventions.cardinalPeriods[character]?.[count];
|
|
22871
|
+
const cyclePeriod = period ?? cardinal;
|
|
22872
|
+
if (!cyclePeriod && count === 1) return quick(character, "", void 0);
|
|
22873
|
+
if (!cyclePeriod || cyclePeriod < (count + 1) * cycle) return void 0;
|
|
22874
|
+
return [
|
|
22875
|
+
...quickFlashes(count, cycle, flash),
|
|
22876
|
+
{ colour: 0, duration: cyclePeriod - count * cycle, intensity: eclipsed }
|
|
22877
|
+
];
|
|
22878
|
+
}
|
|
22879
|
+
function quickFlashes(count, cycle, flash) {
|
|
22880
|
+
const phases = [];
|
|
22881
|
+
for (let index = 0; index < count; index += 1) {
|
|
22882
|
+
phases.push({ colour: 0, duration: flash, intensity: lit });
|
|
22883
|
+
phases.push({ colour: 0, duration: cycle - flash, intensity: eclipsed });
|
|
22884
|
+
}
|
|
22885
|
+
return phases;
|
|
22886
|
+
}
|
|
22887
|
+
function interruptedQuick(character, period) {
|
|
22888
|
+
const cycle = conventions.quickCycle[character];
|
|
22889
|
+
if (!period) return void 0;
|
|
22890
|
+
const count = Math.max(2, Math.floor(conventions.interruptedShare * period / cycle));
|
|
22891
|
+
if (period < (count + 1) * cycle) return void 0;
|
|
22892
|
+
return [
|
|
22893
|
+
...quickFlashes(count, cycle, cycle * conventions.quickDuty),
|
|
22894
|
+
{ colour: 0, duration: period - count * cycle, intensity: eclipsed }
|
|
22895
|
+
];
|
|
22896
|
+
}
|
|
22897
|
+
function withLongFlash(character, group, period) {
|
|
22898
|
+
const first = character.slice(0, character.indexOf("+"));
|
|
22899
|
+
const counts = groupCounts(group);
|
|
22900
|
+
if (group !== "" && !counts) return void 0;
|
|
22901
|
+
const count = counts ? sum(counts) : first === "Fl" ? 1 : 6;
|
|
22902
|
+
const cyclePeriod = period ?? conventions.cardinalPeriods[character] ?? void 0;
|
|
22903
|
+
if (typeof cyclePeriod !== "number") return void 0;
|
|
22904
|
+
let phases;
|
|
22905
|
+
if (first === "Fl") {
|
|
22906
|
+
const flash = Math.min(conventions.flash, conventions.flashShare * cyclePeriod / (count + 2));
|
|
22907
|
+
phases = [];
|
|
22908
|
+
for (let index = 0; index < count; index += 1) {
|
|
22909
|
+
phases.push({ colour: 0, duration: flash, intensity: lit });
|
|
22910
|
+
phases.push({ colour: 0, duration: 2 * flash, intensity: eclipsed });
|
|
22911
|
+
}
|
|
22912
|
+
} else {
|
|
22913
|
+
const cycle = conventions.quickCycle[first];
|
|
22914
|
+
phases = quickFlashes(count, cycle, cycle * conventions.quickDuty);
|
|
22915
|
+
}
|
|
22916
|
+
phases.push({ colour: 0, duration: conventions.longFlash, intensity: lit });
|
|
22917
|
+
const used = phases.reduce((total, phase) => total + phase.duration, 0);
|
|
22918
|
+
const rest = cyclePeriod - used;
|
|
22919
|
+
if (!(rest >= conventions.longFlash / 2)) return void 0;
|
|
22920
|
+
phases.push({ colour: 0, duration: rest, intensity: eclipsed });
|
|
22921
|
+
return phases;
|
|
22922
|
+
}
|
|
22923
|
+
function morseCode(group, period) {
|
|
22924
|
+
const letters = [...group.toUpperCase().replaceAll(/\s+/gu, "")];
|
|
22925
|
+
if (letters.length === 0 || letters.length > 4) return void 0;
|
|
22926
|
+
const codes = letters.map((letter) => morse[letter]);
|
|
22927
|
+
if (codes.some((code) => code === void 0)) return void 0;
|
|
22928
|
+
const signalUnits = [];
|
|
22929
|
+
codes.forEach((code, letterIndex) => {
|
|
22930
|
+
[...code].forEach((signal, signalIndex) => {
|
|
22931
|
+
if (signalIndex > 0) signalUnits.push({ units: 1, intensity: eclipsed });
|
|
22932
|
+
signalUnits.push({ units: signal === "." ? 1 : 3, intensity: lit });
|
|
22933
|
+
});
|
|
22934
|
+
if (letterIndex < codes.length - 1) signalUnits.push({ units: 3, intensity: eclipsed });
|
|
22935
|
+
});
|
|
22936
|
+
const units = signalUnits.reduce((total, signal) => total + signal.units, 0);
|
|
22937
|
+
const unit2 = period ? Math.min(conventions.morseUnit, period / (units + 3)) : conventions.morseUnit;
|
|
22938
|
+
const cyclePeriod = period ?? (units + 7) * unit2;
|
|
22939
|
+
if (!(unit2 >= limits.minPhase)) return void 0;
|
|
22940
|
+
return [
|
|
22941
|
+
...signalUnits.map(({ units: count, intensity }) => ({
|
|
22942
|
+
colour: 0,
|
|
22943
|
+
duration: count * unit2,
|
|
22944
|
+
intensity
|
|
22945
|
+
})),
|
|
22946
|
+
{ colour: 0, duration: cyclePeriod - units * unit2, intensity: eclipsed }
|
|
22947
|
+
];
|
|
22948
|
+
}
|
|
22949
|
+
function alternatingFixed(colours, period) {
|
|
22950
|
+
if (colours < 2 || !period) return void 0;
|
|
22951
|
+
return Array.from({ length: colours }, (_, colour) => ({
|
|
22952
|
+
colour,
|
|
22953
|
+
duration: period / colours,
|
|
22954
|
+
intensity: lit
|
|
22955
|
+
}));
|
|
22956
|
+
}
|
|
22957
|
+
function alternateColours(phases, colours) {
|
|
22958
|
+
const litPhases = phases.filter(({ intensity }) => intensity > eclipsed).length;
|
|
22959
|
+
if (litPhases === 0) return [...phases];
|
|
22960
|
+
const repeats = colours / gcd(litPhases, colours);
|
|
22961
|
+
const result = [];
|
|
22962
|
+
let next = 0;
|
|
22963
|
+
for (let repeat = 0; repeat < repeats; repeat += 1) {
|
|
22964
|
+
for (const phase of phases) {
|
|
22965
|
+
if (phase.intensity > eclipsed) {
|
|
22966
|
+
result.push({ ...phase, colour: next % colours });
|
|
22967
|
+
next += 1;
|
|
22968
|
+
} else {
|
|
22969
|
+
result.push({ ...phase });
|
|
22970
|
+
}
|
|
22971
|
+
}
|
|
22972
|
+
}
|
|
22973
|
+
return result;
|
|
22974
|
+
}
|
|
22975
|
+
function finish(input) {
|
|
22976
|
+
const phases = [];
|
|
22977
|
+
for (const phase of input) {
|
|
22978
|
+
const duration = Math.round(phase.duration * 1e3) / 1e3;
|
|
22979
|
+
if (!Number.isFinite(duration) || duration < limits.minPhase) return void 0;
|
|
22980
|
+
const previous = phases.at(-1);
|
|
22981
|
+
if (previous && previous.intensity === phase.intensity && previous.colour === phase.colour) {
|
|
22982
|
+
previous.duration = Math.round((previous.duration + duration) * 1e3) / 1e3;
|
|
22983
|
+
} else {
|
|
22984
|
+
phases.push({ colour: phase.colour, duration, intensity: phase.intensity });
|
|
22985
|
+
}
|
|
22986
|
+
}
|
|
22987
|
+
if (phases.length > 1) {
|
|
22988
|
+
const first = phases[0];
|
|
22989
|
+
const last = phases.at(-1);
|
|
22990
|
+
if (first.intensity === last.intensity && first.colour === last.colour) {
|
|
22991
|
+
first.duration = Math.round((first.duration + last.duration) * 1e3) / 1e3;
|
|
22992
|
+
phases.pop();
|
|
22993
|
+
}
|
|
22994
|
+
}
|
|
22995
|
+
if (phases.length < 2 || phases.length > limits.maxPhases) return void 0;
|
|
22996
|
+
const periodMs = phases.reduce((total, phase) => total + Math.round(phase.duration * 1e3), 0);
|
|
22997
|
+
if (periodMs > limits.maxPeriod * 1e3) return void 0;
|
|
22998
|
+
const frozen = Object.freeze(phases.map((phase) => Object.freeze({ ...phase })));
|
|
22999
|
+
return Object.freeze({
|
|
23000
|
+
key: frozen.map(
|
|
23001
|
+
({ colour, duration, intensity }) => `${Math.round(duration * 1e3)}:${intensity}:${colour}`
|
|
23002
|
+
).join(","),
|
|
23003
|
+
period: periodMs / 1e3,
|
|
23004
|
+
phases: frozen
|
|
23005
|
+
});
|
|
23006
|
+
}
|
|
23007
|
+
function flashOf(counts, period) {
|
|
23008
|
+
if (!counts || !period) return void 0;
|
|
23009
|
+
return Math.min(conventions.flash, conventions.flashShare * period / sum(counts));
|
|
23010
|
+
}
|
|
23011
|
+
function longFlashOf(counts, period) {
|
|
23012
|
+
if (!counts || !period) return void 0;
|
|
23013
|
+
const pulses = sum(counts);
|
|
23014
|
+
return period >= 2 * pulses * conventions.longFlash ? conventions.longFlash : conventions.flashShare * period / pulses;
|
|
23015
|
+
}
|
|
23016
|
+
function groupCounts(group) {
|
|
23017
|
+
if (group === "") return [1];
|
|
23018
|
+
const parts = group.split("+");
|
|
23019
|
+
const counts = [];
|
|
23020
|
+
for (const part of parts) {
|
|
23021
|
+
if (!/^\s*\d{1,2}\s*$/u.test(part)) return void 0;
|
|
23022
|
+
const count = Number(part);
|
|
23023
|
+
if (count < 1) return void 0;
|
|
23024
|
+
counts.push(count);
|
|
23025
|
+
}
|
|
23026
|
+
return sum(counts) <= 32 ? counts : void 0;
|
|
23027
|
+
}
|
|
23028
|
+
function groupText(value) {
|
|
23029
|
+
if (typeof value === "number" && Number.isInteger(value)) return String(value);
|
|
23030
|
+
return typeof value === "string" ? value.trim() : "";
|
|
23031
|
+
}
|
|
23032
|
+
function colourCount(value) {
|
|
23033
|
+
if (typeof value !== "string") return 0;
|
|
23034
|
+
return value.split(",").filter((name) => name.trim() !== "").length;
|
|
23035
|
+
}
|
|
23036
|
+
function positiveNumber(value) {
|
|
23037
|
+
const number = typeof value === "string" && value.trim() !== "" ? Number(value) : value;
|
|
23038
|
+
return typeof number === "number" && Number.isFinite(number) && number > 0 ? number : void 0;
|
|
23039
|
+
}
|
|
23040
|
+
function sum(values) {
|
|
23041
|
+
return values.reduce((total, value) => total + value, 0);
|
|
23042
|
+
}
|
|
23043
|
+
function gcd(a, b) {
|
|
23044
|
+
return b === 0 ? a : gcd(b, a % b);
|
|
23045
|
+
}
|
|
23046
|
+
|
|
21816
23047
|
// src/icon-package.ts
|
|
21817
23048
|
import { z as z10 } from "zod";
|
|
21818
23049
|
var tileflowIconPackageFileNames = [
|
|
@@ -22518,7 +23749,7 @@ async function requestSessionGrant(input) {
|
|
|
22518
23749
|
else throw error;
|
|
22519
23750
|
}
|
|
22520
23751
|
throwIfSessionGrantAborted(signal);
|
|
22521
|
-
if (response.status === 409 &&
|
|
23752
|
+
if (response.status === 409 && isRecord17(body) && body.code === "COMMERCIAL_SESSION_RESTART_REQUIRED" && body.ok === false && body.retryWithNewSession === true && body.sessionId === input.sessionId) {
|
|
22522
23753
|
throw new TileflowSessionRestartError();
|
|
22523
23754
|
}
|
|
22524
23755
|
if (!response.ok) {
|
|
@@ -22591,7 +23822,7 @@ function sessionGrantAbortReason(signal) {
|
|
|
22591
23822
|
return error;
|
|
22592
23823
|
}
|
|
22593
23824
|
function parseSessionGrantResponse(value, expectedSessionId) {
|
|
22594
|
-
if (!
|
|
23825
|
+
if (!isRecord17(value) || value.ok !== true || value.sessionId !== expectedSessionId) return null;
|
|
22595
23826
|
if (value.usageMode !== void 0 && value.usageMode !== "session") return null;
|
|
22596
23827
|
if (value.billingEnabled !== void 0 && value.billingEnabled !== false) return null;
|
|
22597
23828
|
if (value.disposition !== void 0 && value.disposition !== "ordinary" && value.disposition !== "unbilled_fail_open") {
|
|
@@ -22610,11 +23841,11 @@ function parseSessionGrantResponse(value, expectedSessionId) {
|
|
|
22610
23841
|
}
|
|
22611
23842
|
return value;
|
|
22612
23843
|
}
|
|
22613
|
-
function
|
|
23844
|
+
function isRecord17(value) {
|
|
22614
23845
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
22615
23846
|
}
|
|
22616
23847
|
function isPlainRuntimeRecord(value) {
|
|
22617
|
-
if (!
|
|
23848
|
+
if (!isRecord17(value)) return false;
|
|
22618
23849
|
const prototype = Object.getPrototypeOf(value);
|
|
22619
23850
|
return prototype === Object.prototype || prototype === null;
|
|
22620
23851
|
}
|
|
@@ -24079,7 +25310,7 @@ function readTileflowModelFileSummary(buffer) {
|
|
|
24079
25310
|
height: round2(height, 100),
|
|
24080
25311
|
footprint: {
|
|
24081
25312
|
rings: footprint.length,
|
|
24082
|
-
points: footprint.reduce((
|
|
25313
|
+
points: footprint.reduce((sum2, ring) => sum2 + ring.length / 2, 0),
|
|
24083
25314
|
area: round2(Math.abs(area), 10)
|
|
24084
25315
|
}
|
|
24085
25316
|
};
|
|
@@ -24275,7 +25506,7 @@ function checkModel(model) {
|
|
|
24275
25506
|
throw new RangeError("A footprint ring has at least three points.");
|
|
24276
25507
|
if (footprint.some((ring) => ring.some((value) => !Number.isFinite(value))))
|
|
24277
25508
|
throw new RangeError("A footprint point has no place.");
|
|
24278
|
-
if (footprint.reduce((
|
|
25509
|
+
if (footprint.reduce((sum2, ring) => sum2 + ring.length / 2, 0) > tileflowModelLimits.footprintPoints)
|
|
24279
25510
|
throw new RangeError(
|
|
24280
25511
|
`A footprint has at most ${tileflowModelLimits.footprintPoints} points in all.`
|
|
24281
25512
|
);
|
|
@@ -24541,7 +25772,7 @@ function validFootprint(footprint) {
|
|
|
24541
25772
|
return points2 <= tileflowModelLimits.footprintPoints;
|
|
24542
25773
|
}
|
|
24543
25774
|
function readTileflowLandmarkRegion(json) {
|
|
24544
|
-
if (!
|
|
25775
|
+
if (!isRecord18(json)) return void 0;
|
|
24545
25776
|
const named = json.format === "tileflow-landmark-region-v2";
|
|
24546
25777
|
if (!named && json.format !== "tileflow-landmark-region-v1") return void 0;
|
|
24547
25778
|
const region = json.region;
|
|
@@ -24572,7 +25803,7 @@ function readLandmarks(listed, tx, ty) {
|
|
|
24572
25803
|
if (!Array.isArray(listed) || listed.length === 0) return void 0;
|
|
24573
25804
|
const out = [];
|
|
24574
25805
|
for (const landmark of listed) {
|
|
24575
|
-
if (!
|
|
25806
|
+
if (!isRecord18(landmark)) return void 0;
|
|
24576
25807
|
const { id: id2, at, heading, footprint } = landmark;
|
|
24577
25808
|
if (typeof id2 !== "string" || !landmarkId.test(id2)) return void 0;
|
|
24578
25809
|
if (!Array.isArray(at) || at.length !== 2 || !at.every((value) => typeof value === "number"))
|
|
@@ -24596,10 +25827,10 @@ function readLandmarks(listed, tx, ty) {
|
|
|
24596
25827
|
return out;
|
|
24597
25828
|
}
|
|
24598
25829
|
function readTileflowLandmarksTileJson(json, url) {
|
|
24599
|
-
if (!
|
|
25830
|
+
if (!isRecord18(json) || json.format !== "tileflow-landmarks-v2") return void 0;
|
|
24600
25831
|
const tile = Array.isArray(json.tiles) ? json.tiles[0] : void 0;
|
|
24601
25832
|
const regions2 = json.regions;
|
|
24602
|
-
if (typeof tile !== "string" || !tile.includes("{sha256}") || json.minzoom !== tileflowLandmarkTileZoom || json.maxzoom !== tileflowLandmarkTileZoom || !
|
|
25833
|
+
if (typeof tile !== "string" || !tile.includes("{sha256}") || json.minzoom !== tileflowLandmarkTileZoom || json.maxzoom !== tileflowLandmarkTileZoom || !isRecord18(regions2) || regions2.zoom !== tileflowLandmarkRegionZoom || typeof regions2.url !== "string" || !regions2.url.includes("{x}") || !regions2.url.includes("{y}") || !Array.isArray(regions2.available))
|
|
24603
25834
|
return void 0;
|
|
24604
25835
|
const available = /* @__PURE__ */ new Set();
|
|
24605
25836
|
for (const region of regions2.available) {
|
|
@@ -24617,7 +25848,7 @@ function readTileflowLandmarksTileJson(json, url) {
|
|
|
24617
25848
|
regions: available
|
|
24618
25849
|
};
|
|
24619
25850
|
}
|
|
24620
|
-
function
|
|
25851
|
+
function isRecord18(value) {
|
|
24621
25852
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24622
25853
|
}
|
|
24623
25854
|
|
|
@@ -24656,6 +25887,7 @@ export {
|
|
|
24656
25887
|
createTileflowLineBackgroundFontStack,
|
|
24657
25888
|
createTileflowSessionController,
|
|
24658
25889
|
createTileflowSessionId,
|
|
25890
|
+
declareTileflowNauticalLights,
|
|
24659
25891
|
decodeTileflowModels,
|
|
24660
25892
|
decodeTileflowTreeModel,
|
|
24661
25893
|
defaultTileflowManifestUrl,
|
|
@@ -24728,7 +25960,9 @@ export {
|
|
|
24728
25960
|
readTileflowLandmarksTileJson,
|
|
24729
25961
|
readTileflowModelFileIds,
|
|
24730
25962
|
readTileflowModelFileSummary,
|
|
25963
|
+
readTileflowNauticalLights,
|
|
24731
25964
|
readTileflowNotices,
|
|
25965
|
+
readTileflowSky,
|
|
24732
25966
|
readTileflowStreetLights,
|
|
24733
25967
|
readTileflowSunPreset,
|
|
24734
25968
|
readTileflowTeamModelName,
|
|
@@ -24771,6 +26005,7 @@ export {
|
|
|
24771
26005
|
sha256Hex,
|
|
24772
26006
|
shouldLoadTileflowManifest,
|
|
24773
26007
|
startTileflowSession,
|
|
26008
|
+
steadyTileflowNauticalLights,
|
|
24774
26009
|
tileflowAuthoringManifest,
|
|
24775
26010
|
tileflowAuthoringManifestSchemaVersion,
|
|
24776
26011
|
tileflowBandPlacements,
|
|
@@ -24849,6 +26084,10 @@ export {
|
|
|
24849
26084
|
tileflowLandmarkTileOf,
|
|
24850
26085
|
tileflowLandmarkTileZoom,
|
|
24851
26086
|
tileflowLayerBands,
|
|
26087
|
+
tileflowLightRhythm,
|
|
26088
|
+
tileflowLightRhythmConventions,
|
|
26089
|
+
tileflowLightRhythmLimits,
|
|
26090
|
+
tileflowLightStateAt,
|
|
24852
26091
|
tileflowLineBackgroundDefaults,
|
|
24853
26092
|
tileflowLineBackgroundHaloRatio,
|
|
24854
26093
|
tileflowLineBackgroundLimits,
|
|
@@ -24856,6 +26095,7 @@ export {
|
|
|
24856
26095
|
tileflowLocalDirectoryMessage,
|
|
24857
26096
|
tileflowMapDefaultMaxDepth,
|
|
24858
26097
|
tileflowMapIdSchema,
|
|
26098
|
+
tileflowMaxPitch,
|
|
24859
26099
|
tileflowModelContentType,
|
|
24860
26100
|
tileflowModelDefaultLightingRoles,
|
|
24861
26101
|
tileflowModelFileName,
|
|
@@ -24866,8 +26106,14 @@ export {
|
|
|
24866
26106
|
tileflowModelSurfaceLimits,
|
|
24867
26107
|
tileflowModelTextureChannels,
|
|
24868
26108
|
tileflowModelVertexBytes,
|
|
26109
|
+
tileflowNauticalFacilityIcons,
|
|
24869
26110
|
tileflowNauticalImageRoles,
|
|
26111
|
+
tileflowNauticalLightEclipseOpacity,
|
|
26112
|
+
tileflowNauticalLightStates,
|
|
26113
|
+
tileflowNauticalLightsLimits,
|
|
26114
|
+
tileflowNauticalLightsMetadataKey,
|
|
24870
26115
|
tileflowNauticalNotice,
|
|
26116
|
+
tileflowNauticalPromoteId,
|
|
24871
26117
|
tileflowNauticalSourceId,
|
|
24872
26118
|
tileflowNauticalV1Schema,
|
|
24873
26119
|
tileflowNoticeLimits,
|
|
@@ -24895,6 +26141,8 @@ export {
|
|
|
24895
26141
|
tileflowRuntimeManifestSchema,
|
|
24896
26142
|
tileflowRuntimeManifestVersion,
|
|
24897
26143
|
tileflowSemanticDiffSchemaVersion,
|
|
26144
|
+
tileflowSkyAtSun,
|
|
26145
|
+
tileflowSkyMetadataKey,
|
|
24898
26146
|
tileflowStreetLightsMetadataKey,
|
|
24899
26147
|
tileflowStyleFontFaceLimits,
|
|
24900
26148
|
tileflowStyleFontFacesMetadataKey,
|