UNPKG

@loaders.gl/zarr

Version:

Framework-independent loaders for Zarr

1,447 lines (1,443 loc) 677 kB
(function webpackUniversalModuleDefinition(root, factory) { if (typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if (typeof define === 'function' && define.amd) define([], factory); else if (typeof exports === 'object') exports['loaders'] = factory(); else root['loaders'] = factory();})(globalThis, function () { "use strict"; var __exports__ = (() => { var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __commonJS = (cb, mod) => function __require() { return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; }; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // external-global-plugin:@loaders.gl/core var require_core = __commonJS({ "external-global-plugin:@loaders.gl/core"(exports, module) { module.exports = globalThis.loaders; } }); // bundle.ts var bundle_exports = {}; __export(bundle_exports, { ZarrPixelSource: () => zarr_pixel_source_default, loadZarr: () => loadZarr }); __reExport(bundle_exports, __toESM(require_core(), 1)); // ../../node_modules/zarr/core.mjs var registry = /* @__PURE__ */ new Map(); function addCodec(id, importFn) { registry.set(id, importFn); } async function getCodec(config) { if (!registry.has(config.id)) { throw new Error(`Compression codec ${config.id} is not supported by Zarr.js yet.`); } const codec = await registry.get(config.id)(); return codec.fromConfig(config); } function createProxy(mapping) { return new Proxy(mapping, { set(target, key, value, _receiver) { return target.setItem(key, value); }, get(target, key, _receiver) { return target.getItem(key); }, deleteProperty(target, key) { return target.deleteItem(key); }, has(target, key) { return target.containsItem(key); } }); } function isZarrError(err2) { return typeof err2 === "object" && err2 !== null && "__zarr__" in err2; } function isKeyError(o) { return isZarrError(o) && o.__zarr__ === "KeyError"; } var ContainsArrayError = class extends Error { constructor(path) { super(`path ${path} contains an array`); this.__zarr__ = "ContainsArrayError"; Object.setPrototypeOf(this, ContainsArrayError.prototype); } }; var ContainsGroupError = class extends Error { constructor(path) { super(`path ${path} contains a group`); this.__zarr__ = "ContainsGroupError"; Object.setPrototypeOf(this, ContainsGroupError.prototype); } }; var GroupNotFoundError = class extends Error { constructor(path) { super(`ground not found at path ${path}`); this.__zarr__ = "GroupNotFoundError"; Object.setPrototypeOf(this, GroupNotFoundError.prototype); } }; var PermissionError = class extends Error { constructor(message) { super(message); this.__zarr__ = "PermissionError"; Object.setPrototypeOf(this, PermissionError.prototype); } }; var KeyError = class extends Error { constructor(key) { super(`key ${key} not present`); this.__zarr__ = "KeyError"; Object.setPrototypeOf(this, KeyError.prototype); } }; var TooManyIndicesError = class extends RangeError { constructor(selection, shape) { super(`too many indices for array; expected ${shape.length}, got ${selection.length}`); this.__zarr__ = "TooManyIndicesError"; Object.setPrototypeOf(this, TooManyIndicesError.prototype); } }; var BoundsCheckError = class extends RangeError { constructor(message) { super(message); this.__zarr__ = "BoundsCheckError"; Object.setPrototypeOf(this, BoundsCheckError.prototype); } }; var InvalidSliceError = class extends RangeError { constructor(from, to, stepSize, reason) { super(`slice arguments slice(${from}, ${to}, ${stepSize}) invalid: ${reason}`); this.__zarr__ = "InvalidSliceError"; Object.setPrototypeOf(this, InvalidSliceError.prototype); } }; var NegativeStepError = class extends Error { constructor() { super(`Negative step size is not supported when indexing.`); this.__zarr__ = "NegativeStepError"; Object.setPrototypeOf(this, NegativeStepError.prototype); } }; var ValueError = class extends Error { constructor(message) { super(message); this.__zarr__ = "ValueError"; Object.setPrototypeOf(this, ValueError.prototype); } }; var HTTPError = class extends Error { constructor(code) { super(code); this.__zarr__ = "HTTPError"; Object.setPrototypeOf(this, HTTPError.prototype); } }; function slice(start, stop = void 0, step = null) { if (start === void 0) { throw new InvalidSliceError(start, stop, step, "The first argument must not be undefined"); } if (typeof start === "string" && start !== ":" || typeof stop === "string" && stop !== ":") { throw new InvalidSliceError(start, stop, step, 'Arguments can only be integers, ":" or null'); } if (stop === void 0) { stop = start; start = null; } return { start: start === ":" ? null : start, stop: stop === ":" ? null : stop, step, _slice: true }; } function adjustIndices(start, stop, step, length) { if (start < 0) { start += length; if (start < 0) { start = step < 0 ? -1 : 0; } } else if (start >= length) { start = step < 0 ? length - 1 : length; } if (stop < 0) { stop += length; if (stop < 0) { stop = step < 0 ? -1 : 0; } } else if (stop >= length) { stop = step < 0 ? length - 1 : length; } if (step < 0) { if (stop < start) { const length2 = Math.floor((start - stop - 1) / -step + 1); return [start, stop, step, length2]; } } else { if (start < stop) { const length2 = Math.floor((stop - start - 1) / step + 1); return [start, stop, step, length2]; } } return [start, stop, step, 0]; } function sliceIndices(slice2, length) { let start; let stop; let step; if (slice2.step === null) { step = 1; } else { step = slice2.step; } if (slice2.start === null) { start = step < 0 ? Number.MAX_SAFE_INTEGER : 0; } else { start = slice2.start; if (start < 0) { start += length; } } if (slice2.stop === null) { stop = step < 0 ? -Number.MAX_SAFE_INTEGER : Number.MAX_SAFE_INTEGER; } else { stop = slice2.stop; if (stop < 0) { stop += length; } } const s = adjustIndices(start, stop, step, length); start = s[0]; stop = s[1]; step = s[2]; length = s[3]; if (step === 0) throw new Error("Step size 0 is invalid"); return [start, stop, step, length]; } function ensureArray(selection) { if (!Array.isArray(selection)) { return [selection]; } return selection; } function checkSelectionLength(selection, shape) { if (selection.length > shape.length) { throw new TooManyIndicesError(selection, shape); } } function selectionToSliceIndices(selection, shape) { const sliceIndicesResult = []; const outShape = []; for (let i = 0; i < selection.length; i++) { const s = selection[i]; if (typeof s === "number") { sliceIndicesResult.push(s); } else { const x = sliceIndices(s, shape[i]); const dimLength = x[3]; outShape.push(dimLength); sliceIndicesResult.push(x); } } return [sliceIndicesResult, outShape]; } function normalizeArraySelection(selection, shape, convertIntegerSelectionToSlices = false) { selection = replaceEllipsis(selection, shape); for (let i = 0; i < selection.length; i++) { const dimSelection = selection[i]; if (typeof dimSelection === "number") { if (convertIntegerSelectionToSlices) { selection[i] = slice(dimSelection, dimSelection + 1, 1); } else { selection[i] = normalizeIntegerSelection(dimSelection, shape[i]); } } else if (isIntegerArray(dimSelection)) { throw new TypeError("Integer array selections are not supported (yet)"); } else if (dimSelection === ":" || dimSelection === null) { selection[i] = slice(null, null, 1); } } return selection; } function replaceEllipsis(selection, shape) { selection = ensureArray(selection); let ellipsisIndex = -1; let numEllipsis = 0; for (let i = 0; i < selection.length; i++) { if (selection[i] === "...") { ellipsisIndex = i; numEllipsis += 1; } } if (numEllipsis > 1) { throw new RangeError("an index can only have a single ellipsis ('...')"); } if (numEllipsis === 1) { const numItemsLeft = ellipsisIndex; const numItemsRight = selection.length - (numItemsLeft + 1); const numItems = selection.length - 1; if (numItems >= shape.length) { selection = selection.filter((x) => x !== "..."); } else { const numNewItems = shape.length - numItems; let newItem = selection.slice(0, numItemsLeft).concat(new Array(numNewItems).fill(null)); if (numItemsRight > 0) { newItem = newItem.concat(selection.slice(selection.length - numItemsRight)); } selection = newItem; } } if (selection.length < shape.length) { const numMissing = shape.length - selection.length; selection = selection.concat(new Array(numMissing).fill(null)); } checkSelectionLength(selection, shape); return selection; } function normalizeIntegerSelection(dimSelection, dimLength) { if (dimSelection < 0) { dimSelection = dimLength + dimSelection; } if (dimSelection >= dimLength || dimSelection < 0) { throw new BoundsCheckError(`index out of bounds for dimension with length ${dimLength}`); } return dimSelection; } function isInteger(s) { return typeof s === "number"; } function isIntegerArray(s) { if (!Array.isArray(s)) { return false; } for (const e of s) { if (typeof e !== "number") { return false; } } return true; } function isSlice(s) { if (s !== null && s["_slice"] === true) { return true; } return false; } function isContiguousSlice(s) { return isSlice(s) && (s.step === null || s.step === 1); } function isContiguousSelection(selection) { selection = ensureArray(selection); for (let i = 0; i < selection.length; i++) { const s = selection[i]; if (!(isIntegerArray(s) || isContiguousSlice(s) || s === "...")) { return false; } } return true; } function* product(...iterables) { if (iterables.length === 0) { return; } const iterators = iterables.map((it) => it()); const results = iterators.map((it) => it.next()); for (let i = 0; ; ) { if (results[i].done) { iterators[i] = iterables[i](); results[i] = iterators[i].next(); if (++i >= iterators.length) { return; } } else { yield results.map(({ value }) => value); i = 0; } results[i] = iterators[i].next(); } } var BasicIndexer = class { constructor(selection, array2) { selection = normalizeArraySelection(selection, array2.shape); this.dimIndexers = []; const arrayShape = array2.shape; for (let i = 0; i < arrayShape.length; i++) { let dimSelection = selection[i]; const dimLength = arrayShape[i]; const dimChunkLength = array2.chunks[i]; if (dimSelection === null) { dimSelection = slice(null); } if (isInteger(dimSelection)) { this.dimIndexers.push(new IntDimIndexer(dimSelection, dimLength, dimChunkLength)); } else if (isSlice(dimSelection)) { this.dimIndexers.push(new SliceDimIndexer(dimSelection, dimLength, dimChunkLength)); } else { throw new RangeError(`Unspported selection item for basic indexing; expected integer or slice, got ${dimSelection}`); } } this.shape = []; for (const d of this.dimIndexers) { if (d instanceof SliceDimIndexer) { this.shape.push(d.numItems); } } this.dropAxes = null; } *iter() { const dimIndexerIterables = this.dimIndexers.map((x) => () => x.iter()); const dimIndexerProduct = product(...dimIndexerIterables); for (const dimProjections of dimIndexerProduct) { const chunkCoords = []; const chunkSelection = []; const outSelection = []; for (const p of dimProjections) { chunkCoords.push(p.dimChunkIndex); chunkSelection.push(p.dimChunkSelection); if (p.dimOutSelection !== null) { outSelection.push(p.dimOutSelection); } } yield { chunkCoords, chunkSelection, outSelection }; } } }; var IntDimIndexer = class { constructor(dimSelection, dimLength, dimChunkLength) { dimSelection = normalizeIntegerSelection(dimSelection, dimLength); this.dimSelection = dimSelection; this.dimLength = dimLength; this.dimChunkLength = dimChunkLength; this.numItems = 1; } *iter() { const dimChunkIndex = Math.floor(this.dimSelection / this.dimChunkLength); const dimOffset = dimChunkIndex * this.dimChunkLength; const dimChunkSelection = this.dimSelection - dimOffset; const dimOutSelection = null; yield { dimChunkIndex, dimChunkSelection, dimOutSelection }; } }; var SliceDimIndexer = class { constructor(dimSelection, dimLength, dimChunkLength) { const [start, stop, step] = sliceIndices(dimSelection, dimLength); this.start = start; this.stop = stop; this.step = step; if (this.step < 1) { throw new NegativeStepError(); } this.dimLength = dimLength; this.dimChunkLength = dimChunkLength; this.numItems = Math.max(0, Math.ceil((this.stop - this.start) / this.step)); this.numChunks = Math.ceil(this.dimLength / this.dimChunkLength); } *iter() { const dimChunkIndexFrom = Math.floor(this.start / this.dimChunkLength); const dimChunkIndexTo = Math.ceil(this.stop / this.dimChunkLength); for (let dimChunkIndex = dimChunkIndexFrom; dimChunkIndex < dimChunkIndexTo; dimChunkIndex++) { const dimOffset = dimChunkIndex * this.dimChunkLength; const dimLimit = Math.min(this.dimLength, (dimChunkIndex + 1) * this.dimChunkLength); const dimChunkLength = dimLimit - dimOffset; let dimChunkSelStart; let dimChunkSelStop; let dimOutOffset; if (this.start < dimOffset) { dimChunkSelStart = 0; const remainder = (dimOffset - this.start) % this.step; if (remainder > 0) { dimChunkSelStart += this.step - remainder; } dimOutOffset = Math.ceil((dimOffset - this.start) / this.step); } else { dimChunkSelStart = this.start - dimOffset; dimOutOffset = 0; } if (this.stop > dimLimit) { dimChunkSelStop = dimChunkLength; } else { dimChunkSelStop = this.stop - dimOffset; } const dimChunkSelection = slice(dimChunkSelStart, dimChunkSelStop, this.step); const dimChunkNumItems = Math.ceil((dimChunkSelStop - dimChunkSelStart) / this.step); const dimOutSelection = slice(dimOutOffset, dimOutOffset + dimChunkNumItems); yield { dimChunkIndex, dimChunkSelection, dimOutSelection }; } } }; var IS_NODE = typeof process !== "undefined" && process.versions && process.versions.node; function noop() { } function normalizeStoragePath(path) { if (path === null) { return ""; } if (path instanceof String) { path = path.valueOf(); } path = path.replace(/\\/g, "/"); while (path.length > 0 && path[0] === "/") { path = path.slice(1); } while (path.length > 0 && path[path.length - 1] === "/") { path = path.slice(0, path.length - 1); } path = path.replace(/\/\/+/g, "/"); const segments = path.split("/"); for (const s of segments) { if (s === "." || s === "..") { throw Error("path containing '.' or '..' segment not allowed"); } } return path; } function normalizeShape(shape) { if (typeof shape === "number") { shape = [shape]; } return shape.map((x) => Math.floor(x)); } function normalizeChunks(chunks, shape) { if (chunks === null || chunks === true) { throw new Error("Chunk guessing is not supported yet"); } if (chunks === false) { return shape; } if (typeof chunks === "number") { chunks = [chunks]; } if (chunks.length < shape.length) { chunks = chunks.concat(shape.slice(chunks.length)); } return chunks.map((x, idx) => { if (x === -1 || x === null) { return shape[idx]; } else { return Math.floor(x); } }); } function normalizeOrder(order) { order = order.toUpperCase(); return order; } function normalizeDtype(dtype) { return dtype; } function normalizeFillValue(fillValue) { return fillValue; } function isTotalSlice(item, shape) { if (item === null) { return true; } if (!Array.isArray(item)) { item = [item]; } for (let i = 0; i < Math.min(item.length, shape.length); i++) { const it = item[i]; if (it === null) continue; if (isSlice(it)) { const s = it; const isStepOne = s.step === 1 || s.step === null; if (s.start === null && s.stop === null && isStepOne) { continue; } if (s.stop - s.start === shape[i] && isStepOne) { continue; } return false; } return false; } return true; } function arrayEquals1D(a, b) { if (a.length !== b.length) { return false; } for (let i = 0; i < a.length; i++) { if (a[i] !== b[i]) { return false; } } return true; } function getStrides(shape) { const ndim = shape.length; const strides = Array(ndim); let step = 1; for (let i = ndim - 1; i >= 0; i--) { strides[i] = step; step *= shape[i]; } return strides; } function resolveUrl(root, path) { const base = typeof root === "string" ? new URL(root) : root; if (!base.pathname.endsWith("/")) { base.pathname += "/"; } const resolved = new URL(path, base); resolved.search = base.search; return resolved.href; } function byteSwapInplace(src) { const b = src.BYTES_PER_ELEMENT; if (b === 1) return; if (IS_NODE) { const bytes = Buffer.from(src.buffer, src.byteOffset, src.length * b); if (b === 2) bytes.swap16(); if (b === 4) bytes.swap32(); if (b === 8) bytes.swap64(); return; } const flipper = new Uint8Array(src.buffer, src.byteOffset, src.length * b); const numFlips = b / 2; const endByteIndex = b - 1; let t; for (let i = 0; i < flipper.length; i += b) { for (let j = 0; j < numFlips; j++) { t = flipper[i + j]; flipper[i + j] = flipper[i + endByteIndex - j]; flipper[i + endByteIndex - j] = t; } } } function byteSwap(src) { const copy = src.slice(); byteSwapInplace(copy); return copy; } function convertColMajorToRowMajor2D(src, out, shape) { let idx = 0; const shape0 = shape[0]; const shape1 = shape[1]; const stride0 = shape1; for (let i1 = 0; i1 < shape1; i1++) { for (let i0 = 0; i0 < shape0; i0++) { out[i0 * stride0 + i1] = src[idx++]; } } } function convertColMajorToRowMajor3D(src, out, shape) { let idx = 0; const shape0 = shape[0]; const shape1 = shape[1]; const shape2 = shape[2]; const stride0 = shape2 * shape1; const stride1 = shape2; for (let i2 = 0; i2 < shape2; i2++) { for (let i1 = 0; i1 < shape1; i1++) { for (let i0 = 0; i0 < shape0; i0++) { out[i0 * stride0 + i1 * stride1 + i2] = src[idx++]; } } } } function convertColMajorToRowMajor4D(src, out, shape) { let idx = 0; const shape0 = shape[0]; const shape1 = shape[1]; const shape2 = shape[2]; const shape3 = shape[3]; const stride0 = shape3 * shape2 * shape1; const stride1 = shape3 * shape2; const stride2 = shape3; for (let i3 = 0; i3 < shape3; i3++) { for (let i2 = 0; i2 < shape2; i2++) { for (let i1 = 0; i1 < shape1; i1++) { for (let i0 = 0; i0 < shape0; i0++) { out[i0 * stride0 + i1 * stride1 + i2 * stride2 + i3] = src[idx++]; } } } } } function convertColMajorToRowMajorGeneric(src, out, shape) { const nDims = shape.length; const size = shape.reduce((r, a) => r * a); const rowMajorStrides = shape.map((_, i) => i + 1 === nDims ? 1 : shape.slice(i + 1).reduce((r, a) => r * a, 1)); const index = Array(nDims).fill(0); for (let colMajorIdx = 0; colMajorIdx < size; colMajorIdx++) { let rowMajorIdx = 0; for (let dim = 0; dim < nDims; dim++) { rowMajorIdx += index[dim] * rowMajorStrides[dim]; } out[rowMajorIdx] = src[colMajorIdx]; index[0] += 1; for (let dim = 0; dim < nDims; dim++) { if (index[dim] === shape[dim]) { if (dim + 1 === nDims) { return; } index[dim] = 0; index[dim + 1] += 1; } } } } var colMajorToRowMajorConverters = { [0]: noop, [1]: noop, [2]: convertColMajorToRowMajor2D, [3]: convertColMajorToRowMajor3D, [4]: convertColMajorToRowMajor4D }; function convertColMajorToRowMajor(src, out, shape) { return (colMajorToRowMajorConverters[shape.length] || convertColMajorToRowMajorGeneric)(src, out, shape); } function isArrayBufferLike(obj) { if (obj === null) { return false; } if (obj instanceof ArrayBuffer) { return true; } if (typeof SharedArrayBuffer === "function" && obj instanceof SharedArrayBuffer) { return true; } if (IS_NODE) { return obj.toString().startsWith("[object ArrayBuffer]") || obj.toString().startsWith("[object SharedArrayBuffer]"); } return false; } var ARRAY_META_KEY = ".zarray"; var GROUP_META_KEY = ".zgroup"; var ATTRS_META_KEY = ".zattrs"; async function containsArray(store, path = null) { path = normalizeStoragePath(path); const prefix = pathToPrefix(path); const key = prefix + ARRAY_META_KEY; return store.containsItem(key); } async function containsGroup(store, path = null) { path = normalizeStoragePath(path); const prefix = pathToPrefix(path); const key = prefix + GROUP_META_KEY; return store.containsItem(key); } function pathToPrefix(path) { if (path.length > 0) { return path + "/"; } return ""; } async function requireParentGroup(store, path, chunkStore, overwrite) { if (path.length === 0) { return; } const segments = path.split("/"); let p = ""; for (const s of segments.slice(0, segments.length - 1)) { p += s; if (await containsArray(store, p)) { await initGroupMetadata(store, p, overwrite); } else if (!await containsGroup(store, p)) { await initGroupMetadata(store, p); } p += "/"; } } async function initGroupMetadata(store, path = null, overwrite = false) { path = normalizeStoragePath(path); if (overwrite) { throw Error("Group overwriting not implemented yet :("); } else if (await containsArray(store, path)) { throw new ContainsArrayError(path); } else if (await containsGroup(store, path)) { throw new ContainsGroupError(path); } const metadata = { zarr_format: 2 }; const key = pathToPrefix(path) + GROUP_META_KEY; await store.setItem(key, JSON.stringify(metadata)); } async function initGroup(store, path = null, chunkStore = null, overwrite = false) { path = normalizeStoragePath(path); await requireParentGroup(store, path, chunkStore, overwrite); await initGroupMetadata(store, path, overwrite); } async function initArrayMetadata(store, shape, chunks, dtype, path, compressor, fillValue, order, overwrite, chunkStore, filters, dimensionSeparator) { if (overwrite) { throw Error("Array overwriting not implemented yet :("); } else if (await containsArray(store, path)) { throw new ContainsArrayError(path); } else if (await containsGroup(store, path)) { throw new ContainsGroupError(path); } dtype = normalizeDtype(dtype); shape = normalizeShape(shape); chunks = normalizeChunks(chunks, shape); order = normalizeOrder(order); fillValue = normalizeFillValue(fillValue); if (filters !== null && filters.length > 0) { throw Error("Filters are not supported yet"); } let serializedFillValue = fillValue; if (typeof fillValue === "number") { if (Number.isNaN(fillValue)) serializedFillValue = "NaN"; if (Number.POSITIVE_INFINITY === fillValue) serializedFillValue = "Infinity"; if (Number.NEGATIVE_INFINITY === fillValue) serializedFillValue = "-Infinity"; } filters = null; const metadata = { zarr_format: 2, shape, chunks, dtype, fill_value: serializedFillValue, order, compressor, filters }; if (dimensionSeparator) { metadata.dimension_separator = dimensionSeparator; } const metaKey = pathToPrefix(path) + ARRAY_META_KEY; await store.setItem(metaKey, JSON.stringify(metadata)); } async function initArray(store, shape, chunks, dtype, path = null, compressor = null, fillValue = null, order = "C", overwrite = false, chunkStore = null, filters = null, dimensionSeparator) { path = normalizeStoragePath(path); await requireParentGroup(store, path, chunkStore, overwrite); await initArrayMetadata(store, shape, chunks, dtype, path, compressor, fillValue, order, overwrite, chunkStore, filters, dimensionSeparator); } function parseMetadata(s) { if (typeof s !== "string") { if (IS_NODE && Buffer.isBuffer(s)) { return JSON.parse(s.toString()); } else if (isArrayBufferLike(s)) { const utf8Decoder = new TextDecoder(); const bytes = new Uint8Array(s); return JSON.parse(utf8Decoder.decode(bytes)); } else { return s; } } return JSON.parse(s); } var Attributes = class { constructor(store, key, readOnly, cache = true) { this.store = store; this.key = key; this.readOnly = readOnly; this.cache = cache; this.cachedValue = null; } /** * Retrieve all attributes as a JSON object. */ async asObject() { if (this.cache && this.cachedValue !== null) { return this.cachedValue; } const o = await this.getNoSync(); if (this.cache) { this.cachedValue = o; } return o; } async getNoSync() { try { const data = await this.store.getItem(this.key); return parseMetadata(data); } catch (error) { return {}; } } async setNoSync(key, value) { const d = await this.getNoSync(); d[key] = value; await this.putNoSync(d); return true; } async putNoSync(m) { await this.store.setItem(this.key, JSON.stringify(m)); if (this.cache) { this.cachedValue = m; } } async delNoSync(key) { const d = await this.getNoSync(); delete d[key]; await this.putNoSync(d); return true; } /** * Overwrite all attributes with the provided object in a single operation */ async put(d) { if (this.readOnly) { throw new PermissionError("attributes are read-only"); } return this.putNoSync(d); } async setItem(key, value) { if (this.readOnly) { throw new PermissionError("attributes are read-only"); } return this.setNoSync(key, value); } async getItem(key) { return (await this.asObject())[key]; } async deleteItem(key) { if (this.readOnly) { throw new PermissionError("attributes are read-only"); } return this.delNoSync(key); } async containsItem(key) { return (await this.asObject())[key] !== void 0; } proxy() { return createProxy(this); } }; var DTYPE_TYPEDARRAY_MAPPING = { "|b": Int8Array, "|B": Uint8Array, "|u1": Uint8Array, "|i1": Int8Array, "<b": Int8Array, "<B": Uint8Array, "<u1": Uint8Array, "<i1": Int8Array, "<u2": Uint16Array, "<i2": Int16Array, "<u4": Uint32Array, "<i4": Int32Array, "<f4": Float32Array, "<f8": Float64Array, ">b": Int8Array, ">B": Uint8Array, ">u1": Uint8Array, ">i1": Int8Array, ">u2": Uint16Array, ">i2": Int16Array, ">u4": Uint32Array, ">i4": Int32Array, ">f4": Float32Array, ">f8": Float64Array }; function getTypedArrayCtr(dtype) { const ctr = DTYPE_TYPEDARRAY_MAPPING[dtype]; if (!ctr) { throw Error(`Dtype not recognized or not supported in zarr.js, got ${dtype}.`); } return ctr; } function getTypedArrayDtypeString(t) { if (t instanceof Uint8Array) return "|u1"; if (t instanceof Int8Array) return "|i1"; if (t instanceof Uint16Array) return "<u2"; if (t instanceof Int16Array) return "<i2"; if (t instanceof Uint32Array) return "<u4"; if (t instanceof Int32Array) return "<i4"; if (t instanceof Float32Array) return "<f4"; if (t instanceof Float64Array) return "<f8"; throw new ValueError("Mapping for TypedArray to Dtypestring not known"); } function getNestedArrayConstructor(arr) { if (arr.byteLength !== void 0) { return arr.constructor; } return getNestedArrayConstructor(arr[0]); } function sliceNestedArray(arr, shape, selection) { const normalizedSelection = normalizeArraySelection(selection, shape); const [sliceIndices2, outShape] = selectionToSliceIndices(normalizedSelection, shape); const outArray = _sliceNestedArray(arr, shape, sliceIndices2); return [outArray, outShape]; } function _sliceNestedArray(arr, shape, selection) { const currentSlice = selection[0]; if (typeof currentSlice === "number") { if (shape.length === 1) { return arr[currentSlice]; } else { return _sliceNestedArray(arr[currentSlice], shape.slice(1), selection.slice(1)); } } const [from, to, step, outputSize] = currentSlice; if (outputSize === 0) { return new (getNestedArrayConstructor(arr))(0); } if (shape.length === 1) { if (step === 1) { return arr.slice(from, to); } const newArrData = new arr.constructor(outputSize); for (let i = 0; i < outputSize; i++) { newArrData[i] = arr[from + i * step]; } return newArrData; } let newArr = new Array(outputSize); for (let i = 0; i < outputSize; i++) { newArr[i] = _sliceNestedArray(arr[from + i * step], shape.slice(1), selection.slice(1)); } if (outputSize > 0 && typeof newArr[0] === "number") { const typedArrayConstructor = arr[0].constructor; newArr = typedArrayConstructor.from(newArr); } return newArr; } function setNestedArrayToScalar(dstArr, value, destShape, selection) { const normalizedSelection = normalizeArraySelection(selection, destShape, true); const [sliceIndices2, _outShape] = selectionToSliceIndices(normalizedSelection, destShape); _setNestedArrayToScalar(dstArr, value, destShape, sliceIndices2); } function setNestedArray(dstArr, sourceArr, destShape, sourceShape, selection) { const normalizedSelection = normalizeArraySelection(selection, destShape, false); const [sliceIndices2, outShape] = selectionToSliceIndices(normalizedSelection, destShape); if (JSON.stringify(outShape) !== JSON.stringify(sourceShape)) { throw new ValueError(`Shape mismatch in target and source NestedArray: ${outShape} and ${sourceShape}`); } _setNestedArray(dstArr, sourceArr, destShape, sliceIndices2); } function _setNestedArray(dstArr, sourceArr, shape, selection) { const currentSlice = selection[0]; if (typeof sourceArr === "number") { _setNestedArrayToScalar(dstArr, sourceArr, shape, selection.map((x) => typeof x === "number" ? [x, x + 1, 1, 1] : x)); return; } if (typeof currentSlice === "number") { _setNestedArray(dstArr[currentSlice], sourceArr, shape.slice(1), selection.slice(1)); return; } const [from, _to, step, outputSize] = currentSlice; if (shape.length === 1) { if (step === 1) { dstArr.set(sourceArr, from); } else { for (let i = 0; i < outputSize; i++) { dstArr[from + i * step] = sourceArr[i]; } } return; } for (let i = 0; i < outputSize; i++) { _setNestedArray(dstArr[from + i * step], sourceArr[i], shape.slice(1), selection.slice(1)); } } function _setNestedArrayToScalar(dstArr, value, shape, selection) { const currentSlice = selection[0]; const [from, to, step, outputSize] = currentSlice; if (shape.length === 1) { if (step === 1) { dstArr.fill(value, from, to); } else { for (let i = 0; i < outputSize; i++) { dstArr[from + i * step] = value; } } return; } for (let i = 0; i < outputSize; i++) { _setNestedArrayToScalar(dstArr[from + i * step], value, shape.slice(1), selection.slice(1)); } } function flattenNestedArray(arr, shape, constr) { if (constr === void 0) { constr = getNestedArrayConstructor(arr); } const size = shape.reduce((x, y) => x * y, 1); const outArr = new constr(size); _flattenNestedArray(arr, shape, outArr, 0); return outArr; } function _flattenNestedArray(arr, shape, outArr, offset) { if (shape.length === 1) { outArr.set(arr, offset); return; } if (shape.length === 2) { for (let i = 0; i < shape[0]; i++) { outArr.set(arr[i], offset + shape[1] * i); } return arr; } const nextShape = shape.slice(1); const mult = nextShape.reduce((x, y) => x * y, 1); for (let i = 0; i < shape[0]; i++) { _flattenNestedArray(arr[i], nextShape, outArr, offset + mult * i); } return arr; } var NestedArray = class { constructor(data, shape, dtype) { const dataIsTypedArray = data !== null && !!data.BYTES_PER_ELEMENT; if (shape === void 0) { if (!dataIsTypedArray) { throw new ValueError("Shape argument is required unless you pass in a TypedArray"); } shape = [data.length]; } if (dtype === void 0) { if (!dataIsTypedArray) { throw new ValueError("Dtype argument is required unless you pass in a TypedArray"); } dtype = getTypedArrayDtypeString(data); } shape = normalizeShape(shape); this.shape = shape; this.dtype = dtype; if (dataIsTypedArray && shape.length !== 1) { data = data.buffer; } if (this.shape.length === 0) { this.data = new (getTypedArrayCtr(dtype))(1); } else if ( // tslint:disable-next-line: strict-type-predicates IS_NODE && Buffer.isBuffer(data) || isArrayBufferLike(data) || data === null ) { const numShapeElements = shape.reduce((x, y) => x * y, 1); if (data === null) { data = new ArrayBuffer(numShapeElements * parseInt(dtype[dtype.length - 1], 10)); } const numDataElements = data.byteLength / parseInt(dtype[dtype.length - 1], 10); if (numShapeElements !== numDataElements) { throw new Error(`Buffer has ${numDataElements} of dtype ${dtype}, shape is too large or small ${shape} (flat=${numShapeElements})`); } const typeConstructor = getTypedArrayCtr(dtype); this.data = createNestedArray(data, typeConstructor, shape); } else { this.data = data; } } get(selection) { const [sliceResult, outShape] = sliceNestedArray(this.data, this.shape, selection); if (outShape.length === 0) { return sliceResult; } else { return new NestedArray(sliceResult, outShape, this.dtype); } } set(selection = null, value) { if (selection === null) { selection = [slice(null)]; } if (typeof value === "number") { if (this.shape.length === 0) { this.data[0] = value; } else { setNestedArrayToScalar(this.data, value, this.shape, selection); } } else { setNestedArray(this.data, value.data, this.shape, value.shape, selection); } } flatten() { if (this.shape.length === 1) { return this.data; } return flattenNestedArray(this.data, this.shape, getTypedArrayCtr(this.dtype)); } /** * Currently only supports a single integer as the size, TODO: support start, stop, step. */ static arange(size, dtype = "<i4") { const constr = getTypedArrayCtr(dtype); const data = rangeTypedArray([size], constr); return new NestedArray(data, [size], dtype); } }; function rangeTypedArray(shape, tContructor) { const size = shape.reduce((x, y) => x * y, 1); const data = new tContructor(size); data.set([...Array(size).keys()]); return data; } function createNestedArray(data, t, shape, offset = 0) { if (shape.length === 1) { return new t(data.slice(offset, offset + shape[0] * t.BYTES_PER_ELEMENT)); } const arr = new Array(shape[0]); if (shape.length === 2) { for (let i = 0; i < shape[0]; i++) { arr[i] = new t(data.slice(offset + shape[1] * i * t.BYTES_PER_ELEMENT, offset + shape[1] * (i + 1) * t.BYTES_PER_ELEMENT)); } return arr; } const nextShape = shape.slice(1); const mult = nextShape.reduce((x, y) => x * y, 1); for (let i = 0; i < shape[0]; i++) { arr[i] = createNestedArray(data, t, nextShape, offset + mult * i * t.BYTES_PER_ELEMENT); } return arr; } function setRawArrayToScalar(dstArr, dstStrides, dstShape, dstSelection, value) { const normalizedSelection = normalizeArraySelection(dstSelection, dstShape, true); const [sliceIndices2] = selectionToSliceIndices(normalizedSelection, dstShape); _setRawArrayToScalar(value, dstArr, dstStrides, sliceIndices2); } function setRawArray(dstArr, dstStrides, dstShape, dstSelection, sourceArr, sourceStrides, sourceShape) { const normalizedDstSelection = normalizeArraySelection(dstSelection, dstShape, false); const [dstSliceIndices, outShape] = selectionToSliceIndices(normalizedDstSelection, dstShape); if (JSON.stringify(outShape) !== JSON.stringify(sourceShape)) { throw new ValueError(`Shape mismatch in target and source RawArray: ${outShape} and ${sourceShape}`); } _setRawArray(dstArr, dstStrides, dstSliceIndices, sourceArr, sourceStrides); } function setRawArrayFromChunkItem(dstArr, dstStrides, dstShape, dstSelection, sourceArr, sourceStrides, sourceShape, sourceSelection) { const normalizedDstSelection = normalizeArraySelection(dstSelection, dstShape, true); const [dstSliceIndices] = selectionToSliceIndices(normalizedDstSelection, dstShape); const normalizedSourceSelection = normalizeArraySelection(sourceSelection, sourceShape, false); const [sourceSliceIndicies] = selectionToSliceIndices(normalizedSourceSelection, sourceShape); _setRawArrayFromChunkItem(dstArr, dstStrides, dstSliceIndices, sourceArr, sourceStrides, sourceSliceIndicies); } function _setRawArrayToScalar(value, dstArr, dstStrides, dstSliceIndices) { const [currentDstSlice, ...nextDstSliceIndices] = dstSliceIndices; const [currentDstStride, ...nextDstStrides] = dstStrides; const [from, _to, step, outputSize] = currentDstSlice; if (dstStrides.length === 1) { if (step === 1 && currentDstStride === 1) { dstArr.fill(value, from, from + outputSize); } else { for (let i = 0; i < outputSize; i++) { dstArr[currentDstStride * (from + step * i)] = value; } } return; } for (let i = 0; i < outputSize; i++) { _setRawArrayToScalar(value, dstArr.subarray(currentDstStride * (from + step * i)), nextDstStrides, nextDstSliceIndices); } } function _setRawArray(dstArr, dstStrides, dstSliceIndices, sourceArr, sourceStrides) { if (dstSliceIndices.length === 0) { dstArr.set(sourceArr); return; } const [currentDstSlice, ...nextDstSliceIndices] = dstSliceIndices; const [currentDstStride, ...nextDstStrides] = dstStrides; if (typeof currentDstSlice === "number") { _setRawArray(dstArr.subarray(currentDstSlice * currentDstStride), nextDstStrides, nextDstSliceIndices, sourceArr, sourceStrides); return; } const [currentSourceStride, ...nextSourceStrides] = sourceStrides; const [from, _to, step, outputSize] = currentDstSlice; if (dstStrides.length === 1) { if (step === 1 && currentDstStride === 1 && currentSourceStride === 1) { dstArr.set(sourceArr.subarray(0, outputSize), from); } else { for (let i = 0; i < outputSize; i++) { dstArr[currentDstStride * (from + step * i)] = sourceArr[currentSourceStride * i]; } } return; } for (let i = 0; i < outputSize; i++) { _setRawArray(dstArr.subarray(currentDstStride * (from + i * step)), nextDstStrides, nextDstSliceIndices, sourceArr.subarray(currentSourceStride * i), nextSourceStrides); } } function _setRawArrayFromChunkItem(dstArr, dstStrides, dstSliceIndices, sourceArr, sourceStrides, sourceSliceIndices) { if (sourceSliceIndices.length === 0) { dstArr.set(sourceArr.subarray(0, dstArr.length)); return; } const [currentDstSlice, ...nextDstSliceIndices] = dstSliceIndices; const [currentSourceSlice, ...nextSourceSliceIndices] = sourceSliceIndices; const [currentDstStride, ...nextDstStrides] = dstStrides; const [currentSourceStride, ...nextSourceStrides] = sourceStrides; if (typeof currentSourceSlice === "number") { _setRawArrayFromChunkItem( // Don't update destination offset/slices, just source dstArr, dstStrides, dstSliceIndices, sourceArr.subarray(currentSourceStride * currentSourceSlice), nextSourceStrides, nextSourceSliceIndices ); return; } const [from, _to, step, outputSize] = currentDstSlice; const [sfrom, _sto, sstep, _soutputSize] = currentSourceSlice; if (dstStrides.length === 1 && sourceStrides.length === 1) { if (step === 1 && currentDstStride === 1 && sstep === 1 && currentSourceStride === 1) { dstArr.set(sourceArr.subarray(sfrom, sfrom + outputSize), from); } else { for (let i = 0; i < outputSize; i++) { dstArr[currentDstStride * (from + step * i)] = sourceArr[currentSourceStride * (sfrom + sstep * i)]; } } return; } for (let i = 0; i < outputSize; i++) { _setRawArrayFromChunkItem(dstArr.subarray(currentDstStride * (from + i * step)), nextDstStrides, nextDstSliceIndices, sourceArr.subarray(currentSourceStride * (sfrom + i * sstep)), nextSourceStrides, nextSourceSliceIndices); } } var RawArray = class { constructor(data, shape, dtype, strides) { const dataIsTypedArray = data !== null && !!data.BYTES_PER_ELEMENT; if (shape === void 0) { if (!dataIsTypedArray) { throw new ValueError("Shape argument is required unless you pass in a TypedArray"); } shape = [data.length]; } shape = normalizeShape(shape); if (dtype === void 0) { if (!dataIsTypedArray) { throw new ValueError("Dtype argument is required unless you pass in a TypedArray"); } dtype = getTypedArrayDtypeString(data); } if (strides === void 0) { strides = getStrides(shape); } this.shape = shape; this.dtype = dtype; this.strides = strides; if (dataIsTypedArray && shape.length !== 1) { data = data.buffer; } if (this.shape.length === 0) { this.data = new (getTypedArrayCtr(dtype))(1); } else if ( // tslint:disable-next-line: strict-type-predicates IS_NODE && Buffer.isBuffer(data) || isArrayBufferLike(data) || data === null ) { const numShapeElements = shape.reduce((x, y) => x * y, 1); if (data === null) { data = new ArrayBuffer(numShapeElements * parseInt(dtype[dtype.length - 1], 10)); } const numDataElements = data.byteLength / parseInt(dtype[dtype.length - 1], 10); if (numShapeElements !== numDataElements) { throw new Error(`Buffer has ${numDataElements} of dtype ${dtype}, shape is too large or small ${shape} (flat=${numShapeElements})`); } const typeConstructor = getTypedArrayCtr(dtype); this.data = new typeConstructor(data); } else { this.data = data; } } set(selection = null, value, chunkSelection) { if (selection === null) { selection = [slice(null)]; } if (typeof value === "number") { if (this.shape.length === 0) { this.data[0] = value; } else { setRawArrayToScalar(this.data, this.strides, this.shape, selection, value); } } else if (value instanceof RawArray && chunkSelection) { setRawArrayFromChunkItem(this.data, this.strides, this.shape, selection, value.data, value.strides, value.shape, chunkSelection); } else { setRawArray(this.data, this.strides, this.shape, selection, value.data, value.strides, value.shape); } } }; var eventemitter3 = { exports: {} }; (function(module) { var has = Object.prototype.hasOwnProperty, prefix = "~"; function Events() { } if (Object.create) { Events.prototype = /* @__PURE__ */ Object.create(null); if (!new Events().__proto__) prefix = false; } function EE(fn, context, once) { this.fn = fn; this.context = context; this.once = once || false; } function addListener(emitter, event, fn, context, once) { if (typeof fn !== "function") { throw new TypeError("The listener must be a function"); } var listener = new EE(fn, context || emitter, once), evt = prefix ? prefix + event : event; if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++; else if (!emitter._events[evt].fn) emitter._events[evt].push(listener); else emitter._events[evt] = [emitter._events[evt], listener]; return emitter; } function clearEvent(emitter, evt) { if (--emitter._eventsCount === 0) emitter._events = new Events(); else delete emitter._events[evt]; } function EventEmitter2() { this._events = new Events(); this._eventsCount = 0; } EventEmitter2.prototype.eventNames = function eventNames() { var names = [], events, name; if (this._eventsCount === 0) return names; for (name in events = this._events) { if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); } if (Object.getOwnPropertySymbols) { return names.concat(Object.getOwnPropertySymbols(events)); } return names; }; EventEmitter2.prototype.listeners = function listeners(event) { var evt = prefix ? prefix + event : event, handlers = this._events[evt];