1139 lines
34 KiB
JavaScript
1139 lines
34 KiB
JavaScript
var M = Math.pow, g = (e, t, r) => new Promise((n, i) => {
|
|
var o = (u) => {
|
|
try {
|
|
c(r.next(u));
|
|
} catch (f) {
|
|
i(f);
|
|
}
|
|
}, s = (u) => {
|
|
try {
|
|
c(r.throw(u));
|
|
} catch (f) {
|
|
i(f);
|
|
}
|
|
}, c = (u) => u.done ? n(u.value) : Promise.resolve(u.value).then(o, s);
|
|
c((r = r.apply(e, t)).next());
|
|
}), w = Uint8Array, O = Uint16Array, Oe = Int32Array, ve = new w([
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
1,
|
|
1,
|
|
1,
|
|
1,
|
|
2,
|
|
2,
|
|
2,
|
|
2,
|
|
3,
|
|
3,
|
|
3,
|
|
3,
|
|
4,
|
|
4,
|
|
4,
|
|
4,
|
|
5,
|
|
5,
|
|
5,
|
|
5,
|
|
0,
|
|
/* unused */
|
|
0,
|
|
0,
|
|
/* impossible */
|
|
0
|
|
]), ye = new w([
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
1,
|
|
1,
|
|
2,
|
|
2,
|
|
3,
|
|
3,
|
|
4,
|
|
4,
|
|
5,
|
|
5,
|
|
6,
|
|
6,
|
|
7,
|
|
7,
|
|
8,
|
|
8,
|
|
9,
|
|
9,
|
|
10,
|
|
10,
|
|
11,
|
|
11,
|
|
12,
|
|
12,
|
|
13,
|
|
13,
|
|
/* unused */
|
|
0,
|
|
0
|
|
]), Ke = new w([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]), me = function(e, t) {
|
|
for (var r = new O(31), n = 0; n < 31; ++n)
|
|
r[n] = t += 1 << e[n - 1];
|
|
for (var i = new Oe(r[30]), n = 1; n < 30; ++n)
|
|
for (var o = r[n]; o < r[n + 1]; ++o)
|
|
i[o] = o - r[n] << 5 | n;
|
|
return { b: r, r: i };
|
|
}, pe = me(ve, 2), we = pe.b, Se = pe.r;
|
|
we[28] = 258, Se[258] = 28;
|
|
var Pe = me(ye, 0), Re = Pe.b, xe = new O(32768);
|
|
for (h = 0; h < 32768; ++h)
|
|
z = (h & 43690) >> 1 | (h & 21845) << 1, z = (z & 52428) >> 2 | (z & 13107) << 2, z = (z & 61680) >> 4 | (z & 3855) << 4, xe[h] = ((z & 65280) >> 8 | (z & 255) << 8) >> 1;
|
|
var z, h, K = function(e, t, r) {
|
|
for (var n = e.length, i = 0, o = new O(t); i < n; ++i)
|
|
e[i] && ++o[e[i] - 1];
|
|
var s = new O(t);
|
|
for (i = 1; i < t; ++i)
|
|
s[i] = s[i - 1] + o[i - 1] << 1;
|
|
var c;
|
|
{
|
|
c = new O(1 << t);
|
|
var u = 15 - t;
|
|
for (i = 0; i < n; ++i)
|
|
if (e[i])
|
|
for (var f = i << 4 | e[i], a = t - e[i], l = s[e[i] - 1]++ << a, d = l | (1 << a) - 1; l <= d; ++l)
|
|
c[xe[l] >> u] = f;
|
|
}
|
|
return c;
|
|
}, S = new w(288);
|
|
for (h = 0; h < 144; ++h)
|
|
S[h] = 8;
|
|
var h;
|
|
for (h = 144; h < 256; ++h)
|
|
S[h] = 9;
|
|
var h;
|
|
for (h = 256; h < 280; ++h)
|
|
S[h] = 7;
|
|
var h;
|
|
for (h = 280; h < 288; ++h)
|
|
S[h] = 8;
|
|
var h, Ue = new w(32);
|
|
for (h = 0; h < 32; ++h)
|
|
Ue[h] = 5;
|
|
var h, ke = /* @__PURE__ */ K(S, 9), Ie = /* @__PURE__ */ K(Ue, 5), G = function(e) {
|
|
for (var t = e[0], r = 1; r < e.length; ++r)
|
|
e[r] > t && (t = e[r]);
|
|
return t;
|
|
}, b = function(e, t, r) {
|
|
var n = t / 8 | 0;
|
|
return (e[n] | e[n + 1] << 8) >> (t & 7) & r;
|
|
}, Y = function(e, t) {
|
|
var r = t / 8 | 0;
|
|
return (e[r] | e[r + 1] << 8 | e[r + 2] << 16) >> (t & 7);
|
|
}, _e = function(e) {
|
|
return (e + 7) / 8 | 0;
|
|
}, je = function(e, t, r) {
|
|
(r == null || r > e.length) && (r = e.length);
|
|
var n = new w(r - t);
|
|
return n.set(e.subarray(t, r)), n;
|
|
}, We = [
|
|
"unexpected EOF",
|
|
"invalid block type",
|
|
"invalid length/literal",
|
|
"invalid distance",
|
|
"stream finished",
|
|
"no stream handler",
|
|
,
|
|
"no callback",
|
|
"invalid UTF-8 data",
|
|
"extra field too long",
|
|
"date not in range 1980-2099",
|
|
"filename too long",
|
|
"stream finishing",
|
|
"invalid zip data"
|
|
// determined by unknown compression method
|
|
], p = function(e, t, r) {
|
|
var n = new Error(t || We[e]);
|
|
if (n.code = e, Error.captureStackTrace && Error.captureStackTrace(n, p), !r)
|
|
throw n;
|
|
return n;
|
|
}, ee = function(e, t, r, n) {
|
|
var i = e.length, o = 0;
|
|
if (!i || t.f && !t.l)
|
|
return r || new w(0);
|
|
var s = !r || t.i != 2, c = t.i;
|
|
r || (r = new w(i * 3));
|
|
var u = function(le) {
|
|
var ue = r.length;
|
|
if (le > ue) {
|
|
var fe = new w(Math.max(ue * 2, le));
|
|
fe.set(r), r = fe;
|
|
}
|
|
}, f = t.f || 0, a = t.p || 0, l = t.b || 0, d = t.l, m = t.d, v = t.m, U = t.n, T = i * 8;
|
|
do {
|
|
if (!d) {
|
|
f = b(e, a, 1);
|
|
var P = b(e, a + 1, 3);
|
|
if (a += 3, P)
|
|
if (P == 1)
|
|
d = ke, m = Ie, v = 9, U = 5;
|
|
else if (P == 2) {
|
|
var j = b(e, a, 31) + 257, re = b(e, a + 10, 15) + 4, ne = j + b(e, a + 5, 31) + 1;
|
|
a += 14;
|
|
for (var B = new w(ne), W = new w(19), x = 0; x < re; ++x)
|
|
W[Ke[x]] = b(e, a + x * 3, 7);
|
|
a += re * 3;
|
|
for (var ie = G(W), $e = (1 << ie) - 1, Be = K(W, ie), x = 0; x < ne; ) {
|
|
var oe = Be[b(e, a, $e)];
|
|
a += oe & 15;
|
|
var y = oe >> 4;
|
|
if (y < 16)
|
|
B[x++] = y;
|
|
else {
|
|
var A = 0, R = 0;
|
|
for (y == 16 ? (R = 3 + b(e, a, 3), a += 2, A = B[x - 1]) : y == 17 ? (R = 3 + b(e, a, 7), a += 3) : y == 18 && (R = 11 + b(e, a, 127), a += 7); R--; )
|
|
B[x++] = A;
|
|
}
|
|
}
|
|
var se = B.subarray(0, j), D = B.subarray(j);
|
|
v = G(se), U = G(D), d = K(se, v), m = K(D, U);
|
|
} else
|
|
p(1);
|
|
else {
|
|
var y = _e(a) + 4, I = e[y - 4] | e[y - 3] << 8, _ = y + I;
|
|
if (_ > i) {
|
|
c && p(0);
|
|
break;
|
|
}
|
|
s && u(l + I), r.set(e.subarray(y, _), l), t.b = l += I, t.p = a = _ * 8, t.f = f;
|
|
continue;
|
|
}
|
|
if (a > T) {
|
|
c && p(0);
|
|
break;
|
|
}
|
|
}
|
|
s && u(l + 131072);
|
|
for (var Ve = (1 << v) - 1, Ze = (1 << U) - 1, N = a; ; N = a) {
|
|
var A = d[Y(e, a) & Ve], C = A >> 4;
|
|
if (a += A & 15, a > T) {
|
|
c && p(0);
|
|
break;
|
|
}
|
|
if (A || p(2), C < 256)
|
|
r[l++] = C;
|
|
else if (C == 256) {
|
|
N = a, d = null;
|
|
break;
|
|
} else {
|
|
var ae = C - 254;
|
|
if (C > 264) {
|
|
var x = C - 257, V = ve[x];
|
|
ae = b(e, a, (1 << V) - 1) + we[x], a += V;
|
|
}
|
|
var J = m[Y(e, a) & Ze], F = J >> 4;
|
|
J || p(3), a += J & 15;
|
|
var D = Re[F];
|
|
if (F > 3) {
|
|
var V = ye[F];
|
|
D += Y(e, a) & (1 << V) - 1, a += V;
|
|
}
|
|
if (a > T) {
|
|
c && p(0);
|
|
break;
|
|
}
|
|
s && u(l + 131072);
|
|
var q = l + ae;
|
|
if (l < D) {
|
|
var ce = o - D, He = Math.min(D, q);
|
|
for (ce + l < 0 && p(3); l < He; ++l)
|
|
r[l] = n[ce + l];
|
|
}
|
|
for (; l < q; l += 4)
|
|
r[l] = r[l - D], r[l + 1] = r[l + 1 - D], r[l + 2] = r[l + 2 - D], r[l + 3] = r[l + 3 - D];
|
|
l = q;
|
|
}
|
|
}
|
|
t.l = d, t.p = N, t.b = l, t.f = f, d && (f = 1, t.m = v, t.d = m, t.n = U);
|
|
} while (!f);
|
|
return l == r.length ? r : je(r, 0, l);
|
|
}, Ne = /* @__PURE__ */ new w(0), Je = function(e) {
|
|
(e[0] != 31 || e[1] != 139 || e[2] != 8) && p(6, "invalid gzip data");
|
|
var t = e[3], r = 10;
|
|
t & 4 && (r += (e[10] | e[11] << 8) + 2);
|
|
for (var n = (t >> 3 & 1) + (t >> 4 & 1); n > 0; n -= !e[r++])
|
|
;
|
|
return r + (t & 2);
|
|
}, Fe = function(e) {
|
|
var t = e.length;
|
|
return (e[t - 4] | e[t - 3] << 8 | e[t - 2] << 16 | e[t - 1] << 24) >>> 0;
|
|
}, qe = function(e, t) {
|
|
return ((e[0] & 15) != 8 || e[0] >> 4 > 7 || (e[0] << 8 | e[1]) % 31) && p(6, "invalid zlib data"), (e[1] >> 5 & 1) == 1 && p(6, "invalid zlib data: " + (e[1] & 32 ? "need" : "unexpected") + " dictionary"), (e[1] >> 3 & 4) + 2;
|
|
};
|
|
function Ge(e, t) {
|
|
return ee(e, { i: 2 }, t, t);
|
|
}
|
|
function Ye(e, t) {
|
|
var r = Je(e);
|
|
return r + 8 > e.length && p(6, "invalid gzip data"), ee(e.subarray(r, -8), { i: 2 }, new w(Fe(e)), t);
|
|
}
|
|
function Xe(e, t) {
|
|
return ee(e.subarray(qe(e), -4), { i: 2 }, t, t);
|
|
}
|
|
function X(e, t) {
|
|
return e[0] == 31 && e[1] == 139 && e[2] == 8 ? Ye(e, t) : (e[0] & 15) != 8 || e[0] >> 4 > 7 || (e[0] << 8 | e[1]) % 31 ? Ge(e, t) : Xe(e, t);
|
|
}
|
|
var Qe = typeof TextDecoder < "u" && /* @__PURE__ */ new TextDecoder(), et = 0;
|
|
try {
|
|
Qe.decode(Ne, { stream: !0 }), et = 1;
|
|
} catch {
|
|
}
|
|
var De = (e, t) => e * M(2, t), Z = (e, t) => Math.floor(e / M(2, t)), k = (e, t) => De(e.getUint16(t + 1, !0), 8) + e.getUint8(t), be = (e, t) => De(e.getUint32(t + 2, !0), 16) + e.getUint16(t, !0), tt = (e, t, r, n, i) => {
|
|
if (e !== n.getUint8(i))
|
|
return e - n.getUint8(i);
|
|
const o = k(n, i + 1);
|
|
if (t !== o)
|
|
return t - o;
|
|
const s = k(n, i + 4);
|
|
return r !== s ? r - s : 0;
|
|
}, rt = (e, t, r, n) => {
|
|
const i = Le(e, t | 128, r, n);
|
|
return i ? {
|
|
z: t,
|
|
x: r,
|
|
y: n,
|
|
offset: i[0],
|
|
length: i[1],
|
|
isDir: !0
|
|
} : null;
|
|
}, he = (e, t, r, n) => {
|
|
const i = Le(e, t, r, n);
|
|
return i ? {
|
|
z: t,
|
|
x: r,
|
|
y: n,
|
|
offset: i[0],
|
|
length: i[1],
|
|
isDir: !1
|
|
} : null;
|
|
}, Le = (e, t, r, n) => {
|
|
let i = 0, o = e.byteLength / 17 - 1;
|
|
for (; i <= o; ) {
|
|
const s = o + i >> 1, c = tt(t, r, n, e, s * 17);
|
|
if (c > 0)
|
|
i = s + 1;
|
|
else if (c < 0)
|
|
o = s - 1;
|
|
else
|
|
return [be(e, s * 17 + 7), e.getUint32(s * 17 + 13, !0)];
|
|
}
|
|
return null;
|
|
}, nt = (e, t) => e.isDir && !t.isDir ? 1 : !e.isDir && t.isDir ? -1 : e.z !== t.z ? e.z - t.z : e.x !== t.x ? e.x - t.x : e.y - t.y, Ee = (e, t) => {
|
|
const r = e.getUint8(t * 17);
|
|
return {
|
|
z: r & 127,
|
|
x: k(e, t * 17 + 1),
|
|
y: k(e, t * 17 + 4),
|
|
offset: be(e, t * 17 + 7),
|
|
length: e.getUint32(t * 17 + 13, !0),
|
|
isDir: r >> 7 === 1
|
|
};
|
|
}, de = (e) => {
|
|
const t = [], r = new DataView(e);
|
|
for (let n = 0; n < r.byteLength / 17; n++)
|
|
t.push(Ee(r, n));
|
|
return it(t);
|
|
}, it = (e) => {
|
|
e.sort(nt);
|
|
const t = new ArrayBuffer(17 * e.length), r = new Uint8Array(t);
|
|
for (let n = 0; n < e.length; n++) {
|
|
const i = e[n];
|
|
let o = i.z;
|
|
i.isDir && (o = o | 128), r[n * 17] = o, r[n * 17 + 1] = i.x & 255, r[n * 17 + 2] = i.x >> 8 & 255, r[n * 17 + 3] = i.x >> 16 & 255, r[n * 17 + 4] = i.y & 255, r[n * 17 + 5] = i.y >> 8 & 255, r[n * 17 + 6] = i.y >> 16 & 255, r[n * 17 + 7] = i.offset & 255, r[n * 17 + 8] = Z(i.offset, 8) & 255, r[n * 17 + 9] = Z(i.offset, 16) & 255, r[n * 17 + 10] = Z(i.offset, 24) & 255, r[n * 17 + 11] = Z(i.offset, 32) & 255, r[n * 17 + 12] = Z(i.offset, 48) & 255, r[n * 17 + 13] = i.length & 255, r[n * 17 + 14] = i.length >> 8 & 255, r[n * 17 + 15] = i.length >> 16 & 255, r[n * 17 + 16] = i.length >> 24 & 255;
|
|
}
|
|
return t;
|
|
}, ot = (e, t) => {
|
|
if (e.byteLength < 17)
|
|
return null;
|
|
const r = e.byteLength / 17, n = Ee(e, r - 1);
|
|
if (n.isDir) {
|
|
const i = n.z, o = t.z - i, s = Math.trunc(t.x / (1 << o)), c = Math.trunc(t.y / (1 << o));
|
|
return { z: i, x: s, y: c };
|
|
}
|
|
return null;
|
|
};
|
|
function st(e) {
|
|
return g(this, null, function* () {
|
|
const t = yield e.getBytes(0, 512e3), r = new DataView(t.data), n = r.getUint32(4, !0), i = r.getUint16(8, !0), o = new TextDecoder("utf-8"), s = JSON.parse(
|
|
o.decode(new DataView(t.data, 10, n))
|
|
);
|
|
let c = 0;
|
|
s.compression === "gzip" && (c = 2);
|
|
let u = 0;
|
|
"minzoom" in s && (u = +s.minzoom);
|
|
let f = 0;
|
|
"maxzoom" in s && (f = +s.maxzoom);
|
|
let a = 0, l = 0, d = 0, m = -180, v = -85, U = 180, T = 85;
|
|
if (s.bounds) {
|
|
const y = s.bounds.split(",");
|
|
m = +y[0], v = +y[1], U = +y[2], T = +y[3];
|
|
}
|
|
if (s.center) {
|
|
const y = s.center.split(",");
|
|
a = +y[0], l = +y[1], d = +y[2];
|
|
}
|
|
return {
|
|
specVersion: r.getUint16(2, !0),
|
|
rootDirectoryOffset: 10 + n,
|
|
rootDirectoryLength: i * 17,
|
|
jsonMetadataOffset: 10,
|
|
jsonMetadataLength: n,
|
|
leafDirectoryOffset: 0,
|
|
leafDirectoryLength: void 0,
|
|
tileDataOffset: 0,
|
|
tileDataLength: void 0,
|
|
numAddressedTiles: 0,
|
|
numTileEntries: 0,
|
|
numTileContents: 0,
|
|
clustered: !1,
|
|
internalCompression: 1,
|
|
tileCompression: c,
|
|
tileType: 1,
|
|
minZoom: u,
|
|
maxZoom: f,
|
|
minLon: m,
|
|
minLat: v,
|
|
maxLon: U,
|
|
maxLat: T,
|
|
centerZoom: d,
|
|
centerLon: a,
|
|
centerLat: l,
|
|
etag: t.etag
|
|
};
|
|
});
|
|
}
|
|
function at(e, t, r, n, i, o, s) {
|
|
return g(this, null, function* () {
|
|
let c = yield r.getArrayBuffer(
|
|
t,
|
|
e.rootDirectoryOffset,
|
|
e.rootDirectoryLength,
|
|
e
|
|
);
|
|
e.specVersion === 1 && (c = de(c));
|
|
const u = he(new DataView(c), n, i, o);
|
|
if (u) {
|
|
let l = (yield t.getBytes(u.offset, u.length, s)).data;
|
|
const d = new DataView(l);
|
|
return d.getUint8(0) === 31 && d.getUint8(1) === 139 && (l = X(new Uint8Array(l))), {
|
|
data: l
|
|
};
|
|
}
|
|
const f = ot(new DataView(c), { z: n, x: i, y: o });
|
|
if (f) {
|
|
const a = rt(
|
|
new DataView(c),
|
|
f.z,
|
|
f.x,
|
|
f.y
|
|
);
|
|
if (a) {
|
|
let l = yield r.getArrayBuffer(
|
|
t,
|
|
a.offset,
|
|
a.length,
|
|
e
|
|
);
|
|
e.specVersion === 1 && (l = de(l));
|
|
const d = he(new DataView(l), n, i, o);
|
|
if (d) {
|
|
let v = (yield t.getBytes(
|
|
d.offset,
|
|
d.length,
|
|
s
|
|
)).data;
|
|
const U = new DataView(v);
|
|
return U.getUint8(0) === 31 && U.getUint8(1) === 139 && (v = X(new Uint8Array(v))), {
|
|
data: v
|
|
};
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
var ze = {
|
|
getHeader: st,
|
|
getZxy: at
|
|
}, Dt = (e, t) => {
|
|
let r = !1, n = "";
|
|
const i = L.GridLayer.extend({
|
|
createTile: (o, s) => {
|
|
const c = document.createElement("img"), u = new AbortController(), f = u.signal;
|
|
return c.cancel = () => {
|
|
u.abort();
|
|
}, r || (e.getHeader().then((a) => {
|
|
a.tileType === 1 ? console.error(
|
|
"Error: archive contains MVT vector tiles, but leafletRasterLayer is for displaying raster tiles. See https://github.com/protomaps/PMTiles/tree/main/js for details."
|
|
) : a.tileType === 2 ? n = "image/png" : a.tileType === 3 ? n = "image/jpeg" : a.tileType === 4 ? n = "image/webp" : a.tileType === 5 && (n = "image/avif");
|
|
}), r = !0), e.getZxy(o.z, o.x, o.y, f).then((a) => {
|
|
if (a) {
|
|
const l = new Blob([a.data], { type: n }), d = window.URL.createObjectURL(l);
|
|
c.src = d, c.cancel = void 0, s(void 0, c);
|
|
}
|
|
}).catch((a) => {
|
|
if (a.name !== "AbortError")
|
|
throw a;
|
|
}), c;
|
|
},
|
|
_removeTile: function(o) {
|
|
const s = this._tiles[o];
|
|
s && (s.el.cancel && s.el.cancel(), s.el.width = 0, s.el.height = 0, s.el.deleted = !0, L.DomUtil.remove(s.el), delete this._tiles[o], this.fire("tileunload", {
|
|
tile: s.el,
|
|
coords: this._keyToTileCoords(o)
|
|
}));
|
|
}
|
|
});
|
|
return new i(t);
|
|
}, ct = (e) => (t, r) => {
|
|
if (r instanceof AbortController)
|
|
return e(t, r);
|
|
const n = new AbortController();
|
|
return e(t, n).then(
|
|
(i) => r(
|
|
void 0,
|
|
i.data,
|
|
i.cacheControl || "",
|
|
i.expires || ""
|
|
),
|
|
(i) => r(i)
|
|
).catch((i) => r(i)), { cancel: () => n.abort() };
|
|
}, bt = class {
|
|
/**
|
|
* Initialize the MapLibre PMTiles protocol.
|
|
*
|
|
* * metadata: also load the metadata section of the PMTiles. required for some "inspect" functionality
|
|
* and to automatically populate the map attribution. Requires an extra HTTP request.
|
|
*/
|
|
constructor(e) {
|
|
this.tilev4 = (t, r) => g(this, null, function* () {
|
|
if (t.type === "json") {
|
|
const d = t.url.substr(10);
|
|
let m = this.tiles.get(d);
|
|
if (m || (m = new ge(d), this.tiles.set(d, m)), this.metadata)
|
|
return {
|
|
data: yield m.getTileJson(t.url)
|
|
};
|
|
const v = yield m.getHeader();
|
|
return {
|
|
data: {
|
|
tiles: [`${t.url}/{z}/{x}/{y}`],
|
|
minzoom: v.minZoom,
|
|
maxzoom: v.maxZoom,
|
|
bounds: [v.minLon, v.minLat, v.maxLon, v.maxLat]
|
|
}
|
|
};
|
|
}
|
|
const n = new RegExp(/pmtiles:\/\/(.+)\/(\d+)\/(\d+)\/(\d+)/), i = t.url.match(n);
|
|
if (!i)
|
|
throw new Error("Invalid PMTiles protocol URL");
|
|
const o = i[1];
|
|
let s = this.tiles.get(o);
|
|
s || (s = new ge(o), this.tiles.set(o, s));
|
|
const c = i[2], u = i[3], f = i[4], a = yield s.getHeader(), l = yield s?.getZxy(+c, +u, +f, r.signal);
|
|
return l ? {
|
|
data: new Uint8Array(l.data),
|
|
cacheControl: l.cacheControl,
|
|
expires: l.expires
|
|
} : a.tileType === 1 ? { data: new Uint8Array() } : { data: null };
|
|
}), this.tile = ct(this.tilev4), this.tiles = /* @__PURE__ */ new Map(), this.metadata = e?.metadata || !1;
|
|
}
|
|
/**
|
|
* Add a {@link PMTiles} instance to the global protocol instance.
|
|
*
|
|
* For remote fetch sources, references in MapLibre styles like pmtiles://http://...
|
|
* will resolve to the same instance if the URLs match.
|
|
*/
|
|
add(e) {
|
|
this.tiles.set(e.source.getKey(), e);
|
|
}
|
|
/**
|
|
* Fetch a {@link PMTiles} instance by URL, for remote PMTiles instances.
|
|
*/
|
|
get(e) {
|
|
return this.tiles.get(e);
|
|
}
|
|
};
|
|
function $(e, t) {
|
|
return (t >>> 0) * 4294967296 + (e >>> 0);
|
|
}
|
|
function lt(e, t) {
|
|
const r = t.buf;
|
|
let n = r[t.pos++], i = (n & 112) >> 4;
|
|
if (n < 128 || (n = r[t.pos++], i |= (n & 127) << 3, n < 128) || (n = r[t.pos++], i |= (n & 127) << 10, n < 128) || (n = r[t.pos++], i |= (n & 127) << 17, n < 128) || (n = r[t.pos++], i |= (n & 127) << 24, n < 128) || (n = r[t.pos++], i |= (n & 1) << 31, n < 128))
|
|
return $(e, i);
|
|
throw new Error("Expected varint not more than 10 bytes");
|
|
}
|
|
function H(e) {
|
|
const t = e.buf;
|
|
let r = t[e.pos++], n = r & 127;
|
|
return r < 128 || (r = t[e.pos++], n |= (r & 127) << 7, r < 128) || (r = t[e.pos++], n |= (r & 127) << 14, r < 128) || (r = t[e.pos++], n |= (r & 127) << 21, r < 128) ? n : (r = t[e.pos], n |= (r & 15) << 28, lt(n, e));
|
|
}
|
|
function Me(e, t, r, n) {
|
|
if (n === 0) {
|
|
r === 1 && (t[0] = e - 1 - t[0], t[1] = e - 1 - t[1]);
|
|
const i = t[0];
|
|
t[0] = t[1], t[1] = i;
|
|
}
|
|
}
|
|
function ut(e, t) {
|
|
const r = M(2, e);
|
|
let n = t, i = t, o = t;
|
|
const s = [0, 0];
|
|
let c = 1;
|
|
for (; c < r; )
|
|
n = 1 & o / 2, i = 1 & (o ^ n), Me(c, s, n, i), s[0] += c * n, s[1] += c * i, o = o / 4, c *= 2;
|
|
return [e, s[0], s[1]];
|
|
}
|
|
var ft = [
|
|
0,
|
|
1,
|
|
5,
|
|
21,
|
|
85,
|
|
341,
|
|
1365,
|
|
5461,
|
|
21845,
|
|
87381,
|
|
349525,
|
|
1398101,
|
|
5592405,
|
|
22369621,
|
|
89478485,
|
|
357913941,
|
|
1431655765,
|
|
5726623061,
|
|
22906492245,
|
|
91625968981,
|
|
366503875925,
|
|
1466015503701,
|
|
5864062014805,
|
|
23456248059221,
|
|
93824992236885,
|
|
375299968947541,
|
|
1501199875790165
|
|
];
|
|
function ht(e, t, r) {
|
|
if (e > 26)
|
|
throw Error("Tile zoom level exceeds max safe number limit (26)");
|
|
if (t > M(2, e) - 1 || r > M(2, e) - 1)
|
|
throw Error("tile x/y outside zoom level bounds");
|
|
const n = ft[e], i = M(2, e);
|
|
let o = 0, s = 0, c = 0;
|
|
const u = [t, r];
|
|
let f = i / 2;
|
|
for (; f > 0; )
|
|
o = (u[0] & f) > 0 ? 1 : 0, s = (u[1] & f) > 0 ? 1 : 0, c += f * f * (3 * o ^ s), Me(f, u, o, s), f = f / 2;
|
|
return n + c;
|
|
}
|
|
function Lt(e) {
|
|
let t = 0;
|
|
for (let r = 0; r < 27; r++) {
|
|
const n = (1 << r) * (1 << r);
|
|
if (t + n > e)
|
|
return ut(r, e - t);
|
|
t += n;
|
|
}
|
|
throw Error("Tile zoom level exceeds max safe number limit (26)");
|
|
}
|
|
var dt = /* @__PURE__ */ ((e) => (e[e.Unknown = 0] = "Unknown", e[e.None = 1] = "None", e[e.Gzip = 2] = "Gzip", e[e.Brotli = 3] = "Brotli", e[e.Zstd = 4] = "Zstd", e))(dt || {});
|
|
function te(e, t) {
|
|
return g(this, null, function* () {
|
|
if (t === 1 || t === 0)
|
|
return e;
|
|
if (t === 2) {
|
|
if (typeof globalThis.DecompressionStream > "u")
|
|
return X(new Uint8Array(e));
|
|
const r = new Response(e).body;
|
|
if (!r)
|
|
throw Error("Failed to read response stream");
|
|
const n = r.pipeThrough(
|
|
// biome-ignore lint: needed to detect DecompressionStream in browser+node+cloudflare workers
|
|
new globalThis.DecompressionStream("gzip")
|
|
);
|
|
return new Response(n).arrayBuffer();
|
|
}
|
|
throw Error("Compression method not supported");
|
|
});
|
|
}
|
|
var gt = /* @__PURE__ */ ((e) => (e[e.Unknown = 0] = "Unknown", e[e.Mvt = 1] = "Mvt", e[e.Png = 2] = "Png", e[e.Jpeg = 3] = "Jpeg", e[e.Webp = 4] = "Webp", e[e.Avif = 5] = "Avif", e))(gt || {});
|
|
function vt(e) {
|
|
return e === 1 ? ".mvt" : e === 2 ? ".png" : e === 3 ? ".jpg" : e === 4 ? ".webp" : e === 5 ? ".avif" : "";
|
|
}
|
|
var yt = 127;
|
|
function mt(e, t) {
|
|
let r = 0, n = e.length - 1;
|
|
for (; r <= n; ) {
|
|
const i = n + r >> 1, o = t - e[i].tileId;
|
|
if (o > 0)
|
|
r = i + 1;
|
|
else if (o < 0)
|
|
n = i - 1;
|
|
else
|
|
return e[i];
|
|
}
|
|
return n >= 0 && (e[n].runLength === 0 || t - e[n].tileId < e[n].runLength) ? e[n] : null;
|
|
}
|
|
var Et = class {
|
|
constructor(e) {
|
|
this.file = e;
|
|
}
|
|
getKey() {
|
|
return this.file.name;
|
|
}
|
|
getBytes(e, t) {
|
|
return g(this, null, function* () {
|
|
return { data: yield this.file.slice(e, e + t).arrayBuffer() };
|
|
});
|
|
}
|
|
}, pt = class {
|
|
constructor(e, t = new Headers()) {
|
|
this.url = e, this.customHeaders = t, this.mustReload = !1;
|
|
let r = "";
|
|
"navigator" in globalThis && (r = globalThis.navigator.userAgent || "");
|
|
const n = r.indexOf("Windows") > -1, i = /Chrome|Chromium|Edg|OPR|Brave/.test(r);
|
|
this.chromeWindowsNoCache = !1, n && i && (this.chromeWindowsNoCache = !0);
|
|
}
|
|
getKey() {
|
|
return this.url;
|
|
}
|
|
/**
|
|
* Mutate the custom [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) set for all requests to the remote archive.
|
|
*/
|
|
setHeaders(e) {
|
|
this.customHeaders = e;
|
|
}
|
|
getBytes(e, t, r, n) {
|
|
return g(this, null, function* () {
|
|
let i, o;
|
|
r ? o = r : (i = new AbortController(), o = i.signal);
|
|
const s = new Headers(this.customHeaders);
|
|
s.set("range", `bytes=${e}-${e + t - 1}`);
|
|
let c;
|
|
this.mustReload ? c = "reload" : this.chromeWindowsNoCache && (c = "no-store");
|
|
let u = yield fetch(this.url, {
|
|
signal: o,
|
|
cache: c,
|
|
headers: s
|
|
//biome-ignore lint: "cache" is incompatible between cloudflare workers and browser
|
|
});
|
|
if (e === 0 && u.status === 416) {
|
|
const d = u.headers.get("Content-Range");
|
|
if (!d || !d.startsWith("bytes */"))
|
|
throw Error("Missing content-length on 416 response");
|
|
const m = +d.substr(8);
|
|
u = yield fetch(this.url, {
|
|
signal: o,
|
|
cache: "reload",
|
|
headers: { range: `bytes=0-${m - 1}` }
|
|
//biome-ignore lint: "cache" is incompatible between cloudflare workers and browser
|
|
});
|
|
}
|
|
let f = u.headers.get("Etag");
|
|
if (f?.startsWith("W/") && (f = null), u.status === 416 || n && f && f !== n)
|
|
throw this.mustReload = !0, new Q(
|
|
`Server returned non-matching ETag ${n} after one retry. Check browser extensions and servers for issues that may affect correct ETag headers.`
|
|
);
|
|
if (u.status >= 300)
|
|
throw Error(`Bad response code: ${u.status}`);
|
|
const a = u.headers.get("Content-Length");
|
|
if (u.status === 200 && (!a || +a > t))
|
|
throw i && i.abort(), Error(
|
|
"Server returned no content-length header or content-length exceeding request. Check that your storage backend supports HTTP Byte Serving."
|
|
);
|
|
return {
|
|
data: yield u.arrayBuffer(),
|
|
etag: f || void 0,
|
|
cacheControl: u.headers.get("Cache-Control") || void 0,
|
|
expires: u.headers.get("Expires") || void 0
|
|
};
|
|
});
|
|
}
|
|
};
|
|
function E(e, t) {
|
|
const r = e.getUint32(t + 4, !0), n = e.getUint32(t + 0, !0);
|
|
return r * M(2, 32) + n;
|
|
}
|
|
function wt(e, t) {
|
|
const r = new DataView(e), n = r.getUint8(7);
|
|
if (n > 3)
|
|
throw Error(
|
|
`Archive is spec version ${n} but this library supports up to spec version 3`
|
|
);
|
|
return {
|
|
specVersion: n,
|
|
rootDirectoryOffset: E(r, 8),
|
|
rootDirectoryLength: E(r, 16),
|
|
jsonMetadataOffset: E(r, 24),
|
|
jsonMetadataLength: E(r, 32),
|
|
leafDirectoryOffset: E(r, 40),
|
|
leafDirectoryLength: E(r, 48),
|
|
tileDataOffset: E(r, 56),
|
|
tileDataLength: E(r, 64),
|
|
numAddressedTiles: E(r, 72),
|
|
numTileEntries: E(r, 80),
|
|
numTileContents: E(r, 88),
|
|
clustered: r.getUint8(96) === 1,
|
|
internalCompression: r.getUint8(97),
|
|
tileCompression: r.getUint8(98),
|
|
tileType: r.getUint8(99),
|
|
minZoom: r.getUint8(100),
|
|
maxZoom: r.getUint8(101),
|
|
minLon: r.getInt32(102, !0) / 1e7,
|
|
minLat: r.getInt32(106, !0) / 1e7,
|
|
maxLon: r.getInt32(110, !0) / 1e7,
|
|
maxLat: r.getInt32(114, !0) / 1e7,
|
|
centerZoom: r.getUint8(118),
|
|
centerLon: r.getInt32(119, !0) / 1e7,
|
|
centerLat: r.getInt32(123, !0) / 1e7,
|
|
etag: t
|
|
};
|
|
}
|
|
function Te(e) {
|
|
const t = { buf: new Uint8Array(e), pos: 0 }, r = H(t), n = [];
|
|
let i = 0;
|
|
for (let o = 0; o < r; o++) {
|
|
const s = H(t);
|
|
n.push({ tileId: i + s, offset: 0, length: 0, runLength: 1 }), i += s;
|
|
}
|
|
for (let o = 0; o < r; o++)
|
|
n[o].runLength = H(t);
|
|
for (let o = 0; o < r; o++)
|
|
n[o].length = H(t);
|
|
for (let o = 0; o < r; o++) {
|
|
const s = H(t);
|
|
s === 0 && o > 0 ? n[o].offset = n[o - 1].offset + n[o - 1].length : n[o].offset = s - 1;
|
|
}
|
|
return n;
|
|
}
|
|
function xt(e) {
|
|
const t = new DataView(e);
|
|
return t.getUint16(2, !0) === 2 ? (console.warn(
|
|
"PMTiles spec version 2 has been deprecated; please see github.com/protomaps/PMTiles for tools to upgrade"
|
|
), 2) : t.getUint16(2, !0) === 1 ? (console.warn(
|
|
"PMTiles spec version 1 has been deprecated; please see github.com/protomaps/PMTiles for tools to upgrade"
|
|
), 1) : 3;
|
|
}
|
|
var Q = class extends Error {
|
|
};
|
|
function Ae(e, t) {
|
|
return g(this, null, function* () {
|
|
const r = yield e.getBytes(0, 16384);
|
|
if (new DataView(r.data).getUint16(0, !0) !== 19792)
|
|
throw new Error("Wrong magic number for PMTiles archive");
|
|
if (xt(r.data) < 3)
|
|
return [yield ze.getHeader(e)];
|
|
const i = r.data.slice(0, yt), o = wt(i, r.etag), s = r.data.slice(
|
|
o.rootDirectoryOffset,
|
|
o.rootDirectoryOffset + o.rootDirectoryLength
|
|
), c = `${e.getKey()}|${o.etag || ""}|${o.rootDirectoryOffset}|${o.rootDirectoryLength}`, u = Te(
|
|
yield t(s, o.internalCompression)
|
|
);
|
|
return [o, [c, u.length, u]];
|
|
});
|
|
}
|
|
function Ce(e, t, r, n, i) {
|
|
return g(this, null, function* () {
|
|
const o = yield e.getBytes(r, n, void 0, i.etag), s = yield t(o.data, i.internalCompression), c = Te(s);
|
|
if (c.length === 0)
|
|
throw new Error("Empty directory is invalid");
|
|
return c;
|
|
});
|
|
}
|
|
var zt = class {
|
|
constructor(e = 100, t = !0, r = te) {
|
|
this.cache = /* @__PURE__ */ new Map(), this.maxCacheEntries = e, this.counter = 1, this.decompress = r;
|
|
}
|
|
getHeader(e) {
|
|
return g(this, null, function* () {
|
|
const t = e.getKey(), r = this.cache.get(t);
|
|
if (r)
|
|
return r.lastUsed = this.counter++, r.data;
|
|
const n = yield Ae(e, this.decompress);
|
|
return n[1] && this.cache.set(n[1][0], {
|
|
lastUsed: this.counter++,
|
|
data: n[1][2]
|
|
}), this.cache.set(t, {
|
|
lastUsed: this.counter++,
|
|
data: n[0]
|
|
}), this.prune(), n[0];
|
|
});
|
|
}
|
|
getDirectory(e, t, r, n) {
|
|
return g(this, null, function* () {
|
|
const i = `${e.getKey()}|${n.etag || ""}|${t}|${r}`, o = this.cache.get(i);
|
|
if (o)
|
|
return o.lastUsed = this.counter++, o.data;
|
|
const s = yield Ce(
|
|
e,
|
|
this.decompress,
|
|
t,
|
|
r,
|
|
n
|
|
);
|
|
return this.cache.set(i, {
|
|
lastUsed: this.counter++,
|
|
data: s
|
|
}), this.prune(), s;
|
|
});
|
|
}
|
|
// for v2 backwards compatibility
|
|
getArrayBuffer(e, t, r, n) {
|
|
return g(this, null, function* () {
|
|
const i = `${e.getKey()}|${n.etag || ""}|${t}|${r}`, o = this.cache.get(i);
|
|
if (o)
|
|
return o.lastUsed = this.counter++, yield o.data;
|
|
const s = yield e.getBytes(t, r, void 0, n.etag);
|
|
return this.cache.set(i, {
|
|
lastUsed: this.counter++,
|
|
data: s.data
|
|
}), this.prune(), s.data;
|
|
});
|
|
}
|
|
prune() {
|
|
if (this.cache.size > this.maxCacheEntries) {
|
|
let e = 1 / 0, t;
|
|
this.cache.forEach((r, n) => {
|
|
r.lastUsed < e && (e = r.lastUsed, t = n);
|
|
}), t && this.cache.delete(t);
|
|
}
|
|
}
|
|
invalidate(e) {
|
|
return g(this, null, function* () {
|
|
this.cache.delete(e.getKey());
|
|
});
|
|
}
|
|
}, Ut = class {
|
|
constructor(e = 100, t = !0, r = te) {
|
|
this.cache = /* @__PURE__ */ new Map(), this.invalidations = /* @__PURE__ */ new Map(), this.maxCacheEntries = e, this.counter = 1, this.decompress = r;
|
|
}
|
|
getHeader(e) {
|
|
return g(this, null, function* () {
|
|
const t = e.getKey(), r = this.cache.get(t);
|
|
if (r)
|
|
return r.lastUsed = this.counter++, yield r.data;
|
|
const n = new Promise((i, o) => {
|
|
Ae(e, this.decompress).then((s) => {
|
|
s[1] && this.cache.set(s[1][0], {
|
|
lastUsed: this.counter++,
|
|
data: Promise.resolve(s[1][2])
|
|
}), i(s[0]), this.prune();
|
|
}).catch((s) => {
|
|
o(s);
|
|
});
|
|
});
|
|
return this.cache.set(t, { lastUsed: this.counter++, data: n }), n;
|
|
});
|
|
}
|
|
getDirectory(e, t, r, n) {
|
|
return g(this, null, function* () {
|
|
const i = `${e.getKey()}|${n.etag || ""}|${t}|${r}`, o = this.cache.get(i);
|
|
if (o)
|
|
return o.lastUsed = this.counter++, yield o.data;
|
|
const s = new Promise((c, u) => {
|
|
Ce(e, this.decompress, t, r, n).then((f) => {
|
|
c(f), this.prune();
|
|
}).catch((f) => {
|
|
u(f);
|
|
});
|
|
});
|
|
return this.cache.set(i, { lastUsed: this.counter++, data: s }), s;
|
|
});
|
|
}
|
|
// for v2 backwards compatibility
|
|
getArrayBuffer(e, t, r, n) {
|
|
return g(this, null, function* () {
|
|
const i = `${e.getKey()}|${n.etag || ""}|${t}|${r}`, o = this.cache.get(i);
|
|
if (o)
|
|
return o.lastUsed = this.counter++, yield o.data;
|
|
const s = new Promise((c, u) => {
|
|
e.getBytes(t, r, void 0, n.etag).then((f) => {
|
|
c(f.data), this.cache.has(i), this.prune();
|
|
}).catch((f) => {
|
|
u(f);
|
|
});
|
|
});
|
|
return this.cache.set(i, { lastUsed: this.counter++, data: s }), s;
|
|
});
|
|
}
|
|
prune() {
|
|
if (this.cache.size >= this.maxCacheEntries) {
|
|
let e = 1 / 0, t;
|
|
this.cache.forEach((r, n) => {
|
|
r.lastUsed < e && (e = r.lastUsed, t = n);
|
|
}), t && this.cache.delete(t);
|
|
}
|
|
}
|
|
invalidate(e) {
|
|
return g(this, null, function* () {
|
|
const t = e.getKey();
|
|
if (this.invalidations.get(t))
|
|
return yield this.invalidations.get(t);
|
|
this.cache.delete(e.getKey());
|
|
const r = new Promise((n, i) => {
|
|
this.getHeader(e).then((o) => {
|
|
n(), this.invalidations.delete(t);
|
|
}).catch((o) => {
|
|
i(o);
|
|
});
|
|
});
|
|
this.invalidations.set(t, r);
|
|
});
|
|
}
|
|
}, ge = class {
|
|
constructor(e, t, r) {
|
|
typeof e == "string" ? this.source = new pt(e) : this.source = e, r ? this.decompress = r : this.decompress = te, t ? this.cache = t : this.cache = new Ut();
|
|
}
|
|
/**
|
|
* Return the header of the archive,
|
|
* including information such as tile type, min/max zoom, bounds, and summary statistics.
|
|
*/
|
|
getHeader() {
|
|
return g(this, null, function* () {
|
|
return yield this.cache.getHeader(this.source);
|
|
});
|
|
}
|
|
/** @hidden */
|
|
getZxyAttempt(e, t, r, n) {
|
|
return g(this, null, function* () {
|
|
const i = ht(e, t, r), o = yield this.cache.getHeader(this.source);
|
|
if (o.specVersion < 3)
|
|
return ze.getZxy(o, this.source, this.cache, e, t, r, n);
|
|
if (e < o.minZoom || e > o.maxZoom)
|
|
return;
|
|
let s = o.rootDirectoryOffset, c = o.rootDirectoryLength;
|
|
for (let u = 0; u <= 3; u++) {
|
|
const f = yield this.cache.getDirectory(
|
|
this.source,
|
|
s,
|
|
c,
|
|
o
|
|
), a = mt(f, i);
|
|
if (a) {
|
|
if (a.runLength > 0) {
|
|
const l = yield this.source.getBytes(
|
|
o.tileDataOffset + a.offset,
|
|
a.length,
|
|
n,
|
|
o.etag
|
|
);
|
|
return {
|
|
data: yield this.decompress(l.data, o.tileCompression),
|
|
cacheControl: l.cacheControl,
|
|
expires: l.expires
|
|
};
|
|
}
|
|
s = o.leafDirectoryOffset + a.offset, c = a.length;
|
|
} else
|
|
return;
|
|
}
|
|
throw Error("Maximum directory depth exceeded");
|
|
});
|
|
}
|
|
/**
|
|
* Primary method to get a single tile's bytes from an archive.
|
|
*
|
|
* Returns undefined if the tile does not exist in the archive.
|
|
*/
|
|
getZxy(e, t, r, n) {
|
|
return g(this, null, function* () {
|
|
try {
|
|
return yield this.getZxyAttempt(e, t, r, n);
|
|
} catch (i) {
|
|
if (i instanceof Q)
|
|
return this.cache.invalidate(this.source), yield this.getZxyAttempt(e, t, r, n);
|
|
throw i;
|
|
}
|
|
});
|
|
}
|
|
/** @hidden */
|
|
getMetadataAttempt() {
|
|
return g(this, null, function* () {
|
|
const e = yield this.cache.getHeader(this.source), t = yield this.source.getBytes(
|
|
e.jsonMetadataOffset,
|
|
e.jsonMetadataLength,
|
|
void 0,
|
|
e.etag
|
|
), r = yield this.decompress(
|
|
t.data,
|
|
e.internalCompression
|
|
), n = new TextDecoder("utf-8");
|
|
return JSON.parse(n.decode(r));
|
|
});
|
|
}
|
|
/**
|
|
* Return the arbitrary JSON metadata of the archive.
|
|
*/
|
|
getMetadata() {
|
|
return g(this, null, function* () {
|
|
try {
|
|
return yield this.getMetadataAttempt();
|
|
} catch (e) {
|
|
if (e instanceof Q)
|
|
return this.cache.invalidate(this.source), yield this.getMetadataAttempt();
|
|
throw e;
|
|
}
|
|
});
|
|
}
|
|
/**
|
|
* Construct a [TileJSON](https://github.com/mapbox/tilejson-spec) object.
|
|
*
|
|
* baseTilesUrl is the desired tiles URL, excluding the suffix `/{z}/{x}/{y}.{ext}`.
|
|
* For example, if the desired URL is `http://example.com/tileset/{z}/{x}/{y}.mvt`,
|
|
* the baseTilesUrl should be `https://example.com/tileset`.
|
|
*/
|
|
getTileJson(e) {
|
|
return g(this, null, function* () {
|
|
const t = yield this.getHeader(), r = yield this.getMetadata(), n = vt(t.tileType);
|
|
return {
|
|
tilejson: "3.0.0",
|
|
scheme: "xyz",
|
|
tiles: [`${e}/{z}/{x}/{y}${n}`],
|
|
// biome-ignore lint: TileJSON spec
|
|
vector_layers: r.vector_layers,
|
|
attribution: r.attribution,
|
|
description: r.description,
|
|
name: r.name,
|
|
version: r.version,
|
|
bounds: [t.minLon, t.minLat, t.maxLon, t.maxLat],
|
|
center: [t.centerLon, t.centerLat, t.centerZoom],
|
|
minzoom: t.minZoom,
|
|
maxzoom: t.maxZoom
|
|
};
|
|
});
|
|
}
|
|
};
|
|
export {
|
|
dt as Compression,
|
|
Q as EtagMismatch,
|
|
pt as FetchSource,
|
|
Et as FileSource,
|
|
ge as PMTiles,
|
|
bt as Protocol,
|
|
zt as ResolvedValueCache,
|
|
Ut as SharedPromiseCache,
|
|
gt as TileType,
|
|
wt as bytesToHeader,
|
|
mt as findTile,
|
|
E as getUint64,
|
|
Dt as leafletRasterLayer,
|
|
H as readVarint,
|
|
Lt as tileIdToZxy,
|
|
vt as tileTypeExt,
|
|
ht as zxyToTileId
|
|
};
|