@india-boundary-corrector/leaflet-layer 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,3065 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.js
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ LayerConfig: () => LayerConfig,
24
+ extendLeaflet: () => extendLeaflet,
25
+ getPmtilesUrl: () => import_data2.getPmtilesUrl,
26
+ layerConfigs: () => layerConfigs
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+ var import_data = require("@india-boundary-corrector/data");
30
+
31
+ // ../layer-configs/dist/index.js
32
+ var configs_default = [
33
+ {
34
+ id: "cartodb-dark",
35
+ zoomThreshold: 5,
36
+ tileUrlTemplates: [
37
+ "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
38
+ "https://basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
39
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}{r}.png",
40
+ "https://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png",
41
+ "https://basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png",
42
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_nolabels/{z}/{x}/{y}{r}.png"
43
+ ],
44
+ lineWidthStops: { "1": 0.5, "10": 2.5 },
45
+ lineStyles: [
46
+ { color: "rgb(40, 40, 40)" }
47
+ ]
48
+ },
49
+ {
50
+ id: "cartodb-light",
51
+ startZoom: 0,
52
+ zoomThreshold: 5,
53
+ tileUrlTemplates: [
54
+ "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",
55
+ "https://basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",
56
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}{r}.png",
57
+ "https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png",
58
+ "https://basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png",
59
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_nolabels/{z}/{x}/{y}{r}.png",
60
+ "https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png",
61
+ "https://basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png",
62
+ "https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}{r}.png",
63
+ "https://basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}{r}.png",
64
+ "https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png",
65
+ "https://basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png"
66
+ ],
67
+ lineWidthStops: { "1": 0.25, "2": 0.25, "3": 0.5, "4": 0.75, "5": 1 },
68
+ lineStyles: [
69
+ { color: "rgb(235, 214, 214)", alpha: 0.2, startZoom: 6, widthFraction: 5 },
70
+ { color: "rgb(235, 214, 214)" }
71
+ ]
72
+ },
73
+ {
74
+ id: "open-topo",
75
+ startZoom: 4,
76
+ zoomThreshold: 4,
77
+ tileUrlTemplates: [
78
+ "https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png",
79
+ "https://tile.opentopomap.org/{z}/{x}/{y}.png"
80
+ ],
81
+ lineWidthStops: { "4": 0.75, "5": 1, "6": 1.25, "7": 1.5, "8": 1.75, "9": 1.25, "10": 1.25, "13": 1.5 },
82
+ lineStyles: [
83
+ { color: "rgb(83, 83, 83)", startZoom: 7, endZoom: 8, alpha: 0.4, widthFraction: 4 },
84
+ { color: "rgb(83, 83, 83)", endZoom: 8 },
85
+ { color: "rgb(140, 20, 180)", startZoom: 9, widthFraction: 9, alpha: 0.2 },
86
+ { color: "rgb(140, 20, 180)", startZoom: 9 }
87
+ ]
88
+ },
89
+ {
90
+ id: "osm-carto",
91
+ startZoom: 1,
92
+ zoomThreshold: 1,
93
+ tileUrlTemplates: [
94
+ "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
95
+ "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
96
+ ],
97
+ lineWidthStops: { "1": 0.5, "2": 0.6, "3": 0.7, "4": 1, "10": 3.75 },
98
+ lineStyles: [
99
+ { color: "rgb(200, 180, 200)" },
100
+ { color: "rgb(160, 120, 160)", widthFraction: 0.333, dashArray: [30, 2, 8, 2] }
101
+ ]
102
+ },
103
+ {
104
+ id: "osm-hot",
105
+ startZoom: 2,
106
+ zoomThreshold: 2,
107
+ tileUrlTemplates: [
108
+ "https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png"
109
+ ],
110
+ lineWidthStops: { "2": 3, "3": 3, "7": 3, "8": 3.5, "9": 3.5 },
111
+ lineStyles: [
112
+ { color: "rgb(149, 175, 180)" },
113
+ { color: "rgb(89, 117, 123)", widthFraction: 0.33 }
114
+ ]
115
+ }
116
+ ];
117
+ function templateToRegex(template) {
118
+ const groups = [];
119
+ let pattern = template.replace(/[.*+?^${}()|[\]\\]/g, (char) => {
120
+ if (char === "{" || char === "}") return char;
121
+ return "\\" + char;
122
+ }).replace(/^https:\/\//, "https?://").replace(/^http:\/\//, "https?://").replace(/\{[a-z0-9]-[a-z0-9]\}/gi, () => {
123
+ groups.push("s");
124
+ return "([a-z0-9]+)";
125
+ }).replace(/\{(z|x|y|s|r)\}/gi, (_2, name) => {
126
+ const lowerName = name.toLowerCase();
127
+ groups.push(lowerName);
128
+ if (lowerName === "s") {
129
+ return "([a-z0-9]+)";
130
+ }
131
+ if (lowerName === "r") {
132
+ return "(@\\d+x)?";
133
+ }
134
+ return "(\\d+)";
135
+ });
136
+ return { pattern: new RegExp("^" + pattern + "(\\?.*)?$", "i"), groups };
137
+ }
138
+ function templateToTemplateRegex(template) {
139
+ let pattern = template.replace(/[.*+?^${}()|[\]\\]/g, (char) => {
140
+ if (char === "{" || char === "}") return char;
141
+ return "\\" + char;
142
+ }).replace(/^https:\/\//, "https?://").replace(/^http:\/\//, "https?://").replace(/\{([a-z0-9])-([a-z0-9])\}/gi, (_2, start, end) => `(\\{${start}-${end}\\}|[a-z0-9]+)`).replace(/\{(z|x|y|s|r)\}/gi, (_2, name) => {
143
+ const lowerName = name.toLowerCase();
144
+ if (lowerName === "s") {
145
+ return "(\\{s\\}|[a-z0-9]+)";
146
+ }
147
+ if (lowerName === "r") {
148
+ return "(\\{r\\}|@\\d+x)?";
149
+ }
150
+ return `\\{${lowerName}\\}`;
151
+ });
152
+ return new RegExp("^" + pattern + "(\\?.*)?$", "i");
153
+ }
154
+ var LayerConfig = class _LayerConfig {
155
+ constructor({
156
+ id,
157
+ startZoom = 0,
158
+ zoomThreshold = 5,
159
+ // Tile URL templates for matching (e.g., "https://{s}.tile.example.com/{z}/{x}/{y}.png")
160
+ tileUrlTemplates = [],
161
+ // Line width stops: map of zoom level to line width (at least 2 entries)
162
+ lineWidthStops = { 1: 0.5, 10: 2.5 },
163
+ // Line styles array - each element describes a line to draw
164
+ // { color: string, widthFraction?: number, dashArray?: number[], startZoom?: number, endZoom?: number }
165
+ // Lines are drawn in array order. startZoom defaults to layerConfig startZoom, endZoom defaults to Infinity
166
+ lineStyles = [{ color: "green", widthFraction: 1 }],
167
+ // Factor to multiply line width for deletion blur (default 1.5)
168
+ // Higher values leave gaps where wiped lines meet existing lines
169
+ // Lower values mean wiped lines show through
170
+ delWidthFactor = 1.5,
171
+ // Factor to extend add lines by (multiplied by deletion line width)
172
+ // Helps cover gaps where deleted lines meet the new boundary
173
+ // Set to 0 to disable extension
174
+ lineExtensionFactor = 0.5
175
+ }) {
176
+ if (!id || typeof id !== "string") {
177
+ throw new Error("LayerConfig requires a non-empty string id");
178
+ }
179
+ this.id = id;
180
+ this.startZoom = startZoom;
181
+ this.zoomThreshold = zoomThreshold;
182
+ if (startZoom > zoomThreshold) {
183
+ throw new Error(`LayerConfig "${id}": startZoom (${startZoom}) must be <= zoomThreshold (${zoomThreshold})`);
184
+ }
185
+ const templates = Array.isArray(tileUrlTemplates) ? tileUrlTemplates : tileUrlTemplates ? [tileUrlTemplates] : [];
186
+ this.tileUrlTemplates = templates;
187
+ this._compiledPatterns = templates.map((t) => templateToRegex(t));
188
+ this._templatePatterns = templates.map((t) => templateToTemplateRegex(t));
189
+ if (!lineWidthStops || typeof lineWidthStops !== "object" || Array.isArray(lineWidthStops)) {
190
+ throw new Error(`LayerConfig "${id}": lineWidthStops must be an object`);
191
+ }
192
+ const stopKeys = Object.keys(lineWidthStops);
193
+ if (stopKeys.length < 2) {
194
+ throw new Error(`LayerConfig "${id}": lineWidthStops must have at least 2 entries`);
195
+ }
196
+ for (const key of stopKeys) {
197
+ const zoom = Number(key);
198
+ if (!Number.isInteger(zoom) || zoom < 0) {
199
+ throw new Error(`LayerConfig "${id}": lineWidthStops keys must be non-negative integers, got "${key}"`);
200
+ }
201
+ if (typeof lineWidthStops[key] !== "number" || lineWidthStops[key] <= 0) {
202
+ throw new Error(`LayerConfig "${id}": lineWidthStops values must be positive numbers`);
203
+ }
204
+ }
205
+ this.lineWidthStops = lineWidthStops;
206
+ if (!Array.isArray(lineStyles) || lineStyles.length === 0) {
207
+ throw new Error(`LayerConfig "${id}": lineStyles must be a non-empty array`);
208
+ }
209
+ for (let i2 = 0; i2 < lineStyles.length; i2++) {
210
+ const style = lineStyles[i2];
211
+ if (!style || typeof style !== "object") {
212
+ throw new Error(`LayerConfig "${id}": lineStyles[${i2}] must be an object`);
213
+ }
214
+ if (!style.color || typeof style.color !== "string") {
215
+ throw new Error(`LayerConfig "${id}": lineStyles[${i2}].color must be a non-empty string`);
216
+ }
217
+ }
218
+ this.lineStyles = lineStyles.map((style) => ({
219
+ ...style,
220
+ startZoom: style.startZoom ?? startZoom,
221
+ endZoom: style.endZoom ?? Infinity
222
+ }));
223
+ this.delWidthFactor = delWidthFactor;
224
+ this.lineExtensionFactor = lineExtensionFactor;
225
+ }
226
+ /**
227
+ * Get line styles active at a given zoom level
228
+ * @param {number} z - Zoom level
229
+ * @returns {Array<{color: string, widthFraction?: number, dashArray?: number[]}>}
230
+ */
231
+ getLineStylesForZoom(z2) {
232
+ return this.lineStyles.filter((style) => z2 >= style.startZoom && z2 <= style.endZoom);
233
+ }
234
+ /**
235
+ * Check if this config matches the given template URLs (with {z}/{x}/{y} placeholders)
236
+ * @param {string | string[]} templates - Single template URL or array of template URLs
237
+ * @returns {boolean}
238
+ */
239
+ matchTemplate(templates) {
240
+ if (this._templatePatterns.length === 0) return false;
241
+ const urls = Array.isArray(templates) ? templates : [templates];
242
+ if (urls.length === 0) return false;
243
+ return urls.some(
244
+ (url) => this._templatePatterns.some((pattern) => pattern.test(url))
245
+ );
246
+ }
247
+ /**
248
+ * Check if this config matches the given tile URLs (with actual coordinates)
249
+ * @param {string | string[]} tiles - Single tile URL or array of tile URLs
250
+ * @returns {boolean}
251
+ */
252
+ matchTileUrl(tiles) {
253
+ if (this._compiledPatterns.length === 0) return false;
254
+ const urls = Array.isArray(tiles) ? tiles : [tiles];
255
+ if (urls.length === 0) return false;
256
+ return urls.some(
257
+ (url) => this._compiledPatterns.some(({ pattern }) => pattern.test(url))
258
+ );
259
+ }
260
+ /**
261
+ * Extract tile coordinates (z, x, y) from a URL using this config's templates
262
+ * @param {string} url - Tile URL to extract coordinates from
263
+ * @returns {{ z: number, x: number, y: number } | null}
264
+ */
265
+ extractCoords(url) {
266
+ for (const { pattern, groups } of this._compiledPatterns) {
267
+ const match = url.match(pattern);
268
+ if (match) {
269
+ const result = {};
270
+ for (let i2 = 0; i2 < groups.length; i2++) {
271
+ const name = groups[i2];
272
+ const value = match[i2 + 1];
273
+ if (name === "z" || name === "x" || name === "y") {
274
+ result[name] = parseInt(value, 10);
275
+ }
276
+ }
277
+ if ("z" in result && "x" in result && "y" in result) {
278
+ return { z: result.z, x: result.x, y: result.y };
279
+ }
280
+ }
281
+ }
282
+ return null;
283
+ }
284
+ /**
285
+ * Serialize the config to a plain object for postMessage
286
+ * @returns {Object}
287
+ */
288
+ toJSON() {
289
+ return {
290
+ id: this.id,
291
+ startZoom: this.startZoom,
292
+ zoomThreshold: this.zoomThreshold,
293
+ tileUrlTemplates: this.tileUrlTemplates,
294
+ lineWidthStops: this.lineWidthStops,
295
+ lineStyles: this.lineStyles,
296
+ delWidthFactor: this.delWidthFactor,
297
+ lineExtensionFactor: this.lineExtensionFactor
298
+ };
299
+ }
300
+ /**
301
+ * Create a LayerConfig from a plain object (e.g., from postMessage)
302
+ * @param {Object} obj
303
+ * @returns {LayerConfig}
304
+ */
305
+ static fromJSON(obj) {
306
+ return new _LayerConfig(obj);
307
+ }
308
+ };
309
+ var LayerConfigRegistry = class _LayerConfigRegistry {
310
+ constructor() {
311
+ this.registry = {};
312
+ }
313
+ /**
314
+ * Get a layer config by id
315
+ */
316
+ get(id) {
317
+ return this.registry[id];
318
+ }
319
+ /**
320
+ * Register a new layer config
321
+ */
322
+ register(config) {
323
+ this.registry[config.id] = config;
324
+ }
325
+ /**
326
+ * Remove a layer config by id
327
+ */
328
+ remove(id) {
329
+ if (!this.registry[id]) return false;
330
+ delete this.registry[id];
331
+ return true;
332
+ }
333
+ /**
334
+ * Detect layer config from tile URL templates (with {z}/{x}/{y} placeholders)
335
+ * @param {string | string[]} templates - Single template URL or array of template URLs
336
+ */
337
+ detectFromTemplates(templates) {
338
+ if (!templates || Array.isArray(templates) && templates.length === 0) return void 0;
339
+ for (const config of Object.values(this.registry)) {
340
+ if (config.matchTemplate(templates)) {
341
+ return config;
342
+ }
343
+ }
344
+ return void 0;
345
+ }
346
+ /**
347
+ * Detect layer config from actual tile URLs (with numeric coordinates)
348
+ * @param {string | string[]} urls - Single tile URL or array of tile URLs
349
+ */
350
+ detectFromTileUrls(urls) {
351
+ if (!urls || Array.isArray(urls) && urls.length === 0) return void 0;
352
+ for (const config of Object.values(this.registry)) {
353
+ if (config.matchTileUrl(urls)) {
354
+ return config;
355
+ }
356
+ }
357
+ return void 0;
358
+ }
359
+ /**
360
+ * Get all available layer config ids
361
+ */
362
+ getAvailableIds() {
363
+ return Object.keys(this.registry);
364
+ }
365
+ /**
366
+ * Create a new registry with all configs from this registry plus extra configs.
367
+ * @param {LayerConfig[]} extraLayerConfigs - Additional configs to add
368
+ * @returns {LayerConfigRegistry} A new registry with merged configs
369
+ */
370
+ createMergedRegistry(extraLayerConfigs) {
371
+ const registry = new _LayerConfigRegistry();
372
+ for (const id of this.getAvailableIds()) {
373
+ registry.register(this.get(id));
374
+ }
375
+ if (extraLayerConfigs && extraLayerConfigs.length > 0) {
376
+ for (const config of extraLayerConfigs) {
377
+ registry.register(config);
378
+ }
379
+ }
380
+ return registry;
381
+ }
382
+ /**
383
+ * Parse a tile URL into its components: layer config and coordinates
384
+ * @param {string} url - Tile URL to parse
385
+ * @returns {{ layerConfig: LayerConfig, coords: { z: number, x: number, y: number } } | null}
386
+ */
387
+ parseTileUrl(url) {
388
+ const layerConfig = this.detectFromTileUrls([url]);
389
+ if (!layerConfig) return null;
390
+ const coords = layerConfig.extractCoords(url);
391
+ if (!coords) return null;
392
+ return { layerConfig, coords };
393
+ }
394
+ };
395
+ var layerConfigs = new LayerConfigRegistry();
396
+ for (const configData of configs_default) {
397
+ layerConfigs.register(new LayerConfig(configData));
398
+ }
399
+
400
+ // ../tilefixer/dist/index.js
401
+ var u8 = Uint8Array;
402
+ var u16 = Uint16Array;
403
+ var i32 = Int32Array;
404
+ var fleb = new u8([
405
+ 0,
406
+ 0,
407
+ 0,
408
+ 0,
409
+ 0,
410
+ 0,
411
+ 0,
412
+ 0,
413
+ 1,
414
+ 1,
415
+ 1,
416
+ 1,
417
+ 2,
418
+ 2,
419
+ 2,
420
+ 2,
421
+ 3,
422
+ 3,
423
+ 3,
424
+ 3,
425
+ 4,
426
+ 4,
427
+ 4,
428
+ 4,
429
+ 5,
430
+ 5,
431
+ 5,
432
+ 5,
433
+ 0,
434
+ /* unused */
435
+ 0,
436
+ 0,
437
+ /* impossible */
438
+ 0
439
+ ]);
440
+ var fdeb = new u8([
441
+ 0,
442
+ 0,
443
+ 0,
444
+ 0,
445
+ 1,
446
+ 1,
447
+ 2,
448
+ 2,
449
+ 3,
450
+ 3,
451
+ 4,
452
+ 4,
453
+ 5,
454
+ 5,
455
+ 6,
456
+ 6,
457
+ 7,
458
+ 7,
459
+ 8,
460
+ 8,
461
+ 9,
462
+ 9,
463
+ 10,
464
+ 10,
465
+ 11,
466
+ 11,
467
+ 12,
468
+ 12,
469
+ 13,
470
+ 13,
471
+ /* unused */
472
+ 0,
473
+ 0
474
+ ]);
475
+ var clim = new u8([16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15]);
476
+ var freb = function(eb, start) {
477
+ var b2 = new u16(31);
478
+ for (var i2 = 0; i2 < 31; ++i2) {
479
+ b2[i2] = start += 1 << eb[i2 - 1];
480
+ }
481
+ var r = new i32(b2[30]);
482
+ for (var i2 = 1; i2 < 30; ++i2) {
483
+ for (var j2 = b2[i2]; j2 < b2[i2 + 1]; ++j2) {
484
+ r[j2] = j2 - b2[i2] << 5 | i2;
485
+ }
486
+ }
487
+ return { b: b2, r };
488
+ };
489
+ var _a = freb(fleb, 2);
490
+ var fl = _a.b;
491
+ var revfl = _a.r;
492
+ fl[28] = 258, revfl[258] = 28;
493
+ var _b = freb(fdeb, 0);
494
+ var fd = _b.b;
495
+ var revfd = _b.r;
496
+ var rev = new u16(32768);
497
+ for (i = 0; i < 32768; ++i) {
498
+ x2 = (i & 43690) >> 1 | (i & 21845) << 1;
499
+ x2 = (x2 & 52428) >> 2 | (x2 & 13107) << 2;
500
+ x2 = (x2 & 61680) >> 4 | (x2 & 3855) << 4;
501
+ rev[i] = ((x2 & 65280) >> 8 | (x2 & 255) << 8) >> 1;
502
+ }
503
+ var x2;
504
+ var i;
505
+ var hMap = (function(cd, mb, r) {
506
+ var s = cd.length;
507
+ var i2 = 0;
508
+ var l2 = new u16(mb);
509
+ for (; i2 < s; ++i2) {
510
+ if (cd[i2])
511
+ ++l2[cd[i2] - 1];
512
+ }
513
+ var le = new u16(mb);
514
+ for (i2 = 1; i2 < mb; ++i2) {
515
+ le[i2] = le[i2 - 1] + l2[i2 - 1] << 1;
516
+ }
517
+ var co;
518
+ if (r) {
519
+ co = new u16(1 << mb);
520
+ var rvb = 15 - mb;
521
+ for (i2 = 0; i2 < s; ++i2) {
522
+ if (cd[i2]) {
523
+ var sv = i2 << 4 | cd[i2];
524
+ var r_1 = mb - cd[i2];
525
+ var v2 = le[cd[i2] - 1]++ << r_1;
526
+ for (var m2 = v2 | (1 << r_1) - 1; v2 <= m2; ++v2) {
527
+ co[rev[v2] >> rvb] = sv;
528
+ }
529
+ }
530
+ }
531
+ } else {
532
+ co = new u16(s);
533
+ for (i2 = 0; i2 < s; ++i2) {
534
+ if (cd[i2]) {
535
+ co[i2] = rev[le[cd[i2] - 1]++] >> 15 - cd[i2];
536
+ }
537
+ }
538
+ }
539
+ return co;
540
+ });
541
+ var flt = new u8(288);
542
+ for (i = 0; i < 144; ++i)
543
+ flt[i] = 8;
544
+ var i;
545
+ for (i = 144; i < 256; ++i)
546
+ flt[i] = 9;
547
+ var i;
548
+ for (i = 256; i < 280; ++i)
549
+ flt[i] = 7;
550
+ var i;
551
+ for (i = 280; i < 288; ++i)
552
+ flt[i] = 8;
553
+ var i;
554
+ var fdt = new u8(32);
555
+ for (i = 0; i < 32; ++i)
556
+ fdt[i] = 5;
557
+ var i;
558
+ var flrm = /* @__PURE__ */ hMap(flt, 9, 1);
559
+ var fdrm = /* @__PURE__ */ hMap(fdt, 5, 1);
560
+ var max = function(a) {
561
+ var m2 = a[0];
562
+ for (var i2 = 1; i2 < a.length; ++i2) {
563
+ if (a[i2] > m2)
564
+ m2 = a[i2];
565
+ }
566
+ return m2;
567
+ };
568
+ var bits = function(d, p, m2) {
569
+ var o = p / 8 | 0;
570
+ return (d[o] | d[o + 1] << 8) >> (p & 7) & m2;
571
+ };
572
+ var bits16 = function(d, p) {
573
+ var o = p / 8 | 0;
574
+ return (d[o] | d[o + 1] << 8 | d[o + 2] << 16) >> (p & 7);
575
+ };
576
+ var shft = function(p) {
577
+ return (p + 7) / 8 | 0;
578
+ };
579
+ var slc = function(v2, s, e) {
580
+ if (s == null || s < 0)
581
+ s = 0;
582
+ if (e == null || e > v2.length)
583
+ e = v2.length;
584
+ return new u8(v2.subarray(s, e));
585
+ };
586
+ var ec = [
587
+ "unexpected EOF",
588
+ "invalid block type",
589
+ "invalid length/literal",
590
+ "invalid distance",
591
+ "stream finished",
592
+ "no stream handler",
593
+ ,
594
+ "no callback",
595
+ "invalid UTF-8 data",
596
+ "extra field too long",
597
+ "date not in range 1980-2099",
598
+ "filename too long",
599
+ "stream finishing",
600
+ "invalid zip data"
601
+ // determined by unknown compression method
602
+ ];
603
+ var err = function(ind, msg, nt) {
604
+ var e = new Error(msg || ec[ind]);
605
+ e.code = ind;
606
+ if (Error.captureStackTrace)
607
+ Error.captureStackTrace(e, err);
608
+ if (!nt)
609
+ throw e;
610
+ return e;
611
+ };
612
+ var inflt = function(dat, st, buf, dict) {
613
+ var sl = dat.length, dl = dict ? dict.length : 0;
614
+ if (!sl || st.f && !st.l)
615
+ return buf || new u8(0);
616
+ var noBuf = !buf;
617
+ var resize = noBuf || st.i != 2;
618
+ var noSt = st.i;
619
+ if (noBuf)
620
+ buf = new u8(sl * 3);
621
+ var cbuf = function(l3) {
622
+ var bl = buf.length;
623
+ if (l3 > bl) {
624
+ var nbuf = new u8(Math.max(bl * 2, l3));
625
+ nbuf.set(buf);
626
+ buf = nbuf;
627
+ }
628
+ };
629
+ var final = st.f || 0, pos = st.p || 0, bt = st.b || 0, lm = st.l, dm = st.d, lbt = st.m, dbt = st.n;
630
+ var tbts = sl * 8;
631
+ do {
632
+ if (!lm) {
633
+ final = bits(dat, pos, 1);
634
+ var type = bits(dat, pos + 1, 3);
635
+ pos += 3;
636
+ if (!type) {
637
+ var s = shft(pos) + 4, l2 = dat[s - 4] | dat[s - 3] << 8, t = s + l2;
638
+ if (t > sl) {
639
+ if (noSt)
640
+ err(0);
641
+ break;
642
+ }
643
+ if (resize)
644
+ cbuf(bt + l2);
645
+ buf.set(dat.subarray(s, t), bt);
646
+ st.b = bt += l2, st.p = pos = t * 8, st.f = final;
647
+ continue;
648
+ } else if (type == 1)
649
+ lm = flrm, dm = fdrm, lbt = 9, dbt = 5;
650
+ else if (type == 2) {
651
+ var hLit = bits(dat, pos, 31) + 257, hcLen = bits(dat, pos + 10, 15) + 4;
652
+ var tl = hLit + bits(dat, pos + 5, 31) + 1;
653
+ pos += 14;
654
+ var ldt = new u8(tl);
655
+ var clt = new u8(19);
656
+ for (var i2 = 0; i2 < hcLen; ++i2) {
657
+ clt[clim[i2]] = bits(dat, pos + i2 * 3, 7);
658
+ }
659
+ pos += hcLen * 3;
660
+ var clb = max(clt), clbmsk = (1 << clb) - 1;
661
+ var clm = hMap(clt, clb, 1);
662
+ for (var i2 = 0; i2 < tl; ) {
663
+ var r = clm[bits(dat, pos, clbmsk)];
664
+ pos += r & 15;
665
+ var s = r >> 4;
666
+ if (s < 16) {
667
+ ldt[i2++] = s;
668
+ } else {
669
+ var c = 0, n = 0;
670
+ if (s == 16)
671
+ n = 3 + bits(dat, pos, 3), pos += 2, c = ldt[i2 - 1];
672
+ else if (s == 17)
673
+ n = 3 + bits(dat, pos, 7), pos += 3;
674
+ else if (s == 18)
675
+ n = 11 + bits(dat, pos, 127), pos += 7;
676
+ while (n--)
677
+ ldt[i2++] = c;
678
+ }
679
+ }
680
+ var lt = ldt.subarray(0, hLit), dt = ldt.subarray(hLit);
681
+ lbt = max(lt);
682
+ dbt = max(dt);
683
+ lm = hMap(lt, lbt, 1);
684
+ dm = hMap(dt, dbt, 1);
685
+ } else
686
+ err(1);
687
+ if (pos > tbts) {
688
+ if (noSt)
689
+ err(0);
690
+ break;
691
+ }
692
+ }
693
+ if (resize)
694
+ cbuf(bt + 131072);
695
+ var lms = (1 << lbt) - 1, dms = (1 << dbt) - 1;
696
+ var lpos = pos;
697
+ for (; ; lpos = pos) {
698
+ var c = lm[bits16(dat, pos) & lms], sym = c >> 4;
699
+ pos += c & 15;
700
+ if (pos > tbts) {
701
+ if (noSt)
702
+ err(0);
703
+ break;
704
+ }
705
+ if (!c)
706
+ err(2);
707
+ if (sym < 256)
708
+ buf[bt++] = sym;
709
+ else if (sym == 256) {
710
+ lpos = pos, lm = null;
711
+ break;
712
+ } else {
713
+ var add = sym - 254;
714
+ if (sym > 264) {
715
+ var i2 = sym - 257, b2 = fleb[i2];
716
+ add = bits(dat, pos, (1 << b2) - 1) + fl[i2];
717
+ pos += b2;
718
+ }
719
+ var d = dm[bits16(dat, pos) & dms], dsym = d >> 4;
720
+ if (!d)
721
+ err(3);
722
+ pos += d & 15;
723
+ var dt = fd[dsym];
724
+ if (dsym > 3) {
725
+ var b2 = fdeb[dsym];
726
+ dt += bits16(dat, pos) & (1 << b2) - 1, pos += b2;
727
+ }
728
+ if (pos > tbts) {
729
+ if (noSt)
730
+ err(0);
731
+ break;
732
+ }
733
+ if (resize)
734
+ cbuf(bt + 131072);
735
+ var end = bt + add;
736
+ if (bt < dt) {
737
+ var shift = dl - dt, dend = Math.min(dt, end);
738
+ if (shift + bt < 0)
739
+ err(3);
740
+ for (; bt < dend; ++bt)
741
+ buf[bt] = dict[shift + bt];
742
+ }
743
+ for (; bt < end; ++bt)
744
+ buf[bt] = buf[bt - dt];
745
+ }
746
+ }
747
+ st.l = lm, st.p = lpos, st.b = bt, st.f = final;
748
+ if (lm)
749
+ final = 1, st.m = lbt, st.d = dm, st.n = dbt;
750
+ } while (!final);
751
+ return bt != buf.length && noBuf ? slc(buf, 0, bt) : buf.subarray(0, bt);
752
+ };
753
+ var et = /* @__PURE__ */ new u8(0);
754
+ var gzs = function(d) {
755
+ if (d[0] != 31 || d[1] != 139 || d[2] != 8)
756
+ err(6, "invalid gzip data");
757
+ var flg = d[3];
758
+ var st = 10;
759
+ if (flg & 4)
760
+ st += (d[10] | d[11] << 8) + 2;
761
+ for (var zs = (flg >> 3 & 1) + (flg >> 4 & 1); zs > 0; zs -= !d[st++])
762
+ ;
763
+ return st + (flg & 2);
764
+ };
765
+ var gzl = function(d) {
766
+ var l2 = d.length;
767
+ return (d[l2 - 4] | d[l2 - 3] << 8 | d[l2 - 2] << 16 | d[l2 - 1] << 24) >>> 0;
768
+ };
769
+ var zls = function(d, dict) {
770
+ if ((d[0] & 15) != 8 || d[0] >> 4 > 7 || (d[0] << 8 | d[1]) % 31)
771
+ err(6, "invalid zlib data");
772
+ if ((d[1] >> 5 & 1) == +!dict)
773
+ err(6, "invalid zlib data: " + (d[1] & 32 ? "need" : "unexpected") + " dictionary");
774
+ return (d[1] >> 3 & 4) + 2;
775
+ };
776
+ function inflateSync(data, opts) {
777
+ return inflt(data, { i: 2 }, opts && opts.out, opts && opts.dictionary);
778
+ }
779
+ function gunzipSync(data, opts) {
780
+ var st = gzs(data);
781
+ if (st + 8 > data.length)
782
+ err(6, "invalid gzip data");
783
+ return inflt(data.subarray(st, -8), { i: 2 }, opts && opts.out || new u8(gzl(data)), opts && opts.dictionary);
784
+ }
785
+ function unzlibSync(data, opts) {
786
+ return inflt(data.subarray(zls(data, opts && opts.dictionary), -4), { i: 2 }, opts && opts.out, opts && opts.dictionary);
787
+ }
788
+ function decompressSync(data, opts) {
789
+ return data[0] == 31 && data[1] == 139 && data[2] == 8 ? gunzipSync(data, opts) : (data[0] & 15) != 8 || data[0] >> 4 > 7 || (data[0] << 8 | data[1]) % 31 ? inflateSync(data, opts) : unzlibSync(data, opts);
790
+ }
791
+ var td = typeof TextDecoder != "undefined" && /* @__PURE__ */ new TextDecoder();
792
+ var tds = 0;
793
+ try {
794
+ td.decode(et, { stream: true });
795
+ tds = 1;
796
+ } catch (e) {
797
+ }
798
+ var z = Object.defineProperty;
799
+ var b = Math.pow;
800
+ var l = (i2, e) => z(i2, "name", { value: e, configurable: true });
801
+ var m = (i2, e, t) => new Promise((r, n) => {
802
+ var s = (u) => {
803
+ try {
804
+ a(t.next(u));
805
+ } catch (c) {
806
+ n(c);
807
+ }
808
+ }, o = (u) => {
809
+ try {
810
+ a(t.throw(u));
811
+ } catch (c) {
812
+ n(c);
813
+ }
814
+ }, a = (u) => u.done ? r(u.value) : Promise.resolve(u.value).then(s, o);
815
+ a((t = t.apply(i2, e)).next());
816
+ });
817
+ var re = l((i2, e) => {
818
+ let t = false, r = "", n = L.GridLayer.extend({ createTile: l((s, o) => {
819
+ let a = document.createElement("img"), u = new AbortController(), c = u.signal;
820
+ return a.cancel = () => {
821
+ u.abort();
822
+ }, t || (i2.getHeader().then((d) => {
823
+ d.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.") : d.tileType === 2 ? r = "image/png" : d.tileType === 3 ? r = "image/jpeg" : d.tileType === 4 ? r = "image/webp" : d.tileType === 5 && (r = "image/avif");
824
+ }), t = true), i2.getZxy(s.z, s.x, s.y, c).then((d) => {
825
+ if (d) {
826
+ let h = new Blob([d.data], { type: r }), p = window.URL.createObjectURL(h);
827
+ a.src = p, a.cancel = void 0, o(void 0, a);
828
+ }
829
+ }).catch((d) => {
830
+ if (d.name !== "AbortError") throw d;
831
+ }), a;
832
+ }, "createTile"), _removeTile: l(function(s) {
833
+ let o = this._tiles[s];
834
+ o && (o.el.cancel && o.el.cancel(), o.el.width = 0, o.el.height = 0, o.el.deleted = true, L.DomUtil.remove(o.el), delete this._tiles[s], this.fire("tileunload", { tile: o.el, coords: this._keyToTileCoords(s) }));
835
+ }, "_removeTile") });
836
+ return new n(e);
837
+ }, "leafletRasterLayer");
838
+ var j = l((i2) => (e, t) => {
839
+ if (t instanceof AbortController) return i2(e, t);
840
+ let r = new AbortController();
841
+ return i2(e, r).then((n) => t(void 0, n.data, n.cacheControl || "", n.expires || ""), (n) => t(n)).catch((n) => t(n)), { cancel: l(() => r.abort(), "cancel") };
842
+ }, "v3compat");
843
+ var T = class T2 {
844
+ constructor(e) {
845
+ this.tilev4 = l((e2, t) => m(this, null, function* () {
846
+ if (e2.type === "json") {
847
+ let p = e2.url.substr(10), y = this.tiles.get(p);
848
+ if (y || (y = new x(p), this.tiles.set(p, y)), this.metadata) return { data: yield y.getTileJson(e2.url) };
849
+ let f = yield y.getHeader();
850
+ return (f.minLon >= f.maxLon || f.minLat >= f.maxLat) && console.error(`Bounds of PMTiles archive ${f.minLon},${f.minLat},${f.maxLon},${f.maxLat} are not valid.`), { data: { tiles: [`${e2.url}/{z}/{x}/{y}`], minzoom: f.minZoom, maxzoom: f.maxZoom, bounds: [f.minLon, f.minLat, f.maxLon, f.maxLat] } };
851
+ }
852
+ let r = new RegExp(/pmtiles:\/\/(.+)\/(\d+)\/(\d+)\/(\d+)/), n = e2.url.match(r);
853
+ if (!n) throw new Error("Invalid PMTiles protocol URL");
854
+ let s = n[1], o = this.tiles.get(s);
855
+ o || (o = new x(s), this.tiles.set(s, o));
856
+ let a = n[2], u = n[3], c = n[4], d = yield o.getHeader(), h = yield o == null ? void 0 : o.getZxy(+a, +u, +c, t.signal);
857
+ if (h) return { data: new Uint8Array(h.data), cacheControl: h.cacheControl, expires: h.expires };
858
+ if (d.tileType === 1) {
859
+ if (this.errorOnMissingTile) throw new Error("Tile not found.");
860
+ return { data: new Uint8Array() };
861
+ }
862
+ return { data: null };
863
+ }), "tilev4");
864
+ this.tile = j(this.tilev4);
865
+ this.tiles = /* @__PURE__ */ new Map(), this.metadata = (e == null ? void 0 : e.metadata) || false, this.errorOnMissingTile = (e == null ? void 0 : e.errorOnMissingTile) || false;
866
+ }
867
+ add(e) {
868
+ this.tiles.set(e.source.getKey(), e);
869
+ }
870
+ get(e) {
871
+ return this.tiles.get(e);
872
+ }
873
+ };
874
+ l(T, "Protocol");
875
+ function w(i2, e) {
876
+ return (e >>> 0) * 4294967296 + (i2 >>> 0);
877
+ }
878
+ l(w, "toNum");
879
+ function F(i2, e) {
880
+ let t = e.buf, r = t[e.pos++], n = (r & 112) >> 4;
881
+ if (r < 128 || (r = t[e.pos++], n |= (r & 127) << 3, r < 128) || (r = t[e.pos++], n |= (r & 127) << 10, r < 128) || (r = t[e.pos++], n |= (r & 127) << 17, r < 128) || (r = t[e.pos++], n |= (r & 127) << 24, r < 128) || (r = t[e.pos++], n |= (r & 1) << 31, r < 128)) return w(i2, n);
882
+ throw new Error("Expected varint not more than 10 bytes");
883
+ }
884
+ l(F, "readVarintRemainder");
885
+ function v(i2) {
886
+ let e = i2.buf, t = e[i2.pos++], r = t & 127;
887
+ return t < 128 || (t = e[i2.pos++], r |= (t & 127) << 7, t < 128) || (t = e[i2.pos++], r |= (t & 127) << 14, t < 128) || (t = e[i2.pos++], r |= (t & 127) << 21, t < 128) ? r : (t = e[i2.pos], r |= (t & 15) << 28, F(r, i2));
888
+ }
889
+ l(v, "readVarint");
890
+ function k(i2, e, t, r) {
891
+ if (r === 0) {
892
+ t === 1 && (e[0] = i2 - 1 - e[0], e[1] = i2 - 1 - e[1]);
893
+ let n = e[0];
894
+ e[0] = e[1], e[1] = n;
895
+ }
896
+ }
897
+ l(k, "rotate");
898
+ function N(i2, e) {
899
+ let t = b(2, i2), r = e, n = e, s = e, o = [0, 0], a = 1;
900
+ for (; a < t; ) r = 1 & s / 2, n = 1 & (s ^ r), k(a, o, r, n), o[0] += a * r, o[1] += a * n, s = s / 4, a *= 2;
901
+ return [i2, o[0], o[1]];
902
+ }
903
+ l(N, "idOnLevel");
904
+ var q = [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];
905
+ function G(i2, e, t) {
906
+ if (i2 > 26) throw new Error("Tile zoom level exceeds max safe number limit (26)");
907
+ if (e > b(2, i2) - 1 || t > b(2, i2) - 1) throw new Error("tile x/y outside zoom level bounds");
908
+ let r = q[i2], n = b(2, i2), s = 0, o = 0, a = 0, u = [e, t], c = n / 2;
909
+ for (; c > 0; ) s = (u[0] & c) > 0 ? 1 : 0, o = (u[1] & c) > 0 ? 1 : 0, a += c * c * (3 * s ^ o), k(c, u, s, o), c = c / 2;
910
+ return r + a;
911
+ }
912
+ l(G, "zxyToTileId");
913
+ function ie(i2) {
914
+ let e = 0, t = 0;
915
+ for (let r = 0; r < 27; r++) {
916
+ let n = (1 << r) * (1 << r);
917
+ if (e + n > i2) return N(r, i2 - e);
918
+ e += n;
919
+ }
920
+ throw new Error("Tile zoom level exceeds max safe number limit (26)");
921
+ }
922
+ l(ie, "tileIdToZxy");
923
+ var J = ((s) => (s[s.Unknown = 0] = "Unknown", s[s.None = 1] = "None", s[s.Gzip = 2] = "Gzip", s[s.Brotli = 3] = "Brotli", s[s.Zstd = 4] = "Zstd", s))(J || {});
924
+ function D(i2, e) {
925
+ return m(this, null, function* () {
926
+ if (e === 1 || e === 0) return i2;
927
+ if (e === 2) {
928
+ if (typeof globalThis.DecompressionStream == "undefined") return decompressSync(new Uint8Array(i2));
929
+ let t = new Response(i2).body;
930
+ if (!t) throw new Error("Failed to read response stream");
931
+ let r = t.pipeThrough(new globalThis.DecompressionStream("gzip"));
932
+ return new Response(r).arrayBuffer();
933
+ }
934
+ throw new Error("Compression method not supported");
935
+ });
936
+ }
937
+ l(D, "defaultDecompress");
938
+ var O = ((o) => (o[o.Unknown = 0] = "Unknown", o[o.Mvt = 1] = "Mvt", o[o.Png = 2] = "Png", o[o.Jpeg = 3] = "Jpeg", o[o.Webp = 4] = "Webp", o[o.Avif = 5] = "Avif", o))(O || {});
939
+ function _(i2) {
940
+ return i2 === 1 ? ".mvt" : i2 === 2 ? ".png" : i2 === 3 ? ".jpg" : i2 === 4 ? ".webp" : i2 === 5 ? ".avif" : "";
941
+ }
942
+ l(_, "tileTypeExt");
943
+ var Y = 127;
944
+ function Q(i2, e) {
945
+ let t = 0, r = i2.length - 1;
946
+ for (; t <= r; ) {
947
+ let n = r + t >> 1, s = e - i2[n].tileId;
948
+ if (s > 0) t = n + 1;
949
+ else if (s < 0) r = n - 1;
950
+ else return i2[n];
951
+ }
952
+ return r >= 0 && (i2[r].runLength === 0 || e - i2[r].tileId < i2[r].runLength) ? i2[r] : null;
953
+ }
954
+ l(Q, "findTile");
955
+ var A = class A2 {
956
+ constructor(e) {
957
+ this.file = e;
958
+ }
959
+ getKey() {
960
+ return this.file.name;
961
+ }
962
+ getBytes(e, t) {
963
+ return m(this, null, function* () {
964
+ return { data: yield this.file.slice(e, e + t).arrayBuffer() };
965
+ });
966
+ }
967
+ };
968
+ l(A, "FileSource");
969
+ var U = class U2 {
970
+ constructor(e, t = new Headers()) {
971
+ this.url = e, this.customHeaders = t, this.mustReload = false;
972
+ let r = "";
973
+ "navigator" in globalThis && (r = globalThis.navigator.userAgent || "");
974
+ let n = r.indexOf("Windows") > -1, s = /Chrome|Chromium|Edg|OPR|Brave/.test(r);
975
+ this.chromeWindowsNoCache = false, n && s && (this.chromeWindowsNoCache = true);
976
+ }
977
+ getKey() {
978
+ return this.url;
979
+ }
980
+ setHeaders(e) {
981
+ this.customHeaders = e;
982
+ }
983
+ getBytes(e, t, r, n) {
984
+ return m(this, null, function* () {
985
+ let s, o;
986
+ r ? o = r : (s = new AbortController(), o = s.signal);
987
+ let a = new Headers(this.customHeaders);
988
+ a.set("range", `bytes=${e}-${e + t - 1}`);
989
+ let u;
990
+ this.mustReload ? u = "reload" : this.chromeWindowsNoCache && (u = "no-store");
991
+ let c = yield fetch(this.url, { signal: o, cache: u, headers: a });
992
+ if (e === 0 && c.status === 416) {
993
+ let y = c.headers.get("Content-Range");
994
+ if (!y || !y.startsWith("bytes */")) throw new Error("Missing content-length on 416 response");
995
+ let f = +y.substr(8);
996
+ c = yield fetch(this.url, { signal: o, cache: "reload", headers: { range: `bytes=0-${f - 1}` } });
997
+ }
998
+ let d = c.headers.get("Etag");
999
+ if (d != null && d.startsWith("W/") && (d = null), c.status === 416 || n && d && d !== n) throw this.mustReload = true, new E(`Server returned non-matching ETag ${n} after one retry. Check browser extensions and servers for issues that may affect correct ETag headers.`);
1000
+ if (c.status >= 300) throw new Error(`Bad response code: ${c.status}`);
1001
+ let h = c.headers.get("Content-Length");
1002
+ if (c.status === 200 && (!h || +h > t)) throw s && s.abort(), new Error("Server returned no content-length header or content-length exceeding request. Check that your storage backend supports HTTP Byte Serving.");
1003
+ return { data: yield c.arrayBuffer(), etag: d || void 0, cacheControl: c.headers.get("Cache-Control") || void 0, expires: c.headers.get("Expires") || void 0 };
1004
+ });
1005
+ }
1006
+ };
1007
+ l(U, "FetchSource");
1008
+ var C = U;
1009
+ function g(i2, e) {
1010
+ let t = i2.getUint32(e + 4, true), r = i2.getUint32(e + 0, true);
1011
+ return t * b(2, 32) + r;
1012
+ }
1013
+ l(g, "getUint64");
1014
+ function X(i2, e) {
1015
+ let t = new DataView(i2), r = t.getUint8(7);
1016
+ if (r > 3) throw new Error(`Archive is spec version ${r} but this library supports up to spec version 3`);
1017
+ return { specVersion: r, rootDirectoryOffset: g(t, 8), rootDirectoryLength: g(t, 16), jsonMetadataOffset: g(t, 24), jsonMetadataLength: g(t, 32), leafDirectoryOffset: g(t, 40), leafDirectoryLength: g(t, 48), tileDataOffset: g(t, 56), tileDataLength: g(t, 64), numAddressedTiles: g(t, 72), numTileEntries: g(t, 80), numTileContents: g(t, 88), clustered: t.getUint8(96) === 1, internalCompression: t.getUint8(97), tileCompression: t.getUint8(98), tileType: t.getUint8(99), minZoom: t.getUint8(100), maxZoom: t.getUint8(101), minLon: t.getInt32(102, true) / 1e7, minLat: t.getInt32(106, true) / 1e7, maxLon: t.getInt32(110, true) / 1e7, maxLat: t.getInt32(114, true) / 1e7, centerZoom: t.getUint8(118), centerLon: t.getInt32(119, true) / 1e7, centerLat: t.getInt32(123, true) / 1e7, etag: e };
1018
+ }
1019
+ l(X, "bytesToHeader");
1020
+ function Z(i2) {
1021
+ let e = { buf: new Uint8Array(i2), pos: 0 }, t = v(e), r = [], n = 0;
1022
+ for (let s = 0; s < t; s++) {
1023
+ let o = v(e);
1024
+ r.push({ tileId: n + o, offset: 0, length: 0, runLength: 1 }), n += o;
1025
+ }
1026
+ for (let s = 0; s < t; s++) r[s].runLength = v(e);
1027
+ for (let s = 0; s < t; s++) r[s].length = v(e);
1028
+ for (let s = 0; s < t; s++) {
1029
+ let o = v(e);
1030
+ o === 0 && s > 0 ? r[s].offset = r[s - 1].offset + r[s - 1].length : r[s].offset = o - 1;
1031
+ }
1032
+ return r;
1033
+ }
1034
+ l(Z, "deserializeIndex");
1035
+ var R = class R2 extends Error {
1036
+ };
1037
+ l(R, "EtagMismatch");
1038
+ var E = R;
1039
+ function K(i2, e) {
1040
+ return m(this, null, function* () {
1041
+ let t = yield i2.getBytes(0, 16384);
1042
+ if (new DataView(t.data).getUint16(0, true) !== 19792) throw new Error("Wrong magic number for PMTiles archive");
1043
+ let n = t.data.slice(0, Y), s = X(n, t.etag), o = t.data.slice(s.rootDirectoryOffset, s.rootDirectoryOffset + s.rootDirectoryLength), a = `${i2.getKey()}|${s.etag || ""}|${s.rootDirectoryOffset}|${s.rootDirectoryLength}`, u = Z(yield e(o, s.internalCompression));
1044
+ return [s, [a, u.length, u]];
1045
+ });
1046
+ }
1047
+ l(K, "getHeaderAndRoot");
1048
+ function I(i2, e, t, r, n) {
1049
+ return m(this, null, function* () {
1050
+ let s = yield i2.getBytes(t, r, void 0, n.etag), o = yield e(s.data, n.internalCompression), a = Z(o);
1051
+ if (a.length === 0) throw new Error("Empty directory is invalid");
1052
+ return a;
1053
+ });
1054
+ }
1055
+ l(I, "getDirectory");
1056
+ var H = class H2 {
1057
+ constructor(e = 100, t = true, r = D) {
1058
+ this.cache = /* @__PURE__ */ new Map(), this.maxCacheEntries = e, this.counter = 1, this.decompress = r;
1059
+ }
1060
+ getHeader(e) {
1061
+ return m(this, null, function* () {
1062
+ let t = e.getKey(), r = this.cache.get(t);
1063
+ if (r) return r.lastUsed = this.counter++, r.data;
1064
+ let n = yield K(e, this.decompress);
1065
+ 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];
1066
+ });
1067
+ }
1068
+ getDirectory(e, t, r, n) {
1069
+ return m(this, null, function* () {
1070
+ let s = `${e.getKey()}|${n.etag || ""}|${t}|${r}`, o = this.cache.get(s);
1071
+ if (o) return o.lastUsed = this.counter++, o.data;
1072
+ let a = yield I(e, this.decompress, t, r, n);
1073
+ return this.cache.set(s, { lastUsed: this.counter++, data: a }), this.prune(), a;
1074
+ });
1075
+ }
1076
+ prune() {
1077
+ if (this.cache.size > this.maxCacheEntries) {
1078
+ let e = 1 / 0, t;
1079
+ this.cache.forEach((r, n) => {
1080
+ r.lastUsed < e && (e = r.lastUsed, t = n);
1081
+ }), t && this.cache.delete(t);
1082
+ }
1083
+ }
1084
+ invalidate(e) {
1085
+ return m(this, null, function* () {
1086
+ this.cache.delete(e.getKey());
1087
+ });
1088
+ }
1089
+ };
1090
+ l(H, "ResolvedValueCache");
1091
+ var M = class M2 {
1092
+ constructor(e = 100, t = true, r = D) {
1093
+ this.cache = /* @__PURE__ */ new Map(), this.invalidations = /* @__PURE__ */ new Map(), this.maxCacheEntries = e, this.counter = 1, this.decompress = r;
1094
+ }
1095
+ getHeader(e) {
1096
+ return m(this, null, function* () {
1097
+ let t = e.getKey(), r = this.cache.get(t);
1098
+ if (r) return r.lastUsed = this.counter++, yield r.data;
1099
+ let n = new Promise((s, o) => {
1100
+ K(e, this.decompress).then((a) => {
1101
+ a[1] && this.cache.set(a[1][0], { lastUsed: this.counter++, data: Promise.resolve(a[1][2]) }), s(a[0]), this.prune();
1102
+ }).catch((a) => {
1103
+ o(a);
1104
+ });
1105
+ });
1106
+ return this.cache.set(t, { lastUsed: this.counter++, data: n }), n;
1107
+ });
1108
+ }
1109
+ getDirectory(e, t, r, n) {
1110
+ return m(this, null, function* () {
1111
+ let s = `${e.getKey()}|${n.etag || ""}|${t}|${r}`, o = this.cache.get(s);
1112
+ if (o) return o.lastUsed = this.counter++, yield o.data;
1113
+ let a = new Promise((u, c) => {
1114
+ I(e, this.decompress, t, r, n).then((d) => {
1115
+ u(d), this.prune();
1116
+ }).catch((d) => {
1117
+ c(d);
1118
+ });
1119
+ });
1120
+ return this.cache.set(s, { lastUsed: this.counter++, data: a }), a;
1121
+ });
1122
+ }
1123
+ prune() {
1124
+ if (this.cache.size >= this.maxCacheEntries) {
1125
+ let e = 1 / 0, t;
1126
+ this.cache.forEach((r, n) => {
1127
+ r.lastUsed < e && (e = r.lastUsed, t = n);
1128
+ }), t && this.cache.delete(t);
1129
+ }
1130
+ }
1131
+ invalidate(e) {
1132
+ return m(this, null, function* () {
1133
+ let t = e.getKey();
1134
+ if (this.invalidations.get(t)) return yield this.invalidations.get(t);
1135
+ this.cache.delete(e.getKey());
1136
+ let r = new Promise((n, s) => {
1137
+ this.getHeader(e).then((o) => {
1138
+ n(), this.invalidations.delete(t);
1139
+ }).catch((o) => {
1140
+ s(o);
1141
+ });
1142
+ });
1143
+ this.invalidations.set(t, r);
1144
+ });
1145
+ }
1146
+ };
1147
+ l(M, "SharedPromiseCache");
1148
+ var P = M;
1149
+ var B = class B2 {
1150
+ constructor(e, t, r) {
1151
+ typeof e == "string" ? this.source = new C(e) : this.source = e, r ? this.decompress = r : this.decompress = D, t ? this.cache = t : this.cache = new P();
1152
+ }
1153
+ getHeader() {
1154
+ return m(this, null, function* () {
1155
+ return yield this.cache.getHeader(this.source);
1156
+ });
1157
+ }
1158
+ getZxyAttempt(e, t, r, n) {
1159
+ return m(this, null, function* () {
1160
+ let s = G(e, t, r), o = yield this.cache.getHeader(this.source);
1161
+ if (e < o.minZoom || e > o.maxZoom) return;
1162
+ let a = o.rootDirectoryOffset, u = o.rootDirectoryLength;
1163
+ for (let c = 0; c <= 3; c++) {
1164
+ let d = yield this.cache.getDirectory(this.source, a, u, o), h = Q(d, s);
1165
+ if (h) {
1166
+ if (h.runLength > 0) {
1167
+ let p = yield this.source.getBytes(o.tileDataOffset + h.offset, h.length, n, o.etag);
1168
+ return { data: yield this.decompress(p.data, o.tileCompression), cacheControl: p.cacheControl, expires: p.expires };
1169
+ }
1170
+ a = o.leafDirectoryOffset + h.offset, u = h.length;
1171
+ } else return;
1172
+ }
1173
+ throw new Error("Maximum directory depth exceeded");
1174
+ });
1175
+ }
1176
+ getZxy(e, t, r, n) {
1177
+ return m(this, null, function* () {
1178
+ try {
1179
+ return yield this.getZxyAttempt(e, t, r, n);
1180
+ } catch (s) {
1181
+ if (s instanceof E) return this.cache.invalidate(this.source), yield this.getZxyAttempt(e, t, r, n);
1182
+ throw s;
1183
+ }
1184
+ });
1185
+ }
1186
+ getMetadataAttempt() {
1187
+ return m(this, null, function* () {
1188
+ let 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");
1189
+ return JSON.parse(n.decode(r));
1190
+ });
1191
+ }
1192
+ getMetadata() {
1193
+ return m(this, null, function* () {
1194
+ try {
1195
+ return yield this.getMetadataAttempt();
1196
+ } catch (e) {
1197
+ if (e instanceof E) return this.cache.invalidate(this.source), yield this.getMetadataAttempt();
1198
+ throw e;
1199
+ }
1200
+ });
1201
+ }
1202
+ getTileJson(e) {
1203
+ return m(this, null, function* () {
1204
+ let t = yield this.getHeader(), r = yield this.getMetadata(), n = _(t.tileType);
1205
+ return { tilejson: "3.0.0", scheme: "xyz", tiles: [`${e}/{z}/{x}/{y}${n}`], 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 };
1206
+ });
1207
+ }
1208
+ };
1209
+ l(B, "PMTiles");
1210
+ var x = B;
1211
+ function Point(x22, y) {
1212
+ this.x = x22;
1213
+ this.y = y;
1214
+ }
1215
+ Point.prototype = {
1216
+ /**
1217
+ * Clone this point, returning a new point that can be modified
1218
+ * without affecting the old one.
1219
+ * @return {Point} the clone
1220
+ */
1221
+ clone() {
1222
+ return new Point(this.x, this.y);
1223
+ },
1224
+ /**
1225
+ * Add this point's x & y coordinates to another point,
1226
+ * yielding a new point.
1227
+ * @param {Point} p the other point
1228
+ * @return {Point} output point
1229
+ */
1230
+ add(p) {
1231
+ return this.clone()._add(p);
1232
+ },
1233
+ /**
1234
+ * Subtract this point's x & y coordinates to from point,
1235
+ * yielding a new point.
1236
+ * @param {Point} p the other point
1237
+ * @return {Point} output point
1238
+ */
1239
+ sub(p) {
1240
+ return this.clone()._sub(p);
1241
+ },
1242
+ /**
1243
+ * Multiply this point's x & y coordinates by point,
1244
+ * yielding a new point.
1245
+ * @param {Point} p the other point
1246
+ * @return {Point} output point
1247
+ */
1248
+ multByPoint(p) {
1249
+ return this.clone()._multByPoint(p);
1250
+ },
1251
+ /**
1252
+ * Divide this point's x & y coordinates by point,
1253
+ * yielding a new point.
1254
+ * @param {Point} p the other point
1255
+ * @return {Point} output point
1256
+ */
1257
+ divByPoint(p) {
1258
+ return this.clone()._divByPoint(p);
1259
+ },
1260
+ /**
1261
+ * Multiply this point's x & y coordinates by a factor,
1262
+ * yielding a new point.
1263
+ * @param {number} k factor
1264
+ * @return {Point} output point
1265
+ */
1266
+ mult(k2) {
1267
+ return this.clone()._mult(k2);
1268
+ },
1269
+ /**
1270
+ * Divide this point's x & y coordinates by a factor,
1271
+ * yielding a new point.
1272
+ * @param {number} k factor
1273
+ * @return {Point} output point
1274
+ */
1275
+ div(k2) {
1276
+ return this.clone()._div(k2);
1277
+ },
1278
+ /**
1279
+ * Rotate this point around the 0, 0 origin by an angle a,
1280
+ * given in radians
1281
+ * @param {number} a angle to rotate around, in radians
1282
+ * @return {Point} output point
1283
+ */
1284
+ rotate(a) {
1285
+ return this.clone()._rotate(a);
1286
+ },
1287
+ /**
1288
+ * Rotate this point around p point by an angle a,
1289
+ * given in radians
1290
+ * @param {number} a angle to rotate around, in radians
1291
+ * @param {Point} p Point to rotate around
1292
+ * @return {Point} output point
1293
+ */
1294
+ rotateAround(a, p) {
1295
+ return this.clone()._rotateAround(a, p);
1296
+ },
1297
+ /**
1298
+ * Multiply this point by a 4x1 transformation matrix
1299
+ * @param {[number, number, number, number]} m transformation matrix
1300
+ * @return {Point} output point
1301
+ */
1302
+ matMult(m2) {
1303
+ return this.clone()._matMult(m2);
1304
+ },
1305
+ /**
1306
+ * Calculate this point but as a unit vector from 0, 0, meaning
1307
+ * that the distance from the resulting point to the 0, 0
1308
+ * coordinate will be equal to 1 and the angle from the resulting
1309
+ * point to the 0, 0 coordinate will be the same as before.
1310
+ * @return {Point} unit vector point
1311
+ */
1312
+ unit() {
1313
+ return this.clone()._unit();
1314
+ },
1315
+ /**
1316
+ * Compute a perpendicular point, where the new y coordinate
1317
+ * is the old x coordinate and the new x coordinate is the old y
1318
+ * coordinate multiplied by -1
1319
+ * @return {Point} perpendicular point
1320
+ */
1321
+ perp() {
1322
+ return this.clone()._perp();
1323
+ },
1324
+ /**
1325
+ * Return a version of this point with the x & y coordinates
1326
+ * rounded to integers.
1327
+ * @return {Point} rounded point
1328
+ */
1329
+ round() {
1330
+ return this.clone()._round();
1331
+ },
1332
+ /**
1333
+ * Return the magnitude of this point: this is the Euclidean
1334
+ * distance from the 0, 0 coordinate to this point's x and y
1335
+ * coordinates.
1336
+ * @return {number} magnitude
1337
+ */
1338
+ mag() {
1339
+ return Math.sqrt(this.x * this.x + this.y * this.y);
1340
+ },
1341
+ /**
1342
+ * Judge whether this point is equal to another point, returning
1343
+ * true or false.
1344
+ * @param {Point} other the other point
1345
+ * @return {boolean} whether the points are equal
1346
+ */
1347
+ equals(other) {
1348
+ return this.x === other.x && this.y === other.y;
1349
+ },
1350
+ /**
1351
+ * Calculate the distance from this point to another point
1352
+ * @param {Point} p the other point
1353
+ * @return {number} distance
1354
+ */
1355
+ dist(p) {
1356
+ return Math.sqrt(this.distSqr(p));
1357
+ },
1358
+ /**
1359
+ * Calculate the distance from this point to another point,
1360
+ * without the square root step. Useful if you're comparing
1361
+ * relative distances.
1362
+ * @param {Point} p the other point
1363
+ * @return {number} distance
1364
+ */
1365
+ distSqr(p) {
1366
+ const dx = p.x - this.x, dy = p.y - this.y;
1367
+ return dx * dx + dy * dy;
1368
+ },
1369
+ /**
1370
+ * Get the angle from the 0, 0 coordinate to this point, in radians
1371
+ * coordinates.
1372
+ * @return {number} angle
1373
+ */
1374
+ angle() {
1375
+ return Math.atan2(this.y, this.x);
1376
+ },
1377
+ /**
1378
+ * Get the angle from this point to another point, in radians
1379
+ * @param {Point} b the other point
1380
+ * @return {number} angle
1381
+ */
1382
+ angleTo(b2) {
1383
+ return Math.atan2(this.y - b2.y, this.x - b2.x);
1384
+ },
1385
+ /**
1386
+ * Get the angle between this point and another point, in radians
1387
+ * @param {Point} b the other point
1388
+ * @return {number} angle
1389
+ */
1390
+ angleWith(b2) {
1391
+ return this.angleWithSep(b2.x, b2.y);
1392
+ },
1393
+ /**
1394
+ * Find the angle of the two vectors, solving the formula for
1395
+ * the cross product a x b = |a||b|sin(θ) for θ.
1396
+ * @param {number} x the x-coordinate
1397
+ * @param {number} y the y-coordinate
1398
+ * @return {number} the angle in radians
1399
+ */
1400
+ angleWithSep(x22, y) {
1401
+ return Math.atan2(
1402
+ this.x * y - this.y * x22,
1403
+ this.x * x22 + this.y * y
1404
+ );
1405
+ },
1406
+ /** @param {[number, number, number, number]} m */
1407
+ _matMult(m2) {
1408
+ const x22 = m2[0] * this.x + m2[1] * this.y, y = m2[2] * this.x + m2[3] * this.y;
1409
+ this.x = x22;
1410
+ this.y = y;
1411
+ return this;
1412
+ },
1413
+ /** @param {Point} p */
1414
+ _add(p) {
1415
+ this.x += p.x;
1416
+ this.y += p.y;
1417
+ return this;
1418
+ },
1419
+ /** @param {Point} p */
1420
+ _sub(p) {
1421
+ this.x -= p.x;
1422
+ this.y -= p.y;
1423
+ return this;
1424
+ },
1425
+ /** @param {number} k */
1426
+ _mult(k2) {
1427
+ this.x *= k2;
1428
+ this.y *= k2;
1429
+ return this;
1430
+ },
1431
+ /** @param {number} k */
1432
+ _div(k2) {
1433
+ this.x /= k2;
1434
+ this.y /= k2;
1435
+ return this;
1436
+ },
1437
+ /** @param {Point} p */
1438
+ _multByPoint(p) {
1439
+ this.x *= p.x;
1440
+ this.y *= p.y;
1441
+ return this;
1442
+ },
1443
+ /** @param {Point} p */
1444
+ _divByPoint(p) {
1445
+ this.x /= p.x;
1446
+ this.y /= p.y;
1447
+ return this;
1448
+ },
1449
+ _unit() {
1450
+ this._div(this.mag());
1451
+ return this;
1452
+ },
1453
+ _perp() {
1454
+ const y = this.y;
1455
+ this.y = this.x;
1456
+ this.x = -y;
1457
+ return this;
1458
+ },
1459
+ /** @param {number} angle */
1460
+ _rotate(angle) {
1461
+ const cos = Math.cos(angle), sin = Math.sin(angle), x22 = cos * this.x - sin * this.y, y = sin * this.x + cos * this.y;
1462
+ this.x = x22;
1463
+ this.y = y;
1464
+ return this;
1465
+ },
1466
+ /**
1467
+ * @param {number} angle
1468
+ * @param {Point} p
1469
+ */
1470
+ _rotateAround(angle, p) {
1471
+ const cos = Math.cos(angle), sin = Math.sin(angle), x22 = p.x + cos * (this.x - p.x) - sin * (this.y - p.y), y = p.y + sin * (this.x - p.x) + cos * (this.y - p.y);
1472
+ this.x = x22;
1473
+ this.y = y;
1474
+ return this;
1475
+ },
1476
+ _round() {
1477
+ this.x = Math.round(this.x);
1478
+ this.y = Math.round(this.y);
1479
+ return this;
1480
+ },
1481
+ constructor: Point
1482
+ };
1483
+ Point.convert = function(p) {
1484
+ if (p instanceof Point) {
1485
+ return (
1486
+ /** @type {Point} */
1487
+ p
1488
+ );
1489
+ }
1490
+ if (Array.isArray(p)) {
1491
+ return new Point(+p[0], +p[1]);
1492
+ }
1493
+ if (p.x !== void 0 && p.y !== void 0) {
1494
+ return new Point(+p.x, +p.y);
1495
+ }
1496
+ throw new Error("Expected [x, y] or {x, y} point format");
1497
+ };
1498
+ var VectorTileFeature = class {
1499
+ /**
1500
+ * @param {Pbf} pbf
1501
+ * @param {number} end
1502
+ * @param {number} extent
1503
+ * @param {string[]} keys
1504
+ * @param {(number | string | boolean)[]} values
1505
+ */
1506
+ constructor(pbf, end, extent, keys, values) {
1507
+ this.properties = {};
1508
+ this.extent = extent;
1509
+ this.type = 0;
1510
+ this.id = void 0;
1511
+ this._pbf = pbf;
1512
+ this._geometry = -1;
1513
+ this._keys = keys;
1514
+ this._values = values;
1515
+ pbf.readFields(readFeature, this, end);
1516
+ }
1517
+ loadGeometry() {
1518
+ const pbf = this._pbf;
1519
+ pbf.pos = this._geometry;
1520
+ const end = pbf.readVarint() + pbf.pos;
1521
+ const lines = [];
1522
+ let line;
1523
+ let cmd = 1;
1524
+ let length = 0;
1525
+ let x22 = 0;
1526
+ let y = 0;
1527
+ while (pbf.pos < end) {
1528
+ if (length <= 0) {
1529
+ const cmdLen = pbf.readVarint();
1530
+ cmd = cmdLen & 7;
1531
+ length = cmdLen >> 3;
1532
+ }
1533
+ length--;
1534
+ if (cmd === 1 || cmd === 2) {
1535
+ x22 += pbf.readSVarint();
1536
+ y += pbf.readSVarint();
1537
+ if (cmd === 1) {
1538
+ if (line) lines.push(line);
1539
+ line = [];
1540
+ }
1541
+ if (line) line.push(new Point(x22, y));
1542
+ } else if (cmd === 7) {
1543
+ if (line) {
1544
+ line.push(line[0].clone());
1545
+ }
1546
+ } else {
1547
+ throw new Error(`unknown command ${cmd}`);
1548
+ }
1549
+ }
1550
+ if (line) lines.push(line);
1551
+ return lines;
1552
+ }
1553
+ bbox() {
1554
+ const pbf = this._pbf;
1555
+ pbf.pos = this._geometry;
1556
+ const end = pbf.readVarint() + pbf.pos;
1557
+ let cmd = 1, length = 0, x22 = 0, y = 0, x1 = Infinity, x222 = -Infinity, y1 = Infinity, y2 = -Infinity;
1558
+ while (pbf.pos < end) {
1559
+ if (length <= 0) {
1560
+ const cmdLen = pbf.readVarint();
1561
+ cmd = cmdLen & 7;
1562
+ length = cmdLen >> 3;
1563
+ }
1564
+ length--;
1565
+ if (cmd === 1 || cmd === 2) {
1566
+ x22 += pbf.readSVarint();
1567
+ y += pbf.readSVarint();
1568
+ if (x22 < x1) x1 = x22;
1569
+ if (x22 > x222) x222 = x22;
1570
+ if (y < y1) y1 = y;
1571
+ if (y > y2) y2 = y;
1572
+ } else if (cmd !== 7) {
1573
+ throw new Error(`unknown command ${cmd}`);
1574
+ }
1575
+ }
1576
+ return [x1, y1, x222, y2];
1577
+ }
1578
+ /**
1579
+ * @param {number} x
1580
+ * @param {number} y
1581
+ * @param {number} z
1582
+ * @return {Feature}
1583
+ */
1584
+ toGeoJSON(x22, y, z2) {
1585
+ const size = this.extent * Math.pow(2, z2), x0 = this.extent * x22, y0 = this.extent * y, vtCoords = this.loadGeometry();
1586
+ function projectPoint(p) {
1587
+ return [
1588
+ (p.x + x0) * 360 / size - 180,
1589
+ 360 / Math.PI * Math.atan(Math.exp((1 - (p.y + y0) * 2 / size) * Math.PI)) - 90
1590
+ ];
1591
+ }
1592
+ function projectLine(line) {
1593
+ return line.map(projectPoint);
1594
+ }
1595
+ let geometry;
1596
+ if (this.type === 1) {
1597
+ const points = [];
1598
+ for (const line of vtCoords) {
1599
+ points.push(line[0]);
1600
+ }
1601
+ const coordinates = projectLine(points);
1602
+ geometry = points.length === 1 ? { type: "Point", coordinates: coordinates[0] } : { type: "MultiPoint", coordinates };
1603
+ } else if (this.type === 2) {
1604
+ const coordinates = vtCoords.map(projectLine);
1605
+ geometry = coordinates.length === 1 ? { type: "LineString", coordinates: coordinates[0] } : { type: "MultiLineString", coordinates };
1606
+ } else if (this.type === 3) {
1607
+ const polygons = classifyRings(vtCoords);
1608
+ const coordinates = [];
1609
+ for (const polygon of polygons) {
1610
+ coordinates.push(polygon.map(projectLine));
1611
+ }
1612
+ geometry = coordinates.length === 1 ? { type: "Polygon", coordinates: coordinates[0] } : { type: "MultiPolygon", coordinates };
1613
+ } else {
1614
+ throw new Error("unknown feature type");
1615
+ }
1616
+ const result = {
1617
+ type: "Feature",
1618
+ geometry,
1619
+ properties: this.properties
1620
+ };
1621
+ if (this.id != null) {
1622
+ result.id = this.id;
1623
+ }
1624
+ return result;
1625
+ }
1626
+ };
1627
+ VectorTileFeature.types = ["Unknown", "Point", "LineString", "Polygon"];
1628
+ function readFeature(tag, feature, pbf) {
1629
+ if (tag === 1) feature.id = pbf.readVarint();
1630
+ else if (tag === 2) readTag(pbf, feature);
1631
+ else if (tag === 3) feature.type = /** @type {0 | 1 | 2 | 3} */
1632
+ pbf.readVarint();
1633
+ else if (tag === 4) feature._geometry = pbf.pos;
1634
+ }
1635
+ function readTag(pbf, feature) {
1636
+ const end = pbf.readVarint() + pbf.pos;
1637
+ while (pbf.pos < end) {
1638
+ const key = feature._keys[pbf.readVarint()];
1639
+ const value = feature._values[pbf.readVarint()];
1640
+ feature.properties[key] = value;
1641
+ }
1642
+ }
1643
+ function classifyRings(rings) {
1644
+ const len = rings.length;
1645
+ if (len <= 1) return [rings];
1646
+ const polygons = [];
1647
+ let polygon, ccw;
1648
+ for (let i2 = 0; i2 < len; i2++) {
1649
+ const area = signedArea(rings[i2]);
1650
+ if (area === 0) continue;
1651
+ if (ccw === void 0) ccw = area < 0;
1652
+ if (ccw === area < 0) {
1653
+ if (polygon) polygons.push(polygon);
1654
+ polygon = [rings[i2]];
1655
+ } else if (polygon) {
1656
+ polygon.push(rings[i2]);
1657
+ }
1658
+ }
1659
+ if (polygon) polygons.push(polygon);
1660
+ return polygons;
1661
+ }
1662
+ function signedArea(ring) {
1663
+ let sum = 0;
1664
+ for (let i2 = 0, len = ring.length, j2 = len - 1, p1, p2; i2 < len; j2 = i2++) {
1665
+ p1 = ring[i2];
1666
+ p2 = ring[j2];
1667
+ sum += (p2.x - p1.x) * (p1.y + p2.y);
1668
+ }
1669
+ return sum;
1670
+ }
1671
+ var VectorTileLayer = class {
1672
+ /**
1673
+ * @param {Pbf} pbf
1674
+ * @param {number} [end]
1675
+ */
1676
+ constructor(pbf, end) {
1677
+ this.version = 1;
1678
+ this.name = "";
1679
+ this.extent = 4096;
1680
+ this.length = 0;
1681
+ this._pbf = pbf;
1682
+ this._keys = [];
1683
+ this._values = [];
1684
+ this._features = [];
1685
+ pbf.readFields(readLayer, this, end);
1686
+ this.length = this._features.length;
1687
+ }
1688
+ /** return feature `i` from this layer as a `VectorTileFeature`
1689
+ * @param {number} i
1690
+ */
1691
+ feature(i2) {
1692
+ if (i2 < 0 || i2 >= this._features.length) throw new Error("feature index out of bounds");
1693
+ this._pbf.pos = this._features[i2];
1694
+ const end = this._pbf.readVarint() + this._pbf.pos;
1695
+ return new VectorTileFeature(this._pbf, end, this.extent, this._keys, this._values);
1696
+ }
1697
+ };
1698
+ function readLayer(tag, layer, pbf) {
1699
+ if (tag === 15) layer.version = pbf.readVarint();
1700
+ else if (tag === 1) layer.name = pbf.readString();
1701
+ else if (tag === 5) layer.extent = pbf.readVarint();
1702
+ else if (tag === 2) layer._features.push(pbf.pos);
1703
+ else if (tag === 3) layer._keys.push(pbf.readString());
1704
+ else if (tag === 4) layer._values.push(readValueMessage(pbf));
1705
+ }
1706
+ function readValueMessage(pbf) {
1707
+ let value = null;
1708
+ const end = pbf.readVarint() + pbf.pos;
1709
+ while (pbf.pos < end) {
1710
+ const tag = pbf.readVarint() >> 3;
1711
+ value = tag === 1 ? pbf.readString() : tag === 2 ? pbf.readFloat() : tag === 3 ? pbf.readDouble() : tag === 4 ? pbf.readVarint64() : tag === 5 ? pbf.readVarint() : tag === 6 ? pbf.readSVarint() : tag === 7 ? pbf.readBoolean() : null;
1712
+ }
1713
+ if (value == null) {
1714
+ throw new Error("unknown feature value");
1715
+ }
1716
+ return value;
1717
+ }
1718
+ var VectorTile = class {
1719
+ /**
1720
+ * @param {Pbf} pbf
1721
+ * @param {number} [end]
1722
+ */
1723
+ constructor(pbf, end) {
1724
+ this.layers = pbf.readFields(readTile, {}, end);
1725
+ }
1726
+ };
1727
+ function readTile(tag, layers, pbf) {
1728
+ if (tag === 3) {
1729
+ const layer = new VectorTileLayer(pbf, pbf.readVarint() + pbf.pos);
1730
+ if (layer.length) layers[layer.name] = layer;
1731
+ }
1732
+ }
1733
+ var SHIFT_LEFT_32 = (1 << 16) * (1 << 16);
1734
+ var SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32;
1735
+ var TEXT_DECODER_MIN_LENGTH = 12;
1736
+ var utf8TextDecoder = typeof TextDecoder === "undefined" ? null : new TextDecoder("utf-8");
1737
+ var PBF_VARINT = 0;
1738
+ var PBF_FIXED64 = 1;
1739
+ var PBF_BYTES = 2;
1740
+ var PBF_FIXED32 = 5;
1741
+ var Pbf = class {
1742
+ /**
1743
+ * @param {Uint8Array | ArrayBuffer} [buf]
1744
+ */
1745
+ constructor(buf = new Uint8Array(16)) {
1746
+ this.buf = ArrayBuffer.isView(buf) ? buf : new Uint8Array(buf);
1747
+ this.dataView = new DataView(this.buf.buffer);
1748
+ this.pos = 0;
1749
+ this.type = 0;
1750
+ this.length = this.buf.length;
1751
+ }
1752
+ // === READING =================================================================
1753
+ /**
1754
+ * @template T
1755
+ * @param {(tag: number, result: T, pbf: Pbf) => void} readField
1756
+ * @param {T} result
1757
+ * @param {number} [end]
1758
+ */
1759
+ readFields(readField, result, end = this.length) {
1760
+ while (this.pos < end) {
1761
+ const val = this.readVarint(), tag = val >> 3, startPos = this.pos;
1762
+ this.type = val & 7;
1763
+ readField(tag, result, this);
1764
+ if (this.pos === startPos) this.skip(val);
1765
+ }
1766
+ return result;
1767
+ }
1768
+ /**
1769
+ * @template T
1770
+ * @param {(tag: number, result: T, pbf: Pbf) => void} readField
1771
+ * @param {T} result
1772
+ */
1773
+ readMessage(readField, result) {
1774
+ return this.readFields(readField, result, this.readVarint() + this.pos);
1775
+ }
1776
+ readFixed32() {
1777
+ const val = this.dataView.getUint32(this.pos, true);
1778
+ this.pos += 4;
1779
+ return val;
1780
+ }
1781
+ readSFixed32() {
1782
+ const val = this.dataView.getInt32(this.pos, true);
1783
+ this.pos += 4;
1784
+ return val;
1785
+ }
1786
+ // 64-bit int handling is based on github.com/dpw/node-buffer-more-ints (MIT-licensed)
1787
+ readFixed64() {
1788
+ const val = this.dataView.getUint32(this.pos, true) + this.dataView.getUint32(this.pos + 4, true) * SHIFT_LEFT_32;
1789
+ this.pos += 8;
1790
+ return val;
1791
+ }
1792
+ readSFixed64() {
1793
+ const val = this.dataView.getUint32(this.pos, true) + this.dataView.getInt32(this.pos + 4, true) * SHIFT_LEFT_32;
1794
+ this.pos += 8;
1795
+ return val;
1796
+ }
1797
+ readFloat() {
1798
+ const val = this.dataView.getFloat32(this.pos, true);
1799
+ this.pos += 4;
1800
+ return val;
1801
+ }
1802
+ readDouble() {
1803
+ const val = this.dataView.getFloat64(this.pos, true);
1804
+ this.pos += 8;
1805
+ return val;
1806
+ }
1807
+ /**
1808
+ * @param {boolean} [isSigned]
1809
+ */
1810
+ readVarint(isSigned) {
1811
+ const buf = this.buf;
1812
+ let val, b2;
1813
+ b2 = buf[this.pos++];
1814
+ val = b2 & 127;
1815
+ if (b2 < 128) return val;
1816
+ b2 = buf[this.pos++];
1817
+ val |= (b2 & 127) << 7;
1818
+ if (b2 < 128) return val;
1819
+ b2 = buf[this.pos++];
1820
+ val |= (b2 & 127) << 14;
1821
+ if (b2 < 128) return val;
1822
+ b2 = buf[this.pos++];
1823
+ val |= (b2 & 127) << 21;
1824
+ if (b2 < 128) return val;
1825
+ b2 = buf[this.pos];
1826
+ val |= (b2 & 15) << 28;
1827
+ return readVarintRemainder(val, isSigned, this);
1828
+ }
1829
+ readVarint64() {
1830
+ return this.readVarint(true);
1831
+ }
1832
+ readSVarint() {
1833
+ const num = this.readVarint();
1834
+ return num % 2 === 1 ? (num + 1) / -2 : num / 2;
1835
+ }
1836
+ readBoolean() {
1837
+ return Boolean(this.readVarint());
1838
+ }
1839
+ readString() {
1840
+ const end = this.readVarint() + this.pos;
1841
+ const pos = this.pos;
1842
+ this.pos = end;
1843
+ if (end - pos >= TEXT_DECODER_MIN_LENGTH && utf8TextDecoder) {
1844
+ return utf8TextDecoder.decode(this.buf.subarray(pos, end));
1845
+ }
1846
+ return readUtf8(this.buf, pos, end);
1847
+ }
1848
+ readBytes() {
1849
+ const end = this.readVarint() + this.pos, buffer = this.buf.subarray(this.pos, end);
1850
+ this.pos = end;
1851
+ return buffer;
1852
+ }
1853
+ // verbose for performance reasons; doesn't affect gzipped size
1854
+ /**
1855
+ * @param {number[]} [arr]
1856
+ * @param {boolean} [isSigned]
1857
+ */
1858
+ readPackedVarint(arr = [], isSigned) {
1859
+ const end = this.readPackedEnd();
1860
+ while (this.pos < end) arr.push(this.readVarint(isSigned));
1861
+ return arr;
1862
+ }
1863
+ /** @param {number[]} [arr] */
1864
+ readPackedSVarint(arr = []) {
1865
+ const end = this.readPackedEnd();
1866
+ while (this.pos < end) arr.push(this.readSVarint());
1867
+ return arr;
1868
+ }
1869
+ /** @param {boolean[]} [arr] */
1870
+ readPackedBoolean(arr = []) {
1871
+ const end = this.readPackedEnd();
1872
+ while (this.pos < end) arr.push(this.readBoolean());
1873
+ return arr;
1874
+ }
1875
+ /** @param {number[]} [arr] */
1876
+ readPackedFloat(arr = []) {
1877
+ const end = this.readPackedEnd();
1878
+ while (this.pos < end) arr.push(this.readFloat());
1879
+ return arr;
1880
+ }
1881
+ /** @param {number[]} [arr] */
1882
+ readPackedDouble(arr = []) {
1883
+ const end = this.readPackedEnd();
1884
+ while (this.pos < end) arr.push(this.readDouble());
1885
+ return arr;
1886
+ }
1887
+ /** @param {number[]} [arr] */
1888
+ readPackedFixed32(arr = []) {
1889
+ const end = this.readPackedEnd();
1890
+ while (this.pos < end) arr.push(this.readFixed32());
1891
+ return arr;
1892
+ }
1893
+ /** @param {number[]} [arr] */
1894
+ readPackedSFixed32(arr = []) {
1895
+ const end = this.readPackedEnd();
1896
+ while (this.pos < end) arr.push(this.readSFixed32());
1897
+ return arr;
1898
+ }
1899
+ /** @param {number[]} [arr] */
1900
+ readPackedFixed64(arr = []) {
1901
+ const end = this.readPackedEnd();
1902
+ while (this.pos < end) arr.push(this.readFixed64());
1903
+ return arr;
1904
+ }
1905
+ /** @param {number[]} [arr] */
1906
+ readPackedSFixed64(arr = []) {
1907
+ const end = this.readPackedEnd();
1908
+ while (this.pos < end) arr.push(this.readSFixed64());
1909
+ return arr;
1910
+ }
1911
+ readPackedEnd() {
1912
+ return this.type === PBF_BYTES ? this.readVarint() + this.pos : this.pos + 1;
1913
+ }
1914
+ /** @param {number} val */
1915
+ skip(val) {
1916
+ const type = val & 7;
1917
+ if (type === PBF_VARINT) while (this.buf[this.pos++] > 127) {
1918
+ }
1919
+ else if (type === PBF_BYTES) this.pos = this.readVarint() + this.pos;
1920
+ else if (type === PBF_FIXED32) this.pos += 4;
1921
+ else if (type === PBF_FIXED64) this.pos += 8;
1922
+ else throw new Error(`Unimplemented type: ${type}`);
1923
+ }
1924
+ // === WRITING =================================================================
1925
+ /**
1926
+ * @param {number} tag
1927
+ * @param {number} type
1928
+ */
1929
+ writeTag(tag, type) {
1930
+ this.writeVarint(tag << 3 | type);
1931
+ }
1932
+ /** @param {number} min */
1933
+ realloc(min) {
1934
+ let length = this.length || 16;
1935
+ while (length < this.pos + min) length *= 2;
1936
+ if (length !== this.length) {
1937
+ const buf = new Uint8Array(length);
1938
+ buf.set(this.buf);
1939
+ this.buf = buf;
1940
+ this.dataView = new DataView(buf.buffer);
1941
+ this.length = length;
1942
+ }
1943
+ }
1944
+ finish() {
1945
+ this.length = this.pos;
1946
+ this.pos = 0;
1947
+ return this.buf.subarray(0, this.length);
1948
+ }
1949
+ /** @param {number} val */
1950
+ writeFixed32(val) {
1951
+ this.realloc(4);
1952
+ this.dataView.setInt32(this.pos, val, true);
1953
+ this.pos += 4;
1954
+ }
1955
+ /** @param {number} val */
1956
+ writeSFixed32(val) {
1957
+ this.realloc(4);
1958
+ this.dataView.setInt32(this.pos, val, true);
1959
+ this.pos += 4;
1960
+ }
1961
+ /** @param {number} val */
1962
+ writeFixed64(val) {
1963
+ this.realloc(8);
1964
+ this.dataView.setInt32(this.pos, val & -1, true);
1965
+ this.dataView.setInt32(this.pos + 4, Math.floor(val * SHIFT_RIGHT_32), true);
1966
+ this.pos += 8;
1967
+ }
1968
+ /** @param {number} val */
1969
+ writeSFixed64(val) {
1970
+ this.realloc(8);
1971
+ this.dataView.setInt32(this.pos, val & -1, true);
1972
+ this.dataView.setInt32(this.pos + 4, Math.floor(val * SHIFT_RIGHT_32), true);
1973
+ this.pos += 8;
1974
+ }
1975
+ /** @param {number} val */
1976
+ writeVarint(val) {
1977
+ val = +val || 0;
1978
+ if (val > 268435455 || val < 0) {
1979
+ writeBigVarint(val, this);
1980
+ return;
1981
+ }
1982
+ this.realloc(4);
1983
+ this.buf[this.pos++] = val & 127 | (val > 127 ? 128 : 0);
1984
+ if (val <= 127) return;
1985
+ this.buf[this.pos++] = (val >>>= 7) & 127 | (val > 127 ? 128 : 0);
1986
+ if (val <= 127) return;
1987
+ this.buf[this.pos++] = (val >>>= 7) & 127 | (val > 127 ? 128 : 0);
1988
+ if (val <= 127) return;
1989
+ this.buf[this.pos++] = val >>> 7 & 127;
1990
+ }
1991
+ /** @param {number} val */
1992
+ writeSVarint(val) {
1993
+ this.writeVarint(val < 0 ? -val * 2 - 1 : val * 2);
1994
+ }
1995
+ /** @param {boolean} val */
1996
+ writeBoolean(val) {
1997
+ this.writeVarint(+val);
1998
+ }
1999
+ /** @param {string} str */
2000
+ writeString(str) {
2001
+ str = String(str);
2002
+ this.realloc(str.length * 4);
2003
+ this.pos++;
2004
+ const startPos = this.pos;
2005
+ this.pos = writeUtf8(this.buf, str, this.pos);
2006
+ const len = this.pos - startPos;
2007
+ if (len >= 128) makeRoomForExtraLength(startPos, len, this);
2008
+ this.pos = startPos - 1;
2009
+ this.writeVarint(len);
2010
+ this.pos += len;
2011
+ }
2012
+ /** @param {number} val */
2013
+ writeFloat(val) {
2014
+ this.realloc(4);
2015
+ this.dataView.setFloat32(this.pos, val, true);
2016
+ this.pos += 4;
2017
+ }
2018
+ /** @param {number} val */
2019
+ writeDouble(val) {
2020
+ this.realloc(8);
2021
+ this.dataView.setFloat64(this.pos, val, true);
2022
+ this.pos += 8;
2023
+ }
2024
+ /** @param {Uint8Array} buffer */
2025
+ writeBytes(buffer) {
2026
+ const len = buffer.length;
2027
+ this.writeVarint(len);
2028
+ this.realloc(len);
2029
+ for (let i2 = 0; i2 < len; i2++) this.buf[this.pos++] = buffer[i2];
2030
+ }
2031
+ /**
2032
+ * @template T
2033
+ * @param {(obj: T, pbf: Pbf) => void} fn
2034
+ * @param {T} obj
2035
+ */
2036
+ writeRawMessage(fn, obj) {
2037
+ this.pos++;
2038
+ const startPos = this.pos;
2039
+ fn(obj, this);
2040
+ const len = this.pos - startPos;
2041
+ if (len >= 128) makeRoomForExtraLength(startPos, len, this);
2042
+ this.pos = startPos - 1;
2043
+ this.writeVarint(len);
2044
+ this.pos += len;
2045
+ }
2046
+ /**
2047
+ * @template T
2048
+ * @param {number} tag
2049
+ * @param {(obj: T, pbf: Pbf) => void} fn
2050
+ * @param {T} obj
2051
+ */
2052
+ writeMessage(tag, fn, obj) {
2053
+ this.writeTag(tag, PBF_BYTES);
2054
+ this.writeRawMessage(fn, obj);
2055
+ }
2056
+ /**
2057
+ * @param {number} tag
2058
+ * @param {number[]} arr
2059
+ */
2060
+ writePackedVarint(tag, arr) {
2061
+ if (arr.length) this.writeMessage(tag, writePackedVarint, arr);
2062
+ }
2063
+ /**
2064
+ * @param {number} tag
2065
+ * @param {number[]} arr
2066
+ */
2067
+ writePackedSVarint(tag, arr) {
2068
+ if (arr.length) this.writeMessage(tag, writePackedSVarint, arr);
2069
+ }
2070
+ /**
2071
+ * @param {number} tag
2072
+ * @param {boolean[]} arr
2073
+ */
2074
+ writePackedBoolean(tag, arr) {
2075
+ if (arr.length) this.writeMessage(tag, writePackedBoolean, arr);
2076
+ }
2077
+ /**
2078
+ * @param {number} tag
2079
+ * @param {number[]} arr
2080
+ */
2081
+ writePackedFloat(tag, arr) {
2082
+ if (arr.length) this.writeMessage(tag, writePackedFloat, arr);
2083
+ }
2084
+ /**
2085
+ * @param {number} tag
2086
+ * @param {number[]} arr
2087
+ */
2088
+ writePackedDouble(tag, arr) {
2089
+ if (arr.length) this.writeMessage(tag, writePackedDouble, arr);
2090
+ }
2091
+ /**
2092
+ * @param {number} tag
2093
+ * @param {number[]} arr
2094
+ */
2095
+ writePackedFixed32(tag, arr) {
2096
+ if (arr.length) this.writeMessage(tag, writePackedFixed32, arr);
2097
+ }
2098
+ /**
2099
+ * @param {number} tag
2100
+ * @param {number[]} arr
2101
+ */
2102
+ writePackedSFixed32(tag, arr) {
2103
+ if (arr.length) this.writeMessage(tag, writePackedSFixed32, arr);
2104
+ }
2105
+ /**
2106
+ * @param {number} tag
2107
+ * @param {number[]} arr
2108
+ */
2109
+ writePackedFixed64(tag, arr) {
2110
+ if (arr.length) this.writeMessage(tag, writePackedFixed64, arr);
2111
+ }
2112
+ /**
2113
+ * @param {number} tag
2114
+ * @param {number[]} arr
2115
+ */
2116
+ writePackedSFixed64(tag, arr) {
2117
+ if (arr.length) this.writeMessage(tag, writePackedSFixed64, arr);
2118
+ }
2119
+ /**
2120
+ * @param {number} tag
2121
+ * @param {Uint8Array} buffer
2122
+ */
2123
+ writeBytesField(tag, buffer) {
2124
+ this.writeTag(tag, PBF_BYTES);
2125
+ this.writeBytes(buffer);
2126
+ }
2127
+ /**
2128
+ * @param {number} tag
2129
+ * @param {number} val
2130
+ */
2131
+ writeFixed32Field(tag, val) {
2132
+ this.writeTag(tag, PBF_FIXED32);
2133
+ this.writeFixed32(val);
2134
+ }
2135
+ /**
2136
+ * @param {number} tag
2137
+ * @param {number} val
2138
+ */
2139
+ writeSFixed32Field(tag, val) {
2140
+ this.writeTag(tag, PBF_FIXED32);
2141
+ this.writeSFixed32(val);
2142
+ }
2143
+ /**
2144
+ * @param {number} tag
2145
+ * @param {number} val
2146
+ */
2147
+ writeFixed64Field(tag, val) {
2148
+ this.writeTag(tag, PBF_FIXED64);
2149
+ this.writeFixed64(val);
2150
+ }
2151
+ /**
2152
+ * @param {number} tag
2153
+ * @param {number} val
2154
+ */
2155
+ writeSFixed64Field(tag, val) {
2156
+ this.writeTag(tag, PBF_FIXED64);
2157
+ this.writeSFixed64(val);
2158
+ }
2159
+ /**
2160
+ * @param {number} tag
2161
+ * @param {number} val
2162
+ */
2163
+ writeVarintField(tag, val) {
2164
+ this.writeTag(tag, PBF_VARINT);
2165
+ this.writeVarint(val);
2166
+ }
2167
+ /**
2168
+ * @param {number} tag
2169
+ * @param {number} val
2170
+ */
2171
+ writeSVarintField(tag, val) {
2172
+ this.writeTag(tag, PBF_VARINT);
2173
+ this.writeSVarint(val);
2174
+ }
2175
+ /**
2176
+ * @param {number} tag
2177
+ * @param {string} str
2178
+ */
2179
+ writeStringField(tag, str) {
2180
+ this.writeTag(tag, PBF_BYTES);
2181
+ this.writeString(str);
2182
+ }
2183
+ /**
2184
+ * @param {number} tag
2185
+ * @param {number} val
2186
+ */
2187
+ writeFloatField(tag, val) {
2188
+ this.writeTag(tag, PBF_FIXED32);
2189
+ this.writeFloat(val);
2190
+ }
2191
+ /**
2192
+ * @param {number} tag
2193
+ * @param {number} val
2194
+ */
2195
+ writeDoubleField(tag, val) {
2196
+ this.writeTag(tag, PBF_FIXED64);
2197
+ this.writeDouble(val);
2198
+ }
2199
+ /**
2200
+ * @param {number} tag
2201
+ * @param {boolean} val
2202
+ */
2203
+ writeBooleanField(tag, val) {
2204
+ this.writeVarintField(tag, +val);
2205
+ }
2206
+ };
2207
+ function readVarintRemainder(l2, s, p) {
2208
+ const buf = p.buf;
2209
+ let h, b2;
2210
+ b2 = buf[p.pos++];
2211
+ h = (b2 & 112) >> 4;
2212
+ if (b2 < 128) return toNum(l2, h, s);
2213
+ b2 = buf[p.pos++];
2214
+ h |= (b2 & 127) << 3;
2215
+ if (b2 < 128) return toNum(l2, h, s);
2216
+ b2 = buf[p.pos++];
2217
+ h |= (b2 & 127) << 10;
2218
+ if (b2 < 128) return toNum(l2, h, s);
2219
+ b2 = buf[p.pos++];
2220
+ h |= (b2 & 127) << 17;
2221
+ if (b2 < 128) return toNum(l2, h, s);
2222
+ b2 = buf[p.pos++];
2223
+ h |= (b2 & 127) << 24;
2224
+ if (b2 < 128) return toNum(l2, h, s);
2225
+ b2 = buf[p.pos++];
2226
+ h |= (b2 & 1) << 31;
2227
+ if (b2 < 128) return toNum(l2, h, s);
2228
+ throw new Error("Expected varint not more than 10 bytes");
2229
+ }
2230
+ function toNum(low, high, isSigned) {
2231
+ return isSigned ? high * 4294967296 + (low >>> 0) : (high >>> 0) * 4294967296 + (low >>> 0);
2232
+ }
2233
+ function writeBigVarint(val, pbf) {
2234
+ let low, high;
2235
+ if (val >= 0) {
2236
+ low = val % 4294967296 | 0;
2237
+ high = val / 4294967296 | 0;
2238
+ } else {
2239
+ low = ~(-val % 4294967296);
2240
+ high = ~(-val / 4294967296);
2241
+ if (low ^ 4294967295) {
2242
+ low = low + 1 | 0;
2243
+ } else {
2244
+ low = 0;
2245
+ high = high + 1 | 0;
2246
+ }
2247
+ }
2248
+ if (val >= 18446744073709552e3 || val < -18446744073709552e3) {
2249
+ throw new Error("Given varint doesn't fit into 10 bytes");
2250
+ }
2251
+ pbf.realloc(10);
2252
+ writeBigVarintLow(low, high, pbf);
2253
+ writeBigVarintHigh(high, pbf);
2254
+ }
2255
+ function writeBigVarintLow(low, high, pbf) {
2256
+ pbf.buf[pbf.pos++] = low & 127 | 128;
2257
+ low >>>= 7;
2258
+ pbf.buf[pbf.pos++] = low & 127 | 128;
2259
+ low >>>= 7;
2260
+ pbf.buf[pbf.pos++] = low & 127 | 128;
2261
+ low >>>= 7;
2262
+ pbf.buf[pbf.pos++] = low & 127 | 128;
2263
+ low >>>= 7;
2264
+ pbf.buf[pbf.pos] = low & 127;
2265
+ }
2266
+ function writeBigVarintHigh(high, pbf) {
2267
+ const lsb = (high & 7) << 4;
2268
+ pbf.buf[pbf.pos++] |= lsb | ((high >>>= 3) ? 128 : 0);
2269
+ if (!high) return;
2270
+ pbf.buf[pbf.pos++] = high & 127 | ((high >>>= 7) ? 128 : 0);
2271
+ if (!high) return;
2272
+ pbf.buf[pbf.pos++] = high & 127 | ((high >>>= 7) ? 128 : 0);
2273
+ if (!high) return;
2274
+ pbf.buf[pbf.pos++] = high & 127 | ((high >>>= 7) ? 128 : 0);
2275
+ if (!high) return;
2276
+ pbf.buf[pbf.pos++] = high & 127 | ((high >>>= 7) ? 128 : 0);
2277
+ if (!high) return;
2278
+ pbf.buf[pbf.pos++] = high & 127;
2279
+ }
2280
+ function makeRoomForExtraLength(startPos, len, pbf) {
2281
+ const extraLen = len <= 16383 ? 1 : len <= 2097151 ? 2 : len <= 268435455 ? 3 : Math.floor(Math.log(len) / (Math.LN2 * 7));
2282
+ pbf.realloc(extraLen);
2283
+ for (let i2 = pbf.pos - 1; i2 >= startPos; i2--) pbf.buf[i2 + extraLen] = pbf.buf[i2];
2284
+ }
2285
+ function writePackedVarint(arr, pbf) {
2286
+ for (let i2 = 0; i2 < arr.length; i2++) pbf.writeVarint(arr[i2]);
2287
+ }
2288
+ function writePackedSVarint(arr, pbf) {
2289
+ for (let i2 = 0; i2 < arr.length; i2++) pbf.writeSVarint(arr[i2]);
2290
+ }
2291
+ function writePackedFloat(arr, pbf) {
2292
+ for (let i2 = 0; i2 < arr.length; i2++) pbf.writeFloat(arr[i2]);
2293
+ }
2294
+ function writePackedDouble(arr, pbf) {
2295
+ for (let i2 = 0; i2 < arr.length; i2++) pbf.writeDouble(arr[i2]);
2296
+ }
2297
+ function writePackedBoolean(arr, pbf) {
2298
+ for (let i2 = 0; i2 < arr.length; i2++) pbf.writeBoolean(arr[i2]);
2299
+ }
2300
+ function writePackedFixed32(arr, pbf) {
2301
+ for (let i2 = 0; i2 < arr.length; i2++) pbf.writeFixed32(arr[i2]);
2302
+ }
2303
+ function writePackedSFixed32(arr, pbf) {
2304
+ for (let i2 = 0; i2 < arr.length; i2++) pbf.writeSFixed32(arr[i2]);
2305
+ }
2306
+ function writePackedFixed64(arr, pbf) {
2307
+ for (let i2 = 0; i2 < arr.length; i2++) pbf.writeFixed64(arr[i2]);
2308
+ }
2309
+ function writePackedSFixed64(arr, pbf) {
2310
+ for (let i2 = 0; i2 < arr.length; i2++) pbf.writeSFixed64(arr[i2]);
2311
+ }
2312
+ function readUtf8(buf, pos, end) {
2313
+ let str = "";
2314
+ let i2 = pos;
2315
+ while (i2 < end) {
2316
+ const b0 = buf[i2];
2317
+ let c = null;
2318
+ let bytesPerSequence = b0 > 239 ? 4 : b0 > 223 ? 3 : b0 > 191 ? 2 : 1;
2319
+ if (i2 + bytesPerSequence > end) break;
2320
+ let b1, b2, b3;
2321
+ if (bytesPerSequence === 1) {
2322
+ if (b0 < 128) {
2323
+ c = b0;
2324
+ }
2325
+ } else if (bytesPerSequence === 2) {
2326
+ b1 = buf[i2 + 1];
2327
+ if ((b1 & 192) === 128) {
2328
+ c = (b0 & 31) << 6 | b1 & 63;
2329
+ if (c <= 127) {
2330
+ c = null;
2331
+ }
2332
+ }
2333
+ } else if (bytesPerSequence === 3) {
2334
+ b1 = buf[i2 + 1];
2335
+ b2 = buf[i2 + 2];
2336
+ if ((b1 & 192) === 128 && (b2 & 192) === 128) {
2337
+ c = (b0 & 15) << 12 | (b1 & 63) << 6 | b2 & 63;
2338
+ if (c <= 2047 || c >= 55296 && c <= 57343) {
2339
+ c = null;
2340
+ }
2341
+ }
2342
+ } else if (bytesPerSequence === 4) {
2343
+ b1 = buf[i2 + 1];
2344
+ b2 = buf[i2 + 2];
2345
+ b3 = buf[i2 + 3];
2346
+ if ((b1 & 192) === 128 && (b2 & 192) === 128 && (b3 & 192) === 128) {
2347
+ c = (b0 & 15) << 18 | (b1 & 63) << 12 | (b2 & 63) << 6 | b3 & 63;
2348
+ if (c <= 65535 || c >= 1114112) {
2349
+ c = null;
2350
+ }
2351
+ }
2352
+ }
2353
+ if (c === null) {
2354
+ c = 65533;
2355
+ bytesPerSequence = 1;
2356
+ } else if (c > 65535) {
2357
+ c -= 65536;
2358
+ str += String.fromCharCode(c >>> 10 & 1023 | 55296);
2359
+ c = 56320 | c & 1023;
2360
+ }
2361
+ str += String.fromCharCode(c);
2362
+ i2 += bytesPerSequence;
2363
+ }
2364
+ return str;
2365
+ }
2366
+ function writeUtf8(buf, str, pos) {
2367
+ for (let i2 = 0, c, lead; i2 < str.length; i2++) {
2368
+ c = str.charCodeAt(i2);
2369
+ if (c > 55295 && c < 57344) {
2370
+ if (lead) {
2371
+ if (c < 56320) {
2372
+ buf[pos++] = 239;
2373
+ buf[pos++] = 191;
2374
+ buf[pos++] = 189;
2375
+ lead = c;
2376
+ continue;
2377
+ } else {
2378
+ c = lead - 55296 << 10 | c - 56320 | 65536;
2379
+ lead = null;
2380
+ }
2381
+ } else {
2382
+ if (c > 56319 || i2 + 1 === str.length) {
2383
+ buf[pos++] = 239;
2384
+ buf[pos++] = 191;
2385
+ buf[pos++] = 189;
2386
+ } else {
2387
+ lead = c;
2388
+ }
2389
+ continue;
2390
+ }
2391
+ } else if (lead) {
2392
+ buf[pos++] = 239;
2393
+ buf[pos++] = 191;
2394
+ buf[pos++] = 189;
2395
+ lead = null;
2396
+ }
2397
+ if (c < 128) {
2398
+ buf[pos++] = c;
2399
+ } else {
2400
+ if (c < 2048) {
2401
+ buf[pos++] = c >> 6 | 192;
2402
+ } else {
2403
+ if (c < 65536) {
2404
+ buf[pos++] = c >> 12 | 224;
2405
+ } else {
2406
+ buf[pos++] = c >> 18 | 240;
2407
+ buf[pos++] = c >> 12 & 63 | 128;
2408
+ }
2409
+ buf[pos++] = c >> 6 & 63 | 128;
2410
+ }
2411
+ buf[pos++] = c & 63 | 128;
2412
+ }
2413
+ }
2414
+ return pos;
2415
+ }
2416
+ var DEFAULT_CACHE_SIZE = 64;
2417
+ function toIndex(z2, x22, y) {
2418
+ return `${x22}:${y}:${z2}`;
2419
+ }
2420
+ function parseTile(buffer) {
2421
+ const tile = new VectorTile(new Pbf(buffer));
2422
+ const result = {};
2423
+ for (const [layerName, layer] of Object.entries(tile.layers)) {
2424
+ const features = [];
2425
+ for (let i2 = 0; i2 < layer.length; i2++) {
2426
+ const feature = layer.feature(i2);
2427
+ features.push({
2428
+ id: feature.id,
2429
+ type: feature.type,
2430
+ properties: feature.properties,
2431
+ geometry: feature.loadGeometry(),
2432
+ extent: layer.extent
2433
+ });
2434
+ }
2435
+ result[layerName] = features;
2436
+ }
2437
+ return result;
2438
+ }
2439
+ function transformForOverzoom(corrections, scale, offsetX, offsetY) {
2440
+ const result = {};
2441
+ for (const [layerName, features] of Object.entries(corrections)) {
2442
+ result[layerName] = features.map((feature) => {
2443
+ const extent = feature.extent;
2444
+ const childExtent = extent / scale;
2445
+ const startX = offsetX * childExtent;
2446
+ const startY = offsetY * childExtent;
2447
+ const newGeometry = feature.geometry.map((ring) => {
2448
+ return ring.map((point) => {
2449
+ const x22 = (point.x - startX) * scale;
2450
+ const y = (point.y - startY) * scale;
2451
+ return { x: x22, y };
2452
+ });
2453
+ });
2454
+ return {
2455
+ ...feature,
2456
+ geometry: newGeometry,
2457
+ // Keep original extent since we scaled coordinates to match
2458
+ extent
2459
+ };
2460
+ });
2461
+ }
2462
+ return result;
2463
+ }
2464
+ var CorrectionsSource = class {
2465
+ /**
2466
+ * @param {string} pmtilesUrl - URL to the PMTiles file
2467
+ * @param {Object} [options] - Options
2468
+ * @param {number} [options.cacheSize=64] - Maximum number of tiles to cache
2469
+ * @param {number} [options.maxDataZoom] - Maximum zoom level in PMTiles (auto-detected if not provided)
2470
+ */
2471
+ constructor(pmtilesUrl, options = {}) {
2472
+ this.pmtilesUrl = pmtilesUrl;
2473
+ this.pmtiles = new x(pmtilesUrl);
2474
+ this.cacheSize = options.cacheSize ?? DEFAULT_CACHE_SIZE;
2475
+ this.maxDataZoom = options.maxDataZoom;
2476
+ this.cache = /* @__PURE__ */ new Map();
2477
+ this.inflight = /* @__PURE__ */ new Map();
2478
+ }
2479
+ /**
2480
+ * Get the PMTiles source object.
2481
+ * @returns {PMTiles}
2482
+ */
2483
+ getSource() {
2484
+ return this.pmtiles;
2485
+ }
2486
+ /**
2487
+ * Clear the tile cache.
2488
+ */
2489
+ clearCache() {
2490
+ this.cache.clear();
2491
+ this.inflight.clear();
2492
+ }
2493
+ /**
2494
+ * Auto-detect max zoom from PMTiles metadata.
2495
+ * @returns {Promise<number>}
2496
+ * @private
2497
+ */
2498
+ async _getMaxDataZoom() {
2499
+ if (this.maxDataZoom !== void 0) {
2500
+ return this.maxDataZoom;
2501
+ }
2502
+ const header = await this.pmtiles.getHeader();
2503
+ this.maxDataZoom = header.maxZoom;
2504
+ return this.maxDataZoom;
2505
+ }
2506
+ /**
2507
+ * Fetch and parse a tile from PMTiles.
2508
+ * Implements in-flight request deduplication from protomaps-leaflet.
2509
+ * @param {number} z
2510
+ * @param {number} x
2511
+ * @param {number} y
2512
+ * @returns {Promise<Object<string, Array>>}
2513
+ * @private
2514
+ */
2515
+ async _fetchTile(z2, x22, y) {
2516
+ const idx = toIndex(z2, x22, y);
2517
+ return new Promise((resolve, reject) => {
2518
+ const entry = this.cache.get(idx);
2519
+ if (entry) {
2520
+ entry.used = performance.now();
2521
+ resolve(entry.data);
2522
+ return;
2523
+ }
2524
+ const ifentry = this.inflight.get(idx);
2525
+ if (ifentry) {
2526
+ ifentry.push({ resolve, reject });
2527
+ return;
2528
+ }
2529
+ this.inflight.set(idx, []);
2530
+ this.pmtiles.getZxy(z2, x22, y).then((result) => {
2531
+ let data;
2532
+ if (result) {
2533
+ data = parseTile(result.data);
2534
+ } else {
2535
+ data = {};
2536
+ }
2537
+ this.cache.set(idx, { used: performance.now(), data });
2538
+ const ifentry2 = this.inflight.get(idx);
2539
+ if (ifentry2) {
2540
+ for (const waiter of ifentry2) {
2541
+ waiter.resolve(data);
2542
+ }
2543
+ }
2544
+ this.inflight.delete(idx);
2545
+ resolve(data);
2546
+ if (this.cache.size > this.cacheSize) {
2547
+ let minUsed = Infinity;
2548
+ let minKey = void 0;
2549
+ this.cache.forEach((value, key) => {
2550
+ if (value.used < minUsed) {
2551
+ minUsed = value.used;
2552
+ minKey = key;
2553
+ }
2554
+ });
2555
+ if (minKey) {
2556
+ this.cache.delete(minKey);
2557
+ }
2558
+ }
2559
+ }).catch((e) => {
2560
+ const ifentry2 = this.inflight.get(idx);
2561
+ if (ifentry2) {
2562
+ for (const waiter of ifentry2) {
2563
+ waiter.reject(e);
2564
+ }
2565
+ }
2566
+ this.inflight.delete(idx);
2567
+ reject(e);
2568
+ });
2569
+ });
2570
+ }
2571
+ /**
2572
+ * Get corrections for a tile as a dict of layer name to features.
2573
+ * Supports overzoom beyond maxDataZoom by scaling parent tile data.
2574
+ * @param {number} z - Zoom level
2575
+ * @param {number} x - Tile X coordinate
2576
+ * @param {number} y - Tile Y coordinate
2577
+ * @returns {Promise<Object<string, Array>>} Map of layer name to array of features
2578
+ */
2579
+ async get(z2, x22, y) {
2580
+ const maxDataZoom = await this._getMaxDataZoom();
2581
+ if (z2 > maxDataZoom) {
2582
+ const zoomDiff = z2 - maxDataZoom;
2583
+ const scale = 1 << zoomDiff;
2584
+ const parentX = Math.floor(x22 / scale);
2585
+ const parentY = Math.floor(y / scale);
2586
+ const offsetX = x22 % scale;
2587
+ const offsetY = y % scale;
2588
+ const corrections = await this._fetchTile(maxDataZoom, parentX, parentY);
2589
+ if (Object.keys(corrections).length > 0) {
2590
+ return transformForOverzoom(corrections, scale, offsetX, offsetY);
2591
+ }
2592
+ return {};
2593
+ }
2594
+ return await this._fetchTile(z2, x22, y);
2595
+ }
2596
+ };
2597
+ var MIN_LINE_WIDTH = 0.5;
2598
+ function getLineWidth(zoom, lineWidthStops) {
2599
+ const zooms = Object.keys(lineWidthStops).map(Number).sort((a, b2) => a - b2);
2600
+ if (lineWidthStops[zoom] !== void 0) {
2601
+ return lineWidthStops[zoom];
2602
+ }
2603
+ if (zoom < zooms[0]) {
2604
+ const z1 = zooms[0];
2605
+ const z2 = zooms[1];
2606
+ const w1 = lineWidthStops[z1];
2607
+ const w2 = lineWidthStops[z2];
2608
+ const slope = (w2 - w1) / (z2 - z1);
2609
+ return Math.max(MIN_LINE_WIDTH, w1 + slope * (zoom - z1));
2610
+ }
2611
+ if (zoom > zooms[zooms.length - 1]) {
2612
+ const z1 = zooms[zooms.length - 2];
2613
+ const z2 = zooms[zooms.length - 1];
2614
+ const w1 = lineWidthStops[z1];
2615
+ const w2 = lineWidthStops[z2];
2616
+ const slope = (w2 - w1) / (z2 - z1);
2617
+ return Math.max(MIN_LINE_WIDTH, w2 + slope * (zoom - z2));
2618
+ }
2619
+ for (let i2 = 0; i2 < zooms.length - 1; i2++) {
2620
+ if (zoom > zooms[i2] && zoom < zooms[i2 + 1]) {
2621
+ const z1 = zooms[i2];
2622
+ const z2 = zooms[i2 + 1];
2623
+ const w1 = lineWidthStops[z1];
2624
+ const w2 = lineWidthStops[z2];
2625
+ const t = (zoom - z1) / (z2 - z1);
2626
+ return w1 + t * (w2 - w1);
2627
+ }
2628
+ }
2629
+ return 1;
2630
+ }
2631
+ function getFeaturesBoundingBox(features, tileSize, padding = 0) {
2632
+ let minX = Infinity, minY = Infinity;
2633
+ let maxX = -Infinity, maxY = -Infinity;
2634
+ for (const feature of features) {
2635
+ const scale = tileSize / feature.extent;
2636
+ for (const ring of feature.geometry) {
2637
+ for (const point of ring) {
2638
+ const px = point.x * scale;
2639
+ const py = point.y * scale;
2640
+ if (px < minX) minX = px;
2641
+ if (py < minY) minY = py;
2642
+ if (px > maxX) maxX = px;
2643
+ if (py > maxY) maxY = py;
2644
+ }
2645
+ }
2646
+ }
2647
+ return {
2648
+ minX: Math.max(0, Math.floor(minX - padding)),
2649
+ minY: Math.max(0, Math.floor(minY - padding)),
2650
+ maxX: Math.min(tileSize, Math.ceil(maxX + padding)),
2651
+ maxY: Math.min(tileSize, Math.ceil(maxY + padding))
2652
+ };
2653
+ }
2654
+ function medianFromHistogram(histogram, values) {
2655
+ const count = values.length;
2656
+ if (count === 0) return 0;
2657
+ histogram.fill(0);
2658
+ for (let i2 = 0; i2 < count; i2++) {
2659
+ histogram[values[i2]]++;
2660
+ }
2661
+ const medianPos = count >> 1;
2662
+ let cumulative = 0;
2663
+ for (let v2 = 0; v2 < 256; v2++) {
2664
+ cumulative += histogram[v2];
2665
+ if (cumulative > medianPos) {
2666
+ return v2;
2667
+ }
2668
+ }
2669
+ return 0;
2670
+ }
2671
+ function applyMedianBlurAlongPath(ctx, features, lineWidth, tileSize, maskCanvas) {
2672
+ if (features.length === 0) return;
2673
+ const imageData = ctx.getImageData(0, 0, tileSize, tileSize);
2674
+ const data = imageData.data;
2675
+ const width = tileSize;
2676
+ const height = tileSize;
2677
+ if (!maskCanvas || maskCanvas.width !== tileSize || maskCanvas.height !== tileSize) {
2678
+ maskCanvas = new OffscreenCanvas(tileSize, tileSize);
2679
+ }
2680
+ const maskCtx = maskCanvas.getContext("2d");
2681
+ maskCtx.fillStyle = "black";
2682
+ maskCtx.fillRect(0, 0, tileSize, tileSize);
2683
+ maskCtx.strokeStyle = "white";
2684
+ maskCtx.lineWidth = lineWidth;
2685
+ maskCtx.lineCap = "round";
2686
+ maskCtx.lineJoin = "round";
2687
+ for (const feature of features) {
2688
+ const scale = tileSize / feature.extent;
2689
+ for (const ring of feature.geometry) {
2690
+ if (ring.length === 0) continue;
2691
+ maskCtx.beginPath();
2692
+ maskCtx.moveTo(ring[0].x * scale, ring[0].y * scale);
2693
+ for (let i2 = 1; i2 < ring.length; i2++) {
2694
+ maskCtx.lineTo(ring[i2].x * scale, ring[i2].y * scale);
2695
+ }
2696
+ maskCtx.stroke();
2697
+ }
2698
+ }
2699
+ const maskData = maskCtx.getImageData(0, 0, tileSize, tileSize).data;
2700
+ const radius = Math.max(2, Math.ceil(lineWidth / 2) + 1);
2701
+ const output = new Uint8ClampedArray(data);
2702
+ const bbox = getFeaturesBoundingBox(features, tileSize, radius);
2703
+ const histogram = new Uint16Array(256);
2704
+ const rValues = [];
2705
+ const gValues = [];
2706
+ const bValues = [];
2707
+ for (let y = bbox.minY; y < bbox.maxY; y++) {
2708
+ for (let x22 = bbox.minX; x22 < bbox.maxX; x22++) {
2709
+ const maskIdx = (y * width + x22) * 4;
2710
+ if (maskData[maskIdx] < 128) continue;
2711
+ rValues.length = 0;
2712
+ gValues.length = 0;
2713
+ bValues.length = 0;
2714
+ for (let dy = -radius; dy <= radius; dy++) {
2715
+ for (let dx = -radius; dx <= radius; dx++) {
2716
+ const nx = x22 + dx;
2717
+ const ny = y + dy;
2718
+ if (nx < 0 || nx >= width || ny < 0 || ny >= height) continue;
2719
+ const nMaskIdx = (ny * width + nx) * 4;
2720
+ if (maskData[nMaskIdx] >= 128) continue;
2721
+ const nIdx = nMaskIdx;
2722
+ rValues.push(data[nIdx]);
2723
+ gValues.push(data[nIdx + 1]);
2724
+ bValues.push(data[nIdx + 2]);
2725
+ }
2726
+ }
2727
+ if (rValues.length >= 3) {
2728
+ const idx = maskIdx;
2729
+ output[idx] = medianFromHistogram(histogram, rValues);
2730
+ output[idx + 1] = medianFromHistogram(histogram, gValues);
2731
+ output[idx + 2] = medianFromHistogram(histogram, bValues);
2732
+ }
2733
+ }
2734
+ }
2735
+ ctx.putImageData(new ImageData(output, width, height), 0, 0);
2736
+ }
2737
+ function isAtExtentEdge(coord, extent, tolerance = 0.01) {
2738
+ const tol = extent * tolerance;
2739
+ return coord <= tol || coord >= extent - tol;
2740
+ }
2741
+ function extendFeaturesEnds(features, extensionLength) {
2742
+ return features.map((feature) => {
2743
+ const extent = feature.extent;
2744
+ const newGeometry = feature.geometry.map((ring) => {
2745
+ if (ring.length < 2) return ring;
2746
+ const newRing = [...ring];
2747
+ const start = ring[0];
2748
+ const second = ring[1];
2749
+ if (!isAtExtentEdge(start.x, extent) && !isAtExtentEdge(start.y, extent)) {
2750
+ const dx = start.x - second.x;
2751
+ const dy = start.y - second.y;
2752
+ const len = Math.sqrt(dx * dx + dy * dy);
2753
+ if (len > 0) {
2754
+ const ux = dx / len;
2755
+ const uy = dy / len;
2756
+ newRing[0] = {
2757
+ x: start.x + ux * extensionLength,
2758
+ y: start.y + uy * extensionLength
2759
+ };
2760
+ }
2761
+ }
2762
+ const lastIdx = ring.length - 1;
2763
+ const end = ring[lastIdx];
2764
+ const prev = ring[lastIdx - 1];
2765
+ if (!isAtExtentEdge(end.x, extent) && !isAtExtentEdge(end.y, extent)) {
2766
+ const dx = end.x - prev.x;
2767
+ const dy = end.y - prev.y;
2768
+ const len = Math.sqrt(dx * dx + dy * dy);
2769
+ if (len > 0) {
2770
+ const ux = dx / len;
2771
+ const uy = dy / len;
2772
+ newRing[lastIdx] = {
2773
+ x: end.x + ux * extensionLength,
2774
+ y: end.y + uy * extensionLength
2775
+ };
2776
+ }
2777
+ }
2778
+ return newRing;
2779
+ });
2780
+ return { ...feature, geometry: newGeometry };
2781
+ });
2782
+ }
2783
+ function drawFeatures(ctx, features, color, lineWidth, tileSize, dashArray, alpha) {
2784
+ const prevAlpha = ctx.globalAlpha;
2785
+ if (alpha !== void 0) {
2786
+ ctx.globalAlpha = alpha;
2787
+ }
2788
+ ctx.strokeStyle = color;
2789
+ ctx.lineWidth = lineWidth;
2790
+ ctx.lineJoin = "round";
2791
+ if (dashArray && dashArray.length > 0) {
2792
+ ctx.setLineDash(dashArray);
2793
+ ctx.lineCap = "butt";
2794
+ } else {
2795
+ ctx.setLineDash([]);
2796
+ ctx.lineCap = "round";
2797
+ }
2798
+ for (const feature of features) {
2799
+ const scale = tileSize / feature.extent;
2800
+ for (const ring of feature.geometry) {
2801
+ if (ring.length === 0) continue;
2802
+ ctx.beginPath();
2803
+ ctx.moveTo(ring[0].x * scale, ring[0].y * scale);
2804
+ for (let i2 = 1; i2 < ring.length; i2++) {
2805
+ ctx.lineTo(ring[i2].x * scale, ring[i2].y * scale);
2806
+ }
2807
+ ctx.stroke();
2808
+ }
2809
+ }
2810
+ if (alpha !== void 0) {
2811
+ ctx.globalAlpha = prevAlpha;
2812
+ }
2813
+ }
2814
+ var BoundaryCorrector = class {
2815
+ /**
2816
+ * @param {string} pmtilesUrl - URL to the PMTiles file
2817
+ * @param {Object} [options] - Options
2818
+ * @param {number} [options.cacheSize=64] - Maximum number of tiles to cache
2819
+ * @param {number} [options.maxDataZoom] - Maximum zoom level in PMTiles (auto-detected if not provided)
2820
+ */
2821
+ constructor(pmtilesUrl, options = {}) {
2822
+ this.correctionsSource = new CorrectionsSource(pmtilesUrl, options);
2823
+ this._maskCanvas = null;
2824
+ }
2825
+ /**
2826
+ * Get the PMTiles source object.
2827
+ * @returns {PMTiles}
2828
+ */
2829
+ getSource() {
2830
+ return this.correctionsSource.getSource();
2831
+ }
2832
+ /**
2833
+ * Clear the tile cache.
2834
+ */
2835
+ clearCache() {
2836
+ this.correctionsSource.clearCache();
2837
+ }
2838
+ /**
2839
+ * Get corrections for a tile as a dict of layer name to features.
2840
+ * Supports overzoom beyond maxDataZoom by scaling parent tile data.
2841
+ * @param {number} z - Zoom level
2842
+ * @param {number} x - Tile X coordinate
2843
+ * @param {number} y - Tile Y coordinate
2844
+ * @returns {Promise<Object<string, Array>>} Map of layer name to array of features
2845
+ */
2846
+ async getCorrections(z2, x22, y) {
2847
+ return await this.correctionsSource.get(z2, x22, y);
2848
+ }
2849
+ /**
2850
+ * Apply corrections to a raster tile.
2851
+ * @param {Object<string, Array>} corrections - Feature map from getCorrections
2852
+ * @param {ArrayBuffer} rasterTile - The original raster tile as ArrayBuffer
2853
+ * @param {Object} layerConfig - Layer configuration with colors and styles
2854
+ * @param {number} zoom - Current zoom level
2855
+ * @param {number} [tileSize=256] - Size of the tile in pixels
2856
+ * @returns {Promise<ArrayBuffer>} The corrected tile as ArrayBuffer (PNG)
2857
+ */
2858
+ async fixTile(corrections, rasterTile, layerConfig, zoom, tileSize = 256) {
2859
+ const {
2860
+ startZoom = 0,
2861
+ zoomThreshold,
2862
+ lineWidthStops,
2863
+ delWidthFactor
2864
+ } = layerConfig;
2865
+ if (zoom < startZoom) {
2866
+ return rasterTile;
2867
+ }
2868
+ let activeLineStyles;
2869
+ if (layerConfig.getLineStylesForZoom) {
2870
+ activeLineStyles = layerConfig.getLineStylesForZoom(zoom);
2871
+ } else {
2872
+ const allStyles = layerConfig.lineStyles || [];
2873
+ activeLineStyles = allStyles.filter((style) => {
2874
+ const styleStart = style.startZoom ?? startZoom;
2875
+ const styleEnd = style.endZoom ?? Infinity;
2876
+ return zoom >= styleStart && zoom <= styleEnd;
2877
+ });
2878
+ }
2879
+ const useOsm = zoom >= zoomThreshold;
2880
+ const addLayerName = useOsm ? "to-add-osm" : "to-add-ne";
2881
+ const delLayerName = useOsm ? "to-del-osm" : "to-del-ne";
2882
+ const canvas = new OffscreenCanvas(tileSize, tileSize);
2883
+ const ctx = canvas.getContext("2d");
2884
+ const blob = new Blob([rasterTile]);
2885
+ const imageBitmap = await createImageBitmap(blob);
2886
+ ctx.drawImage(imageBitmap, 0, 0, tileSize, tileSize);
2887
+ const baseLineWidth = getLineWidth(zoom, lineWidthStops);
2888
+ const maxWidthFraction = activeLineStyles.length > 0 ? Math.max(...activeLineStyles.map((s) => s.widthFraction ?? 1)) : 1;
2889
+ const delLineWidth = baseLineWidth * maxWidthFraction * delWidthFactor;
2890
+ const delFeatures = corrections[delLayerName] || [];
2891
+ if (delFeatures.length > 0) {
2892
+ if (!this._maskCanvas || this._maskCanvas.width !== tileSize) {
2893
+ this._maskCanvas = new OffscreenCanvas(tileSize, tileSize);
2894
+ }
2895
+ applyMedianBlurAlongPath(ctx, delFeatures, delLineWidth, tileSize, this._maskCanvas);
2896
+ }
2897
+ let addFeatures = corrections[addLayerName] || [];
2898
+ if (addFeatures.length > 0 && activeLineStyles.length > 0) {
2899
+ const extensionFactor = layerConfig.lineExtensionFactor ?? 0.5;
2900
+ if (extensionFactor > 0 && delFeatures.length > 0) {
2901
+ const extent = addFeatures[0]?.extent || 4096;
2902
+ const extensionLength = delLineWidth * extensionFactor / tileSize * extent;
2903
+ addFeatures = extendFeaturesEnds(addFeatures, extensionLength);
2904
+ }
2905
+ for (const style of activeLineStyles) {
2906
+ const { color, widthFraction = 1, dashArray, alpha = 1 } = style;
2907
+ const lineWidth = baseLineWidth * widthFraction;
2908
+ drawFeatures(ctx, addFeatures, color, lineWidth, tileSize, dashArray, alpha);
2909
+ }
2910
+ }
2911
+ const outputBlob = await canvas.convertToBlob({ type: "image/png" });
2912
+ return outputBlob.arrayBuffer();
2913
+ }
2914
+ /**
2915
+ * Fetch a tile, apply corrections, and return the result.
2916
+ * @param {string} tileUrl - URL of the raster tile
2917
+ * @param {number} z - Zoom level
2918
+ * @param {number} x - Tile X coordinate
2919
+ * @param {number} y - Tile Y coordinate
2920
+ * @param {Object} layerConfig - Layer configuration with colors and styles
2921
+ * @param {Object} [options] - Fetch options
2922
+ * @param {number} [options.tileSize=256] - Tile size in pixels
2923
+ * @param {AbortSignal} [options.signal] - Abort signal for fetch
2924
+ * @param {RequestMode} [options.mode] - Fetch mode (e.g., 'cors')
2925
+ * @returns {Promise<{data: ArrayBuffer, wasFixed: boolean}>}
2926
+ */
2927
+ async fetchAndFixTile(tileUrl, z2, x22, y, layerConfig, options = {}) {
2928
+ const { tileSize = 256, signal, mode } = options;
2929
+ const fetchOptions = {};
2930
+ if (signal) fetchOptions.signal = signal;
2931
+ if (mode) fetchOptions.mode = mode;
2932
+ if (!layerConfig) {
2933
+ const response = await fetch(tileUrl, fetchOptions);
2934
+ if (!response.ok) throw new Error(`Tile fetch failed: ${response.status}`);
2935
+ return { data: await response.arrayBuffer(), wasFixed: false };
2936
+ }
2937
+ const [tileResult, correctionsResult] = await Promise.allSettled([
2938
+ fetch(tileUrl, fetchOptions).then((r) => {
2939
+ if (!r.ok) throw new Error(`Tile fetch failed: ${r.status}`);
2940
+ return r.arrayBuffer();
2941
+ }),
2942
+ this.getCorrections(z2, x22, y)
2943
+ ]);
2944
+ if (signal?.aborted) {
2945
+ throw new DOMException("Aborted", "AbortError");
2946
+ }
2947
+ if (tileResult.status === "rejected") {
2948
+ throw tileResult.reason;
2949
+ }
2950
+ const tileData = tileResult.value;
2951
+ const correctionsFailed = correctionsResult.status === "rejected";
2952
+ const correctionsError = correctionsFailed ? correctionsResult.reason : null;
2953
+ const corrections = correctionsResult.status === "fulfilled" ? correctionsResult.value : {};
2954
+ const hasCorrections = Object.values(corrections).some((arr) => arr && arr.length > 0);
2955
+ if (!hasCorrections) {
2956
+ return { data: tileData, wasFixed: false, correctionsFailed, correctionsError };
2957
+ }
2958
+ const fixedData = await this.fixTile(corrections, tileData, layerConfig, z2, tileSize);
2959
+ return { data: fixedData, wasFixed: true, correctionsFailed: false, correctionsError: null };
2960
+ }
2961
+ };
2962
+
2963
+ // src/index.js
2964
+ var import_data2 = require("@india-boundary-corrector/data");
2965
+ function extendLeaflet(L2) {
2966
+ if (L2.TileLayer.IndiaBoundaryCorrected) {
2967
+ return;
2968
+ }
2969
+ L2.TileLayer.IndiaBoundaryCorrected = L2.TileLayer.extend({
2970
+ options: {
2971
+ pmtilesUrl: null,
2972
+ layerConfig: null,
2973
+ extraLayerConfigs: null
2974
+ },
2975
+ initialize: function(url, options) {
2976
+ L2.TileLayer.prototype.initialize.call(this, url, options);
2977
+ this._pmtilesUrl = this.options.pmtilesUrl ?? (0, import_data.getPmtilesUrl)();
2978
+ this._tileFixer = new BoundaryCorrector(this._pmtilesUrl);
2979
+ this._registry = layerConfigs.createMergedRegistry(this.options.extraLayerConfigs);
2980
+ if (typeof this.options.layerConfig === "string") {
2981
+ this._layerConfig = this._registry.get(this.options.layerConfig);
2982
+ } else if (this.options.layerConfig) {
2983
+ this._layerConfig = this.options.layerConfig;
2984
+ } else {
2985
+ this._layerConfig = this._registry.detectFromTemplates([url]);
2986
+ }
2987
+ if (!this._layerConfig) {
2988
+ console.warn("[L.TileLayer.IndiaBoundaryCorrected] Could not detect layer config from URL. Corrections will not be applied.");
2989
+ }
2990
+ },
2991
+ /**
2992
+ * Handle tile fetching and correction application logic.
2993
+ * This method is extracted for testability.
2994
+ * @param {string} tileUrl - URL of the raster tile
2995
+ * @param {number} z - Zoom level
2996
+ * @param {number} x - Tile X coordinate
2997
+ * @param {number} y - Tile Y coordinate
2998
+ * @param {number} tileSize - Tile size in pixels
2999
+ * @returns {Promise<{blob: Blob, wasFixed: boolean, correctionsFailed: boolean, correctionsError: Error|null}>}
3000
+ * @private
3001
+ */
3002
+ _fetchAndFixTile: async function(tileUrl, z2, x3, y, tileSize) {
3003
+ const { data, wasFixed, correctionsFailed, correctionsError } = await this._tileFixer.fetchAndFixTile(
3004
+ tileUrl,
3005
+ z2,
3006
+ x3,
3007
+ y,
3008
+ this._layerConfig,
3009
+ { tileSize }
3010
+ );
3011
+ const blob = new Blob([data], { type: wasFixed ? "image/png" : void 0 });
3012
+ return { blob, wasFixed, correctionsFailed, correctionsError };
3013
+ },
3014
+ createTile: function(coords, done) {
3015
+ const tile = document.createElement("img");
3016
+ tile.alt = "";
3017
+ if (this.options.crossOrigin || this.options.crossOrigin === "") {
3018
+ tile.crossOrigin = this.options.crossOrigin === true ? "" : this.options.crossOrigin;
3019
+ }
3020
+ if (typeof this.options.referrerPolicy === "string") {
3021
+ tile.referrerPolicy = this.options.referrerPolicy;
3022
+ }
3023
+ if (!this._layerConfig) {
3024
+ tile.onload = () => done(null, tile);
3025
+ tile.onerror = (e) => done(e, tile);
3026
+ tile.src = this.getTileUrl(coords);
3027
+ return tile;
3028
+ }
3029
+ const tileUrl = this.getTileUrl(coords);
3030
+ const z2 = coords.z;
3031
+ const x3 = coords.x;
3032
+ const y = coords.y;
3033
+ const tileSize = this.options.tileSize || 256;
3034
+ this._fetchAndFixTile(tileUrl, z2, x3, y, tileSize).then(({ blob, wasFixed, correctionsFailed, correctionsError }) => {
3035
+ if (correctionsFailed) {
3036
+ console.warn("[L.TileLayer.IndiaBoundaryCorrected] Corrections fetch failed:", correctionsError);
3037
+ this.fire("correctionerror", { error: correctionsError, coords: { z: z2, x: x3, y }, tileUrl });
3038
+ }
3039
+ tile.src = URL.createObjectURL(blob);
3040
+ tile.onload = () => {
3041
+ URL.revokeObjectURL(tile.src);
3042
+ done(null, tile);
3043
+ };
3044
+ tile.onerror = (e) => {
3045
+ URL.revokeObjectURL(tile.src);
3046
+ done(e, tile);
3047
+ };
3048
+ }).catch((err2) => {
3049
+ console.warn("[L.TileLayer.IndiaBoundaryCorrected] Tile fetch failed:", err2);
3050
+ done(err2, tile);
3051
+ });
3052
+ return tile;
3053
+ },
3054
+ getTileFixer: function() {
3055
+ return this._tileFixer;
3056
+ },
3057
+ getLayerConfig: function() {
3058
+ return this._layerConfig;
3059
+ }
3060
+ });
3061
+ L2.tileLayer.indiaBoundaryCorrected = function(url, options) {
3062
+ return new L2.TileLayer.IndiaBoundaryCorrected(url, options);
3063
+ };
3064
+ }
3065
+ //# sourceMappingURL=index.cjs.map