import {
ExtraSamplesValues,
arrayFields,
fieldTagNames,
fieldTypeNames,
fieldTypes,
geoKeyNames,
globals_exports,
photometricInterpretations
} from "./chunk-QTABLK4X.js";
import "./chunk-C5KGH6RQ.js";
import {
ImageCanvas_default,
fromResolutionLike
} from "./chunk-3TN6D4MD.js";
import {
ATTRIBUTION,
OSM_default
} from "./chunk-43GYE2V5.js";
import {
Vector_default,
loadFeaturesXhr
} from "./chunk-PD2E5XZ4.js";
import {
Image_default as Image_default2,
orthographic,
scale as scale3,
translate,
translation
} from "./chunk-E7S7Q7VV.js";
import "./chunk-V7WRBSQ6.js";
import "./chunk-W7BDJOQY.js";
import "./chunk-7JXPN73Q.js";
import {
Feature_default
} from "./chunk-E53S5GN6.js";
import {
DataTile_default,
LRUCache_default,
Tile_default as Tile_default2,
asArrayLike,
asImageLike,
toArray
} from "./chunk-UNDFRJ2M.js";
import "./chunk-JFXZSSOM.js";
import "./chunk-ZUI5NXIU.js";
import {
TileQueue_default
} from "./chunk-CAVOO5JW.js";
import "./chunk-M5TTSD4C.js";
import "./chunk-RW3V7S4F.js";
import "./chunk-I6K7MRGV.js";
import "./chunk-PGWX4545.js";
import "./chunk-AYBYZSAV.js";
import {
ViewHint_default
} from "./chunk-YLJGUH5Z.js";
import {
Point_default
} from "./chunk-AZGMK675.js";
import {
TileEventType_default,
TileGrid_default,
TileImage_default,
TileSourceEvent,
Tile_default as Tile_default3,
UrlTile_default,
XYZ_default,
appendParams,
createFromTemplates,
createFromTileUrlFunctions,
createXYZ,
expandUrl,
extentFromProjection,
getForProjection,
nullTileUrlFunction,
pickUrl,
renderXYZTemplate
} from "./chunk-3ZDRPUXW.js";
import {
Source_default
} from "./chunk-6Y7C6NBJ.js";
import {
ERROR_THRESHOLD,
ImageTile_default,
Tile_default,
Triangulation_default,
calculateSourceExtentResolution,
calculateSourceResolution,
createOrUpdate2 as createOrUpdate,
getCacheKey,
getKeyZXY,
hash,
render
} from "./chunk-7XMWB3J4.js";
import {
TileState_default
} from "./chunk-5D2XPBR2.js";
import {
ImageState_default,
Image_default,
decode,
scale as scale2,
toSize
} from "./chunk-SHUBVYN4.js";
import {
DEFAULT_MAX_ZOOM,
DEFAULT_TILE_SIZE
} from "./chunk-FM44FOIC.js";
import "./chunk-LMC3RO5P.js";
import {
apply,
create,
makeInverse,
multiply
} from "./chunk-X52LGBOS.js";
import {
assert
} from "./chunk-QFCIXVZ3.js";
import {
Projection_default,
add,
compareVersions,
createTransformFromCoordinateTransform,
equivalent,
error,
fromCode,
get,
getTransformFromProjections,
scale,
toLonLat,
toUserCoordinate,
toUserExtent,
transform,
transformExtent
} from "./chunk-A3RXLHYB.js";
import "./chunk-ZLPTRF2L.js";
import {
ceil,
clamp,
floor,
modulo,
round
} from "./chunk-54BTDBAD.js";
import {
createCanvasContext2D,
releaseCanvas
} from "./chunk-UPTVWZ45.js";
import {
WORKER_OFFSCREEN_CANVAS
} from "./chunk-5XHD7RSF.js";
import {
getUid
} from "./chunk-Q5ZULJHM.js";
import {
Disposable_default,
Event_default,
listen,
listenOnce,
unlistenByKey
} from "./chunk-NGFXCWUF.js";
import {
EventType_default,
linearFindNearest,
toPromise
} from "./chunk-K25ZO44T.js";
import {
applyTransform,
buffer,
containsExtent,
createEmpty,
createOrUpdateFromCoordinate,
equals,
extend,
getArea,
getBottomLeft,
getCenter,
getForViewAndSize,
getHeight,
getIntersection,
getTopLeft,
getTopRight,
getWidth,
intersects,
isEmpty as isEmpty2,
scaleFromCenter,
wrapAndSliceX
} from "./chunk-SRXHWJOY.js";
import {
isEmpty
} from "./chunk-5RHQVMYD.js";
import {
__commonJS,
__toESM
} from "./chunk-DC5AMYBS.js";
// node_modules/xml-utils/get-attribute.js
var require_get_attribute = __commonJS({
"node_modules/xml-utils/get-attribute.js"(exports, module) {
function getAttribute2(tag, attributeName, options) {
const debug = options && options.debug || false;
if (debug) console.log("[xml-utils] getting " + attributeName + " in " + tag);
const xml = typeof tag === "object" ? tag.outer : tag;
const opening = xml.slice(0, xml.indexOf(">") + 1);
const quotechars = ['"', "'"];
for (let i = 0; i < quotechars.length; i++) {
const char = quotechars[i];
const pattern = attributeName + "\\=" + char + "([^" + char + "]*)" + char;
if (debug) console.log("[xml-utils] pattern:", pattern);
const re = new RegExp(pattern);
const match = re.exec(opening);
if (debug) console.log("[xml-utils] match:", match);
if (match) return match[1];
}
}
module.exports = getAttribute2;
module.exports.default = getAttribute2;
}
});
// node_modules/xml-utils/index-of-match.js
var require_index_of_match = __commonJS({
"node_modules/xml-utils/index-of-match.js"(exports, module) {
function indexOfMatch(xml, pattern, startIndex) {
const re = new RegExp(pattern);
const match = re.exec(xml.slice(startIndex));
if (match) return startIndex + match.index;
else return -1;
}
module.exports = indexOfMatch;
module.exports.default = indexOfMatch;
}
});
// node_modules/xml-utils/index-of-match-end.js
var require_index_of_match_end = __commonJS({
"node_modules/xml-utils/index-of-match-end.js"(exports, module) {
function indexOfMatchEnd(xml, pattern, startIndex) {
const re = new RegExp(pattern);
const match = re.exec(xml.slice(startIndex));
if (match) return startIndex + match.index + match[0].length - 1;
else return -1;
}
module.exports = indexOfMatchEnd;
module.exports.default = indexOfMatchEnd;
}
});
// node_modules/xml-utils/count-substring.js
var require_count_substring = __commonJS({
"node_modules/xml-utils/count-substring.js"(exports, module) {
function countSubstring(string, substring) {
const pattern = new RegExp(substring, "g");
const match = string.match(pattern);
return match ? match.length : 0;
}
module.exports = countSubstring;
module.exports.default = countSubstring;
}
});
// node_modules/xml-utils/find-tag-by-name.js
var require_find_tag_by_name = __commonJS({
"node_modules/xml-utils/find-tag-by-name.js"(exports, module) {
var indexOfMatch = require_index_of_match();
var indexOfMatchEnd = require_index_of_match_end();
var countSubstring = require_count_substring();
function findTagByName(xml, tagName, options) {
const debug = options && options.debug || false;
const nested = !(options && typeof options.nested === false);
const startIndex = options && options.startIndex || 0;
if (debug) console.log("[xml-utils] starting findTagByName with", tagName, " and ", options);
const start = indexOfMatch(xml, `<${tagName}[
>/]`, startIndex);
if (debug) console.log("[xml-utils] start:", start);
if (start === -1) return void 0;
const afterStart = xml.slice(start + tagName.length);
let relativeEnd = indexOfMatchEnd(afterStart, "^[^<]*[ /]>", 0);
const selfClosing = relativeEnd !== -1 && afterStart[relativeEnd - 1] === "/";
if (debug) console.log("[xml-utils] selfClosing:", selfClosing);
if (selfClosing === false) {
if (nested) {
let startIndex2 = 0;
let openings = 1;
let closings = 0;
while ((relativeEnd = indexOfMatchEnd(afterStart, "[ /]" + tagName + ">", startIndex2)) !== -1) {
const clip = afterStart.substring(startIndex2, relativeEnd + 1);
openings += countSubstring(clip, "<" + tagName + "[ \n >]");
closings += countSubstring(clip, "" + tagName + ">");
if (closings >= openings) break;
startIndex2 = relativeEnd;
}
} else {
relativeEnd = indexOfMatchEnd(afterStart, "[ /]" + tagName + ">", 0);
}
}
const end = start + tagName.length + relativeEnd + 1;
if (debug) console.log("[xml-utils] end:", end);
if (end === -1) return void 0;
const outer = xml.slice(start, end);
let inner;
if (selfClosing) {
inner = null;
} else {
inner = outer.slice(outer.indexOf(">") + 1, outer.lastIndexOf("<"));
}
return { inner, outer, start, end };
}
module.exports = findTagByName;
module.exports.default = findTagByName;
}
});
// node_modules/xml-utils/find-tags-by-name.js
var require_find_tags_by_name = __commonJS({
"node_modules/xml-utils/find-tags-by-name.js"(exports, module) {
var findTagByName = require_find_tag_by_name();
function findTagsByName2(xml, tagName, options) {
const tags = [];
const debug = options && options.debug || false;
const nested = options && typeof options.nested === "boolean" ? options.nested : true;
let startIndex = options && options.startIndex || 0;
let tag;
while (tag = findTagByName(xml, tagName, { debug, startIndex })) {
if (nested) {
startIndex = tag.start + 1 + tagName.length;
} else {
startIndex = tag.end;
}
tags.push(tag);
}
if (debug) console.log("findTagsByName found", tags.length, "tags");
return tags;
}
module.exports = findTagsByName2;
module.exports.default = findTagsByName2;
}
});
// browser-external:http
var require_http = __commonJS({
"browser-external:http"(exports, module) {
module.exports = Object.create(new Proxy({}, {
get(_, key) {
if (key !== "__esModule" && key !== "__proto__" && key !== "constructor" && key !== "splice") {
console.warn(`Module "http" has been externalized for browser compatibility. Cannot access "http.${key}" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.`);
}
}
}));
}
});
// browser-external:https
var require_https = __commonJS({
"browser-external:https"(exports, module) {
module.exports = Object.create(new Proxy({}, {
get(_, key) {
if (key !== "__esModule" && key !== "__proto__" && key !== "constructor" && key !== "splice") {
console.warn(`Module "https" has been externalized for browser compatibility. Cannot access "https.${key}" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.`);
}
}
}));
}
});
// browser-external:url
var require_url = __commonJS({
"browser-external:url"(exports, module) {
module.exports = Object.create(new Proxy({}, {
get(_, key) {
if (key !== "__esModule" && key !== "__proto__" && key !== "constructor" && key !== "splice") {
console.warn(`Module "url" has been externalized for browser compatibility. Cannot access "url.${key}" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.`);
}
}
}));
}
});
// browser-external:fs
var require_fs = __commonJS({
"browser-external:fs"(exports, module) {
module.exports = Object.create(new Proxy({}, {
get(_, key) {
if (key !== "__esModule" && key !== "__proto__" && key !== "constructor" && key !== "splice") {
console.warn(`Module "fs" has been externalized for browser compatibility. Cannot access "fs.${key}" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.`);
}
}
}));
}
});
// node_modules/ol/source/BingMaps.js
function quadKey(tileCoord) {
const z = tileCoord[0];
const digits = new Array(z);
let mask = 1 << z - 1;
let i, charCode;
for (i = 0; i < z; ++i) {
charCode = 48;
if (tileCoord[1] & mask) {
charCode += 1;
}
if (tileCoord[2] & mask) {
charCode += 2;
}
digits[i] = String.fromCharCode(charCode);
mask >>= 1;
}
return digits.join("");
}
var TOS_ATTRIBUTION = 'Terms of Use';
var BingMaps = class extends TileImage_default {
/**
* @param {Options} options Bing Maps options.
*/
constructor(options) {
const hidpi = options.hidpi !== void 0 ? options.hidpi : false;
super({
cacheSize: options.cacheSize,
crossOrigin: "anonymous",
interpolate: options.interpolate,
projection: get("EPSG:3857"),
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
state: "loading",
tileLoadFunction: options.tileLoadFunction,
tilePixelRatio: hidpi ? 2 : 1,
wrapX: options.wrapX !== void 0 ? options.wrapX : true,
transition: options.transition,
zDirection: options.zDirection
});
this.hidpi_ = hidpi;
this.culture_ = options.culture !== void 0 ? options.culture : "en-us";
this.maxZoom_ = options.maxZoom !== void 0 ? options.maxZoom : -1;
this.apiKey_ = options.key;
this.imagerySet_ = options.imagerySet;
this.placeholderTiles_ = options.placeholderTiles;
const url = (options.url || "https://dev.virtualearth.net/REST/v1/Imagery/Metadata/") + this.imagerySet_ + "?uriScheme=https&include=ImageryProviders&key=" + this.apiKey_ + "&c=" + this.culture_;
fetch(url).then((response) => response.json()).then((json) => this.handleImageryMetadataResponse(json));
}
/**
* Get the api key used for this source.
*
* @return {string} The api key.
* @api
*/
getApiKey() {
return this.apiKey_;
}
/**
* Get the imagery set associated with this source.
*
* @return {string} The imagery set.
* @api
*/
getImagerySet() {
return this.imagerySet_;
}
/**
* @param {BingMapsImageryMetadataResponse} response Response.
*/
handleImageryMetadataResponse(response) {
if (response.statusCode != 200 || response.statusDescription != "OK" || response.authenticationResultCode != "ValidCredentials" || response.resourceSets.length != 1 || response.resourceSets[0].resources.length != 1) {
this.setState("error");
return;
}
const resource = response.resourceSets[0].resources[0];
const maxZoom2 = this.maxZoom_ == -1 ? resource.zoomMax : this.maxZoom_;
const sourceProjection = this.getProjection();
const extent = extentFromProjection(sourceProjection);
const scale4 = this.hidpi_ ? 2 : 1;
const tileSize = resource.imageWidth == resource.imageHeight ? resource.imageWidth / scale4 : [resource.imageWidth / scale4, resource.imageHeight / scale4];
const tileGrid = createXYZ({
extent,
minZoom: resource.zoomMin,
maxZoom: maxZoom2,
tileSize
});
this.tileGrid = tileGrid;
const culture = this.culture_;
const hidpi = this.hidpi_;
const placeholderTiles = this.placeholderTiles_;
this.tileUrlFunction = createFromTileUrlFunctions(
resource.imageUrlSubdomains.map(function(subdomain) {
const quadKeyTileCoord = [0, 0, 0];
const imageUrl = resource.imageUrl.replace("{subdomain}", subdomain).replace("{culture}", culture);
return (
/**
* @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {string|undefined} Tile URL.
*/
(function(tileCoord, pixelRatio, projection) {
if (!tileCoord) {
return void 0;
}
createOrUpdate(
tileCoord[0],
tileCoord[1],
tileCoord[2],
quadKeyTileCoord
);
const url = new URL(
imageUrl.replace("{quadkey}", quadKey(quadKeyTileCoord))
);
const params = url.searchParams;
if (hidpi) {
params.set("dpi", "d1");
params.set("device", "mobile");
}
if (placeholderTiles === true) {
params.delete("n");
} else if (placeholderTiles === false) {
params.set("n", "z");
}
return url.toString();
})
);
})
);
if (resource.imageryProviders) {
const transform2 = getTransformFromProjections(
get("EPSG:4326"),
this.getProjection()
);
this.setAttributions((frameState) => {
const attributions = [];
const viewState = frameState.viewState;
const tileGrid2 = this.getTileGrid();
const z = tileGrid2.getZForResolution(
viewState.resolution,
this.zDirection
);
const tileCoord = tileGrid2.getTileCoordForCoordAndZ(
viewState.center,
z
);
const zoom = tileCoord[0];
resource.imageryProviders.map(function(imageryProvider) {
let intersecting = false;
const coverageAreas = imageryProvider.coverageAreas;
for (let i = 0, ii = coverageAreas.length; i < ii; ++i) {
const coverageArea = coverageAreas[i];
if (zoom >= coverageArea.zoomMin && zoom <= coverageArea.zoomMax) {
const bbox = coverageArea.bbox;
const epsg4326Extent = [bbox[1], bbox[0], bbox[3], bbox[2]];
const extent2 = applyTransform(epsg4326Extent, transform2);
if (intersects(extent2, frameState.extent)) {
intersecting = true;
break;
}
}
}
if (intersecting) {
attributions.push(imageryProvider.attribution);
}
});
attributions.push(TOS_ATTRIBUTION);
return attributions;
});
}
this.setState("ready");
}
};
var BingMaps_default = BingMaps;
// node_modules/ol/source/CartoDB.js
var CartoDB = class extends XYZ_default {
/**
* @param {Options} options CartoDB options.
*/
constructor(options) {
super({
attributions: options.attributions,
cacheSize: options.cacheSize,
crossOrigin: options.crossOrigin,
maxZoom: options.maxZoom !== void 0 ? options.maxZoom : 18,
minZoom: options.minZoom,
projection: options.projection,
transition: options.transition,
wrapX: options.wrapX,
zDirection: options.zDirection
});
this.account_ = options.account;
this.mapId_ = options.map || "";
this.config_ = options.config || {};
this.templateCache_ = {};
this.initializeMap_();
}
/**
* Returns the current config.
* @return {!Object} The current configuration.
* @api
*/
getConfig() {
return this.config_;
}
/**
* Updates the carto db config.
* @param {Object} config a key-value lookup. Values will replace current values
* in the config.
* @api
*/
updateConfig(config) {
Object.assign(this.config_, config);
this.initializeMap_();
}
/**
* Sets the CartoDB config
* @param {Object} config In the case of anonymous maps, a CartoDB configuration
* object.
* If using named maps, a key-value lookup with the template parameters.
* @api
*/
setConfig(config) {
this.config_ = config || {};
this.initializeMap_();
}
/**
* Issue a request to initialize the CartoDB map.
* @private
*/
initializeMap_() {
const paramHash = JSON.stringify(this.config_);
if (this.templateCache_[paramHash]) {
this.applyTemplate_(this.templateCache_[paramHash]);
return;
}
let mapUrl = "https://" + this.account_ + ".carto.com/api/v1/map";
if (this.mapId_) {
mapUrl += "/named/" + this.mapId_;
}
const client = new XMLHttpRequest();
client.addEventListener(
"load",
this.handleInitResponse_.bind(this, paramHash)
);
client.addEventListener("error", this.handleInitError_.bind(this));
client.open("POST", mapUrl);
client.setRequestHeader("Content-type", "application/json");
client.send(JSON.stringify(this.config_));
}
/**
* Handle map initialization response.
* @param {string} paramHash a hash representing the parameter set that was used
* for the request
* @param {Event} event Event.
* @private
*/
handleInitResponse_(paramHash, event) {
const client = (
/** @type {XMLHttpRequest} */
event.target
);
if (!client.status || client.status >= 200 && client.status < 300) {
let response;
try {
response = /** @type {CartoDBLayerInfo} */
JSON.parse(client.responseText);
} catch {
this.setState("error");
return;
}
this.applyTemplate_(response);
this.templateCache_[paramHash] = response;
this.setState("ready");
} else {
this.setState("error");
}
}
/**
* @private
* @param {Event} event Event.
*/
handleInitError_(event) {
this.setState("error");
}
/**
* Apply the new tile urls returned by carto db
* @param {CartoDBLayerInfo} data Result of carto db call.
* @private
*/
applyTemplate_(data) {
const tilesUrl = "https://" + data.cdn_url.https + "/" + this.account_ + "/api/v1/map/" + data.layergroupid + "/{z}/{x}/{y}.png";
this.setUrl(tilesUrl);
}
};
var CartoDB_default = CartoDB;
// node_modules/ol/source/Cluster.js
var Cluster = class extends Vector_default {
/**
* @param {Options} [options] Cluster options.
*/
constructor(options) {
options = options || {};
super({
attributions: options.attributions,
wrapX: options.wrapX
});
this.resolution = void 0;
this.distance = options.distance !== void 0 ? options.distance : 20;
this.minDistance = options.minDistance || 0;
this.interpolationRatio = 0;
this.features = [];
this.geometryFunction = options.geometryFunction || function(feature) {
const geometry = (
/** @type {Point} */
feature.getGeometry()
);
assert(
!geometry || geometry.getType() === "Point",
"The default `geometryFunction` can only handle `Point` or null geometries"
);
return geometry;
};
this.createCustomCluster_ = options.createCluster;
this.source = null;
this.boundRefresh_ = this.refresh.bind(this);
this.updateDistance(this.distance, this.minDistance);
this.setSource(options.source || null);
}
/**
* Remove all features from the source.
* @param {boolean} [fast] Skip dispatching of {@link module:ol/source/VectorEventType~VectorEventType#removefeature} events.
* @api
* @override
*/
clear(fast) {
this.features.length = 0;
super.clear(fast);
}
/**
* Get the distance in pixels between clusters.
* @return {number} Distance.
* @api
*/
getDistance() {
return this.distance;
}
/**
* Get a reference to the wrapped source.
* @return {VectorSource|null} Source.
* @api
*/
getSource() {
return this.source;
}
/**
* @param {import("../extent.js").Extent} extent Extent.
* @param {number} resolution Resolution.
* @param {import("../proj/Projection.js").default} projection Projection.
* @override
*/
loadFeatures(extent, resolution, projection) {
var _a;
(_a = this.source) == null ? void 0 : _a.loadFeatures(extent, resolution, projection);
if (resolution !== this.resolution) {
this.resolution = resolution;
this.refresh();
}
}
/**
* Set the distance within which features will be clusterd together.
* @param {number} distance The distance in pixels.
* @api
*/
setDistance(distance) {
this.updateDistance(distance, this.minDistance);
}
/**
* Set the minimum distance between clusters. Will be capped at the
* configured distance.
* @param {number} minDistance The minimum distance in pixels.
* @api
*/
setMinDistance(minDistance) {
this.updateDistance(this.distance, minDistance);
}
/**
* The configured minimum distance between clusters.
* @return {number} The minimum distance in pixels.
* @api
*/
getMinDistance() {
return this.minDistance;
}
/**
* Replace the wrapped source.
* @param {VectorSource|null} source The new source for this instance.
* @api
*/
setSource(source) {
if (this.source) {
this.source.removeEventListener(EventType_default.CHANGE, this.boundRefresh_);
}
this.source = source;
if (source) {
source.addEventListener(EventType_default.CHANGE, this.boundRefresh_);
}
this.refresh();
}
/**
* Handle the source changing.
* @override
*/
refresh() {
this.clear();
this.cluster();
this.addFeatures(this.features);
}
/**
* Update the distances and refresh the source if necessary.
* @param {number} distance The new distance.
* @param {number} minDistance The new minimum distance.
*/
updateDistance(distance, minDistance) {
const ratio = distance === 0 ? 0 : Math.min(minDistance, distance) / distance;
const changed = distance !== this.distance || this.interpolationRatio !== ratio;
this.distance = distance;
this.minDistance = minDistance;
this.interpolationRatio = ratio;
if (changed) {
this.refresh();
}
}
/**
* @protected
*/
cluster() {
if (this.resolution === void 0 || !this.source) {
return;
}
const extent = createEmpty();
const mapDistance = this.distance * this.resolution;
const features = this.source.getFeatures();
const clustered = {};
for (let i = 0, ii = features.length; i < ii; i++) {
const feature = features[i];
if (!(getUid(feature) in clustered)) {
const geometry = this.geometryFunction(feature);
if (geometry) {
const coordinates = geometry.getCoordinates();
createOrUpdateFromCoordinate(coordinates, extent);
buffer(extent, mapDistance, extent);
const neighbors = this.source.getFeaturesInExtent(extent).filter(function(neighbor) {
const uid = getUid(neighbor);
if (uid in clustered) {
return false;
}
clustered[uid] = true;
return true;
});
this.features.push(this.createCluster(neighbors, extent));
}
}
}
}
/**
* @param {Array} features Features
* @param {import("../extent.js").Extent} extent The searched extent for these features.
* @return {Feature} The cluster feature.
* @protected
*/
createCluster(features, extent) {
const centroid = [0, 0];
for (let i = features.length - 1; i >= 0; --i) {
const geometry2 = this.geometryFunction(features[i]);
if (geometry2) {
add(centroid, geometry2.getCoordinates());
} else {
features.splice(i, 1);
}
}
scale(centroid, 1 / features.length);
const searchCenter = getCenter(extent);
const ratio = this.interpolationRatio;
const geometry = new Point_default([
centroid[0] * (1 - ratio) + searchCenter[0] * ratio,
centroid[1] * (1 - ratio) + searchCenter[1] * ratio
]);
if (this.createCustomCluster_) {
return this.createCustomCluster_(geometry, features);
}
return new Feature_default({
geometry,
features
});
}
};
var Cluster_default = Cluster;
// node_modules/ol/webgl/Canvas.js
var VERTEX_SHADER = `
attribute vec4 a_position;
attribute vec4 a_texcoord;
uniform mat4 u_matrix;
uniform mat4 u_textureMatrix;
varying vec2 v_texcoord;
void main() {
gl_Position = u_matrix * a_position;
vec2 texcoord = (u_textureMatrix * a_texcoord).xy;
v_texcoord = texcoord;
}
`;
var FRAGMENT_SHADER = `
precision mediump float;
varying vec2 v_texcoord;
uniform sampler2D u_texture;
void main() {
if (
v_texcoord.x < 0.0 ||
v_texcoord.y < 0.0 ||
v_texcoord.x > 1.0 ||
v_texcoord.y > 1.0
) {
discard;
}
gl_FragColor = texture2D(u_texture, v_texcoord);
}
`;
var Canvas = class {
/**
* @param {WebGLRenderingContext} gl Context to render in.
*/
constructor(gl) {
this.gl_ = gl;
this.program_ = createProgram(gl, FRAGMENT_SHADER, VERTEX_SHADER);
this.positionLocation = gl.getAttribLocation(this.program_, "a_position");
this.texcoordLocation = gl.getAttribLocation(this.program_, "a_texcoord");
this.matrixLocation = gl.getUniformLocation(this.program_, "u_matrix");
this.textureMatrixLocation = gl.getUniformLocation(
this.program_,
"u_textureMatrix"
);
this.textureLocation = gl.getUniformLocation(this.program_, "u_texture");
this.positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);
this.positions = [0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1];
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array(this.positions),
gl.STATIC_DRAW
);
this.texcoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffer);
this.texcoords = [0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1];
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array(this.texcoords),
gl.STATIC_DRAW
);
}
/**
* 2dContext drawImage call implemented in webgl.
* Unlike images, textures do not have a width and height associated
* with them so we'll pass in the width and height of the texture.
*
* @param {WebGLTexture} tex Image to draw.
* @param {number} texWidth Image width.
* @param {number} texHeight Image height.
* @param {number} srcX Top-left x-point to read src image.
* @param {number} srcY Top-left y-point to read src image.
* @param {number} [srcWidth] Width of source to read.
* @param {number} [srcHeight] Height of source to read.
* @param {number} [dstX] Top-left x-point of destination.
* @param {number} [dstY] Top-left y-point of destination.
* @param {number} [dstWidth] Width of written image in destination.
* @param {number} [dstHeight] Height of written image in destination.
* @param {number} [width] Width of canvas.
* @param {number} [height] Height of canvas.
*/
drawImage(tex, texWidth, texHeight, srcX, srcY, srcWidth, srcHeight, dstX, dstY, dstWidth, dstHeight, width, height) {
const gl = this.gl_;
if (dstX === void 0) {
dstX = srcX;
}
if (dstY === void 0) {
dstY = srcY;
}
if (srcWidth === void 0) {
srcWidth = texWidth;
}
if (srcHeight === void 0) {
srcHeight = texHeight;
}
if (dstWidth === void 0) {
dstWidth = srcWidth;
}
if (dstHeight === void 0) {
dstHeight = srcHeight;
}
if (width === void 0) {
width = gl.canvas.width;
}
if (height === void 0) {
height = gl.canvas.height;
}
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.useProgram(this.program_);
gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);
gl.enableVertexAttribArray(this.positionLocation);
gl.vertexAttribPointer(this.positionLocation, 2, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffer);
gl.enableVertexAttribArray(this.texcoordLocation);
gl.vertexAttribPointer(this.texcoordLocation, 2, gl.FLOAT, false, 0, 0);
let matrix = orthographic(0, width, 0, height, -1, 1);
matrix = translate(matrix, dstX, dstY, 0);
matrix = scale3(matrix, dstWidth, dstHeight, 1);
gl.uniformMatrix4fv(this.matrixLocation, false, matrix);
let texMatrix = translation(srcX / texWidth, srcY / texHeight, 0);
texMatrix = scale3(
texMatrix,
srcWidth / texWidth,
srcHeight / texHeight,
1
);
gl.uniformMatrix4fv(this.textureMatrixLocation, false, texMatrix);
gl.uniform1i(this.textureLocation, 0);
gl.drawArrays(gl.TRIANGLES, 0, this.positions.length / 2);
}
};
function createShader(gl, type, source) {
const shader = gl.createShader(type);
if (shader === null) {
throw new Error("Shader compilation failed");
}
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
const log = gl.getShaderInfoLog(shader);
if (log === null) {
throw new Error("Shader info log creation failed");
}
throw new Error(log);
}
return shader;
}
function createProgram(gl, fragmentSource, vertexSource) {
const program = gl.createProgram();
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentSource);
if (program === null) {
throw new Error("Program creation failed");
}
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
const log = gl.getProgramInfoLog(program);
if (log === null) {
throw new Error("Program info log creation failed");
}
throw new Error();
}
return program;
}
// node_modules/ol/reproj/glreproj.js
var EDGE_VERTEX_SHADER = `
attribute vec4 a_position;
uniform mat4 u_matrix;
void main() {
gl_Position = u_matrix * a_position;
}
`;
var EDGE_FRAGMENT_SHADER = `
precision mediump float;
uniform vec4 u_val;
void main() {
gl_FragColor = u_val;
}
`;
var TRIANGLE_VERTEX_SHADER = `
attribute vec4 a_position;
attribute vec2 a_texcoord;
varying vec2 v_texcoord;
uniform mat4 u_matrix;
void main() {
gl_Position = u_matrix * a_position;
v_texcoord = a_texcoord;
}
`;
var TRIANGLE_FRAGMENT_SHADER = `
precision mediump float;
varying vec2 v_texcoord;
uniform sampler2D u_texture;
void main() {
if (v_texcoord.x < 0.0 || v_texcoord.x > 1.0 || v_texcoord.y < 0.0 || v_texcoord.y > 1.0) {
discard;
}
gl_FragColor = texture2D(u_texture, v_texcoord);
}
`;
function createCanvasContextWebGL(width, height, canvasPool2, settings) {
let canvas;
if (canvasPool2 && canvasPool2.length) {
canvas = /** @type {HTMLCanvasElement} */
canvasPool2.shift();
} else if (WORKER_OFFSCREEN_CANVAS) {
canvas = new OffscreenCanvas(width || 300, height || 300);
} else {
canvas = document.createElement("canvas");
}
if (width) {
canvas.width = width;
}
if (height) {
canvas.height = height;
}
return (
/** @type {WebGLRenderingContext} */
canvas.getContext("webgl", settings)
);
}
function releaseGLCanvas(gl) {
const canvas = gl.canvas;
canvas.width = 1;
canvas.height = 1;
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
}
var canvasGLPool = [];
function render2(gl, width_, height_, pixelRatio, sourceResolution, targetResolution, targetExtent, triangulation, sources, gutter, dataType, renderEdges, interpolate, drawSingle) {
const width = Math.round(pixelRatio * width_);
const height = Math.round(pixelRatio * height_);
gl.canvas.width = width;
gl.canvas.height = height;
let resultFrameBuffer;
let resultTexture;
{
resultTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, resultTexture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
if (interpolate) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
} else {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
}
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA,
width,
height,
0,
gl.RGBA,
dataType,
null
);
resultFrameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, resultFrameBuffer);
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D,
resultTexture,
0
);
}
if (resultFrameBuffer === null) {
throw new Error("Could not create framebuffer");
}
if (resultTexture === null) {
throw new Error("Could not create texture");
}
if (sources.length === 0) {
return {
width,
height,
framebuffer: resultFrameBuffer,
texture: resultTexture
};
}
const sourceDataExtent = createEmpty();
sources.forEach(function(src, i, arr) {
extend(sourceDataExtent, src.extent);
});
let stitchTexture;
let stitchWidth;
let stitchHeight;
const stitchScale = 1 / sourceResolution;
if (!drawSingle || sources.length !== 1 || gutter !== 0) {
stitchTexture = gl.createTexture();
if (resultTexture === null) {
throw new Error("Could not create texture");
}
stitchWidth = Math.round(getWidth(sourceDataExtent) * stitchScale);
stitchHeight = Math.round(getHeight(sourceDataExtent) * stitchScale);
const maxTexSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
const largeSide = Math.max(stitchWidth, stitchHeight);
const scaleFactor = largeSide > maxTexSize ? maxTexSize / largeSide : 1;
const stitchWidthFixed = Math.round(stitchWidth * scaleFactor);
const stitchHeightFixed = Math.round(stitchHeight * scaleFactor);
gl.bindTexture(gl.TEXTURE_2D, stitchTexture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
if (interpolate) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
} else {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
}
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA,
stitchWidthFixed,
stitchHeightFixed,
0,
gl.RGBA,
dataType,
null
);
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D,
stitchTexture,
0
);
const webGLCanvas = new Canvas(gl);
sources.forEach(function(src, i, arr) {
const xPos = (src.extent[0] - sourceDataExtent[0]) * stitchScale * scaleFactor;
const yPos = -(src.extent[3] - sourceDataExtent[3]) * stitchScale * scaleFactor;
const srcWidth = getWidth(src.extent) * stitchScale * scaleFactor;
const srcHeight = getHeight(src.extent) * stitchScale * scaleFactor;
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.viewport(0, 0, stitchWidthFixed, stitchHeightFixed);
if (src.clipExtent) {
const xPos2 = (src.clipExtent[0] - sourceDataExtent[0]) * stitchScale * scaleFactor;
const yPos2 = -(src.clipExtent[3] - sourceDataExtent[3]) * stitchScale * scaleFactor;
const width2 = getWidth(src.clipExtent) * stitchScale * scaleFactor;
const height2 = getHeight(src.clipExtent) * stitchScale * scaleFactor;
gl.enable(gl.SCISSOR_TEST);
gl.scissor(
interpolate ? xPos2 : Math.round(xPos2),
interpolate ? yPos2 : Math.round(yPos2),
interpolate ? width2 : Math.round(xPos2 + width2) - Math.round(xPos2),
interpolate ? height2 : Math.round(yPos2 + height2) - Math.round(yPos2)
);
}
webGLCanvas.drawImage(
src.texture,
src.width,
src.height,
gutter,
gutter,
src.width - 2 * gutter,
src.height - 2 * gutter,
interpolate ? xPos : Math.round(xPos),
interpolate ? yPos : Math.round(yPos),
interpolate ? srcWidth : Math.round(xPos + srcWidth) - Math.round(xPos),
interpolate ? srcHeight : Math.round(yPos + srcHeight) - Math.round(yPos),
stitchWidthFixed,
stitchHeightFixed
);
gl.disable(gl.SCISSOR_TEST);
});
gl.deleteFramebuffer(fb);
} else {
stitchTexture = sources[0].texture;
stitchWidth = sources[0].width;
stitchHeight = sources[0].width;
}
const targetTopLeft = getTopLeft(targetExtent);
const sourceTopLeft = getTopLeft(sourceDataExtent);
const getUVs = (target) => {
const u0 = (target[0][0] - targetTopLeft[0]) / targetResolution * pixelRatio;
const v0 = -(target[0][1] - targetTopLeft[1]) / targetResolution * pixelRatio;
const u1 = (target[1][0] - targetTopLeft[0]) / targetResolution * pixelRatio;
const v1 = -(target[1][1] - targetTopLeft[1]) / targetResolution * pixelRatio;
const u2 = (target[2][0] - targetTopLeft[0]) / targetResolution * pixelRatio;
const v2 = -(target[2][1] - targetTopLeft[1]) / targetResolution * pixelRatio;
return { u1, v1, u0, v0, u2, v2 };
};
gl.bindFramebuffer(gl.FRAMEBUFFER, resultFrameBuffer);
gl.viewport(0, 0, width, height);
{
const vertices = [];
const texcoords = [];
const triProgram = createProgram(
gl,
TRIANGLE_FRAGMENT_SHADER,
TRIANGLE_VERTEX_SHADER
);
gl.useProgram(triProgram);
const textureLocation = gl.getUniformLocation(triProgram, "u_texture");
gl.bindTexture(gl.TEXTURE_2D, stitchTexture);
gl.uniform1i(textureLocation, 0);
triangulation.getTriangles().forEach(function(triangle, i, arr) {
const source = triangle.source;
const target = triangle.target;
const { u1, v1, u0, v0, u2, v2 } = getUVs(target);
const su0 = (source[0][0] - sourceTopLeft[0]) / sourceResolution / stitchWidth;
const sv0 = -(source[0][1] - sourceTopLeft[1]) / sourceResolution / stitchHeight;
const su1 = (source[1][0] - sourceTopLeft[0]) / sourceResolution / stitchWidth;
const sv1 = -(source[1][1] - sourceTopLeft[1]) / sourceResolution / stitchHeight;
const su2 = (source[2][0] - sourceTopLeft[0]) / sourceResolution / stitchWidth;
const sv2 = -(source[2][1] - sourceTopLeft[1]) / sourceResolution / stitchHeight;
vertices.push(u1, v1, u0, v0, u2, v2);
texcoords.push(su1, sv1, su0, sv0, su2, sv2);
});
const matrix = orthographic(0, width, height, 0, -1, 1);
const matrixLocation = gl.getUniformLocation(triProgram, "u_matrix");
gl.uniformMatrix4fv(matrixLocation, false, matrix);
const positionLocation = gl.getAttribLocation(triProgram, "a_position");
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLocation);
const texcoordLocation = gl.getAttribLocation(triProgram, "a_texcoord");
const texcoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texcoords), gl.STATIC_DRAW);
gl.vertexAttribPointer(texcoordLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(texcoordLocation);
gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 2);
}
if (renderEdges) {
const edgeProgram = createProgram(
gl,
EDGE_FRAGMENT_SHADER,
EDGE_VERTEX_SHADER
);
gl.useProgram(edgeProgram);
const matrix = orthographic(0, width, height, 0, -1, 1);
const matrixLocation = gl.getUniformLocation(edgeProgram, "u_matrix");
gl.uniformMatrix4fv(matrixLocation, false, matrix);
const burnval = Array.isArray(renderEdges) ? renderEdges : [0, 0, 0, 255];
const burnvalLocation = gl.getUniformLocation(edgeProgram, "u_val");
const isFloat = true;
if (isFloat) {
gl.uniform4fv(burnvalLocation, burnval);
} else {
gl.uniform4iv(burnvalLocation, burnval);
}
const positionLocation = gl.getAttribLocation(edgeProgram, "a_position");
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLocation);
const lines = triangulation.getTriangles().reduce(function(lines2, triangle) {
const target = triangle.target;
const { u1, v1, u0, v0, u2, v2 } = getUVs(target);
return lines2.concat([u1, v1, u0, v0, u0, v0, u2, v2, u2, v2, u1, v1]);
}, []);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(lines), gl.STATIC_DRAW);
gl.drawArrays(gl.LINES, 0, lines.length / 2);
}
return {
width,
height,
framebuffer: resultFrameBuffer,
texture: resultTexture
};
}
// node_modules/ol/reproj/DataTile.js
var ReprojDataTile = class extends DataTile_default {
/**
* @param {Options} options Tile options.
*/
constructor(options) {
super({
tileCoord: options.tileCoord,
loader: () => Promise.resolve(new Uint8ClampedArray(4)),
interpolate: options.interpolate,
transition: options.transition
});
this.renderEdges_ = options.renderEdges !== void 0 ? options.renderEdges : false;
this.pixelRatio_ = options.pixelRatio;
this.gutter_ = options.gutter;
this.reprojData_ = null;
this.reprojError_ = null;
this.reprojSize_ = void 0;
this.sourceTileGrid_ = options.sourceTileGrid;
this.targetTileGrid_ = options.targetTileGrid;
this.wrappedTileCoord_ = options.wrappedTileCoord || options.tileCoord;
this.sourceTiles_ = [];
this.sourcesListenerKeys_ = null;
this.sourceZ_ = 0;
const sourceProj = options.sourceProj;
const sourceProjExtent = sourceProj.getExtent();
const sourceTileGridExtent = options.sourceTileGrid.getExtent();
this.clipExtent_ = sourceProj.canWrapX() ? sourceTileGridExtent ? getIntersection(sourceProjExtent, sourceTileGridExtent) : sourceProjExtent : sourceTileGridExtent;
const targetExtent = this.targetTileGrid_.getTileCoordExtent(
this.wrappedTileCoord_
);
const maxTargetExtent = this.targetTileGrid_.getExtent();
let maxSourceExtent = this.sourceTileGrid_.getExtent();
const limitedTargetExtent = maxTargetExtent ? getIntersection(targetExtent, maxTargetExtent) : targetExtent;
if (getArea(limitedTargetExtent) === 0) {
this.state = TileState_default.EMPTY;
return;
}
if (sourceProjExtent) {
if (!maxSourceExtent) {
maxSourceExtent = sourceProjExtent;
} else {
maxSourceExtent = getIntersection(maxSourceExtent, sourceProjExtent);
}
}
const targetResolution = this.targetTileGrid_.getResolution(
this.wrappedTileCoord_[0]
);
const targetProj = options.targetProj;
const sourceResolution = calculateSourceExtentResolution(
sourceProj,
targetProj,
limitedTargetExtent,
targetResolution
);
if (!isFinite(sourceResolution) || sourceResolution <= 0) {
this.state = TileState_default.EMPTY;
return;
}
const errorThresholdInPixels = options.errorThreshold !== void 0 ? options.errorThreshold : ERROR_THRESHOLD;
this.triangulation_ = new Triangulation_default(
sourceProj,
targetProj,
limitedTargetExtent,
maxSourceExtent,
sourceResolution * errorThresholdInPixels,
targetResolution,
options.transformMatrix
);
if (this.triangulation_.getTriangles().length === 0) {
this.state = TileState_default.EMPTY;
return;
}
this.sourceZ_ = this.sourceTileGrid_.getZForResolution(sourceResolution);
let sourceExtent = this.triangulation_.calculateSourceExtent();
if (maxSourceExtent) {
if (sourceProj.canWrapX()) {
sourceExtent[1] = clamp(
sourceExtent[1],
maxSourceExtent[1],
maxSourceExtent[3]
);
sourceExtent[3] = clamp(
sourceExtent[3],
maxSourceExtent[1],
maxSourceExtent[3]
);
} else {
sourceExtent = getIntersection(sourceExtent, maxSourceExtent);
}
}
if (!getArea(sourceExtent)) {
this.state = TileState_default.EMPTY;
} else {
let worldWidth = 0;
let worldsAway = 0;
if (sourceProj.canWrapX()) {
worldWidth = getWidth(sourceProjExtent);
worldsAway = Math.floor(
(sourceExtent[0] - sourceProjExtent[0]) / worldWidth
);
}
const sourceExtents = wrapAndSliceX(
sourceExtent.slice(),
sourceProj,
true
);
sourceExtents.forEach((extent) => {
const sourceRange = this.sourceTileGrid_.getTileRangeForExtentAndZ(
extent,
this.sourceZ_
);
const getTile = options.getTileFunction;
for (let srcX = sourceRange.minX; srcX <= sourceRange.maxX; srcX++) {
for (let srcY = sourceRange.minY; srcY <= sourceRange.maxY; srcY++) {
const tile = getTile(this.sourceZ_, srcX, srcY, this.pixelRatio_);
if (tile) {
const offset = worldsAway * worldWidth;
this.sourceTiles_.push({ tile, offset });
}
}
}
++worldsAway;
});
if (this.sourceTiles_.length === 0) {
this.state = TileState_default.EMPTY;
}
}
}
/**
* Get the tile size.
* @return {import('../size.js').Size} Tile size.
* @override
*/
getSize() {
return this.reprojSize_;
}
/**
* Get the data for the tile.
* @return {import("../DataTile.js").Data} Tile data.
* @override
*/
getData() {
return this.reprojData_;
}
/**
* Get any loading error.
* @return {Error} Loading error.
* @override
*/
getError() {
return this.reprojError_;
}
/**
* @private
*/
reproject_() {
const dataSources = [];
let imageLike = false;
this.sourceTiles_.forEach((source) => {
var _a;
const tile = source.tile;
if (!tile || tile.getState() !== TileState_default.LOADED) {
return;
}
const size2 = tile.getSize();
const gutter = this.gutter_;
let tileData;
const arrayData = asArrayLike(tile.getData());
if (arrayData) {
tileData = arrayData;
} else {
imageLike = true;
tileData = toArray(asImageLike(tile.getData()));
}
const pixelSize = [size2[0] + 2 * gutter, size2[1] + 2 * gutter];
const isFloat = tileData instanceof Float32Array;
const pixelCount = pixelSize[0] * pixelSize[1];
const DataType = isFloat ? Float32Array : Uint8ClampedArray;
const tileDataR = new DataType(
/** @type {ArrayBuffer} */
tileData.buffer
);
const bytesPerElement = DataType.BYTES_PER_ELEMENT;
const bytesPerPixel = bytesPerElement * tileDataR.length / pixelCount;
const bytesPerRow = tileDataR.byteLength / pixelSize[1];
const bandCount2 = Math.floor(
bytesPerRow / bytesPerElement / pixelSize[0]
);
const extent = this.sourceTileGrid_.getTileCoordExtent(tile.tileCoord);
extent[0] += source.offset;
extent[2] += source.offset;
const clipExtent = (_a = this.clipExtent_) == null ? void 0 : _a.slice();
if (clipExtent) {
clipExtent[0] += source.offset;
clipExtent[2] += source.offset;
}
dataSources.push({
extent,
clipExtent,
data: tileDataR,
dataType: DataType,
bytesPerPixel,
pixelSize,
bandCount: bandCount2
});
});
this.sourceTiles_.length = 0;
if (dataSources.length === 0) {
this.state = TileState_default.ERROR;
this.changed();
return;
}
const z = this.wrappedTileCoord_[0];
const size = this.targetTileGrid_.getTileSize(z);
const targetWidth = typeof size === "number" ? size : size[0];
const targetHeight = typeof size === "number" ? size : size[1];
const outWidth = Math.round(targetWidth * this.pixelRatio_);
const outHeight = Math.round(targetHeight * this.pixelRatio_);
const targetResolution = this.targetTileGrid_.getResolution(z);
const sourceResolution = this.sourceTileGrid_.getResolution(this.sourceZ_);
const targetExtent = this.targetTileGrid_.getTileCoordExtent(
this.wrappedTileCoord_
);
const bandCount = dataSources[0].bandCount;
const dataR = new dataSources[0].dataType(bandCount * outWidth * outHeight);
const gl = createCanvasContextWebGL(outWidth, outHeight, canvasGLPool, {
premultipliedAlpha: false,
antialias: false
});
let willInterpolate;
const format = gl.RGBA;
let textureType;
if (dataSources[0].dataType == Float32Array) {
textureType = gl.FLOAT;
gl.getExtension("WEBGL_color_buffer_float");
gl.getExtension("OES_texture_float");
gl.getExtension("EXT_float_blend");
const extension = gl.getExtension("OES_texture_float_linear");
const canInterpolate = extension !== null;
willInterpolate = canInterpolate && this.interpolate;
} else {
textureType = gl.UNSIGNED_BYTE;
willInterpolate = this.interpolate;
}
const BANDS_PR_REPROJ = 4;
const reprojs = Math.ceil(bandCount / BANDS_PR_REPROJ);
for (let reproj = reprojs - 1; reproj >= 0; --reproj) {
const sources = [];
for (let i = 0, len = dataSources.length; i < len; ++i) {
const dataSource = dataSources[i];
const pixelSize = dataSource.pixelSize;
const width2 = pixelSize[0];
const height2 = pixelSize[1];
const data2 = new dataSource.dataType(BANDS_PR_REPROJ * width2 * height2);
const dataS = dataSource.data;
let offset2 = reproj * BANDS_PR_REPROJ;
for (let j = 0, len2 = data2.length; j < len2; j += BANDS_PR_REPROJ) {
data2[j] = dataS[offset2];
data2[j + 1] = dataS[offset2 + 1];
data2[j + 2] = dataS[offset2 + 2];
data2[j + 3] = dataS[offset2 + 3];
offset2 += bandCount;
}
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
if (willInterpolate) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
} else {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
}
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(
gl.TEXTURE_2D,
0,
format,
width2,
height2,
0,
format,
textureType,
data2
);
sources.push({
extent: dataSource.extent,
clipExtent: dataSource.clipExtent,
texture,
width: width2,
height: height2
});
}
const { framebuffer, width, height } = render2(
gl,
targetWidth,
targetHeight,
this.pixelRatio_,
sourceResolution,
targetResolution,
targetExtent,
this.triangulation_,
sources,
this.gutter_,
textureType,
this.renderEdges_,
willInterpolate
);
const rows = width;
const cols = height * BANDS_PR_REPROJ;
const data = new dataSources[0].dataType(rows * cols);
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.readPixels(0, 0, width, height, gl.RGBA, textureType, data);
let offset = reproj * BANDS_PR_REPROJ;
for (let i = 0, len = data.length; i < len; i += BANDS_PR_REPROJ) {
const flipY = (rows - 1 - (i / cols | 0)) * cols + i % cols;
dataR[offset] = data[flipY];
dataR[offset + 1] = data[flipY + 1];
dataR[offset + 2] = data[flipY + 2];
dataR[offset + 3] = data[flipY + 3];
offset += bandCount;
}
}
releaseGLCanvas(gl);
canvasGLPool.push(gl.canvas);
if (imageLike) {
const context = createCanvasContext2D(targetWidth, targetHeight);
const imageData = new ImageData(dataR, targetWidth);
context.putImageData(imageData, 0, 0);
this.reprojData_ = context.canvas;
} else {
this.reprojData_ = dataR;
}
this.reprojSize_ = [outWidth, outHeight];
this.state = TileState_default.LOADED;
this.changed();
}
/**
* Load not yet loaded URI.
* @override
*/
load() {
if (this.state !== TileState_default.IDLE && this.state !== TileState_default.ERROR) {
return;
}
this.state = TileState_default.LOADING;
this.changed();
let leftToLoad = 0;
this.sourcesListenerKeys_ = [];
this.sourceTiles_.forEach(({ tile }) => {
const state = tile.getState();
if (state !== TileState_default.IDLE && state !== TileState_default.LOADING) {
return;
}
leftToLoad++;
const sourceListenKey = listen(tile, EventType_default.CHANGE, () => {
const state2 = tile.getState();
if (state2 == TileState_default.LOADED || state2 == TileState_default.ERROR || state2 == TileState_default.EMPTY) {
unlistenByKey(sourceListenKey);
leftToLoad--;
if (leftToLoad === 0) {
this.unlistenSources_();
this.reproject_();
}
}
});
this.sourcesListenerKeys_.push(sourceListenKey);
});
if (leftToLoad === 0) {
setTimeout(this.reproject_.bind(this), 0);
} else {
this.sourceTiles_.forEach(function({ tile }) {
const state = tile.getState();
if (state == TileState_default.IDLE) {
tile.load();
}
});
}
}
/**
* @private
*/
unlistenSources_() {
this.sourcesListenerKeys_.forEach(unlistenByKey);
this.sourcesListenerKeys_ = null;
}
};
var DataTile_default2 = ReprojDataTile;
// node_modules/ol/source/DataTile.js
var DataTileSource = class extends Tile_default3 {
/**
* @param {Options} options DataTile source options.
*/
constructor(options) {
const projection = options.projection === void 0 ? "EPSG:3857" : options.projection;
let tileGrid = options.tileGrid;
if (tileGrid === void 0 && projection) {
tileGrid = createXYZ({
extent: extentFromProjection(projection),
maxResolution: options.maxResolution,
maxZoom: options.maxZoom,
minZoom: options.minZoom,
tileSize: options.tileSize
});
}
super({
cacheSize: 0.1,
// don't cache on the source
attributions: options.attributions,
attributionsCollapsible: options.attributionsCollapsible,
projection,
tileGrid,
state: options.state,
wrapX: options.wrapX,
transition: options.transition,
interpolate: options.interpolate,
key: options.key,
zDirection: options.zDirection
});
this.gutter_ = options.gutter !== void 0 ? options.gutter : 0;
this.tileSize_ = options.tileSize ? toSize(options.tileSize) : null;
this.tileSizes_ = null;
this.tileLoadingKeys_ = {};
this.loader_ = options.loader;
this.handleTileChange_ = this.handleTileChange_.bind(this);
this.bandCount = options.bandCount === void 0 ? 4 : options.bandCount;
this.tileGridForProjection_ = {};
this.crossOrigin_ = options.crossOrigin || "anonymous";
this.transformMatrix = null;
}
/**
* Set the source tile sizes. The length of the array is expected to match the number of
* levels in the tile grid.
* @protected
* @param {Array} tileSizes An array of tile sizes.
*/
setTileSizes(tileSizes) {
this.tileSizes_ = tileSizes;
}
/**
* Get the source tile size at the given zoom level. This may be different than the rendered tile
* size.
* @protected
* @param {number} z Tile zoom level.
* @return {import('../size.js').Size} The source tile size.
*/
getTileSize(z) {
if (this.tileSizes_) {
return this.tileSizes_[z];
}
if (this.tileSize_) {
return this.tileSize_;
}
const tileGrid = this.getTileGrid();
return tileGrid ? toSize(tileGrid.getTileSize(z)) : [256, 256];
}
/**
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {number} Gutter.
* @override
*/
getGutterForProjection(projection) {
const thisProj = this.getProjection();
if ((!thisProj || equivalent(thisProj, projection)) && !this.transformMatrix) {
return this.gutter_;
}
return 0;
}
/**
* @param {Loader} loader The data loader.
* @protected
*/
setLoader(loader) {
this.loader_ = loader;
}
/**
* @param {number} z Tile coordinate z.
* @param {number} x Tile coordinate x.
* @param {number} y Tile coordinate y.
* @param {import("../proj/Projection.js").default} targetProj The output projection.
* @param {import("../proj/Projection.js").default} sourceProj The input projection.
* @param {import("../structs/LRUCache.js").default} [tileCache] Tile cache.
* @return {!TileType} Tile.
*/
getReprojTile_(z, x, y, targetProj, sourceProj, tileCache) {
const sourceTileGrid = this.tileGrid || this.getTileGridForProjection(sourceProj || targetProj);
const reprojTilePixelRatio = Math.max.apply(
null,
sourceTileGrid.getResolutions().map((r, z2) => {
const tileSize = toSize(sourceTileGrid.getTileSize(z2));
const textureSize = this.getTileSize(z2);
return Math.max(
textureSize[0] / tileSize[0],
textureSize[1] / tileSize[1]
);
})
);
const targetTileGrid = this.getTileGridForProjection(targetProj);
const tileCoord = [z, x, y];
const wrappedTileCoord = this.getTileCoordForTileUrlFunction(
tileCoord,
targetProj
);
const options = Object.assign(
{
sourceProj: sourceProj || targetProj,
sourceTileGrid,
targetProj,
targetTileGrid,
tileCoord,
wrappedTileCoord,
pixelRatio: reprojTilePixelRatio,
gutter: this.gutter_,
getTileFunction: (z2, x2, y2, pixelRatio) => this.getTile(z2, x2, y2, pixelRatio, void 0, tileCache),
transformMatrix: this.transformMatrix
},
/** @type {import("../reproj/DataTile.js").Options} */
this.tileOptions
);
const tile = (
/** @type {TileType} */
/** @type {*} */
new DataTile_default2(options)
);
tile.key = this.getKey();
return tile;
}
/**
* @param {number} z Tile coordinate z.
* @param {number} x Tile coordinate x.
* @param {number} y Tile coordinate y.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} [projection] Projection.
* @param {import("../structs/LRUCache.js").default} [tileCache] Tile cache.
* @return {TileType|null} Tile (or null if outside source extent).
* @override
*/
getTile(z, x, y, pixelRatio, projection, tileCache) {
var _a;
const sourceProjection = this.getProjection();
if (projection && (sourceProjection && !equivalent(sourceProjection, projection) || this.transformMatrix)) {
return this.getReprojTile_(
z,
x,
y,
projection,
sourceProjection,
tileCache
);
}
const size = this.getTileSize(z);
const sourceLoader = this.loader_;
const controller = new AbortController();
const loaderOptions = {
signal: controller.signal,
crossOrigin: this.crossOrigin_
};
const tileCoord = this.getTileCoordForTileUrlFunction([z, x, y]);
if (!tileCoord) {
return null;
}
const key = this.getKey();
const cacheKey = getCacheKey(this, key, z, x, y);
if (tileCache && tileCache.containsKey(cacheKey)) {
return (
/** @type {TileType} */
tileCache.get(cacheKey)
);
}
const requestZ = tileCoord[0];
const requestX = tileCoord[1];
const requestY = tileCoord[2];
const range = (_a = this.getTileGrid()) == null ? void 0 : _a.getFullTileRange(requestZ);
if (range) {
loaderOptions.maxY = range.getHeight() - 1;
}
function loader() {
return toPromise(function() {
return sourceLoader(requestZ, requestX, requestY, loaderOptions);
});
}
const options = Object.assign(
{
tileCoord: [z, x, y],
loader,
size,
controller
},
this.tileOptions
);
const tile = (
/** @type {TileType} */
/** @type {*} */
new DataTile_default(options)
);
tile.key = this.getKey();
tile.addEventListener(EventType_default.CHANGE, this.handleTileChange_);
tileCache == null ? void 0 : tileCache.set(cacheKey, tile);
return tile;
}
/**
* Handle tile change events.
* @param {import("../events/Event.js").default} event Event.
*/
handleTileChange_(event) {
const tile = (
/** @type {import("../Tile.js").default} */
event.target
);
const uid = getUid(tile);
const tileState = tile.getState();
let type;
if (tileState == TileState_default.LOADING) {
this.tileLoadingKeys_[uid] = true;
type = TileEventType_default.TILELOADSTART;
} else if (uid in this.tileLoadingKeys_) {
delete this.tileLoadingKeys_[uid];
type = tileState == TileState_default.ERROR ? TileEventType_default.TILELOADERROR : tileState == TileState_default.LOADED ? TileEventType_default.TILELOADEND : void 0;
}
if (type) {
this.dispatchEvent(new TileSourceEvent(type, tile));
}
}
/**
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {!import("../tilegrid/TileGrid.js").default} Tile grid.
* @override
*/
getTileGridForProjection(projection) {
const thisProj = this.getProjection();
if (this.tileGrid && (!thisProj || equivalent(thisProj, projection)) && !this.transformMatrix) {
return this.tileGrid;
}
const projKey = getUid(projection);
if (!(projKey in this.tileGridForProjection_)) {
this.tileGridForProjection_[projKey] = getForProjection(projection);
}
return this.tileGridForProjection_[projKey];
}
/**
* Sets the tile grid to use when reprojecting the tiles to the given
* projection instead of the default tile grid for the projection.
*
* This can be useful when the default tile grid cannot be created
* (e.g. projection has no extent defined) or
* for optimization reasons (custom tile size, resolutions, ...).
*
* @param {import("../proj.js").ProjectionLike} projection Projection.
* @param {import("../tilegrid/TileGrid.js").default} tilegrid Tile grid to use for the projection.
* @api
*/
setTileGridForProjection(projection, tilegrid) {
const proj = get(projection);
if (proj) {
const projKey = getUid(proj);
if (!(projKey in this.tileGridForProjection_)) {
this.tileGridForProjection_[projKey] = tilegrid;
}
}
}
};
var DataTile_default3 = DataTileSource;
// node_modules/@petamoriken/float16/src/_util/messages.mjs
var THIS_IS_NOT_AN_OBJECT = "This is not an object";
var THIS_IS_NOT_A_FLOAT16ARRAY_OBJECT = "This is not a Float16Array object";
var THIS_CONSTRUCTOR_IS_NOT_A_SUBCLASS_OF_FLOAT16ARRAY = "This constructor is not a subclass of Float16Array";
var THE_CONSTRUCTOR_PROPERTY_VALUE_IS_NOT_AN_OBJECT = "The constructor property value is not an object";
var SPECIES_CONSTRUCTOR_DIDNT_RETURN_TYPEDARRAY_OBJECT = "Species constructor didn't return TypedArray object";
var DERIVED_CONSTRUCTOR_CREATED_TYPEDARRAY_OBJECT_WHICH_WAS_TOO_SMALL_LENGTH = "Derived constructor created TypedArray object which was too small length";
var ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER = "Attempting to access detached ArrayBuffer";
var CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT = "Cannot convert undefined or null to object";
var CANNOT_MIX_BIGINT_AND_OTHER_TYPES = "Cannot mix BigInt and other types, use explicit conversions";
var ITERATOR_PROPERTY_IS_NOT_CALLABLE = "@@iterator property is not callable";
var REDUCE_OF_EMPTY_ARRAY_WITH_NO_INITIAL_VALUE = "Reduce of empty array with no initial value";
var THE_COMPARISON_FUNCTION_MUST_BE_EITHER_A_FUNCTION_OR_UNDEFINED = "The comparison function must be either a function or undefined";
var OFFSET_IS_OUT_OF_BOUNDS = "Offset is out of bounds";
// node_modules/@petamoriken/float16/src/_util/primordials.mjs
function uncurryThis(target) {
return (thisArg, ...args) => {
return ReflectApply(target, thisArg, args);
};
}
function uncurryThisGetter(target, key) {
return uncurryThis(
ReflectGetOwnPropertyDescriptor(
target,
key
).get
);
}
var {
apply: ReflectApply,
construct: ReflectConstruct,
defineProperty: ReflectDefineProperty,
get: ReflectGet,
getOwnPropertyDescriptor: ReflectGetOwnPropertyDescriptor,
getPrototypeOf: ReflectGetPrototypeOf,
has: ReflectHas,
ownKeys: ReflectOwnKeys,
set: ReflectSet,
setPrototypeOf: ReflectSetPrototypeOf
} = Reflect;
var NativeProxy = Proxy;
var {
EPSILON,
MAX_SAFE_INTEGER,
isFinite: NumberIsFinite,
isNaN: NumberIsNaN
} = Number;
var {
iterator: SymbolIterator,
species: SymbolSpecies,
toStringTag: SymbolToStringTag,
for: SymbolFor
} = Symbol;
var NativeObject = Object;
var {
create: ObjectCreate,
defineProperty: ObjectDefineProperty,
freeze: ObjectFreeze,
is: ObjectIs
} = NativeObject;
var ObjectPrototype = NativeObject.prototype;
var ObjectPrototype__lookupGetter__ = (
/** @type {any} */
ObjectPrototype.__lookupGetter__ ? uncurryThis(
/** @type {any} */
ObjectPrototype.__lookupGetter__
) : (object, key) => {
if (object == null) {
throw NativeTypeError(
CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT
);
}
let target = NativeObject(object);
do {
const descriptor = ReflectGetOwnPropertyDescriptor(target, key);
if (descriptor !== void 0) {
if (ObjectHasOwn(descriptor, "get")) {
return descriptor.get;
}
return;
}
} while ((target = ReflectGetPrototypeOf(target)) !== null);
}
);
var ObjectHasOwn = (
/** @type {any} */
NativeObject.hasOwn || uncurryThis(ObjectPrototype.hasOwnProperty)
);
var NativeArray = Array;
var ArrayIsArray = NativeArray.isArray;
var ArrayPrototype = NativeArray.prototype;
var ArrayPrototypeJoin = uncurryThis(ArrayPrototype.join);
var ArrayPrototypePush = uncurryThis(ArrayPrototype.push);
var ArrayPrototypeToLocaleString = uncurryThis(
ArrayPrototype.toLocaleString
);
var NativeArrayPrototypeSymbolIterator = ArrayPrototype[SymbolIterator];
var ArrayPrototypeSymbolIterator = uncurryThis(NativeArrayPrototypeSymbolIterator);
var {
abs: MathAbs,
trunc: MathTrunc
} = Math;
var NativeArrayBuffer = ArrayBuffer;
var ArrayBufferIsView = NativeArrayBuffer.isView;
var ArrayBufferPrototype = NativeArrayBuffer.prototype;
var ArrayBufferPrototypeSlice = uncurryThis(ArrayBufferPrototype.slice);
var ArrayBufferPrototypeGetByteLength = uncurryThisGetter(ArrayBufferPrototype, "byteLength");
var NativeSharedArrayBuffer = typeof SharedArrayBuffer !== "undefined" ? SharedArrayBuffer : null;
var SharedArrayBufferPrototypeGetByteLength = NativeSharedArrayBuffer && uncurryThisGetter(NativeSharedArrayBuffer.prototype, "byteLength");
var TypedArray = ReflectGetPrototypeOf(Uint8Array);
var TypedArrayFrom = TypedArray.from;
var TypedArrayPrototype = TypedArray.prototype;
var NativeTypedArrayPrototypeSymbolIterator = TypedArrayPrototype[SymbolIterator];
var TypedArrayPrototypeKeys = uncurryThis(TypedArrayPrototype.keys);
var TypedArrayPrototypeValues = uncurryThis(
TypedArrayPrototype.values
);
var TypedArrayPrototypeEntries = uncurryThis(
TypedArrayPrototype.entries
);
var TypedArrayPrototypeSet = uncurryThis(TypedArrayPrototype.set);
var TypedArrayPrototypeReverse = uncurryThis(
TypedArrayPrototype.reverse
);
var TypedArrayPrototypeFill = uncurryThis(TypedArrayPrototype.fill);
var TypedArrayPrototypeCopyWithin = uncurryThis(
TypedArrayPrototype.copyWithin
);
var TypedArrayPrototypeSort = uncurryThis(TypedArrayPrototype.sort);
var TypedArrayPrototypeSlice = uncurryThis(TypedArrayPrototype.slice);
var TypedArrayPrototypeSubarray = uncurryThis(
TypedArrayPrototype.subarray
);
var TypedArrayPrototypeGetBuffer = uncurryThisGetter(
TypedArrayPrototype,
"buffer"
);
var TypedArrayPrototypeGetByteOffset = uncurryThisGetter(
TypedArrayPrototype,
"byteOffset"
);
var TypedArrayPrototypeGetLength = uncurryThisGetter(
TypedArrayPrototype,
"length"
);
var TypedArrayPrototypeGetSymbolToStringTag = uncurryThisGetter(
TypedArrayPrototype,
SymbolToStringTag
);
var NativeUint8Array = Uint8Array;
var NativeUint16Array = Uint16Array;
var Uint16ArrayFrom = (...args) => {
return ReflectApply(TypedArrayFrom, NativeUint16Array, args);
};
var NativeUint32Array = Uint32Array;
var NativeFloat32Array = Float32Array;
var ArrayIteratorPrototype = ReflectGetPrototypeOf([][SymbolIterator]());
var ArrayIteratorPrototypeNext = uncurryThis(ArrayIteratorPrototype.next);
var GeneratorPrototypeNext = uncurryThis((function* () {
})().next);
var IteratorPrototype = ReflectGetPrototypeOf(ArrayIteratorPrototype);
var DataViewPrototype = DataView.prototype;
var DataViewPrototypeGetUint16 = uncurryThis(
DataViewPrototype.getUint16
);
var DataViewPrototypeSetUint16 = uncurryThis(
DataViewPrototype.setUint16
);
var NativeTypeError = TypeError;
var NativeRangeError = RangeError;
var NativeWeakSet = WeakSet;
var WeakSetPrototype = NativeWeakSet.prototype;
var WeakSetPrototypeAdd = uncurryThis(WeakSetPrototype.add);
var WeakSetPrototypeHas = uncurryThis(WeakSetPrototype.has);
var NativeWeakMap = WeakMap;
var WeakMapPrototype = NativeWeakMap.prototype;
var WeakMapPrototypeGet = uncurryThis(WeakMapPrototype.get);
var WeakMapPrototypeHas = uncurryThis(WeakMapPrototype.has);
var WeakMapPrototypeSet = uncurryThis(WeakMapPrototype.set);
// node_modules/@petamoriken/float16/src/_util/arrayIterator.mjs
var arrayIterators = new NativeWeakMap();
var SafeIteratorPrototype = ObjectCreate(null, {
next: {
value: function next() {
const arrayIterator = WeakMapPrototypeGet(arrayIterators, this);
return ArrayIteratorPrototypeNext(arrayIterator);
}
},
[SymbolIterator]: {
value: function values() {
return this;
}
}
});
function safeIfNeeded(array) {
if (array[SymbolIterator] === NativeArrayPrototypeSymbolIterator && ArrayIteratorPrototype.next === ArrayIteratorPrototypeNext) {
return array;
}
const safe = ObjectCreate(SafeIteratorPrototype);
WeakMapPrototypeSet(arrayIterators, safe, ArrayPrototypeSymbolIterator(array));
return safe;
}
var generators = new NativeWeakMap();
var DummyArrayIteratorPrototype = ObjectCreate(IteratorPrototype, {
next: {
value: function next2() {
const generator = WeakMapPrototypeGet(generators, this);
return GeneratorPrototypeNext(generator);
},
writable: true,
configurable: true
}
});
for (const key of ReflectOwnKeys(ArrayIteratorPrototype)) {
if (key === "next") {
continue;
}
ObjectDefineProperty(DummyArrayIteratorPrototype, key, ReflectGetOwnPropertyDescriptor(ArrayIteratorPrototype, key));
}
function wrap(generator) {
const dummy = ObjectCreate(DummyArrayIteratorPrototype);
WeakMapPrototypeSet(generators, dummy, generator);
return dummy;
}
// node_modules/@petamoriken/float16/src/_util/is.mjs
function isObject(value) {
return value !== null && typeof value === "object" || typeof value === "function";
}
function isObjectLike(value) {
return value !== null && typeof value === "object";
}
function isNativeTypedArray(value) {
return TypedArrayPrototypeGetSymbolToStringTag(value) !== void 0;
}
function isNativeBigIntTypedArray(value) {
const typedArrayName = TypedArrayPrototypeGetSymbolToStringTag(value);
return typedArrayName === "BigInt64Array" || typedArrayName === "BigUint64Array";
}
function isArrayBuffer(value) {
try {
if (ArrayIsArray(value)) {
return false;
}
ArrayBufferPrototypeGetByteLength(
/** @type {any} */
value
);
return true;
} catch (e) {
return false;
}
}
function isSharedArrayBuffer(value) {
if (NativeSharedArrayBuffer === null) {
return false;
}
try {
SharedArrayBufferPrototypeGetByteLength(
/** @type {any} */
value
);
return true;
} catch (e) {
return false;
}
}
function isAnyArrayBuffer(value) {
return isArrayBuffer(value) || isSharedArrayBuffer(value);
}
function isOrdinaryArray(value) {
if (!ArrayIsArray(value)) {
return false;
}
return value[SymbolIterator] === NativeArrayPrototypeSymbolIterator && ArrayIteratorPrototype.next === ArrayIteratorPrototypeNext;
}
function isOrdinaryNativeTypedArray(value) {
if (!isNativeTypedArray(value)) {
return false;
}
return value[SymbolIterator] === NativeTypedArrayPrototypeSymbolIterator && ArrayIteratorPrototype.next === ArrayIteratorPrototypeNext;
}
function isCanonicalIntegerIndexString(value) {
if (typeof value !== "string") {
return false;
}
const number = +value;
if (value !== number + "") {
return false;
}
if (!NumberIsFinite(number)) {
return false;
}
return number === MathTrunc(number);
}
// node_modules/@petamoriken/float16/src/_util/brand.mjs
var brand = SymbolFor("__Float16Array__");
function hasFloat16ArrayBrand(target) {
if (!isObjectLike(target)) {
return false;
}
const prototype = ReflectGetPrototypeOf(target);
if (!isObjectLike(prototype)) {
return false;
}
const constructor = prototype.constructor;
if (constructor === void 0) {
return false;
}
if (!isObject(constructor)) {
throw NativeTypeError(THE_CONSTRUCTOR_PROPERTY_VALUE_IS_NOT_AN_OBJECT);
}
return ReflectHas(constructor, brand);
}
// node_modules/@petamoriken/float16/src/_util/converter.mjs
var INVERSE_OF_EPSILON = 1 / EPSILON;
function roundTiesToEven(num) {
return num + INVERSE_OF_EPSILON - INVERSE_OF_EPSILON;
}
var FLOAT16_MIN_VALUE = 6103515625e-14;
var FLOAT16_MAX_VALUE = 65504;
var FLOAT16_EPSILON = 9765625e-10;
var FLOAT16_EPSILON_MULTIPLIED_BY_FLOAT16_MIN_VALUE = FLOAT16_EPSILON * FLOAT16_MIN_VALUE;
var FLOAT16_EPSILON_DEVIDED_BY_EPSILON = FLOAT16_EPSILON * INVERSE_OF_EPSILON;
function roundToFloat16(num) {
const number = +num;
if (!NumberIsFinite(number) || number === 0) {
return number;
}
const sign = number > 0 ? 1 : -1;
const absolute = MathAbs(number);
if (absolute < FLOAT16_MIN_VALUE) {
return sign * roundTiesToEven(absolute / FLOAT16_EPSILON_MULTIPLIED_BY_FLOAT16_MIN_VALUE) * FLOAT16_EPSILON_MULTIPLIED_BY_FLOAT16_MIN_VALUE;
}
const temp = (1 + FLOAT16_EPSILON_DEVIDED_BY_EPSILON) * absolute;
const result = temp - (temp - absolute);
if (result > FLOAT16_MAX_VALUE || NumberIsNaN(result)) {
return sign * Infinity;
}
return sign * result;
}
var buffer2 = new NativeArrayBuffer(4);
var floatView = new NativeFloat32Array(buffer2);
var uint32View = new NativeUint32Array(buffer2);
var baseTable = new NativeUint16Array(512);
var shiftTable = new NativeUint8Array(512);
for (let i = 0; i < 256; ++i) {
const e = i - 127;
if (e < -24) {
baseTable[i] = 0;
baseTable[i | 256] = 32768;
shiftTable[i] = 24;
shiftTable[i | 256] = 24;
} else if (e < -14) {
baseTable[i] = 1024 >> -e - 14;
baseTable[i | 256] = 1024 >> -e - 14 | 32768;
shiftTable[i] = -e - 1;
shiftTable[i | 256] = -e - 1;
} else if (e <= 15) {
baseTable[i] = e + 15 << 10;
baseTable[i | 256] = e + 15 << 10 | 32768;
shiftTable[i] = 13;
shiftTable[i | 256] = 13;
} else if (e < 128) {
baseTable[i] = 31744;
baseTable[i | 256] = 64512;
shiftTable[i] = 24;
shiftTable[i | 256] = 24;
} else {
baseTable[i] = 31744;
baseTable[i | 256] = 64512;
shiftTable[i] = 13;
shiftTable[i | 256] = 13;
}
}
function roundToFloat16Bits(num) {
floatView[0] = roundToFloat16(num);
const f = uint32View[0];
const e = f >> 23 & 511;
return baseTable[e] + ((f & 8388607) >> shiftTable[e]);
}
var mantissaTable = new NativeUint32Array(2048);
for (let i = 1; i < 1024; ++i) {
let m = i << 13;
let e = 0;
while ((m & 8388608) === 0) {
m <<= 1;
e -= 8388608;
}
m &= ~8388608;
e += 947912704;
mantissaTable[i] = m | e;
}
for (let i = 1024; i < 2048; ++i) {
mantissaTable[i] = 939524096 + (i - 1024 << 13);
}
var exponentTable = new NativeUint32Array(64);
for (let i = 1; i < 31; ++i) {
exponentTable[i] = i << 23;
}
exponentTable[31] = 1199570944;
exponentTable[32] = 2147483648;
for (let i = 33; i < 63; ++i) {
exponentTable[i] = 2147483648 + (i - 32 << 23);
}
exponentTable[63] = 3347054592;
var offsetTable = new NativeUint16Array(64);
for (let i = 1; i < 64; ++i) {
if (i !== 32) {
offsetTable[i] = 1024;
}
}
function convertToNumber(float16bits) {
const i = float16bits >> 10;
uint32View[0] = mantissaTable[offsetTable[i] + (float16bits & 1023)] + exponentTable[i];
return floatView[0];
}
// node_modules/@petamoriken/float16/src/_util/spec.mjs
function ToIntegerOrInfinity(target) {
const number = +target;
if (NumberIsNaN(number) || number === 0) {
return 0;
}
return MathTrunc(number);
}
function ToLength(target) {
const length = ToIntegerOrInfinity(target);
if (length < 0) {
return 0;
}
return length < MAX_SAFE_INTEGER ? length : MAX_SAFE_INTEGER;
}
function SpeciesConstructor(target, defaultConstructor) {
if (!isObject(target)) {
throw NativeTypeError(THIS_IS_NOT_AN_OBJECT);
}
const constructor = target.constructor;
if (constructor === void 0) {
return defaultConstructor;
}
if (!isObject(constructor)) {
throw NativeTypeError(THE_CONSTRUCTOR_PROPERTY_VALUE_IS_NOT_AN_OBJECT);
}
const species = constructor[SymbolSpecies];
if (species == null) {
return defaultConstructor;
}
return species;
}
function IsDetachedBuffer(buffer3) {
if (isSharedArrayBuffer(buffer3)) {
return false;
}
try {
ArrayBufferPrototypeSlice(buffer3, 0, 0);
return false;
} catch (e) {
}
return true;
}
function defaultCompare(x, y) {
const isXNaN = NumberIsNaN(x);
const isYNaN = NumberIsNaN(y);
if (isXNaN && isYNaN) {
return 0;
}
if (isXNaN) {
return 1;
}
if (isYNaN) {
return -1;
}
if (x < y) {
return -1;
}
if (x > y) {
return 1;
}
if (x === 0 && y === 0) {
const isXPlusZero = ObjectIs(x, 0);
const isYPlusZero = ObjectIs(y, 0);
if (!isXPlusZero && isYPlusZero) {
return -1;
}
if (isXPlusZero && !isYPlusZero) {
return 1;
}
}
return 0;
}
// node_modules/@petamoriken/float16/src/Float16Array.mjs
var BYTES_PER_ELEMENT = 2;
var float16bitsArrays = new NativeWeakMap();
function isFloat16Array(target) {
return WeakMapPrototypeHas(float16bitsArrays, target) || !ArrayBufferIsView(target) && hasFloat16ArrayBrand(target);
}
function assertFloat16Array(target) {
if (!isFloat16Array(target)) {
throw NativeTypeError(THIS_IS_NOT_A_FLOAT16ARRAY_OBJECT);
}
}
function assertSpeciesTypedArray(target, count) {
const isTargetFloat16Array = isFloat16Array(target);
const isTargetTypedArray = isNativeTypedArray(target);
if (!isTargetFloat16Array && !isTargetTypedArray) {
throw NativeTypeError(SPECIES_CONSTRUCTOR_DIDNT_RETURN_TYPEDARRAY_OBJECT);
}
if (typeof count === "number") {
let length;
if (isTargetFloat16Array) {
const float16bitsArray = getFloat16BitsArray(target);
length = TypedArrayPrototypeGetLength(float16bitsArray);
} else {
length = TypedArrayPrototypeGetLength(target);
}
if (length < count) {
throw NativeTypeError(
DERIVED_CONSTRUCTOR_CREATED_TYPEDARRAY_OBJECT_WHICH_WAS_TOO_SMALL_LENGTH
);
}
}
if (isNativeBigIntTypedArray(target)) {
throw NativeTypeError(CANNOT_MIX_BIGINT_AND_OTHER_TYPES);
}
}
function getFloat16BitsArray(float16) {
const float16bitsArray = WeakMapPrototypeGet(float16bitsArrays, float16);
if (float16bitsArray !== void 0) {
const buffer4 = TypedArrayPrototypeGetBuffer(float16bitsArray);
if (IsDetachedBuffer(buffer4)) {
throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
}
return float16bitsArray;
}
const buffer3 = (
/** @type {any} */
float16.buffer
);
if (IsDetachedBuffer(buffer3)) {
throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
}
const cloned = ReflectConstruct(Float16Array, [
buffer3,
/** @type {any} */
float16.byteOffset,
/** @type {any} */
float16.length
], float16.constructor);
return WeakMapPrototypeGet(float16bitsArrays, cloned);
}
function copyToArray(float16bitsArray) {
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const array = [];
for (let i = 0; i < length; ++i) {
array[i] = convertToNumber(float16bitsArray[i]);
}
return array;
}
var TypedArrayPrototypeGetters = new NativeWeakSet();
for (const key of ReflectOwnKeys(TypedArrayPrototype)) {
if (key === SymbolToStringTag) {
continue;
}
const descriptor = ReflectGetOwnPropertyDescriptor(TypedArrayPrototype, key);
if (ObjectHasOwn(descriptor, "get") && typeof descriptor.get === "function") {
WeakSetPrototypeAdd(TypedArrayPrototypeGetters, descriptor.get);
}
}
var handler = ObjectFreeze(
/** @type {ProxyHandler} */
{
get(target, key, receiver) {
if (isCanonicalIntegerIndexString(key) && ObjectHasOwn(target, key)) {
return convertToNumber(ReflectGet(target, key));
}
if (WeakSetPrototypeHas(TypedArrayPrototypeGetters, ObjectPrototype__lookupGetter__(target, key))) {
return ReflectGet(target, key);
}
return ReflectGet(target, key, receiver);
},
set(target, key, value, receiver) {
if (isCanonicalIntegerIndexString(key) && ObjectHasOwn(target, key)) {
return ReflectSet(target, key, roundToFloat16Bits(value));
}
return ReflectSet(target, key, value, receiver);
},
getOwnPropertyDescriptor(target, key) {
if (isCanonicalIntegerIndexString(key) && ObjectHasOwn(target, key)) {
const descriptor = ReflectGetOwnPropertyDescriptor(target, key);
descriptor.value = convertToNumber(descriptor.value);
return descriptor;
}
return ReflectGetOwnPropertyDescriptor(target, key);
},
defineProperty(target, key, descriptor) {
if (isCanonicalIntegerIndexString(key) && ObjectHasOwn(target, key) && ObjectHasOwn(descriptor, "value")) {
descriptor.value = roundToFloat16Bits(descriptor.value);
return ReflectDefineProperty(target, key, descriptor);
}
return ReflectDefineProperty(target, key, descriptor);
}
}
);
var Float16Array = class _Float16Array {
/** @see https://tc39.es/ecma262/#sec-typedarray */
constructor(input, _byteOffset, _length) {
let float16bitsArray;
if (isFloat16Array(input)) {
float16bitsArray = ReflectConstruct(NativeUint16Array, [getFloat16BitsArray(input)], new.target);
} else if (isObject(input) && !isAnyArrayBuffer(input)) {
let list;
let length;
if (isNativeTypedArray(input)) {
list = input;
length = TypedArrayPrototypeGetLength(input);
const buffer3 = TypedArrayPrototypeGetBuffer(input);
if (IsDetachedBuffer(buffer3)) {
throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
}
if (isNativeBigIntTypedArray(input)) {
throw NativeTypeError(CANNOT_MIX_BIGINT_AND_OTHER_TYPES);
}
const data = new NativeArrayBuffer(
length * BYTES_PER_ELEMENT
);
float16bitsArray = ReflectConstruct(NativeUint16Array, [data], new.target);
} else {
const iterator = input[SymbolIterator];
if (iterator != null && typeof iterator !== "function") {
throw NativeTypeError(ITERATOR_PROPERTY_IS_NOT_CALLABLE);
}
if (iterator != null) {
if (isOrdinaryArray(input)) {
list = input;
length = input.length;
} else {
list = [.../** @type {Iterable} */
input];
length = list.length;
}
} else {
list = /** @type {ArrayLike} */
input;
length = ToLength(list.length);
}
float16bitsArray = ReflectConstruct(NativeUint16Array, [length], new.target);
}
for (let i = 0; i < length; ++i) {
float16bitsArray[i] = roundToFloat16Bits(list[i]);
}
} else {
float16bitsArray = ReflectConstruct(NativeUint16Array, arguments, new.target);
}
const proxy = (
/** @type {any} */
new NativeProxy(float16bitsArray, handler)
);
WeakMapPrototypeSet(float16bitsArrays, proxy, float16bitsArray);
return proxy;
}
/**
* limitation: `Object.getOwnPropertyNames(Float16Array)` or `Reflect.ownKeys(Float16Array)` include this key
* @see https://tc39.es/ecma262/#sec-%typedarray%.from
*/
static from(src, ...opts) {
const Constructor = this;
if (!ReflectHas(Constructor, brand)) {
throw NativeTypeError(
THIS_CONSTRUCTOR_IS_NOT_A_SUBCLASS_OF_FLOAT16ARRAY
);
}
if (Constructor === _Float16Array) {
if (isFloat16Array(src) && opts.length === 0) {
const float16bitsArray = getFloat16BitsArray(src);
const uint16 = new NativeUint16Array(
TypedArrayPrototypeGetBuffer(float16bitsArray),
TypedArrayPrototypeGetByteOffset(float16bitsArray),
TypedArrayPrototypeGetLength(float16bitsArray)
);
return new _Float16Array(
TypedArrayPrototypeGetBuffer(TypedArrayPrototypeSlice(uint16))
);
}
if (opts.length === 0) {
return new _Float16Array(
TypedArrayPrototypeGetBuffer(
Uint16ArrayFrom(src, roundToFloat16Bits)
)
);
}
const mapFunc = opts[0];
const thisArg = opts[1];
return new _Float16Array(
TypedArrayPrototypeGetBuffer(
Uint16ArrayFrom(src, function(val, ...args) {
return roundToFloat16Bits(
ReflectApply(mapFunc, this, [val, ...safeIfNeeded(args)])
);
}, thisArg)
)
);
}
let list;
let length;
const iterator = src[SymbolIterator];
if (iterator != null && typeof iterator !== "function") {
throw NativeTypeError(ITERATOR_PROPERTY_IS_NOT_CALLABLE);
}
if (iterator != null) {
if (isOrdinaryArray(src)) {
list = src;
length = src.length;
} else if (isOrdinaryNativeTypedArray(src)) {
list = src;
length = TypedArrayPrototypeGetLength(src);
} else {
list = [...src];
length = list.length;
}
} else {
if (src == null) {
throw NativeTypeError(
CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT
);
}
list = NativeObject(src);
length = ToLength(list.length);
}
const array = new Constructor(length);
if (opts.length === 0) {
for (let i = 0; i < length; ++i) {
array[i] = /** @type {number} */
list[i];
}
} else {
const mapFunc = opts[0];
const thisArg = opts[1];
for (let i = 0; i < length; ++i) {
array[i] = ReflectApply(mapFunc, thisArg, [list[i], i]);
}
}
return array;
}
/**
* limitation: `Object.getOwnPropertyNames(Float16Array)` or `Reflect.ownKeys(Float16Array)` include this key
* @see https://tc39.es/ecma262/#sec-%typedarray%.of
*/
static of(...items) {
const Constructor = this;
if (!ReflectHas(Constructor, brand)) {
throw NativeTypeError(
THIS_CONSTRUCTOR_IS_NOT_A_SUBCLASS_OF_FLOAT16ARRAY
);
}
const length = items.length;
if (Constructor === _Float16Array) {
const proxy = new _Float16Array(length);
const float16bitsArray = getFloat16BitsArray(proxy);
for (let i = 0; i < length; ++i) {
float16bitsArray[i] = roundToFloat16Bits(items[i]);
}
return proxy;
}
const array = new Constructor(length);
for (let i = 0; i < length; ++i) {
array[i] = items[i];
}
return array;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.keys */
keys() {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
return TypedArrayPrototypeKeys(float16bitsArray);
}
/**
* limitation: returns a object whose prototype is not `%ArrayIteratorPrototype%`
* @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.values
*/
values() {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
return wrap((function* () {
for (const val of TypedArrayPrototypeValues(float16bitsArray)) {
yield convertToNumber(val);
}
})());
}
/**
* limitation: returns a object whose prototype is not `%ArrayIteratorPrototype%`
* @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.entries
*/
entries() {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
return wrap((function* () {
for (const [i, val] of TypedArrayPrototypeEntries(float16bitsArray)) {
yield (
/** @type {[number, number]} */
[i, convertToNumber(val)]
);
}
})());
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.at */
at(index) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const relativeIndex = ToIntegerOrInfinity(index);
const k = relativeIndex >= 0 ? relativeIndex : length + relativeIndex;
if (k < 0 || k >= length) {
return;
}
return convertToNumber(float16bitsArray[k]);
}
/** @see https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.with */
with(index, value) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const relativeIndex = ToIntegerOrInfinity(index);
const k = relativeIndex >= 0 ? relativeIndex : length + relativeIndex;
const number = +value;
if (k < 0 || k >= length) {
throw NativeRangeError(OFFSET_IS_OUT_OF_BOUNDS);
}
const uint16 = new NativeUint16Array(
TypedArrayPrototypeGetBuffer(float16bitsArray),
TypedArrayPrototypeGetByteOffset(float16bitsArray),
TypedArrayPrototypeGetLength(float16bitsArray)
);
const cloned = new _Float16Array(
TypedArrayPrototypeGetBuffer(
TypedArrayPrototypeSlice(uint16)
)
);
const array = getFloat16BitsArray(cloned);
array[k] = roundToFloat16Bits(number);
return cloned;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.map */
map(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0];
const Constructor = SpeciesConstructor(float16bitsArray, _Float16Array);
if (Constructor === _Float16Array) {
const proxy = new _Float16Array(length);
const array2 = getFloat16BitsArray(proxy);
for (let i = 0; i < length; ++i) {
const val = convertToNumber(float16bitsArray[i]);
array2[i] = roundToFloat16Bits(
ReflectApply(callback, thisArg, [val, i, this])
);
}
return proxy;
}
const array = new Constructor(length);
assertSpeciesTypedArray(array, length);
for (let i = 0; i < length; ++i) {
const val = convertToNumber(float16bitsArray[i]);
array[i] = ReflectApply(callback, thisArg, [val, i, this]);
}
return (
/** @type {any} */
array
);
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.filter */
filter(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0];
const kept = [];
for (let i = 0; i < length; ++i) {
const val = convertToNumber(float16bitsArray[i]);
if (ReflectApply(callback, thisArg, [val, i, this])) {
ArrayPrototypePush(kept, val);
}
}
const Constructor = SpeciesConstructor(float16bitsArray, _Float16Array);
const array = new Constructor(kept);
assertSpeciesTypedArray(array);
return (
/** @type {any} */
array
);
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.reduce */
reduce(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
if (length === 0 && opts.length === 0) {
throw NativeTypeError(REDUCE_OF_EMPTY_ARRAY_WITH_NO_INITIAL_VALUE);
}
let accumulator, start;
if (opts.length === 0) {
accumulator = convertToNumber(float16bitsArray[0]);
start = 1;
} else {
accumulator = opts[0];
start = 0;
}
for (let i = start; i < length; ++i) {
accumulator = callback(
accumulator,
convertToNumber(float16bitsArray[i]),
i,
this
);
}
return accumulator;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.reduceright */
reduceRight(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
if (length === 0 && opts.length === 0) {
throw NativeTypeError(REDUCE_OF_EMPTY_ARRAY_WITH_NO_INITIAL_VALUE);
}
let accumulator, start;
if (opts.length === 0) {
accumulator = convertToNumber(float16bitsArray[length - 1]);
start = length - 2;
} else {
accumulator = opts[0];
start = length - 1;
}
for (let i = start; i >= 0; --i) {
accumulator = callback(
accumulator,
convertToNumber(float16bitsArray[i]),
i,
this
);
}
return accumulator;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.foreach */
forEach(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0];
for (let i = 0; i < length; ++i) {
ReflectApply(callback, thisArg, [
convertToNumber(float16bitsArray[i]),
i,
this
]);
}
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.find */
find(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0];
for (let i = 0; i < length; ++i) {
const value = convertToNumber(float16bitsArray[i]);
if (ReflectApply(callback, thisArg, [value, i, this])) {
return value;
}
}
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.findindex */
findIndex(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0];
for (let i = 0; i < length; ++i) {
const value = convertToNumber(float16bitsArray[i]);
if (ReflectApply(callback, thisArg, [value, i, this])) {
return i;
}
}
return -1;
}
/** @see https://tc39.es/proposal-array-find-from-last/index.html#sec-%typedarray%.prototype.findlast */
findLast(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0];
for (let i = length - 1; i >= 0; --i) {
const value = convertToNumber(float16bitsArray[i]);
if (ReflectApply(callback, thisArg, [value, i, this])) {
return value;
}
}
}
/** @see https://tc39.es/proposal-array-find-from-last/index.html#sec-%typedarray%.prototype.findlastindex */
findLastIndex(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0];
for (let i = length - 1; i >= 0; --i) {
const value = convertToNumber(float16bitsArray[i]);
if (ReflectApply(callback, thisArg, [value, i, this])) {
return i;
}
}
return -1;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.every */
every(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0];
for (let i = 0; i < length; ++i) {
if (!ReflectApply(callback, thisArg, [
convertToNumber(float16bitsArray[i]),
i,
this
])) {
return false;
}
}
return true;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.some */
some(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0];
for (let i = 0; i < length; ++i) {
if (ReflectApply(callback, thisArg, [
convertToNumber(float16bitsArray[i]),
i,
this
])) {
return true;
}
}
return false;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.set */
set(input, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const targetOffset = ToIntegerOrInfinity(opts[0]);
if (targetOffset < 0) {
throw NativeRangeError(OFFSET_IS_OUT_OF_BOUNDS);
}
if (input == null) {
throw NativeTypeError(
CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT
);
}
if (isNativeBigIntTypedArray(input)) {
throw NativeTypeError(
CANNOT_MIX_BIGINT_AND_OTHER_TYPES
);
}
if (isFloat16Array(input)) {
return TypedArrayPrototypeSet(
getFloat16BitsArray(this),
getFloat16BitsArray(input),
targetOffset
);
}
if (isNativeTypedArray(input)) {
const buffer3 = TypedArrayPrototypeGetBuffer(input);
if (IsDetachedBuffer(buffer3)) {
throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
}
}
const targetLength = TypedArrayPrototypeGetLength(float16bitsArray);
const src = NativeObject(input);
const srcLength = ToLength(src.length);
if (targetOffset === Infinity || srcLength + targetOffset > targetLength) {
throw NativeRangeError(OFFSET_IS_OUT_OF_BOUNDS);
}
for (let i = 0; i < srcLength; ++i) {
float16bitsArray[i + targetOffset] = roundToFloat16Bits(src[i]);
}
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.reverse */
reverse() {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
TypedArrayPrototypeReverse(float16bitsArray);
return this;
}
/** @see https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.toReversed */
toReversed() {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const uint16 = new NativeUint16Array(
TypedArrayPrototypeGetBuffer(float16bitsArray),
TypedArrayPrototypeGetByteOffset(float16bitsArray),
TypedArrayPrototypeGetLength(float16bitsArray)
);
const cloned = new _Float16Array(
TypedArrayPrototypeGetBuffer(
TypedArrayPrototypeSlice(uint16)
)
);
const clonedFloat16bitsArray = getFloat16BitsArray(cloned);
TypedArrayPrototypeReverse(clonedFloat16bitsArray);
return cloned;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.fill */
fill(value, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
TypedArrayPrototypeFill(
float16bitsArray,
roundToFloat16Bits(value),
...safeIfNeeded(opts)
);
return this;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.copywithin */
copyWithin(target, start, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
TypedArrayPrototypeCopyWithin(float16bitsArray, target, start, ...safeIfNeeded(opts));
return this;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.sort */
sort(compareFn) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const sortCompare = compareFn !== void 0 ? compareFn : defaultCompare;
TypedArrayPrototypeSort(float16bitsArray, (x, y) => {
return sortCompare(convertToNumber(x), convertToNumber(y));
});
return this;
}
/** @see https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.toSorted */
toSorted(compareFn) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
if (compareFn !== void 0 && typeof compareFn !== "function") {
throw new NativeTypeError(THE_COMPARISON_FUNCTION_MUST_BE_EITHER_A_FUNCTION_OR_UNDEFINED);
}
const sortCompare = compareFn !== void 0 ? compareFn : defaultCompare;
const uint16 = new NativeUint16Array(
TypedArrayPrototypeGetBuffer(float16bitsArray),
TypedArrayPrototypeGetByteOffset(float16bitsArray),
TypedArrayPrototypeGetLength(float16bitsArray)
);
const cloned = new _Float16Array(
TypedArrayPrototypeGetBuffer(
TypedArrayPrototypeSlice(uint16)
)
);
const clonedFloat16bitsArray = getFloat16BitsArray(cloned);
TypedArrayPrototypeSort(clonedFloat16bitsArray, (x, y) => {
return sortCompare(convertToNumber(x), convertToNumber(y));
});
return cloned;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.slice */
slice(start, end) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const Constructor = SpeciesConstructor(float16bitsArray, _Float16Array);
if (Constructor === _Float16Array) {
const uint16 = new NativeUint16Array(
TypedArrayPrototypeGetBuffer(float16bitsArray),
TypedArrayPrototypeGetByteOffset(float16bitsArray),
TypedArrayPrototypeGetLength(float16bitsArray)
);
return new _Float16Array(
TypedArrayPrototypeGetBuffer(
TypedArrayPrototypeSlice(uint16, start, end)
)
);
}
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const relativeStart = ToIntegerOrInfinity(start);
const relativeEnd = end === void 0 ? length : ToIntegerOrInfinity(end);
let k;
if (relativeStart === -Infinity) {
k = 0;
} else if (relativeStart < 0) {
k = length + relativeStart > 0 ? length + relativeStart : 0;
} else {
k = length < relativeStart ? length : relativeStart;
}
let final;
if (relativeEnd === -Infinity) {
final = 0;
} else if (relativeEnd < 0) {
final = length + relativeEnd > 0 ? length + relativeEnd : 0;
} else {
final = length < relativeEnd ? length : relativeEnd;
}
const count = final - k > 0 ? final - k : 0;
const array = new Constructor(count);
assertSpeciesTypedArray(array, count);
if (count === 0) {
return array;
}
const buffer3 = TypedArrayPrototypeGetBuffer(float16bitsArray);
if (IsDetachedBuffer(buffer3)) {
throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
}
let n = 0;
while (k < final) {
array[n] = convertToNumber(float16bitsArray[k]);
++k;
++n;
}
return (
/** @type {any} */
array
);
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.subarray */
subarray(begin, end) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const Constructor = SpeciesConstructor(float16bitsArray, _Float16Array);
const uint16 = new NativeUint16Array(
TypedArrayPrototypeGetBuffer(float16bitsArray),
TypedArrayPrototypeGetByteOffset(float16bitsArray),
TypedArrayPrototypeGetLength(float16bitsArray)
);
const uint16Subarray = TypedArrayPrototypeSubarray(uint16, begin, end);
const array = new Constructor(
TypedArrayPrototypeGetBuffer(uint16Subarray),
TypedArrayPrototypeGetByteOffset(uint16Subarray),
TypedArrayPrototypeGetLength(uint16Subarray)
);
assertSpeciesTypedArray(array);
return (
/** @type {any} */
array
);
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.indexof */
indexOf(element, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
let from = ToIntegerOrInfinity(opts[0]);
if (from === Infinity) {
return -1;
}
if (from < 0) {
from += length;
if (from < 0) {
from = 0;
}
}
for (let i = from; i < length; ++i) {
if (ObjectHasOwn(float16bitsArray, i) && convertToNumber(float16bitsArray[i]) === element) {
return i;
}
}
return -1;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.lastindexof */
lastIndexOf(element, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
let from = opts.length >= 1 ? ToIntegerOrInfinity(opts[0]) : length - 1;
if (from === -Infinity) {
return -1;
}
if (from >= 0) {
from = from < length - 1 ? from : length - 1;
} else {
from += length;
}
for (let i = from; i >= 0; --i) {
if (ObjectHasOwn(float16bitsArray, i) && convertToNumber(float16bitsArray[i]) === element) {
return i;
}
}
return -1;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.includes */
includes(element, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
let from = ToIntegerOrInfinity(opts[0]);
if (from === Infinity) {
return false;
}
if (from < 0) {
from += length;
if (from < 0) {
from = 0;
}
}
const isNaN2 = NumberIsNaN(element);
for (let i = from; i < length; ++i) {
const value = convertToNumber(float16bitsArray[i]);
if (isNaN2 && NumberIsNaN(value)) {
return true;
}
if (value === element) {
return true;
}
}
return false;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.join */
join(separator) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const array = copyToArray(float16bitsArray);
return ArrayPrototypeJoin(array, separator);
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.tolocalestring */
toLocaleString(...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const array = copyToArray(float16bitsArray);
return ArrayPrototypeToLocaleString(array, ...safeIfNeeded(opts));
}
/** @see https://tc39.es/ecma262/#sec-get-%typedarray%.prototype-@@tostringtag */
get [SymbolToStringTag]() {
if (isFloat16Array(this)) {
return (
/** @type {any} */
"Float16Array"
);
}
}
};
ObjectDefineProperty(Float16Array, "BYTES_PER_ELEMENT", {
value: BYTES_PER_ELEMENT
});
ObjectDefineProperty(Float16Array, brand, {});
ReflectSetPrototypeOf(Float16Array, TypedArray);
var Float16ArrayPrototype = Float16Array.prototype;
ObjectDefineProperty(Float16ArrayPrototype, "BYTES_PER_ELEMENT", {
value: BYTES_PER_ELEMENT
});
ObjectDefineProperty(Float16ArrayPrototype, SymbolIterator, {
value: Float16ArrayPrototype.values,
writable: true,
configurable: true
});
ReflectSetPrototypeOf(Float16ArrayPrototype, TypedArrayPrototype);
// node_modules/@petamoriken/float16/src/DataView.mjs
function getFloat16(dataView, byteOffset, ...opts) {
return convertToNumber(
DataViewPrototypeGetUint16(dataView, byteOffset, ...safeIfNeeded(opts))
);
}
// node_modules/geotiff/dist-module/geotiffimage.js
var import_get_attribute = __toESM(require_get_attribute(), 1);
var import_find_tags_by_name = __toESM(require_find_tags_by_name(), 1);
// node_modules/geotiff/dist-module/rgb.js
function fromWhiteIsZero(raster, max) {
const { width, height } = raster;
const rgbRaster = new Uint8Array(width * height * 3);
let value;
for (let i = 0, j = 0; i < raster.length; ++i, j += 3) {
value = 256 - raster[i] / max * 256;
rgbRaster[j] = value;
rgbRaster[j + 1] = value;
rgbRaster[j + 2] = value;
}
return rgbRaster;
}
function fromBlackIsZero(raster, max) {
const { width, height } = raster;
const rgbRaster = new Uint8Array(width * height * 3);
let value;
for (let i = 0, j = 0; i < raster.length; ++i, j += 3) {
value = raster[i] / max * 256;
rgbRaster[j] = value;
rgbRaster[j + 1] = value;
rgbRaster[j + 2] = value;
}
return rgbRaster;
}
function fromPalette(raster, colorMap) {
const { width, height } = raster;
const rgbRaster = new Uint8Array(width * height * 3);
const greenOffset = colorMap.length / 3;
const blueOffset = colorMap.length / 3 * 2;
for (let i = 0, j = 0; i < raster.length; ++i, j += 3) {
const mapIndex = raster[i];
rgbRaster[j] = colorMap[mapIndex] / 65536 * 256;
rgbRaster[j + 1] = colorMap[mapIndex + greenOffset] / 65536 * 256;
rgbRaster[j + 2] = colorMap[mapIndex + blueOffset] / 65536 * 256;
}
return rgbRaster;
}
function fromCMYK(cmykRaster) {
const { width, height } = cmykRaster;
const rgbRaster = new Uint8Array(width * height * 3);
for (let i = 0, j = 0; i < cmykRaster.length; i += 4, j += 3) {
const c = cmykRaster[i];
const m = cmykRaster[i + 1];
const y = cmykRaster[i + 2];
const k = cmykRaster[i + 3];
rgbRaster[j] = 255 * ((255 - c) / 256) * ((255 - k) / 256);
rgbRaster[j + 1] = 255 * ((255 - m) / 256) * ((255 - k) / 256);
rgbRaster[j + 2] = 255 * ((255 - y) / 256) * ((255 - k) / 256);
}
return rgbRaster;
}
function fromYCbCr(yCbCrRaster) {
const { width, height } = yCbCrRaster;
const rgbRaster = new Uint8ClampedArray(width * height * 3);
for (let i = 0, j = 0; i < yCbCrRaster.length; i += 3, j += 3) {
const y = yCbCrRaster[i];
const cb = yCbCrRaster[i + 1];
const cr = yCbCrRaster[i + 2];
rgbRaster[j] = y + 1.402 * (cr - 128);
rgbRaster[j + 1] = y - 0.34414 * (cb - 128) - 0.71414 * (cr - 128);
rgbRaster[j + 2] = y + 1.772 * (cb - 128);
}
return rgbRaster;
}
var Xn = 0.95047;
var Yn = 1;
var Zn = 1.08883;
function fromCIELab(cieLabRaster) {
const { width, height } = cieLabRaster;
const rgbRaster = new Uint8Array(width * height * 3);
for (let i = 0, j = 0; i < cieLabRaster.length; i += 3, j += 3) {
const L = cieLabRaster[i + 0];
const a_ = cieLabRaster[i + 1] << 24 >> 24;
const b_ = cieLabRaster[i + 2] << 24 >> 24;
let y = (L + 16) / 116;
let x = a_ / 500 + y;
let z = y - b_ / 200;
let r;
let g;
let b;
x = Xn * (x * x * x > 8856e-6 ? x * x * x : (x - 16 / 116) / 7.787);
y = Yn * (y * y * y > 8856e-6 ? y * y * y : (y - 16 / 116) / 7.787);
z = Zn * (z * z * z > 8856e-6 ? z * z * z : (z - 16 / 116) / 7.787);
r = x * 3.2406 + y * -1.5372 + z * -0.4986;
g = x * -0.9689 + y * 1.8758 + z * 0.0415;
b = x * 0.0557 + y * -0.204 + z * 1.057;
r = r > 31308e-7 ? 1.055 * r ** (1 / 2.4) - 0.055 : 12.92 * r;
g = g > 31308e-7 ? 1.055 * g ** (1 / 2.4) - 0.055 : 12.92 * g;
b = b > 31308e-7 ? 1.055 * b ** (1 / 2.4) - 0.055 : 12.92 * b;
rgbRaster[j] = Math.max(0, Math.min(1, r)) * 255;
rgbRaster[j + 1] = Math.max(0, Math.min(1, g)) * 255;
rgbRaster[j + 2] = Math.max(0, Math.min(1, b)) * 255;
}
return rgbRaster;
}
// node_modules/geotiff/dist-module/compression/index.js
var registry = /* @__PURE__ */ new Map();
function addDecoder(cases, importFn) {
if (!Array.isArray(cases)) {
cases = [cases];
}
cases.forEach((c) => registry.set(c, importFn));
}
async function getDecoder(fileDirectory) {
const importFn = registry.get(fileDirectory.Compression);
if (!importFn) {
throw new Error(`Unknown compression method identifier: ${fileDirectory.Compression}`);
}
const Decoder = await importFn();
return new Decoder(fileDirectory);
}
addDecoder([void 0, 1], () => import("./raw-UKC26CDE.js").then((m) => m.default));
addDecoder(5, () => import("./lzw-7DRJSDK5.js").then((m) => m.default));
addDecoder(6, () => {
throw new Error("old style JPEG compression is not supported.");
});
addDecoder(7, () => import("./jpeg-HGEGG7HT.js").then((m) => m.default));
addDecoder([8, 32946], () => import("./deflate-IME5YE3D.js").then((m) => m.default));
addDecoder(32773, () => import("./packbits-F6QMWCFA.js").then((m) => m.default));
addDecoder(
34887,
() => import("./lerc-YJMC4I3X.js").then(async (m) => {
await m.zstd.init();
return m;
}).then((m) => m.default)
);
addDecoder(50001, () => import("./webimage-T4PTOJUP.js").then((m) => m.default));
// node_modules/geotiff/dist-module/resample.js
function copyNewSize(array, width, height, samplesPerPixel = 1) {
return new (Object.getPrototypeOf(array)).constructor(width * height * samplesPerPixel);
}
function resampleNearest(valueArrays, inWidth, inHeight, outWidth, outHeight) {
const relX = inWidth / outWidth;
const relY = inHeight / outHeight;
return valueArrays.map((array) => {
const newArray = copyNewSize(array, outWidth, outHeight);
for (let y = 0; y < outHeight; ++y) {
const cy = Math.min(Math.round(relY * y), inHeight - 1);
for (let x = 0; x < outWidth; ++x) {
const cx = Math.min(Math.round(relX * x), inWidth - 1);
const value = array[cy * inWidth + cx];
newArray[y * outWidth + x] = value;
}
}
return newArray;
});
}
function lerp(v0, v1, t) {
return (1 - t) * v0 + t * v1;
}
function resampleBilinear(valueArrays, inWidth, inHeight, outWidth, outHeight) {
const relX = inWidth / outWidth;
const relY = inHeight / outHeight;
return valueArrays.map((array) => {
const newArray = copyNewSize(array, outWidth, outHeight);
for (let y = 0; y < outHeight; ++y) {
const rawY = relY * y;
const yl = Math.floor(rawY);
const yh = Math.min(Math.ceil(rawY), inHeight - 1);
for (let x = 0; x < outWidth; ++x) {
const rawX = relX * x;
const tx = rawX % 1;
const xl = Math.floor(rawX);
const xh = Math.min(Math.ceil(rawX), inWidth - 1);
const ll = array[yl * inWidth + xl];
const hl = array[yl * inWidth + xh];
const lh = array[yh * inWidth + xl];
const hh = array[yh * inWidth + xh];
const value = lerp(
lerp(ll, hl, tx),
lerp(lh, hh, tx),
rawY % 1
);
newArray[y * outWidth + x] = value;
}
}
return newArray;
});
}
function resample(valueArrays, inWidth, inHeight, outWidth, outHeight, method = "nearest") {
switch (method.toLowerCase()) {
case "nearest":
return resampleNearest(valueArrays, inWidth, inHeight, outWidth, outHeight);
case "bilinear":
case "linear":
return resampleBilinear(valueArrays, inWidth, inHeight, outWidth, outHeight);
default:
throw new Error(`Unsupported resampling method: '${method}'`);
}
}
function resampleNearestInterleaved(valueArray, inWidth, inHeight, outWidth, outHeight, samples) {
const relX = inWidth / outWidth;
const relY = inHeight / outHeight;
const newArray = copyNewSize(valueArray, outWidth, outHeight, samples);
for (let y = 0; y < outHeight; ++y) {
const cy = Math.min(Math.round(relY * y), inHeight - 1);
for (let x = 0; x < outWidth; ++x) {
const cx = Math.min(Math.round(relX * x), inWidth - 1);
for (let i = 0; i < samples; ++i) {
const value = valueArray[cy * inWidth * samples + cx * samples + i];
newArray[y * outWidth * samples + x * samples + i] = value;
}
}
}
return newArray;
}
function resampleBilinearInterleaved(valueArray, inWidth, inHeight, outWidth, outHeight, samples) {
const relX = inWidth / outWidth;
const relY = inHeight / outHeight;
const newArray = copyNewSize(valueArray, outWidth, outHeight, samples);
for (let y = 0; y < outHeight; ++y) {
const rawY = relY * y;
const yl = Math.floor(rawY);
const yh = Math.min(Math.ceil(rawY), inHeight - 1);
for (let x = 0; x < outWidth; ++x) {
const rawX = relX * x;
const tx = rawX % 1;
const xl = Math.floor(rawX);
const xh = Math.min(Math.ceil(rawX), inWidth - 1);
for (let i = 0; i < samples; ++i) {
const ll = valueArray[yl * inWidth * samples + xl * samples + i];
const hl = valueArray[yl * inWidth * samples + xh * samples + i];
const lh = valueArray[yh * inWidth * samples + xl * samples + i];
const hh = valueArray[yh * inWidth * samples + xh * samples + i];
const value = lerp(
lerp(ll, hl, tx),
lerp(lh, hh, tx),
rawY % 1
);
newArray[y * outWidth * samples + x * samples + i] = value;
}
}
}
return newArray;
}
function resampleInterleaved(valueArray, inWidth, inHeight, outWidth, outHeight, samples, method = "nearest") {
switch (method.toLowerCase()) {
case "nearest":
return resampleNearestInterleaved(
valueArray,
inWidth,
inHeight,
outWidth,
outHeight,
samples
);
case "bilinear":
case "linear":
return resampleBilinearInterleaved(
valueArray,
inWidth,
inHeight,
outWidth,
outHeight,
samples
);
default:
throw new Error(`Unsupported resampling method: '${method}'`);
}
}
// node_modules/geotiff/dist-module/geotiffimage.js
function sum(array, start, end) {
let s = 0;
for (let i = start; i < end; ++i) {
s += array[i];
}
return s;
}
function arrayForType(format, bitsPerSample, size) {
switch (format) {
case 1:
if (bitsPerSample <= 8) {
return new Uint8Array(size);
} else if (bitsPerSample <= 16) {
return new Uint16Array(size);
} else if (bitsPerSample <= 32) {
return new Uint32Array(size);
}
break;
case 2:
if (bitsPerSample === 8) {
return new Int8Array(size);
} else if (bitsPerSample === 16) {
return new Int16Array(size);
} else if (bitsPerSample === 32) {
return new Int32Array(size);
}
break;
case 3:
switch (bitsPerSample) {
case 16:
case 32:
return new Float32Array(size);
case 64:
return new Float64Array(size);
default:
break;
}
break;
default:
break;
}
throw Error("Unsupported data format/bitsPerSample");
}
function needsNormalization(format, bitsPerSample) {
if ((format === 1 || format === 2) && bitsPerSample <= 32 && bitsPerSample % 8 === 0) {
return false;
} else if (format === 3 && (bitsPerSample === 16 || bitsPerSample === 32 || bitsPerSample === 64)) {
return false;
}
return true;
}
function normalizeArray(inBuffer, format, planarConfiguration, samplesPerPixel, bitsPerSample, tileWidth, tileHeight) {
const view = new DataView(inBuffer);
const outSize = planarConfiguration === 2 ? tileHeight * tileWidth : tileHeight * tileWidth * samplesPerPixel;
const samplesToTransfer = planarConfiguration === 2 ? 1 : samplesPerPixel;
const outArray = arrayForType(format, bitsPerSample, outSize);
const bitMask = parseInt("1".repeat(bitsPerSample), 2);
if (format === 1) {
let pixelBitSkip;
if (planarConfiguration === 1) {
pixelBitSkip = samplesPerPixel * bitsPerSample;
} else {
pixelBitSkip = bitsPerSample;
}
let bitsPerLine = tileWidth * pixelBitSkip;
if ((bitsPerLine & 7) !== 0) {
bitsPerLine = bitsPerLine + 7 & ~7;
}
for (let y = 0; y < tileHeight; ++y) {
const lineBitOffset = y * bitsPerLine;
for (let x = 0; x < tileWidth; ++x) {
const pixelBitOffset = lineBitOffset + x * samplesToTransfer * bitsPerSample;
for (let i = 0; i < samplesToTransfer; ++i) {
const bitOffset = pixelBitOffset + i * bitsPerSample;
const outIndex = (y * tileWidth + x) * samplesToTransfer + i;
const byteOffset = Math.floor(bitOffset / 8);
const innerBitOffset = bitOffset % 8;
if (innerBitOffset + bitsPerSample <= 8) {
outArray[outIndex] = view.getUint8(byteOffset) >> 8 - bitsPerSample - innerBitOffset & bitMask;
} else if (innerBitOffset + bitsPerSample <= 16) {
outArray[outIndex] = view.getUint16(byteOffset) >> 16 - bitsPerSample - innerBitOffset & bitMask;
} else if (innerBitOffset + bitsPerSample <= 24) {
const raw = view.getUint16(byteOffset) << 8 | view.getUint8(byteOffset + 2);
outArray[outIndex] = raw >> 24 - bitsPerSample - innerBitOffset & bitMask;
} else {
outArray[outIndex] = view.getUint32(byteOffset) >> 32 - bitsPerSample - innerBitOffset & bitMask;
}
}
}
}
} else if (format === 3) {
}
return outArray.buffer;
}
var GeoTIFFImage = class {
/**
* @constructor
* @param {Object} fileDirectory The parsed file directory
* @param {Object} geoKeys The parsed geo-keys
* @param {DataView} dataView The DataView for the underlying file.
* @param {Boolean} littleEndian Whether the file is encoded in little or big endian
* @param {Boolean} cache Whether or not decoded tiles shall be cached
* @param {import('./source/basesource').BaseSource} source The datasource to read from
*/
constructor(fileDirectory, geoKeys, dataView, littleEndian, cache, source) {
this.fileDirectory = fileDirectory;
this.geoKeys = geoKeys;
this.dataView = dataView;
this.littleEndian = littleEndian;
this.tiles = cache ? {} : null;
this.isTiled = !fileDirectory.StripOffsets;
const planarConfiguration = fileDirectory.PlanarConfiguration;
this.planarConfiguration = typeof planarConfiguration === "undefined" ? 1 : planarConfiguration;
if (this.planarConfiguration !== 1 && this.planarConfiguration !== 2) {
throw new Error("Invalid planar configuration.");
}
this.source = source;
}
/**
* Returns the associated parsed file directory.
* @returns {Object} the parsed file directory
*/
getFileDirectory() {
return this.fileDirectory;
}
/**
* Returns the associated parsed geo keys.
* @returns {Object} the parsed geo keys
*/
getGeoKeys() {
return this.geoKeys;
}
/**
* Returns the width of the image.
* @returns {Number} the width of the image
*/
getWidth() {
return this.fileDirectory.ImageWidth;
}
/**
* Returns the height of the image.
* @returns {Number} the height of the image
*/
getHeight() {
return this.fileDirectory.ImageLength;
}
/**
* Returns the number of samples per pixel.
* @returns {Number} the number of samples per pixel
*/
getSamplesPerPixel() {
return typeof this.fileDirectory.SamplesPerPixel !== "undefined" ? this.fileDirectory.SamplesPerPixel : 1;
}
/**
* Returns the width of each tile.
* @returns {Number} the width of each tile
*/
getTileWidth() {
return this.isTiled ? this.fileDirectory.TileWidth : this.getWidth();
}
/**
* Returns the height of each tile.
* @returns {Number} the height of each tile
*/
getTileHeight() {
if (this.isTiled) {
return this.fileDirectory.TileLength;
}
if (typeof this.fileDirectory.RowsPerStrip !== "undefined") {
return Math.min(this.fileDirectory.RowsPerStrip, this.getHeight());
}
return this.getHeight();
}
getBlockWidth() {
return this.getTileWidth();
}
getBlockHeight(y) {
if (this.isTiled || (y + 1) * this.getTileHeight() <= this.getHeight()) {
return this.getTileHeight();
} else {
return this.getHeight() - y * this.getTileHeight();
}
}
/**
* Calculates the number of bytes for each pixel across all samples. Only full
* bytes are supported, an exception is thrown when this is not the case.
* @returns {Number} the bytes per pixel
*/
getBytesPerPixel() {
let bytes = 0;
for (let i = 0; i < this.fileDirectory.BitsPerSample.length; ++i) {
bytes += this.getSampleByteSize(i);
}
return bytes;
}
getSampleByteSize(i) {
if (i >= this.fileDirectory.BitsPerSample.length) {
throw new RangeError(`Sample index ${i} is out of range.`);
}
return Math.ceil(this.fileDirectory.BitsPerSample[i] / 8);
}
getReaderForSample(sampleIndex) {
const format = this.fileDirectory.SampleFormat ? this.fileDirectory.SampleFormat[sampleIndex] : 1;
const bitsPerSample = this.fileDirectory.BitsPerSample[sampleIndex];
switch (format) {
case 1:
if (bitsPerSample <= 8) {
return DataView.prototype.getUint8;
} else if (bitsPerSample <= 16) {
return DataView.prototype.getUint16;
} else if (bitsPerSample <= 32) {
return DataView.prototype.getUint32;
}
break;
case 2:
if (bitsPerSample <= 8) {
return DataView.prototype.getInt8;
} else if (bitsPerSample <= 16) {
return DataView.prototype.getInt16;
} else if (bitsPerSample <= 32) {
return DataView.prototype.getInt32;
}
break;
case 3:
switch (bitsPerSample) {
case 16:
return function(offset, littleEndian) {
return getFloat16(this, offset, littleEndian);
};
case 32:
return DataView.prototype.getFloat32;
case 64:
return DataView.prototype.getFloat64;
default:
break;
}
break;
default:
break;
}
throw Error("Unsupported data format/bitsPerSample");
}
getSampleFormat(sampleIndex = 0) {
return this.fileDirectory.SampleFormat ? this.fileDirectory.SampleFormat[sampleIndex] : 1;
}
getBitsPerSample(sampleIndex = 0) {
return this.fileDirectory.BitsPerSample[sampleIndex];
}
getArrayForSample(sampleIndex, size) {
const format = this.getSampleFormat(sampleIndex);
const bitsPerSample = this.getBitsPerSample(sampleIndex);
return arrayForType(format, bitsPerSample, size);
}
/**
* Returns the decoded strip or tile.
* @param {Number} x the strip or tile x-offset
* @param {Number} y the tile y-offset (0 for stripped images)
* @param {Number} sample the sample to get for separated samples
* @param {import("./geotiff").Pool|import("./geotiff").BaseDecoder} poolOrDecoder the decoder or decoder pool
* @param {AbortSignal} [signal] An AbortSignal that may be signalled if the request is
* to be aborted
* @returns {Promise.}
*/
async getTileOrStrip(x, y, sample, poolOrDecoder, signal) {
const numTilesPerRow = Math.ceil(this.getWidth() / this.getTileWidth());
const numTilesPerCol = Math.ceil(this.getHeight() / this.getTileHeight());
let index;
const { tiles } = this;
if (this.planarConfiguration === 1) {
index = y * numTilesPerRow + x;
} else if (this.planarConfiguration === 2) {
index = sample * numTilesPerRow * numTilesPerCol + y * numTilesPerRow + x;
}
let offset;
let byteCount;
if (this.isTiled) {
offset = this.fileDirectory.TileOffsets[index];
byteCount = this.fileDirectory.TileByteCounts[index];
} else {
offset = this.fileDirectory.StripOffsets[index];
byteCount = this.fileDirectory.StripByteCounts[index];
}
const slice = (await this.source.fetch([{ offset, length: byteCount }], signal))[0];
let request;
if (tiles === null || !tiles[index]) {
request = (async () => {
let data = await poolOrDecoder.decode(this.fileDirectory, slice);
const sampleFormat = this.getSampleFormat();
const bitsPerSample = this.getBitsPerSample();
if (needsNormalization(sampleFormat, bitsPerSample)) {
data = normalizeArray(
data,
sampleFormat,
this.planarConfiguration,
this.getSamplesPerPixel(),
bitsPerSample,
this.getTileWidth(),
this.getBlockHeight(y)
);
}
return data;
})();
if (tiles !== null) {
tiles[index] = request;
}
} else {
request = tiles[index];
}
return { x, y, sample, data: await request };
}
/**
* Internal read function.
* @private
* @param {Array} imageWindow The image window in pixel coordinates
* @param {Array} samples The selected samples (0-based indices)
* @param {TypedArray|TypedArray[]} valueArrays The array(s) to write into
* @param {Boolean} interleave Whether or not to write in an interleaved manner
* @param {import("./geotiff").Pool|AbstractDecoder} poolOrDecoder the decoder or decoder pool
* @param {number} width the width of window to be read into
* @param {number} height the height of window to be read into
* @param {number} resampleMethod the resampling method to be used when interpolating
* @param {AbortSignal} [signal] An AbortSignal that may be signalled if the request is
* to be aborted
* @returns {Promise}
*/
async _readRaster(imageWindow, samples, valueArrays, interleave, poolOrDecoder, width, height, resampleMethod, signal) {
const tileWidth = this.getTileWidth();
const tileHeight = this.getTileHeight();
const imageWidth = this.getWidth();
const imageHeight = this.getHeight();
const minXTile = Math.max(Math.floor(imageWindow[0] / tileWidth), 0);
const maxXTile = Math.min(
Math.ceil(imageWindow[2] / tileWidth),
Math.ceil(imageWidth / tileWidth)
);
const minYTile = Math.max(Math.floor(imageWindow[1] / tileHeight), 0);
const maxYTile = Math.min(
Math.ceil(imageWindow[3] / tileHeight),
Math.ceil(imageHeight / tileHeight)
);
const windowWidth = imageWindow[2] - imageWindow[0];
let bytesPerPixel = this.getBytesPerPixel();
const srcSampleOffsets = [];
const sampleReaders = [];
for (let i = 0; i < samples.length; ++i) {
if (this.planarConfiguration === 1) {
srcSampleOffsets.push(sum(this.fileDirectory.BitsPerSample, 0, samples[i]) / 8);
} else {
srcSampleOffsets.push(0);
}
sampleReaders.push(this.getReaderForSample(samples[i]));
}
const promises = [];
const { littleEndian } = this;
for (let yTile = minYTile; yTile < maxYTile; ++yTile) {
for (let xTile = minXTile; xTile < maxXTile; ++xTile) {
let getPromise;
if (this.planarConfiguration === 1) {
getPromise = this.getTileOrStrip(xTile, yTile, 0, poolOrDecoder, signal);
}
for (let sampleIndex = 0; sampleIndex < samples.length; ++sampleIndex) {
const si = sampleIndex;
const sample = samples[sampleIndex];
if (this.planarConfiguration === 2) {
bytesPerPixel = this.getSampleByteSize(sample);
getPromise = this.getTileOrStrip(xTile, yTile, sample, poolOrDecoder, signal);
}
const promise = getPromise.then((tile) => {
const buffer3 = tile.data;
const dataView = new DataView(buffer3);
const blockHeight = this.getBlockHeight(tile.y);
const firstLine = tile.y * tileHeight;
const firstCol = tile.x * tileWidth;
const lastLine = firstLine + blockHeight;
const lastCol = (tile.x + 1) * tileWidth;
const reader = sampleReaders[si];
const ymax = Math.min(blockHeight, blockHeight - (lastLine - imageWindow[3]), imageHeight - firstLine);
const xmax = Math.min(tileWidth, tileWidth - (lastCol - imageWindow[2]), imageWidth - firstCol);
for (let y = Math.max(0, imageWindow[1] - firstLine); y < ymax; ++y) {
for (let x = Math.max(0, imageWindow[0] - firstCol); x < xmax; ++x) {
const pixelOffset = (y * tileWidth + x) * bytesPerPixel;
const value = reader.call(
dataView,
pixelOffset + srcSampleOffsets[si],
littleEndian
);
let windowCoordinate;
if (interleave) {
windowCoordinate = (y + firstLine - imageWindow[1]) * windowWidth * samples.length + (x + firstCol - imageWindow[0]) * samples.length + si;
valueArrays[windowCoordinate] = value;
} else {
windowCoordinate = (y + firstLine - imageWindow[1]) * windowWidth + x + firstCol - imageWindow[0];
valueArrays[si][windowCoordinate] = value;
}
}
}
});
promises.push(promise);
}
}
}
await Promise.all(promises);
if (width && imageWindow[2] - imageWindow[0] !== width || height && imageWindow[3] - imageWindow[1] !== height) {
let resampled;
if (interleave) {
resampled = resampleInterleaved(
valueArrays,
imageWindow[2] - imageWindow[0],
imageWindow[3] - imageWindow[1],
width,
height,
samples.length,
resampleMethod
);
} else {
resampled = resample(
valueArrays,
imageWindow[2] - imageWindow[0],
imageWindow[3] - imageWindow[1],
width,
height,
resampleMethod
);
}
resampled.width = width;
resampled.height = height;
return resampled;
}
valueArrays.width = width || imageWindow[2] - imageWindow[0];
valueArrays.height = height || imageWindow[3] - imageWindow[1];
return valueArrays;
}
/**
* Reads raster data from the image. This function reads all selected samples
* into separate arrays of the correct type for that sample or into a single
* combined array when `interleave` is set. When provided, only a subset
* of the raster is read for each sample.
*
* @param {ReadRasterOptions} [options={}] optional parameters
* @returns {Promise} the decoded arrays as a promise
*/
async readRasters({
window: wnd,
samples = [],
interleave,
pool = null,
width,
height,
resampleMethod,
fillValue,
signal
} = {}) {
const imageWindow = wnd || [0, 0, this.getWidth(), this.getHeight()];
if (imageWindow[0] > imageWindow[2] || imageWindow[1] > imageWindow[3]) {
throw new Error("Invalid subsets");
}
const imageWindowWidth = imageWindow[2] - imageWindow[0];
const imageWindowHeight = imageWindow[3] - imageWindow[1];
const numPixels = imageWindowWidth * imageWindowHeight;
const samplesPerPixel = this.getSamplesPerPixel();
if (!samples || !samples.length) {
for (let i = 0; i < samplesPerPixel; ++i) {
samples.push(i);
}
} else {
for (let i = 0; i < samples.length; ++i) {
if (samples[i] >= samplesPerPixel) {
return Promise.reject(new RangeError(`Invalid sample index '${samples[i]}'.`));
}
}
}
let valueArrays;
if (interleave) {
const format = this.fileDirectory.SampleFormat ? Math.max.apply(null, this.fileDirectory.SampleFormat) : 1;
const bitsPerSample = Math.max.apply(null, this.fileDirectory.BitsPerSample);
valueArrays = arrayForType(format, bitsPerSample, numPixels * samples.length);
if (fillValue) {
valueArrays.fill(fillValue);
}
} else {
valueArrays = [];
for (let i = 0; i < samples.length; ++i) {
const valueArray = this.getArrayForSample(samples[i], numPixels);
if (Array.isArray(fillValue) && i < fillValue.length) {
valueArray.fill(fillValue[i]);
} else if (fillValue && !Array.isArray(fillValue)) {
valueArray.fill(fillValue);
}
valueArrays.push(valueArray);
}
}
const poolOrDecoder = pool || await getDecoder(this.fileDirectory);
const result = await this._readRaster(
imageWindow,
samples,
valueArrays,
interleave,
poolOrDecoder,
width,
height,
resampleMethod,
signal
);
return result;
}
/**
* Reads raster data from the image as RGB. The result is always an
* interleaved typed array.
* Colorspaces other than RGB will be transformed to RGB, color maps expanded.
* When no other method is applicable, the first sample is used to produce a
* grayscale image.
* When provided, only a subset of the raster is read for each sample.
*
* @param {Object} [options] optional parameters
* @param {Array} [options.window] the subset to read data from in pixels.
* @param {boolean} [options.interleave=true] whether the data shall be read
* in one single array or separate
* arrays.
* @param {import("./geotiff").Pool} [options.pool=null] The optional decoder pool to use.
* @param {number} [options.width] The desired width of the output. When the width is no the
* same as the images, resampling will be performed.
* @param {number} [options.height] The desired height of the output. When the width is no the
* same as the images, resampling will be performed.
* @param {string} [options.resampleMethod='nearest'] The desired resampling method.
* @param {boolean} [options.enableAlpha=false] Enable reading alpha channel if present.
* @param {AbortSignal} [options.signal] An AbortSignal that may be signalled if the request is
* to be aborted
* @returns {Promise} the RGB array as a Promise
*/
async readRGB({
window: window2,
interleave = true,
pool = null,
width,
height,
resampleMethod,
enableAlpha = false,
signal
} = {}) {
const imageWindow = window2 || [0, 0, this.getWidth(), this.getHeight()];
if (imageWindow[0] > imageWindow[2] || imageWindow[1] > imageWindow[3]) {
throw new Error("Invalid subsets");
}
const pi = this.fileDirectory.PhotometricInterpretation;
if (pi === photometricInterpretations.RGB) {
let s = [0, 1, 2];
if (!(this.fileDirectory.ExtraSamples === ExtraSamplesValues.Unspecified) && enableAlpha) {
s = [];
for (let i = 0; i < this.fileDirectory.BitsPerSample.length; i += 1) {
s.push(i);
}
}
return this.readRasters({
window: window2,
interleave,
samples: s,
pool,
width,
height,
resampleMethod,
signal
});
}
let samples;
switch (pi) {
case photometricInterpretations.WhiteIsZero:
case photometricInterpretations.BlackIsZero:
case photometricInterpretations.Palette:
samples = [0];
break;
case photometricInterpretations.CMYK:
samples = [0, 1, 2, 3];
break;
case photometricInterpretations.YCbCr:
case photometricInterpretations.CIELab:
samples = [0, 1, 2];
break;
default:
throw new Error("Invalid or unsupported photometric interpretation.");
}
const subOptions = {
window: imageWindow,
interleave: true,
samples,
pool,
width,
height,
resampleMethod,
signal
};
const { fileDirectory } = this;
const raster = await this.readRasters(subOptions);
const max = 2 ** this.fileDirectory.BitsPerSample[0];
let data;
switch (pi) {
case photometricInterpretations.WhiteIsZero:
data = fromWhiteIsZero(raster, max);
break;
case photometricInterpretations.BlackIsZero:
data = fromBlackIsZero(raster, max);
break;
case photometricInterpretations.Palette:
data = fromPalette(raster, fileDirectory.ColorMap);
break;
case photometricInterpretations.CMYK:
data = fromCMYK(raster);
break;
case photometricInterpretations.YCbCr:
data = fromYCbCr(raster);
break;
case photometricInterpretations.CIELab:
data = fromCIELab(raster);
break;
default:
throw new Error("Unsupported photometric interpretation.");
}
if (!interleave) {
const red = new Uint8Array(data.length / 3);
const green = new Uint8Array(data.length / 3);
const blue = new Uint8Array(data.length / 3);
for (let i = 0, j = 0; i < data.length; i += 3, ++j) {
red[j] = data[i];
green[j] = data[i + 1];
blue[j] = data[i + 2];
}
data = [red, green, blue];
}
data.width = raster.width;
data.height = raster.height;
return data;
}
/**
* Returns an array of tiepoints.
* @returns {Object[]}
*/
getTiePoints() {
if (!this.fileDirectory.ModelTiepoint) {
return [];
}
const tiePoints = [];
for (let i = 0; i < this.fileDirectory.ModelTiepoint.length; i += 6) {
tiePoints.push({
i: this.fileDirectory.ModelTiepoint[i],
j: this.fileDirectory.ModelTiepoint[i + 1],
k: this.fileDirectory.ModelTiepoint[i + 2],
x: this.fileDirectory.ModelTiepoint[i + 3],
y: this.fileDirectory.ModelTiepoint[i + 4],
z: this.fileDirectory.ModelTiepoint[i + 5]
});
}
return tiePoints;
}
/**
* Returns the parsed GDAL metadata items.
*
* If sample is passed to null, dataset-level metadata will be returned.
* Otherwise only metadata specific to the provided sample will be returned.
*
* @param {number} [sample=null] The sample index.
* @returns {Object}
*/
getGDALMetadata(sample = null) {
const metadata = {};
if (!this.fileDirectory.GDAL_METADATA) {
return null;
}
const string = this.fileDirectory.GDAL_METADATA;
let items = (0, import_find_tags_by_name.default)(string, "Item");
if (sample === null) {
items = items.filter((item) => (0, import_get_attribute.default)(item, "sample") === void 0);
} else {
items = items.filter((item) => Number((0, import_get_attribute.default)(item, "sample")) === sample);
}
for (let i = 0; i < items.length; ++i) {
const item = items[i];
metadata[(0, import_get_attribute.default)(item, "name")] = item.inner;
}
return metadata;
}
/**
* Returns the GDAL nodata value
* @returns {number|null}
*/
getGDALNoData() {
if (!this.fileDirectory.GDAL_NODATA) {
return null;
}
const string = this.fileDirectory.GDAL_NODATA;
return Number(string.substring(0, string.length - 1));
}
/**
* Returns the image origin as a XYZ-vector. When the image has no affine
* transformation, then an exception is thrown.
* @returns {Array} The origin as a vector
*/
getOrigin() {
const tiePoints = this.fileDirectory.ModelTiepoint;
const modelTransformation = this.fileDirectory.ModelTransformation;
if (tiePoints && tiePoints.length === 6) {
return [
tiePoints[3],
tiePoints[4],
tiePoints[5]
];
}
if (modelTransformation) {
return [
modelTransformation[3],
modelTransformation[7],
modelTransformation[11]
];
}
throw new Error("The image does not have an affine transformation.");
}
/**
* Returns the image resolution as a XYZ-vector. When the image has no affine
* transformation, then an exception is thrown.
* @param {GeoTIFFImage} [referenceImage=null] A reference image to calculate the resolution from
* in cases when the current image does not have the
* required tags on its own.
* @returns {Array} The resolution as a vector
*/
getResolution(referenceImage = null) {
const modelPixelScale = this.fileDirectory.ModelPixelScale;
const modelTransformation = this.fileDirectory.ModelTransformation;
if (modelPixelScale) {
return [
modelPixelScale[0],
-modelPixelScale[1],
modelPixelScale[2]
];
}
if (modelTransformation) {
if (modelTransformation[1] === 0 && modelTransformation[4] === 0) {
return [
modelTransformation[0],
-modelTransformation[5],
modelTransformation[10]
];
}
return [
Math.sqrt(modelTransformation[0] * modelTransformation[0] + modelTransformation[4] * modelTransformation[4]),
-Math.sqrt(modelTransformation[1] * modelTransformation[1] + modelTransformation[5] * modelTransformation[5]),
modelTransformation[10]
];
}
if (referenceImage) {
const [refResX, refResY, refResZ] = referenceImage.getResolution();
return [
refResX * referenceImage.getWidth() / this.getWidth(),
refResY * referenceImage.getHeight() / this.getHeight(),
refResZ * referenceImage.getWidth() / this.getWidth()
];
}
throw new Error("The image does not have an affine transformation.");
}
/**
* Returns whether or not the pixels of the image depict an area (or point).
* @returns {Boolean} Whether the pixels are a point
*/
pixelIsArea() {
return this.geoKeys.GTRasterTypeGeoKey === 1;
}
/**
* Returns the image bounding box as an array of 4 values: min-x, min-y,
* max-x and max-y. When the image has no affine transformation, then an
* exception is thrown.
* @param {boolean} [tilegrid=false] If true return extent for a tilegrid
* without adjustment for ModelTransformation.
* @returns {Array} The bounding box
*/
getBoundingBox(tilegrid = false) {
const height = this.getHeight();
const width = this.getWidth();
if (this.fileDirectory.ModelTransformation && !tilegrid) {
const [a, b, c, d, e, f, g, h] = this.fileDirectory.ModelTransformation;
const corners = [
[0, 0],
[0, height],
[width, 0],
[width, height]
];
const projected = corners.map(([I, J]) => [
d + a * I + b * J,
h + e * I + f * J
]);
const xs = projected.map((pt) => pt[0]);
const ys = projected.map((pt) => pt[1]);
return [
Math.min(...xs),
Math.min(...ys),
Math.max(...xs),
Math.max(...ys)
];
} else {
const origin = this.getOrigin();
const resolution = this.getResolution();
const x1 = origin[0];
const y1 = origin[1];
const x2 = x1 + resolution[0] * width;
const y2 = y1 + resolution[1] * height;
return [
Math.min(x1, x2),
Math.min(y1, y2),
Math.max(x1, x2),
Math.max(y1, y2)
];
}
}
};
var geotiffimage_default = GeoTIFFImage;
// node_modules/geotiff/dist-module/dataview64.js
var DataView64 = class {
constructor(arrayBuffer) {
this._dataView = new DataView(arrayBuffer);
}
get buffer() {
return this._dataView.buffer;
}
getUint64(offset, littleEndian) {
const left = this.getUint32(offset, littleEndian);
const right = this.getUint32(offset + 4, littleEndian);
let combined;
if (littleEndian) {
combined = left + 2 ** 32 * right;
if (!Number.isSafeInteger(combined)) {
throw new Error(
`${combined} exceeds MAX_SAFE_INTEGER. Precision may be lost. Please report if you get this message to https://github.com/geotiffjs/geotiff.js/issues`
);
}
return combined;
}
combined = 2 ** 32 * left + right;
if (!Number.isSafeInteger(combined)) {
throw new Error(
`${combined} exceeds MAX_SAFE_INTEGER. Precision may be lost. Please report if you get this message to https://github.com/geotiffjs/geotiff.js/issues`
);
}
return combined;
}
// adapted from https://stackoverflow.com/a/55338384/8060591
getInt64(offset, littleEndian) {
let value = 0;
const isNegative = (this._dataView.getUint8(offset + (littleEndian ? 7 : 0)) & 128) > 0;
let carrying = true;
for (let i = 0; i < 8; i++) {
let byte = this._dataView.getUint8(offset + (littleEndian ? i : 7 - i));
if (isNegative) {
if (carrying) {
if (byte !== 0) {
byte = ~(byte - 1) & 255;
carrying = false;
}
} else {
byte = ~byte & 255;
}
}
value += byte * 256 ** i;
}
if (isNegative) {
value = -value;
}
return value;
}
getUint8(offset, littleEndian) {
return this._dataView.getUint8(offset, littleEndian);
}
getInt8(offset, littleEndian) {
return this._dataView.getInt8(offset, littleEndian);
}
getUint16(offset, littleEndian) {
return this._dataView.getUint16(offset, littleEndian);
}
getInt16(offset, littleEndian) {
return this._dataView.getInt16(offset, littleEndian);
}
getUint32(offset, littleEndian) {
return this._dataView.getUint32(offset, littleEndian);
}
getInt32(offset, littleEndian) {
return this._dataView.getInt32(offset, littleEndian);
}
getFloat16(offset, littleEndian) {
return getFloat16(this._dataView, offset, littleEndian);
}
getFloat32(offset, littleEndian) {
return this._dataView.getFloat32(offset, littleEndian);
}
getFloat64(offset, littleEndian) {
return this._dataView.getFloat64(offset, littleEndian);
}
};
// node_modules/geotiff/dist-module/dataslice.js
var DataSlice = class {
constructor(arrayBuffer, sliceOffset, littleEndian, bigTiff) {
this._dataView = new DataView(arrayBuffer);
this._sliceOffset = sliceOffset;
this._littleEndian = littleEndian;
this._bigTiff = bigTiff;
}
get sliceOffset() {
return this._sliceOffset;
}
get sliceTop() {
return this._sliceOffset + this.buffer.byteLength;
}
get littleEndian() {
return this._littleEndian;
}
get bigTiff() {
return this._bigTiff;
}
get buffer() {
return this._dataView.buffer;
}
covers(offset, length) {
return this.sliceOffset <= offset && this.sliceTop >= offset + length;
}
readUint8(offset) {
return this._dataView.getUint8(
offset - this._sliceOffset,
this._littleEndian
);
}
readInt8(offset) {
return this._dataView.getInt8(
offset - this._sliceOffset,
this._littleEndian
);
}
readUint16(offset) {
return this._dataView.getUint16(
offset - this._sliceOffset,
this._littleEndian
);
}
readInt16(offset) {
return this._dataView.getInt16(
offset - this._sliceOffset,
this._littleEndian
);
}
readUint32(offset) {
return this._dataView.getUint32(
offset - this._sliceOffset,
this._littleEndian
);
}
readInt32(offset) {
return this._dataView.getInt32(
offset - this._sliceOffset,
this._littleEndian
);
}
readFloat32(offset) {
return this._dataView.getFloat32(
offset - this._sliceOffset,
this._littleEndian
);
}
readFloat64(offset) {
return this._dataView.getFloat64(
offset - this._sliceOffset,
this._littleEndian
);
}
readUint64(offset) {
const left = this.readUint32(offset);
const right = this.readUint32(offset + 4);
let combined;
if (this._littleEndian) {
combined = left + 2 ** 32 * right;
if (!Number.isSafeInteger(combined)) {
throw new Error(
`${combined} exceeds MAX_SAFE_INTEGER. Precision may be lost. Please report if you get this message to https://github.com/geotiffjs/geotiff.js/issues`
);
}
return combined;
}
combined = 2 ** 32 * left + right;
if (!Number.isSafeInteger(combined)) {
throw new Error(
`${combined} exceeds MAX_SAFE_INTEGER. Precision may be lost. Please report if you get this message to https://github.com/geotiffjs/geotiff.js/issues`
);
}
return combined;
}
// adapted from https://stackoverflow.com/a/55338384/8060591
readInt64(offset) {
let value = 0;
const isNegative = (this._dataView.getUint8(offset + (this._littleEndian ? 7 : 0)) & 128) > 0;
let carrying = true;
for (let i = 0; i < 8; i++) {
let byte = this._dataView.getUint8(
offset + (this._littleEndian ? i : 7 - i)
);
if (isNegative) {
if (carrying) {
if (byte !== 0) {
byte = ~(byte - 1) & 255;
carrying = false;
}
} else {
byte = ~byte & 255;
}
}
value += byte * 256 ** i;
}
if (isNegative) {
value = -value;
}
return value;
}
readOffset(offset) {
if (this._bigTiff) {
return this.readUint64(offset);
}
return this.readUint32(offset);
}
};
// node_modules/geotiff/dist-module/pool.js
var defaultPoolSize = typeof navigator !== "undefined" ? navigator.hardwareConcurrency || 2 : 2;
var Pool = class {
/**
* @constructor
* @param {Number} [size] The size of the pool. Defaults to the number of CPUs
* available. When this parameter is `null` or 0, then the
* decoding will be done in the main thread.
* @param {function(): Worker} [createWorker] A function that creates the decoder worker.
* Defaults to a worker with all decoders that ship with geotiff.js. The `createWorker()`
* function is expected to return a `Worker` compatible with Web Workers. For code that
* runs in Node, [web-worker](https://www.npmjs.com/package/web-worker) is a good choice.
*
* A worker that uses a custom lzw decoder would look like this `my-custom-worker.js` file:
* ```js
* import { addDecoder, getDecoder } from 'geotiff';
* addDecoder(5, () => import ('./my-custom-lzw').then((m) => m.default));
* self.addEventListener('message', async (e) => {
* const { id, fileDirectory, buffer } = e.data;
* const decoder = await getDecoder(fileDirectory);
* const decoded = await decoder.decode(fileDirectory, buffer);
* self.postMessage({ decoded, id }, [decoded]);
* });
* ```
* The way the above code is built into a worker by the `createWorker()` function
* depends on the used bundler. For most bundlers, something like this will work:
* ```js
* function createWorker() {
* return new Worker(new URL('./my-custom-worker.js', import.meta.url));
* }
* ```
*/
constructor(size = defaultPoolSize, createWorker2) {
this.workers = null;
this._awaitingDecoder = null;
this.size = size;
this.messageId = 0;
if (size) {
this._awaitingDecoder = createWorker2 ? Promise.resolve(createWorker2) : new Promise((resolve) => {
import("./decoder-FUDNTCPN.js").then((module) => {
resolve(module.create);
});
});
this._awaitingDecoder.then((create2) => {
this._awaitingDecoder = null;
this.workers = [];
for (let i = 0; i < size; i++) {
this.workers.push({ worker: create2(), idle: true });
}
});
}
}
/**
* Decode the given block of bytes with the set compression method.
* @param {ArrayBuffer} buffer the array buffer of bytes to decode.
* @returns {Promise} the decoded result as a `Promise`
*/
async decode(fileDirectory, buffer3) {
if (this._awaitingDecoder) {
await this._awaitingDecoder;
}
return this.size === 0 ? getDecoder(fileDirectory).then((decoder) => decoder.decode(fileDirectory, buffer3)) : new Promise((resolve) => {
const worker = this.workers.find((candidate) => candidate.idle) || this.workers[Math.floor(Math.random() * this.size)];
worker.idle = false;
const id = this.messageId++;
const onMessage = (e) => {
if (e.data.id === id) {
worker.idle = true;
resolve(e.data.decoded);
worker.worker.removeEventListener("message", onMessage);
}
};
worker.worker.addEventListener("message", onMessage);
worker.worker.postMessage({ fileDirectory, buffer: buffer3, id }, [buffer3]);
});
}
destroy() {
if (this.workers) {
this.workers.forEach((worker) => {
worker.worker.terminate();
});
this.workers = null;
}
}
};
var pool_default = Pool;
// node_modules/geotiff/dist-module/source/httputils.js
var CRLFCRLF = "\r\n\r\n";
function itemsToObject(items) {
if (typeof Object.fromEntries !== "undefined") {
return Object.fromEntries(items);
}
const obj = {};
for (const [key, value] of items) {
obj[key.toLowerCase()] = value;
}
return obj;
}
function parseHeaders(text) {
const items = text.split("\r\n").map((line) => {
const kv = line.split(":").map((str) => str.trim());
kv[0] = kv[0].toLowerCase();
return kv;
});
return itemsToObject(items);
}
function parseContentType(rawContentType) {
const [type, ...rawParams] = rawContentType.split(";").map((s) => s.trim());
const paramsItems = rawParams.map((param) => param.split("="));
return { type, params: itemsToObject(paramsItems) };
}
function parseContentRange(rawContentRange) {
let start;
let end;
let total;
if (rawContentRange) {
[, start, end, total] = rawContentRange.match(/bytes (\d+)-(\d+)\/(\d+)/);
start = parseInt(start, 10);
end = parseInt(end, 10);
total = parseInt(total, 10);
}
return { start, end, total };
}
function parseByteRanges(responseArrayBuffer, boundary) {
let offset = null;
const decoder = new TextDecoder("ascii");
const out = [];
const startBoundary = `--${boundary}`;
const endBoundary = `${startBoundary}--`;
for (let i = 0; i < 10; ++i) {
const text = decoder.decode(
new Uint8Array(responseArrayBuffer, i, startBoundary.length)
);
if (text === startBoundary) {
offset = i;
}
}
if (offset === null) {
throw new Error("Could not find initial boundary");
}
while (offset < responseArrayBuffer.byteLength) {
const text = decoder.decode(
new Uint8Array(
responseArrayBuffer,
offset,
Math.min(startBoundary.length + 1024, responseArrayBuffer.byteLength - offset)
)
);
if (text.length === 0 || text.startsWith(endBoundary)) {
break;
}
if (!text.startsWith(startBoundary)) {
throw new Error("Part does not start with boundary");
}
const innerText = text.substr(startBoundary.length + 2);
if (innerText.length === 0) {
break;
}
const endOfHeaders = innerText.indexOf(CRLFCRLF);
const headers = parseHeaders(innerText.substr(0, endOfHeaders));
const { start, end, total } = parseContentRange(headers["content-range"]);
const startOfData = offset + startBoundary.length + endOfHeaders + CRLFCRLF.length;
const length = parseInt(end, 10) + 1 - parseInt(start, 10);
out.push({
headers,
data: responseArrayBuffer.slice(startOfData, startOfData + length),
offset: start,
length,
fileSize: total
});
offset = startOfData + length + 4;
}
return out;
}
// node_modules/geotiff/dist-module/source/basesource.js
var BaseSource = class {
/**
*
* @param {Slice[]} slices
* @returns {ArrayBuffer[]}
*/
async fetch(slices, signal = void 0) {
return Promise.all(
slices.map((slice) => this.fetchSlice(slice, signal))
);
}
/**
*
* @param {Slice} slice
* @returns {ArrayBuffer}
*/
async fetchSlice(slice) {
throw new Error(`fetching of slice ${slice} not possible, not implemented`);
}
/**
* Returns the filesize if already determined and null otherwise
*/
get fileSize() {
return null;
}
async close() {
}
};
// node_modules/quick-lru/index.js
var QuickLRU = class extends Map {
constructor(options = {}) {
super();
if (!(options.maxSize && options.maxSize > 0)) {
throw new TypeError("`maxSize` must be a number greater than 0");
}
if (typeof options.maxAge === "number" && options.maxAge === 0) {
throw new TypeError("`maxAge` must be a number greater than 0");
}
this.maxSize = options.maxSize;
this.maxAge = options.maxAge || Number.POSITIVE_INFINITY;
this.onEviction = options.onEviction;
this.cache = /* @__PURE__ */ new Map();
this.oldCache = /* @__PURE__ */ new Map();
this._size = 0;
}
// TODO: Use private class methods when targeting Node.js 16.
_emitEvictions(cache) {
if (typeof this.onEviction !== "function") {
return;
}
for (const [key, item] of cache) {
this.onEviction(key, item.value);
}
}
_deleteIfExpired(key, item) {
if (typeof item.expiry === "number" && item.expiry <= Date.now()) {
if (typeof this.onEviction === "function") {
this.onEviction(key, item.value);
}
return this.delete(key);
}
return false;
}
_getOrDeleteIfExpired(key, item) {
const deleted = this._deleteIfExpired(key, item);
if (deleted === false) {
return item.value;
}
}
_getItemValue(key, item) {
return item.expiry ? this._getOrDeleteIfExpired(key, item) : item.value;
}
_peek(key, cache) {
const item = cache.get(key);
return this._getItemValue(key, item);
}
_set(key, value) {
this.cache.set(key, value);
this._size++;
if (this._size >= this.maxSize) {
this._size = 0;
this._emitEvictions(this.oldCache);
this.oldCache = this.cache;
this.cache = /* @__PURE__ */ new Map();
}
}
_moveToRecent(key, item) {
this.oldCache.delete(key);
this._set(key, item);
}
*_entriesAscending() {
for (const item of this.oldCache) {
const [key, value] = item;
if (!this.cache.has(key)) {
const deleted = this._deleteIfExpired(key, value);
if (deleted === false) {
yield item;
}
}
}
for (const item of this.cache) {
const [key, value] = item;
const deleted = this._deleteIfExpired(key, value);
if (deleted === false) {
yield item;
}
}
}
get(key) {
if (this.cache.has(key)) {
const item = this.cache.get(key);
return this._getItemValue(key, item);
}
if (this.oldCache.has(key)) {
const item = this.oldCache.get(key);
if (this._deleteIfExpired(key, item) === false) {
this._moveToRecent(key, item);
return item.value;
}
}
}
set(key, value, { maxAge = this.maxAge } = {}) {
const expiry = typeof maxAge === "number" && maxAge !== Number.POSITIVE_INFINITY ? Date.now() + maxAge : void 0;
if (this.cache.has(key)) {
this.cache.set(key, {
value,
expiry
});
} else {
this._set(key, { value, expiry });
}
return this;
}
has(key) {
if (this.cache.has(key)) {
return !this._deleteIfExpired(key, this.cache.get(key));
}
if (this.oldCache.has(key)) {
return !this._deleteIfExpired(key, this.oldCache.get(key));
}
return false;
}
peek(key) {
if (this.cache.has(key)) {
return this._peek(key, this.cache);
}
if (this.oldCache.has(key)) {
return this._peek(key, this.oldCache);
}
}
delete(key) {
const deleted = this.cache.delete(key);
if (deleted) {
this._size--;
}
return this.oldCache.delete(key) || deleted;
}
clear() {
this.cache.clear();
this.oldCache.clear();
this._size = 0;
}
resize(newSize) {
if (!(newSize && newSize > 0)) {
throw new TypeError("`maxSize` must be a number greater than 0");
}
const items = [...this._entriesAscending()];
const removeCount = items.length - newSize;
if (removeCount < 0) {
this.cache = new Map(items);
this.oldCache = /* @__PURE__ */ new Map();
this._size = items.length;
} else {
if (removeCount > 0) {
this._emitEvictions(items.slice(0, removeCount));
}
this.oldCache = new Map(items.slice(removeCount));
this.cache = /* @__PURE__ */ new Map();
this._size = 0;
}
this.maxSize = newSize;
}
*keys() {
for (const [key] of this) {
yield key;
}
}
*values() {
for (const [, value] of this) {
yield value;
}
}
*[Symbol.iterator]() {
for (const item of this.cache) {
const [key, value] = item;
const deleted = this._deleteIfExpired(key, value);
if (deleted === false) {
yield [key, value.value];
}
}
for (const item of this.oldCache) {
const [key, value] = item;
if (!this.cache.has(key)) {
const deleted = this._deleteIfExpired(key, value);
if (deleted === false) {
yield [key, value.value];
}
}
}
}
*entriesDescending() {
let items = [...this.cache];
for (let i = items.length - 1; i >= 0; --i) {
const item = items[i];
const [key, value] = item;
const deleted = this._deleteIfExpired(key, value);
if (deleted === false) {
yield [key, value.value];
}
}
items = [...this.oldCache];
for (let i = items.length - 1; i >= 0; --i) {
const item = items[i];
const [key, value] = item;
if (!this.cache.has(key)) {
const deleted = this._deleteIfExpired(key, value);
if (deleted === false) {
yield [key, value.value];
}
}
}
}
*entriesAscending() {
for (const [key, value] of this._entriesAscending()) {
yield [key, value.value];
}
}
get size() {
if (!this._size) {
return this.oldCache.size;
}
let oldCacheSize = 0;
for (const key of this.oldCache.keys()) {
if (!this.cache.has(key)) {
oldCacheSize++;
}
}
return Math.min(this._size + oldCacheSize, this.maxSize);
}
entries() {
return this.entriesAscending();
}
forEach(callbackFunction, thisArgument = this) {
for (const [key, value] of this.entriesAscending()) {
callbackFunction.call(thisArgument, value, key, this);
}
}
get [Symbol.toStringTag]() {
return JSON.stringify([...this.entriesAscending()]);
}
};
// node_modules/geotiff/dist-module/utils.js
function assign(target, source) {
for (const key in source) {
if (source.hasOwnProperty(key)) {
target[key] = source[key];
}
}
}
function invert(oldObj) {
const newObj = {};
for (const key in oldObj) {
if (oldObj.hasOwnProperty(key)) {
const value = oldObj[key];
newObj[value] = key;
}
}
return newObj;
}
function times(numTimes, func) {
const results = [];
for (let i = 0; i < numTimes; i++) {
results.push(func(i));
}
return results;
}
async function wait(milliseconds) {
return new Promise((resolve) => setTimeout(resolve, milliseconds));
}
function zip(a, b) {
const A = Array.isArray(a) ? a : Array.from(a);
const B = Array.isArray(b) ? b : Array.from(b);
return A.map((k, i) => [k, B[i]]);
}
var AbortError = class _AbortError extends Error {
constructor(params) {
super(params);
if (Error.captureStackTrace) {
Error.captureStackTrace(this, _AbortError);
}
this.name = "AbortError";
}
};
var CustomAggregateError = class extends Error {
constructor(errors, message) {
super(message);
this.errors = errors;
this.message = message;
this.name = "AggregateError";
}
};
var AggregateError = CustomAggregateError;
// node_modules/geotiff/dist-module/source/blockedsource.js
var Block = class {
/**
*
* @param {number} offset
* @param {number} length
* @param {ArrayBuffer} [data]
*/
constructor(offset, length, data = null) {
this.offset = offset;
this.length = length;
this.data = data;
}
/**
* @returns {number} the top byte border
*/
get top() {
return this.offset + this.length;
}
};
var BlockGroup = class {
/**
*
* @param {number} offset
* @param {number} length
* @param {number[]} blockIds
*/
constructor(offset, length, blockIds) {
this.offset = offset;
this.length = length;
this.blockIds = blockIds;
}
};
var BlockedSource = class extends BaseSource {
/**
*
* @param {BaseSource} source The underlying source that shall be blocked and cached
* @param {object} options
* @param {number} [options.blockSize]
* @param {number} [options.cacheSize]
*/
constructor(source, { blockSize = 65536, cacheSize = 100 } = {}) {
super();
this.source = source;
this.blockSize = blockSize;
this.blockCache = new QuickLRU({
maxSize: cacheSize,
onEviction: (blockId, block) => {
this.evictedBlocks.set(blockId, block);
}
});
this.evictedBlocks = /* @__PURE__ */ new Map();
this.blockRequests = /* @__PURE__ */ new Map();
this.blockIdsToFetch = /* @__PURE__ */ new Set();
this.abortedBlockIds = /* @__PURE__ */ new Set();
}
get fileSize() {
return this.source.fileSize;
}
/**
*
* @param {import("./basesource").Slice[]} slices
*/
async fetch(slices, signal) {
const blockRequests = [];
const missingBlockIds = [];
const allBlockIds = [];
this.evictedBlocks.clear();
for (const { offset, length } of slices) {
let top = offset + length;
const { fileSize } = this;
if (fileSize !== null) {
top = Math.min(top, fileSize);
}
const firstBlockOffset = Math.floor(offset / this.blockSize) * this.blockSize;
for (let current = firstBlockOffset; current < top; current += this.blockSize) {
const blockId = Math.floor(current / this.blockSize);
if (!this.blockCache.has(blockId) && !this.blockRequests.has(blockId)) {
this.blockIdsToFetch.add(blockId);
missingBlockIds.push(blockId);
}
if (this.blockRequests.has(blockId)) {
blockRequests.push(this.blockRequests.get(blockId));
}
allBlockIds.push(blockId);
}
}
await wait();
this.fetchBlocks(signal);
const missingRequests = [];
for (const blockId of missingBlockIds) {
if (this.blockRequests.has(blockId)) {
missingRequests.push(this.blockRequests.get(blockId));
}
}
await Promise.allSettled(blockRequests);
await Promise.allSettled(missingRequests);
const abortedBlockRequests = [];
const abortedBlockIds = allBlockIds.filter((id) => this.abortedBlockIds.has(id) || !this.blockCache.has(id));
abortedBlockIds.forEach((id) => this.blockIdsToFetch.add(id));
if (abortedBlockIds.length > 0 && signal && !signal.aborted) {
this.fetchBlocks(null);
for (const blockId of abortedBlockIds) {
const block = this.blockRequests.get(blockId);
if (!block) {
throw new Error(`Block ${blockId} is not in the block requests`);
}
abortedBlockRequests.push(block);
}
await Promise.allSettled(abortedBlockRequests);
}
if (signal && signal.aborted) {
throw new AbortError("Request was aborted");
}
const blocks = allBlockIds.map((id) => this.blockCache.get(id) || this.evictedBlocks.get(id));
const failedBlocks = blocks.filter((i) => !i);
if (failedBlocks.length) {
throw new AggregateError(failedBlocks, "Request failed");
}
const requiredBlocks = new Map(zip(allBlockIds, blocks));
return this.readSliceData(slices, requiredBlocks);
}
/**
*
* @param {AbortSignal} signal
*/
fetchBlocks(signal) {
if (this.blockIdsToFetch.size > 0) {
const groups = this.groupBlocks(this.blockIdsToFetch);
const groupRequests = this.source.fetch(groups, signal);
for (let groupIndex = 0; groupIndex < groups.length; ++groupIndex) {
const group = groups[groupIndex];
for (const blockId of group.blockIds) {
this.blockRequests.set(blockId, (async () => {
try {
const response = (await groupRequests)[groupIndex];
const blockOffset = blockId * this.blockSize;
const o = blockOffset - response.offset;
const t = Math.min(o + this.blockSize, response.data.byteLength);
const data = response.data.slice(o, t);
const block = new Block(
blockOffset,
data.byteLength,
data,
blockId
);
this.blockCache.set(blockId, block);
this.abortedBlockIds.delete(blockId);
} catch (err) {
if (err.name === "AbortError") {
err.signal = signal;
this.blockCache.delete(blockId);
this.abortedBlockIds.add(blockId);
} else {
throw err;
}
} finally {
this.blockRequests.delete(blockId);
}
})());
}
}
this.blockIdsToFetch.clear();
}
}
/**
*
* @param {Set} blockIds
* @returns {BlockGroup[]}
*/
groupBlocks(blockIds) {
const sortedBlockIds = Array.from(blockIds).sort((a, b) => a - b);
if (sortedBlockIds.length === 0) {
return [];
}
let current = [];
let lastBlockId = null;
const groups = [];
for (const blockId of sortedBlockIds) {
if (lastBlockId === null || lastBlockId + 1 === blockId) {
current.push(blockId);
lastBlockId = blockId;
} else {
groups.push(new BlockGroup(
current[0] * this.blockSize,
current.length * this.blockSize,
current
));
current = [blockId];
lastBlockId = blockId;
}
}
groups.push(new BlockGroup(
current[0] * this.blockSize,
current.length * this.blockSize,
current
));
return groups;
}
/**
*
* @param {import("./basesource").Slice[]} slices
* @param {Map} blocks
*/
readSliceData(slices, blocks) {
return slices.map((slice) => {
let top = slice.offset + slice.length;
if (this.fileSize !== null) {
top = Math.min(this.fileSize, top);
}
const blockIdLow = Math.floor(slice.offset / this.blockSize);
const blockIdHigh = Math.floor(top / this.blockSize);
const sliceData = new ArrayBuffer(slice.length);
const sliceView = new Uint8Array(sliceData);
for (let blockId = blockIdLow; blockId <= blockIdHigh; ++blockId) {
const block = blocks.get(blockId);
const delta = block.offset - slice.offset;
const topDelta = block.top - top;
let blockInnerOffset = 0;
let rangeInnerOffset = 0;
let usedBlockLength;
if (delta < 0) {
blockInnerOffset = -delta;
} else if (delta > 0) {
rangeInnerOffset = delta;
}
if (topDelta < 0) {
usedBlockLength = block.length - blockInnerOffset;
} else {
usedBlockLength = top - block.offset - blockInnerOffset;
}
const blockView = new Uint8Array(block.data, blockInnerOffset, usedBlockLength);
sliceView.set(blockView, rangeInnerOffset);
}
return sliceData;
});
}
};
// node_modules/geotiff/dist-module/source/client/base.js
var BaseResponse = class {
/**
* Returns whether the response has an ok'ish status code
*/
get ok() {
return this.status >= 200 && this.status <= 299;
}
/**
* Returns the status code of the response
*/
get status() {
throw new Error("not implemented");
}
/**
* Returns the value of the specified header
* @param {string} headerName the header name
* @returns {string} the header value
*/
getHeader(headerName) {
throw new Error("not implemented");
}
/**
* @returns {ArrayBuffer} the response data of the request
*/
async getData() {
throw new Error("not implemented");
}
};
var BaseClient = class {
constructor(url) {
this.url = url;
}
/**
* Send a request with the options
* @param {{headers: HeadersInit, signal: AbortSignal}} [options={}]
* @returns {Promise}
*/
async request({ headers, signal } = {}) {
throw new Error("request is not implemented");
}
};
// node_modules/geotiff/dist-module/source/client/fetch.js
var FetchResponse = class extends BaseResponse {
/**
* BaseResponse facade for fetch API Response
* @param {Response} response
*/
constructor(response) {
super();
this.response = response;
}
get status() {
return this.response.status;
}
getHeader(name) {
return this.response.headers.get(name);
}
async getData() {
const data = this.response.arrayBuffer ? await this.response.arrayBuffer() : (await this.response.buffer()).buffer;
return data;
}
};
var FetchClient = class extends BaseClient {
constructor(url, credentials) {
super(url);
this.credentials = credentials;
}
/**
* @param {{headers: HeadersInit, signal: AbortSignal}} [options={}]
* @returns {Promise}
*/
async request({ headers, signal } = {}) {
const response = await fetch(this.url, {
headers,
credentials: this.credentials,
signal
});
return new FetchResponse(response);
}
};
// node_modules/geotiff/dist-module/source/client/xhr.js
var XHRResponse = class extends BaseResponse {
/**
* BaseResponse facade for XMLHttpRequest
* @param {XMLHttpRequest} xhr
* @param {ArrayBuffer} data
*/
constructor(xhr, data) {
super();
this.xhr = xhr;
this.data = data;
}
get status() {
return this.xhr.status;
}
getHeader(name) {
return this.xhr.getResponseHeader(name);
}
async getData() {
return this.data;
}
};
var XHRClient = class extends BaseClient {
constructRequest(headers, signal) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", this.url);
xhr.responseType = "arraybuffer";
for (const [key, value] of Object.entries(headers)) {
xhr.setRequestHeader(key, value);
}
xhr.onload = () => {
const data = xhr.response;
resolve(new XHRResponse(xhr, data));
};
xhr.onerror = reject;
xhr.onabort = () => reject(new AbortError("Request aborted"));
xhr.send();
if (signal) {
if (signal.aborted) {
xhr.abort();
}
signal.addEventListener("abort", () => xhr.abort());
}
});
}
async request({ headers, signal } = {}) {
const response = await this.constructRequest(headers, signal);
return response;
}
};
// node_modules/geotiff/dist-module/source/client/http.js
var import_http = __toESM(require_http(), 1);
var import_https = __toESM(require_https(), 1);
var import_url = __toESM(require_url(), 1);
var HttpResponse = class extends BaseResponse {
/**
* BaseResponse facade for node HTTP/HTTPS API Response
* @param {http.ServerResponse} response
*/
constructor(response, dataPromise) {
super();
this.response = response;
this.dataPromise = dataPromise;
}
get status() {
return this.response.statusCode;
}
getHeader(name) {
return this.response.headers[name];
}
async getData() {
const data = await this.dataPromise;
return data;
}
};
var HttpClient = class extends BaseClient {
constructor(url) {
super(url);
this.parsedUrl = import_url.default.parse(this.url);
this.httpApi = this.parsedUrl.protocol === "http:" ? import_http.default : import_https.default;
}
constructRequest(headers, signal) {
return new Promise((resolve, reject) => {
const request = this.httpApi.get(
{
...this.parsedUrl,
headers
},
(response) => {
const dataPromise = new Promise((resolveData) => {
const chunks = [];
response.on("data", (chunk) => {
chunks.push(chunk);
});
response.on("end", () => {
const data = Buffer.concat(chunks).buffer;
resolveData(data);
});
response.on("error", reject);
});
resolve(new HttpResponse(response, dataPromise));
}
);
request.on("error", reject);
if (signal) {
if (signal.aborted) {
request.destroy(new AbortError("Request aborted"));
}
signal.addEventListener("abort", () => request.destroy(new AbortError("Request aborted")));
}
});
}
async request({ headers, signal } = {}) {
const response = await this.constructRequest(headers, signal);
return response;
}
};
// node_modules/geotiff/dist-module/source/remote.js
var RemoteSource = class extends BaseSource {
/**
*
* @param {BaseClient} client
* @param {object} headers
* @param {numbers} maxRanges
* @param {boolean} allowFullFile
*/
constructor(client, headers, maxRanges, allowFullFile) {
super();
this.client = client;
this.headers = headers;
this.maxRanges = maxRanges;
this.allowFullFile = allowFullFile;
this._fileSize = null;
}
/**
*
* @param {Slice[]} slices
*/
async fetch(slices, signal) {
if (this.maxRanges >= slices.length) {
return this.fetchSlices(slices, signal);
} else if (this.maxRanges > 0 && slices.length > 1) {
}
return Promise.all(
slices.map((slice) => this.fetchSlice(slice, signal))
);
}
async fetchSlices(slices, signal) {
const response = await this.client.request({
headers: {
...this.headers,
Range: `bytes=${slices.map(({ offset, length }) => `${offset}-${offset + length}`).join(",")}`
},
signal
});
if (!response.ok) {
throw new Error("Error fetching data.");
} else if (response.status === 206) {
const { type, params } = parseContentType(response.getHeader("content-type"));
if (type === "multipart/byteranges") {
const byteRanges = parseByteRanges(await response.getData(), params.boundary);
this._fileSize = byteRanges[0].fileSize || null;
return byteRanges;
}
const data = await response.getData();
const { start, end, total } = parseContentRange(response.getHeader("content-range"));
this._fileSize = total || null;
const first = [{
data,
offset: start,
length: end - start
}];
if (slices.length > 1) {
const others = await Promise.all(slices.slice(1).map((slice) => this.fetchSlice(slice, signal)));
return first.concat(others);
}
return first;
} else {
if (!this.allowFullFile) {
throw new Error("Server responded with full file");
}
const data = await response.getData();
this._fileSize = data.byteLength;
return [{
data,
offset: 0,
length: data.byteLength
}];
}
}
async fetchSlice(slice, signal) {
const { offset, length } = slice;
const response = await this.client.request({
headers: {
...this.headers,
Range: `bytes=${offset}-${offset + length}`
},
signal
});
if (!response.ok) {
throw new Error("Error fetching data.");
} else if (response.status === 206) {
const data = await response.getData();
const { total } = parseContentRange(response.getHeader("content-range"));
this._fileSize = total || null;
return {
data,
offset,
length
};
} else {
if (!this.allowFullFile) {
throw new Error("Server responded with full file");
}
const data = await response.getData();
this._fileSize = data.byteLength;
return {
data,
offset: 0,
length: data.byteLength
};
}
}
get fileSize() {
return this._fileSize;
}
};
function maybeWrapInBlockedSource(source, { blockSize, cacheSize }) {
if (blockSize === null) {
return source;
}
return new BlockedSource(source, { blockSize, cacheSize });
}
function makeFetchSource(url, { headers = {}, credentials, maxRanges = 0, allowFullFile = false, ...blockOptions } = {}) {
const client = new FetchClient(url, credentials);
const source = new RemoteSource(client, headers, maxRanges, allowFullFile);
return maybeWrapInBlockedSource(source, blockOptions);
}
function makeXHRSource(url, { headers = {}, maxRanges = 0, allowFullFile = false, ...blockOptions } = {}) {
const client = new XHRClient(url);
const source = new RemoteSource(client, headers, maxRanges, allowFullFile);
return maybeWrapInBlockedSource(source, blockOptions);
}
function makeHttpSource(url, { headers = {}, maxRanges = 0, allowFullFile = false, ...blockOptions } = {}) {
const client = new HttpClient(url);
const source = new RemoteSource(client, headers, maxRanges, allowFullFile);
return maybeWrapInBlockedSource(source, blockOptions);
}
function makeRemoteSource(url, { forceXHR = false, ...clientOptions } = {}) {
if (typeof fetch === "function" && !forceXHR) {
return makeFetchSource(url, clientOptions);
}
if (typeof XMLHttpRequest !== "undefined") {
return makeXHRSource(url, clientOptions);
}
return makeHttpSource(url, clientOptions);
}
// node_modules/geotiff/dist-module/source/filereader.js
var FileReaderSource = class extends BaseSource {
constructor(file) {
super();
this.file = file;
}
async fetchSlice(slice, signal) {
return new Promise((resolve, reject) => {
const blob = this.file.slice(slice.offset, slice.offset + slice.length);
const reader = new FileReader();
reader.onload = (event) => resolve(event.target.result);
reader.onerror = reject;
reader.onabort = reject;
reader.readAsArrayBuffer(blob);
if (signal) {
signal.addEventListener("abort", () => reader.abort());
}
});
}
};
function makeFileReaderSource(file) {
return new FileReaderSource(file);
}
// node_modules/geotiff/dist-module/source/file.js
var import_fs = __toESM(require_fs(), 1);
// node_modules/geotiff/dist-module/geotiffwriter.js
var tagName2Code = invert(fieldTagNames);
var geoKeyName2Code = invert(geoKeyNames);
var name2code = {};
assign(name2code, tagName2Code);
assign(name2code, geoKeyName2Code);
var typeName2byte = invert(fieldTypeNames);
var _binBE = {
nextZero: (data, o) => {
let oincr = o;
while (data[oincr] !== 0) {
oincr++;
}
return oincr;
},
readUshort: (buff, p) => {
return buff[p] << 8 | buff[p + 1];
},
readShort: (buff, p) => {
const a = _binBE.ui8;
a[0] = buff[p + 1];
a[1] = buff[p + 0];
return _binBE.i16[0];
},
readInt: (buff, p) => {
const a = _binBE.ui8;
a[0] = buff[p + 3];
a[1] = buff[p + 2];
a[2] = buff[p + 1];
a[3] = buff[p + 0];
return _binBE.i32[0];
},
readUint: (buff, p) => {
const a = _binBE.ui8;
a[0] = buff[p + 3];
a[1] = buff[p + 2];
a[2] = buff[p + 1];
a[3] = buff[p + 0];
return _binBE.ui32[0];
},
readASCII: (buff, p, l) => {
return l.map((i) => String.fromCharCode(buff[p + i])).join("");
},
readFloat: (buff, p) => {
const a = _binBE.ui8;
times(4, (i) => {
a[i] = buff[p + 3 - i];
});
return _binBE.fl32[0];
},
readDouble: (buff, p) => {
const a = _binBE.ui8;
times(8, (i) => {
a[i] = buff[p + 7 - i];
});
return _binBE.fl64[0];
},
writeUshort: (buff, p, n) => {
buff[p] = n >> 8 & 255;
buff[p + 1] = n & 255;
},
writeUint: (buff, p, n) => {
buff[p] = n >> 24 & 255;
buff[p + 1] = n >> 16 & 255;
buff[p + 2] = n >> 8 & 255;
buff[p + 3] = n >> 0 & 255;
},
writeASCII: (buff, p, s) => {
times(s.length, (i) => {
buff[p + i] = s.charCodeAt(i);
});
},
ui8: new Uint8Array(8)
};
_binBE.fl64 = new Float64Array(_binBE.ui8.buffer);
_binBE.writeDouble = (buff, p, n) => {
_binBE.fl64[0] = n;
times(8, (i) => {
buff[p + i] = _binBE.ui8[7 - i];
});
};
// node_modules/geotiff/dist-module/logging.js
var DummyLogger = class {
log() {
}
debug() {
}
info() {
}
warn() {
}
error() {
}
time() {
}
timeEnd() {
}
};
var LOGGER = new DummyLogger();
// node_modules/geotiff/dist-module/geotiff.js
function getFieldTypeLength(fieldType) {
switch (fieldType) {
case fieldTypes.BYTE:
case fieldTypes.ASCII:
case fieldTypes.SBYTE:
case fieldTypes.UNDEFINED:
return 1;
case fieldTypes.SHORT:
case fieldTypes.SSHORT:
return 2;
case fieldTypes.LONG:
case fieldTypes.SLONG:
case fieldTypes.FLOAT:
case fieldTypes.IFD:
return 4;
case fieldTypes.RATIONAL:
case fieldTypes.SRATIONAL:
case fieldTypes.DOUBLE:
case fieldTypes.LONG8:
case fieldTypes.SLONG8:
case fieldTypes.IFD8:
return 8;
default:
throw new RangeError(`Invalid field type: ${fieldType}`);
}
}
function parseGeoKeyDirectory(fileDirectory) {
const rawGeoKeyDirectory = fileDirectory.GeoKeyDirectory;
if (!rawGeoKeyDirectory) {
return null;
}
const geoKeyDirectory = {};
for (let i = 4; i <= rawGeoKeyDirectory[3] * 4; i += 4) {
const key = geoKeyNames[rawGeoKeyDirectory[i]];
const location = rawGeoKeyDirectory[i + 1] ? fieldTagNames[rawGeoKeyDirectory[i + 1]] : null;
const count = rawGeoKeyDirectory[i + 2];
const offset = rawGeoKeyDirectory[i + 3];
let value = null;
if (!location) {
value = offset;
} else {
value = fileDirectory[location];
if (typeof value === "undefined" || value === null) {
throw new Error(`Could not get value of geoKey '${key}'.`);
} else if (typeof value === "string") {
value = value.substring(offset, offset + count - 1);
} else if (value.subarray) {
value = value.subarray(offset, offset + count);
if (count === 1) {
value = value[0];
}
}
}
geoKeyDirectory[key] = value;
}
return geoKeyDirectory;
}
function getValues(dataSlice, fieldType, count, offset) {
let values2 = null;
let readMethod = null;
const fieldTypeLength = getFieldTypeLength(fieldType);
switch (fieldType) {
case fieldTypes.BYTE:
case fieldTypes.ASCII:
case fieldTypes.UNDEFINED:
values2 = new Uint8Array(count);
readMethod = dataSlice.readUint8;
break;
case fieldTypes.SBYTE:
values2 = new Int8Array(count);
readMethod = dataSlice.readInt8;
break;
case fieldTypes.SHORT:
values2 = new Uint16Array(count);
readMethod = dataSlice.readUint16;
break;
case fieldTypes.SSHORT:
values2 = new Int16Array(count);
readMethod = dataSlice.readInt16;
break;
case fieldTypes.LONG:
case fieldTypes.IFD:
values2 = new Uint32Array(count);
readMethod = dataSlice.readUint32;
break;
case fieldTypes.SLONG:
values2 = new Int32Array(count);
readMethod = dataSlice.readInt32;
break;
case fieldTypes.LONG8:
case fieldTypes.IFD8:
values2 = new Array(count);
readMethod = dataSlice.readUint64;
break;
case fieldTypes.SLONG8:
values2 = new Array(count);
readMethod = dataSlice.readInt64;
break;
case fieldTypes.RATIONAL:
values2 = new Uint32Array(count * 2);
readMethod = dataSlice.readUint32;
break;
case fieldTypes.SRATIONAL:
values2 = new Int32Array(count * 2);
readMethod = dataSlice.readInt32;
break;
case fieldTypes.FLOAT:
values2 = new Float32Array(count);
readMethod = dataSlice.readFloat32;
break;
case fieldTypes.DOUBLE:
values2 = new Float64Array(count);
readMethod = dataSlice.readFloat64;
break;
default:
throw new RangeError(`Invalid field type: ${fieldType}`);
}
if (!(fieldType === fieldTypes.RATIONAL || fieldType === fieldTypes.SRATIONAL)) {
for (let i = 0; i < count; ++i) {
values2[i] = readMethod.call(
dataSlice,
offset + i * fieldTypeLength
);
}
} else {
for (let i = 0; i < count; i += 2) {
values2[i] = readMethod.call(
dataSlice,
offset + i * fieldTypeLength
);
values2[i + 1] = readMethod.call(
dataSlice,
offset + (i * fieldTypeLength + 4)
);
}
}
if (fieldType === fieldTypes.ASCII) {
return new TextDecoder("utf-8").decode(values2);
}
return values2;
}
var ImageFileDirectory = class {
constructor(fileDirectory, geoKeyDirectory, nextIFDByteOffset) {
this.fileDirectory = fileDirectory;
this.geoKeyDirectory = geoKeyDirectory;
this.nextIFDByteOffset = nextIFDByteOffset;
}
};
var GeoTIFFImageIndexError = class extends Error {
constructor(index) {
super(`No image at index ${index}`);
this.index = index;
}
};
var GeoTIFFBase = class {
/**
* (experimental) Reads raster data from the best fitting image. This function uses
* the image with the lowest resolution that is still a higher resolution than the
* requested resolution.
* When specified, the `bbox` option is translated to the `window` option and the
* `resX` and `resY` to `width` and `height` respectively.
* Then, the [readRasters]{@link GeoTIFFImage#readRasters} method of the selected
* image is called and the result returned.
* @see GeoTIFFImage.readRasters
* @param {import('./geotiffimage').ReadRasterOptions} [options={}] optional parameters
* @returns {Promise} the decoded array(s), with `height` and `width`, as a promise
*/
async readRasters(options = {}) {
const { window: imageWindow, width, height } = options;
let { resX, resY, bbox } = options;
const firstImage = await this.getImage();
let usedImage = firstImage;
const imageCount = await this.getImageCount();
const imgBBox = firstImage.getBoundingBox();
if (imageWindow && bbox) {
throw new Error('Both "bbox" and "window" passed.');
}
if (width || height) {
if (imageWindow) {
const [oX, oY] = firstImage.getOrigin();
const [rX, rY] = firstImage.getResolution();
bbox = [
oX + imageWindow[0] * rX,
oY + imageWindow[1] * rY,
oX + imageWindow[2] * rX,
oY + imageWindow[3] * rY
];
}
const usedBBox = bbox || imgBBox;
if (width) {
if (resX) {
throw new Error("Both width and resX passed");
}
resX = (usedBBox[2] - usedBBox[0]) / width;
}
if (height) {
if (resY) {
throw new Error("Both width and resY passed");
}
resY = (usedBBox[3] - usedBBox[1]) / height;
}
}
if (resX || resY) {
const allImages = [];
for (let i = 0; i < imageCount; ++i) {
const image = await this.getImage(i);
const { SubfileType: subfileType, NewSubfileType: newSubfileType } = image.fileDirectory;
if (i === 0 || subfileType === 2 || newSubfileType & 1) {
allImages.push(image);
}
}
allImages.sort((a, b) => a.getWidth() - b.getWidth());
for (let i = 0; i < allImages.length; ++i) {
const image = allImages[i];
const imgResX = (imgBBox[2] - imgBBox[0]) / image.getWidth();
const imgResY = (imgBBox[3] - imgBBox[1]) / image.getHeight();
usedImage = image;
if (resX && resX > imgResX || resY && resY > imgResY) {
break;
}
}
}
let wnd = imageWindow;
if (bbox) {
const [oX, oY] = firstImage.getOrigin();
const [imageResX, imageResY] = usedImage.getResolution(firstImage);
wnd = [
Math.round((bbox[0] - oX) / imageResX),
Math.round((bbox[1] - oY) / imageResY),
Math.round((bbox[2] - oX) / imageResX),
Math.round((bbox[3] - oY) / imageResY)
];
wnd = [
Math.min(wnd[0], wnd[2]),
Math.min(wnd[1], wnd[3]),
Math.max(wnd[0], wnd[2]),
Math.max(wnd[1], wnd[3])
];
}
return usedImage.readRasters({ ...options, window: wnd });
}
};
var GeoTIFF = class _GeoTIFF extends GeoTIFFBase {
/**
* @constructor
* @param {*} source The datasource to read from.
* @param {boolean} littleEndian Whether the image uses little endian.
* @param {boolean} bigTiff Whether the image uses bigTIFF conventions.
* @param {number} firstIFDOffset The numeric byte-offset from the start of the image
* to the first IFD.
* @param {GeoTIFFOptions} [options] further options.
*/
constructor(source, littleEndian, bigTiff, firstIFDOffset, options = {}) {
super();
this.source = source;
this.littleEndian = littleEndian;
this.bigTiff = bigTiff;
this.firstIFDOffset = firstIFDOffset;
this.cache = options.cache || false;
this.ifdRequests = [];
this.ghostValues = null;
}
async getSlice(offset, size) {
const fallbackSize = this.bigTiff ? 4048 : 1024;
return new DataSlice(
(await this.source.fetch([{
offset,
length: typeof size !== "undefined" ? size : fallbackSize
}]))[0],
offset,
this.littleEndian,
this.bigTiff
);
}
/**
* Instructs to parse an image file directory at the given file offset.
* As there is no way to ensure that a location is indeed the start of an IFD,
* this function must be called with caution (e.g only using the IFD offsets from
* the headers or other IFDs).
* @param {number} offset the offset to parse the IFD at
* @returns {Promise} the parsed IFD
*/
async parseFileDirectoryAt(offset) {
const entrySize = this.bigTiff ? 20 : 12;
const offsetSize = this.bigTiff ? 8 : 2;
let dataSlice = await this.getSlice(offset);
const numDirEntries = this.bigTiff ? dataSlice.readUint64(offset) : dataSlice.readUint16(offset);
const byteSize = numDirEntries * entrySize + (this.bigTiff ? 16 : 6);
if (!dataSlice.covers(offset, byteSize)) {
dataSlice = await this.getSlice(offset, byteSize);
}
const fileDirectory = {};
let i = offset + (this.bigTiff ? 8 : 2);
for (let entryCount = 0; entryCount < numDirEntries; i += entrySize, ++entryCount) {
const fieldTag = dataSlice.readUint16(i);
const fieldType = dataSlice.readUint16(i + 2);
const typeCount = this.bigTiff ? dataSlice.readUint64(i + 4) : dataSlice.readUint32(i + 4);
let fieldValues;
let value;
const fieldTypeLength = getFieldTypeLength(fieldType);
const valueOffset = i + (this.bigTiff ? 12 : 8);
if (fieldTypeLength * typeCount <= (this.bigTiff ? 8 : 4)) {
fieldValues = getValues(dataSlice, fieldType, typeCount, valueOffset);
} else {
const actualOffset = dataSlice.readOffset(valueOffset);
const length = getFieldTypeLength(fieldType) * typeCount;
if (dataSlice.covers(actualOffset, length)) {
fieldValues = getValues(dataSlice, fieldType, typeCount, actualOffset);
} else {
const fieldDataSlice = await this.getSlice(actualOffset, length);
fieldValues = getValues(fieldDataSlice, fieldType, typeCount, actualOffset);
}
}
if (typeCount === 1 && arrayFields.indexOf(fieldTag) === -1 && !(fieldType === fieldTypes.RATIONAL || fieldType === fieldTypes.SRATIONAL)) {
value = fieldValues[0];
} else {
value = fieldValues;
}
fileDirectory[fieldTagNames[fieldTag]] = value;
}
const geoKeyDirectory = parseGeoKeyDirectory(fileDirectory);
const nextIFDByteOffset = dataSlice.readOffset(
offset + offsetSize + entrySize * numDirEntries
);
return new ImageFileDirectory(
fileDirectory,
geoKeyDirectory,
nextIFDByteOffset
);
}
async requestIFD(index) {
if (this.ifdRequests[index]) {
return this.ifdRequests[index];
} else if (index === 0) {
this.ifdRequests[index] = this.parseFileDirectoryAt(this.firstIFDOffset);
return this.ifdRequests[index];
} else if (!this.ifdRequests[index - 1]) {
try {
this.ifdRequests[index - 1] = this.requestIFD(index - 1);
} catch (e) {
if (e instanceof GeoTIFFImageIndexError) {
throw new GeoTIFFImageIndexError(index);
}
throw e;
}
}
this.ifdRequests[index] = (async () => {
const previousIfd = await this.ifdRequests[index - 1];
if (previousIfd.nextIFDByteOffset === 0) {
throw new GeoTIFFImageIndexError(index);
}
return this.parseFileDirectoryAt(previousIfd.nextIFDByteOffset);
})();
return this.ifdRequests[index];
}
/**
* Get the n-th internal subfile of an image. By default, the first is returned.
*
* @param {number} [index=0] the index of the image to return.
* @returns {Promise} the image at the given index
*/
async getImage(index = 0) {
const ifd = await this.requestIFD(index);
return new geotiffimage_default(
ifd.fileDirectory,
ifd.geoKeyDirectory,
this.dataView,
this.littleEndian,
this.cache,
this.source
);
}
/**
* Returns the count of the internal subfiles.
*
* @returns {Promise} the number of internal subfile images
*/
async getImageCount() {
let index = 0;
let hasNext = true;
while (hasNext) {
try {
await this.requestIFD(index);
++index;
} catch (e) {
if (e instanceof GeoTIFFImageIndexError) {
hasNext = false;
} else {
throw e;
}
}
}
return index;
}
/**
* Get the values of the COG ghost area as a parsed map.
* See https://gdal.org/drivers/raster/cog.html#header-ghost-area for reference
* @returns {Promise