From 305f5cc9ae7af6b2791019c77fe6616100376b92 Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Tue, 26 May 2026 23:23:54 +0800 Subject: [PATCH 01/16] feat: add initial packages + tsconfig --- .vscode/extensions.json | 5 + .vscode/settings.json | 8 + .yarn/sdks/integrations.yml | 5 + .yarn/sdks/typescript/bin/tsc | 32 + .yarn/sdks/typescript/bin/tsserver | 32 + .yarn/sdks/typescript/lib/tsc.js | 32 + .yarn/sdks/typescript/lib/tsserver.js | 248 + .yarn/sdks/typescript/lib/tsserverlibrary.js | 248 + .yarn/sdks/typescript/lib/typescript.js | 32 + .yarn/sdks/typescript/package.json | 10 + package.json | 34 +- src/tsconfig.json | 43 + src/web/tsconfig.json | 9 + yarn.lock | 4687 ++++++++++++++++++ 14 files changed, 5424 insertions(+), 1 deletion(-) create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json create mode 100644 .yarn/sdks/integrations.yml create mode 100755 .yarn/sdks/typescript/bin/tsc create mode 100755 .yarn/sdks/typescript/bin/tsserver create mode 100644 .yarn/sdks/typescript/lib/tsc.js create mode 100644 .yarn/sdks/typescript/lib/tsserver.js create mode 100644 .yarn/sdks/typescript/lib/tsserverlibrary.js create mode 100644 .yarn/sdks/typescript/lib/typescript.js create mode 100644 .yarn/sdks/typescript/package.json create mode 100644 src/tsconfig.json create mode 100644 src/web/tsconfig.json diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..06dd640 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,5 @@ +{ + "recommendations": [ + "arcanis.vscode-zipfs" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7629b32 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "search.exclude": { + "**/.yarn": true, + "**/.pnp.*": true + }, + "typescript.tsdk": ".yarn/sdks/typescript/lib", + "typescript.enablePromptUseWorkspaceTsdk": true +} diff --git a/.yarn/sdks/integrations.yml b/.yarn/sdks/integrations.yml new file mode 100644 index 0000000..aa9d0d0 --- /dev/null +++ b/.yarn/sdks/integrations.yml @@ -0,0 +1,5 @@ +# This file is automatically generated by @yarnpkg/sdks. +# Manual changes might be lost! + +integrations: + - vscode diff --git a/.yarn/sdks/typescript/bin/tsc b/.yarn/sdks/typescript/bin/tsc new file mode 100755 index 0000000..867a7bd --- /dev/null +++ b/.yarn/sdks/typescript/bin/tsc @@ -0,0 +1,32 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, register} = require(`module`); +const {resolve} = require(`path`); +const {pathToFileURL} = require(`url`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); +const absRequire = createRequire(absPnpApiPath); + +const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); +const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/bin/tsc + require(absPnpApiPath).setup(); + if (isPnpLoaderEnabled && register) { + register(pathToFileURL(absPnpLoaderPath)); + } + } +} + +const wrapWithUserWrapper = existsSync(absUserWrapperPath) + ? exports => absRequire(absUserWrapperPath)(exports) + : exports => exports; + +// Defer to the real typescript/bin/tsc your application uses +module.exports = wrapWithUserWrapper(absRequire(`typescript/bin/tsc`)); diff --git a/.yarn/sdks/typescript/bin/tsserver b/.yarn/sdks/typescript/bin/tsserver new file mode 100755 index 0000000..3fc5aa3 --- /dev/null +++ b/.yarn/sdks/typescript/bin/tsserver @@ -0,0 +1,32 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, register} = require(`module`); +const {resolve} = require(`path`); +const {pathToFileURL} = require(`url`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); +const absRequire = createRequire(absPnpApiPath); + +const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); +const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/bin/tsserver + require(absPnpApiPath).setup(); + if (isPnpLoaderEnabled && register) { + register(pathToFileURL(absPnpLoaderPath)); + } + } +} + +const wrapWithUserWrapper = existsSync(absUserWrapperPath) + ? exports => absRequire(absUserWrapperPath)(exports) + : exports => exports; + +// Defer to the real typescript/bin/tsserver your application uses +module.exports = wrapWithUserWrapper(absRequire(`typescript/bin/tsserver`)); diff --git a/.yarn/sdks/typescript/lib/tsc.js b/.yarn/sdks/typescript/lib/tsc.js new file mode 100644 index 0000000..da411bd --- /dev/null +++ b/.yarn/sdks/typescript/lib/tsc.js @@ -0,0 +1,32 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, register} = require(`module`); +const {resolve} = require(`path`); +const {pathToFileURL} = require(`url`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); +const absRequire = createRequire(absPnpApiPath); + +const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); +const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/lib/tsc.js + require(absPnpApiPath).setup(); + if (isPnpLoaderEnabled && register) { + register(pathToFileURL(absPnpLoaderPath)); + } + } +} + +const wrapWithUserWrapper = existsSync(absUserWrapperPath) + ? exports => absRequire(absUserWrapperPath)(exports) + : exports => exports; + +// Defer to the real typescript/lib/tsc.js your application uses +module.exports = wrapWithUserWrapper(absRequire(`typescript/lib/tsc.js`)); diff --git a/.yarn/sdks/typescript/lib/tsserver.js b/.yarn/sdks/typescript/lib/tsserver.js new file mode 100644 index 0000000..6249c46 --- /dev/null +++ b/.yarn/sdks/typescript/lib/tsserver.js @@ -0,0 +1,248 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, register} = require(`module`); +const {resolve} = require(`path`); +const {pathToFileURL} = require(`url`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); +const absRequire = createRequire(absPnpApiPath); + +const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); +const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/lib/tsserver.js + require(absPnpApiPath).setup(); + if (isPnpLoaderEnabled && register) { + register(pathToFileURL(absPnpLoaderPath)); + } + } +} + +const wrapWithUserWrapper = existsSync(absUserWrapperPath) + ? exports => absRequire(absUserWrapperPath)(exports) + : exports => exports; + +const moduleWrapper = exports => { + return wrapWithUserWrapper(moduleWrapperFn(exports)); +}; + +const moduleWrapperFn = tsserver => { + if (!process.versions.pnp) { + return tsserver; + } + + const {isAbsolute} = require(`path`); + const pnpApi = require(`pnpapi`); + + const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//); + const isPortal = str => str.startsWith("portal:/"); + const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`); + + const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => { + return `${locator.name}@${locator.reference}`; + })); + + // VSCode sends the zip paths to TS using the "zip://" prefix, that TS + // doesn't understand. This layer makes sure to remove the protocol + // before forwarding it to TS, and to add it back on all returned paths. + + function toEditorPath(str) { + // We add the `zip:` prefix to both `.zip/` paths and virtual paths + if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) { + // We also take the opportunity to turn virtual paths into physical ones; + // this makes it much easier to work with workspaces that list peer + // dependencies, since otherwise Ctrl+Click would bring us to the virtual + // file instances instead of the real ones. + // + // We only do this to modules owned by the the dependency tree roots. + // This avoids breaking the resolution when jumping inside a vendor + // with peer dep (otherwise jumping into react-dom would show resolution + // errors on react). + // + const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str; + if (resolved) { + const locator = pnpApi.findPackageLocator(resolved); + if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) { + str = resolved; + } + } + + str = normalize(str); + + if (str.match(/\.zip\//)) { + switch (hostInfo) { + // Absolute VSCode `Uri.fsPath`s need to start with a slash. + // VSCode only adds it automatically for supported schemes, + // so we have to do it manually for the `zip` scheme. + // The path needs to start with a caret otherwise VSCode doesn't handle the protocol + // + // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910 + // + // 2021-10-08: VSCode changed the format in 1.61. + // Before | ^zip:/c:/foo/bar.zip/package.json + // After | ^/zip//c:/foo/bar.zip/package.json + // + // 2022-04-06: VSCode changed the format in 1.66. + // Before | ^/zip//c:/foo/bar.zip/package.json + // After | ^/zip/c:/foo/bar.zip/package.json + // + // 2022-05-06: VSCode changed the format in 1.68 + // Before | ^/zip/c:/foo/bar.zip/package.json + // After | ^/zip//c:/foo/bar.zip/package.json + // + case `vscode <1.61`: { + str = `^zip:${str}`; + } break; + + case `vscode <1.66`: { + str = `^/zip/${str}`; + } break; + + case `vscode <1.68`: { + str = `^/zip${str}`; + } break; + + case `vscode`: { + str = `^/zip/${str}`; + } break; + + // To make "go to definition" work, + // We have to resolve the actual file system path from virtual path + // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip) + case `coc-nvim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = resolve(`zipfile:${str}`); + } break; + + // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server) + // We have to resolve the actual file system path from virtual path, + // everything else is up to neovim + case `neovim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = `zipfile://${str}`; + } break; + + default: { + str = `zip:${str}`; + } break; + } + } else { + str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`); + } + } + + return str; + } + + function fromEditorPath(str) { + switch (hostInfo) { + case `coc-nvim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for coc-nvim is in format of //zipfile://.yarn/... + // So in order to convert it back, we use .* to match all the thing + // before `zipfile:` + return process.platform === `win32` + ? str.replace(/^.*zipfile:\//, ``) + : str.replace(/^.*zipfile:/, ``); + } break; + + case `neovim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for neovim is in format of zipfile:////.yarn/... + return str.replace(/^zipfile:\/\//, ``); + } break; + + case `vscode`: + default: { + return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`) + } break; + } + } + + // Force enable 'allowLocalPluginLoads' + // TypeScript tries to resolve plugins using a path relative to itself + // which doesn't work when using the global cache + // https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238 + // VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but + // TypeScript already does local loads and if this code is running the user trusts the workspace + // https://github.com/microsoft/vscode/issues/45856 + const ConfiguredProject = tsserver.server.ConfiguredProject; + const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype; + ConfiguredProject.prototype.enablePluginsWithOptions = function() { + this.projectService.allowLocalPluginLoads = true; + return originalEnablePluginsWithOptions.apply(this, arguments); + }; + + // And here is the point where we hijack the VSCode <-> TS communications + // by adding ourselves in the middle. We locate everything that looks + // like an absolute path of ours and normalize it. + + const Session = tsserver.server.Session; + const {onMessage: originalOnMessage, send: originalSend} = Session.prototype; + let hostInfo = `unknown`; + + Object.assign(Session.prototype, { + onMessage(/** @type {string | object} */ message) { + const isStringMessage = typeof message === 'string'; + const parsedMessage = isStringMessage ? JSON.parse(message) : message; + + if ( + parsedMessage != null && + typeof parsedMessage === `object` && + parsedMessage.arguments && + typeof parsedMessage.arguments.hostInfo === `string` + ) { + hostInfo = parsedMessage.arguments.hostInfo; + if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) { + const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match( + // The RegExp from https://semver.org/ but without the caret at the start + /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ + ) ?? []).map(Number) + + if (major === 1) { + if (minor < 61) { + hostInfo += ` <1.61`; + } else if (minor < 66) { + hostInfo += ` <1.66`; + } else if (minor < 68) { + hostInfo += ` <1.68`; + } + } + } + } + + const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => { + return typeof value === 'string' ? fromEditorPath(value) : value; + }); + + return originalOnMessage.call( + this, + isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON) + ); + }, + + send(/** @type {any} */ msg) { + return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => { + return typeof value === `string` ? toEditorPath(value) : value; + }))); + } + }); + + return tsserver; +}; + +const [major, minor] = absRequire(`typescript/package.json`).version.split(`.`, 2).map(value => parseInt(value, 10)); +// In TypeScript@>=5.5 the tsserver uses the public TypeScript API so that needs to be patched as well. +// Ref https://github.com/microsoft/TypeScript/pull/55326 +if (major > 5 || (major === 5 && minor >= 5)) { + moduleWrapper(absRequire(`typescript`)); +} + +// Defer to the real typescript/lib/tsserver.js your application uses +module.exports = moduleWrapper(absRequire(`typescript/lib/tsserver.js`)); diff --git a/.yarn/sdks/typescript/lib/tsserverlibrary.js b/.yarn/sdks/typescript/lib/tsserverlibrary.js new file mode 100644 index 0000000..0e50e0a --- /dev/null +++ b/.yarn/sdks/typescript/lib/tsserverlibrary.js @@ -0,0 +1,248 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, register} = require(`module`); +const {resolve} = require(`path`); +const {pathToFileURL} = require(`url`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); +const absRequire = createRequire(absPnpApiPath); + +const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); +const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript/lib/tsserverlibrary.js + require(absPnpApiPath).setup(); + if (isPnpLoaderEnabled && register) { + register(pathToFileURL(absPnpLoaderPath)); + } + } +} + +const wrapWithUserWrapper = existsSync(absUserWrapperPath) + ? exports => absRequire(absUserWrapperPath)(exports) + : exports => exports; + +const moduleWrapper = exports => { + return wrapWithUserWrapper(moduleWrapperFn(exports)); +}; + +const moduleWrapperFn = tsserver => { + if (!process.versions.pnp) { + return tsserver; + } + + const {isAbsolute} = require(`path`); + const pnpApi = require(`pnpapi`); + + const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//); + const isPortal = str => str.startsWith("portal:/"); + const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`); + + const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => { + return `${locator.name}@${locator.reference}`; + })); + + // VSCode sends the zip paths to TS using the "zip://" prefix, that TS + // doesn't understand. This layer makes sure to remove the protocol + // before forwarding it to TS, and to add it back on all returned paths. + + function toEditorPath(str) { + // We add the `zip:` prefix to both `.zip/` paths and virtual paths + if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) { + // We also take the opportunity to turn virtual paths into physical ones; + // this makes it much easier to work with workspaces that list peer + // dependencies, since otherwise Ctrl+Click would bring us to the virtual + // file instances instead of the real ones. + // + // We only do this to modules owned by the the dependency tree roots. + // This avoids breaking the resolution when jumping inside a vendor + // with peer dep (otherwise jumping into react-dom would show resolution + // errors on react). + // + const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str; + if (resolved) { + const locator = pnpApi.findPackageLocator(resolved); + if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) { + str = resolved; + } + } + + str = normalize(str); + + if (str.match(/\.zip\//)) { + switch (hostInfo) { + // Absolute VSCode `Uri.fsPath`s need to start with a slash. + // VSCode only adds it automatically for supported schemes, + // so we have to do it manually for the `zip` scheme. + // The path needs to start with a caret otherwise VSCode doesn't handle the protocol + // + // Ref: https://github.com/microsoft/vscode/issues/105014#issuecomment-686760910 + // + // 2021-10-08: VSCode changed the format in 1.61. + // Before | ^zip:/c:/foo/bar.zip/package.json + // After | ^/zip//c:/foo/bar.zip/package.json + // + // 2022-04-06: VSCode changed the format in 1.66. + // Before | ^/zip//c:/foo/bar.zip/package.json + // After | ^/zip/c:/foo/bar.zip/package.json + // + // 2022-05-06: VSCode changed the format in 1.68 + // Before | ^/zip/c:/foo/bar.zip/package.json + // After | ^/zip//c:/foo/bar.zip/package.json + // + case `vscode <1.61`: { + str = `^zip:${str}`; + } break; + + case `vscode <1.66`: { + str = `^/zip/${str}`; + } break; + + case `vscode <1.68`: { + str = `^/zip${str}`; + } break; + + case `vscode`: { + str = `^/zip/${str}`; + } break; + + // To make "go to definition" work, + // We have to resolve the actual file system path from virtual path + // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip) + case `coc-nvim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = resolve(`zipfile:${str}`); + } break; + + // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server) + // We have to resolve the actual file system path from virtual path, + // everything else is up to neovim + case `neovim`: { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = `zipfile://${str}`; + } break; + + default: { + str = `zip:${str}`; + } break; + } + } else { + str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`); + } + } + + return str; + } + + function fromEditorPath(str) { + switch (hostInfo) { + case `coc-nvim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for coc-nvim is in format of //zipfile://.yarn/... + // So in order to convert it back, we use .* to match all the thing + // before `zipfile:` + return process.platform === `win32` + ? str.replace(/^.*zipfile:\//, ``) + : str.replace(/^.*zipfile:/, ``); + } break; + + case `neovim`: { + str = str.replace(/\.zip::/, `.zip/`); + // The path for neovim is in format of zipfile:////.yarn/... + return str.replace(/^zipfile:\/\//, ``); + } break; + + case `vscode`: + default: { + return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`) + } break; + } + } + + // Force enable 'allowLocalPluginLoads' + // TypeScript tries to resolve plugins using a path relative to itself + // which doesn't work when using the global cache + // https://github.com/microsoft/TypeScript/blob/1b57a0395e0bff191581c9606aab92832001de62/src/server/project.ts#L2238 + // VSCode doesn't want to enable 'allowLocalPluginLoads' due to security concerns but + // TypeScript already does local loads and if this code is running the user trusts the workspace + // https://github.com/microsoft/vscode/issues/45856 + const ConfiguredProject = tsserver.server.ConfiguredProject; + const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype; + ConfiguredProject.prototype.enablePluginsWithOptions = function() { + this.projectService.allowLocalPluginLoads = true; + return originalEnablePluginsWithOptions.apply(this, arguments); + }; + + // And here is the point where we hijack the VSCode <-> TS communications + // by adding ourselves in the middle. We locate everything that looks + // like an absolute path of ours and normalize it. + + const Session = tsserver.server.Session; + const {onMessage: originalOnMessage, send: originalSend} = Session.prototype; + let hostInfo = `unknown`; + + Object.assign(Session.prototype, { + onMessage(/** @type {string | object} */ message) { + const isStringMessage = typeof message === 'string'; + const parsedMessage = isStringMessage ? JSON.parse(message) : message; + + if ( + parsedMessage != null && + typeof parsedMessage === `object` && + parsedMessage.arguments && + typeof parsedMessage.arguments.hostInfo === `string` + ) { + hostInfo = parsedMessage.arguments.hostInfo; + if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) { + const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match( + // The RegExp from https://semver.org/ but without the caret at the start + /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ + ) ?? []).map(Number) + + if (major === 1) { + if (minor < 61) { + hostInfo += ` <1.61`; + } else if (minor < 66) { + hostInfo += ` <1.66`; + } else if (minor < 68) { + hostInfo += ` <1.68`; + } + } + } + } + + const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => { + return typeof value === 'string' ? fromEditorPath(value) : value; + }); + + return originalOnMessage.call( + this, + isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON) + ); + }, + + send(/** @type {any} */ msg) { + return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => { + return typeof value === `string` ? toEditorPath(value) : value; + }))); + } + }); + + return tsserver; +}; + +const [major, minor] = absRequire(`typescript/package.json`).version.split(`.`, 2).map(value => parseInt(value, 10)); +// In TypeScript@>=5.5 the tsserver uses the public TypeScript API so that needs to be patched as well. +// Ref https://github.com/microsoft/TypeScript/pull/55326 +if (major > 5 || (major === 5 && minor >= 5)) { + moduleWrapper(absRequire(`typescript`)); +} + +// Defer to the real typescript/lib/tsserverlibrary.js your application uses +module.exports = moduleWrapper(absRequire(`typescript/lib/tsserverlibrary.js`)); diff --git a/.yarn/sdks/typescript/lib/typescript.js b/.yarn/sdks/typescript/lib/typescript.js new file mode 100644 index 0000000..7b6cc22 --- /dev/null +++ b/.yarn/sdks/typescript/lib/typescript.js @@ -0,0 +1,32 @@ +#!/usr/bin/env node + +const {existsSync} = require(`fs`); +const {createRequire, register} = require(`module`); +const {resolve} = require(`path`); +const {pathToFileURL} = require(`url`); + +const relPnpApiPath = "../../../../.pnp.cjs"; + +const absPnpApiPath = resolve(__dirname, relPnpApiPath); +const absUserWrapperPath = resolve(__dirname, `./sdk.user.cjs`); +const absRequire = createRequire(absPnpApiPath); + +const absPnpLoaderPath = resolve(absPnpApiPath, `../.pnp.loader.mjs`); +const isPnpLoaderEnabled = existsSync(absPnpLoaderPath); + +if (existsSync(absPnpApiPath)) { + if (!process.versions.pnp) { + // Setup the environment to be able to require typescript + require(absPnpApiPath).setup(); + if (isPnpLoaderEnabled && register) { + register(pathToFileURL(absPnpLoaderPath)); + } + } +} + +const wrapWithUserWrapper = existsSync(absUserWrapperPath) + ? exports => absRequire(absUserWrapperPath)(exports) + : exports => exports; + +// Defer to the real typescript your application uses +module.exports = wrapWithUserWrapper(absRequire(`typescript`)); diff --git a/.yarn/sdks/typescript/package.json b/.yarn/sdks/typescript/package.json new file mode 100644 index 0000000..2f36993 --- /dev/null +++ b/.yarn/sdks/typescript/package.json @@ -0,0 +1,10 @@ +{ + "name": "typescript", + "version": "6.0.3-sdk", + "main": "./lib/typescript.js", + "type": "commonjs", + "bin": { + "tsc": "./bin/tsc", + "tsserver": "./bin/tsserver" + } +} diff --git a/package.json b/package.json index e9b100b..b68c3fd 100644 --- a/package.json +++ b/package.json @@ -1,4 +1,36 @@ { "name": "plugins", - "packageManager": "yarn@4.12.0" + "packageManager": "yarn@4.12.0", + "workspaces": [ + "src/common/*", + "src/runner/*", + "src/web/*" + ], + "devDependencies": { + "@rollup/plugin-node-resolve": "^16.0.3", + "@rollup/plugin-terser": "^1.0.0", + "@rollup/plugin-typescript": "^12.3.0", + "@sourceacademy/conductor": "^0.3.0", + "@types/jest": "^30.0.0", + "eslint": "^10.0.3", + "eslint-config-prettier": "^10.1.8", + "jest": "^30.3.0", + "prettier": "^3.8.1", + "rollup": "^4.60.0", + "ts-jest": "^29.4.6", + "typescript": "^6.0.3", + "typescript-eslint": "^8.57.1" + }, + "dependencies": { + "rollup": "^4.60.2" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/source-academy/plugins.git" + }, + "license": "ISC", + "bugs": { + "url": "https://github.com/source-academy/plugins/issues" + }, + "homepage": "https://github.com/source-academy/plugins#readme" } diff --git a/src/tsconfig.json b/src/tsconfig.json new file mode 100644 index 0000000..552a857 --- /dev/null +++ b/src/tsconfig.json @@ -0,0 +1,43 @@ +// Deployment tsconfig + +{ + "compilerOptions": { + /* Allow JavaScript files to be imported inside your project, instead of just .ts and .tsx files. */ + "allowJs": false, + /* When set to true, allowSyntheticDefaultImports allows you to write an import like "import React from "react";" */ + "allowSyntheticDefaultImports": true, + /* See https://www.typescriptlang.org/tsconfig#esModuleInterop */ + "esModuleInterop": true, + + "forceConsistentCasingInFileNames": true, + /* See https://www.typescriptlang.org/tsconfig#lib */ + "lib": ["es6", "dom", "es2016", "ESNext", "scripthost"], + /* Sets the module system for the program. See the Modules reference page for more information. */ + "module": "esnext", + /* Specify the module resolution strategy: 'node' (Node.js) or 'classic' (used in TypeScript before the release of 1.6). */ + "moduleResolution": "bundler", + "skipLibCheck": true, + + "noEmit": true, + + /* Allows importing modules with a ‘.json’ extension, which is a common practice in node projects. */ + "resolveJsonModule": true, + /* Enables the generation of sourcemap files. These files allow debuggers and other tools to display the original TypeScript source code when actually working with the emitted JavaScript files. */ + "sourceMap": false, + /* The strict flag enables a wide range of type checking behavior that results in stronger guarantees of program correctness. */ + "strict": true, + /* The target setting changes which JS features are downleveled and which are left intact. */ + "target": "es6", + /* In some cases where no type annotations are present, TypeScript will fall back to a type of any for a variable when it cannot infer the type. */ + /* *** TEMPORARILY ADDED UNTIL ALL MODULES HAVE BEEN REFACTORED!!!!!!!!!!! *** */ + "noImplicitAny": false, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + + /* Ensure that imports used only as types get removed */ + // "verbatimModuleSyntax": true, + "isolatedModules": true + }, + /* Specifies an array of filenames or patterns that should be skipped when resolving include. */ + "exclude": ["**/dist"] +} \ No newline at end of file diff --git a/src/web/tsconfig.json b/src/web/tsconfig.json new file mode 100644 index 0000000..9bfa0ef --- /dev/null +++ b/src/web/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + // Tabs should never need to emit any kind of files + "declaration": false, + "jsx": "react-jsx", + "types": ["react", "react-konva"] + } +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index d6b2946..c2aa53b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,8 +5,4695 @@ __metadata: version: 8 cacheKey: 10c0 +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.27.1, @babel/code-frame@npm:^7.28.6, @babel/code-frame@npm:^7.29.0": + version: 7.29.0 + resolution: "@babel/code-frame@npm:7.29.0" + dependencies: + "@babel/helper-validator-identifier": "npm:^7.28.5" + js-tokens: "npm:^4.0.0" + picocolors: "npm:^1.1.1" + checksum: 10c0/d34cc504e7765dfb576a663d97067afb614525806b5cad1a5cc1a7183b916fec8ff57fa233585e3926fd5a9e6b31aae6df91aa81ae9775fb7a28f658d3346f0d + languageName: node + linkType: hard + +"@babel/compat-data@npm:^7.28.6": + version: 7.29.3 + resolution: "@babel/compat-data@npm:7.29.3" + checksum: 10c0/81bddd53ce1b1395576fbb7cb739631a976f6b421cd260e6cf2715a9691b9a0ec12ca5c4e1bb88088e60dc87875f6e4ef7fa8674f1dc96ae1bd7c357416605a7 + languageName: node + linkType: hard + +"@babel/core@npm:^7.23.9, @babel/core@npm:^7.27.4": + version: 7.29.0 + resolution: "@babel/core@npm:7.29.0" + dependencies: + "@babel/code-frame": "npm:^7.29.0" + "@babel/generator": "npm:^7.29.0" + "@babel/helper-compilation-targets": "npm:^7.28.6" + "@babel/helper-module-transforms": "npm:^7.28.6" + "@babel/helpers": "npm:^7.28.6" + "@babel/parser": "npm:^7.29.0" + "@babel/template": "npm:^7.28.6" + "@babel/traverse": "npm:^7.29.0" + "@babel/types": "npm:^7.29.0" + "@jridgewell/remapping": "npm:^2.3.5" + convert-source-map: "npm:^2.0.0" + debug: "npm:^4.1.0" + gensync: "npm:^1.0.0-beta.2" + json5: "npm:^2.2.3" + semver: "npm:^6.3.1" + checksum: 10c0/5127d2e8e842ae409e11bcbb5c2dff9874abf5415e8026925af7308e903f4f43397341467a130490d1a39884f461bc2b67f3063bce0be44340db89687fd852aa + languageName: node + linkType: hard + +"@babel/generator@npm:^7.27.5, @babel/generator@npm:^7.29.0": + version: 7.29.1 + resolution: "@babel/generator@npm:7.29.1" + dependencies: + "@babel/parser": "npm:^7.29.0" + "@babel/types": "npm:^7.29.0" + "@jridgewell/gen-mapping": "npm:^0.3.12" + "@jridgewell/trace-mapping": "npm:^0.3.28" + jsesc: "npm:^3.0.2" + checksum: 10c0/349086e6876258ef3fb2823030fee0f6c0eb9c3ebe35fc572e16997f8c030d765f636ddc6299edae63e760ea6658f8ee9a2edfa6d6b24c9a80c917916b973551 + languageName: node + linkType: hard + +"@babel/helper-compilation-targets@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-compilation-targets@npm:7.28.6" + dependencies: + "@babel/compat-data": "npm:^7.28.6" + "@babel/helper-validator-option": "npm:^7.27.1" + browserslist: "npm:^4.24.0" + lru-cache: "npm:^5.1.1" + semver: "npm:^6.3.1" + checksum: 10c0/3fcdf3b1b857a1578e99d20508859dbd3f22f3c87b8a0f3dc540627b4be539bae7f6e61e49d931542fe5b557545347272bbdacd7f58a5c77025a18b745593a50 + languageName: node + linkType: hard + +"@babel/helper-globals@npm:^7.28.0": + version: 7.28.0 + resolution: "@babel/helper-globals@npm:7.28.0" + checksum: 10c0/5a0cd0c0e8c764b5f27f2095e4243e8af6fa145daea2b41b53c0c1414fe6ff139e3640f4e2207ae2b3d2153a1abd346f901c26c290ee7cb3881dd922d4ee9232 + languageName: node + linkType: hard + +"@babel/helper-module-imports@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-module-imports@npm:7.28.6" + dependencies: + "@babel/traverse": "npm:^7.28.6" + "@babel/types": "npm:^7.28.6" + checksum: 10c0/b49d8d8f204d9dbfd5ac70c54e533e5269afb3cea966a9d976722b13e9922cc773a653405f53c89acb247d5aebdae4681d631a3ae3df77ec046b58da76eda2ac + languageName: node + linkType: hard + +"@babel/helper-module-transforms@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/helper-module-transforms@npm:7.28.6" + dependencies: + "@babel/helper-module-imports": "npm:^7.28.6" + "@babel/helper-validator-identifier": "npm:^7.28.5" + "@babel/traverse": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 10c0/6f03e14fc30b287ce0b839474b5f271e72837d0cafe6b172d759184d998fbee3903a035e81e07c2c596449e504f453463d58baa65b6f40a37ded5bec74620b2b + languageName: node + linkType: hard + +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.28.6, @babel/helper-plugin-utils@npm:^7.8.0": + version: 7.28.6 + resolution: "@babel/helper-plugin-utils@npm:7.28.6" + checksum: 10c0/3f5f8acc152fdbb69a84b8624145ff4f9b9f6e776cb989f9f968f8606eb7185c5c3cfcf3ba08534e37e1e0e1c118ac67080610333f56baa4f7376c99b5f1143d + languageName: node + linkType: hard + +"@babel/helper-string-parser@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-string-parser@npm:7.27.1" + checksum: 10c0/8bda3448e07b5583727c103560bcf9c4c24b3c1051a4c516d4050ef69df37bb9a4734a585fe12725b8c2763de0a265aa1e909b485a4e3270b7cfd3e4dbe4b602 + languageName: node + linkType: hard + +"@babel/helper-validator-identifier@npm:^7.28.5": + version: 7.28.5 + resolution: "@babel/helper-validator-identifier@npm:7.28.5" + checksum: 10c0/42aaebed91f739a41f3d80b72752d1f95fd7c72394e8e4bd7cdd88817e0774d80a432451bcba17c2c642c257c483bf1d409dd4548883429ea9493a3bc4ab0847 + languageName: node + linkType: hard + +"@babel/helper-validator-option@npm:^7.27.1": + version: 7.27.1 + resolution: "@babel/helper-validator-option@npm:7.27.1" + checksum: 10c0/6fec5f006eba40001a20f26b1ef5dbbda377b7b68c8ad518c05baa9af3f396e780bdfded24c4eef95d14bb7b8fd56192a6ed38d5d439b97d10efc5f1a191d148 + languageName: node + linkType: hard + +"@babel/helpers@npm:^7.28.6": + version: 7.29.2 + resolution: "@babel/helpers@npm:7.29.2" + dependencies: + "@babel/template": "npm:^7.28.6" + "@babel/types": "npm:^7.29.0" + checksum: 10c0/dab0e65b9318b2502a62c58bc0913572318595eec0482c31f0ad416b72636e6698a1d7c57cd2791d4528eb8c548bca88d338dc4d2a55a108dc1f6702f9bc5512 + languageName: node + linkType: hard + +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.28.6, @babel/parser@npm:^7.29.0": + version: 7.29.3 + resolution: "@babel/parser@npm:7.29.3" + dependencies: + "@babel/types": "npm:^7.29.0" + bin: + parser: ./bin/babel-parser.js + checksum: 10c0/f06920c819550c0db689e4c5b626bf55ba3cebf80ebe9ccfa434e134036cf3de50951fe759f74abb2dae381989239860bde46d4600328578ad1f7114c3711a6d + languageName: node + linkType: hard + +"@babel/plugin-syntax-async-generators@npm:^7.8.4": + version: 7.8.4 + resolution: "@babel/plugin-syntax-async-generators@npm:7.8.4" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/d13efb282838481348c71073b6be6245b35d4f2f964a8f71e4174f235009f929ef7613df25f8d2338e2d3e44bc4265a9f8638c6aaa136d7a61fe95985f9725c8 + languageName: node + linkType: hard + +"@babel/plugin-syntax-bigint@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-bigint@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/686891b81af2bc74c39013655da368a480f17dd237bf9fbc32048e5865cb706d5a8f65438030da535b332b1d6b22feba336da8fa931f663b6b34e13147d12dde + languageName: node + linkType: hard + +"@babel/plugin-syntax-class-properties@npm:^7.12.13": + version: 7.12.13 + resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.12.13" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/95168fa186416195280b1264fb18afcdcdcea780b3515537b766cb90de6ce042d42dd6a204a39002f794ae5845b02afb0fd4861a3308a861204a55e68310a120 + languageName: node + linkType: hard + +"@babel/plugin-syntax-class-static-block@npm:^7.14.5": + version: 7.14.5 + resolution: "@babel/plugin-syntax-class-static-block@npm:7.14.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.14.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/4464bf9115f4a2d02ce1454411baf9cfb665af1da53709c5c56953e5e2913745b0fcce82982a00463d6facbdd93445c691024e310b91431a1e2f024b158f6371 + languageName: node + linkType: hard + +"@babel/plugin-syntax-import-attributes@npm:^7.24.7": + version: 7.28.6 + resolution: "@babel/plugin-syntax-import-attributes@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/1be160e2c426faa74e5be2e30e39e8d0d8c543063bd5d06cd804f8751b8fbcb82ce824ca7f9ce4b09c003693f6c06a11ce503b7e34d85e1a259631e4c3f72ad2 + languageName: node + linkType: hard + +"@babel/plugin-syntax-import-meta@npm:^7.10.4": + version: 7.10.4 + resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.10.4" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/0b08b5e4c3128523d8e346f8cfc86824f0da2697b1be12d71af50a31aff7a56ceb873ed28779121051475010c28d6146a6bfea8518b150b71eeb4e46190172ee + languageName: node + linkType: hard + +"@babel/plugin-syntax-json-strings@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-json-strings@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/e98f31b2ec406c57757d115aac81d0336e8434101c224edd9a5c93cefa53faf63eacc69f3138960c8b25401315af03df37f68d316c151c4b933136716ed6906e + languageName: node + linkType: hard + +"@babel/plugin-syntax-jsx@npm:^7.27.1": + version: 7.28.6 + resolution: "@babel/plugin-syntax-jsx@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/b98fc3cd75e4ca3d5ca1162f610c286e14ede1486e0d297c13a5eb0ac85680ac9656d17d348bddd9160a54d797a08cea5eaac02b9330ddebb7b26732b7b99fb5 + languageName: node + linkType: hard + +"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4": + version: 7.10.4 + resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.10.4" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/2594cfbe29411ad5bc2ad4058de7b2f6a8c5b86eda525a993959438615479e59c012c14aec979e538d60a584a1a799b60d1b8942c3b18468cb9d99b8fd34cd0b + languageName: node + linkType: hard + +"@babel/plugin-syntax-nullish-coalescing-operator@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-nullish-coalescing-operator@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/2024fbb1162899094cfc81152449b12bd0cc7053c6d4bda8ac2852545c87d0a851b1b72ed9560673cbf3ef6248257262c3c04aabf73117215c1b9cc7dd2542ce + languageName: node + linkType: hard + +"@babel/plugin-syntax-numeric-separator@npm:^7.10.4": + version: 7.10.4 + resolution: "@babel/plugin-syntax-numeric-separator@npm:7.10.4" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.10.4" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/c55a82b3113480942c6aa2fcbe976ff9caa74b7b1109ff4369641dfbc88d1da348aceb3c31b6ed311c84d1e7c479440b961906c735d0ab494f688bf2fd5b9bb9 + languageName: node + linkType: hard + +"@babel/plugin-syntax-object-rest-spread@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-object-rest-spread@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/ee1eab52ea6437e3101a0a7018b0da698545230015fc8ab129d292980ec6dff94d265e9e90070e8ae5fed42f08f1622c14c94552c77bcac784b37f503a82ff26 + languageName: node + linkType: hard + +"@babel/plugin-syntax-optional-catch-binding@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-optional-catch-binding@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/27e2493ab67a8ea6d693af1287f7e9acec206d1213ff107a928e85e173741e1d594196f99fec50e9dde404b09164f39dec5864c767212154ffe1caa6af0bc5af + languageName: node + linkType: hard + +"@babel/plugin-syntax-optional-chaining@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-optional-chaining@npm:7.8.3" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.8.0" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/46edddf2faa6ebf94147b8e8540dfc60a5ab718e2de4d01b2c0bdf250a4d642c2bd47cbcbb739febcb2bf75514dbcefad3c52208787994b8d0f8822490f55e81 + languageName: node + linkType: hard + +"@babel/plugin-syntax-private-property-in-object@npm:^7.14.5": + version: 7.14.5 + resolution: "@babel/plugin-syntax-private-property-in-object@npm:7.14.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.14.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/69822772561706c87f0a65bc92d0772cea74d6bc0911537904a676d5ff496a6d3ac4e05a166d8125fce4a16605bace141afc3611074e170a994e66e5397787f3 + languageName: node + linkType: hard + +"@babel/plugin-syntax-top-level-await@npm:^7.14.5": + version: 7.14.5 + resolution: "@babel/plugin-syntax-top-level-await@npm:7.14.5" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.14.5" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/14bf6e65d5bc1231ffa9def5f0ef30b19b51c218fcecaa78cd1bdf7939dfdf23f90336080b7f5196916368e399934ce5d581492d8292b46a2fb569d8b2da106f + languageName: node + linkType: hard + +"@babel/plugin-syntax-typescript@npm:^7.27.1": + version: 7.28.6 + resolution: "@babel/plugin-syntax-typescript@npm:7.28.6" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.28.6" + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 10c0/b0c392a35624883ac480277401ac7d92d8646b66e33639f5d350de7a6723924265985ae11ab9ebd551740ded261c443eaa9a87ea19def9763ca1e0d78c97dea8 + languageName: node + linkType: hard + +"@babel/template@npm:^7.28.6": + version: 7.28.6 + resolution: "@babel/template@npm:7.28.6" + dependencies: + "@babel/code-frame": "npm:^7.28.6" + "@babel/parser": "npm:^7.28.6" + "@babel/types": "npm:^7.28.6" + checksum: 10c0/66d87225ed0bc77f888181ae2d97845021838c619944877f7c4398c6748bcf611f216dfd6be74d39016af502bca876e6ce6873db3c49e4ac354c56d34d57e9f5 + languageName: node + linkType: hard + +"@babel/traverse@npm:^7.28.6, @babel/traverse@npm:^7.29.0": + version: 7.29.0 + resolution: "@babel/traverse@npm:7.29.0" + dependencies: + "@babel/code-frame": "npm:^7.29.0" + "@babel/generator": "npm:^7.29.0" + "@babel/helper-globals": "npm:^7.28.0" + "@babel/parser": "npm:^7.29.0" + "@babel/template": "npm:^7.28.6" + "@babel/types": "npm:^7.29.0" + debug: "npm:^4.3.1" + checksum: 10c0/f63ef6e58d02a9fbf3c0e2e5f1c877da3e0bc57f91a19d2223d53e356a76859cbaf51171c9211c71816d94a0e69efa2732fd27ffc0e1bbc84b636e60932333eb + languageName: node + linkType: hard + +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.27.3, @babel/types@npm:^7.28.2, @babel/types@npm:^7.28.6, @babel/types@npm:^7.29.0": + version: 7.29.0 + resolution: "@babel/types@npm:7.29.0" + dependencies: + "@babel/helper-string-parser": "npm:^7.27.1" + "@babel/helper-validator-identifier": "npm:^7.28.5" + checksum: 10c0/23cc3466e83bcbfab8b9bd0edaafdb5d4efdb88b82b3be6728bbade5ba2f0996f84f63b1c5f7a8c0d67efded28300898a5f930b171bb40b311bca2029c4e9b4f + languageName: node + linkType: hard + +"@bcoe/v8-coverage@npm:^0.2.3": + version: 0.2.3 + resolution: "@bcoe/v8-coverage@npm:0.2.3" + checksum: 10c0/6b80ae4cb3db53f486da2dc63b6e190a74c8c3cca16bb2733f234a0b6a9382b09b146488ae08e2b22cf00f6c83e20f3e040a2f7894f05c045c946d6a090b1d52 + languageName: node + linkType: hard + +"@emnapi/core@npm:^1.4.3": + version: 1.10.0 + resolution: "@emnapi/core@npm:1.10.0" + dependencies: + "@emnapi/wasi-threads": "npm:1.2.1" + tslib: "npm:^2.4.0" + checksum: 10c0/f51d08227857b60632de7714d708124f0e100a1462dde6df8221760939aa3204a73193830371830fac0716f3ccd2129f2cac1b17cd7d7958bc4da9018a296edb + languageName: node + linkType: hard + +"@emnapi/runtime@npm:^1.4.3": + version: 1.10.0 + resolution: "@emnapi/runtime@npm:1.10.0" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/953f14991d1aefb92ee6f8eb27dea725e484791a53a0cb5f47d9e0087b9a2c929ff2e92adf95af15d6ad456db6300c6b761ebf72b50a875b874a83520b3ba093 + languageName: node + linkType: hard + +"@emnapi/wasi-threads@npm:1.2.1": + version: 1.2.1 + resolution: "@emnapi/wasi-threads@npm:1.2.1" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/32fcfa81ab396533b2ec1f4082b1ff779a05d9c836bbbd3f4398405b0e6814c0d9503b7993130e37bc6941dbc1ded49f55e9700ae9ca4e803bab2b5bc5deb331 + languageName: node + linkType: hard + +"@eslint-community/eslint-utils@npm:^4.8.0, @eslint-community/eslint-utils@npm:^4.9.1": + version: 4.9.1 + resolution: "@eslint-community/eslint-utils@npm:4.9.1" + dependencies: + eslint-visitor-keys: "npm:^3.4.3" + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + checksum: 10c0/dc4ab5e3e364ef27e33666b11f4b86e1a6c1d7cbf16f0c6ff87b1619b3562335e9201a3d6ce806221887ff780ec9d828962a290bb910759fd40a674686503f02 + languageName: node + linkType: hard + +"@eslint-community/regexpp@npm:^4.12.2": + version: 4.12.2 + resolution: "@eslint-community/regexpp@npm:4.12.2" + checksum: 10c0/fddcbc66851b308478d04e302a4d771d6917a0b3740dc351513c0da9ca2eab8a1adf99f5e0aa7ab8b13fa0df005c81adeee7e63a92f3effd7d367a163b721c2d + languageName: node + linkType: hard + +"@eslint/config-array@npm:^0.23.5": + version: 0.23.5 + resolution: "@eslint/config-array@npm:0.23.5" + dependencies: + "@eslint/object-schema": "npm:^3.0.5" + debug: "npm:^4.3.1" + minimatch: "npm:^10.2.4" + checksum: 10c0/b24833c4c76e78ee075d306cd3f095db46b2db0f90cc13a6ee6e4275f9889731c05bf5403ab5fefb79c756e07ac9184ed0e04570341382f9eccbccc80e6d1a0c + languageName: node + linkType: hard + +"@eslint/config-helpers@npm:^0.5.5": + version: 0.5.5 + resolution: "@eslint/config-helpers@npm:0.5.5" + dependencies: + "@eslint/core": "npm:^1.2.1" + checksum: 10c0/18889c062cd6bdbd4cd92fe57318c44465ea66184aa0ba204a4420712c66764c64093a7905b6c2ffde23e51b268ca2cec1a39c605d336bebf17ee1ba4f0fc0bb + languageName: node + linkType: hard + +"@eslint/core@npm:^1.2.1": + version: 1.2.1 + resolution: "@eslint/core@npm:1.2.1" + dependencies: + "@types/json-schema": "npm:^7.0.15" + checksum: 10c0/10979b40588ecfef771fcb5013a542a35fb30692cc95a65f3481b0b36fbd89f5679efeb30d57f4eed35203d859aabace2a620177d6c536f71b299a1af2f3398f + languageName: node + linkType: hard + +"@eslint/object-schema@npm:^3.0.5": + version: 3.0.5 + resolution: "@eslint/object-schema@npm:3.0.5" + checksum: 10c0/1db337431f520b99e9edda64ef5fafd7ec6a029843eeb608753025125b6649d861d843cffafafd3c4e37926d7d5f9ec0c6a8e3665c13c3da2144e8132892e92e + languageName: node + linkType: hard + +"@eslint/plugin-kit@npm:^0.7.1": + version: 0.7.1 + resolution: "@eslint/plugin-kit@npm:0.7.1" + dependencies: + "@eslint/core": "npm:^1.2.1" + levn: "npm:^0.4.1" + checksum: 10c0/335b0c1c46fd906cb50bd5ce442b9cee18dc44342ce35c718ba4a63d1aa51d2797f16a517b2f4fe371ccd777b6862fafb2dc8195e00e69197ef4cb17ab32c01b + languageName: node + linkType: hard + +"@humanfs/core@npm:^0.19.2": + version: 0.19.2 + resolution: "@humanfs/core@npm:0.19.2" + dependencies: + "@humanfs/types": "npm:^0.15.0" + checksum: 10c0/d0a1d52d7b30c27d49475a53072d1510b81c5803e44b342fb8faf3887f1aa27593a1e6dc76a45268e7892d3f4e198146659281f6b6d55eacf3fd5a38bac30c5c + languageName: node + linkType: hard + +"@humanfs/node@npm:^0.16.6": + version: 0.16.8 + resolution: "@humanfs/node@npm:0.16.8" + dependencies: + "@humanfs/core": "npm:^0.19.2" + "@humanfs/types": "npm:^0.15.0" + "@humanwhocodes/retry": "npm:^0.4.0" + checksum: 10c0/56140579db811af4e160b195d45d0f29acf644d192c93fe24c9e594ebf06f19dfc157494a07c84540b8a071c0e4b37209c2362765d31734f4d0be869c2422e25 + languageName: node + linkType: hard + +"@humanfs/types@npm:^0.15.0": + version: 0.15.0 + resolution: "@humanfs/types@npm:0.15.0" + checksum: 10c0/fc26b9a024b0e55f7eaf64036df94345bf5d36d6a41ef80ef38e78f1f7430ce26cf435af736adae58913baae18eac3f38c18739054a3d379102015978eae862e + languageName: node + linkType: hard + +"@humanwhocodes/module-importer@npm:^1.0.1": + version: 1.0.1 + resolution: "@humanwhocodes/module-importer@npm:1.0.1" + checksum: 10c0/909b69c3b86d482c26b3359db16e46a32e0fb30bd306a3c176b8313b9e7313dba0f37f519de6aa8b0a1921349e505f259d19475e123182416a506d7f87e7f529 + languageName: node + linkType: hard + +"@humanwhocodes/retry@npm:^0.4.0, @humanwhocodes/retry@npm:^0.4.2": + version: 0.4.3 + resolution: "@humanwhocodes/retry@npm:0.4.3" + checksum: 10c0/3775bb30087d4440b3f7406d5a057777d90e4b9f435af488a4923ef249e93615fb78565a85f173a186a076c7706a81d0d57d563a2624e4de2c5c9c66c486ce42 + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: "npm:^5.1.2" + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: "npm:^7.0.1" + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: "npm:^8.1.0" + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: 10c0/b1bf42535d49f11dc137f18d5e4e63a28c5569de438a221c369483731e9dac9fb797af554e8bf02b6192d1e5eba6e6402cf93900c3d0ac86391d00d04876789e + languageName: node + linkType: hard + +"@isaacs/fs-minipass@npm:^4.0.0": + version: 4.0.1 + resolution: "@isaacs/fs-minipass@npm:4.0.1" + dependencies: + minipass: "npm:^7.0.4" + checksum: 10c0/c25b6dc1598790d5b55c0947a9b7d111cfa92594db5296c3b907e2f533c033666f692a3939eadac17b1c7c40d362d0b0635dc874cbfe3e70db7c2b07cc97a5d2 + languageName: node + linkType: hard + +"@istanbuljs/load-nyc-config@npm:^1.0.0": + version: 1.1.0 + resolution: "@istanbuljs/load-nyc-config@npm:1.1.0" + dependencies: + camelcase: "npm:^5.3.1" + find-up: "npm:^4.1.0" + get-package-type: "npm:^0.1.0" + js-yaml: "npm:^3.13.1" + resolve-from: "npm:^5.0.0" + checksum: 10c0/dd2a8b094887da5a1a2339543a4933d06db2e63cbbc2e288eb6431bd832065df0c099d091b6a67436e71b7d6bf85f01ce7c15f9253b4cbebcc3b9a496165ba42 + languageName: node + linkType: hard + +"@istanbuljs/schema@npm:^0.1.2, @istanbuljs/schema@npm:^0.1.3": + version: 0.1.6 + resolution: "@istanbuljs/schema@npm:0.1.6" + checksum: 10c0/bb0d370bf3dd454d2f37f1bccb8921e2da99adacef2da56ef47850e25d7a4de69cf639ead8c189755aef38921369024b4afea3535a5c2ac9082b3e1171bcbc3a + languageName: node + linkType: hard + +"@jest/console@npm:30.3.0": + version: 30.3.0 + resolution: "@jest/console@npm:30.3.0" + dependencies: + "@jest/types": "npm:30.3.0" + "@types/node": "npm:*" + chalk: "npm:^4.1.2" + jest-message-util: "npm:30.3.0" + jest-util: "npm:30.3.0" + slash: "npm:^3.0.0" + checksum: 10c0/5458f26b0591b847b719a707cbd1d6b2b99960784a1480a28d19200a807b6092f066c1bd1810df8c6adebf934a64de7b6022dc35082cd7c8f09f35940da104d9 + languageName: node + linkType: hard + +"@jest/core@npm:30.3.0": + version: 30.3.0 + resolution: "@jest/core@npm:30.3.0" + dependencies: + "@jest/console": "npm:30.3.0" + "@jest/pattern": "npm:30.0.1" + "@jest/reporters": "npm:30.3.0" + "@jest/test-result": "npm:30.3.0" + "@jest/transform": "npm:30.3.0" + "@jest/types": "npm:30.3.0" + "@types/node": "npm:*" + ansi-escapes: "npm:^4.3.2" + chalk: "npm:^4.1.2" + ci-info: "npm:^4.2.0" + exit-x: "npm:^0.2.2" + graceful-fs: "npm:^4.2.11" + jest-changed-files: "npm:30.3.0" + jest-config: "npm:30.3.0" + jest-haste-map: "npm:30.3.0" + jest-message-util: "npm:30.3.0" + jest-regex-util: "npm:30.0.1" + jest-resolve: "npm:30.3.0" + jest-resolve-dependencies: "npm:30.3.0" + jest-runner: "npm:30.3.0" + jest-runtime: "npm:30.3.0" + jest-snapshot: "npm:30.3.0" + jest-util: "npm:30.3.0" + jest-validate: "npm:30.3.0" + jest-watcher: "npm:30.3.0" + pretty-format: "npm:30.3.0" + slash: "npm:^3.0.0" + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + checksum: 10c0/1735f2263cca10c6cae4e1dbde9c3ccb36e2cbd1cc10bac6fc45e187b06c4e33a6a029f9a6444a3cd43a2a44ffaec3b686d94f70965cebf2b885b198c8615322 + languageName: node + linkType: hard + +"@jest/diff-sequences@npm:30.3.0": + version: 30.3.0 + resolution: "@jest/diff-sequences@npm:30.3.0" + checksum: 10c0/8922c16a869b839b6c05f677023b3e5a9aa1610ad78a9c5ec8bd6654e35e8136ea1c7b60ad561910e2ad964bfdb0b09b0254ff8dcfacd4562095766f60c63d76 + languageName: node + linkType: hard + +"@jest/environment@npm:30.3.0": + version: 30.3.0 + resolution: "@jest/environment@npm:30.3.0" + dependencies: + "@jest/fake-timers": "npm:30.3.0" + "@jest/types": "npm:30.3.0" + "@types/node": "npm:*" + jest-mock: "npm:30.3.0" + checksum: 10c0/4068ccc2e4761e52909239c21e71f73b57ad087bd120b75d3232c68d911686d68fd0fb20e19725517a624b0aa9d45431b00503bd1d5ab2f4958e1a18d265d8d5 + languageName: node + linkType: hard + +"@jest/expect-utils@npm:30.3.0": + version: 30.3.0 + resolution: "@jest/expect-utils@npm:30.3.0" + dependencies: + "@jest/get-type": "npm:30.1.0" + checksum: 10c0/4bb60fb434cb8ed325735bd39171b61621e110502ecc502089805d203ecb17b9fc5a400aeffb83b41fabcc819628a9c38c955f90a716d6aaff193d10926fc854 + languageName: node + linkType: hard + +"@jest/expect@npm:30.3.0": + version: 30.3.0 + resolution: "@jest/expect@npm:30.3.0" + dependencies: + expect: "npm:30.3.0" + jest-snapshot: "npm:30.3.0" + checksum: 10c0/1e052975fdf2b977a63dc9f3db1de56be9dce8e5cd660d9c72cc25093324b990b3e93318cd0c1ff9df7cb30ec7eef71331bc7e19d39700eb3f4498e17ee4c9e0 + languageName: node + linkType: hard + +"@jest/fake-timers@npm:30.3.0": + version: 30.3.0 + resolution: "@jest/fake-timers@npm:30.3.0" + dependencies: + "@jest/types": "npm:30.3.0" + "@sinonjs/fake-timers": "npm:^15.0.0" + "@types/node": "npm:*" + jest-message-util: "npm:30.3.0" + jest-mock: "npm:30.3.0" + jest-util: "npm:30.3.0" + checksum: 10c0/114855ca14d6b34c886855445852a5b960bc3df0ef97c4b971b375747fe0206b3111ec60efc6e658565677022f0d790acd7e232e478f3390ea854d04dea0c4d8 + languageName: node + linkType: hard + +"@jest/get-type@npm:30.1.0": + version: 30.1.0 + resolution: "@jest/get-type@npm:30.1.0" + checksum: 10c0/3e65fd5015f551c51ec68fca31bbd25b466be0e8ee8075d9610fa1c686ea1e70a942a0effc7b10f4ea9a338c24337e1ad97ff69d3ebacc4681b7e3e80d1b24ac + languageName: node + linkType: hard + +"@jest/globals@npm:30.3.0": + version: 30.3.0 + resolution: "@jest/globals@npm:30.3.0" + dependencies: + "@jest/environment": "npm:30.3.0" + "@jest/expect": "npm:30.3.0" + "@jest/types": "npm:30.3.0" + jest-mock: "npm:30.3.0" + checksum: 10c0/013554dcbf75867e715801e98a5c6eefbea67cb388efd019be9e0d83979d7354874c4b33bbabc95de698215f5b891e921c26a284841504f9825fd789432b1cd0 + languageName: node + linkType: hard + +"@jest/pattern@npm:30.0.1": + version: 30.0.1 + resolution: "@jest/pattern@npm:30.0.1" + dependencies: + "@types/node": "npm:*" + jest-regex-util: "npm:30.0.1" + checksum: 10c0/32c5a7bfb6c591f004dac0ed36d645002ed168971e4c89bd915d1577031672870032594767557b855c5bc330aa1e39a2f54bf150d2ee88a7a0886e9cb65318bc + languageName: node + linkType: hard + +"@jest/reporters@npm:30.3.0": + version: 30.3.0 + resolution: "@jest/reporters@npm:30.3.0" + dependencies: + "@bcoe/v8-coverage": "npm:^0.2.3" + "@jest/console": "npm:30.3.0" + "@jest/test-result": "npm:30.3.0" + "@jest/transform": "npm:30.3.0" + "@jest/types": "npm:30.3.0" + "@jridgewell/trace-mapping": "npm:^0.3.25" + "@types/node": "npm:*" + chalk: "npm:^4.1.2" + collect-v8-coverage: "npm:^1.0.2" + exit-x: "npm:^0.2.2" + glob: "npm:^10.5.0" + graceful-fs: "npm:^4.2.11" + istanbul-lib-coverage: "npm:^3.0.0" + istanbul-lib-instrument: "npm:^6.0.0" + istanbul-lib-report: "npm:^3.0.0" + istanbul-lib-source-maps: "npm:^5.0.0" + istanbul-reports: "npm:^3.1.3" + jest-message-util: "npm:30.3.0" + jest-util: "npm:30.3.0" + jest-worker: "npm:30.3.0" + slash: "npm:^3.0.0" + string-length: "npm:^4.0.2" + v8-to-istanbul: "npm:^9.0.1" + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + checksum: 10c0/e1b6fb13df94435d4b8e6f4d4bd1c27dfc572ca7393b0a95d14c98013abe3c962aa28e2c56864f3ddd0894834d21c9a67485d11e6c31532aaaeea66ca6a2a026 + languageName: node + linkType: hard + +"@jest/schemas@npm:30.0.5": + version: 30.0.5 + resolution: "@jest/schemas@npm:30.0.5" + dependencies: + "@sinclair/typebox": "npm:^0.34.0" + checksum: 10c0/449dcd7ec5c6505e9ac3169d1143937e67044ae3e66a729ce4baf31812dfd30535f2b3b2934393c97cfdf5984ff581120e6b38f62b8560c8b5b7cc07f4175f65 + languageName: node + linkType: hard + +"@jest/snapshot-utils@npm:30.3.0": + version: 30.3.0 + resolution: "@jest/snapshot-utils@npm:30.3.0" + dependencies: + "@jest/types": "npm:30.3.0" + chalk: "npm:^4.1.2" + graceful-fs: "npm:^4.2.11" + natural-compare: "npm:^1.4.0" + checksum: 10c0/ba4fea05a418b257d128d8f9eb7672a9004952563a45ad577bed80e5b2ea2ec6e6d3a24535781cc6530d9904d8fda7b27d15952d079ccdbe88f87a5e71112df0 + languageName: node + linkType: hard + +"@jest/source-map@npm:30.0.1": + version: 30.0.1 + resolution: "@jest/source-map@npm:30.0.1" + dependencies: + "@jridgewell/trace-mapping": "npm:^0.3.25" + callsites: "npm:^3.1.0" + graceful-fs: "npm:^4.2.11" + checksum: 10c0/e7bda2786fc9f483d9dd7566c58c4bd948830997be862dfe80a3ae5550ff3f84753abb52e705d02ebe9db9f34ba7ebec4c2db11882048cdeef7a66f6332b3897 + languageName: node + linkType: hard + +"@jest/test-result@npm:30.3.0": + version: 30.3.0 + resolution: "@jest/test-result@npm:30.3.0" + dependencies: + "@jest/console": "npm:30.3.0" + "@jest/types": "npm:30.3.0" + "@types/istanbul-lib-coverage": "npm:^2.0.6" + collect-v8-coverage: "npm:^1.0.2" + checksum: 10c0/67bcd405d0a1ac85b55afabf26e0ee0f184f9cfe0e659a44e0e4a4456c1c7fed9d2288f0116b017eaddfa49ded8c44426b8694c44f9a8a2af35be9202b8a9165 + languageName: node + linkType: hard + +"@jest/test-sequencer@npm:30.3.0": + version: 30.3.0 + resolution: "@jest/test-sequencer@npm:30.3.0" + dependencies: + "@jest/test-result": "npm:30.3.0" + graceful-fs: "npm:^4.2.11" + jest-haste-map: "npm:30.3.0" + slash: "npm:^3.0.0" + checksum: 10c0/698be35e7145e79ea9d66071d4ec255f6cef4b5972b5142d299f3edbcbc0428cadf8ddecc6d21e938c98ed72b73b15a6d5f81e7b8b370aaa130d2f6b26fd017c + languageName: node + linkType: hard + +"@jest/transform@npm:30.3.0": + version: 30.3.0 + resolution: "@jest/transform@npm:30.3.0" + dependencies: + "@babel/core": "npm:^7.27.4" + "@jest/types": "npm:30.3.0" + "@jridgewell/trace-mapping": "npm:^0.3.25" + babel-plugin-istanbul: "npm:^7.0.1" + chalk: "npm:^4.1.2" + convert-source-map: "npm:^2.0.0" + fast-json-stable-stringify: "npm:^2.1.0" + graceful-fs: "npm:^4.2.11" + jest-haste-map: "npm:30.3.0" + jest-regex-util: "npm:30.0.1" + jest-util: "npm:30.3.0" + pirates: "npm:^4.0.7" + slash: "npm:^3.0.0" + write-file-atomic: "npm:^5.0.1" + checksum: 10c0/5ad0b5361910680b5160e3dc347c0beb75b4edc35a165ef4fc55837d01365179c276dd6f9cc80f7db94048c641b0c188757e1c98c6d4e9b55577956efbc00574 + languageName: node + linkType: hard + +"@jest/types@npm:30.3.0": + version: 30.3.0 + resolution: "@jest/types@npm:30.3.0" + dependencies: + "@jest/pattern": "npm:30.0.1" + "@jest/schemas": "npm:30.0.5" + "@types/istanbul-lib-coverage": "npm:^2.0.6" + "@types/istanbul-reports": "npm:^3.0.4" + "@types/node": "npm:*" + "@types/yargs": "npm:^17.0.33" + chalk: "npm:^4.1.2" + checksum: 10c0/c3e3f4de0b77a7ced345f47d3687b1094c1b6c1521529a7ca66a76f9a80194f79179a1dbc32d6761a5b67914a8f78be1e65d1408107efcb1f252c4a63b5ddd92 + languageName: node + linkType: hard + +"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.5": + version: 0.3.13 + resolution: "@jridgewell/gen-mapping@npm:0.3.13" + dependencies: + "@jridgewell/sourcemap-codec": "npm:^1.5.0" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10c0/9a7d65fb13bd9aec1fbab74cda08496839b7e2ceb31f5ab922b323e94d7c481ce0fc4fd7e12e2610915ed8af51178bdc61e168e92a8c8b8303b030b03489b13b + languageName: node + linkType: hard + +"@jridgewell/remapping@npm:^2.3.5": + version: 2.3.5 + resolution: "@jridgewell/remapping@npm:2.3.5" + dependencies: + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.24" + checksum: 10c0/3de494219ffeb2c5c38711d0d7bb128097edf91893090a2dbc8ee0b55d092bb7347b1fd0f478486c5eab010e855c73927b1666f2107516d472d24a73017d1194 + languageName: node + linkType: hard + +"@jridgewell/resolve-uri@npm:^3.1.0": + version: 3.1.2 + resolution: "@jridgewell/resolve-uri@npm:3.1.2" + checksum: 10c0/d502e6fb516b35032331406d4e962c21fe77cdf1cbdb49c6142bcbd9e30507094b18972778a6e27cbad756209cfe34b1a27729e6fa08a2eb92b33943f680cf1e + languageName: node + linkType: hard + +"@jridgewell/source-map@npm:^0.3.3": + version: 0.3.11 + resolution: "@jridgewell/source-map@npm:0.3.11" + dependencies: + "@jridgewell/gen-mapping": "npm:^0.3.5" + "@jridgewell/trace-mapping": "npm:^0.3.25" + checksum: 10c0/50a4fdafe0b8f655cb2877e59fe81320272eaa4ccdbe6b9b87f10614b2220399ae3e05c16137a59db1f189523b42c7f88bd097ee991dbd7bc0e01113c583e844 + languageName: node + linkType: hard + +"@jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0": + version: 1.5.5 + resolution: "@jridgewell/sourcemap-codec@npm:1.5.5" + checksum: 10c0/f9e538f302b63c0ebc06eecb1dd9918dd4289ed36147a0ddce35d6ea4d7ebbda243cda7b2213b6a5e1d8087a298d5cf630fb2bd39329cdecb82017023f6081a0 + languageName: node + linkType: hard + +"@jridgewell/trace-mapping@npm:^0.3.12, @jridgewell/trace-mapping@npm:^0.3.23, @jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.25, @jridgewell/trace-mapping@npm:^0.3.28": + version: 0.3.31 + resolution: "@jridgewell/trace-mapping@npm:0.3.31" + dependencies: + "@jridgewell/resolve-uri": "npm:^3.1.0" + "@jridgewell/sourcemap-codec": "npm:^1.4.14" + checksum: 10c0/4b30ec8cd56c5fd9a661f088230af01e0c1a3888d11ffb6b47639700f71225be21d1f7e168048d6d4f9449207b978a235c07c8f15c07705685d16dc06280e9d9 + languageName: node + linkType: hard + +"@napi-rs/wasm-runtime@npm:^0.2.11": + version: 0.2.12 + resolution: "@napi-rs/wasm-runtime@npm:0.2.12" + dependencies: + "@emnapi/core": "npm:^1.4.3" + "@emnapi/runtime": "npm:^1.4.3" + "@tybys/wasm-util": "npm:^0.10.0" + checksum: 10c0/6d07922c0613aab30c6a497f4df297ca7c54e5b480e00035e0209b872d5c6aab7162fc49477267556109c2c7ed1eb9c65a174e27e9b87568106a87b0a6e3ca7d + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 10c0/5bd7576bb1b38a47a7fc7b51ac9f38748e772beebc56200450c4a817d712232b8f1d3ef70532c80840243c657d491cf6a6be1e3a214cff907645819fdc34aadd + languageName: node + linkType: hard + +"@pkgr/core@npm:^0.2.9": + version: 0.2.9 + resolution: "@pkgr/core@npm:0.2.9" + checksum: 10c0/ac8e4e8138b1a7a4ac6282873aef7389c352f1f8b577b4850778f5182e4a39a5241facbe48361fec817f56d02b51691b383010843fb08b34a8e8ea3614688fd5 + languageName: node + linkType: hard + +"@rollup/plugin-node-resolve@npm:^16.0.3": + version: 16.0.3 + resolution: "@rollup/plugin-node-resolve@npm:16.0.3" + dependencies: + "@rollup/pluginutils": "npm:^5.0.1" + "@types/resolve": "npm:1.20.2" + deepmerge: "npm:^4.2.2" + is-module: "npm:^1.0.0" + resolve: "npm:^1.22.1" + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + checksum: 10c0/5bafff8e51cd28b5b3b8f415c30a893f5bfdb1a54469e00b3dc6530f26051620f3dfa172f40544361948b46cc3070cb34fd44ade66d38c0677d74c846fbc58dc + languageName: node + linkType: hard + +"@rollup/plugin-terser@npm:^1.0.0": + version: 1.0.0 + resolution: "@rollup/plugin-terser@npm:1.0.0" + dependencies: + serialize-javascript: "npm:^7.0.3" + smob: "npm:^1.0.0" + terser: "npm:^5.17.4" + peerDependencies: + rollup: ^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + checksum: 10c0/08be445cc2e0677132ee06cdebbcd1b6cd3ab22e220fcd89d8a22eaf9ee501a940f425931ac65c65ab113803ad31a895f2575716248609c882c8e562fd6cc2d4 + languageName: node + linkType: hard + +"@rollup/plugin-typescript@npm:^12.3.0": + version: 12.3.0 + resolution: "@rollup/plugin-typescript@npm:12.3.0" + dependencies: + "@rollup/pluginutils": "npm:^5.1.0" + resolve: "npm:^1.22.1" + peerDependencies: + rollup: ^2.14.0||^3.0.0||^4.0.0 + tslib: "*" + typescript: ">=3.7.0" + peerDependenciesMeta: + rollup: + optional: true + tslib: + optional: true + checksum: 10c0/41d14e9a9792d8d9751c275cf87c2de796ddd1a64c96fedc622baad8cfbb1247537e37ae428e59e1850de7d7165941ee1a4030dbe9bebd5fbb38c5e4f751d8b5 + languageName: node + linkType: hard + +"@rollup/pluginutils@npm:^5.0.1, @rollup/pluginutils@npm:^5.1.0": + version: 5.3.0 + resolution: "@rollup/pluginutils@npm:5.3.0" + dependencies: + "@types/estree": "npm:^1.0.0" + estree-walker: "npm:^2.0.2" + picomatch: "npm:^4.0.2" + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + checksum: 10c0/001834bf62d7cf5bac424d2617c113f7f7d3b2bf3c1778cbcccb72cdc957b68989f8e7747c782c2b911f1dde8257f56f8ac1e779e29e74e638e3f1e2cac2bcd0 + languageName: node + linkType: hard + +"@rollup/rollup-android-arm-eabi@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.60.2" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@rollup/rollup-android-arm64@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-android-arm64@npm:4.60.2" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-arm64@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-darwin-arm64@npm:4.60.2" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-darwin-x64@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-darwin-x64@npm:4.60.2" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-arm64@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.60.2" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-freebsd-x64@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-freebsd-x64@npm:4.60.2" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-gnueabihf@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.60.2" + conditions: os=linux & cpu=arm & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm-musleabihf@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.60.2" + conditions: os=linux & cpu=arm & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-gnu@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.60.2" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-arm64-musl@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.60.2" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-loong64-gnu@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-linux-loong64-gnu@npm:4.60.2" + conditions: os=linux & cpu=loong64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-loong64-musl@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-linux-loong64-musl@npm:4.60.2" + conditions: os=linux & cpu=loong64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-ppc64-gnu@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.60.2" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-ppc64-musl@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-linux-ppc64-musl@npm:4.60.2" + conditions: os=linux & cpu=ppc64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-gnu@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.60.2" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-riscv64-musl@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.60.2" + conditions: os=linux & cpu=riscv64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-linux-s390x-gnu@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.60.2" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-gnu@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.60.2" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@rollup/rollup-linux-x64-musl@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.60.2" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@rollup/rollup-openbsd-x64@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-openbsd-x64@npm:4.60.2" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-openharmony-arm64@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-openharmony-arm64@npm:4.60.2" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-arm64-msvc@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.60.2" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-ia32-msvc@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.60.2" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@rollup/rollup-win32-x64-gnu@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-win32-x64-gnu@npm:4.60.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@rollup/rollup-win32-x64-msvc@npm:4.60.2": + version: 4.60.2 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.60.2" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"@sinclair/typebox@npm:^0.34.0": + version: 0.34.49 + resolution: "@sinclair/typebox@npm:0.34.49" + checksum: 10c0/16b7d87f039a49b68c10bb4cdcae2ce5242b2472228851fd6483731616aba4ef977690aa517b230a8d20da8185bb416eb34e326f30568b3963c1cf26b05d1ad8 + languageName: node + linkType: hard + +"@sinonjs/commons@npm:^3.0.1": + version: 3.0.1 + resolution: "@sinonjs/commons@npm:3.0.1" + dependencies: + type-detect: "npm:4.0.8" + checksum: 10c0/1227a7b5bd6c6f9584274db996d7f8cee2c8c350534b9d0141fc662eaf1f292ea0ae3ed19e5e5271c8fd390d27e492ca2803acd31a1978be2cdc6be0da711403 + languageName: node + linkType: hard + +"@sinonjs/fake-timers@npm:^15.0.0": + version: 15.3.2 + resolution: "@sinonjs/fake-timers@npm:15.3.2" + dependencies: + "@sinonjs/commons": "npm:^3.0.1" + checksum: 10c0/fea39af47e70acf7f6b431b857dc5b50886e1a19d48189bc7f9cf90806a9fdfd4931c04343558724772d429c47fb53df640fc8c8d6ddf6ad66164bd7cbd3220a + languageName: node + linkType: hard + +"@sourceacademy/common-cse@file:../../common/cse::locator=%40sourceacademy%2Fweb-cse%40workspace%3Asrc%2Fweb%2Fcse": + version: 0.0.0 + resolution: "@sourceacademy/common-cse@file:../../common/cse#../../common/cse::hash=34d89a&locator=%40sourceacademy%2Fweb-cse%40workspace%3Asrc%2Fweb%2Fcse" + checksum: 10c0/e395e96ad0e08ffdff5a47c106e1af4a0eb39dc4833c52420e07a951260693fb2c4ec75d65d5405db84dae291b8136ef42ca05d0a7f0a4769dd5729102dcfa32 + languageName: node + linkType: hard + +"@sourceacademy/common-cse@workspace:src/common/cse": + version: 0.0.0-use.local + resolution: "@sourceacademy/common-cse@workspace:src/common/cse" + languageName: unknown + linkType: soft + +"@sourceacademy/conductor@npm:^0.3.0": + version: 0.3.0 + resolution: "@sourceacademy/conductor@npm:0.3.0" + checksum: 10c0/e6d50cc0b9188fa5ec54c3bb2e6b9a0f9391ba37449e74a326c89c4e14deb00c4882700062427737e6f6fca556fd95d91fa9d7f6e125fe1d43938a65cc3c0c4d + languageName: node + linkType: hard + +"@sourceacademy/runner-cse@workspace:src/runner/cse": + version: 0.0.0-use.local + resolution: "@sourceacademy/runner-cse@workspace:src/runner/cse" + languageName: unknown + linkType: soft + +"@sourceacademy/web-cse@workspace:src/web/cse": + version: 0.0.0-use.local + resolution: "@sourceacademy/web-cse@workspace:src/web/cse" + dependencies: + "@sourceacademy/common-cse": ../../common/cse + "@types/react": "npm:^19.2.14" + "@types/react-dom": "npm:^19.2.3" + konva: "npm:^10.2.5" + react: "npm:^19.2.5" + react-dom: "npm:^19.2.5" + react-konva: "npm:^19.2.3" + typescript: "npm:^6.0.3" + languageName: unknown + linkType: soft + +"@tybys/wasm-util@npm:^0.10.0": + version: 0.10.1 + resolution: "@tybys/wasm-util@npm:0.10.1" + dependencies: + tslib: "npm:^2.4.0" + checksum: 10c0/b255094f293794c6d2289300c5fbcafbb5532a3aed3a5ffd2f8dc1828e639b88d75f6a376dd8f94347a44813fd7a7149d8463477a9a49525c8b2dcaa38c2d1e8 + languageName: node + linkType: hard + +"@types/babel__core@npm:^7.20.5": + version: 7.20.5 + resolution: "@types/babel__core@npm:7.20.5" + dependencies: + "@babel/parser": "npm:^7.20.7" + "@babel/types": "npm:^7.20.7" + "@types/babel__generator": "npm:*" + "@types/babel__template": "npm:*" + "@types/babel__traverse": "npm:*" + checksum: 10c0/bdee3bb69951e833a4b811b8ee9356b69a61ed5b7a23e1a081ec9249769117fa83aaaf023bb06562a038eb5845155ff663e2d5c75dd95c1d5ccc91db012868ff + languageName: node + linkType: hard + +"@types/babel__generator@npm:*": + version: 7.27.0 + resolution: "@types/babel__generator@npm:7.27.0" + dependencies: + "@babel/types": "npm:^7.0.0" + checksum: 10c0/9f9e959a8792df208a9d048092fda7e1858bddc95c6314857a8211a99e20e6830bdeb572e3587ae8be5429e37f2a96fcf222a9f53ad232f5537764c9e13a2bbd + languageName: node + linkType: hard + +"@types/babel__template@npm:*": + version: 7.4.4 + resolution: "@types/babel__template@npm:7.4.4" + dependencies: + "@babel/parser": "npm:^7.1.0" + "@babel/types": "npm:^7.0.0" + checksum: 10c0/cc84f6c6ab1eab1427e90dd2b76ccee65ce940b778a9a67be2c8c39e1994e6f5bbc8efa309f6cea8dc6754994524cd4d2896558df76d92e7a1f46ecffee7112b + languageName: node + linkType: hard + +"@types/babel__traverse@npm:*": + version: 7.28.0 + resolution: "@types/babel__traverse@npm:7.28.0" + dependencies: + "@babel/types": "npm:^7.28.2" + checksum: 10c0/b52d7d4e8fc6a9018fe7361c4062c1c190f5778cf2466817cb9ed19d69fbbb54f9a85ffedeb748ed8062d2cf7d4cc088ee739848f47c57740de1c48cbf0d0994 + languageName: node + linkType: hard + +"@types/esrecurse@npm:^4.3.1": + version: 4.3.1 + resolution: "@types/esrecurse@npm:4.3.1" + checksum: 10c0/90dad74d5da3ad27606d8e8e757322f33171cfeaa15ad558b615cf71bb2a516492d18f55f4816384685a3eb2412142e732bbae9a4a7cd2cf3deb7572aa4ebe03 + languageName: node + linkType: hard + +"@types/estree@npm:1.0.8, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.6, @types/estree@npm:^1.0.8": + version: 1.0.8 + resolution: "@types/estree@npm:1.0.8" + checksum: 10c0/39d34d1afaa338ab9763f37ad6066e3f349444f9052b9676a7cc0252ef9485a41c6d81c9c4e0d26e9077993354edf25efc853f3224dd4b447175ef62bdcc86a5 + languageName: node + linkType: hard + +"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.1, @types/istanbul-lib-coverage@npm:^2.0.6": + version: 2.0.6 + resolution: "@types/istanbul-lib-coverage@npm:2.0.6" + checksum: 10c0/3948088654f3eeb45363f1db158354fb013b362dba2a5c2c18c559484d5eb9f6fd85b23d66c0a7c2fcfab7308d0a585b14dadaca6cc8bf89ebfdc7f8f5102fb7 + languageName: node + linkType: hard + +"@types/istanbul-lib-report@npm:*": + version: 3.0.3 + resolution: "@types/istanbul-lib-report@npm:3.0.3" + dependencies: + "@types/istanbul-lib-coverage": "npm:*" + checksum: 10c0/247e477bbc1a77248f3c6de5dadaae85ff86ac2d76c5fc6ab1776f54512a745ff2a5f791d22b942e3990ddbd40f3ef5289317c4fca5741bedfaa4f01df89051c + languageName: node + linkType: hard + +"@types/istanbul-reports@npm:^3.0.4": + version: 3.0.4 + resolution: "@types/istanbul-reports@npm:3.0.4" + dependencies: + "@types/istanbul-lib-report": "npm:*" + checksum: 10c0/1647fd402aced5b6edac87274af14ebd6b3a85447ef9ad11853a70fd92a98d35f81a5d3ea9fcb5dbb5834e800c6e35b64475e33fcae6bfa9acc70d61497c54ee + languageName: node + linkType: hard + +"@types/jest@npm:^30.0.0": + version: 30.0.0 + resolution: "@types/jest@npm:30.0.0" + dependencies: + expect: "npm:^30.0.0" + pretty-format: "npm:^30.0.0" + checksum: 10c0/20c6ce574154bc16f8dd6a97afacca4b8c4921a819496a3970382031c509ebe87a1b37b152a1b8475089b82d8ca951a9e95beb4b9bf78fbf579b1536f0b65969 + languageName: node + linkType: hard + +"@types/json-schema@npm:^7.0.15": + version: 7.0.15 + resolution: "@types/json-schema@npm:7.0.15" + checksum: 10c0/a996a745e6c5d60292f36731dd41341339d4eeed8180bb09226e5c8d23759067692b1d88e5d91d72ee83dfc00d3aca8e7bd43ea120516c17922cbcb7c3e252db + languageName: node + linkType: hard + +"@types/node@npm:*": + version: 25.6.0 + resolution: "@types/node@npm:25.6.0" + dependencies: + undici-types: "npm:~7.19.0" + checksum: 10c0/d2d2015630ff098a201407f55f5077a20270ae4f465c739b40865cd9933b91b9c5d2b85568eadaf3db0801b91e267333ca7eb39f007428b173d1cdab4b339ac5 + languageName: node + linkType: hard + +"@types/react-dom@npm:^19.2.3": + version: 19.2.3 + resolution: "@types/react-dom@npm:19.2.3" + peerDependencies: + "@types/react": ^19.2.0 + checksum: 10c0/b486ebe0f4e2fb35e2e108df1d8fc0927ca5d6002d5771e8a739de11239fe62d0e207c50886185253c99eb9dedfeeb956ea7429e5ba17f6693c7acb4c02f8cd1 + languageName: node + linkType: hard + +"@types/react-reconciler@npm:^0.28.9": + version: 0.28.9 + resolution: "@types/react-reconciler@npm:0.28.9" + peerDependencies: + "@types/react": "*" + checksum: 10c0/9fe71fa856aab2cd4742fe0416bdd4f5c82ecc05ef6451ee7fcb65a5efdf5fa588f5820fbe2a665b15371b0da3bfc4097f28bb6d450b9a834af2d0fc00f403bd + languageName: node + linkType: hard + +"@types/react-reconciler@npm:^0.33.0": + version: 0.33.0 + resolution: "@types/react-reconciler@npm:0.33.0" + peerDependencies: + "@types/react": "*" + checksum: 10c0/190c203d93c0df9a42fabd693ce059dbdf6c53e15eb14502d9e5b946c981231c5846b867de15522ff61368e9218a8508a9db5476f3e47b5d664bbb2c84b31ac7 + languageName: node + linkType: hard + +"@types/react@npm:^19.2.14": + version: 19.2.14 + resolution: "@types/react@npm:19.2.14" + dependencies: + csstype: "npm:^3.2.2" + checksum: 10c0/7d25bf41b57719452d86d2ac0570b659210402707313a36ee612666bf11275a1c69824f8c3ee1fdca077ccfe15452f6da8f1224529b917050eb2d861e52b59b7 + languageName: node + linkType: hard + +"@types/resolve@npm:1.20.2": + version: 1.20.2 + resolution: "@types/resolve@npm:1.20.2" + checksum: 10c0/c5b7e1770feb5ccfb6802f6ad82a7b0d50874c99331e0c9b259e415e55a38d7a86ad0901c57665d93f75938be2a6a0bc9aa06c9749192cadb2e4512800bbc6e6 + languageName: node + linkType: hard + +"@types/stack-utils@npm:^2.0.3": + version: 2.0.3 + resolution: "@types/stack-utils@npm:2.0.3" + checksum: 10c0/1f4658385ae936330581bcb8aa3a066df03867d90281cdf89cc356d404bd6579be0f11902304e1f775d92df22c6dd761d4451c804b0a4fba973e06211e9bd77c + languageName: node + linkType: hard + +"@types/yargs-parser@npm:*": + version: 21.0.3 + resolution: "@types/yargs-parser@npm:21.0.3" + checksum: 10c0/e71c3bd9d0b73ca82e10bee2064c384ab70f61034bbfb78e74f5206283fc16a6d85267b606b5c22cb2a3338373586786fed595b2009825d6a9115afba36560a0 + languageName: node + linkType: hard + +"@types/yargs@npm:^17.0.33": + version: 17.0.35 + resolution: "@types/yargs@npm:17.0.35" + dependencies: + "@types/yargs-parser": "npm:*" + checksum: 10c0/609557826a6b85e73ccf587923f6429850d6dc70e420b455bab4601b670bfadf684b09ae288bccedab042c48ba65f1666133cf375814204b544009f57d6eef63 + languageName: node + linkType: hard + +"@typescript-eslint/eslint-plugin@npm:8.59.1": + version: 8.59.1 + resolution: "@typescript-eslint/eslint-plugin@npm:8.59.1" + dependencies: + "@eslint-community/regexpp": "npm:^4.12.2" + "@typescript-eslint/scope-manager": "npm:8.59.1" + "@typescript-eslint/type-utils": "npm:8.59.1" + "@typescript-eslint/utils": "npm:8.59.1" + "@typescript-eslint/visitor-keys": "npm:8.59.1" + ignore: "npm:^7.0.5" + natural-compare: "npm:^1.4.0" + ts-api-utils: "npm:^2.5.0" + peerDependencies: + "@typescript-eslint/parser": ^8.59.1 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10c0/6dedd272d1aac960df74ab81e38bb4b398ac11b52118c69493a3aeecd15984c83bd4cae89df2e8362fbc2213f0a6d68c00d71dd53868fa1b5e1011290d4ea7b6 + languageName: node + linkType: hard + +"@typescript-eslint/parser@npm:8.59.1": + version: 8.59.1 + resolution: "@typescript-eslint/parser@npm:8.59.1" + dependencies: + "@typescript-eslint/scope-manager": "npm:8.59.1" + "@typescript-eslint/types": "npm:8.59.1" + "@typescript-eslint/typescript-estree": "npm:8.59.1" + "@typescript-eslint/visitor-keys": "npm:8.59.1" + debug: "npm:^4.4.3" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10c0/a20271b96e35fa5a8deea11ec40b30f7987daa5c3402e6e763e474517a25af20749a620490af159c2a65048065dea8a6d5fa3527ccc7a3716c2cd648a05ebc55 + languageName: node + linkType: hard + +"@typescript-eslint/project-service@npm:8.59.1": + version: 8.59.1 + resolution: "@typescript-eslint/project-service@npm:8.59.1" + dependencies: + "@typescript-eslint/tsconfig-utils": "npm:^8.59.1" + "@typescript-eslint/types": "npm:^8.59.1" + debug: "npm:^4.4.3" + peerDependencies: + typescript: ">=4.8.4 <6.1.0" + checksum: 10c0/487e60e9696fbae11070fd0591a009c94b932af2a92d37a1a9d9f9eac5bbc2f56fef83f3d4e72349dfdaadf95473bb5fb7332eb13f9296b87b3f14e842f42747 + languageName: node + linkType: hard + +"@typescript-eslint/scope-manager@npm:8.59.1": + version: 8.59.1 + resolution: "@typescript-eslint/scope-manager@npm:8.59.1" + dependencies: + "@typescript-eslint/types": "npm:8.59.1" + "@typescript-eslint/visitor-keys": "npm:8.59.1" + checksum: 10c0/05c19039bde67691ad7a558ac61260639593ab0ffd8b73903b0f23c770aa3d79868bc8c1a11cdd5b0c8226e5dcef9ab1d679db46b5c5fe019541216170451614 + languageName: node + linkType: hard + +"@typescript-eslint/tsconfig-utils@npm:8.59.1, @typescript-eslint/tsconfig-utils@npm:^8.59.1": + version: 8.59.1 + resolution: "@typescript-eslint/tsconfig-utils@npm:8.59.1" + peerDependencies: + typescript: ">=4.8.4 <6.1.0" + checksum: 10c0/a3d123edbc39e7bfa3f58f722fe755787e71771d97b03ed80ea0706dcf3f25895e217e61b38049db1b05f246a26c6afb4e4a518bad21e7d1e71bb8dc136084ce + languageName: node + linkType: hard + +"@typescript-eslint/type-utils@npm:8.59.1": + version: 8.59.1 + resolution: "@typescript-eslint/type-utils@npm:8.59.1" + dependencies: + "@typescript-eslint/types": "npm:8.59.1" + "@typescript-eslint/typescript-estree": "npm:8.59.1" + "@typescript-eslint/utils": "npm:8.59.1" + debug: "npm:^4.4.3" + ts-api-utils: "npm:^2.5.0" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10c0/c5f0f8e53f85ddf796a45b485937b7d5aef5c884fed412ff945392376166242658e4b431bd9633e1e08d6dba7e83b6125283e4866f5a9b4ae61fec355705122d + languageName: node + linkType: hard + +"@typescript-eslint/types@npm:8.59.1, @typescript-eslint/types@npm:^8.59.1": + version: 8.59.1 + resolution: "@typescript-eslint/types@npm:8.59.1" + checksum: 10c0/a0bf98389e8673d4aa1034fdef9bb78f576b3dc6b8f413d4adf07ef6edff4a33fdb916148c3bac2cafdbf282c765eebf253c2a05edf3fda4123b8889921cd518 + languageName: node + linkType: hard + +"@typescript-eslint/typescript-estree@npm:8.59.1": + version: 8.59.1 + resolution: "@typescript-eslint/typescript-estree@npm:8.59.1" + dependencies: + "@typescript-eslint/project-service": "npm:8.59.1" + "@typescript-eslint/tsconfig-utils": "npm:8.59.1" + "@typescript-eslint/types": "npm:8.59.1" + "@typescript-eslint/visitor-keys": "npm:8.59.1" + debug: "npm:^4.4.3" + minimatch: "npm:^10.2.2" + semver: "npm:^7.7.3" + tinyglobby: "npm:^0.2.15" + ts-api-utils: "npm:^2.5.0" + peerDependencies: + typescript: ">=4.8.4 <6.1.0" + checksum: 10c0/80b2624185d303741a710ba90e4fcb4e52320c1fc614f62cce785bfb39dfb9560ea5d325ff590d929c689b7dae7c28a598a26e1862477cc108c4ae4e8fe62c78 + languageName: node + linkType: hard + +"@typescript-eslint/utils@npm:8.59.1": + version: 8.59.1 + resolution: "@typescript-eslint/utils@npm:8.59.1" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.9.1" + "@typescript-eslint/scope-manager": "npm:8.59.1" + "@typescript-eslint/types": "npm:8.59.1" + "@typescript-eslint/typescript-estree": "npm:8.59.1" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10c0/82a3fdb52d5f54622f8796eaeca508c630e65bfb94423645c1097b377fd56cf43b2999a83f11f42924e0cbb93b22faca6e572ee27cf550795b99e22193a0d41c + languageName: node + linkType: hard + +"@typescript-eslint/visitor-keys@npm:8.59.1": + version: 8.59.1 + resolution: "@typescript-eslint/visitor-keys@npm:8.59.1" + dependencies: + "@typescript-eslint/types": "npm:8.59.1" + eslint-visitor-keys: "npm:^5.0.0" + checksum: 10c0/1144426dda53e855698301eae6301ae928785915225e6a775f0b51bf5d67b67e90def7b851e851ce76235cff3e1324132d03c7843a33ce2c4f0eb0764cc2b80a + languageName: node + linkType: hard + +"@ungap/structured-clone@npm:^1.3.0": + version: 1.3.0 + resolution: "@ungap/structured-clone@npm:1.3.0" + checksum: 10c0/0fc3097c2540ada1fc340ee56d58d96b5b536a2a0dab6e3ec17d4bfc8c4c86db345f61a375a8185f9da96f01c69678f836a2b57eeaa9e4b8eeafd26428e57b0a + languageName: node + linkType: hard + +"@unrs/resolver-binding-android-arm-eabi@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-android-arm-eabi@npm:1.11.1" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@unrs/resolver-binding-android-arm64@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-android-arm64@npm:1.11.1" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-darwin-arm64@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-darwin-arm64@npm:1.11.1" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-darwin-x64@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-darwin-x64@npm:1.11.1" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-freebsd-x64@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-freebsd-x64@npm:1.11.1" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-arm-gnueabihf@npm:1.11.1" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm-musleabihf@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-arm-musleabihf@npm:1.11.1" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm64-gnu@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-arm64-gnu@npm:1.11.1" + conditions: os=linux & cpu=arm64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-arm64-musl@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-arm64-musl@npm:1.11.1" + conditions: os=linux & cpu=arm64 & libc=musl + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-ppc64-gnu@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-ppc64-gnu@npm:1.11.1" + conditions: os=linux & cpu=ppc64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-riscv64-gnu@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-riscv64-gnu@npm:1.11.1" + conditions: os=linux & cpu=riscv64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-riscv64-musl@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-riscv64-musl@npm:1.11.1" + conditions: os=linux & cpu=riscv64 & libc=musl + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-s390x-gnu@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-s390x-gnu@npm:1.11.1" + conditions: os=linux & cpu=s390x & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-x64-gnu@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-x64-gnu@npm:1.11.1" + conditions: os=linux & cpu=x64 & libc=glibc + languageName: node + linkType: hard + +"@unrs/resolver-binding-linux-x64-musl@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-linux-x64-musl@npm:1.11.1" + conditions: os=linux & cpu=x64 & libc=musl + languageName: node + linkType: hard + +"@unrs/resolver-binding-wasm32-wasi@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-wasm32-wasi@npm:1.11.1" + dependencies: + "@napi-rs/wasm-runtime": "npm:^0.2.11" + conditions: cpu=wasm32 + languageName: node + linkType: hard + +"@unrs/resolver-binding-win32-arm64-msvc@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-win32-arm64-msvc@npm:1.11.1" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@unrs/resolver-binding-win32-ia32-msvc@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-win32-ia32-msvc@npm:1.11.1" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@unrs/resolver-binding-win32-x64-msvc@npm:1.11.1": + version: 1.11.1 + resolution: "@unrs/resolver-binding-win32-x64-msvc@npm:1.11.1" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + +"abbrev@npm:^4.0.0": + version: 4.0.0 + resolution: "abbrev@npm:4.0.0" + checksum: 10c0/b4cc16935235e80702fc90192e349e32f8ef0ed151ef506aa78c81a7c455ec18375c4125414b99f84b2e055199d66383e787675f0bcd87da7a4dbd59f9eac1d5 + languageName: node + linkType: hard + +"acorn-jsx@npm:^5.3.2": + version: 5.3.2 + resolution: "acorn-jsx@npm:5.3.2" + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + checksum: 10c0/4c54868fbef3b8d58927d5e33f0a4de35f59012fe7b12cf9dfbb345fb8f46607709e1c4431be869a23fb63c151033d84c4198fa9f79385cec34fcb1dd53974c1 + languageName: node + linkType: hard + +"acorn@npm:^8.15.0, acorn@npm:^8.16.0": + version: 8.16.0 + resolution: "acorn@npm:8.16.0" + bin: + acorn: bin/acorn + checksum: 10c0/c9c52697227661b68d0debaf972222d4f622aa06b185824164e153438afa7b08273432ca43ea792cadb24dada1d46f6f6bb1ef8de9956979288cc1b96bf9914e + languageName: node + linkType: hard + +"ajv@npm:^6.14.0": + version: 6.15.0 + resolution: "ajv@npm:6.15.0" + dependencies: + fast-deep-equal: "npm:^3.1.1" + fast-json-stable-stringify: "npm:^2.0.0" + json-schema-traverse: "npm:^0.4.1" + uri-js: "npm:^4.2.2" + checksum: 10c0/67966499dd272ecde1c2e467084411132891523d057487587879d39ac04207f4351b7b2324c83198013967fbfa632c1612adc960114a30770fbe07a0773b32c2 + languageName: node + linkType: hard + +"ansi-escapes@npm:^4.3.2": + version: 4.3.2 + resolution: "ansi-escapes@npm:4.3.2" + dependencies: + type-fest: "npm:^0.21.3" + checksum: 10c0/da917be01871525a3dfcf925ae2977bc59e8c513d4423368645634bf5d4ceba5401574eb705c1e92b79f7292af5a656f78c5725a4b0e1cec97c4b413705c1d50 + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 10c0/9a64bb8627b434ba9327b60c027742e5d17ac69277960d041898596271d992d4d52ba7267a63ca10232e29f6107fc8a835f6ce8d719b88c5f8493f8254813737 + languageName: node + linkType: hard + +"ansi-regex@npm:^6.2.2": + version: 6.2.2 + resolution: "ansi-regex@npm:6.2.2" + checksum: 10c0/05d4acb1d2f59ab2cf4b794339c7b168890d44dda4bf0ce01152a8da0213aca207802f930442ce8cd22d7a92f44907664aac6508904e75e038fa944d2601b30f + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0, ansi-styles@npm:^4.1.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: "npm:^2.0.1" + checksum: 10c0/895a23929da416f2bd3de7e9cb4eabd340949328ab85ddd6e484a637d8f6820d485f53933446f5291c3b760cbc488beb8e88573dd0f9c7daf83dccc8fe81b041 + languageName: node + linkType: hard + +"ansi-styles@npm:^5.2.0": + version: 5.2.0 + resolution: "ansi-styles@npm:5.2.0" + checksum: 10c0/9c4ca80eb3c2fb7b33841c210d2f20807f40865d27008d7c3f707b7f95cab7d67462a565e2388ac3285b71cb3d9bb2173de8da37c57692a362885ec34d6e27df + languageName: node + linkType: hard + +"ansi-styles@npm:^6.1.0": + version: 6.2.3 + resolution: "ansi-styles@npm:6.2.3" + checksum: 10c0/23b8a4ce14e18fb854693b95351e286b771d23d8844057ed2e7d083cd3e708376c3323707ec6a24365f7d7eda3ca00327fe04092e29e551499ec4c8b7bfac868 + languageName: node + linkType: hard + +"anymatch@npm:^3.1.3": + version: 3.1.3 + resolution: "anymatch@npm:3.1.3" + dependencies: + normalize-path: "npm:^3.0.0" + picomatch: "npm:^2.0.4" + checksum: 10c0/57b06ae984bc32a0d22592c87384cd88fe4511b1dd7581497831c56d41939c8a001b28e7b853e1450f2bf61992dfcaa8ae2d0d161a0a90c4fb631ef07098fbac + languageName: node + linkType: hard + +"argparse@npm:^1.0.7": + version: 1.0.10 + resolution: "argparse@npm:1.0.10" + dependencies: + sprintf-js: "npm:~1.0.2" + checksum: 10c0/b2972c5c23c63df66bca144dbc65d180efa74f25f8fd9b7d9a0a6c88ae839db32df3d54770dcb6460cf840d232b60695d1a6b1053f599d84e73f7437087712de + languageName: node + linkType: hard + +"babel-jest@npm:30.3.0": + version: 30.3.0 + resolution: "babel-jest@npm:30.3.0" + dependencies: + "@jest/transform": "npm:30.3.0" + "@types/babel__core": "npm:^7.20.5" + babel-plugin-istanbul: "npm:^7.0.1" + babel-preset-jest: "npm:30.3.0" + chalk: "npm:^4.1.2" + graceful-fs: "npm:^4.2.11" + slash: "npm:^3.0.0" + peerDependencies: + "@babel/core": ^7.11.0 || ^8.0.0-0 + checksum: 10c0/5e41e124a404ddb78aa37a20336d7c883feab5ad9c4f4c72ae26db71be2fcca345874b9a7fef97d9c5f64f144a264b247ebde8acfe493578320f314ca581bac3 + languageName: node + linkType: hard + +"babel-plugin-istanbul@npm:^7.0.1": + version: 7.0.1 + resolution: "babel-plugin-istanbul@npm:7.0.1" + dependencies: + "@babel/helper-plugin-utils": "npm:^7.0.0" + "@istanbuljs/load-nyc-config": "npm:^1.0.0" + "@istanbuljs/schema": "npm:^0.1.3" + istanbul-lib-instrument: "npm:^6.0.2" + test-exclude: "npm:^6.0.0" + checksum: 10c0/92975e3df12503b168695463b451468da0c20e117807221652eb8e33a26c160f3b9d4c5c4e65495657420e871c6a54e5e31f539e2e1da37ef2261d7ddd4b1dfd + languageName: node + linkType: hard + +"babel-plugin-jest-hoist@npm:30.3.0": + version: 30.3.0 + resolution: "babel-plugin-jest-hoist@npm:30.3.0" + dependencies: + "@types/babel__core": "npm:^7.20.5" + checksum: 10c0/5e15900a6487356131e084970f4a9ebe24b702d74930f786e897d4fab90b0987054f66661a3570ea692f429dcd158c2214c97ecf08f7356cbc60029d7b277c74 + languageName: node + linkType: hard + +"babel-preset-current-node-syntax@npm:^1.2.0": + version: 1.2.0 + resolution: "babel-preset-current-node-syntax@npm:1.2.0" + dependencies: + "@babel/plugin-syntax-async-generators": "npm:^7.8.4" + "@babel/plugin-syntax-bigint": "npm:^7.8.3" + "@babel/plugin-syntax-class-properties": "npm:^7.12.13" + "@babel/plugin-syntax-class-static-block": "npm:^7.14.5" + "@babel/plugin-syntax-import-attributes": "npm:^7.24.7" + "@babel/plugin-syntax-import-meta": "npm:^7.10.4" + "@babel/plugin-syntax-json-strings": "npm:^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators": "npm:^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3" + "@babel/plugin-syntax-numeric-separator": "npm:^7.10.4" + "@babel/plugin-syntax-object-rest-spread": "npm:^7.8.3" + "@babel/plugin-syntax-optional-catch-binding": "npm:^7.8.3" + "@babel/plugin-syntax-optional-chaining": "npm:^7.8.3" + "@babel/plugin-syntax-private-property-in-object": "npm:^7.14.5" + "@babel/plugin-syntax-top-level-await": "npm:^7.14.5" + peerDependencies: + "@babel/core": ^7.0.0 || ^8.0.0-0 + checksum: 10c0/94a4f81cddf9b051045d08489e4fff7336292016301664c138cfa3d9ffe3fe2ba10a24ad6ae589fd95af1ac72ba0216e1653555c187e694d7b17be0c002bea10 + languageName: node + linkType: hard + +"babel-preset-jest@npm:30.3.0": + version: 30.3.0 + resolution: "babel-preset-jest@npm:30.3.0" + dependencies: + babel-plugin-jest-hoist: "npm:30.3.0" + babel-preset-current-node-syntax: "npm:^1.2.0" + peerDependencies: + "@babel/core": ^7.11.0 || ^8.0.0-beta.1 + checksum: 10c0/a6839a1527d254bf04e82c0cf61a6a2aa283123a74f0a552e6fce462cb990abebab75a13ec3e9c58b09a865d4d2dfbac710c2d3975ae3ce6f2707cb314915c66 + languageName: node + linkType: hard + +"balanced-match@npm:^1.0.0": + version: 1.0.2 + resolution: "balanced-match@npm:1.0.2" + checksum: 10c0/9308baf0a7e4838a82bbfd11e01b1cb0f0cf2893bc1676c27c2a8c0e70cbae1c59120c3268517a8ae7fb6376b4639ef81ca22582611dbee4ed28df945134aaee + languageName: node + linkType: hard + +"balanced-match@npm:^4.0.2": + version: 4.0.4 + resolution: "balanced-match@npm:4.0.4" + checksum: 10c0/07e86102a3eb2ee2a6a1a89164f29d0dbaebd28f2ca3f5ca786f36b8b23d9e417eb3be45a4acf754f837be5ac0a2317de90d3fcb7f4f4dc95720a1f36b26a17b + languageName: node + linkType: hard + +"baseline-browser-mapping@npm:^2.10.12": + version: 2.10.25 + resolution: "baseline-browser-mapping@npm:2.10.25" + bin: + baseline-browser-mapping: dist/cli.cjs + checksum: 10c0/3955a01d1ca9487b23805b89250465911c0aa7aa1bd7b6207ab64257c945ad50e37d2d6d33b559e47e20cf1d3b1930fc15115bfbc340e84fd33c238a01bdebb6 + languageName: node + linkType: hard + +"brace-expansion@npm:^1.1.7": + version: 1.1.14 + resolution: "brace-expansion@npm:1.1.14" + dependencies: + balanced-match: "npm:^1.0.0" + concat-map: "npm:0.0.1" + checksum: 10c0/b6fdac832bc4e36a753658c9ed052c2e1a2be221763b002df25d1efbf7d21724334e726a6cd5eadc72a4b19ec3efb632d629cc003bc9c62f7af7a7915ffa4385 + languageName: node + linkType: hard + +"brace-expansion@npm:^2.0.2": + version: 2.1.0 + resolution: "brace-expansion@npm:2.1.0" + dependencies: + balanced-match: "npm:^1.0.0" + checksum: 10c0/439cedf3e23d7993b37919f1d6fdc653ec21a42437ec3e7460bea9ca8b17edf7a24a633273c31d61aa4335877cf29a443f1871814131c87997a1e6223e1f1502 + languageName: node + linkType: hard + +"brace-expansion@npm:^5.0.5": + version: 5.0.5 + resolution: "brace-expansion@npm:5.0.5" + dependencies: + balanced-match: "npm:^4.0.2" + checksum: 10c0/4d238e14ed4f5cc9c07285550a41cef23121ca08ba99fa9eb5b55b580dcb6bf868b8210aa10526bdc9f8dc97f33ca2a7259039c4cc131a93042beddb424c48e3 + languageName: node + linkType: hard + +"browserslist@npm:^4.24.0": + version: 4.28.2 + resolution: "browserslist@npm:4.28.2" + dependencies: + baseline-browser-mapping: "npm:^2.10.12" + caniuse-lite: "npm:^1.0.30001782" + electron-to-chromium: "npm:^1.5.328" + node-releases: "npm:^2.0.36" + update-browserslist-db: "npm:^1.2.3" + bin: + browserslist: cli.js + checksum: 10c0/c0228b6330f785b7fa59d2d360124ec6d9322f96ed9f3ee1f873e33ecc9503a6f0ffc3b71191a28c4ff6e930b753b30043da1c33844a9548f3018d491f09ce60 + languageName: node + linkType: hard + +"bs-logger@npm:^0.2.6": + version: 0.2.6 + resolution: "bs-logger@npm:0.2.6" + dependencies: + fast-json-stable-stringify: "npm:2.x" + checksum: 10c0/80e89aaaed4b68e3374ce936f2eb097456a0dddbf11f75238dbd53140b1e39259f0d248a5089ed456f1158984f22191c3658d54a713982f676709fbe1a6fa5a0 + languageName: node + linkType: hard + +"bser@npm:2.1.1": + version: 2.1.1 + resolution: "bser@npm:2.1.1" + dependencies: + node-int64: "npm:^0.4.0" + checksum: 10c0/24d8dfb7b6d457d73f32744e678a60cc553e4ec0e9e1a01cf614b44d85c3c87e188d3cc78ef0442ce5032ee6818de20a0162ba1074725c0d08908f62ea979227 + languageName: node + linkType: hard + +"buffer-from@npm:^1.0.0": + version: 1.1.2 + resolution: "buffer-from@npm:1.1.2" + checksum: 10c0/124fff9d66d691a86d3b062eff4663fe437a9d9ee4b47b1b9e97f5a5d14f6d5399345db80f796827be7c95e70a8e765dd404b7c3ff3b3324f98e9b0c8826cc34 + languageName: node + linkType: hard + +"callsites@npm:^3.1.0": + version: 3.1.0 + resolution: "callsites@npm:3.1.0" + checksum: 10c0/fff92277400eb06c3079f9e74f3af120db9f8ea03bad0e84d9aede54bbe2d44a56cccb5f6cf12211f93f52306df87077ecec5b712794c5a9b5dac6d615a3f301 + languageName: node + linkType: hard + +"camelcase@npm:^5.3.1": + version: 5.3.1 + resolution: "camelcase@npm:5.3.1" + checksum: 10c0/92ff9b443bfe8abb15f2b1513ca182d16126359ad4f955ebc83dc4ddcc4ef3fdd2c078bc223f2673dc223488e75c99b16cc4d056624374b799e6a1555cf61b23 + languageName: node + linkType: hard + +"camelcase@npm:^6.3.0": + version: 6.3.0 + resolution: "camelcase@npm:6.3.0" + checksum: 10c0/0d701658219bd3116d12da3eab31acddb3f9440790c0792e0d398f0a520a6a4058018e546862b6fba89d7ae990efaeb97da71e1913e9ebf5a8b5621a3d55c710 + languageName: node + linkType: hard + +"caniuse-lite@npm:^1.0.30001782": + version: 1.0.30001791 + resolution: "caniuse-lite@npm:1.0.30001791" + checksum: 10c0/53c8b5dad1c196a5e495405a7d2dc1db58aed9be02f60cf2a2e29d2c8d8cbb6c39beabf958d6aa191ab967ddcf49f22319452256b980bad1e271615acfe58940 + languageName: node + linkType: hard + +"chalk@npm:^4.1.2": + version: 4.1.2 + resolution: "chalk@npm:4.1.2" + dependencies: + ansi-styles: "npm:^4.1.0" + supports-color: "npm:^7.1.0" + checksum: 10c0/4a3fef5cc34975c898ffe77141450f679721df9dde00f6c304353fa9c8b571929123b26a0e4617bde5018977eb655b31970c297b91b63ee83bb82aeb04666880 + languageName: node + linkType: hard + +"char-regex@npm:^1.0.2": + version: 1.0.2 + resolution: "char-regex@npm:1.0.2" + checksum: 10c0/57a09a86371331e0be35d9083ba429e86c4f4648ecbe27455dbfb343037c16ee6fdc7f6b61f433a57cc5ded5561d71c56a150e018f40c2ffb7bc93a26dae341e + languageName: node + linkType: hard + +"chownr@npm:^3.0.0": + version: 3.0.0 + resolution: "chownr@npm:3.0.0" + checksum: 10c0/43925b87700f7e3893296c8e9c56cc58f926411cce3a6e5898136daaf08f08b9a8eb76d37d3267e707d0dcc17aed2e2ebdf5848c0c3ce95cf910a919935c1b10 + languageName: node + linkType: hard + +"ci-info@npm:^4.2.0": + version: 4.4.0 + resolution: "ci-info@npm:4.4.0" + checksum: 10c0/44156201545b8dde01aa8a09ee2fe9fc7a73b1bef9adbd4606c9f61c8caeeb73fb7a575c88b0443f7b4edb5ee45debaa59ed54ba5f99698339393ca01349eb3a + languageName: node + linkType: hard + +"cjs-module-lexer@npm:^2.1.0": + version: 2.2.0 + resolution: "cjs-module-lexer@npm:2.2.0" + checksum: 10c0/aec4ca58f87145fac221386790ecaae8b012f2e2359a45acb61d8c75ea4fa84f6ea869f17abc1a7e91a808eff0fed581209632f03540de16f72f0a28f5fd35ac + languageName: node + linkType: hard + +"cliui@npm:^8.0.1": + version: 8.0.1 + resolution: "cliui@npm:8.0.1" + dependencies: + string-width: "npm:^4.2.0" + strip-ansi: "npm:^6.0.1" + wrap-ansi: "npm:^7.0.0" + checksum: 10c0/4bda0f09c340cbb6dfdc1ed508b3ca080f12992c18d68c6be4d9cf51756033d5266e61ec57529e610dacbf4da1c634423b0c1b11037709cc6b09045cbd815df5 + languageName: node + linkType: hard + +"co@npm:^4.6.0": + version: 4.6.0 + resolution: "co@npm:4.6.0" + checksum: 10c0/c0e85ea0ca8bf0a50cbdca82efc5af0301240ca88ebe3644a6ffb8ffe911f34d40f8fbcf8f1d52c5ddd66706abd4d3bfcd64259f1e8e2371d4f47573b0dc8c28 + languageName: node + linkType: hard + +"collect-v8-coverage@npm:^1.0.2": + version: 1.0.3 + resolution: "collect-v8-coverage@npm:1.0.3" + checksum: 10c0/bc62ba251bcce5e3354a8f88fa6442bee56e3e612fec08d4dfcf66179b41ea0bf544b0f78c4ebc0f8050871220af95bb5c5578a6aef346feea155640582f09dc + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: "npm:~1.1.4" + checksum: 10c0/37e1150172f2e311fe1b2df62c6293a342ee7380da7b9cfdba67ea539909afbd74da27033208d01d6d5cfc65ee7868a22e18d7e7648e004425441c0f8a15a7d7 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: 10c0/a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95 + languageName: node + linkType: hard + +"commander@npm:^2.20.0": + version: 2.20.3 + resolution: "commander@npm:2.20.3" + checksum: 10c0/74c781a5248c2402a0a3e966a0a2bba3c054aad144f5c023364be83265e796b20565aa9feff624132ff629aa64e16999fa40a743c10c12f7c61e96a794b99288 + languageName: node + linkType: hard + +"concat-map@npm:0.0.1": + version: 0.0.1 + resolution: "concat-map@npm:0.0.1" + checksum: 10c0/c996b1cfdf95b6c90fee4dae37e332c8b6eb7d106430c17d538034c0ad9a1630cb194d2ab37293b1bdd4d779494beee7786d586a50bd9376fd6f7bcc2bd4c98f + languageName: node + linkType: hard + +"convert-source-map@npm:^2.0.0": + version: 2.0.0 + resolution: "convert-source-map@npm:2.0.0" + checksum: 10c0/8f2f7a27a1a011cc6cc88cc4da2d7d0cfa5ee0369508baae3d98c260bb3ac520691464e5bbe4ae7cdf09860c1d69ecc6f70c63c6e7c7f7e3f18ec08484dc7d9b + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": + version: 7.0.6 + resolution: "cross-spawn@npm:7.0.6" + dependencies: + path-key: "npm:^3.1.0" + shebang-command: "npm:^2.0.0" + which: "npm:^2.0.1" + checksum: 10c0/053ea8b2135caff68a9e81470e845613e374e7309a47731e81639de3eaeb90c3d01af0e0b44d2ab9d50b43467223b88567dfeb3262db942dc063b9976718ffc1 + languageName: node + linkType: hard + +"csstype@npm:^3.2.2": + version: 3.2.3 + resolution: "csstype@npm:3.2.3" + checksum: 10c0/cd29c51e70fa822f1cecd8641a1445bed7063697469d35633b516e60fe8c1bde04b08f6c5b6022136bb669b64c63d4173af54864510fbb4ee23281801841a3ce + languageName: node + linkType: hard + +"debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.4.3": + version: 4.4.3 + resolution: "debug@npm:4.4.3" + dependencies: + ms: "npm:^2.1.3" + peerDependenciesMeta: + supports-color: + optional: true + checksum: 10c0/d79136ec6c83ecbefd0f6a5593da6a9c91ec4d7ddc4b54c883d6e71ec9accb5f67a1a5e96d00a328196b5b5c86d365e98d8a3a70856aaf16b4e7b1985e67f5a6 + languageName: node + linkType: hard + +"dedent@npm:^1.6.0": + version: 1.7.2 + resolution: "dedent@npm:1.7.2" + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + checksum: 10c0/acaff07cac355b93f17b1b17ebbb84d3cc55af6ab4b7814c3f505e061903e168bc6bf9ddce331552d64dee1525f0b4c549c9ade46aebfac6f69caaed74e90751 + languageName: node + linkType: hard + +"deep-is@npm:^0.1.3": + version: 0.1.4 + resolution: "deep-is@npm:0.1.4" + checksum: 10c0/7f0ee496e0dff14a573dc6127f14c95061b448b87b995fc96c017ce0a1e66af1675e73f1d6064407975bc4ea6ab679497a29fff7b5b9c4e99cb10797c1ad0b4c + languageName: node + linkType: hard + +"deepmerge@npm:^4.2.2, deepmerge@npm:^4.3.1": + version: 4.3.1 + resolution: "deepmerge@npm:4.3.1" + checksum: 10c0/e53481aaf1aa2c4082b5342be6b6d8ad9dfe387bc92ce197a66dea08bd4265904a087e75e464f14d1347cf2ac8afe1e4c16b266e0561cc5df29382d3c5f80044 + languageName: node + linkType: hard + +"detect-newline@npm:^3.1.0": + version: 3.1.0 + resolution: "detect-newline@npm:3.1.0" + checksum: 10c0/c38cfc8eeb9fda09febb44bcd85e467c970d4e3bf526095394e5a4f18bc26dd0cf6b22c69c1fa9969261521c593836db335c2795218f6d781a512aea2fb8209d + languageName: node + linkType: hard + +"eastasianwidth@npm:^0.2.0": + version: 0.2.0 + resolution: "eastasianwidth@npm:0.2.0" + checksum: 10c0/26f364ebcdb6395f95124fda411f63137a4bfb5d3a06453f7f23dfe52502905bd84e0488172e0f9ec295fdc45f05c23d5d91baf16bd26f0fe9acd777a188dc39 + languageName: node + linkType: hard + +"electron-to-chromium@npm:^1.5.328": + version: 1.5.349 + resolution: "electron-to-chromium@npm:1.5.349" + checksum: 10c0/5acd94d9c70b91383f95bc9c04f39b6f92263ef2b232f4f0d4c71d17dcd3db49ef480cd025c379f6d58b534cf568ca5cb566b0f9be238f057b9a5773d76760ec + languageName: node + linkType: hard + +"emittery@npm:^0.13.1": + version: 0.13.1 + resolution: "emittery@npm:0.13.1" + checksum: 10c0/1573d0ae29ab34661b6c63251ff8f5facd24ccf6a823f19417ae8ba8c88ea450325788c67f16c99edec8de4b52ce93a10fe441ece389fd156e88ee7dab9bfa35 + languageName: node + linkType: hard + +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: 10c0/b6053ad39951c4cf338f9092d7bfba448cdfd46fe6a2a034700b149ac9ffbc137e361cbd3c442297f86bed2e5f7576c1b54cc0a6bf8ef5106cc62f496af35010 + languageName: node + linkType: hard + +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 10c0/af014e759a72064cf66e6e694a7fc6b0ed3d8db680427b021a89727689671cefe9d04151b2cad51dbaf85d5ba790d061cd167f1cf32eb7b281f6368b3c181639 + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 10c0/285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4 + languageName: node + linkType: hard + +"error-ex@npm:^1.3.1": + version: 1.3.4 + resolution: "error-ex@npm:1.3.4" + dependencies: + is-arrayish: "npm:^0.2.1" + checksum: 10c0/b9e34ff4778b8f3b31a8377e1c654456f4c41aeaa3d10a1138c3b7635d8b7b2e03eb2475d46d8ae055c1f180a1063e100bffabf64ea7e7388b37735df5328664 + languageName: node + linkType: hard + +"es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: 10c0/0a61325670072f98d8ae3b914edab3559b6caa980f08054a3b872052640d91da01d38df55df797fcc916389d77fc92b8d5906cf028f4db46d7e3003abecbca85 + languageName: node + linkType: hard + +"escalade@npm:^3.1.1, escalade@npm:^3.2.0": + version: 3.2.0 + resolution: "escalade@npm:3.2.0" + checksum: 10c0/ced4dd3a78e15897ed3be74e635110bbf3b08877b0a41be50dcb325ee0e0b5f65fc2d50e9845194d7c4633f327e2e1c6cce00a71b617c5673df0374201d67f65 + languageName: node + linkType: hard + +"escape-string-regexp@npm:^2.0.0": + version: 2.0.0 + resolution: "escape-string-regexp@npm:2.0.0" + checksum: 10c0/2530479fe8db57eace5e8646c9c2a9c80fa279614986d16dcc6bcaceb63ae77f05a851ba6c43756d816c61d7f4534baf56e3c705e3e0d884818a46808811c507 + languageName: node + linkType: hard + +"escape-string-regexp@npm:^4.0.0": + version: 4.0.0 + resolution: "escape-string-regexp@npm:4.0.0" + checksum: 10c0/9497d4dd307d845bd7f75180d8188bb17ea8c151c1edbf6b6717c100e104d629dc2dfb687686181b0f4b7d732c7dfdc4d5e7a8ff72de1b0ca283a75bbb3a9cd9 + languageName: node + linkType: hard + +"eslint-config-prettier@npm:^10.1.8": + version: 10.1.8 + resolution: "eslint-config-prettier@npm:10.1.8" + peerDependencies: + eslint: ">=7.0.0" + bin: + eslint-config-prettier: bin/cli.js + checksum: 10c0/e1bcfadc9eccd526c240056b1e59c5cd26544fe59feb85f38f4f1f116caed96aea0b3b87868e68b3099e55caaac3f2e5b9f58110f85db893e83a332751192682 + languageName: node + linkType: hard + +"eslint-scope@npm:^9.1.2": + version: 9.1.2 + resolution: "eslint-scope@npm:9.1.2" + dependencies: + "@types/esrecurse": "npm:^4.3.1" + "@types/estree": "npm:^1.0.8" + esrecurse: "npm:^4.3.0" + estraverse: "npm:^5.2.0" + checksum: 10c0/9fb8bca5a73e5741efb6cec84467027b6cb6f4203ff9b43a938e272c5cd30800bde46a5c20dfd1609f840225f0b62b7673be391b20acadf8658ca9fa4729b3dd + languageName: node + linkType: hard + +"eslint-visitor-keys@npm:^3.4.3": + version: 3.4.3 + resolution: "eslint-visitor-keys@npm:3.4.3" + checksum: 10c0/92708e882c0a5ffd88c23c0b404ac1628cf20104a108c745f240a13c332a11aac54f49a22d5762efbffc18ecbc9a580d1b7ad034bf5f3cc3307e5cbff2ec9820 + languageName: node + linkType: hard + +"eslint-visitor-keys@npm:^5.0.0, eslint-visitor-keys@npm:^5.0.1": + version: 5.0.1 + resolution: "eslint-visitor-keys@npm:5.0.1" + checksum: 10c0/16190bdf2cbae40a1109384c94450c526a79b0b9c3cb21e544256ed85ac48a4b84db66b74a6561d20fe6ab77447f150d711c2ad5ad74df4fcc133736bce99678 + languageName: node + linkType: hard + +"eslint@npm:^10.0.3": + version: 10.3.0 + resolution: "eslint@npm:10.3.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.8.0" + "@eslint-community/regexpp": "npm:^4.12.2" + "@eslint/config-array": "npm:^0.23.5" + "@eslint/config-helpers": "npm:^0.5.5" + "@eslint/core": "npm:^1.2.1" + "@eslint/plugin-kit": "npm:^0.7.1" + "@humanfs/node": "npm:^0.16.6" + "@humanwhocodes/module-importer": "npm:^1.0.1" + "@humanwhocodes/retry": "npm:^0.4.2" + "@types/estree": "npm:^1.0.6" + ajv: "npm:^6.14.0" + cross-spawn: "npm:^7.0.6" + debug: "npm:^4.3.2" + escape-string-regexp: "npm:^4.0.0" + eslint-scope: "npm:^9.1.2" + eslint-visitor-keys: "npm:^5.0.1" + espree: "npm:^11.2.0" + esquery: "npm:^1.7.0" + esutils: "npm:^2.0.2" + fast-deep-equal: "npm:^3.1.3" + file-entry-cache: "npm:^8.0.0" + find-up: "npm:^5.0.0" + glob-parent: "npm:^6.0.2" + ignore: "npm:^5.2.0" + imurmurhash: "npm:^0.1.4" + is-glob: "npm:^4.0.0" + json-stable-stringify-without-jsonify: "npm:^1.0.1" + minimatch: "npm:^10.2.4" + natural-compare: "npm:^1.4.0" + optionator: "npm:^0.9.3" + peerDependencies: + jiti: "*" + peerDependenciesMeta: + jiti: + optional: true + bin: + eslint: bin/eslint.js + checksum: 10c0/81e3ceba949f62d1b530660279db86cf814f5dc43d7cc3759a8008fe4fc679d46568279fe1cceb7ddbbc98ab57a96ae524f6e811ffc6897b49b90ea08aa785e5 + languageName: node + linkType: hard + +"espree@npm:^11.2.0": + version: 11.2.0 + resolution: "espree@npm:11.2.0" + dependencies: + acorn: "npm:^8.16.0" + acorn-jsx: "npm:^5.3.2" + eslint-visitor-keys: "npm:^5.0.1" + checksum: 10c0/cf87e18ffd9dc113eb8d16588e7757701bc10c9934a71cce8b89c2611d51672681a918307bd6b19ac3ccd0e7ba1cbccc2f815b36b52fa7e73097b251014c3d81 + languageName: node + linkType: hard + +"esprima@npm:^4.0.0": + version: 4.0.1 + resolution: "esprima@npm:4.0.1" + bin: + esparse: ./bin/esparse.js + esvalidate: ./bin/esvalidate.js + checksum: 10c0/ad4bab9ead0808cf56501750fd9d3fb276f6b105f987707d059005d57e182d18a7c9ec7f3a01794ebddcca676773e42ca48a32d67a250c9d35e009ca613caba3 + languageName: node + linkType: hard + +"esquery@npm:^1.7.0": + version: 1.7.0 + resolution: "esquery@npm:1.7.0" + dependencies: + estraverse: "npm:^5.1.0" + checksum: 10c0/77d5173db450b66f3bc685d11af4c90cffeedb340f34a39af96d43509a335ce39c894fd79233df32d38f5e4e219fa0f7076f6ec90bae8320170ba082c0db4793 + languageName: node + linkType: hard + +"esrecurse@npm:^4.3.0": + version: 4.3.0 + resolution: "esrecurse@npm:4.3.0" + dependencies: + estraverse: "npm:^5.2.0" + checksum: 10c0/81a37116d1408ded88ada45b9fb16dbd26fba3aadc369ce50fcaf82a0bac12772ebd7b24cd7b91fc66786bf2c1ac7b5f196bc990a473efff972f5cb338877cf5 + languageName: node + linkType: hard + +"estraverse@npm:^5.1.0, estraverse@npm:^5.2.0": + version: 5.3.0 + resolution: "estraverse@npm:5.3.0" + checksum: 10c0/1ff9447b96263dec95d6d67431c5e0771eb9776427421260a3e2f0fdd5d6bd4f8e37a7338f5ad2880c9f143450c9b1e4fc2069060724570a49cf9cf0312bd107 + languageName: node + linkType: hard + +"estree-walker@npm:^2.0.2": + version: 2.0.2 + resolution: "estree-walker@npm:2.0.2" + checksum: 10c0/53a6c54e2019b8c914dc395890153ffdc2322781acf4bd7d1a32d7aedc1710807bdcd866ac133903d5629ec601fbb50abe8c2e5553c7f5a0afdd9b6af6c945af + languageName: node + linkType: hard + +"esutils@npm:^2.0.2": + version: 2.0.3 + resolution: "esutils@npm:2.0.3" + checksum: 10c0/9a2fe69a41bfdade834ba7c42de4723c97ec776e40656919c62cbd13607c45e127a003f05f724a1ea55e5029a4cf2de444b13009f2af71271e42d93a637137c7 + languageName: node + linkType: hard + +"execa@npm:^5.1.1": + version: 5.1.1 + resolution: "execa@npm:5.1.1" + dependencies: + cross-spawn: "npm:^7.0.3" + get-stream: "npm:^6.0.0" + human-signals: "npm:^2.1.0" + is-stream: "npm:^2.0.0" + merge-stream: "npm:^2.0.0" + npm-run-path: "npm:^4.0.1" + onetime: "npm:^5.1.2" + signal-exit: "npm:^3.0.3" + strip-final-newline: "npm:^2.0.0" + checksum: 10c0/c8e615235e8de4c5addf2fa4c3da3e3aa59ce975a3e83533b4f6a71750fb816a2e79610dc5f1799b6e28976c9ae86747a36a606655bf8cb414a74d8d507b304f + languageName: node + linkType: hard + +"exit-x@npm:^0.2.2": + version: 0.2.2 + resolution: "exit-x@npm:0.2.2" + checksum: 10c0/212a7a095ca5540e9581f1ef2d1d6a40df7a6027c8cc96e78ce1d16b86d1a88326d4a0eff8dff2b5ec1e68bb0c1edd5d0dfdde87df1869bf7514d4bc6a5cbd72 + languageName: node + linkType: hard + +"expect@npm:30.3.0, expect@npm:^30.0.0": + version: 30.3.0 + resolution: "expect@npm:30.3.0" + dependencies: + "@jest/expect-utils": "npm:30.3.0" + "@jest/get-type": "npm:30.1.0" + jest-matcher-utils: "npm:30.3.0" + jest-message-util: "npm:30.3.0" + jest-mock: "npm:30.3.0" + jest-util: "npm:30.3.0" + checksum: 10c0/a07a157a0c8b3f1e29bfe5ccbf03a3add2c69fe60d1af8a0980053bb6403d721d5f5e4616f1ea5833b747913f8c880c79ce4d98c23a71a2f0c27cf7273892576 + languageName: node + linkType: hard + +"exponential-backoff@npm:^3.1.1": + version: 3.1.3 + resolution: "exponential-backoff@npm:3.1.3" + checksum: 10c0/77e3ae682b7b1f4972f563c6dbcd2b0d54ac679e62d5d32f3e5085feba20483cf28bd505543f520e287a56d4d55a28d7874299941faf637e779a1aa5994d1267 + languageName: node + linkType: hard + +"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": + version: 3.1.3 + resolution: "fast-deep-equal@npm:3.1.3" + checksum: 10c0/40dedc862eb8992c54579c66d914635afbec43350afbbe991235fdcb4e3a8d5af1b23ae7e79bef7d4882d0ecee06c3197488026998fb19f72dc95acff1d1b1d0 + languageName: node + linkType: hard + +"fast-json-stable-stringify@npm:2.x, fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0": + version: 2.1.0 + resolution: "fast-json-stable-stringify@npm:2.1.0" + checksum: 10c0/7f081eb0b8a64e0057b3bb03f974b3ef00135fbf36c1c710895cd9300f13c94ba809bb3a81cf4e1b03f6e5285610a61abbd7602d0652de423144dfee5a389c9b + languageName: node + linkType: hard + +"fast-levenshtein@npm:^2.0.6": + version: 2.0.6 + resolution: "fast-levenshtein@npm:2.0.6" + checksum: 10c0/111972b37338bcb88f7d9e2c5907862c280ebf4234433b95bc611e518d192ccb2d38119c4ac86e26b668d75f7f3894f4ff5c4982899afced7ca78633b08287c4 + languageName: node + linkType: hard + +"fb-watchman@npm:^2.0.2": + version: 2.0.2 + resolution: "fb-watchman@npm:2.0.2" + dependencies: + bser: "npm:2.1.1" + checksum: 10c0/feae89ac148adb8f6ae8ccd87632e62b13563e6fb114cacb5265c51f585b17e2e268084519fb2edd133872f1d47a18e6bfd7e5e08625c0d41b93149694187581 + languageName: node + linkType: hard + +"fdir@npm:^6.5.0": + version: 6.5.0 + resolution: "fdir@npm:6.5.0" + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + checksum: 10c0/e345083c4306b3aed6cb8ec551e26c36bab5c511e99ea4576a16750ddc8d3240e63826cc624f5ae17ad4dc82e68a253213b60d556c11bfad064b7607847ed07f + languageName: node + linkType: hard + +"file-entry-cache@npm:^8.0.0": + version: 8.0.0 + resolution: "file-entry-cache@npm:8.0.0" + dependencies: + flat-cache: "npm:^4.0.0" + checksum: 10c0/9e2b5938b1cd9b6d7e3612bdc533afd4ac17b2fc646569e9a8abbf2eb48e5eb8e316bc38815a3ef6a1b456f4107f0d0f055a614ca613e75db6bf9ff4d72c1638 + languageName: node + linkType: hard + +"find-up@npm:^4.0.0, find-up@npm:^4.1.0": + version: 4.1.0 + resolution: "find-up@npm:4.1.0" + dependencies: + locate-path: "npm:^5.0.0" + path-exists: "npm:^4.0.0" + checksum: 10c0/0406ee89ebeefa2d507feb07ec366bebd8a6167ae74aa4e34fb4c4abd06cf782a3ce26ae4194d70706f72182841733f00551c209fe575cb00bd92104056e78c1 + languageName: node + linkType: hard + +"find-up@npm:^5.0.0": + version: 5.0.0 + resolution: "find-up@npm:5.0.0" + dependencies: + locate-path: "npm:^6.0.0" + path-exists: "npm:^4.0.0" + checksum: 10c0/062c5a83a9c02f53cdd6d175a37ecf8f87ea5bbff1fdfb828f04bfa021441bc7583e8ebc0872a4c1baab96221fb8a8a275a19809fb93fbc40bd69ec35634069a + languageName: node + linkType: hard + +"flat-cache@npm:^4.0.0": + version: 4.0.1 + resolution: "flat-cache@npm:4.0.1" + dependencies: + flatted: "npm:^3.2.9" + keyv: "npm:^4.5.4" + checksum: 10c0/2c59d93e9faa2523e4fda6b4ada749bed432cfa28c8e251f33b25795e426a1c6dbada777afb1f74fcfff33934fdbdea921ee738fcc33e71adc9d6eca984a1cfc + languageName: node + linkType: hard + +"flatted@npm:^3.2.9": + version: 3.4.2 + resolution: "flatted@npm:3.4.2" + checksum: 10c0/a65b67aae7172d6cdf63691be7de6c5cd5adbdfdfe2e9da1a09b617c9512ed794037741ee53d93114276bff3f93cd3b0d97d54f9b316e1e4885dde6e9ffdf7ed + languageName: node + linkType: hard + +"foreground-child@npm:^3.1.0": + version: 3.3.1 + resolution: "foreground-child@npm:3.3.1" + dependencies: + cross-spawn: "npm:^7.0.6" + signal-exit: "npm:^4.0.1" + checksum: 10c0/8986e4af2430896e65bc2788d6679067294d6aee9545daefc84923a0a4b399ad9c7a3ea7bd8c0b2b80fdf4a92de4c69df3f628233ff3224260e9c1541a9e9ed3 + languageName: node + linkType: hard + +"fs.realpath@npm:^1.0.0": + version: 1.0.0 + resolution: "fs.realpath@npm:1.0.0" + checksum: 10c0/444cf1291d997165dfd4c0d58b69f0e4782bfd9149fd72faa4fe299e68e0e93d6db941660b37dd29153bf7186672ececa3b50b7e7249477b03fdf850f287c948 + languageName: node + linkType: hard + +"fsevents@npm:^2.3.3, fsevents@npm:~2.3.2": + version: 2.3.3 + resolution: "fsevents@npm:2.3.3" + dependencies: + node-gyp: "npm:latest" + checksum: 10c0/a1f0c44595123ed717febbc478aa952e47adfc28e2092be66b8ab1635147254ca6cfe1df792a8997f22716d4cbafc73309899ff7bfac2ac3ad8cf2e4ecc3ec60 + conditions: os=darwin + languageName: node + linkType: hard + +"fsevents@patch:fsevents@npm%3A^2.3.3#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin": + version: 2.3.3 + resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" + dependencies: + node-gyp: "npm:latest" + conditions: os=darwin + languageName: node + linkType: hard + +"function-bind@npm:^1.1.2": + version: 1.1.2 + resolution: "function-bind@npm:1.1.2" + checksum: 10c0/d8680ee1e5fcd4c197e4ac33b2b4dce03c71f4d91717292785703db200f5c21f977c568d28061226f9b5900cbcd2c84463646134fd5337e7925e0942bc3f46d5 + languageName: node + linkType: hard + +"gensync@npm:^1.0.0-beta.2": + version: 1.0.0-beta.2 + resolution: "gensync@npm:1.0.0-beta.2" + checksum: 10c0/782aba6cba65b1bb5af3b095d96249d20edbe8df32dbf4696fd49be2583faf676173bf4809386588828e4dd76a3354fcbeb577bab1c833ccd9fc4577f26103f8 + languageName: node + linkType: hard + +"get-caller-file@npm:^2.0.5": + version: 2.0.5 + resolution: "get-caller-file@npm:2.0.5" + checksum: 10c0/c6c7b60271931fa752aeb92f2b47e355eac1af3a2673f47c9589e8f8a41adc74d45551c1bc57b5e66a80609f10ffb72b6f575e4370d61cc3f7f3aaff01757cde + languageName: node + linkType: hard + +"get-package-type@npm:^0.1.0": + version: 0.1.0 + resolution: "get-package-type@npm:0.1.0" + checksum: 10c0/e34cdf447fdf1902a1f6d5af737eaadf606d2ee3518287abde8910e04159368c268568174b2e71102b87b26c2020486f126bfca9c4fb1ceb986ff99b52ecd1be + languageName: node + linkType: hard + +"get-stream@npm:^6.0.0": + version: 6.0.1 + resolution: "get-stream@npm:6.0.1" + checksum: 10c0/49825d57d3fd6964228e6200a58169464b8e8970489b3acdc24906c782fb7f01f9f56f8e6653c4a50713771d6658f7cfe051e5eb8c12e334138c9c918b296341 + languageName: node + linkType: hard + +"glob-parent@npm:^6.0.2": + version: 6.0.2 + resolution: "glob-parent@npm:6.0.2" + dependencies: + is-glob: "npm:^4.0.3" + checksum: 10c0/317034d88654730230b3f43bb7ad4f7c90257a426e872ea0bf157473ac61c99bf5d205fad8f0185f989be8d2fa6d3c7dce1645d99d545b6ea9089c39f838e7f8 + languageName: node + linkType: hard + +"glob@npm:^10.5.0": + version: 10.5.0 + resolution: "glob@npm:10.5.0" + dependencies: + foreground-child: "npm:^3.1.0" + jackspeak: "npm:^3.1.2" + minimatch: "npm:^9.0.4" + minipass: "npm:^7.1.2" + package-json-from-dist: "npm:^1.0.0" + path-scurry: "npm:^1.11.1" + bin: + glob: dist/esm/bin.mjs + checksum: 10c0/100705eddbde6323e7b35e1d1ac28bcb58322095bd8e63a7d0bef1a2cdafe0d0f7922a981b2b48369a4f8c1b077be5c171804534c3509dfe950dde15fbe6d828 + languageName: node + linkType: hard + +"glob@npm:^7.1.4": + version: 7.2.3 + resolution: "glob@npm:7.2.3" + dependencies: + fs.realpath: "npm:^1.0.0" + inflight: "npm:^1.0.4" + inherits: "npm:2" + minimatch: "npm:^3.1.1" + once: "npm:^1.3.0" + path-is-absolute: "npm:^1.0.0" + checksum: 10c0/65676153e2b0c9095100fe7f25a778bf45608eeb32c6048cf307f579649bcc30353277b3b898a3792602c65764e5baa4f643714dfbdfd64ea271d210c7a425fe + languageName: node + linkType: hard + +"graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.6": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 + languageName: node + linkType: hard + +"handlebars@npm:^4.7.9": + version: 4.7.9 + resolution: "handlebars@npm:4.7.9" + dependencies: + minimist: "npm:^1.2.5" + neo-async: "npm:^2.6.2" + source-map: "npm:^0.6.1" + uglify-js: "npm:^3.1.4" + wordwrap: "npm:^1.0.0" + dependenciesMeta: + uglify-js: + optional: true + bin: + handlebars: bin/handlebars + checksum: 10c0/22f8105a7e68e81aff2662bb434edf05f757d21d850731d71cec886d69c10cd33d3c43e34b2892968ec62de8241611851d3d0674c8ef324ea3e01dc66262faa9 + languageName: node + linkType: hard + +"has-flag@npm:^4.0.0": + version: 4.0.0 + resolution: "has-flag@npm:4.0.0" + checksum: 10c0/2e789c61b7888d66993e14e8331449e525ef42aac53c627cc53d1c3334e768bcb6abdc4f5f0de1478a25beec6f0bd62c7549058b7ac53e924040d4f301f02fd1 + languageName: node + linkType: hard + +"hasown@npm:^2.0.2": + version: 2.0.3 + resolution: "hasown@npm:2.0.3" + dependencies: + function-bind: "npm:^1.1.2" + checksum: 10c0/f5eb28c3fd0d3e4facd821c1eeee3836c37b70ab0b0fc532e8a39976e18fef43652415dadc52f8c7a5ff6d5ac93b7bef128789aa6f90f4e9b9a9083dce74ab38 + languageName: node + linkType: hard + +"html-escaper@npm:^2.0.0": + version: 2.0.2 + resolution: "html-escaper@npm:2.0.2" + checksum: 10c0/208e8a12de1a6569edbb14544f4567e6ce8ecc30b9394fcaa4e7bb1e60c12a7c9a1ed27e31290817157e8626f3a4f29e76c8747030822eb84a6abb15c255f0a0 + languageName: node + linkType: hard + +"human-signals@npm:^2.1.0": + version: 2.1.0 + resolution: "human-signals@npm:2.1.0" + checksum: 10c0/695edb3edfcfe9c8b52a76926cd31b36978782062c0ed9b1192b36bebc75c4c87c82e178dfcb0ed0fc27ca59d434198aac0bd0be18f5781ded775604db22304a + languageName: node + linkType: hard + +"ignore@npm:^5.2.0": + version: 5.3.2 + resolution: "ignore@npm:5.3.2" + checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 + languageName: node + linkType: hard + +"ignore@npm:^7.0.5": + version: 7.0.5 + resolution: "ignore@npm:7.0.5" + checksum: 10c0/ae00db89fe873064a093b8999fe4cc284b13ef2a178636211842cceb650b9c3e390d3339191acb145d81ed5379d2074840cf0c33a20bdbd6f32821f79eb4ad5d + languageName: node + linkType: hard + +"import-local@npm:^3.2.0": + version: 3.2.0 + resolution: "import-local@npm:3.2.0" + dependencies: + pkg-dir: "npm:^4.2.0" + resolve-cwd: "npm:^3.0.0" + bin: + import-local-fixture: fixtures/cli.js + checksum: 10c0/94cd6367a672b7e0cb026970c85b76902d2710a64896fa6de93bd5c571dd03b228c5759308959de205083e3b1c61e799f019c9e36ee8e9c523b993e1057f0433 + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 10c0/8b51313850dd33605c6c9d3fd9638b714f4c4c40250cff658209f30d40da60f78992fb2df5dabee4acf589a6a82bbc79ad5486550754bd9ec4e3fc0d4a57d6a6 + languageName: node + linkType: hard + +"inflight@npm:^1.0.4": + version: 1.0.6 + resolution: "inflight@npm:1.0.6" + dependencies: + once: "npm:^1.3.0" + wrappy: "npm:1" + checksum: 10c0/7faca22584600a9dc5b9fca2cd5feb7135ac8c935449837b315676b4c90aa4f391ec4f42240178244b5a34e8bede1948627fda392ca3191522fc46b34e985ab2 + languageName: node + linkType: hard + +"inherits@npm:2": + version: 2.0.4 + resolution: "inherits@npm:2.0.4" + checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 + languageName: node + linkType: hard + +"is-arrayish@npm:^0.2.1": + version: 0.2.1 + resolution: "is-arrayish@npm:0.2.1" + checksum: 10c0/e7fb686a739068bb70f860b39b67afc62acc62e36bb61c5f965768abce1873b379c563e61dd2adad96ebb7edf6651111b385e490cf508378959b0ed4cac4e729 + languageName: node + linkType: hard + +"is-core-module@npm:^2.16.1": + version: 2.16.1 + resolution: "is-core-module@npm:2.16.1" + dependencies: + hasown: "npm:^2.0.2" + checksum: 10c0/898443c14780a577e807618aaae2b6f745c8538eca5c7bc11388a3f2dc6de82b9902bcc7eb74f07be672b11bbe82dd6a6edded44a00cb3d8f933d0459905eedd + languageName: node + linkType: hard + +"is-extglob@npm:^2.1.1": + version: 2.1.1 + resolution: "is-extglob@npm:2.1.1" + checksum: 10c0/5487da35691fbc339700bbb2730430b07777a3c21b9ebaecb3072512dfd7b4ba78ac2381a87e8d78d20ea08affb3f1971b4af629173a6bf435ff8a4c47747912 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 10c0/bb11d825e049f38e04c06373a8d72782eee0205bda9d908cc550ccb3c59b99d750ff9537982e01733c1c94a58e35400661f57042158ff5e8f3e90cf936daf0fc + languageName: node + linkType: hard + +"is-generator-fn@npm:^2.1.0": + version: 2.1.0 + resolution: "is-generator-fn@npm:2.1.0" + checksum: 10c0/2957cab387997a466cd0bf5c1b6047bd21ecb32bdcfd8996b15747aa01002c1c88731802f1b3d34ac99f4f6874b626418bd118658cf39380fe5fff32a3af9c4d + languageName: node + linkType: hard + +"is-glob@npm:^4.0.0, is-glob@npm:^4.0.3": + version: 4.0.3 + resolution: "is-glob@npm:4.0.3" + dependencies: + is-extglob: "npm:^2.1.1" + checksum: 10c0/17fb4014e22be3bbecea9b2e3a76e9e34ff645466be702f1693e8f1ee1adac84710d0be0bd9f967d6354036fd51ab7c2741d954d6e91dae6bb69714de92c197a + languageName: node + linkType: hard + +"is-module@npm:^1.0.0": + version: 1.0.0 + resolution: "is-module@npm:1.0.0" + checksum: 10c0/795a3914bcae7c26a1c23a1e5574c42eac13429625045737bf3e324ce865c0601d61aee7a5afbca1bee8cb300c7d9647e7dc98860c9bdbc3b7fdc51d8ac0bffc + languageName: node + linkType: hard + +"is-stream@npm:^2.0.0": + version: 2.0.1 + resolution: "is-stream@npm:2.0.1" + checksum: 10c0/7c284241313fc6efc329b8d7f08e16c0efeb6baab1b4cd0ba579eb78e5af1aa5da11e68559896a2067cd6c526bd29241dda4eb1225e627d5aa1a89a76d4635a5 + languageName: node + linkType: hard + +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 10c0/228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d + languageName: node + linkType: hard + +"isexe@npm:^4.0.0": + version: 4.0.0 + resolution: "isexe@npm:4.0.0" + checksum: 10c0/5884815115bceac452877659a9c7726382531592f43dc29e5d48b7c4100661aed54018cb90bd36cb2eaeba521092570769167acbb95c18d39afdccbcca06c5ce + languageName: node + linkType: hard + +"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0": + version: 3.2.2 + resolution: "istanbul-lib-coverage@npm:3.2.2" + checksum: 10c0/6c7ff2106769e5f592ded1fb418f9f73b4411fd5a084387a5410538332b6567cd1763ff6b6cadca9b9eb2c443cce2f7ea7d7f1b8d315f9ce58539793b1e0922b + languageName: node + linkType: hard + +"istanbul-lib-instrument@npm:^6.0.0, istanbul-lib-instrument@npm:^6.0.2": + version: 6.0.3 + resolution: "istanbul-lib-instrument@npm:6.0.3" + dependencies: + "@babel/core": "npm:^7.23.9" + "@babel/parser": "npm:^7.23.9" + "@istanbuljs/schema": "npm:^0.1.3" + istanbul-lib-coverage: "npm:^3.2.0" + semver: "npm:^7.5.4" + checksum: 10c0/a1894e060dd2a3b9f046ffdc87b44c00a35516f5e6b7baf4910369acca79e506fc5323a816f811ae23d82334b38e3ddeb8b3b331bd2c860540793b59a8689128 + languageName: node + linkType: hard + +"istanbul-lib-report@npm:^3.0.0": + version: 3.0.1 + resolution: "istanbul-lib-report@npm:3.0.1" + dependencies: + istanbul-lib-coverage: "npm:^3.0.0" + make-dir: "npm:^4.0.0" + supports-color: "npm:^7.1.0" + checksum: 10c0/84323afb14392de8b6a5714bd7e9af845cfbd56cfe71ed276cda2f5f1201aea673c7111901227ee33e68e4364e288d73861eb2ed48f6679d1e69a43b6d9b3ba7 + languageName: node + linkType: hard + +"istanbul-lib-source-maps@npm:^5.0.0": + version: 5.0.6 + resolution: "istanbul-lib-source-maps@npm:5.0.6" + dependencies: + "@jridgewell/trace-mapping": "npm:^0.3.23" + debug: "npm:^4.1.1" + istanbul-lib-coverage: "npm:^3.0.0" + checksum: 10c0/ffe75d70b303a3621ee4671554f306e0831b16f39ab7f4ab52e54d356a5d33e534d97563e318f1333a6aae1d42f91ec49c76b6cd3f3fb378addcb5c81da0255f + languageName: node + linkType: hard + +"istanbul-reports@npm:^3.1.3": + version: 3.2.0 + resolution: "istanbul-reports@npm:3.2.0" + dependencies: + html-escaper: "npm:^2.0.0" + istanbul-lib-report: "npm:^3.0.0" + checksum: 10c0/d596317cfd9c22e1394f22a8d8ba0303d2074fe2e971887b32d870e4b33f8464b10f8ccbe6847808f7db485f084eba09e6c2ed706b3a978e4b52f07085b8f9bc + languageName: node + linkType: hard + +"its-fine@npm:^2.0.0": + version: 2.0.0 + resolution: "its-fine@npm:2.0.0" + dependencies: + "@types/react-reconciler": "npm:^0.28.9" + peerDependencies: + react: ^19.0.0 + checksum: 10c0/1ff1ff3257c0c7eb115c9c26cf0506eb84162edc1a63d3136780d146f7c7833298b240d0fcb46888909773f1a7d16539e0c03f2482cff1a5a502d6436686fe21 + languageName: node + linkType: hard + +"jackspeak@npm:^3.1.2": + version: 3.4.3 + resolution: "jackspeak@npm:3.4.3" + dependencies: + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 10c0/6acc10d139eaefdbe04d2f679e6191b3abf073f111edf10b1de5302c97ec93fffeb2fdd8681ed17f16268aa9dd4f8c588ed9d1d3bffbbfa6e8bf897cbb3149b9 + languageName: node + linkType: hard + +"jest-changed-files@npm:30.3.0": + version: 30.3.0 + resolution: "jest-changed-files@npm:30.3.0" + dependencies: + execa: "npm:^5.1.1" + jest-util: "npm:30.3.0" + p-limit: "npm:^3.1.0" + checksum: 10c0/5a2f9790f8ab7f5804ebbf0fcdd908c40286d602d76abbecc6bea72e7f3c60b77dc8a3d3f5acdddd11653b2574f471a5c126ceda0734bc6a7d607cf145843525 + languageName: node + linkType: hard + +"jest-circus@npm:30.3.0": + version: 30.3.0 + resolution: "jest-circus@npm:30.3.0" + dependencies: + "@jest/environment": "npm:30.3.0" + "@jest/expect": "npm:30.3.0" + "@jest/test-result": "npm:30.3.0" + "@jest/types": "npm:30.3.0" + "@types/node": "npm:*" + chalk: "npm:^4.1.2" + co: "npm:^4.6.0" + dedent: "npm:^1.6.0" + is-generator-fn: "npm:^2.1.0" + jest-each: "npm:30.3.0" + jest-matcher-utils: "npm:30.3.0" + jest-message-util: "npm:30.3.0" + jest-runtime: "npm:30.3.0" + jest-snapshot: "npm:30.3.0" + jest-util: "npm:30.3.0" + p-limit: "npm:^3.1.0" + pretty-format: "npm:30.3.0" + pure-rand: "npm:^7.0.0" + slash: "npm:^3.0.0" + stack-utils: "npm:^2.0.6" + checksum: 10c0/a3a0eb973699b400fb6de4207a7fbc5b33f51523e5e94f954d0e6e60418ea95099883614495fce54d805a321cb65e883592048b73203a59b8f4e53d1bb975a07 + languageName: node + linkType: hard + +"jest-cli@npm:30.3.0": + version: 30.3.0 + resolution: "jest-cli@npm:30.3.0" + dependencies: + "@jest/core": "npm:30.3.0" + "@jest/test-result": "npm:30.3.0" + "@jest/types": "npm:30.3.0" + chalk: "npm:^4.1.2" + exit-x: "npm:^0.2.2" + import-local: "npm:^3.2.0" + jest-config: "npm:30.3.0" + jest-util: "npm:30.3.0" + jest-validate: "npm:30.3.0" + yargs: "npm:^17.7.2" + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + bin: + jest: ./bin/jest.js + checksum: 10c0/764d77551e0fb6d666212e89d01be6f7bb1a2b3adb918bba7c5c37593a11b01cf2af645506c2b6438335cfc79bfcf41bfd4680958d8ca751851752a7c66269d3 + languageName: node + linkType: hard + +"jest-config@npm:30.3.0": + version: 30.3.0 + resolution: "jest-config@npm:30.3.0" + dependencies: + "@babel/core": "npm:^7.27.4" + "@jest/get-type": "npm:30.1.0" + "@jest/pattern": "npm:30.0.1" + "@jest/test-sequencer": "npm:30.3.0" + "@jest/types": "npm:30.3.0" + babel-jest: "npm:30.3.0" + chalk: "npm:^4.1.2" + ci-info: "npm:^4.2.0" + deepmerge: "npm:^4.3.1" + glob: "npm:^10.5.0" + graceful-fs: "npm:^4.2.11" + jest-circus: "npm:30.3.0" + jest-docblock: "npm:30.2.0" + jest-environment-node: "npm:30.3.0" + jest-regex-util: "npm:30.0.1" + jest-resolve: "npm:30.3.0" + jest-runner: "npm:30.3.0" + jest-util: "npm:30.3.0" + jest-validate: "npm:30.3.0" + parse-json: "npm:^5.2.0" + pretty-format: "npm:30.3.0" + slash: "npm:^3.0.0" + strip-json-comments: "npm:^3.1.1" + peerDependencies: + "@types/node": "*" + esbuild-register: ">=3.4.0" + ts-node: ">=9.0.0" + peerDependenciesMeta: + "@types/node": + optional: true + esbuild-register: + optional: true + ts-node: + optional: true + checksum: 10c0/157607e5ac5e83924df97d992fbd40a1540af07c5a7be296fae49455b3729687847304f3b4a9112e7da17593b76cec3453cd55c1ecd4334f7318f2489d7d10a1 + languageName: node + linkType: hard + +"jest-diff@npm:30.3.0": + version: 30.3.0 + resolution: "jest-diff@npm:30.3.0" + dependencies: + "@jest/diff-sequences": "npm:30.3.0" + "@jest/get-type": "npm:30.1.0" + chalk: "npm:^4.1.2" + pretty-format: "npm:30.3.0" + checksum: 10c0/573a2a1a155b95fbde547d8ee33a5375179a8d03d4586025478dac16d695e4614aef075c3afa57e0f3a96cea8f638fa68a55c1e625f6e86b4f5b9e5850311ffb + languageName: node + linkType: hard + +"jest-docblock@npm:30.2.0": + version: 30.2.0 + resolution: "jest-docblock@npm:30.2.0" + dependencies: + detect-newline: "npm:^3.1.0" + checksum: 10c0/2578366604eef1b36d59ffe1fc52a710995571535d437f83d94ff94756a83f78e699c1ba004c38a34c01859d669fd6c64e865c23c5a7d5bf4837cfca4bef3dda + languageName: node + linkType: hard + +"jest-each@npm:30.3.0": + version: 30.3.0 + resolution: "jest-each@npm:30.3.0" + dependencies: + "@jest/get-type": "npm:30.1.0" + "@jest/types": "npm:30.3.0" + chalk: "npm:^4.1.2" + jest-util: "npm:30.3.0" + pretty-format: "npm:30.3.0" + checksum: 10c0/d23d2b43b3ea42beaf99648e2cf1c74b8a13c3e45c7c882979171471c225f7d666cb4a0d5f1ff9031b4504866fa3badc7266ffd885d3d8035420c559a31501e1 + languageName: node + linkType: hard + +"jest-environment-node@npm:30.3.0": + version: 30.3.0 + resolution: "jest-environment-node@npm:30.3.0" + dependencies: + "@jest/environment": "npm:30.3.0" + "@jest/fake-timers": "npm:30.3.0" + "@jest/types": "npm:30.3.0" + "@types/node": "npm:*" + jest-mock: "npm:30.3.0" + jest-util: "npm:30.3.0" + jest-validate: "npm:30.3.0" + checksum: 10c0/2a4be80861e569fa11456d89ff2aaedd71726ae02ade8f2cc6fbc86ba8749e24c37864676c4718fc08a40f6e6d2b2b51bc48d715b09b1e93e15e42e4a10f7b5b + languageName: node + linkType: hard + +"jest-haste-map@npm:30.3.0": + version: 30.3.0 + resolution: "jest-haste-map@npm:30.3.0" + dependencies: + "@jest/types": "npm:30.3.0" + "@types/node": "npm:*" + anymatch: "npm:^3.1.3" + fb-watchman: "npm:^2.0.2" + fsevents: "npm:^2.3.3" + graceful-fs: "npm:^4.2.11" + jest-regex-util: "npm:30.0.1" + jest-util: "npm:30.3.0" + jest-worker: "npm:30.3.0" + picomatch: "npm:^4.0.3" + walker: "npm:^1.0.8" + dependenciesMeta: + fsevents: + optional: true + checksum: 10c0/b9ef350082b15d4c119d6188f781024d859d6cfb17ae25d15c90c3a373234e16109afbeffdcf1af4baf6a85eb0cbbab00439c981ad43037c0f05d89ff98bd1af + languageName: node + linkType: hard + +"jest-leak-detector@npm:30.3.0": + version: 30.3.0 + resolution: "jest-leak-detector@npm:30.3.0" + dependencies: + "@jest/get-type": "npm:30.1.0" + pretty-format: "npm:30.3.0" + checksum: 10c0/a648c082b74e6c7d0c2e890002094ba97b108398fa3d0316958fc74321aa7b0824507a685d261a463856f219a724b86a6073bac86d351cf0675ecf962c1ee0ca + languageName: node + linkType: hard + +"jest-matcher-utils@npm:30.3.0": + version: 30.3.0 + resolution: "jest-matcher-utils@npm:30.3.0" + dependencies: + "@jest/get-type": "npm:30.1.0" + chalk: "npm:^4.1.2" + jest-diff: "npm:30.3.0" + pretty-format: "npm:30.3.0" + checksum: 10c0/4c5f4b6435964110e64c4b5b42e3553fffe303ecdd68021147a7bcc72914aec3a899867c50db22b250c72aded53e3f7a9f64d83c9dca2e65ce27f36d23c6ca78 + languageName: node + linkType: hard + +"jest-message-util@npm:30.3.0": + version: 30.3.0 + resolution: "jest-message-util@npm:30.3.0" + dependencies: + "@babel/code-frame": "npm:^7.27.1" + "@jest/types": "npm:30.3.0" + "@types/stack-utils": "npm:^2.0.3" + chalk: "npm:^4.1.2" + graceful-fs: "npm:^4.2.11" + picomatch: "npm:^4.0.3" + pretty-format: "npm:30.3.0" + slash: "npm:^3.0.0" + stack-utils: "npm:^2.0.6" + checksum: 10c0/6ce611caef76394872b23a111286b48e56f42655d14a5fbd0629d9b7437ed892e85ad96b15864bc22185c24ef670afb6665c57b9729458a36d50ffe8310f0926 + languageName: node + linkType: hard + +"jest-mock@npm:30.3.0": + version: 30.3.0 + resolution: "jest-mock@npm:30.3.0" + dependencies: + "@jest/types": "npm:30.3.0" + "@types/node": "npm:*" + jest-util: "npm:30.3.0" + checksum: 10c0/9d95d550c6c998a85887c48ff5ee26de4bca18be91462ea8a8135d6023d591132465756f74981ca39b60f8708dfe38213a55bd4b619798a7b9438ca10d718099 + languageName: node + linkType: hard + +"jest-pnp-resolver@npm:^1.2.3": + version: 1.2.3 + resolution: "jest-pnp-resolver@npm:1.2.3" + peerDependencies: + jest-resolve: "*" + peerDependenciesMeta: + jest-resolve: + optional: true + checksum: 10c0/86eec0c78449a2de733a6d3e316d49461af6a858070e113c97f75fb742a48c2396ea94150cbca44159ffd4a959f743a47a8b37a792ef6fdad2cf0a5cba973fac + languageName: node + linkType: hard + +"jest-regex-util@npm:30.0.1": + version: 30.0.1 + resolution: "jest-regex-util@npm:30.0.1" + checksum: 10c0/f30c70524ebde2d1012afe5ffa5691d5d00f7d5ba9e43d588f6460ac6fe96f9e620f2f9b36a02d0d3e7e77bc8efb8b3450ae3b80ac53c8be5099e01bf54f6728 + languageName: node + linkType: hard + +"jest-resolve-dependencies@npm:30.3.0": + version: 30.3.0 + resolution: "jest-resolve-dependencies@npm:30.3.0" + dependencies: + jest-regex-util: "npm:30.0.1" + jest-snapshot: "npm:30.3.0" + checksum: 10c0/25dde0c8c050bc3437332f37ab87484f597596b80ece77a93e4da2b466b42e45cc5ad748270c1477587536de15eea1ffe83a32638e824b120830c3a87c9a5b71 + languageName: node + linkType: hard + +"jest-resolve@npm:30.3.0": + version: 30.3.0 + resolution: "jest-resolve@npm:30.3.0" + dependencies: + chalk: "npm:^4.1.2" + graceful-fs: "npm:^4.2.11" + jest-haste-map: "npm:30.3.0" + jest-pnp-resolver: "npm:^1.2.3" + jest-util: "npm:30.3.0" + jest-validate: "npm:30.3.0" + slash: "npm:^3.0.0" + unrs-resolver: "npm:^1.7.11" + checksum: 10c0/540f59f160c232c1b922b111a93f24ef5202d75e00f2e994de976badf6e88879893b474320ff363a6b97259a7a208b6a4f5eeabede787eea9b7912a12ac64b1b + languageName: node + linkType: hard + +"jest-runner@npm:30.3.0": + version: 30.3.0 + resolution: "jest-runner@npm:30.3.0" + dependencies: + "@jest/console": "npm:30.3.0" + "@jest/environment": "npm:30.3.0" + "@jest/test-result": "npm:30.3.0" + "@jest/transform": "npm:30.3.0" + "@jest/types": "npm:30.3.0" + "@types/node": "npm:*" + chalk: "npm:^4.1.2" + emittery: "npm:^0.13.1" + exit-x: "npm:^0.2.2" + graceful-fs: "npm:^4.2.11" + jest-docblock: "npm:30.2.0" + jest-environment-node: "npm:30.3.0" + jest-haste-map: "npm:30.3.0" + jest-leak-detector: "npm:30.3.0" + jest-message-util: "npm:30.3.0" + jest-resolve: "npm:30.3.0" + jest-runtime: "npm:30.3.0" + jest-util: "npm:30.3.0" + jest-watcher: "npm:30.3.0" + jest-worker: "npm:30.3.0" + p-limit: "npm:^3.1.0" + source-map-support: "npm:0.5.13" + checksum: 10c0/6fb205f48541658f0b23b6c9a6730f0133f07c994a22ef506ebfcded5bbb444b655ac828074157e6579e664609a46f6a5bf3d366b694c6c8b523b5207a70499c + languageName: node + linkType: hard + +"jest-runtime@npm:30.3.0": + version: 30.3.0 + resolution: "jest-runtime@npm:30.3.0" + dependencies: + "@jest/environment": "npm:30.3.0" + "@jest/fake-timers": "npm:30.3.0" + "@jest/globals": "npm:30.3.0" + "@jest/source-map": "npm:30.0.1" + "@jest/test-result": "npm:30.3.0" + "@jest/transform": "npm:30.3.0" + "@jest/types": "npm:30.3.0" + "@types/node": "npm:*" + chalk: "npm:^4.1.2" + cjs-module-lexer: "npm:^2.1.0" + collect-v8-coverage: "npm:^1.0.2" + glob: "npm:^10.5.0" + graceful-fs: "npm:^4.2.11" + jest-haste-map: "npm:30.3.0" + jest-message-util: "npm:30.3.0" + jest-mock: "npm:30.3.0" + jest-regex-util: "npm:30.0.1" + jest-resolve: "npm:30.3.0" + jest-snapshot: "npm:30.3.0" + jest-util: "npm:30.3.0" + slash: "npm:^3.0.0" + strip-bom: "npm:^4.0.0" + checksum: 10c0/79c486157a926d5be5c66356ad26cc3792cca1afb1490e255a550f52784b6c92eea42f1cb3b2c7565650ea777cf17ffc3f8e305d6b97888e7d273f6d7f282686 + languageName: node + linkType: hard + +"jest-snapshot@npm:30.3.0": + version: 30.3.0 + resolution: "jest-snapshot@npm:30.3.0" + dependencies: + "@babel/core": "npm:^7.27.4" + "@babel/generator": "npm:^7.27.5" + "@babel/plugin-syntax-jsx": "npm:^7.27.1" + "@babel/plugin-syntax-typescript": "npm:^7.27.1" + "@babel/types": "npm:^7.27.3" + "@jest/expect-utils": "npm:30.3.0" + "@jest/get-type": "npm:30.1.0" + "@jest/snapshot-utils": "npm:30.3.0" + "@jest/transform": "npm:30.3.0" + "@jest/types": "npm:30.3.0" + babel-preset-current-node-syntax: "npm:^1.2.0" + chalk: "npm:^4.1.2" + expect: "npm:30.3.0" + graceful-fs: "npm:^4.2.11" + jest-diff: "npm:30.3.0" + jest-matcher-utils: "npm:30.3.0" + jest-message-util: "npm:30.3.0" + jest-util: "npm:30.3.0" + pretty-format: "npm:30.3.0" + semver: "npm:^7.7.2" + synckit: "npm:^0.11.8" + checksum: 10c0/c1dd295d9d4962f2504c965575212fc62a358a849c66ab96b2f6e608ebdf6a6029ca505bb0693664a54a534e581883665d404a59976a5b46b1a1f88b537e96c5 + languageName: node + linkType: hard + +"jest-util@npm:30.3.0": + version: 30.3.0 + resolution: "jest-util@npm:30.3.0" + dependencies: + "@jest/types": "npm:30.3.0" + "@types/node": "npm:*" + chalk: "npm:^4.1.2" + ci-info: "npm:^4.2.0" + graceful-fs: "npm:^4.2.11" + picomatch: "npm:^4.0.3" + checksum: 10c0/eea6f39e52a8cb2b1a28bb315a90dc6a8e450fffed73bb5ef4489d02d86f7d91be600d83f1dcba22956b8ac5fefa8f1b250e636c8402d3e8b50a5eec8b5963b2 + languageName: node + linkType: hard + +"jest-validate@npm:30.3.0": + version: 30.3.0 + resolution: "jest-validate@npm:30.3.0" + dependencies: + "@jest/get-type": "npm:30.1.0" + "@jest/types": "npm:30.3.0" + camelcase: "npm:^6.3.0" + chalk: "npm:^4.1.2" + leven: "npm:^3.1.0" + pretty-format: "npm:30.3.0" + checksum: 10c0/645629e9ae0926252dee26b0ad71b9f0392daa896328393479c63b1b13d2a70df4dac8b5053227c64e0120e930db1242897898c40706f135f20f73ef77fcf4f5 + languageName: node + linkType: hard + +"jest-watcher@npm:30.3.0": + version: 30.3.0 + resolution: "jest-watcher@npm:30.3.0" + dependencies: + "@jest/test-result": "npm:30.3.0" + "@jest/types": "npm:30.3.0" + "@types/node": "npm:*" + ansi-escapes: "npm:^4.3.2" + chalk: "npm:^4.1.2" + emittery: "npm:^0.13.1" + jest-util: "npm:30.3.0" + string-length: "npm:^4.0.2" + checksum: 10c0/2631be5cc122fbf14cb0bb7566cdea6d6c432b984d8ef3c6385254bb6c378342e0754cbd2dfe094d80762d44bd1c7015de2ec2100eb6f192906619d8b229e1a5 + languageName: node + linkType: hard + +"jest-worker@npm:30.3.0": + version: 30.3.0 + resolution: "jest-worker@npm:30.3.0" + dependencies: + "@types/node": "npm:*" + "@ungap/structured-clone": "npm:^1.3.0" + jest-util: "npm:30.3.0" + merge-stream: "npm:^2.0.0" + supports-color: "npm:^8.1.1" + checksum: 10c0/25dfb1bc43d389e1daf8baad0ef7964249f001a7da7d92c61e398840424ca13fb1fb6242f6e021f0cbb37952f90371fb8be1ef0183b5d04ef161fdb8f09ee78e + languageName: node + linkType: hard + +"jest@npm:^30.3.0": + version: 30.3.0 + resolution: "jest@npm:30.3.0" + dependencies: + "@jest/core": "npm:30.3.0" + "@jest/types": "npm:30.3.0" + import-local: "npm:^3.2.0" + jest-cli: "npm:30.3.0" + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + bin: + jest: ./bin/jest.js + checksum: 10c0/1f940424b741d1541c3d71e311f77c3cfaf31cff9ab2d53180333f00a31f157790a8d3d413b72b8dd2bb191aa75769fa741d9bc9085df779cd59689559a65815 + languageName: node + linkType: hard + +"js-tokens@npm:^4.0.0": + version: 4.0.0 + resolution: "js-tokens@npm:4.0.0" + checksum: 10c0/e248708d377aa058eacf2037b07ded847790e6de892bbad3dac0abba2e759cb9f121b00099a65195616badcb6eca8d14d975cb3e89eb1cfda644756402c8aeed + languageName: node + linkType: hard + +"js-yaml@npm:^3.13.1": + version: 3.14.2 + resolution: "js-yaml@npm:3.14.2" + dependencies: + argparse: "npm:^1.0.7" + esprima: "npm:^4.0.0" + bin: + js-yaml: bin/js-yaml.js + checksum: 10c0/3261f25912f5dd76605e5993d0a126c2b6c346311885d3c483706cd722efe34f697ea0331f654ce27c00a42b426e524518ec89d65ed02ea47df8ad26dcc8ce69 + languageName: node + linkType: hard + +"jsesc@npm:^3.0.2": + version: 3.1.0 + resolution: "jsesc@npm:3.1.0" + bin: + jsesc: bin/jsesc + checksum: 10c0/531779df5ec94f47e462da26b4cbf05eb88a83d9f08aac2ba04206508fc598527a153d08bd462bae82fc78b3eaa1a908e1a4a79f886e9238641c4cdefaf118b1 + languageName: node + linkType: hard + +"json-buffer@npm:3.0.1": + version: 3.0.1 + resolution: "json-buffer@npm:3.0.1" + checksum: 10c0/0d1c91569d9588e7eef2b49b59851f297f3ab93c7b35c7c221e288099322be6b562767d11e4821da500f3219542b9afd2e54c5dc573107c1126ed1080f8e96d7 + languageName: node + linkType: hard + +"json-parse-even-better-errors@npm:^2.3.0": + version: 2.3.1 + resolution: "json-parse-even-better-errors@npm:2.3.1" + checksum: 10c0/140932564c8f0b88455432e0f33c4cb4086b8868e37524e07e723f4eaedb9425bdc2bafd71bd1d9765bd15fd1e2d126972bc83990f55c467168c228c24d665f3 + languageName: node + linkType: hard + +"json-schema-traverse@npm:^0.4.1": + version: 0.4.1 + resolution: "json-schema-traverse@npm:0.4.1" + checksum: 10c0/108fa90d4cc6f08243aedc6da16c408daf81793bf903e9fd5ab21983cda433d5d2da49e40711da016289465ec2e62e0324dcdfbc06275a607fe3233fde4942ce + languageName: node + linkType: hard + +"json-stable-stringify-without-jsonify@npm:^1.0.1": + version: 1.0.1 + resolution: "json-stable-stringify-without-jsonify@npm:1.0.1" + checksum: 10c0/cb168b61fd4de83e58d09aaa6425ef71001bae30d260e2c57e7d09a5fd82223e2f22a042dedaab8db23b7d9ae46854b08bb1f91675a8be11c5cffebef5fb66a5 + languageName: node + linkType: hard + +"json5@npm:^2.2.3": + version: 2.2.3 + resolution: "json5@npm:2.2.3" + bin: + json5: lib/cli.js + checksum: 10c0/5a04eed94810fa55c5ea138b2f7a5c12b97c3750bc63d11e511dcecbfef758003861522a070c2272764ee0f4e3e323862f386945aeb5b85b87ee43f084ba586c + languageName: node + linkType: hard + +"keyv@npm:^4.5.4": + version: 4.5.4 + resolution: "keyv@npm:4.5.4" + dependencies: + json-buffer: "npm:3.0.1" + checksum: 10c0/aa52f3c5e18e16bb6324876bb8b59dd02acf782a4b789c7b2ae21107fab95fab3890ed448d4f8dba80ce05391eeac4bfabb4f02a20221342982f806fa2cf271e + languageName: node + linkType: hard + +"konva@npm:^10.2.5": + version: 10.2.5 + resolution: "konva@npm:10.2.5" + checksum: 10c0/5233d9d26632fe48cb7e9b0ce2b9bf5c8bea580cb9afb4065bd2fc09734836b49c8bfb2ee40659f0289e720363eaee023fe3205d8717fd9279035b66dca12e8e + languageName: node + linkType: hard + +"leven@npm:^3.1.0": + version: 3.1.0 + resolution: "leven@npm:3.1.0" + checksum: 10c0/cd778ba3fbab0f4d0500b7e87d1f6e1f041507c56fdcd47e8256a3012c98aaee371d4c15e0a76e0386107af2d42e2b7466160a2d80688aaa03e66e49949f42df + languageName: node + linkType: hard + +"levn@npm:^0.4.1": + version: 0.4.1 + resolution: "levn@npm:0.4.1" + dependencies: + prelude-ls: "npm:^1.2.1" + type-check: "npm:~0.4.0" + checksum: 10c0/effb03cad7c89dfa5bd4f6989364bfc79994c2042ec5966cb9b95990e2edee5cd8969ddf42616a0373ac49fac1403437deaf6e9050fbbaa3546093a59b9ac94e + languageName: node + linkType: hard + +"lines-and-columns@npm:^1.1.6": + version: 1.2.4 + resolution: "lines-and-columns@npm:1.2.4" + checksum: 10c0/3da6ee62d4cd9f03f5dc90b4df2540fb85b352081bee77fe4bbcd12c9000ead7f35e0a38b8d09a9bb99b13223446dd8689ff3c4959807620726d788701a83d2d + languageName: node + linkType: hard + +"locate-path@npm:^5.0.0": + version: 5.0.0 + resolution: "locate-path@npm:5.0.0" + dependencies: + p-locate: "npm:^4.1.0" + checksum: 10c0/33a1c5247e87e022f9713e6213a744557a3e9ec32c5d0b5efb10aa3a38177615bf90221a5592674857039c1a0fd2063b82f285702d37b792d973e9e72ace6c59 + languageName: node + linkType: hard + +"locate-path@npm:^6.0.0": + version: 6.0.0 + resolution: "locate-path@npm:6.0.0" + dependencies: + p-locate: "npm:^5.0.0" + checksum: 10c0/d3972ab70dfe58ce620e64265f90162d247e87159b6126b01314dd67be43d50e96a50b517bce2d9452a79409c7614054c277b5232377de50416564a77ac7aad3 + languageName: node + linkType: hard + +"lodash.memoize@npm:^4.1.2": + version: 4.1.2 + resolution: "lodash.memoize@npm:4.1.2" + checksum: 10c0/c8713e51eccc650422716a14cece1809cfe34bc5ab5e242b7f8b4e2241c2483697b971a604252807689b9dd69bfe3a98852e19a5b89d506b000b4187a1285df8 + languageName: node + linkType: hard + +"lru-cache@npm:^10.2.0": + version: 10.4.3 + resolution: "lru-cache@npm:10.4.3" + checksum: 10c0/ebd04fbca961e6c1d6c0af3799adcc966a1babe798f685bb84e6599266599cd95d94630b10262f5424539bc4640107e8a33aa28585374abf561d30d16f4b39fb + languageName: node + linkType: hard + +"lru-cache@npm:^5.1.1": + version: 5.1.1 + resolution: "lru-cache@npm:5.1.1" + dependencies: + yallist: "npm:^3.0.2" + checksum: 10c0/89b2ef2ef45f543011e38737b8a8622a2f8998cddf0e5437174ef8f1f70a8b9d14a918ab3e232cb3ba343b7abddffa667f0b59075b2b80e6b4d63c3de6127482 + languageName: node + linkType: hard + +"make-dir@npm:^4.0.0": + version: 4.0.0 + resolution: "make-dir@npm:4.0.0" + dependencies: + semver: "npm:^7.5.3" + checksum: 10c0/69b98a6c0b8e5c4fe9acb61608a9fbcfca1756d910f51e5dbe7a9e5cfb74fca9b8a0c8a0ffdf1294a740826c1ab4871d5bf3f62f72a3049e5eac6541ddffed68 + languageName: node + linkType: hard + +"make-error@npm:^1.3.6": + version: 1.3.6 + resolution: "make-error@npm:1.3.6" + checksum: 10c0/171e458d86854c6b3fc46610cfacf0b45149ba043782558c6875d9f42f222124384ad0b468c92e996d815a8a2003817a710c0a160e49c1c394626f76fa45396f + languageName: node + linkType: hard + +"makeerror@npm:1.0.12": + version: 1.0.12 + resolution: "makeerror@npm:1.0.12" + dependencies: + tmpl: "npm:1.0.5" + checksum: 10c0/b0e6e599780ce6bab49cc413eba822f7d1f0dfebd1c103eaa3785c59e43e22c59018323cf9e1708f0ef5329e94a745d163fcbb6bff8e4c6742f9be9e86f3500c + languageName: node + linkType: hard + +"merge-stream@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-stream@npm:2.0.0" + checksum: 10c0/867fdbb30a6d58b011449b8885601ec1690c3e41c759ecd5a9d609094f7aed0096c37823ff4a7190ef0b8f22cc86beb7049196ff68c016e3b3c671d0dac91ce5 + languageName: node + linkType: hard + +"mimic-fn@npm:^2.1.0": + version: 2.1.0 + resolution: "mimic-fn@npm:2.1.0" + checksum: 10c0/b26f5479d7ec6cc2bce275a08f146cf78f5e7b661b18114e2506dd91ec7ec47e7a25bf4360e5438094db0560bcc868079fb3b1fb3892b833c1ecbf63f80c95a4 + languageName: node + linkType: hard + +"minimatch@npm:^10.2.2, minimatch@npm:^10.2.4": + version: 10.2.5 + resolution: "minimatch@npm:10.2.5" + dependencies: + brace-expansion: "npm:^5.0.5" + checksum: 10c0/6bb058bd6324104b9ec2f763476a35386d05079c1f5fe4fbf1f324a25237cd4534d6813ecd71f48208f4e635c1221899bef94c3c89f7df55698fe373aaae20fd + languageName: node + linkType: hard + +"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1": + version: 3.1.5 + resolution: "minimatch@npm:3.1.5" + dependencies: + brace-expansion: "npm:^1.1.7" + checksum: 10c0/2ecbdc0d33f07bddb0315a8b5afbcb761307a8778b48f0b312418ccbced99f104a2d17d8aca7573433c70e8ccd1c56823a441897a45e384ea76ef401a26ace70 + languageName: node + linkType: hard + +"minimatch@npm:^9.0.4": + version: 9.0.9 + resolution: "minimatch@npm:9.0.9" + dependencies: + brace-expansion: "npm:^2.0.2" + checksum: 10c0/0b6a58530dbb00361745aa6c8cffaba4c90f551afe7c734830bd95fd88ebf469dd7355a027824ea1d09e37181cfeb0a797fb17df60c15ac174303ac110eb7e86 + languageName: node + linkType: hard + +"minimist@npm:^1.2.5": + version: 1.2.8 + resolution: "minimist@npm:1.2.8" + checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.4, minipass@npm:^7.1.2": + version: 7.1.3 + resolution: "minipass@npm:7.1.3" + checksum: 10c0/539da88daca16533211ea5a9ee98dc62ff5742f531f54640dd34429e621955e91cc280a91a776026264b7f9f6735947629f920944e9c1558369e8bf22eb33fbb + languageName: node + linkType: hard + +"minizlib@npm:^3.1.0": + version: 3.1.0 + resolution: "minizlib@npm:3.1.0" + dependencies: + minipass: "npm:^7.1.2" + checksum: 10c0/5aad75ab0090b8266069c9aabe582c021ae53eb33c6c691054a13a45db3b4f91a7fb1bd79151e6b4e9e9a86727b522527c0a06ec7d45206b745d54cd3097bcec + languageName: node + linkType: hard + +"ms@npm:^2.1.3": + version: 2.1.3 + resolution: "ms@npm:2.1.3" + checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 + languageName: node + linkType: hard + +"napi-postinstall@npm:^0.3.0": + version: 0.3.4 + resolution: "napi-postinstall@npm:0.3.4" + bin: + napi-postinstall: lib/cli.js + checksum: 10c0/b33d64150828bdade3a5d07368a8b30da22ee393f8dd8432f1b9e5486867be21c84ec443dd875dd3ef3c7401a079a7ab7e2aa9d3538a889abbcd96495d5104fe + languageName: node + linkType: hard + +"natural-compare@npm:^1.4.0": + version: 1.4.0 + resolution: "natural-compare@npm:1.4.0" + checksum: 10c0/f5f9a7974bfb28a91afafa254b197f0f22c684d4a1731763dda960d2c8e375b36c7d690e0d9dc8fba774c537af14a7e979129bca23d88d052fbeb9466955e447 + languageName: node + linkType: hard + +"neo-async@npm:^2.6.2": + version: 2.6.2 + resolution: "neo-async@npm:2.6.2" + checksum: 10c0/c2f5a604a54a8ec5438a342e1f356dff4bc33ccccdb6dc668d94fe8e5eccfc9d2c2eea6064b0967a767ba63b33763f51ccf2cd2441b461a7322656c1f06b3f5d + languageName: node + linkType: hard + +"node-gyp@npm:latest": + version: 12.3.0 + resolution: "node-gyp@npm:12.3.0" + dependencies: + env-paths: "npm:^2.2.0" + exponential-backoff: "npm:^3.1.1" + graceful-fs: "npm:^4.2.6" + nopt: "npm:^9.0.0" + proc-log: "npm:^6.0.0" + semver: "npm:^7.3.5" + tar: "npm:^7.5.4" + tinyglobby: "npm:^0.2.12" + undici: "npm:^6.25.0" + which: "npm:^6.0.0" + bin: + node-gyp: bin/node-gyp.js + checksum: 10c0/9d9032b405cbe42f72a105259d9eb679376470c102df4a2dbaa51e07d59bf741dcffb85897087ea9d8318b9cabb824a8978af51508ae142f0239ae1e6a3c2329 + languageName: node + linkType: hard + +"node-int64@npm:^0.4.0": + version: 0.4.0 + resolution: "node-int64@npm:0.4.0" + checksum: 10c0/a6a4d8369e2f2720e9c645255ffde909c0fbd41c92ea92a5607fc17055955daac99c1ff589d421eee12a0d24e99f7bfc2aabfeb1a4c14742f6c099a51863f31a + languageName: node + linkType: hard + +"node-releases@npm:^2.0.36": + version: 2.0.38 + resolution: "node-releases@npm:2.0.38" + checksum: 10c0/db9909234ed750c5b9d0075f83214cd16b76370b54eab50e3554f3ba939ba7ac39f3aca2ddf93471ae8553dbde2ea9354b0ae380c9cff1f8e53b55e414903413 + languageName: node + linkType: hard + +"nopt@npm:^9.0.0": + version: 9.0.0 + resolution: "nopt@npm:9.0.0" + dependencies: + abbrev: "npm:^4.0.0" + bin: + nopt: bin/nopt.js + checksum: 10c0/1822eb6f9b020ef6f7a7516d7b64a8036e09666ea55ac40416c36e4b2b343122c3cff0e2f085675f53de1d2db99a2a89a60ccea1d120bcd6a5347bf6ceb4a7fd + languageName: node + linkType: hard + +"normalize-path@npm:^3.0.0": + version: 3.0.0 + resolution: "normalize-path@npm:3.0.0" + checksum: 10c0/e008c8142bcc335b5e38cf0d63cfd39d6cf2d97480af9abdbe9a439221fd4d749763bab492a8ee708ce7a194bb00c9da6d0a115018672310850489137b3da046 + languageName: node + linkType: hard + +"npm-run-path@npm:^4.0.1": + version: 4.0.1 + resolution: "npm-run-path@npm:4.0.1" + dependencies: + path-key: "npm:^3.0.0" + checksum: 10c0/6f9353a95288f8455cf64cbeb707b28826a7f29690244c1e4bb61ec573256e021b6ad6651b394eb1ccfd00d6ec50147253aba2c5fe58a57ceb111fad62c519ac + languageName: node + linkType: hard + +"once@npm:^1.3.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: "npm:1" + checksum: 10c0/5d48aca287dfefabd756621c5dfce5c91a549a93e9fdb7b8246bc4c4790aa2ec17b34a260530474635147aeb631a2dcc8b32c613df0675f96041cbb8244517d0 + languageName: node + linkType: hard + +"onetime@npm:^5.1.2": + version: 5.1.2 + resolution: "onetime@npm:5.1.2" + dependencies: + mimic-fn: "npm:^2.1.0" + checksum: 10c0/ffcef6fbb2692c3c40749f31ea2e22677a876daea92959b8a80b521d95cca7a668c884d8b2045d1d8ee7d56796aa405c405462af112a1477594cc63531baeb8f + languageName: node + linkType: hard + +"optionator@npm:^0.9.3": + version: 0.9.4 + resolution: "optionator@npm:0.9.4" + dependencies: + deep-is: "npm:^0.1.3" + fast-levenshtein: "npm:^2.0.6" + levn: "npm:^0.4.1" + prelude-ls: "npm:^1.2.1" + type-check: "npm:^0.4.0" + word-wrap: "npm:^1.2.5" + checksum: 10c0/4afb687a059ee65b61df74dfe87d8d6815cd6883cb8b3d5883a910df72d0f5d029821f37025e4bccf4048873dbdb09acc6d303d27b8f76b1a80dd5a7d5334675 + languageName: node + linkType: hard + +"p-limit@npm:^2.2.0": + version: 2.3.0 + resolution: "p-limit@npm:2.3.0" + dependencies: + p-try: "npm:^2.0.0" + checksum: 10c0/8da01ac53efe6a627080fafc127c873da40c18d87b3f5d5492d465bb85ec7207e153948df6b9cbaeb130be70152f874229b8242ee2be84c0794082510af97f12 + languageName: node + linkType: hard + +"p-limit@npm:^3.0.2, p-limit@npm:^3.1.0": + version: 3.1.0 + resolution: "p-limit@npm:3.1.0" + dependencies: + yocto-queue: "npm:^0.1.0" + checksum: 10c0/9db675949dbdc9c3763c89e748d0ef8bdad0afbb24d49ceaf4c46c02c77d30db4e0652ed36d0a0a7a95154335fab810d95c86153105bb73b3a90448e2bb14e1a + languageName: node + linkType: hard + +"p-locate@npm:^4.1.0": + version: 4.1.0 + resolution: "p-locate@npm:4.1.0" + dependencies: + p-limit: "npm:^2.2.0" + checksum: 10c0/1b476ad69ad7f6059744f343b26d51ce091508935c1dbb80c4e0a2f397ffce0ca3a1f9f5cd3c7ce19d7929a09719d5c65fe70d8ee289c3f267cd36f2881813e9 + languageName: node + linkType: hard + +"p-locate@npm:^5.0.0": + version: 5.0.0 + resolution: "p-locate@npm:5.0.0" + dependencies: + p-limit: "npm:^3.0.2" + checksum: 10c0/2290d627ab7903b8b70d11d384fee714b797f6040d9278932754a6860845c4d3190603a0772a663c8cb5a7b21d1b16acb3a6487ebcafa9773094edc3dfe6009a + languageName: node + linkType: hard + +"p-try@npm:^2.0.0": + version: 2.2.0 + resolution: "p-try@npm:2.2.0" + checksum: 10c0/c36c19907734c904b16994e6535b02c36c2224d433e01a2f1ab777237f4d86e6289fd5fd464850491e940379d4606ed850c03e0f9ab600b0ebddb511312e177f + languageName: node + linkType: hard + +"package-json-from-dist@npm:^1.0.0": + version: 1.0.1 + resolution: "package-json-from-dist@npm:1.0.1" + checksum: 10c0/62ba2785eb655fec084a257af34dbe24292ab74516d6aecef97ef72d4897310bc6898f6c85b5cd22770eaa1ce60d55a0230e150fb6a966e3ecd6c511e23d164b + languageName: node + linkType: hard + +"parse-json@npm:^5.2.0": + version: 5.2.0 + resolution: "parse-json@npm:5.2.0" + dependencies: + "@babel/code-frame": "npm:^7.0.0" + error-ex: "npm:^1.3.1" + json-parse-even-better-errors: "npm:^2.3.0" + lines-and-columns: "npm:^1.1.6" + checksum: 10c0/77947f2253005be7a12d858aedbafa09c9ae39eb4863adf330f7b416ca4f4a08132e453e08de2db46459256fb66afaac5ee758b44fe6541b7cdaf9d252e59585 + languageName: node + linkType: hard + +"path-exists@npm:^4.0.0": + version: 4.0.0 + resolution: "path-exists@npm:4.0.0" + checksum: 10c0/8c0bd3f5238188197dc78dced15207a4716c51cc4e3624c44fc97acf69558f5ebb9a2afff486fe1b4ee148e0c133e96c5e11a9aa5c48a3006e3467da070e5e1b + languageName: node + linkType: hard + +"path-is-absolute@npm:^1.0.0": + version: 1.0.1 + resolution: "path-is-absolute@npm:1.0.1" + checksum: 10c0/127da03c82172a2a50099cddbf02510c1791fc2cc5f7713ddb613a56838db1e8168b121a920079d052e0936c23005562059756d653b7c544c53185efe53be078 + languageName: node + linkType: hard + +"path-key@npm:^3.0.0, path-key@npm:^3.1.0": + version: 3.1.1 + resolution: "path-key@npm:3.1.1" + checksum: 10c0/748c43efd5a569c039d7a00a03b58eecd1d75f3999f5a28303d75f521288df4823bc057d8784eb72358b2895a05f29a070bc9f1f17d28226cc4e62494cc58c4c + languageName: node + linkType: hard + +"path-parse@npm:^1.0.7": + version: 1.0.7 + resolution: "path-parse@npm:1.0.7" + checksum: 10c0/11ce261f9d294cc7a58d6a574b7f1b935842355ec66fba3c3fd79e0f036462eaf07d0aa95bb74ff432f9afef97ce1926c720988c6a7451d8a584930ae7de86e1 + languageName: node + linkType: hard + +"path-scurry@npm:^1.11.1": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" + dependencies: + lru-cache: "npm:^10.2.0" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + checksum: 10c0/32a13711a2a505616ae1cc1b5076801e453e7aae6ac40ab55b388bb91b9d0547a52f5aaceff710ea400205f18691120d4431e520afbe4266b836fadede15872d + languageName: node + linkType: hard + +"picocolors@npm:^1.1.1": + version: 1.1.1 + resolution: "picocolors@npm:1.1.1" + checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 + languageName: node + linkType: hard + +"picomatch@npm:^2.0.4": + version: 2.3.2 + resolution: "picomatch@npm:2.3.2" + checksum: 10c0/a554d1709e59be97d1acb9eaedbbc700a5c03dbd4579807baed95100b00420bc729335440ef15004ae2378984e2487a7c1cebd743cfdb72b6fa9ab69223c0d61 + languageName: node + linkType: hard + +"picomatch@npm:^4.0.2, picomatch@npm:^4.0.3, picomatch@npm:^4.0.4": + version: 4.0.4 + resolution: "picomatch@npm:4.0.4" + checksum: 10c0/e2c6023372cc7b5764719a5ffb9da0f8e781212fa7ca4bd0562db929df8e117460f00dff3cb7509dacfc06b86de924b247f504d0ce1806a37fac4633081466b0 + languageName: node + linkType: hard + +"pirates@npm:^4.0.7": + version: 4.0.7 + resolution: "pirates@npm:4.0.7" + checksum: 10c0/a51f108dd811beb779d58a76864bbd49e239fa40c7984cd11596c75a121a8cc789f1c8971d8bb15f0dbf9d48b76c05bb62fcbce840f89b688c0fa64b37e8478a + languageName: node + linkType: hard + +"pkg-dir@npm:^4.2.0": + version: 4.2.0 + resolution: "pkg-dir@npm:4.2.0" + dependencies: + find-up: "npm:^4.0.0" + checksum: 10c0/c56bda7769e04907a88423feb320babaed0711af8c436ce3e56763ab1021ba107c7b0cafb11cde7529f669cfc22bffcaebffb573645cbd63842ea9fb17cd7728 + languageName: node + linkType: hard + "plugins@workspace:.": version: 0.0.0-use.local resolution: "plugins@workspace:." + dependencies: + "@rollup/plugin-node-resolve": "npm:^16.0.3" + "@rollup/plugin-terser": "npm:^1.0.0" + "@rollup/plugin-typescript": "npm:^12.3.0" + "@sourceacademy/conductor": "npm:^0.3.0" + "@types/jest": "npm:^30.0.0" + eslint: "npm:^10.0.3" + eslint-config-prettier: "npm:^10.1.8" + jest: "npm:^30.3.0" + prettier: "npm:^3.8.1" + rollup: "npm:^4.60.0" + ts-jest: "npm:^29.4.6" + typescript: "npm:^6.0.3" + typescript-eslint: "npm:^8.57.1" languageName: unknown linkType: soft + +"prelude-ls@npm:^1.2.1": + version: 1.2.1 + resolution: "prelude-ls@npm:1.2.1" + checksum: 10c0/b00d617431e7886c520a6f498a2e14c75ec58f6d93ba48c3b639cf241b54232d90daa05d83a9e9b9fef6baa63cb7e1e4602c2372fea5bc169668401eb127d0cd + languageName: node + linkType: hard + +"prettier@npm:^3.8.1": + version: 3.8.3 + resolution: "prettier@npm:3.8.3" + bin: + prettier: bin/prettier.cjs + checksum: 10c0/754816fd7593eb80f6376d7476d463e832c38a12f32775a82683adb6e35b772b1f484d65f19401507b983a8c8a7cd5a4a9f12006bd56491e8f35503473f77473 + languageName: node + linkType: hard + +"pretty-format@npm:30.3.0, pretty-format@npm:^30.0.0": + version: 30.3.0 + resolution: "pretty-format@npm:30.3.0" + dependencies: + "@jest/schemas": "npm:30.0.5" + ansi-styles: "npm:^5.2.0" + react-is: "npm:^18.3.1" + checksum: 10c0/719b27d70cd8b01013485054c5d094e1fe85e093b09ee73553e3b19302da3cf54fbd6a7ea9577d6471aeff8d372200e56979ffc4c831e2133520bd18060895fb + languageName: node + linkType: hard + +"proc-log@npm:^6.0.0": + version: 6.1.0 + resolution: "proc-log@npm:6.1.0" + checksum: 10c0/4f178d4062733ead9d71a9b1ab24ebcecdfe2250916a5b1555f04fe2eda972a0ec76fbaa8df1ad9c02707add6749219d118a4fc46dc56bdfe4dde4b47d80bb82 + languageName: node + linkType: hard + +"punycode@npm:^2.1.0": + version: 2.3.1 + resolution: "punycode@npm:2.3.1" + checksum: 10c0/14f76a8206bc3464f794fb2e3d3cc665ae416c01893ad7a02b23766eb07159144ee612ad67af5e84fa4479ccfe67678c4feb126b0485651b302babf66f04f9e9 + languageName: node + linkType: hard + +"pure-rand@npm:^7.0.0": + version: 7.0.1 + resolution: "pure-rand@npm:7.0.1" + checksum: 10c0/9cade41030f5ec95f5d55a11a71404cd6f46b69becaad892097cd7f58e2c6248cd0a933349ca7d21336ab629f1da42ffe899699b671bc4651600eaf6e57f837e + languageName: node + linkType: hard + +"react-dom@npm:^19.2.5": + version: 19.2.5 + resolution: "react-dom@npm:19.2.5" + dependencies: + scheduler: "npm:^0.27.0" + peerDependencies: + react: ^19.2.5 + checksum: 10c0/8067606e9f58e4c2e8cb5f09570217dbc71c4843ebcaa20ae2085912d3e3a351f17d8f7c1713313cdda7f272840c8c34ff6c860fcb840862071bceea218e0c63 + languageName: node + linkType: hard + +"react-is@npm:^18.3.1": + version: 18.3.1 + resolution: "react-is@npm:18.3.1" + checksum: 10c0/f2f1e60010c683479e74c63f96b09fb41603527cd131a9959e2aee1e5a8b0caf270b365e5ca77d4a6b18aae659b60a86150bb3979073528877029b35aecd2072 + languageName: node + linkType: hard + +"react-konva@npm:^19.2.3": + version: 19.2.3 + resolution: "react-konva@npm:19.2.3" + dependencies: + "@types/react-reconciler": "npm:^0.33.0" + its-fine: "npm:^2.0.0" + react-reconciler: "npm:0.33.0" + scheduler: "npm:0.27.0" + peerDependencies: + konva: ^8.0.1 || ^7.2.5 || ^9.0.0 || ^10.0.0 + react: ^19.2.0 + react-dom: ^19.2.0 + checksum: 10c0/7a7fa60d1e85d794be13bfab5890939f7adc39b29857118103de07bbe4b441281050376bf3e75d0bf6758d4a38dd04100d2a0686e855dc54a8845799cc5d99e6 + languageName: node + linkType: hard + +"react-reconciler@npm:0.33.0": + version: 0.33.0 + resolution: "react-reconciler@npm:0.33.0" + dependencies: + scheduler: "npm:^0.27.0" + peerDependencies: + react: ^19.2.0 + checksum: 10c0/3f7b27ea8d0ff4c8bf0e402a285e1af9b7d0e6f4c1a70a28f4384938bc1130bc82a90a31df0b79ef5e380e2e55e2598bd90b4dbf802b1203d735ba0355817d3a + languageName: node + linkType: hard + +"react@npm:^19.2.5": + version: 19.2.5 + resolution: "react@npm:19.2.5" + checksum: 10c0/4b5f231dbef92886f602533c9ce3bde04d99f0e71dfb5d794c43e02726efaad0421c08688f75fc98a6d6e1dc017372e1af7abbfecdc86a79968f461675931a7a + languageName: node + linkType: hard + +"require-directory@npm:^2.1.1": + version: 2.1.1 + resolution: "require-directory@npm:2.1.1" + checksum: 10c0/83aa76a7bc1531f68d92c75a2ca2f54f1b01463cb566cf3fbc787d0de8be30c9dbc211d1d46be3497dac5785fe296f2dd11d531945ac29730643357978966e99 + languageName: node + linkType: hard + +"resolve-cwd@npm:^3.0.0": + version: 3.0.0 + resolution: "resolve-cwd@npm:3.0.0" + dependencies: + resolve-from: "npm:^5.0.0" + checksum: 10c0/e608a3ebd15356264653c32d7ecbc8fd702f94c6703ea4ac2fb81d9c359180cba0ae2e6b71faa446631ed6145454d5a56b227efc33a2d40638ac13f8beb20ee4 + languageName: node + linkType: hard + +"resolve-from@npm:^5.0.0": + version: 5.0.0 + resolution: "resolve-from@npm:5.0.0" + checksum: 10c0/b21cb7f1fb746de8107b9febab60095187781137fd803e6a59a76d421444b1531b641bba5857f5dc011974d8a5c635d61cec49e6bd3b7fc20e01f0fafc4efbf2 + languageName: node + linkType: hard + +"resolve@npm:^1.22.1": + version: 1.22.12 + resolution: "resolve@npm:1.22.12" + dependencies: + es-errors: "npm:^1.3.0" + is-core-module: "npm:^2.16.1" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10c0/b16dc9b537c02e8c3388f7d3dcff9741d3071625f9a97ac1c885f2b0ca51e78df22328fb6d6ef214dd9101fb7cfc19aa2836fe3410402a94f3f7b8639c7149bf + languageName: node + linkType: hard + +"resolve@patch:resolve@npm%3A^1.22.1#optional!builtin": + version: 1.22.12 + resolution: "resolve@patch:resolve@npm%3A1.22.12#optional!builtin::version=1.22.12&hash=c3c19d" + dependencies: + es-errors: "npm:^1.3.0" + is-core-module: "npm:^2.16.1" + path-parse: "npm:^1.0.7" + supports-preserve-symlinks-flag: "npm:^1.0.0" + bin: + resolve: bin/resolve + checksum: 10c0/fc6519984ae1f894d877c0060ba8b1f5ba3bc0e85a02f74e141929c118c23d74d9735619a9cc2965397387e514884245c65d72a40731dcb6cfc84c7bcdc8321e + languageName: node + linkType: hard + +"rollup@npm:^4.60.0": + version: 4.60.2 + resolution: "rollup@npm:4.60.2" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.60.2" + "@rollup/rollup-android-arm64": "npm:4.60.2" + "@rollup/rollup-darwin-arm64": "npm:4.60.2" + "@rollup/rollup-darwin-x64": "npm:4.60.2" + "@rollup/rollup-freebsd-arm64": "npm:4.60.2" + "@rollup/rollup-freebsd-x64": "npm:4.60.2" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.60.2" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.60.2" + "@rollup/rollup-linux-arm64-gnu": "npm:4.60.2" + "@rollup/rollup-linux-arm64-musl": "npm:4.60.2" + "@rollup/rollup-linux-loong64-gnu": "npm:4.60.2" + "@rollup/rollup-linux-loong64-musl": "npm:4.60.2" + "@rollup/rollup-linux-ppc64-gnu": "npm:4.60.2" + "@rollup/rollup-linux-ppc64-musl": "npm:4.60.2" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.60.2" + "@rollup/rollup-linux-riscv64-musl": "npm:4.60.2" + "@rollup/rollup-linux-s390x-gnu": "npm:4.60.2" + "@rollup/rollup-linux-x64-gnu": "npm:4.60.2" + "@rollup/rollup-linux-x64-musl": "npm:4.60.2" + "@rollup/rollup-openbsd-x64": "npm:4.60.2" + "@rollup/rollup-openharmony-arm64": "npm:4.60.2" + "@rollup/rollup-win32-arm64-msvc": "npm:4.60.2" + "@rollup/rollup-win32-ia32-msvc": "npm:4.60.2" + "@rollup/rollup-win32-x64-gnu": "npm:4.60.2" + "@rollup/rollup-win32-x64-msvc": "npm:4.60.2" + "@types/estree": "npm:1.0.8" + fsevents: "npm:~2.3.2" + dependenciesMeta: + "@rollup/rollup-android-arm-eabi": + optional: true + "@rollup/rollup-android-arm64": + optional: true + "@rollup/rollup-darwin-arm64": + optional: true + "@rollup/rollup-darwin-x64": + optional: true + "@rollup/rollup-freebsd-arm64": + optional: true + "@rollup/rollup-freebsd-x64": + optional: true + "@rollup/rollup-linux-arm-gnueabihf": + optional: true + "@rollup/rollup-linux-arm-musleabihf": + optional: true + "@rollup/rollup-linux-arm64-gnu": + optional: true + "@rollup/rollup-linux-arm64-musl": + optional: true + "@rollup/rollup-linux-loong64-gnu": + optional: true + "@rollup/rollup-linux-loong64-musl": + optional: true + "@rollup/rollup-linux-ppc64-gnu": + optional: true + "@rollup/rollup-linux-ppc64-musl": + optional: true + "@rollup/rollup-linux-riscv64-gnu": + optional: true + "@rollup/rollup-linux-riscv64-musl": + optional: true + "@rollup/rollup-linux-s390x-gnu": + optional: true + "@rollup/rollup-linux-x64-gnu": + optional: true + "@rollup/rollup-linux-x64-musl": + optional: true + "@rollup/rollup-openbsd-x64": + optional: true + "@rollup/rollup-openharmony-arm64": + optional: true + "@rollup/rollup-win32-arm64-msvc": + optional: true + "@rollup/rollup-win32-ia32-msvc": + optional: true + "@rollup/rollup-win32-x64-gnu": + optional: true + "@rollup/rollup-win32-x64-msvc": + optional: true + fsevents: + optional: true + bin: + rollup: dist/bin/rollup + checksum: 10c0/f67d6156fc5b895f33b929a4762392906d00fa5550f0a1f5e66519ab1c05d835aec5f201b4e748c29d1c87f024d3d9c4b0a2d1285668456db661d82b961d379c + languageName: node + linkType: hard + +"scheduler@npm:0.27.0, scheduler@npm:^0.27.0": + version: 0.27.0 + resolution: "scheduler@npm:0.27.0" + checksum: 10c0/4f03048cb05a3c8fddc45813052251eca00688f413a3cee236d984a161da28db28ba71bd11e7a3dd02f7af84ab28d39fb311431d3b3772fed557945beb00c452 + languageName: node + linkType: hard + +"semver@npm:^6.3.1": + version: 6.3.1 + resolution: "semver@npm:6.3.1" + bin: + semver: bin/semver.js + checksum: 10c0/e3d79b609071caa78bcb6ce2ad81c7966a46a7431d9d58b8800cfa9cb6a63699b3899a0e4bcce36167a284578212d9ae6942b6929ba4aa5015c079a67751d42d + languageName: node + linkType: hard + +"semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.7.2, semver@npm:^7.7.3, semver@npm:^7.7.4": + version: 7.7.4 + resolution: "semver@npm:7.7.4" + bin: + semver: bin/semver.js + checksum: 10c0/5215ad0234e2845d4ea5bb9d836d42b03499546ddafb12075566899fc617f68794bb6f146076b6881d755de17d6c6cc73372555879ec7dce2c2feee947866ad2 + languageName: node + linkType: hard + +"serialize-javascript@npm:^7.0.3": + version: 7.0.5 + resolution: "serialize-javascript@npm:7.0.5" + checksum: 10c0/7b7818e5267f6d474ec7a56d36ba69dd712726a13eab37706ec94615fb7ca8945471f2b7fb0dc9dbe8c79c1930c1079d97f66f91315c8c8c2ca6c38898cec96f + languageName: node + linkType: hard + +"shebang-command@npm:^2.0.0": + version: 2.0.0 + resolution: "shebang-command@npm:2.0.0" + dependencies: + shebang-regex: "npm:^3.0.0" + checksum: 10c0/a41692e7d89a553ef21d324a5cceb5f686d1f3c040759c50aab69688634688c5c327f26f3ecf7001ebfd78c01f3c7c0a11a7c8bfd0a8bc9f6240d4f40b224e4e + languageName: node + linkType: hard + +"shebang-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "shebang-regex@npm:3.0.0" + checksum: 10c0/1dbed0726dd0e1152a92696c76c7f06084eb32a90f0528d11acd764043aacf76994b2fb30aa1291a21bd019d6699164d048286309a278855ee7bec06cf6fb690 + languageName: node + linkType: hard + +"signal-exit@npm:^3.0.3": + version: 3.0.7 + resolution: "signal-exit@npm:3.0.7" + checksum: 10c0/25d272fa73e146048565e08f3309d5b942c1979a6f4a58a8c59d5fa299728e9c2fcd1a759ec870863b1fd38653670240cd420dad2ad9330c71f36608a6a1c912 + languageName: node + linkType: hard + +"signal-exit@npm:^4.0.1": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: 10c0/41602dce540e46d599edba9d9860193398d135f7ff72cab629db5171516cfae628d21e7bfccde1bbfdf11c48726bc2a6d1a8fb8701125852fbfda7cf19c6aa83 + languageName: node + linkType: hard + +"slash@npm:^3.0.0": + version: 3.0.0 + resolution: "slash@npm:3.0.0" + checksum: 10c0/e18488c6a42bdfd4ac5be85b2ced3ccd0224773baae6ad42cfbb9ec74fc07f9fa8396bd35ee638084ead7a2a0818eb5e7151111544d4731ce843019dab4be47b + languageName: node + linkType: hard + +"smob@npm:^1.0.0": + version: 1.6.1 + resolution: "smob@npm:1.6.1" + checksum: 10c0/5de0da7dcedcb5fa94578dec24b3f7c4cbc3823dac5b92d293927357d924e494df4a31168e5e19bdec030c2675d2209044d189740e59bb268feb2b0d5c221a70 + languageName: node + linkType: hard + +"source-map-support@npm:0.5.13": + version: 0.5.13 + resolution: "source-map-support@npm:0.5.13" + dependencies: + buffer-from: "npm:^1.0.0" + source-map: "npm:^0.6.0" + checksum: 10c0/137539f8c453fa0f496ea42049ab5da4569f96781f6ac8e5bfda26937be9494f4e8891f523c5f98f0e85f71b35d74127a00c46f83f6a4f54672b58d53202565e + languageName: node + linkType: hard + +"source-map-support@npm:~0.5.20": + version: 0.5.21 + resolution: "source-map-support@npm:0.5.21" + dependencies: + buffer-from: "npm:^1.0.0" + source-map: "npm:^0.6.0" + checksum: 10c0/9ee09942f415e0f721d6daad3917ec1516af746a8120bba7bb56278707a37f1eb8642bde456e98454b8a885023af81a16e646869975f06afc1a711fb90484e7d + languageName: node + linkType: hard + +"source-map@npm:^0.6.0, source-map@npm:^0.6.1": + version: 0.6.1 + resolution: "source-map@npm:0.6.1" + checksum: 10c0/ab55398007c5e5532957cb0beee2368529618ac0ab372d789806f5718123cc4367d57de3904b4e6a4170eb5a0b0f41373066d02ca0735a0c4d75c7d328d3e011 + languageName: node + linkType: hard + +"sprintf-js@npm:~1.0.2": + version: 1.0.3 + resolution: "sprintf-js@npm:1.0.3" + checksum: 10c0/ecadcfe4c771890140da5023d43e190b7566d9cf8b2d238600f31bec0fc653f328da4450eb04bd59a431771a8e9cc0e118f0aa3974b683a4981b4e07abc2a5bb + languageName: node + linkType: hard + +"stack-utils@npm:^2.0.6": + version: 2.0.6 + resolution: "stack-utils@npm:2.0.6" + dependencies: + escape-string-regexp: "npm:^2.0.0" + checksum: 10c0/651c9f87667e077584bbe848acaecc6049bc71979f1e9a46c7b920cad4431c388df0f51b8ad7cfd6eed3db97a2878d0fc8b3122979439ea8bac29c61c95eec8a + languageName: node + linkType: hard + +"string-length@npm:^4.0.2": + version: 4.0.2 + resolution: "string-length@npm:4.0.2" + dependencies: + char-regex: "npm:^1.0.2" + strip-ansi: "npm:^6.0.0" + checksum: 10c0/1cd77409c3d7db7bc59406f6bcc9ef0783671dcbabb23597a1177c166906ef2ee7c8290f78cae73a8aec858768f189d2cb417797df5e15ec4eb5e16b3346340c + languageName: node + linkType: hard + +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: "npm:^8.0.0" + is-fullwidth-code-point: "npm:^3.0.0" + strip-ansi: "npm:^6.0.1" + checksum: 10c0/1e525e92e5eae0afd7454086eed9c818ee84374bb80328fc41217ae72ff5f065ef1c9d7f72da41de40c75fa8bb3dee63d92373fd492c84260a552c636392a47b + languageName: node + linkType: hard + +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": + version: 5.1.2 + resolution: "string-width@npm:5.1.2" + dependencies: + eastasianwidth: "npm:^0.2.0" + emoji-regex: "npm:^9.2.2" + strip-ansi: "npm:^7.0.1" + checksum: 10c0/ab9c4264443d35b8b923cbdd513a089a60de339216d3b0ed3be3ba57d6880e1a192b70ae17225f764d7adbf5994e9bb8df253a944736c15a0240eff553c678ca + languageName: node + linkType: hard + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: "npm:^5.0.1" + checksum: 10c0/1ae5f212a126fe5b167707f716942490e3933085a5ff6c008ab97ab2f272c8025d3aa218b7bd6ab25729ca20cc81cddb252102f8751e13482a5199e873680952 + languageName: node + linkType: hard + +"strip-ansi@npm:^7.0.1": + version: 7.2.0 + resolution: "strip-ansi@npm:7.2.0" + dependencies: + ansi-regex: "npm:^6.2.2" + checksum: 10c0/544d13b7582f8254811ea97db202f519e189e59d35740c46095897e254e4f1aa9fe1524a83ad6bc5ad67d4dd6c0281d2e0219ed62b880a6238a16a17d375f221 + languageName: node + linkType: hard + +"strip-bom@npm:^4.0.0": + version: 4.0.0 + resolution: "strip-bom@npm:4.0.0" + checksum: 10c0/26abad1172d6bc48985ab9a5f96c21e440f6e7e476686de49be813b5a59b3566dccb5c525b831ec54fe348283b47f3ffb8e080bc3f965fde12e84df23f6bb7ef + languageName: node + linkType: hard + +"strip-final-newline@npm:^2.0.0": + version: 2.0.0 + resolution: "strip-final-newline@npm:2.0.0" + checksum: 10c0/bddf8ccd47acd85c0e09ad7375409d81653f645fda13227a9d459642277c253d877b68f2e5e4d819fe75733b0e626bac7e954c04f3236f6d196f79c94fa4a96f + languageName: node + linkType: hard + +"strip-json-comments@npm:^3.1.1": + version: 3.1.1 + resolution: "strip-json-comments@npm:3.1.1" + checksum: 10c0/9681a6257b925a7fa0f285851c0e613cc934a50661fa7bb41ca9cbbff89686bb4a0ee366e6ecedc4daafd01e83eee0720111ab294366fe7c185e935475ebcecd + languageName: node + linkType: hard + +"supports-color@npm:^7.1.0": + version: 7.2.0 + resolution: "supports-color@npm:7.2.0" + dependencies: + has-flag: "npm:^4.0.0" + checksum: 10c0/afb4c88521b8b136b5f5f95160c98dee7243dc79d5432db7efc27efb219385bbc7d9427398e43dd6cc730a0f87d5085ce1652af7efbe391327bc0a7d0f7fc124 + languageName: node + linkType: hard + +"supports-color@npm:^8.1.1": + version: 8.1.1 + resolution: "supports-color@npm:8.1.1" + dependencies: + has-flag: "npm:^4.0.0" + checksum: 10c0/ea1d3c275dd604c974670f63943ed9bd83623edc102430c05adb8efc56ba492746b6e95386e7831b872ec3807fd89dd8eb43f735195f37b5ec343e4234cc7e89 + languageName: node + linkType: hard + +"supports-preserve-symlinks-flag@npm:^1.0.0": + version: 1.0.0 + resolution: "supports-preserve-symlinks-flag@npm:1.0.0" + checksum: 10c0/6c4032340701a9950865f7ae8ef38578d8d7053f5e10518076e6554a9381fa91bd9c6850193695c141f32b21f979c985db07265a758867bac95de05f7d8aeb39 + languageName: node + linkType: hard + +"synckit@npm:^0.11.8": + version: 0.11.12 + resolution: "synckit@npm:0.11.12" + dependencies: + "@pkgr/core": "npm:^0.2.9" + checksum: 10c0/cc4d446806688ae0d728ae7bb3f53176d065cf9536647fb85bdd721dcefbd7bf94874df6799ff61580f2b03a392659219b778a9254ad499f9a1f56c34787c235 + languageName: node + linkType: hard + +"tar@npm:^7.5.4": + version: 7.5.13 + resolution: "tar@npm:7.5.13" + dependencies: + "@isaacs/fs-minipass": "npm:^4.0.0" + chownr: "npm:^3.0.0" + minipass: "npm:^7.1.2" + minizlib: "npm:^3.1.0" + yallist: "npm:^5.0.0" + checksum: 10c0/5c65b8084799bde7a791593a1c1a45d3d6ee98182e3700b24c247b7b8f8654df4191642abbdb07ff25043d45dcff35620827c3997b88ae6c12040f64bed5076b + languageName: node + linkType: hard + +"terser@npm:^5.17.4": + version: 5.46.2 + resolution: "terser@npm:5.46.2" + dependencies: + "@jridgewell/source-map": "npm:^0.3.3" + acorn: "npm:^8.15.0" + commander: "npm:^2.20.0" + source-map-support: "npm:~0.5.20" + bin: + terser: bin/terser + checksum: 10c0/476f1820160c42e6b2f611410115b00321c4666d421f12db87f13810f8789de45cb254e3ad5178650696d0ba6b706f5a0a239272255d6d1be95816c660f8cbbb + languageName: node + linkType: hard + +"test-exclude@npm:^6.0.0": + version: 6.0.0 + resolution: "test-exclude@npm:6.0.0" + dependencies: + "@istanbuljs/schema": "npm:^0.1.2" + glob: "npm:^7.1.4" + minimatch: "npm:^3.0.4" + checksum: 10c0/019d33d81adff3f9f1bfcff18125fb2d3c65564f437d9be539270ee74b994986abb8260c7c2ce90e8f30162178b09dbbce33c6389273afac4f36069c48521f57 + languageName: node + linkType: hard + +"tinyglobby@npm:^0.2.12, tinyglobby@npm:^0.2.15": + version: 0.2.16 + resolution: "tinyglobby@npm:0.2.16" + dependencies: + fdir: "npm:^6.5.0" + picomatch: "npm:^4.0.4" + checksum: 10c0/f2e09fd93dd95c41e522113b686ff6f7c13020962f8698a864a257f3d7737599afc47722b7ab726e12f8a813f779906187911ff8ee6701ede65072671a7e934b + languageName: node + linkType: hard + +"tmpl@npm:1.0.5": + version: 1.0.5 + resolution: "tmpl@npm:1.0.5" + checksum: 10c0/f935537799c2d1922cb5d6d3805f594388f75338fe7a4a9dac41504dd539704ca4db45b883b52e7b0aa5b2fd5ddadb1452bf95cd23a69da2f793a843f9451cc9 + languageName: node + linkType: hard + +"ts-api-utils@npm:^2.5.0": + version: 2.5.0 + resolution: "ts-api-utils@npm:2.5.0" + peerDependencies: + typescript: ">=4.8.4" + checksum: 10c0/767849383c114e7f1971fa976b20e73ac28fd0c70d8d65c0004790bf4d8f89888c7e4cf6d5949f9c1beae9bc3c64835bef77bbe27fddf45a3c7b60cebcf85c8c + languageName: node + linkType: hard + +"ts-jest@npm:^29.4.6": + version: 29.4.9 + resolution: "ts-jest@npm:29.4.9" + dependencies: + bs-logger: "npm:^0.2.6" + fast-json-stable-stringify: "npm:^2.1.0" + handlebars: "npm:^4.7.9" + json5: "npm:^2.2.3" + lodash.memoize: "npm:^4.1.2" + make-error: "npm:^1.3.6" + semver: "npm:^7.7.4" + type-fest: "npm:^4.41.0" + yargs-parser: "npm:^21.1.1" + peerDependencies: + "@babel/core": ">=7.0.0-beta.0 <8" + "@jest/transform": ^29.0.0 || ^30.0.0 + "@jest/types": ^29.0.0 || ^30.0.0 + babel-jest: ^29.0.0 || ^30.0.0 + jest: ^29.0.0 || ^30.0.0 + jest-util: ^29.0.0 || ^30.0.0 + typescript: ">=4.3 <7" + peerDependenciesMeta: + "@babel/core": + optional: true + "@jest/transform": + optional: true + "@jest/types": + optional: true + babel-jest: + optional: true + esbuild: + optional: true + jest-util: + optional: true + bin: + ts-jest: cli.js + checksum: 10c0/901eb382817d1f48fc56b6c9b82de989f176660295695ae1fcd55f06f71d2c107766e1413ab24a59fa964c2ef79a60dd23ac1f382b05ae04f2b454fb4eb5ad4f + languageName: node + linkType: hard + +"tslib@npm:^2.4.0": + version: 2.8.1 + resolution: "tslib@npm:2.8.1" + checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 + languageName: node + linkType: hard + +"type-check@npm:^0.4.0, type-check@npm:~0.4.0": + version: 0.4.0 + resolution: "type-check@npm:0.4.0" + dependencies: + prelude-ls: "npm:^1.2.1" + checksum: 10c0/7b3fd0ed43891e2080bf0c5c504b418fbb3e5c7b9708d3d015037ba2e6323a28152ec163bcb65212741fa5d2022e3075ac3c76440dbd344c9035f818e8ecee58 + languageName: node + linkType: hard + +"type-detect@npm:4.0.8": + version: 4.0.8 + resolution: "type-detect@npm:4.0.8" + checksum: 10c0/8fb9a51d3f365a7de84ab7f73b653534b61b622aa6800aecdb0f1095a4a646d3f5eb295322127b6573db7982afcd40ab492d038cf825a42093a58b1e1353e0bd + languageName: node + linkType: hard + +"type-fest@npm:^0.21.3": + version: 0.21.3 + resolution: "type-fest@npm:0.21.3" + checksum: 10c0/902bd57bfa30d51d4779b641c2bc403cdf1371fb9c91d3c058b0133694fcfdb817aef07a47f40faf79039eecbaa39ee9d3c532deff244f3a19ce68cea71a61e8 + languageName: node + linkType: hard + +"type-fest@npm:^4.41.0": + version: 4.41.0 + resolution: "type-fest@npm:4.41.0" + checksum: 10c0/f5ca697797ed5e88d33ac8f1fec21921839871f808dc59345c9cf67345bfb958ce41bd821165dbf3ae591cedec2bf6fe8882098dfdd8dc54320b859711a2c1e4 + languageName: node + linkType: hard + +"typescript-eslint@npm:^8.57.1": + version: 8.59.1 + resolution: "typescript-eslint@npm:8.59.1" + dependencies: + "@typescript-eslint/eslint-plugin": "npm:8.59.1" + "@typescript-eslint/parser": "npm:8.59.1" + "@typescript-eslint/typescript-estree": "npm:8.59.1" + "@typescript-eslint/utils": "npm:8.59.1" + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: ">=4.8.4 <6.1.0" + checksum: 10c0/93f3d66e2a2427a719a19f7bfd5d21c76a6bdcf9cfe82ba14d37f869434893f7d4d62c75671a87a93a3ef13816636d2bfe79b2f145d6cbcda5efbfddd90c1c2d + languageName: node + linkType: hard + +"typescript@npm:^6.0.3": + version: 6.0.3 + resolution: "typescript@npm:6.0.3" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10c0/4a25ff5045b984370f48f196b3a0120779b1b343d40b9a68d114ea5e5fff099809b2bb777576991a63a5cd59cf7bffd96ff6fe10afcefbcb8bd6fb96ad4b6606 + languageName: node + linkType: hard + +"typescript@patch:typescript@npm%3A^6.0.3#optional!builtin": + version: 6.0.3 + resolution: "typescript@patch:typescript@npm%3A6.0.3#optional!builtin::version=6.0.3&hash=5786d5" + bin: + tsc: bin/tsc + tsserver: bin/tsserver + checksum: 10c0/2f25c74e65663c248fa1ade2b8459d9ce5372ff9dad07067310f132966ebec1d93f6c42f0baf77a6b6a7a91460463f708e6887013aaade22111037457c6b25df + languageName: node + linkType: hard + +"uglify-js@npm:^3.1.4": + version: 3.19.3 + resolution: "uglify-js@npm:3.19.3" + bin: + uglifyjs: bin/uglifyjs + checksum: 10c0/83b0a90eca35f778e07cad9622b80c448b6aad457c9ff8e568afed978212b42930a95f9e1be943a1ffa4258a3340fbb899f41461131c05bb1d0a9c303aed8479 + languageName: node + linkType: hard + +"undici-types@npm:~7.19.0": + version: 7.19.2 + resolution: "undici-types@npm:7.19.2" + checksum: 10c0/7159f10546f9f6c47d36776bb1bbf8671e87c1e587a6fee84ae1f111ae8de4f914efa8ca0dfcd224f4f4a9dfc3f6028f627ccb5ddaccf82d7fd54671b89fac3e + languageName: node + linkType: hard + +"undici@npm:^6.25.0": + version: 6.25.0 + resolution: "undici@npm:6.25.0" + checksum: 10c0/2597cc6689bdb02c210c557b1f85febbfda65becae6e6fc1061508e2f33734d25207f81cd8af56ada9956329eb3a7bd7431e87dcfeceba20ee87059b57dcf985 + languageName: node + linkType: hard + +"unrs-resolver@npm:^1.7.11": + version: 1.11.1 + resolution: "unrs-resolver@npm:1.11.1" + dependencies: + "@unrs/resolver-binding-android-arm-eabi": "npm:1.11.1" + "@unrs/resolver-binding-android-arm64": "npm:1.11.1" + "@unrs/resolver-binding-darwin-arm64": "npm:1.11.1" + "@unrs/resolver-binding-darwin-x64": "npm:1.11.1" + "@unrs/resolver-binding-freebsd-x64": "npm:1.11.1" + "@unrs/resolver-binding-linux-arm-gnueabihf": "npm:1.11.1" + "@unrs/resolver-binding-linux-arm-musleabihf": "npm:1.11.1" + "@unrs/resolver-binding-linux-arm64-gnu": "npm:1.11.1" + "@unrs/resolver-binding-linux-arm64-musl": "npm:1.11.1" + "@unrs/resolver-binding-linux-ppc64-gnu": "npm:1.11.1" + "@unrs/resolver-binding-linux-riscv64-gnu": "npm:1.11.1" + "@unrs/resolver-binding-linux-riscv64-musl": "npm:1.11.1" + "@unrs/resolver-binding-linux-s390x-gnu": "npm:1.11.1" + "@unrs/resolver-binding-linux-x64-gnu": "npm:1.11.1" + "@unrs/resolver-binding-linux-x64-musl": "npm:1.11.1" + "@unrs/resolver-binding-wasm32-wasi": "npm:1.11.1" + "@unrs/resolver-binding-win32-arm64-msvc": "npm:1.11.1" + "@unrs/resolver-binding-win32-ia32-msvc": "npm:1.11.1" + "@unrs/resolver-binding-win32-x64-msvc": "npm:1.11.1" + napi-postinstall: "npm:^0.3.0" + dependenciesMeta: + "@unrs/resolver-binding-android-arm-eabi": + optional: true + "@unrs/resolver-binding-android-arm64": + optional: true + "@unrs/resolver-binding-darwin-arm64": + optional: true + "@unrs/resolver-binding-darwin-x64": + optional: true + "@unrs/resolver-binding-freebsd-x64": + optional: true + "@unrs/resolver-binding-linux-arm-gnueabihf": + optional: true + "@unrs/resolver-binding-linux-arm-musleabihf": + optional: true + "@unrs/resolver-binding-linux-arm64-gnu": + optional: true + "@unrs/resolver-binding-linux-arm64-musl": + optional: true + "@unrs/resolver-binding-linux-ppc64-gnu": + optional: true + "@unrs/resolver-binding-linux-riscv64-gnu": + optional: true + "@unrs/resolver-binding-linux-riscv64-musl": + optional: true + "@unrs/resolver-binding-linux-s390x-gnu": + optional: true + "@unrs/resolver-binding-linux-x64-gnu": + optional: true + "@unrs/resolver-binding-linux-x64-musl": + optional: true + "@unrs/resolver-binding-wasm32-wasi": + optional: true + "@unrs/resolver-binding-win32-arm64-msvc": + optional: true + "@unrs/resolver-binding-win32-ia32-msvc": + optional: true + "@unrs/resolver-binding-win32-x64-msvc": + optional: true + checksum: 10c0/c91b112c71a33d6b24e5c708dab43ab80911f2df8ee65b87cd7a18fb5af446708e98c4b415ca262026ad8df326debcc7ca6a801b2935504d87fd6f0b9d70dce1 + languageName: node + linkType: hard + +"update-browserslist-db@npm:^1.2.3": + version: 1.2.3 + resolution: "update-browserslist-db@npm:1.2.3" + dependencies: + escalade: "npm:^3.2.0" + picocolors: "npm:^1.1.1" + peerDependencies: + browserslist: ">= 4.21.0" + bin: + update-browserslist-db: cli.js + checksum: 10c0/13a00355ea822388f68af57410ce3255941d5fb9b7c49342c4709a07c9f230bbef7f7499ae0ca7e0de532e79a82cc0c4edbd125f1a323a1845bf914efddf8bec + languageName: node + linkType: hard + +"uri-js@npm:^4.2.2": + version: 4.4.1 + resolution: "uri-js@npm:4.4.1" + dependencies: + punycode: "npm:^2.1.0" + checksum: 10c0/4ef57b45aa820d7ac6496e9208559986c665e49447cb072744c13b66925a362d96dd5a46c4530a6b8e203e5db5fe849369444440cb22ecfc26c679359e5dfa3c + languageName: node + linkType: hard + +"v8-to-istanbul@npm:^9.0.1": + version: 9.3.0 + resolution: "v8-to-istanbul@npm:9.3.0" + dependencies: + "@jridgewell/trace-mapping": "npm:^0.3.12" + "@types/istanbul-lib-coverage": "npm:^2.0.1" + convert-source-map: "npm:^2.0.0" + checksum: 10c0/968bcf1c7c88c04df1ffb463c179558a2ec17aa49e49376120504958239d9e9dad5281aa05f2a78542b8557f2be0b0b4c325710262f3b838b40d703d5ed30c23 + languageName: node + linkType: hard + +"walker@npm:^1.0.8": + version: 1.0.8 + resolution: "walker@npm:1.0.8" + dependencies: + makeerror: "npm:1.0.12" + checksum: 10c0/a17e037bccd3ca8a25a80cb850903facdfed0de4864bd8728f1782370715d679fa72e0a0f5da7c1c1379365159901e5935f35be531229da53bbfc0efdabdb48e + languageName: node + linkType: hard + +"which@npm:^2.0.1": + version: 2.0.2 + resolution: "which@npm:2.0.2" + dependencies: + isexe: "npm:^2.0.0" + bin: + node-which: ./bin/node-which + checksum: 10c0/66522872a768b60c2a65a57e8ad184e5372f5b6a9ca6d5f033d4b0dc98aff63995655a7503b9c0a2598936f532120e81dd8cc155e2e92ed662a2b9377cc4374f + languageName: node + linkType: hard + +"which@npm:^6.0.0": + version: 6.0.1 + resolution: "which@npm:6.0.1" + dependencies: + isexe: "npm:^4.0.0" + bin: + node-which: bin/which.js + checksum: 10c0/7e710e54ea36d2d6183bee2f9caa27a3b47b9baf8dee55a199b736fcf85eab3b9df7556fca3d02b50af7f3dfba5ea3a45644189836df06267df457e354da66d5 + languageName: node + linkType: hard + +"word-wrap@npm:^1.2.5": + version: 1.2.5 + resolution: "word-wrap@npm:1.2.5" + checksum: 10c0/e0e4a1ca27599c92a6ca4c32260e8a92e8a44f4ef6ef93f803f8ed823f486e0889fc0b93be4db59c8d51b3064951d25e43d434e95dc8c960cc3a63d65d00ba20 + languageName: node + linkType: hard + +"wordwrap@npm:^1.0.0": + version: 1.0.0 + resolution: "wordwrap@npm:1.0.0" + checksum: 10c0/7ed2e44f3c33c5c3e3771134d2b0aee4314c9e49c749e37f464bf69f2bcdf0cbf9419ca638098e2717cff4875c47f56a007532f6111c3319f557a2ca91278e92 + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: "npm:^4.0.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + checksum: 10c0/d15fc12c11e4cbc4044a552129ebc75ee3f57aa9c1958373a4db0292d72282f54373b536103987a4a7594db1ef6a4f10acf92978f79b98c49306a4b58c77d4da + languageName: node + linkType: hard + +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" + dependencies: + ansi-styles: "npm:^6.1.0" + string-width: "npm:^5.0.1" + strip-ansi: "npm:^7.0.1" + checksum: 10c0/138ff58a41d2f877eae87e3282c0630fc2789012fc1af4d6bd626eeb9a2f9a65ca92005e6e69a75c7b85a68479fe7443c7dbe1eb8fbaa681a4491364b7c55c60 + languageName: node + linkType: hard + +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 10c0/56fece1a4018c6a6c8e28fbc88c87e0fbf4ea8fd64fc6c63b18f4acc4bd13e0ad2515189786dd2c30d3eec9663d70f4ecf699330002f8ccb547e4a18231fc9f0 + languageName: node + linkType: hard + +"write-file-atomic@npm:^5.0.1": + version: 5.0.1 + resolution: "write-file-atomic@npm:5.0.1" + dependencies: + imurmurhash: "npm:^0.1.4" + signal-exit: "npm:^4.0.1" + checksum: 10c0/e8c850a8e3e74eeadadb8ad23c9d9d63e4e792bd10f4836ed74189ef6e996763959f1249c5650e232f3c77c11169d239cbfc8342fc70f3fe401407d23810505d + languageName: node + linkType: hard + +"y18n@npm:^5.0.5": + version: 5.0.8 + resolution: "y18n@npm:5.0.8" + checksum: 10c0/4df2842c36e468590c3691c894bc9cdbac41f520566e76e24f59401ba7d8b4811eb1e34524d57e54bc6d864bcb66baab7ffd9ca42bf1eda596618f9162b91249 + languageName: node + linkType: hard + +"yallist@npm:^3.0.2": + version: 3.1.1 + resolution: "yallist@npm:3.1.1" + checksum: 10c0/c66a5c46bc89af1625476f7f0f2ec3653c1a1791d2f9407cfb4c2ba812a1e1c9941416d71ba9719876530e3340a99925f697142989371b72d93b9ee628afd8c1 + languageName: node + linkType: hard + +"yallist@npm:^5.0.0": + version: 5.0.0 + resolution: "yallist@npm:5.0.0" + checksum: 10c0/a499c81ce6d4a1d260d4ea0f6d49ab4da09681e32c3f0472dee16667ed69d01dae63a3b81745a24bd78476ec4fcf856114cb4896ace738e01da34b2c42235416 + languageName: node + linkType: hard + +"yargs-parser@npm:^21.1.1": + version: 21.1.1 + resolution: "yargs-parser@npm:21.1.1" + checksum: 10c0/f84b5e48169479d2f402239c59f084cfd1c3acc197a05c59b98bab067452e6b3ea46d4dd8ba2985ba7b3d32a343d77df0debd6b343e5dae3da2aab2cdf5886b2 + languageName: node + linkType: hard + +"yargs@npm:^17.7.2": + version: 17.7.2 + resolution: "yargs@npm:17.7.2" + dependencies: + cliui: "npm:^8.0.1" + escalade: "npm:^3.1.1" + get-caller-file: "npm:^2.0.5" + require-directory: "npm:^2.1.1" + string-width: "npm:^4.2.3" + y18n: "npm:^5.0.5" + yargs-parser: "npm:^21.1.1" + checksum: 10c0/ccd7e723e61ad5965fffbb791366db689572b80cca80e0f96aad968dfff4156cd7cd1ad18607afe1046d8241e6fb2d6c08bf7fa7bfb5eaec818735d8feac8f05 + languageName: node + linkType: hard + +"yocto-queue@npm:^0.1.0": + version: 0.1.0 + resolution: "yocto-queue@npm:0.1.0" + checksum: 10c0/dceb44c28578b31641e13695d200d34ec4ab3966a5729814d5445b194933c096b7ced71494ce53a0e8820685d1d010df8b2422e5bf2cdea7e469d97ffbea306f + languageName: node + linkType: hard From 5ca4abbd72ac3867a9416376474978a0a408c7e9 Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Tue, 26 May 2026 23:57:24 +0800 Subject: [PATCH 02/16] feat: add ESLint and Prettier + tsconfigs --- .prettierrc | 5 + .vscode/extensions.json | 4 +- .yarn/sdks/typescript/lib/tsc.js | 8 +- .yarn/sdks/typescript/lib/tsserver.js | 177 ++++++++++++------- .yarn/sdks/typescript/lib/tsserverlibrary.js | 177 ++++++++++++------- .yarn/sdks/typescript/lib/typescript.js | 8 +- eslint.config.mjs | 39 ++++ package.json | 9 + src/tsconfig.json | 4 +- src/tsconfig.test.json | 7 + src/web/tsconfig.json | 2 +- 11 files changed, 292 insertions(+), 148 deletions(-) create mode 100644 .prettierrc create mode 100644 eslint.config.mjs create mode 100644 src/tsconfig.test.json diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..ac5d019 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "printWidth": 100, + "arrowParens": "avoid", + "endOfLine": "auto" +} \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 06dd640..1453f7f 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,5 +1,3 @@ { - "recommendations": [ - "arcanis.vscode-zipfs" - ] + "recommendations": ["arcanis.vscode-zipfs"] } diff --git a/.yarn/sdks/typescript/lib/tsc.js b/.yarn/sdks/typescript/lib/tsc.js index da411bd..857b6f9 100644 --- a/.yarn/sdks/typescript/lib/tsc.js +++ b/.yarn/sdks/typescript/lib/tsc.js @@ -1,9 +1,9 @@ #!/usr/bin/env node -const {existsSync} = require(`fs`); -const {createRequire, register} = require(`module`); -const {resolve} = require(`path`); -const {pathToFileURL} = require(`url`); +const { existsSync } = require(`fs`); +const { createRequire, register } = require(`module`); +const { resolve } = require(`path`); +const { pathToFileURL } = require(`url`); const relPnpApiPath = "../../../../.pnp.cjs"; diff --git a/.yarn/sdks/typescript/lib/tsserver.js b/.yarn/sdks/typescript/lib/tsserver.js index 6249c46..c266bc6 100644 --- a/.yarn/sdks/typescript/lib/tsserver.js +++ b/.yarn/sdks/typescript/lib/tsserver.js @@ -1,9 +1,9 @@ #!/usr/bin/env node -const {existsSync} = require(`fs`); -const {createRequire, register} = require(`module`); -const {resolve} = require(`path`); -const {pathToFileURL} = require(`url`); +const { existsSync } = require(`fs`); +const { createRequire, register } = require(`module`); +const { resolve } = require(`path`); +const { pathToFileURL } = require(`url`); const relPnpApiPath = "../../../../.pnp.cjs"; @@ -37,16 +37,18 @@ const moduleWrapperFn = tsserver => { return tsserver; } - const {isAbsolute} = require(`path`); + const { isAbsolute } = require(`path`); const pnpApi = require(`pnpapi`); const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//); const isPortal = str => str.startsWith("portal:/"); const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`); - const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => { - return `${locator.name}@${locator.reference}`; - })); + const dependencyTreeRoots = new Set( + pnpApi.getDependencyTreeRoots().map(locator => { + return `${locator.name}@${locator.reference}`; + }), + ); // VSCode sends the zip paths to TS using the "zip://" prefix, that TS // doesn't understand. This layer makes sure to remove the protocol @@ -54,7 +56,11 @@ const moduleWrapperFn = tsserver => { function toEditorPath(str) { // We add the `zip:` prefix to both `.zip/` paths and virtual paths - if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) { + if ( + isAbsolute(str) && + !str.match(/^\^?(zip:|\/zip\/)/) && + (str.match(/\.zip\//) || isVirtual(str)) + ) { // We also take the opportunity to turn virtual paths into physical ones; // this makes it much easier to work with workspaces that list peer // dependencies, since otherwise Ctrl+Click would bring us to the virtual @@ -68,7 +74,11 @@ const moduleWrapperFn = tsserver => { const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str; if (resolved) { const locator = pnpApi.findPackageLocator(resolved); - if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) { + if ( + locator && + (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || + isPortal(locator.reference)) + ) { str = resolved; } } @@ -96,41 +106,55 @@ const moduleWrapperFn = tsserver => { // Before | ^/zip/c:/foo/bar.zip/package.json // After | ^/zip//c:/foo/bar.zip/package.json // - case `vscode <1.61`: { - str = `^zip:${str}`; - } break; + case `vscode <1.61`: + { + str = `^zip:${str}`; + } + break; - case `vscode <1.66`: { - str = `^/zip/${str}`; - } break; + case `vscode <1.66`: + { + str = `^/zip/${str}`; + } + break; - case `vscode <1.68`: { - str = `^/zip${str}`; - } break; + case `vscode <1.68`: + { + str = `^/zip${str}`; + } + break; - case `vscode`: { - str = `^/zip/${str}`; - } break; + case `vscode`: + { + str = `^/zip/${str}`; + } + break; // To make "go to definition" work, // We have to resolve the actual file system path from virtual path // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip) - case `coc-nvim`: { - str = normalize(resolved).replace(/\.zip\//, `.zip::`); - str = resolve(`zipfile:${str}`); - } break; + case `coc-nvim`: + { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = resolve(`zipfile:${str}`); + } + break; // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server) // We have to resolve the actual file system path from virtual path, // everything else is up to neovim - case `neovim`: { - str = normalize(resolved).replace(/\.zip\//, `.zip::`); - str = `zipfile://${str}`; - } break; - - default: { - str = `zip:${str}`; - } break; + case `neovim`: + { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = `zipfile://${str}`; + } + break; + + default: + { + str = `zip:${str}`; + } + break; } } else { str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`); @@ -142,26 +166,35 @@ const moduleWrapperFn = tsserver => { function fromEditorPath(str) { switch (hostInfo) { - case `coc-nvim`: { - str = str.replace(/\.zip::/, `.zip/`); - // The path for coc-nvim is in format of //zipfile://.yarn/... - // So in order to convert it back, we use .* to match all the thing - // before `zipfile:` - return process.platform === `win32` - ? str.replace(/^.*zipfile:\//, ``) - : str.replace(/^.*zipfile:/, ``); - } break; - - case `neovim`: { - str = str.replace(/\.zip::/, `.zip/`); - // The path for neovim is in format of zipfile:////.yarn/... - return str.replace(/^zipfile:\/\//, ``); - } break; + case `coc-nvim`: + { + str = str.replace(/\.zip::/, `.zip/`); + // The path for coc-nvim is in format of //zipfile://.yarn/... + // So in order to convert it back, we use .* to match all the thing + // before `zipfile:` + return process.platform === `win32` + ? str.replace(/^.*zipfile:\//, ``) + : str.replace(/^.*zipfile:/, ``); + } + break; + + case `neovim`: + { + str = str.replace(/\.zip::/, `.zip/`); + // The path for neovim is in format of zipfile:////.yarn/... + return str.replace(/^zipfile:\/\//, ``); + } + break; case `vscode`: - default: { - return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`) - } break; + default: + { + return str.replace( + /^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, + process.platform === `win32` ? `` : `/`, + ); + } + break; } } @@ -173,8 +206,9 @@ const moduleWrapperFn = tsserver => { // TypeScript already does local loads and if this code is running the user trusts the workspace // https://github.com/microsoft/vscode/issues/45856 const ConfiguredProject = tsserver.server.ConfiguredProject; - const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype; - ConfiguredProject.prototype.enablePluginsWithOptions = function() { + const { enablePluginsWithOptions: originalEnablePluginsWithOptions } = + ConfiguredProject.prototype; + ConfiguredProject.prototype.enablePluginsWithOptions = function () { this.projectService.allowLocalPluginLoads = true; return originalEnablePluginsWithOptions.apply(this, arguments); }; @@ -184,12 +218,12 @@ const moduleWrapperFn = tsserver => { // like an absolute path of ours and normalize it. const Session = tsserver.server.Session; - const {onMessage: originalOnMessage, send: originalSend} = Session.prototype; + const { onMessage: originalOnMessage, send: originalSend } = Session.prototype; let hostInfo = `unknown`; Object.assign(Session.prototype, { onMessage(/** @type {string | object} */ message) { - const isStringMessage = typeof message === 'string'; + const isStringMessage = typeof message === "string"; const parsedMessage = isStringMessage ? JSON.parse(message) : message; if ( @@ -200,10 +234,12 @@ const moduleWrapperFn = tsserver => { ) { hostInfo = parsedMessage.arguments.hostInfo; if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) { - const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match( - // The RegExp from https://semver.org/ but without the caret at the start - /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ - ) ?? []).map(Number) + const [, major, minor] = ( + process.env.VSCODE_IPC_HOOK.match( + // The RegExp from https://semver.org/ but without the caret at the start + /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/, + ) ?? [] + ).map(Number); if (major === 1) { if (minor < 61) { @@ -218,26 +254,33 @@ const moduleWrapperFn = tsserver => { } const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => { - return typeof value === 'string' ? fromEditorPath(value) : value; + return typeof value === "string" ? fromEditorPath(value) : value; }); return originalOnMessage.call( this, - isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON) + isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON), ); }, send(/** @type {any} */ msg) { - return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => { - return typeof value === `string` ? toEditorPath(value) : value; - }))); - } + return originalSend.call( + this, + JSON.parse( + JSON.stringify(msg, (key, value) => { + return typeof value === `string` ? toEditorPath(value) : value; + }), + ), + ); + }, }); return tsserver; }; -const [major, minor] = absRequire(`typescript/package.json`).version.split(`.`, 2).map(value => parseInt(value, 10)); +const [major, minor] = absRequire(`typescript/package.json`) + .version.split(`.`, 2) + .map(value => parseInt(value, 10)); // In TypeScript@>=5.5 the tsserver uses the public TypeScript API so that needs to be patched as well. // Ref https://github.com/microsoft/TypeScript/pull/55326 if (major > 5 || (major === 5 && minor >= 5)) { diff --git a/.yarn/sdks/typescript/lib/tsserverlibrary.js b/.yarn/sdks/typescript/lib/tsserverlibrary.js index 0e50e0a..3072888 100644 --- a/.yarn/sdks/typescript/lib/tsserverlibrary.js +++ b/.yarn/sdks/typescript/lib/tsserverlibrary.js @@ -1,9 +1,9 @@ #!/usr/bin/env node -const {existsSync} = require(`fs`); -const {createRequire, register} = require(`module`); -const {resolve} = require(`path`); -const {pathToFileURL} = require(`url`); +const { existsSync } = require(`fs`); +const { createRequire, register } = require(`module`); +const { resolve } = require(`path`); +const { pathToFileURL } = require(`url`); const relPnpApiPath = "../../../../.pnp.cjs"; @@ -37,16 +37,18 @@ const moduleWrapperFn = tsserver => { return tsserver; } - const {isAbsolute} = require(`path`); + const { isAbsolute } = require(`path`); const pnpApi = require(`pnpapi`); const isVirtual = str => str.match(/\/(\$\$virtual|__virtual__)\//); const isPortal = str => str.startsWith("portal:/"); const normalize = str => str.replace(/\\/g, `/`).replace(/^\/?/, `/`); - const dependencyTreeRoots = new Set(pnpApi.getDependencyTreeRoots().map(locator => { - return `${locator.name}@${locator.reference}`; - })); + const dependencyTreeRoots = new Set( + pnpApi.getDependencyTreeRoots().map(locator => { + return `${locator.name}@${locator.reference}`; + }), + ); // VSCode sends the zip paths to TS using the "zip://" prefix, that TS // doesn't understand. This layer makes sure to remove the protocol @@ -54,7 +56,11 @@ const moduleWrapperFn = tsserver => { function toEditorPath(str) { // We add the `zip:` prefix to both `.zip/` paths and virtual paths - if (isAbsolute(str) && !str.match(/^\^?(zip:|\/zip\/)/) && (str.match(/\.zip\//) || isVirtual(str))) { + if ( + isAbsolute(str) && + !str.match(/^\^?(zip:|\/zip\/)/) && + (str.match(/\.zip\//) || isVirtual(str)) + ) { // We also take the opportunity to turn virtual paths into physical ones; // this makes it much easier to work with workspaces that list peer // dependencies, since otherwise Ctrl+Click would bring us to the virtual @@ -68,7 +74,11 @@ const moduleWrapperFn = tsserver => { const resolved = isVirtual(str) ? pnpApi.resolveVirtual(str) : str; if (resolved) { const locator = pnpApi.findPackageLocator(resolved); - if (locator && (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || isPortal(locator.reference))) { + if ( + locator && + (dependencyTreeRoots.has(`${locator.name}@${locator.reference}`) || + isPortal(locator.reference)) + ) { str = resolved; } } @@ -96,41 +106,55 @@ const moduleWrapperFn = tsserver => { // Before | ^/zip/c:/foo/bar.zip/package.json // After | ^/zip//c:/foo/bar.zip/package.json // - case `vscode <1.61`: { - str = `^zip:${str}`; - } break; + case `vscode <1.61`: + { + str = `^zip:${str}`; + } + break; - case `vscode <1.66`: { - str = `^/zip/${str}`; - } break; + case `vscode <1.66`: + { + str = `^/zip/${str}`; + } + break; - case `vscode <1.68`: { - str = `^/zip${str}`; - } break; + case `vscode <1.68`: + { + str = `^/zip${str}`; + } + break; - case `vscode`: { - str = `^/zip/${str}`; - } break; + case `vscode`: + { + str = `^/zip/${str}`; + } + break; // To make "go to definition" work, // We have to resolve the actual file system path from virtual path // and convert scheme to supported by [vim-rzip](https://github.com/lbrayner/vim-rzip) - case `coc-nvim`: { - str = normalize(resolved).replace(/\.zip\//, `.zip::`); - str = resolve(`zipfile:${str}`); - } break; + case `coc-nvim`: + { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = resolve(`zipfile:${str}`); + } + break; // Support neovim native LSP and [typescript-language-server](https://github.com/theia-ide/typescript-language-server) // We have to resolve the actual file system path from virtual path, // everything else is up to neovim - case `neovim`: { - str = normalize(resolved).replace(/\.zip\//, `.zip::`); - str = `zipfile://${str}`; - } break; - - default: { - str = `zip:${str}`; - } break; + case `neovim`: + { + str = normalize(resolved).replace(/\.zip\//, `.zip::`); + str = `zipfile://${str}`; + } + break; + + default: + { + str = `zip:${str}`; + } + break; } } else { str = str.replace(/^\/?/, process.platform === `win32` ? `` : `/`); @@ -142,26 +166,35 @@ const moduleWrapperFn = tsserver => { function fromEditorPath(str) { switch (hostInfo) { - case `coc-nvim`: { - str = str.replace(/\.zip::/, `.zip/`); - // The path for coc-nvim is in format of //zipfile://.yarn/... - // So in order to convert it back, we use .* to match all the thing - // before `zipfile:` - return process.platform === `win32` - ? str.replace(/^.*zipfile:\//, ``) - : str.replace(/^.*zipfile:/, ``); - } break; - - case `neovim`: { - str = str.replace(/\.zip::/, `.zip/`); - // The path for neovim is in format of zipfile:////.yarn/... - return str.replace(/^zipfile:\/\//, ``); - } break; + case `coc-nvim`: + { + str = str.replace(/\.zip::/, `.zip/`); + // The path for coc-nvim is in format of //zipfile://.yarn/... + // So in order to convert it back, we use .* to match all the thing + // before `zipfile:` + return process.platform === `win32` + ? str.replace(/^.*zipfile:\//, ``) + : str.replace(/^.*zipfile:/, ``); + } + break; + + case `neovim`: + { + str = str.replace(/\.zip::/, `.zip/`); + // The path for neovim is in format of zipfile:////.yarn/... + return str.replace(/^zipfile:\/\//, ``); + } + break; case `vscode`: - default: { - return str.replace(/^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, process.platform === `win32` ? `` : `/`) - } break; + default: + { + return str.replace( + /^\^?(zip:|\/zip(\/ts-nul-authority)?)\/+/, + process.platform === `win32` ? `` : `/`, + ); + } + break; } } @@ -173,8 +206,9 @@ const moduleWrapperFn = tsserver => { // TypeScript already does local loads and if this code is running the user trusts the workspace // https://github.com/microsoft/vscode/issues/45856 const ConfiguredProject = tsserver.server.ConfiguredProject; - const {enablePluginsWithOptions: originalEnablePluginsWithOptions} = ConfiguredProject.prototype; - ConfiguredProject.prototype.enablePluginsWithOptions = function() { + const { enablePluginsWithOptions: originalEnablePluginsWithOptions } = + ConfiguredProject.prototype; + ConfiguredProject.prototype.enablePluginsWithOptions = function () { this.projectService.allowLocalPluginLoads = true; return originalEnablePluginsWithOptions.apply(this, arguments); }; @@ -184,12 +218,12 @@ const moduleWrapperFn = tsserver => { // like an absolute path of ours and normalize it. const Session = tsserver.server.Session; - const {onMessage: originalOnMessage, send: originalSend} = Session.prototype; + const { onMessage: originalOnMessage, send: originalSend } = Session.prototype; let hostInfo = `unknown`; Object.assign(Session.prototype, { onMessage(/** @type {string | object} */ message) { - const isStringMessage = typeof message === 'string'; + const isStringMessage = typeof message === "string"; const parsedMessage = isStringMessage ? JSON.parse(message) : message; if ( @@ -200,10 +234,12 @@ const moduleWrapperFn = tsserver => { ) { hostInfo = parsedMessage.arguments.hostInfo; if (hostInfo === `vscode` && process.env.VSCODE_IPC_HOOK) { - const [, major, minor] = (process.env.VSCODE_IPC_HOOK.match( - // The RegExp from https://semver.org/ but without the caret at the start - /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/ - ) ?? []).map(Number) + const [, major, minor] = ( + process.env.VSCODE_IPC_HOOK.match( + // The RegExp from https://semver.org/ but without the caret at the start + /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/, + ) ?? [] + ).map(Number); if (major === 1) { if (minor < 61) { @@ -218,26 +254,33 @@ const moduleWrapperFn = tsserver => { } const processedMessageJSON = JSON.stringify(parsedMessage, (key, value) => { - return typeof value === 'string' ? fromEditorPath(value) : value; + return typeof value === "string" ? fromEditorPath(value) : value; }); return originalOnMessage.call( this, - isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON) + isStringMessage ? processedMessageJSON : JSON.parse(processedMessageJSON), ); }, send(/** @type {any} */ msg) { - return originalSend.call(this, JSON.parse(JSON.stringify(msg, (key, value) => { - return typeof value === `string` ? toEditorPath(value) : value; - }))); - } + return originalSend.call( + this, + JSON.parse( + JSON.stringify(msg, (key, value) => { + return typeof value === `string` ? toEditorPath(value) : value; + }), + ), + ); + }, }); return tsserver; }; -const [major, minor] = absRequire(`typescript/package.json`).version.split(`.`, 2).map(value => parseInt(value, 10)); +const [major, minor] = absRequire(`typescript/package.json`) + .version.split(`.`, 2) + .map(value => parseInt(value, 10)); // In TypeScript@>=5.5 the tsserver uses the public TypeScript API so that needs to be patched as well. // Ref https://github.com/microsoft/TypeScript/pull/55326 if (major > 5 || (major === 5 && minor >= 5)) { diff --git a/.yarn/sdks/typescript/lib/typescript.js b/.yarn/sdks/typescript/lib/typescript.js index 7b6cc22..bc1c8f7 100644 --- a/.yarn/sdks/typescript/lib/typescript.js +++ b/.yarn/sdks/typescript/lib/typescript.js @@ -1,9 +1,9 @@ #!/usr/bin/env node -const {existsSync} = require(`fs`); -const {createRequire, register} = require(`module`); -const {resolve} = require(`path`); -const {pathToFileURL} = require(`url`); +const { existsSync } = require(`fs`); +const { createRequire, register } = require(`module`); +const { resolve } = require(`path`); +const { pathToFileURL } = require(`url`); const relPnpApiPath = "../../../../.pnp.cjs"; diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..70a94a9 --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,39 @@ +import eslintConfigPrettierFlat from "eslint-config-prettier/flat"; +import { defineConfig } from "eslint/config"; +import tseslint from "typescript-eslint"; + +export default defineConfig([ + { + ignores: ["dist", "coverage"], + }, + tseslint.configs.recommended, + eslintConfigPrettierFlat, + { + files: ["src/**/*.{ts,tsx}"], + languageOptions: { + parser: tseslint.parser, + parserOptions: { + project: ["src/tsconfig.json", "src/tsconfig.test.json"], + tsconfigRootDir: import.meta.dirname, + }, + }, + plugins: { + "@typescript-eslint": tseslint.plugin, + }, + rules: { + "@typescript-eslint/no-namespace": "off", + "@typescript-eslint/ban-ts-comment": "warn", + "@typescript-eslint/no-import-type-side-effects": "error", + "@typescript-eslint/no-unnecessary-type-assertion": "error", + "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }], + "@typescript-eslint/require-await": "error", + "@typescript-eslint/return-await": ["error", "in-try-catch"], + }, + }, + { + files: ["src/**/*.js"], + rules: { + "@typescript-eslint/no-require-imports": "off", + }, + }, +]); diff --git a/package.json b/package.json index b68c3fd..13a5dd8 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,15 @@ "src/runner/*", "src/web/*" ], + "scripts": { + "build": "tsx libs/build.ts", + "dev": "tsx libs/build.ts --watch", + "test": "jest", + "test-coverage": "jest --coverage", + "lint": "eslint --concurrency=auto src", + "format": "prettier --write \"**/*.{ts,tsx,json,js,mjs}\"", + "format:ci": "prettier --list-different \"**/*.{ts,tsx,json,js,mjs}\"" + }, "devDependencies": { "@rollup/plugin-node-resolve": "^16.0.3", "@rollup/plugin-terser": "^1.0.0", diff --git a/src/tsconfig.json b/src/tsconfig.json index 552a857..6933b96 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -39,5 +39,5 @@ "isolatedModules": true }, /* Specifies an array of filenames or patterns that should be skipped when resolving include. */ - "exclude": ["**/dist"] -} \ No newline at end of file + "exclude": ["**/dist", "src/**/__tests__"] +} diff --git a/src/tsconfig.test.json b/src/tsconfig.test.json new file mode 100644 index 0000000..49b732d --- /dev/null +++ b/src/tsconfig.test.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "types": ["jest"] + }, + "include": ["src/**/__tests__"] +} diff --git a/src/web/tsconfig.json b/src/web/tsconfig.json index 9bfa0ef..87e7edf 100644 --- a/src/web/tsconfig.json +++ b/src/web/tsconfig.json @@ -6,4 +6,4 @@ "jsx": "react-jsx", "types": ["react", "react-konva"] } -} \ No newline at end of file +} From 10e4aaedb95c2548e4f4170b830c433cb86e869b Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Wed, 27 May 2026 00:43:16 +0800 Subject: [PATCH 03/16] feat: add build script --- .gitignore | 2 + lib/build.ts | 32 ++++ lib/tsconfig.json | 38 ++++ package.json | 8 +- yarn.lock | 455 +++++++++++++++++++++++++++++++--------------- 5 files changed, 388 insertions(+), 147 deletions(-) create mode 100644 lib/build.ts create mode 100644 lib/tsconfig.json diff --git a/.gitignore b/.gitignore index f03eaec..416aee9 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ node_modules #!.yarn/cache .pnp.* + +dist \ No newline at end of file diff --git a/lib/build.ts b/lib/build.ts new file mode 100644 index 0000000..b0facc0 --- /dev/null +++ b/lib/build.ts @@ -0,0 +1,32 @@ +import { Command } from "commander"; +import packageJSON from "../package.json" with { type: "json" }; +import fs from "fs/promises"; +import { spawn } from "child_process"; +const program = new Command(); + +export async function generateManifest() { + await Promise.all(packageJSON.workspaces.map(async (workspace) => { + const manifest: Record = {}; + const pluginType = workspace.split("/").slice(-2)[0]; + for await (const file of fs.glob(`${workspace}/manifest.json`)) { + const manifest = JSON.parse(await fs.readFile(file, "utf-8")); + const folderName = file.split("/").slice(0, -1).join("/"); + manifest[folderName] = manifest; + } + await fs.writeFile(`dist/${pluginType}.json`, JSON.stringify(manifest, null, 2)); + })); +} + +export async function build(extraArgs: string[] = []) { + await Promise.all([ + generateManifest(), + spawn("yarn", ["workspaces", "foreach", "-Apt", "run", "build", ...extraArgs], { stdio: "inherit" }) + ]) +} + +// TO-DO: Add more options +const options = program + .parse(); +const extraArgs = options.args; +await build(extraArgs); + diff --git a/lib/tsconfig.json b/lib/tsconfig.json new file mode 100644 index 0000000..9fb89ff --- /dev/null +++ b/lib/tsconfig.json @@ -0,0 +1,38 @@ +// Deployment tsconfig + +{ + "compilerOptions": { + /* Allow JavaScript files to be imported inside your project, instead of just .ts and .tsx files. */ + "allowJs": false, + /* When set to true, allowSyntheticDefaultImports allows you to write an import like "import React from "react";" */ + "allowSyntheticDefaultImports": true, + /* See https://www.typescriptlang.org/tsconfig#esModuleInterop */ + "esModuleInterop": true, + + "forceConsistentCasingInFileNames": true, + /* Sets the module system for the program. See the Modules reference page for more information. */ + "module": "nodenext", + /* Specify the module resolution strategy: 'node' (Node.js) or 'classic' (used in TypeScript before the release of 1.6). */ + "moduleResolution": "nodenext", + "skipLibCheck": true, + + "noEmit": true, + + /* Allows importing modules with a ‘.json’ extension, which is a common practice in node projects. */ + "resolveJsonModule": true, + /* Enables the generation of sourcemap files. These files allow debuggers and other tools to display the original TypeScript source code when actually working with the emitted JavaScript files. */ + "sourceMap": false, + /* The strict flag enables a wide range of type checking behavior that results in stronger guarantees of program correctness. */ + "strict": true, + /* The target setting changes which JS features are downleveled and which are left intact. */ + "target": "esnext", + /* In some cases where no type annotations are present, TypeScript will fall back to a type of any for a variable when it cannot infer the type. */ + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + + /* Ensure that imports used only as types get removed */ + // "verbatimModuleSyntax": true, + "isolatedModules": true, + "types": ["node"] + }, +} diff --git a/package.json b/package.json index 13a5dd8..4489972 100644 --- a/package.json +++ b/package.json @@ -6,9 +6,10 @@ "src/runner/*", "src/web/*" ], + "type": "module", "scripts": { - "build": "tsx libs/build.ts", - "dev": "tsx libs/build.ts --watch", + "build": "tsx lib/build.ts", + "dev": "tsx lib/build.ts --watch", "test": "jest", "test-coverage": "jest --coverage", "lint": "eslint --concurrency=auto src", @@ -21,12 +22,15 @@ "@rollup/plugin-typescript": "^12.3.0", "@sourceacademy/conductor": "^0.3.0", "@types/jest": "^30.0.0", + "@types/node": "^25.9.1", + "commander": "^14.0.3", "eslint": "^10.0.3", "eslint-config-prettier": "^10.1.8", "jest": "^30.3.0", "prettier": "^3.8.1", "rollup": "^4.60.0", "ts-jest": "^29.4.6", + "tsx": "^4.22.3", "typescript": "^6.0.3", "typescript-eslint": "^8.57.1" }, diff --git a/yarn.lock b/yarn.lock index c2aa53b..481cafb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -409,6 +409,188 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/aix-ppc64@npm:0.28.0" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/android-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/android-arm64@npm:0.28.0" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/android-arm@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/android-arm@npm:0.28.0" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + +"@esbuild/android-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/android-x64@npm:0.28.0" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/darwin-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/darwin-arm64@npm:0.28.0" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/darwin-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/darwin-x64@npm:0.28.0" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/freebsd-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/freebsd-arm64@npm:0.28.0" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/freebsd-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/freebsd-x64@npm:0.28.0" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/linux-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-arm64@npm:0.28.0" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/linux-arm@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-arm@npm:0.28.0" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + +"@esbuild/linux-ia32@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-ia32@npm:0.28.0" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/linux-loong64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-loong64@npm:0.28.0" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + +"@esbuild/linux-mips64el@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-mips64el@npm:0.28.0" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + +"@esbuild/linux-ppc64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-ppc64@npm:0.28.0" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + +"@esbuild/linux-riscv64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-riscv64@npm:0.28.0" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + +"@esbuild/linux-s390x@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-s390x@npm:0.28.0" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + +"@esbuild/linux-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/linux-x64@npm:0.28.0" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/netbsd-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/netbsd-arm64@npm:0.28.0" + conditions: os=netbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/netbsd-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/netbsd-x64@npm:0.28.0" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openbsd-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/openbsd-arm64@npm:0.28.0" + conditions: os=openbsd & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/openbsd-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/openbsd-x64@npm:0.28.0" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/openharmony-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/openharmony-arm64@npm:0.28.0" + conditions: os=openharmony & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/sunos-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/sunos-x64@npm:0.28.0" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + +"@esbuild/win32-arm64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/win32-arm64@npm:0.28.0" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + +"@esbuild/win32-ia32@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/win32-ia32@npm:0.28.0" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + +"@esbuild/win32-x64@npm:0.28.0": + version: 0.28.0 + resolution: "@esbuild/win32-x64@npm:0.28.0" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@eslint-community/eslint-utils@npm:^4.8.0, @eslint-community/eslint-utils@npm:^4.9.1": version: 4.9.1 resolution: "@eslint-community/eslint-utils@npm:4.9.1" @@ -1169,19 +1351,6 @@ __metadata: languageName: node linkType: hard -"@sourceacademy/common-cse@file:../../common/cse::locator=%40sourceacademy%2Fweb-cse%40workspace%3Asrc%2Fweb%2Fcse": - version: 0.0.0 - resolution: "@sourceacademy/common-cse@file:../../common/cse#../../common/cse::hash=34d89a&locator=%40sourceacademy%2Fweb-cse%40workspace%3Asrc%2Fweb%2Fcse" - checksum: 10c0/e395e96ad0e08ffdff5a47c106e1af4a0eb39dc4833c52420e07a951260693fb2c4ec75d65d5405db84dae291b8136ef42ca05d0a7f0a4769dd5729102dcfa32 - languageName: node - linkType: hard - -"@sourceacademy/common-cse@workspace:src/common/cse": - version: 0.0.0-use.local - resolution: "@sourceacademy/common-cse@workspace:src/common/cse" - languageName: unknown - linkType: soft - "@sourceacademy/conductor@npm:^0.3.0": version: 0.3.0 resolution: "@sourceacademy/conductor@npm:0.3.0" @@ -1189,27 +1358,6 @@ __metadata: languageName: node linkType: hard -"@sourceacademy/runner-cse@workspace:src/runner/cse": - version: 0.0.0-use.local - resolution: "@sourceacademy/runner-cse@workspace:src/runner/cse" - languageName: unknown - linkType: soft - -"@sourceacademy/web-cse@workspace:src/web/cse": - version: 0.0.0-use.local - resolution: "@sourceacademy/web-cse@workspace:src/web/cse" - dependencies: - "@sourceacademy/common-cse": ../../common/cse - "@types/react": "npm:^19.2.14" - "@types/react-dom": "npm:^19.2.3" - konva: "npm:^10.2.5" - react: "npm:^19.2.5" - react-dom: "npm:^19.2.5" - react-konva: "npm:^19.2.3" - typescript: "npm:^6.0.3" - languageName: unknown - linkType: soft - "@tybys/wasm-util@npm:^0.10.0": version: 0.10.1 resolution: "@tybys/wasm-util@npm:0.10.1" @@ -1325,39 +1473,12 @@ __metadata: languageName: node linkType: hard -"@types/react-dom@npm:^19.2.3": - version: 19.2.3 - resolution: "@types/react-dom@npm:19.2.3" - peerDependencies: - "@types/react": ^19.2.0 - checksum: 10c0/b486ebe0f4e2fb35e2e108df1d8fc0927ca5d6002d5771e8a739de11239fe62d0e207c50886185253c99eb9dedfeeb956ea7429e5ba17f6693c7acb4c02f8cd1 - languageName: node - linkType: hard - -"@types/react-reconciler@npm:^0.28.9": - version: 0.28.9 - resolution: "@types/react-reconciler@npm:0.28.9" - peerDependencies: - "@types/react": "*" - checksum: 10c0/9fe71fa856aab2cd4742fe0416bdd4f5c82ecc05ef6451ee7fcb65a5efdf5fa588f5820fbe2a665b15371b0da3bfc4097f28bb6d450b9a834af2d0fc00f403bd - languageName: node - linkType: hard - -"@types/react-reconciler@npm:^0.33.0": - version: 0.33.0 - resolution: "@types/react-reconciler@npm:0.33.0" - peerDependencies: - "@types/react": "*" - checksum: 10c0/190c203d93c0df9a42fabd693ce059dbdf6c53e15eb14502d9e5b946c981231c5846b867de15522ff61368e9218a8508a9db5476f3e47b5d664bbb2c84b31ac7 - languageName: node - linkType: hard - -"@types/react@npm:^19.2.14": - version: 19.2.14 - resolution: "@types/react@npm:19.2.14" +"@types/node@npm:^25.9.1": + version: 25.9.1 + resolution: "@types/node@npm:25.9.1" dependencies: - csstype: "npm:^3.2.2" - checksum: 10c0/7d25bf41b57719452d86d2ac0570b659210402707313a36ee612666bf11275a1c69824f8c3ee1fdca077ccfe15452f6da8f1224529b917050eb2d861e52b59b7 + undici-types: "npm:>=7.24.0 <7.24.7" + checksum: 10c0/9a04682842bebbcf21a1779dfeab9aa733d7bd7bbc0a0edb641ab3a9a3d43eac543225acf669c334f458f1956443ebc072bc3c72840c543b8b356cab5c82d456 languageName: node linkType: hard @@ -2044,6 +2165,13 @@ __metadata: languageName: node linkType: hard +"commander@npm:^14.0.3": + version: 14.0.3 + resolution: "commander@npm:14.0.3" + checksum: 10c0/755652564bbf56ff2ff083313912b326450d3f8d8c85f4b71416539c9a05c3c67dbd206821ca72635bf6b160e2afdefcb458e86b317827d5cb333b69ce7f1a24 + languageName: node + linkType: hard + "commander@npm:^2.20.0": version: 2.20.3 resolution: "commander@npm:2.20.3" @@ -2076,13 +2204,6 @@ __metadata: languageName: node linkType: hard -"csstype@npm:^3.2.2": - version: 3.2.3 - resolution: "csstype@npm:3.2.3" - checksum: 10c0/cd29c51e70fa822f1cecd8641a1445bed7063697469d35633b516e60fe8c1bde04b08f6c5b6022136bb669b64c63d4173af54864510fbb4ee23281801841a3ce - languageName: node - linkType: hard - "debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.4.3": version: 4.4.3 resolution: "debug@npm:4.4.3" @@ -2186,6 +2307,95 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:~0.28.0": + version: 0.28.0 + resolution: "esbuild@npm:0.28.0" + dependencies: + "@esbuild/aix-ppc64": "npm:0.28.0" + "@esbuild/android-arm": "npm:0.28.0" + "@esbuild/android-arm64": "npm:0.28.0" + "@esbuild/android-x64": "npm:0.28.0" + "@esbuild/darwin-arm64": "npm:0.28.0" + "@esbuild/darwin-x64": "npm:0.28.0" + "@esbuild/freebsd-arm64": "npm:0.28.0" + "@esbuild/freebsd-x64": "npm:0.28.0" + "@esbuild/linux-arm": "npm:0.28.0" + "@esbuild/linux-arm64": "npm:0.28.0" + "@esbuild/linux-ia32": "npm:0.28.0" + "@esbuild/linux-loong64": "npm:0.28.0" + "@esbuild/linux-mips64el": "npm:0.28.0" + "@esbuild/linux-ppc64": "npm:0.28.0" + "@esbuild/linux-riscv64": "npm:0.28.0" + "@esbuild/linux-s390x": "npm:0.28.0" + "@esbuild/linux-x64": "npm:0.28.0" + "@esbuild/netbsd-arm64": "npm:0.28.0" + "@esbuild/netbsd-x64": "npm:0.28.0" + "@esbuild/openbsd-arm64": "npm:0.28.0" + "@esbuild/openbsd-x64": "npm:0.28.0" + "@esbuild/openharmony-arm64": "npm:0.28.0" + "@esbuild/sunos-x64": "npm:0.28.0" + "@esbuild/win32-arm64": "npm:0.28.0" + "@esbuild/win32-ia32": "npm:0.28.0" + "@esbuild/win32-x64": "npm:0.28.0" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-arm64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-arm64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/openharmony-arm64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10c0/8acd95c238ec6c4a9d16163277faf228a8994b642d187b3fe667ffbb469008e6748cde144fdc3c175bf8e78ee49e15a0ed9b9f183fdb5fcea1772f87fb1372a4 + languageName: node + linkType: hard + "escalade@npm:^3.1.1, escalade@npm:^3.2.0": version: 3.2.0 resolution: "escalade@npm:3.2.0" @@ -2499,7 +2709,7 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:^2.3.3, fsevents@npm:~2.3.2": +"fsevents@npm:^2.3.3, fsevents@npm:~2.3.2, fsevents@npm:~2.3.3": version: 2.3.3 resolution: "fsevents@npm:2.3.3" dependencies: @@ -2509,7 +2719,7 @@ __metadata: languageName: node linkType: hard -"fsevents@patch:fsevents@npm%3A^2.3.3#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin": +"fsevents@patch:fsevents@npm%3A^2.3.3#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.2#optional!builtin, fsevents@patch:fsevents@npm%3A~2.3.3#optional!builtin": version: 2.3.3 resolution: "fsevents@patch:fsevents@npm%3A2.3.3#optional!builtin::version=2.3.3&hash=df0bf1" dependencies: @@ -2823,17 +3033,6 @@ __metadata: languageName: node linkType: hard -"its-fine@npm:^2.0.0": - version: 2.0.0 - resolution: "its-fine@npm:2.0.0" - dependencies: - "@types/react-reconciler": "npm:^0.28.9" - peerDependencies: - react: ^19.0.0 - checksum: 10c0/1ff1ff3257c0c7eb115c9c26cf0506eb84162edc1a63d3136780d146f7c7833298b240d0fcb46888909773f1a7d16539e0c03f2482cff1a5a502d6436686fe21 - languageName: node - linkType: hard - "jackspeak@npm:^3.1.2": version: 3.4.3 resolution: "jackspeak@npm:3.4.3" @@ -3358,13 +3557,6 @@ __metadata: languageName: node linkType: hard -"konva@npm:^10.2.5": - version: 10.2.5 - resolution: "konva@npm:10.2.5" - checksum: 10c0/5233d9d26632fe48cb7e9b0ce2b9bf5c8bea580cb9afb4065bd2fc09734836b49c8bfb2ee40659f0289e720363eaee023fe3205d8717fd9279035b66dca12e8e - languageName: node - linkType: hard - "leven@npm:^3.1.0": version: 3.1.0 resolution: "leven@npm:3.1.0" @@ -3788,12 +3980,15 @@ __metadata: "@rollup/plugin-typescript": "npm:^12.3.0" "@sourceacademy/conductor": "npm:^0.3.0" "@types/jest": "npm:^30.0.0" + "@types/node": "npm:^25.9.1" + commander: "npm:^14.0.3" eslint: "npm:^10.0.3" eslint-config-prettier: "npm:^10.1.8" jest: "npm:^30.3.0" prettier: "npm:^3.8.1" rollup: "npm:^4.60.0" ts-jest: "npm:^29.4.6" + tsx: "npm:^4.22.3" typescript: "npm:^6.0.3" typescript-eslint: "npm:^8.57.1" languageName: unknown @@ -3847,17 +4042,6 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:^19.2.5": - version: 19.2.5 - resolution: "react-dom@npm:19.2.5" - dependencies: - scheduler: "npm:^0.27.0" - peerDependencies: - react: ^19.2.5 - checksum: 10c0/8067606e9f58e4c2e8cb5f09570217dbc71c4843ebcaa20ae2085912d3e3a351f17d8f7c1713313cdda7f272840c8c34ff6c860fcb840862071bceea218e0c63 - languageName: node - linkType: hard - "react-is@npm:^18.3.1": version: 18.3.1 resolution: "react-is@npm:18.3.1" @@ -3865,40 +4049,6 @@ __metadata: languageName: node linkType: hard -"react-konva@npm:^19.2.3": - version: 19.2.3 - resolution: "react-konva@npm:19.2.3" - dependencies: - "@types/react-reconciler": "npm:^0.33.0" - its-fine: "npm:^2.0.0" - react-reconciler: "npm:0.33.0" - scheduler: "npm:0.27.0" - peerDependencies: - konva: ^8.0.1 || ^7.2.5 || ^9.0.0 || ^10.0.0 - react: ^19.2.0 - react-dom: ^19.2.0 - checksum: 10c0/7a7fa60d1e85d794be13bfab5890939f7adc39b29857118103de07bbe4b441281050376bf3e75d0bf6758d4a38dd04100d2a0686e855dc54a8845799cc5d99e6 - languageName: node - linkType: hard - -"react-reconciler@npm:0.33.0": - version: 0.33.0 - resolution: "react-reconciler@npm:0.33.0" - dependencies: - scheduler: "npm:^0.27.0" - peerDependencies: - react: ^19.2.0 - checksum: 10c0/3f7b27ea8d0ff4c8bf0e402a285e1af9b7d0e6f4c1a70a28f4384938bc1130bc82a90a31df0b79ef5e380e2e55e2598bd90b4dbf802b1203d735ba0355817d3a - languageName: node - linkType: hard - -"react@npm:^19.2.5": - version: 19.2.5 - resolution: "react@npm:19.2.5" - checksum: 10c0/4b5f231dbef92886f602533c9ce3bde04d99f0e71dfb5d794c43e02726efaad0421c08688f75fc98a6d6e1dc017372e1af7abbfecdc86a79968f461675931a7a - languageName: node - linkType: hard - "require-directory@npm:^2.1.1": version: 2.1.1 resolution: "require-directory@npm:2.1.1" @@ -4040,13 +4190,6 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:0.27.0, scheduler@npm:^0.27.0": - version: 0.27.0 - resolution: "scheduler@npm:0.27.0" - checksum: 10c0/4f03048cb05a3c8fddc45813052251eca00688f413a3cee236d984a161da28db28ba71bd11e7a3dd02f7af84ab28d39fb311431d3b3772fed557945beb00c452 - languageName: node - linkType: hard - "semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" @@ -4375,6 +4518,21 @@ __metadata: languageName: node linkType: hard +"tsx@npm:^4.22.3": + version: 4.22.3 + resolution: "tsx@npm:4.22.3" + dependencies: + esbuild: "npm:~0.28.0" + fsevents: "npm:~2.3.3" + dependenciesMeta: + fsevents: + optional: true + bin: + tsx: dist/cli.mjs + checksum: 10c0/09a5a7d354ff75e5af6285217d709ec80a46c2ee19e0d9b5c5d00eab81047c3ea6b2a5498a2c5255f3960d6e7acd1a1eee34b9433dc56fb32907ca3b38271f41 + languageName: node + linkType: hard + "type-check@npm:^0.4.0, type-check@npm:~0.4.0": version: 0.4.0 resolution: "type-check@npm:0.4.0" @@ -4449,6 +4607,13 @@ __metadata: languageName: node linkType: hard +"undici-types@npm:>=7.24.0 <7.24.7": + version: 7.24.6 + resolution: "undici-types@npm:7.24.6" + checksum: 10c0/d9cd8befb643ac904615c280a095ba4240531f6bb4a5e75a22a7483630ca8d3f1016d2ab6ace6ceda1f63b3a2db2fe037fafe121d6917a0187573aa548ff78ca + languageName: node + linkType: hard + "undici-types@npm:~7.19.0": version: 7.19.2 resolution: "undici-types@npm:7.19.2" From 260ef389b24cd44827b47c130621b94412c3815f Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Wed, 27 May 2026 01:07:08 +0800 Subject: [PATCH 04/16] feat: add CI/CD infra --- .github/workflows/on_pr.yml | 31 ++++++++++++++++++++++++ .github/workflows/on_push.yml | 44 +++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 .github/workflows/on_pr.yml create mode 100644 .github/workflows/on_push.yml diff --git a/.github/workflows/on_pr.yml b/.github/workflows/on_pr.yml new file mode 100644 index 0000000..de591f1 --- /dev/null +++ b/.github/workflows/on_pr.yml @@ -0,0 +1,31 @@ +name: Node.js CI + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + - run: corepack enable + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: yarn + - run: yarn install --frozen-lockfile + - run: yarn run build + - run: yarn run format:ci + - run: yarn run lint + - run: yarn run test-coverage + - name: Coveralls + uses: coverallsapp/github-action@v2 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/on_push.yml b/.github/workflows/on_push.yml new file mode 100644 index 0000000..27d18c4 --- /dev/null +++ b/.github/workflows/on_push.yml @@ -0,0 +1,44 @@ +name: Build and deploy runner +on: + push: + branches: + - main + +jobs: + build: + name: Build runner + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v6 + - name: Enable corepack + run: corepack enable + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: yarn + - name: Install dependencies + run: yarn install --frozen-lockfile + - name: yarn run build + run: yarn run build + - name: Upload artifacts + id: deployment + uses: actions/upload-pages-artifact@v3 + with: + path: dist/ + + deploy: + needs: build + name: Deploy runner + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 \ No newline at end of file From 6bbe3500e62c9bfeac73560e03684a481b0d923b Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Thu, 28 May 2026 19:20:21 +0800 Subject: [PATCH 05/16] feat: add test plugins --- .gitignore | 6 +- .vscode/settings.json | 3 +- .yarnrc.yml | 4 + jest.config.cjs | 5 + lib/build.ts | 3 +- package.json | 17 +- src/common/test/jest.config.cjs | 14 + src/common/test/manifest.json | 3 + src/common/test/package.json | 38 + src/common/test/rollup.config.mjs | 22 + src/common/test/src/__tests__/common.test.ts | 4 + src/common/test/src/index.ts | 6 + src/common/test/tsconfig.json | 15 + src/runner/test/jest.config.cjs | 15 + src/runner/test/manifest.json | 3 + src/runner/test/package.json | 42 + src/runner/test/rollup.config.mjs | 22 + src/runner/test/src/__tests__/runner.test.ts | 5 + src/runner/test/src/index.ts | 18 + src/runner/test/tsconfig.json | 14 + src/tsconfig.json | 6 +- src/web/test/jest.config.cjs | 15 + src/web/test/manifest.json | 3 + src/web/test/package.json | 37 + src/web/test/rollup.config.mjs | 22 + src/web/test/src/index.ts | 19 + src/web/test/tsconfig.json | 14 + src/web/tsconfig.json | 3 +- yarn.lock | 1093 +++++++++++------- 29 files changed, 1038 insertions(+), 433 deletions(-) create mode 100644 .yarnrc.yml create mode 100644 jest.config.cjs create mode 100644 src/common/test/jest.config.cjs create mode 100644 src/common/test/manifest.json create mode 100644 src/common/test/package.json create mode 100644 src/common/test/rollup.config.mjs create mode 100644 src/common/test/src/__tests__/common.test.ts create mode 100644 src/common/test/src/index.ts create mode 100644 src/common/test/tsconfig.json create mode 100644 src/runner/test/jest.config.cjs create mode 100644 src/runner/test/manifest.json create mode 100644 src/runner/test/package.json create mode 100644 src/runner/test/rollup.config.mjs create mode 100644 src/runner/test/src/__tests__/runner.test.ts create mode 100644 src/runner/test/src/index.ts create mode 100644 src/runner/test/tsconfig.json create mode 100644 src/web/test/jest.config.cjs create mode 100644 src/web/test/manifest.json create mode 100644 src/web/test/package.json create mode 100644 src/web/test/rollup.config.mjs create mode 100644 src/web/test/src/index.ts create mode 100644 src/web/test/tsconfig.json diff --git a/.gitignore b/.gitignore index 416aee9..e3f058e 100644 --- a/.gitignore +++ b/.gitignore @@ -16,4 +16,8 @@ node_modules #!.yarn/cache .pnp.* -dist \ No newline at end of file +# Output of the build process +dist + +# Output of the test coverage process +coverage \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 7629b32..d8d3bef 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -4,5 +4,6 @@ "**/.pnp.*": true }, "typescript.tsdk": ".yarn/sdks/typescript/lib", - "typescript.enablePromptUseWorkspaceTsdk": true + "typescript.enablePromptUseWorkspaceTsdk": true, + "js/ts.tsdk.path": ".yarn/sdks/typescript/lib" } diff --git a/.yarnrc.yml b/.yarnrc.yml new file mode 100644 index 0000000..e7d552a --- /dev/null +++ b/.yarnrc.yml @@ -0,0 +1,4 @@ +packageExtensions: + ts-jest@^29.4.6: + dependencies: + jest-util: ^29.7.0 \ No newline at end of file diff --git a/jest.config.cjs b/jest.config.cjs new file mode 100644 index 0000000..6d50ad1 --- /dev/null +++ b/jest.config.cjs @@ -0,0 +1,5 @@ +const packageJson = require("./package.json"); +module.exports = { + projects: packageJson.workspaces +} + diff --git a/lib/build.ts b/lib/build.ts index b0facc0..cbd7fa0 100644 --- a/lib/build.ts +++ b/lib/build.ts @@ -5,6 +5,7 @@ import { spawn } from "child_process"; const program = new Command(); export async function generateManifest() { + await fs.mkdir("dist"); await Promise.all(packageJSON.workspaces.map(async (workspace) => { const manifest: Record = {}; const pluginType = workspace.split("/").slice(-2)[0]; @@ -18,7 +19,7 @@ export async function generateManifest() { } export async function build(extraArgs: string[] = []) { - await Promise.all([ + await Promise.allSettled([ generateManifest(), spawn("yarn", ["workspaces", "foreach", "-Apt", "run", "build", ...extraArgs], { stdio: "inherit" }) ]) diff --git a/package.json b/package.json index 4489972..336ba22 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,9 @@ "name": "plugins", "packageManager": "yarn@4.12.0", "workspaces": [ - "src/common/*", - "src/runner/*", - "src/web/*" + "src/common/*/", + "src/runner/*/", + "src/web/*/" ], "type": "module", "scripts": { @@ -17,26 +17,19 @@ "format:ci": "prettier --list-different \"**/*.{ts,tsx,json,js,mjs}\"" }, "devDependencies": { - "@rollup/plugin-node-resolve": "^16.0.3", - "@rollup/plugin-terser": "^1.0.0", - "@rollup/plugin-typescript": "^12.3.0", "@sourceacademy/conductor": "^0.3.0", "@types/jest": "^30.0.0", "@types/node": "^25.9.1", "commander": "^14.0.3", "eslint": "^10.0.3", "eslint-config-prettier": "^10.1.8", - "jest": "^30.3.0", + "jest": "^30.4.2", "prettier": "^3.8.1", - "rollup": "^4.60.0", - "ts-jest": "^29.4.6", + "ts-jest": "^29.4.11", "tsx": "^4.22.3", "typescript": "^6.0.3", "typescript-eslint": "^8.57.1" }, - "dependencies": { - "rollup": "^4.60.2" - }, "repository": { "type": "git", "url": "git+https://github.com/source-academy/plugins.git" diff --git a/src/common/test/jest.config.cjs b/src/common/test/jest.config.cjs new file mode 100644 index 0000000..1c3a78c --- /dev/null +++ b/src/common/test/jest.config.cjs @@ -0,0 +1,14 @@ +module.exports = { + preset: "ts-jest/presets/js-with-ts-esm", + testEnvironment: "node", + transform: { + "^.+\\.tsx?$": [ + "ts-jest", + { + useESM: true, + }, + ], + }, + testPathIgnorePatterns: [".*?dist/"], + coverageReporters: ["lcov"], +}; \ No newline at end of file diff --git a/src/common/test/manifest.json b/src/common/test/manifest.json new file mode 100644 index 0000000..830ff20 --- /dev/null +++ b/src/common/test/manifest.json @@ -0,0 +1,3 @@ +{ + "type": "internal" +} \ No newline at end of file diff --git a/src/common/test/package.json b/src/common/test/package.json new file mode 100644 index 0000000..e031b71 --- /dev/null +++ b/src/common/test/package.json @@ -0,0 +1,38 @@ +{ + "name": "@sourceacademy/common-test", + "version": "0.0.1", + "packageManager": "yarn@4.6.0", + "description": "The test common plugin for the plugins repository", + "scripts": { + "build": "rollup -c", + "prepack": "yarn build", + "test": "jest", + "test-coverage": "jest --coverage" + }, + "license": "ISC", + "files": [ + "dist" + ], + "main": "dist/index.cjs", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.mjs", + "require": "./dist/index.cjs", + "types": "./dist/index.d.ts" + } + }, + "devDependencies": { + "@rollup/plugin-node-resolve": "^16.0.3", + "@rollup/plugin-terser": "^1.0.0", + "@rollup/plugin-typescript": "^12.3.0", + "@sourceacademy/common-test": "workspace:*", + "@types/jest": "^30.0.0", + "jest": "^30.4.2", + "rollup": "^4.60.2", + "ts-jest": "^29.4.11", + "tslib": "^2.8.1", + "typescript": "^6.0.3" + } +} diff --git a/src/common/test/rollup.config.mjs b/src/common/test/rollup.config.mjs new file mode 100644 index 0000000..a9670b6 --- /dev/null +++ b/src/common/test/rollup.config.mjs @@ -0,0 +1,22 @@ +import packageJson from "./package.json" with { type: "json" }; +import nodeResolve from "@rollup/plugin-node-resolve"; +import terser from "@rollup/plugin-terser"; +import typescript from "@rollup/plugin-typescript"; + +/** + * @type {import('rollup').RollupOptions} + */ +export default { + input: "src/index.ts", + output: [ + { + file: "dist/index.cjs", + format: "cjs", + }, + { + file: "dist/index.mjs", + format: "esm", + }, + ], + plugins: [nodeResolve(), typescript(), terser()], +}; \ No newline at end of file diff --git a/src/common/test/src/__tests__/common.test.ts b/src/common/test/src/__tests__/common.test.ts new file mode 100644 index 0000000..146f46f --- /dev/null +++ b/src/common/test/src/__tests__/common.test.ts @@ -0,0 +1,4 @@ +import { CHANNEL_ID } from ".."; +test("should have a valid channel id", () => { + expect(CHANNEL_ID).toBe("test"); +}); \ No newline at end of file diff --git a/src/common/test/src/index.ts b/src/common/test/src/index.ts new file mode 100644 index 0000000..dcf12a7 --- /dev/null +++ b/src/common/test/src/index.ts @@ -0,0 +1,6 @@ +export const WEB_ID = "__web_test"; +export const RUNNER_ID = "__runner_test"; + +export const CHANNEL_ID = "test"; + +export type TestMessage = "ping" | "pong"; \ No newline at end of file diff --git a/src/common/test/tsconfig.json b/src/common/test/tsconfig.json new file mode 100644 index 0000000..35238f5 --- /dev/null +++ b/src/common/test/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../tsconfig.json", + "exclude": [ + "./dist" + ], + "include": [ + "./src" + ], + "compilerOptions": { + "declaration": true, + "outDir": "./dist", + "rootDir": "./src", + "types": ["jest"] + } +} \ No newline at end of file diff --git a/src/runner/test/jest.config.cjs b/src/runner/test/jest.config.cjs new file mode 100644 index 0000000..44e6776 --- /dev/null +++ b/src/runner/test/jest.config.cjs @@ -0,0 +1,15 @@ +module.exports = { + preset: "ts-jest/presets/js-with-ts-esm", + testEnvironment: "node", + transform: { + "^.+\\.tsx?$": [ + "ts-jest", + { + useESM: true, + tsconfig: "src/tsconfig.json", + }, + ], + }, + testPathIgnorePatterns: [".*?dist/"], + coverageReporters: ["lcov"], +}; \ No newline at end of file diff --git a/src/runner/test/manifest.json b/src/runner/test/manifest.json new file mode 100644 index 0000000..fd96295 --- /dev/null +++ b/src/runner/test/manifest.json @@ -0,0 +1,3 @@ +{ + "type": "installable" +} \ No newline at end of file diff --git a/src/runner/test/package.json b/src/runner/test/package.json new file mode 100644 index 0000000..4a89ed1 --- /dev/null +++ b/src/runner/test/package.json @@ -0,0 +1,42 @@ +{ + "name": "@sourceacademy/runner-test", + "version": "0.0.1", + "packageManager": "yarn@4.6.0", + "description": "The test runner plugin for the plugins repository", + "scripts": { + "build": "rollup -c", + "prepack": "yarn build", + "test": "jest", + "test-coverage": "jest --coverage" + }, + "license": "ISC", + "files": [ + "dist" + ], + "main": "dist/index.cjs", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.mjs", + "require": "./dist/index.cjs", + "types": "./dist/index.d.ts" + } + }, + "peerDependencies": { + "@sourceacademy/conductor": ">=0.3.0" + }, + "devDependencies": { + "@rollup/plugin-node-resolve": "^16.0.3", + "@rollup/plugin-terser": "^1.0.0", + "@rollup/plugin-typescript": "^12.3.0", + "@sourceacademy/common-test": "workspace:*", + "@sourceacademy/conductor": ">=0.3.0", + "@types/jest": "^30.0.0", + "jest": "^30.4.2", + "rollup": "^4.60.2", + "ts-jest": "^29.4.11", + "tslib": "^2.8.1", + "typescript": "^6.0.3" + } +} diff --git a/src/runner/test/rollup.config.mjs b/src/runner/test/rollup.config.mjs new file mode 100644 index 0000000..a9670b6 --- /dev/null +++ b/src/runner/test/rollup.config.mjs @@ -0,0 +1,22 @@ +import packageJson from "./package.json" with { type: "json" }; +import nodeResolve from "@rollup/plugin-node-resolve"; +import terser from "@rollup/plugin-terser"; +import typescript from "@rollup/plugin-typescript"; + +/** + * @type {import('rollup').RollupOptions} + */ +export default { + input: "src/index.ts", + output: [ + { + file: "dist/index.cjs", + format: "cjs", + }, + { + file: "dist/index.mjs", + format: "esm", + }, + ], + plugins: [nodeResolve(), typescript(), terser()], +}; \ No newline at end of file diff --git a/src/runner/test/src/__tests__/runner.test.ts b/src/runner/test/src/__tests__/runner.test.ts new file mode 100644 index 0000000..875f4b0 --- /dev/null +++ b/src/runner/test/src/__tests__/runner.test.ts @@ -0,0 +1,5 @@ +import { TestPlugin } from ".."; +import { CHANNEL_ID } from "@sourceacademy/common-test"; +test("should have a valid channel id", () => { + expect(TestPlugin.channelAttach).toEqual([CHANNEL_ID]); +}); diff --git a/src/runner/test/src/index.ts b/src/runner/test/src/index.ts new file mode 100644 index 0000000..03053c4 --- /dev/null +++ b/src/runner/test/src/index.ts @@ -0,0 +1,18 @@ +import { CHANNEL_ID, RUNNER_ID, type TestMessage } from "@sourceacademy/common-test"; +import { IPlugin, IChannel, IConduit } from "@sourceacademy/conductor/conduit"; +export abstract class TestPlugin implements IPlugin { + readonly id: string = RUNNER_ID; + static readonly channelAttach = [CHANNEL_ID]; + private readonly __testChannel: IChannel; + constructor( + _conduit: IConduit, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + [testChannel]: IChannel[], + ) { + this.__testChannel = testChannel; + this.__testChannel.subscribe((message) => { + console.log(message); + }); + this.__testChannel.send("ping"); + } +} diff --git a/src/runner/test/tsconfig.json b/src/runner/test/tsconfig.json new file mode 100644 index 0000000..bccdab1 --- /dev/null +++ b/src/runner/test/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../../tsconfig.json", + "exclude": [ + "./dist" + ], + "include": [ + "./src" + ], + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src", + "types": ["jest"] + } +} \ No newline at end of file diff --git a/src/tsconfig.json b/src/tsconfig.json index 6933b96..485c5b1 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -29,15 +29,13 @@ /* The target setting changes which JS features are downleveled and which are left intact. */ "target": "es6", /* In some cases where no type annotations are present, TypeScript will fall back to a type of any for a variable when it cannot infer the type. */ - /* *** TEMPORARILY ADDED UNTIL ALL MODULES HAVE BEEN REFACTORED!!!!!!!!!!! *** */ - "noImplicitAny": false, "experimentalDecorators": true, "emitDecoratorMetadata": true, /* Ensure that imports used only as types get removed */ // "verbatimModuleSyntax": true, - "isolatedModules": true + "isolatedModules": true, }, /* Specifies an array of filenames or patterns that should be skipped when resolving include. */ - "exclude": ["**/dist", "src/**/__tests__"] + "exclude": ["**/dist"] } diff --git a/src/web/test/jest.config.cjs b/src/web/test/jest.config.cjs new file mode 100644 index 0000000..d3d8364 --- /dev/null +++ b/src/web/test/jest.config.cjs @@ -0,0 +1,15 @@ +module.exports = { + preset: "ts-jest/presets/js-with-ts-esm", + testEnvironment: "node", + transform: { + "^.+\\.tsx?$": [ + "ts-jest", + { + useESM: true, + tsconfig: "./tsconfig.json", + }, + ], + }, + testPathIgnorePatterns: [".*?dist/"], + coverageReporters: ["lcov"], +}; \ No newline at end of file diff --git a/src/web/test/manifest.json b/src/web/test/manifest.json new file mode 100644 index 0000000..fd96295 --- /dev/null +++ b/src/web/test/manifest.json @@ -0,0 +1,3 @@ +{ + "type": "installable" +} \ No newline at end of file diff --git a/src/web/test/package.json b/src/web/test/package.json new file mode 100644 index 0000000..d081044 --- /dev/null +++ b/src/web/test/package.json @@ -0,0 +1,37 @@ +{ + "name": "@sourceacademy/web-test", + "version": "0.0.1", + "packageManager": "yarn@4.6.0", + "description": "The test web plugin for the plugins repository", + "scripts": { + "build": "rollup -c", + "prepack": "yarn build" + }, + "license": "ISC", + "files": [ + "dist" + ], + "main": "dist/index.cjs", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.mjs", + "require": "./dist/index.cjs", + "types": "./dist/index.d.ts" + } + }, + "devDependencies": { + "@rollup/plugin-node-resolve": "^16.0.3", + "@rollup/plugin-terser": "^1.0.0", + "@rollup/plugin-typescript": "^12.3.0", + "@sourceacademy/common-test": "workspace:*", + "@sourceacademy/conductor": ">=0.3.0", + "@types/jest": "^30.0.0", + "jest": "^30.4.2", + "rollup": "^4.60.2", + "ts-jest": "^29.4.11", + "tslib": "^2.8.1", + "typescript": "^6.0.3" + } +} diff --git a/src/web/test/rollup.config.mjs b/src/web/test/rollup.config.mjs new file mode 100644 index 0000000..a9670b6 --- /dev/null +++ b/src/web/test/rollup.config.mjs @@ -0,0 +1,22 @@ +import packageJson from "./package.json" with { type: "json" }; +import nodeResolve from "@rollup/plugin-node-resolve"; +import terser from "@rollup/plugin-terser"; +import typescript from "@rollup/plugin-typescript"; + +/** + * @type {import('rollup').RollupOptions} + */ +export default { + input: "src/index.ts", + output: [ + { + file: "dist/index.cjs", + format: "cjs", + }, + { + file: "dist/index.mjs", + format: "esm", + }, + ], + plugins: [nodeResolve(), typescript(), terser()], +}; \ No newline at end of file diff --git a/src/web/test/src/index.ts b/src/web/test/src/index.ts new file mode 100644 index 0000000..89e08ef --- /dev/null +++ b/src/web/test/src/index.ts @@ -0,0 +1,19 @@ +import { CHANNEL_ID, WEB_ID, type TestMessage } from "@sourceacademy/common-test"; +import { IPlugin, IChannel, IConduit } from "@sourceacademy/conductor/conduit"; + +export abstract class TestPlugin implements IPlugin { + readonly id: string = WEB_ID; + static readonly channelAttach = [CHANNEL_ID]; + private readonly __testChannel: IChannel; + constructor( + _conduit: IConduit, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + [testChannel]: IChannel[], + ) { + this.__testChannel = testChannel; + this.__testChannel.subscribe((message) => { + console.log(message); + }); + this.__testChannel.send("ping"); + } +} diff --git a/src/web/test/tsconfig.json b/src/web/test/tsconfig.json new file mode 100644 index 0000000..e07ecd8 --- /dev/null +++ b/src/web/test/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "../tsconfig.json", + "exclude": [ + "./dist" + ], + "include": [ + "./src" + ], + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src", + "types": ["jest"] + } +} \ No newline at end of file diff --git a/src/web/tsconfig.json b/src/web/tsconfig.json index 87e7edf..4e83688 100644 --- a/src/web/tsconfig.json +++ b/src/web/tsconfig.json @@ -3,7 +3,6 @@ "compilerOptions": { // Tabs should never need to emit any kind of files "declaration": false, - "jsx": "react-jsx", - "types": ["react", "react-konva"] + "jsx": "react-jsx" } } diff --git a/yarn.lock b/yarn.lock index 481cafb..9cc66f7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -739,57 +739,58 @@ __metadata: languageName: node linkType: hard -"@jest/console@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/console@npm:30.3.0" +"@jest/console@npm:30.4.1": + version: 30.4.1 + resolution: "@jest/console@npm:30.4.1" dependencies: - "@jest/types": "npm:30.3.0" + "@jest/types": "npm:30.4.1" "@types/node": "npm:*" chalk: "npm:^4.1.2" - jest-message-util: "npm:30.3.0" - jest-util: "npm:30.3.0" + jest-message-util: "npm:30.4.1" + jest-util: "npm:30.4.1" slash: "npm:^3.0.0" - checksum: 10c0/5458f26b0591b847b719a707cbd1d6b2b99960784a1480a28d19200a807b6092f066c1bd1810df8c6adebf934a64de7b6022dc35082cd7c8f09f35940da104d9 + checksum: 10c0/f782722ef5754ab864b996000cf1f0545f7be9db6ba8f89cb2381dfab9910a52c59a830e5ea069a76840023e40806493d9900d8eb7e9821d23a11a498f32739e languageName: node linkType: hard -"@jest/core@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/core@npm:30.3.0" +"@jest/core@npm:30.4.2": + version: 30.4.2 + resolution: "@jest/core@npm:30.4.2" dependencies: - "@jest/console": "npm:30.3.0" - "@jest/pattern": "npm:30.0.1" - "@jest/reporters": "npm:30.3.0" - "@jest/test-result": "npm:30.3.0" - "@jest/transform": "npm:30.3.0" - "@jest/types": "npm:30.3.0" + "@jest/console": "npm:30.4.1" + "@jest/pattern": "npm:30.4.0" + "@jest/reporters": "npm:30.4.1" + "@jest/test-result": "npm:30.4.1" + "@jest/transform": "npm:30.4.1" + "@jest/types": "npm:30.4.1" "@types/node": "npm:*" ansi-escapes: "npm:^4.3.2" chalk: "npm:^4.1.2" ci-info: "npm:^4.2.0" exit-x: "npm:^0.2.2" + fast-json-stable-stringify: "npm:^2.1.0" graceful-fs: "npm:^4.2.11" - jest-changed-files: "npm:30.3.0" - jest-config: "npm:30.3.0" - jest-haste-map: "npm:30.3.0" - jest-message-util: "npm:30.3.0" - jest-regex-util: "npm:30.0.1" - jest-resolve: "npm:30.3.0" - jest-resolve-dependencies: "npm:30.3.0" - jest-runner: "npm:30.3.0" - jest-runtime: "npm:30.3.0" - jest-snapshot: "npm:30.3.0" - jest-util: "npm:30.3.0" - jest-validate: "npm:30.3.0" - jest-watcher: "npm:30.3.0" - pretty-format: "npm:30.3.0" + jest-changed-files: "npm:30.4.1" + jest-config: "npm:30.4.2" + jest-haste-map: "npm:30.4.1" + jest-message-util: "npm:30.4.1" + jest-regex-util: "npm:30.4.0" + jest-resolve: "npm:30.4.1" + jest-resolve-dependencies: "npm:30.4.2" + jest-runner: "npm:30.4.2" + jest-runtime: "npm:30.4.2" + jest-snapshot: "npm:30.4.1" + jest-util: "npm:30.4.1" + jest-validate: "npm:30.4.1" + jest-watcher: "npm:30.4.1" + pretty-format: "npm:30.4.1" slash: "npm:^3.0.0" peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: node-notifier: optional: true - checksum: 10c0/1735f2263cca10c6cae4e1dbde9c3ccb36e2cbd1cc10bac6fc45e187b06c4e33a6a029f9a6444a3cd43a2a44ffaec3b686d94f70965cebf2b885b198c8615322 + checksum: 10c0/4237ec79d5403b82ba89e3be6e4318d9f37c3a11281bd76cfbdd4ff08d8c89850555607c4d494dab3526e01a90db3539e549017883967dd392b5084f1be0d5b2 languageName: node linkType: hard @@ -800,15 +801,22 @@ __metadata: languageName: node linkType: hard -"@jest/environment@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/environment@npm:30.3.0" +"@jest/diff-sequences@npm:30.4.0": + version: 30.4.0 + resolution: "@jest/diff-sequences@npm:30.4.0" + checksum: 10c0/b4358b1b885098b905cb777f58788ddd45f90c4ebc3ce2c04fb1d4c9516f35ac2d9daef8263cd21c537bd7a52ab320f03e4ba9521677959ae20e3d405356b420 + languageName: node + linkType: hard + +"@jest/environment@npm:30.4.1": + version: 30.4.1 + resolution: "@jest/environment@npm:30.4.1" dependencies: - "@jest/fake-timers": "npm:30.3.0" - "@jest/types": "npm:30.3.0" + "@jest/fake-timers": "npm:30.4.1" + "@jest/types": "npm:30.4.1" "@types/node": "npm:*" - jest-mock: "npm:30.3.0" - checksum: 10c0/4068ccc2e4761e52909239c21e71f73b57ad087bd120b75d3232c68d911686d68fd0fb20e19725517a624b0aa9d45431b00503bd1d5ab2f4958e1a18d265d8d5 + jest-mock: "npm:30.4.1" + checksum: 10c0/704987ff8650c91a8ed13796ce47e9c55da3c12a01902d9e384330cead18eb4d34ce665a8d9962dddf2736fac006f92efc1039b8da424adf8fdc16f8d81aff6c languageName: node linkType: hard @@ -821,27 +829,36 @@ __metadata: languageName: node linkType: hard -"@jest/expect@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/expect@npm:30.3.0" +"@jest/expect-utils@npm:30.4.1": + version: 30.4.1 + resolution: "@jest/expect-utils@npm:30.4.1" dependencies: - expect: "npm:30.3.0" - jest-snapshot: "npm:30.3.0" - checksum: 10c0/1e052975fdf2b977a63dc9f3db1de56be9dce8e5cd660d9c72cc25093324b990b3e93318cd0c1ff9df7cb30ec7eef71331bc7e19d39700eb3f4498e17ee4c9e0 + "@jest/get-type": "npm:30.1.0" + checksum: 10c0/6dea9e11ebcc7be68fea5950ae5a1b7ff9fd1490101ee8af0aede336b9934ab24a28bcafe2f1171dac0f95982406386c609ca2659b9132e1a9d419e8d69b9cd4 languageName: node linkType: hard -"@jest/fake-timers@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/fake-timers@npm:30.3.0" +"@jest/expect@npm:30.4.1": + version: 30.4.1 + resolution: "@jest/expect@npm:30.4.1" dependencies: - "@jest/types": "npm:30.3.0" - "@sinonjs/fake-timers": "npm:^15.0.0" + expect: "npm:30.4.1" + jest-snapshot: "npm:30.4.1" + checksum: 10c0/2133183e735982879408036237b115abc2e57fa52bb7324be0a1f2ab6941a57da93b2e6f498dc110b7d007dd20463013fbcc5b24377cf65e6a8518d3b2ff76bd + languageName: node + linkType: hard + +"@jest/fake-timers@npm:30.4.1": + version: 30.4.1 + resolution: "@jest/fake-timers@npm:30.4.1" + dependencies: + "@jest/types": "npm:30.4.1" + "@sinonjs/fake-timers": "npm:^15.4.0" "@types/node": "npm:*" - jest-message-util: "npm:30.3.0" - jest-mock: "npm:30.3.0" - jest-util: "npm:30.3.0" - checksum: 10c0/114855ca14d6b34c886855445852a5b960bc3df0ef97c4b971b375747fe0206b3111ec60efc6e658565677022f0d790acd7e232e478f3390ea854d04dea0c4d8 + jest-message-util: "npm:30.4.1" + jest-mock: "npm:30.4.1" + jest-util: "npm:30.4.1" + checksum: 10c0/4a10e4eb64bb5ea2531cdcc79f3058731f5c14faf2a74f498fcb37f6690c3c0f9b12a9856736d26e34631eb38db12e12812da71de27b9d332df44dda9f460fbe languageName: node linkType: hard @@ -852,15 +869,15 @@ __metadata: languageName: node linkType: hard -"@jest/globals@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/globals@npm:30.3.0" +"@jest/globals@npm:30.4.1": + version: 30.4.1 + resolution: "@jest/globals@npm:30.4.1" dependencies: - "@jest/environment": "npm:30.3.0" - "@jest/expect": "npm:30.3.0" - "@jest/types": "npm:30.3.0" - jest-mock: "npm:30.3.0" - checksum: 10c0/013554dcbf75867e715801e98a5c6eefbea67cb388efd019be9e0d83979d7354874c4b33bbabc95de698215f5b891e921c26a284841504f9825fd789432b1cd0 + "@jest/environment": "npm:30.4.1" + "@jest/expect": "npm:30.4.1" + "@jest/types": "npm:30.4.1" + jest-mock: "npm:30.4.1" + checksum: 10c0/7961eefdc9e69ba7754d11a1bae4bc2960f33e03d9c1d6c73f27895b8cf92a9118a234330f31dc8efe16e835fe70ef9cc6c26f60121f6b6e9fac71c8b1bcd709 languageName: node linkType: hard @@ -874,15 +891,25 @@ __metadata: languageName: node linkType: hard -"@jest/reporters@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/reporters@npm:30.3.0" +"@jest/pattern@npm:30.4.0": + version: 30.4.0 + resolution: "@jest/pattern@npm:30.4.0" + dependencies: + "@types/node": "npm:*" + jest-regex-util: "npm:30.4.0" + checksum: 10c0/05bc0799f84f3750bbbff0f9a546979efd0dbcee86c1be98b9e2811a68885809ec7b5cca39b8dda1497cb7cf17b7be936019fba8dfbcd9c53b181e03e67f4f82 + languageName: node + linkType: hard + +"@jest/reporters@npm:30.4.1": + version: 30.4.1 + resolution: "@jest/reporters@npm:30.4.1" dependencies: "@bcoe/v8-coverage": "npm:^0.2.3" - "@jest/console": "npm:30.3.0" - "@jest/test-result": "npm:30.3.0" - "@jest/transform": "npm:30.3.0" - "@jest/types": "npm:30.3.0" + "@jest/console": "npm:30.4.1" + "@jest/test-result": "npm:30.4.1" + "@jest/transform": "npm:30.4.1" + "@jest/types": "npm:30.4.1" "@jridgewell/trace-mapping": "npm:^0.3.25" "@types/node": "npm:*" chalk: "npm:^4.1.2" @@ -895,9 +922,9 @@ __metadata: istanbul-lib-report: "npm:^3.0.0" istanbul-lib-source-maps: "npm:^5.0.0" istanbul-reports: "npm:^3.1.3" - jest-message-util: "npm:30.3.0" - jest-util: "npm:30.3.0" - jest-worker: "npm:30.3.0" + jest-message-util: "npm:30.4.1" + jest-util: "npm:30.4.1" + jest-worker: "npm:30.4.1" slash: "npm:^3.0.0" string-length: "npm:^4.0.2" v8-to-istanbul: "npm:^9.0.1" @@ -906,7 +933,7 @@ __metadata: peerDependenciesMeta: node-notifier: optional: true - checksum: 10c0/e1b6fb13df94435d4b8e6f4d4bd1c27dfc572ca7393b0a95d14c98013abe3c962aa28e2c56864f3ddd0894834d21c9a67485d11e6c31532aaaeea66ca6a2a026 + checksum: 10c0/cf5220462c6242fa564bbeb6d5988ebfd814e0351f3bddae07323b55c68c7ebd4aa4c23e717231ab4b2d63c4fc7fa4615b9dad8584be534bd44622981242dceb languageName: node linkType: hard @@ -919,15 +946,33 @@ __metadata: languageName: node linkType: hard -"@jest/snapshot-utils@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/snapshot-utils@npm:30.3.0" +"@jest/schemas@npm:30.4.1": + version: 30.4.1 + resolution: "@jest/schemas@npm:30.4.1" dependencies: - "@jest/types": "npm:30.3.0" + "@sinclair/typebox": "npm:^0.34.0" + checksum: 10c0/96f388ebfc1974457fcbde2ad36c40a0b549cba3f624fe8d9d6e5903a152dc75e4043f4ac9ac7668622f2ecb0f9a4dcb9a38edf3bc0d52b82045b2bb2b69b72a + languageName: node + linkType: hard + +"@jest/schemas@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/schemas@npm:29.6.3" + dependencies: + "@sinclair/typebox": "npm:^0.27.8" + checksum: 10c0/b329e89cd5f20b9278ae1233df74016ebf7b385e0d14b9f4c1ad18d096c4c19d1e687aa113a9c976b16ec07f021ae53dea811fb8c1248a50ac34fbe009fdf6be + languageName: node + linkType: hard + +"@jest/snapshot-utils@npm:30.4.1": + version: 30.4.1 + resolution: "@jest/snapshot-utils@npm:30.4.1" + dependencies: + "@jest/types": "npm:30.4.1" chalk: "npm:^4.1.2" graceful-fs: "npm:^4.2.11" natural-compare: "npm:^1.4.0" - checksum: 10c0/ba4fea05a418b257d128d8f9eb7672a9004952563a45ad577bed80e5b2ea2ec6e6d3a24535781cc6530d9904d8fda7b27d15952d079ccdbe88f87a5e71112df0 + checksum: 10c0/81da9079719eece02b89c45cb97162b5b7d794981652c8d8fe2846843ac81ce219ea4bc21bde7cf76c9032006435f82bd9aee8d6139d90b77078ddad4865af02 languageName: node linkType: hard @@ -942,49 +987,49 @@ __metadata: languageName: node linkType: hard -"@jest/test-result@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/test-result@npm:30.3.0" +"@jest/test-result@npm:30.4.1": + version: 30.4.1 + resolution: "@jest/test-result@npm:30.4.1" dependencies: - "@jest/console": "npm:30.3.0" - "@jest/types": "npm:30.3.0" + "@jest/console": "npm:30.4.1" + "@jest/types": "npm:30.4.1" "@types/istanbul-lib-coverage": "npm:^2.0.6" collect-v8-coverage: "npm:^1.0.2" - checksum: 10c0/67bcd405d0a1ac85b55afabf26e0ee0f184f9cfe0e659a44e0e4a4456c1c7fed9d2288f0116b017eaddfa49ded8c44426b8694c44f9a8a2af35be9202b8a9165 + checksum: 10c0/920fa3fe3cc8b5e11bfe36066d733030f1245865d7cac4862e3783a96f9c0a087fd8073c8cb56e4c87c6fcc97b46e6f828ecd3b10dd8e208f5e1b983fcc5cdb8 languageName: node linkType: hard -"@jest/test-sequencer@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/test-sequencer@npm:30.3.0" +"@jest/test-sequencer@npm:30.4.1": + version: 30.4.1 + resolution: "@jest/test-sequencer@npm:30.4.1" dependencies: - "@jest/test-result": "npm:30.3.0" + "@jest/test-result": "npm:30.4.1" graceful-fs: "npm:^4.2.11" - jest-haste-map: "npm:30.3.0" + jest-haste-map: "npm:30.4.1" slash: "npm:^3.0.0" - checksum: 10c0/698be35e7145e79ea9d66071d4ec255f6cef4b5972b5142d299f3edbcbc0428cadf8ddecc6d21e938c98ed72b73b15a6d5f81e7b8b370aaa130d2f6b26fd017c + checksum: 10c0/531b19ffb2358b3b22a56b306359acf66db2073978dd6df8a9522b5b4034ad7540a9cb84bdfebbcb2872686d6d2ab8cabea04ad23ef9d4488cbafd03f7511501 languageName: node linkType: hard -"@jest/transform@npm:30.3.0": - version: 30.3.0 - resolution: "@jest/transform@npm:30.3.0" +"@jest/transform@npm:30.4.1": + version: 30.4.1 + resolution: "@jest/transform@npm:30.4.1" dependencies: "@babel/core": "npm:^7.27.4" - "@jest/types": "npm:30.3.0" + "@jest/types": "npm:30.4.1" "@jridgewell/trace-mapping": "npm:^0.3.25" babel-plugin-istanbul: "npm:^7.0.1" chalk: "npm:^4.1.2" convert-source-map: "npm:^2.0.0" fast-json-stable-stringify: "npm:^2.1.0" graceful-fs: "npm:^4.2.11" - jest-haste-map: "npm:30.3.0" - jest-regex-util: "npm:30.0.1" - jest-util: "npm:30.3.0" + jest-haste-map: "npm:30.4.1" + jest-regex-util: "npm:30.4.0" + jest-util: "npm:30.4.1" pirates: "npm:^4.0.7" slash: "npm:^3.0.0" write-file-atomic: "npm:^5.0.1" - checksum: 10c0/5ad0b5361910680b5160e3dc347c0beb75b4edc35a165ef4fc55837d01365179c276dd6f9cc80f7db94048c641b0c188757e1c98c6d4e9b55577956efbc00574 + checksum: 10c0/194f463f179f6ab3ccd6f4f0f03a117e3c01a7ce098ebf562250aca4c900ed3a9ec08b694227788eabd7cb4e0597f1d0788077c7550ddc679f68a0ad21cc87e0 languageName: node linkType: hard @@ -1003,6 +1048,35 @@ __metadata: languageName: node linkType: hard +"@jest/types@npm:30.4.1": + version: 30.4.1 + resolution: "@jest/types@npm:30.4.1" + dependencies: + "@jest/pattern": "npm:30.4.0" + "@jest/schemas": "npm:30.4.1" + "@types/istanbul-lib-coverage": "npm:^2.0.6" + "@types/istanbul-reports": "npm:^3.0.4" + "@types/node": "npm:*" + "@types/yargs": "npm:^17.0.33" + chalk: "npm:^4.1.2" + checksum: 10c0/4c79f6dbdb1c7eaab5da255fc696c7cae744759d4020e42da8aa63b37fe55ce594be73075fe1ee5407dd59d7e47975be9f674bfc81e91bae2c89c62d27ba55a1 + languageName: node + linkType: hard + +"@jest/types@npm:^29.6.3": + version: 29.6.3 + resolution: "@jest/types@npm:29.6.3" + dependencies: + "@jest/schemas": "npm:^29.6.3" + "@types/istanbul-lib-coverage": "npm:^2.0.0" + "@types/istanbul-reports": "npm:^3.0.0" + "@types/node": "npm:*" + "@types/yargs": "npm:^17.0.8" + chalk: "npm:^4.0.0" + checksum: 10c0/ea4e493dd3fb47933b8ccab201ae573dcc451f951dc44ed2a86123cd8541b82aa9d2b1031caf9b1080d6673c517e2dcc25a44b2dc4f3fbc37bfc965d444888c0 + languageName: node + linkType: hard + "@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.5": version: 0.3.13 resolution: "@jridgewell/gen-mapping@npm:0.3.13" @@ -1151,181 +1225,188 @@ __metadata: languageName: node linkType: hard -"@rollup/rollup-android-arm-eabi@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-android-arm-eabi@npm:4.60.2" +"@rollup/rollup-android-arm-eabi@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-android-arm-eabi@npm:4.60.4" conditions: os=android & cpu=arm languageName: node linkType: hard -"@rollup/rollup-android-arm64@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-android-arm64@npm:4.60.2" +"@rollup/rollup-android-arm64@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-android-arm64@npm:4.60.4" conditions: os=android & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-arm64@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-darwin-arm64@npm:4.60.2" +"@rollup/rollup-darwin-arm64@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-darwin-arm64@npm:4.60.4" conditions: os=darwin & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-darwin-x64@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-darwin-x64@npm:4.60.2" +"@rollup/rollup-darwin-x64@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-darwin-x64@npm:4.60.4" conditions: os=darwin & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-freebsd-arm64@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-freebsd-arm64@npm:4.60.2" +"@rollup/rollup-freebsd-arm64@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-freebsd-arm64@npm:4.60.4" conditions: os=freebsd & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-freebsd-x64@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-freebsd-x64@npm:4.60.2" +"@rollup/rollup-freebsd-x64@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-freebsd-x64@npm:4.60.4" conditions: os=freebsd & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-linux-arm-gnueabihf@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.60.2" +"@rollup/rollup-linux-arm-gnueabihf@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-arm-gnueabihf@npm:4.60.4" conditions: os=linux & cpu=arm & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm-musleabihf@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.60.2" +"@rollup/rollup-linux-arm-musleabihf@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-arm-musleabihf@npm:4.60.4" conditions: os=linux & cpu=arm & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-arm64-gnu@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.60.2" +"@rollup/rollup-linux-arm64-gnu@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-arm64-gnu@npm:4.60.4" conditions: os=linux & cpu=arm64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-arm64-musl@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-linux-arm64-musl@npm:4.60.2" +"@rollup/rollup-linux-arm64-musl@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-arm64-musl@npm:4.60.4" conditions: os=linux & cpu=arm64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-loong64-gnu@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-linux-loong64-gnu@npm:4.60.2" +"@rollup/rollup-linux-loong64-gnu@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-loong64-gnu@npm:4.60.4" conditions: os=linux & cpu=loong64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-loong64-musl@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-linux-loong64-musl@npm:4.60.2" +"@rollup/rollup-linux-loong64-musl@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-loong64-musl@npm:4.60.4" conditions: os=linux & cpu=loong64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-ppc64-gnu@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.60.2" +"@rollup/rollup-linux-ppc64-gnu@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-ppc64-gnu@npm:4.60.4" conditions: os=linux & cpu=ppc64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-ppc64-musl@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-linux-ppc64-musl@npm:4.60.2" +"@rollup/rollup-linux-ppc64-musl@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-ppc64-musl@npm:4.60.4" conditions: os=linux & cpu=ppc64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-gnu@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.60.2" +"@rollup/rollup-linux-riscv64-gnu@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-riscv64-gnu@npm:4.60.4" conditions: os=linux & cpu=riscv64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-riscv64-musl@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.60.2" +"@rollup/rollup-linux-riscv64-musl@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-riscv64-musl@npm:4.60.4" conditions: os=linux & cpu=riscv64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-linux-s390x-gnu@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.60.2" +"@rollup/rollup-linux-s390x-gnu@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-s390x-gnu@npm:4.60.4" conditions: os=linux & cpu=s390x & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-gnu@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-linux-x64-gnu@npm:4.60.2" +"@rollup/rollup-linux-x64-gnu@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-x64-gnu@npm:4.60.4" conditions: os=linux & cpu=x64 & libc=glibc languageName: node linkType: hard -"@rollup/rollup-linux-x64-musl@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-linux-x64-musl@npm:4.60.2" +"@rollup/rollup-linux-x64-musl@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-linux-x64-musl@npm:4.60.4" conditions: os=linux & cpu=x64 & libc=musl languageName: node linkType: hard -"@rollup/rollup-openbsd-x64@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-openbsd-x64@npm:4.60.2" +"@rollup/rollup-openbsd-x64@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-openbsd-x64@npm:4.60.4" conditions: os=openbsd & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-openharmony-arm64@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-openharmony-arm64@npm:4.60.2" +"@rollup/rollup-openharmony-arm64@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-openharmony-arm64@npm:4.60.4" conditions: os=openharmony & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-arm64-msvc@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.60.2" +"@rollup/rollup-win32-arm64-msvc@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-win32-arm64-msvc@npm:4.60.4" conditions: os=win32 & cpu=arm64 languageName: node linkType: hard -"@rollup/rollup-win32-ia32-msvc@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.60.2" +"@rollup/rollup-win32-ia32-msvc@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-win32-ia32-msvc@npm:4.60.4" conditions: os=win32 & cpu=ia32 languageName: node linkType: hard -"@rollup/rollup-win32-x64-gnu@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-win32-x64-gnu@npm:4.60.2" +"@rollup/rollup-win32-x64-gnu@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-win32-x64-gnu@npm:4.60.4" conditions: os=win32 & cpu=x64 languageName: node linkType: hard -"@rollup/rollup-win32-x64-msvc@npm:4.60.2": - version: 4.60.2 - resolution: "@rollup/rollup-win32-x64-msvc@npm:4.60.2" +"@rollup/rollup-win32-x64-msvc@npm:4.60.4": + version: 4.60.4 + resolution: "@rollup/rollup-win32-x64-msvc@npm:4.60.4" conditions: os=win32 & cpu=x64 languageName: node linkType: hard +"@sinclair/typebox@npm:^0.27.8": + version: 0.27.10 + resolution: "@sinclair/typebox@npm:0.27.10" + checksum: 10c0/ca42a02817656dbdae464ed4bb8aca6ad4718d7618e270760fea84a834ad0ecc1a22eba51421f09e5047174571131356ff3b5d80d609ced775d631df7b404b0d + languageName: node + linkType: hard + "@sinclair/typebox@npm:^0.34.0": version: 0.34.49 resolution: "@sinclair/typebox@npm:0.34.49" @@ -1342,22 +1423,77 @@ __metadata: languageName: node linkType: hard -"@sinonjs/fake-timers@npm:^15.0.0": - version: 15.3.2 - resolution: "@sinonjs/fake-timers@npm:15.3.2" +"@sinonjs/fake-timers@npm:^15.4.0": + version: 15.4.0 + resolution: "@sinonjs/fake-timers@npm:15.4.0" dependencies: "@sinonjs/commons": "npm:^3.0.1" - checksum: 10c0/fea39af47e70acf7f6b431b857dc5b50886e1a19d48189bc7f9cf90806a9fdfd4931c04343558724772d429c47fb53df640fc8c8d6ddf6ad66164bd7cbd3220a + checksum: 10c0/de4522afe0699fa8d3ae9d1715cbaa4b47e518c707bb7988a9ec6c7c67557d9f6df451f6be0338598b984a86f65aab9fab38dd9ce75a3c0ffb801a9500d5b10d languageName: node linkType: hard -"@sourceacademy/conductor@npm:^0.3.0": +"@sourceacademy/common-test@workspace:*, @sourceacademy/common-test@workspace:src/common/test": + version: 0.0.0-use.local + resolution: "@sourceacademy/common-test@workspace:src/common/test" + dependencies: + "@rollup/plugin-node-resolve": "npm:^16.0.3" + "@rollup/plugin-terser": "npm:^1.0.0" + "@rollup/plugin-typescript": "npm:^12.3.0" + "@sourceacademy/common-test": "workspace:*" + "@types/jest": "npm:^30.0.0" + jest: "npm:^30.4.2" + rollup: "npm:^4.60.2" + ts-jest: "npm:^29.4.11" + tslib: "npm:^2.8.1" + typescript: "npm:^6.0.3" + languageName: unknown + linkType: soft + +"@sourceacademy/conductor@npm:>=0.3.0, @sourceacademy/conductor@npm:^0.3.0": version: 0.3.0 resolution: "@sourceacademy/conductor@npm:0.3.0" checksum: 10c0/e6d50cc0b9188fa5ec54c3bb2e6b9a0f9391ba37449e74a326c89c4e14deb00c4882700062427737e6f6fca556fd95d91fa9d7f6e125fe1d43938a65cc3c0c4d languageName: node linkType: hard +"@sourceacademy/runner-test@workspace:src/runner/test": + version: 0.0.0-use.local + resolution: "@sourceacademy/runner-test@workspace:src/runner/test" + dependencies: + "@rollup/plugin-node-resolve": "npm:^16.0.3" + "@rollup/plugin-terser": "npm:^1.0.0" + "@rollup/plugin-typescript": "npm:^12.3.0" + "@sourceacademy/common-test": "workspace:*" + "@sourceacademy/conductor": "npm:>=0.3.0" + "@types/jest": "npm:^30.0.0" + jest: "npm:^30.4.2" + rollup: "npm:^4.60.2" + ts-jest: "npm:^29.4.11" + tslib: "npm:^2.8.1" + typescript: "npm:^6.0.3" + peerDependencies: + "@sourceacademy/conductor": ">=0.3.0" + languageName: unknown + linkType: soft + +"@sourceacademy/web-test@workspace:src/web/test": + version: 0.0.0-use.local + resolution: "@sourceacademy/web-test@workspace:src/web/test" + dependencies: + "@rollup/plugin-node-resolve": "npm:^16.0.3" + "@rollup/plugin-terser": "npm:^1.0.0" + "@rollup/plugin-typescript": "npm:^12.3.0" + "@sourceacademy/common-test": "workspace:*" + "@sourceacademy/conductor": "npm:>=0.3.0" + "@types/jest": "npm:^30.0.0" + jest: "npm:^30.4.2" + rollup: "npm:^4.60.2" + ts-jest: "npm:^29.4.11" + tslib: "npm:^2.8.1" + typescript: "npm:^6.0.3" + languageName: unknown + linkType: soft + "@tybys/wasm-util@npm:^0.10.0": version: 0.10.1 resolution: "@tybys/wasm-util@npm:0.10.1" @@ -1422,7 +1558,7 @@ __metadata: languageName: node linkType: hard -"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.1, @types/istanbul-lib-coverage@npm:^2.0.6": +"@types/istanbul-lib-coverage@npm:*, @types/istanbul-lib-coverage@npm:^2.0.0, @types/istanbul-lib-coverage@npm:^2.0.1, @types/istanbul-lib-coverage@npm:^2.0.6": version: 2.0.6 resolution: "@types/istanbul-lib-coverage@npm:2.0.6" checksum: 10c0/3948088654f3eeb45363f1db158354fb013b362dba2a5c2c18c559484d5eb9f6fd85b23d66c0a7c2fcfab7308d0a585b14dadaca6cc8bf89ebfdc7f8f5102fb7 @@ -1438,7 +1574,7 @@ __metadata: languageName: node linkType: hard -"@types/istanbul-reports@npm:^3.0.4": +"@types/istanbul-reports@npm:^3.0.0, @types/istanbul-reports@npm:^3.0.4": version: 3.0.4 resolution: "@types/istanbul-reports@npm:3.0.4" dependencies: @@ -1503,7 +1639,7 @@ __metadata: languageName: node linkType: hard -"@types/yargs@npm:^17.0.33": +"@types/yargs@npm:^17.0.33, @types/yargs@npm:^17.0.8": version: 17.0.35 resolution: "@types/yargs@npm:17.0.35" dependencies: @@ -1891,20 +2027,20 @@ __metadata: languageName: node linkType: hard -"babel-jest@npm:30.3.0": - version: 30.3.0 - resolution: "babel-jest@npm:30.3.0" +"babel-jest@npm:30.4.1": + version: 30.4.1 + resolution: "babel-jest@npm:30.4.1" dependencies: - "@jest/transform": "npm:30.3.0" + "@jest/transform": "npm:30.4.1" "@types/babel__core": "npm:^7.20.5" babel-plugin-istanbul: "npm:^7.0.1" - babel-preset-jest: "npm:30.3.0" + babel-preset-jest: "npm:30.4.0" chalk: "npm:^4.1.2" graceful-fs: "npm:^4.2.11" slash: "npm:^3.0.0" peerDependencies: "@babel/core": ^7.11.0 || ^8.0.0-0 - checksum: 10c0/5e41e124a404ddb78aa37a20336d7c883feab5ad9c4f4c72ae26db71be2fcca345874b9a7fef97d9c5f64f144a264b247ebde8acfe493578320f314ca581bac3 + checksum: 10c0/339b449011f31dc9eb18d9c49f0bb84e8de284e1107e64159a2f4a432bbd532d6a729774a56b7fbe76f5ddd716a0b4b7ad737265feab23b4d0225489b79a6f72 languageName: node linkType: hard @@ -1921,12 +2057,12 @@ __metadata: languageName: node linkType: hard -"babel-plugin-jest-hoist@npm:30.3.0": - version: 30.3.0 - resolution: "babel-plugin-jest-hoist@npm:30.3.0" +"babel-plugin-jest-hoist@npm:30.4.0": + version: 30.4.0 + resolution: "babel-plugin-jest-hoist@npm:30.4.0" dependencies: "@types/babel__core": "npm:^7.20.5" - checksum: 10c0/5e15900a6487356131e084970f4a9ebe24b702d74930f786e897d4fab90b0987054f66661a3570ea692f429dcd158c2214c97ecf08f7356cbc60029d7b277c74 + checksum: 10c0/1738ed536bb5ff536b4d406b8db7dbbd76cf10f80bb20d902e6efdda79898f045b9a991124d7104d8c398d0bd995d511d57694952645fba0f6250595a45277b0 languageName: node linkType: hard @@ -1955,15 +2091,15 @@ __metadata: languageName: node linkType: hard -"babel-preset-jest@npm:30.3.0": - version: 30.3.0 - resolution: "babel-preset-jest@npm:30.3.0" +"babel-preset-jest@npm:30.4.0": + version: 30.4.0 + resolution: "babel-preset-jest@npm:30.4.0" dependencies: - babel-plugin-jest-hoist: "npm:30.3.0" + babel-plugin-jest-hoist: "npm:30.4.0" babel-preset-current-node-syntax: "npm:^1.2.0" peerDependencies: "@babel/core": ^7.11.0 || ^8.0.0-beta.1 - checksum: 10c0/a6839a1527d254bf04e82c0cf61a6a2aa283123a74f0a552e6fce462cb990abebab75a13ec3e9c58b09a865d4d2dfbac710c2d3975ae3ce6f2707cb314915c66 + checksum: 10c0/ca2623aa4d8bf82b1fd01e5724a87cea7f80ff089341cf12415e9ce4b10f74838ecc6c8a48921f421f90bcd44f7929c0ad300146082e2f400253adb97ab5eb3a languageName: node linkType: hard @@ -2086,7 +2222,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^4.1.2": +"chalk@npm:^4.0.0, chalk@npm:^4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -2110,6 +2246,13 @@ __metadata: languageName: node linkType: hard +"ci-info@npm:^3.2.0": + version: 3.9.0 + resolution: "ci-info@npm:3.9.0" + checksum: 10c0/6f0109e36e111684291d46123d491bc4e7b7a1934c3a20dea28cba89f1d4a03acd892f5f6a81ed3855c38647e285a150e3c9ba062e38943bef57fee6c1554c3a + languageName: node + linkType: hard + "ci-info@npm:^4.2.0": version: 4.4.0 resolution: "ci-info@npm:4.4.0" @@ -2583,7 +2726,21 @@ __metadata: languageName: node linkType: hard -"expect@npm:30.3.0, expect@npm:^30.0.0": +"expect@npm:30.4.1": + version: 30.4.1 + resolution: "expect@npm:30.4.1" + dependencies: + "@jest/expect-utils": "npm:30.4.1" + "@jest/get-type": "npm:30.1.0" + jest-matcher-utils: "npm:30.4.1" + jest-message-util: "npm:30.4.1" + jest-mock: "npm:30.4.1" + jest-util: "npm:30.4.1" + checksum: 10c0/ad04fbdffac5a2bae186478938a60f737e3aac823db9a80c87f3f390f9f458bddcc454dc3a3997d715706747c6aff928923e6a71db3a221adb89a51cc1582e72 + languageName: node + linkType: hard + +"expect@npm:^30.0.0": version: 30.3.0 resolution: "expect@npm:30.3.0" dependencies: @@ -2802,7 +2959,7 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.6": +"graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 @@ -3046,58 +3203,58 @@ __metadata: languageName: node linkType: hard -"jest-changed-files@npm:30.3.0": - version: 30.3.0 - resolution: "jest-changed-files@npm:30.3.0" +"jest-changed-files@npm:30.4.1": + version: 30.4.1 + resolution: "jest-changed-files@npm:30.4.1" dependencies: execa: "npm:^5.1.1" - jest-util: "npm:30.3.0" + jest-util: "npm:30.4.1" p-limit: "npm:^3.1.0" - checksum: 10c0/5a2f9790f8ab7f5804ebbf0fcdd908c40286d602d76abbecc6bea72e7f3c60b77dc8a3d3f5acdddd11653b2574f471a5c126ceda0734bc6a7d607cf145843525 + checksum: 10c0/324bbec3920a7d9ceb1d11872b9f1befe73d152a7ef289243f663bf3b22afe124c2c656ec316e44393f30a83b74a1738b56307a066906fa49b800686fd4d0f04 languageName: node linkType: hard -"jest-circus@npm:30.3.0": - version: 30.3.0 - resolution: "jest-circus@npm:30.3.0" +"jest-circus@npm:30.4.2": + version: 30.4.2 + resolution: "jest-circus@npm:30.4.2" dependencies: - "@jest/environment": "npm:30.3.0" - "@jest/expect": "npm:30.3.0" - "@jest/test-result": "npm:30.3.0" - "@jest/types": "npm:30.3.0" + "@jest/environment": "npm:30.4.1" + "@jest/expect": "npm:30.4.1" + "@jest/test-result": "npm:30.4.1" + "@jest/types": "npm:30.4.1" "@types/node": "npm:*" chalk: "npm:^4.1.2" co: "npm:^4.6.0" dedent: "npm:^1.6.0" is-generator-fn: "npm:^2.1.0" - jest-each: "npm:30.3.0" - jest-matcher-utils: "npm:30.3.0" - jest-message-util: "npm:30.3.0" - jest-runtime: "npm:30.3.0" - jest-snapshot: "npm:30.3.0" - jest-util: "npm:30.3.0" + jest-each: "npm:30.4.1" + jest-matcher-utils: "npm:30.4.1" + jest-message-util: "npm:30.4.1" + jest-runtime: "npm:30.4.2" + jest-snapshot: "npm:30.4.1" + jest-util: "npm:30.4.1" p-limit: "npm:^3.1.0" - pretty-format: "npm:30.3.0" + pretty-format: "npm:30.4.1" pure-rand: "npm:^7.0.0" slash: "npm:^3.0.0" stack-utils: "npm:^2.0.6" - checksum: 10c0/a3a0eb973699b400fb6de4207a7fbc5b33f51523e5e94f954d0e6e60418ea95099883614495fce54d805a321cb65e883592048b73203a59b8f4e53d1bb975a07 + checksum: 10c0/5d99f1336eb249057063a007fabad4ced802501fbaad7ddeea8db9553fa54fbd44d26e71e8bf61a0979d42b3b93a3d920e6f00afa26cdbb70d1e7d0969515d10 languageName: node linkType: hard -"jest-cli@npm:30.3.0": - version: 30.3.0 - resolution: "jest-cli@npm:30.3.0" +"jest-cli@npm:30.4.2": + version: 30.4.2 + resolution: "jest-cli@npm:30.4.2" dependencies: - "@jest/core": "npm:30.3.0" - "@jest/test-result": "npm:30.3.0" - "@jest/types": "npm:30.3.0" + "@jest/core": "npm:30.4.2" + "@jest/test-result": "npm:30.4.1" + "@jest/types": "npm:30.4.1" chalk: "npm:^4.1.2" exit-x: "npm:^0.2.2" import-local: "npm:^3.2.0" - jest-config: "npm:30.3.0" - jest-util: "npm:30.3.0" - jest-validate: "npm:30.3.0" + jest-config: "npm:30.4.2" + jest-util: "npm:30.4.1" + jest-validate: "npm:30.4.1" yargs: "npm:^17.7.2" peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 @@ -3106,35 +3263,35 @@ __metadata: optional: true bin: jest: ./bin/jest.js - checksum: 10c0/764d77551e0fb6d666212e89d01be6f7bb1a2b3adb918bba7c5c37593a11b01cf2af645506c2b6438335cfc79bfcf41bfd4680958d8ca751851752a7c66269d3 + checksum: 10c0/a036a1bf06ce7d5fed644a518c4a4ccf60c5fe5f3d96d143973048e6690c4a28a4f97fa3275d90ca236430a1b2a7c10544e7e190a4f2edfdf0a4e6daf1f6a384 languageName: node linkType: hard -"jest-config@npm:30.3.0": - version: 30.3.0 - resolution: "jest-config@npm:30.3.0" +"jest-config@npm:30.4.2": + version: 30.4.2 + resolution: "jest-config@npm:30.4.2" dependencies: "@babel/core": "npm:^7.27.4" "@jest/get-type": "npm:30.1.0" - "@jest/pattern": "npm:30.0.1" - "@jest/test-sequencer": "npm:30.3.0" - "@jest/types": "npm:30.3.0" - babel-jest: "npm:30.3.0" + "@jest/pattern": "npm:30.4.0" + "@jest/test-sequencer": "npm:30.4.1" + "@jest/types": "npm:30.4.1" + babel-jest: "npm:30.4.1" chalk: "npm:^4.1.2" ci-info: "npm:^4.2.0" deepmerge: "npm:^4.3.1" glob: "npm:^10.5.0" graceful-fs: "npm:^4.2.11" - jest-circus: "npm:30.3.0" - jest-docblock: "npm:30.2.0" - jest-environment-node: "npm:30.3.0" - jest-regex-util: "npm:30.0.1" - jest-resolve: "npm:30.3.0" - jest-runner: "npm:30.3.0" - jest-util: "npm:30.3.0" - jest-validate: "npm:30.3.0" + jest-circus: "npm:30.4.2" + jest-docblock: "npm:30.4.0" + jest-environment-node: "npm:30.4.1" + jest-regex-util: "npm:30.4.0" + jest-resolve: "npm:30.4.1" + jest-runner: "npm:30.4.2" + jest-util: "npm:30.4.1" + jest-validate: "npm:30.4.1" parse-json: "npm:^5.2.0" - pretty-format: "npm:30.3.0" + pretty-format: "npm:30.4.1" slash: "npm:^3.0.0" strip-json-comments: "npm:^3.1.1" peerDependencies: @@ -3148,7 +3305,7 @@ __metadata: optional: true ts-node: optional: true - checksum: 10c0/157607e5ac5e83924df97d992fbd40a1540af07c5a7be296fae49455b3729687847304f3b4a9112e7da17593b76cec3453cd55c1ecd4334f7318f2489d7d10a1 + checksum: 10c0/18300b1dc54a4bfb5d1db6c10aeb01b6c64736224e3f60d119da9504d49cbab5a76d789f38c44af7d168418463356db6843ad7e44f249c63ce7f409758eba0c6 languageName: node linkType: hard @@ -3164,72 +3321,84 @@ __metadata: languageName: node linkType: hard -"jest-docblock@npm:30.2.0": - version: 30.2.0 - resolution: "jest-docblock@npm:30.2.0" +"jest-diff@npm:30.4.1": + version: 30.4.1 + resolution: "jest-diff@npm:30.4.1" + dependencies: + "@jest/diff-sequences": "npm:30.4.0" + "@jest/get-type": "npm:30.1.0" + chalk: "npm:^4.1.2" + pretty-format: "npm:30.4.1" + checksum: 10c0/787e11f0ea27e94815479d6c5415e4173da1e74bede34c1515b8515fc9d1fe053e2ad25a3c31f9998a7292c186a0e4d395ed82e0e149d57d7708ee6759b442e9 + languageName: node + linkType: hard + +"jest-docblock@npm:30.4.0": + version: 30.4.0 + resolution: "jest-docblock@npm:30.4.0" dependencies: detect-newline: "npm:^3.1.0" - checksum: 10c0/2578366604eef1b36d59ffe1fc52a710995571535d437f83d94ff94756a83f78e699c1ba004c38a34c01859d669fd6c64e865c23c5a7d5bf4837cfca4bef3dda + checksum: 10c0/1fe1c971207e1b905e4f23d98e508a03ae631337e9ffa347ff2f6df81a1d75ced7ed3e52a809fad75fb8a8cd55b6bda4483bc124e5e1d7529eeb4ef76b29e913 languageName: node linkType: hard -"jest-each@npm:30.3.0": - version: 30.3.0 - resolution: "jest-each@npm:30.3.0" +"jest-each@npm:30.4.1": + version: 30.4.1 + resolution: "jest-each@npm:30.4.1" dependencies: "@jest/get-type": "npm:30.1.0" - "@jest/types": "npm:30.3.0" + "@jest/types": "npm:30.4.1" chalk: "npm:^4.1.2" - jest-util: "npm:30.3.0" - pretty-format: "npm:30.3.0" - checksum: 10c0/d23d2b43b3ea42beaf99648e2cf1c74b8a13c3e45c7c882979171471c225f7d666cb4a0d5f1ff9031b4504866fa3badc7266ffd885d3d8035420c559a31501e1 + jest-util: "npm:30.4.1" + pretty-format: "npm:30.4.1" + checksum: 10c0/41bc1cec23901cb0c7d8f547a70574fffca8cc16a1660ed97645bf3b61f4e6151aaa58bb14ce55a3cd9f5a63a2cc782a39366caf3304a2159d1e3cc5ae79a9e4 languageName: node linkType: hard -"jest-environment-node@npm:30.3.0": - version: 30.3.0 - resolution: "jest-environment-node@npm:30.3.0" +"jest-environment-node@npm:30.4.1": + version: 30.4.1 + resolution: "jest-environment-node@npm:30.4.1" dependencies: - "@jest/environment": "npm:30.3.0" - "@jest/fake-timers": "npm:30.3.0" - "@jest/types": "npm:30.3.0" + "@jest/environment": "npm:30.4.1" + "@jest/fake-timers": "npm:30.4.1" + "@jest/types": "npm:30.4.1" "@types/node": "npm:*" - jest-mock: "npm:30.3.0" - jest-util: "npm:30.3.0" - jest-validate: "npm:30.3.0" - checksum: 10c0/2a4be80861e569fa11456d89ff2aaedd71726ae02ade8f2cc6fbc86ba8749e24c37864676c4718fc08a40f6e6d2b2b51bc48d715b09b1e93e15e42e4a10f7b5b + jest-mock: "npm:30.4.1" + jest-util: "npm:30.4.1" + jest-validate: "npm:30.4.1" + checksum: 10c0/d8d6bb22bfd280f077b5856558d9d7112c48fd3bae6eda9b76694f1c8e1be783a725686a137437d180c9d49e6b37386c8e342e0b8e5bfcb6526dee9c10cc31ec languageName: node linkType: hard -"jest-haste-map@npm:30.3.0": - version: 30.3.0 - resolution: "jest-haste-map@npm:30.3.0" +"jest-haste-map@npm:30.4.1": + version: 30.4.1 + resolution: "jest-haste-map@npm:30.4.1" dependencies: - "@jest/types": "npm:30.3.0" + "@jest/types": "npm:30.4.1" "@types/node": "npm:*" anymatch: "npm:^3.1.3" fb-watchman: "npm:^2.0.2" fsevents: "npm:^2.3.3" graceful-fs: "npm:^4.2.11" - jest-regex-util: "npm:30.0.1" - jest-util: "npm:30.3.0" - jest-worker: "npm:30.3.0" + jest-regex-util: "npm:30.4.0" + jest-util: "npm:30.4.1" + jest-worker: "npm:30.4.1" picomatch: "npm:^4.0.3" walker: "npm:^1.0.8" dependenciesMeta: fsevents: optional: true - checksum: 10c0/b9ef350082b15d4c119d6188f781024d859d6cfb17ae25d15c90c3a373234e16109afbeffdcf1af4baf6a85eb0cbbab00439c981ad43037c0f05d89ff98bd1af + checksum: 10c0/1350c24952bbf31c86cb1ed4e2e5edd4766a93e2be8816c4648c05463d06cfae89f3c73732f9274fdb626fdfdfe6605ed6f259b6c21257df536a6379d4b9a5e7 languageName: node linkType: hard -"jest-leak-detector@npm:30.3.0": - version: 30.3.0 - resolution: "jest-leak-detector@npm:30.3.0" +"jest-leak-detector@npm:30.4.1": + version: 30.4.1 + resolution: "jest-leak-detector@npm:30.4.1" dependencies: "@jest/get-type": "npm:30.1.0" - pretty-format: "npm:30.3.0" - checksum: 10c0/a648c082b74e6c7d0c2e890002094ba97b108398fa3d0316958fc74321aa7b0824507a685d261a463856f219a724b86a6073bac86d351cf0675ecf962c1ee0ca + pretty-format: "npm:30.4.1" + checksum: 10c0/57256ac08f12186e3ed1687126b8d75a12de9c4ffa959ff41322e9ba5f93e3ed8af91dc36bc4d59f77cef6d4008bcf5a3e646cdd950743898576aec8dbae6778 languageName: node linkType: hard @@ -3245,6 +3414,18 @@ __metadata: languageName: node linkType: hard +"jest-matcher-utils@npm:30.4.1": + version: 30.4.1 + resolution: "jest-matcher-utils@npm:30.4.1" + dependencies: + "@jest/get-type": "npm:30.1.0" + chalk: "npm:^4.1.2" + jest-diff: "npm:30.4.1" + pretty-format: "npm:30.4.1" + checksum: 10c0/ddbb0c7075def27ba30160883c327cb3fd13f561f5789d00a1edca1b48b0651f8ea23a1c51bcfcb6413a68c47d658bcf47a34701b8a39ce135dd28d87a3117af + languageName: node + linkType: hard + "jest-message-util@npm:30.3.0": version: 30.3.0 resolution: "jest-message-util@npm:30.3.0" @@ -3262,6 +3443,24 @@ __metadata: languageName: node linkType: hard +"jest-message-util@npm:30.4.1": + version: 30.4.1 + resolution: "jest-message-util@npm:30.4.1" + dependencies: + "@babel/code-frame": "npm:^7.27.1" + "@jest/types": "npm:30.4.1" + "@types/stack-utils": "npm:^2.0.3" + chalk: "npm:^4.1.2" + graceful-fs: "npm:^4.2.11" + jest-util: "npm:30.4.1" + picomatch: "npm:^4.0.3" + pretty-format: "npm:30.4.1" + slash: "npm:^3.0.0" + stack-utils: "npm:^2.0.6" + checksum: 10c0/ae7427544e042bc1c14abf3c0dbe8b83d0dbec22a9a5efefaca5b8ccb6b9bf391abe732e6f2117ca995c6889bfe1be35c78cec75e5ea0a50e28cffe1ba6f9fdf + languageName: node + linkType: hard + "jest-mock@npm:30.3.0": version: 30.3.0 resolution: "jest-mock@npm:30.3.0" @@ -3273,6 +3472,17 @@ __metadata: languageName: node linkType: hard +"jest-mock@npm:30.4.1": + version: 30.4.1 + resolution: "jest-mock@npm:30.4.1" + dependencies: + "@jest/types": "npm:30.4.1" + "@types/node": "npm:*" + jest-util: "npm:30.4.1" + checksum: 10c0/5185a41255285c1634c5d85dda037afaaadfc12793b3293c9e253a30bb67449f8df968447f830abb9cf7a52e63694e6734680130e8085ce119056280890bf6fc + languageName: node + linkType: hard + "jest-pnp-resolver@npm:^1.2.3": version: 1.2.3 resolution: "jest-pnp-resolver@npm:1.2.3" @@ -3292,118 +3502,125 @@ __metadata: languageName: node linkType: hard -"jest-resolve-dependencies@npm:30.3.0": - version: 30.3.0 - resolution: "jest-resolve-dependencies@npm:30.3.0" +"jest-regex-util@npm:30.4.0": + version: 30.4.0 + resolution: "jest-regex-util@npm:30.4.0" + checksum: 10c0/fe7426f67b54d38bed8e9d6e6a099d63d72f41f5bf65b922d9d03fedcb55c614b45657207632f6ee22d0a59d8d11327891f258d23f68a58912fcdb0f7db48435 + languageName: node + linkType: hard + +"jest-resolve-dependencies@npm:30.4.2": + version: 30.4.2 + resolution: "jest-resolve-dependencies@npm:30.4.2" dependencies: - jest-regex-util: "npm:30.0.1" - jest-snapshot: "npm:30.3.0" - checksum: 10c0/25dde0c8c050bc3437332f37ab87484f597596b80ece77a93e4da2b466b42e45cc5ad748270c1477587536de15eea1ffe83a32638e824b120830c3a87c9a5b71 + jest-regex-util: "npm:30.4.0" + jest-snapshot: "npm:30.4.1" + checksum: 10c0/4101afabd2a4ef4e6c82bf82ea145286c1238373f7611938e8d47ddcf5aaa6e10af365436a934b7af194451e351774829cb021ac73f857b4873dcccc7aabb616 languageName: node linkType: hard -"jest-resolve@npm:30.3.0": - version: 30.3.0 - resolution: "jest-resolve@npm:30.3.0" +"jest-resolve@npm:30.4.1": + version: 30.4.1 + resolution: "jest-resolve@npm:30.4.1" dependencies: chalk: "npm:^4.1.2" graceful-fs: "npm:^4.2.11" - jest-haste-map: "npm:30.3.0" + jest-haste-map: "npm:30.4.1" jest-pnp-resolver: "npm:^1.2.3" - jest-util: "npm:30.3.0" - jest-validate: "npm:30.3.0" + jest-util: "npm:30.4.1" + jest-validate: "npm:30.4.1" slash: "npm:^3.0.0" unrs-resolver: "npm:^1.7.11" - checksum: 10c0/540f59f160c232c1b922b111a93f24ef5202d75e00f2e994de976badf6e88879893b474320ff363a6b97259a7a208b6a4f5eeabede787eea9b7912a12ac64b1b + checksum: 10c0/0a99ef4f4fd7b3678d58a5e1cf8f0b5ec1997cdba21f5d66a8b26353d57a226f8e6a5fffc450c8836e90ab0e20d5e7935d0dea939d9a9b6a08781b9a7413184c languageName: node linkType: hard -"jest-runner@npm:30.3.0": - version: 30.3.0 - resolution: "jest-runner@npm:30.3.0" +"jest-runner@npm:30.4.2": + version: 30.4.2 + resolution: "jest-runner@npm:30.4.2" dependencies: - "@jest/console": "npm:30.3.0" - "@jest/environment": "npm:30.3.0" - "@jest/test-result": "npm:30.3.0" - "@jest/transform": "npm:30.3.0" - "@jest/types": "npm:30.3.0" + "@jest/console": "npm:30.4.1" + "@jest/environment": "npm:30.4.1" + "@jest/test-result": "npm:30.4.1" + "@jest/transform": "npm:30.4.1" + "@jest/types": "npm:30.4.1" "@types/node": "npm:*" chalk: "npm:^4.1.2" emittery: "npm:^0.13.1" exit-x: "npm:^0.2.2" graceful-fs: "npm:^4.2.11" - jest-docblock: "npm:30.2.0" - jest-environment-node: "npm:30.3.0" - jest-haste-map: "npm:30.3.0" - jest-leak-detector: "npm:30.3.0" - jest-message-util: "npm:30.3.0" - jest-resolve: "npm:30.3.0" - jest-runtime: "npm:30.3.0" - jest-util: "npm:30.3.0" - jest-watcher: "npm:30.3.0" - jest-worker: "npm:30.3.0" + jest-docblock: "npm:30.4.0" + jest-environment-node: "npm:30.4.1" + jest-haste-map: "npm:30.4.1" + jest-leak-detector: "npm:30.4.1" + jest-message-util: "npm:30.4.1" + jest-resolve: "npm:30.4.1" + jest-runtime: "npm:30.4.2" + jest-util: "npm:30.4.1" + jest-watcher: "npm:30.4.1" + jest-worker: "npm:30.4.1" p-limit: "npm:^3.1.0" source-map-support: "npm:0.5.13" - checksum: 10c0/6fb205f48541658f0b23b6c9a6730f0133f07c994a22ef506ebfcded5bbb444b655ac828074157e6579e664609a46f6a5bf3d366b694c6c8b523b5207a70499c + checksum: 10c0/339e630fb1a7db52e208ed9f12f722122733fe9a450d9bd83c0fccc10fbc5142a8808f624c41ab1e25833af02f9c3eca85561554b75a5b3ad75b4a226f72c5cf languageName: node linkType: hard -"jest-runtime@npm:30.3.0": - version: 30.3.0 - resolution: "jest-runtime@npm:30.3.0" +"jest-runtime@npm:30.4.2": + version: 30.4.2 + resolution: "jest-runtime@npm:30.4.2" dependencies: - "@jest/environment": "npm:30.3.0" - "@jest/fake-timers": "npm:30.3.0" - "@jest/globals": "npm:30.3.0" + "@jest/environment": "npm:30.4.1" + "@jest/fake-timers": "npm:30.4.1" + "@jest/globals": "npm:30.4.1" "@jest/source-map": "npm:30.0.1" - "@jest/test-result": "npm:30.3.0" - "@jest/transform": "npm:30.3.0" - "@jest/types": "npm:30.3.0" + "@jest/test-result": "npm:30.4.1" + "@jest/transform": "npm:30.4.1" + "@jest/types": "npm:30.4.1" "@types/node": "npm:*" chalk: "npm:^4.1.2" cjs-module-lexer: "npm:^2.1.0" collect-v8-coverage: "npm:^1.0.2" glob: "npm:^10.5.0" graceful-fs: "npm:^4.2.11" - jest-haste-map: "npm:30.3.0" - jest-message-util: "npm:30.3.0" - jest-mock: "npm:30.3.0" - jest-regex-util: "npm:30.0.1" - jest-resolve: "npm:30.3.0" - jest-snapshot: "npm:30.3.0" - jest-util: "npm:30.3.0" + jest-haste-map: "npm:30.4.1" + jest-message-util: "npm:30.4.1" + jest-mock: "npm:30.4.1" + jest-regex-util: "npm:30.4.0" + jest-resolve: "npm:30.4.1" + jest-snapshot: "npm:30.4.1" + jest-util: "npm:30.4.1" slash: "npm:^3.0.0" strip-bom: "npm:^4.0.0" - checksum: 10c0/79c486157a926d5be5c66356ad26cc3792cca1afb1490e255a550f52784b6c92eea42f1cb3b2c7565650ea777cf17ffc3f8e305d6b97888e7d273f6d7f282686 + checksum: 10c0/9fce55b0c78fbe47dc2c10a944e9513833fd43c14f292460ef5cdd91e375088bf35549336e66f69fc9d29bf4f410894e9a7eef0bf12a6f39d99174a5300c2c53 languageName: node linkType: hard -"jest-snapshot@npm:30.3.0": - version: 30.3.0 - resolution: "jest-snapshot@npm:30.3.0" +"jest-snapshot@npm:30.4.1": + version: 30.4.1 + resolution: "jest-snapshot@npm:30.4.1" dependencies: "@babel/core": "npm:^7.27.4" "@babel/generator": "npm:^7.27.5" "@babel/plugin-syntax-jsx": "npm:^7.27.1" "@babel/plugin-syntax-typescript": "npm:^7.27.1" "@babel/types": "npm:^7.27.3" - "@jest/expect-utils": "npm:30.3.0" + "@jest/expect-utils": "npm:30.4.1" "@jest/get-type": "npm:30.1.0" - "@jest/snapshot-utils": "npm:30.3.0" - "@jest/transform": "npm:30.3.0" - "@jest/types": "npm:30.3.0" + "@jest/snapshot-utils": "npm:30.4.1" + "@jest/transform": "npm:30.4.1" + "@jest/types": "npm:30.4.1" babel-preset-current-node-syntax: "npm:^1.2.0" chalk: "npm:^4.1.2" - expect: "npm:30.3.0" + expect: "npm:30.4.1" graceful-fs: "npm:^4.2.11" - jest-diff: "npm:30.3.0" - jest-matcher-utils: "npm:30.3.0" - jest-message-util: "npm:30.3.0" - jest-util: "npm:30.3.0" - pretty-format: "npm:30.3.0" + jest-diff: "npm:30.4.1" + jest-matcher-utils: "npm:30.4.1" + jest-message-util: "npm:30.4.1" + jest-util: "npm:30.4.1" + pretty-format: "npm:30.4.1" semver: "npm:^7.7.2" synckit: "npm:^0.11.8" - checksum: 10c0/c1dd295d9d4962f2504c965575212fc62a358a849c66ab96b2f6e608ebdf6a6029ca505bb0693664a54a534e581883665d404a59976a5b46b1a1f88b537e96c5 + checksum: 10c0/cebd70277b6f0d2606f22815480146cf1e37295ed69a1d16e260a99a2ab48db167857e2fb9a938923d22ac13203c83a5e31d7f066b58d87c6d42db58c914ff13 languageName: node linkType: hard @@ -3421,57 +3638,85 @@ __metadata: languageName: node linkType: hard -"jest-validate@npm:30.3.0": - version: 30.3.0 - resolution: "jest-validate@npm:30.3.0" +"jest-util@npm:30.4.1": + version: 30.4.1 + resolution: "jest-util@npm:30.4.1" + dependencies: + "@jest/types": "npm:30.4.1" + "@types/node": "npm:*" + chalk: "npm:^4.1.2" + ci-info: "npm:^4.2.0" + graceful-fs: "npm:^4.2.11" + picomatch: "npm:^4.0.3" + checksum: 10c0/3efe1f25e5a172d04c6af8612d82867ab603b7c1bd8cb89073ff834679b44eba178793cf3af162cf5e25be13aa736ebd23a7826683acc85bddc5873f305b1f6e + languageName: node + linkType: hard + +"jest-util@npm:^29.7.0": + version: 29.7.0 + resolution: "jest-util@npm:29.7.0" + dependencies: + "@jest/types": "npm:^29.6.3" + "@types/node": "npm:*" + chalk: "npm:^4.0.0" + ci-info: "npm:^3.2.0" + graceful-fs: "npm:^4.2.9" + picomatch: "npm:^2.2.3" + checksum: 10c0/bc55a8f49fdbb8f51baf31d2a4f312fb66c9db1483b82f602c9c990e659cdd7ec529c8e916d5a89452ecbcfae4949b21b40a7a59d4ffc0cd813a973ab08c8150 + languageName: node + linkType: hard + +"jest-validate@npm:30.4.1": + version: 30.4.1 + resolution: "jest-validate@npm:30.4.1" dependencies: "@jest/get-type": "npm:30.1.0" - "@jest/types": "npm:30.3.0" + "@jest/types": "npm:30.4.1" camelcase: "npm:^6.3.0" chalk: "npm:^4.1.2" leven: "npm:^3.1.0" - pretty-format: "npm:30.3.0" - checksum: 10c0/645629e9ae0926252dee26b0ad71b9f0392daa896328393479c63b1b13d2a70df4dac8b5053227c64e0120e930db1242897898c40706f135f20f73ef77fcf4f5 + pretty-format: "npm:30.4.1" + checksum: 10c0/23e6677ee6d06476f368c8b6d442b4207e5fbe062e74c1da3eae9ed30a18605f4e8a14809fa9cc7f22a2d8446e8de91a512f59c278720db2ad61c77dc25ffefc languageName: node linkType: hard -"jest-watcher@npm:30.3.0": - version: 30.3.0 - resolution: "jest-watcher@npm:30.3.0" +"jest-watcher@npm:30.4.1": + version: 30.4.1 + resolution: "jest-watcher@npm:30.4.1" dependencies: - "@jest/test-result": "npm:30.3.0" - "@jest/types": "npm:30.3.0" + "@jest/test-result": "npm:30.4.1" + "@jest/types": "npm:30.4.1" "@types/node": "npm:*" ansi-escapes: "npm:^4.3.2" chalk: "npm:^4.1.2" emittery: "npm:^0.13.1" - jest-util: "npm:30.3.0" + jest-util: "npm:30.4.1" string-length: "npm:^4.0.2" - checksum: 10c0/2631be5cc122fbf14cb0bb7566cdea6d6c432b984d8ef3c6385254bb6c378342e0754cbd2dfe094d80762d44bd1c7015de2ec2100eb6f192906619d8b229e1a5 + checksum: 10c0/a56e1714b7b0f9c620c5cee95a84a48b780093594cd188e365a24768f208714895a0deb784ee48e4eec7f1828bc00435ab3c39208d490c33be3786937e997c97 languageName: node linkType: hard -"jest-worker@npm:30.3.0": - version: 30.3.0 - resolution: "jest-worker@npm:30.3.0" +"jest-worker@npm:30.4.1": + version: 30.4.1 + resolution: "jest-worker@npm:30.4.1" dependencies: "@types/node": "npm:*" "@ungap/structured-clone": "npm:^1.3.0" - jest-util: "npm:30.3.0" + jest-util: "npm:30.4.1" merge-stream: "npm:^2.0.0" supports-color: "npm:^8.1.1" - checksum: 10c0/25dfb1bc43d389e1daf8baad0ef7964249f001a7da7d92c61e398840424ca13fb1fb6242f6e021f0cbb37952f90371fb8be1ef0183b5d04ef161fdb8f09ee78e + checksum: 10c0/3eb7ec7e928b82491e66ae6709e3a1eef3edad2bc351514a5d52037b997151989de6ce2912d6a5a3806ae3ae3bf6a1c36b1ad7bbc567d0790503fdb74576f140 languageName: node linkType: hard -"jest@npm:^30.3.0": - version: 30.3.0 - resolution: "jest@npm:30.3.0" +"jest@npm:^30.4.2": + version: 30.4.2 + resolution: "jest@npm:30.4.2" dependencies: - "@jest/core": "npm:30.3.0" - "@jest/types": "npm:30.3.0" + "@jest/core": "npm:30.4.2" + "@jest/types": "npm:30.4.1" import-local: "npm:^3.2.0" - jest-cli: "npm:30.3.0" + jest-cli: "npm:30.4.2" peerDependencies: node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 peerDependenciesMeta: @@ -3479,7 +3724,7 @@ __metadata: optional: true bin: jest: ./bin/jest.js - checksum: 10c0/1f940424b741d1541c3d71e311f77c3cfaf31cff9ab2d53180333f00a31f157790a8d3d413b72b8dd2bb191aa75769fa741d9bc9085df779cd59689559a65815 + checksum: 10c0/26a76eaabfc043abd8ee702b97f61ff968dde03412efdb4a69c22c99a5e4bf47788a3e45f75134aec1377a686a9d59d1e3bae85a816e409013475a80de1458ec languageName: node linkType: hard @@ -3941,7 +4186,7 @@ __metadata: languageName: node linkType: hard -"picomatch@npm:^2.0.4": +"picomatch@npm:^2.0.4, picomatch@npm:^2.2.3": version: 2.3.2 resolution: "picomatch@npm:2.3.2" checksum: 10c0/a554d1709e59be97d1acb9eaedbbc700a5c03dbd4579807baed95100b00420bc729335440ef15004ae2378984e2487a7c1cebd743cfdb72b6fa9ab69223c0d61 @@ -3975,19 +4220,15 @@ __metadata: version: 0.0.0-use.local resolution: "plugins@workspace:." dependencies: - "@rollup/plugin-node-resolve": "npm:^16.0.3" - "@rollup/plugin-terser": "npm:^1.0.0" - "@rollup/plugin-typescript": "npm:^12.3.0" "@sourceacademy/conductor": "npm:^0.3.0" "@types/jest": "npm:^30.0.0" "@types/node": "npm:^25.9.1" commander: "npm:^14.0.3" eslint: "npm:^10.0.3" eslint-config-prettier: "npm:^10.1.8" - jest: "npm:^30.3.0" + jest: "npm:^30.4.2" prettier: "npm:^3.8.1" - rollup: "npm:^4.60.0" - ts-jest: "npm:^29.4.6" + ts-jest: "npm:^29.4.11" tsx: "npm:^4.22.3" typescript: "npm:^6.0.3" typescript-eslint: "npm:^8.57.1" @@ -4021,6 +4262,18 @@ __metadata: languageName: node linkType: hard +"pretty-format@npm:30.4.1": + version: 30.4.1 + resolution: "pretty-format@npm:30.4.1" + dependencies: + "@jest/schemas": "npm:30.4.1" + ansi-styles: "npm:^5.2.0" + react-is-18: "npm:react-is@^18.3.1" + react-is-19: "npm:react-is@^19.2.5" + checksum: 10c0/c7e6633740cd2f6d382f188c00c8b4b3f2bee3cda16db6753471c6bb4b94f76531358d3a7793062a0fb00d72ebfb934e8ae1d4f5ced6bb34c8e7f60996f90076 + languageName: node + linkType: hard + "proc-log@npm:^6.0.0": version: 6.1.0 resolution: "proc-log@npm:6.1.0" @@ -4042,13 +4295,20 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^18.3.1": +"react-is-18@npm:react-is@^18.3.1, react-is@npm:^18.3.1": version: 18.3.1 resolution: "react-is@npm:18.3.1" checksum: 10c0/f2f1e60010c683479e74c63f96b09fb41603527cd131a9959e2aee1e5a8b0caf270b365e5ca77d4a6b18aae659b60a86150bb3979073528877029b35aecd2072 languageName: node linkType: hard +"react-is-19@npm:react-is@^19.2.5": + version: 19.2.6 + resolution: "react-is@npm:19.2.6" + checksum: 10c0/263177f370fc156b279d22570dd6e922a0ad641a4a426a4cb70284b8003b00ef532d59f2beca1d22a1ca0b37f85f9077d7733ca5d344ebecd2942e9bc2a2a3c0 + languageName: node + linkType: hard + "require-directory@npm:^2.1.1": version: 2.1.1 resolution: "require-directory@npm:2.1.1" @@ -4100,35 +4360,35 @@ __metadata: languageName: node linkType: hard -"rollup@npm:^4.60.0": - version: 4.60.2 - resolution: "rollup@npm:4.60.2" - dependencies: - "@rollup/rollup-android-arm-eabi": "npm:4.60.2" - "@rollup/rollup-android-arm64": "npm:4.60.2" - "@rollup/rollup-darwin-arm64": "npm:4.60.2" - "@rollup/rollup-darwin-x64": "npm:4.60.2" - "@rollup/rollup-freebsd-arm64": "npm:4.60.2" - "@rollup/rollup-freebsd-x64": "npm:4.60.2" - "@rollup/rollup-linux-arm-gnueabihf": "npm:4.60.2" - "@rollup/rollup-linux-arm-musleabihf": "npm:4.60.2" - "@rollup/rollup-linux-arm64-gnu": "npm:4.60.2" - "@rollup/rollup-linux-arm64-musl": "npm:4.60.2" - "@rollup/rollup-linux-loong64-gnu": "npm:4.60.2" - "@rollup/rollup-linux-loong64-musl": "npm:4.60.2" - "@rollup/rollup-linux-ppc64-gnu": "npm:4.60.2" - "@rollup/rollup-linux-ppc64-musl": "npm:4.60.2" - "@rollup/rollup-linux-riscv64-gnu": "npm:4.60.2" - "@rollup/rollup-linux-riscv64-musl": "npm:4.60.2" - "@rollup/rollup-linux-s390x-gnu": "npm:4.60.2" - "@rollup/rollup-linux-x64-gnu": "npm:4.60.2" - "@rollup/rollup-linux-x64-musl": "npm:4.60.2" - "@rollup/rollup-openbsd-x64": "npm:4.60.2" - "@rollup/rollup-openharmony-arm64": "npm:4.60.2" - "@rollup/rollup-win32-arm64-msvc": "npm:4.60.2" - "@rollup/rollup-win32-ia32-msvc": "npm:4.60.2" - "@rollup/rollup-win32-x64-gnu": "npm:4.60.2" - "@rollup/rollup-win32-x64-msvc": "npm:4.60.2" +"rollup@npm:^4.60.2": + version: 4.60.4 + resolution: "rollup@npm:4.60.4" + dependencies: + "@rollup/rollup-android-arm-eabi": "npm:4.60.4" + "@rollup/rollup-android-arm64": "npm:4.60.4" + "@rollup/rollup-darwin-arm64": "npm:4.60.4" + "@rollup/rollup-darwin-x64": "npm:4.60.4" + "@rollup/rollup-freebsd-arm64": "npm:4.60.4" + "@rollup/rollup-freebsd-x64": "npm:4.60.4" + "@rollup/rollup-linux-arm-gnueabihf": "npm:4.60.4" + "@rollup/rollup-linux-arm-musleabihf": "npm:4.60.4" + "@rollup/rollup-linux-arm64-gnu": "npm:4.60.4" + "@rollup/rollup-linux-arm64-musl": "npm:4.60.4" + "@rollup/rollup-linux-loong64-gnu": "npm:4.60.4" + "@rollup/rollup-linux-loong64-musl": "npm:4.60.4" + "@rollup/rollup-linux-ppc64-gnu": "npm:4.60.4" + "@rollup/rollup-linux-ppc64-musl": "npm:4.60.4" + "@rollup/rollup-linux-riscv64-gnu": "npm:4.60.4" + "@rollup/rollup-linux-riscv64-musl": "npm:4.60.4" + "@rollup/rollup-linux-s390x-gnu": "npm:4.60.4" + "@rollup/rollup-linux-x64-gnu": "npm:4.60.4" + "@rollup/rollup-linux-x64-musl": "npm:4.60.4" + "@rollup/rollup-openbsd-x64": "npm:4.60.4" + "@rollup/rollup-openharmony-arm64": "npm:4.60.4" + "@rollup/rollup-win32-arm64-msvc": "npm:4.60.4" + "@rollup/rollup-win32-ia32-msvc": "npm:4.60.4" + "@rollup/rollup-win32-x64-gnu": "npm:4.60.4" + "@rollup/rollup-win32-x64-msvc": "npm:4.60.4" "@types/estree": "npm:1.0.8" fsevents: "npm:~2.3.2" dependenciesMeta: @@ -4186,7 +4446,7 @@ __metadata: optional: true bin: rollup: dist/bin/rollup - checksum: 10c0/f67d6156fc5b895f33b929a4762392906d00fa5550f0a1f5e66519ab1c05d835aec5f201b4e748c29d1c87f024d3d9c4b0a2d1285668456db661d82b961d379c + checksum: 10c0/2734511579da220408eefb877b51281767d790652cee25da8fcd4936c947e3db14882b5edb1d0d5d5bf60f2a71a58ae7d5f7f46c11e3fdf33182538953886243 languageName: node linkType: hard @@ -4199,7 +4459,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.7.2, semver@npm:^7.7.3, semver@npm:^7.7.4": +"semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.7.2, semver@npm:^7.7.3": version: 7.7.4 resolution: "semver@npm:7.7.4" bin: @@ -4208,6 +4468,15 @@ __metadata: languageName: node linkType: hard +"semver@npm:^7.8.0": + version: 7.8.1 + resolution: "semver@npm:7.8.1" + bin: + semver: bin/semver.js + checksum: 10c0/92d6871d6347e1f99d0ba396a70f2545ccf2a032cda3d378fa0699edf7506b5c6d266aed55c8b88e72bd91a30d2351e4f39db479375374430fcdc4b58f4e3c1a + languageName: node + linkType: hard + "serialize-javascript@npm:^7.0.3": version: 7.0.5 resolution: "serialize-javascript@npm:7.0.5" @@ -4471,9 +4740,9 @@ __metadata: languageName: node linkType: hard -"ts-jest@npm:^29.4.6": - version: 29.4.9 - resolution: "ts-jest@npm:29.4.9" +"ts-jest@npm:^29.4.11": + version: 29.4.11 + resolution: "ts-jest@npm:29.4.11" dependencies: bs-logger: "npm:^0.2.6" fast-json-stable-stringify: "npm:^2.1.0" @@ -4481,7 +4750,7 @@ __metadata: json5: "npm:^2.2.3" lodash.memoize: "npm:^4.1.2" make-error: "npm:^1.3.6" - semver: "npm:^7.7.4" + semver: "npm:^7.8.0" type-fest: "npm:^4.41.0" yargs-parser: "npm:^21.1.1" peerDependencies: @@ -4507,11 +4776,11 @@ __metadata: optional: true bin: ts-jest: cli.js - checksum: 10c0/901eb382817d1f48fc56b6c9b82de989f176660295695ae1fcd55f06f71d2c107766e1413ab24a59fa964c2ef79a60dd23ac1f382b05ae04f2b454fb4eb5ad4f + checksum: 10c0/f9e6ab3235f33088c4d6441da97d4b03b1fe9c21f4d859d7acf3f325ea36471a6c1ea9301f445b2670efa1a391dcddc31ecd8641a2d673752d074136311b8480 languageName: node linkType: hard -"tslib@npm:^2.4.0": +"tslib@npm:^2.4.0, tslib@npm:^2.8.1": version: 2.8.1 resolution: "tslib@npm:2.8.1" checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 From 30341f91e321481ca2f0798089ec644039451055 Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Thu, 28 May 2026 19:44:02 +0800 Subject: [PATCH 06/16] fix: Gemini issues --- eslint.config.mjs | 2 +- lib/build.ts | 31 ++++++++++++++++++++++--------- src/common/test/package.json | 1 - src/common/test/rollup.config.mjs | 1 - src/runner/test/rollup.config.mjs | 1 - src/web/test/rollup.config.mjs | 1 - 6 files changed, 23 insertions(+), 14 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 70a94a9..cfae433 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -4,7 +4,7 @@ import tseslint from "typescript-eslint"; export default defineConfig([ { - ignores: ["dist", "coverage"], + ignores: ["**/dist", "coverage"], }, tseslint.configs.recommended, eslintConfigPrettierFlat, diff --git a/lib/build.ts b/lib/build.ts index cbd7fa0..b7da749 100644 --- a/lib/build.ts +++ b/lib/build.ts @@ -5,23 +5,36 @@ import { spawn } from "child_process"; const program = new Command(); export async function generateManifest() { - await fs.mkdir("dist"); + await fs.mkdir("dist", { recursive: true }); await Promise.all(packageJSON.workspaces.map(async (workspace) => { const manifest: Record = {}; - const pluginType = workspace.split("/").slice(-2)[0]; - for await (const file of fs.glob(`${workspace}/manifest.json`)) { - const manifest = JSON.parse(await fs.readFile(file, "utf-8")); - const folderName = file.split("/").slice(0, -1).join("/"); - manifest[folderName] = manifest; + const pluginType = workspace.split("/").slice(-3)[0]; + for await (const file of fs.glob(`${workspace}manifest.json`)) { + const manifestFile = JSON.parse(await fs.readFile(file, "utf-8")); + const folderName = file.split("/").slice(-2)[0]; + manifest[folderName] = manifestFile; } await fs.writeFile(`dist/${pluginType}.json`, JSON.stringify(manifest, null, 2)); })); } - +export async function spawnPromise(...args: Parameters) { + return new Promise((resolve, reject) => { + const child = spawn(...args); + child.on("close", (code) => { + if (code === 0) { + resolve(); + } + else { + reject(new Error(`Process exited with code ${code}`)); + } + } + ); + }); +} export async function build(extraArgs: string[] = []) { - await Promise.allSettled([ + await Promise.all([ generateManifest(), - spawn("yarn", ["workspaces", "foreach", "-Apt", "run", "build", ...extraArgs], { stdio: "inherit" }) + spawnPromise("yarn", ["workspaces", "foreach", "-Apt", "run", "build", ...extraArgs], { stdio: "inherit" }) ]) } diff --git a/src/common/test/package.json b/src/common/test/package.json index e031b71..5661835 100644 --- a/src/common/test/package.json +++ b/src/common/test/package.json @@ -27,7 +27,6 @@ "@rollup/plugin-node-resolve": "^16.0.3", "@rollup/plugin-terser": "^1.0.0", "@rollup/plugin-typescript": "^12.3.0", - "@sourceacademy/common-test": "workspace:*", "@types/jest": "^30.0.0", "jest": "^30.4.2", "rollup": "^4.60.2", diff --git a/src/common/test/rollup.config.mjs b/src/common/test/rollup.config.mjs index a9670b6..0da8fa2 100644 --- a/src/common/test/rollup.config.mjs +++ b/src/common/test/rollup.config.mjs @@ -1,4 +1,3 @@ -import packageJson from "./package.json" with { type: "json" }; import nodeResolve from "@rollup/plugin-node-resolve"; import terser from "@rollup/plugin-terser"; import typescript from "@rollup/plugin-typescript"; diff --git a/src/runner/test/rollup.config.mjs b/src/runner/test/rollup.config.mjs index a9670b6..0da8fa2 100644 --- a/src/runner/test/rollup.config.mjs +++ b/src/runner/test/rollup.config.mjs @@ -1,4 +1,3 @@ -import packageJson from "./package.json" with { type: "json" }; import nodeResolve from "@rollup/plugin-node-resolve"; import terser from "@rollup/plugin-terser"; import typescript from "@rollup/plugin-typescript"; diff --git a/src/web/test/rollup.config.mjs b/src/web/test/rollup.config.mjs index a9670b6..0da8fa2 100644 --- a/src/web/test/rollup.config.mjs +++ b/src/web/test/rollup.config.mjs @@ -1,4 +1,3 @@ -import packageJson from "./package.json" with { type: "json" }; import nodeResolve from "@rollup/plugin-node-resolve"; import terser from "@rollup/plugin-terser"; import typescript from "@rollup/plugin-typescript"; From 1c8759d468a2e55b1073ddbc1eaea7d4e3a46eca Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Thu, 28 May 2026 19:45:16 +0800 Subject: [PATCH 07/16] chore: format files --- lib/build.ts | 58 ++++++++++---------- lib/tsconfig.json | 2 +- src/common/test/manifest.json | 4 +- src/common/test/rollup.config.mjs | 2 +- src/common/test/src/__tests__/common.test.ts | 4 +- src/common/test/src/index.ts | 2 +- src/common/test/tsconfig.json | 10 +--- src/runner/test/manifest.json | 4 +- src/runner/test/rollup.config.mjs | 2 +- src/runner/test/src/index.ts | 4 +- src/runner/test/tsconfig.json | 10 +--- src/tsconfig.json | 2 +- src/web/test/manifest.json | 4 +- src/web/test/rollup.config.mjs | 2 +- src/web/test/src/index.ts | 4 +- src/web/test/tsconfig.json | 10 +--- 16 files changed, 56 insertions(+), 68 deletions(-) diff --git a/lib/build.ts b/lib/build.ts index b7da749..8420766 100644 --- a/lib/build.ts +++ b/lib/build.ts @@ -5,42 +5,42 @@ import { spawn } from "child_process"; const program = new Command(); export async function generateManifest() { - await fs.mkdir("dist", { recursive: true }); - await Promise.all(packageJSON.workspaces.map(async (workspace) => { - const manifest: Record = {}; - const pluginType = workspace.split("/").slice(-3)[0]; - for await (const file of fs.glob(`${workspace}manifest.json`)) { - const manifestFile = JSON.parse(await fs.readFile(file, "utf-8")); - const folderName = file.split("/").slice(-2)[0]; - manifest[folderName] = manifestFile; - } - await fs.writeFile(`dist/${pluginType}.json`, JSON.stringify(manifest, null, 2)); - })); + await fs.mkdir("dist", { recursive: true }); + await Promise.all( + packageJSON.workspaces.map(async workspace => { + const manifest: Record = {}; + const pluginType = workspace.split("/").slice(-3)[0]; + for await (const file of fs.glob(`${workspace}manifest.json`)) { + const manifestFile = JSON.parse(await fs.readFile(file, "utf-8")); + const folderName = file.split("/").slice(-2)[0]; + manifest[folderName] = manifestFile; + } + await fs.writeFile(`dist/${pluginType}.json`, JSON.stringify(manifest, null, 2)); + }), + ); } export async function spawnPromise(...args: Parameters) { - return new Promise((resolve, reject) => { - const child = spawn(...args); - child.on("close", (code) => { - if (code === 0) { - resolve(); - } - else { - reject(new Error(`Process exited with code ${code}`)); - } - } - ); + return new Promise((resolve, reject) => { + const child = spawn(...args); + child.on("close", code => { + if (code === 0) { + resolve(); + } else { + reject(new Error(`Process exited with code ${code}`)); + } }); + }); } export async function build(extraArgs: string[] = []) { - await Promise.all([ - generateManifest(), - spawnPromise("yarn", ["workspaces", "foreach", "-Apt", "run", "build", ...extraArgs], { stdio: "inherit" }) - ]) + await Promise.all([ + generateManifest(), + spawnPromise("yarn", ["workspaces", "foreach", "-Apt", "run", "build", ...extraArgs], { + stdio: "inherit", + }), + ]); } // TO-DO: Add more options -const options = program - .parse(); +const options = program.parse(); const extraArgs = options.args; await build(extraArgs); - diff --git a/lib/tsconfig.json b/lib/tsconfig.json index 9fb89ff..5e12213 100644 --- a/lib/tsconfig.json +++ b/lib/tsconfig.json @@ -34,5 +34,5 @@ // "verbatimModuleSyntax": true, "isolatedModules": true, "types": ["node"] - }, + } } diff --git a/src/common/test/manifest.json b/src/common/test/manifest.json index 830ff20..06d21f0 100644 --- a/src/common/test/manifest.json +++ b/src/common/test/manifest.json @@ -1,3 +1,3 @@ { - "type": "internal" -} \ No newline at end of file + "type": "internal" +} diff --git a/src/common/test/rollup.config.mjs b/src/common/test/rollup.config.mjs index 0da8fa2..238a07c 100644 --- a/src/common/test/rollup.config.mjs +++ b/src/common/test/rollup.config.mjs @@ -18,4 +18,4 @@ export default { }, ], plugins: [nodeResolve(), typescript(), terser()], -}; \ No newline at end of file +}; diff --git a/src/common/test/src/__tests__/common.test.ts b/src/common/test/src/__tests__/common.test.ts index 146f46f..bdba641 100644 --- a/src/common/test/src/__tests__/common.test.ts +++ b/src/common/test/src/__tests__/common.test.ts @@ -1,4 +1,4 @@ import { CHANNEL_ID } from ".."; test("should have a valid channel id", () => { - expect(CHANNEL_ID).toBe("test"); -}); \ No newline at end of file + expect(CHANNEL_ID).toBe("test"); +}); diff --git a/src/common/test/src/index.ts b/src/common/test/src/index.ts index dcf12a7..8aa5d5b 100644 --- a/src/common/test/src/index.ts +++ b/src/common/test/src/index.ts @@ -3,4 +3,4 @@ export const RUNNER_ID = "__runner_test"; export const CHANNEL_ID = "test"; -export type TestMessage = "ping" | "pong"; \ No newline at end of file +export type TestMessage = "ping" | "pong"; diff --git a/src/common/test/tsconfig.json b/src/common/test/tsconfig.json index 35238f5..88a8445 100644 --- a/src/common/test/tsconfig.json +++ b/src/common/test/tsconfig.json @@ -1,15 +1,11 @@ { "extends": "../../tsconfig.json", - "exclude": [ - "./dist" - ], - "include": [ - "./src" - ], + "exclude": ["./dist"], + "include": ["./src"], "compilerOptions": { "declaration": true, "outDir": "./dist", "rootDir": "./src", "types": ["jest"] } -} \ No newline at end of file +} diff --git a/src/runner/test/manifest.json b/src/runner/test/manifest.json index fd96295..e263f73 100644 --- a/src/runner/test/manifest.json +++ b/src/runner/test/manifest.json @@ -1,3 +1,3 @@ { - "type": "installable" -} \ No newline at end of file + "type": "installable" +} diff --git a/src/runner/test/rollup.config.mjs b/src/runner/test/rollup.config.mjs index 0da8fa2..238a07c 100644 --- a/src/runner/test/rollup.config.mjs +++ b/src/runner/test/rollup.config.mjs @@ -18,4 +18,4 @@ export default { }, ], plugins: [nodeResolve(), typescript(), terser()], -}; \ No newline at end of file +}; diff --git a/src/runner/test/src/index.ts b/src/runner/test/src/index.ts index 03053c4..4667ba0 100644 --- a/src/runner/test/src/index.ts +++ b/src/runner/test/src/index.ts @@ -10,8 +10,8 @@ export abstract class TestPlugin implements IPlugin { [testChannel]: IChannel[], ) { this.__testChannel = testChannel; - this.__testChannel.subscribe((message) => { - console.log(message); + this.__testChannel.subscribe(message => { + console.log(message); }); this.__testChannel.send("ping"); } diff --git a/src/runner/test/tsconfig.json b/src/runner/test/tsconfig.json index bccdab1..ebd661f 100644 --- a/src/runner/test/tsconfig.json +++ b/src/runner/test/tsconfig.json @@ -1,14 +1,10 @@ { "extends": "../../tsconfig.json", - "exclude": [ - "./dist" - ], - "include": [ - "./src" - ], + "exclude": ["./dist"], + "include": ["./src"], "compilerOptions": { "outDir": "./dist", "rootDir": "./src", "types": ["jest"] } -} \ No newline at end of file +} diff --git a/src/tsconfig.json b/src/tsconfig.json index 485c5b1..14d7396 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -34,7 +34,7 @@ /* Ensure that imports used only as types get removed */ // "verbatimModuleSyntax": true, - "isolatedModules": true, + "isolatedModules": true }, /* Specifies an array of filenames or patterns that should be skipped when resolving include. */ "exclude": ["**/dist"] diff --git a/src/web/test/manifest.json b/src/web/test/manifest.json index fd96295..e263f73 100644 --- a/src/web/test/manifest.json +++ b/src/web/test/manifest.json @@ -1,3 +1,3 @@ { - "type": "installable" -} \ No newline at end of file + "type": "installable" +} diff --git a/src/web/test/rollup.config.mjs b/src/web/test/rollup.config.mjs index 0da8fa2..238a07c 100644 --- a/src/web/test/rollup.config.mjs +++ b/src/web/test/rollup.config.mjs @@ -18,4 +18,4 @@ export default { }, ], plugins: [nodeResolve(), typescript(), terser()], -}; \ No newline at end of file +}; diff --git a/src/web/test/src/index.ts b/src/web/test/src/index.ts index 89e08ef..ca0a97d 100644 --- a/src/web/test/src/index.ts +++ b/src/web/test/src/index.ts @@ -11,8 +11,8 @@ export abstract class TestPlugin implements IPlugin { [testChannel]: IChannel[], ) { this.__testChannel = testChannel; - this.__testChannel.subscribe((message) => { - console.log(message); + this.__testChannel.subscribe(message => { + console.log(message); }); this.__testChannel.send("ping"); } diff --git a/src/web/test/tsconfig.json b/src/web/test/tsconfig.json index e07ecd8..101b674 100644 --- a/src/web/test/tsconfig.json +++ b/src/web/test/tsconfig.json @@ -1,14 +1,10 @@ { "extends": "../tsconfig.json", - "exclude": [ - "./dist" - ], - "include": [ - "./src" - ], + "exclude": ["./dist"], + "include": ["./src"], "compilerOptions": { "outDir": "./dist", "rootDir": "./src", "types": ["jest"] } -} \ No newline at end of file +} From 19f724b74f3c0c4c3566eabc9f9c496468b64fca Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Thu, 28 May 2026 19:52:47 +0800 Subject: [PATCH 08/16] fix: add yarn.lock --- yarn.lock | 1 - 1 file changed, 1 deletion(-) diff --git a/yarn.lock b/yarn.lock index 9cc66f7..070ab44 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1439,7 +1439,6 @@ __metadata: "@rollup/plugin-node-resolve": "npm:^16.0.3" "@rollup/plugin-terser": "npm:^1.0.0" "@rollup/plugin-typescript": "npm:^12.3.0" - "@sourceacademy/common-test": "workspace:*" "@types/jest": "npm:^30.0.0" jest: "npm:^30.4.2" rollup: "npm:^4.60.2" From f26ab4bdeb6c68d99874efca86f70a459f3617b8 Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Thu, 28 May 2026 19:57:28 +0800 Subject: [PATCH 09/16] fix: update build script to topologically sort devDependencies --- lib/build.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/build.ts b/lib/build.ts index 8420766..8e72828 100644 --- a/lib/build.ts +++ b/lib/build.ts @@ -34,7 +34,7 @@ export async function spawnPromise(...args: Parameters) { export async function build(extraArgs: string[] = []) { await Promise.all([ generateManifest(), - spawnPromise("yarn", ["workspaces", "foreach", "-Apt", "run", "build", ...extraArgs], { + spawnPromise("yarn", ["workspaces", "foreach", "-Apt", "--topological-dev", "run", "build", ...extraArgs], { stdio: "inherit", }), ]); From 28dd7eb1b5bdb3e596db19c8cd660b5a8d7e87ef Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Thu, 28 May 2026 19:57:54 +0800 Subject: [PATCH 10/16] chore: format files --- lib/build.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/build.ts b/lib/build.ts index 8e72828..4083916 100644 --- a/lib/build.ts +++ b/lib/build.ts @@ -34,9 +34,13 @@ export async function spawnPromise(...args: Parameters) { export async function build(extraArgs: string[] = []) { await Promise.all([ generateManifest(), - spawnPromise("yarn", ["workspaces", "foreach", "-Apt", "--topological-dev", "run", "build", ...extraArgs], { - stdio: "inherit", - }), + spawnPromise( + "yarn", + ["workspaces", "foreach", "-Apt", "--topological-dev", "run", "build", ...extraArgs], + { + stdio: "inherit", + }, + ), ]); } From d444035075df5bd8644d4e6d2dca481d22526a33 Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Thu, 28 May 2026 20:02:13 +0800 Subject: [PATCH 11/16] chore: format files --- renovate.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/renovate.json b/renovate.json index 5db72dd..22a9943 100644 --- a/renovate.json +++ b/renovate.json @@ -1,6 +1,4 @@ { "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended" - ] + "extends": ["config:recommended"] } From aa882df5f357f5cd73a7fe1b049818e8e0135f28 Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Sat, 6 Jun 2026 22:54:03 +0800 Subject: [PATCH 12/16] feat: add changesets to automate versioning bumps --- .changeset/README.md | 8 + .changeset/config.json | 11 + .github/workflows/on_push.yml | 7 + package.json | 1 + yarn.lock | 722 +++++++++++++++++++++++++++++++++- 5 files changed, 743 insertions(+), 6 deletions(-) create mode 100644 .changeset/README.md create mode 100644 .changeset/config.json diff --git a/.changeset/README.md b/.changeset/README.md new file mode 100644 index 0000000..654c6d4 --- /dev/null +++ b/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets). + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md). diff --git a/.changeset/config.json b/.changeset/config.json new file mode 100644 index 0000000..5c58ec9 --- /dev/null +++ b/.changeset/config.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@3.1.4/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "restricted", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [] +} diff --git a/.github/workflows/on_push.yml b/.github/workflows/on_push.yml index 27d18c4..d424237 100644 --- a/.github/workflows/on_push.yml +++ b/.github/workflows/on_push.yml @@ -22,6 +22,13 @@ jobs: run: yarn install --frozen-lockfile - name: yarn run build run: yarn run build + - name: Create Release Pull Request or Publish to npm + id: changesets + uses: changesets/action@v1 + with: + publish: changeset publish + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Upload artifacts id: deployment uses: actions/upload-pages-artifact@v3 diff --git a/package.json b/package.json index 336ba22..8e76eb4 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "format:ci": "prettier --list-different \"**/*.{ts,tsx,json,js,mjs}\"" }, "devDependencies": { + "@changesets/cli": "^2.31.0", "@sourceacademy/conductor": "^0.3.0", "@types/jest": "^30.0.0", "@types/node": "^25.9.1", diff --git a/yarn.lock b/yarn.lock index 070ab44..536a9e0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -338,6 +338,13 @@ __metadata: languageName: node linkType: hard +"@babel/runtime@npm:^7.5.5": + version: 7.29.7 + resolution: "@babel/runtime@npm:7.29.7" + checksum: 10c0/ca11572f7146b21e0bde6a9ed4bb6a89eafbee5f0944c7eb54d0d8a2dac962c33638a1d611e14faa71dfbb92b4b5f9236232208568a6b7d5c6f3f39ddb91771e + languageName: node + linkType: hard + "@babel/template@npm:^7.28.6": version: 7.28.6 resolution: "@babel/template@npm:7.28.6" @@ -381,6 +388,239 @@ __metadata: languageName: node linkType: hard +"@changesets/apply-release-plan@npm:^7.1.1": + version: 7.1.1 + resolution: "@changesets/apply-release-plan@npm:7.1.1" + dependencies: + "@changesets/config": "npm:^3.1.4" + "@changesets/get-version-range-type": "npm:^0.4.0" + "@changesets/git": "npm:^3.0.4" + "@changesets/should-skip-package": "npm:^0.1.2" + "@changesets/types": "npm:^6.1.0" + "@manypkg/get-packages": "npm:^1.1.3" + detect-indent: "npm:^6.0.0" + fs-extra: "npm:^7.0.1" + lodash.startcase: "npm:^4.4.0" + outdent: "npm:^0.5.0" + prettier: "npm:^2.7.1" + resolve-from: "npm:^5.0.0" + semver: "npm:^7.5.3" + checksum: 10c0/27de184e74e8e48b43fca1f73e7c7a2887b0cdacfe7ba9c09cdc4547dff0de1587bed5fe2d5ec0a3754fa422f6b8a528e0ac452c22ac7a6ae5211f5ac089bfb2 + languageName: node + linkType: hard + +"@changesets/assemble-release-plan@npm:^6.0.10": + version: 6.0.10 + resolution: "@changesets/assemble-release-plan@npm:6.0.10" + dependencies: + "@changesets/errors": "npm:^0.2.0" + "@changesets/get-dependents-graph": "npm:^2.1.4" + "@changesets/should-skip-package": "npm:^0.1.2" + "@changesets/types": "npm:^6.1.0" + "@manypkg/get-packages": "npm:^1.1.3" + semver: "npm:^7.5.3" + checksum: 10c0/a0ea336a5f19f8d0a97b684983bcd9c3bb8d6881b7b6abd5b482b301795ae4600924c188982f5f98dc48ac88e94a063b66ab72659041eb2623ade3e35f05d555 + languageName: node + linkType: hard + +"@changesets/changelog-git@npm:^0.2.1": + version: 0.2.1 + resolution: "@changesets/changelog-git@npm:0.2.1" + dependencies: + "@changesets/types": "npm:^6.1.0" + checksum: 10c0/6a6fb315ffb2266fcb8f32ae9a60ccdb5436e52350a2f53beacf9822d3355f9052aba5001a718e12af472b4a8fabd69b408d0b11c02ac909ba7a183d27a9f7fd + languageName: node + linkType: hard + +"@changesets/cli@npm:^2.31.0": + version: 2.31.0 + resolution: "@changesets/cli@npm:2.31.0" + dependencies: + "@changesets/apply-release-plan": "npm:^7.1.1" + "@changesets/assemble-release-plan": "npm:^6.0.10" + "@changesets/changelog-git": "npm:^0.2.1" + "@changesets/config": "npm:^3.1.4" + "@changesets/errors": "npm:^0.2.0" + "@changesets/get-dependents-graph": "npm:^2.1.4" + "@changesets/get-release-plan": "npm:^4.0.16" + "@changesets/git": "npm:^3.0.4" + "@changesets/logger": "npm:^0.1.1" + "@changesets/pre": "npm:^2.0.2" + "@changesets/read": "npm:^0.6.7" + "@changesets/should-skip-package": "npm:^0.1.2" + "@changesets/types": "npm:^6.1.0" + "@changesets/write": "npm:^0.4.0" + "@inquirer/external-editor": "npm:^1.0.2" + "@manypkg/get-packages": "npm:^1.1.3" + ansi-colors: "npm:^4.1.3" + enquirer: "npm:^2.4.1" + fs-extra: "npm:^7.0.1" + mri: "npm:^1.2.0" + package-manager-detector: "npm:^0.2.0" + picocolors: "npm:^1.1.0" + resolve-from: "npm:^5.0.0" + semver: "npm:^7.5.3" + spawndamnit: "npm:^3.0.1" + term-size: "npm:^2.1.0" + bin: + changeset: bin.js + checksum: 10c0/3b15f4f5fc7ccaa0b82ca4f9803977ed141b6bed66f83cf8004c2f4ab8e3a00c3a813569b76e4c757d0a8ca5e778bcb6df6e4df91be6c98e0dfaa2cff87c9434 + languageName: node + linkType: hard + +"@changesets/config@npm:^3.1.4": + version: 3.1.4 + resolution: "@changesets/config@npm:3.1.4" + dependencies: + "@changesets/errors": "npm:^0.2.0" + "@changesets/get-dependents-graph": "npm:^2.1.4" + "@changesets/logger": "npm:^0.1.1" + "@changesets/should-skip-package": "npm:^0.1.2" + "@changesets/types": "npm:^6.1.0" + "@manypkg/get-packages": "npm:^1.1.3" + fs-extra: "npm:^7.0.1" + micromatch: "npm:^4.0.8" + checksum: 10c0/1c0e7975aa719e2c87dfda3f5a1eb81b9f4852cdfb5b5c9d181fa2f8f485e92370b3bdfdb6f666432207dd75a3f79fa8fffe7847d48fb11308acb5ecf327bc12 + languageName: node + linkType: hard + +"@changesets/errors@npm:^0.2.0": + version: 0.2.0 + resolution: "@changesets/errors@npm:0.2.0" + dependencies: + extendable-error: "npm:^0.1.5" + checksum: 10c0/f2757c752ab04e9733b0dfd7903f1caf873f9e603794c4d9ea2294af4f937c73d07273c24be864ad0c30b6a98424360d5b96a6eab14f97f3cf2cbfd3763b95c1 + languageName: node + linkType: hard + +"@changesets/get-dependents-graph@npm:^2.1.4": + version: 2.1.4 + resolution: "@changesets/get-dependents-graph@npm:2.1.4" + dependencies: + "@changesets/types": "npm:^6.1.0" + "@manypkg/get-packages": "npm:^1.1.3" + picocolors: "npm:^1.1.0" + semver: "npm:^7.5.3" + checksum: 10c0/37b12ba42f16c458d0b574bcafa0247ff2b9a218686a64c86fc75bccc9ba3982f9c27206542941cf3a0563d9b199f40a830682b45e9fd902536de91344cbd0a2 + languageName: node + linkType: hard + +"@changesets/get-release-plan@npm:^4.0.16": + version: 4.0.16 + resolution: "@changesets/get-release-plan@npm:4.0.16" + dependencies: + "@changesets/assemble-release-plan": "npm:^6.0.10" + "@changesets/config": "npm:^3.1.4" + "@changesets/pre": "npm:^2.0.2" + "@changesets/read": "npm:^0.6.7" + "@changesets/types": "npm:^6.1.0" + "@manypkg/get-packages": "npm:^1.1.3" + checksum: 10c0/4be4553e13fe331f6d5b2ed98fece21c8d2b38c04a0543f726a0398b7538ef8fd073d712c35ae4540ed4fc6f84f08de6335318bc09dd562b189fb6968d049e95 + languageName: node + linkType: hard + +"@changesets/get-version-range-type@npm:^0.4.0": + version: 0.4.0 + resolution: "@changesets/get-version-range-type@npm:0.4.0" + checksum: 10c0/e466208c8383489a383f37958d8b5b9aed38539f9287b47fe155a2e8855973f6960fb1724a1ee33b11580d65e1011059045ee654e8ef51e4783017d8989c9d3f + languageName: node + linkType: hard + +"@changesets/git@npm:^3.0.4": + version: 3.0.4 + resolution: "@changesets/git@npm:3.0.4" + dependencies: + "@changesets/errors": "npm:^0.2.0" + "@manypkg/get-packages": "npm:^1.1.3" + is-subdir: "npm:^1.1.1" + micromatch: "npm:^4.0.8" + spawndamnit: "npm:^3.0.1" + checksum: 10c0/4abbdc1dec6ddc50b6ad927d9eba4f23acd775fdff615415813099befb0cecd1b0f56ceea5e18a5a3cbbb919d68179366074b02a954fbf4016501e5fd125d2b5 + languageName: node + linkType: hard + +"@changesets/logger@npm:^0.1.1": + version: 0.1.1 + resolution: "@changesets/logger@npm:0.1.1" + dependencies: + picocolors: "npm:^1.1.0" + checksum: 10c0/a0933b5bd4d99e10730b22612dc1bdfd25b8804c5b48f8cada050bf5c7a89b2ae9a61687f846a5e9e5d379a95b59fef795c8d5d91e49a251f8da2be76133f83f + languageName: node + linkType: hard + +"@changesets/parse@npm:^0.4.3": + version: 0.4.3 + resolution: "@changesets/parse@npm:0.4.3" + dependencies: + "@changesets/types": "npm:^6.1.0" + js-yaml: "npm:^4.1.1" + checksum: 10c0/4d8488eaf224974ae335fec964dc1dc486abcfa9f96856cf4267c2765b02ed6af1778375ec03d38252ebab9e191aa4a11c5f37a6ad42e907e08290fed2b9690c + languageName: node + linkType: hard + +"@changesets/pre@npm:^2.0.2": + version: 2.0.2 + resolution: "@changesets/pre@npm:2.0.2" + dependencies: + "@changesets/errors": "npm:^0.2.0" + "@changesets/types": "npm:^6.1.0" + "@manypkg/get-packages": "npm:^1.1.3" + fs-extra: "npm:^7.0.1" + checksum: 10c0/0af9396d84c47a88d79b757e9db4e3579b6620260f92c243b8349e7fcefca3c2652583f6d215c13115bed5d5cdc30c975f307fd6acbb89d205b1ba2ae403b918 + languageName: node + linkType: hard + +"@changesets/read@npm:^0.6.7": + version: 0.6.7 + resolution: "@changesets/read@npm:0.6.7" + dependencies: + "@changesets/git": "npm:^3.0.4" + "@changesets/logger": "npm:^0.1.1" + "@changesets/parse": "npm:^0.4.3" + "@changesets/types": "npm:^6.1.0" + fs-extra: "npm:^7.0.1" + p-filter: "npm:^2.1.0" + picocolors: "npm:^1.1.0" + checksum: 10c0/eebda5f5cea8684b9cb470e74cd5e67043a62ca54452ac88bb1a998bebeee1a2e3a642dc76818155a145863551c65f10f9c4ff85378b0419179fc60049edbbc6 + languageName: node + linkType: hard + +"@changesets/should-skip-package@npm:^0.1.2": + version: 0.1.2 + resolution: "@changesets/should-skip-package@npm:0.1.2" + dependencies: + "@changesets/types": "npm:^6.1.0" + "@manypkg/get-packages": "npm:^1.1.3" + checksum: 10c0/484e339e7d6e6950e12bff4eda6e8eccb077c0fbb1f09dd95d2ae948b715226a838c71eaf50cd2d7e0e631ce3bfb1ca93ac752436e6feae5b87aece2e917b440 + languageName: node + linkType: hard + +"@changesets/types@npm:^4.0.1": + version: 4.1.0 + resolution: "@changesets/types@npm:4.1.0" + checksum: 10c0/a372ad21f6a1e0d4ce6c19573c1ca269eef1ad53c26751ad9515a24f003e7c49dcd859dbb1fedb6badaf7be956c1559e8798304039e0ec0da2d9a68583f13464 + languageName: node + linkType: hard + +"@changesets/types@npm:^6.1.0": + version: 6.1.0 + resolution: "@changesets/types@npm:6.1.0" + checksum: 10c0/b4cea3a4465d1eaf0bbd7be1e404aca5a055a61d4cc72aadcb73bbbda1670b4022736b8d3052616cbf1f451afa0637545d077697f4b923236539af9cd5abce6c + languageName: node + linkType: hard + +"@changesets/write@npm:^0.4.0": + version: 0.4.0 + resolution: "@changesets/write@npm:0.4.0" + dependencies: + "@changesets/types": "npm:^6.1.0" + fs-extra: "npm:^7.0.1" + human-id: "npm:^4.1.1" + prettier: "npm:^2.7.1" + checksum: 10c0/311f4d0e536d1b5f2d3f9053537d62b2d4cdbd51e1d2767807ac9d1e0f380367f915d2ad370e5c73902d5a54bffd282d53fff5418c8ad31df51751d652bea826 + languageName: node + linkType: hard + "@emnapi/core@npm:^1.4.3": version: 1.10.0 resolution: "@emnapi/core@npm:1.10.0" @@ -696,6 +936,21 @@ __metadata: languageName: node linkType: hard +"@inquirer/external-editor@npm:^1.0.2": + version: 1.0.3 + resolution: "@inquirer/external-editor@npm:1.0.3" + dependencies: + chardet: "npm:^2.1.1" + iconv-lite: "npm:^0.7.0" + peerDependencies: + "@types/node": ">=18" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: 10c0/82951cb7f3762dd78cca2ea291396841e3f4adfe26004b5badfed1cec4b6a04bb567dff94d0e41b35c61bdd7957317c64c22f58074d14b238d44e44d9e420019 + languageName: node + linkType: hard + "@isaacs/cliui@npm:^8.0.2": version: 8.0.2 resolution: "@isaacs/cliui@npm:8.0.2" @@ -1131,6 +1386,32 @@ __metadata: languageName: node linkType: hard +"@manypkg/find-root@npm:^1.1.0": + version: 1.1.0 + resolution: "@manypkg/find-root@npm:1.1.0" + dependencies: + "@babel/runtime": "npm:^7.5.5" + "@types/node": "npm:^12.7.1" + find-up: "npm:^4.1.0" + fs-extra: "npm:^8.1.0" + checksum: 10c0/0ee907698e6c73d6f1821ff630f3fec6dcf38260817c8752fec8991ac38b95ba431ab11c2773ddf9beb33d0e057f1122b00e8ffc9b8411b3fd24151413626fa6 + languageName: node + linkType: hard + +"@manypkg/get-packages@npm:^1.1.3": + version: 1.1.3 + resolution: "@manypkg/get-packages@npm:1.1.3" + dependencies: + "@babel/runtime": "npm:^7.5.5" + "@changesets/types": "npm:^4.0.1" + "@manypkg/find-root": "npm:^1.1.0" + fs-extra: "npm:^8.1.0" + globby: "npm:^11.0.0" + read-yaml-file: "npm:^1.1.0" + checksum: 10c0/f05907d1174ae28861eaa06d0efdc144f773d9a4b8b65e1e7cdc01eb93361d335351b4a336e05c6aac02661be39e8809a3f7ad28bc67b6b338071434ab442130 + languageName: node + linkType: hard + "@napi-rs/wasm-runtime@npm:^0.2.11": version: 0.2.12 resolution: "@napi-rs/wasm-runtime@npm:0.2.12" @@ -1142,6 +1423,33 @@ __metadata: languageName: node linkType: hard +"@nodelib/fs.scandir@npm:2.1.5": + version: 2.1.5 + resolution: "@nodelib/fs.scandir@npm:2.1.5" + dependencies: + "@nodelib/fs.stat": "npm:2.0.5" + run-parallel: "npm:^1.1.9" + checksum: 10c0/732c3b6d1b1e967440e65f284bd06e5821fedf10a1bea9ed2bb75956ea1f30e08c44d3def9d6a230666574edbaf136f8cfd319c14fd1f87c66e6a44449afb2eb + languageName: node + linkType: hard + +"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": + version: 2.0.5 + resolution: "@nodelib/fs.stat@npm:2.0.5" + checksum: 10c0/88dafe5e3e29a388b07264680dc996c17f4bda48d163a9d4f5c1112979f0ce8ec72aa7116122c350b4e7976bc5566dc3ddb579be1ceaacc727872eb4ed93926d + languageName: node + linkType: hard + +"@nodelib/fs.walk@npm:^1.2.3": + version: 1.2.8 + resolution: "@nodelib/fs.walk@npm:1.2.8" + dependencies: + "@nodelib/fs.scandir": "npm:2.1.5" + fastq: "npm:^1.6.0" + checksum: 10c0/db9de047c3bb9b51f9335a7bb46f4fcfb6829fb628318c12115fbaf7d369bfce71c15b103d1fc3b464812d936220ee9bc1c8f762d032c9f6be9acc99249095b1 + languageName: node + linkType: hard + "@pkgjs/parseargs@npm:^0.11.0": version: 0.11.0 resolution: "@pkgjs/parseargs@npm:0.11.0" @@ -1608,6 +1916,13 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:^12.7.1": + version: 12.20.55 + resolution: "@types/node@npm:12.20.55" + checksum: 10c0/3b190bb0410047d489c49bbaab592d2e6630de6a50f00ba3d7d513d59401d279972a8f5a598b5bb8ddc1702f8a2f4ec57a65d93852f9c329639738e7053637d1 + languageName: node + linkType: hard + "@types/node@npm:^25.9.1": version: 25.9.1 resolution: "@types/node@npm:25.9.1" @@ -1961,6 +2276,13 @@ __metadata: languageName: node linkType: hard +"ansi-colors@npm:^4.1.1, ansi-colors@npm:^4.1.3": + version: 4.1.3 + resolution: "ansi-colors@npm:4.1.3" + checksum: 10c0/ec87a2f59902f74e61eada7f6e6fe20094a628dab765cfdbd03c3477599368768cffccdb5d3bb19a1b6c99126783a143b1fee31aab729b31ffe5836c7e5e28b9 + languageName: node + linkType: hard + "ansi-escapes@npm:^4.3.2": version: 4.3.2 resolution: "ansi-escapes@npm:4.3.2" @@ -2026,6 +2348,20 @@ __metadata: languageName: node linkType: hard +"argparse@npm:^2.0.1": + version: 2.0.1 + resolution: "argparse@npm:2.0.1" + checksum: 10c0/c5640c2d89045371c7cedd6a70212a04e360fd34d6edeae32f6952c63949e3525ea77dbec0289d8213a99bbaeab5abfa860b5c12cf88a2e6cf8106e90dd27a7e + languageName: node + linkType: hard + +"array-union@npm:^2.1.0": + version: 2.1.0 + resolution: "array-union@npm:2.1.0" + checksum: 10c0/429897e68110374f39b771ec47a7161fc6a8fc33e196857c0a396dc75df0b5f65e4d046674db764330b6bb66b39ef48dd7c53b6a2ee75cfb0681e0c1a7033962 + languageName: node + linkType: hard + "babel-jest@npm:30.4.1": version: 30.4.1 resolution: "babel-jest@npm:30.4.1" @@ -2125,6 +2461,15 @@ __metadata: languageName: node linkType: hard +"better-path-resolve@npm:1.0.0": + version: 1.0.0 + resolution: "better-path-resolve@npm:1.0.0" + dependencies: + is-windows: "npm:^1.0.0" + checksum: 10c0/7335130729d59a14b8e4753fea180ca84e287cccc20cb5f2438a95667abc5810327c414eee7b3c79ed1b5a348a40284ea872958f50caba69432c40405eb0acce + languageName: node + linkType: hard + "brace-expansion@npm:^1.1.7": version: 1.1.14 resolution: "brace-expansion@npm:1.1.14" @@ -2153,6 +2498,15 @@ __metadata: languageName: node linkType: hard +"braces@npm:^3.0.3": + version: 3.0.3 + resolution: "braces@npm:3.0.3" + dependencies: + fill-range: "npm:^7.1.1" + checksum: 10c0/7c6dfd30c338d2997ba77500539227b9d1f85e388a5f43220865201e407e076783d0881f2d297b9f80951b4c957fcf0b51c1d2d24227631643c3f7c284b0aa04 + languageName: node + linkType: hard + "browserslist@npm:^4.24.0": version: 4.28.2 resolution: "browserslist@npm:4.28.2" @@ -2238,6 +2592,13 @@ __metadata: languageName: node linkType: hard +"chardet@npm:^2.1.1": + version: 2.1.1 + resolution: "chardet@npm:2.1.1" + checksum: 10c0/d8391dd412338442b3de0d3a488aa9327f8bcf74b62b8723d6bd0b85c4084d50b731320e0a7c710edb1d44de75969995d2784b80e4c13b004a6c7a0db4c6e793 + languageName: node + linkType: hard + "chownr@npm:^3.0.0": version: 3.0.0 resolution: "chownr@npm:3.0.0" @@ -2335,7 +2696,7 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6": +"cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.5, cross-spawn@npm:^7.0.6": version: 7.0.6 resolution: "cross-spawn@npm:7.0.6" dependencies: @@ -2384,6 +2745,13 @@ __metadata: languageName: node linkType: hard +"detect-indent@npm:^6.0.0": + version: 6.1.0 + resolution: "detect-indent@npm:6.1.0" + checksum: 10c0/dd83cdeda9af219cf77f5e9a0dc31d828c045337386cfb55ce04fad94ba872ee7957336834154f7647b89b899c3c7acc977c57a79b7c776b506240993f97acc7 + languageName: node + linkType: hard + "detect-newline@npm:^3.1.0": version: 3.1.0 resolution: "detect-newline@npm:3.1.0" @@ -2391,6 +2759,15 @@ __metadata: languageName: node linkType: hard +"dir-glob@npm:^3.0.1": + version: 3.0.1 + resolution: "dir-glob@npm:3.0.1" + dependencies: + path-type: "npm:^4.0.0" + checksum: 10c0/dcac00920a4d503e38bb64001acb19df4efc14536ada475725e12f52c16777afdee4db827f55f13a908ee7efc0cb282e2e3dbaeeb98c0993dd93d1802d3bf00c + languageName: node + linkType: hard + "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -2426,6 +2803,16 @@ __metadata: languageName: node linkType: hard +"enquirer@npm:^2.4.1": + version: 2.4.1 + resolution: "enquirer@npm:2.4.1" + dependencies: + ansi-colors: "npm:^4.1.1" + strip-ansi: "npm:^6.0.1" + checksum: 10c0/43850479d7a51d36a9c924b518dcdc6373b5a8ae3401097d336b7b7e258324749d0ad37a1fcaa5706f04799baa05585cd7af19ebdf7667673e7694435fcea918 + languageName: node + linkType: hard + "env-paths@npm:^2.2.0": version: 2.2.1 resolution: "env-paths@npm:2.2.1" @@ -2760,6 +3147,13 @@ __metadata: languageName: node linkType: hard +"extendable-error@npm:^0.1.5": + version: 0.1.7 + resolution: "extendable-error@npm:0.1.7" + checksum: 10c0/c46648b7682448428f81b157cbfe480170fd96359c55db477a839ddeaa34905a18cba0b989bafe5e83f93c2491a3fcc7cc536063ea326ba9d72e9c6e2fe736a7 + languageName: node + linkType: hard + "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -2767,6 +3161,19 @@ __metadata: languageName: node linkType: hard +"fast-glob@npm:^3.2.9": + version: 3.3.3 + resolution: "fast-glob@npm:3.3.3" + dependencies: + "@nodelib/fs.stat": "npm:^2.0.2" + "@nodelib/fs.walk": "npm:^1.2.3" + glob-parent: "npm:^5.1.2" + merge2: "npm:^1.3.0" + micromatch: "npm:^4.0.8" + checksum: 10c0/f6aaa141d0d3384cf73cbcdfc52f475ed293f6d5b65bfc5def368b09163a9f7e5ec2b3014d80f733c405f58e470ee0cc451c2937685045cddcdeaa24199c43fe + languageName: node + linkType: hard + "fast-json-stable-stringify@npm:2.x, fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0": version: 2.1.0 resolution: "fast-json-stable-stringify@npm:2.1.0" @@ -2781,6 +3188,15 @@ __metadata: languageName: node linkType: hard +"fastq@npm:^1.6.0": + version: 1.20.1 + resolution: "fastq@npm:1.20.1" + dependencies: + reusify: "npm:^1.0.4" + checksum: 10c0/e5dd725884decb1f11e5c822221d76136f239d0236f176fab80b7b8f9e7619ae57e6b4e5b73defc21e6b9ef99437ee7b545cff8e6c2c337819633712fa9d352e + languageName: node + linkType: hard + "fb-watchman@npm:^2.0.2": version: 2.0.2 resolution: "fb-watchman@npm:2.0.2" @@ -2811,6 +3227,15 @@ __metadata: languageName: node linkType: hard +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" + dependencies: + to-regex-range: "npm:^5.0.1" + checksum: 10c0/b75b691bbe065472f38824f694c2f7449d7f5004aa950426a2c28f0306c60db9b880c0b0e4ed819997ffb882d1da02cfcfc819bddc94d71627f5269682edf018 + languageName: node + linkType: hard + "find-up@npm:^4.0.0, find-up@npm:^4.1.0": version: 4.1.0 resolution: "find-up@npm:4.1.0" @@ -2858,6 +3283,28 @@ __metadata: languageName: node linkType: hard +"fs-extra@npm:^7.0.1": + version: 7.0.1 + resolution: "fs-extra@npm:7.0.1" + dependencies: + graceful-fs: "npm:^4.1.2" + jsonfile: "npm:^4.0.0" + universalify: "npm:^0.1.0" + checksum: 10c0/1943bb2150007e3739921b8d13d4109abdc3cc481e53b97b7ea7f77eda1c3c642e27ae49eac3af074e3496ea02fde30f411ef410c760c70a38b92e656e5da784 + languageName: node + linkType: hard + +"fs-extra@npm:^8.1.0": + version: 8.1.0 + resolution: "fs-extra@npm:8.1.0" + dependencies: + graceful-fs: "npm:^4.2.0" + jsonfile: "npm:^4.0.0" + universalify: "npm:^0.1.0" + checksum: 10c0/259f7b814d9e50d686899550c4f9ded85c46c643f7fe19be69504888e007fcbc08f306fae8ec495b8b998635e997c9e3e175ff2eeed230524ef1c1684cc96423 + languageName: node + linkType: hard + "fs.realpath@npm:^1.0.0": version: 1.0.0 resolution: "fs.realpath@npm:1.0.0" @@ -2919,6 +3366,15 @@ __metadata: languageName: node linkType: hard +"glob-parent@npm:^5.1.2": + version: 5.1.2 + resolution: "glob-parent@npm:5.1.2" + dependencies: + is-glob: "npm:^4.0.1" + checksum: 10c0/cab87638e2112bee3f839ef5f6e0765057163d39c66be8ec1602f3823da4692297ad4e972de876ea17c44d652978638d2fd583c6713d0eb6591706825020c9ee + languageName: node + linkType: hard + "glob-parent@npm:^6.0.2": version: 6.0.2 resolution: "glob-parent@npm:6.0.2" @@ -2958,7 +3414,21 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": +"globby@npm:^11.0.0": + version: 11.1.0 + resolution: "globby@npm:11.1.0" + dependencies: + array-union: "npm:^2.1.0" + dir-glob: "npm:^3.0.1" + fast-glob: "npm:^3.2.9" + ignore: "npm:^5.2.0" + merge2: "npm:^1.4.1" + slash: "npm:^3.0.0" + checksum: 10c0/b39511b4afe4bd8a7aead3a27c4ade2b9968649abab0a6c28b1a90141b96ca68ca5db1302f7c7bd29eab66bf51e13916b8e0a3d0ac08f75e1e84a39b35691189 + languageName: node + linkType: hard + +"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.5, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": version: 4.2.11 resolution: "graceful-fs@npm:4.2.11" checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 @@ -3006,6 +3476,15 @@ __metadata: languageName: node linkType: hard +"human-id@npm:^4.1.1": + version: 4.2.0 + resolution: "human-id@npm:4.2.0" + bin: + human-id: dist/cli.js + checksum: 10c0/80071f3b785b2e91080b5f9aa2d079c2e9a464e009ea12c035255b61d1b70beefe7eda42209dff9c1bb9a9fa58e50ada38c1b314ba3a23266a72cd5e9a453e1f + languageName: node + linkType: hard + "human-signals@npm:^2.1.0": version: 2.1.0 resolution: "human-signals@npm:2.1.0" @@ -3013,6 +3492,15 @@ __metadata: languageName: node linkType: hard +"iconv-lite@npm:^0.7.0": + version: 0.7.2 + resolution: "iconv-lite@npm:0.7.2" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 10c0/3c228920f3bd307f56bf8363706a776f4a060eb042f131cd23855ceca962951b264d0997ab38a1ad340e1c5df8499ed26e1f4f0db6b2a2ad9befaff22f14b722 + languageName: node + linkType: hard + "ignore@npm:^5.2.0": version: 5.3.2 resolution: "ignore@npm:5.3.2" @@ -3100,7 +3588,7 @@ __metadata: languageName: node linkType: hard -"is-glob@npm:^4.0.0, is-glob@npm:^4.0.3": +"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3": version: 4.0.3 resolution: "is-glob@npm:4.0.3" dependencies: @@ -3116,6 +3604,13 @@ __metadata: languageName: node linkType: hard +"is-number@npm:^7.0.0": + version: 7.0.0 + resolution: "is-number@npm:7.0.0" + checksum: 10c0/b4686d0d3053146095ccd45346461bc8e53b80aeb7671cc52a4de02dbbf7dc0d1d2a986e2fe4ae206984b4d34ef37e8b795ebc4f4295c978373e6575e295d811 + languageName: node + linkType: hard + "is-stream@npm:^2.0.0": version: 2.0.1 resolution: "is-stream@npm:2.0.1" @@ -3123,6 +3618,22 @@ __metadata: languageName: node linkType: hard +"is-subdir@npm:^1.1.1": + version: 1.2.0 + resolution: "is-subdir@npm:1.2.0" + dependencies: + better-path-resolve: "npm:1.0.0" + checksum: 10c0/03a03ee2ee6578ce589b1cfaf00e65c86b20fd1b82c1660625557c535439a7477cda77e20c62cda6d4c99e7fd908b4619355ae2d989f4a524a35350a44353032 + languageName: node + linkType: hard + +"is-windows@npm:^1.0.0": + version: 1.0.2 + resolution: "is-windows@npm:1.0.2" + checksum: 10c0/b32f418ab3385604a66f1b7a3ce39d25e8881dee0bd30816dc8344ef6ff9df473a732bcc1ec4e84fe99b2f229ae474f7133e8e93f9241686cfcf7eebe53ba7a5 + languageName: node + linkType: hard + "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" @@ -3734,7 +4245,7 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:^3.13.1": +"js-yaml@npm:^3.13.1, js-yaml@npm:^3.6.1": version: 3.14.2 resolution: "js-yaml@npm:3.14.2" dependencies: @@ -3746,6 +4257,17 @@ __metadata: languageName: node linkType: hard +"js-yaml@npm:^4.1.1": + version: 4.2.0 + resolution: "js-yaml@npm:4.2.0" + dependencies: + argparse: "npm:^2.0.1" + bin: + js-yaml: bin/js-yaml.js + checksum: 10c0/1916456c118746603b067d74bbcbb0445d9a1d5e474ad4ae775e7b20525bed902e01d9d97dd0c81fcd8d4f596162309d0eb057f4aa38f3e9647f14075e9dea45 + languageName: node + linkType: hard + "jsesc@npm:^3.0.2": version: 3.1.0 resolution: "jsesc@npm:3.1.0" @@ -3792,6 +4314,18 @@ __metadata: languageName: node linkType: hard +"jsonfile@npm:^4.0.0": + version: 4.0.0 + resolution: "jsonfile@npm:4.0.0" + dependencies: + graceful-fs: "npm:^4.1.6" + dependenciesMeta: + graceful-fs: + optional: true + checksum: 10c0/7dc94b628d57a66b71fb1b79510d460d662eb975b5f876d723f81549c2e9cd316d58a2ddf742b2b93a4fa6b17b2accaf1a738a0e2ea114bdfb13a32e5377e480 + languageName: node + linkType: hard + "keyv@npm:^4.5.4": version: 4.5.4 resolution: "keyv@npm:4.5.4" @@ -3850,6 +4384,13 @@ __metadata: languageName: node linkType: hard +"lodash.startcase@npm:^4.4.0": + version: 4.4.0 + resolution: "lodash.startcase@npm:4.4.0" + checksum: 10c0/bd82aa87a45de8080e1c5ee61128c7aee77bf7f1d86f4ff94f4a6d7438fc9e15e5f03374b947be577a93804c8ad6241f0251beaf1452bf716064eeb657b3a9f0 + languageName: node + linkType: hard + "lru-cache@npm:^10.2.0": version: 10.4.3 resolution: "lru-cache@npm:10.4.3" @@ -3898,6 +4439,23 @@ __metadata: languageName: node linkType: hard +"merge2@npm:^1.3.0, merge2@npm:^1.4.1": + version: 1.4.1 + resolution: "merge2@npm:1.4.1" + checksum: 10c0/254a8a4605b58f450308fc474c82ac9a094848081bf4c06778200207820e5193726dc563a0d2c16468810516a5c97d9d3ea0ca6585d23c58ccfff2403e8dbbeb + languageName: node + linkType: hard + +"micromatch@npm:^4.0.8": + version: 4.0.8 + resolution: "micromatch@npm:4.0.8" + dependencies: + braces: "npm:^3.0.3" + picomatch: "npm:^2.3.1" + checksum: 10c0/166fa6eb926b9553f32ef81f5f531d27b4ce7da60e5baf8c021d043b27a388fb95e46a8038d5045877881e673f8134122b59624d5cecbd16eb50a42e7a6b5ca8 + languageName: node + linkType: hard + "mimic-fn@npm:^2.1.0": version: 2.1.0 resolution: "mimic-fn@npm:2.1.0" @@ -3955,6 +4513,13 @@ __metadata: languageName: node linkType: hard +"mri@npm:^1.2.0": + version: 1.2.0 + resolution: "mri@npm:1.2.0" + checksum: 10c0/a3d32379c2554cf7351db6237ddc18dc9e54e4214953f3da105b97dc3babe0deb3ffe99cf409b38ea47cc29f9430561ba6b53b24ab8f9ce97a4b50409e4a50e7 + languageName: node + linkType: hard + "ms@npm:^2.1.3": version: 2.1.3 resolution: "ms@npm:2.1.3" @@ -4078,6 +4643,22 @@ __metadata: languageName: node linkType: hard +"outdent@npm:^0.5.0": + version: 0.5.0 + resolution: "outdent@npm:0.5.0" + checksum: 10c0/e216a4498889ba1babae06af84cdc4091f7cac86da49d22d0163b3be202a5f52efcd2bcd3dfca60a361eb3a27b4299f185c5655061b6b402552d7fcd1d040cff + languageName: node + linkType: hard + +"p-filter@npm:^2.1.0": + version: 2.1.0 + resolution: "p-filter@npm:2.1.0" + dependencies: + p-map: "npm:^2.0.0" + checksum: 10c0/5ac34b74b3b691c04212d5dd2319ed484f591c557a850a3ffc93a08cb38c4f5540be059c6b10a185773c479ca583a91ea00c7d6c9958c815e6b74d052f356645 + languageName: node + linkType: hard + "p-limit@npm:^2.2.0": version: 2.3.0 resolution: "p-limit@npm:2.3.0" @@ -4114,6 +4695,13 @@ __metadata: languageName: node linkType: hard +"p-map@npm:^2.0.0": + version: 2.1.0 + resolution: "p-map@npm:2.1.0" + checksum: 10c0/735dae87badd4737a2dd582b6d8f93e49a1b79eabbc9815a4d63a528d5e3523e978e127a21d784cccb637010e32103a40d2aaa3ab23ae60250b1a820ca752043 + languageName: node + linkType: hard + "p-try@npm:^2.0.0": version: 2.2.0 resolution: "p-try@npm:2.2.0" @@ -4128,6 +4716,15 @@ __metadata: languageName: node linkType: hard +"package-manager-detector@npm:^0.2.0": + version: 0.2.11 + resolution: "package-manager-detector@npm:0.2.11" + dependencies: + quansync: "npm:^0.2.7" + checksum: 10c0/247991de461b9e731f3463b7dae9ce187e53095b7b94d7d96eec039abf418b61ccf74464bec1d0c11d97311f33472e77baccd4c5898f77358da4b5b33395e0b1 + languageName: node + linkType: hard + "parse-json@npm:^5.2.0": version: 5.2.0 resolution: "parse-json@npm:5.2.0" @@ -4178,14 +4775,21 @@ __metadata: languageName: node linkType: hard -"picocolors@npm:^1.1.1": +"path-type@npm:^4.0.0": + version: 4.0.0 + resolution: "path-type@npm:4.0.0" + checksum: 10c0/666f6973f332f27581371efaf303fd6c272cc43c2057b37aa99e3643158c7e4b2626549555d88626e99ea9e046f82f32e41bbde5f1508547e9a11b149b52387c + languageName: node + linkType: hard + +"picocolors@npm:^1.1.0, picocolors@npm:^1.1.1": version: 1.1.1 resolution: "picocolors@npm:1.1.1" checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58 languageName: node linkType: hard -"picomatch@npm:^2.0.4, picomatch@npm:^2.2.3": +"picomatch@npm:^2.0.4, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1": version: 2.3.2 resolution: "picomatch@npm:2.3.2" checksum: 10c0/a554d1709e59be97d1acb9eaedbbc700a5c03dbd4579807baed95100b00420bc729335440ef15004ae2378984e2487a7c1cebd743cfdb72b6fa9ab69223c0d61 @@ -4199,6 +4803,13 @@ __metadata: languageName: node linkType: hard +"pify@npm:^4.0.1": + version: 4.0.1 + resolution: "pify@npm:4.0.1" + checksum: 10c0/6f9d404b0d47a965437403c9b90eca8bb2536407f03de165940e62e72c8c8b75adda5516c6b9b23675a5877cc0bcac6bdfb0ef0e39414cd2476d5495da40e7cf + languageName: node + linkType: hard + "pirates@npm:^4.0.7": version: 4.0.7 resolution: "pirates@npm:4.0.7" @@ -4219,6 +4830,7 @@ __metadata: version: 0.0.0-use.local resolution: "plugins@workspace:." dependencies: + "@changesets/cli": "npm:^2.31.0" "@sourceacademy/conductor": "npm:^0.3.0" "@types/jest": "npm:^30.0.0" "@types/node": "npm:^25.9.1" @@ -4241,6 +4853,15 @@ __metadata: languageName: node linkType: hard +"prettier@npm:^2.7.1": + version: 2.8.8 + resolution: "prettier@npm:2.8.8" + bin: + prettier: bin-prettier.js + checksum: 10c0/463ea8f9a0946cd5b828d8cf27bd8b567345cf02f56562d5ecde198b91f47a76b7ac9eae0facd247ace70e927143af6135e8cf411986b8cb8478784a4d6d724a + languageName: node + linkType: hard + "prettier@npm:^3.8.1": version: 3.8.3 resolution: "prettier@npm:3.8.3" @@ -4294,6 +4915,20 @@ __metadata: languageName: node linkType: hard +"quansync@npm:^0.2.7": + version: 0.2.11 + resolution: "quansync@npm:0.2.11" + checksum: 10c0/cb9a1f8ebce074069f2f6a78578873ffedd9de9f6aa212039b44c0870955c04a71c3b1311b5d97f8ac2f2ec476de202d0a5c01160cb12bc0a11b7ef36d22ef56 + languageName: node + linkType: hard + +"queue-microtask@npm:^1.2.2": + version: 1.2.3 + resolution: "queue-microtask@npm:1.2.3" + checksum: 10c0/900a93d3cdae3acd7d16f642c29a642aea32c2026446151f0778c62ac089d4b8e6c986811076e1ae180a694cedf077d453a11b58ff0a865629a4f82ab558e102 + languageName: node + linkType: hard + "react-is-18@npm:react-is@^18.3.1, react-is@npm:^18.3.1": version: 18.3.1 resolution: "react-is@npm:18.3.1" @@ -4308,6 +4943,18 @@ __metadata: languageName: node linkType: hard +"read-yaml-file@npm:^1.1.0": + version: 1.1.0 + resolution: "read-yaml-file@npm:1.1.0" + dependencies: + graceful-fs: "npm:^4.1.5" + js-yaml: "npm:^3.6.1" + pify: "npm:^4.0.1" + strip-bom: "npm:^3.0.0" + checksum: 10c0/85a9ba08bb93f3c91089bab4f1603995ec7156ee595f8ce40ae9f49d841cbb586511508bd47b7cf78c97f678c679b2c6e2c0092e63f124214af41b6f8a25ca31 + languageName: node + linkType: hard + "require-directory@npm:^2.1.1": version: 2.1.1 resolution: "require-directory@npm:2.1.1" @@ -4359,6 +5006,13 @@ __metadata: languageName: node linkType: hard +"reusify@npm:^1.0.4": + version: 1.1.0 + resolution: "reusify@npm:1.1.0" + checksum: 10c0/4eff0d4a5f9383566c7d7ec437b671cc51b25963bd61bf127c3f3d3f68e44a026d99b8d2f1ad344afff8d278a8fe70a8ea092650a716d22287e8bef7126bb2fa + languageName: node + linkType: hard + "rollup@npm:^4.60.2": version: 4.60.4 resolution: "rollup@npm:4.60.4" @@ -4449,6 +5103,22 @@ __metadata: languageName: node linkType: hard +"run-parallel@npm:^1.1.9": + version: 1.2.0 + resolution: "run-parallel@npm:1.2.0" + dependencies: + queue-microtask: "npm:^1.2.2" + checksum: 10c0/200b5ab25b5b8b7113f9901bfe3afc347e19bb7475b267d55ad0eb86a62a46d77510cb0f232507c9e5d497ebda569a08a9867d0d14f57a82ad5564d991588b39 + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3.0.0": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: 10c0/7e3c8b2e88a1841c9671094bbaeebd94448111dd90a81a1f606f3f67708a6ec57763b3b47f06da09fc6054193e0e6709e77325415dc8422b04497a8070fa02d4 + languageName: node + linkType: hard + "semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" @@ -4554,6 +5224,16 @@ __metadata: languageName: node linkType: hard +"spawndamnit@npm:^3.0.1": + version: 3.0.1 + resolution: "spawndamnit@npm:3.0.1" + dependencies: + cross-spawn: "npm:^7.0.5" + signal-exit: "npm:^4.0.1" + checksum: 10c0/a9821a59bc78a665bd44718dea8f4f4010bb1a374972b0a6a1633b9186cda6d6fd93f22d1e49d9944d6bb175ba23ce29036a4bd624884fb157d981842c3682f3 + languageName: node + linkType: hard + "sprintf-js@npm:~1.0.2": version: 1.0.3 resolution: "sprintf-js@npm:1.0.3" @@ -4620,6 +5300,13 @@ __metadata: languageName: node linkType: hard +"strip-bom@npm:^3.0.0": + version: 3.0.0 + resolution: "strip-bom@npm:3.0.0" + checksum: 10c0/51201f50e021ef16672593d7434ca239441b7b760e905d9f33df6e4f3954ff54ec0e0a06f100d028af0982d6f25c35cd5cda2ce34eaebccd0250b8befb90d8f1 + languageName: node + linkType: hard + "strip-bom@npm:^4.0.0": version: 4.0.0 resolution: "strip-bom@npm:4.0.0" @@ -4688,6 +5375,13 @@ __metadata: languageName: node linkType: hard +"term-size@npm:^2.1.0": + version: 2.2.1 + resolution: "term-size@npm:2.2.1" + checksum: 10c0/89f6bba1d05d425156c0910982f9344d9e4aebf12d64bfa1f460d93c24baa7bc4c4a21d355fbd7153c316433df0538f64d0ae6e336cc4a69fdda4f85d62bc79d + languageName: node + linkType: hard + "terser@npm:^5.17.4": version: 5.46.2 resolution: "terser@npm:5.46.2" @@ -4730,6 +5424,15 @@ __metadata: languageName: node linkType: hard +"to-regex-range@npm:^5.0.1": + version: 5.0.1 + resolution: "to-regex-range@npm:5.0.1" + dependencies: + is-number: "npm:^7.0.0" + checksum: 10c0/487988b0a19c654ff3e1961b87f471702e708fa8a8dd02a298ef16da7206692e8552a0250e8b3e8759270f62e9d8314616f6da274734d3b558b1fc7b7724e892 + languageName: node + linkType: hard + "ts-api-utils@npm:^2.5.0": version: 2.5.0 resolution: "ts-api-utils@npm:2.5.0" @@ -4896,6 +5599,13 @@ __metadata: languageName: node linkType: hard +"universalify@npm:^0.1.0": + version: 0.1.2 + resolution: "universalify@npm:0.1.2" + checksum: 10c0/e70e0339f6b36f34c9816f6bf9662372bd241714dc77508d231d08386d94f2c4aa1ba1318614f92015f40d45aae1b9075cd30bd490efbe39387b60a76ca3f045 + languageName: node + linkType: hard + "unrs-resolver@npm:^1.7.11": version: 1.11.1 resolution: "unrs-resolver@npm:1.11.1" From 34b7a93bafdb13716f329aca802fedc102b4b1f7 Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Sat, 6 Jun 2026 23:51:51 +0800 Subject: [PATCH 13/16] fix: properly copy dist files --- .changeset/config.json | 2 +- lib/build.ts | 75 ++++++++++++++++++++++++++++++++++- src/common/test/manifest.json | 2 +- src/runner/test/tsconfig.json | 1 + src/web/test/tsconfig.json | 1 + 5 files changed, 77 insertions(+), 4 deletions(-) diff --git a/.changeset/config.json b/.changeset/config.json index 5c58ec9..66cb5aa 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -8,4 +8,4 @@ "baseBranch": "main", "updateInternalDependencies": "patch", "ignore": [] -} +} \ No newline at end of file diff --git a/lib/build.ts b/lib/build.ts index 4083916..dead7cd 100644 --- a/lib/build.ts +++ b/lib/build.ts @@ -4,21 +4,60 @@ import fs from "fs/promises"; import { spawn } from "child_process"; const program = new Command(); +interface Manifest { + type: "installable" | "external"; +} + +const globalManifest: Record> = {}; + +/** + * Generates the manifest files for each plugin and updates the changeset config to ignore non-installable plugins. + * The manifest files are generated by reading the manifest.json file in each plugin folder and writing it to the dist folder. + * The changeset config is updated to ignore non-installable plugins to prevent unnecessary version bumps and releases. + * @example + * await generateManifest(); + * This will generate the manifest files for each plugin and update the changeset config to ignore non-installable plugins. + */ export async function generateManifest() { + // Create dist directory if it doesn't exist await fs.mkdir("dist", { recursive: true }); + + // The ignore list is used to keep track of non-installable plugins, which should be ignored in changesets to prevent unnecessary version bumps and releases. + const ignoreList: string[] = []; + await Promise.all( packageJSON.workspaces.map(async workspace => { - const manifest: Record = {}; + const manifest: Record = {}; + // pluginType is either "web", "runner" or "common" const pluginType = workspace.split("/").slice(-3)[0]; for await (const file of fs.glob(`${workspace}manifest.json`)) { const manifestFile = JSON.parse(await fs.readFile(file, "utf-8")); + // folderName is the name of the plugin folder (generally the same as the plugin name) const folderName = file.split("/").slice(-2)[0]; - manifest[folderName] = manifestFile; + manifest[folderName] = manifestFile as Manifest; + if (manifestFile.type !== "installable") { + ignoreList.push(`@sourceacademy/${pluginType}-${folderName}`); + } } + globalManifest[pluginType] = manifest; await fs.writeFile(`dist/${pluginType}.json`, JSON.stringify(manifest, null, 2)); }), ); + + // Update changeset config to ignore non-installable plugins + const changesetConfig = await fs.readFile(".changeset/config.json", "utf-8"); + const changesetConfigJSON = JSON.parse(changesetConfig); + changesetConfigJSON.ignore = ignoreList; + await fs.writeFile(".changeset/config.json", JSON.stringify(changesetConfigJSON, null, 2)); } + +/** + * A helper function to spawn a child process and return a promise that resolves when the process exits with code 0, and rejects otherwise. + * @param args The arguments passed to spawn + * @returns A promise that resolves when the process exits with code 0, and rejects otherwise. + * @example + * await spawnPromise("yarn", ["build"]); + */ export async function spawnPromise(...args: Parameters) { return new Promise((resolve, reject) => { const child = spawn(...args); @@ -31,6 +70,37 @@ export async function spawnPromise(...args: Parameters) { }); }); } + +/** + * Copies the dist files from each "external" plugin (i.e. plugins that are bundles) to the dist folder. + * This is necessary because the dist files are not included in the workspace build process, and we need to copy them manually to the dist folder for them to be included in the final build output. + * @example + * await copyDistFiles(); + */ +export async function copyDistFiles() { + await Promise.all( + // Iterate over each plugin type (web, runner, common) + Object.entries(globalManifest).map(async ([pluginType, manifest]) => { + await Promise.all( + // Iterate over each plugin in the plugin type and copy the dist files if the plugin is of type "external" + Object.entries(manifest).map(async ([pluginName, pluginManifest]) => { + if (pluginManifest.type === "external") { + await fs.cp(`src/${pluginType}/${pluginName}/dist`, `dist/${pluginType}/${pluginName}/dist`, { recursive: true }); + } + }), + ); + }), + ); +} + +/** + * Builds the plugins by generating the manifest and running the build script for each plugin. + * The build script is run in topological order to ensure that dependencies are built before the plugins that depend on them. + * @param extraArgs Extra arguments to pass to the build script of each plugin. For example, if you want to run the build script in watch mode, you can pass ["--watch"] as extraArgs. + * @example + * await build(["--watch"]); + * This will run the build script of each plugin with the --watch flag, which is useful for development. + */ export async function build(extraArgs: string[] = []) { await Promise.all([ generateManifest(), @@ -42,6 +112,7 @@ export async function build(extraArgs: string[] = []) { }, ), ]); + await copyDistFiles(); } // TO-DO: Add more options diff --git a/src/common/test/manifest.json b/src/common/test/manifest.json index 06d21f0..e263f73 100644 --- a/src/common/test/manifest.json +++ b/src/common/test/manifest.json @@ -1,3 +1,3 @@ { - "type": "internal" + "type": "installable" } diff --git a/src/runner/test/tsconfig.json b/src/runner/test/tsconfig.json index ebd661f..88a8445 100644 --- a/src/runner/test/tsconfig.json +++ b/src/runner/test/tsconfig.json @@ -3,6 +3,7 @@ "exclude": ["./dist"], "include": ["./src"], "compilerOptions": { + "declaration": true, "outDir": "./dist", "rootDir": "./src", "types": ["jest"] diff --git a/src/web/test/tsconfig.json b/src/web/test/tsconfig.json index 101b674..471f5d3 100644 --- a/src/web/test/tsconfig.json +++ b/src/web/test/tsconfig.json @@ -3,6 +3,7 @@ "exclude": ["./dist"], "include": ["./src"], "compilerOptions": { + "declaration": true, "outDir": "./dist", "rootDir": "./src", "types": ["jest"] From 1da7e820e1e30c8e4711498e1705954a1e53d8dd Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Sat, 6 Jun 2026 23:53:35 +0800 Subject: [PATCH 14/16] chore: format files --- .changeset/config.json | 2 +- lib/build.ts | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.changeset/config.json b/.changeset/config.json index 66cb5aa..5c58ec9 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -8,4 +8,4 @@ "baseBranch": "main", "updateInternalDependencies": "patch", "ignore": [] -} \ No newline at end of file +} diff --git a/lib/build.ts b/lib/build.ts index dead7cd..f4d50ab 100644 --- a/lib/build.ts +++ b/lib/build.ts @@ -12,14 +12,14 @@ const globalManifest: Record> = {}; /** * Generates the manifest files for each plugin and updates the changeset config to ignore non-installable plugins. - * The manifest files are generated by reading the manifest.json file in each plugin folder and writing it to the dist folder. + * The manifest files are generated by reading the manifest.json file in each plugin folder and writing it to the dist folder. * The changeset config is updated to ignore non-installable plugins to prevent unnecessary version bumps and releases. * @example * await generateManifest(); * This will generate the manifest files for each plugin and update the changeset config to ignore non-installable plugins. */ export async function generateManifest() { - // Create dist directory if it doesn't exist + // Create dist directory if it doesn't exist await fs.mkdir("dist", { recursive: true }); // The ignore list is used to keep track of non-installable plugins, which should be ignored in changesets to prevent unnecessary version bumps and releases. @@ -85,7 +85,11 @@ export async function copyDistFiles() { // Iterate over each plugin in the plugin type and copy the dist files if the plugin is of type "external" Object.entries(manifest).map(async ([pluginName, pluginManifest]) => { if (pluginManifest.type === "external") { - await fs.cp(`src/${pluginType}/${pluginName}/dist`, `dist/${pluginType}/${pluginName}/dist`, { recursive: true }); + await fs.cp( + `src/${pluginType}/${pluginName}/dist`, + `dist/${pluginType}/${pluginName}/dist`, + { recursive: true }, + ); } }), ); @@ -94,7 +98,7 @@ export async function copyDistFiles() { } /** - * Builds the plugins by generating the manifest and running the build script for each plugin. + * Builds the plugins by generating the manifest and running the build script for each plugin. * The build script is run in topological order to ensure that dependencies are built before the plugins that depend on them. * @param extraArgs Extra arguments to pass to the build script of each plugin. For example, if you want to run the build script in watch mode, you can pass ["--watch"] as extraArgs. * @example From 7e9293f81f722e84a9100c618c5429b2d1e1bba0 Mon Sep 17 00:00:00 2001 From: Aarav Malani Date: Sat, 6 Jun 2026 23:56:42 +0800 Subject: [PATCH 15/16] chore: prettierignore the config file for changeset --- .changeset/config.json | 2 +- .prettierignore | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 .prettierignore diff --git a/.changeset/config.json b/.changeset/config.json index 5c58ec9..66cb5aa 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -8,4 +8,4 @@ "baseBranch": "main", "updateInternalDependencies": "patch", "ignore": [] -} +} \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..612f7df --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +.changeset/config.json \ No newline at end of file From 7e1bf5f4abb0641f60fb4b3d3e0516a24105c307 Mon Sep 17 00:00:00 2001 From: Shrey Jain <“shreyjain5132@email.com> Date: Wed, 10 Jun 2026 11:41:32 +0530 Subject: [PATCH 16/16] feat(stepper): add common-stepper and runner-stepper plugin packages --- .changeset/config.json | 4 +- src/common/stepper/jest.config.cjs | 14 + src/common/stepper/manifest.json | 3 + src/common/stepper/package.json | 37 + src/common/stepper/rollup.config.mjs | 21 + .../stepper/src/__tests__/common.test.ts | 9 + src/common/stepper/src/index.ts | 102 +++ src/common/stepper/tsconfig.json | 11 + src/runner/stepper/jest.config.cjs | 14 + src/runner/stepper/manifest.json | 3 + src/runner/stepper/package.json | 42 + src/runner/stepper/rollup.config.mjs | 21 + .../stepper/src/__tests__/runner.test.ts | 73 ++ src/runner/stepper/src/index.ts | 75 ++ src/runner/stepper/tsconfig.json | 11 + src/web/stepper/manifest.json | 3 + src/web/stepper/package.json | 43 + src/web/stepper/rollup.config.mjs | 28 + src/web/stepper/src/StepperHostPlugin.tsx | 95 ++ src/web/stepper/src/SubstVisualizer.tsx | 809 ++++++++++++++++++ src/web/stepper/src/index.ts | 4 + src/web/stepper/src/styles.ts | 123 +++ src/web/stepper/tsconfig.json | 11 + yarn.lock | 566 +++++++++++- 24 files changed, 2116 insertions(+), 6 deletions(-) create mode 100644 src/common/stepper/jest.config.cjs create mode 100644 src/common/stepper/manifest.json create mode 100644 src/common/stepper/package.json create mode 100644 src/common/stepper/rollup.config.mjs create mode 100644 src/common/stepper/src/__tests__/common.test.ts create mode 100644 src/common/stepper/src/index.ts create mode 100644 src/common/stepper/tsconfig.json create mode 100644 src/runner/stepper/jest.config.cjs create mode 100644 src/runner/stepper/manifest.json create mode 100644 src/runner/stepper/package.json create mode 100644 src/runner/stepper/rollup.config.mjs create mode 100644 src/runner/stepper/src/__tests__/runner.test.ts create mode 100644 src/runner/stepper/src/index.ts create mode 100644 src/runner/stepper/tsconfig.json create mode 100644 src/web/stepper/manifest.json create mode 100644 src/web/stepper/package.json create mode 100644 src/web/stepper/rollup.config.mjs create mode 100644 src/web/stepper/src/StepperHostPlugin.tsx create mode 100644 src/web/stepper/src/SubstVisualizer.tsx create mode 100644 src/web/stepper/src/index.ts create mode 100644 src/web/stepper/src/styles.ts create mode 100644 src/web/stepper/tsconfig.json diff --git a/.changeset/config.json b/.changeset/config.json index 66cb5aa..8542547 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -7,5 +7,7 @@ "access": "restricted", "baseBranch": "main", "updateInternalDependencies": "patch", - "ignore": [] + "ignore": [ + "@sourceacademy/web-stepper" + ] } \ No newline at end of file diff --git a/src/common/stepper/jest.config.cjs b/src/common/stepper/jest.config.cjs new file mode 100644 index 0000000..06bb4a9 --- /dev/null +++ b/src/common/stepper/jest.config.cjs @@ -0,0 +1,14 @@ +module.exports = { + preset: "ts-jest/presets/js-with-ts-esm", + testEnvironment: "node", + transform: { + "^.+\\.tsx?$": [ + "ts-jest", + { + useESM: true, + }, + ], + }, + testPathIgnorePatterns: [".*?dist/"], + coverageReporters: ["lcov"], +}; diff --git a/src/common/stepper/manifest.json b/src/common/stepper/manifest.json new file mode 100644 index 0000000..e263f73 --- /dev/null +++ b/src/common/stepper/manifest.json @@ -0,0 +1,3 @@ +{ + "type": "installable" +} diff --git a/src/common/stepper/package.json b/src/common/stepper/package.json new file mode 100644 index 0000000..eff1ec3 --- /dev/null +++ b/src/common/stepper/package.json @@ -0,0 +1,37 @@ +{ + "name": "@sourceacademy/common-stepper", + "version": "0.0.1", + "packageManager": "yarn@4.6.0", + "description": "Shared, language-agnostic protocol for the Source Academy stepper plugin pair", + "scripts": { + "build": "rollup -c", + "prepack": "yarn build", + "test": "jest", + "test-coverage": "jest --coverage" + }, + "license": "ISC", + "files": [ + "dist" + ], + "main": "dist/index.cjs", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.mjs", + "require": "./dist/index.cjs", + "types": "./dist/index.d.ts" + } + }, + "devDependencies": { + "@rollup/plugin-node-resolve": "^16.0.3", + "@rollup/plugin-terser": "^1.0.0", + "@rollup/plugin-typescript": "^12.3.0", + "@types/jest": "^30.0.0", + "jest": "^30.4.2", + "rollup": "^4.60.2", + "ts-jest": "^29.4.11", + "tslib": "^2.8.1", + "typescript": "^6.0.3" + } +} diff --git a/src/common/stepper/rollup.config.mjs b/src/common/stepper/rollup.config.mjs new file mode 100644 index 0000000..238a07c --- /dev/null +++ b/src/common/stepper/rollup.config.mjs @@ -0,0 +1,21 @@ +import nodeResolve from "@rollup/plugin-node-resolve"; +import terser from "@rollup/plugin-terser"; +import typescript from "@rollup/plugin-typescript"; + +/** + * @type {import('rollup').RollupOptions} + */ +export default { + input: "src/index.ts", + output: [ + { + file: "dist/index.cjs", + format: "cjs", + }, + { + file: "dist/index.mjs", + format: "esm", + }, + ], + plugins: [nodeResolve(), typescript(), terser()], +}; diff --git a/src/common/stepper/src/__tests__/common.test.ts b/src/common/stepper/src/__tests__/common.test.ts new file mode 100644 index 0000000..089de28 --- /dev/null +++ b/src/common/stepper/src/__tests__/common.test.ts @@ -0,0 +1,9 @@ +import { RUNNER_ID, STEPPER_CHANNEL_ID, WEB_ID } from ".."; + +test("runner and web ids are distinct", () => { + expect(RUNNER_ID).not.toBe(WEB_ID); +}); + +test("has a stable channel id", () => { + expect(STEPPER_CHANNEL_ID).toBe("__stepper"); +}); diff --git a/src/common/stepper/src/index.ts b/src/common/stepper/src/index.ts new file mode 100644 index 0000000..e21905d --- /dev/null +++ b/src/common/stepper/src/index.ts @@ -0,0 +1,102 @@ +/** + * Shared, language-agnostic protocol for the Source Academy Stepper plugin pair. + * + * The Stepper is split into: + * - a {@link https://github.com/source-academy/conductor | Conductor} **runner** plugin + * (`@sourceacademy/runner-stepper`) that turns an AST into evaluation steps, and + * - a **web/host** plugin (`@sourceacademy/web-stepper`) that displays those steps. + * + * They communicate over a single {@link STEPPER_CHANNEL_ID | channel} using the + * {@link StepperMessage} protocol. Everything that crosses the channel must be plain, + * structured-clone-able JSON — class instances with methods cannot survive a `MessageChannel`. + */ + +/** The channel the stepper runner and host plugins communicate over. */ +export const STEPPER_CHANNEL_ID = "__stepper"; + +/** The id of the runner (worker-side) stepper plugin. */ +export const RUNNER_ID = "__runner_stepper"; + +/** The id of the web/host (browser-side) stepper plugin. */ +export const WEB_ID = "__web_stepper"; + +/** + * The id used to look the stepper up in the plugin directory (i.e. the argument to + * `IRunnerPlugin.hostLoadPlugin`). The host resolves this to the web plugin's bundle URL. + */ +export const STEPPER_DIRECTORY_ID = "stepper"; + +/** + * A single AST node, serialized to plain JSON. + * + * Language-specific stepper ASTs are class instances dispatched on a `type` string. After + * serialization the methods are gone, but `type` and the child fields remain so the host can + * still render the node. Every node additionally carries a stable {@link SerializedStepperNode.nodeId} + * assigned during serialization, so markers can reference nodes by id rather than by object + * identity (which does not survive serialization). + */ +export interface SerializedStepperNode { + /** The node kind, e.g. `"BinaryExpression"`. Mirrors the source AST's `type`. */ + type: string; + /** A stable id, unique within a single step's tree. Used to match {@link SerializedMarker}s. */ + nodeId: string; + /** Child nodes, arrays of nodes, and primitive properties of the original node. */ + [key: string]: unknown; +} + +/** + * Highlights a redex (reducible expression) within a step and explains the reduction. + * + * In the original (in-memory) stepper a marker pointed at a node by reference. Because that + * identity is lost across the channel, a serialized marker instead references the target node by + * its {@link SerializedStepperNode.nodeId} via {@link SerializedMarker.redexId}. + */ +export interface SerializedMarker { + /** The `nodeId` of the highlighted node, or `null`/absent when there is nothing to highlight. */ + redexId?: string | null; + /** + * The `type` of the highlighted node (e.g. `"DebuggerStatement"`). Serialized alongside + * {@link redexId} because the host can no longer dereference the node to read its type (object + * identity is lost across the channel). Used e.g. for breakpoint navigation. + */ + redexNodeType?: string; + /** Whether the highlight applies before or after the reduction. */ + redexType?: "beforeMarker" | "afterMarker"; + /** A human-readable explanation of the reduction, shown alongside the step. */ + explanation?: string; +} + +/** One step of an evaluation: a fully-serialized AST plus the markers describing the reduction. */ +export interface SerializedStepperStep { + /** The program AST at this step. */ + ast: SerializedStepperNode; + /** Markers highlighting/explaining the redex(es) involved in reaching the next step. */ + markers?: SerializedMarker[]; +} + +/* -------------------------------------------------------------------------- */ +/* Channel protocol */ +/* -------------------------------------------------------------------------- */ + +/** Runner → host: the computed evaluation steps for the most recent run. */ +export interface StepperStepsMessage { + type: "steps"; + steps: SerializedStepperStep[]; +} + +/** Runner → host: stepping failed (e.g. a parse error). */ +export interface StepperErrorMessage { + type: "error"; + error: string; +} + +/** + * Host → runner: asks the runner to (re)send the steps it last computed. Used to repopulate the + * display when the stepper tab is (re)opened without re-running the program. + */ +export interface StepperRequestMessage { + type: "request"; +} + +/** Every message that may cross the {@link STEPPER_CHANNEL_ID} channel. */ +export type StepperMessage = StepperStepsMessage | StepperErrorMessage | StepperRequestMessage; diff --git a/src/common/stepper/tsconfig.json b/src/common/stepper/tsconfig.json new file mode 100644 index 0000000..88a8445 --- /dev/null +++ b/src/common/stepper/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "exclude": ["./dist"], + "include": ["./src"], + "compilerOptions": { + "declaration": true, + "outDir": "./dist", + "rootDir": "./src", + "types": ["jest"] + } +} diff --git a/src/runner/stepper/jest.config.cjs b/src/runner/stepper/jest.config.cjs new file mode 100644 index 0000000..06bb4a9 --- /dev/null +++ b/src/runner/stepper/jest.config.cjs @@ -0,0 +1,14 @@ +module.exports = { + preset: "ts-jest/presets/js-with-ts-esm", + testEnvironment: "node", + transform: { + "^.+\\.tsx?$": [ + "ts-jest", + { + useESM: true, + }, + ], + }, + testPathIgnorePatterns: [".*?dist/"], + coverageReporters: ["lcov"], +}; diff --git a/src/runner/stepper/manifest.json b/src/runner/stepper/manifest.json new file mode 100644 index 0000000..e263f73 --- /dev/null +++ b/src/runner/stepper/manifest.json @@ -0,0 +1,3 @@ +{ + "type": "installable" +} diff --git a/src/runner/stepper/package.json b/src/runner/stepper/package.json new file mode 100644 index 0000000..9cbb721 --- /dev/null +++ b/src/runner/stepper/package.json @@ -0,0 +1,42 @@ +{ + "name": "@sourceacademy/runner-stepper", + "version": "0.0.1", + "packageManager": "yarn@4.6.0", + "description": "Language-agnostic runner plugin for the Source Academy stepper", + "scripts": { + "build": "rollup -c", + "prepack": "yarn build", + "test": "jest", + "test-coverage": "jest --coverage" + }, + "license": "ISC", + "files": [ + "dist" + ], + "main": "dist/index.cjs", + "module": "dist/index.mjs", + "types": "dist/index.d.ts", + "exports": { + ".": { + "import": "./dist/index.mjs", + "require": "./dist/index.cjs", + "types": "./dist/index.d.ts" + } + }, + "peerDependencies": { + "@sourceacademy/conductor": ">=0.3.0" + }, + "devDependencies": { + "@rollup/plugin-node-resolve": "^16.0.3", + "@rollup/plugin-terser": "^1.0.0", + "@rollup/plugin-typescript": "^12.3.0", + "@sourceacademy/common-stepper": "workspace:*", + "@sourceacademy/conductor": ">=0.3.0", + "@types/jest": "^30.0.0", + "jest": "^30.4.2", + "rollup": "^4.60.2", + "ts-jest": "^29.4.11", + "tslib": "^2.8.1", + "typescript": "^6.0.3" + } +} diff --git a/src/runner/stepper/rollup.config.mjs b/src/runner/stepper/rollup.config.mjs new file mode 100644 index 0000000..238a07c --- /dev/null +++ b/src/runner/stepper/rollup.config.mjs @@ -0,0 +1,21 @@ +import nodeResolve from "@rollup/plugin-node-resolve"; +import terser from "@rollup/plugin-terser"; +import typescript from "@rollup/plugin-typescript"; + +/** + * @type {import('rollup').RollupOptions} + */ +export default { + input: "src/index.ts", + output: [ + { + file: "dist/index.cjs", + format: "cjs", + }, + { + file: "dist/index.mjs", + format: "esm", + }, + ], + plugins: [nodeResolve(), typescript(), terser()], +}; diff --git a/src/runner/stepper/src/__tests__/runner.test.ts b/src/runner/stepper/src/__tests__/runner.test.ts new file mode 100644 index 0000000..813e306 --- /dev/null +++ b/src/runner/stepper/src/__tests__/runner.test.ts @@ -0,0 +1,73 @@ +import { RUNNER_ID, STEPPER_CHANNEL_ID } from "@sourceacademy/common-stepper"; +import { BaseStepperRunnerPlugin } from ".."; + +class FakeChannel { + name = STEPPER_CHANNEL_ID; + sent: unknown[] = []; + private subscribers: ((m: unknown) => void)[] = []; + send(message: unknown) { + this.sent.push(message); + } + subscribe(fn: (m: unknown) => void) { + this.subscribers.push(fn); + } + unsubscribe(fn: (m: unknown) => void) { + this.subscribers = this.subscribers.filter(s => s !== fn); + } + close() {} + emit(message: unknown) { + this.subscribers.forEach(fn => fn(message)); + } +} + +// A trivial concrete stepper: every "AST" (a number n) becomes n no-op steps. +class CountingStepper extends BaseStepperRunnerPlugin { + getSteps(ast: number) { + return Array.from({ length: ast }, (_, i) => ({ + ast: { type: "Literal", nodeId: String(i), value: i }, + })); + } +} + +test("attaches to the stepper channel", () => { + expect(BaseStepperRunnerPlugin.channelAttach).toEqual([STEPPER_CHANNEL_ID]); +}); + +test("has the runner id", () => { + const channel = new FakeChannel(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const plugin = new CountingStepper({} as any, [channel as any]); + expect(plugin.id).toBe(RUNNER_ID); +}); + +test("sendSteps computes, caches and pushes steps; request replays them", async () => { + const channel = new FakeChannel(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const plugin = new CountingStepper({} as any, [channel as any]); + await plugin.sendSteps(2); + expect(channel.sent).toEqual([ + { + type: "steps", + steps: [ + { ast: { type: "Literal", nodeId: "0", value: 0 } }, + { ast: { type: "Literal", nodeId: "1", value: 1 } }, + ], + }, + ]); + channel.emit({ type: "request" }); + expect(channel.sent).toHaveLength(2); + expect(channel.sent[1]).toEqual(channel.sent[0]); +}); + +test("sendSteps reports errors instead of throwing", async () => { + const channel = new FakeChannel(); + class Boom extends BaseStepperRunnerPlugin { + getSteps(): never { + throw new Error("kaboom"); + } + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const plugin = new Boom({} as any, [channel as any]); + await plugin.sendSteps(1); + expect(channel.sent).toEqual([{ type: "error", error: "kaboom" }]); +}); diff --git a/src/runner/stepper/src/index.ts b/src/runner/stepper/src/index.ts new file mode 100644 index 0000000..c4db53f --- /dev/null +++ b/src/runner/stepper/src/index.ts @@ -0,0 +1,75 @@ +import { + RUNNER_ID, + STEPPER_CHANNEL_ID, + type SerializedStepperStep, + type StepperMessage, +} from "@sourceacademy/common-stepper"; +import { IChannel, IConduit, IPlugin } from "@sourceacademy/conductor/conduit"; + +/** + * The language-agnostic runner half of the stepper. + * + * This base class owns everything that is *not* language-specific: the channel wiring, the + * request/replay protocol with the host, error reporting, and caching of the most recent steps. + * + * A concrete language stepper (e.g. js-slang, py-slang) extends this class and implements the + * single abstract method {@link getSteps}, whose **only input is an AST**. The class is generic + * over the AST type `TAst` so each language can use its own node representation while the core + * stays language-agnostic. + * + * The evaluator drives stepping by calling {@link sendSteps} with a freshly-parsed AST (parsing is + * the evaluator's/language's concern, never this plugin's). + * + * @typeParam TAst The language's AST/root-node type accepted by {@link getSteps}. + */ +export abstract class BaseStepperRunnerPlugin implements IPlugin { + static readonly channelAttach = [STEPPER_CHANNEL_ID]; + readonly id: string = RUNNER_ID; + + private readonly __stepperChannel: IChannel; + /** The steps from the most recent {@link sendSteps} call, replayed on host request. */ + private __lastSteps: SerializedStepperStep[] = []; + + constructor( + _conduit: IConduit, + [stepperChannel]: IChannel[], + ) { + this.__stepperChannel = stepperChannel; + this.__stepperChannel.subscribe(message => { + // The host re-opened the stepper tab and wants the latest steps without a re-run. + if (message.type === "request") { + this.__stepperChannel.send({ type: "steps", steps: this.__lastSteps }); + } + }); + } + + /** + * The language-specific core of the stepper: given an AST, produce the ordered evaluation steps + * (each a serialized AST plus markers/explanations). Must return plain, structured-clone-able + * JSON — see `SerializedStepperStep`. + * + * @param ast The program AST to step through. + * @returns The evaluation steps, synchronously or as a promise. + */ + abstract getSteps(ast: TAst): SerializedStepperStep[] | Promise; + + /** + * Computes the steps for `ast` and pushes them to the host plugin for display. Call this from the + * evaluator after parsing a chunk, when stepping is desired. Errors are reported to the host + * rather than thrown, so a stepping failure does not break the run. + * + * @param ast The freshly-parsed program AST. + */ + async sendSteps(ast: TAst): Promise { + try { + const steps = await this.getSteps(ast); + this.__lastSteps = steps; + this.__stepperChannel.send({ type: "steps", steps }); + } catch (error) { + this.__stepperChannel.send({ + type: "error", + error: error instanceof Error ? error.message : String(error), + }); + } + } +} diff --git a/src/runner/stepper/tsconfig.json b/src/runner/stepper/tsconfig.json new file mode 100644 index 0000000..88a8445 --- /dev/null +++ b/src/runner/stepper/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "exclude": ["./dist"], + "include": ["./src"], + "compilerOptions": { + "declaration": true, + "outDir": "./dist", + "rootDir": "./src", + "types": ["jest"] + } +} diff --git a/src/web/stepper/manifest.json b/src/web/stepper/manifest.json new file mode 100644 index 0000000..3463661 --- /dev/null +++ b/src/web/stepper/manifest.json @@ -0,0 +1,3 @@ +{ + "type": "external" +} diff --git a/src/web/stepper/package.json b/src/web/stepper/package.json new file mode 100644 index 0000000..a0627b9 --- /dev/null +++ b/src/web/stepper/package.json @@ -0,0 +1,43 @@ +{ + "name": "@sourceacademy/web-stepper", + "version": "0.0.1", + "packageManager": "yarn@4.6.0", + "description": "Host (web) plugin for the Source Academy stepper: renders evaluation steps", + "scripts": { + "build": "rollup -c", + "prepack": "yarn build" + }, + "license": "ISC", + "files": [ + "dist" + ], + "main": "dist/index.mjs", + "module": "dist/index.mjs", + "exports": { + ".": { + "import": "./dist/index.mjs" + } + }, + "peerDependencies": { + "@blueprintjs/core": ">=5", + "react": ">=18", + "react-dom": ">=18" + }, + "devDependencies": { + "@blueprintjs/core": "^6.0.0", + "@mantine/hooks": "^9.0.0", + "@rollup/plugin-commonjs": "^28.0.0", + "@rollup/plugin-node-resolve": "^16.0.3", + "@rollup/plugin-terser": "^1.0.0", + "@rollup/plugin-typescript": "^12.3.0", + "@sourceacademy/common-stepper": "workspace:*", + "@sourceacademy/conductor": ">=0.3.0", + "@types/react": "^19.0.0", + "classnames": "^2.3.2", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "rollup": "^4.60.2", + "tslib": "^2.8.1", + "typescript": "^6.0.3" + } +} diff --git a/src/web/stepper/rollup.config.mjs b/src/web/stepper/rollup.config.mjs new file mode 100644 index 0000000..19995a5 --- /dev/null +++ b/src/web/stepper/rollup.config.mjs @@ -0,0 +1,28 @@ +import nodeResolve from "@rollup/plugin-node-resolve"; +import commonjs from "@rollup/plugin-commonjs"; +import terser from "@rollup/plugin-terser"; +import typescript from "@rollup/plugin-typescript"; + +// Shared with the host frontend (resolved at runtime via the host's import map), so they are not +// bundled: this keeps the bundle tiny and, crucially, makes the plugin use the *same* React and +// Blueprint instances as the frontend — guaranteeing a single React tree and identical styling. +const external = [ + "react", + "react-dom", + "react/jsx-runtime", + "react/jsx-dev-runtime", + "@blueprintjs/core", +]; + +/** + * @type {import('rollup').RollupOptions} + */ +export default { + input: "src/index.ts", + output: { + file: "dist/index.mjs", + format: "esm", + }, + external, + plugins: [nodeResolve({ browser: true, preferBuiltins: false }), commonjs(), typescript(), terser()], +}; diff --git a/src/web/stepper/src/StepperHostPlugin.tsx b/src/web/stepper/src/StepperHostPlugin.tsx new file mode 100644 index 0000000..88f03fb --- /dev/null +++ b/src/web/stepper/src/StepperHostPlugin.tsx @@ -0,0 +1,95 @@ +import { + STEPPER_CHANNEL_ID, + WEB_ID, + type SerializedStepperStep, + type StepperMessage, +} from "@sourceacademy/common-stepper"; +import { IChannel, IConduit, IPlugin } from "@sourceacademy/conductor/conduit"; +import { createElement, useSyncExternalStore } from "react"; + +import StepperView from "./SubstVisualizer"; + +/** + * Describes a side-content tab contributed by a web plugin. The frontend's generic plugin-tab host + * reads this structurally (it does not import the plugin's types), so any web plugin that exposes a + * `tab` can render UI without per-plugin frontend code. + */ +export interface PluginTab { + /** Stable id for the tab. */ + id: string; + /** Tab label shown to the user. */ + label: string; + /** Blueprint icon name for the tab. */ + iconName: string; + /** The React component rendered as the tab body. Self-contained; takes no props. */ + Component: React.ComponentType; +} + +/** + * The host (browser-side) half of the stepper. It listens on the stepper channel for steps pushed + * by the runner plugin, holds them as an external store, and exposes a {@link PluginTab} whose + * component renders them. This plugin is entirely language-agnostic — it only knows the serialized + * step protocol from `@sourceacademy/common-stepper`. + */ +export class StepperHostPlugin implements IPlugin { + static readonly channelAttach = [STEPPER_CHANNEL_ID]; + readonly id: string = WEB_ID; + + private readonly __stepperChannel: IChannel; + private __steps: SerializedStepperStep[] = []; + private __error: string | null = null; + private readonly __listeners = new Set<() => void>(); + + readonly tab: PluginTab; + + constructor(_conduit: IConduit, [stepperChannel]: IChannel[]) { + this.__stepperChannel = stepperChannel; + this.__stepperChannel.subscribe(message => { + if (message.type === "steps") { + this.__steps = message.steps; + this.__error = null; + this.__emit(); + } else if (message.type === "error") { + this.__steps = []; + this.__error = message.error; + this.__emit(); + } + }); + // Ask the runner to replay any steps it already computed (e.g. tab opened after a run). + this.__stepperChannel.send({ type: "request" }); + + const plugin = this; + this.tab = { + id: "stepper", + label: "Stepper", + iconName: "flow-review", + Component: function StepperTab() { + const steps = useSyncExternalStore( + listener => plugin.subscribe(listener), + () => plugin.getSteps(), + ); + return createElement(StepperView, { content: steps }); + }, + }; + } + + /** The most recently received steps. */ + getSteps(): SerializedStepperStep[] { + return this.__steps; + } + + /** The most recent stepping error, if any. */ + getError(): string | null { + return this.__error; + } + + /** Subscribe to step/error updates. Returns an unsubscribe function. */ + subscribe(listener: () => void): () => void { + this.__listeners.add(listener); + return () => this.__listeners.delete(listener); + } + + private __emit(): void { + this.__listeners.forEach(listener => listener()); + } +} diff --git a/src/web/stepper/src/SubstVisualizer.tsx b/src/web/stepper/src/SubstVisualizer.tsx new file mode 100644 index 0000000..8cb3af1 --- /dev/null +++ b/src/web/stepper/src/SubstVisualizer.tsx @@ -0,0 +1,809 @@ +import { + Button, + ButtonGroup, + Card, + Classes, + Divider, + Icon, + Popover, + Pre, + Slider, +} from "@blueprintjs/core"; +import { getHotkeyHandler, type HotkeyItem } from "@mantine/hooks"; +import type { SerializedStepperNode, SerializedStepperStep } from "@sourceacademy/common-stepper"; +import classNames from "classnames"; +import { useCallback, useEffect, useState } from "react"; + +import { injectStepperStyles } from "./styles"; + +/** + * The serialized AST nodes are plain JSON. `Record` lets the renderer read the + * language-specific fields (e.g. `left`, `operator`, `params`) without per-node typing, exactly as + * the original (class-based) renderer did after casting. + */ +type StepperNode = SerializedStepperNode & Record; + +function SubstDefaultText() { + return ( +
+
+ Welcome to the Stepper! +
+
+ On this tab, the REPL will be hidden from view, so do check that your code has no errors + before running the stepper. You may use this tool by writing your program on the left, then + dragging the slider above to see its evaluation. +
+
+ On even-numbered steps, the part of the program that will be evaluated next is highlighted in + yellow. On odd-numbered steps, the result of the evaluation is highlighted in green. You can + change the maximum steps limit (500-5000, default 1000) in the control bar. +
+
+ + Some useful keyboard shortcuts: +
+
+ a: Move to the first step +
+ e: Move to the last step +
+ f: Move to the next step +
+ b: Move to the previous step +
+
+ Note that these shortcuts are only active when the browser focus is on this tab (click on or + above the explanation text). +
+
+ ); +} + +function SubstCodeDisplay(props: { content: string }) { + return ( + +
{props.content}
+
+ ); +} + +type StepperViewProps = { + content: SerializedStepperStep[]; +}; + +/** + * The presentational stepper: a slider + breakpoint controls over a list of serialized steps, with + * a custom AST renderer and an explanation panel. A faithful port of the frontend's legacy + * `SideContentSubstVisualizer`, minus its redux/i18n/js-slang couplings. + */ +export default function StepperView(props: StepperViewProps) { + const [stepValue, setStepValue] = useState(1); + const lastStepValue = props.content.length; + const hasRunCode = lastStepValue !== 0; + + useEffect(() => injectStepperStyles(), []); + + // reset stepValue when content changes + useEffect(() => { + setStepValue(1); + }, [props.content]); + + const stepNextBreakpoint = useCallback(() => { + // Search forward from current step for a DebuggerStatement redex + for (let i = stepValue; i < props.content.length; i++) { + const markers = props.content[i].markers; + if (markers?.some(marker => marker.redexNodeType === "DebuggerStatement")) { + setStepValue(i + 1); // +1 because stepValue is 1-indexed + return; + } + } + // Optional: If no next breakpoint found, go to the last step + setStepValue(props.content.length); + }, [stepValue, props.content]); + + const stepPreviousBreakpoint = useCallback(() => { + // Start searching from the step BEFORE the current one + for (let i = stepValue - 2; i >= 0; i--) { + const markers = props.content[i].markers; + const isDebuggerStep = markers?.some(marker => marker.redexNodeType === "DebuggerStatement"); + if (isDebuggerStep) { + setStepValue(i + 1); // Convert back to 1-based indexing + return; + } + } + // Optional: If no previous breakpoint found, go to the first step + setStepValue(1); + }, [stepValue, props.content]); + + const stepPrevious = () => setStepValue(Math.max(1, stepValue - 1)); + const stepNext = () => setStepValue(Math.min(props.content.length, stepValue + 1)); + + // Setup hotkey bindings + const hotkeyBindings: HotkeyItem[] = hasRunCode + ? [ + ["a", stepPreviousBreakpoint], + ["f", stepNext], + ["b", stepPrevious], + ["e", stepNextBreakpoint], + ] + : [ + ["a", () => {}], + ["f", () => {}], + ["b", () => {}], + ["e", () => {}], + ]; + const hotkeyHandler = getHotkeyHandler(hotkeyBindings); + + const getExplanation = useCallback( + (value: number): string => { + const contIndex = value <= lastStepValue ? value - 1 : 0; + // Right now, prioritize the first marker + const markers = props.content[contIndex].markers; + if (markers === undefined || markers[0] === undefined) { + return "..."; + } else { + return markers[0].explanation ?? "..."; + } + }, + [lastStepValue, props.content], + ); + + const getAST = useCallback( + (value: number): SerializedStepperStep => { + const contIndex = value <= lastStepValue ? value - 1 : 0; + return props.content[contIndex]; + }, + [lastStepValue, props.content], + ); + + return ( +
+ +
+ +
{" "} +
+ {hasRunCode ? : } + {hasRunCode ? : null} +
+ ); +} + +/* + Custom AST renderer for Stepper (Inspired by astring library) + This custom AST renderer utilizes the recursive approach of handling rendering of various + StepperNodes by using nested
and . Unlike React-ace, using our own renderer makes our + stepper more customizable. For example, we can add a code component that is hoverable using a + blueprint tooltip. +*/ + +interface RenderContext { + parentNode?: StepperNode; + isRight?: boolean; // specified for binary expression + styleWrapper: StyleWrapper; + popoverDepth?: number; +} + +type StyleWrapper = (node: StepperNode) => (preformatted: React.ReactNode) => React.ReactNode; + +// composeStyleWrapper takes two style wrappers and merges their effect together. +function composeStyleWrapper( + first: StyleWrapper | undefined, + second: StyleWrapper | undefined, +): StyleWrapper | undefined { + return first === undefined && second === undefined + ? undefined + : first === undefined + ? second + : second === undefined + ? first + : (node: StepperNode) => (preformatted: React.ReactNode) => { + const afterFirstStyle = first(node)(preformatted); + return second(node)(afterFirstStyle); + }; +} + +interface FunctionDefinitionPopoverContentProps { + node: StepperNode; + styleWrapper: StyleWrapper | undefined; + popoverDepth: number; + renderNode: (node: StepperNode, context: RenderContext) => React.ReactNode; + renderFunctionArguments: ( + nodes: StepperNode[], + renderNodeFn: (node: StepperNode, context: RenderContext) => React.ReactNode, + styleWrapper: StyleWrapper | undefined, + popoverDepth: number, + ) => React.ReactNode; +} + +function FunctionDefinitionPopoverContent({ + node, + styleWrapper, + popoverDepth, + renderNode, + renderFunctionArguments, +}: FunctionDefinitionPopoverContentProps) { + return ( +
+
+ + {" Function definition"} +
+          
+            {renderFunctionArguments(node.params, renderNode, styleWrapper, popoverDepth)}
+            {" => "}
+            {renderNode(node.body, {
+              styleWrapper: styleWrapper ?? (_node => p => p),
+              popoverDepth: popoverDepth + 1,
+            })}
+          
+        
+
+
+ ); +} + +/** + * renderNode renders a serialized Stepper AST node to a React ReactNode. + */ +function renderNode(currentNode: StepperNode, renderContext: RenderContext): React.ReactNode { + const styleWrapper = renderContext.styleWrapper; + const popoverDepth = renderContext.popoverDepth ?? 0; + const renderers = { + Literal(node: StepperNode) { + const stringifyLiteralValue = (value: any) => + typeof value === "string" ? '"' + value + '"' : value !== null ? value.toString() : "null"; + return ( + + {node.raw ? node.raw : stringifyLiteralValue(node.value)} + + ); + }, + Identifier(node: StepperNode) { + return {node.name}; + }, + // Expressions + UnaryExpression(node: StepperNode) { + return ( + + {`${node.operator}`} + {renderNode(node.argument, { + parentNode: node, + styleWrapper: styleWrapper, + popoverDepth: popoverDepth, + })} + + ); + }, + BinaryExpression(node: StepperNode) { + return ( + + {renderNode(node.left, { + parentNode: node, + isRight: false, + styleWrapper: styleWrapper, + popoverDepth: popoverDepth, + })} + {` ${node.operator} `} + {renderNode(node.right, { + parentNode: node, + isRight: true, + styleWrapper: styleWrapper, + popoverDepth: popoverDepth, + })} + + ); + }, + LogicalExpression(node: StepperNode) { + return ( + + {renderNode(node.left, { + parentNode: node, + isRight: false, + styleWrapper: styleWrapper, + popoverDepth: popoverDepth, + })} + {` ${node.operator} `} + {renderNode(node.right, { + parentNode: node, + isRight: true, + styleWrapper: styleWrapper, + popoverDepth: popoverDepth, + })} + + ); + }, + ConditionalExpression(node: StepperNode) { + return ( + + {renderNode(node.test, { styleWrapper: styleWrapper, popoverDepth: popoverDepth })} + {` ? `} + {renderNode(node.consequent, { styleWrapper: styleWrapper, popoverDepth: popoverDepth })} + {` : `} + {renderNode(node.alternate, { styleWrapper: styleWrapper, popoverDepth: popoverDepth })} + + ); + }, + ArrayExpression(node: StepperNode) { + // Render all arguments inside an array + const args: React.ReactNode[] = node.elements + .filter((arg: StepperNode | null) => arg !== null) + .map((arg: StepperNode) => + renderNode(arg, { styleWrapper: styleWrapper, popoverDepth: popoverDepth }), + ); + + const renderedArguments = args.slice(1).reduce( + (result, item) => ( + + {result} + {", "} + {item} + + ), + args[0], + ); + return ( + + {"["} + {renderedArguments} + {"]"} + + ); + }, + ArrowFunctionExpression(node: StepperNode) { + /** + * Add hovering effect to children nodes only if it is an identifier with the name + * corresponding to the name of lambda expression + */ + function muTermStyleWrapper(targetNode: StepperNode) { + if (targetNode.type === "Identifier" && targetNode.name === node.name) { + function addHovering(preprocessed: React.ReactNode): React.ReactNode { + return ( + + + } + > + {preprocessed} + + + ); + } + return addHovering; + } else { + // Do nothing + return (preprocessed: React.ReactNode) => preprocessed; + } + } + + // If the name is specified, render the name and add hovering for the body. + return node.name ? ( + + + } + > + {node.name} + + + ) : ( + + {renderFunctionArguments(node.params, renderNode, styleWrapper, popoverDepth)} + {" => "} + {renderNode(node.body, { + styleWrapper: composeStyleWrapper(styleWrapper, muTermStyleWrapper)!, + popoverDepth: popoverDepth, + })} + + ); + }, + CallExpression(node: StepperNode) { + let renderedCallee = renderNode(node.callee, { + styleWrapper: styleWrapper, + popoverDepth: popoverDepth, + }); + if (node.callee.type === "ArrowFunctionExpression" && node.callee.name === undefined) { + renderedCallee = ( + + {"("} + {renderedCallee} + {")"} + + ); + } + return ( + + {renderedCallee} + {renderArguments(node.arguments)} + + ); + }, + Program(node: StepperNode) { + return ( + + {node.body.map((ast: StepperNode, index: number) => ( +
+ {renderNode(ast, { styleWrapper: styleWrapper, popoverDepth: popoverDepth })} +
+ ))} +
+ ); + }, + IfStatement(node: StepperNode) { + return ( + + + {"if "} + {"("} + + {renderNode(node.test, { styleWrapper: styleWrapper, popoverDepth: popoverDepth })} + + {") "} + + + {renderNode(node.consequent, { + styleWrapper: styleWrapper, + popoverDepth: popoverDepth, + })} + + {node.alternate && ( + + {" else "} + {renderNode(node.alternate, { + styleWrapper: styleWrapper, + popoverDepth: popoverDepth, + })} + + )} + + ); + }, + ReturnStatement(node: StepperNode) { + return ( + + {"return "} + {node.argument && + renderNode(node.argument, { styleWrapper: styleWrapper, popoverDepth: popoverDepth })} + {";"} + + ); + }, + BlockStatement(node: StepperNode) { + return ( + + {"{"} + {node.body.map((ast: StepperNode, index: number) => ( +
+ {renderNode(ast, { styleWrapper, popoverDepth: popoverDepth })} +
+ ))} + {"}"} +
+ ); + }, + ExpressionStatement(node: StepperNode) { + return ( + + {renderNode(node.expression, { styleWrapper: styleWrapper, popoverDepth: popoverDepth })} + {";"} + + ); + }, + FunctionDeclaration(node: StepperNode) { + return ( + + {`function ${node.id.name}`} + {renderArguments(node.params)} + + {" "} + {renderNode(node.body, { styleWrapper: styleWrapper, popoverDepth: popoverDepth })} + + + ); + }, + VariableDeclaration(node: StepperNode) { + return ( + + {node.kind} + {node.declarations.map((ast: StepperNode, idx: number) => ( + + {idx !== 0 && ", "} + {renderNode(ast, { styleWrapper: styleWrapper, popoverDepth: popoverDepth })} + + ))} + {";"} + + ); + }, + VariableDeclarator(node: StepperNode) { + return ( + + {renderNode(node.id, { styleWrapper: styleWrapper, popoverDepth: popoverDepth })} + {" = "} + {node.init + ? renderNode(node.init, { styleWrapper: styleWrapper, popoverDepth: popoverDepth }) + : "undefined"} + + ); + }, + DebuggerStatement(_node: StepperNode) { + return debugger;; + }, + }; + + // Additional renderers + const renderFunctionArguments = ( + nodes: StepperNode[], + renderNodeFn: typeof renderNode, + styleWrapper: StyleWrapper | undefined, + popoverDepth: number, + ) => { + const args: React.ReactNode[] = nodes.map(arg => + renderNodeFn(arg, { + styleWrapper: styleWrapper ?? (_node => p => p), + popoverDepth: popoverDepth, + }), + ); + let renderedArguments = args.slice(1).reduce( + (result, item) => ( + + {result} + {", "} + {item} + + ), + args[0], + ); + if (args.length !== 1) { + renderedArguments = ( + + {"("} + {renderedArguments} + {")"} + + ); + } + return renderedArguments; + }; + + const renderArguments = (nodes: StepperNode[]) => { + const args: React.ReactNode[] = nodes.map(arg => + renderNode(arg, { styleWrapper: styleWrapper, popoverDepth: popoverDepth }), + ); + let renderedArguments = args.slice(1).reduce( + (result, item) => ( + + {result} + {", "} + {item} + + ), + args[0], + ); + renderedArguments = ( + + {"("} + {renderedArguments} + {")"} + + ); + return renderedArguments; + }; + + // Entry point of rendering + const renderer = (renderers as unknown as Record React.ReactNode>)[ + currentNode.type + ]; + const isParenthesis = expressionNeedsParenthesis( + currentNode, + renderContext.parentNode, + renderContext.isRight, + ); + let result: React.ReactNode = renderer ? renderer(currentNode) : `<${currentNode.type}>`; // For debugging in case some AST renderer has not been implemented yet + if (isParenthesis) { + result = ( + + {"("} + {result} + {")"} + + ); + } + // custom wrapper style + if (styleWrapper) { + result = styleWrapper(currentNode)(result); + } + return result; +} +/////////////////////////////////// Custom AST Renderer for Stepper ////////////////////////////////// + +/** + * A React component that handles rendering of a single step's AST + markers. + */ +function CustomASTRenderer(props: SerializedStepperStep): React.ReactNode { + const getDisplayedNode = useCallback((): React.ReactNode => { + function markerStyleWrapper(node: StepperNode) { + // eslint-disable-next-line react/display-name + return (rendered: React.ReactNode) => { + if (props.markers === undefined) { + return rendered; + } + // highlight the entire function declaration body if it's a function declaration, + // else just highlight that line + let returnNode = {rendered}; + props.markers.forEach(marker => { + // Match by stable node id rather than object identity, which does not survive + // serialization across the runner/host channel. + if (marker.redexId !== undefined && marker.redexId === node.nodeId) { + const Wrapper = node.type === "FunctionDeclaration" ? "div" : "span"; + returnNode = {returnNode}; + } + }); + return returnNode; + }; + } + return renderNode(props.ast, { + styleWrapper: markerStyleWrapper, + popoverDepth: 0, + }); + }, [props]); + return
{getDisplayedNode()}
; +} + +/** + * expressionNeedsParenthesis + * checks whether there should be parentheses wrapped around the node or not + */ +function expressionNeedsParenthesis( + node: StepperNode, + parentNode?: StepperNode, + isRightHand?: boolean, +) { + if (parentNode === undefined) { + return false; + } + + const nodePrecedence = EXPRESSIONS_PRECEDENCE[node.type as keyof typeof EXPRESSIONS_PRECEDENCE]; + if (nodePrecedence === NEEDS_PARENTHESES) { + return true; + } + const parentNodePrecedence = + EXPRESSIONS_PRECEDENCE[parentNode.type as keyof typeof EXPRESSIONS_PRECEDENCE]; + if (nodePrecedence === undefined || parentNodePrecedence === undefined) { + return false; + } + + if (nodePrecedence !== parentNodePrecedence) { + return ( + (!isRightHand && nodePrecedence === 15 && parentNodePrecedence === 14) || + nodePrecedence < parentNodePrecedence + ); + } + + if (!("operator" in node) || !("operator" in parentNode)) { + return false; + } + + if (nodePrecedence !== 13 && nodePrecedence !== 14) { + // Not a `LogicalExpression` or `BinaryExpression` + return false; + } + if (node.operator === "**" && parentNode.operator === "**") { + // Exponentiation operator has right-to-left associativity + return !isRightHand; + } + if ( + nodePrecedence === 13 && + parentNodePrecedence === 13 && + (node.operator === "??" || parentNode.operator === "??") + ) { + return true; + } + + const nodeOperatorPrecedence = + OPERATOR_PRECEDENCE[node.operator as keyof typeof OPERATOR_PRECEDENCE]; + const parentNodeOperatorPrecedence = + OPERATOR_PRECEDENCE[parentNode.operator as keyof typeof OPERATOR_PRECEDENCE]; + return isRightHand + ? nodeOperatorPrecedence <= parentNodeOperatorPrecedence + : nodeOperatorPrecedence <= parentNodeOperatorPrecedence; +} +const OPERATOR_PRECEDENCE = { + "||": 2, + "??": 3, + "&&": 4, + "|": 5, + "^": 6, + "&": 7, + "==": 8, + "!=": 8, + "===": 8, + "!==": 8, + "<": 9, + ">": 9, + "<=": 9, + ">=": 9, + in: 9, + instanceof: 9, + "<<": 10, + ">>": 10, + ">>>": 10, + "+": 11, + "-": 11, + "*": 12, + "%": 12, + "/": 12, + "**": 13, +}; +const NEEDS_PARENTHESES = 17; +const EXPRESSIONS_PRECEDENCE = { + // Definitions + ArrayExpression: 20, + TaggedTemplateExpression: 20, + ThisExpression: 20, + Identifier: 20, + PrivateIdentifier: 20, + Literal: 18, + TemplateLiteral: 20, + Super: 20, + SequenceExpression: 20, + // Operations + MemberExpression: 19, + ChainExpression: 19, + CallExpression: 19, + NewExpression: 19, + // Other definitions + ArrowFunctionExpression: NEEDS_PARENTHESES, + ClassExpression: NEEDS_PARENTHESES, + FunctionExpression: NEEDS_PARENTHESES, + ObjectExpression: NEEDS_PARENTHESES, + // Other operations + UpdateExpression: 16, + UnaryExpression: 15, + AwaitExpression: 15, + BinaryExpression: 14, + LogicalExpression: 13, + ConditionalExpression: 4, + AssignmentExpression: 3, + YieldExpression: 2, + RestElement: 1, +}; diff --git a/src/web/stepper/src/index.ts b/src/web/stepper/src/index.ts new file mode 100644 index 0000000..06387ee --- /dev/null +++ b/src/web/stepper/src/index.ts @@ -0,0 +1,4 @@ +// Conductor's external-plugin loader imports the bundle and reads its `plugin` export, so the host +// plugin class must be exported under that name. +export { StepperHostPlugin as plugin } from "./StepperHostPlugin"; +export type { PluginTab } from "./StepperHostPlugin"; diff --git a/src/web/stepper/src/styles.ts b/src/web/stepper/src/styles.ts new file mode 100644 index 0000000..6af8dbf --- /dev/null +++ b/src/web/stepper/src/styles.ts @@ -0,0 +1,123 @@ +/** + * The stepper's styling, self-contained so the Host plugin needs no styles from the frontend. + * Values are inlined from the frontend's `_stepperVariables.scss` / `_workspace.scss` so the + * rendered output is visually identical to the legacy in-frontend stepper. + */ +const STEPPER_CSS = ` +.sa-substituter .stepper-literal, +.stepper-popover .stepper-literal { color: #ff6078; } +.sa-substituter .stepper-operator, +.stepper-popover .stepper-operator { color: #f89210; } +.sa-substituter .stepper-identifier, +.stepper-popover .stepper-identifier { color: #f8d871; } +.sa-substituter .stepper-conditional-operator, +.stepper-popover .stepper-conditional-operator { color: #ffffff; } + +.sa-substituter .stepper-display { + font: 16px/normal 'Inconsolata', 'Consolas', monospace; + color: #ffffff; + margin-bottom: 16px; +} + +/* The explanation panel wraps a Blueprint
 in a . Blueprint's 
 carries its own
+ * background + inset box-shadow + padding, which reads as a second box nested inside the Card. The
+ * legacy in-frontend stepper avoided this because the REPL's SCSS cascade flattened the 
; this
+ * plugin is self-contained, so flatten it here. Keep the monospace/whitespace formatting; only drop
+ * the box so the Card is the single visible container. The element+2-class selector outranks
+ * Blueprint's '.bp6-dark .bp6-pre'. */
+.sa-substituter pre.result-output {
+  background: transparent;
+  box-shadow: none;
+  margin: 0;
+  padding: 0;
+  color: #ffffff;
+  white-space: pre-wrap;
+  word-break: break-word;
+  font: 16px/normal 'Inconsolata', 'Consolas', monospace;
+}
+.stepper-popover .stepper-display {
+  font: 16px/normal 'Inconsolata', 'Consolas', monospace;
+}
+
+.sa-substituter .stepper-mu-term,
+.stepper-popover .stepper-mu-term {
+  font-weight: bold;
+  pointer-events: auto;
+  cursor: pointer;
+  z-index: 20;
+  padding: 0px 3px;
+  border-radius: 5px;
+  background: transparent;
+}
+.sa-substituter .stepper-mu-term:hover { background: transparent; }
+
+.sa-substituter .beforeMarker {
+  position: relative;
+  -webkit-box-decoration-break: slice;
+  box-decoration-break: slice;
+  background: rgba(172, 0, 0, 0.75);
+  pointer-events: auto;
+  cursor: pointer;
+  z-index: 20;
+}
+.sa-substituter .beforeMarker:hover { background: rgba(100, 101, 57, 0.75); }
+
+.sa-substituter .afterMarker {
+  position: relative;
+  -webkit-box-decoration-break: clone;
+  box-decoration-break: clone;
+  background: green;
+  pointer-events: auto;
+  cursor: pointer;
+  z-index: 20;
+}
+.sa-substituter .afterMarker:hover { background: rgba(61, 101, 57, 0.75); }
+
+/* Match the legacy stepper's margin around the whole component */
+.sa-substituter {
+  margin: 15px;
+  height: unset;
+}
+
+/* Hide all intermediate slider step labels; only show first and last.
+ * Mirrors the frontend's _workspace.scss rule for #bp6-tab-panel_side-content-tabs_subst_visualiser */
+.sa-substituter .bp6-slider-label,
+.sa-substituter .bp5-slider-label,
+.sa-substituter .bp4-slider-label,
+.sa-substituter .bp3-slider-label {
+  width: max-content;
+  display: none;
+}
+.sa-substituter .bp6-slider-label:first-child,
+.sa-substituter .bp6-slider-label:last-child,
+.sa-substituter .bp5-slider-label:first-child,
+.sa-substituter .bp5-slider-label:last-child,
+.sa-substituter .bp4-slider-label:first-child,
+.sa-substituter .bp4-slider-label:last-child,
+.sa-substituter .bp3-slider-label:first-child,
+.sa-substituter .bp3-slider-label:last-child {
+  display: inline;
+}
+
+/* Match the legacy stepper's explanation card styling */
+.sa-substituter .bp6-card,
+.sa-substituter .bp5-card,
+.sa-substituter .bp4-card,
+.sa-substituter .bp3-card {
+  background-color: #1a2530;
+  padding: 0.4rem 0.6rem 0.4rem 0.6rem;
+  margin: 2rem 0 0.5rem 0;
+}
+`;
+
+const STYLE_ELEMENT_ID = "__sa_stepper_styles";
+
+/** Injects the stepper stylesheet into the document once. No-op outside the browser. */
+export function injectStepperStyles(): void {
+  if (typeof document === "undefined") return;
+  if (document.getElementById(STYLE_ELEMENT_ID)) return;
+  const style = document.createElement("style");
+  style.id = STYLE_ELEMENT_ID;
+  style.textContent = STEPPER_CSS;
+  document.head.appendChild(style);
+}
diff --git a/src/web/stepper/tsconfig.json b/src/web/stepper/tsconfig.json
new file mode 100644
index 0000000..9bcec64
--- /dev/null
+++ b/src/web/stepper/tsconfig.json
@@ -0,0 +1,11 @@
+{
+  "extends": "../tsconfig.json",
+  "exclude": ["./dist"],
+  "include": ["./src"],
+  "compilerOptions": {
+    "declaration": false,
+    "outDir": "./dist",
+    "rootDir": "./src",
+    "types": []
+  }
+}
diff --git a/yarn.lock b/yarn.lock
index 536a9e0..80b2381 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -338,7 +338,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@babel/runtime@npm:^7.5.5":
+"@babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.8.7":
   version: 7.29.7
   resolution: "@babel/runtime@npm:7.29.7"
   checksum: 10c0/ca11572f7146b21e0bde6a9ed4bb6a89eafbee5f0944c7eb54d0d8a2dac962c33638a1d611e14faa71dfbb92b4b5f9236232208568a6b7d5c6f3f39ddb91771e
@@ -388,6 +388,60 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@blueprintjs/colors@npm:^5.1.16":
+  version: 5.1.16
+  resolution: "@blueprintjs/colors@npm:5.1.16"
+  dependencies:
+    tslib: "npm:~2.6.2"
+  checksum: 10c0/e6019c658d48240b69a855d0757d2097282458d60459f26be59458c7b5b3e170bc4d62e7c0b67893f7e1b7bcf46ea6fcd7e4f38e1483f2762aa865080de7b650
+  languageName: node
+  linkType: hard
+
+"@blueprintjs/core@npm:^6.0.0":
+  version: 6.15.0
+  resolution: "@blueprintjs/core@npm:6.15.0"
+  dependencies:
+    "@blueprintjs/colors": "npm:^5.1.16"
+    "@blueprintjs/icons": "npm:^6.10.0"
+    "@floating-ui/react": "npm:^0.27.13"
+    "@popperjs/core": "npm:^2.11.8"
+    classnames: "npm:^2.3.1"
+    normalize.css: "npm:^8.0.1"
+    react-popper: "npm:^2.3.0"
+    react-transition-group: "npm:^4.4.5"
+    tslib: "npm:~2.6.2"
+  peerDependencies:
+    "@types/react": 18
+    react: 18
+    react-dom: 18
+  peerDependenciesMeta:
+    "@types/react":
+      optional: true
+  bin:
+    upgrade-blueprint-2.0.0-rename: scripts/upgrade-blueprint-2.0.0-rename.sh
+    upgrade-blueprint-3.0.0-rename: scripts/upgrade-blueprint-3.0.0-rename.sh
+  checksum: 10c0/f55c325d9eb5c4e8498bfaaeb1e0a2fd5c12c761e3d662a6698d32b94919b3c35fbdb5d38637cbaf692b54aef4b884474de5da733b33b0c965252da99ddec20f
+  languageName: node
+  linkType: hard
+
+"@blueprintjs/icons@npm:^6.10.0":
+  version: 6.10.0
+  resolution: "@blueprintjs/icons@npm:6.10.0"
+  dependencies:
+    change-case: "npm:^4.1.2"
+    classnames: "npm:^2.3.1"
+    tslib: "npm:~2.6.2"
+  peerDependencies:
+    "@types/react": 18
+    react: 18
+    react-dom: 18
+  peerDependenciesMeta:
+    "@types/react":
+      optional: true
+  checksum: 10c0/1111739e69a1ca4273c988d75236e9f2e3cf5b297bda90a74568fcb8edf39eae71dad57ae5d892b303dff28f93e5bb17f575670c1a30245ccb8a458480c60484
+  languageName: node
+  linkType: hard
+
 "@changesets/apply-release-plan@npm:^7.1.1":
   version: 7.1.1
   resolution: "@changesets/apply-release-plan@npm:7.1.1"
@@ -895,6 +949,58 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@floating-ui/core@npm:^1.7.5":
+  version: 1.7.5
+  resolution: "@floating-ui/core@npm:1.7.5"
+  dependencies:
+    "@floating-ui/utils": "npm:^0.2.11"
+  checksum: 10c0/f9c52205e198b231d63a387b09c659aab08c46a1899e0b0bbe147b8b4f048b546f15ba17cb5d2a471da9534f1883d979425e13e5c4ceee67be63e4b0abd4db5d
+  languageName: node
+  linkType: hard
+
+"@floating-ui/dom@npm:^1.7.6":
+  version: 1.7.6
+  resolution: "@floating-ui/dom@npm:1.7.6"
+  dependencies:
+    "@floating-ui/core": "npm:^1.7.5"
+    "@floating-ui/utils": "npm:^0.2.11"
+  checksum: 10c0/5c098e0d7b58c9bc769f276cca1766994c2c9c70c92d091a61bba8b3e9be53c011e0a79a8457fc2fb2f3d91697a26eb52e0a4962ef936dc963b45f58613c212f
+  languageName: node
+  linkType: hard
+
+"@floating-ui/react-dom@npm:^2.1.8":
+  version: 2.1.8
+  resolution: "@floating-ui/react-dom@npm:2.1.8"
+  dependencies:
+    "@floating-ui/dom": "npm:^1.7.6"
+  peerDependencies:
+    react: ">=16.8.0"
+    react-dom: ">=16.8.0"
+  checksum: 10c0/26260ca4bb23b57c73b824062505abf977a008ce6e0463bdacca74f7e49853c4cd1d2bbf1a77c6caa17fa37dfffda2c6c4cd07a8737ebd7474aaff7818401d75
+  languageName: node
+  linkType: hard
+
+"@floating-ui/react@npm:^0.27.13":
+  version: 0.27.19
+  resolution: "@floating-ui/react@npm:0.27.19"
+  dependencies:
+    "@floating-ui/react-dom": "npm:^2.1.8"
+    "@floating-ui/utils": "npm:^0.2.11"
+    tabbable: "npm:^6.0.0"
+  peerDependencies:
+    react: ">=17.0.0"
+    react-dom: ">=17.0.0"
+  checksum: 10c0/2a2cdfd3e67e0606833b63f922ad2a9037974f22b944e1cb8c0991b4c40450f8413d69745c0bbf4646e5ba283747f60d2fdc9a8d289b68b24448e59d81a3a96d
+  languageName: node
+  linkType: hard
+
+"@floating-ui/utils@npm:^0.2.11":
+  version: 0.2.11
+  resolution: "@floating-ui/utils@npm:0.2.11"
+  checksum: 10c0/f4bcea1559bdbb721ecc8e8ead423ac58d6a5b6e70b602cf0810ba6ad4ed1c77211b207faa88b278a9042f0c743133de08a203ed6741c1b6443423332884d5b3
+  languageName: node
+  linkType: hard
+
 "@humanfs/core@npm:^0.19.2":
   version: 0.19.2
   resolution: "@humanfs/core@npm:0.19.2"
@@ -1369,7 +1475,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"@jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0":
+"@jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.5.0, @jridgewell/sourcemap-codec@npm:^1.5.5":
   version: 1.5.5
   resolution: "@jridgewell/sourcemap-codec@npm:1.5.5"
   checksum: 10c0/f9e538f302b63c0ebc06eecb1dd9918dd4289ed36147a0ddce35d6ea4d7ebbda243cda7b2213b6a5e1d8087a298d5cf630fb2bd39329cdecb82017023f6081a0
@@ -1386,6 +1492,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@mantine/hooks@npm:^9.0.0":
+  version: 9.3.0
+  resolution: "@mantine/hooks@npm:9.3.0"
+  peerDependencies:
+    react: ^19.2.0
+  checksum: 10c0/ed95a2551b34719d43d7b195cf05248498f20add736a2e4ec582b677e5a9efb53b562010df79dc9af7db087e76e9ac42192443c9d03f76963b5dba7dfc2e0a63
+  languageName: node
+  linkType: hard
+
 "@manypkg/find-root@npm:^1.1.0":
   version: 1.1.0
   resolution: "@manypkg/find-root@npm:1.1.0"
@@ -1464,6 +1579,33 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@popperjs/core@npm:^2.11.8":
+  version: 2.11.8
+  resolution: "@popperjs/core@npm:2.11.8"
+  checksum: 10c0/4681e682abc006d25eb380d0cf3efc7557043f53b6aea7a5057d0d1e7df849a00e281cd8ea79c902a35a414d7919621fc2ba293ecec05f413598e0b23d5a1e63
+  languageName: node
+  linkType: hard
+
+"@rollup/plugin-commonjs@npm:^28.0.0":
+  version: 28.0.9
+  resolution: "@rollup/plugin-commonjs@npm:28.0.9"
+  dependencies:
+    "@rollup/pluginutils": "npm:^5.0.1"
+    commondir: "npm:^1.0.1"
+    estree-walker: "npm:^2.0.2"
+    fdir: "npm:^6.2.0"
+    is-reference: "npm:1.2.1"
+    magic-string: "npm:^0.30.3"
+    picomatch: "npm:^4.0.2"
+  peerDependencies:
+    rollup: ^2.68.0||^3.0.0||^4.0.0
+  peerDependenciesMeta:
+    rollup:
+      optional: true
+  checksum: 10c0/b7af70614a53c549a1ba1e9647879b644bcf44ec78850f04018b929f4ee414274f867fa438308409a06ef8a3a179ed24c25e4f8ef77eb341dfddd2b0cb88c389
+  languageName: node
+  linkType: hard
+
 "@rollup/plugin-node-resolve@npm:^16.0.3":
   version: 16.0.3
   resolution: "@rollup/plugin-node-resolve@npm:16.0.3"
@@ -1740,6 +1882,22 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@sourceacademy/common-stepper@workspace:*, @sourceacademy/common-stepper@workspace:src/common/stepper":
+  version: 0.0.0-use.local
+  resolution: "@sourceacademy/common-stepper@workspace:src/common/stepper"
+  dependencies:
+    "@rollup/plugin-node-resolve": "npm:^16.0.3"
+    "@rollup/plugin-terser": "npm:^1.0.0"
+    "@rollup/plugin-typescript": "npm:^12.3.0"
+    "@types/jest": "npm:^30.0.0"
+    jest: "npm:^30.4.2"
+    rollup: "npm:^4.60.2"
+    ts-jest: "npm:^29.4.11"
+    tslib: "npm:^2.8.1"
+    typescript: "npm:^6.0.3"
+  languageName: unknown
+  linkType: soft
+
 "@sourceacademy/common-test@workspace:*, @sourceacademy/common-test@workspace:src/common/test":
   version: 0.0.0-use.local
   resolution: "@sourceacademy/common-test@workspace:src/common/test"
@@ -1763,6 +1921,26 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@sourceacademy/runner-stepper@workspace:src/runner/stepper":
+  version: 0.0.0-use.local
+  resolution: "@sourceacademy/runner-stepper@workspace:src/runner/stepper"
+  dependencies:
+    "@rollup/plugin-node-resolve": "npm:^16.0.3"
+    "@rollup/plugin-terser": "npm:^1.0.0"
+    "@rollup/plugin-typescript": "npm:^12.3.0"
+    "@sourceacademy/common-stepper": "workspace:*"
+    "@sourceacademy/conductor": "npm:>=0.3.0"
+    "@types/jest": "npm:^30.0.0"
+    jest: "npm:^30.4.2"
+    rollup: "npm:^4.60.2"
+    ts-jest: "npm:^29.4.11"
+    tslib: "npm:^2.8.1"
+    typescript: "npm:^6.0.3"
+  peerDependencies:
+    "@sourceacademy/conductor": ">=0.3.0"
+  languageName: unknown
+  linkType: soft
+
 "@sourceacademy/runner-test@workspace:src/runner/test":
   version: 0.0.0-use.local
   resolution: "@sourceacademy/runner-test@workspace:src/runner/test"
@@ -1783,6 +1961,32 @@ __metadata:
   languageName: unknown
   linkType: soft
 
+"@sourceacademy/web-stepper@workspace:src/web/stepper":
+  version: 0.0.0-use.local
+  resolution: "@sourceacademy/web-stepper@workspace:src/web/stepper"
+  dependencies:
+    "@blueprintjs/core": "npm:^6.0.0"
+    "@mantine/hooks": "npm:^9.0.0"
+    "@rollup/plugin-commonjs": "npm:^28.0.0"
+    "@rollup/plugin-node-resolve": "npm:^16.0.3"
+    "@rollup/plugin-terser": "npm:^1.0.0"
+    "@rollup/plugin-typescript": "npm:^12.3.0"
+    "@sourceacademy/common-stepper": "workspace:*"
+    "@sourceacademy/conductor": "npm:>=0.3.0"
+    "@types/react": "npm:^19.0.0"
+    classnames: "npm:^2.3.2"
+    react: "npm:^19.0.0"
+    react-dom: "npm:^19.0.0"
+    rollup: "npm:^4.60.2"
+    tslib: "npm:^2.8.1"
+    typescript: "npm:^6.0.3"
+  peerDependencies:
+    "@blueprintjs/core": ">=5"
+    react: ">=18"
+    react-dom: ">=18"
+  languageName: unknown
+  linkType: soft
+
 "@sourceacademy/web-test@workspace:src/web/test":
   version: 0.0.0-use.local
   resolution: "@sourceacademy/web-test@workspace:src/web/test"
@@ -1858,6 +2062,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@types/estree@npm:*":
+  version: 1.0.9
+  resolution: "@types/estree@npm:1.0.9"
+  checksum: 10c0/3ad3286ca2988cd550dafb8f2ad599c8474868e954fa601a36655bdfefd8039f7c714b8c1c7f2ae219ffbd58bd4660e66fa7479a0120fc02d4777057d4865387
+  languageName: node
+  linkType: hard
+
 "@types/estree@npm:1.0.8, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.6, @types/estree@npm:^1.0.8":
   version: 1.0.8
   resolution: "@types/estree@npm:1.0.8"
@@ -1932,6 +2143,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"@types/react@npm:^19.0.0":
+  version: 19.2.17
+  resolution: "@types/react@npm:19.2.17"
+  dependencies:
+    csstype: "npm:^3.2.2"
+  checksum: 10c0/bc2c4af96b3e480604424de70d5ebda90c5f4b485df471858c0bc2d7d70364b606ec3c4d8579f94f01aa0c6c0591f56bcf14cba5689f5eea4b74250ccdc3a232
+  languageName: node
+  linkType: hard
+
 "@types/resolve@npm:1.20.2":
   version: 1.20.2
   resolution: "@types/resolve@npm:1.20.2"
@@ -2554,6 +2774,16 @@ __metadata:
   languageName: node
   linkType: hard
 
+"camel-case@npm:^4.1.2":
+  version: 4.1.2
+  resolution: "camel-case@npm:4.1.2"
+  dependencies:
+    pascal-case: "npm:^3.1.2"
+    tslib: "npm:^2.0.3"
+  checksum: 10c0/bf9eefaee1f20edbed2e9a442a226793bc72336e2b99e5e48c6b7252b6f70b080fc46d8246ab91939e2af91c36cdd422e0af35161e58dd089590f302f8f64c8a
+  languageName: node
+  linkType: hard
+
 "camelcase@npm:^5.3.1":
   version: 5.3.1
   resolution: "camelcase@npm:5.3.1"
@@ -2575,6 +2805,17 @@ __metadata:
   languageName: node
   linkType: hard
 
+"capital-case@npm:^1.0.4":
+  version: 1.0.4
+  resolution: "capital-case@npm:1.0.4"
+  dependencies:
+    no-case: "npm:^3.0.4"
+    tslib: "npm:^2.0.3"
+    upper-case-first: "npm:^2.0.2"
+  checksum: 10c0/6a034af73401f6e55d91ea35c190bbf8bda21714d4ea8bb8f1799311d123410a80f0875db4e3236dc3f97d74231ff4bf1c8783f2be13d7733c7d990c57387281
+  languageName: node
+  linkType: hard
+
 "chalk@npm:^4.0.0, chalk@npm:^4.1.2":
   version: 4.1.2
   resolution: "chalk@npm:4.1.2"
@@ -2585,6 +2826,26 @@ __metadata:
   languageName: node
   linkType: hard
 
+"change-case@npm:^4.1.2":
+  version: 4.1.2
+  resolution: "change-case@npm:4.1.2"
+  dependencies:
+    camel-case: "npm:^4.1.2"
+    capital-case: "npm:^1.0.4"
+    constant-case: "npm:^3.0.4"
+    dot-case: "npm:^3.0.4"
+    header-case: "npm:^2.0.4"
+    no-case: "npm:^3.0.4"
+    param-case: "npm:^3.0.4"
+    pascal-case: "npm:^3.1.2"
+    path-case: "npm:^3.0.4"
+    sentence-case: "npm:^3.0.4"
+    snake-case: "npm:^3.0.4"
+    tslib: "npm:^2.0.3"
+  checksum: 10c0/95a6e48563cd393241ce18470c7310a8a050304a64b63addac487560ab039ce42b099673d1d293cc10652324d92060de11b5d918179fe3b5af2ee521fb03ca58
+  languageName: node
+  linkType: hard
+
 "char-regex@npm:^1.0.2":
   version: 1.0.2
   resolution: "char-regex@npm:1.0.2"
@@ -2627,6 +2888,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"classnames@npm:^2.3.1, classnames@npm:^2.3.2":
+  version: 2.5.1
+  resolution: "classnames@npm:2.5.1"
+  checksum: 10c0/afff4f77e62cea2d79c39962980bf316bacb0d7c49e13a21adaadb9221e1c6b9d3cdb829d8bb1b23c406f4e740507f37e1dcf506f7e3b7113d17c5bab787aa69
+  languageName: node
+  linkType: hard
+
 "cliui@npm:^8.0.1":
   version: 8.0.1
   resolution: "cliui@npm:8.0.1"
@@ -2682,6 +2950,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"commondir@npm:^1.0.1":
+  version: 1.0.1
+  resolution: "commondir@npm:1.0.1"
+  checksum: 10c0/33a124960e471c25ee19280c9ce31ccc19574b566dc514fe4f4ca4c34fa8b0b57cf437671f5de380e11353ea9426213fca17687dd2ef03134fea2dbc53809fd6
+  languageName: node
+  linkType: hard
+
 "concat-map@npm:0.0.1":
   version: 0.0.1
   resolution: "concat-map@npm:0.0.1"
@@ -2689,6 +2964,17 @@ __metadata:
   languageName: node
   linkType: hard
 
+"constant-case@npm:^3.0.4":
+  version: 3.0.4
+  resolution: "constant-case@npm:3.0.4"
+  dependencies:
+    no-case: "npm:^3.0.4"
+    tslib: "npm:^2.0.3"
+    upper-case: "npm:^2.0.2"
+  checksum: 10c0/91d54f18341fcc491ae66d1086642b0cc564be3e08984d7b7042f8b0a721c8115922f7f11d6a09f13ed96ff326eabae11f9d1eb0335fa9d8b6e39e4df096010e
+  languageName: node
+  linkType: hard
+
 "convert-source-map@npm:^2.0.0":
   version: 2.0.0
   resolution: "convert-source-map@npm:2.0.0"
@@ -2707,6 +2993,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"csstype@npm:^3.0.2, csstype@npm:^3.2.2":
+  version: 3.2.3
+  resolution: "csstype@npm:3.2.3"
+  checksum: 10c0/cd29c51e70fa822f1cecd8641a1445bed7063697469d35633b516e60fe8c1bde04b08f6c5b6022136bb669b64c63d4173af54864510fbb4ee23281801841a3ce
+  languageName: node
+  linkType: hard
+
 "debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.4.3":
   version: 4.4.3
   resolution: "debug@npm:4.4.3"
@@ -2768,6 +3061,26 @@ __metadata:
   languageName: node
   linkType: hard
 
+"dom-helpers@npm:^5.0.1":
+  version: 5.2.1
+  resolution: "dom-helpers@npm:5.2.1"
+  dependencies:
+    "@babel/runtime": "npm:^7.8.7"
+    csstype: "npm:^3.0.2"
+  checksum: 10c0/f735074d66dd759b36b158fa26e9d00c9388ee0e8c9b16af941c38f014a37fc80782de83afefd621681b19ac0501034b4f1c4a3bff5caa1b8667f0212b5e124c
+  languageName: node
+  linkType: hard
+
+"dot-case@npm:^3.0.4":
+  version: 3.0.4
+  resolution: "dot-case@npm:3.0.4"
+  dependencies:
+    no-case: "npm:^3.0.4"
+    tslib: "npm:^2.0.3"
+  checksum: 10c0/5b859ea65097a7ea870e2c91b5768b72ddf7fa947223fd29e167bcdff58fe731d941c48e47a38ec8aa8e43044c8fbd15cd8fa21689a526bc34b6548197cd5b05
+  languageName: node
+  linkType: hard
+
 "eastasianwidth@npm:^0.2.0":
   version: 0.2.0
   resolution: "eastasianwidth@npm:0.2.0"
@@ -3206,7 +3519,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"fdir@npm:^6.5.0":
+"fdir@npm:^6.2.0, fdir@npm:^6.5.0":
   version: 6.5.0
   resolution: "fdir@npm:6.5.0"
   peerDependencies:
@@ -3469,6 +3782,16 @@ __metadata:
   languageName: node
   linkType: hard
 
+"header-case@npm:^2.0.4":
+  version: 2.0.4
+  resolution: "header-case@npm:2.0.4"
+  dependencies:
+    capital-case: "npm:^1.0.4"
+    tslib: "npm:^2.0.3"
+  checksum: 10c0/c9f295d9d8e38fa50679281fd70d80726962256e888a76c8e72e526453da7a1832dcb427caa716c1ad5d79841d4537301b90156fa30298fefd3d68f4ea2181bb
+  languageName: node
+  linkType: hard
+
 "html-escaper@npm:^2.0.0":
   version: 2.0.2
   resolution: "html-escaper@npm:2.0.2"
@@ -3611,6 +3934,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"is-reference@npm:1.2.1":
+  version: 1.2.1
+  resolution: "is-reference@npm:1.2.1"
+  dependencies:
+    "@types/estree": "npm:*"
+  checksum: 10c0/7dc819fc8de7790264a0a5d531164f9f5b9ef5aa1cd05f35322d14db39c8a2ec78fd5d4bf57f9789f3ddd2b3abeea7728432b759636157a42db12a9e8c3b549b
+  languageName: node
+  linkType: hard
+
 "is-stream@npm:^2.0.0":
   version: 2.0.1
   resolution: "is-stream@npm:2.0.1"
@@ -4238,7 +4570,7 @@ __metadata:
   languageName: node
   linkType: hard
 
-"js-tokens@npm:^4.0.0":
+"js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0":
   version: 4.0.0
   resolution: "js-tokens@npm:4.0.0"
   checksum: 10c0/e248708d377aa058eacf2037b07ded847790e6de892bbad3dac0abba2e759cb9f121b00099a65195616badcb6eca8d14d975cb3e89eb1cfda644756402c8aeed
@@ -4391,6 +4723,26 @@ __metadata:
   languageName: node
   linkType: hard
 
+"loose-envify@npm:^1.0.0, loose-envify@npm:^1.4.0":
+  version: 1.4.0
+  resolution: "loose-envify@npm:1.4.0"
+  dependencies:
+    js-tokens: "npm:^3.0.0 || ^4.0.0"
+  bin:
+    loose-envify: cli.js
+  checksum: 10c0/655d110220983c1a4b9c0c679a2e8016d4b67f6e9c7b5435ff5979ecdb20d0813f4dec0a08674fcbdd4846a3f07edbb50a36811fd37930b94aaa0d9daceb017e
+  languageName: node
+  linkType: hard
+
+"lower-case@npm:^2.0.2":
+  version: 2.0.2
+  resolution: "lower-case@npm:2.0.2"
+  dependencies:
+    tslib: "npm:^2.0.3"
+  checksum: 10c0/3d925e090315cf7dc1caa358e0477e186ffa23947740e4314a7429b6e62d72742e0bbe7536a5ae56d19d7618ce998aba05caca53c2902bd5742fdca5fc57fd7b
+  languageName: node
+  linkType: hard
+
 "lru-cache@npm:^10.2.0":
   version: 10.4.3
   resolution: "lru-cache@npm:10.4.3"
@@ -4407,6 +4759,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"magic-string@npm:^0.30.3":
+  version: 0.30.21
+  resolution: "magic-string@npm:0.30.21"
+  dependencies:
+    "@jridgewell/sourcemap-codec": "npm:^1.5.5"
+  checksum: 10c0/299378e38f9a270069fc62358522ddfb44e94244baa0d6a8980ab2a9b2490a1d03b236b447eee309e17eb3bddfa482c61259d47960eb018a904f0ded52780c4a
+  languageName: node
+  linkType: hard
+
 "make-dir@npm:^4.0.0":
   version: 4.0.0
   resolution: "make-dir@npm:4.0.0"
@@ -4550,6 +4911,16 @@ __metadata:
   languageName: node
   linkType: hard
 
+"no-case@npm:^3.0.4":
+  version: 3.0.4
+  resolution: "no-case@npm:3.0.4"
+  dependencies:
+    lower-case: "npm:^2.0.2"
+    tslib: "npm:^2.0.3"
+  checksum: 10c0/8ef545f0b3f8677c848f86ecbd42ca0ff3cd9dd71c158527b344c69ba14710d816d8489c746b6ca225e7b615108938a0bda0a54706f8c255933703ac1cf8e703
+  languageName: node
+  linkType: hard
+
 "node-gyp@npm:latest":
   version: 12.3.0
   resolution: "node-gyp@npm:12.3.0"
@@ -4602,6 +4973,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"normalize.css@npm:^8.0.1":
+  version: 8.0.1
+  resolution: "normalize.css@npm:8.0.1"
+  checksum: 10c0/4ddf56d1af5ca755fa5e692e718316d8758ecb792aa96e1ad206824b5810a043763d681d6f7697d46573515f5e9690038b4c91a95c1997567128815545fb8cd7
+  languageName: node
+  linkType: hard
+
 "npm-run-path@npm:^4.0.1":
   version: 4.0.1
   resolution: "npm-run-path@npm:4.0.1"
@@ -4611,6 +4989,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"object-assign@npm:^4.1.1":
+  version: 4.1.1
+  resolution: "object-assign@npm:4.1.1"
+  checksum: 10c0/1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414
+  languageName: node
+  linkType: hard
+
 "once@npm:^1.3.0":
   version: 1.4.0
   resolution: "once@npm:1.4.0"
@@ -4725,6 +5110,16 @@ __metadata:
   languageName: node
   linkType: hard
 
+"param-case@npm:^3.0.4":
+  version: 3.0.4
+  resolution: "param-case@npm:3.0.4"
+  dependencies:
+    dot-case: "npm:^3.0.4"
+    tslib: "npm:^2.0.3"
+  checksum: 10c0/ccc053f3019f878eca10e70ec546d92f51a592f762917dafab11c8b532715dcff58356118a6f350976e4ab109e321756f05739643ed0ca94298e82291e6f9e76
+  languageName: node
+  linkType: hard
+
 "parse-json@npm:^5.2.0":
   version: 5.2.0
   resolution: "parse-json@npm:5.2.0"
@@ -4737,6 +5132,26 @@ __metadata:
   languageName: node
   linkType: hard
 
+"pascal-case@npm:^3.1.2":
+  version: 3.1.2
+  resolution: "pascal-case@npm:3.1.2"
+  dependencies:
+    no-case: "npm:^3.0.4"
+    tslib: "npm:^2.0.3"
+  checksum: 10c0/05ff7c344809fd272fc5030ae0ee3da8e4e63f36d47a1e0a4855ca59736254192c5a27b5822ed4bae96e54048eec5f6907713cfcfff7cdf7a464eaf7490786d8
+  languageName: node
+  linkType: hard
+
+"path-case@npm:^3.0.4":
+  version: 3.0.4
+  resolution: "path-case@npm:3.0.4"
+  dependencies:
+    dot-case: "npm:^3.0.4"
+    tslib: "npm:^2.0.3"
+  checksum: 10c0/b6b14637228a558793f603aaeb2fcd981e738b8b9319421b713532fba96d75aa94024b9f6b9ae5aa33d86755144a5b36697d28db62ae45527dbd672fcc2cf0b7
+  languageName: node
+  linkType: hard
+
 "path-exists@npm:^4.0.0":
   version: 4.0.0
   resolution: "path-exists@npm:4.0.0"
@@ -4901,6 +5316,17 @@ __metadata:
   languageName: node
   linkType: hard
 
+"prop-types@npm:^15.6.2":
+  version: 15.8.1
+  resolution: "prop-types@npm:15.8.1"
+  dependencies:
+    loose-envify: "npm:^1.4.0"
+    object-assign: "npm:^4.1.1"
+    react-is: "npm:^16.13.1"
+  checksum: 10c0/59ece7ca2fb9838031d73a48d4becb9a7cc1ed10e610517c7d8f19a1e02fa47f7c27d557d8a5702bec3cfeccddc853579832b43f449e54635803f277b1c78077
+  languageName: node
+  linkType: hard
+
 "punycode@npm:^2.1.0":
   version: 2.3.1
   resolution: "punycode@npm:2.3.1"
@@ -4929,6 +5355,24 @@ __metadata:
   languageName: node
   linkType: hard
 
+"react-dom@npm:^19.0.0":
+  version: 19.2.7
+  resolution: "react-dom@npm:19.2.7"
+  dependencies:
+    scheduler: "npm:^0.27.0"
+  peerDependencies:
+    react: ^19.2.7
+  checksum: 10c0/970ff600f6e80d47d39e2f226f12f226173b3cba3382efc97c5f0cd663de9af38c7a4c11c213fb936094faeac83060d660247accaa96b752180d5b951b9cfecb
+  languageName: node
+  linkType: hard
+
+"react-fast-compare@npm:^3.0.1":
+  version: 3.2.2
+  resolution: "react-fast-compare@npm:3.2.2"
+  checksum: 10c0/0bbd2f3eb41ab2ff7380daaa55105db698d965c396df73e6874831dbafec8c4b5b08ba36ff09df01526caa3c61595247e3269558c284e37646241cba2b90a367
+  languageName: node
+  linkType: hard
+
 "react-is-18@npm:react-is@^18.3.1, react-is@npm:^18.3.1":
   version: 18.3.1
   resolution: "react-is@npm:18.3.1"
@@ -4943,6 +5387,49 @@ __metadata:
   languageName: node
   linkType: hard
 
+"react-is@npm:^16.13.1":
+  version: 16.13.1
+  resolution: "react-is@npm:16.13.1"
+  checksum: 10c0/33977da7a5f1a287936a0c85639fec6ca74f4f15ef1e59a6bc20338fc73dc69555381e211f7a3529b8150a1f71e4225525b41b60b52965bda53ce7d47377ada1
+  languageName: node
+  linkType: hard
+
+"react-popper@npm:^2.3.0":
+  version: 2.3.0
+  resolution: "react-popper@npm:2.3.0"
+  dependencies:
+    react-fast-compare: "npm:^3.0.1"
+    warning: "npm:^4.0.2"
+  peerDependencies:
+    "@popperjs/core": ^2.0.0
+    react: ^16.8.0 || ^17 || ^18
+    react-dom: ^16.8.0 || ^17 || ^18
+  checksum: 10c0/23f93540537ca4c035425bb8d5e51b11131fbc921d7ac1d041d0ae557feac8c877f3a012d36b94df8787803f52ed81e6df9257ac9e58719875f7805518d6db3f
+  languageName: node
+  linkType: hard
+
+"react-transition-group@npm:^4.4.5":
+  version: 4.4.5
+  resolution: "react-transition-group@npm:4.4.5"
+  dependencies:
+    "@babel/runtime": "npm:^7.5.5"
+    dom-helpers: "npm:^5.0.1"
+    loose-envify: "npm:^1.4.0"
+    prop-types: "npm:^15.6.2"
+  peerDependencies:
+    react: ">=16.6.0"
+    react-dom: ">=16.6.0"
+  checksum: 10c0/2ba754ba748faefa15f87c96dfa700d5525054a0141de8c75763aae6734af0740e77e11261a1e8f4ffc08fd9ab78510122e05c21c2d79066c38bb6861a886c82
+  languageName: node
+  linkType: hard
+
+"react@npm:^19.0.0":
+  version: 19.2.7
+  resolution: "react@npm:19.2.7"
+  checksum: 10c0/0bd0e2f1bbd4ba97561c6597bf8a5fec05e6476fe61e165c1065598d16668efc6715205599c94d3ddd49d36cb0f21cbf1b9bcc18ee840b805ce222c3e8d558ac
+  languageName: node
+  linkType: hard
+
 "read-yaml-file@npm:^1.1.0":
   version: 1.1.0
   resolution: "read-yaml-file@npm:1.1.0"
@@ -5119,6 +5606,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"scheduler@npm:^0.27.0":
+  version: 0.27.0
+  resolution: "scheduler@npm:0.27.0"
+  checksum: 10c0/4f03048cb05a3c8fddc45813052251eca00688f413a3cee236d984a161da28db28ba71bd11e7a3dd02f7af84ab28d39fb311431d3b3772fed557945beb00c452
+  languageName: node
+  linkType: hard
+
 "semver@npm:^6.3.1":
   version: 6.3.1
   resolution: "semver@npm:6.3.1"
@@ -5146,6 +5640,17 @@ __metadata:
   languageName: node
   linkType: hard
 
+"sentence-case@npm:^3.0.4":
+  version: 3.0.4
+  resolution: "sentence-case@npm:3.0.4"
+  dependencies:
+    no-case: "npm:^3.0.4"
+    tslib: "npm:^2.0.3"
+    upper-case-first: "npm:^2.0.2"
+  checksum: 10c0/9a90527a51300cf5faea7fae0c037728f9ddcff23ac083883774c74d180c0a03c31aab43d5c3347512e8c1b31a0d4712512ec82beb71aa79b85149f9abeb5467
+  languageName: node
+  linkType: hard
+
 "serialize-javascript@npm:^7.0.3":
   version: 7.0.5
   resolution: "serialize-javascript@npm:7.0.5"
@@ -5197,6 +5702,16 @@ __metadata:
   languageName: node
   linkType: hard
 
+"snake-case@npm:^3.0.4":
+  version: 3.0.4
+  resolution: "snake-case@npm:3.0.4"
+  dependencies:
+    dot-case: "npm:^3.0.4"
+    tslib: "npm:^2.0.3"
+  checksum: 10c0/ab19a913969f58f4474fe9f6e8a026c8a2142a01f40b52b79368068343177f818cdfef0b0c6b9558f298782441d5ca8ed5932eb57822439fad791d866e62cecd
+  languageName: node
+  linkType: hard
+
 "source-map-support@npm:0.5.13":
   version: 0.5.13
   resolution: "source-map-support@npm:0.5.13"
@@ -5362,6 +5877,13 @@ __metadata:
   languageName: node
   linkType: hard
 
+"tabbable@npm:^6.0.0":
+  version: 6.4.0
+  resolution: "tabbable@npm:6.4.0"
+  checksum: 10c0/d931427f4a96b801fd8801ba296a702119e06f70ad262fed8abc5271225c9f1ca51b89fdec4fb2f22e1d35acb3d2881db0a17cedc758272e9ecb540d00299d76
+  languageName: node
+  linkType: hard
+
 "tar@npm:^7.5.4":
   version: 7.5.13
   resolution: "tar@npm:7.5.13"
@@ -5482,13 +6004,20 @@ __metadata:
   languageName: node
   linkType: hard
 
-"tslib@npm:^2.4.0, tslib@npm:^2.8.1":
+"tslib@npm:^2.0.3, tslib@npm:^2.4.0, tslib@npm:^2.8.1":
   version: 2.8.1
   resolution: "tslib@npm:2.8.1"
   checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62
   languageName: node
   linkType: hard
 
+"tslib@npm:~2.6.2":
+  version: 2.6.3
+  resolution: "tslib@npm:2.6.3"
+  checksum: 10c0/2598aef53d9dbe711af75522464b2104724d6467b26a60f2bdac8297d2b5f1f6b86a71f61717384aa8fd897240467aaa7bcc36a0700a0faf751293d1331db39a
+  languageName: node
+  linkType: hard
+
 "tsx@npm:^4.22.3":
   version: 4.22.3
   resolution: "tsx@npm:4.22.3"
@@ -5687,6 +6216,24 @@ __metadata:
   languageName: node
   linkType: hard
 
+"upper-case-first@npm:^2.0.2":
+  version: 2.0.2
+  resolution: "upper-case-first@npm:2.0.2"
+  dependencies:
+    tslib: "npm:^2.0.3"
+  checksum: 10c0/ccad6a0b143310ebfba2b5841f30bef71246297385f1329c022c902b2b5fc5aee009faf1ac9da5ab3ba7f615b88f5dc1cd80461b18a8f38cb1d4c3eb92538ea9
+  languageName: node
+  linkType: hard
+
+"upper-case@npm:^2.0.2":
+  version: 2.0.2
+  resolution: "upper-case@npm:2.0.2"
+  dependencies:
+    tslib: "npm:^2.0.3"
+  checksum: 10c0/5ac176c9d3757abb71400df167f9abb46d63152d5797c630d1a9f083fbabd89711fb4b3dc6de06ff0138fe8946fa5b8518b4fcdae9ca8a3e341417075beae069
+  languageName: node
+  linkType: hard
+
 "uri-js@npm:^4.2.2":
   version: 4.4.1
   resolution: "uri-js@npm:4.4.1"
@@ -5716,6 +6263,15 @@ __metadata:
   languageName: node
   linkType: hard
 
+"warning@npm:^4.0.2":
+  version: 4.0.3
+  resolution: "warning@npm:4.0.3"
+  dependencies:
+    loose-envify: "npm:^1.0.0"
+  checksum: 10c0/aebab445129f3e104c271f1637fa38e55eb25f968593e3825bd2f7a12bd58dc3738bb70dc8ec85826621d80b4acfed5a29ebc9da17397c6125864d72301b937e
+  languageName: node
+  linkType: hard
+
 "which@npm:^2.0.1":
   version: 2.0.2
   resolution: "which@npm:2.0.2"