@india-boundary-corrector/maplibre-protocol 0.1.0 → 0.2.0

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.
@@ -30,13 +30,13 @@ var IndiaBoundaryCorrector = (() => {
30
30
  });
31
31
 
32
32
  // ../data/version.js
33
- var packageVersion = "0.1.0";
33
+ var packageVersion = "0.2.0";
34
34
 
35
35
  // ../data/index.js
36
36
  var import_meta = {};
37
37
  var PACKAGE_NAME = "@india-boundary-corrector/data";
38
38
  var PMTILES_FILENAME = "india_boundary_corrections.pmtiles.gz";
39
- var FALLBACK_CDNS = /* @__PURE__ */ new Set(["esm.sh", "skypack.dev", "cdn.skypack.dev"]);
39
+ var FALLBACK_CDNS = /* @__PURE__ */ new Set(["esm.sh", "skypack.dev", "cdn.skypack.dev", "unpkg.com"]);
40
40
  var DEFAULT_CDN_URL = `https://cdn.jsdelivr.net/npm/${PACKAGE_NAME}@${packageVersion}/${PMTILES_FILENAME}`;
41
41
  var CURRENT_SCRIPT_URL = typeof document !== "undefined" && document.currentScript && document.currentScript.src || null;
42
42
  function detectPmtilesUrl() {
@@ -74,6 +74,26 @@ var IndiaBoundaryCorrector = (() => {
74
74
  var configs_default = [
75
75
  {
76
76
  id: "cartodb-dark",
77
+ tileUrlTemplates: [
78
+ "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png",
79
+ "https://basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png",
80
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png",
81
+ "https://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png",
82
+ "https://basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png",
83
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_nolabels/{z}/{x}/{y}.png"
84
+ ],
85
+ lineWidthStops: { "0": 1, "2": 1, "3": 1, "10": 2, "12": 2 },
86
+ lineStyles: [
87
+ { color: "rgb(40, 40, 40)", layerSuffix: "ne", endZoom: 4 },
88
+ { color: "rgb(40, 40, 40)", layerSuffix: "ne-disp", endZoom: 4 },
89
+ { color: "rgb(40, 40, 40)", layerSuffix: "osm", startZoom: 5 },
90
+ { color: "rgb(40, 40, 40)", layerSuffix: "osm-disp", startZoom: 5 },
91
+ { color: "rgb(40, 40, 40)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.3, dashArray: [2, 2], delWidthFactor: 2 },
92
+ { color: "rgb(40, 40, 40)", layerSuffix: "ne-internal", startZoom: 4, endZoom: 4, widthFraction: 0.3, dashArray: [2, 2], delWidthFactor: 3 }
93
+ ]
94
+ },
95
+ {
96
+ id: "cartodb-dark-retina",
77
97
  tileUrlTemplates: [
78
98
  "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
79
99
  "https://basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
@@ -82,17 +102,46 @@ var IndiaBoundaryCorrector = (() => {
82
102
  "https://basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png",
83
103
  "https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_nolabels/{z}/{x}/{y}{r}.png"
84
104
  ],
85
- lineWidthStops: { "0": 1, "2": 1, "3": 1, "10": 2.5 },
105
+ lineWidthStops: { "0": 1.5, "2": 1.5, "3": 1.5, "6": 2.5, "10": 3 },
86
106
  lineStyles: [
87
107
  { color: "rgb(40, 40, 40)", layerSuffix: "ne", endZoom: 4 },
88
108
  { color: "rgb(40, 40, 40)", layerSuffix: "ne-disp", endZoom: 4 },
89
109
  { color: "rgb(40, 40, 40)", layerSuffix: "osm", startZoom: 5 },
90
110
  { color: "rgb(40, 40, 40)", layerSuffix: "osm-disp", startZoom: 5 },
91
- { color: "rgb(40, 40, 40)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.3, dashArray: [2, 2] }
111
+ { color: "rgb(40, 40, 40)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.3, dashArray: [4, 4], delWidthFactor: 2 },
112
+ { color: "rgb(40, 40, 40)", layerSuffix: "ne-internal", startZoom: 4, endZoom: 4, widthFraction: 0.3, dashArray: [4, 4], delWidthFactor: 3 }
92
113
  ]
93
114
  },
94
115
  {
95
116
  id: "cartodb-light",
117
+ tileUrlTemplates: [
118
+ "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
119
+ "https://basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
120
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png",
121
+ "https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png",
122
+ "https://basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png",
123
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_nolabels/{z}/{x}/{y}.png",
124
+ "https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png",
125
+ "https://basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png",
126
+ "https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png",
127
+ "https://basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png",
128
+ "https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}.png",
129
+ "https://basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}.png"
130
+ ],
131
+ lineWidthStops: { "1": 0.5, "2": 0.75, "3": 0.75, "4": 1, "5": 1, "7": 1.5, "16": 2.5 },
132
+ lineStyles: [
133
+ { color: "rgb(235, 214, 214)", layerSuffix: "ne", endZoom: 4, lineExtensionFactor: 0.1, delWidthFactor: 2.5 },
134
+ { color: "rgb(235, 214, 214)", layerSuffix: "ne-disp", endZoom: 4, delWidthFactor: 0 },
135
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.2, startZoom: 6, endZoom: 11, widthFraction: 5, lineExtensionFactor: 0.1 },
136
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.2, startZoom: 12, widthFraction: 4, lineExtensionFactor: 0.1 },
137
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm", startZoom: 5, lineExtensionFactor: 0.1 },
138
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", startZoom: 5, delWidthFactor: 0 },
139
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.5, dashArray: [2, 2], delWidthFactor: 2 },
140
+ { color: "rgb(235, 214, 214)", layerSuffix: "ne-internal", startZoom: 4, endZoom: 4, widthFraction: 0.5, dashArray: [2, 2], delWidthFactor: 2.5 }
141
+ ]
142
+ },
143
+ {
144
+ id: "cartodb-light-retina",
96
145
  tileUrlTemplates: [
97
146
  "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",
98
147
  "https://basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",
@@ -107,15 +156,16 @@ var IndiaBoundaryCorrector = (() => {
107
156
  "https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png",
108
157
  "https://basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png"
109
158
  ],
110
- lineWidthStops: { "1": 0.5, "2": 0.5, "3": 0.5, "4": 1, "5": 1.25, "7": 1.5, "16": 2.5 },
159
+ lineWidthStops: { "1": 0.75, "2": 0.75, "3": 0.75, "4": 1, "5": 1, "7": 1.5, "11": 2 },
111
160
  lineStyles: [
112
- { color: "rgb(235, 214, 214)", layerSuffix: "ne", endZoom: 4, lineExtensionFactor: 0.1, delWidthFactor: 2 },
113
- { color: "rgb(235, 214, 214)", layerSuffix: "ne-disp", endZoom: 4, lineExtensionFactor: 0 },
114
- { color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.2, startZoom: 6, widthFraction: 3, lineExtensionFactor: 0.1 },
161
+ { color: "rgb(235, 214, 214)", layerSuffix: "ne", endZoom: 4, lineExtensionFactor: 0.1, delWidthFactor: 2.5 },
162
+ { color: "rgb(235, 214, 214)", layerSuffix: "ne-disp", endZoom: 4, delWidthFactor: 0 },
163
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 6, endZoom: 11, widthFraction: 5, lineExtensionFactor: 0.1 },
164
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 12, widthFraction: 4, lineExtensionFactor: 0.1 },
115
165
  { color: "rgb(235, 214, 214)", layerSuffix: "osm", startZoom: 5, lineExtensionFactor: 0.1 },
116
- { color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", alpha: 0.2, startZoom: 6, widthFraction: 3, lineExtensionFactor: 0 },
117
- { color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", startZoom: 5, lineExtensionFactor: 0 },
118
- { color: "rgb(235, 214, 214)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.75, dashArray: [2, 2], delWidthFactor: 2 }
166
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", startZoom: 5, delWidthFactor: 0 },
167
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.5, dashArray: [4, 4], delWidthFactor: 2 },
168
+ { color: "rgb(235, 214, 214)", layerSuffix: "ne-internal", startZoom: 4, endZoom: 4, widthFraction: 0.5, dashArray: [4, 4], delWidthFactor: 2.5 }
119
169
  ]
120
170
  },
121
171
  {
@@ -142,10 +192,10 @@ var IndiaBoundaryCorrector = (() => {
142
192
  lineWidthStops: { "1": 0.5, "2": 0.6, "3": 0.7, "4": 1, "10": 3.75 },
143
193
  lineStyles: [
144
194
  { color: "rgb(200, 180, 200)", layerSuffix: "osm", startZoom: 1, endZoom: 3, delWidthFactor: 2.5, widthFraction: 1.5 },
145
- { color: "rgb(200, 180, 200)", layerSuffix: "osm", startZoom: 4 },
146
- { color: "rgb(160, 120, 160)", layerSuffix: "osm", startZoom: 4, widthFraction: 0.333, dashArray: [30, 2, 8, 2] },
195
+ { color: "rgb(200, 180, 200)", layerSuffix: "osm", startZoom: 4, delWidthFactor: 1.5 },
196
+ { color: "rgb(160, 120, 160)", layerSuffix: "osm", startZoom: 4, widthFraction: 0.333, dashArray: [30, 2, 8, 2], delWidthFactor: 0 },
147
197
  { color: "rgb(200, 180, 200)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.45 },
148
- { color: "rgb(160, 120, 160)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.15, dashArray: [4, 2, 10] }
198
+ { color: "rgb(160, 120, 160)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.15, dashArray: [10, 4, 2] }
149
199
  ]
150
200
  },
151
201
  {
@@ -158,13 +208,17 @@ var IndiaBoundaryCorrector = (() => {
158
208
  lineStyles: [
159
209
  { color: "rgb(149, 175, 180)", layerSuffix: "osm", lineExtensionFactor: 0.25, startZoom: 2 },
160
210
  { color: "rgb(89, 117, 123)", layerSuffix: "osm", widthFraction: 0.33, lineExtensionFactor: 0.25, startZoom: 2 },
161
- { color: "rgb(172, 163, 163)", layerSuffix: "osm-internal", widthFraction: 0.33, startZoom: 4, dashArray: [7, 7, 7] }
211
+ { color: "rgb(172, 163, 163)", layerSuffix: "osm-internal", widthFraction: 0.33, startZoom: 4, dashArray: [7, 7] }
162
212
  ]
163
213
  }
164
214
  ];
165
215
  var INFINITY = -1;
216
+ var MIN_LINE_WIDTH = 0.1;
217
+ var DEFAULT_LINE_WIDTH = 1;
166
218
  function templateToRegex(template) {
167
219
  const groups = [];
220
+ const hasRetina = template.includes("{r}");
221
+ const hasExtension = /\.(png|jpg|jpeg|webp|gif)$/i.test(template);
168
222
  let pattern = template.replace(/[.*+?^${}()|[\]\\]/g, (char) => {
169
223
  if (char === "{" || char === "}") return char;
170
224
  return "\\" + char;
@@ -178,13 +232,22 @@ var IndiaBoundaryCorrector = (() => {
178
232
  return "([a-z0-9]+)";
179
233
  }
180
234
  if (lowerName === "r") {
181
- return "(@\\d+x)?";
235
+ return "(@\\d+x)";
182
236
  }
183
237
  return "(\\d+)";
184
238
  });
239
+ if (!hasRetina) {
240
+ if (hasExtension) {
241
+ pattern = pattern.replace(/(\\\.(png|jpg|jpeg|webp|gif))/, "(?!@\\d+x)$1");
242
+ } else {
243
+ pattern = pattern + "(?!@\\d+x)";
244
+ }
245
+ }
185
246
  return { pattern: new RegExp("^" + pattern + "(\\?.*)?$", "i"), groups };
186
247
  }
187
248
  function templateToTemplateRegex(template) {
249
+ const hasRetina = template.includes("{r}");
250
+ const hasExtension = /\.(png|jpg|jpeg|webp|gif)$/i.test(template);
188
251
  let pattern = template.replace(/[.*+?^${}()|[\]\\]/g, (char) => {
189
252
  if (char === "{" || char === "}") return char;
190
253
  return "\\" + char;
@@ -194,10 +257,17 @@ var IndiaBoundaryCorrector = (() => {
194
257
  return "(\\{s\\}|\\{[a-z0-9]-[a-z0-9]\\}|[a-z0-9]+)";
195
258
  }
196
259
  if (lowerName === "r") {
197
- return "(\\{r\\}|@\\d+x)?";
260
+ return "(\\{r\\}|@\\d+x)";
198
261
  }
199
262
  return `\\{${lowerName}\\}`;
200
263
  });
264
+ if (!hasRetina) {
265
+ if (hasExtension) {
266
+ pattern = pattern.replace(/(\\\.(png|jpg|jpeg|webp|gif))/, "(?!@\\d+x|\\{r\\})$1");
267
+ } else {
268
+ pattern = pattern + "(?!@\\d+x|\\{r\\})";
269
+ }
270
+ }
201
271
  return new RegExp("^" + pattern + "(\\?.*)?$", "i");
202
272
  }
203
273
  function isValidColor(color) {
@@ -266,7 +336,7 @@ var IndiaBoundaryCorrector = (() => {
266
336
  * @param {number} [options.lineExtensionFactor=0.5] - Factor to extend lines by (multiplied by deletion line width)
267
337
  * @param {number} [options.delWidthFactor=1.5] - Factor to multiply line width for deletion blur
268
338
  */
269
- constructor({ color, layerSuffix, widthFraction = 1, dashArray, alpha = 1, startZoom = 0, endZoom = INFINITY, lineExtensionFactor = 0.5, delWidthFactor = 1.5 }) {
339
+ constructor({ color, layerSuffix, widthFraction = 1, dashArray, alpha = 1, startZoom = 0, endZoom = INFINITY, lineExtensionFactor = 0, delWidthFactor = 1.5 }) {
270
340
  this.color = color;
271
341
  this.layerSuffix = layerSuffix;
272
342
  this.widthFraction = widthFraction;
@@ -396,6 +466,45 @@ var IndiaBoundaryCorrector = (() => {
396
466
  const activeStyles = this.getLineStylesForZoom(z2);
397
467
  return [...new Set(activeStyles.map((s) => s.layerSuffix))];
398
468
  }
469
+ /**
470
+ * Interpolate or extrapolate line width for a given zoom level.
471
+ * Uses the lineWidthStops map to calculate the appropriate width.
472
+ * @param {number} zoom - Zoom level
473
+ * @returns {number}
474
+ */
475
+ getLineWidth(zoom) {
476
+ const zooms = Object.keys(this.lineWidthStops).map(Number).sort((a, b2) => a - b2);
477
+ if (this.lineWidthStops[zoom] !== void 0) {
478
+ return this.lineWidthStops[zoom];
479
+ }
480
+ if (zoom < zooms[0]) {
481
+ const z1 = zooms[0];
482
+ const z2 = zooms[1];
483
+ const w1 = this.lineWidthStops[z1];
484
+ const w2 = this.lineWidthStops[z2];
485
+ const slope = (w2 - w1) / (z2 - z1);
486
+ return Math.max(MIN_LINE_WIDTH, w1 + slope * (zoom - z1));
487
+ }
488
+ if (zoom > zooms[zooms.length - 1]) {
489
+ const z1 = zooms[zooms.length - 2];
490
+ const z2 = zooms[zooms.length - 1];
491
+ const w1 = this.lineWidthStops[z1];
492
+ const w2 = this.lineWidthStops[z2];
493
+ const slope = (w2 - w1) / (z2 - z1);
494
+ return Math.max(MIN_LINE_WIDTH, w2 + slope * (zoom - z2));
495
+ }
496
+ for (let i2 = 0; i2 < zooms.length - 1; i2++) {
497
+ if (zoom > zooms[i2] && zoom < zooms[i2 + 1]) {
498
+ const z1 = zooms[i2];
499
+ const z2 = zooms[i2 + 1];
500
+ const w1 = this.lineWidthStops[z1];
501
+ const w2 = this.lineWidthStops[z2];
502
+ const t = (zoom - z1) / (z2 - z1);
503
+ return w1 + t * (w2 - w1);
504
+ }
505
+ }
506
+ return DEFAULT_LINE_WIDTH;
507
+ }
399
508
  /**
400
509
  * Check if this config matches the given template URLs (with {z}/{x}/{y} placeholders)
401
510
  * @param {string | string[]} templates - Single template URL or array of template URLs
@@ -2795,6 +2904,26 @@ var IndiaBoundaryCorrector = (() => {
2795
2904
  var configs_default2 = [
2796
2905
  {
2797
2906
  id: "cartodb-dark",
2907
+ tileUrlTemplates: [
2908
+ "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png",
2909
+ "https://basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png",
2910
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png",
2911
+ "https://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png",
2912
+ "https://basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png",
2913
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_nolabels/{z}/{x}/{y}.png"
2914
+ ],
2915
+ lineWidthStops: { "0": 1, "2": 1, "3": 1, "10": 2, "12": 2 },
2916
+ lineStyles: [
2917
+ { color: "rgb(40, 40, 40)", layerSuffix: "ne", endZoom: 4 },
2918
+ { color: "rgb(40, 40, 40)", layerSuffix: "ne-disp", endZoom: 4 },
2919
+ { color: "rgb(40, 40, 40)", layerSuffix: "osm", startZoom: 5 },
2920
+ { color: "rgb(40, 40, 40)", layerSuffix: "osm-disp", startZoom: 5 },
2921
+ { color: "rgb(40, 40, 40)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.3, dashArray: [2, 2], delWidthFactor: 2 },
2922
+ { color: "rgb(40, 40, 40)", layerSuffix: "ne-internal", startZoom: 4, endZoom: 4, widthFraction: 0.3, dashArray: [2, 2], delWidthFactor: 3 }
2923
+ ]
2924
+ },
2925
+ {
2926
+ id: "cartodb-dark-retina",
2798
2927
  tileUrlTemplates: [
2799
2928
  "https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
2800
2929
  "https://basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png",
@@ -2803,17 +2932,46 @@ var IndiaBoundaryCorrector = (() => {
2803
2932
  "https://basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png",
2804
2933
  "https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_nolabels/{z}/{x}/{y}{r}.png"
2805
2934
  ],
2806
- lineWidthStops: { "0": 1, "2": 1, "3": 1, "10": 2.5 },
2935
+ lineWidthStops: { "0": 1.5, "2": 1.5, "3": 1.5, "6": 2.5, "10": 3 },
2807
2936
  lineStyles: [
2808
2937
  { color: "rgb(40, 40, 40)", layerSuffix: "ne", endZoom: 4 },
2809
2938
  { color: "rgb(40, 40, 40)", layerSuffix: "ne-disp", endZoom: 4 },
2810
2939
  { color: "rgb(40, 40, 40)", layerSuffix: "osm", startZoom: 5 },
2811
2940
  { color: "rgb(40, 40, 40)", layerSuffix: "osm-disp", startZoom: 5 },
2812
- { color: "rgb(40, 40, 40)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.3, dashArray: [2, 2] }
2941
+ { color: "rgb(40, 40, 40)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.3, dashArray: [4, 4], delWidthFactor: 2 },
2942
+ { color: "rgb(40, 40, 40)", layerSuffix: "ne-internal", startZoom: 4, endZoom: 4, widthFraction: 0.3, dashArray: [4, 4], delWidthFactor: 3 }
2813
2943
  ]
2814
2944
  },
2815
2945
  {
2816
2946
  id: "cartodb-light",
2947
+ tileUrlTemplates: [
2948
+ "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
2949
+ "https://basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png",
2950
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png",
2951
+ "https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png",
2952
+ "https://basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}.png",
2953
+ "https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_nolabels/{z}/{x}/{y}.png",
2954
+ "https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png",
2955
+ "https://basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}.png",
2956
+ "https://{s}.basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png",
2957
+ "https://basemaps.cartocdn.com/rastertiles/voyager_nolabels/{z}/{x}/{y}.png",
2958
+ "https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}.png",
2959
+ "https://basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}.png"
2960
+ ],
2961
+ lineWidthStops: { "1": 0.5, "2": 0.75, "3": 0.75, "4": 1, "5": 1, "7": 1.5, "16": 2.5 },
2962
+ lineStyles: [
2963
+ { color: "rgb(235, 214, 214)", layerSuffix: "ne", endZoom: 4, lineExtensionFactor: 0.1, delWidthFactor: 2.5 },
2964
+ { color: "rgb(235, 214, 214)", layerSuffix: "ne-disp", endZoom: 4, delWidthFactor: 0 },
2965
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.2, startZoom: 6, endZoom: 11, widthFraction: 5, lineExtensionFactor: 0.1 },
2966
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.2, startZoom: 12, widthFraction: 4, lineExtensionFactor: 0.1 },
2967
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm", startZoom: 5, lineExtensionFactor: 0.1 },
2968
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", startZoom: 5, delWidthFactor: 0 },
2969
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.5, dashArray: [2, 2], delWidthFactor: 2 },
2970
+ { color: "rgb(235, 214, 214)", layerSuffix: "ne-internal", startZoom: 4, endZoom: 4, widthFraction: 0.5, dashArray: [2, 2], delWidthFactor: 2.5 }
2971
+ ]
2972
+ },
2973
+ {
2974
+ id: "cartodb-light-retina",
2817
2975
  tileUrlTemplates: [
2818
2976
  "https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",
2819
2977
  "https://basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png",
@@ -2828,15 +2986,16 @@ var IndiaBoundaryCorrector = (() => {
2828
2986
  "https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png",
2829
2987
  "https://basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png"
2830
2988
  ],
2831
- lineWidthStops: { "1": 0.5, "2": 0.5, "3": 0.5, "4": 1, "5": 1.25, "7": 1.5, "16": 2.5 },
2989
+ lineWidthStops: { "1": 0.75, "2": 0.75, "3": 0.75, "4": 1, "5": 1, "7": 1.5, "11": 2 },
2832
2990
  lineStyles: [
2833
- { color: "rgb(235, 214, 214)", layerSuffix: "ne", endZoom: 4, lineExtensionFactor: 0.1, delWidthFactor: 2 },
2834
- { color: "rgb(235, 214, 214)", layerSuffix: "ne-disp", endZoom: 4, lineExtensionFactor: 0 },
2835
- { color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.2, startZoom: 6, widthFraction: 3, lineExtensionFactor: 0.1 },
2991
+ { color: "rgb(235, 214, 214)", layerSuffix: "ne", endZoom: 4, lineExtensionFactor: 0.1, delWidthFactor: 2.5 },
2992
+ { color: "rgb(235, 214, 214)", layerSuffix: "ne-disp", endZoom: 4, delWidthFactor: 0 },
2993
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 6, endZoom: 11, widthFraction: 5, lineExtensionFactor: 0.1 },
2994
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm", alpha: 0.1, startZoom: 12, widthFraction: 4, lineExtensionFactor: 0.1 },
2836
2995
  { color: "rgb(235, 214, 214)", layerSuffix: "osm", startZoom: 5, lineExtensionFactor: 0.1 },
2837
- { color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", alpha: 0.2, startZoom: 6, widthFraction: 3, lineExtensionFactor: 0 },
2838
- { color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", startZoom: 5, lineExtensionFactor: 0 },
2839
- { color: "rgb(235, 214, 214)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.75, dashArray: [2, 2], delWidthFactor: 2 }
2996
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm-disp", startZoom: 5, delWidthFactor: 0 },
2997
+ { color: "rgb(235, 214, 214)", layerSuffix: "osm-internal", startZoom: 5, widthFraction: 0.5, dashArray: [4, 4], delWidthFactor: 2 },
2998
+ { color: "rgb(235, 214, 214)", layerSuffix: "ne-internal", startZoom: 4, endZoom: 4, widthFraction: 0.5, dashArray: [4, 4], delWidthFactor: 2.5 }
2840
2999
  ]
2841
3000
  },
2842
3001
  {
@@ -2863,10 +3022,10 @@ var IndiaBoundaryCorrector = (() => {
2863
3022
  lineWidthStops: { "1": 0.5, "2": 0.6, "3": 0.7, "4": 1, "10": 3.75 },
2864
3023
  lineStyles: [
2865
3024
  { color: "rgb(200, 180, 200)", layerSuffix: "osm", startZoom: 1, endZoom: 3, delWidthFactor: 2.5, widthFraction: 1.5 },
2866
- { color: "rgb(200, 180, 200)", layerSuffix: "osm", startZoom: 4 },
2867
- { color: "rgb(160, 120, 160)", layerSuffix: "osm", startZoom: 4, widthFraction: 0.333, dashArray: [30, 2, 8, 2] },
3025
+ { color: "rgb(200, 180, 200)", layerSuffix: "osm", startZoom: 4, delWidthFactor: 1.5 },
3026
+ { color: "rgb(160, 120, 160)", layerSuffix: "osm", startZoom: 4, widthFraction: 0.333, dashArray: [30, 2, 8, 2], delWidthFactor: 0 },
2868
3027
  { color: "rgb(200, 180, 200)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.45 },
2869
- { color: "rgb(160, 120, 160)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.15, dashArray: [4, 2, 10] }
3028
+ { color: "rgb(160, 120, 160)", layerSuffix: "osm-internal", startZoom: 4, widthFraction: 0.15, dashArray: [10, 4, 2] }
2870
3029
  ]
2871
3030
  },
2872
3031
  {
@@ -2879,13 +3038,17 @@ var IndiaBoundaryCorrector = (() => {
2879
3038
  lineStyles: [
2880
3039
  { color: "rgb(149, 175, 180)", layerSuffix: "osm", lineExtensionFactor: 0.25, startZoom: 2 },
2881
3040
  { color: "rgb(89, 117, 123)", layerSuffix: "osm", widthFraction: 0.33, lineExtensionFactor: 0.25, startZoom: 2 },
2882
- { color: "rgb(172, 163, 163)", layerSuffix: "osm-internal", widthFraction: 0.33, startZoom: 4, dashArray: [7, 7, 7] }
3041
+ { color: "rgb(172, 163, 163)", layerSuffix: "osm-internal", widthFraction: 0.33, startZoom: 4, dashArray: [7, 7] }
2883
3042
  ]
2884
3043
  }
2885
3044
  ];
2886
3045
  var INFINITY2 = -1;
3046
+ var MIN_LINE_WIDTH2 = 0.1;
3047
+ var DEFAULT_LINE_WIDTH2 = 1;
2887
3048
  function templateToRegex2(template) {
2888
3049
  const groups = [];
3050
+ const hasRetina = template.includes("{r}");
3051
+ const hasExtension = /\.(png|jpg|jpeg|webp|gif)$/i.test(template);
2889
3052
  let pattern = template.replace(/[.*+?^${}()|[\]\\]/g, (char) => {
2890
3053
  if (char === "{" || char === "}") return char;
2891
3054
  return "\\" + char;
@@ -2899,13 +3062,22 @@ var IndiaBoundaryCorrector = (() => {
2899
3062
  return "([a-z0-9]+)";
2900
3063
  }
2901
3064
  if (lowerName === "r") {
2902
- return "(@\\d+x)?";
3065
+ return "(@\\d+x)";
2903
3066
  }
2904
3067
  return "(\\d+)";
2905
3068
  });
3069
+ if (!hasRetina) {
3070
+ if (hasExtension) {
3071
+ pattern = pattern.replace(/(\\\.(png|jpg|jpeg|webp|gif))/, "(?!@\\d+x)$1");
3072
+ } else {
3073
+ pattern = pattern + "(?!@\\d+x)";
3074
+ }
3075
+ }
2906
3076
  return { pattern: new RegExp("^" + pattern + "(\\?.*)?$", "i"), groups };
2907
3077
  }
2908
3078
  function templateToTemplateRegex2(template) {
3079
+ const hasRetina = template.includes("{r}");
3080
+ const hasExtension = /\.(png|jpg|jpeg|webp|gif)$/i.test(template);
2909
3081
  let pattern = template.replace(/[.*+?^${}()|[\]\\]/g, (char) => {
2910
3082
  if (char === "{" || char === "}") return char;
2911
3083
  return "\\" + char;
@@ -2915,10 +3087,17 @@ var IndiaBoundaryCorrector = (() => {
2915
3087
  return "(\\{s\\}|\\{[a-z0-9]-[a-z0-9]\\}|[a-z0-9]+)";
2916
3088
  }
2917
3089
  if (lowerName === "r") {
2918
- return "(\\{r\\}|@\\d+x)?";
3090
+ return "(\\{r\\}|@\\d+x)";
2919
3091
  }
2920
3092
  return `\\{${lowerName}\\}`;
2921
3093
  });
3094
+ if (!hasRetina) {
3095
+ if (hasExtension) {
3096
+ pattern = pattern.replace(/(\\\.(png|jpg|jpeg|webp|gif))/, "(?!@\\d+x|\\{r\\})$1");
3097
+ } else {
3098
+ pattern = pattern + "(?!@\\d+x|\\{r\\})";
3099
+ }
3100
+ }
2922
3101
  return new RegExp("^" + pattern + "(\\?.*)?$", "i");
2923
3102
  }
2924
3103
  function isValidColor2(color) {
@@ -2987,7 +3166,7 @@ var IndiaBoundaryCorrector = (() => {
2987
3166
  * @param {number} [options.lineExtensionFactor=0.5] - Factor to extend lines by (multiplied by deletion line width)
2988
3167
  * @param {number} [options.delWidthFactor=1.5] - Factor to multiply line width for deletion blur
2989
3168
  */
2990
- constructor({ color, layerSuffix, widthFraction = 1, dashArray, alpha = 1, startZoom = 0, endZoom = INFINITY2, lineExtensionFactor = 0.5, delWidthFactor = 1.5 }) {
3169
+ constructor({ color, layerSuffix, widthFraction = 1, dashArray, alpha = 1, startZoom = 0, endZoom = INFINITY2, lineExtensionFactor = 0, delWidthFactor = 1.5 }) {
2991
3170
  this.color = color;
2992
3171
  this.layerSuffix = layerSuffix;
2993
3172
  this.widthFraction = widthFraction;
@@ -3117,6 +3296,45 @@ var IndiaBoundaryCorrector = (() => {
3117
3296
  const activeStyles = this.getLineStylesForZoom(z2);
3118
3297
  return [...new Set(activeStyles.map((s) => s.layerSuffix))];
3119
3298
  }
3299
+ /**
3300
+ * Interpolate or extrapolate line width for a given zoom level.
3301
+ * Uses the lineWidthStops map to calculate the appropriate width.
3302
+ * @param {number} zoom - Zoom level
3303
+ * @returns {number}
3304
+ */
3305
+ getLineWidth(zoom) {
3306
+ const zooms = Object.keys(this.lineWidthStops).map(Number).sort((a, b2) => a - b2);
3307
+ if (this.lineWidthStops[zoom] !== void 0) {
3308
+ return this.lineWidthStops[zoom];
3309
+ }
3310
+ if (zoom < zooms[0]) {
3311
+ const z1 = zooms[0];
3312
+ const z2 = zooms[1];
3313
+ const w1 = this.lineWidthStops[z1];
3314
+ const w2 = this.lineWidthStops[z2];
3315
+ const slope = (w2 - w1) / (z2 - z1);
3316
+ return Math.max(MIN_LINE_WIDTH2, w1 + slope * (zoom - z1));
3317
+ }
3318
+ if (zoom > zooms[zooms.length - 1]) {
3319
+ const z1 = zooms[zooms.length - 2];
3320
+ const z2 = zooms[zooms.length - 1];
3321
+ const w1 = this.lineWidthStops[z1];
3322
+ const w2 = this.lineWidthStops[z2];
3323
+ const slope = (w2 - w1) / (z2 - z1);
3324
+ return Math.max(MIN_LINE_WIDTH2, w2 + slope * (zoom - z2));
3325
+ }
3326
+ for (let i2 = 0; i2 < zooms.length - 1; i2++) {
3327
+ if (zoom > zooms[i2] && zoom < zooms[i2 + 1]) {
3328
+ const z1 = zooms[i2];
3329
+ const z2 = zooms[i2 + 1];
3330
+ const w1 = this.lineWidthStops[z1];
3331
+ const w2 = this.lineWidthStops[z2];
3332
+ const t = (zoom - z1) / (z2 - z1);
3333
+ return w1 + t * (w2 - w1);
3334
+ }
3335
+ }
3336
+ return DEFAULT_LINE_WIDTH2;
3337
+ }
3120
3338
  /**
3121
3339
  * Check if this config matches the given template URLs (with {z}/{x}/{y} placeholders)
3122
3340
  * @param {string | string[]} templates - Single template URL or array of template URLs
@@ -3307,42 +3525,7 @@ var IndiaBoundaryCorrector = (() => {
3307
3525
  return new _TileFetchError(response.status, response.url, body);
3308
3526
  }
3309
3527
  };
3310
- var MIN_LINE_WIDTH = 0.1;
3311
3528
  var DEFAULT_TILE_EXTENT = 4096;
3312
- var DEFAULT_LINE_WIDTH = 1;
3313
- function getLineWidth(zoom, lineWidthStops) {
3314
- const zooms = Object.keys(lineWidthStops).map(Number).sort((a, b2) => a - b2);
3315
- if (lineWidthStops[zoom] !== void 0) {
3316
- return lineWidthStops[zoom];
3317
- }
3318
- if (zoom < zooms[0]) {
3319
- const z1 = zooms[0];
3320
- const z2 = zooms[1];
3321
- const w1 = lineWidthStops[z1];
3322
- const w2 = lineWidthStops[z2];
3323
- const slope = (w2 - w1) / (z2 - z1);
3324
- return Math.max(MIN_LINE_WIDTH, w1 + slope * (zoom - z1));
3325
- }
3326
- if (zoom > zooms[zooms.length - 1]) {
3327
- const z1 = zooms[zooms.length - 2];
3328
- const z2 = zooms[zooms.length - 1];
3329
- const w1 = lineWidthStops[z1];
3330
- const w2 = lineWidthStops[z2];
3331
- const slope = (w2 - w1) / (z2 - z1);
3332
- return Math.max(MIN_LINE_WIDTH, w2 + slope * (zoom - z2));
3333
- }
3334
- for (let i2 = 0; i2 < zooms.length - 1; i2++) {
3335
- if (zoom > zooms[i2] && zoom < zooms[i2 + 1]) {
3336
- const z1 = zooms[i2];
3337
- const z2 = zooms[i2 + 1];
3338
- const w1 = lineWidthStops[z1];
3339
- const w2 = lineWidthStops[z2];
3340
- const t = (zoom - z1) / (z2 - z1);
3341
- return w1 + t * (w2 - w1);
3342
- }
3343
- }
3344
- return DEFAULT_LINE_WIDTH;
3345
- }
3346
3529
  function getFeaturesBoundingBox(features, tileSize, padding = 0) {
3347
3530
  let minX = Infinity, minY = Infinity;
3348
3531
  let maxX = -Infinity, maxY = -Infinity;
@@ -3603,7 +3786,6 @@ var IndiaBoundaryCorrector = (() => {
3603
3786
  * @returns {Promise<ArrayBuffer>} The corrected tile as ArrayBuffer (PNG)
3604
3787
  */
3605
3788
  async fixTile(corrections, rasterTile, layerConfig, zoom) {
3606
- const { lineWidthStops } = layerConfig;
3607
3789
  let activeLineStyles;
3608
3790
  if (layerConfig.getLineStylesForZoom) {
3609
3791
  activeLineStyles = layerConfig.getLineStylesForZoom(zoom);
@@ -3628,7 +3810,7 @@ var IndiaBoundaryCorrector = (() => {
3628
3810
  const canvas = this._canvas;
3629
3811
  const ctx = canvas.getContext("2d", { willReadFrequently: true });
3630
3812
  ctx.drawImage(imageBitmap, 0, 0, tileSize, tileSize);
3631
- const baseLineWidth = getLineWidth(zoom, lineWidthStops);
3813
+ const baseLineWidth = layerConfig.getLineWidth(zoom);
3632
3814
  const delLineWidthBySuffix = {};
3633
3815
  for (const suffix of layerSuffixes) {
3634
3816
  const stylesForSuffix = activeLineStyles.filter((s) => s.layerSuffix === suffix);