// The vendored pulseq +mr package as numbl boot files. The tree is inlined // into the bundle at build time (raw imports); see src/engine/pulseq/VENDORED.md // for provenance. import type { BootFile } from 'numbl/browser' const raw = import.meta.glob('./pulseq/+mr/**/*.m', { query: '?raw', import: 'default', eager: true, }) as Record // pulseq's md5 needs Java (MATLAB) or the `hash` builtin (Octave). numbl // provides `hash`, but md5.m only reaches it through its isOctave branch — // replace the whole file with a direct wrapper. const MD5_OVERRIDE = `function digest = md5(message, noBuiltIn) digest = hash('MD5', char(message)); end ` // There is no Python/SigPy (and no OS `system` command) in the browser. // isSigPyAvailable probes for it via system(); stub it to "not available" so // pulse designers (adiabatic, SLR) take their internal non-sigpy path. const ISSIGPY_OVERRIDE = `function [sigPyOK, pythonExe] = isSigPyAvailable() sigPyOK = false; pythonExe = ''; end ` const OVERRIDES: Record = { '+mr/+aux/md5.m': MD5_OVERRIDE, '+mr/+aux/isSigPyAvailable.m': ISSIGPY_OVERRIDE, } /** Boot-file list for a session: the +mr tree with app-level overrides applied. */ export function mrBootFiles(): BootFile[] { const files: BootFile[] = [] for (const [key, content] of Object.entries(raw)) { const path = key.replace('./pulseq/', '') files.push({ path, content: OVERRIDES[path] ?? content }) } return files }