From 3dc64f4cb8aaef83fc354f8db2bd04d46362eacc Mon Sep 17 00:00:00 2001
From: Matt McCormick
Date: Sun, 1 Dec 2024 12:42:40 -0500
Subject: [PATCH 01/12] WIP: ITK-Wasm surface generation pipeline
Anti-aliased segmentation to surface generation with the aim to make
improvements in well-behaved (non-intersecting, well-proportioned) triangles, smooth, reduced sampling artifacts, retains sulci.
---
main.js | 424 +++++++------
package-lock.json | 1470 +++++++++++++++++++++++++++++++++++++++++++++
package.json | 2 +
vite.config.js | 14 +-
4 files changed, 1709 insertions(+), 201 deletions(-)
diff --git a/main.js b/main.js
index 732b2f7..de9ef3f 100644
--- a/main.js
+++ b/main.js
@@ -1,21 +1,23 @@
-import { Niivue, NVMeshUtilities } from "@niivue/niivue"
-import { Niimath } from "@niivue/niimath"
+import { Niivue, NVMeshUtilities } from "@niivue/niivue";
+import { Niimath } from "@niivue/niimath";
// import {runInference } from './brainchop-mainthread.js'
-import { inferenceModelsList, brainChopOpts } from "./brainchop-parameters.js"
-import { isChrome, localSystemDetails } from "./brainchop-telemetry.js"
-import MyWorker from "./brainchop-webworker.js?worker"
+import { inferenceModelsList, brainChopOpts } from "./brainchop-parameters.js";
+import { isChrome, localSystemDetails } from "./brainchop-telemetry.js";
+import MyWorker from "./brainchop-webworker.js?worker";
+import { antiAliasCuberille } from "@itk-wasm/cuberille";
+import { nii2iwi, iwm2meshCore } from "@niivue/cbor-loader";
async function main() {
- const niimath = new Niimath()
- await niimath.init()
+ const niimath = new Niimath();
+ await niimath.init();
// const wrapper = await NiiMathWrapper.load()
/*smoothCheck.onchange = function () {
nv1.setInterpolation(!smoothCheck.checked)
}*/
aboutBtn.onclick = function () {
const url = "https://github.com/niivue/brain2print";
- window.open(url, '_blank');
- }
+ window.open(url, "_blank");
+ };
/*diagnosticsBtn.onclick = function () {
if (diagnosticsString.length < 1) {
window.alert('No diagnostic string generated: run a model to create diagnostics')
@@ -25,278 +27,312 @@ async function main() {
window.alert('Diagnostics copied to clipboard\n' + diagnosticsString)
}*/
opacitySlider0.oninput = function () {
- nv1.setOpacity(0, opacitySlider0.value / 255)
- nv1.updateGLVolume()
- }
+ nv1.setOpacity(0, opacitySlider0.value / 255);
+ nv1.updateGLVolume();
+ };
opacitySlider1.oninput = function () {
- if (nv1.volumes.length < 2) return
- nv1.setOpacity(1, opacitySlider1.value / 255)
- }
+ if (nv1.volumes.length < 2) return;
+ nv1.setOpacity(1, opacitySlider1.value / 255);
+ };
async function ensureConformed() {
- let nii = nv1.volumes[0]
- let isConformed = ((nii.dims[1] === 256) && (nii.dims[2] === 256) && (nii.dims[3] === 256))
- if ((nii.permRAS[0] !== -1) || (nii.permRAS[1] !== 3) || (nii.permRAS[2] !== -2))
- isConformed = false
- if (isConformed)
- return
- let nii2 = await nv1.conform(nii, false)
- await nv1.removeVolume(nv1.volumes[0])
- await nv1.addVolume(nii2)
+ let nii = nv1.volumes[0];
+ let isConformed =
+ nii.dims[1] === 256 && nii.dims[2] === 256 && nii.dims[3] === 256;
+ if (nii.permRAS[0] !== -1 || nii.permRAS[1] !== 3 || nii.permRAS[2] !== -2)
+ isConformed = false;
+ if (isConformed) return;
+ let nii2 = await nv1.conform(nii, false);
+ await nv1.removeVolume(nv1.volumes[0]);
+ await nv1.addVolume(nii2);
}
async function closeAllOverlays() {
while (nv1.volumes.length > 1) {
- await nv1.removeVolume(nv1.volumes[1])
+ await nv1.removeVolume(nv1.volumes[1]);
}
}
modelSelect.onchange = async function () {
- if (this.selectedIndex < 0)
- modelSelect.selectedIndex = 11
- await closeAllOverlays()
- await ensureConformed()
- let model = inferenceModelsList[this.selectedIndex]
- model.isNvidia = false
- const rendererInfo = nv1.gl.getExtension('WEBGL_debug_renderer_info')
+ if (this.selectedIndex < 0) modelSelect.selectedIndex = 11;
+ await closeAllOverlays();
+ await ensureConformed();
+ let model = inferenceModelsList[this.selectedIndex];
+ model.isNvidia = false;
+ const rendererInfo = nv1.gl.getExtension("WEBGL_debug_renderer_info");
if (rendererInfo) {
- model.isNvidia = nv1.gl.getParameter(rendererInfo.UNMASKED_RENDERER_WEBGL).includes('NVIDIA')
-
+ model.isNvidia = nv1.gl
+ .getParameter(rendererInfo.UNMASKED_RENDERER_WEBGL)
+ .includes("NVIDIA");
}
-
- let opts = brainChopOpts
- opts.rootURL = location.href
+
+ let opts = brainChopOpts;
+ opts.rootURL = location.href;
const isLocalhost = Boolean(
- window.location.hostname === 'localhost' ||
- // [::1] is the IPv6 localhost address.
- window.location.hostname === '[::1]' ||
- // 127.0.0.1/8 is considered localhost for IPv4.
- window.location.hostname.match(
+ window.location.hostname === "localhost" ||
+ // [::1] is the IPv6 localhost address.
+ window.location.hostname === "[::1]" ||
+ // 127.0.0.1/8 is considered localhost for IPv4.
+ window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
- )
- )
- if (isLocalhost)
- opts.rootURL = location.protocol + '//' + location.host
+ )
+ );
+ if (isLocalhost) opts.rootURL = location.protocol + "//" + location.host;
if (workerCheck.checked) {
- if(typeof(chopWorker) !== "undefined") {
- console.log('Unable to start new segmentation: previous call has not completed')
- return
+ if (typeof chopWorker !== "undefined") {
+ console.log(
+ "Unable to start new segmentation: previous call has not completed"
+ );
+ return;
}
- chopWorker = await new MyWorker({ type: "module" })
- let hdr = {datatypeCode: nv1.volumes[0].hdr.datatypeCode, dims: nv1.volumes[0].hdr.dims}
- let msg = {opts:opts, modelEntry: model, niftiHeader: hdr, niftiImage: nv1.volumes[0].img}
- chopWorker.postMessage(msg)
- chopWorker.onmessage = function(event) {
- let cmd = event.data.cmd
- if (cmd === 'ui') {
- if (event.data.modalMessage !== "") {
- chopWorker.terminate()
- chopWorker = undefined
- }
- callbackUI(event.data.message, event.data.progressFrac, event.data.modalMessage, event.data.statData)
+ chopWorker = await new MyWorker({ type: "module" });
+ let hdr = {
+ datatypeCode: nv1.volumes[0].hdr.datatypeCode,
+ dims: nv1.volumes[0].hdr.dims,
+ };
+ let msg = {
+ opts: opts,
+ modelEntry: model,
+ niftiHeader: hdr,
+ niftiImage: nv1.volumes[0].img,
+ };
+ chopWorker.postMessage(msg);
+ chopWorker.onmessage = function (event) {
+ let cmd = event.data.cmd;
+ if (cmd === "ui") {
+ if (event.data.modalMessage !== "") {
+ chopWorker.terminate();
+ chopWorker = undefined;
+ }
+ callbackUI(
+ event.data.message,
+ event.data.progressFrac,
+ event.data.modalMessage,
+ event.data.statData
+ );
}
- if (cmd === 'img') {
- chopWorker.terminate()
- chopWorker = undefined
- callbackImg(event.data.img, event.data.opts, event.data.modelEntry)
+ if (cmd === "img") {
+ chopWorker.terminate();
+ chopWorker = undefined;
+ callbackImg(event.data.img, event.data.opts, event.data.modelEntry);
}
- }
+ };
} else {
- console.log('Only provided with webworker code, see main brainchop github repository for main thread code')
+ console.log(
+ "Only provided with webworker code, see main brainchop github repository for main thread code"
+ );
// runInference(opts, model, nv1.volumes[0].hdr, nv1.volumes[0].img, callbackImg, callbackUI)
}
- }
+ };
saveBtn.onclick = function () {
- nv1.volumes[1].saveToDisk("Custom.nii")
- }
+ nv1.volumes[1].saveToDisk("Custom.nii");
+ };
workerCheck.onchange = function () {
- modelSelect.onchange()
- }
+ modelSelect.onchange();
+ };
clipCheck.onchange = function () {
if (clipCheck.checked) {
- nv1.setClipPlane([0, 0, 90])
+ nv1.setClipPlane([0, 0, 90]);
} else {
- nv1.setClipPlane([2, 0, 90])
+ nv1.setClipPlane([2, 0, 90]);
}
- }
+ };
function doLoadImage() {
- opacitySlider0.oninput()
+ opacitySlider0.oninput();
}
async function fetchJSON(fnm) {
- const response = await fetch(fnm)
- const js = await response.json()
- return js
+ const response = await fetch(fnm);
+ const js = await response.json();
+ return js;
}
async function callbackImg(img, opts, modelEntry) {
- closeAllOverlays()
- let overlayVolume = await nv1.volumes[0].clone()
- overlayVolume.zeroImage()
- overlayVolume.hdr.scl_inter = 0
- overlayVolume.hdr.scl_slope = 1
- overlayVolume.img = new Uint8Array(img)
+ closeAllOverlays();
+ let overlayVolume = await nv1.volumes[0].clone();
+ overlayVolume.zeroImage();
+ overlayVolume.hdr.scl_inter = 0;
+ overlayVolume.hdr.scl_slope = 1;
+ overlayVolume.img = new Uint8Array(img);
if (modelEntry.colormapPath) {
- let cmap = await fetchJSON(modelEntry.colormapPath)
- overlayVolume.setColormapLabel(cmap)
+ let cmap = await fetchJSON(modelEntry.colormapPath);
+ overlayVolume.setColormapLabel(cmap);
// n.b. most models create indexed labels, but those without colormap mask scalar input
- overlayVolume.hdr.intent_code = 1002 // NIFTI_INTENT_LABEL
+ overlayVolume.hdr.intent_code = 1002; // NIFTI_INTENT_LABEL
} else {
- let colormap = opts.atlasSelectedColorTable.toLowerCase()
- const cmaps = nv1.colormaps()
+ let colormap = opts.atlasSelectedColorTable.toLowerCase();
+ const cmaps = nv1.colormaps();
if (!cmaps.includes(colormap)) {
- colormap = 'actc'
+ colormap = "actc";
}
- overlayVolume.colormap = colormap
+ overlayVolume.colormap = colormap;
}
- overlayVolume.opacity = opacitySlider1.value / 255
- await nv1.addVolume(overlayVolume)
+ overlayVolume.opacity = opacitySlider1.value / 255;
+ await nv1.addVolume(overlayVolume);
}
async function reportTelemetry(statData) {
- if (typeof statData === 'string' || statData instanceof String) {
+ if (typeof statData === "string" || statData instanceof String) {
function strToArray(str) {
- const list = JSON.parse(str)
- const array = []
+ const list = JSON.parse(str);
+ const array = [];
for (const key in list) {
- array[key] = list[key]
+ array[key] = list[key];
}
- return array
+ return array;
}
- statData = strToArray(statData)
+ statData = strToArray(statData);
}
- statData = await localSystemDetails(statData, nv1.gl)
- diagnosticsString = ':: Diagnostics can help resolve issues https://github.com/neuroneural/brainchop/issues ::\n'
- for (var key in statData){
- diagnosticsString += key + ': ' + statData[key]+'\n'
+ statData = await localSystemDetails(statData, nv1.gl);
+ diagnosticsString =
+ ":: Diagnostics can help resolve issues https://github.com/neuroneural/brainchop/issues ::\n";
+ for (var key in statData) {
+ diagnosticsString += key + ": " + statData[key] + "\n";
}
}
- function callbackUI(message = "", progressFrac = -1, modalMessage = "", statData = []) {
+ function callbackUI(
+ message = "",
+ progressFrac = -1,
+ modalMessage = "",
+ statData = []
+ ) {
if (message !== "") {
- console.log(message)
- document.getElementById("location").innerHTML = message
+ console.log(message);
+ document.getElementById("location").innerHTML = message;
}
- if (isNaN(progressFrac)) { //memory issue
- memstatus.style.color = "red"
- memstatus.innerHTML = "Memory Issue"
+ if (isNaN(progressFrac)) {
+ //memory issue
+ memstatus.style.color = "red";
+ memstatus.innerHTML = "Memory Issue";
} else if (progressFrac >= 0) {
- modelProgress.value = progressFrac * modelProgress.max
+ modelProgress.value = progressFrac * modelProgress.max;
}
if (modalMessage !== "") {
- window.alert(modalMessage)
+ window.alert(modalMessage);
}
if (Object.keys(statData).length > 0) {
- reportTelemetry(statData)
+ reportTelemetry(statData);
}
}
function handleLocationChange(data) {
- document.getElementById("location").innerHTML = " " + data.string
+ document.getElementById("location").innerHTML =
+ " " + data.string;
}
let defaults = {
backColor: [0.4, 0.4, 0.4, 1],
show3Dcrosshair: true,
onLocationChange: handleLocationChange,
- }
+ };
createMeshBtn.onclick = function () {
- if (nv1.meshes.length > 0)
- nv1.removeMesh(nv1.meshes[0])
+ if (nv1.meshes.length > 0) nv1.removeMesh(nv1.meshes[0]);
if (nv1.volumes.length < 1) {
- window.alert("Image not loaded. Drag and drop an image.")
+ window.alert("Image not loaded. Drag and drop an image.");
} else {
- remeshDialog.show()
+ remeshDialog.show();
}
- }
+ };
applyBtn.onclick = async function () {
- const niiBuffer = await nv1.saveImage({volumeByIndex: nv1.volumes.length - 1}).buffer
- const niiBlob = new Blob([niiBuffer], { type: 'application/octet-stream' })
- const niiFile = new File([niiBlob], 'input.nii')
+ const niiBuffer = await nv1.saveImage({
+ volumeByIndex: nv1.volumes.length - 1,
+ }).buffer;
+ const niiBlob = new Blob([niiBuffer], { type: "application/octet-stream" });
+ const niiFile = new File([niiBlob], "input.nii");
// get an ImageProcessor instance from niimath
// so we can build up the operations we want to perform
// based on the UI controls
- let image = niimath.image(niiFile)
- loadingCircle.classList.remove('hidden')
- // initialize the operations object for the niimath mesh function
- let ops = {
- i: 0.5,
- }
- //const largestCheckValue = largestCheck.checked
- if (largestCheck.checked) {
- ops.l = 1
- }
- let reduce = Math.min(Math.max(Number(shrinkPct.value) / 100, 0.01), 1)
- ops.r = reduce
- let smooth = parseFloat(smoothSlide.value)
- ops.s = smooth
- if (bubbleCheck.checked) {
- ops.b = 1
- }
+ // let image = niimath.image(niiFile);
+ // loadingCircle.classList.remove("hidden");
+ // // initialize the operations object for the niimath mesh function
+ // let ops = {
+ // i: 0.5,
+ // };
+ // //const largestCheckValue = largestCheck.checked
+ // if (largestCheck.checked) {
+ // ops.l = 1;
+ // }
+ // let reduce = Math.min(Math.max(Number(shrinkPct.value) / 100, 0.01), 1);
+ // ops.r = reduce;
+ // let smooth = parseFloat(smoothSlide.value);
+ // ops.s = smooth;
+ // if (bubbleCheck.checked) {
+ // ops.b = 1;
+ // }
- let hollowInt = Number(hollowSelect.value )
- if (hollowInt < 0){
- // append the hollow operation to the image processor
- // but dont run it yet.
- image = image.hollow(0.5, hollowInt)
- }
+ // let hollowInt = Number(hollowSelect.value);
+ // if (hollowInt < 0) {
+ // // append the hollow operation to the image processor
+ // // but dont run it yet.
+ // image = image.hollow(0.5, hollowInt);
+ // }
+
+ // let closeFloat = Number(closeMM.value);
+ // if (isFinite(closeFloat) && closeFloat > 0) {
+ // // append the close operation to the image processor
+ // // but dont run it yet.
+ // image = image.close(0.5, closeFloat, 2 * closeFloat);
+ // }
+ // // add the mesh operations
+ // image = image.mesh(ops);
+ // console.log("niimath mesh operation", image.commands);
+ const hdr = nv1.volumes[1].hdr;
+ const img = nv1.volumes[1].img;
+
+ const itkImage = nii2iwi(hdr, img, false);
+ itkImage.size = itkImage.size.map(Number);
+ const { mesh } = await antiAliasCuberille(itkImage);
+
+ const niiMesh = iwm2meshCore(mesh);
+ console.log(niiMesh);
+ console.log(nv1);
- let closeFloat = Number(closeMM.value)
- if ((isFinite(closeFloat)) && (closeFloat > 0)){
- // append the close operation to the image processor
- // but dont run it yet.
- image = image.close(0.5, closeFloat, 2 * closeFloat)
- }
- // add the mesh operations
- image = image.mesh(ops)
- console.log('niimath mesh operation', image.commands)
// finally, run the full set of operations
- const outFile = await image.run('output.mz3')
- const arrayBuffer = await outFile.arrayBuffer()
- loadingCircle.classList.add('hidden')
- if (nv1.meshes.length > 0)
- nv1.removeMesh(nv1.meshes[0])
- await nv1.loadFromArrayBuffer(arrayBuffer, 'output.mz3')
- nv1.reverseFaces(0)
- }
+ // const outFile = await image.run("output.mz3");
+ // const outFile = await image.run("output.nii");
+ // const arrayBuffer = await outFile.arrayBuffer();
+ loadingCircle.classList.add("hidden");
+ if (nv1.meshes.length > 0) nv1.removeMesh(nv1.meshes[0]);
+ // await nv1.loadFromArrayBuffer(arrayBuffer, "output.mz3");
+ // nv1.reverseFaces(0);
+ };
saveMeshBtn.onclick = function () {
if (nv1.meshes.length < 1) {
- window.alert("No mesh open for saving. Use 'Create Mesh'.")
+ window.alert("No mesh open for saving. Use 'Create Mesh'.");
} else {
- saveDialog.show()
+ saveDialog.show();
}
- }
+ };
applySaveBtn.onclick = function () {
if (nv1.meshes.length < 1) {
- return
+ return;
}
- let format = 'obj'
+ let format = "obj";
if (formatSelect.selectedIndex === 0) {
- format = 'mz3'
+ format = "mz3";
}
if (formatSelect.selectedIndex === 2) {
- format = 'stl'
+ format = "stl";
}
- const scale = 1 / Number(scaleSelect.value)
- const pts = nv1.meshes[0].pts.slice()
- for (let i = 0; i < pts.length; i++)
- pts[i] *= scale;
- NVMeshUtilities.saveMesh(pts, nv1.meshes[0].tris, `mesh.${format}`, true)
- }
+ const scale = 1 / Number(scaleSelect.value);
+ const pts = nv1.meshes[0].pts.slice();
+ for (let i = 0; i < pts.length; i++) pts[i] *= scale;
+ NVMeshUtilities.saveMesh(pts, nv1.meshes[0].tris, `mesh.${format}`, true);
+ };
- var diagnosticsString = ''
- var chopWorker
- let nv1 = new Niivue(defaults)
- nv1.attachToCanvas(gl1)
- nv1.opts.dragMode = nv1.dragModes.pan
- nv1.opts.multiplanarForceRender = true
- nv1.opts.yoke3Dto2DZoom = true
- nv1.opts.crosshairGap = 11
- await nv1.loadVolumes([{ url: "./t1_crop.nii.gz" }])
+ var diagnosticsString = "";
+ var chopWorker;
+ let nv1 = new Niivue(defaults);
+ nv1.attachToCanvas(gl1);
+ nv1.opts.dragMode = nv1.dragModes.pan;
+ nv1.opts.multiplanarForceRender = true;
+ nv1.opts.yoke3Dto2DZoom = true;
+ nv1.opts.crosshairGap = 11;
+ await nv1.loadVolumes([{ url: "./t1_crop.nii.gz" }]);
for (let i = 0; i < inferenceModelsList.length; i++) {
- var option = document.createElement("option")
- option.text = inferenceModelsList[i].modelName
- option.value = inferenceModelsList[i].id.toString()
- modelSelect.appendChild(option)
+ var option = document.createElement("option");
+ option.text = inferenceModelsList[i].modelName;
+ option.value = inferenceModelsList[i].id.toString();
+ modelSelect.appendChild(option);
}
- nv1.onImageLoaded = doLoadImage
- modelSelect.selectedIndex = -1
- workerCheck.checked = await isChrome() //TODO: Safari does not yet support WebGL TFJS webworkers, test FireFox
+ nv1.onImageLoaded = doLoadImage;
+ modelSelect.selectedIndex = -1;
+ workerCheck.checked = await isChrome(); //TODO: Safari does not yet support WebGL TFJS webworkers, test FireFox
// uncomment next two lines to automatically run segmentation when web page is loaded
// modelSelect.selectedIndex = 11
// modelSelect.onchange()
-
}
-main()
+main();
diff --git a/package-lock.json b/package-lock.json
index 8b3f78a..da662dd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,6 +8,8 @@
"name": "niivue-brainchop",
"version": "0.1.0",
"dependencies": {
+ "@itk-wasm/cuberille": "^0.1.0",
+ "@niivue/cbor-loader": "^1.0.0",
"@niivue/niimath": "^0.1.1",
"@niivue/niivue": "^0.44.2",
"@tensorflow/tfjs": "^4.19.0",
@@ -17,6 +19,78 @@
"vite": "^5.4.2"
}
},
+ "node_modules/@cbor-extract/cbor-extract-darwin-arm64": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.2.0.tgz",
+ "integrity": "sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@cbor-extract/cbor-extract-darwin-x64": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-x64/-/cbor-extract-darwin-x64-2.2.0.tgz",
+ "integrity": "sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@cbor-extract/cbor-extract-linux-arm": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm/-/cbor-extract-linux-arm-2.2.0.tgz",
+ "integrity": "sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@cbor-extract/cbor-extract-linux-arm64": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm64/-/cbor-extract-linux-arm64-2.2.0.tgz",
+ "integrity": "sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@cbor-extract/cbor-extract-linux-x64": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-x64/-/cbor-extract-linux-x64-2.2.0.tgz",
+ "integrity": "sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@cbor-extract/cbor-extract-win32-x64": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.2.0.tgz",
+ "integrity": "sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
"node_modules/@esbuild/aix-ppc64": {
"version": "0.21.5",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
@@ -408,6 +482,105 @@
"node": ">=12"
}
},
+ "node_modules/@ipld/car": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/@ipld/car/-/car-5.3.3.tgz",
+ "integrity": "sha512-4vgV5Ml4HCJ2iTx7vYhu0ui+Xxo1HQTtVeYgD+JKd5Wij8TlOFZnxOSickqpLcuf1fdGEStgqVItx15UWfzDYA==",
+ "dependencies": {
+ "@ipld/dag-cbor": "^9.0.7",
+ "cborg": "^4.0.5",
+ "multiformats": "^13.0.0",
+ "varint": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/@ipld/dag-cbor": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/@ipld/dag-cbor/-/dag-cbor-9.2.2.tgz",
+ "integrity": "sha512-uIEOuruCqKTP50OBWwgz4Js2+LhiBQaxc57cnP71f45b1mHEAo1OCR1Zn/TbvSW/mV1x+JqhacIktkKyaYqhCw==",
+ "dependencies": {
+ "cborg": "^4.0.0",
+ "multiformats": "^13.1.0"
+ },
+ "engines": {
+ "node": ">=16.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/@ipld/dag-json": {
+ "version": "10.2.3",
+ "resolved": "https://registry.npmjs.org/@ipld/dag-json/-/dag-json-10.2.3.tgz",
+ "integrity": "sha512-itacv1j1hvYgLox2B42Msn70QLzcr0MEo5yGIENuw2SM/lQzq9bmBiMky+kDsIrsqqblKTXcHBZnnmK7D4a6ZQ==",
+ "dependencies": {
+ "cborg": "^4.0.0",
+ "multiformats": "^13.1.0"
+ },
+ "engines": {
+ "node": ">=16.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/@ipld/dag-pb": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/@ipld/dag-pb/-/dag-pb-4.1.3.tgz",
+ "integrity": "sha512-ueULCaaSCcD+dQga6nKiRr+RSeVgdiYiEPKVUu5iQMNYDN+9osd0KpR3UDd9uQQ+6RWuv9L34SchfEwj7YIbOA==",
+ "dependencies": {
+ "multiformats": "^13.1.0"
+ },
+ "engines": {
+ "node": ">=16.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/@ipld/unixfs": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@ipld/unixfs/-/unixfs-3.0.0.tgz",
+ "integrity": "sha512-Tj3/BPOlnemcZQ2ETIZAO8hqAs9KNzWyX5J9+JCL9jDwvYwjxeYjqJ3v+9DusNvTBmJhZnGVP6ijUHrsuOLp+g==",
+ "dependencies": {
+ "@ipld/dag-pb": "^4.0.0",
+ "@multiformats/murmur3": "^2.1.3",
+ "@perma/map": "^1.0.2",
+ "actor": "^2.3.1",
+ "multiformats": "^13.0.1",
+ "protobufjs": "^7.1.2",
+ "rabin-rs": "^2.1.0"
+ }
+ },
+ "node_modules/@itk-wasm/cuberille": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/@itk-wasm/cuberille/-/cuberille-0.1.0.tgz",
+ "integrity": "sha512-ftbGcnMkEBmIDO2s95AJFXEL9DwnR0XtaH0I0+mAdHo/JggNw5/gKbViGod7TDwm+9Y+ZRXqBaCjGc6372bgWw==",
+ "dependencies": {
+ "itk-wasm": "1.0.0-b.184"
+ }
+ },
+ "node_modules/@itk-wasm/dam": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@itk-wasm/dam/-/dam-1.1.1.tgz",
+ "integrity": "sha512-7+9L3lrLMKF4y6B6qjs8GqfbpxT0waOJUM14NdMNEA6M+BoBS8fdHREhQHo2s7QMA5O7I+Jv7m+dyqlisGnbdQ==",
+ "dependencies": {
+ "axios": "^1.4.0",
+ "commander": "^10.0.1",
+ "decompress": "^4.2.1",
+ "files-from-path": "^1.0.0",
+ "ipfs-car": "^1.0.0",
+ "tar": "^6.1.13"
+ },
+ "bin": {
+ "dam": "cli.js"
+ }
+ },
+ "node_modules/@itk-wasm/dam/node_modules/commander": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/@lukeed/csprng": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz",
@@ -427,6 +600,56 @@
"node": ">=8"
}
},
+ "node_modules/@multiformats/blake2": {
+ "version": "1.0.13",
+ "resolved": "https://registry.npmjs.org/@multiformats/blake2/-/blake2-1.0.13.tgz",
+ "integrity": "sha512-T1Kzya0wjj85CaVeRSpJ858EnSvW1pw94GSitxYf84VsNdv5XYbJ6QG8y26Ft1bVALzrUCmqkQrR53QHSyu6RA==",
+ "dependencies": {
+ "blakejs": "^1.1.1",
+ "multiformats": "^9.5.4"
+ }
+ },
+ "node_modules/@multiformats/blake2/node_modules/multiformats": {
+ "version": "9.9.0",
+ "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz",
+ "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="
+ },
+ "node_modules/@multiformats/murmur3": {
+ "version": "2.1.8",
+ "resolved": "https://registry.npmjs.org/@multiformats/murmur3/-/murmur3-2.1.8.tgz",
+ "integrity": "sha512-6vId1C46ra3R1sbJUOFCZnsUIveR9oF20yhPmAFxPm0JfrX3/ZRCgP3YDrBzlGoEppOXnA9czHeYc0T9mB6hbA==",
+ "dependencies": {
+ "multiformats": "^13.0.0",
+ "murmurhash3js-revisited": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/@multiformats/sha3": {
+ "version": "2.0.17",
+ "resolved": "https://registry.npmjs.org/@multiformats/sha3/-/sha3-2.0.17.tgz",
+ "integrity": "sha512-7ik6pk178qLO2cpNucgf48UnAOBMkq/2H92DP4SprZOJqM9zqbVaKS7XyYW6UvhRsDJ3wi921fYv1ihTtQHLtA==",
+ "dependencies": {
+ "js-sha3": "^0.8.0",
+ "multiformats": "^9.5.4"
+ }
+ },
+ "node_modules/@multiformats/sha3/node_modules/multiformats": {
+ "version": "9.9.0",
+ "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz",
+ "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="
+ },
+ "node_modules/@niivue/cbor-loader": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@niivue/cbor-loader/-/cbor-loader-1.0.0.tgz",
+ "integrity": "sha512-56YWElTO6NT8EFa9KQ6TlMq393D8hLAAecAS9ACa3MKFd50UkY70eUn0k7P/Vyv4itQin7D6b2ZUaJ4dhK5kUg==",
+ "dependencies": {
+ "cbor-x": "^1.6.0",
+ "nifti-reader-js": "^0.6.8"
+ }
+ },
"node_modules/@niivue/niimath": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@niivue/niimath/-/niimath-0.1.1.tgz",
@@ -452,6 +675,69 @@
"@rollup/rollup-linux-x64-gnu": "^4.18.1"
}
},
+ "node_modules/@perma/map": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@perma/map/-/map-1.0.3.tgz",
+ "integrity": "sha512-Bf5njk0fnJGTFE2ETntq0N1oJ6YdCPIpTDn3R3KYZJQdeYSOCNL7mBrFlGnbqav8YQhJA/p81pvHINX9vAtHkQ==",
+ "dependencies": {
+ "@multiformats/murmur3": "^2.1.0",
+ "murmurhash3js-revisited": "^3.0.0"
+ }
+ },
+ "node_modules/@protobufjs/aspromise": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
+ "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="
+ },
+ "node_modules/@protobufjs/base64": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
+ "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="
+ },
+ "node_modules/@protobufjs/codegen": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
+ "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="
+ },
+ "node_modules/@protobufjs/eventemitter": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
+ "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="
+ },
+ "node_modules/@protobufjs/fetch": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
+ "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.1",
+ "@protobufjs/inquire": "^1.1.0"
+ }
+ },
+ "node_modules/@protobufjs/float": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
+ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="
+ },
+ "node_modules/@protobufjs/inquire": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
+ "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="
+ },
+ "node_modules/@protobufjs/path": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
+ "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="
+ },
+ "node_modules/@protobufjs/pool": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
+ "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="
+ },
+ "node_modules/@protobufjs/utf8": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
+ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="
+ },
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.21.0",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.21.0.tgz",
@@ -780,6 +1066,16 @@
"@tensorflow/tfjs-core": "4.19.0"
}
},
+ "node_modules/@thewtex/zstddec": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@thewtex/zstddec/-/zstddec-0.2.1.tgz",
+ "integrity": "sha512-1yTu7m/qU1nsJy4mCZAB3GAhczsClhw+WIXK0oe598eHcvefH16WLOYN4Uko7K2/Ttz9KEBvvT7WFrZD41ShgA=="
+ },
+ "node_modules/@types/emscripten": {
+ "version": "1.39.13",
+ "resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-1.39.13.tgz",
+ "integrity": "sha512-cFq+fO/isvhvmuP/+Sl4K4jtU6E23DoivtbO4r50e3odaxAiVdbfSYRDdJ4gCdxx+3aRjhphS5ZMwIH4hFy/Cw=="
+ },
"node_modules/@types/estree": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
@@ -832,11 +1128,42 @@
"node": ">=10"
}
},
+ "node_modules/@web3-storage/car-block-validator": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@web3-storage/car-block-validator/-/car-block-validator-1.2.0.tgz",
+ "integrity": "sha512-KKQ/M5WtpH/JlkX+bQYKzdG4azmSF495T7vpewje2xh7MBh1d94/BLblxCcLM/larWvXDxOkbAyTTdlECAAuUw==",
+ "dependencies": {
+ "@multiformats/blake2": "^1.0.13",
+ "@multiformats/murmur3": "^1.1.3",
+ "@multiformats/sha3": "^2.0.15",
+ "multiformats": "9.9.0",
+ "uint8arrays": "^3.1.1"
+ }
+ },
+ "node_modules/@web3-storage/car-block-validator/node_modules/@multiformats/murmur3": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@multiformats/murmur3/-/murmur3-1.1.3.tgz",
+ "integrity": "sha512-wAPLUErGR8g6Lt+bAZn6218k9YQPym+sjszsXL6o4zfxbA22P+gxWZuuD9wDbwL55xrKO5idpcuQUX7/E3oHcw==",
+ "dependencies": {
+ "multiformats": "^9.5.4",
+ "murmurhash3js-revisited": "^3.0.0"
+ }
+ },
+ "node_modules/@web3-storage/car-block-validator/node_modules/multiformats": {
+ "version": "9.9.0",
+ "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz",
+ "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="
+ },
"node_modules/@webgpu/types": {
"version": "0.1.38",
"resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.38.tgz",
"integrity": "sha512-7LrhVKz2PRh+DD7+S+PVaFd5HxaWQvoMqBbsV9fNJO1pjUs1P8bM2vQVNfk+3URTqbuTI7gkXi0rfsN0IadoBA=="
},
+ "node_modules/actor": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/actor/-/actor-2.3.1.tgz",
+ "integrity": "sha512-ST/3wnvcP2tKDXnum7nLCLXm+/rsf8vPocXH2Fre6D8FQwNkGDd4JEitBlXj007VQJfiGYRQvXqwOBZVi+JtRg=="
+ },
"node_modules/ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
@@ -880,6 +1207,149 @@
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
+ "node_modules/axios": {
+ "version": "1.7.8",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.8.tgz",
+ "integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/bl": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
+ "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==",
+ "dependencies": {
+ "readable-stream": "^2.3.5",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/blakejs": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz",
+ "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ=="
+ },
+ "node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "node_modules/buffer-alloc": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
+ "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
+ "dependencies": {
+ "buffer-alloc-unsafe": "^1.1.0",
+ "buffer-fill": "^1.0.0"
+ }
+ },
+ "node_modules/buffer-alloc-unsafe": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
+ "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg=="
+ },
+ "node_modules/buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/buffer-fill": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
+ "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ=="
+ },
+ "node_modules/cbor-extract": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/cbor-extract/-/cbor-extract-2.2.0.tgz",
+ "integrity": "sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==",
+ "hasInstallScript": true,
+ "optional": true,
+ "dependencies": {
+ "node-gyp-build-optional-packages": "5.1.1"
+ },
+ "bin": {
+ "download-cbor-prebuilds": "bin/download-prebuilds.js"
+ },
+ "optionalDependencies": {
+ "@cbor-extract/cbor-extract-darwin-arm64": "2.2.0",
+ "@cbor-extract/cbor-extract-darwin-x64": "2.2.0",
+ "@cbor-extract/cbor-extract-linux-arm": "2.2.0",
+ "@cbor-extract/cbor-extract-linux-arm64": "2.2.0",
+ "@cbor-extract/cbor-extract-linux-x64": "2.2.0",
+ "@cbor-extract/cbor-extract-win32-x64": "2.2.0"
+ }
+ },
+ "node_modules/cbor-x": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/cbor-x/-/cbor-x-1.6.0.tgz",
+ "integrity": "sha512-0kareyRwHSkL6ws5VXHEf8uY1liitysCVJjlmhaLG+IXLqhSaOO+t63coaso7yjwEzWZzLy8fJo06gZDVQM9Qg==",
+ "optionalDependencies": {
+ "cbor-extract": "^2.2.0"
+ }
+ },
+ "node_modules/cborg": {
+ "version": "4.2.6",
+ "resolved": "https://registry.npmjs.org/cborg/-/cborg-4.2.6.tgz",
+ "integrity": "sha512-77vo4KlSwfjCIXcyZUVei4l2gdjesSCeYSx4U/Upwix7pcWZq8uw21sVRpjwn7mjEi//ieJPTj1MRWDHmud1Rg==",
+ "bin": {
+ "cborg": "lib/bin.js"
+ }
+ },
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -895,6 +1365,14 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
+ "node_modules/chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/cliui": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
@@ -932,6 +1410,11 @@
"node": ">= 0.8"
}
},
+ "node_modules/comlink": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/comlink/-/comlink-4.4.2.tgz",
+ "integrity": "sha512-OxGdvBmJuNKSCMO4NTl1L47VRp6xn2wG4F/2hYzB6tiCb709otOxtEYCSvK80PtjODfXXZu8ds+Nw5kVCjqd2g=="
+ },
"node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -947,6 +1430,11 @@
"url": "https://opencollective.com/core-js"
}
},
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
+ },
"node_modules/cssfilter": {
"version": "0.0.10",
"resolved": "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz",
@@ -964,6 +1452,95 @@
"xss": "1.0.14"
}
},
+ "node_modules/decompress": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz",
+ "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==",
+ "dependencies": {
+ "decompress-tar": "^4.0.0",
+ "decompress-tarbz2": "^4.0.0",
+ "decompress-targz": "^4.0.0",
+ "decompress-unzip": "^4.0.1",
+ "graceful-fs": "^4.1.10",
+ "make-dir": "^1.0.0",
+ "pify": "^2.3.0",
+ "strip-dirs": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-tar": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz",
+ "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==",
+ "dependencies": {
+ "file-type": "^5.2.0",
+ "is-stream": "^1.1.0",
+ "tar-stream": "^1.5.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-tarbz2": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz",
+ "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==",
+ "dependencies": {
+ "decompress-tar": "^4.1.0",
+ "file-type": "^6.1.0",
+ "is-stream": "^1.1.0",
+ "seek-bzip": "^1.0.5",
+ "unbzip2-stream": "^1.0.9"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-tarbz2/node_modules/file-type": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz",
+ "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-targz": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz",
+ "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==",
+ "dependencies": {
+ "decompress-tar": "^4.1.1",
+ "file-type": "^5.2.0",
+ "is-stream": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-unzip": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz",
+ "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==",
+ "dependencies": {
+ "file-type": "^3.8.0",
+ "get-stream": "^2.2.0",
+ "pify": "^2.3.0",
+ "yauzl": "^2.4.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-unzip/node_modules/file-type": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
+ "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
@@ -972,11 +1549,28 @@
"node": ">=0.4.0"
}
},
+ "node_modules/detect-libc": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
+ "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
+ "optional": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
+ "node_modules/end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
"node_modules/esbuild": {
"version": "0.21.5",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
@@ -1024,11 +1618,62 @@
"node": ">=6"
}
},
+ "node_modules/eventemitter3": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
+ "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="
+ },
+ "node_modules/fd-slicer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+ "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
+ "dependencies": {
+ "pend": "~1.2.0"
+ }
+ },
"node_modules/fflate": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
"integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A=="
},
+ "node_modules/file-type": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
+ "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/files-from-path": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/files-from-path/-/files-from-path-1.1.1.tgz",
+ "integrity": "sha512-M2JDH/0gHqIsdwTnp8IBMWEYUUiHe9ei0ZMTXLxqKFcGxJF4Ki+nicw2k8HP5KGEzPLTyJ81XwLmP8l8rKa6qg==",
+ "dependencies": {
+ "graceful-fs": "^4.2.10"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.9",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+ "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
"node_modules/form-data": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
@@ -1042,6 +1687,51 @@
"node": ">= 6"
}
},
+ "node_modules/fs-constants": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
+ },
+ "node_modules/fs-extra": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
+ "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
+ "node_modules/fs-minipass": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/fs-minipass/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
+ },
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -1065,11 +1755,64 @@
"node": "6.* || 8.* || >= 10.*"
}
},
+ "node_modules/get-stream": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
+ "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==",
+ "dependencies": {
+ "object-assign": "^4.0.1",
+ "pinkie-promise": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/gl-matrix": {
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/gl-matrix/-/gl-matrix-3.4.3.tgz",
"integrity": "sha512-wcCp8vu8FT22BnvKVPjXa/ICBWRq/zjFfdofZy1WSpQZpphblv12/bOQLBC1rMM7SGOFS9ltVmKOHil5+Ml7gA=="
},
+ "node_modules/glob": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+ "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
+ },
+ "node_modules/hamt-sharding": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/hamt-sharding/-/hamt-sharding-3.0.6.tgz",
+ "integrity": "sha512-nZeamxfymIWLpVcAN0CRrb7uVq3hCOGj9IcL6NMA6VVCVWqj+h9Jo/SmaWuS92AEDf1thmHsM5D5c70hM3j2Tg==",
+ "dependencies": {
+ "sparse-array": "^1.3.1",
+ "uint8arrays": "^5.0.1"
+ }
+ },
+ "node_modules/hamt-sharding/node_modules/uint8arrays": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.1.0.tgz",
+ "integrity": "sha512-vA6nFepEmlSKkMBnLBaUMVvAC4G3CTmO58C12y4sq6WPDOR7mOFYOi7GlrQ4djeSbP6JG9Pv9tJDM97PedRSww==",
+ "dependencies": {
+ "multiformats": "^13.0.0"
+ }
+ },
"node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -1078,6 +1821,111 @@
"node": ">=8"
}
},
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "node_modules/interface-blockstore": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/interface-blockstore/-/interface-blockstore-5.3.1.tgz",
+ "integrity": "sha512-nhgrQnz6yUQEqxTFLhlOBurQOy5lWlwCpgFmZ3GTObTVTQS9RZjK/JTozY6ty9uz2lZs7VFJSqwjWAltorJ4Vw==",
+ "dependencies": {
+ "interface-store": "^6.0.0",
+ "multiformats": "^13.2.3"
+ }
+ },
+ "node_modules/interface-store": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/interface-store/-/interface-store-6.0.2.tgz",
+ "integrity": "sha512-KSFCXtBlNoG0hzwNa0RmhHtrdhzexp+S+UY2s0rWTBJyfdEIgn6i6Zl9otVqrcFYbYrneBT7hbmHQ8gE0C3umA=="
+ },
+ "node_modules/ipfs-car": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/ipfs-car/-/ipfs-car-1.2.0.tgz",
+ "integrity": "sha512-A++1UesxqwfNv14NmFxr4MHi+vD9rR6SWr87MU9o0315Mzqys48pEefL8rlCAA9cw2qKYeT/ZPYVtqIMAr6U1Q==",
+ "dependencies": {
+ "@ipld/car": "^5.1.0",
+ "@ipld/dag-cbor": "^9.0.0",
+ "@ipld/dag-json": "^10.0.1",
+ "@ipld/dag-pb": "^4.0.2",
+ "@ipld/unixfs": "^3.0.0",
+ "@web3-storage/car-block-validator": "^1.0.1",
+ "files-from-path": "^1.0.0",
+ "ipfs-unixfs-exporter": "^13.0.1",
+ "multiformats": "^13.0.1",
+ "sade": "^1.8.1",
+ "varint": "^6.0.0"
+ },
+ "bin": {
+ "🚘": "bin.js",
+ "ipfs-car": "bin.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/ipfs-unixfs": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/ipfs-unixfs/-/ipfs-unixfs-11.2.0.tgz",
+ "integrity": "sha512-J8FN1qM5nfrDo8sQKQwfj0+brTg1uBfZK2vY9hxci33lcl3BFrsELS9+1+4q/8tO1ASKfxZO8W3Pi2O4sVX2Lg==",
+ "dependencies": {
+ "protons-runtime": "^5.5.0",
+ "uint8arraylist": "^2.4.8"
+ }
+ },
+ "node_modules/ipfs-unixfs-exporter": {
+ "version": "13.6.1",
+ "resolved": "https://registry.npmjs.org/ipfs-unixfs-exporter/-/ipfs-unixfs-exporter-13.6.1.tgz",
+ "integrity": "sha512-pYPI4oBTWao2//sFzAL0pURyojn79q/u5BuK6L5/nVbVUQVw6DcVP5uB1ySdWlTM2H+0Zlhp9+OL9aJBRIICpg==",
+ "dependencies": {
+ "@ipld/dag-cbor": "^9.2.1",
+ "@ipld/dag-json": "^10.2.2",
+ "@ipld/dag-pb": "^4.1.2",
+ "@multiformats/murmur3": "^2.1.8",
+ "hamt-sharding": "^3.0.6",
+ "interface-blockstore": "^5.3.0",
+ "ipfs-unixfs": "^11.0.0",
+ "it-filter": "^3.1.1",
+ "it-last": "^3.0.6",
+ "it-map": "^3.1.1",
+ "it-parallel": "^3.0.8",
+ "it-pipe": "^3.0.1",
+ "it-pushable": "^3.2.3",
+ "multiformats": "^13.2.3",
+ "p-queue": "^8.0.1",
+ "progress-events": "^1.0.1"
+ }
+ },
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
@@ -1086,16 +1934,188 @@
"node": ">=8"
}
},
+ "node_modules/is-natural-number": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz",
+ "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ=="
+ },
+ "node_modules/is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
+ },
+ "node_modules/it-filter": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/it-filter/-/it-filter-3.1.1.tgz",
+ "integrity": "sha512-TOXmVuaSkxlLp2hXKoMTra0WMZMKVFxE3vSsbIA+PbADNCBAHhjJ/lM31vBOUTddHMO34Ku++vU8T9PLlBxQtg==",
+ "dependencies": {
+ "it-peekable": "^3.0.0"
+ }
+ },
+ "node_modules/it-last": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/it-last/-/it-last-3.0.6.tgz",
+ "integrity": "sha512-M4/get95O85u2vWvWQinF8SJUc/RPC5bWTveBTYXvlP2q5TF9Y+QhT3nz+CRCyS2YEc66VJkyl/da6WrJ0wKhw=="
+ },
+ "node_modules/it-map": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/it-map/-/it-map-3.1.1.tgz",
+ "integrity": "sha512-9bCSwKD1yN1wCOgJ9UOl+46NQtdatosPWzxxUk2NdTLwRPXLh+L7iwCC9QKsbgM60RQxT/nH8bKMqm3H/o8IHQ==",
+ "dependencies": {
+ "it-peekable": "^3.0.0"
+ }
+ },
+ "node_modules/it-merge": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/it-merge/-/it-merge-3.0.5.tgz",
+ "integrity": "sha512-2l7+mPf85pyRF5pqi0dKcA54E5Jm/2FyY5GsOaN51Ta0ipC7YZ3szuAsH8wOoB6eKY4XsU4k2X+mzPmFBMayEA==",
+ "dependencies": {
+ "it-pushable": "^3.2.3"
+ }
+ },
+ "node_modules/it-parallel": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/it-parallel/-/it-parallel-3.0.8.tgz",
+ "integrity": "sha512-URLhs6eG4Hdr4OdvgBBPDzOjBeSSmI+Kqex2rv/aAyYClME26RYHirLVhZsZP5M+ZP6M34iRlXk8Wlqtezuqpg==",
+ "dependencies": {
+ "p-defer": "^4.0.1"
+ }
+ },
+ "node_modules/it-peekable": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/it-peekable/-/it-peekable-3.0.5.tgz",
+ "integrity": "sha512-JWQOGMt6rKiPcY30zUVMR4g6YxkpueTwHVE7CMs/aGqCf4OydM6w+7ZM3PvmO1e0TocjuR4aL8xyZWR46cTqCQ=="
+ },
+ "node_modules/it-pipe": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/it-pipe/-/it-pipe-3.0.1.tgz",
+ "integrity": "sha512-sIoNrQl1qSRg2seYSBH/3QxWhJFn9PKYvOf/bHdtCBF0bnghey44VyASsWzn5dAx0DCDDABq1hZIuzKmtBZmKA==",
+ "dependencies": {
+ "it-merge": "^3.0.0",
+ "it-pushable": "^3.1.2",
+ "it-stream-types": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16.0.0",
+ "npm": ">=7.0.0"
+ }
+ },
+ "node_modules/it-pushable": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/it-pushable/-/it-pushable-3.2.3.tgz",
+ "integrity": "sha512-gzYnXYK8Y5t5b/BnJUr7glfQLO4U5vyb05gPx/TyTw+4Bv1zM9gFk4YsOrnulWefMewlphCjKkakFvj1y99Tcg==",
+ "dependencies": {
+ "p-defer": "^4.0.0"
+ }
+ },
+ "node_modules/it-stream-types": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/it-stream-types/-/it-stream-types-2.0.2.tgz",
+ "integrity": "sha512-Rz/DEZ6Byn/r9+/SBCuJhpPATDF9D+dz5pbgSUyBsCDtza6wtNATrz/jz1gDyNanC3XdLboriHnOC925bZRBww=="
+ },
+ "node_modules/itk-wasm": {
+ "version": "1.0.0-b.184",
+ "resolved": "https://registry.npmjs.org/itk-wasm/-/itk-wasm-1.0.0-b.184.tgz",
+ "integrity": "sha512-wmRpOvbG4aPRf51B/VsVj0pZtGmgmI5U8sorYIVW01RQIFqybXoBdHK6AR4d/Wb3MZfFgtWHi++MnpljLORhkg==",
+ "dependencies": {
+ "@itk-wasm/dam": "^1.1.1",
+ "@thewtex/zstddec": "^0.2.1",
+ "@types/emscripten": "^1.39.10",
+ "axios": "^1.6.2",
+ "chalk": "^5.3.0",
+ "comlink": "^4.4.1",
+ "commander": "^11.1.0",
+ "fs-extra": "^11.2.0",
+ "glob": "^8.1.0",
+ "markdown-table": "^3.0.3",
+ "mime-types": "^2.1.35",
+ "wasm-feature-detect": "^1.6.1"
+ },
+ "bin": {
+ "itk-wasm": "src/itk-wasm-cli.js"
+ }
+ },
+ "node_modules/itk-wasm/node_modules/chalk": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+ "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/itk-wasm/node_modules/commander": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
+ "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
+ "engines": {
+ "node": ">=16"
+ }
+ },
"node_modules/jpeg-lossless-decoder-js": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/jpeg-lossless-decoder-js/-/jpeg-lossless-decoder-js-2.0.7.tgz",
"integrity": "sha512-tbZlhFkKmx+JaqVMkq47SKWGuXLkIaV8fTbnhO39dYEnQrSShLGuLCGb0n6ntXjtmk6oAWGiIriWOLwj9od0yQ=="
},
+ "node_modules/js-sha3": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz",
+ "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q=="
+ },
+ "node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
"node_modules/long": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
"integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA=="
},
+ "node_modules/make-dir": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
+ "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
+ "dependencies": {
+ "pify": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/make-dir/node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/markdown-table": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz",
+ "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@@ -1115,6 +2135,80 @@
"node": ">= 0.6"
}
},
+ "node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minizlib": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "dependencies": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/minizlib/node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/mri": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
+ "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/multiformats": {
+ "version": "13.3.1",
+ "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-13.3.1.tgz",
+ "integrity": "sha512-QxowxTNwJ3r5RMctoGA5p13w5RbRT2QDkoM+yFlqfLiioBp78nhDjnRLvmSBI9+KAqN4VdgOVWM9c0CHd86m3g=="
+ },
+ "node_modules/murmurhash3js-revisited": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/murmurhash3js-revisited/-/murmurhash3js-revisited-3.0.0.tgz",
+ "integrity": "sha512-/sF3ee6zvScXMb1XFJ8gDsSnY+X8PbOyjIuBhtgis10W2Jx4ZjIhikUCIF9c4gpJxVnQIsPAFrSwTCuAjicP6g==",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
"node_modules/nanoid": {
"version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
@@ -1161,11 +2255,83 @@
}
}
},
+ "node_modules/node-gyp-build-optional-packages": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz",
+ "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==",
+ "optional": true,
+ "dependencies": {
+ "detect-libc": "^2.0.1"
+ },
+ "bin": {
+ "node-gyp-build-optional-packages": "bin.js",
+ "node-gyp-build-optional-packages-optional": "optional.js",
+ "node-gyp-build-optional-packages-test": "build-test.js"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/p-defer": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-4.0.1.tgz",
+ "integrity": "sha512-Mr5KC5efvAK5VUptYEIopP1bakB85k2IWXaRC0rsh1uwn1L6M0LVml8OIQ4Gudg4oyZakf7FmeRLkMMtZW1i5A==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-queue": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.0.1.tgz",
+ "integrity": "sha512-NXzu9aQJTAzbBqOt2hwsR63ea7yvxJc0PwN/zobNAudYfb1B7R08SzB4TsLeSbUCuG467NhnoT0oO6w1qRO+BA==",
+ "dependencies": {
+ "eventemitter3": "^5.0.1",
+ "p-timeout": "^6.1.2"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-timeout": {
+ "version": "6.1.3",
+ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.3.tgz",
+ "integrity": "sha512-UJUyfKbwvr/uZSV6btANfb+0t/mOhKV/KXcCUTp8FcQI+v/0d+wXqH4htrW0E4rR6WiEO/EPvUFiV9D5OI4vlw==",
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/pako": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz",
"integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug=="
},
+ "node_modules/pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="
+ },
"node_modules/picocolors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
@@ -1173,6 +2339,33 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==",
+ "dependencies": {
+ "pinkie": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/postcss": {
"version": "8.4.41",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz",
@@ -1202,6 +2395,99 @@
"node": "^10 || ^12 || >=14"
}
},
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
+ },
+ "node_modules/progress-events": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/progress-events/-/progress-events-1.0.1.tgz",
+ "integrity": "sha512-MOzLIwhpt64KIVN64h1MwdKWiyKFNc/S6BoYKPIVUHFg0/eIEyBulhWCgn678v/4c0ri3FdGuzXymNCv02MUIw=="
+ },
+ "node_modules/protobufjs": {
+ "version": "7.4.0",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz",
+ "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==",
+ "hasInstallScript": true,
+ "dependencies": {
+ "@protobufjs/aspromise": "^1.1.2",
+ "@protobufjs/base64": "^1.1.2",
+ "@protobufjs/codegen": "^2.0.4",
+ "@protobufjs/eventemitter": "^1.1.0",
+ "@protobufjs/fetch": "^1.1.0",
+ "@protobufjs/float": "^1.0.2",
+ "@protobufjs/inquire": "^1.1.0",
+ "@protobufjs/path": "^1.1.2",
+ "@protobufjs/pool": "^1.1.0",
+ "@protobufjs/utf8": "^1.1.0",
+ "@types/node": ">=13.7.0",
+ "long": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/protobufjs/node_modules/long": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
+ "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q=="
+ },
+ "node_modules/protons-runtime": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/protons-runtime/-/protons-runtime-5.5.0.tgz",
+ "integrity": "sha512-EsALjF9QsrEk6gbCx3lmfHxVN0ah7nG3cY7GySD4xf4g8cr7g543zB88Foh897Sr1RQJ9yDCUsoT1i1H/cVUFA==",
+ "dependencies": {
+ "uint8-varint": "^2.0.2",
+ "uint8arraylist": "^2.4.3",
+ "uint8arrays": "^5.0.1"
+ }
+ },
+ "node_modules/protons-runtime/node_modules/uint8arrays": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.1.0.tgz",
+ "integrity": "sha512-vA6nFepEmlSKkMBnLBaUMVvAC4G3CTmO58C12y4sq6WPDOR7mOFYOi7GlrQ4djeSbP6JG9Pv9tJDM97PedRSww==",
+ "dependencies": {
+ "multiformats": "^13.0.0"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ },
+ "node_modules/rabin-rs": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/rabin-rs/-/rabin-rs-2.1.0.tgz",
+ "integrity": "sha512-5y72gAXPzIBsAMHcpxZP8eMDuDT98qMP1BqSDHRbHkJJXEgWIN1lA47LxUqzsK6jknOJtgfkQr9v+7qMlFDm6g=="
+ },
+ "node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/readable-stream/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "node_modules/readable-stream/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
"node_modules/regenerator-runtime": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
@@ -1259,6 +2545,17 @@
"tslib": "^2.1.0"
}
},
+ "node_modules/sade": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
+ "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
+ "dependencies": {
+ "mri": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -1283,6 +2580,18 @@
"resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz",
"integrity": "sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg=="
},
+ "node_modules/seek-bzip": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz",
+ "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==",
+ "dependencies": {
+ "commander": "^2.8.1"
+ },
+ "bin": {
+ "seek-bunzip": "bin/seek-bunzip",
+ "seek-table": "bin/seek-bzip-table"
+ }
+ },
"node_modules/source-map-js": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
@@ -1293,6 +2602,11 @@
"node": ">=0.10.0"
}
},
+ "node_modules/sparse-array": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/sparse-array/-/sparse-array-1.3.2.tgz",
+ "integrity": "sha512-ZT711fePGn3+kQyLuv1fpd3rNSkNF8vd5Kv2D+qnOANeyKs3fx6bUMGWRPvgTTcYV64QMqZKZwcuaQSP3AZ0tg=="
+ },
"node_modules/sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@@ -1330,6 +2644,14 @@
"node": ">=8"
}
},
+ "node_modules/strip-dirs": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz",
+ "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==",
+ "dependencies": {
+ "is-natural-number": "^4.0.1"
+ }
+ },
"node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -1341,6 +2663,49 @@
"node": ">=8"
}
},
+ "node_modules/tar": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
+ "dependencies": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^5.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/tar-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz",
+ "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==",
+ "dependencies": {
+ "bl": "^1.0.0",
+ "buffer-alloc": "^1.2.0",
+ "end-of-stream": "^1.0.0",
+ "fs-constants": "^1.0.0",
+ "readable-stream": "^2.3.0",
+ "to-buffer": "^1.1.1",
+ "xtend": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
+ },
+ "node_modules/to-buffer": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz",
+ "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg=="
+ },
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
@@ -1351,11 +2716,84 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
+ "node_modules/uint8-varint": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/uint8-varint/-/uint8-varint-2.0.4.tgz",
+ "integrity": "sha512-FwpTa7ZGA/f/EssWAb5/YV6pHgVF1fViKdW8cWaEarjB8t7NyofSWBdOTyFPaGuUG4gx3v1O3PQ8etsiOs3lcw==",
+ "dependencies": {
+ "uint8arraylist": "^2.0.0",
+ "uint8arrays": "^5.0.0"
+ }
+ },
+ "node_modules/uint8-varint/node_modules/uint8arrays": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.1.0.tgz",
+ "integrity": "sha512-vA6nFepEmlSKkMBnLBaUMVvAC4G3CTmO58C12y4sq6WPDOR7mOFYOi7GlrQ4djeSbP6JG9Pv9tJDM97PedRSww==",
+ "dependencies": {
+ "multiformats": "^13.0.0"
+ }
+ },
+ "node_modules/uint8arraylist": {
+ "version": "2.4.8",
+ "resolved": "https://registry.npmjs.org/uint8arraylist/-/uint8arraylist-2.4.8.tgz",
+ "integrity": "sha512-vc1PlGOzglLF0eae1M8mLRTBivsvrGsdmJ5RbK3e+QRvRLOZfZhQROTwH/OfyF3+ZVUg9/8hE8bmKP2CvP9quQ==",
+ "dependencies": {
+ "uint8arrays": "^5.0.1"
+ }
+ },
+ "node_modules/uint8arraylist/node_modules/uint8arrays": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-5.1.0.tgz",
+ "integrity": "sha512-vA6nFepEmlSKkMBnLBaUMVvAC4G3CTmO58C12y4sq6WPDOR7mOFYOi7GlrQ4djeSbP6JG9Pv9tJDM97PedRSww==",
+ "dependencies": {
+ "multiformats": "^13.0.0"
+ }
+ },
+ "node_modules/uint8arrays": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-3.1.1.tgz",
+ "integrity": "sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==",
+ "dependencies": {
+ "multiformats": "^9.4.2"
+ }
+ },
+ "node_modules/uint8arrays/node_modules/multiformats": {
+ "version": "9.9.0",
+ "resolved": "https://registry.npmjs.org/multiformats/-/multiformats-9.9.0.tgz",
+ "integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="
+ },
+ "node_modules/unbzip2-stream": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
+ "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
+ "dependencies": {
+ "buffer": "^5.2.1",
+ "through": "^2.3.8"
+ }
+ },
"node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
},
+ "node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+ },
+ "node_modules/varint": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz",
+ "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg=="
+ },
"node_modules/vite": {
"version": "5.4.2",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.2.tgz",
@@ -1416,6 +2854,11 @@
}
}
},
+ "node_modules/wasm-feature-detect": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/wasm-feature-detect/-/wasm-feature-detect-1.8.0.tgz",
+ "integrity": "sha512-zksaLKM2fVlnB5jQQDqKXXwYHLQUVH9es+5TOOHwGOVJOCeRBCiPjwSg+3tN2AdTCzjgli4jijCH290kXb/zWQ=="
+ },
"node_modules/webidl-conversions": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
@@ -1446,6 +2889,11 @@
"url": "https://github.com/chalk/wrap-ansi?sponsor=1"
}
},
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+ },
"node_modules/xss": {
"version": "1.0.14",
"resolved": "https://registry.npmjs.org/xss/-/xss-1.0.14.tgz",
@@ -1461,6 +2909,14 @@
"node": ">= 0.10.0"
}
},
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
@@ -1469,6 +2925,11 @@
"node": ">=10"
}
},
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
"node_modules/yargs": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
@@ -1493,6 +2954,15 @@
"engines": {
"node": ">=10"
}
+ },
+ "node_modules/yauzl": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
+ "dependencies": {
+ "buffer-crc32": "~0.2.3",
+ "fd-slicer": "~1.1.0"
+ }
}
}
}
diff --git a/package.json b/package.json
index 3a21cad..f9c2085 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,8 @@
"preview": "vite preview"
},
"dependencies": {
+ "@itk-wasm/cuberille": "^0.1.0",
+ "@niivue/cbor-loader": "^1.0.0",
"@niivue/niimath": "^0.1.1",
"@niivue/niivue": "^0.44.2",
"@tensorflow/tfjs": "^4.19.0",
diff --git a/vite.config.js b/vite.config.js
index 25e5b81..59f3ae4 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -1,16 +1,16 @@
-import { defineConfig } from 'vite'
+import { defineConfig } from "vite";
export default defineConfig({
// root: '.',
- base: './',
+ base: "./",
server: {
- open: 'index.html',
+ open: "index.html",
},
worker: {
- format: 'esm'
+ format: "esm",
},
// exclude @niivue/niimath from optimization
optimizeDeps: {
- exclude: ['@niivue/niimath']
- }
-})
\ No newline at end of file
+ exclude: ["@niivue/niimath", "@itk-wasm/cuberille"],
+ },
+});
From d43dbf4bc235c39345ef128dd1abcbe9cc334c4f Mon Sep 17 00:00:00 2001
From: neurolabusc
Date: Tue, 3 Dec 2024 09:17:08 -0500
Subject: [PATCH 02/12] Update cbor-loader
---
main.js | 63 +++++++++--------------------------------------
package-lock.json | 9 ++++---
package.json | 2 +-
3 files changed, 17 insertions(+), 57 deletions(-)
diff --git a/main.js b/main.js
index de9ef3f..e371845 100644
--- a/main.js
+++ b/main.js
@@ -226,67 +226,26 @@ async function main() {
}
};
applyBtn.onclick = async function () {
+ const volIdx = nv1.volumes.length - 1
const niiBuffer = await nv1.saveImage({
- volumeByIndex: nv1.volumes.length - 1,
+ volumeByIndex: volIdx,
}).buffer;
const niiBlob = new Blob([niiBuffer], { type: "application/octet-stream" });
const niiFile = new File([niiBlob], "input.nii");
- // get an ImageProcessor instance from niimath
- // so we can build up the operations we want to perform
- // based on the UI controls
- // let image = niimath.image(niiFile);
- // loadingCircle.classList.remove("hidden");
- // // initialize the operations object for the niimath mesh function
- // let ops = {
- // i: 0.5,
- // };
- // //const largestCheckValue = largestCheck.checked
- // if (largestCheck.checked) {
- // ops.l = 1;
- // }
- // let reduce = Math.min(Math.max(Number(shrinkPct.value) / 100, 0.01), 1);
- // ops.r = reduce;
- // let smooth = parseFloat(smoothSlide.value);
- // ops.s = smooth;
- // if (bubbleCheck.checked) {
- // ops.b = 1;
- // }
-
- // let hollowInt = Number(hollowSelect.value);
- // if (hollowInt < 0) {
- // // append the hollow operation to the image processor
- // // but dont run it yet.
- // image = image.hollow(0.5, hollowInt);
- // }
-
- // let closeFloat = Number(closeMM.value);
- // if (isFinite(closeFloat) && closeFloat > 0) {
- // // append the close operation to the image processor
- // // but dont run it yet.
- // image = image.close(0.5, closeFloat, 2 * closeFloat);
- // }
- // // add the mesh operations
- // image = image.mesh(ops);
- // console.log("niimath mesh operation", image.commands);
- const hdr = nv1.volumes[1].hdr;
- const img = nv1.volumes[1].img;
-
+ loadingCircle.classList.remove("hidden");
+ const hdr = nv1.volumes[volIdx].hdr;
+ const img = nv1.volumes[volIdx].img;
const itkImage = nii2iwi(hdr, img, false);
itkImage.size = itkImage.size.map(Number);
const { mesh } = await antiAliasCuberille(itkImage);
-
const niiMesh = iwm2meshCore(mesh);
- console.log(niiMesh);
- console.log(nv1);
-
- // finally, run the full set of operations
- // const outFile = await image.run("output.mz3");
- // const outFile = await image.run("output.nii");
- // const arrayBuffer = await outFile.arrayBuffer();
loadingCircle.classList.add("hidden");
- if (nv1.meshes.length > 0) nv1.removeMesh(nv1.meshes[0]);
- // await nv1.loadFromArrayBuffer(arrayBuffer, "output.mz3");
- // nv1.reverseFaces(0);
+ while (nv1.meshes.length > 0) {
+ nv1.removeMesh(nv1.meshes[0]);
+ }
+ const meshBuffer = NVMeshUtilities.createMZ3(niiMesh.positions, niiMesh.indices, false)
+ await nv1.loadFromArrayBuffer(meshBuffer, 'trefoil.mz3')
+ nv1.reverseFaces(0);
};
saveMeshBtn.onclick = function () {
if (nv1.meshes.length < 1) {
diff --git a/package-lock.json b/package-lock.json
index da662dd..2e300af 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,7 +9,7 @@
"version": "0.1.0",
"dependencies": {
"@itk-wasm/cuberille": "^0.1.0",
- "@niivue/cbor-loader": "^1.0.0",
+ "@niivue/cbor-loader": "^1.1.0",
"@niivue/niimath": "^0.1.1",
"@niivue/niivue": "^0.44.2",
"@tensorflow/tfjs": "^4.19.0",
@@ -642,9 +642,10 @@
"integrity": "sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg=="
},
"node_modules/@niivue/cbor-loader": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@niivue/cbor-loader/-/cbor-loader-1.0.0.tgz",
- "integrity": "sha512-56YWElTO6NT8EFa9KQ6TlMq393D8hLAAecAS9ACa3MKFd50UkY70eUn0k7P/Vyv4itQin7D6b2ZUaJ4dhK5kUg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@niivue/cbor-loader/-/cbor-loader-1.1.0.tgz",
+ "integrity": "sha512-ZRQmZlCn7GP98zo3y7WuxxwbhBSVf0u0Ri7h0VdQurRogcO2tSLjADarWebVFPq9w1vbXuvC2xkChsInZeNGvQ==",
+ "license": "BSD-2-Clause",
"dependencies": {
"cbor-x": "^1.6.0",
"nifti-reader-js": "^0.6.8"
diff --git a/package.json b/package.json
index f9c2085..edb2d49 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,7 @@
},
"dependencies": {
"@itk-wasm/cuberille": "^0.1.0",
- "@niivue/cbor-loader": "^1.0.0",
+ "@niivue/cbor-loader": "^1.1.0",
"@niivue/niimath": "^0.1.1",
"@niivue/niivue": "^0.44.2",
"@tensorflow/tfjs": "^4.19.0",
From a1e270ca913fe35026e05c101193cb9c563145b0 Mon Sep 17 00:00:00 2001
From: Matt McCormick
Date: Tue, 17 Dec 2024 23:46:30 -0500
Subject: [PATCH 03/12] Repair, smooth, and remesh
Make the mesh manifold and smoothed.
---
main.js | 16 ++++++++++----
package-lock.json | 54 +++++++++++++++++++++++++++++++++++++++++++++++
package.json | 1 +
vite.config.js | 2 +-
4 files changed, 68 insertions(+), 5 deletions(-)
diff --git a/main.js b/main.js
index e371845..bd0b565 100644
--- a/main.js
+++ b/main.js
@@ -5,6 +5,7 @@ import { inferenceModelsList, brainChopOpts } from "./brainchop-parameters.js";
import { isChrome, localSystemDetails } from "./brainchop-telemetry.js";
import MyWorker from "./brainchop-webworker.js?worker";
import { antiAliasCuberille } from "@itk-wasm/cuberille";
+import { repair, smoothRemesh } from "@itk-wasm/mesh-filters";
import { nii2iwi, iwm2meshCore } from "@niivue/cbor-loader";
async function main() {
@@ -237,15 +238,22 @@ async function main() {
const img = nv1.volumes[volIdx].img;
const itkImage = nii2iwi(hdr, img, false);
itkImage.size = itkImage.size.map(Number);
- const { mesh } = await antiAliasCuberille(itkImage);
- const niiMesh = iwm2meshCore(mesh);
+ const { mesh } = await antiAliasCuberille(itkImage, { noClosing: true });
+ const { outputMesh: repairedMesh } = await repair(mesh);
+ while (nv1.meshes.length > 0) {
+ nv1.removeMesh(nv1.meshes[0]);
+ }
+ const initialNiiMesh = iwm2meshCore(repairedMesh);
+ const initialNiiMeshBuffer = NVMeshUtilities.createMZ3(initialNiiMesh.positions, initialNiiMesh.indices, false)
+ await nv1.loadFromArrayBuffer(initialNiiMeshBuffer, 'trefoil.mz3')
+ const { outputMesh: smoothedMesh } = await smoothRemesh(repairedMesh, { newtonIterations: 1, numberPoints: 75 });
+ const niiMesh = iwm2meshCore(smoothedMesh);
loadingCircle.classList.add("hidden");
while (nv1.meshes.length > 0) {
nv1.removeMesh(nv1.meshes[0]);
}
- const meshBuffer = NVMeshUtilities.createMZ3(niiMesh.positions, niiMesh.indices, false)
+ const meshBuffer = NVMeshUtilities.createMZ3(niiMesh.positions, niiMesh.indices, false)
await nv1.loadFromArrayBuffer(meshBuffer, 'trefoil.mz3')
- nv1.reverseFaces(0);
};
saveMeshBtn.onclick = function () {
if (nv1.meshes.length < 1) {
diff --git a/package-lock.json b/package-lock.json
index 2e300af..12afb99 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
"version": "0.1.0",
"dependencies": {
"@itk-wasm/cuberille": "^0.1.0",
+ "@itk-wasm/mesh-filters": "^0.1.0",
"@niivue/cbor-loader": "^1.1.0",
"@niivue/niimath": "^0.1.1",
"@niivue/niivue": "^0.44.2",
@@ -581,6 +582,59 @@
"node": ">=14"
}
},
+ "node_modules/@itk-wasm/mesh-filters": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/@itk-wasm/mesh-filters/-/mesh-filters-0.1.0.tgz",
+ "integrity": "sha512-6ugGkzU1wrnyTPJPItyTfDNfIxkQyTfCCIh2d4czb5esflDV09UZn4+mnSK5Rz9/bp1Q5fZrNnyEv+ocDJjrsg==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "itk-wasm": "1.0.0-b.183"
+ }
+ },
+ "node_modules/@itk-wasm/mesh-filters/node_modules/chalk": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+ "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@itk-wasm/mesh-filters/node_modules/commander": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
+ "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@itk-wasm/mesh-filters/node_modules/itk-wasm": {
+ "version": "1.0.0-b.183",
+ "resolved": "https://registry.npmjs.org/itk-wasm/-/itk-wasm-1.0.0-b.183.tgz",
+ "integrity": "sha512-B3/W8MqKZ3KOl+96W1CvgAJjOmlqsac7iaEooP98k3yzH04oAsuyh3xZooOxDVNCucEdIj2Zt7lALbdFv+BoPQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@itk-wasm/dam": "^1.1.1",
+ "@thewtex/zstddec": "^0.2.1",
+ "@types/emscripten": "^1.39.10",
+ "axios": "^1.6.2",
+ "chalk": "^5.3.0",
+ "comlink": "^4.4.1",
+ "commander": "^11.1.0",
+ "fs-extra": "^11.2.0",
+ "glob": "^8.1.0",
+ "markdown-table": "^3.0.3",
+ "mime-types": "^2.1.35",
+ "wasm-feature-detect": "^1.6.1"
+ },
+ "bin": {
+ "itk-wasm": "src/itk-wasm-cli.js"
+ }
+ },
"node_modules/@lukeed/csprng": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz",
diff --git a/package.json b/package.json
index edb2d49..7cbcfa2 100644
--- a/package.json
+++ b/package.json
@@ -10,6 +10,7 @@
},
"dependencies": {
"@itk-wasm/cuberille": "^0.1.0",
+ "@itk-wasm/mesh-filters": "^0.1.0",
"@niivue/cbor-loader": "^1.1.0",
"@niivue/niimath": "^0.1.1",
"@niivue/niivue": "^0.44.2",
diff --git a/vite.config.js b/vite.config.js
index 59f3ae4..d1c22a5 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -11,6 +11,6 @@ export default defineConfig({
},
// exclude @niivue/niimath from optimization
optimizeDeps: {
- exclude: ["@niivue/niimath", "@itk-wasm/cuberille"],
+ exclude: ["@niivue/niimath", "@itk-wasm/cuberille", "@itk-wasm/mesh-filters"],
},
});
From 258d3d349b5ff2b52cd4d049f33c2e253f9fe7ae Mon Sep 17 00:00:00 2001
From: Matt McCormick
Date: Tue, 17 Dec 2024 23:54:54 -0500
Subject: [PATCH 04/12] README documentation updates
---
README.md | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index 787ab78..fbcdf15 100644
--- a/README.md
+++ b/README.md
@@ -9,23 +9,23 @@ This is an extension of [brainchop](https://github.com/neuroneural/brainchop) th
1. Open the [live demo](https://niivue.github.io/brain2print/).
2. **Option 1** The web page automatically loads with a default T1 MRI scan. If you want to use this scan, go to step 5.
3. **Option 2** If your T1 MRI scan is in NIfTI format, drag and drop the file onto the web page.
-4. **Option 3** If your image is in DICOM format, it may load if you drag and drop the files. If this fails, convert your images with dcm2niix.
+4. **Option 3** If your image is in DICOM format, it may load if you drag and drop the files. If this fails, convert your images with [dcm2niix](https://github.com/rordenlab/dcm2niix).
5. Segment your brain scan by choosing a model from the `Segmentation Model` pull-down menu. Not all models with with all graphics cards. The `Tissue GWM (High Acc, Low Mem)` is a good starting point. Hopefully, it will accurately segment your brain into gray matter, white matter and cerebral spinal fluid.
6. Press the `Create Mesh` button and select your preferred settings:
- ![settings dialog](Settings.png)
- - [Closing](https://en.wikipedia.org/wiki/Closing_(morphology)) removes small crevices and cavities in your mesh which can plague printing.
- - Fill bubbles will remove any cavities, this includes large cavities for example the ventricles for a brain scan.
+ - Fill bubbles will remove any cavities. This includes large cavities such as the brain's ventricles.
- The `Largest cluster only` will only extract a single mesh.
- - You can choose `Smoothing` to make the surfaces less jagged (note this can create self intersecting triangles that can confound some printers).
- - You can choose to `Simplify` [reduce the number of triangles](https://github.com/sp4cerat/Fast-Quadric-Mesh-Simplification) to create smaller files (note this can create self intersecting triangles that can confound some printers).
+ - You can choose `Smoothing` to make the surfaces less jagged at the expense of computation time.
+ - You can choose to `Simplify` to reduce the number of triangles and create smaller files.
+
7. Once you have set your preferences, press `Apply`.
8. You will see the mesh appear and can interactively view it. If you are unhappy with the result, repeat step 6 with different settings. If you want to print the results, press the `Save Mesh` button.
## How it Works
-This web application uses some of the latest browser technologies that allow the tissue segmentation model to run on your local GPU, regardless of the type of GPU. This is possible via the `WebGPU` browser API. Additionally, we leverage `WebAssembly` to run the `niimath` [WASM wrapper](https://www.npmjs.com/package/@niivue/niimath) to turn the tissue segmentation into a 3D mesh. No data ever leaves your machine.
+This web application uses some of the latest browser technologies that allow the tissue segmentation model to run on your local GPU, regardless of the type of GPU. This is possible via the `WebGPU` browser API. Additionally, we leverage `WebAssembly` to run the `niimath` [WASM wrapper](https://www.npmjs.com/package/@niivue/niimath) and [ITK-Wasm](https://wasm.itk.org) to turn the tissue segmentation into a 3D mesh. No data ever leaves your machine.
### Developers - Running a Local Live Demo
@@ -50,5 +50,4 @@ npm run build
- [brainchop](https://github.com/neuroneural/brainchop)
- [niivue](https://github.com/niivue/niivue)
- [niimath](https://github.com/rordenlab/niimath)
-
-
+- [ITK-Wasm](https://github.com/InsightSoftwareConsortium/ITK-Wasm)
From 661400b31fa2f91aab04a41866fed3dc1fa52840 Mon Sep 17 00:00:00 2001
From: Matt McCormick
Date: Wed, 18 Dec 2024 00:29:17 -0500
Subject: [PATCH 05/12] User interface simplifications
---
README.md | 2 --
index.html | 35 +++++------------------------------
main.js | 13 +++----------
3 files changed, 8 insertions(+), 42 deletions(-)
diff --git a/README.md b/README.md
index fbcdf15..391c3f1 100644
--- a/README.md
+++ b/README.md
@@ -15,8 +15,6 @@ This is an extension of [brainchop](https://github.com/neuroneural/brainchop) th
- ![settings dialog](Settings.png)
- - Fill bubbles will remove any cavities. This includes large cavities such as the brain's ventricles.
- - The `Largest cluster only` will only extract a single mesh.
- You can choose `Smoothing` to make the surfaces less jagged at the expense of computation time.
- You can choose to `Simplify` to reduce the number of triangles and create smaller files.
diff --git a/index.html b/index.html
index ba861d2..3c10c0d 100644
--- a/index.html
+++ b/index.html
@@ -55,46 +55,21 @@
-
+
From ae9aafdc08289d8f0c5bce9287fc431a14782b6b Mon Sep 17 00:00:00 2001
From: Matt McCormick
Date: Wed, 18 Dec 2024 15:23:20 -0500
Subject: [PATCH 07/12] Disable buttons when not valid, provide mesh processing
feedback
---
index.html | 7 ++++---
main.js | 9 +++++++++
2 files changed, 13 insertions(+), 3 deletions(-)
diff --git a/index.html b/index.html
index 748d5a3..13f8b65 100644
--- a/index.html
+++ b/index.html
@@ -27,14 +27,14 @@
-
+
-
+
-
+
@@ -43,6 +43,7 @@
+
diff --git a/main.js b/main.js
index 77dcd0d..e4d8c5b 100644
--- a/main.js
+++ b/main.js
@@ -161,6 +161,8 @@ async function main() {
}
overlayVolume.opacity = opacitySlider1.value / 255;
await nv1.addVolume(overlayVolume);
+ saveBtn.disabled = false
+ createMeshBtn.disabled = false
}
async function reportTelemetry(statData) {
if (typeof statData === "string" || statData instanceof String) {
@@ -225,10 +227,13 @@ async function main() {
applyBtn.onclick = async function () {
const volIdx = nv1.volumes.length - 1
loadingCircle.classList.remove("hidden");
+ meshProcessingMsg.classList.remove("hidden")
+ meshProcessingMsg.textContent = "Generating mesh from segmentation"
const hdr = nv1.volumes[volIdx].hdr;
const img = nv1.volumes[volIdx].img;
const itkImage = nii2iwi(hdr, img, false);
itkImage.size = itkImage.size.map(Number);
+
const { mesh } = await antiAliasCuberille(itkImage, { noClosing: true });
const { outputMesh: repairedMesh } = await repair(mesh);
while (nv1.meshes.length > 0) {
@@ -237,11 +242,15 @@ async function main() {
const initialNiiMesh = iwm2meshCore(repairedMesh);
const initialNiiMeshBuffer = NVMeshUtilities.createMZ3(initialNiiMesh.positions, initialNiiMesh.indices, false)
await nv1.loadFromArrayBuffer(initialNiiMeshBuffer, 'trefoil.mz3')
+ saveMeshBtn.disabled = false
+
+ meshProcessingMsg.textContent = "Smoothing and remeshing"
const smooth = parseInt(smoothSlide.value)
const shrink = parseFloat(shrinkPct.value)
const { outputMesh: smoothedMesh } = await smoothRemesh(repairedMesh, { newtonIterations: smooth, numberPoints: shrink });
const niiMesh = iwm2meshCore(smoothedMesh);
loadingCircle.classList.add("hidden");
+ meshProcessingMsg.classList.add("hidden");
while (nv1.meshes.length > 0) {
nv1.removeMesh(nv1.meshes[0]);
}
From 65969f056372f2f6db32602c97f62dcee0c029d7 Mon Sep 17 00:00:00 2001
From: Matt McCormick
Date: Wed, 18 Dec 2024 15:44:47 -0500
Subject: [PATCH 08/12] Keep largest mesh component
We could switch to niimath once
https://github.com/rordenlab/niimath/pull/34
has been merged, if desired.
---
main.js | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/main.js b/main.js
index e4d8c5b..42ab370 100644
--- a/main.js
+++ b/main.js
@@ -5,7 +5,7 @@ import { inferenceModelsList, brainChopOpts } from "./brainchop-parameters.js";
import { isChrome, localSystemDetails } from "./brainchop-telemetry.js";
import MyWorker from "./brainchop-webworker.js?worker";
import { antiAliasCuberille } from "@itk-wasm/cuberille";
-import { repair, smoothRemesh } from "@itk-wasm/mesh-filters";
+import { repair, smoothRemesh, keepLargestComponent } from "@itk-wasm/mesh-filters";
import { nii2iwi, iwm2meshCore } from "@niivue/cbor-loader";
async function main() {
@@ -235,11 +235,14 @@ async function main() {
itkImage.size = itkImage.size.map(Number);
const { mesh } = await antiAliasCuberille(itkImage, { noClosing: true });
+ meshProcessingMsg.textContent = "Generating manifold"
const { outputMesh: repairedMesh } = await repair(mesh);
+ meshProcessingMsg.textContent = "Keep largest mesh component"
+ const { outputMesh: largestOnly } = await keepLargestComponent(repairedMesh)
while (nv1.meshes.length > 0) {
nv1.removeMesh(nv1.meshes[0]);
}
- const initialNiiMesh = iwm2meshCore(repairedMesh);
+ const initialNiiMesh = iwm2meshCore(largestOnly);
const initialNiiMeshBuffer = NVMeshUtilities.createMZ3(initialNiiMesh.positions, initialNiiMesh.indices, false)
await nv1.loadFromArrayBuffer(initialNiiMeshBuffer, 'trefoil.mz3')
saveMeshBtn.disabled = false
@@ -247,7 +250,7 @@ async function main() {
meshProcessingMsg.textContent = "Smoothing and remeshing"
const smooth = parseInt(smoothSlide.value)
const shrink = parseFloat(shrinkPct.value)
- const { outputMesh: smoothedMesh } = await smoothRemesh(repairedMesh, { newtonIterations: smooth, numberPoints: shrink });
+ const { outputMesh: smoothedMesh } = await smoothRemesh(largestOnly, { newtonIterations: smooth, numberPoints: shrink });
const niiMesh = iwm2meshCore(smoothedMesh);
loadingCircle.classList.add("hidden");
meshProcessingMsg.classList.add("hidden");
From 82049ebe3dbabd0b0aa748c3c2f19ace4e8c2c7d Mon Sep 17 00:00:00 2001
From: Matt McCormick
Date: Wed, 18 Dec 2024 15:53:00 -0500
Subject: [PATCH 09/12] Update Settings.png
---
Settings.png | Bin 5737 -> 11473 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
mode change 100644 => 100755 Settings.png
diff --git a/Settings.png b/Settings.png
old mode 100644
new mode 100755
index 41a9cf6130a2e7bf23beec37970cffc6321a8f00..95f00ce5553deea2c9287d4fbbdac576fd998e70
GIT binary patch
literal 11473
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
literal 5737
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
P+8Y3=q@`FRZyEMKT4S&@
From f73583d36ef2162f99f95078369303842941e965 Mon Sep 17 00:00:00 2001
From: Matt McCormick
Date: Wed, 18 Dec 2024 16:07:44 -0500
Subject: [PATCH 10/12] Use vendored ITK-Wasm wasm modules
These are fetched on-demand in web workers from JsDelivr by default.
---
main.js | 18 ++-
package-lock.json | 353 +++++++++++++++++++++++++++++++++++++++++++++-
package.json | 3 +-
vite.config.js | 10 ++
4 files changed, 380 insertions(+), 4 deletions(-)
diff --git a/main.js b/main.js
index 42ab370..4d54812 100644
--- a/main.js
+++ b/main.js
@@ -4,10 +4,24 @@ import { Niimath } from "@niivue/niimath";
import { inferenceModelsList, brainChopOpts } from "./brainchop-parameters.js";
import { isChrome, localSystemDetails } from "./brainchop-telemetry.js";
import MyWorker from "./brainchop-webworker.js?worker";
-import { antiAliasCuberille } from "@itk-wasm/cuberille";
-import { repair, smoothRemesh, keepLargestComponent } from "@itk-wasm/mesh-filters";
+import {
+ antiAliasCuberille,
+ setPipelinesBaseUrl as setCuberillePipelinesUrl
+} from "@itk-wasm/cuberille";
+import {
+ repair,
+ smoothRemesh,
+ keepLargestComponent,
+ setPipelinesBaseUrl as setMeshFiltersPipelinesUrl,
+} from "@itk-wasm/mesh-filters";
import { nii2iwi, iwm2meshCore } from "@niivue/cbor-loader";
+// Use local, vendored WebAssembly module assets
+const viteBaseUrl = import.meta.env.BASE_URL
+const pipelinesBaseUrl = new URL(`${viteBaseUrl}pipelines`, document.location.origin).href
+setCuberillePipelinesUrl(pipelinesBaseUrl)
+setMeshFiltersPipelinesUrl(pipelinesBaseUrl)
+
async function main() {
const niimath = new Niimath();
await niimath.init();
diff --git a/package-lock.json b/package-lock.json
index 12afb99..f7d2c70 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17,7 +17,8 @@
"gl-matrix": "^3.4.3"
},
"devDependencies": {
- "vite": "^5.4.2"
+ "vite": "^5.4.2",
+ "vite-plugin-static-copy": "^2.2.0"
}
},
"node_modules/@cbor-extract/cbor-extract-darwin-arm64": {
@@ -730,6 +731,44 @@
"@rollup/rollup-linux-x64-gnu": "^4.18.1"
}
},
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/@perma/map": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@perma/map/-/map-1.0.3.tgz",
@@ -1241,6 +1280,20 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
"node_modules/argparse": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -1296,6 +1349,19 @@
}
]
},
+ "node_modules/binary-extensions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
+ "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/bl": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
@@ -1318,6 +1384,19 @@
"balanced-match": "^1.0.0"
}
},
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
@@ -1420,6 +1499,31 @@
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
+ "node_modules/chokidar": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
+ "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
"node_modules/chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
@@ -1678,6 +1782,33 @@
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz",
"integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="
},
+ "node_modules/fast-glob": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
+ "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fastq": {
+ "version": "1.17.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
+ "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
"node_modules/fd-slicer": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
@@ -1710,6 +1841,19 @@
"node": ">=18"
}
},
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/follow-redirects": {
"version": "1.15.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
@@ -1846,6 +1990,19 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
@@ -1981,6 +2138,29 @@
"progress-events": "^1.0.1"
}
},
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
@@ -1989,11 +2169,34 @@
"node": ">=8"
}
},
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/is-natural-number": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz",
"integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ=="
},
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
"node_modules/is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
@@ -2171,6 +2374,30 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
@@ -2324,6 +2551,16 @@
"node-gyp-build-optional-packages-test": "build-test.js"
}
},
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -2394,6 +2631,19 @@
"dev": true,
"license": "ISC"
},
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
"node_modules/pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
@@ -2511,6 +2761,27 @@
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/rabin-rs": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/rabin-rs/-/rabin-rs-2.1.0.tgz",
@@ -2543,6 +2814,19 @@
"safe-buffer": "~5.1.0"
}
},
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
"node_modules/regenerator-runtime": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
@@ -2556,6 +2840,17 @@
"node": ">=0.10.0"
}
},
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
"node_modules/rollup": {
"version": "4.21.0",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.21.0.tgz",
@@ -2592,6 +2887,30 @@
"fsevents": "~2.3.2"
}
},
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
"node_modules/rxjs": {
"version": "7.8.1",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
@@ -2761,6 +3080,19 @@
"resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz",
"integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg=="
},
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
@@ -2909,6 +3241,25 @@
}
}
},
+ "node_modules/vite-plugin-static-copy": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-2.2.0.tgz",
+ "integrity": "sha512-ytMrKdR9iWEYHbUxs6x53m+MRl4SJsOSoMu1U1+Pfg0DjPeMlsRVx3RR5jvoonineDquIue83Oq69JvNsFSU5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^3.5.3",
+ "fast-glob": "^3.2.11",
+ "fs-extra": "^11.1.0",
+ "picocolors": "^1.0.0"
+ },
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ },
+ "peerDependencies": {
+ "vite": "^5.0.0 || ^6.0.0"
+ }
+ },
"node_modules/wasm-feature-detect": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/wasm-feature-detect/-/wasm-feature-detect-1.8.0.tgz",
diff --git a/package.json b/package.json
index 7cbcfa2..04ef63d 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
"gl-matrix": "^3.4.3"
},
"devDependencies": {
- "vite": "^5.4.2"
+ "vite": "^5.4.2",
+ "vite-plugin-static-copy": "^2.2.0"
}
}
diff --git a/vite.config.js b/vite.config.js
index d1c22a5..8394a46 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -1,4 +1,5 @@
import { defineConfig } from "vite";
+import { viteStaticCopy } from 'vite-plugin-static-copy'
export default defineConfig({
// root: '.',
@@ -13,4 +14,13 @@ export default defineConfig({
optimizeDeps: {
exclude: ["@niivue/niimath", "@itk-wasm/cuberille", "@itk-wasm/mesh-filters"],
},
+ plugins: [
+ // put lazy loaded JavaScript and Wasm bundles in dist directory
+ viteStaticCopy({
+ targets: [
+ { src: 'node_modules/@itk-wasm/cuberille/dist/pipelines/*.{js,wasm,wasm.zst}', dest: 'pipelines' },
+ { src: 'node_modules/@itk-wasm/mesh-filters/dist/pipelines/*.{js,wasm,wasm.zst}', dest: 'pipelines' },
+ ],
+ })
+ ],
});
From 652a164bcc57d5e4ced2604931ddad38dd9b856b Mon Sep 17 00:00:00 2001
From: Matt McCormick
Date: Wed, 18 Dec 2024 16:13:08 -0500
Subject: [PATCH 11/12] Use a high maximumHoleArea
Ensure we have no surface holes.
---
main.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/main.js b/main.js
index 4d54812..8b01a2b 100644
--- a/main.js
+++ b/main.js
@@ -250,7 +250,7 @@ async function main() {
const { mesh } = await antiAliasCuberille(itkImage, { noClosing: true });
meshProcessingMsg.textContent = "Generating manifold"
- const { outputMesh: repairedMesh } = await repair(mesh);
+ const { outputMesh: repairedMesh } = await repair(mesh, { maximumHoleArea: 50.0 });
meshProcessingMsg.textContent = "Keep largest mesh component"
const { outputMesh: largestOnly } = await keepLargestComponent(repairedMesh)
while (nv1.meshes.length > 0) {
From f80b90353d843cbf1544e966757feb0abdf4ed47 Mon Sep 17 00:00:00 2001
From: Matt McCormick
Date: Wed, 18 Dec 2024 16:13:30 -0500
Subject: [PATCH 12/12] README typo
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 391c3f1..026da43 100644
--- a/README.md
+++ b/README.md
@@ -10,7 +10,7 @@ This is an extension of [brainchop](https://github.com/neuroneural/brainchop) th
2. **Option 1** The web page automatically loads with a default T1 MRI scan. If you want to use this scan, go to step 5.
3. **Option 2** If your T1 MRI scan is in NIfTI format, drag and drop the file onto the web page.
4. **Option 3** If your image is in DICOM format, it may load if you drag and drop the files. If this fails, convert your images with [dcm2niix](https://github.com/rordenlab/dcm2niix).
-5. Segment your brain scan by choosing a model from the `Segmentation Model` pull-down menu. Not all models with with all graphics cards. The `Tissue GWM (High Acc, Low Mem)` is a good starting point. Hopefully, it will accurately segment your brain into gray matter, white matter and cerebral spinal fluid.
+5. Segment your brain scan by choosing a model from the `Segmentation Model` pull-down menu. Not all models work with all graphics cards. The `Tissue GWM (High Acc, Low Mem)` is a good starting point. Hopefully, it will accurately segment your brain into gray matter, white matter and cerebral spinal fluid.
6. Press the `Create Mesh` button and select your preferred settings:
- ![settings dialog](Settings.png)