@vitessce/config 3.8.5 → 3.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,6 +1,18 @@
1
1
  const FileType = {
2
2
  // Joint file types
3
3
  ANNDATA_ZARR: "anndata.zarr",
4
+ ANNDATA_ZARR_ZIP: "anndata.zarr.zip",
5
+ SPATIALDATA_ZARR: "spatialdata.zarr",
6
+ SPATIALDATA_ZARR_ZIP: "spatialdata.zarr.zip",
7
+ // OME-Zarr
8
+ IMAGE_OME_ZARR: "image.ome-zarr",
9
+ OBS_SEGMENTATIONS_OME_ZARR: "obsSegmentations.ome-zarr",
10
+ // OME-Zarr - Zipped
11
+ IMAGE_OME_ZARR_ZIP: "image.ome-zarr.zip",
12
+ OBS_SEGMENTATIONS_OME_ZARR_ZIP: "obsSegmentations.ome-zarr.zip",
13
+ // OME-TIFF
14
+ IMAGE_OME_TIFF: "image.ome-tiff",
15
+ OBS_SEGMENTATIONS_OME_TIFF: "obsSegmentations.ome-tiff",
4
16
  RASTER_JSON: "raster.json",
5
17
  RASTER_OME_ZARR: "raster.ome-zarr"
6
18
  };
@@ -28,12 +40,12 @@ var hasRequiredPluralize;
28
40
  function requirePluralize() {
29
41
  if (hasRequiredPluralize) return pluralize$1.exports;
30
42
  hasRequiredPluralize = 1;
31
- (function(module, exports) {
32
- (function(root, pluralize2) {
43
+ (function(module2, exports) {
44
+ (function(root2, pluralize2) {
33
45
  if (typeof commonjsRequire === "function" && true && true) {
34
- module.exports = pluralize2();
46
+ module2.exports = pluralize2();
35
47
  } else {
36
- root.pluralize = pluralize2();
48
+ root2.pluralize = pluralize2();
37
49
  }
38
50
  })(pluralize, function() {
39
51
  var pluralRules = [];
@@ -430,12 +442,12 @@ var hasRequiredLoglevel;
430
442
  function requireLoglevel() {
431
443
  if (hasRequiredLoglevel) return loglevel$1.exports;
432
444
  hasRequiredLoglevel = 1;
433
- (function(module) {
434
- (function(root, definition) {
435
- if (module.exports) {
436
- module.exports = definition();
445
+ (function(module2) {
446
+ (function(root2, definition) {
447
+ if (module2.exports) {
448
+ module2.exports = definition();
437
449
  } else {
438
- root.log = definition();
450
+ root2.log = definition();
439
451
  }
440
452
  })(loglevel, function() {
441
453
  var noop = function() {
@@ -1419,10 +1431,10 @@ class VitessceConfig {
1419
1431
  * @returns {VitessceConfig} A new config instance, with values set to match
1420
1432
  * the config parameter.
1421
1433
  */
1422
- static fromJSON(config) {
1423
- const { name, description, version: schemaVersion } = config;
1434
+ static fromJSON(config2) {
1435
+ const { name, description, version: schemaVersion } = config2;
1424
1436
  const vc = new VitessceConfig({ schemaVersion, name, description });
1425
- config.datasets.forEach((d) => {
1437
+ config2.datasets.forEach((d) => {
1426
1438
  const newDataset = vc.addDataset(d.name, d.description, { uid: d.uid });
1427
1439
  d.files.forEach((f) => {
1428
1440
  newDataset.addFile({
@@ -1433,9 +1445,9 @@ class VitessceConfig {
1433
1445
  });
1434
1446
  });
1435
1447
  });
1436
- Object.keys(config.coordinationSpace).forEach((cType) => {
1448
+ Object.keys(config2.coordinationSpace).forEach((cType) => {
1437
1449
  if (cType !== CoordinationType.DATASET) {
1438
- const cObj = config.coordinationSpace[cType];
1450
+ const cObj = config2.coordinationSpace[cType];
1439
1451
  vc.config.coordinationSpace[cType] = {};
1440
1452
  Object.entries(cObj).forEach(([cScopeName, cScopeValue]) => {
1441
1453
  const scope = new VitessceConfigCoordinationScope(cType, cScopeName);
@@ -1444,7 +1456,7 @@ class VitessceConfig {
1444
1456
  });
1445
1457
  }
1446
1458
  });
1447
- config.layout.forEach((c) => {
1459
+ config2.layout.forEach((c) => {
1448
1460
  const newView = new VitessceConfigView(
1449
1461
  c.component,
1450
1462
  c.coordinationScopes,
@@ -1577,15 +1589,15 @@ const filterViews = (hintsConfig, possibleViews) => {
1577
1589
  }
1578
1590
  return resultViews;
1579
1591
  };
1580
- class AbstractAutoConfig {
1592
+ let AbstractAutoConfig$1 = class AbstractAutoConfig {
1581
1593
  async composeViewsConfig() {
1582
1594
  throw new Error("The composeViewsConfig() method has not been implemented.");
1583
1595
  }
1584
1596
  async composeFileConfig() {
1585
1597
  throw new Error("The composeFileConfig() method has not been implemented.");
1586
1598
  }
1587
- }
1588
- class OmeTiffAutoConfig extends AbstractAutoConfig {
1599
+ };
1600
+ class OmeTiffAutoConfig extends AbstractAutoConfig$1 {
1589
1601
  constructor(fileUrl) {
1590
1602
  super();
1591
1603
  this.fileUrl = fileUrl;
@@ -1618,7 +1630,7 @@ class OmeTiffAutoConfig extends AbstractAutoConfig {
1618
1630
  };
1619
1631
  }
1620
1632
  }
1621
- class OmeZarrAutoConfig extends AbstractAutoConfig {
1633
+ class OmeZarrAutoConfig extends AbstractAutoConfig$1 {
1622
1634
  constructor(fileUrl) {
1623
1635
  super();
1624
1636
  this.fileUrl = fileUrl;
@@ -1639,7 +1651,7 @@ class OmeZarrAutoConfig extends AbstractAutoConfig {
1639
1651
  };
1640
1652
  }
1641
1653
  }
1642
- class AnndataZarrAutoConfig extends AbstractAutoConfig {
1654
+ class AnndataZarrAutoConfig extends AbstractAutoConfig$1 {
1643
1655
  constructor(fileUrl) {
1644
1656
  super();
1645
1657
  this.fileUrl = fileUrl;
@@ -2046,7 +2058,7 @@ function getHintOptions(fileUrls) {
2046
2058
  const datasetType = Object.keys(fileTypes).sort().join(",");
2047
2059
  return HINT_TYPE_TO_FILE_TYPE_MAP?.[datasetType] || [];
2048
2060
  }
2049
- async function generateConfig(fileUrls, hintTitle = null) {
2061
+ async function generateConfig$1(fileUrls, hintTitle = null) {
2050
2062
  const vc = new VitessceConfig({
2051
2063
  schemaVersion: "1.0.15",
2052
2064
  name: "An automatically generated config. Adjust values and add layout components if needed.",
@@ -2081,16 +2093,2469 @@ async function generateConfig(fileUrls, hintTitle = null) {
2081
2093
  return vc.toJSON();
2082
2094
  });
2083
2095
  }
2096
+ function strip_prefix(path) {
2097
+ return path.slice(1);
2098
+ }
2099
+ function fetch_range(url, offset, length, opts = {}) {
2100
+ if (offset !== void 0 && length !== void 0) {
2101
+ opts = {
2102
+ ...opts,
2103
+ headers: {
2104
+ ...opts.headers,
2105
+ Range: `bytes=${offset}-${offset + length - 1}`
2106
+ }
2107
+ };
2108
+ }
2109
+ return fetch(url, opts);
2110
+ }
2111
+ function merge_init(storeOverrides, requestOverrides) {
2112
+ return {
2113
+ ...storeOverrides,
2114
+ ...requestOverrides,
2115
+ headers: {
2116
+ ...storeOverrides.headers,
2117
+ ...requestOverrides.headers
2118
+ }
2119
+ };
2120
+ }
2121
+ function assert$1(expression, msg = "") {
2122
+ if (!expression)
2123
+ throw new Error(msg);
2124
+ }
2125
+ function resolve(root2, path) {
2126
+ const base = typeof root2 === "string" ? new URL(root2) : root2;
2127
+ if (!base.pathname.endsWith("/")) {
2128
+ base.pathname += "/";
2129
+ }
2130
+ const resolved = new URL(path.slice(1), base);
2131
+ resolved.search = base.search;
2132
+ return resolved;
2133
+ }
2134
+ async function handle_response(response) {
2135
+ if (response.status === 404) {
2136
+ return void 0;
2137
+ }
2138
+ if (response.status === 200 || response.status === 206) {
2139
+ return new Uint8Array(await response.arrayBuffer());
2140
+ }
2141
+ throw new Error(`Unexpected response status ${response.status} ${response.statusText}`);
2142
+ }
2143
+ async function fetch_suffix(url, suffix_length, init, use_suffix_request) {
2144
+ if (use_suffix_request) {
2145
+ return fetch(url, {
2146
+ ...init,
2147
+ headers: { ...init.headers, Range: `bytes=-${suffix_length}` }
2148
+ });
2149
+ }
2150
+ let response = await fetch(url, { ...init, method: "HEAD" });
2151
+ if (!response.ok) {
2152
+ return response;
2153
+ }
2154
+ let content_length = response.headers.get("Content-Length");
2155
+ let length = Number(content_length);
2156
+ return fetch_range(url, length - suffix_length, length, init);
2157
+ }
2158
+ class FetchStore {
2159
+ #overrides;
2160
+ #use_suffix_request;
2161
+ constructor(url, options = {}) {
2162
+ this.url = url;
2163
+ this.#overrides = options.overrides ?? {};
2164
+ this.#use_suffix_request = options.useSuffixRequest ?? false;
2165
+ }
2166
+ #merge_init(overrides) {
2167
+ return merge_init(this.#overrides, overrides);
2168
+ }
2169
+ async get(key, options = {}) {
2170
+ let href = resolve(this.url, key).href;
2171
+ let response = await fetch(href, this.#merge_init(options));
2172
+ return handle_response(response);
2173
+ }
2174
+ async getRange(key, range, options = {}) {
2175
+ let url = resolve(this.url, key);
2176
+ let init = this.#merge_init(options);
2177
+ let response;
2178
+ if ("suffixLength" in range) {
2179
+ response = await fetch_suffix(url, range.suffixLength, init, this.#use_suffix_request);
2180
+ } else {
2181
+ response = await fetch_range(url, range.offset, range.length, init);
2182
+ }
2183
+ return handle_response(response);
2184
+ }
2185
+ }
2186
+ class BoolArray {
2187
+ #bytes;
2188
+ constructor(x, byteOffset, length) {
2189
+ if (typeof x === "number") {
2190
+ this.#bytes = new Uint8Array(x);
2191
+ } else if (x instanceof ArrayBuffer) {
2192
+ this.#bytes = new Uint8Array(x, byteOffset, length);
2193
+ } else {
2194
+ this.#bytes = new Uint8Array(Array.from(x, (v) => v ? 1 : 0));
2195
+ }
2196
+ }
2197
+ get BYTES_PER_ELEMENT() {
2198
+ return 1;
2199
+ }
2200
+ get byteOffset() {
2201
+ return this.#bytes.byteOffset;
2202
+ }
2203
+ get byteLength() {
2204
+ return this.#bytes.byteLength;
2205
+ }
2206
+ get buffer() {
2207
+ return this.#bytes.buffer;
2208
+ }
2209
+ get length() {
2210
+ return this.#bytes.length;
2211
+ }
2212
+ get(idx) {
2213
+ let value = this.#bytes[idx];
2214
+ return typeof value === "number" ? value !== 0 : value;
2215
+ }
2216
+ set(idx, value) {
2217
+ this.#bytes[idx] = value ? 1 : 0;
2218
+ }
2219
+ fill(value) {
2220
+ this.#bytes.fill(value ? 1 : 0);
2221
+ }
2222
+ *[Symbol.iterator]() {
2223
+ for (let i = 0; i < this.length; i++) {
2224
+ yield this.get(i);
2225
+ }
2226
+ }
2227
+ }
2228
+ class ByteStringArray {
2229
+ #encoder;
2230
+ constructor(chars, x, byteOffset, length) {
2231
+ this.chars = chars;
2232
+ this.#encoder = new TextEncoder();
2233
+ if (typeof x === "number") {
2234
+ this._data = new Uint8Array(x * chars);
2235
+ } else if (x instanceof ArrayBuffer) {
2236
+ if (length)
2237
+ length = length * chars;
2238
+ this._data = new Uint8Array(x, byteOffset, length);
2239
+ } else {
2240
+ let values = Array.from(x);
2241
+ this._data = new Uint8Array(values.length * chars);
2242
+ for (let i = 0; i < values.length; i++) {
2243
+ this.set(i, values[i]);
2244
+ }
2245
+ }
2246
+ }
2247
+ get BYTES_PER_ELEMENT() {
2248
+ return this.chars;
2249
+ }
2250
+ get byteOffset() {
2251
+ return this._data.byteOffset;
2252
+ }
2253
+ get byteLength() {
2254
+ return this._data.byteLength;
2255
+ }
2256
+ get buffer() {
2257
+ return this._data.buffer;
2258
+ }
2259
+ get length() {
2260
+ return this.byteLength / this.BYTES_PER_ELEMENT;
2261
+ }
2262
+ get(idx) {
2263
+ const view = new Uint8Array(this.buffer, this.byteOffset + this.chars * idx, this.chars);
2264
+ return new TextDecoder().decode(view).replace(/\x00/g, "");
2265
+ }
2266
+ set(idx, value) {
2267
+ const view = new Uint8Array(this.buffer, this.byteOffset + this.chars * idx, this.chars);
2268
+ view.fill(0);
2269
+ view.set(this.#encoder.encode(value));
2270
+ }
2271
+ fill(value) {
2272
+ const encoded = this.#encoder.encode(value);
2273
+ for (let i = 0; i < this.length; i++) {
2274
+ this._data.set(encoded, i * this.chars);
2275
+ }
2276
+ }
2277
+ *[Symbol.iterator]() {
2278
+ for (let i = 0; i < this.length; i++) {
2279
+ yield this.get(i);
2280
+ }
2281
+ }
2282
+ }
2283
+ class UnicodeStringArray {
2284
+ #data;
2285
+ constructor(chars, x, byteOffset, length) {
2286
+ this.chars = chars;
2287
+ if (typeof x === "number") {
2288
+ this.#data = new Int32Array(x * chars);
2289
+ } else if (x instanceof ArrayBuffer) {
2290
+ if (length)
2291
+ length *= chars;
2292
+ this.#data = new Int32Array(x, byteOffset, length);
2293
+ } else {
2294
+ const values = x;
2295
+ const d = new UnicodeStringArray(chars, 1);
2296
+ this.#data = new Int32Array(function* () {
2297
+ for (let str of values) {
2298
+ d.set(0, str);
2299
+ yield* d.#data;
2300
+ }
2301
+ }());
2302
+ }
2303
+ }
2304
+ get BYTES_PER_ELEMENT() {
2305
+ return this.#data.BYTES_PER_ELEMENT * this.chars;
2306
+ }
2307
+ get byteLength() {
2308
+ return this.#data.byteLength;
2309
+ }
2310
+ get byteOffset() {
2311
+ return this.#data.byteOffset;
2312
+ }
2313
+ get buffer() {
2314
+ return this.#data.buffer;
2315
+ }
2316
+ get length() {
2317
+ return this.#data.length / this.chars;
2318
+ }
2319
+ get(idx) {
2320
+ const offset = this.chars * idx;
2321
+ let result = "";
2322
+ for (let i = 0; i < this.chars; i++) {
2323
+ result += String.fromCodePoint(this.#data[offset + i]);
2324
+ }
2325
+ return result.replace(/\u0000/g, "");
2326
+ }
2327
+ set(idx, value) {
2328
+ const offset = this.chars * idx;
2329
+ const view = this.#data.subarray(offset, offset + this.chars);
2330
+ view.fill(0);
2331
+ for (let i = 0; i < this.chars; i++) {
2332
+ view[i] = value.codePointAt(i) ?? 0;
2333
+ }
2334
+ }
2335
+ fill(value) {
2336
+ this.set(0, value);
2337
+ let encoded = this.#data.subarray(0, this.chars);
2338
+ for (let i = 1; i < this.length; i++) {
2339
+ this.#data.set(encoded, i * this.chars);
2340
+ }
2341
+ }
2342
+ *[Symbol.iterator]() {
2343
+ for (let i = 0; i < this.length; i++) {
2344
+ yield this.get(i);
2345
+ }
2346
+ }
2347
+ }
2348
+ function json_encode_object(o) {
2349
+ const str = JSON.stringify(o, null, 2);
2350
+ return new TextEncoder().encode(str);
2351
+ }
2352
+ function json_decode_object(bytes) {
2353
+ const str = new TextDecoder().decode(bytes);
2354
+ return JSON.parse(str);
2355
+ }
2356
+ function byteswap_inplace(view, bytes_per_element2) {
2357
+ const numFlips = bytes_per_element2 / 2;
2358
+ const endByteIndex = bytes_per_element2 - 1;
2359
+ let t = 0;
2360
+ for (let i = 0; i < view.length; i += bytes_per_element2) {
2361
+ for (let j = 0; j < numFlips; j += 1) {
2362
+ t = view[i + j];
2363
+ view[i + j] = view[i + endByteIndex - j];
2364
+ view[i + endByteIndex - j] = t;
2365
+ }
2366
+ }
2367
+ }
2368
+ function get_ctr(data_type) {
2369
+ if (data_type === "v2:object") {
2370
+ return globalThis.Array;
2371
+ }
2372
+ let match = data_type.match(/v2:([US])(\d+)/);
2373
+ if (match) {
2374
+ let [, kind, chars] = match;
2375
+ return (kind === "U" ? UnicodeStringArray : ByteStringArray).bind(null, Number(chars));
2376
+ }
2377
+ let ctr = {
2378
+ int8: Int8Array,
2379
+ int16: Int16Array,
2380
+ int32: Int32Array,
2381
+ int64: globalThis.BigInt64Array,
2382
+ uint8: Uint8Array,
2383
+ uint16: Uint16Array,
2384
+ uint32: Uint32Array,
2385
+ uint64: globalThis.BigUint64Array,
2386
+ float16: globalThis.Float16Array,
2387
+ float32: Float32Array,
2388
+ float64: Float64Array,
2389
+ bool: BoolArray
2390
+ }[data_type];
2391
+ assert(ctr, `Unknown or unsupported data_type: ${data_type}`);
2392
+ return ctr;
2393
+ }
2394
+ function get_strides(shape, order) {
2395
+ const rank = shape.length;
2396
+ if (typeof order === "string") {
2397
+ order = order === "C" ? Array.from({ length: rank }, (_, i) => i) : Array.from({ length: rank }, (_, i) => rank - 1 - i);
2398
+ }
2399
+ assert(rank === order.length, "Order length must match the number of dimensions.");
2400
+ let step = 1;
2401
+ let stride = new Array(rank);
2402
+ for (let i = order.length - 1; i >= 0; i--) {
2403
+ stride[order[i]] = step;
2404
+ step *= shape[order[i]];
2405
+ }
2406
+ return stride;
2407
+ }
2408
+ function create_chunk_key_encoder({ name, configuration }) {
2409
+ if (name === "default") {
2410
+ const separator = configuration?.separator ?? "/";
2411
+ return (chunk_coords) => ["c", ...chunk_coords].join(separator);
2412
+ }
2413
+ if (name === "v2") {
2414
+ const separator = configuration?.separator ?? ".";
2415
+ return (chunk_coords) => chunk_coords.join(separator) || "0";
2416
+ }
2417
+ throw new Error(`Unknown chunk key encoding: ${name}`);
2418
+ }
2419
+ function coerce_dtype(dtype) {
2420
+ if (dtype === "|O") {
2421
+ return { data_type: "v2:object" };
2422
+ }
2423
+ let match = dtype.match(/^([<|>])(.*)$/);
2424
+ assert(match, `Invalid dtype: ${dtype}`);
2425
+ let [, endian, rest] = match;
2426
+ let data_type = {
2427
+ b1: "bool",
2428
+ i1: "int8",
2429
+ u1: "uint8",
2430
+ i2: "int16",
2431
+ u2: "uint16",
2432
+ i4: "int32",
2433
+ u4: "uint32",
2434
+ i8: "int64",
2435
+ u8: "uint64",
2436
+ f2: "float16",
2437
+ f4: "float32",
2438
+ f8: "float64"
2439
+ }[rest] ?? (rest.startsWith("S") || rest.startsWith("U") ? `v2:${rest}` : void 0);
2440
+ assert(data_type, `Unsupported or unknown dtype: ${dtype}`);
2441
+ if (endian === "|") {
2442
+ return { data_type };
2443
+ }
2444
+ return { data_type, endian: endian === "<" ? "little" : "big" };
2445
+ }
2446
+ function v2_to_v3_array_metadata(meta, attributes = {}) {
2447
+ let codecs = [];
2448
+ let dtype = coerce_dtype(meta.dtype);
2449
+ if (meta.order === "F") {
2450
+ codecs.push({ name: "transpose", configuration: { order: "F" } });
2451
+ }
2452
+ if ("endian" in dtype && dtype.endian === "big") {
2453
+ codecs.push({ name: "bytes", configuration: { endian: "big" } });
2454
+ }
2455
+ for (let { id, ...configuration } of meta.filters ?? []) {
2456
+ codecs.push({ name: id, configuration });
2457
+ }
2458
+ if (meta.compressor) {
2459
+ let { id, ...configuration } = meta.compressor;
2460
+ codecs.push({ name: id, configuration });
2461
+ }
2462
+ return {
2463
+ zarr_format: 3,
2464
+ node_type: "array",
2465
+ shape: meta.shape,
2466
+ data_type: dtype.data_type,
2467
+ chunk_grid: {
2468
+ name: "regular",
2469
+ configuration: {
2470
+ chunk_shape: meta.chunks
2471
+ }
2472
+ },
2473
+ chunk_key_encoding: {
2474
+ name: "v2",
2475
+ configuration: {
2476
+ separator: meta.dimension_separator ?? "."
2477
+ }
2478
+ },
2479
+ codecs,
2480
+ fill_value: meta.fill_value,
2481
+ attributes
2482
+ };
2483
+ }
2484
+ function v2_to_v3_group_metadata(_meta, attributes = {}) {
2485
+ return {
2486
+ zarr_format: 3,
2487
+ node_type: "group",
2488
+ attributes
2489
+ };
2490
+ }
2491
+ function is_dtype(dtype, query) {
2492
+ if (query !== "number" && query !== "bigint" && query !== "boolean" && query !== "object" && query !== "string") {
2493
+ return dtype === query;
2494
+ }
2495
+ let is_boolean = dtype === "bool";
2496
+ if (query === "boolean")
2497
+ return is_boolean;
2498
+ let is_string = dtype.startsWith("v2:U") || dtype.startsWith("v2:S");
2499
+ if (query === "string")
2500
+ return is_string;
2501
+ let is_bigint = dtype === "int64" || dtype === "uint64";
2502
+ if (query === "bigint")
2503
+ return is_bigint;
2504
+ let is_object = dtype === "v2:object";
2505
+ if (query === "object")
2506
+ return is_object;
2507
+ return !is_string && !is_bigint && !is_boolean && !is_object;
2508
+ }
2509
+ function is_sharding_codec(codec) {
2510
+ return codec?.name === "sharding_indexed";
2511
+ }
2512
+ function ensure_correct_scalar(metadata) {
2513
+ if ((metadata.data_type === "uint64" || metadata.data_type === "int64") && metadata.fill_value != null) {
2514
+ return BigInt(metadata.fill_value);
2515
+ }
2516
+ return metadata.fill_value;
2517
+ }
2518
+ function rethrow_unless(error, ...errors) {
2519
+ if (!errors.some((ErrorClass) => error instanceof ErrorClass)) {
2520
+ throw error;
2521
+ }
2522
+ }
2523
+ function assert(expression, msg = "") {
2524
+ if (!expression) {
2525
+ throw new Error(msg);
2526
+ }
2527
+ }
2528
+ async function decompress(data, { format, signal }) {
2529
+ const response = data instanceof Response ? data : new Response(data);
2530
+ assert(response.body, "Response does not contain body.");
2531
+ try {
2532
+ const decompressedResponse = new Response(response.body.pipeThrough(new DecompressionStream(format), { signal }));
2533
+ const buffer = await decompressedResponse.arrayBuffer();
2534
+ return buffer;
2535
+ } catch {
2536
+ signal?.throwIfAborted();
2537
+ throw new Error(`Failed to decode ${format}`);
2538
+ }
2539
+ }
2540
+ class BitroundCodec {
2541
+ constructor(configuration, _meta) {
2542
+ this.kind = "array_to_array";
2543
+ assert(configuration.keepbits >= 0, "keepbits must be zero or positive");
2544
+ }
2545
+ static fromConfig(configuration, meta) {
2546
+ return new BitroundCodec(configuration, meta);
2547
+ }
2548
+ /**
2549
+ * Encode a chunk of data with bit-rounding.
2550
+ * @param _arr - The chunk to encode
2551
+ */
2552
+ encode(_arr) {
2553
+ throw new Error("`BitroundCodec.encode` is not implemented. Please open an issue at https://github.com/manzt/zarrita.js/issues.");
2554
+ }
2555
+ /**
2556
+ * Decode a chunk of data (no-op).
2557
+ * @param arr - The chunk to decode
2558
+ * @returns The decoded chunk
2559
+ */
2560
+ decode(arr) {
2561
+ return arr;
2562
+ }
2563
+ }
2564
+ const LITTLE_ENDIAN_OS = system_is_little_endian();
2565
+ function system_is_little_endian() {
2566
+ const a = new Uint32Array([305419896]);
2567
+ const b = new Uint8Array(a.buffer, a.byteOffset, a.byteLength);
2568
+ return !(b[0] === 18);
2569
+ }
2570
+ function bytes_per_element(TypedArray) {
2571
+ if ("BYTES_PER_ELEMENT" in TypedArray) {
2572
+ return TypedArray.BYTES_PER_ELEMENT;
2573
+ }
2574
+ return 4;
2575
+ }
2576
+ class BytesCodec {
2577
+ constructor(configuration, meta) {
2578
+ this.kind = "array_to_bytes";
2579
+ this.#endian = configuration?.endian;
2580
+ this.#TypedArray = get_ctr(meta.data_type);
2581
+ this.#shape = meta.shape;
2582
+ this.#stride = get_strides(meta.shape, "C");
2583
+ const sample = new this.#TypedArray(0);
2584
+ this.#BYTES_PER_ELEMENT = sample.BYTES_PER_ELEMENT;
2585
+ }
2586
+ #stride;
2587
+ #TypedArray;
2588
+ #BYTES_PER_ELEMENT;
2589
+ #shape;
2590
+ #endian;
2591
+ static fromConfig(configuration, meta) {
2592
+ return new BytesCodec(configuration, meta);
2593
+ }
2594
+ encode(arr) {
2595
+ let bytes = new Uint8Array(arr.data.buffer);
2596
+ if (LITTLE_ENDIAN_OS && this.#endian === "big") {
2597
+ byteswap_inplace(bytes, bytes_per_element(this.#TypedArray));
2598
+ }
2599
+ return bytes;
2600
+ }
2601
+ decode(bytes) {
2602
+ if (LITTLE_ENDIAN_OS && this.#endian === "big") {
2603
+ byteswap_inplace(bytes, bytes_per_element(this.#TypedArray));
2604
+ }
2605
+ return {
2606
+ data: new this.#TypedArray(bytes.buffer, bytes.byteOffset, bytes.byteLength / this.#BYTES_PER_ELEMENT),
2607
+ shape: this.#shape,
2608
+ stride: this.#stride
2609
+ };
2610
+ }
2611
+ }
2612
+ class Crc32cCodec {
2613
+ constructor() {
2614
+ this.kind = "bytes_to_bytes";
2615
+ }
2616
+ static fromConfig() {
2617
+ return new Crc32cCodec();
2618
+ }
2619
+ encode(_) {
2620
+ throw new Error("Not implemented");
2621
+ }
2622
+ decode(arr) {
2623
+ return new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength - 4);
2624
+ }
2625
+ }
2626
+ class GzipCodec {
2627
+ constructor() {
2628
+ this.kind = "bytes_to_bytes";
2629
+ }
2630
+ static fromConfig(_) {
2631
+ return new GzipCodec();
2632
+ }
2633
+ encode(_bytes) {
2634
+ throw new Error("Gzip encoding is not enabled by default. Please register a custom codec with `numcodecs/gzip`.");
2635
+ }
2636
+ async decode(bytes) {
2637
+ const buffer = await decompress(bytes, { format: "gzip" });
2638
+ return new Uint8Array(buffer);
2639
+ }
2640
+ }
2641
+ function throw_on_nan_replacer(_key, value) {
2642
+ assert(!Number.isNaN(value), "JsonCodec allow_nan is false but NaN was encountered during encoding.");
2643
+ assert(value !== Number.POSITIVE_INFINITY, "JsonCodec allow_nan is false but Infinity was encountered during encoding.");
2644
+ assert(value !== Number.NEGATIVE_INFINITY, "JsonCodec allow_nan is false but -Infinity was encountered during encoding.");
2645
+ return value;
2646
+ }
2647
+ function sort_keys_replacer(_key, value) {
2648
+ return value instanceof Object && !Array.isArray(value) ? Object.keys(value).sort().reduce((sorted, key) => {
2649
+ sorted[key] = value[key];
2650
+ return sorted;
2651
+ }, {}) : value;
2652
+ }
2653
+ class JsonCodec {
2654
+ constructor(configuration = {}) {
2655
+ this.kind = "array_to_bytes";
2656
+ this.configuration = configuration;
2657
+ const { encoding = "utf-8", skipkeys = false, ensure_ascii = true, check_circular = true, allow_nan = true, sort_keys = true, indent, strict = true } = configuration;
2658
+ let separators = configuration.separators;
2659
+ if (!separators) {
2660
+ if (!indent) {
2661
+ separators = [",", ":"];
2662
+ } else {
2663
+ separators = [", ", ": "];
2664
+ }
2665
+ }
2666
+ this.#encoder_config = {
2667
+ encoding,
2668
+ skipkeys,
2669
+ ensure_ascii,
2670
+ check_circular,
2671
+ allow_nan,
2672
+ indent,
2673
+ separators,
2674
+ sort_keys
2675
+ };
2676
+ this.#decoder_config = { strict };
2677
+ }
2678
+ #encoder_config;
2679
+ #decoder_config;
2680
+ static fromConfig(configuration) {
2681
+ return new JsonCodec(configuration);
2682
+ }
2683
+ encode(buf) {
2684
+ const { indent, encoding, ensure_ascii, check_circular, allow_nan, sort_keys } = this.#encoder_config;
2685
+ assert(encoding === "utf-8", "JsonCodec does not yet support non-utf-8 encoding.");
2686
+ const replacer_functions = [];
2687
+ assert(check_circular, "JsonCodec does not yet support skipping the check for circular references during encoding.");
2688
+ if (!allow_nan) {
2689
+ replacer_functions.push(throw_on_nan_replacer);
2690
+ }
2691
+ if (sort_keys) {
2692
+ replacer_functions.push(sort_keys_replacer);
2693
+ }
2694
+ const items = Array.from(buf.data);
2695
+ items.push("|O");
2696
+ items.push(buf.shape);
2697
+ let replacer;
2698
+ if (replacer_functions.length) {
2699
+ replacer = (key, value) => {
2700
+ let new_value = value;
2701
+ for (let sub_replacer of replacer_functions) {
2702
+ new_value = sub_replacer(key, new_value);
2703
+ }
2704
+ return new_value;
2705
+ };
2706
+ }
2707
+ let json_str = JSON.stringify(items, replacer, indent);
2708
+ if (ensure_ascii) {
2709
+ json_str = json_str.replace(/[\u007F-\uFFFF]/g, (chr) => {
2710
+ const full_str = `0000${chr.charCodeAt(0).toString(16)}`;
2711
+ const sub_str = full_str.substring(full_str.length - 4);
2712
+ return `\\u${sub_str}`;
2713
+ });
2714
+ }
2715
+ return new TextEncoder().encode(json_str);
2716
+ }
2717
+ decode(bytes) {
2718
+ const { strict } = this.#decoder_config;
2719
+ assert(strict, "JsonCodec does not yet support non-strict decoding.");
2720
+ const items = json_decode_object(bytes);
2721
+ const shape = items.pop();
2722
+ items.pop();
2723
+ assert(shape, "0D not implemented for JsonCodec.");
2724
+ const stride = get_strides(shape, "C");
2725
+ const data = items;
2726
+ return { data, shape, stride };
2727
+ }
2728
+ }
2729
+ function proxy(arr) {
2730
+ if (arr instanceof BoolArray || arr instanceof ByteStringArray || arr instanceof UnicodeStringArray) {
2731
+ const arrp = new Proxy(arr, {
2732
+ get(target, prop) {
2733
+ return target.get(Number(prop));
2734
+ },
2735
+ set(target, prop, value) {
2736
+ target.set(Number(prop), value);
2737
+ return true;
2738
+ }
2739
+ });
2740
+ return arrp;
2741
+ }
2742
+ return arr;
2743
+ }
2744
+ function empty_like(chunk, order) {
2745
+ let data;
2746
+ if (chunk.data instanceof ByteStringArray || chunk.data instanceof UnicodeStringArray) {
2747
+ data = new chunk.constructor(
2748
+ // @ts-expect-error
2749
+ chunk.data.length,
2750
+ chunk.data.chars
2751
+ );
2752
+ } else {
2753
+ data = new chunk.constructor(chunk.data.length);
2754
+ }
2755
+ return {
2756
+ data,
2757
+ shape: chunk.shape,
2758
+ stride: get_strides(chunk.shape, order)
2759
+ };
2760
+ }
2761
+ function convert_array_order(src, target) {
2762
+ let out = empty_like(src, target);
2763
+ let n_dims = src.shape.length;
2764
+ let size = src.data.length;
2765
+ let index = Array(n_dims).fill(0);
2766
+ let src_data = proxy(src.data);
2767
+ let out_data = proxy(out.data);
2768
+ for (let src_idx = 0; src_idx < size; src_idx++) {
2769
+ let out_idx = 0;
2770
+ for (let dim = 0; dim < n_dims; dim++) {
2771
+ out_idx += index[dim] * out.stride[dim];
2772
+ }
2773
+ out_data[out_idx] = src_data[src_idx];
2774
+ index[0] += 1;
2775
+ for (let dim = 0; dim < n_dims; dim++) {
2776
+ if (index[dim] === src.shape[dim]) {
2777
+ if (dim + 1 === n_dims) {
2778
+ break;
2779
+ }
2780
+ index[dim] = 0;
2781
+ index[dim + 1] += 1;
2782
+ }
2783
+ }
2784
+ }
2785
+ return out;
2786
+ }
2787
+ function get_order(chunk) {
2788
+ let rank = chunk.shape.length;
2789
+ assert(rank === chunk.stride.length, "Shape and stride must have the same length.");
2790
+ return chunk.stride.map((s, i) => ({ stride: s, index: i })).sort((a, b) => b.stride - a.stride).map((entry) => entry.index);
2791
+ }
2792
+ function matches_order(chunk, target) {
2793
+ let source = get_order(chunk);
2794
+ assert(source.length === target.length, "Orders must match");
2795
+ return source.every((dim, i) => dim === target[i]);
2796
+ }
2797
+ class TransposeCodec {
2798
+ constructor(configuration, meta) {
2799
+ this.kind = "array_to_array";
2800
+ let value = configuration.order ?? "C";
2801
+ let rank = meta.shape.length;
2802
+ let order = new Array(rank);
2803
+ let inverseOrder = new Array(rank);
2804
+ if (value === "C") {
2805
+ for (let i = 0; i < rank; ++i) {
2806
+ order[i] = i;
2807
+ inverseOrder[i] = i;
2808
+ }
2809
+ } else if (value === "F") {
2810
+ for (let i = 0; i < rank; ++i) {
2811
+ order[i] = rank - i - 1;
2812
+ inverseOrder[i] = rank - i - 1;
2813
+ }
2814
+ } else {
2815
+ order = value;
2816
+ order.forEach((x, i) => {
2817
+ assert(inverseOrder[x] === void 0, `Invalid permutation: ${JSON.stringify(value)}`);
2818
+ inverseOrder[x] = i;
2819
+ });
2820
+ }
2821
+ this.#order = order;
2822
+ this.#inverseOrder = inverseOrder;
2823
+ }
2824
+ #order;
2825
+ #inverseOrder;
2826
+ static fromConfig(configuration, meta) {
2827
+ return new TransposeCodec(configuration, meta);
2828
+ }
2829
+ encode(arr) {
2830
+ if (matches_order(arr, this.#inverseOrder)) {
2831
+ return arr;
2832
+ }
2833
+ return convert_array_order(arr, this.#inverseOrder);
2834
+ }
2835
+ decode(arr) {
2836
+ return {
2837
+ data: arr.data,
2838
+ shape: arr.shape,
2839
+ stride: get_strides(arr.shape, this.#order)
2840
+ };
2841
+ }
2842
+ }
2843
+ class VLenUTF8 {
2844
+ constructor(shape) {
2845
+ this.kind = "array_to_bytes";
2846
+ this.#shape = shape;
2847
+ this.#strides = get_strides(shape, "C");
2848
+ }
2849
+ #shape;
2850
+ #strides;
2851
+ static fromConfig(_, meta) {
2852
+ return new VLenUTF8(meta.shape);
2853
+ }
2854
+ encode(_chunk) {
2855
+ throw new Error("Method not implemented.");
2856
+ }
2857
+ decode(bytes) {
2858
+ let decoder = new TextDecoder();
2859
+ let view = new DataView(bytes.buffer);
2860
+ let data = Array(view.getUint32(0, true));
2861
+ let pos = 4;
2862
+ for (let i = 0; i < data.length; i++) {
2863
+ let item_length = view.getUint32(pos, true);
2864
+ pos += 4;
2865
+ data[i] = decoder.decode(bytes.buffer.slice(pos, pos + item_length));
2866
+ pos += item_length;
2867
+ }
2868
+ return { data, shape: this.#shape, stride: this.#strides };
2869
+ }
2870
+ }
2871
+ class ZlibCodec {
2872
+ constructor() {
2873
+ this.kind = "bytes_to_bytes";
2874
+ }
2875
+ static fromConfig(_) {
2876
+ return new ZlibCodec();
2877
+ }
2878
+ encode(_bytes) {
2879
+ throw new Error("Zlib encoding is not enabled by default. Please register a codec with `numcodecs/zlib`.");
2880
+ }
2881
+ async decode(bytes) {
2882
+ const buffer = await decompress(bytes, { format: "deflate" });
2883
+ return new Uint8Array(buffer);
2884
+ }
2885
+ }
2886
+ function create_default_registry() {
2887
+ return (/* @__PURE__ */ new Map()).set("blosc", () => import("./blosc-DvQQ1ST0.js").then((m) => m.default)).set("lz4", () => import("./lz4-BIbM36RN.js").then((m) => m.default)).set("zstd", () => import("./zstd-CO575QiM.js").then((m) => m.default)).set("gzip", () => GzipCodec).set("zlib", () => ZlibCodec).set("transpose", () => TransposeCodec).set("bytes", () => BytesCodec).set("crc32c", () => Crc32cCodec).set("vlen-utf8", () => VLenUTF8).set("json2", () => JsonCodec).set("bitround", () => BitroundCodec);
2888
+ }
2889
+ const registry = create_default_registry();
2890
+ function create_codec_pipeline(chunk_metadata) {
2891
+ let codecs;
2892
+ return {
2893
+ async encode(chunk) {
2894
+ if (!codecs)
2895
+ codecs = await load_codecs(chunk_metadata);
2896
+ for (const codec of codecs.array_to_array) {
2897
+ chunk = await codec.encode(chunk);
2898
+ }
2899
+ let bytes = await codecs.array_to_bytes.encode(chunk);
2900
+ for (const codec of codecs.bytes_to_bytes) {
2901
+ bytes = await codec.encode(bytes);
2902
+ }
2903
+ return bytes;
2904
+ },
2905
+ async decode(bytes) {
2906
+ if (!codecs)
2907
+ codecs = await load_codecs(chunk_metadata);
2908
+ for (let i = codecs.bytes_to_bytes.length - 1; i >= 0; i--) {
2909
+ bytes = await codecs.bytes_to_bytes[i].decode(bytes);
2910
+ }
2911
+ let chunk = await codecs.array_to_bytes.decode(bytes);
2912
+ for (let i = codecs.array_to_array.length - 1; i >= 0; i--) {
2913
+ chunk = await codecs.array_to_array[i].decode(chunk);
2914
+ }
2915
+ return chunk;
2916
+ }
2917
+ };
2918
+ }
2919
+ async function load_codecs(chunk_meta) {
2920
+ let promises = chunk_meta.codecs.map(async (meta) => {
2921
+ let Codec = await registry.get(meta.name)?.();
2922
+ assert(Codec, `Unknown codec: ${meta.name}`);
2923
+ return { Codec, meta };
2924
+ });
2925
+ let array_to_array = [];
2926
+ let array_to_bytes;
2927
+ let bytes_to_bytes = [];
2928
+ for await (let { Codec, meta } of promises) {
2929
+ let codec = Codec.fromConfig(meta.configuration, chunk_meta);
2930
+ switch (codec.kind) {
2931
+ case "array_to_array":
2932
+ array_to_array.push(codec);
2933
+ break;
2934
+ case "array_to_bytes":
2935
+ array_to_bytes = codec;
2936
+ break;
2937
+ default:
2938
+ bytes_to_bytes.push(codec);
2939
+ }
2940
+ }
2941
+ if (!array_to_bytes) {
2942
+ assert(is_typed_array_like_meta(chunk_meta), `Cannot encode ${chunk_meta.data_type} to bytes without a codec`);
2943
+ array_to_bytes = BytesCodec.fromConfig({ endian: "little" }, chunk_meta);
2944
+ }
2945
+ return { array_to_array, array_to_bytes, bytes_to_bytes };
2946
+ }
2947
+ function is_typed_array_like_meta(meta) {
2948
+ return meta.data_type !== "v2:object";
2949
+ }
2950
+ class NodeNotFoundError extends Error {
2951
+ constructor(context, options = {}) {
2952
+ super(`Node not found: ${context}`, options);
2953
+ this.name = "NodeNotFoundError";
2954
+ }
2955
+ }
2956
+ class KeyError extends Error {
2957
+ constructor(path) {
2958
+ super(`Missing key: ${path}`);
2959
+ this.name = "KeyError";
2960
+ }
2961
+ }
2962
+ async function get_consolidated_metadata(store, metadataKeyOption) {
2963
+ const metadataKey = metadataKeyOption ?? ".zmetadata";
2964
+ let bytes = await store.get(`/${metadataKey}`);
2965
+ if (!bytes) {
2966
+ throw new NodeNotFoundError("v2 consolidated metadata", {
2967
+ cause: new KeyError(`/${metadataKey}`)
2968
+ });
2969
+ }
2970
+ let meta = json_decode_object(bytes);
2971
+ assert(meta.zarr_consolidated_format === 1, "Unsupported consolidated format.");
2972
+ return meta;
2973
+ }
2974
+ function is_meta_key(key) {
2975
+ return key.endsWith(".zarray") || key.endsWith(".zgroup") || key.endsWith(".zattrs") || key.endsWith("zarr.json");
2976
+ }
2977
+ function is_v3(meta) {
2978
+ return "zarr_format" in meta && meta.zarr_format === 3;
2979
+ }
2980
+ async function withConsolidated(store, opts = {}) {
2981
+ let v2_meta = await get_consolidated_metadata(store, opts.metadataKey);
2982
+ let known_meta = {};
2983
+ for (let [key, value] of Object.entries(v2_meta.metadata)) {
2984
+ known_meta[`/${key}`] = value;
2985
+ }
2986
+ return {
2987
+ async get(...args) {
2988
+ let [key, opts2] = args;
2989
+ if (known_meta[key]) {
2990
+ return json_encode_object(known_meta[key]);
2991
+ }
2992
+ let maybe_bytes = await store.get(key, opts2);
2993
+ if (is_meta_key(key) && maybe_bytes) {
2994
+ let meta = json_decode_object(maybe_bytes);
2995
+ known_meta[key] = meta;
2996
+ }
2997
+ return maybe_bytes;
2998
+ },
2999
+ // Delegate range requests to the underlying store.
3000
+ // Note: Supporting range requests for consolidated metadata is possible
3001
+ // but unlikely to be useful enough to justify the effort.
3002
+ getRange: store.getRange?.bind(store),
3003
+ contents() {
3004
+ let contents = [];
3005
+ for (let [key, value] of Object.entries(known_meta)) {
3006
+ let parts = key.split("/");
3007
+ let filename = parts.pop();
3008
+ let path = parts.join("/") || "/";
3009
+ if (filename === ".zarray")
3010
+ contents.push({ path, kind: "array" });
3011
+ if (filename === ".zgroup")
3012
+ contents.push({ path, kind: "group" });
3013
+ if (is_v3(value)) {
3014
+ contents.push({ path, kind: value.node_type });
3015
+ }
3016
+ }
3017
+ return contents;
3018
+ }
3019
+ };
3020
+ }
3021
+ const MAX_BIG_UINT = 18446744073709551615n;
3022
+ function create_sharded_chunk_getter(location, shard_shape, encode_shard_key, sharding_config) {
3023
+ assert(location.store.getRange, "Store does not support range requests");
3024
+ let get_range = location.store.getRange.bind(location.store);
3025
+ let index_shape = shard_shape.map((d, i) => d / sharding_config.chunk_shape[i]);
3026
+ let index_codec = create_codec_pipeline({
3027
+ data_type: "uint64",
3028
+ shape: [...index_shape, 2],
3029
+ codecs: sharding_config.index_codecs
3030
+ });
3031
+ let cache = {};
3032
+ return async (chunk_coord) => {
3033
+ let shard_coord = chunk_coord.map((d, i) => Math.floor(d / index_shape[i]));
3034
+ let shard_path = location.resolve(encode_shard_key(shard_coord)).path;
3035
+ let index;
3036
+ if (shard_path in cache) {
3037
+ index = cache[shard_path];
3038
+ } else {
3039
+ let checksum_size = 4;
3040
+ let index_size = 16 * index_shape.reduce((a, b) => a * b, 1);
3041
+ let bytes = await get_range(shard_path, {
3042
+ suffixLength: index_size + checksum_size
3043
+ });
3044
+ index = cache[shard_path] = bytes ? await index_codec.decode(bytes) : null;
3045
+ }
3046
+ if (index === null) {
3047
+ return void 0;
3048
+ }
3049
+ let { data, shape, stride } = index;
3050
+ let linear_offset = chunk_coord.map((d, i) => d % shape[i]).reduce((acc, sel, idx) => acc + sel * stride[idx], 0);
3051
+ let offset = data[linear_offset];
3052
+ let length = data[linear_offset + 1];
3053
+ if (offset === MAX_BIG_UINT && length === MAX_BIG_UINT) {
3054
+ return void 0;
3055
+ }
3056
+ return get_range(shard_path, {
3057
+ offset: Number(offset),
3058
+ length: Number(length)
3059
+ });
3060
+ };
3061
+ }
3062
+ var _a;
3063
+ class Location {
3064
+ constructor(store, path = "/") {
3065
+ this.store = store;
3066
+ this.path = path;
3067
+ }
3068
+ resolve(path) {
3069
+ let root2 = new URL(`file://${this.path.endsWith("/") ? this.path : `${this.path}/`}`);
3070
+ return new Location(this.store, decodeURIComponent(new URL(path, root2).pathname));
3071
+ }
3072
+ }
3073
+ function root(store) {
3074
+ return new Location(store ?? /* @__PURE__ */ new Map());
3075
+ }
3076
+ class Group extends Location {
3077
+ constructor(store, path, metadata) {
3078
+ super(store, path);
3079
+ this.kind = "group";
3080
+ this.#metadata = metadata;
3081
+ }
3082
+ #metadata;
3083
+ get attrs() {
3084
+ return this.#metadata.attributes;
3085
+ }
3086
+ }
3087
+ function get_array_order(codecs) {
3088
+ const maybe_transpose_codec = codecs.find((c) => c.name === "transpose");
3089
+ return maybe_transpose_codec?.configuration?.order ?? "C";
3090
+ }
3091
+ const CONTEXT_MARKER = Symbol("zarrita.context");
3092
+ function create_context(location, metadata) {
3093
+ let { configuration } = metadata.codecs.find(is_sharding_codec) ?? {};
3094
+ let shared_context = {
3095
+ encode_chunk_key: create_chunk_key_encoder(metadata.chunk_key_encoding),
3096
+ TypedArray: get_ctr(metadata.data_type),
3097
+ fill_value: metadata.fill_value
3098
+ };
3099
+ if (configuration) {
3100
+ let native_order2 = get_array_order(configuration.codecs);
3101
+ return {
3102
+ ...shared_context,
3103
+ kind: "sharded",
3104
+ chunk_shape: configuration.chunk_shape,
3105
+ codec: create_codec_pipeline({
3106
+ data_type: metadata.data_type,
3107
+ shape: configuration.chunk_shape,
3108
+ codecs: configuration.codecs
3109
+ }),
3110
+ get_strides(shape) {
3111
+ return get_strides(shape, native_order2);
3112
+ },
3113
+ get_chunk_bytes: create_sharded_chunk_getter(location, metadata.chunk_grid.configuration.chunk_shape, shared_context.encode_chunk_key, configuration)
3114
+ };
3115
+ }
3116
+ let native_order = get_array_order(metadata.codecs);
3117
+ return {
3118
+ ...shared_context,
3119
+ kind: "regular",
3120
+ chunk_shape: metadata.chunk_grid.configuration.chunk_shape,
3121
+ codec: create_codec_pipeline({
3122
+ data_type: metadata.data_type,
3123
+ shape: metadata.chunk_grid.configuration.chunk_shape,
3124
+ codecs: metadata.codecs
3125
+ }),
3126
+ get_strides(shape) {
3127
+ return get_strides(shape, native_order);
3128
+ },
3129
+ async get_chunk_bytes(chunk_coords, options) {
3130
+ let chunk_key = shared_context.encode_chunk_key(chunk_coords);
3131
+ let chunk_path = location.resolve(chunk_key).path;
3132
+ return location.store.get(chunk_path, options);
3133
+ }
3134
+ };
3135
+ }
3136
+ let Array$1 = class Array2 extends (_a = Location, _a) {
3137
+ constructor(store, path, metadata) {
3138
+ super(store, path);
3139
+ this.kind = "array";
3140
+ this.#metadata = {
3141
+ ...metadata,
3142
+ fill_value: ensure_correct_scalar(metadata)
3143
+ };
3144
+ this[CONTEXT_MARKER] = create_context(this, metadata);
3145
+ }
3146
+ #metadata;
3147
+ get attrs() {
3148
+ return this.#metadata.attributes;
3149
+ }
3150
+ get shape() {
3151
+ return this.#metadata.shape;
3152
+ }
3153
+ get chunks() {
3154
+ return this[CONTEXT_MARKER].chunk_shape;
3155
+ }
3156
+ get dtype() {
3157
+ return this.#metadata.data_type;
3158
+ }
3159
+ async getChunk(chunk_coords, options) {
3160
+ let context = this[CONTEXT_MARKER];
3161
+ let maybe_bytes = await context.get_chunk_bytes(chunk_coords, options);
3162
+ if (!maybe_bytes) {
3163
+ let size = context.chunk_shape.reduce((a, b) => a * b, 1);
3164
+ let data = new context.TypedArray(size);
3165
+ data.fill(context.fill_value);
3166
+ return {
3167
+ data,
3168
+ shape: context.chunk_shape,
3169
+ stride: context.get_strides(context.chunk_shape)
3170
+ };
3171
+ }
3172
+ return context.codec.decode(maybe_bytes);
3173
+ }
3174
+ /**
3175
+ * A helper method to narrow `zarr.Array` Dtype.
3176
+ *
3177
+ * ```typescript
3178
+ * let arr: zarr.Array<DataType, FetchStore> = zarr.open(store, { kind: "array" });
3179
+ *
3180
+ * // Option 1: narrow by scalar type (e.g. "bool", "raw", "bigint", "number")
3181
+ * if (arr.is("bigint")) {
3182
+ * // zarr.Array<"int64" | "uint64", FetchStore>
3183
+ * }
3184
+ *
3185
+ * // Option 3: exact match
3186
+ * if (arr.is("float32")) {
3187
+ * // zarr.Array<"float32", FetchStore, "/">
3188
+ * }
3189
+ * ```
3190
+ */
3191
+ is(query) {
3192
+ return is_dtype(this.dtype, query);
3193
+ }
3194
+ };
3195
+ let VERSION_COUNTER = create_version_counter();
3196
+ function create_version_counter() {
3197
+ let version_counts = /* @__PURE__ */ new WeakMap();
3198
+ function get_counts(store) {
3199
+ let counts = version_counts.get(store) ?? { v2: 0, v3: 0 };
3200
+ version_counts.set(store, counts);
3201
+ return counts;
3202
+ }
3203
+ return {
3204
+ increment(store, version) {
3205
+ get_counts(store)[version] += 1;
3206
+ },
3207
+ version_max(store) {
3208
+ let counts = get_counts(store);
3209
+ return counts.v3 > counts.v2 ? "v3" : "v2";
3210
+ }
3211
+ };
3212
+ }
3213
+ async function load_attrs(location) {
3214
+ let meta_bytes = await location.store.get(location.resolve(".zattrs").path);
3215
+ if (!meta_bytes)
3216
+ return {};
3217
+ return json_decode_object(meta_bytes);
3218
+ }
3219
+ async function open_v2(location, options = {}) {
3220
+ let loc = "store" in location ? location : new Location(location);
3221
+ let attrs = {};
3222
+ if (options.attrs ?? true)
3223
+ attrs = await load_attrs(loc);
3224
+ if (options.kind === "array")
3225
+ return open_array_v2(loc, attrs);
3226
+ if (options.kind === "group")
3227
+ return open_group_v2(loc, attrs);
3228
+ return open_array_v2(loc, attrs).catch((err) => {
3229
+ rethrow_unless(err, NodeNotFoundError);
3230
+ return open_group_v2(loc, attrs);
3231
+ });
3232
+ }
3233
+ async function open_array_v2(location, attrs) {
3234
+ let { path } = location.resolve(".zarray");
3235
+ let meta = await location.store.get(path);
3236
+ if (!meta) {
3237
+ throw new NodeNotFoundError("v2 array", {
3238
+ cause: new KeyError(path)
3239
+ });
3240
+ }
3241
+ VERSION_COUNTER.increment(location.store, "v2");
3242
+ return new Array$1(location.store, location.path, v2_to_v3_array_metadata(json_decode_object(meta), attrs));
3243
+ }
3244
+ async function open_group_v2(location, attrs) {
3245
+ let { path } = location.resolve(".zgroup");
3246
+ let meta = await location.store.get(path);
3247
+ if (!meta) {
3248
+ throw new NodeNotFoundError("v2 group", {
3249
+ cause: new KeyError(path)
3250
+ });
3251
+ }
3252
+ VERSION_COUNTER.increment(location.store, "v2");
3253
+ return new Group(location.store, location.path, v2_to_v3_group_metadata(json_decode_object(meta), attrs));
3254
+ }
3255
+ async function _open_v3(location) {
3256
+ let { store, path } = location.resolve("zarr.json");
3257
+ let meta = await location.store.get(path);
3258
+ if (!meta) {
3259
+ throw new NodeNotFoundError("v3 array or group", {
3260
+ cause: new KeyError(path)
3261
+ });
3262
+ }
3263
+ let meta_doc = json_decode_object(meta);
3264
+ if (meta_doc.node_type === "array") {
3265
+ meta_doc.fill_value = ensure_correct_scalar(meta_doc);
3266
+ }
3267
+ return meta_doc.node_type === "array" ? new Array$1(store, location.path, meta_doc) : new Group(store, location.path, meta_doc);
3268
+ }
3269
+ async function open_v3(location, options = {}) {
3270
+ let loc = "store" in location ? location : new Location(location);
3271
+ let node = await _open_v3(loc);
3272
+ VERSION_COUNTER.increment(loc.store, "v3");
3273
+ if (options.kind === void 0)
3274
+ return node;
3275
+ if (options.kind === "array" && node instanceof Array$1)
3276
+ return node;
3277
+ if (options.kind === "group" && node instanceof Group)
3278
+ return node;
3279
+ let kind = node instanceof Array$1 ? "array" : "group";
3280
+ throw new Error(`Expected node of kind ${options.kind}, found ${kind}.`);
3281
+ }
3282
+ async function open(location, options = {}) {
3283
+ let store = "store" in location ? location.store : location;
3284
+ let version_max = VERSION_COUNTER.version_max(store);
3285
+ let open_primary = version_max === "v2" ? open.v2 : open.v3;
3286
+ let open_secondary = version_max === "v2" ? open.v3 : open.v2;
3287
+ return open_primary(location, options).catch((err) => {
3288
+ rethrow_unless(err, NodeNotFoundError);
3289
+ return open_secondary(location, options);
3290
+ });
3291
+ }
3292
+ open.v2 = open_v2;
3293
+ open.v3 = open_v3;
3294
+ function readBlobAsArrayBuffer(blob) {
3295
+ if (blob.arrayBuffer) {
3296
+ return blob.arrayBuffer();
3297
+ }
3298
+ return new Promise((resolve2, reject) => {
3299
+ const reader = new FileReader();
3300
+ reader.addEventListener("loadend", () => {
3301
+ resolve2(reader.result);
3302
+ });
3303
+ reader.addEventListener("error", reject);
3304
+ reader.readAsArrayBuffer(blob);
3305
+ });
3306
+ }
3307
+ async function readBlobAsUint8Array(blob) {
3308
+ const arrayBuffer = await readBlobAsArrayBuffer(blob);
3309
+ return new Uint8Array(arrayBuffer);
3310
+ }
3311
+ function isBlob(v) {
3312
+ return typeof Blob !== "undefined" && v instanceof Blob;
3313
+ }
3314
+ function isSharedArrayBuffer(b) {
3315
+ return typeof SharedArrayBuffer !== "undefined" && b instanceof SharedArrayBuffer;
3316
+ }
3317
+ const isNode = typeof process !== "undefined" && process.versions && typeof process.versions.node !== "undefined" && typeof process.versions.electron === "undefined";
3318
+ function isTypedArraySameAsArrayBuffer(typedArray) {
3319
+ return typedArray.byteOffset === 0 && typedArray.byteLength === typedArray.buffer.byteLength;
3320
+ }
3321
+ class ArrayBufferReader {
3322
+ constructor(arrayBufferOrView) {
3323
+ this.typedArray = arrayBufferOrView instanceof ArrayBuffer || isSharedArrayBuffer(arrayBufferOrView) ? new Uint8Array(arrayBufferOrView) : new Uint8Array(arrayBufferOrView.buffer, arrayBufferOrView.byteOffset, arrayBufferOrView.byteLength);
3324
+ }
3325
+ async getLength() {
3326
+ return this.typedArray.byteLength;
3327
+ }
3328
+ async read(offset, length) {
3329
+ return new Uint8Array(this.typedArray.buffer, this.typedArray.byteOffset + offset, length);
3330
+ }
3331
+ }
3332
+ let BlobReader$1 = class BlobReader {
3333
+ constructor(blob) {
3334
+ this.blob = blob;
3335
+ }
3336
+ async getLength() {
3337
+ return this.blob.size;
3338
+ }
3339
+ async read(offset, length) {
3340
+ const blob = this.blob.slice(offset, offset + length);
3341
+ const arrayBuffer = await readBlobAsArrayBuffer(blob);
3342
+ return new Uint8Array(arrayBuffer);
3343
+ }
3344
+ async sliceAsBlob(offset, length, type = "") {
3345
+ return this.blob.slice(offset, offset + length, type);
3346
+ }
3347
+ };
3348
+ function inflate(data, buf) {
3349
+ var u8 = Uint8Array;
3350
+ if (data[0] == 3 && data[1] == 0) return buf ? buf : new u8(0);
3351
+ var bitsF = _bitsF, bitsE = _bitsE, decodeTiny = _decodeTiny, get17 = _get17;
3352
+ var noBuf = buf == null;
3353
+ if (noBuf) buf = new u8(data.length >>> 2 << 3);
3354
+ var BFINAL = 0, BTYPE = 0, HLIT = 0, HDIST = 0, HCLEN = 0, ML = 0, MD = 0;
3355
+ var off = 0, pos = 0;
3356
+ var lmap, dmap;
3357
+ while (BFINAL == 0) {
3358
+ BFINAL = bitsF(data, pos, 1);
3359
+ BTYPE = bitsF(data, pos + 1, 2);
3360
+ pos += 3;
3361
+ if (BTYPE == 0) {
3362
+ if ((pos & 7) != 0) pos += 8 - (pos & 7);
3363
+ var p8 = (pos >>> 3) + 4, len = data[p8 - 4] | data[p8 - 3] << 8;
3364
+ if (noBuf) buf = _check(buf, off + len);
3365
+ buf.set(new u8(data.buffer, data.byteOffset + p8, len), off);
3366
+ pos = p8 + len << 3;
3367
+ off += len;
3368
+ continue;
3369
+ }
3370
+ if (noBuf) buf = _check(buf, off + (1 << 17));
3371
+ if (BTYPE == 1) {
3372
+ lmap = U.flmap;
3373
+ dmap = U.fdmap;
3374
+ ML = (1 << 9) - 1;
3375
+ MD = (1 << 5) - 1;
3376
+ }
3377
+ if (BTYPE == 2) {
3378
+ HLIT = bitsE(data, pos, 5) + 257;
3379
+ HDIST = bitsE(data, pos + 5, 5) + 1;
3380
+ HCLEN = bitsE(data, pos + 10, 4) + 4;
3381
+ pos += 14;
3382
+ for (var i = 0; i < 38; i += 2) {
3383
+ U.itree[i] = 0;
3384
+ U.itree[i + 1] = 0;
3385
+ }
3386
+ var tl = 1;
3387
+ for (var i = 0; i < HCLEN; i++) {
3388
+ var l = bitsE(data, pos + i * 3, 3);
3389
+ U.itree[(U.ordr[i] << 1) + 1] = l;
3390
+ if (l > tl) tl = l;
3391
+ }
3392
+ pos += 3 * HCLEN;
3393
+ makeCodes(U.itree, tl);
3394
+ codes2map(U.itree, tl, U.imap);
3395
+ lmap = U.lmap;
3396
+ dmap = U.dmap;
3397
+ pos = decodeTiny(U.imap, (1 << tl) - 1, HLIT + HDIST, data, pos, U.ttree);
3398
+ var mx0 = _copyOut(U.ttree, 0, HLIT, U.ltree);
3399
+ ML = (1 << mx0) - 1;
3400
+ var mx1 = _copyOut(U.ttree, HLIT, HDIST, U.dtree);
3401
+ MD = (1 << mx1) - 1;
3402
+ makeCodes(U.ltree, mx0);
3403
+ codes2map(U.ltree, mx0, lmap);
3404
+ makeCodes(U.dtree, mx1);
3405
+ codes2map(U.dtree, mx1, dmap);
3406
+ }
3407
+ while (true) {
3408
+ var code = lmap[get17(data, pos) & ML];
3409
+ pos += code & 15;
3410
+ var lit = code >>> 4;
3411
+ if (lit >>> 8 == 0) {
3412
+ buf[off++] = lit;
3413
+ } else if (lit == 256) {
3414
+ break;
3415
+ } else {
3416
+ var end = off + lit - 254;
3417
+ if (lit > 264) {
3418
+ var ebs = U.ldef[lit - 257];
3419
+ end = off + (ebs >>> 3) + bitsE(data, pos, ebs & 7);
3420
+ pos += ebs & 7;
3421
+ }
3422
+ var dcode = dmap[get17(data, pos) & MD];
3423
+ pos += dcode & 15;
3424
+ var dlit = dcode >>> 4;
3425
+ var dbs = U.ddef[dlit], dst = (dbs >>> 4) + bitsF(data, pos, dbs & 15);
3426
+ pos += dbs & 15;
3427
+ if (noBuf) buf = _check(buf, off + (1 << 17));
3428
+ while (off < end) {
3429
+ buf[off] = buf[off++ - dst];
3430
+ buf[off] = buf[off++ - dst];
3431
+ buf[off] = buf[off++ - dst];
3432
+ buf[off] = buf[off++ - dst];
3433
+ }
3434
+ off = end;
3435
+ }
3436
+ }
3437
+ }
3438
+ return buf.length == off ? buf : buf.slice(0, off);
3439
+ }
3440
+ function _check(buf, len) {
3441
+ var bl = buf.length;
3442
+ if (len <= bl) return buf;
3443
+ var nbuf = new Uint8Array(Math.max(bl << 1, len));
3444
+ nbuf.set(buf, 0);
3445
+ return nbuf;
3446
+ }
3447
+ function _decodeTiny(lmap, LL, len, data, pos, tree) {
3448
+ var bitsE = _bitsE, get17 = _get17;
3449
+ var i = 0;
3450
+ while (i < len) {
3451
+ var code = lmap[get17(data, pos) & LL];
3452
+ pos += code & 15;
3453
+ var lit = code >>> 4;
3454
+ if (lit <= 15) {
3455
+ tree[i] = lit;
3456
+ i++;
3457
+ } else {
3458
+ var ll = 0, n = 0;
3459
+ if (lit == 16) {
3460
+ n = 3 + bitsE(data, pos, 2);
3461
+ pos += 2;
3462
+ ll = tree[i - 1];
3463
+ } else if (lit == 17) {
3464
+ n = 3 + bitsE(data, pos, 3);
3465
+ pos += 3;
3466
+ } else if (lit == 18) {
3467
+ n = 11 + bitsE(data, pos, 7);
3468
+ pos += 7;
3469
+ }
3470
+ var ni = i + n;
3471
+ while (i < ni) {
3472
+ tree[i] = ll;
3473
+ i++;
3474
+ }
3475
+ }
3476
+ }
3477
+ return pos;
3478
+ }
3479
+ function _copyOut(src, off, len, tree) {
3480
+ var mx = 0, i = 0, tl = tree.length >>> 1;
3481
+ while (i < len) {
3482
+ var v = src[i + off];
3483
+ tree[i << 1] = 0;
3484
+ tree[(i << 1) + 1] = v;
3485
+ if (v > mx) mx = v;
3486
+ i++;
3487
+ }
3488
+ while (i < tl) {
3489
+ tree[i << 1] = 0;
3490
+ tree[(i << 1) + 1] = 0;
3491
+ i++;
3492
+ }
3493
+ return mx;
3494
+ }
3495
+ function makeCodes(tree, MAX_BITS) {
3496
+ var max_code = tree.length;
3497
+ var code, bits, n, i, len;
3498
+ var bl_count = U.bl_count;
3499
+ for (var i = 0; i <= MAX_BITS; i++) bl_count[i] = 0;
3500
+ for (i = 1; i < max_code; i += 2) bl_count[tree[i]]++;
3501
+ var next_code = U.next_code;
3502
+ code = 0;
3503
+ bl_count[0] = 0;
3504
+ for (bits = 1; bits <= MAX_BITS; bits++) {
3505
+ code = code + bl_count[bits - 1] << 1;
3506
+ next_code[bits] = code;
3507
+ }
3508
+ for (n = 0; n < max_code; n += 2) {
3509
+ len = tree[n + 1];
3510
+ if (len != 0) {
3511
+ tree[n] = next_code[len];
3512
+ next_code[len]++;
3513
+ }
3514
+ }
3515
+ }
3516
+ function codes2map(tree, MAX_BITS, map) {
3517
+ var max_code = tree.length;
3518
+ var r15 = U.rev15;
3519
+ for (var i = 0; i < max_code; i += 2) if (tree[i + 1] != 0) {
3520
+ var lit = i >> 1;
3521
+ var cl = tree[i + 1], val = lit << 4 | cl;
3522
+ var rest = MAX_BITS - cl, i0 = tree[i] << rest, i1 = i0 + (1 << rest);
3523
+ while (i0 != i1) {
3524
+ var p0 = r15[i0] >>> 15 - MAX_BITS;
3525
+ map[p0] = val;
3526
+ i0++;
3527
+ }
3528
+ }
3529
+ }
3530
+ function revCodes(tree, MAX_BITS) {
3531
+ var r15 = U.rev15, imb = 15 - MAX_BITS;
3532
+ for (var i = 0; i < tree.length; i += 2) {
3533
+ var i0 = tree[i] << MAX_BITS - tree[i + 1];
3534
+ tree[i] = r15[i0] >>> imb;
3535
+ }
3536
+ }
3537
+ function _bitsE(dt, pos, length) {
3538
+ return (dt[pos >>> 3] | dt[(pos >>> 3) + 1] << 8) >>> (pos & 7) & (1 << length) - 1;
3539
+ }
3540
+ function _bitsF(dt, pos, length) {
3541
+ return (dt[pos >>> 3] | dt[(pos >>> 3) + 1] << 8 | dt[(pos >>> 3) + 2] << 16) >>> (pos & 7) & (1 << length) - 1;
3542
+ }
3543
+ function _get17(dt, pos) {
3544
+ return (dt[pos >>> 3] | dt[(pos >>> 3) + 1] << 8 | dt[(pos >>> 3) + 2] << 16) >>> (pos & 7);
3545
+ }
3546
+ const U = function() {
3547
+ var u16 = Uint16Array, u32 = Uint32Array;
3548
+ return {
3549
+ next_code: new u16(16),
3550
+ bl_count: new u16(16),
3551
+ ordr: [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15],
3552
+ of0: [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 999, 999, 999],
3553
+ exb: [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0, 0],
3554
+ ldef: new u16(32),
3555
+ df0: [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 65535, 65535],
3556
+ dxb: [0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 0, 0],
3557
+ ddef: new u32(32),
3558
+ flmap: new u16(512),
3559
+ fltree: [],
3560
+ fdmap: new u16(32),
3561
+ fdtree: [],
3562
+ lmap: new u16(32768),
3563
+ ltree: [],
3564
+ ttree: [],
3565
+ dmap: new u16(32768),
3566
+ dtree: [],
3567
+ imap: new u16(512),
3568
+ itree: [],
3569
+ //rev9 : new u16( 512)
3570
+ rev15: new u16(1 << 15),
3571
+ lhst: new u32(286),
3572
+ dhst: new u32(30),
3573
+ ihst: new u32(19),
3574
+ lits: new u32(15e3),
3575
+ strt: new u16(1 << 16),
3576
+ prev: new u16(1 << 15)
3577
+ };
3578
+ }();
3579
+ (function() {
3580
+ var len = 1 << 15;
3581
+ for (var i = 0; i < len; i++) {
3582
+ var x = i;
3583
+ x = (x & 2863311530) >>> 1 | (x & 1431655765) << 1;
3584
+ x = (x & 3435973836) >>> 2 | (x & 858993459) << 2;
3585
+ x = (x & 4042322160) >>> 4 | (x & 252645135) << 4;
3586
+ x = (x & 4278255360) >>> 8 | (x & 16711935) << 8;
3587
+ U.rev15[i] = (x >>> 16 | x << 16) >>> 17;
3588
+ }
3589
+ function pushV(tgt, n, sv) {
3590
+ while (n-- != 0) tgt.push(0, sv);
3591
+ }
3592
+ for (var i = 0; i < 32; i++) {
3593
+ U.ldef[i] = U.of0[i] << 3 | U.exb[i];
3594
+ U.ddef[i] = U.df0[i] << 4 | U.dxb[i];
3595
+ }
3596
+ pushV(U.fltree, 144, 8);
3597
+ pushV(U.fltree, 255 - 143, 9);
3598
+ pushV(U.fltree, 279 - 255, 7);
3599
+ pushV(U.fltree, 287 - 279, 8);
3600
+ makeCodes(U.fltree, 9);
3601
+ codes2map(U.fltree, 9, U.flmap);
3602
+ revCodes(U.fltree, 9);
3603
+ pushV(U.fdtree, 32, 5);
3604
+ makeCodes(U.fdtree, 5);
3605
+ codes2map(U.fdtree, 5, U.fdmap);
3606
+ revCodes(U.fdtree, 5);
3607
+ pushV(U.itree, 19, 0);
3608
+ pushV(U.ltree, 286, 0);
3609
+ pushV(U.dtree, 30, 0);
3610
+ pushV(U.ttree, 320, 0);
3611
+ })();
3612
+ ({
3613
+ table: function() {
3614
+ var tab = new Uint32Array(256);
3615
+ for (var n = 0; n < 256; n++) {
3616
+ var c = n;
3617
+ for (var k = 0; k < 8; k++) {
3618
+ if (c & 1) c = 3988292384 ^ c >>> 1;
3619
+ else c = c >>> 1;
3620
+ }
3621
+ tab[n] = c;
3622
+ }
3623
+ return tab;
3624
+ }()
3625
+ });
3626
+ function inflateRaw(file, buf) {
3627
+ return inflate(file, buf);
3628
+ }
3629
+ const config = {
3630
+ numWorkers: 1,
3631
+ workerURL: "",
3632
+ useWorkers: false
3633
+ };
3634
+ let nextId = 0;
3635
+ const waitingForWorkerQueue = [];
3636
+ function startWorker(url) {
3637
+ return new Promise((resolve2, reject) => {
3638
+ const worker = new Worker(url);
3639
+ worker.onmessage = (e) => {
3640
+ if (e.data === "start") {
3641
+ worker.onerror = void 0;
3642
+ worker.onmessage = void 0;
3643
+ resolve2(worker);
3644
+ } else {
3645
+ reject(new Error(`unexpected message: ${e.data}`));
3646
+ }
3647
+ };
3648
+ worker.onerror = reject;
3649
+ });
3650
+ }
3651
+ function dynamicRequire(mod, request) {
3652
+ return mod.require ? mod.require(request) : {};
3653
+ }
3654
+ (function() {
3655
+ if (isNode) {
3656
+ const { Worker: Worker2 } = dynamicRequire(module, "worker_threads");
3657
+ return {
3658
+ async createWorker(url) {
3659
+ return new Worker2(url);
3660
+ },
3661
+ addEventListener(worker, fn) {
3662
+ worker.on("message", (data) => {
3663
+ fn({ target: worker, data });
3664
+ });
3665
+ },
3666
+ async terminate(worker) {
3667
+ await worker.terminate();
3668
+ }
3669
+ };
3670
+ } else {
3671
+ return {
3672
+ async createWorker(url) {
3673
+ try {
3674
+ const worker = await startWorker(url);
3675
+ return worker;
3676
+ } catch (e) {
3677
+ console.warn("could not load worker:", url);
3678
+ }
3679
+ let text;
3680
+ try {
3681
+ const req = await fetch(url, { mode: "cors" });
3682
+ if (!req.ok) {
3683
+ throw new Error(`could not load: ${url}`);
3684
+ }
3685
+ text = await req.text();
3686
+ url = URL.createObjectURL(new Blob([text], { type: "application/javascript" }));
3687
+ const worker = await startWorker(url);
3688
+ config.workerURL = url;
3689
+ return worker;
3690
+ } catch (e) {
3691
+ console.warn("could not load worker via fetch:", url);
3692
+ }
3693
+ if (text !== void 0) {
3694
+ try {
3695
+ url = `data:application/javascript;base64,${btoa(text)}`;
3696
+ const worker = await startWorker(url);
3697
+ config.workerURL = url;
3698
+ return worker;
3699
+ } catch (e) {
3700
+ console.warn("could not load worker via dataURI");
3701
+ }
3702
+ }
3703
+ console.warn("workers will not be used");
3704
+ throw new Error("can not start workers");
3705
+ },
3706
+ addEventListener(worker, fn) {
3707
+ worker.addEventListener("message", fn);
3708
+ },
3709
+ async terminate(worker) {
3710
+ worker.terminate();
3711
+ }
3712
+ };
3713
+ }
3714
+ })();
3715
+ function inflateRawLocal(src, uncompressedSize, type, resolve2) {
3716
+ const dst = new Uint8Array(uncompressedSize);
3717
+ inflateRaw(src, dst);
3718
+ resolve2(type ? new Blob([dst], { type }) : dst.buffer);
3719
+ }
3720
+ async function processWaitingForWorkerQueue() {
3721
+ if (waitingForWorkerQueue.length === 0) {
3722
+ return;
3723
+ }
3724
+ while (waitingForWorkerQueue.length) {
3725
+ const { src, uncompressedSize, type, resolve: resolve2 } = waitingForWorkerQueue.shift();
3726
+ let data = src;
3727
+ if (isBlob(src)) {
3728
+ data = await readBlobAsUint8Array(src);
3729
+ }
3730
+ inflateRawLocal(data, uncompressedSize, type, resolve2);
3731
+ }
3732
+ }
3733
+ function inflateRawAsync(src, uncompressedSize, type) {
3734
+ return new Promise((resolve2, reject) => {
3735
+ waitingForWorkerQueue.push({ src, uncompressedSize, type, resolve: resolve2, reject, id: nextId++ });
3736
+ processWaitingForWorkerQueue();
3737
+ });
3738
+ }
3739
+ function dosDateTimeToDate(date, time) {
3740
+ const day = date & 31;
3741
+ const month = (date >> 5 & 15) - 1;
3742
+ const year = (date >> 9 & 127) + 1980;
3743
+ const millisecond = 0;
3744
+ const second = (time & 31) * 2;
3745
+ const minute = time >> 5 & 63;
3746
+ const hour = time >> 11 & 31;
3747
+ return new Date(year, month, day, hour, minute, second, millisecond);
3748
+ }
3749
+ class ZipEntry {
3750
+ constructor(reader, rawEntry) {
3751
+ this._reader = reader;
3752
+ this._rawEntry = rawEntry;
3753
+ this.name = rawEntry.name;
3754
+ this.nameBytes = rawEntry.nameBytes;
3755
+ this.size = rawEntry.uncompressedSize;
3756
+ this.compressedSize = rawEntry.compressedSize;
3757
+ this.comment = rawEntry.comment;
3758
+ this.commentBytes = rawEntry.commentBytes;
3759
+ this.compressionMethod = rawEntry.compressionMethod;
3760
+ this.lastModDate = dosDateTimeToDate(rawEntry.lastModFileDate, rawEntry.lastModFileTime);
3761
+ this.isDirectory = rawEntry.uncompressedSize === 0 && rawEntry.name.endsWith("/");
3762
+ this.encrypted = !!(rawEntry.generalPurposeBitFlag & 1);
3763
+ this.externalFileAttributes = rawEntry.externalFileAttributes;
3764
+ this.versionMadeBy = rawEntry.versionMadeBy;
3765
+ }
3766
+ // returns a promise that returns a Blob for this entry
3767
+ async blob(type = "application/octet-stream") {
3768
+ return await readEntryDataAsBlob(this._reader, this._rawEntry, type);
3769
+ }
3770
+ // returns a promise that returns an ArrayBuffer for this entry
3771
+ async arrayBuffer() {
3772
+ return await readEntryDataAsArrayBuffer(this._reader, this._rawEntry);
3773
+ }
3774
+ // returns text, assumes the text is valid utf8. If you want more options decode arrayBuffer yourself
3775
+ async text() {
3776
+ const buffer = await this.arrayBuffer();
3777
+ return decodeBuffer(new Uint8Array(buffer));
3778
+ }
3779
+ // returns text with JSON.parse called on it. If you want more options decode arrayBuffer yourself
3780
+ async json() {
3781
+ const text = await this.text();
3782
+ return JSON.parse(text);
3783
+ }
3784
+ }
3785
+ const EOCDR_WITHOUT_COMMENT_SIZE = 22;
3786
+ const MAX_COMMENT_SIZE = 65535;
3787
+ const EOCDR_SIGNATURE = 101010256;
3788
+ const ZIP64_EOCDR_SIGNATURE = 101075792;
3789
+ async function readAs(reader, offset, length) {
3790
+ return await reader.read(offset, length);
3791
+ }
3792
+ async function readAsBlobOrTypedArray(reader, offset, length, type) {
3793
+ if (reader.sliceAsBlob) {
3794
+ return await reader.sliceAsBlob(offset, length, type);
3795
+ }
3796
+ return await reader.read(offset, length);
3797
+ }
3798
+ const crc$1 = {
3799
+ unsigned() {
3800
+ return 0;
3801
+ }
3802
+ };
3803
+ function getUint16LE(uint8View, offset) {
3804
+ return uint8View[offset] + uint8View[offset + 1] * 256;
3805
+ }
3806
+ function getUint32LE(uint8View, offset) {
3807
+ return uint8View[offset] + uint8View[offset + 1] * 256 + uint8View[offset + 2] * 65536 + uint8View[offset + 3] * 16777216;
3808
+ }
3809
+ function getUint64LE(uint8View, offset) {
3810
+ return getUint32LE(uint8View, offset) + getUint32LE(uint8View, offset + 4) * 4294967296;
3811
+ }
3812
+ const utf8Decoder = new TextDecoder();
3813
+ function decodeBuffer(uint8View, isUTF8) {
3814
+ if (isSharedArrayBuffer(uint8View.buffer)) {
3815
+ uint8View = new Uint8Array(uint8View);
3816
+ }
3817
+ return utf8Decoder.decode(uint8View);
3818
+ }
3819
+ async function findEndOfCentralDirector(reader, totalLength) {
3820
+ const size = Math.min(EOCDR_WITHOUT_COMMENT_SIZE + MAX_COMMENT_SIZE, totalLength);
3821
+ const readStart = totalLength - size;
3822
+ const data = await readAs(reader, readStart, size);
3823
+ for (let i = size - EOCDR_WITHOUT_COMMENT_SIZE; i >= 0; --i) {
3824
+ if (getUint32LE(data, i) !== EOCDR_SIGNATURE) {
3825
+ continue;
3826
+ }
3827
+ const eocdr = new Uint8Array(data.buffer, data.byteOffset + i, data.byteLength - i);
3828
+ const diskNumber = getUint16LE(eocdr, 4);
3829
+ if (diskNumber !== 0) {
3830
+ throw new Error(`multi-volume zip files are not supported. This is volume: ${diskNumber}`);
3831
+ }
3832
+ const entryCount = getUint16LE(eocdr, 10);
3833
+ const centralDirectorySize = getUint32LE(eocdr, 12);
3834
+ const centralDirectoryOffset = getUint32LE(eocdr, 16);
3835
+ const commentLength = getUint16LE(eocdr, 20);
3836
+ const expectedCommentLength = eocdr.length - EOCDR_WITHOUT_COMMENT_SIZE;
3837
+ if (commentLength !== expectedCommentLength) {
3838
+ throw new Error(`invalid comment length. expected: ${expectedCommentLength}, actual: ${commentLength}`);
3839
+ }
3840
+ const commentBytes = new Uint8Array(eocdr.buffer, eocdr.byteOffset + 22, commentLength);
3841
+ const comment = decodeBuffer(commentBytes);
3842
+ if (entryCount === 65535 || centralDirectoryOffset === 4294967295) {
3843
+ return await readZip64CentralDirectory(reader, readStart + i, comment, commentBytes);
3844
+ } else {
3845
+ return await readEntries(reader, centralDirectoryOffset, centralDirectorySize, entryCount, comment, commentBytes);
3846
+ }
3847
+ }
3848
+ throw new Error("could not find end of central directory. maybe not zip file");
3849
+ }
3850
+ const END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE = 117853008;
3851
+ async function readZip64CentralDirectory(reader, offset, comment, commentBytes) {
3852
+ const zip64EocdlOffset = offset - 20;
3853
+ const eocdl = await readAs(reader, zip64EocdlOffset, 20);
3854
+ if (getUint32LE(eocdl, 0) !== END_OF_CENTRAL_DIRECTORY_LOCATOR_SIGNATURE) {
3855
+ throw new Error("invalid zip64 end of central directory locator signature");
3856
+ }
3857
+ const zip64EocdrOffset = getUint64LE(eocdl, 8);
3858
+ const zip64Eocdr = await readAs(reader, zip64EocdrOffset, 56);
3859
+ if (getUint32LE(zip64Eocdr, 0) !== ZIP64_EOCDR_SIGNATURE) {
3860
+ throw new Error("invalid zip64 end of central directory record signature");
3861
+ }
3862
+ const entryCount = getUint64LE(zip64Eocdr, 32);
3863
+ const centralDirectorySize = getUint64LE(zip64Eocdr, 40);
3864
+ const centralDirectoryOffset = getUint64LE(zip64Eocdr, 48);
3865
+ return readEntries(reader, centralDirectoryOffset, centralDirectorySize, entryCount, comment, commentBytes);
3866
+ }
3867
+ const CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE = 33639248;
3868
+ async function readEntries(reader, centralDirectoryOffset, centralDirectorySize, rawEntryCount, comment, commentBytes) {
3869
+ let readEntryCursor = 0;
3870
+ const allEntriesBuffer = await readAs(reader, centralDirectoryOffset, centralDirectorySize);
3871
+ const rawEntries = [];
3872
+ for (let e = 0; e < rawEntryCount; ++e) {
3873
+ const buffer = allEntriesBuffer.subarray(readEntryCursor, readEntryCursor + 46);
3874
+ const signature = getUint32LE(buffer, 0);
3875
+ if (signature !== CENTRAL_DIRECTORY_FILE_HEADER_SIGNATURE) {
3876
+ throw new Error(`invalid central directory file header signature: 0x${signature.toString(16)}`);
3877
+ }
3878
+ const rawEntry = {
3879
+ // 4 - Version made by
3880
+ versionMadeBy: getUint16LE(buffer, 4),
3881
+ // 6 - Version needed to extract (minimum)
3882
+ versionNeededToExtract: getUint16LE(buffer, 6),
3883
+ // 8 - General purpose bit flag
3884
+ generalPurposeBitFlag: getUint16LE(buffer, 8),
3885
+ // 10 - Compression method
3886
+ compressionMethod: getUint16LE(buffer, 10),
3887
+ // 12 - File last modification time
3888
+ lastModFileTime: getUint16LE(buffer, 12),
3889
+ // 14 - File last modification date
3890
+ lastModFileDate: getUint16LE(buffer, 14),
3891
+ // 16 - CRC-32
3892
+ crc32: getUint32LE(buffer, 16),
3893
+ // 20 - Compressed size
3894
+ compressedSize: getUint32LE(buffer, 20),
3895
+ // 24 - Uncompressed size
3896
+ uncompressedSize: getUint32LE(buffer, 24),
3897
+ // 28 - File name length (n)
3898
+ fileNameLength: getUint16LE(buffer, 28),
3899
+ // 30 - Extra field length (m)
3900
+ extraFieldLength: getUint16LE(buffer, 30),
3901
+ // 32 - File comment length (k)
3902
+ fileCommentLength: getUint16LE(buffer, 32),
3903
+ // 34 - Disk number where file starts
3904
+ // 36 - Internal file attributes
3905
+ internalFileAttributes: getUint16LE(buffer, 36),
3906
+ // 38 - External file attributes
3907
+ externalFileAttributes: getUint32LE(buffer, 38),
3908
+ // 42 - Relative offset of local file header
3909
+ relativeOffsetOfLocalHeader: getUint32LE(buffer, 42)
3910
+ };
3911
+ if (rawEntry.generalPurposeBitFlag & 64) {
3912
+ throw new Error("strong encryption is not supported");
3913
+ }
3914
+ readEntryCursor += 46;
3915
+ const data = allEntriesBuffer.subarray(readEntryCursor, readEntryCursor + rawEntry.fileNameLength + rawEntry.extraFieldLength + rawEntry.fileCommentLength);
3916
+ rawEntry.nameBytes = data.slice(0, rawEntry.fileNameLength);
3917
+ rawEntry.name = decodeBuffer(rawEntry.nameBytes);
3918
+ const fileCommentStart = rawEntry.fileNameLength + rawEntry.extraFieldLength;
3919
+ const extraFieldBuffer = data.slice(rawEntry.fileNameLength, fileCommentStart);
3920
+ rawEntry.extraFields = [];
3921
+ let i = 0;
3922
+ while (i < extraFieldBuffer.length - 3) {
3923
+ const headerId = getUint16LE(extraFieldBuffer, i + 0);
3924
+ const dataSize = getUint16LE(extraFieldBuffer, i + 2);
3925
+ const dataStart = i + 4;
3926
+ const dataEnd = dataStart + dataSize;
3927
+ if (dataEnd > extraFieldBuffer.length) {
3928
+ throw new Error("extra field length exceeds extra field buffer size");
3929
+ }
3930
+ rawEntry.extraFields.push({
3931
+ id: headerId,
3932
+ data: extraFieldBuffer.slice(dataStart, dataEnd)
3933
+ });
3934
+ i = dataEnd;
3935
+ }
3936
+ rawEntry.commentBytes = data.slice(fileCommentStart, fileCommentStart + rawEntry.fileCommentLength);
3937
+ rawEntry.comment = decodeBuffer(rawEntry.commentBytes);
3938
+ readEntryCursor += data.length;
3939
+ if (rawEntry.uncompressedSize === 4294967295 || rawEntry.compressedSize === 4294967295 || rawEntry.relativeOffsetOfLocalHeader === 4294967295) {
3940
+ const zip64ExtraField = rawEntry.extraFields.find((e2) => e2.id === 1);
3941
+ if (!zip64ExtraField) {
3942
+ throw new Error("expected zip64 extended information extra field");
3943
+ }
3944
+ const zip64EiefBuffer = zip64ExtraField.data;
3945
+ let index = 0;
3946
+ if (rawEntry.uncompressedSize === 4294967295) {
3947
+ if (index + 8 > zip64EiefBuffer.length) {
3948
+ throw new Error("zip64 extended information extra field does not include uncompressed size");
3949
+ }
3950
+ rawEntry.uncompressedSize = getUint64LE(zip64EiefBuffer, index);
3951
+ index += 8;
3952
+ }
3953
+ if (rawEntry.compressedSize === 4294967295) {
3954
+ if (index + 8 > zip64EiefBuffer.length) {
3955
+ throw new Error("zip64 extended information extra field does not include compressed size");
3956
+ }
3957
+ rawEntry.compressedSize = getUint64LE(zip64EiefBuffer, index);
3958
+ index += 8;
3959
+ }
3960
+ if (rawEntry.relativeOffsetOfLocalHeader === 4294967295) {
3961
+ if (index + 8 > zip64EiefBuffer.length) {
3962
+ throw new Error("zip64 extended information extra field does not include relative header offset");
3963
+ }
3964
+ rawEntry.relativeOffsetOfLocalHeader = getUint64LE(zip64EiefBuffer, index);
3965
+ index += 8;
3966
+ }
3967
+ }
3968
+ const nameField = rawEntry.extraFields.find((e2) => e2.id === 28789 && e2.data.length >= 6 && // too short to be meaningful
3969
+ e2.data[0] === 1 && // Version 1 byte version of this extra field, currently 1
3970
+ getUint32LE(e2.data, 1), crc$1.unsigned(rawEntry.nameBytes));
3971
+ if (nameField) {
3972
+ rawEntry.fileName = decodeBuffer(nameField.data.slice(5));
3973
+ }
3974
+ if (rawEntry.compressionMethod === 0) {
3975
+ let expectedCompressedSize = rawEntry.uncompressedSize;
3976
+ if ((rawEntry.generalPurposeBitFlag & 1) !== 0) {
3977
+ expectedCompressedSize += 12;
3978
+ }
3979
+ if (rawEntry.compressedSize !== expectedCompressedSize) {
3980
+ throw new Error(`compressed size mismatch for stored file: ${rawEntry.compressedSize} != ${expectedCompressedSize}`);
3981
+ }
3982
+ }
3983
+ rawEntries.push(rawEntry);
3984
+ }
3985
+ const zip = {
3986
+ comment,
3987
+ commentBytes
3988
+ };
3989
+ return {
3990
+ zip,
3991
+ entries: rawEntries.map((e) => new ZipEntry(reader, e))
3992
+ };
3993
+ }
3994
+ async function readEntryDataHeader(reader, rawEntry) {
3995
+ if (rawEntry.generalPurposeBitFlag & 1) {
3996
+ throw new Error("encrypted entries not supported");
3997
+ }
3998
+ const buffer = await readAs(reader, rawEntry.relativeOffsetOfLocalHeader, 30);
3999
+ const totalLength = await reader.getLength();
4000
+ const signature = getUint32LE(buffer, 0);
4001
+ if (signature !== 67324752) {
4002
+ throw new Error(`invalid local file header signature: 0x${signature.toString(16)}`);
4003
+ }
4004
+ const fileNameLength = getUint16LE(buffer, 26);
4005
+ const extraFieldLength = getUint16LE(buffer, 28);
4006
+ const localFileHeaderEnd = rawEntry.relativeOffsetOfLocalHeader + buffer.length + fileNameLength + extraFieldLength;
4007
+ let decompress2;
4008
+ if (rawEntry.compressionMethod === 0) {
4009
+ decompress2 = false;
4010
+ } else if (rawEntry.compressionMethod === 8) {
4011
+ decompress2 = true;
4012
+ } else {
4013
+ throw new Error(`unsupported compression method: ${rawEntry.compressionMethod}`);
4014
+ }
4015
+ const fileDataStart = localFileHeaderEnd;
4016
+ const fileDataEnd = fileDataStart + rawEntry.compressedSize;
4017
+ if (rawEntry.compressedSize !== 0) {
4018
+ if (fileDataEnd > totalLength) {
4019
+ throw new Error(`file data overflows file bounds: ${fileDataStart} + ${rawEntry.compressedSize} > ${totalLength}`);
4020
+ }
4021
+ }
4022
+ return {
4023
+ decompress: decompress2,
4024
+ fileDataStart
4025
+ };
4026
+ }
4027
+ async function readEntryDataAsArrayBuffer(reader, rawEntry) {
4028
+ const { decompress: decompress2, fileDataStart } = await readEntryDataHeader(reader, rawEntry);
4029
+ if (!decompress2) {
4030
+ const dataView = await readAs(reader, fileDataStart, rawEntry.compressedSize);
4031
+ return isTypedArraySameAsArrayBuffer(dataView) ? dataView.buffer : dataView.slice().buffer;
4032
+ }
4033
+ const typedArrayOrBlob = await readAsBlobOrTypedArray(reader, fileDataStart, rawEntry.compressedSize);
4034
+ const result = await inflateRawAsync(typedArrayOrBlob, rawEntry.uncompressedSize);
4035
+ return result;
4036
+ }
4037
+ async function readEntryDataAsBlob(reader, rawEntry, type) {
4038
+ const { decompress: decompress2, fileDataStart } = await readEntryDataHeader(reader, rawEntry);
4039
+ if (!decompress2) {
4040
+ const typedArrayOrBlob2 = await readAsBlobOrTypedArray(reader, fileDataStart, rawEntry.compressedSize, type);
4041
+ if (isBlob(typedArrayOrBlob2)) {
4042
+ return typedArrayOrBlob2;
4043
+ }
4044
+ return new Blob([isSharedArrayBuffer(typedArrayOrBlob2.buffer) ? new Uint8Array(typedArrayOrBlob2) : typedArrayOrBlob2], { type });
4045
+ }
4046
+ const typedArrayOrBlob = await readAsBlobOrTypedArray(reader, fileDataStart, rawEntry.compressedSize);
4047
+ const result = await inflateRawAsync(typedArrayOrBlob, rawEntry.uncompressedSize, type);
4048
+ return result;
4049
+ }
4050
+ async function unzipRaw(source) {
4051
+ let reader;
4052
+ if (typeof Blob !== "undefined" && source instanceof Blob) {
4053
+ reader = new BlobReader$1(source);
4054
+ } else if (source instanceof ArrayBuffer || source && source.buffer && source.buffer instanceof ArrayBuffer) {
4055
+ reader = new ArrayBufferReader(source);
4056
+ } else if (isSharedArrayBuffer(source) || isSharedArrayBuffer(source.buffer)) {
4057
+ reader = new ArrayBufferReader(source);
4058
+ } else if (typeof source === "string") {
4059
+ const req = await fetch(source);
4060
+ if (!req.ok) {
4061
+ throw new Error(`failed http request ${source}, status: ${req.status}: ${req.statusText}`);
4062
+ }
4063
+ const blob = await req.blob();
4064
+ reader = new BlobReader$1(blob);
4065
+ } else if (typeof source.getLength === "function" && typeof source.read === "function") {
4066
+ reader = source;
4067
+ } else {
4068
+ throw new Error("unsupported source type");
4069
+ }
4070
+ const totalLength = await reader.getLength();
4071
+ if (totalLength > Number.MAX_SAFE_INTEGER) {
4072
+ throw new Error(`file too large. size: ${totalLength}. Only file sizes up 4503599627370496 bytes are supported`);
4073
+ }
4074
+ return await findEndOfCentralDirector(reader, totalLength);
4075
+ }
4076
+ async function unzip(source) {
4077
+ const { zip, entries } = await unzipRaw(source);
4078
+ return {
4079
+ zip,
4080
+ entries: Object.fromEntries(entries.map((v) => [v.name, v]))
4081
+ };
4082
+ }
4083
+ class BlobReader2 {
4084
+ constructor(blob) {
4085
+ this.blob = blob;
4086
+ }
4087
+ async getLength() {
4088
+ return this.blob.size;
4089
+ }
4090
+ async read(offset, length) {
4091
+ const blob = this.blob.slice(offset, offset + length);
4092
+ return new Uint8Array(await blob.arrayBuffer());
4093
+ }
4094
+ }
4095
+ class HTTPRangeReader {
4096
+ #overrides;
4097
+ constructor(url, opts = {}) {
4098
+ this.url = url;
4099
+ this.#overrides = opts.overrides ?? {};
4100
+ }
4101
+ async getLength() {
4102
+ if (this.length === void 0) {
4103
+ const req = await fetch(this.url, {
4104
+ ...this.#overrides,
4105
+ method: "HEAD"
4106
+ });
4107
+ assert$1(req.ok, `failed http request ${this.url}, status: ${req.status}: ${req.statusText}`);
4108
+ this.length = Number(req.headers.get("content-length"));
4109
+ if (Number.isNaN(this.length)) {
4110
+ throw Error("could not get length");
4111
+ }
4112
+ }
4113
+ return this.length;
4114
+ }
4115
+ async read(offset, size) {
4116
+ if (size === 0) {
4117
+ return new Uint8Array(0);
4118
+ }
4119
+ const req = await fetch_range(this.url, offset, size, this.#overrides);
4120
+ assert$1(req.ok, `failed http request ${this.url}, status: ${req.status} offset: ${offset} size: ${size}: ${req.statusText}`);
4121
+ return new Uint8Array(await req.arrayBuffer());
4122
+ }
4123
+ }
4124
+ class ZipFileStore {
4125
+ constructor(reader, opts = {}) {
4126
+ this.info = unzip(reader).then((info) => {
4127
+ if (opts.transformEntries) {
4128
+ info.entries = opts.transformEntries(info.entries);
4129
+ }
4130
+ return info;
4131
+ });
4132
+ }
4133
+ async get(key) {
4134
+ let entry = (await this.info).entries[strip_prefix(key)];
4135
+ if (!entry)
4136
+ return;
4137
+ return new Uint8Array(await entry.arrayBuffer());
4138
+ }
4139
+ async has(key) {
4140
+ return strip_prefix(key) in (await this.info).entries;
4141
+ }
4142
+ static fromUrl(href, opts = {}) {
4143
+ return new ZipFileStore(new HTTPRangeReader(href, opts), opts);
4144
+ }
4145
+ static fromBlob(blob, opts = {}) {
4146
+ return new ZipFileStore(new BlobReader2(blob), opts);
4147
+ }
4148
+ }
4149
+ function transformEntriesForZipFileStore(entries) {
4150
+ const topLevelZarrDirectories = new Set(Object.keys(entries).map((k) => k.split("/")[0]).filter((firstPathItem) => firstPathItem?.endsWith(".zarr")));
4151
+ if (topLevelZarrDirectories.size === 0) {
4152
+ return entries;
4153
+ }
4154
+ if (topLevelZarrDirectories.size > 1) {
4155
+ throw Error("expected exactly one top-level .zarr directory");
4156
+ }
4157
+ const topLevelZarrDirectory = Array.from(topLevelZarrDirectories)[0];
4158
+ const newEntries = Object.fromEntries(Object.entries(entries).map(([k, v]) => {
4159
+ let newKey = k;
4160
+ if (k.split("/")[0] === topLevelZarrDirectory) {
4161
+ newKey = k.substring(topLevelZarrDirectory.length + 1);
4162
+ }
4163
+ return [newKey, v];
4164
+ }));
4165
+ return newEntries;
4166
+ }
4167
+ class AbstractAutoConfig2 {
4168
+ constructor(parsedStore) {
4169
+ const { url, fileType, zmetadata } = parsedStore;
4170
+ this.url = url;
4171
+ this.fileType = fileType;
4172
+ this.zmetadata = zmetadata;
4173
+ }
4174
+ // eslint-disable-next-line class-methods-use-this
4175
+ addFiles(vc, dataset) {
4176
+ throw new Error("The addFiles() method has not been implemented.");
4177
+ }
4178
+ // eslint-disable-next-line class-methods-use-this
4179
+ addViews(vc, dataset, layoutOption) {
4180
+ throw new Error("The addViews() method has not been implemented.");
4181
+ }
4182
+ }
4183
+ class AnnDataAutoConfig extends AbstractAutoConfig2 {
4184
+ getOptions() {
4185
+ const { zmetadata } = this;
4186
+ const options = {
4187
+ obsEmbedding: [],
4188
+ obsSets: []
4189
+ };
4190
+ zmetadata.forEach(({ path, attrs }) => {
4191
+ const lowerPath = path.toLowerCase();
4192
+ const relPath = path.substring(1);
4193
+ if (["/x"].includes(lowerPath)) {
4194
+ options.obsFeatureMatrix = {
4195
+ path: relPath
4196
+ // TODO: Also check the shape of X.
4197
+ // If X is very large, try to initialize initial-filtering properties
4198
+ // (will require that /var contains a boolean column however.)
4199
+ };
4200
+ }
4201
+ if (["/obsm/x_spatial", "/obsm/spatial"].includes(lowerPath)) {
4202
+ options.obsLocations = {
4203
+ path: relPath
4204
+ };
4205
+ }
4206
+ if (["/obsm/x_umap", "/obsm/umap"].includes(lowerPath)) {
4207
+ options.obsEmbedding.push({ path: relPath, embeddingType: "UMAP" });
4208
+ }
4209
+ if (["/obsm/x_tsne", "/obsm/tsne"].includes(lowerPath)) {
4210
+ options.obsEmbedding.push({ path: relPath, embeddingType: "t-SNE" });
4211
+ }
4212
+ if (["/obsm/x_pca", "/obsm/pca"].includes(lowerPath)) {
4213
+ options.obsEmbedding.push({ path: relPath, embeddingType: "PCA" });
4214
+ }
4215
+ const supportedObsSetsPaths = [
4216
+ "cluster",
4217
+ "clusters",
4218
+ "subcluster",
4219
+ "cell_type",
4220
+ "celltype",
4221
+ "leiden",
4222
+ "louvain",
4223
+ "disease",
4224
+ "organism",
4225
+ "self_reported_ethnicity",
4226
+ "tissue",
4227
+ "sex"
4228
+ ].map((colname) => `/obs/${colname}`);
4229
+ if (supportedObsSetsPaths.includes(lowerPath)) {
4230
+ const name = relPath.split("/").at(-1);
4231
+ options.obsSets.push({ path: relPath, name });
4232
+ }
4233
+ });
4234
+ return options;
4235
+ }
4236
+ addFiles(vc, dataset) {
4237
+ const { url, fileType } = this;
4238
+ dataset.addFile({
4239
+ url,
4240
+ fileType,
4241
+ options: this.getOptions()
4242
+ // TODO: coordination values?
4243
+ });
4244
+ }
4245
+ // eslint-disable-next-line class-methods-use-this
4246
+ addViews(vc, dataset, layoutOption) {
4247
+ }
4248
+ }
4249
+ class SpatialDataAutoConfig extends AbstractAutoConfig2 {
4250
+ getOptions() {
4251
+ const { zmetadata } = this;
4252
+ const options = {};
4253
+ const availableElements = zmetadata.filter(({ path }) => {
4254
+ const relPath = path.substring(1);
4255
+ return relPath.match(/^(tables|table|images|labels|shapes|points)\/([^/]*)$/);
4256
+ });
4257
+ availableElements.forEach(({ path, attrs }) => {
4258
+ const relPath = path.substring(1);
4259
+ const firstCoordinateSystem = attrs?.multiscales?.[0]?.coordinateTransformations?.[0]?.output?.name;
4260
+ if (relPath.match(/^(images)\/([^/]*)$/)) {
4261
+ options.image = {
4262
+ path: relPath,
4263
+ coordinateSystem: firstCoordinateSystem
4264
+ // TODO: support a fileUid property in the schema?
4265
+ };
4266
+ }
4267
+ if (relPath.match(/^(labels)\/([^/]*)$/)) {
4268
+ options.obsSegmentations = {
4269
+ path: relPath,
4270
+ coordinateSystem: firstCoordinateSystem
4271
+ // TODO: support a fileUid property in the schema?
4272
+ };
4273
+ }
4274
+ if (relPath.match(/^(shapes)\/([^/]*)$/)) {
4275
+ options.obsSpots = {
4276
+ path: relPath,
4277
+ coordinateSystem: firstCoordinateSystem
4278
+ };
4279
+ }
4280
+ if (relPath.match(/^(points)\/([^/]*)$/)) {
4281
+ options.obsPoints = {
4282
+ path: relPath,
4283
+ coordinateSystem: firstCoordinateSystem
4284
+ };
4285
+ }
4286
+ if (relPath.match(/^(tables|table)\/([^/]*)$/)) {
4287
+ const tableEls = zmetadata.filter(({ path: subpath }) => subpath.startsWith(path));
4288
+ const hasX = tableEls.find((el) => el.path === `${path}/X`);
4289
+ if (hasX) {
4290
+ options.obsFeatureMatrix = {
4291
+ path: hasX.path.substring(1)
4292
+ // region: null,
4293
+ };
4294
+ }
4295
+ const hasObs = tableEls.find((el) => el.path === `${path}/obs`);
4296
+ if (hasObs) {
4297
+ const columnOrder = hasObs.attrs?.["column-order"];
4298
+ options.obsSets = {
4299
+ // region: null,
4300
+ tablePath: relPath,
4301
+ obsSets: columnOrder.map((c) => ({
4302
+ // TODO: determine whether this column is string/categorical.
4303
+ // TODO: determine whether this column contains too many
4304
+ // categories to make sense to consider a cell set.
4305
+ path: `${hasObs.path.substring(1)}/${c}`,
4306
+ name: c
4307
+ }))
4308
+ };
4309
+ }
4310
+ }
4311
+ });
4312
+ return options;
4313
+ }
4314
+ addFiles(vc, dataset) {
4315
+ const { url, fileType } = this;
4316
+ dataset.addFile({
4317
+ url,
4318
+ fileType,
4319
+ options: this.getOptions()
4320
+ // TODO: coordination values?
4321
+ });
4322
+ }
4323
+ // eslint-disable-next-line class-methods-use-this
4324
+ addViews(vc, dataset, layoutOption) {
4325
+ const options = this.getOptions();
4326
+ const spatialView = vc.addView(dataset, "spatialBeta");
4327
+ const lcView = vc.addView(dataset, "layerControllerBeta");
4328
+ const controlViews = [lcView];
4329
+ if (options.obsSets) {
4330
+ const obsSets = vc.addView(dataset, "obsSets");
4331
+ controlViews.push(obsSets);
4332
+ }
4333
+ if (options.obsFeatureMatrix) {
4334
+ const featureList = vc.addView(dataset, "featureList");
4335
+ controlViews.push(featureList);
4336
+ }
4337
+ vc.layout(hconcat(spatialView, vconcat(...controlViews)));
4338
+ }
4339
+ }
4340
+ class OmeAutoConfig extends AbstractAutoConfig2 {
4341
+ addFiles(vc, dataset) {
4342
+ const { url, fileType } = this;
4343
+ dataset.addFile({
4344
+ url,
4345
+ fileType
4346
+ // TODO: options?
4347
+ // TODO: coordination values?
4348
+ });
4349
+ }
4350
+ // eslint-disable-next-line class-methods-use-this
4351
+ addViews(vc, dataset, layoutOption) {
4352
+ const spatialView = vc.addView(dataset, "spatialBeta");
4353
+ const lcView = vc.addView(dataset, "layerControllerBeta");
4354
+ vc.layout(hconcat(spatialView, lcView));
4355
+ }
4356
+ }
4357
+ const FILE_TYPE_DELIM = "$";
4358
+ const fileTypeToExtensions = {
4359
+ [FileType.IMAGE_OME_TIFF]: [".ome.tif", ".ome.tiff", ".ome.tf2", ".ome.tf8"],
4360
+ [FileType.IMAGE_OME_ZARR]: [".ome.zarr"],
4361
+ [FileType.IMAGE_OME_ZARR_ZIP]: [".ome.zarr.zip"],
4362
+ [FileType.ANNDATA_ZARR]: [".ad.zarr", ".h5ad.zarr", ".adata.zarr", ".anndata.zarr"],
4363
+ [FileType.ANNDATA_ZARR_ZIP]: [".ad.zarr.zip", ".h5ad.zarr.zip", ".adata.zarr.zip", ".anndata.zarr.zip"],
4364
+ // TODO: how to handle h5ad-based AnnData (since needs reference JSON file).
4365
+ // Perhaps just assume one H5AD+one JSON (or .ref.json) file correspond to each other?
4366
+ [FileType.SPATIALDATA_ZARR]: [".sd.zarr", ".sdata.zarr", ".spatialdata.zarr"],
4367
+ [FileType.SPATIALDATA_ZARR_ZIP]: [".sd.zarr.zip", ".sdata.zarr.zip", ".spatialdata.zarr.zip"]
4368
+ };
4369
+ const fileTypeToClass = {
4370
+ // OME-TIFF
4371
+ [FileType.IMAGE_OME_TIFF]: OmeAutoConfig,
4372
+ [FileType.OBS_SEGMENTATIONS_OME_TIFF]: OmeAutoConfig,
4373
+ // OME-Zarr
4374
+ [FileType.IMAGE_OME_ZARR]: OmeAutoConfig,
4375
+ [FileType.IMAGE_OME_ZARR_ZIP]: OmeAutoConfig,
4376
+ [FileType.OBS_SEGMENTATIONS_OME_ZARR]: OmeAutoConfig,
4377
+ [FileType.OBS_SEGMENTATIONS_OME_ZARR_ZIP]: OmeAutoConfig,
4378
+ // AnnData
4379
+ [FileType.ANNDATA_ZARR]: AnnDataAutoConfig,
4380
+ [FileType.ANNDATA_ZARR_ZIP]: AnnDataAutoConfig,
4381
+ // SpatialData
4382
+ [FileType.SPATIALDATA_ZARR]: SpatialDataAutoConfig,
4383
+ [FileType.SPATIALDATA_ZARR_ZIP]: SpatialDataAutoConfig
4384
+ };
4385
+ const ZARR_FILETYPES = [
4386
+ FileType.ANNDATA_ZARR,
4387
+ FileType.ANNDATA_ZARR_ZIP,
4388
+ FileType.SPATIALDATA_ZARR,
4389
+ FileType.SPATIALDATA_ZARR_ZIP,
4390
+ FileType.IMAGE_OME_ZARR,
4391
+ FileType.IMAGE_OME_ZARR_ZIP,
4392
+ FileType.OBS_SEGMENTATIONS_OME_ZARR,
4393
+ FileType.OBS_SEGMENTATIONS_OME_ZARR_ZIP
4394
+ ];
4395
+ function urlToFileType(url) {
4396
+ const match = Object.entries(fileTypeToExtensions).find(
4397
+ // eslint-disable-next-line no-unused-vars
4398
+ ([fileType, extensions]) => extensions.some((ext) => url.endsWith(ext))
4399
+ );
4400
+ if (match) {
4401
+ return match[0];
4402
+ }
4403
+ throw new Error("The file extension contained in the URL did not map to a supported fileType.");
4404
+ }
4405
+ function getStore(parsedUrl) {
4406
+ const { fileType, url } = parsedUrl;
4407
+ if (!ZARR_FILETYPES.includes(fileType)) {
4408
+ return null;
4409
+ }
4410
+ return fileType.endsWith(".zip") ? ZipFileStore.fromUrl(url, {
4411
+ transformEntries: transformEntriesForZipFileStore
4412
+ }) : new FetchStore(url);
4413
+ }
4414
+ function ensureStores(parsedUrls) {
4415
+ return parsedUrls.map((parsedUrl) => {
4416
+ if (parsedUrl.store) {
4417
+ return parsedUrl;
4418
+ }
4419
+ const store = getStore(parsedUrl);
4420
+ return {
4421
+ ...parsedUrl,
4422
+ store
4423
+ };
4424
+ });
4425
+ }
4426
+ function parseUrls(arr) {
4427
+ return arr.map((urlWithHash) => {
4428
+ const parts = urlWithHash.split(FILE_TYPE_DELIM);
4429
+ if (parts.length === 1) {
4430
+ const [url] = parts;
4431
+ return {
4432
+ url,
4433
+ fileType: urlToFileType(url)
4434
+ };
4435
+ }
4436
+ if (parts.length === 2) {
4437
+ const [url, fileType] = parts;
4438
+ return {
4439
+ url,
4440
+ fileType
4441
+ };
4442
+ }
4443
+ throw new Error(`Only expected zero or one ${FILE_TYPE_DELIM} character per URL, but received more.`);
4444
+ });
4445
+ }
4446
+ function parseUrlsFromString(s) {
4447
+ const urlsWithHashes = s.split(";");
4448
+ return parseUrls(urlsWithHashes);
4449
+ }
4450
+ async function parsedUrlToZmetadata(parsedUrl) {
4451
+ const { store: initialStore } = parsedUrl;
4452
+ if (!initialStore) {
4453
+ return null;
4454
+ }
4455
+ let store;
4456
+ let promises = [];
4457
+ try {
4458
+ try {
4459
+ store = await withConsolidated(initialStore);
4460
+ } catch {
4461
+ store = await withConsolidated(initialStore, { metadataKey: "zmetadata" });
4462
+ }
4463
+ const contents = store.contents();
4464
+ promises = contents.map(async (value) => {
4465
+ const item = await open(root(store).resolve(value.path));
4466
+ return {
4467
+ ...value,
4468
+ attrs: item.attrs
4469
+ };
4470
+ });
4471
+ } catch {
4472
+ store = initialStore;
4473
+ const keysToTry = [
4474
+ // Note: OME-NGFF metadata is stored in the root attrs.
4475
+ "/",
4476
+ // AnnData keys
4477
+ "/X",
4478
+ "/layers",
4479
+ "/obs",
4480
+ "/var",
4481
+ "/obsm",
4482
+ "/obsm/spatial",
4483
+ "/obsm/X_spatial",
4484
+ "/obsm/pca",
4485
+ "/obsm/X_pca",
4486
+ "/obsm/tsne",
4487
+ "/obsm/X_tsne",
4488
+ "/obsm/umap",
4489
+ "/obsm/X_umap"
4490
+ // TODO: second round of getting metadata for
4491
+ // columns listed in /obs and /var .attrs['column-order'] ?
4492
+ // SpatialData keys
4493
+ // Note: For spatialData, we assume the store is always consolidated.
4494
+ // TODO: throw error if spatialdata + not consolidated?
4495
+ ];
4496
+ promises = keysToTry.map(async (k) => {
4497
+ try {
4498
+ const item = await open(root(store).resolve(k));
4499
+ return {
4500
+ path: k,
4501
+ kind: item.kind,
4502
+ attrs: item.attrs
4503
+ };
4504
+ } catch {
4505
+ return null;
4506
+ }
4507
+ });
4508
+ }
4509
+ return (await Promise.all(promises)).filter((entry) => entry !== null);
4510
+ }
4511
+ async function generateConfig(parsedUrls, layoutOption = null) {
4512
+ const parsedStores = ensureStores(parsedUrls);
4513
+ const zmetadataStores = await Promise.all(
4514
+ parsedStores.map(async (parsedStore) => ({
4515
+ ...parsedStore,
4516
+ zmetadata: await parsedUrlToZmetadata(parsedStore)
4517
+ }))
4518
+ );
4519
+ const vc = new VitessceConfig({
4520
+ schemaVersion: "1.0.17",
4521
+ name: "Automatically-generated configuration.",
4522
+ // TODO: write a description based on what is known
4523
+ // (fileType(s) and maybe layoutOption).
4524
+ description: "Populate with a description of this visualization."
4525
+ });
4526
+ const dataset = vc.addDataset("Main dataset");
4527
+ zmetadataStores.forEach((parsedStore) => {
4528
+ const { fileType } = parsedStore;
4529
+ const AutoConfigClass = fileTypeToClass[fileType];
4530
+ const autoConfig = new AutoConfigClass(parsedStore);
4531
+ autoConfig.addFiles(vc, dataset);
4532
+ autoConfig.addViews(vc, dataset, layoutOption);
4533
+ });
4534
+ const stores = Object.fromEntries(
4535
+ // Here, we use `parsedUrls` rather than `parsedStores`
4536
+ // so that we do not provide more stores than intended
4537
+ // (i.e., we do not provide stores which were solely created
4538
+ // to obtain zmetadata).
4539
+ parsedUrls.filter((d) => d.store).map((d) => [d.url, d.store])
4540
+ );
4541
+ return {
4542
+ config: vc,
4543
+ stores
4544
+ };
4545
+ }
2084
4546
  export {
2085
4547
  CL as CoordinationLevel,
2086
4548
  HINTS_CONFIG,
2087
4549
  HINT_TYPE_TO_FILE_TYPE_MAP,
2088
4550
  VitessceConfig,
2089
- generateConfig,
4551
+ generateConfig$1 as generateConfig,
4552
+ generateConfig as generateConfigAlt,
2090
4553
  getCoordinationSpaceAndScopes,
2091
4554
  getHintOptions,
2092
4555
  getInitialCoordinationScopeName,
2093
4556
  getInitialCoordinationScopePrefix,
2094
4557
  hconcat,
4558
+ parseUrls,
4559
+ parseUrlsFromString,
2095
4560
  vconcat
2096
4561
  };