PageSourceSearch

https://censusmapper.ca/_next/static/media/maplibre-gl-worker-dev.3djs8r0hsudhr.mjs

js censusmapper.ca collected 2026-10-02 04:33:40 UTC 38,015 bytes, 1,033 lines download raw bytes

vendor: 38,015 bytes, lines 1-1033
1/**
2* MapLibre GL JS
3* @license 3-Clause BSD. Full text of license: https://github.com/maplibre/maplibre-gl-js/blob/v6.11.1/LICENSE.txt
4*/
5import { An as addProtocol, Br as EXTENT, D as clipGeometry, Dt as RGBAImage, Et as AlphaImage, F as potpack, Fn as isAbortError, G as GeoJSONVT, H as rtlWorkerPlugin, Ir as warnOnce, Ln as JSON_PREFIX, Mn as removeProtocol, N as ImageAtlas, On as makeRequest, Tn as getJSON, Ui as Point, Vt as CollisionBoxArray, _ as createStyleLayer, bt as DEMData, c as GeoJSONWrapper, d as OverscaledTileID, dn as createExpression, dr as isImageBitmap, dt as VectorTile, en as EvaluationParameters, g as Actor, gr as isWorker, i as MLTVectorTile, l as fromVectorTileJs, ln as groupByLayout, lr as getImageData, nn as register, o as DictionaryCoder, r as FeatureIndex, rr as extend, t as BoundedLRUCache, tr as ensureError, un as featureFilter, vr as mapObject, wn as getArrayBuffer, z as PbfReader } from "./maplibre-gl-shared-dev.mjs";
6//#region src/style/style_layer_index.ts
7var StyleLayerIndex = class {
8	constructor(layerConfigs, globalState) {
9		this.keyCache = {};
10		if (layerConfigs) this.replace(layerConfigs, globalState);
11	}
12	replace(layerConfigs, globalState) {
13		this._layerConfigs = {};
14		this._layers = {};
15		this.update(layerConfigs, [], globalState);
16	}
17	update(layerConfigs, removedIds, globalState) {
18		for (const layerConfig of layerConfigs) {
19			this._layerConfigs[layerConfig.id] = layerConfig;
20			const layer = this._layers[layerConfig.id] = createStyleLayer(layerConfig, globalState);
21			layer._featureFilter = featureFilter(layer.filter, `layers[${layerConfig.id}].filter`, globalState);
22			if (this.keyCache[layerConfig.id]) delete this.keyCache[layerConfig.id];
23		}
24		for (const id of removedIds) {
25			delete this.keyCache[id];
26			delete this._layerConfigs[id];
27			delete this._layers[id];
28		}
29		this.familiesBySource = {};
30		const groups = groupByLayout(Object.values(this._layerConfigs), this.keyCache);
31		for (const layerConfigs of groups) {
32			const layers = layerConfigs.map((layerConfig) => this._layers[layerConfig.id]);
33			const layer = layers[0];
34			if (layer.isHidden()) continue;
35			const sourceId = layer.source || "";
36			let sourceGroup = this.familiesBySource[sourceId];
37			sourceGroup ||= this.familiesBySource[sourceId] = {};
38			const sourceLayerId = layer.sourceLayer || "_geojsonTileLayer";
39			let sourceLayerFamilies = sourceGroup[sourceLayerId];
40			sourceLayerFamilies ||= sourceGroup[sourceLayerId] = [];
41			sourceLayerFamilies.push(layers);
42		}
43	}
44};
45//#endregion
46//#region src/render/glyph_atlas.ts
47const padding = 1;
48var GlyphAtlas = class {
49	constructor(stacks) {
50		const positions = {};
51		const bins = [];
52		for (const stack in stacks) {
53			const glyphs = stacks[stack];
54			const stackPositions = positions[stack] = {};
55			for (const id in glyphs) {
56				const src = glyphs[id];
57				if (!src || src.bitmap.width === 0 || src.bitmap.height === 0) continue;
58				const bin = {
59					x: 0,
60					y: 0,
61					w: src.bitmap.width + 2,
62					h: src.bitmap.height + 2
63				};
64				bins.push(bin);
65				stackPositions[id] = {
66					rect: bin,
67					metrics: src.metrics
68				};
69			}
70		}
71		const { w, h } = potpack(bins);
72		const image = new AlphaImage({
73			width: w || 1,
74			height: h || 1
75		});
76		for (const stack in stacks) {
77			const glyphs = stacks[stack];
78			for (const id in glyphs) {
79				const src = glyphs[id];
80				if (!src || src.bitmap.width === 0 || src.bitmap.height === 0) continue;
81				const bin = positions[stack][id].rect;
82				AlphaImage.copy(src.bitmap, image, {
83					x: 0,
84					y: 0
85				}, {
86					x: bin.x + padding,
87					y: bin.y + padding
88				}, src.bitmap);
89			}
90		}
91		this.image = image;
92		this.positions = positions;
93	}
94};
95register("GlyphAtlas", GlyphAtlas);
96//#endregion
97//#region src/source/worker_tile.ts
98var WorkerTile = class {
99	constructor(params) {
100		this.tileID = new OverscaledTileID(params.tileID.overscaledZ, params.tileID.wrap, params.tileID.canonical.z, params.tileID.canonical.x, params.tileID.canonical.y);
101		this.uid = params.uid;
102		this.zoom = params.zoom;
103		this.pixelRatio = params.pixelRatio;
104		this.tileSize = params.tileSize;
105		this.source = params.source;
106		this.overscaling = this.tileID.overscaleFactor();
107		this.showCollisionBoxes = params.showCollisionBoxes;
108		this.collectResourceTiming = !!params.collectResourceTiming;
109		this.returnDependencies = !!params.returnDependencies;
110		this.promoteId = params.promoteId;
111		this.inFlightDependencies = [];
112	}
113	async parse(data, layerIndex, availableImages, actor, subdivisionGranularity) {
114		this.data = data;
115		this.collisionBoxArray = new CollisionBoxArray();
116		const sourceLayerCoder = new DictionaryCoder(Object.keys(data.layers).sort());
117		const featureIndex = new FeatureIndex(this.tileID, this.promoteId);
118		featureIndex.bucketLayerIDs = [];
119		const buckets = {};
120		const options = {
121			featureIndex,
122			iconDependencies: {},
123			patternDependencies: {},
124			glyphDependencies: {},
125			dashDependencies: {},
126			availableImages,
127			subdivisionGranularity
128		};
129		const layerFamilies = layerIndex.familiesBySource[this.source];
130		for (const sourceLayerId in layerFamilies) {
131			const sourceLayer = data.layers[sourceLayerId];
132			if (!sourceLayer) continue;
133			if (sourceLayer.version === 1) warnOnce(`Vector tile source "${this.source}" layer "${sourceLayerId}" does not use vector tile spec v2 and therefore may have some rendering errors.`);
134			const sourceLayerIndex = sourceLayerCoder.encode(sourceLayerId);
135			const features = [];
136			for (let index = 0; index < sourceLayer.length; index++) {
137				const feature = sourceLayer.feature(index);
138				const id = featureIndex.getId(feature, sourceLayerId);
139				features.push({
140					feature,
141					id,
142					index,
143					sourceLayerIndex
144				});
145			}
146			for (const family of layerFamilies[sourceLayerId]) {
147				const layer = family[0];
148				if (layer.source !== this.source) warnOnce(`layer.source = ${layer.source} does not equal this.source = ${this.source}`);
149				if (layer.isHidden(this.zoom, true)) continue;
150				recalculateLayers(family, this.zoom, availableImages);
151				(buckets[layer.id] = layer.createBucket({
152					index: featureIndex.bucketLayerIDs.length,
153					layers: family,
154					zoom: this.zoom,
155					pixelRatio: this.pixelRatio,
156					overscaling: this.overscaling,
157					collisionBoxArray: this.collisionBoxArray,
158					sourceLayerIndex,
159					sourceID: this.source
160				})).populate(features, options, this.tileID.canonical);
161				featureIndex.bucketLayerIDs.push(family.map((l) => l.id));
162			}
163		}
164		const stacks = mapObject(options.glyphDependencies, (glyphs) => Object.keys(glyphs));
165		for (const request of this.inFlightDependencies) request?.abort();
166		this.inFlightDependencies = [];
167		let getGlyphsPromise = Promise.resolve({});
168		if (Object.keys(stacks).length) {
169			const abortController = new AbortController();
170			this.inFlightDependencies.push(abortController);
171			getGlyphsPromise = actor.sendAsync({
172				type: "GG",
173				data: {
174					stacks,
175					source: this.source,
176					tileID: this.tileID,
177					type: "glyphs"
178				}
179			}, abortController);
180		}
181		const icons = Object.keys(options.iconDependencies);
182		let getIconsPromise = Promise.resolve({});
183		if (icons.length) {
184			const abortController = new AbortController();
185			this.inFlightDependencies.push(abortController);
186			getIconsPromise = actor.sendAsync({
187				type: "GI",
188				data: {
189					icons,
190					source: this.source,
191					tileID: this.tileID,
192					type: "icons"
193				}
194			}, abortController);
195		}
196		const patterns = Object.keys(options.patternDependencies);
197		let getPatternsPromise = Promise.resolve({});
198		if (patterns.length) {
199			const abortController = new AbortController();
200			this.inFlightDependencies.push(abortController);
201			getPatternsPromise = actor.sendAsync({
202				type: "GI",
203				data: {
204					icons: patterns,
205					source: this.source,
206					tileID: this.tileID,
207					type: "patterns"
208				}
209			}, abortController);
210		}
211		const dashes = options.dashDependencies;
212		let getDashesPromise = Promise.resolve({});
213		if (Object.keys(dashes).length) {
214			const abortController = new AbortController();
215			this.inFlightDependencies.push(abortController);
216			getDashesPromise = actor.sendAsync({
217				type: "GDA",
218				data: { dashes }
219			}, abortController);
220		}
221		const [glyphMap, iconMap, patternMap, dashPositions] = await Promise.all([
222			getGlyphsPromise,
223			getIconsPromise,
224			getPatternsPromise,
225			getDashesPromise
226		]);
227		const glyphAtlas = new GlyphAtlas(glyphMap);
228		const imageAtlas = new ImageAtlas(iconMap, patternMap);
229		for (const key in buckets) {
230			const bucket = buckets[key];
231			if (!bucket.hasDependencies) continue;
232			recalculateLayers(bucket.layers, this.zoom, availableImages);
233			bucket.addFeatures({
234				options,
235				canonical: this.tileID.canonical,
236				glyphMap,
237				glyphPositions: glyphAtlas.positions,
238				iconMap,
239				iconPositions: imageAtlas.iconPositions,
240				patternMap,
241				patternPositions: imageAtlas.patternPositions,
242				dashPositions,
243				showCollisionBoxes: this.showCollisionBoxes
244			});
245		}
246		return {
247			buckets: Object.values(buckets).filter((b) => !b.isEmpty()),
248			featureIndex,
249			collisionBoxArray: this.collisionBoxArray,
250			glyphAtlasImage: glyphAtlas.image,
251			imageAtlas,
252			dashPositions,
253			glyphMap: this.returnDependencies ? glyphMap : null,
254			iconMap: this.returnDependencies ? iconMap : null,
255			glyphPositions: this.returnDependencies ? glyphAtlas.positions : null
256		};
257	}
258};
259function recalculateLayers(layers, zoom, availableImages) {
260	const parameters = new EvaluationParameters(zoom);
261	for (const layer of layers) layer.recalculate(parameters, availableImages);
262}
263//#endregion
264//#region src/source/worker_tile_state.ts
265var WorkerTileState = class {
266	constructor() {
267		this.loading = {};
268		this.loaded = {};
269		this.parsing = {};
270	}
271	startLoading(uid, tile) {
272		this.loading[uid] = tile;
273	}
274	finishLoading(uid) {
275		delete this.loading[uid];
276	}
277	abort(uid) {
278		const tile = this.loading[uid];
279		if (!tile?.abort) return;
280		tile.abort.abort();
281		delete this.loading[uid];
282	}
283	getParsing(uid) {
284		return this.parsing[uid];
285	}
286	setParsing(uid, state) {
287		this.parsing[uid] = state;
288	}
289	removeParsing(uid) {
290		delete this.parsing[uid];
291	}
292	markLoaded(uid, tile) {
293		this.loaded[uid] = tile;
294	}
295	getLoaded(uid) {
296		const tile = this.loaded[uid];
297		if (!tile) return void 0;
298		return tile;
299	}
300	removeLoaded(uid) {
301		delete this.loaded[uid];
302	}
303	clearLoaded() {
304		this.loaded = {};
305	}
306};
307//#endregion
308//#region src/util/request_performance.ts
309/**
310* @internal
311* Safe wrapper for the performance resource timing API in web workers with graceful degradation
312*/
313var RequestPerformance = class {
314	constructor(url) {
315		this.start = `${url}#start`;
316		this.end = `${url}#end`;
317		this.measure = url;
318		performance.mark(this.start);
319	}
320	finish() {
321		performance.mark(this.end);
322		let resourceTimingData = performance.getEntriesByName(this.measure);
323		if (resourceTimingData.length === 0) {
324			performance.measure(this.measure, this.start, this.end);
325			resourceTimingData = performance.getEntriesByName(this.measure);
326			performance.clearMarks(this.start);
327			performance.clearMarks(this.end);
328			performance.clearMeasures(this.measure);
329		}
330		return resourceTimingData;
331	}
332};
333//#endregion
334//#region src/source/vector_tile_overzoomed.ts
335var VectorTileFeatureOverzoomed = class {
336	constructor(type, geometry, properties, id, extent) {
337		this.type = type;
338		this.properties = properties ? properties : {};
339		this.extent = extent;
340		this.pointsArray = geometry;
341		this.id = id;
342	}
343	loadGeometry() {
344		return this.pointsArray.map((ring) => ring.map((point) => new Point(point.x, point.y)));
345	}
346};
347var VectorTileLayerOverzoomed = class {
348	constructor(features, layerName, extent) {
349		this.version = 2;
350		this._myFeatures = features;
351		this.name = layerName;
352		this.length = features.length;
353		this.extent = extent;
354	}
355	feature(i) {
356		return this._myFeatures[i];
357	}
358};
359var VectorTileOverzoomed = class {
360	constructor() {
361		this.layers = {};
362	}
363	addLayer(layer) {
364		this.layers[layer.name] = layer;
365	}
366};
367/**
368* This function slices a source tile layer into an overzoomed tile layer for a target tile ID.
369* @param sourceLayer - the source tile layer to slice
370* @param maxZoomTileID - the maximum zoom tile ID
371* @param targetTileID - the target tile ID
372* @returns - the overzoomed tile layer
373*/
374function sliceVectorTileLayer(sourceLayer, maxZoomTileID, targetTileID) {
375	const { extent } = sourceLayer;
376	const dz = targetTileID.z - maxZoomTileID.z;
377	const scale = Math.pow(2, dz);
378	const offsetX = (targetTileID.x - maxZoomTileID.x * scale) * extent;
379	const offsetY = (targetTileID.y - maxZoomTileID.y * scale) * extent;
380	const featureWrappers = [];
381	for (let index = 0; index < sourceLayer.length; index++) {
382		const feature = sourceLayer.feature(index);
383		let geometry = feature.loadGeometry();
384		for (const ring of geometry) for (const point of ring) {
385			point.x = point.x * scale - offsetX;
386			point.y = point.y * scale - offsetY;
387		}
388		const buffer = 128;
389		geometry = clipGeometry(geometry, feature.type, -128, -128, extent + buffer, extent + buffer);
390		if (geometry.length === 0) continue;
391		featureWrappers.push(new VectorTileFeatureOverzoomed(feature.type, geometry, feature.properties, feature.id, extent));
392	}
393	return new VectorTileLayerOverzoomed(featureWrappers, sourceLayer.name, extent);
394}
395//#endregion
396//#region src/source/vector_tile_worker_source.ts
397/**
398* The {@link WorkerSource} implementation that supports {@link VectorTileSource}. This class is
399* used by vector tile sources to perform tile processing operations in a separate worker thread.
400*/
401var VectorTileWorkerSource = class {
402	constructor(actor, layerIndex, availableImages) {
403		this.actor = actor;
404		this.layerIndex = layerIndex;
405		this.availableImages = availableImages;
406		this.tileState = new WorkerTileState();
407		this.overzoomedTileResultCache = new BoundedLRUCache(1e3);
408	}
409	/**
410	* Loads a vector tile
411	*/
412	loadVectorTile(params, rawData) {
413		try {
414			return {
415				vectorTile: params.encoding !== "mlt" ? new VectorTile(new PbfReader(rawData)) : new MLTVectorTile(rawData),
416				rawData
417			};
418		} catch (ex) {
419			const bytes = new Uint8Array(rawData);
420			const isGzipped = bytes[0] === 31 && bytes[1] === 139;
421			let errorMessage = `Unable to parse the tile at ${params.request.url}, `;
422			if (isGzipped) errorMessage += "please make sure the data is not gzipped and that you have configured the relevant header in the server";
423			else errorMessage += `got error: ${ensureError(ex).message}`;
424			throw new Error(errorMessage);
425		}
426	}
427	/**
428	* Implements {@link WorkerSource.loadTile}.
429	*/
430	async loadTile(params) {
431		const { uid, overzoomParameters } = params;
432		if (overzoomParameters) params.request = overzoomParameters.overzoomRequest;
433		const timing = this._startRequestTiming(params);
434		const workerTile = new WorkerTile(params);
435		this.tileState.startLoading(uid, workerTile);
436		const abortController = new AbortController();
437		workerTile.abort = abortController;
438		try {
439			const tileResponse = await getArrayBuffer(params.request, abortController);
440			if (params.etag && params.etag === tileResponse.etag) {
441				this.tileState.finishLoading(uid);
442				return this._getEtagUnmodifiedResult(tileResponse, timing);
443			}
444			const tileResult = this.loadVectorTile(params, tileResponse.data);
445			this.tileState.finishLoading(uid);
446			if (!tileResult) return null;
447			let { vectorTile, rawData } = tileResult;
448			if (overzoomParameters) ({vectorTile, rawData} = this._getOverzoomTile(params, vectorTile));
449			const cacheControl = this._getExpiryData(tileResponse);
450			const resourceTiming = this._finishRequestTiming(timing);
451			workerTile.vectorTile = vectorTile;
452			workerTile.etag = tileResponse.etag;
453			this.tileState.markLoaded(uid, workerTile);
454			const parsingState = {
455				rawData,
456				cacheControl,
457				resourceTiming
458			};
459			this.tileState.setParsing(uid, parsingState);
460			return await this._parseWorkerTile(workerTile, params);
461		} catch (err) {
462			this.tileState.finishLoading(uid);
463			this.tileState.markLoaded(uid, workerTile);
464			throw err;
465		}
466	}
467	_getEtagUnmodifiedResult(response, timing) {
468		const cacheControl = this._getExpiryData(response);
469		const resourceTiming = this._finishRequestTiming(timing);
470		return extend({ etagUnmodified: true }, cacheControl, resourceTiming);
471	}
472	async _parseWorkerTile(workerTile, params) {
473		const parseState = this.tileState.getParsing(workerTile.uid);
474		let result = await workerTile.parse(workerTile.vectorTile, this.layerIndex, this.availableImages, this.actor, params.subdivisionGranularity);
475		if (parseState) {
476			const { rawData, cacheControl, resourceTiming } = parseState;
477			const encoding = params.overzoomParameters ? "mvt" : params.encoding;
478			result = extend({
479				rawTileData: rawData.slice(0),
480				encoding
481			}, result, cacheControl, resourceTiming);
482			this.tileState.removeParsing(workerTile.uid);
483		} else if (workerTile.etag) result = extend(result, { etag: workerTile.etag });
484		return result;
485	}
486	_getExpiryData({ expires, cacheControl, etag }) {
487		const data = {};
488		if (expires) data.expires = expires;
489		if (cacheControl) data.cacheControl = cacheControl;
490		if (etag) data.etag = etag;
491		return data;
492	}
493	_startRequestTiming(params) {
494		if (!params.request?.collectResourceTiming) return;
495		return new RequestPerformance(params.request.url);
496	}
497	_finishRequestTiming(timing) {
498		const timingData = timing?.finish();
499		if (!timingData) return {};
500		return { resourceTiming: JSON.parse(JSON.stringify(timingData)) };
501	}
502	/**
503	* If we are seeking a tile deeper than the source's max available canonical tile, get the overzoomed tile
504	* @param params - the worker tile parameters
505	* @param maxZoomVectorTile - the original vector tile at the source's max available canonical zoom
506	* @returns the overzoomed tile and its raw data
507	*/
508	_getOverzoomTile(params, maxZoomVectorTile) {
509		const { tileID, source, overzoomParameters } = params;
510		const { maxZoomTileID } = overzoomParameters;
511		const cacheKey = `${maxZoomTileID.key}_${tileID.key}_${params.request?.url}`;
512		const cachedOverzoomTile = this.overzoomedTileResultCache.get(cacheKey);
513		if (cachedOverzoomTile) return cachedOverzoomTile;
514		const overzoomedVectorTile = new VectorTileOverzoomed();
515		const layerFamilies = this.layerIndex.familiesBySource[source];
516		for (const sourceLayerId in layerFamilies) {
517			const sourceLayer = maxZoomVectorTile.layers[sourceLayerId];
518			if (!sourceLayer) continue;
519			const slicedTileLayer = sliceVectorTileLayer(sourceLayer, maxZoomTileID, tileID.canonical);
520			if (slicedTileLayer.length > 0) overzoomedVectorTile.addLayer(slicedTileLayer);
521		}
522		const overzoomedVectorTileResult = {
523			vectorTile: overzoomedVectorTile,
524			rawData: fromVectorTileJs(overzoomedVectorTile).buffer
525		};
526		this.overzoomedTileResultCache.set(cacheKey, overzoomedVectorTileResult);
527		return overzoomedVectorTileResult;
528	}
529	/**
530	* Implements {@link WorkerSource.reloadTile}.
531	*/
532	async reloadTile(params) {
533		const uid = params.uid;
534		const workerTile = this.tileState.getLoaded(uid);
535		if (!workerTile) throw new Error("Should not be trying to reload a tile that was never loaded or has been removed");
536		if (!workerTile.vectorTile) return;
537		workerTile.showCollisionBoxes = params.showCollisionBoxes;
538		return await this._parseWorkerTile(workerTile, params);
539	}
540	/**
541	* Implements {@link WorkerSource.abortTile}.
542	*/
543	async abortTile(params) {
544		this.tileState.abort(params.uid);
545	}
546	/**
547	* Implements {@link WorkerSource.removeTile}.
548	*/
549	async removeTile(params) {
550		this.tileState.removeLoaded(params.uid);
551	}
552};
553//#endregion
554//#region src/source/raster_dem_tile_worker_source.ts
555var RasterDEMTileWorkerSource = class {
556	constructor() {
557		this.loaded = {};
558	}
559	async loadTile(params) {
560		const { uid, encoding, rawImageData, redFactor, greenFactor, blueFactor, baseShift } = params;
561		const width = rawImageData.width + 4;
562		const height = rawImageData.height + 4;
563		const imagePixels = isImageBitmap(rawImageData) ? new RGBAImage({
564			width,
565			height
566		}, await getImageData(rawImageData, -2, -2, width, height)) : rawImageData;
567		const dem = new DEMData(uid, imagePixels, encoding, redFactor, greenFactor, blueFactor, baseShift);
568		this.loaded ||= {};
569		this.loaded[uid] = dem;
570		return dem;
571	}
572	removeTile(params) {
573		const loaded = this.loaded, uid = params.uid;
574		if (loaded?.[uid]) delete loaded[uid];
575	}
576};
577//#endregion
578//#region src/source/geojson_worker_source.ts
579/**
580* The {@link WorkerSource} implementation that supports {@link GeoJSONSource}.
581* This class is designed to be easily reused to support custom source types
582* for data formats that can be parsed/converted into an in-memory GeoJSON
583* representation. To do so, create it with
584* `new GeoJSONWorkerSource(actor, layerIndex, customLoadGeoJSONFunction)`.
585* For a full example, see [mapbox-gl-topojson](https://github.com/developmentseed/mapbox-gl-topojson).
586*/
587var GeoJSONWorkerSource = class {
588	constructor(actor, layerIndex, availableImages, createGeoJSONIndexFunc = createGeoJSONIndex) {
589		this.actor = actor;
590		this.layerIndex = layerIndex;
591		this.availableImages = availableImages;
592		this.tileState = new WorkerTileState();
593		this._createGeoJSONIndex = createGeoJSONIndexFunc;
594	}
595	/**
596	* Retrieves and sends loaded vector tiles to the main thread.
597	*/
598	loadVectorTile(params) {
599		if (!this._geoJSONIndex) throw new Error("Unable to parse the data into a cluster or geojson");
600		const { z, x, y } = params.tileID.canonical;
601		const geoJSONTile = this._geoJSONIndex.getTile(z, x, y);
602		if (!geoJSONTile) return null;
603		const geojsonWrapper = new GeoJSONWrapper(geoJSONTile.features, {
604			version: 2,
605			extent: EXTENT
606		});
607		return {
608			vectorTile: geojsonWrapper,
609			rawData: fromVectorTileJs(geojsonWrapper, JSON_PREFIX).buffer
610		};
611	}
612	/**
613	* Implements {@link WorkerSource.loadTile}.
614	*/
615	async loadTile(params) {
616		const { uid } = params;
617		const workerTile = new WorkerTile(params);
618		workerTile.abort = new AbortController();
619		try {
620			const loadResult = this.loadVectorTile(params);
621			if (!loadResult) return null;
622			const { vectorTile, rawData } = loadResult;
623			workerTile.vectorTile = vectorTile;
624			this.tileState.markLoaded(uid, workerTile);
625			const parsingState = { rawData };
626			this.tileState.setParsing(uid, parsingState);
627			return await this._parseWorkerTile(workerTile, params);
628		} catch (err) {
629			this.tileState.markLoaded(uid, workerTile);
630			throw err;
631		}
632	}
633	async _parseWorkerTile(workerTile, params) {
634		const parseState = this.tileState.getParsing(workerTile.uid);
635		let result = await workerTile.parse(workerTile.vectorTile, this.layerIndex, this.availableImages, this.actor, params.subdivisionGranularity);
636		if (parseState) {
637			const { rawData } = parseState;
638			result = extend({
639				rawTileData: rawData.slice(0),
640				encoding: "mvt"
641			}, result);
642			this.tileState.removeParsing(workerTile.uid);
643		}
644		return result;
645	}
646	/**
647	* Implements {@link WorkerSource.abortTile}.
648	*/
649	async abortTile(params) {
650		this.tileState.abort(params.uid);
651	}
652	/**
653	* Implements {@link WorkerSource.removeTile}.
654	*/
655	async removeTile(params) {
656		this.tileState.removeLoaded(params.uid);
657	}
658	/**
659	* Fetches (if appropriate), parses and indexes geojson data into tiles. This
660	* preparatory method must be called before {@link GeoJSONWorkerSource.loadTile}
661	* can correctly serve up tiles. The first call to this method must contain a valid
662	* {@link params.data}, {@link params.request} or {@link params.dataDiff}. Subsequent
663	* calls may omit these parameters to reprocess the existing data (such as to update
664	* clustering options).
665	*
666	* Defers to {@link GeoJSONWorkerSource.loadAndProcessGeoJSON} for the pre-processing.
667	*
668	* When a `loadData` request comes in while a previous one is being processed,
669	* the previous one is aborted.
670	*
671	* @param params - the parameters
672	* @returns a promise that resolves when the data is loaded and parsed into a GeoJSON object
673	*/
674	async loadData(params) {
675		this._pendingRequest?.abort();
676		const timing = this._startRequestTiming(params);
677		this._pendingRequest = new AbortController();
678		try {
679			await this.loadAndProcessGeoJSON(params, this._pendingRequest);
680			delete this._pendingRequest;
681			this.tileState.clearLoaded();
682			const result = {};
683			if (params.request) result.data = params.data;
684			this._finishRequestTiming(timing, params, result);
685			return result;
686		} catch (err) {
687			delete this._pendingRequest;
688			if (!isAbortError(err)) throw err;
689			return { abandoned: true };
690		}
691	}
692	_startRequestTiming(params) {
693		if (!params.request?.collectResourceTiming) return;
694		return new RequestPerformance(params.request.url);
695	}
696	_finishRequestTiming(timing, params, result) {
697		const timingData = timing?.finish();
698		if (!timingData) return;
699		result.resourceTiming = { [params.source]: JSON.parse(JSON.stringify(timingData)) };
700	}
701	/**
702	* Implements {@link WorkerSource.reloadTile}.
703	*
704	* If the tile is loaded, reload by re-parsing the already available tile data.
705	* Otherwise, such as after a setData() call, we load the tile fresh.
706	*
707	* @param params - the parameters
708	* @returns A promise that resolves when the tile is reloaded
709	*/
710	async reloadTile(params) {
711		const uid = params.uid;
712		const workerTile = this.tileState.getLoaded(uid);
713		if (!workerTile) return await this.loadTile(params);
714		if (!workerTile.vectorTile) return;
715		workerTile.showCollisionBoxes = params.showCollisionBoxes;
716		return await this._parseWorkerTile(workerTile, params);
717	}
718	/**
719	* Fetch, parse and process GeoJSON according to the given parameters.
720	* Defers to {@link GeoJSONWorkerSource._loadGeoJSONFromString} for the fetching and parsing.
721	*
722	* @param params - the parameters
723	* @param abortController - the abort controller that allows aborting this operation
724	* @returns a promise that is resolved with the processes GeoJSON
725	*/
726	async loadAndProcessGeoJSON(params, abortController) {
727		if (params.request) params.data = (await getJSON(params.request, abortController)).data;
728		if (params.data) {
729			params.data = this._filterGeoJSON(params.data, params.filter, params.source);
730			this._geoJSONIndex = this._createGeoJSONIndex(params.data, params);
731			return;
732		}
733		if (params.dataDiff) {
734			this._geoJSONIndex ??= this._createGeoJSONIndex({
735				type: "FeatureCollection",
736				features: []
737			}, params);
738			this._geoJSONIndex.updateData(params.dataDiff, this._getFilterPredicate(params.filter, params.source));
739			return;
740		}
741		if (params.updateCluster) this._geoJSONIndex.updateClusterOptions(params.geojsonVtOptions.cluster, getSuperclusterOptions(params));
742		if (this._geoJSONIndex == null) throw new Error(`Input data given to '${params.source}' is not a valid GeoJSON object.`);
743	}
744	/**
745	* Applies a filter to a GeoJSON object.
746	*/
747	_filterGeoJSON(data, filter, source) {
748		if (data.type !== "FeatureCollection") return data;
749		const predicate = this._getFilterPredicate(filter, source);
750		if (!predicate) return data;
751		return {
752			type: "FeatureCollection",
753			features: data.features.filter((feature) => predicate(feature))
754		};
755	}
756	/**
757	* Gets a predicate function that can be used to filter GeoJSON features.
758	*/
759	_getFilterPredicate(filter, source) {
760		if (typeof filter !== "boolean" && !filter?.length) return void 0;
761		const compiled = createExpression(filter, `sources.${source}.filter`, {
762			type: "boolean",
763			"property-type": "data-driven",
764			overridable: false,
765			transition: false
766		});
767		if (compiled.result === "error") throw new Error(compiled.value.map((err) => `${err.key}: ${err.message}`).join(", "));
768		return (feature) => compiled.value.evaluate({ zoom: 0 }, feature);
769	}
770	async removeSource(_params) {
771		this._pendingRequest?.abort();
772	}
773	getClusterExpansionZoom(params) {
774		return this._geoJSONIndex.getClusterExpansionZoom(params.clusterId);
775	}
776	getClusterChildren(params) {
777		return this._geoJSONIndex.getClusterChildren(params.clusterId);
778	}
779	getClusterLeaves(params) {
780		return this._geoJSONIndex.getClusterLeaves(params.clusterId, params.limit, params.offset);
781	}
782};
783function createGeoJSONIndex(data, params) {
784	const options = extend(params.geojsonVtOptions || {}, {
785		updateable: true,
786		clusterOptions: getSuperclusterOptions(params)
787	});
788	return new GeoJSONVT(data, options);
789}
790function getSuperclusterOptions({ geojsonVtOptions, clusterProperties, source }) {
791	if (!clusterProperties || !geojsonVtOptions.clusterOptions) return geojsonVtOptions.clusterOptions;
792	const mapExpressions = {};
793	const reduceExpressions = {};
794	const globals = {
795		accumulated: null,
796		zoom: 0
797	};
798	const feature = { properties: null };
799	const propertyNames = Object.keys(clusterProperties);
800	for (const key of propertyNames) {
801		const [operator, mapExpression] = clusterProperties[key];
802		const mapExpressionParsed = createExpression(mapExpression, `sources.${source}.clusterProperties.${key}[1]`);
803		const reduceExpressionParsed = createExpression(typeof operator === "string" ? [
804			operator,
805			["accumulated"],
806			["get", key]
807		] : operator, `sources.${source}.clusterProperties.${key}[0]`);
808		mapExpressions[key] = mapExpressionParsed.value;
809		reduceExpressions[key] = reduceExpressionParsed.value;
810	}
811	geojsonVtOptions.clusterOptions.map = (pointProperties) => {
812		feature.properties = pointProperties;
813		const properties = {};
814		for (const key of propertyNames) properties[key] = mapExpressions[key].evaluate(globals, feature);
815		return properties;
816	};
817	geojsonVtOptions.clusterOptions.reduce = (accumulated, clusterProperties) => {
818		feature.properties = clusterProperties;
819		for (const key of propertyNames) {
820			globals.accumulated = accumulated[key];
821			accumulated[key] = reduceExpressions[key].evaluate(globals, feature);
822		}
823	};
824	return geojsonVtOptions.clusterOptions;
825}
826//#endregion
827//#region src/source/worker.ts
828/**
829* Loads an external script into worker (global) scope. The loader picks a
830* strategy based on what the script actually is:
831*
832* - `.mjs` URLs: dynamic `import()` directly, no fetch/sniff overhead. Worker
833*   CSP needs `script-src` to permit the URL.
834*
835* - Other URLs: fetch the source and sniff for ESM syntax (top-level `import`
836*   or `export`). If ESM is detected, run it through a blob-URL dynamic
837*   `import()` so the browser parses it as a module; this requires
838*   `script-src blob:` in the worker CSP. Otherwise treat it as UMD/IIFE and
839*   run it via `globalThis.eval`, which requires `script-src 'unsafe-eval'`.
840*/
841async function loadScript(url) {
842	if (url.endsWith(".mjs")) {
843		await import(
844			/* @vite-ignore */
845			url
846);
847		return;
848	}
849	const response = await fetch(url, { credentials: "same-origin" });
850	if (!response.ok) throw new Error(`Failed to load ${url}: ${response.status}`);
851	const code = await response.text();
852	if (/^[ \t]*(import|export)\s/m.test(code)) {
853		const blobUrl = URL.createObjectURL(new Blob([code], { type: "text/javascript" }));
854		try {
855			await import(
856				/* @vite-ignore */
857				blobUrl
858);
859		} finally {
860			URL.revokeObjectURL(blobUrl);
861		}
862		return;
863	}
864	globalThis.eval(code);
865}
866/**
867* The Worker class responsible for background thread related execution
868*/
869var Worker = class {
870	constructor(self) {
871		this.self = self;
872		this.actor = new Actor(self);
873		this.layerIndexes = {};
874		this.availableImages = {};
875		this.workerSources = {};
876		this.demWorkerSources = {};
877		this.externalWorkerSourceTypes = {};
878		this.globalStates = /* @__PURE__ */ new Map();
879		this.self.registerWorkerSource = (name, WorkerSource) => {
880			if (this.externalWorkerSourceTypes[name]) throw new Error(`Worker source with name "${name}" already registered.`);
881			this.externalWorkerSourceTypes[name] = WorkerSource;
882		};
883		this.self.addProtocol = addProtocol;
884		this.self.removeProtocol = removeProtocol;
885		/**
886		* Invoked by a right-to-left text plugin once it has fetched and parsed.
887		*
888		* @deprecated MapLibre shapes Arabic and reorders bidirectional text itself. A plugin
889		* registered here still replaces the built-in implementation, but this will be removed in a
890		* future release.
891		*/
892		this.self.registerRTLTextPlugin = (rtlTextPlugin) => {
893			rtlWorkerPlugin.setMethods(rtlTextPlugin);
894		};
895		this.self.makeRequest = makeRequest;
896		this.actor.registerMessageHandler("LDT", (mapId, params) => {
897			return this._getDEMWorkerSource(mapId, params.source).loadTile(params);
898		});
899		this.actor.registerMessageHandler("RDT", async (mapId, params) => {
900			this._getDEMWorkerSource(mapId, params.source).removeTile(params);
901		});
902		this.actor.registerMessageHandler("GCEZ", async (mapId, params) => {
903			return this._getWorkerSource(mapId, params.type, params.source).getClusterExpansionZoom(params);
904		});
905		this.actor.registerMessageHandler("GCC", async (mapId, params) => {
906			return this._getWorkerSource(mapId, params.type, params.source).getClusterChildren(params);
907		});
908		this.actor.registerMessageHandler("GCL", async (mapId, params) => {
909			return this._getWorkerSource(mapId, params.type, params.source).getClusterLeaves(params);
910		});
911		this.actor.registerMessageHandler("LD", (mapId, params) => {
912			return this._getWorkerSource(mapId, params.type, params.source).loadData(params);
913		});
914		this.actor.registerMessageHandler("LT", (mapId, params) => {
915			return this._getWorkerSource(mapId, params.type, params.source).loadTile(params);
916		});
917		this.actor.registerMessageHandler("RT", (mapId, params) => {
918			return this._getWorkerSource(mapId, params.type, params.source).reloadTile(params);
919		});
920		this.actor.registerMessageHandler("AT", (mapId, params) => {
921			return this._getWorkerSource(mapId, params.type, params.source).abortTile(params);
922		});
923		this.actor.registerMessageHandler("RMT", (mapId, params) => {
924			return this._getWorkerSource(mapId, params.type, params.source).removeTile(params);
925		});
926		this.actor.registerMessageHandler("RS", async (mapId, params) => {
927			if (!this.workerSources[mapId]?.[params.type]?.[params.source]) return;
928			const worker = this.workerSources[mapId][params.type][params.source];
929			delete this.workerSources[mapId][params.type][params.source];
930			if (worker.removeSource !== void 0) worker.removeSource(params);
931		});
932		this.actor.registerMessageHandler("RM", async (mapId) => {
933			delete this.layerIndexes[mapId];
934			delete this.availableImages[mapId];
935			delete this.workerSources[mapId];
936			delete this.demWorkerSources[mapId];
937			this.globalStates.delete(mapId);
938		});
939		this.actor.registerMessageHandler("SR", async (_mapId, params) => {
940			this.referrer = params;
941		});
942		this.actor.registerMessageHandler("SRPS", (mapId, params) => {
943			return this._syncRTLPluginState(mapId, params);
944		});
945		this.actor.registerMessageHandler("IS", async (_mapId, params) => {
946			await loadScript(params);
947		});
948		this.actor.registerMessageHandler("SI", (mapId, params) => {
949			return this._setImages(mapId, params);
950		});
951		this.actor.registerMessageHandler("UL", async (mapId, params) => {
952			this._getLayerIndex(mapId).update(params.layers, params.removedIds, this._getGlobalState(mapId));
953		});
954		this.actor.registerMessageHandler("UGS", async (mapId, params) => {
955			const globalState = this._getGlobalState(mapId);
956			for (const key in params) globalState[key] = params[key];
957		});
958		this.actor.registerMessageHandler("SL", async (mapId, params) => {
959			this._getLayerIndex(mapId).replace(params, this._getGlobalState(mapId));
960		});
961	}
962	_getGlobalState(mapId) {
963		let state = this.globalStates.get(mapId);
964		if (!state) {
965			state = {};
966			this.globalStates.set(mapId, state);
967		}
968		return state;
969	}
970	async _setImages(mapId, images) {
971		this.availableImages[mapId] = images;
972		for (const workerSource in this.workerSources[mapId]) {
973			const ws = this.workerSources[mapId][workerSource];
974			for (const source in ws) ws[source].availableImages = images;
975		}
976	}
977	async _syncRTLPluginState(mapId, incomingState) {
978		return await rtlWorkerPlugin.syncState(incomingState, loadScript);
979	}
980	_getAvailableImages(mapId) {
981		let availableImages = this.availableImages[mapId];
982		availableImages ||= [];
983		return availableImages;
984	}
985	_getLayerIndex(mapId) {
986		let layerIndexes = this.layerIndexes[mapId];
987		layerIndexes ||= this.layerIndexes[mapId] = new StyleLayerIndex();
988		return layerIndexes;
989	}
990	/**
991	* This is basically a lazy initialization of a worker per mapId and sourceType and sourceName
992	* @param mapId - the mapId
993	* @param sourceType - the source type - 'vector' for example
994	* @param sourceName - the source name - 'osm' for example
995	* @returns a new instance or a cached one
996	*/
997	_getWorkerSource(mapId, sourceType, sourceName) {
998		this.workerSources[mapId] ||= {};
999		this.workerSources[mapId][sourceType] ||= {};
1000		if (!this.workerSources[mapId][sourceType][sourceName]) {
1001			const actor = { sendAsync: (message, abortController) => {
1002				message.targetMapId = mapId;
1003				return this.actor.sendAsync(message, abortController);
1004			} };
1005			switch (sourceType) {
1006				case "vector":
1007					this.workerSources[mapId][sourceType][sourceName] = new VectorTileWorkerSource(actor, this._getLayerIndex(mapId), this._getAvailableImages(mapId));
1008					break;
1009				case "geojson":
1010					this.workerSources[mapId][sourceType][sourceName] = new GeoJSONWorkerSource(actor, this._getLayerIndex(mapId), this._getAvailableImages(mapId));
1011					break;
1012				default: this.workerSources[mapId][sourceType][sourceName] = new this.externalWorkerSourceTypes[sourceType](actor, this._getLayerIndex(mapId), this._getAvailableImages(mapId));
1013			}
1014		}
1015		return this.workerSources[mapId][sourceType][sourceName];
1016	}
1017	/**
1018	* This is basically a lazy initialization of a worker per mapId and source
1019	* @param mapId - the mapId
1020	* @param sourceType - the source type - 'raster-dem' for example
1021	* @returns a new instance or a cached one
1022	*/
1023	_getDEMWorkerSource(mapId, sourceType) {
1024		this.demWorkerSources[mapId] ||= {};
1025		this.demWorkerSources[mapId][sourceType] ||= new RasterDEMTileWorkerSource();
1026		return this.demWorkerSources[mapId][sourceType];
1027	}
1028};
1029if (isWorker(self)) self.worker = new Worker(self);
1030//#endregion
1031export { Worker as default };
1032
1033//# sourceMappingURL=maplibre-gl-worker-dev.mjs.map

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.