diff --git a/.commitlintrc b/.commitlintrc new file mode 100644 index 0000000..c30e5a9 --- /dev/null +++ b/.commitlintrc @@ -0,0 +1,3 @@ +{ + "extends": ["@commitlint/config-conventional"] +} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 8517a6d..28e140d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,76 +1,85 @@ name: Release on: + workflow_dispatch: + inputs: + branch: + description: 'The branch to release from (e.g., main, beta, next). Semantic-release must be configured for this branch.' + required: true + default: 'main' push: branches: - main + - beta jobs: build: strategy: fail-fast: false - runs-on: ubuntu-latest + runs-on: windows-latest steps: - name: Checkout uses: actions/checkout@v4 with: persist-credentials: false - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: '3.13' - - - name: Install GCC - id: install-gcc - uses: awalsh128/cache-apt-pkgs-action@latest - with: - packages: build-essential@latest - version: 1.0 - - name: Setup Bun uses: oven-sh/setup-bun@v2 with: bun-version: latest - - name: Install node-gyp - run: bun add -g node-gyp - - name: Install dependencies - run: bun install --ignore-scripts --frozen-lockfile + run: bun install --frozen-lockfile + + - name: Setup zig + uses: mlugg/setup-zig@v1 - name: Build - run: bun run build + run: bun run build.ts - # - name: Upload artifact - # uses: actions/upload-artifact@v4 - # with: - # name: memoryjs - # path: lib/ + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: memoryprocess + path: lib/ - # release: - # needs: [build] - # runs-on: ubuntu-latest - # steps: - # - name: Checkout - # uses: actions/checkout@v4 - # with: - # ref: ${{ github.event.inputs.checkout-branch }} - # submodules: true + release: + needs: [build] + runs-on: ubuntu-latest + permissions: + contents: write + issues: write + pull-requests: write + id-token: write + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + ref: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.branch || github.ref }} + persist-credentials: false - # - name: Download artifacts - # uses: actions/download-artifact@v4.1.7 - # with: - # name: memoryjs - # path: lib/ + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: memoryprocess + path: lib/ + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' - # - name: Setup Node - # uses: actions/setup-node@v4 - # with: - # node-version: '20' - # registry-url: 'https://registry.npmjs.org' - # env: - # NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} + - name: Configure npm + run: | + echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc + npm whoami + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - # - name: Publish release - # run: npm publish --access public \ No newline at end of file + - name: Run semantic-release + run: npx semantic-release + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} \ No newline at end of file diff --git a/.releaserc b/.releaserc new file mode 100644 index 0000000..a0c9b69 --- /dev/null +++ b/.releaserc @@ -0,0 +1,20 @@ +{ + "branches": [ + "main", + { "name": "beta", "prerelease": true }, + { "name": "alpha", "prerelease": true } + ], + "plugins": [ + "@semantic-release/commit-analyzer", + "@semantic-release/release-note-generator", + "@semantic-release/npm", + "@semantic-release/github", + [ + "@semantic-release/git", + { + "assets": ["package.json", "CHANGELOG.md"], + "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" + } + ] + ] +} diff --git a/LICENSE.md b/LICENSE.md index 2f2e53a..884d213 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ -The MIT License (MIT) +MIT License -Copyright (c) 2019 Robert Valentyne +Copyright (c) 2025 JoShMiQueL Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -18,5 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 910a241..ec2e6f5 100644 --- a/README.md +++ b/README.md @@ -1,806 +1,66 @@ +> [!WARNING] +> This package relies heavily on **Bun's native FFI (`bun:ffi`)** for performance and interacting with system APIs. +> +> Currently, Bun does not provide a polyfill for `bun:ffi` when building for Node.js (`target: 'node'`). Therefore, this package is **only compatible with the Bun runtime** and **will not work** if run directly with Node.js. +> +> While Bun intends to add polyfills for `bun:*` modules in the future to improve Node.js compatibility for bundled code (see [Bundler Docs](https://bun.sh/docs/bundler#target)), this is not yet implemented for `bun:ffi`. +> +> **Requirements:** +> * Bun v1.2.9 or later (required to run the code) + +--- +

- + Banner + MemoryProcess is an NPM package to read and write process memory
- @joshmiquel/memoryjs is an NPM package to read and write process memory, now with Bun.js support! -

- This is a fork of the original memoryjs package, maintained by JoShMiQueL with added Bun.js support. + This is a fork of the original memoryjs package, maintained by JoShMiQueL

- GitHub License - - GitHub Actions Workflow Status + GitHub License + + GitHub Actions Workflow Status - - NPM Downloads + + NPM Downloads - - NPM Version + + NPM Version

---- - -

- Features • - Getting Started • - Usage • - Documentation • - Debug -

- - -# Features - -- List all open processes -- List all modules associated with a process -- Close process/file handles -- Find a specific module within a process -- Read and write process memory (w/big-endian support) -- Read and write buffers (arbitrary structs) -- Change memory protection -- Reserve/allocate, commit or change regions of memory -- Fetch a list of memory regions within a process -- Pattern scanning -- Execute a function within a process -- Hardware breakpoints (find out what accesses/writes to this address, etc) -- Inject & unload DLLs -- Read memory mapped files -- ESModule support -- Full TypeScript support with built-in type definitions - -## Future Plans - -This fork is actively working on migrating the project to be a native Bun.js package, which will bring several improvements: - -- Native compilation using Bun's C API instead of node-gyp -- Better performance through Bun's optimizations -- Simplified installation process -- Enhanced TypeScript support - -## TODO -- WriteFile support (for driver interactions) -- Async/await support -- Migrate to [Bun's C API](https://bun.sh/blog/compile-and-run-c-in-js) to remove node-gyp dependency - -# Getting Started - -## Install - -This is a Node add-on (last tested to be working on Node.js `v14.15.0` and Bun.js `v1.0.25`) and requires [node-gyp](https://github.com/nodejs/node-gyp) to build the native modules. +## Current Status -Both Node.js and Bun.js users need to [follow these steps](https://github.com/nodejs/node-gyp#user-content-installation) to install and setup `node-gyp`. +This package is currently under active development. The following core functions are implemented and available for use: -```bash -# Using npm -npm install memoryjs +* `openProcess(processIdentifier: string | number): ProcessInfo`: Opens a process by its name or ID. +* `closeProcess(handle: number): void`: Closes an opened process handle. +* `readMemory(handle: number, address: number, dataType: string): any`: Reads memory from a specific address in the target process. +* `writeMemory(handle: number, address: number, value: any, dataType: string): void`: Writes memory to a specific address in the target process. -# Using bun -bun add memoryjs -``` - -When using memoryjs, the target process should match the platform architecture of the Node version running. -For example if you want to target a 64 bit process, you should try and use a 64 bit version of Node. - -You also need to recompile the library and target the platform you want. Head to the memoryjs node module directory, open up a terminal and run one of the following compile scripts: - -```bash -# Using npm - will automatically compile based on the detected Node architecture -npm run build - -# Using bun - will automatically compile based on the detected Node architecture -bun run build - -# compile to target 32 bit processes -npm run build32 -# or with bun -bun run build32 - -# compile to target 64 bit processes -npm run build64 -# or with bun -bun run build64 -``` - -## Node Webkit / Electron - -If you are planning to use this module with Node Webkit or Electron, take a look at [Liam Mitchell](https://github.com/LiamKarlMitchell)'s build notes [here](https://github.com/Rob--/memoryjs/issues/23). - -# Usage - -## Import -``` javascript -// CommonJS -const memoryjs = require('memoryjs'); - -// ESModule -import memoryjs from 'memoryjs'; - -// TypeScript -import memoryjs, { ProcessObject, ModuleObject } from 'memoryjs'; - -// Initialize -const processName = "csgo.exe"; -const process = memoryjs.openProcess(processName); -``` - -## TypeScript Support -The package includes built-in TypeScript definitions. All functions, objects, and constants are fully typed: +The `ProcessInfo` object returned by `openProcess` contains information about the opened process: ```typescript -// Types are available for all returned objects -const process: ProcessObject = memoryjs.openProcess(processName); -const module: ModuleObject = memoryjs.findModule('kernel32.dll', process.th32ProcessID); - -// Enums and constants are also typed -import { DataType, ProtectionFlags } from 'memoryjs'; - -// Read memory with type safety -const value: number = memoryjs.readMemory(process.handle, address, DataType.INT); - -// Protection flags with TypeScript enums -const oldProtection = memoryjs.virtualProtectEx( - process.handle, - address, - size, - ProtectionFlags.PAGE_EXECUTE_READWRITE -); -``` - -## Processes -- Open a process -- Get all processes -- Close a process (release handle) - -```javascript -// sync: open a process -const processObject = memoryjs.openProcess(processName); - -// async: open a process -memoryjs.openProcess(processName, (error, processObject) => {}); - - -// sync: get all processes -const processes = memoryjs.getProcesses(); - -// async: get all processes -memoryjs.getProcesses((error, processes) => {}); - - -// close a process (release handle) -memoryjs.closeHandle(handle); -``` - -See the [Documentation](#user-content-process-object) section of this README to see what a process object looks like. - -## Modules -- Find a module -- Get all modules - -``` javascript -// sync: find a module -const moduleObject = memoryjs.findModule(moduleName, processId); - -// async: find a module -memoryjs.findModule(moduleName, processId, (error, moduleObject) => {}); - - -// sync: get all modules -const modules = memoryjs.getModules(processId); - -// async: get all modules -memoryjs.getModules(processId, (error, modules) => {}); -``` - -See the [Documentation](#user-content-module-object) section of this README to see what a module object looks like. - -## Memory -- Read data type from memory -- Read buffer from memory -- Write data type to memory -- Write buffer to memory -- Fetch memory regions - -``` javascript -// sync: read data type from memory -const value = memoryjs.readMemory(handle, address, dataType); - -// async: read data type from memory -memoryjs.readMemory(handle, address, dataType, (error, value) => {}); - - -// sync: read buffer from memory -const buffer = memoryjs.readBuffer(handle, address, size); - -// async: read buffer from memory -memoryjs.readBuffer(handle, address, size, (error, buffer) => {}); - - -// sync: write data type to memory -memoryjs.writeMemory(handle, address, value, dataType); - - -// sync: write buffer to memory -memoryjs.writeBuffer(handle, address, buffer); - - -// sync: fetch memory regions -const regions = memoryjs.getRegions(handle); - -// async: fetch memory regions -memoryjs.getRegions(handle, (regions) => {}); -``` - -See the [Documentation](#user-content-documentation) section of this README to see what values `dataType` can be. - -## Memory Mapped Files -- Open a named file mapping object -- Map a view of a file into a specified process -- Close handle to the file mapping object - -```javascript -// sync: open a named file mapping object -const fileHandle = memoryjs.openFileMapping(fileName); - - -// sync: map entire file into a specified process -const baseAddress = memoryjs.mapViewOfFile(processHandle, fileName); - - -// sync: map portion of a file into a specified process -const baseAddress = memoryjs.mapViewOfFile(processHandle, fileName, offset, viewSize, pageProtection); - - -// sync: close handle to a file mapping object -const success = memoryjs.closeHandle(fileHandle); -``` - -See the [Documentation](#user-content-documentation) section of this README to see details on the parameters and return values for these functions. - -## Protection -- Change/set the protection on a region of memory - -```javascript -// sync: change/set the protection on a region of memory -const oldProtection = memoryjs.virtualProtectEx(handle, address, size, protection); -``` - -See the [Documentation](#user-content-protection-type) section of this README to see what values `protection` can be. - -## Pattern Scanning -- Pattern scan all modules and memory regions -- Pattern scan a given module -- Pattern scan a memory region or module at the given base address - -```javascript -// sync: pattern scan all modules and memory regions -const address = memoryjs.findPattern(handle, pattern, flags, patternOffset); - -// async: pattern scan all modules and memory regions -memoryjs.findPattern(handle, pattern, flags, patternOffset, (error, address) => {}); - - -// sync: pattern scan a given module -const address = memoryjs.findPattern(handle, moduleName, pattern, flags, patternOffset); - -// async: pattern scan a given module -memoryjs.findPattern(handle, moduleName, pattern, flags, patternOffset, (error, address) => {}); - - -// sync: pattern scan a memory region or module at the given base address -const address = memoryjs.findPattern(handle, baseAddress, pattern, flags, patternOffset); - -// async: pattern scan a memory region or module at the given base address -memoryjs.findPattern(handle, baseAddress, pattern, flags, patternOffset, (error, address) => {}); -``` - -## Function Execution -- Execute a function in a remote process - -``` javascript -// sync: execute a function in a remote process -const result = memoryjs.callFunction(handle, args, returnType, address); - -// async: execute a function in a remote process -memoryjs.callFunction(handle, args, returnType, address, (error, result) => {}); -``` - -Click [here](#user-content-result-object) to see what a result object looks like. - -Click [here](#user-content-function-execution-1) for details about how to format the arguments and the return type. - -## DLL Injection -- Inject a DLL -- Unload a DLL by module base address -- Unload a DLL by module name - -```javascript -// sync: inject a DLL -const success = memoryjs.injectDll(handle, dllPath); - -// async: inject a DLL -memoryjs.injectDll(handle, dllPath, (error, success) => {}); - - -// sync: unload a DLL by module base address -const success = memoryjs.unloadDll(handle, moduleBaseAddress); - -// async: unload a DLL by module base address -memoryjs.unloadDll(handle, moduleBaseAddress, (error, success) => {}); - - -// sync: unload a DLL by module name -const success = memoryjs.unloadDll(handle, moduleName); - -// async: unload a DLL by module name -memoryjs.unloadDll(handle, moduleName, (error, success) => {}); -``` - -## Hardware Breakpoints -- Attach debugger -- Detach debugger -- Wait for debug event -- Handle debug event -- Set hardware breakpoint -- Remove hardware breakpoint - -``` javascript -// sync: attach debugger -const success = memoryjs.attachDebugger(processId, exitOnDetach); - -// sync: detach debugger -const success = memoryjs.detachDebugger(processId); - -// sync: wait for debug event -const success = memoryjs.awaitDebugEvent(hardwareRegister, millisTimeout); - -// sync: handle debug event -const success = memoryjs.handleDebugEvent(processId, threadId); - -// sync: set hardware breakpoint -const success = memoryjs.setHardwareBreakpoint(processId, address, hardwareRegister, trigger, length); - -// sync: remove hardware breakpoint -const success = memoryjs.removeHardwareBreakpoint(processId, hardwareRegister); -``` - -# Documentation - -Note: this documentation is currently being updated, refer to the [Wiki](https://github.com/Rob--/memoryjs/wiki) for more information. - -## Process Object -``` javascript -{ dwSize: 304, - th32ProcessID: 10316, - cntThreads: 47, - th32ParentProcessID: 7804, - pcPriClassBase: 8, - szExeFile: "csgo.exe", - modBaseAddr: 1673789440, - handle: 808 } -``` - -The `handle` and `modBaseAddr` properties are only available when opening a process and not when listing processes. - -## Module Object -``` javascript -{ modBaseAddr: 468123648, - modBaseSize: 80302080, - szExePath: 'c:\\program files (x86)\\steam\\steamapps\\common\\counter-strike global offensive\\csgo\\bin\\client.dll', - szModule: 'client.dll', - th32ProcessID: 10316, - GlblcntUsage: 2 } - ``` - -## Result Object -``` javascript -{ returnValue: 1.23, - exitCode: 2 } -``` - -This object is returned when a function is executed in a remote process: -- `returnValue` is the value returned from the function that was called -- `exitCode` is the termination status of the thread - -## Data Types - -When using the write or read functions, the data type (dataType) parameter should reference a constant from within the library: - -| Constant | Bytes | Aliases | Range | -|-------------------|-------|------------------------------------|-------| -| `memoryjs.BOOL` | 1 | `memoryjs.BOOLEAN` | 0 to 1 | -| `memoryjs.INT8` | 1 | `memoryjs.BYTE`, `memoryjs.CHAR` | -128 to 127 | -| `memoryjs.UINT8` | 1 | `memoryjs.UBYTE`, `memoryjs.UCHAR` | 0 to 255 | -| `memoryjs.INT16` | 2 | `memoryjs.SHORT` | -32,768 to 32,767 | -| `memoryjs.UINT16` | 2 | `memoryjs.USHORT`, `memoryjs.WORD` | 0 to 65,535 | -| `memoryjs.INT32` | 4 | `memoryjs.INT`, `memoryjs.LONG` | -2,147,483,648 to 2,147,483,647 | -| `memoryjs.UINT32` | 4 | `memoryjs.UINT`, `memoryjs.ULONG`, `memoryjs.DWORD` | 0 to 4,294,967,295 | -| `memoryjs.INT64` | 8 | n/a | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 | -| `memoryjs.UINT64` | 8 | n/a | 0 to 18,446,744,073,709,551,615 | -| `memoryjs.FLOAT` | 4 | n/a | 3.4E +/- 38 (7 digits) | -| `memoryjs.DOUBLE` | 8 | n/a | 1.7E +/- 308 (15 digits) | -| `memoryjs.PTR` | 4/8 | `memoryjs.POINTER` | n/a | -| `memoryjs.UPTR` | 4/8 | `memoryjs.UPOINTER` | n/a | -| `memoryjs.STR` | n/a | `memoryjs.STRING` | n/a | -| `memoryjs.VEC3` | 12 | `memoryjs.VECTOR3` | n/a | -| `memoryjs.VEC4` | 16 | `memoryjs.VECTOR4` | n/a | - - -Notes: -- all functions that accept an address also accept the address as a BigInt -- pointer will be 4 bytes in a 32 bit build, and 8 bytes in a 64 bit build. -- to read in big-endian mode, append `_BE` to the data type. For example: `memoryjs.DOUBLE_BE`. -- when writing 64 bit integers (`INT64`, `UINT64`, `INT64_BE`, `UINT64_BE`) you will need to supply a [BigInt](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt). When reading a 64 bit integer, you will receive a BigInt. - -These data types are to used to denote the type of data being read or written. - -64 bit integer example: -```javascript -const value = memoryjs.readMemory(handle, address, memoryjs.INT64); -console.log(typeof value); // bigint -memoryjs.writeMemory(handle, address, value + 1n, memoryjs.INT64); -``` - -Vector3 is a data structure of three floats: -```javascript -const vector3 = { x: 0.0, y: 0.0, z: 0.0 }; -memoryjs.writeMemory(handle, address, vector3, memoryjs.VEC3); -``` - -Vector4 is a data structure of four floats: -```javascript -const vector4 = { w: 0.0, x: 0.0, y: 0.0, z: 0.0 }; -memoryjs.writeMemory(handle, address, vector4, memoryjs.VEC4); -``` - -## Generic Structures - -If you have a structure you want to write to memory, you can use buffers. For an example on how to do this, view the [buffers example](https://github.com/Rob--/memoryjs/blob/master/examples/buffers.js). - -To write/read a structure to/from memory, you can use [structron](https://github.com/LordVonAdel/structron) to define your structures and use them to write or parse buffers. - -If you want to read a `std::string` using `structron`, the library exposes a custom type that can be used to read/write strings: -```javascript -// To create the type, we need to pass the process handle, base address of the -// structure, and the target process architecture (either "32" or "64"). -const stringType = memoryjs.STRUCTRON_TYPE_STRING(processObject.handle, structAddress, '64'); - -// Create a custom structure using the custom type, full example in /examples/buffers.js -const Struct = require('structron'); -const Player = new Struct() - .addMember(string, 'name'); -``` - -Alternatively, you can use the [concentrate](https://github.com/deoxxa/concentrate) and [dissolve](https://github.com/deoxxa/dissolve) libraries to achieve the same thing. An old example of this is [here](https://github.com/Rob--/memoryjs/blob/aa6ed7d302fb1ac315aaa90558db43d128746912/examples/buffers.js). - -## Protection Type - -Protection type is a bit flag DWORD value. - -This parameter should reference a constant from the library: - -`memoryjs.PAGE_NOACCESS, memoryjs.PAGE_READONLY, memoryjs.PAGE_READWRITE, memoryjs.PAGE_WRITECOPY, memoryjs.PAGE_EXECUTE, memoryjs.PAGE_EXECUTE_READ, memoryjs.PAGE_EXECUTE_READWRITE, memoryjs.PAGE_EXECUTE_WRITECOPY, memoryjs.PAGE_GUARD, memoryjs.PAGE_NOCACHE, memoryjs.PAGE_WRITECOMBINE, memoryjs.PAGE_ENCLAVE_THREAD_CONTROL, memoryjs.PAGE_TARGETS_NO_UPDATE, memoryjs.PAGE_TARGETS_INVALID, memoryjs.PAGE_ENCLAVE_UNVALIDATED` - -Refer to MSDN's [Memory Protection Constants](https://docs.microsoft.com/en-gb/windows/desktop/Memory/memory-protection-constants) for more information. - -## Memory Allocation Type - -Memory allocation type is a bit flag DWORD value. - -This parameter should reference a constat from the library: - -`memoryjs.MEM_COMMIT, memoryjs.MEM_RESERVE, memoryjs.MEM_RESET, memoryjs.MEM_RESET_UNDO` - -Refer to MSDN's [VirtualAllocEx](https://docs.microsoft.com/en-us/windows/desktop/api/memoryapi/nf-memoryapi-virtualallocex) documentation for more information. - -## Strings - -You can use this library to read either a "string", or "char*" and to write a string. - -In both cases you want to get the address of the char array: - -```c++ -std::string str1 = "hello"; -std::cout << "Address: 0x" << hex << (DWORD) str1.c_str() << dec << std::endl; - -char* str2 = "hello"; -std::cout << "Address: 0x" << hex << (DWORD) str2 << dec << std::endl; -``` - -From here you can simply use this address to write and read memory. - -There is one caveat when reading a string in memory however, due to the fact that the library does not know -how long the string is, it will continue reading until it finds the first null-terminator. To prevent an -infinite loop, it will stop reading if it has not found a null-terminator after 1 million characters. - -One way to bypass this limitation in the future would be to allow a parameter to let users set the maximum -character count. - -### Signature Type - -When pattern scanning, flags need to be raised for the signature types. The signature type parameter needs to be one of the following: - -`0x0` or `memoryjs.NORMAL` which denotes a normal signature. - -`0x1` or `memoryjs.READ` which will read the memory at the address. - -`0x2` or `memoryjs.SUBSTRACT` which will subtract the image base from the address. - -To raise multiple flags, use the bitwise OR operator: `memoryjs.READ | memoryjs.SUBTRACT`. - -## Memory Mapped Files - -The library exposes functions to map obtain a handle to and read a memory mapped file. - -**openFileMapping(fileName)** -- *fileName*: name of the file mapping object to be opened -- returns: handle to the file mapping object - -Refer to [MSDN's OpenFileMappingA](https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-openfilemappinga) documentation for more information. - -**mapViewOfFile(processHandle, fileName)** -- *processHandle*: the target process to map the file to -- *fileHandle*: handle of the file mapping object, obtained by `memoryjs.openFileMapping` -- Description: maps the entire file to target process' memory. Page protection defaults to `constants.PAGE_READONLY`. -- Returns: the base address of the mapped file - -**mapViewOfFile(processHandle, fileName, offset, viewSize, pageProtection)** -- *processHandle*: the target process to map the file to -- *fileHandle*: handle of the file mapping object, obtained by `memoryjs.openFileMapping` -- *offset* (`number` or `bigint`): the offset from the beginning of the file (has to be multiple of 64KB) -- *viewSize* (`number` or `bigint`): the number of bytes to map (if `0`, the entire file will be read, regardless of offset) -- *pageProtection*: desired page protection -- Description: maps a view of the file to the target process' memory -- Returns: the base address of the mapped file - -Refer to [MSDN's MapViewOfFile2](https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffile2) documentation for more information. - -See [Protection Type](#user-content-protection-type) for page protection types. - -### Example -We have a process that creates a file mapping: -```c++ -HANDLE fileHandle = CreateFileA("C:\\foo.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); -HANDLE fileMappingHandle = CreateFileMappingA(fileHandle, NULL, PAGE_READONLY, 0, 0, "MappedFooFile"); -``` - -We can map the file to a specified target process and read the file with `memoryjs`: -```javascript -const processObject = memoryjs.openProcess("example.exe"); -const fileHandle = memoryjs.openFileMapping("MappedFooFile"); - -// read entire file -const baseAddress = memoryjs.mapViewOfFile(processObject.handle, fileHandle.handle); -const data = memoryjs.readMemory(processObject.handle, baseAddress, memoryjs.STR); - -// read 10 bytes after 64KB -const baseAddress = memoryjs.mapViewOfFile(processObject.handle, fileHandle.handle, 65536, 10, constants.PAGE_READONLY); -const buffer = memoryjs.readBuffer(processObject.handle, baseAddress, 10); -const data = buffer.toString(); - -const success = memoryjs.closeHandle(fileHandle); -``` - -If you want to read a memory mapped file without having a target process to map the file to, you can map it to the current Node process with global variable `process.pid`: -```javascript -const processObject = memoryjs.openProcess(process.pid); -``` - -## Function Execution - -Remote function execution works by building an array of arguments and dynamically generating shellcode that is injected into the target process and executed, for this reason crashes may occur. - -To call a function in a process, the `callFunction` function can be used. The library supports passing arguments to the function and need to be in the following format: - -```javascript -[{ type: T_INT, value: 4 }] -``` - -The library expects the arguments to be an array of objects where each object has a `type` which denotes the data type of the argument, and a `value` which is the actual value of the argument. The various supported data types can be found below. - - -``` javascript -memoryjs.T_VOID = 0x0, -memoryjs.T_STRING = 0x1, -memoryjs.T_CHAR = 0x2, -memoryjs.T_BOOL = 0x3, -memoryjs.T_INT = 0x4, -memoryjs.T_DOUBLE = 0x5, -memoryjs.T_FLOAT = 0x6, -``` - -When using `callFunction`, you also need to supply the return type of the function, which again needs to be one of the above values. - -For example, given the following C++ function: - -``` c++ -int add(int a, int b) { - return a + b; -} -``` - -You would call this function as so: - -```javascript -const args = [{ - type: memoryjs.T_INT, - value: 2, -}, { - type: memoryjs.T_INT, - value: 5, -}]; -const returnType = T_INT; - -> memoryjs.callFunction(handle, args, returnType, address); -{ returnValue: 7, exitCode: 7 } -``` - -See the [result object documentation](user-content-result-object) for details on what `callFunction` returns. - -Notes: currently passing a `double` as an argument is not supported, but returning one is. - -Much thanks to the [various contributors](https://github.com/Rob--/memoryjs/issues/6) that made this feature possible. - -## Hardware Breakpoints - -Hardware breakpoints work by attaching a debugger to the process, setting a breakpoint on a certain address and declaring a trigger type (e.g. breakpoint on writing to the address) and then continuously waiting for a debug event to arise (and then consequently handling it). - -This library exposes the main functions, but also includes a wrapper class to simplify the process. For a complete code example, checkout our [debugging example](https://github.com/Rob--/memoryjs/blob/master/examples/debugging.js). - -When setting a breakpoint, you are required to pass a trigger type: -- `memoryjs.TRIGGER_ACCESS` - breakpoint occurs when the address is accessed -- `memoryjs.TRIGGER_WRITE` - breakpoint occurs when the address is written to - -Do note that when monitoring an address containing a string, the `size` parameter of the `setHardwareBreakpoint` function should be the length of the string. When using the `Debugger` wrapper class, the wrapper will automatically determine the size of the string by attempting to read it. - -To summarise: -- When using the `Debugger` class: - - No need to pass the `size` parameter to `setHardwareBreakpoint` - - No need to manually pick a hardware register - - Debug events are picked up via an event listener - - `setHardwareBreakpoint` returns the register that was used for the breakpoint - -- When manually using the debugger functions: - - The `size` parameter is the size of the variable in memory (e.g. int32 = 4 bytes). For a string, this parameter is the length of the string - - Manually need to pick a hardware register (via `memoryjs.DR0` through `memoryhs.DR3`). Only 4 hardware registers are available (some CPUs may even has less than 4 available). This means only 4 breakpoints can be set at any given time - - Need to manually wait for debug and handle debug events - - `setHardwareBreakpoint` returns a boolean stating whether the operation as successful - -For more reading about debugging and hardware breakpoints, checkout the following links: -- [DebugActiveProcess](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679295(v=vs.85).aspx) - attaching the debugger -- [DebugSetProcessKillOnExit](https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-debugsetprocesskillonexit) - kill the process when detaching -- [DebugActiveProcessStop](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679296(v=vs.85).aspx) - detaching the debugger -- [WaitForDebugEvent](https://msdn.microsoft.com/en-us/library/windows/desktop/ms681423(v=vs.85).aspx) - waiting for the breakpoint to be triggered -- [ContinueDebugEvent](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679285(v=vs.85).aspx) - handling the event - -### Using the Debugger Wrapper: - -The Debugger wrapper contains these functions you should use: - -``` javascript -class Debugger { - attach(processId, killOnDetach = false); - detach(processId); - setHardwareBreakpoint(processId, address, trigger, dataType); - removeHardwareBreakpoint(processId, register); +interface ProcessInfo { + handle: number; // Process handle + processId: number; // Process ID (PID) + baseAddress: number; // Base address of the main module + size: number; // Size of the main module + path: string; // Full path to the process executable } ``` -1. Attach the debugger -``` javascript -const hardwareDebugger = memoryjs.Debugger; -hardwareDebugger.attach(processId); -``` - -2. Set a hardware breakpoint -``` javascript -const address = 0xDEADBEEF; -const trigger = memoryjs.TRIGGER_ACCESS; -const dataType = memoryjs.INT; -const register = hardwareDebugger.setHardwareBreakpoint(processId, address, trigger, dataType); -``` - -3. Create an event listener for debug events (breakpoints) -``` javascript -// `debugEvent` event emission catches debug events from all registers -hardwareDebugger.on('debugEvent', ({ register, event }) => { - console.log(`Hardware Register ${register} breakpoint`); - console.log(event); -}); +More functions are planned for future releases to expand the capabilities of this library. -// You can listen to debug events from specific hardware registers -// by listening to whatever register was returned from `setHardwareBreakpoint` -hardwareDebugger.on(register, (event) => { - console.log(event); -}); -``` - -### When Manually Debugging: - -1. Attach the debugger -``` javascript -const hardwareDebugger = memoryjs.Debugger; -hardwareDebugger.attach(processId); -``` - -2. Set a hardware breakpoint (determine which register to use and the size of the data type) -``` javascript -// available registers: DR0 through DR3 -const register = memoryjs.DR0; -// int = 4 bytes -const size = 4; - -const address = 0xDEADBEEF; -const trigger = memoryjs.TRIGGER_ACCESS; -const dataType = memoryjs.INT; - -const success = memoryjs.setHardwareBreakpoint(processId, address, register, trigger, size); -``` - -3. Create the await/handle debug event loop -``` javascript -const timeout = 100; - -setInterval(() => { - // `debugEvent` can be null if no event occurred - const debugEvent = memoryjs.awaitDebugEvent(register, timeout); - - // If a breakpoint occurred, handle it - if (debugEvent) { - memoryjs.handleDebugEvent(debugEvent.processId, debugEvent.threadId); - } -}, timeout); -``` - -Note: a loop is not required, e.g. no loop required if you want to simply wait until the first detection of the address being accessed or written to. - -# Debug - -### 1. Re-compile the project to be debugged - -Go to the root directory of the module and run one of the following commands: -```bash -# will automatically compile based on the detected Node architecture -npm run debug - -# compile to target 32 bit processes -npm run debug32 - -# compile to target 64 bit processes -npm run debug64 -``` - -### 2. Change the `index.js` file to require the debug module - -Go to the root directory and change the line in `index.js` from: -```javascript -const memoryjs = require('./build/Release/memoryjs'); -``` - -To the following: -```javascript -const memoryjs = require('./build/Debug/memoryjs'); -``` - -### 3. Open the project in Visual Studio - -Open the `binding.sln` solution in Visual Studio, found in the `build` folder in the project's root directory. - -### 4. Setup Visual Studio debug configuration - - 1. In the toolbar, click "Project" then "Properties" - 2. Under "Configuration Properties", click "Debugging" - 3. Set the "Command" property to the location of your `node.exe` file (e.g. `C:\nodejs\node.exe`) - 4. Set the "Command Arguments" property to the location of your script file (e.g. `C:\project\test.js`) - -### 5. Set breakpoints - -Explore the project files in Visual Studio (by expanding `..` and then `lib` in the Solution Explorer). Header files can be viewed by holding `Alt` and clicking on the header file names at the top of the source code files. - -Breakpoints are set by clicking to the left of the line number. +## Data Types -### 6. Run the debugger +The `dataType` parameter in `readMemory` and `writeMemory` specifies the type of data to be read or written. Currently, the following data type strings are supported (based on the C++ implementation): -Start debugging by either pressing `F5`, by clicking "Debug" in the toolbar and then "Start Debugging", or by clicking "Local Windows Debugger". +* **Integers:** `int`, `int32`, `long`, `uint`, `uint32`, `ulong`, `dword` (all 4 bytes) +* **Shorts:** `short`, `int16`, `ushort`, `uint16`, `word` (all 2 bytes) +* **Chars/Bytes:** `char`, `int8`, `byte`, `uchar`, `uint8`, `ubyte` (all 1 byte) +* **Floating Point:** `float` (4 bytes), `double` (8 bytes) -The script you've set as the command argument in step 4 will be run, and Visual Studio will pause on the breakpoints set and allow you to step through the code line by line and inspect variables. +> [!NOTE] +> Work is planned to define more specific TypeScript types for the `dataType` parameter and the `value` parameter in `writeMemory` to improve type safety and developer experience. diff --git a/assets/banner.png b/assets/banner.png new file mode 100644 index 0000000..0eb59bc Binary files /dev/null and b/assets/banner.png differ diff --git a/assets/logo.png b/assets/logo.png deleted file mode 100644 index a8d3330..0000000 Binary files a/assets/logo.png and /dev/null differ diff --git a/binding.gyp b/binding.gyp deleted file mode 100644 index d2f58eb..0000000 --- a/binding.gyp +++ /dev/null @@ -1,20 +0,0 @@ -{ - "targets": [ - { - "target_name": "memoryjs", - "include_dirs" : [ - " { - const startTime = performance.now(); - const proc = Bun.spawnSync(command, { cwd }); - - if (proc.exitCode !== 0) { - const error = new Error(`Command failed: ${command.join(' ')}\n${proc.stderr.toString()}`); - log(error.message, 'error'); - log(proc.stderr.toString(), 'error'); - throw error; - } - - const duration = performance.now() - startTime; - return; -} - async function build(options: BuildOptions = {}) { const startTime = performance.now(); - const { - arch = 'x64', - debug = false, - clean = true - } = options; + let buildSuccess = false; - log('🚀 Building @joshmiquel/memoryjs...', 'info'); + const { outdir = BUILD_PATH } = options; + const tempDllFilePath = path.join(TEMP_DLL_PATH, 'memoryprocess.dll'); + const finalDllPath = path.join(outdir, 'memoryprocess.dll'); + + log('🚀 Building MemoryProcess...', 'info'); try { - // Build native module - const nodeGypArgs = ['node-gyp']; - if (clean) nodeGypArgs.push('clean'); - nodeGypArgs.push('configure', 'build', `--arch=${arch}`); - if (debug) nodeGypArgs.push('--debug'); - - await execCommand(nodeGypArgs); + await fs.mkdir(outdir, { recursive: true }); + await fs.mkdir(TEMP_DLL_PATH, { recursive: true }); + log('✓ Directories ensured', 'success'); + + + await $`zig build-lib native/*.cc -dynamic -target x86_64-windows-gnu -lc -lc++ -femit-bin=${tempDllFilePath}`; log('✓ Native module built', 'success'); - // Build TypeScript files with Bun + await fs.copyFile(tempDllFilePath, finalDllPath); + log(`✓ Copied DLL to ${finalDllPath}`, 'success'); + await Bun.build({ entrypoints: [ - 'index.ts', - 'src/debugger.ts', - 'src/types.ts', - 'src/utils.ts' + "src/index.ts" ], - outdir: 'lib', - target: 'node', - splitting: true, - minify: !debug + outdir, + target: 'bun', + splitting: false, + minify: true, + external: ["*.dll"] }); log('✓ TypeScript files built', 'success'); - // Run these tasks sequentially - // Clean build directory - await execCommand(['rm', '-rf', 'build']); - - // Generate TypeScript declaration files - await execCommand(['tsc']); - - // Generate API documentation - await execCommand(['api-extractor', 'run', '--local']); + // Create the node-error.js file for Node.js environments + const nodeErrorContent = `throw new Error('The "memoryprocess" package requires the Bun runtime (https://bun.sh) and is not compatible with Node.js.');`; + const nodeErrorPath = path.join(outdir, 'node-error.js'); + await fs.writeFile(nodeErrorPath, nodeErrorContent); + log('✓ Node.js error file created', 'success'); + + await $`bunx tsc`; + log("✓ TypeScript declaration files generated", "success") + + const extractorConfig: ExtractorConfig = ExtractorConfig.loadFileAndPrepare(apiExtractorJsonPath); + + const extractorResult: ExtractorResult = Extractor.invoke(extractorConfig, { + localBuild: true, + }); - // Clean temporary types - await execCommand(['rm', '-rf', 'temptypes']); + if (extractorResult.succeeded) { + log("✓ API Extractor completed", "success"); + buildSuccess = true; + } else { + log( + `API Extractor completed with ${extractorResult.errorCount} errors` + + ` and ${extractorResult.warningCount} warnings`, "error" + ); + buildSuccess = false; + } const totalTime = performance.now() - startTime; - log(`✨ Build completed in ${formatTime(totalTime)}`, 'success'); + if (buildSuccess) { + log(`✨ Build completed successfully in ${formatTime(totalTime)}`, 'success'); + } else { + log(` Build failed after ${formatTime(totalTime)}`, 'error'); + } + + } catch (error) { - log(`Build failed: ${error.message}`, 'error'); - process.exit(1); + buildSuccess = false; + if (error instanceof Error) { + log(`Build failed: ${error.message}`, 'error'); + } else { + log(`Build failed: ${String(error)}`, 'error'); + } + console.error(error); + + } finally { + try { + await fs.rm(TEMP_DLL_PATH, { recursive: true, force: true }); + log('✓ Temporary directory cleaned up', 'info'); + } catch (cleanupError) { + log(`Failed to clean up temporary directory: ${cleanupError}`, 'error'); + } + process.exit(buildSuccess ? 0 : 1); } } -// Run build if this is the main module if (import.meta.path === Bun.main) { await build(); } diff --git a/bun.lock b/bun.lock index d8cb73c..e4a06e2 100644 --- a/bun.lock +++ b/bun.lock @@ -2,18 +2,23 @@ "lockfileVersion": 1, "workspaces": { "": { - "name": "@joshmiquel/memoryjs", - "dependencies": { - "node-addon-api": "8.3.1", - }, + "name": "memoryprocess", "devDependencies": { "@biomejs/biome": "1.9.4", + "@commitlint/cli": "^19.8.0", + "@commitlint/config-conventional": "^19.8.0", "@microsoft/api-extractor": "7.52.3", + "@semantic-release/commit-analyzer": "^13.0.1", + "@semantic-release/git": "^10.0.1", + "@semantic-release/github": "^11.0.1", + "@semantic-release/npm": "^12.0.1", + "@semantic-release/release-notes-generator": "^14.0.3", "@types/bun": "latest", "lefthook": "1.11.10", + "semantic-release": "^24.2.3", }, "peerDependencies": { - "typescript": "^5", + "typescript": "^5.8.3", }, }, }, @@ -22,6 +27,10 @@ "lefthook", ], "packages": { + "@babel/code-frame": ["@babel/code-frame@7.26.2", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.25.9", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" } }, "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.9", "", {}, "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="], + "@biomejs/biome": ["@biomejs/biome@1.9.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "1.9.4", "@biomejs/cli-darwin-x64": "1.9.4", "@biomejs/cli-linux-arm64": "1.9.4", "@biomejs/cli-linux-arm64-musl": "1.9.4", "@biomejs/cli-linux-x64": "1.9.4", "@biomejs/cli-linux-x64-musl": "1.9.4", "@biomejs/cli-win32-arm64": "1.9.4", "@biomejs/cli-win32-x64": "1.9.4" }, "bin": { "biome": "bin/biome" } }, "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog=="], "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@1.9.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw=="], @@ -40,6 +49,42 @@ "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@1.9.4", "", { "os": "win32", "cpu": "x64" }, "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA=="], + "@colors/colors": ["@colors/colors@1.5.0", "", {}, "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ=="], + + "@commitlint/cli": ["@commitlint/cli@19.8.0", "", { "dependencies": { "@commitlint/format": "^19.8.0", "@commitlint/lint": "^19.8.0", "@commitlint/load": "^19.8.0", "@commitlint/read": "^19.8.0", "@commitlint/types": "^19.8.0", "tinyexec": "^0.3.0", "yargs": "^17.0.0" }, "bin": { "commitlint": "./cli.js" } }, "sha512-t/fCrLVu+Ru01h0DtlgHZXbHV2Y8gKocTR5elDOqIRUzQd0/6hpt2VIWOj9b3NDo7y4/gfxeR2zRtXq/qO6iUg=="], + + "@commitlint/config-conventional": ["@commitlint/config-conventional@19.8.0", "", { "dependencies": { "@commitlint/types": "^19.8.0", "conventional-changelog-conventionalcommits": "^7.0.2" } }, "sha512-9I2kKJwcAPwMoAj38hwqFXG0CzS2Kj+SAByPUQ0SlHTfb7VUhYVmo7G2w2tBrqmOf7PFd6MpZ/a1GQJo8na8kw=="], + + "@commitlint/config-validator": ["@commitlint/config-validator@19.8.0", "", { "dependencies": { "@commitlint/types": "^19.8.0", "ajv": "^8.11.0" } }, "sha512-+r5ZvD/0hQC3w5VOHJhGcCooiAVdynFlCe2d6I9dU+PvXdV3O+fU4vipVg+6hyLbQUuCH82mz3HnT/cBQTYYuA=="], + + "@commitlint/ensure": ["@commitlint/ensure@19.8.0", "", { "dependencies": { "@commitlint/types": "^19.8.0", "lodash.camelcase": "^4.3.0", "lodash.kebabcase": "^4.1.1", "lodash.snakecase": "^4.1.1", "lodash.startcase": "^4.4.0", "lodash.upperfirst": "^4.3.1" } }, "sha512-kNiNU4/bhEQ/wutI1tp1pVW1mQ0QbAjfPRo5v8SaxoVV+ARhkB8Wjg3BSseNYECPzWWfg/WDqQGIfV1RaBFQZg=="], + + "@commitlint/execute-rule": ["@commitlint/execute-rule@19.8.0", "", {}, "sha512-fuLeI+EZ9x2v/+TXKAjplBJWI9CNrHnyi5nvUQGQt4WRkww/d95oVRsc9ajpt4xFrFmqMZkd/xBQHZDvALIY7A=="], + + "@commitlint/format": ["@commitlint/format@19.8.0", "", { "dependencies": { "@commitlint/types": "^19.8.0", "chalk": "^5.3.0" } }, "sha512-EOpA8IERpQstxwp/WGnDArA7S+wlZDeTeKi98WMOvaDLKbjptuHWdOYYr790iO7kTCif/z971PKPI2PkWMfOxg=="], + + "@commitlint/is-ignored": ["@commitlint/is-ignored@19.8.0", "", { "dependencies": { "@commitlint/types": "^19.8.0", "semver": "^7.6.0" } }, "sha512-L2Jv9yUg/I+jF3zikOV0rdiHUul9X3a/oU5HIXhAJLE2+TXTnEBfqYP9G5yMw/Yb40SnR764g4fyDK6WR2xtpw=="], + + "@commitlint/lint": ["@commitlint/lint@19.8.0", "", { "dependencies": { "@commitlint/is-ignored": "^19.8.0", "@commitlint/parse": "^19.8.0", "@commitlint/rules": "^19.8.0", "@commitlint/types": "^19.8.0" } }, "sha512-+/NZKyWKSf39FeNpqhfMebmaLa1P90i1Nrb1SrA7oSU5GNN/lksA4z6+ZTnsft01YfhRZSYMbgGsARXvkr/VLQ=="], + + "@commitlint/load": ["@commitlint/load@19.8.0", "", { "dependencies": { "@commitlint/config-validator": "^19.8.0", "@commitlint/execute-rule": "^19.8.0", "@commitlint/resolve-extends": "^19.8.0", "@commitlint/types": "^19.8.0", "chalk": "^5.3.0", "cosmiconfig": "^9.0.0", "cosmiconfig-typescript-loader": "^6.1.0", "lodash.isplainobject": "^4.0.6", "lodash.merge": "^4.6.2", "lodash.uniq": "^4.5.0" } }, "sha512-4rvmm3ff81Sfb+mcWT5WKlyOa+Hd33WSbirTVUer0wjS1Hv/Hzr07Uv1ULIV9DkimZKNyOwXn593c+h8lsDQPQ=="], + + "@commitlint/message": ["@commitlint/message@19.8.0", "", {}, "sha512-qs/5Vi9bYjf+ZV40bvdCyBn5DvbuelhR6qewLE8Bh476F7KnNyLfdM/ETJ4cp96WgeeHo6tesA2TMXS0sh5X4A=="], + + "@commitlint/parse": ["@commitlint/parse@19.8.0", "", { "dependencies": { "@commitlint/types": "^19.8.0", "conventional-changelog-angular": "^7.0.0", "conventional-commits-parser": "^5.0.0" } }, "sha512-YNIKAc4EXvNeAvyeEnzgvm1VyAe0/b3Wax7pjJSwXuhqIQ1/t2hD3OYRXb6D5/GffIvaX82RbjD+nWtMZCLL7Q=="], + + "@commitlint/read": ["@commitlint/read@19.8.0", "", { "dependencies": { "@commitlint/top-level": "^19.8.0", "@commitlint/types": "^19.8.0", "git-raw-commits": "^4.0.0", "minimist": "^1.2.8", "tinyexec": "^0.3.0" } }, "sha512-6ywxOGYajcxK1y1MfzrOnwsXO6nnErna88gRWEl3qqOOP8MDu/DTeRkGLXBFIZuRZ7mm5yyxU5BmeUvMpNte5w=="], + + "@commitlint/resolve-extends": ["@commitlint/resolve-extends@19.8.0", "", { "dependencies": { "@commitlint/config-validator": "^19.8.0", "@commitlint/types": "^19.8.0", "global-directory": "^4.0.1", "import-meta-resolve": "^4.0.0", "lodash.mergewith": "^4.6.2", "resolve-from": "^5.0.0" } }, "sha512-CLanRQwuG2LPfFVvrkTrBR/L/DMy3+ETsgBqW1OvRxmzp/bbVJW0Xw23LnnExgYcsaFtos967lul1CsbsnJlzQ=="], + + "@commitlint/rules": ["@commitlint/rules@19.8.0", "", { "dependencies": { "@commitlint/ensure": "^19.8.0", "@commitlint/message": "^19.8.0", "@commitlint/to-lines": "^19.8.0", "@commitlint/types": "^19.8.0" } }, "sha512-IZ5IE90h6DSWNuNK/cwjABLAKdy8tP8OgGVGbXe1noBEX5hSsu00uRlLu6JuruiXjWJz2dZc+YSw3H0UZyl/mA=="], + + "@commitlint/to-lines": ["@commitlint/to-lines@19.8.0", "", {}, "sha512-3CKLUw41Cur8VMjh16y8LcsOaKbmQjAKCWlXx6B0vOUREplp6em9uIVhI8Cv934qiwkbi2+uv+mVZPnXJi1o9A=="], + + "@commitlint/top-level": ["@commitlint/top-level@19.8.0", "", { "dependencies": { "find-up": "^7.0.0" } }, "sha512-Rphgoc/omYZisoNkcfaBRPQr4myZEHhLPx2/vTXNLjiCw4RgfPR1wEgUpJ9OOmDCiv5ZyIExhprNLhteqH4FuQ=="], + + "@commitlint/types": ["@commitlint/types@19.8.0", "", { "dependencies": { "@types/conventional-commits-parser": "^5.0.0", "chalk": "^5.3.0" } }, "sha512-LRjP623jPyf3Poyfb0ohMj8I3ORyBDOwXAgxxVPbSD0unJuW2mJWeiRfaQinjtccMqC5Wy1HOMfa4btKjbNxbg=="], + "@microsoft/api-extractor": ["@microsoft/api-extractor@7.52.3", "", { "dependencies": { "@microsoft/api-extractor-model": "7.30.5", "@microsoft/tsdoc": "~0.15.1", "@microsoft/tsdoc-config": "~0.17.1", "@rushstack/node-core-library": "5.13.0", "@rushstack/rig-package": "0.5.3", "@rushstack/terminal": "0.15.2", "@rushstack/ts-command-line": "4.23.7", "lodash": "~4.17.15", "minimatch": "~3.0.3", "resolve": "~1.22.1", "semver": "~7.5.4", "source-map": "~0.6.1", "typescript": "5.8.2" }, "bin": { "api-extractor": "bin/api-extractor" } }, "sha512-QEs6l8h7p9eOSHrQ9NBBUZhUuq+j/2QKcRgigbSs2YQepKz8glvsqmsUOp+nvuaY60ps7KkpVVYQCj81WLoMVQ=="], "@microsoft/api-extractor-model": ["@microsoft/api-extractor-model@7.30.5", "", { "dependencies": { "@microsoft/tsdoc": "~0.15.1", "@microsoft/tsdoc-config": "~0.17.1", "@rushstack/node-core-library": "5.13.0" } }, "sha512-0ic4rcbcDZHz833RaTZWTGu+NpNgrxVNjVaor0ZDUymfDFzjA/Uuk8hYziIUIOEOSTfmIQqyzVwlzxZxPe7tOA=="], @@ -48,6 +93,40 @@ "@microsoft/tsdoc-config": ["@microsoft/tsdoc-config@0.17.1", "", { "dependencies": { "@microsoft/tsdoc": "0.15.1", "ajv": "~8.12.0", "jju": "~1.4.0", "resolve": "~1.22.2" } }, "sha512-UtjIFe0C6oYgTnad4q1QP4qXwLhe6tIpNTRStJ2RZEPIkqQPREAwE5spzVxsdn9UaEMUqhh0AqSx3X4nWAKXWw=="], + "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], + + "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], + + "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + + "@octokit/auth-token": ["@octokit/auth-token@5.1.2", "", {}, "sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw=="], + + "@octokit/core": ["@octokit/core@6.1.5", "", { "dependencies": { "@octokit/auth-token": "^5.0.0", "@octokit/graphql": "^8.2.2", "@octokit/request": "^9.2.3", "@octokit/request-error": "^6.1.8", "@octokit/types": "^14.0.0", "before-after-hook": "^3.0.2", "universal-user-agent": "^7.0.0" } }, "sha512-vvmsN0r7rguA+FySiCsbaTTobSftpIDIpPW81trAmsv9TGxg3YCujAxRYp/Uy8xmDgYCzzgulG62H7KYUFmeIg=="], + + "@octokit/endpoint": ["@octokit/endpoint@10.1.4", "", { "dependencies": { "@octokit/types": "^14.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-OlYOlZIsfEVZm5HCSR8aSg02T2lbUWOsCQoPKfTXJwDzcHQBrVBGdGXb89dv2Kw2ToZaRtudp8O3ZIYoaOjKlA=="], + + "@octokit/graphql": ["@octokit/graphql@8.2.2", "", { "dependencies": { "@octokit/request": "^9.2.3", "@octokit/types": "^14.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-Yi8hcoqsrXGdt0yObxbebHXFOiUA+2v3n53epuOg1QUgOB6c4XzvisBNVXJSl8RYA5KrDuSL2yq9Qmqe5N0ryA=="], + + "@octokit/openapi-types": ["@octokit/openapi-types@25.0.0", "", {}, "sha512-FZvktFu7HfOIJf2BScLKIEYjDsw6RKc7rBJCdvCTfKsVnx2GEB/Nbzjr29DUdb7vQhlzS/j8qDzdditP0OC6aw=="], + + "@octokit/plugin-paginate-rest": ["@octokit/plugin-paginate-rest@11.6.0", "", { "dependencies": { "@octokit/types": "^13.10.0" }, "peerDependencies": { "@octokit/core": ">=6" } }, "sha512-n5KPteiF7pWKgBIBJSk8qzoZWcUkza2O6A0za97pMGVrGfPdltxrfmfF5GucHYvHGZD8BdaZmmHGz5cX/3gdpw=="], + + "@octokit/plugin-retry": ["@octokit/plugin-retry@7.2.1", "", { "dependencies": { "@octokit/request-error": "^6.1.8", "@octokit/types": "^14.0.0", "bottleneck": "^2.15.3" }, "peerDependencies": { "@octokit/core": ">=6" } }, "sha512-wUc3gv0D6vNHpGxSaR3FlqJpTXGWgqmk607N9L3LvPL4QjaxDgX/1nY2mGpT37Khn+nlIXdljczkRnNdTTV3/A=="], + + "@octokit/plugin-throttling": ["@octokit/plugin-throttling@9.6.1", "", { "dependencies": { "@octokit/types": "^13.7.0", "bottleneck": "^2.15.3" }, "peerDependencies": { "@octokit/core": "^6.1.3" } }, "sha512-bt3EBUkeKUzDQXRCcFrR9SWVqlLFRRqcCrr6uAorWt6NXTyjMKqcGrFmXqJy9NCbnKgiIZ2OXWq04theFc76Jg=="], + + "@octokit/request": ["@octokit/request@9.2.3", "", { "dependencies": { "@octokit/endpoint": "^10.1.4", "@octokit/request-error": "^6.1.8", "@octokit/types": "^14.0.0", "fast-content-type-parse": "^2.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-Ma+pZU8PXLOEYzsWf0cn/gY+ME57Wq8f49WTXA8FMHp2Ps9djKw//xYJ1je8Hm0pR2lU9FUGeJRWOtxq6olt4w=="], + + "@octokit/request-error": ["@octokit/request-error@6.1.8", "", { "dependencies": { "@octokit/types": "^14.0.0" } }, "sha512-WEi/R0Jmq+IJKydWlKDmryPcmdYSVjL3ekaiEL1L9eo1sUnqMJ+grqmC9cjk7CA7+b2/T397tO5d8YLOH3qYpQ=="], + + "@octokit/types": ["@octokit/types@14.0.0", "", { "dependencies": { "@octokit/openapi-types": "^25.0.0" } }, "sha512-VVmZP0lEhbo2O1pdq63gZFiGCKkm8PPp8AUOijlwPO6hojEVjspA0MWKP7E4hbvGxzFKNqKr6p0IYtOH/Wf/zA=="], + + "@pnpm/config.env-replace": ["@pnpm/config.env-replace@1.1.0", "", {}, "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w=="], + + "@pnpm/network.ca-file": ["@pnpm/network.ca-file@1.0.2", "", { "dependencies": { "graceful-fs": "4.2.10" } }, "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA=="], + + "@pnpm/npm-conf": ["@pnpm/npm-conf@2.3.1", "", { "dependencies": { "@pnpm/config.env-replace": "^1.1.0", "@pnpm/network.ca-file": "^1.0.1", "config-chain": "^1.1.11" } }, "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw=="], + "@rushstack/node-core-library": ["@rushstack/node-core-library@5.13.0", "", { "dependencies": { "ajv": "~8.13.0", "ajv-draft-04": "~1.0.0", "ajv-formats": "~3.0.1", "fs-extra": "~11.3.0", "import-lazy": "~4.0.0", "jju": "~1.4.0", "resolve": "~1.22.1", "semver": "~7.5.4" }, "peerDependencies": { "@types/node": "*" }, "optionalPeers": ["@types/node"] }, "sha512-IGVhy+JgUacAdCGXKUrRhwHMTzqhWwZUI+qEPcdzsb80heOw0QPbhhoVsoiMF7Klp8eYsp7hzpScMXmOa3Uhfg=="], "@rushstack/rig-package": ["@rushstack/rig-package@0.5.3", "", { "dependencies": { "resolve": "~1.22.1", "strip-json-comments": "~3.1.1" } }, "sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow=="], @@ -56,52 +135,278 @@ "@rushstack/ts-command-line": ["@rushstack/ts-command-line@4.23.7", "", { "dependencies": { "@rushstack/terminal": "0.15.2", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" } }, "sha512-Gr9cB7DGe6uz5vq2wdr89WbVDKz0UeuFEn5H2CfWDe7JvjFFaiV15gi6mqDBTbHhHCWS7w8mF1h3BnIfUndqdA=="], + "@sec-ant/readable-stream": ["@sec-ant/readable-stream@0.4.1", "", {}, "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg=="], + + "@semantic-release/commit-analyzer": ["@semantic-release/commit-analyzer@13.0.1", "", { "dependencies": { "conventional-changelog-angular": "^8.0.0", "conventional-changelog-writer": "^8.0.0", "conventional-commits-filter": "^5.0.0", "conventional-commits-parser": "^6.0.0", "debug": "^4.0.0", "import-from-esm": "^2.0.0", "lodash-es": "^4.17.21", "micromatch": "^4.0.2" }, "peerDependencies": { "semantic-release": ">=20.1.0" } }, "sha512-wdnBPHKkr9HhNhXOhZD5a2LNl91+hs8CC2vsAVYxtZH3y0dV3wKn+uZSN61rdJQZ8EGxzWB3inWocBHV9+u/CQ=="], + + "@semantic-release/error": ["@semantic-release/error@3.0.0", "", {}, "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw=="], + + "@semantic-release/git": ["@semantic-release/git@10.0.1", "", { "dependencies": { "@semantic-release/error": "^3.0.0", "aggregate-error": "^3.0.0", "debug": "^4.0.0", "dir-glob": "^3.0.0", "execa": "^5.0.0", "lodash": "^4.17.4", "micromatch": "^4.0.0", "p-reduce": "^2.0.0" }, "peerDependencies": { "semantic-release": ">=18.0.0" } }, "sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w=="], + + "@semantic-release/github": ["@semantic-release/github@11.0.1", "", { "dependencies": { "@octokit/core": "^6.0.0", "@octokit/plugin-paginate-rest": "^11.0.0", "@octokit/plugin-retry": "^7.0.0", "@octokit/plugin-throttling": "^9.0.0", "@semantic-release/error": "^4.0.0", "aggregate-error": "^5.0.0", "debug": "^4.3.4", "dir-glob": "^3.0.1", "globby": "^14.0.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "issue-parser": "^7.0.0", "lodash-es": "^4.17.21", "mime": "^4.0.0", "p-filter": "^4.0.0", "url-join": "^5.0.0" }, "peerDependencies": { "semantic-release": ">=24.1.0" } }, "sha512-Z9cr0LgU/zgucbT9cksH0/pX9zmVda9hkDPcgIE0uvjMQ8w/mElDivGjx1w1pEQ+MuQJ5CBq3VCF16S6G4VH3A=="], + + "@semantic-release/npm": ["@semantic-release/npm@12.0.1", "", { "dependencies": { "@semantic-release/error": "^4.0.0", "aggregate-error": "^5.0.0", "execa": "^9.0.0", "fs-extra": "^11.0.0", "lodash-es": "^4.17.21", "nerf-dart": "^1.0.0", "normalize-url": "^8.0.0", "npm": "^10.5.0", "rc": "^1.2.8", "read-pkg": "^9.0.0", "registry-auth-token": "^5.0.0", "semver": "^7.1.2", "tempy": "^3.0.0" }, "peerDependencies": { "semantic-release": ">=20.1.0" } }, "sha512-/6nntGSUGK2aTOI0rHPwY3ZjgY9FkXmEHbW9Kr+62NVOsyqpKKeP0lrCH+tphv+EsNdJNmqqwijTEnVWUMQ2Nw=="], + + "@semantic-release/release-notes-generator": ["@semantic-release/release-notes-generator@14.0.3", "", { "dependencies": { "conventional-changelog-angular": "^8.0.0", "conventional-changelog-writer": "^8.0.0", "conventional-commits-filter": "^5.0.0", "conventional-commits-parser": "^6.0.0", "debug": "^4.0.0", "get-stream": "^7.0.0", "import-from-esm": "^2.0.0", "into-stream": "^7.0.0", "lodash-es": "^4.17.21", "read-package-up": "^11.0.0" }, "peerDependencies": { "semantic-release": ">=20.1.0" } }, "sha512-XxAZRPWGwO5JwJtS83bRdoIhCiYIx8Vhr+u231pQAsdFIAbm19rSVJLdnBN+Avvk7CKvNQE/nJ4y7uqKH6WTiw=="], + + "@sindresorhus/is": ["@sindresorhus/is@4.6.0", "", {}, "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw=="], + + "@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@2.3.0", "", {}, "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg=="], + "@types/argparse": ["@types/argparse@1.0.38", "", {}, "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA=="], "@types/bun": ["@types/bun@1.2.9", "", { "dependencies": { "bun-types": "1.2.9" } }, "sha512-epShhLGQYc4Bv/aceHbmBhOz1XgUnuTZgcxjxk+WXwNyDXavv5QHD1QEFV0FwbTSQtNq6g4ZcV6y0vZakTjswg=="], + "@types/conventional-commits-parser": ["@types/conventional-commits-parser@5.0.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ=="], + "@types/node": ["@types/node@22.14.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw=="], + "@types/normalize-package-data": ["@types/normalize-package-data@2.4.4", "", {}, "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA=="], + "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], + "JSONStream": ["JSONStream@1.3.5", "", { "dependencies": { "jsonparse": "^1.2.0", "through": ">=2.2.7 <3" }, "bin": { "JSONStream": "./bin.js" } }, "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ=="], + + "agent-base": ["agent-base@7.1.3", "", {}, "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw=="], + + "aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="], + "ajv": ["ajv@8.12.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA=="], "ajv-draft-04": ["ajv-draft-04@1.0.0", "", { "peerDependencies": { "ajv": "^8.5.0" }, "optionalPeers": ["ajv"] }, "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw=="], "ajv-formats": ["ajv-formats@3.0.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ=="], + "ansi-escapes": ["ansi-escapes@7.0.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw=="], + + "ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], + + "ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="], + + "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="], + "argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], + "argv-formatter": ["argv-formatter@1.0.0", "", {}, "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw=="], + + "array-ify": ["array-ify@1.0.0", "", {}, "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng=="], + "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + "before-after-hook": ["before-after-hook@3.0.2", "", {}, "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A=="], + + "bottleneck": ["bottleneck@2.19.5", "", {}, "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw=="], + "brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="], + "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], + "bun-types": ["bun-types@1.2.9", "", { "dependencies": { "@types/node": "*", "@types/ws": "*" } }, "sha512-dk/kOEfQbajENN/D6FyiSgOKEuUi9PWfqKQJEgwKrCMWbjS/S6tEXp178mWvWAcUSYm9ArDlWHZKO3T/4cLXiw=="], + "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], + + "chalk": ["chalk@5.4.1", "", {}, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="], + + "char-regex": ["char-regex@1.0.2", "", {}, "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw=="], + + "clean-stack": ["clean-stack@2.2.0", "", {}, "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A=="], + + "cli-highlight": ["cli-highlight@2.1.11", "", { "dependencies": { "chalk": "^4.0.0", "highlight.js": "^10.7.1", "mz": "^2.4.0", "parse5": "^5.1.1", "parse5-htmlparser2-tree-adapter": "^6.0.0", "yargs": "^16.0.0" }, "bin": { "highlight": "bin/highlight" } }, "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg=="], + + "cli-table3": ["cli-table3@0.6.5", "", { "dependencies": { "string-width": "^4.2.0" }, "optionalDependencies": { "@colors/colors": "1.5.0" } }, "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ=="], + + "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], + + "color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], + + "color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], + + "compare-func": ["compare-func@2.0.0", "", { "dependencies": { "array-ify": "^1.0.0", "dot-prop": "^5.1.0" } }, "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA=="], + "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], + "config-chain": ["config-chain@1.1.13", "", { "dependencies": { "ini": "^1.3.4", "proto-list": "~1.2.1" } }, "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ=="], + + "conventional-changelog-angular": ["conventional-changelog-angular@8.0.0", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-CLf+zr6St0wIxos4bmaKHRXWAcsCXrJU6F4VdNDrGRK3B8LDLKoX3zuMV5GhtbGkVR/LohZ6MT6im43vZLSjmA=="], + + "conventional-changelog-conventionalcommits": ["conventional-changelog-conventionalcommits@7.0.2", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w=="], + + "conventional-changelog-writer": ["conventional-changelog-writer@8.0.1", "", { "dependencies": { "conventional-commits-filter": "^5.0.0", "handlebars": "^4.7.7", "meow": "^13.0.0", "semver": "^7.5.2" }, "bin": { "conventional-changelog-writer": "dist/cli/index.js" } }, "sha512-hlqcy3xHred2gyYg/zXSMXraY2mjAYYo0msUCpK+BGyaVJMFCKWVXPIHiaacGO2GGp13kvHWXFhYmxT4QQqW3Q=="], + + "conventional-commits-filter": ["conventional-commits-filter@5.0.0", "", {}, "sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q=="], + + "conventional-commits-parser": ["conventional-commits-parser@6.1.0", "", { "dependencies": { "meow": "^13.0.0" }, "bin": { "conventional-commits-parser": "dist/cli/index.js" } }, "sha512-5nxDo7TwKB5InYBl4ZC//1g9GRwB/F3TXOGR9hgUjMGfvSP4Vu5NkpNro2+1+TIEy1vwxApl5ircECr2ri5JIw=="], + + "convert-hrtime": ["convert-hrtime@5.0.0", "", {}, "sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg=="], + + "core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="], + + "cosmiconfig": ["cosmiconfig@9.0.0", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg=="], + + "cosmiconfig-typescript-loader": ["cosmiconfig-typescript-loader@6.1.0", "", { "dependencies": { "jiti": "^2.4.1" }, "peerDependencies": { "@types/node": "*", "cosmiconfig": ">=9", "typescript": ">=5" } }, "sha512-tJ1w35ZRUiM5FeTzT7DtYWAFFv37ZLqSRkGi2oeCK1gPhvaWjkAtfXvLmvE1pRfxxp9aQo6ba/Pvg1dKj05D4g=="], + + "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], + + "crypto-random-string": ["crypto-random-string@4.0.0", "", { "dependencies": { "type-fest": "^1.0.1" } }, "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA=="], + + "dargs": ["dargs@8.1.0", "", {}, "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw=="], + + "debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="], + + "dir-glob": ["dir-glob@3.0.1", "", { "dependencies": { "path-type": "^4.0.0" } }, "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="], + + "dot-prop": ["dot-prop@5.3.0", "", { "dependencies": { "is-obj": "^2.0.0" } }, "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q=="], + + "duplexer2": ["duplexer2@0.1.4", "", { "dependencies": { "readable-stream": "^2.0.2" } }, "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA=="], + + "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "emojilib": ["emojilib@2.4.0", "", {}, "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw=="], + + "env-ci": ["env-ci@11.1.0", "", { "dependencies": { "execa": "^8.0.0", "java-properties": "^1.0.2" } }, "sha512-Z8dnwSDbV1XYM9SBF2J0GcNVvmfmfh3a49qddGIROhBoVro6MZVTji15z/sJbQ2ko2ei8n988EU1wzoLU/tF+g=="], + + "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], + + "environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="], + + "error-ex": ["error-ex@1.3.2", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g=="], + + "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], + + "escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], + + "execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="], + + "fast-content-type-parse": ["fast-content-type-parse@2.0.1", "", {}, "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q=="], + "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], + "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], + + "fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="], + + "figures": ["figures@6.1.0", "", { "dependencies": { "is-unicode-supported": "^2.0.0" } }, "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg=="], + + "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], + + "find-up": ["find-up@7.0.0", "", { "dependencies": { "locate-path": "^7.2.0", "path-exists": "^5.0.0", "unicorn-magic": "^0.1.0" } }, "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g=="], + + "find-up-simple": ["find-up-simple@1.0.1", "", {}, "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ=="], + + "find-versions": ["find-versions@6.0.0", "", { "dependencies": { "semver-regex": "^4.0.5", "super-regex": "^1.0.0" } }, "sha512-2kCCtc+JvcZ86IGAz3Z2Y0A1baIz9fL31pH/0S1IqZr9Iwnjq8izfPtrCyQKO6TLMPELLsQMre7VDqeIKCsHkA=="], + + "from2": ["from2@2.3.0", "", { "dependencies": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" } }, "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g=="], + "fs-extra": ["fs-extra@11.3.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew=="], "function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="], + "function-timeout": ["function-timeout@1.0.2", "", {}, "sha512-939eZS4gJ3htTHAldmyyuzlrD58P03fHG49v2JfFXbV6OhvZKRC9j2yAtdHw/zrp2zXHuv05zMIy40F0ge7spA=="], + + "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], + + "get-stream": ["get-stream@7.0.1", "", {}, "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ=="], + + "git-log-parser": ["git-log-parser@1.2.1", "", { "dependencies": { "argv-formatter": "~1.0.0", "spawn-error-forwarder": "~1.0.0", "split2": "~1.0.0", "stream-combiner2": "~1.1.1", "through2": "~2.0.0", "traverse": "0.6.8" } }, "sha512-PI+sPDvHXNPl5WNOErAK05s3j0lgwUzMN6o8cyQrDaKfT3qd7TmNJKeXX+SknI5I0QhG5fVPAEwSY4tRGDtYoQ=="], + + "git-raw-commits": ["git-raw-commits@4.0.0", "", { "dependencies": { "dargs": "^8.0.0", "meow": "^12.0.1", "split2": "^4.0.0" }, "bin": { "git-raw-commits": "cli.mjs" } }, "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ=="], + + "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + + "global-directory": ["global-directory@4.0.1", "", { "dependencies": { "ini": "4.1.1" } }, "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q=="], + + "globby": ["globby@14.1.0", "", { "dependencies": { "@sindresorhus/merge-streams": "^2.1.0", "fast-glob": "^3.3.3", "ignore": "^7.0.3", "path-type": "^6.0.0", "slash": "^5.1.0", "unicorn-magic": "^0.3.0" } }, "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA=="], + "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + "handlebars": ["handlebars@4.7.8", "", { "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "optionalDependencies": { "uglify-js": "^3.1.4" }, "bin": { "handlebars": "bin/handlebars" } }, "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ=="], + "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], + "highlight.js": ["highlight.js@10.7.3", "", {}, "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A=="], + + "hook-std": ["hook-std@3.0.0", "", {}, "sha512-jHRQzjSDzMtFy34AGj1DN+vq54WVuhSvKgrHf0OMiFQTwDD4L/qqofVEWjLOBMTn5+lCD3fPg32W9yOfnEJTTw=="], + + "hosted-git-info": ["hosted-git-info@8.1.0", "", { "dependencies": { "lru-cache": "^10.0.1" } }, "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw=="], + + "http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], + + "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + + "human-signals": ["human-signals@2.1.0", "", {}, "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="], + + "ignore": ["ignore@7.0.3", "", {}, "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA=="], + + "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], + + "import-from-esm": ["import-from-esm@2.0.0", "", { "dependencies": { "debug": "^4.3.4", "import-meta-resolve": "^4.0.0" } }, "sha512-YVt14UZCgsX1vZQ3gKjkWVdBdHQ6eu3MPU1TBgL1H5orXe2+jWD006WCPPtOuwlQm10NuzOW5WawiF1Q9veW8g=="], + "import-lazy": ["import-lazy@4.0.0", "", {}, "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw=="], + "import-meta-resolve": ["import-meta-resolve@4.1.0", "", {}, "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw=="], + + "indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="], + + "index-to-position": ["index-to-position@1.1.0", "", {}, "sha512-XPdx9Dq4t9Qk1mTMbWONJqU7boCoumEH7fRET37HX5+khDUl3J2W6PdALxhILYlIYx2amlwYcRPp28p0tSiojg=="], + + "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="], + + "ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="], + + "into-stream": ["into-stream@7.0.0", "", { "dependencies": { "from2": "^2.3.0", "p-is-promise": "^3.0.0" } }, "sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw=="], + + "is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="], + "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="], + "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="], + + "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], + + "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], + + "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], + + "is-obj": ["is-obj@2.0.0", "", {}, "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w=="], + + "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], + + "is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], + + "is-text-path": ["is-text-path@2.0.0", "", { "dependencies": { "text-extensions": "^2.0.0" } }, "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw=="], + + "is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="], + + "isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], + + "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + + "issue-parser": ["issue-parser@7.0.1", "", { "dependencies": { "lodash.capitalize": "^4.2.1", "lodash.escaperegexp": "^4.1.2", "lodash.isplainobject": "^4.0.6", "lodash.isstring": "^4.0.1", "lodash.uniqby": "^4.7.0" } }, "sha512-3YZcUUR2Wt1WsapF+S/WiA2WmlW0cWAoPccMqne7AxEBhCdFeTPjfv/Axb8V2gyCgY3nRw+ksZ3xSUX+R47iAg=="], + + "java-properties": ["java-properties@1.0.2", "", {}, "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ=="], + + "jiti": ["jiti@2.4.2", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A=="], + "jju": ["jju@1.4.0", "", {}, "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA=="], + "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + + "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], + + "json-parse-better-errors": ["json-parse-better-errors@1.0.2", "", {}, "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw=="], + + "json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="], + "json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], "jsonfile": ["jsonfile@6.1.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ=="], + "jsonparse": ["jsonparse@1.3.1", "", {}, "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg=="], + "lefthook": ["lefthook@1.11.10", "", { "optionalDependencies": { "lefthook-darwin-arm64": "1.11.10", "lefthook-darwin-x64": "1.11.10", "lefthook-freebsd-arm64": "1.11.10", "lefthook-freebsd-x64": "1.11.10", "lefthook-linux-arm64": "1.11.10", "lefthook-linux-x64": "1.11.10", "lefthook-openbsd-arm64": "1.11.10", "lefthook-openbsd-x64": "1.11.10", "lefthook-windows-arm64": "1.11.10", "lefthook-windows-x64": "1.11.10" }, "bin": { "lefthook": "bin/index.js" } }, "sha512-nuiRqBADcRiU6dzwf2H1zBCsdcWGEOsxY8hqoXw5nkEuoTEYN1Bwi2vskHXjIzJ62iCOCo4FZhcHBAzT9gwL5g=="], "lefthook-darwin-arm64": ["lefthook-darwin-arm64@1.11.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Rufl8BRP77GRFtgNwW95/FHPD0VDfu5bRyzASPcyVrFczJiBK1glAHRdYrErBDNqJhEEjkyv9+EkCZS/MnDKPQ=="], @@ -124,48 +429,912 @@ "lefthook-windows-x64": ["lefthook-windows-x64@1.11.10", "", { "os": "win32", "cpu": "x64" }, "sha512-zpf/0sG50xsGnwVG/a2giUbmaM/g0uIRqxN5qBbmwKCf0P4PPD2r1xiFZNDb520+tUTC1lWe0RWVoSSwZbBQRA=="], + "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], + + "load-json-file": ["load-json-file@4.0.0", "", { "dependencies": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", "pify": "^3.0.0", "strip-bom": "^3.0.0" } }, "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw=="], + + "locate-path": ["locate-path@7.2.0", "", { "dependencies": { "p-locate": "^6.0.0" } }, "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA=="], + "lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="], + "lodash-es": ["lodash-es@4.17.21", "", {}, "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw=="], + + "lodash.camelcase": ["lodash.camelcase@4.3.0", "", {}, "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="], + + "lodash.capitalize": ["lodash.capitalize@4.2.1", "", {}, "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw=="], + + "lodash.escaperegexp": ["lodash.escaperegexp@4.1.2", "", {}, "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw=="], + + "lodash.isplainobject": ["lodash.isplainobject@4.0.6", "", {}, "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="], + + "lodash.isstring": ["lodash.isstring@4.0.1", "", {}, "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw=="], + + "lodash.kebabcase": ["lodash.kebabcase@4.1.1", "", {}, "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g=="], + + "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], + + "lodash.mergewith": ["lodash.mergewith@4.6.2", "", {}, "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ=="], + + "lodash.snakecase": ["lodash.snakecase@4.1.1", "", {}, "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw=="], + + "lodash.startcase": ["lodash.startcase@4.4.0", "", {}, "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg=="], + + "lodash.uniq": ["lodash.uniq@4.5.0", "", {}, "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ=="], + + "lodash.uniqby": ["lodash.uniqby@4.7.0", "", {}, "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww=="], + + "lodash.upperfirst": ["lodash.upperfirst@4.3.1", "", {}, "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg=="], + "lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], + "marked": ["marked@12.0.2", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q=="], + + "marked-terminal": ["marked-terminal@7.3.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "ansi-regex": "^6.1.0", "chalk": "^5.4.1", "cli-highlight": "^2.1.11", "cli-table3": "^0.6.5", "node-emoji": "^2.2.0", "supports-hyperlinks": "^3.1.0" }, "peerDependencies": { "marked": ">=1 <16" } }, "sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw=="], + + "meow": ["meow@13.2.0", "", {}, "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA=="], + + "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="], + + "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], + + "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], + + "mime": ["mime@4.0.7", "", { "bin": { "mime": "bin/cli.js" } }, "sha512-2OfDPL+e03E0LrXaGYOtTFIYhiuzep94NSsuhrNULq+stylcJedcHdzHtz0atMUuGwJfFYs0YL5xeC/Ca2x0eQ=="], + + "mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], + "minimatch": ["minimatch@3.0.8", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q=="], - "node-addon-api": ["node-addon-api@8.3.1", "", {}, "sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA=="], + "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], + + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], + + "neo-async": ["neo-async@2.6.2", "", {}, "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="], + + "nerf-dart": ["nerf-dart@1.0.0", "", {}, "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g=="], + + "node-emoji": ["node-emoji@2.2.0", "", { "dependencies": { "@sindresorhus/is": "^4.6.0", "char-regex": "^1.0.2", "emojilib": "^2.4.0", "skin-tone": "^2.0.0" } }, "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw=="], + + "normalize-package-data": ["normalize-package-data@6.0.2", "", { "dependencies": { "hosted-git-info": "^7.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" } }, "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g=="], + + "normalize-url": ["normalize-url@8.0.1", "", {}, "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w=="], + + "npm": ["npm@10.9.2", "", { "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/arborist": "^8.0.0", "@npmcli/config": "^9.0.0", "@npmcli/fs": "^4.0.0", "@npmcli/map-workspaces": "^4.0.2", "@npmcli/package-json": "^6.1.0", "@npmcli/promise-spawn": "^8.0.2", "@npmcli/redact": "^3.0.0", "@npmcli/run-script": "^9.0.1", "@sigstore/tuf": "^3.0.0", "abbrev": "^3.0.0", "archy": "~1.0.0", "cacache": "^19.0.1", "chalk": "^5.3.0", "ci-info": "^4.1.0", "cli-columns": "^4.0.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", "glob": "^10.4.5", "graceful-fs": "^4.2.11", "hosted-git-info": "^8.0.2", "ini": "^5.0.0", "init-package-json": "^7.0.2", "is-cidr": "^5.1.0", "json-parse-even-better-errors": "^4.0.0", "libnpmaccess": "^9.0.0", "libnpmdiff": "^7.0.0", "libnpmexec": "^9.0.0", "libnpmfund": "^6.0.0", "libnpmhook": "^11.0.0", "libnpmorg": "^7.0.0", "libnpmpack": "^8.0.0", "libnpmpublish": "^10.0.1", "libnpmsearch": "^8.0.0", "libnpmteam": "^7.0.0", "libnpmversion": "^7.0.0", "make-fetch-happen": "^14.0.3", "minimatch": "^9.0.5", "minipass": "^7.1.1", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", "node-gyp": "^11.0.0", "nopt": "^8.0.0", "normalize-package-data": "^7.0.0", "npm-audit-report": "^6.0.0", "npm-install-checks": "^7.1.1", "npm-package-arg": "^12.0.0", "npm-pick-manifest": "^10.0.0", "npm-profile": "^11.0.1", "npm-registry-fetch": "^18.0.2", "npm-user-validate": "^3.0.0", "p-map": "^4.0.0", "pacote": "^19.0.1", "parse-conflict-json": "^4.0.0", "proc-log": "^5.0.0", "qrcode-terminal": "^0.12.0", "read": "^4.0.0", "semver": "^7.6.3", "spdx-expression-parse": "^4.0.0", "ssri": "^12.0.0", "supports-color": "^9.4.0", "tar": "^6.2.1", "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", "treeverse": "^3.0.0", "validate-npm-package-name": "^6.0.0", "which": "^5.0.0", "write-file-atomic": "^6.0.0" }, "bin": { "npm": "bin/npm-cli.js", "npx": "bin/npx-cli.js" } }, "sha512-iriPEPIkoMYUy3F6f3wwSZAU93E0Eg6cHwIR6jzzOXWSy+SD/rOODEs74cVONHKSx2obXtuUoyidVEhISrisgQ=="], + + "npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="], + + "object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="], + + "onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], + + "p-each-series": ["p-each-series@3.0.0", "", {}, "sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw=="], + + "p-filter": ["p-filter@4.1.0", "", { "dependencies": { "p-map": "^7.0.1" } }, "sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw=="], + + "p-is-promise": ["p-is-promise@3.0.0", "", {}, "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ=="], + + "p-limit": ["p-limit@4.0.0", "", { "dependencies": { "yocto-queue": "^1.0.0" } }, "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ=="], + + "p-locate": ["p-locate@6.0.0", "", { "dependencies": { "p-limit": "^4.0.0" } }, "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw=="], + + "p-map": ["p-map@7.0.3", "", {}, "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA=="], + + "p-reduce": ["p-reduce@2.1.0", "", {}, "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw=="], + + "p-try": ["p-try@1.0.0", "", {}, "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww=="], + + "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], + + "parse-json": ["parse-json@8.3.0", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "index-to-position": "^1.1.0", "type-fest": "^4.39.1" } }, "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ=="], + + "parse-ms": ["parse-ms@4.0.0", "", {}, "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw=="], + + "parse5": ["parse5@5.1.1", "", {}, "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug=="], + + "parse5-htmlparser2-tree-adapter": ["parse5-htmlparser2-tree-adapter@6.0.1", "", { "dependencies": { "parse5": "^6.0.1" } }, "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA=="], + + "path-exists": ["path-exists@5.0.0", "", {}, "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ=="], + + "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], + "path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + + "pify": ["pify@3.0.0", "", {}, "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg=="], + + "pkg-conf": ["pkg-conf@2.1.0", "", { "dependencies": { "find-up": "^2.0.0", "load-json-file": "^4.0.0" } }, "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g=="], + + "pretty-ms": ["pretty-ms@9.2.0", "", { "dependencies": { "parse-ms": "^4.0.0" } }, "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg=="], + + "process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="], + + "proto-list": ["proto-list@1.2.4", "", {}, "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA=="], + "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], + "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], + + "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="], + + "read-package-up": ["read-package-up@11.0.0", "", { "dependencies": { "find-up-simple": "^1.0.0", "read-pkg": "^9.0.0", "type-fest": "^4.6.0" } }, "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ=="], + + "read-pkg": ["read-pkg@9.0.1", "", { "dependencies": { "@types/normalize-package-data": "^2.4.3", "normalize-package-data": "^6.0.0", "parse-json": "^8.0.0", "type-fest": "^4.6.0", "unicorn-magic": "^0.1.0" } }, "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA=="], + + "readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], + + "registry-auth-token": ["registry-auth-token@5.1.0", "", { "dependencies": { "@pnpm/npm-conf": "^2.1.0" } }, "sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw=="], + + "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], + "require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="], "resolve": ["resolve@1.22.10", "", { "dependencies": { "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w=="], + "resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], + + "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], + + "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], + + "safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], + + "semantic-release": ["semantic-release@24.2.3", "", { "dependencies": { "@semantic-release/commit-analyzer": "^13.0.0-beta.1", "@semantic-release/error": "^4.0.0", "@semantic-release/github": "^11.0.0", "@semantic-release/npm": "^12.0.0", "@semantic-release/release-notes-generator": "^14.0.0-beta.1", "aggregate-error": "^5.0.0", "cosmiconfig": "^9.0.0", "debug": "^4.0.0", "env-ci": "^11.0.0", "execa": "^9.0.0", "figures": "^6.0.0", "find-versions": "^6.0.0", "get-stream": "^6.0.0", "git-log-parser": "^1.2.0", "hook-std": "^3.0.0", "hosted-git-info": "^8.0.0", "import-from-esm": "^2.0.0", "lodash-es": "^4.17.21", "marked": "^12.0.0", "marked-terminal": "^7.0.0", "micromatch": "^4.0.2", "p-each-series": "^3.0.0", "p-reduce": "^3.0.0", "read-package-up": "^11.0.0", "resolve-from": "^5.0.0", "semver": "^7.3.2", "semver-diff": "^4.0.0", "signale": "^1.2.1", "yargs": "^17.5.1" }, "bin": { "semantic-release": "bin/semantic-release.js" } }, "sha512-KRhQG9cUazPavJiJEFIJ3XAMjgfd0fcK3B+T26qOl8L0UG5aZUjeRfREO0KM5InGtYwxqiiytkJrbcYoLDEv0A=="], + "semver": ["semver@7.5.4", "", { "dependencies": { "lru-cache": "^6.0.0" }, "bin": { "semver": "bin/semver.js" } }, "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA=="], + "semver-diff": ["semver-diff@4.0.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA=="], + + "semver-regex": ["semver-regex@4.0.5", "", {}, "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw=="], + + "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], + + "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], + + "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], + + "signale": ["signale@1.4.0", "", { "dependencies": { "chalk": "^2.3.2", "figures": "^2.0.0", "pkg-conf": "^2.1.0" } }, "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w=="], + + "skin-tone": ["skin-tone@2.0.0", "", { "dependencies": { "unicode-emoji-modifier-base": "^1.0.0" } }, "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA=="], + + "slash": ["slash@5.1.0", "", {}, "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg=="], + "source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + "spawn-error-forwarder": ["spawn-error-forwarder@1.0.0", "", {}, "sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g=="], + + "spdx-correct": ["spdx-correct@3.2.0", "", { "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA=="], + + "spdx-exceptions": ["spdx-exceptions@2.5.0", "", {}, "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w=="], + + "spdx-expression-parse": ["spdx-expression-parse@3.0.1", "", { "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q=="], + + "spdx-license-ids": ["spdx-license-ids@3.0.21", "", {}, "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg=="], + + "split2": ["split2@1.0.0", "", { "dependencies": { "through2": "~2.0.0" } }, "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg=="], + "sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="], + "stream-combiner2": ["stream-combiner2@1.1.1", "", { "dependencies": { "duplexer2": "~0.1.0", "readable-stream": "^2.0.2" } }, "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw=="], + "string-argv": ["string-argv@0.3.2", "", {}, "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q=="], + "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], + + "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="], + + "strip-final-newline": ["strip-final-newline@2.0.0", "", {}, "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="], + "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], + "super-regex": ["super-regex@1.0.0", "", { "dependencies": { "function-timeout": "^1.0.1", "time-span": "^5.1.0" } }, "sha512-CY8u7DtbvucKuquCmOFEKhr9Besln7n9uN8eFbwcoGYWXOMW07u2o8njWaiXt11ylS3qoGF55pILjRmPlbodyg=="], + "supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], + "supports-hyperlinks": ["supports-hyperlinks@3.2.0", "", { "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" } }, "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig=="], + "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], - "typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="], + "temp-dir": ["temp-dir@3.0.0", "", {}, "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw=="], - "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + "tempy": ["tempy@3.1.0", "", { "dependencies": { "is-stream": "^3.0.0", "temp-dir": "^3.0.0", "type-fest": "^2.12.2", "unique-string": "^3.0.0" } }, "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g=="], - "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], + "text-extensions": ["text-extensions@2.4.0", "", {}, "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g=="], - "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], + "thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="], - "yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + "thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="], - "@rushstack/node-core-library/ajv": ["ajv@8.13.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.4.1" } }, "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA=="], + "through": ["through@2.3.8", "", {}, "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="], - "ajv-formats/ajv": ["ajv@8.13.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.4.1" } }, "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA=="], + "through2": ["through2@2.0.5", "", { "dependencies": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" } }, "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ=="], + + "time-span": ["time-span@5.1.0", "", { "dependencies": { "convert-hrtime": "^5.0.0" } }, "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA=="], + + "tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], + + "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], + + "traverse": ["traverse@0.6.8", "", {}, "sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA=="], + + "type-fest": ["type-fest@4.40.0", "", {}, "sha512-ABHZ2/tS2JkvH1PEjxFDTUWC8dB5OsIGZP4IFLhR293GqT5Y5qB1WwL2kMPYhQW9DVgVD8Hd7I8gjwPIf5GFkw=="], + + "typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="], + + "uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="], + + "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + + "unicode-emoji-modifier-base": ["unicode-emoji-modifier-base@1.0.0", "", {}, "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g=="], + + "unicorn-magic": ["unicorn-magic@0.3.0", "", {}, "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA=="], + + "unique-string": ["unique-string@3.0.0", "", { "dependencies": { "crypto-random-string": "^4.0.0" } }, "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ=="], + + "universal-user-agent": ["universal-user-agent@7.0.2", "", {}, "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q=="], + + "universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], + + "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], + + "url-join": ["url-join@5.0.0", "", {}, "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA=="], + + "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + + "validate-npm-package-license": ["validate-npm-package-license@3.0.4", "", { "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew=="], + + "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + + "wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="], + + "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + + "xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="], + + "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], + + "yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="], + + "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="], + + "yocto-queue": ["yocto-queue@1.2.1", "", {}, "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg=="], + + "yoctocolors": ["yoctocolors@2.1.1", "", {}, "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ=="], + + "@commitlint/config-validator/ajv": ["ajv@8.13.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.4.1" } }, "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA=="], + + "@commitlint/is-ignored/semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="], + + "@commitlint/parse/conventional-changelog-angular": ["conventional-changelog-angular@7.0.0", "", { "dependencies": { "compare-func": "^2.0.0" } }, "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ=="], + + "@commitlint/parse/conventional-commits-parser": ["conventional-commits-parser@5.0.0", "", { "dependencies": { "JSONStream": "^1.3.5", "is-text-path": "^2.0.0", "meow": "^12.0.1", "split2": "^4.0.0" }, "bin": { "conventional-commits-parser": "cli.mjs" } }, "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA=="], + + "@octokit/plugin-paginate-rest/@octokit/types": ["@octokit/types@13.10.0", "", { "dependencies": { "@octokit/openapi-types": "^24.2.0" } }, "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA=="], + + "@octokit/plugin-throttling/@octokit/types": ["@octokit/types@13.10.0", "", { "dependencies": { "@octokit/openapi-types": "^24.2.0" } }, "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA=="], + + "@pnpm/network.ca-file/graceful-fs": ["graceful-fs@4.2.10", "", {}, "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="], + + "@rushstack/node-core-library/ajv": ["ajv@8.13.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.4.1" } }, "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA=="], + + "@semantic-release/github/@semantic-release/error": ["@semantic-release/error@4.0.0", "", {}, "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ=="], + + "@semantic-release/github/aggregate-error": ["aggregate-error@5.0.0", "", { "dependencies": { "clean-stack": "^5.2.0", "indent-string": "^5.0.0" } }, "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw=="], + + "@semantic-release/npm/@semantic-release/error": ["@semantic-release/error@4.0.0", "", {}, "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ=="], + + "@semantic-release/npm/aggregate-error": ["aggregate-error@5.0.0", "", { "dependencies": { "clean-stack": "^5.2.0", "indent-string": "^5.0.0" } }, "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw=="], + + "@semantic-release/npm/execa": ["execa@9.5.2", "", { "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "cross-spawn": "^7.0.3", "figures": "^6.1.0", "get-stream": "^9.0.0", "human-signals": "^8.0.0", "is-plain-obj": "^4.1.0", "is-stream": "^4.0.1", "npm-run-path": "^6.0.0", "pretty-ms": "^9.0.0", "signal-exit": "^4.1.0", "strip-final-newline": "^4.0.0", "yoctocolors": "^2.0.0" } }, "sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q=="], + + "ajv-formats/ajv": ["ajv@8.13.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.4.1" } }, "sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA=="], + + "cli-highlight/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], + + "cli-highlight/yargs": ["yargs@16.2.0", "", { "dependencies": { "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.0", "y18n": "^5.0.5", "yargs-parser": "^20.2.2" } }, "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw=="], + + "cosmiconfig/parse-json": ["parse-json@5.2.0", "", { "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="], + + "crypto-random-string/type-fest": ["type-fest@1.4.0", "", {}, "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA=="], + + "env-ci/execa": ["execa@8.0.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", "human-signals": "^5.0.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" } }, "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg=="], + + "execa/get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="], + + "find-up/unicorn-magic": ["unicorn-magic@0.1.0", "", {}, "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ=="], + + "git-raw-commits/meow": ["meow@12.1.1", "", {}, "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw=="], + + "git-raw-commits/split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="], + + "global-directory/ini": ["ini@4.1.1", "", {}, "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g=="], + + "globby/path-type": ["path-type@6.0.0", "", {}, "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ=="], + + "hosted-git-info/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], + + "js-yaml/argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="], + + "load-json-file/parse-json": ["parse-json@4.0.0", "", { "dependencies": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" } }, "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw=="], + + "normalize-package-data/hosted-git-info": ["hosted-git-info@7.0.2", "", { "dependencies": { "lru-cache": "^10.0.1" } }, "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w=="], + + "normalize-package-data/semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="], + + "npm/@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], + + "npm/@isaacs/fs-minipass": ["@isaacs/fs-minipass@4.0.1", "", { "dependencies": { "minipass": "^7.0.4" } }, "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w=="], + + "npm/@isaacs/string-locale-compare": ["@isaacs/string-locale-compare@1.1.0", "", { "bundled": true }, "sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ=="], + + "npm/@npmcli/agent": ["@npmcli/agent@3.0.0", "", { "dependencies": { "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.1", "lru-cache": "^10.0.1", "socks-proxy-agent": "^8.0.3" } }, "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q=="], + + "npm/@npmcli/arborist": ["@npmcli/arborist@8.0.0", "", { "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", "@npmcli/fs": "^4.0.0", "@npmcli/installed-package-contents": "^3.0.0", "@npmcli/map-workspaces": "^4.0.1", "@npmcli/metavuln-calculator": "^8.0.0", "@npmcli/name-from-folder": "^3.0.0", "@npmcli/node-gyp": "^4.0.0", "@npmcli/package-json": "^6.0.1", "@npmcli/query": "^4.0.0", "@npmcli/redact": "^3.0.0", "@npmcli/run-script": "^9.0.1", "bin-links": "^5.0.0", "cacache": "^19.0.1", "common-ancestor-path": "^1.0.1", "hosted-git-info": "^8.0.0", "json-parse-even-better-errors": "^4.0.0", "json-stringify-nice": "^1.1.4", "lru-cache": "^10.2.2", "minimatch": "^9.0.4", "nopt": "^8.0.0", "npm-install-checks": "^7.1.0", "npm-package-arg": "^12.0.0", "npm-pick-manifest": "^10.0.0", "npm-registry-fetch": "^18.0.1", "pacote": "^19.0.0", "parse-conflict-json": "^4.0.0", "proc-log": "^5.0.0", "proggy": "^3.0.0", "promise-all-reject-late": "^1.0.0", "promise-call-limit": "^3.0.1", "read-package-json-fast": "^4.0.0", "semver": "^7.3.7", "ssri": "^12.0.0", "treeverse": "^3.0.0", "walk-up-path": "^3.0.1" }, "bundled": true, "bin": { "arborist": "bin/index.js" } }, "sha512-APDXxtXGSftyXibl0dZ3CuZYmmVnkiN3+gkqwXshY4GKC2rof2+Lg0sGuj6H1p2YfBAKd7PRwuMVhu6Pf/nQ/A=="], + + "npm/@npmcli/config": ["@npmcli/config@9.0.0", "", { "dependencies": { "@npmcli/map-workspaces": "^4.0.1", "@npmcli/package-json": "^6.0.1", "ci-info": "^4.0.0", "ini": "^5.0.0", "nopt": "^8.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5", "walk-up-path": "^3.0.1" }, "bundled": true }, "sha512-P5Vi16Y+c8E0prGIzX112ug7XxqfaPFUVW/oXAV+2VsxplKZEnJozqZ0xnK8V8w/SEsBf+TXhUihrEIAU4CA5Q=="], + + "npm/@npmcli/fs": ["@npmcli/fs@4.0.0", "", { "dependencies": { "semver": "^7.3.5" }, "bundled": true }, "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q=="], + + "npm/@npmcli/git": ["@npmcli/git@6.0.3", "", { "dependencies": { "@npmcli/promise-spawn": "^8.0.0", "ini": "^5.0.0", "lru-cache": "^10.0.1", "npm-pick-manifest": "^10.0.0", "proc-log": "^5.0.0", "promise-retry": "^2.0.1", "semver": "^7.3.5", "which": "^5.0.0" } }, "sha512-GUYESQlxZRAdhs3UhbB6pVRNUELQOHXwK9ruDkwmCv2aZ5y0SApQzUJCg02p3A7Ue2J5hxvlk1YI53c00NmRyQ=="], + + "npm/@npmcli/installed-package-contents": ["@npmcli/installed-package-contents@3.0.0", "", { "dependencies": { "npm-bundled": "^4.0.0", "npm-normalize-package-bin": "^4.0.0" }, "bin": { "installed-package-contents": "bin/index.js" } }, "sha512-fkxoPuFGvxyrH+OQzyTkX2LUEamrF4jZSmxjAtPPHHGO0dqsQ8tTKjnIS8SAnPHdk2I03BDtSMR5K/4loKg79Q=="], + + "npm/@npmcli/map-workspaces": ["@npmcli/map-workspaces@4.0.2", "", { "dependencies": { "@npmcli/name-from-folder": "^3.0.0", "@npmcli/package-json": "^6.0.0", "glob": "^10.2.2", "minimatch": "^9.0.0" }, "bundled": true }, "sha512-mnuMuibEbkaBTYj9HQ3dMe6L0ylYW+s/gfz7tBDMFY/la0w9Kf44P9aLn4/+/t3aTR3YUHKoT6XQL9rlicIe3Q=="], + + "npm/@npmcli/metavuln-calculator": ["@npmcli/metavuln-calculator@8.0.1", "", { "dependencies": { "cacache": "^19.0.0", "json-parse-even-better-errors": "^4.0.0", "pacote": "^20.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5" } }, "sha512-WXlJx9cz3CfHSt9W9Opi1PTFc4WZLFomm5O8wekxQZmkyljrBRwATwDxfC9iOXJwYVmfiW1C1dUe0W2aN0UrSg=="], + + "npm/@npmcli/name-from-folder": ["@npmcli/name-from-folder@3.0.0", "", {}, "sha512-61cDL8LUc9y80fXn+lir+iVt8IS0xHqEKwPu/5jCjxQTVoSCmkXvw4vbMrzAMtmghz3/AkiBjhHkDKUH+kf7kA=="], + + "npm/@npmcli/node-gyp": ["@npmcli/node-gyp@4.0.0", "", {}, "sha512-+t5DZ6mO/QFh78PByMq1fGSAub/agLJZDRfJRMeOSNCt8s9YVlTjmGpIPwPhvXTGUIJk+WszlT0rQa1W33yzNA=="], + + "npm/@npmcli/package-json": ["@npmcli/package-json@6.1.1", "", { "dependencies": { "@npmcli/git": "^6.0.0", "glob": "^10.2.2", "hosted-git-info": "^8.0.0", "json-parse-even-better-errors": "^4.0.0", "proc-log": "^5.0.0", "semver": "^7.5.3", "validate-npm-package-license": "^3.0.4" }, "bundled": true }, "sha512-d5qimadRAUCO4A/Txw71VM7UrRZzV+NPclxz/dc+M6B2oYwjWTjqh8HA/sGQgs9VZuJ6I/P7XIAlJvgrl27ZOw=="], + + "npm/@npmcli/promise-spawn": ["@npmcli/promise-spawn@8.0.2", "", { "dependencies": { "which": "^5.0.0" }, "bundled": true }, "sha512-/bNJhjc+o6qL+Dwz/bqfTQClkEO5nTQ1ZEcdCkAQjhkZMHIh22LPG7fNh1enJP1NKWDqYiiABnjFCY7E0zHYtQ=="], + + "npm/@npmcli/query": ["@npmcli/query@4.0.1", "", { "dependencies": { "postcss-selector-parser": "^7.0.0" } }, "sha512-4OIPFb4weUUwkDXJf4Hh1inAn8neBGq3xsH4ZsAaN6FK3ldrFkH7jSpCc7N9xesi0Sp+EBXJ9eGMDrEww2Ztqw=="], + + "npm/@npmcli/redact": ["@npmcli/redact@3.1.1", "", { "bundled": true }, "sha512-3Hc2KGIkrvJWJqTbvueXzBeZlmvoOxc2jyX00yzr3+sNFquJg0N8hH4SAPLPVrkWIRQICVpVgjrss971awXVnA=="], + + "npm/@npmcli/run-script": ["@npmcli/run-script@9.1.0", "", { "dependencies": { "@npmcli/node-gyp": "^4.0.0", "@npmcli/package-json": "^6.0.0", "@npmcli/promise-spawn": "^8.0.0", "node-gyp": "^11.0.0", "proc-log": "^5.0.0", "which": "^5.0.0" }, "bundled": true }, "sha512-aoNSbxtkePXUlbZB+anS1LqsJdctG5n3UVhfU47+CDdwMi6uNTBMF9gPcQRnqghQd2FGzcwwIFBruFMxjhBewg=="], + + "npm/@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="], + + "npm/@sigstore/bundle": ["@sigstore/bundle@3.1.0", "", { "dependencies": { "@sigstore/protobuf-specs": "^0.4.0" } }, "sha512-Mm1E3/CmDDCz3nDhFKTuYdB47EdRFRQMOE/EAbiG1MJW77/w1b3P7Qx7JSrVJs8PfwOLOVcKQCHErIwCTyPbag=="], + + "npm/@sigstore/core": ["@sigstore/core@2.0.0", "", {}, "sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg=="], + + "npm/@sigstore/protobuf-specs": ["@sigstore/protobuf-specs@0.4.1", "", {}, "sha512-7MJXQhIm7dWF9zo7rRtMYh8d2gSnc3+JddeQOTIg6gUN7FjcuckZ9EwGq+ReeQtbbl3Tbf5YqRrWxA1DMfIn+w=="], + + "npm/@sigstore/sign": ["@sigstore/sign@3.1.0", "", { "dependencies": { "@sigstore/bundle": "^3.1.0", "@sigstore/core": "^2.0.0", "@sigstore/protobuf-specs": "^0.4.0", "make-fetch-happen": "^14.0.2", "proc-log": "^5.0.0", "promise-retry": "^2.0.1" } }, "sha512-knzjmaOHOov1Ur7N/z4B1oPqZ0QX5geUfhrVaqVlu+hl0EAoL4o+l0MSULINcD5GCWe3Z0+YJO8ues6vFlW0Yw=="], + + "npm/@sigstore/tuf": ["@sigstore/tuf@3.1.0", "", { "dependencies": { "@sigstore/protobuf-specs": "^0.4.0", "tuf-js": "^3.0.1" }, "bundled": true }, "sha512-suVMQEA+sKdOz5hwP9qNcEjX6B45R+hFFr4LAWzbRc5O+U2IInwvay/bpG5a4s+qR35P/JK/PiKiRGjfuLy1IA=="], + + "npm/@sigstore/verify": ["@sigstore/verify@2.1.0", "", { "dependencies": { "@sigstore/bundle": "^3.1.0", "@sigstore/core": "^2.0.0", "@sigstore/protobuf-specs": "^0.4.0" } }, "sha512-kAAM06ca4CzhvjIZdONAL9+MLppW3K48wOFy1TbuaWFW/OMfl8JuTgW0Bm02JB1WJGT/ET2eqav0KTEKmxqkIA=="], + + "npm/@tufjs/canonical-json": ["@tufjs/canonical-json@2.0.0", "", {}, "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA=="], + + "npm/@tufjs/models": ["@tufjs/models@3.0.1", "", { "dependencies": { "@tufjs/canonical-json": "2.0.0", "minimatch": "^9.0.5" } }, "sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA=="], + + "npm/abbrev": ["abbrev@3.0.1", "", { "bundled": true }, "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg=="], + + "npm/agent-base": ["agent-base@7.1.3", "", {}, "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw=="], + + "npm/aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="], + + "npm/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "npm/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="], + + "npm/aproba": ["aproba@2.0.0", "", {}, "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="], + + "npm/archy": ["archy@1.0.0", "", { "bundled": true }, "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw=="], + + "npm/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + + "npm/bin-links": ["bin-links@5.0.0", "", { "dependencies": { "cmd-shim": "^7.0.0", "npm-normalize-package-bin": "^4.0.0", "proc-log": "^5.0.0", "read-cmd-shim": "^5.0.0", "write-file-atomic": "^6.0.0" } }, "sha512-sdleLVfCjBtgO5cNjA2HVRvWBJAHs4zwenaCPMNJAJU0yNxpzj80IpjOIimkpkr+mhlA+how5poQtt53PygbHA=="], + + "npm/binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], + + "npm/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="], + + "npm/cacache": ["cacache@19.0.1", "", { "dependencies": { "@npmcli/fs": "^4.0.0", "fs-minipass": "^3.0.0", "glob": "^10.2.2", "lru-cache": "^10.0.1", "minipass": "^7.0.3", "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^7.0.2", "ssri": "^12.0.0", "tar": "^7.4.3", "unique-filename": "^4.0.0" }, "bundled": true }, "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ=="], + + "npm/chalk": ["chalk@5.4.1", "", { "bundled": true }, "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w=="], + + "npm/chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="], + + "npm/ci-info": ["ci-info@4.2.0", "", { "bundled": true }, "sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg=="], + + "npm/cidr-regex": ["cidr-regex@4.1.3", "", { "dependencies": { "ip-regex": "^5.0.0" } }, "sha512-86M1y3ZeQvpZkZejQCcS+IaSWjlDUC+ORP0peScQ4uEUFCZ8bEQVz7NlJHqysoUb6w3zCjx4Mq/8/2RHhMwHYw=="], + + "npm/clean-stack": ["clean-stack@2.2.0", "", {}, "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A=="], + + "npm/cli-columns": ["cli-columns@4.0.0", "", { "dependencies": { "string-width": "^4.2.3", "strip-ansi": "^6.0.1" }, "bundled": true }, "sha512-XW2Vg+w+L9on9wtwKpyzluIPCWXjaBahI7mTcYjx+BVIYD9c3yqcv/yKC7CmdCZat4rq2yiE1UMSJC5ivKfMtQ=="], + + "npm/cmd-shim": ["cmd-shim@7.0.0", "", {}, "sha512-rtpaCbr164TPPh+zFdkWpCyZuKkjpAzODfaZCf/SVJZzJN+4bHQb/LP3Jzq5/+84um3XXY8r548XiWKSborwVw=="], + + "npm/color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "npm/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "npm/common-ancestor-path": ["common-ancestor-path@1.0.1", "", {}, "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w=="], + + "npm/cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], + + "npm/cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], + + "npm/debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="], + + "npm/diff": ["diff@5.2.0", "", {}, "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A=="], + + "npm/eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="], + + "npm/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], + + "npm/encoding": ["encoding@0.1.13", "", { "dependencies": { "iconv-lite": "^0.6.2" } }, "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A=="], + + "npm/env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], + + "npm/err-code": ["err-code@2.0.3", "", {}, "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA=="], + + "npm/exponential-backoff": ["exponential-backoff@3.1.2", "", {}, "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA=="], + + "npm/fastest-levenshtein": ["fastest-levenshtein@1.0.16", "", { "bundled": true }, "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg=="], + + "npm/fdir": ["fdir@6.4.3", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw=="], + + "npm/foreground-child": ["foreground-child@3.3.1", "", { "dependencies": { "cross-spawn": "^7.0.6", "signal-exit": "^4.0.1" } }, "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw=="], + + "npm/fs-minipass": ["fs-minipass@3.0.3", "", { "dependencies": { "minipass": "^7.0.3" }, "bundled": true }, "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw=="], + + "npm/glob": ["glob@10.4.5", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bundled": true, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg=="], + + "npm/graceful-fs": ["graceful-fs@4.2.11", "", { "bundled": true }, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + + "npm/hosted-git-info": ["hosted-git-info@8.1.0", "", { "dependencies": { "lru-cache": "^10.0.1" }, "bundled": true }, "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw=="], + + "npm/http-cache-semantics": ["http-cache-semantics@4.1.1", "", {}, "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ=="], + + "npm/http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], + + "npm/https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], + + "npm/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + + "npm/ignore-walk": ["ignore-walk@7.0.0", "", { "dependencies": { "minimatch": "^9.0.0" } }, "sha512-T4gbf83A4NH95zvhVYZc+qWocBBGlpzUXLPGurJggw/WIOwicfXJChLDP/iBZnN5WqROSu5Bm3hhle4z8a8YGQ=="], + + "npm/imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], + + "npm/indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="], + + "npm/ini": ["ini@5.0.0", "", { "bundled": true }, "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw=="], + + "npm/init-package-json": ["init-package-json@7.0.2", "", { "dependencies": { "@npmcli/package-json": "^6.0.0", "npm-package-arg": "^12.0.0", "promzard": "^2.0.0", "read": "^4.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4", "validate-npm-package-name": "^6.0.0" }, "bundled": true }, "sha512-Qg6nAQulaOQZjvaSzVLtYRqZmuqOi7gTknqqgdhZy7LV5oO+ppvHWq15tZYzGyxJLTH5BxRTqTa+cPDx2pSD9Q=="], + + "npm/ip-address": ["ip-address@9.0.5", "", { "dependencies": { "jsbn": "1.1.0", "sprintf-js": "^1.1.3" } }, "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g=="], + + "npm/ip-regex": ["ip-regex@5.0.0", "", {}, "sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw=="], + + "npm/is-cidr": ["is-cidr@5.1.1", "", { "dependencies": { "cidr-regex": "^4.1.1" }, "bundled": true }, "sha512-AwzRMjtJNTPOgm7xuYZ71715z99t+4yRnSnSzgK5err5+heYi4zMuvmpUadaJ28+KCXCQo8CjUrKQZRWSPmqTQ=="], + + "npm/is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], + + "npm/isexe": ["isexe@3.1.1", "", {}, "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ=="], + + "npm/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], + + "npm/jsbn": ["jsbn@1.1.0", "", {}, "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="], + + "npm/json-parse-even-better-errors": ["json-parse-even-better-errors@4.0.0", "", { "bundled": true }, "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA=="], + + "npm/json-stringify-nice": ["json-stringify-nice@1.1.4", "", {}, "sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw=="], + + "npm/jsonparse": ["jsonparse@1.3.1", "", {}, "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg=="], + + "npm/just-diff": ["just-diff@6.0.2", "", {}, "sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA=="], + + "npm/just-diff-apply": ["just-diff-apply@5.5.0", "", {}, "sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw=="], + + "npm/libnpmaccess": ["libnpmaccess@9.0.0", "", { "dependencies": { "npm-package-arg": "^12.0.0", "npm-registry-fetch": "^18.0.1" }, "bundled": true }, "sha512-mTCFoxyevNgXRrvgdOhghKJnCWByBc9yp7zX4u9RBsmZjwOYdUDEBfL5DdgD1/8gahsYnauqIWFbq0iK6tO6CQ=="], + + "npm/libnpmdiff": ["libnpmdiff@7.0.0", "", { "dependencies": { "@npmcli/arborist": "^8.0.0", "@npmcli/installed-package-contents": "^3.0.0", "binary-extensions": "^2.3.0", "diff": "^5.1.0", "minimatch": "^9.0.4", "npm-package-arg": "^12.0.0", "pacote": "^19.0.0", "tar": "^6.2.1" }, "bundled": true }, "sha512-MjvsBJL1AT4ofsSsBRse5clxv7gfPbdgzT0VE+xmVTxE8M92T22laeX9vqFhaQKInSeKiZ2L9w/FVhoCCGPdUg=="], + + "npm/libnpmexec": ["libnpmexec@9.0.0", "", { "dependencies": { "@npmcli/arborist": "^8.0.0", "@npmcli/run-script": "^9.0.1", "ci-info": "^4.0.0", "npm-package-arg": "^12.0.0", "pacote": "^19.0.0", "proc-log": "^5.0.0", "read": "^4.0.0", "read-package-json-fast": "^4.0.0", "semver": "^7.3.7", "walk-up-path": "^3.0.1" }, "bundled": true }, "sha512-5dOwgvt0srgrOkwsjNWokx23BvQXEaUo87HWIY+9lymvAto2VSunNS+Ih7WXVwvkJk7cZ0jhS2H3rNK8G9Anxw=="], + + "npm/libnpmfund": ["libnpmfund@6.0.0", "", { "dependencies": { "@npmcli/arborist": "^8.0.0" }, "bundled": true }, "sha512-+7ZTxPyJ0O/Y0xKoEd1CxPCUQ4ldn6EZ2qUMI/E1gJkfzcwb3AdFlSWk1WEXaGBu2+EqMrPf4Xu5lXFWw2Jd3w=="], + + "npm/libnpmhook": ["libnpmhook@11.0.0", "", { "dependencies": { "aproba": "^2.0.0", "npm-registry-fetch": "^18.0.1" }, "bundled": true }, "sha512-Xc18rD9NFbRwZbYCQ+UCF5imPsiHSyuQA8RaCA2KmOUo8q4kmBX4JjGWzmZnxZCT8s6vwzmY1BvHNqBGdg9oBQ=="], + + "npm/libnpmorg": ["libnpmorg@7.0.0", "", { "dependencies": { "aproba": "^2.0.0", "npm-registry-fetch": "^18.0.1" }, "bundled": true }, "sha512-DcTodX31gDEiFrlIHurBQiBlBO6Var2KCqMVCk+HqZhfQXqUfhKGmFOp0UHr6HR1lkTVM0MzXOOYtUObk0r6Dg=="], + + "npm/libnpmpack": ["libnpmpack@8.0.0", "", { "dependencies": { "@npmcli/arborist": "^8.0.0", "@npmcli/run-script": "^9.0.1", "npm-package-arg": "^12.0.0", "pacote": "^19.0.0" }, "bundled": true }, "sha512-Z5zqR+j8PNOki97D4XnKlekLQjqJYkqCFZeac07XCJYA3aq6O7wYIpn7RqLcNfFm+u3ZsdblY2VQENMoiHA+FQ=="], + + "npm/libnpmpublish": ["libnpmpublish@10.0.1", "", { "dependencies": { "ci-info": "^4.0.0", "normalize-package-data": "^7.0.0", "npm-package-arg": "^12.0.0", "npm-registry-fetch": "^18.0.1", "proc-log": "^5.0.0", "semver": "^7.3.7", "sigstore": "^3.0.0", "ssri": "^12.0.0" }, "bundled": true }, "sha512-xNa1DQs9a8dZetNRV0ky686MNzv1MTqB3szgOlRR3Fr24x1gWRu7aB9OpLZsml0YekmtppgHBkyZ+8QZlzmEyw=="], + + "npm/libnpmsearch": ["libnpmsearch@8.0.0", "", { "dependencies": { "npm-registry-fetch": "^18.0.1" }, "bundled": true }, "sha512-W8FWB78RS3Nkl1gPSHOlF024qQvcoU/e3m9BGDuBfVZGfL4MJ91GXXb04w3zJCGOW9dRQUyWVEqupFjCrgltDg=="], + + "npm/libnpmteam": ["libnpmteam@7.0.0", "", { "dependencies": { "aproba": "^2.0.0", "npm-registry-fetch": "^18.0.1" }, "bundled": true }, "sha512-PKLOoVukN34qyJjgEm5DEOnDwZkeVMUHRx8NhcKDiCNJGPl7G/pF1cfBw8yicMwRlHaHkld1FdujOzKzy4AlwA=="], + + "npm/libnpmversion": ["libnpmversion@7.0.0", "", { "dependencies": { "@npmcli/git": "^6.0.1", "@npmcli/run-script": "^9.0.1", "json-parse-even-better-errors": "^4.0.0", "proc-log": "^5.0.0", "semver": "^7.3.7" }, "bundled": true }, "sha512-0xle91R6F8r/Q/4tHOnyKko+ZSquEXNdxwRdKCPv4kC1cOVBMFXRsKKrVtRKtXcFn362U8ZlJefk4Apu00424g=="], + + "npm/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "npm/make-fetch-happen": ["make-fetch-happen@14.0.3", "", { "dependencies": { "@npmcli/agent": "^3.0.0", "cacache": "^19.0.1", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", "minipass-fetch": "^4.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^5.0.0", "promise-retry": "^2.0.1", "ssri": "^12.0.0" }, "bundled": true }, "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ=="], + + "npm/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" }, "bundled": true }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], + + "npm/minipass": ["minipass@7.1.2", "", { "bundled": true }, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], + + "npm/minipass-collect": ["minipass-collect@2.0.1", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw=="], + + "npm/minipass-fetch": ["minipass-fetch@4.0.1", "", { "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^1.0.3", "minizlib": "^3.0.1" }, "optionalDependencies": { "encoding": "^0.1.13" } }, "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ=="], + + "npm/minipass-flush": ["minipass-flush@1.0.5", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw=="], + + "npm/minipass-pipeline": ["minipass-pipeline@1.2.4", "", { "dependencies": { "minipass": "^3.0.0" }, "bundled": true }, "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A=="], + + "npm/minipass-sized": ["minipass-sized@1.0.3", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g=="], + + "npm/minizlib": ["minizlib@3.0.2", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA=="], + + "npm/mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="], + + "npm/ms": ["ms@2.1.3", "", { "bundled": true }, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + + "npm/mute-stream": ["mute-stream@2.0.0", "", {}, "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA=="], + + "npm/negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="], + + "npm/node-gyp": ["node-gyp@11.2.0", "", { "dependencies": { "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", "make-fetch-happen": "^14.0.3", "nopt": "^8.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5", "tar": "^7.4.3", "tinyglobby": "^0.2.12", "which": "^5.0.0" }, "bundled": true, "bin": { "node-gyp": "bin/node-gyp.js" } }, "sha512-T0S1zqskVUSxcsSTkAsLc7xCycrRYmtDHadDinzocrThjyQCn5kMlEBSj6H4qDbgsIOSLmmlRIeb0lZXj+UArA=="], + + "npm/nopt": ["nopt@8.1.0", "", { "dependencies": { "abbrev": "^3.0.0" }, "bundled": true, "bin": { "nopt": "bin/nopt.js" } }, "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A=="], + + "npm/normalize-package-data": ["normalize-package-data@7.0.0", "", { "dependencies": { "hosted-git-info": "^8.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" }, "bundled": true }, "sha512-k6U0gKRIuNCTkwHGZqblCfLfBRh+w1vI6tBo+IeJwq2M8FUiOqhX7GH+GArQGScA7azd1WfyRCvxoXDO3hQDIA=="], + + "npm/npm-audit-report": ["npm-audit-report@6.0.0", "", { "bundled": true }, "sha512-Ag6Y1irw/+CdSLqEEAn69T8JBgBThj5mw0vuFIKeP7hATYuQuS5jkMjK6xmVB8pr7U4g5Audbun0lHhBDMIBRA=="], + + "npm/npm-bundled": ["npm-bundled@4.0.0", "", { "dependencies": { "npm-normalize-package-bin": "^4.0.0" } }, "sha512-IxaQZDMsqfQ2Lz37VvyyEtKLe8FsRZuysmedy/N06TU1RyVppYKXrO4xIhR0F+7ubIBox6Q7nir6fQI3ej39iA=="], + + "npm/npm-install-checks": ["npm-install-checks@7.1.1", "", { "dependencies": { "semver": "^7.1.1" }, "bundled": true }, "sha512-u6DCwbow5ynAX5BdiHQ9qvexme4U3qHW3MWe5NqH+NeBm0LbiH6zvGjNNew1fY+AZZUtVHbOPF3j7mJxbUzpXg=="], + + "npm/npm-normalize-package-bin": ["npm-normalize-package-bin@4.0.0", "", {}, "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w=="], + + "npm/npm-package-arg": ["npm-package-arg@12.0.2", "", { "dependencies": { "hosted-git-info": "^8.0.0", "proc-log": "^5.0.0", "semver": "^7.3.5", "validate-npm-package-name": "^6.0.0" }, "bundled": true }, "sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA=="], + + "npm/npm-packlist": ["npm-packlist@9.0.0", "", { "dependencies": { "ignore-walk": "^7.0.0" } }, "sha512-8qSayfmHJQTx3nJWYbbUmflpyarbLMBc6LCAjYsiGtXxDB68HaZpb8re6zeaLGxZzDuMdhsg70jryJe+RrItVQ=="], + + "npm/npm-pick-manifest": ["npm-pick-manifest@10.0.0", "", { "dependencies": { "npm-install-checks": "^7.1.0", "npm-normalize-package-bin": "^4.0.0", "npm-package-arg": "^12.0.0", "semver": "^7.3.5" }, "bundled": true }, "sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ=="], + + "npm/npm-profile": ["npm-profile@11.0.1", "", { "dependencies": { "npm-registry-fetch": "^18.0.0", "proc-log": "^5.0.0" }, "bundled": true }, "sha512-HP5Cw9WHwFS9vb4fxVlkNAQBUhVL5BmW6rAR+/JWkpwqcFJid7TihKUdYDWqHl0NDfLd0mpucheGySqo8ysyfw=="], + + "npm/npm-registry-fetch": ["npm-registry-fetch@18.0.2", "", { "dependencies": { "@npmcli/redact": "^3.0.0", "jsonparse": "^1.3.1", "make-fetch-happen": "^14.0.0", "minipass": "^7.0.2", "minipass-fetch": "^4.0.0", "minizlib": "^3.0.1", "npm-package-arg": "^12.0.0", "proc-log": "^5.0.0" }, "bundled": true }, "sha512-LeVMZBBVy+oQb5R6FDV9OlJCcWDU+al10oKpe+nsvcHnG24Z3uM3SvJYKfGJlfGjVU8v9liejCrUR/M5HO5NEQ=="], + + "npm/npm-user-validate": ["npm-user-validate@3.0.0", "", { "bundled": true }, "sha512-9xi0RdSmJ4mPYTC393VJPz1Sp8LyCx9cUnm/L9Qcb3cFO8gjT4mN20P9FAsea8qDHdQ7LtcN8VLh2UT47SdKCw=="], + + "npm/p-map": ["p-map@4.0.0", "", { "dependencies": { "aggregate-error": "^3.0.0" }, "bundled": true }, "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ=="], + + "npm/package-json-from-dist": ["package-json-from-dist@1.0.1", "", {}, "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="], + + "npm/pacote": ["pacote@19.0.1", "", { "dependencies": { "@npmcli/git": "^6.0.0", "@npmcli/installed-package-contents": "^3.0.0", "@npmcli/package-json": "^6.0.0", "@npmcli/promise-spawn": "^8.0.0", "@npmcli/run-script": "^9.0.0", "cacache": "^19.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", "npm-package-arg": "^12.0.0", "npm-packlist": "^9.0.0", "npm-pick-manifest": "^10.0.0", "npm-registry-fetch": "^18.0.0", "proc-log": "^5.0.0", "promise-retry": "^2.0.1", "sigstore": "^3.0.0", "ssri": "^12.0.0", "tar": "^6.1.11" }, "bundled": true, "bin": { "pacote": "bin/index.js" } }, "sha512-zIpxWAsr/BvhrkSruspG8aqCQUUrWtpwx0GjiRZQhEM/pZXrigA32ElN3vTcCPUDOFmHr6SFxwYrvVUs5NTEUg=="], + + "npm/parse-conflict-json": ["parse-conflict-json@4.0.0", "", { "dependencies": { "json-parse-even-better-errors": "^4.0.0", "just-diff": "^6.0.0", "just-diff-apply": "^5.2.0" }, "bundled": true }, "sha512-37CN2VtcuvKgHUs8+0b1uJeEsbGn61GRHz469C94P5xiOoqpDYJYwjg4RY9Vmz39WyZAVkR5++nbJwLMIgOCnQ=="], + + "npm/path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="], + + "npm/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="], + + "npm/picomatch": ["picomatch@4.0.2", "", {}, "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg=="], + + "npm/postcss-selector-parser": ["postcss-selector-parser@7.1.0", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA=="], + + "npm/proc-log": ["proc-log@5.0.0", "", { "bundled": true }, "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ=="], + + "npm/proggy": ["proggy@3.0.0", "", {}, "sha512-QE8RApCM3IaRRxVzxrjbgNMpQEX6Wu0p0KBeoSiSEw5/bsGwZHsshF4LCxH2jp/r6BU+bqA3LrMDEYNfJnpD8Q=="], + + "npm/promise-all-reject-late": ["promise-all-reject-late@1.0.1", "", {}, "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw=="], + + "npm/promise-call-limit": ["promise-call-limit@3.0.2", "", {}, "sha512-mRPQO2T1QQVw11E7+UdCJu7S61eJVWknzml9sC1heAdj1jxl0fWMBypIt9ZOcLFf8FkG995ZD7RnVk7HH72fZw=="], + + "npm/promise-retry": ["promise-retry@2.0.1", "", { "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" } }, "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g=="], + + "npm/promzard": ["promzard@2.0.0", "", { "dependencies": { "read": "^4.0.0" } }, "sha512-Ncd0vyS2eXGOjchIRg6PVCYKetJYrW1BSbbIo+bKdig61TB6nH2RQNF2uP+qMpsI73L/jURLWojcw8JNIKZ3gg=="], + + "npm/qrcode-terminal": ["qrcode-terminal@0.12.0", "", { "bundled": true, "bin": { "qrcode-terminal": "./bin/qrcode-terminal.js" } }, "sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ=="], + + "npm/read": ["read@4.1.0", "", { "dependencies": { "mute-stream": "^2.0.0" }, "bundled": true }, "sha512-uRfX6K+f+R8OOrYScaM3ixPY4erg69f8DN6pgTvMcA9iRc8iDhwrA4m3Yu8YYKsXJgVvum+m8PkRboZwwuLzYA=="], + + "npm/read-cmd-shim": ["read-cmd-shim@5.0.0", "", {}, "sha512-SEbJV7tohp3DAAILbEMPXavBjAnMN0tVnh4+9G8ihV4Pq3HYF9h8QNez9zkJ1ILkv9G2BjdzwctznGZXgu/HGw=="], + + "npm/read-package-json-fast": ["read-package-json-fast@4.0.0", "", { "dependencies": { "json-parse-even-better-errors": "^4.0.0", "npm-normalize-package-bin": "^4.0.0" } }, "sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg=="], + + "npm/retry": ["retry@0.12.0", "", {}, "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="], + + "npm/safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + + "npm/semver": ["semver@7.7.1", "", { "bundled": true, "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="], + + "npm/shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], + + "npm/shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="], + + "npm/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + + "npm/sigstore": ["sigstore@3.1.0", "", { "dependencies": { "@sigstore/bundle": "^3.1.0", "@sigstore/core": "^2.0.0", "@sigstore/protobuf-specs": "^0.4.0", "@sigstore/sign": "^3.1.0", "@sigstore/tuf": "^3.1.0", "@sigstore/verify": "^2.1.0" } }, "sha512-ZpzWAFHIFqyFE56dXqgX/DkDRZdz+rRcjoIk/RQU4IX0wiCv1l8S7ZrXDHcCc+uaf+6o7w3h2l3g6GYG5TKN9Q=="], + + "npm/smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="], + + "npm/socks": ["socks@2.8.4", "", { "dependencies": { "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" } }, "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ=="], + + "npm/socks-proxy-agent": ["socks-proxy-agent@8.0.5", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "^4.3.4", "socks": "^2.8.3" } }, "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw=="], + + "npm/spdx-correct": ["spdx-correct@3.2.0", "", { "dependencies": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA=="], + + "npm/spdx-exceptions": ["spdx-exceptions@2.5.0", "", {}, "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w=="], + + "npm/spdx-expression-parse": ["spdx-expression-parse@4.0.0", "", { "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" }, "bundled": true }, "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ=="], + + "npm/spdx-license-ids": ["spdx-license-ids@3.0.21", "", {}, "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg=="], + + "npm/sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="], + + "npm/ssri": ["ssri@12.0.0", "", { "dependencies": { "minipass": "^7.0.3" }, "bundled": true }, "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ=="], + + "npm/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "npm/string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], + + "npm/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "npm/strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], + + "npm/supports-color": ["supports-color@9.4.0", "", { "bundled": true }, "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw=="], + + "npm/tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" }, "bundled": true }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="], + + "npm/text-table": ["text-table@0.2.0", "", { "bundled": true }, "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="], + + "npm/tiny-relative-date": ["tiny-relative-date@1.3.0", "", { "bundled": true }, "sha512-MOQHpzllWxDCHHaDno30hhLfbouoYlOI8YlMNtvKe1zXbjEVhbcEovQxvZrPvtiYW630GQDoMMarCnjfyfHA+A=="], + + "npm/tinyglobby": ["tinyglobby@0.2.12", "", { "dependencies": { "fdir": "^6.4.3", "picomatch": "^4.0.2" } }, "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww=="], + + "npm/treeverse": ["treeverse@3.0.0", "", { "bundled": true }, "sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ=="], + + "npm/tuf-js": ["tuf-js@3.0.1", "", { "dependencies": { "@tufjs/models": "3.0.1", "debug": "^4.3.6", "make-fetch-happen": "^14.0.1" } }, "sha512-+68OP1ZzSF84rTckf3FA95vJ1Zlx/uaXyiiKyPd1pA4rZNkpEvDAKmsu1xUSmbF/chCRYgZ6UZkDwC7PmzmAyA=="], + + "npm/unique-filename": ["unique-filename@4.0.0", "", { "dependencies": { "unique-slug": "^5.0.0" } }, "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ=="], + + "npm/unique-slug": ["unique-slug@5.0.0", "", { "dependencies": { "imurmurhash": "^0.1.4" } }, "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg=="], + + "npm/util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + + "npm/validate-npm-package-license": ["validate-npm-package-license@3.0.4", "", { "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew=="], + + "npm/validate-npm-package-name": ["validate-npm-package-name@6.0.0", "", { "bundled": true }, "sha512-d7KLgL1LD3U3fgnvWEY1cQXoO/q6EQ1BSz48Sa149V/5zVTAbgmZIpyI8TRi6U9/JNyeYLlTKsEMPtLC27RFUg=="], + + "npm/walk-up-path": ["walk-up-path@3.0.1", "", {}, "sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA=="], + + "npm/which": ["which@5.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bundled": true, "bin": { "node-which": "bin/which.js" } }, "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ=="], + + "npm/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="], + + "npm/wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + + "npm/write-file-atomic": ["write-file-atomic@6.0.0", "", { "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" }, "bundled": true }, "sha512-GmqrO8WJ1NuzJ2DrziEI2o57jKAVIQNf8a18W3nCYU3H7PNWqCCVTeH6/NQE93CIllIgQS98rrmVkYgTX9fFJQ=="], + + "npm/yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="], + + "parse5-htmlparser2-tree-adapter/parse5": ["parse5@6.0.1", "", {}, "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="], + + "pkg-conf/find-up": ["find-up@2.1.0", "", { "dependencies": { "locate-path": "^2.0.0" } }, "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ=="], + + "rc/strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="], + + "read-pkg/unicorn-magic": ["unicorn-magic@0.1.0", "", {}, "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ=="], + + "semantic-release/@semantic-release/error": ["@semantic-release/error@4.0.0", "", {}, "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ=="], + + "semantic-release/aggregate-error": ["aggregate-error@5.0.0", "", { "dependencies": { "clean-stack": "^5.2.0", "indent-string": "^5.0.0" } }, "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw=="], + + "semantic-release/execa": ["execa@9.5.2", "", { "dependencies": { "@sindresorhus/merge-streams": "^4.0.0", "cross-spawn": "^7.0.3", "figures": "^6.1.0", "get-stream": "^9.0.0", "human-signals": "^8.0.0", "is-plain-obj": "^4.1.0", "is-stream": "^4.0.1", "npm-run-path": "^6.0.0", "pretty-ms": "^9.0.0", "signal-exit": "^4.1.0", "strip-final-newline": "^4.0.0", "yoctocolors": "^2.0.0" } }, "sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q=="], + + "semantic-release/get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="], + + "semantic-release/p-reduce": ["p-reduce@3.0.0", "", {}, "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q=="], + + "semver-diff/semver": ["semver@7.7.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA=="], + + "signale/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="], + + "signale/figures": ["figures@2.0.0", "", { "dependencies": { "escape-string-regexp": "^1.0.5" } }, "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA=="], + + "strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], + + "supports-hyperlinks/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + + "tempy/is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="], + + "tempy/type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="], + + "wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "@commitlint/parse/conventional-commits-parser/meow": ["meow@12.1.1", "", {}, "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw=="], + + "@commitlint/parse/conventional-commits-parser/split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="], + + "@octokit/plugin-paginate-rest/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="], + + "@octokit/plugin-throttling/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="], + + "@semantic-release/github/aggregate-error/clean-stack": ["clean-stack@5.2.0", "", { "dependencies": { "escape-string-regexp": "5.0.0" } }, "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ=="], + + "@semantic-release/github/aggregate-error/indent-string": ["indent-string@5.0.0", "", {}, "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg=="], + + "@semantic-release/npm/aggregate-error/clean-stack": ["clean-stack@5.2.0", "", { "dependencies": { "escape-string-regexp": "5.0.0" } }, "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ=="], + + "@semantic-release/npm/aggregate-error/indent-string": ["indent-string@5.0.0", "", {}, "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg=="], + + "@semantic-release/npm/execa/@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@4.0.0", "", {}, "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="], + + "@semantic-release/npm/execa/get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="], + + "@semantic-release/npm/execa/human-signals": ["human-signals@8.0.1", "", {}, "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ=="], + + "@semantic-release/npm/execa/is-stream": ["is-stream@4.0.1", "", {}, "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A=="], + + "@semantic-release/npm/execa/npm-run-path": ["npm-run-path@6.0.0", "", { "dependencies": { "path-key": "^4.0.0", "unicorn-magic": "^0.3.0" } }, "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA=="], + + "@semantic-release/npm/execa/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + + "@semantic-release/npm/execa/strip-final-newline": ["strip-final-newline@4.0.0", "", {}, "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw=="], + + "cli-highlight/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "cli-highlight/chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="], + + "cli-highlight/yargs/cliui": ["cliui@7.0.4", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ=="], + + "cli-highlight/yargs/yargs-parser": ["yargs-parser@20.2.9", "", {}, "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="], + + "env-ci/execa/get-stream": ["get-stream@8.0.1", "", {}, "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA=="], + + "env-ci/execa/human-signals": ["human-signals@5.0.0", "", {}, "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ=="], + + "env-ci/execa/is-stream": ["is-stream@3.0.0", "", {}, "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="], + + "env-ci/execa/npm-run-path": ["npm-run-path@5.3.0", "", { "dependencies": { "path-key": "^4.0.0" } }, "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ=="], + + "env-ci/execa/onetime": ["onetime@6.0.0", "", { "dependencies": { "mimic-fn": "^4.0.0" } }, "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ=="], + + "env-ci/execa/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + + "env-ci/execa/strip-final-newline": ["strip-final-newline@3.0.0", "", {}, "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw=="], + + "normalize-package-data/hosted-git-info/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], + + "npm/@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], + + "npm/@isaacs/cliui/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="], + + "npm/@npmcli/metavuln-calculator/pacote": ["pacote@20.0.0", "", { "dependencies": { "@npmcli/git": "^6.0.0", "@npmcli/installed-package-contents": "^3.0.0", "@npmcli/package-json": "^6.0.0", "@npmcli/promise-spawn": "^8.0.0", "@npmcli/run-script": "^9.0.0", "cacache": "^19.0.0", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", "npm-package-arg": "^12.0.0", "npm-packlist": "^9.0.0", "npm-pick-manifest": "^10.0.0", "npm-registry-fetch": "^18.0.0", "proc-log": "^5.0.0", "promise-retry": "^2.0.1", "sigstore": "^3.0.0", "ssri": "^12.0.0", "tar": "^6.1.11" }, "bin": { "pacote": "bin/index.js" } }, "sha512-pRjC5UFwZCgx9kUFDVM9YEahv4guZ1nSLqwmWiLUnDbGsjs+U5w7z6Uc8HNR1a6x8qnu5y9xtGE6D1uAuYz+0A=="], + + "npm/cacache/p-map": ["p-map@7.0.3", "", {}, "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA=="], + + "npm/cacache/tar": ["tar@7.4.3", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.0.1", "mkdirp": "^3.0.1", "yallist": "^5.0.0" } }, "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw=="], + + "npm/cross-spawn/which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], + + "npm/minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "npm/minipass-pipeline/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "npm/minipass-sized/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "npm/node-gyp/tar": ["tar@7.4.3", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.0.1", "mkdirp": "^3.0.1", "yallist": "^5.0.0" } }, "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw=="], + + "npm/spdx-correct/spdx-expression-parse": ["spdx-expression-parse@3.0.1", "", { "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q=="], + + "npm/tar/fs-minipass": ["fs-minipass@2.1.0", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg=="], + + "npm/tar/minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="], + + "npm/tar/minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="], + + "npm/validate-npm-package-license/spdx-expression-parse": ["spdx-expression-parse@3.0.1", "", { "dependencies": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q=="], + + "npm/wrap-ansi/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="], + + "npm/wrap-ansi/strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="], + + "npm/wrap-ansi-cjs/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + + "pkg-conf/find-up/locate-path": ["locate-path@2.0.0", "", { "dependencies": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" } }, "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA=="], + + "semantic-release/aggregate-error/clean-stack": ["clean-stack@5.2.0", "", { "dependencies": { "escape-string-regexp": "5.0.0" } }, "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ=="], + + "semantic-release/aggregate-error/indent-string": ["indent-string@5.0.0", "", {}, "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg=="], + + "semantic-release/execa/@sindresorhus/merge-streams": ["@sindresorhus/merge-streams@4.0.0", "", {}, "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ=="], + + "semantic-release/execa/get-stream": ["get-stream@9.0.1", "", { "dependencies": { "@sec-ant/readable-stream": "^0.4.1", "is-stream": "^4.0.1" } }, "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA=="], + + "semantic-release/execa/human-signals": ["human-signals@8.0.1", "", {}, "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ=="], + + "semantic-release/execa/is-stream": ["is-stream@4.0.1", "", {}, "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A=="], + + "semantic-release/execa/npm-run-path": ["npm-run-path@6.0.0", "", { "dependencies": { "path-key": "^4.0.0", "unicorn-magic": "^0.3.0" } }, "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA=="], + + "semantic-release/execa/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + + "semantic-release/execa/strip-final-newline": ["strip-final-newline@4.0.0", "", {}, "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw=="], + + "signale/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], + + "signale/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="], + + "signale/figures/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], + + "wrap-ansi/ansi-styles/color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "@semantic-release/npm/execa/npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], + + "cli-highlight/chalk/ansi-styles/color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], + + "env-ci/execa/npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], + + "env-ci/execa/onetime/mimic-fn": ["mimic-fn@4.0.0", "", {}, "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw=="], + + "npm/@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], + + "npm/@isaacs/cliui/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], + + "npm/cacache/tar/chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], + + "npm/cacache/tar/mkdirp": ["mkdirp@3.0.1", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="], + + "npm/cacache/tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], + + "npm/cross-spawn/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], + + "npm/node-gyp/tar/chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], + + "npm/node-gyp/tar/mkdirp": ["mkdirp@3.0.1", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="], + + "npm/node-gyp/tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], + + "npm/tar/fs-minipass/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "npm/tar/minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + + "npm/wrap-ansi/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="], + + "npm/wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@6.1.0", "", {}, "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="], + + "pkg-conf/find-up/locate-path/p-locate": ["p-locate@2.0.0", "", { "dependencies": { "p-limit": "^1.1.0" } }, "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg=="], + + "pkg-conf/find-up/locate-path/path-exists": ["path-exists@3.0.0", "", {}, "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ=="], + + "semantic-release/execa/npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="], + + "signale/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="], + + "wrap-ansi/ansi-styles/color-convert/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "cli-highlight/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], + + "pkg-conf/find-up/locate-path/p-locate/p-limit": ["p-limit@1.3.0", "", { "dependencies": { "p-try": "^1.0.0" } }, "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q=="], } } diff --git a/config/api-extractor.json b/config/api-extractor.json index 393b8fd..5063ac4 100644 --- a/config/api-extractor.json +++ b/config/api-extractor.json @@ -45,7 +45,7 @@ * * SUPPORTED TOKENS: , , */ - "mainEntryPointFilePath": "/temptypes/index.d.ts", + "mainEntryPointFilePath": "/lib/index.d.ts", /** * A list of NPM package names whose exports should be treated as part of this package. diff --git a/examples/buffers.js b/examples/buffers.js deleted file mode 100644 index f1b447c..0000000 --- a/examples/buffers.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * This example uses the following structs defined in C++: - struct vector { - float x, y, z; - }; - - struct player { - vector position; - double health; - std::string name; - float distance; - bool alive; - }; -*/ - -// https://github.com/LordVonAdel/structron -const Struct = require('structron'); -const memoryjs = require('../index'); - -const processObject = memoryjs.openProcess('Testing.exe'); -const structAddress = 0x000000DEADBEEF; - -// -- Step 1: define the structures - -// Custom double consumer/producer (since it's not yet implemented in `structron`) -const double = { - read(buffer, offset) { - return buffer.readDoubleLE(offset); - }, - write(value, context, offset) { - context.buffer.writeDoubleLE(value, offset); - }, - SIZE: 8, -}; - -// Use string consumer/producer provided by the library (custom implementation for `std::string`), -// pass process handle and base address of structure so the library can read/write the string, -// also requires passing the platform architecture to determine the structure of `std::string` -const string = memoryjs.STRUCTRON_TYPE_STRING(processObject.handle, structAddress, '64'); - -// Define vector structure -const Vector = new Struct() - .addMember(Struct.TYPES.FLOAT, 'x') // 4 bytes - .addMember(Struct.TYPES.FLOAT, 'y') // 4 bytes - .addMember(Struct.TYPES.FLOAT, 'z'); // 4 bytes - -// Define player structure -const Player = new Struct() - .addMember(Vector, 'position') // 12 bytes - .addMember(Struct.TYPES.SKIP(4), 'unused') // compiler padding to put member on 8 byte boundary - .addMember(double, 'health') // 8 bytes - .addMember(string, 'name') // 32 bytes (in 64bit process, 24 bytes in 32bit process) - .addMember(Struct.TYPES.FLOAT, 'distance') // 4 bytes - .addMember(Struct.TYPES.BYTE, 'alive'); // 1 byte - -// -- Step 2: create object to write to memory -const object = { - position: { - x: 1.23, y: 4.56, z: 7.89, - }, - health: 80.12, - name: 'Example Name 1234567890', - distance: 4.20, - alive: false, -}; - -// -- Step 3: create buffer from object and write to memory -let context = Player.write(object); -memoryjs.writeBuffer(processObject.handle, structAddress, context.buffer); - -// -- Step 4: read buffer from memory and parse -const buffer = memoryjs.readBuffer(processObject.handle, structAddress, context.buffer.length); - -context = Player.readContext(buffer); - -if (!context.hasErrors()) { - console.log(context.data); -} diff --git a/examples/debugging.js b/examples/debugging.js deleted file mode 100644 index 225e446..0000000 --- a/examples/debugging.js +++ /dev/null @@ -1,92 +0,0 @@ -const memoryjs = require('../index'); -const processName = 'Testing Things.exe'; - -const processObject = memoryjs.openProcess(processName); -const processId = processObject.th32ProcessID; - -// Address of variable -const address = 0xEFFBF0; - -// When should we breakpoint? On read, write or execute -const trigger = memoryjs.TRIGGER_ACCESS; -const dataType = memoryjs.INT; - -// Whether to end the process once debugging has finished -const killOnDetatch = false; - -/** - * Example 1: Using the `Debugger` wrapper class. - * The library contanis a wrapper class for hardware debugging. - * It works by simply registering a hardware breakpoint and - * then listening for all debug events that are emitted when - * a breakpoint occurs. - */ - -const hardwareDebugger = memoryjs.Debugger; - -// Attach the debugger to the process -hardwareDebugger.attach(processId, killOnDetatch); - -const registerUsed = hardwareDebugger.setHardwareBreakpoint(processId, address, trigger, dataType); - -// `debugEvent` event emission catches debug events from all registers -hardwareDebugger.on('debugEvent', ({ register, event }) => { - console.log(`Hardware Register ${register} breakpoint`); - console.log(event); -}); - -// You can listen to debug events from specific hardware registers -// by listening to whatever register was returned from `setHardwareBreakpoint` -hardwareDebugger.on(registerUsed, (event) => { - console.log(event); -}); - -// Don't forget to call `hardwareDebugger.detatch()` when you're done! - -/** - * Example 2: Manually using the exposed functions - * There are a few steps involved when not using the wrapper: - * - * 1. Attatch the debugger - * 2. Set your hardware breakpoints by manually referencing - * which register you want to set. It's important you keep - * track of which hardware registers you use as there are only 4 - * meaning only 4 breakpoints can be set. - * You also need to manually reference the size of the data type. - * 3. Constantly call `awaitDebugEvent` to wait for debug events - * 4. When a debug event occurs, call `handleDebugEvent` - * 5. Don't forget to detatch the debugger via `memoryjs.detatch(processId)` - */ - -memoryjs.attachDebugger(processId, killOnDetatch); - -// There are 4 hardware registers: -// `memoryjs.DR0` through `memoryjs.DR3` -const registerToUse = memoryjs.DR0; - -// Our `address` references an integer variable. An integer -// is 4 bytes therefore we pass `4` to the `size` parameter. -const size = 4; -memoryjs.setHardwareBreakpoint(processId, address, registerToUse, trigger, size); - -// How long to wait for the debug event before timing out -const timeout = 100; - -// The interval duration must be the same or larger than the `timeout` value. -// `awaitDebugEvent` works by waiting a certain amount of time before timing out, -// therefore we only want to call the method again when we're sure the previous -// call has already timed out. -setInterval(() => { - // `debugEvent` can be null if no event occurred - const debugEvent = memoryjs.awaitDebugEvent(registerToUse, timeout); - - // If a breakpoint occurred, handle it - if (debugEvent) { - memoryjs.handleDebugEvent(debugEvent.processId, debugEvent.threadId); - } -}, timeout); - -// Don't forget to detatch the debugger! -// memoryjs.detatchDebugger(processId); - -memoryjs.closeProcess(processObject.handle); diff --git a/examples/general.js b/examples/general.js deleted file mode 100644 index 0b1e5e2..0000000 --- a/examples/general.js +++ /dev/null @@ -1,104 +0,0 @@ -const memoryjs = require('./index'); -const processName = 'csgo.exe'; -let clientModule; -const offset = 0x00A9D44C; - -// open a process (sync) -const processObject = memoryjs.openProcess(processName); - -// open a process (async) -memoryjs.openProcess(processName, (error, processObject) => { - console.log(JSON.stringify(processObject, null, 3)); - - if (process.szExeFile) { - console.log('Successfully opened handle on', processName); - - memoryjs.closeProcess(processObject.handle); - console.log('Closed handle on', processName); - } else { - console.log('Unable to open handle on', processName); - } -}); - -// get all processes (sync) -const processes = memoryjs.getProcesses(); -console.log('\nGetting all processes (sync)\n---\n'); -processes.forEach(({ szExeFile }) => console.log(szExeFile)); - -// get all processes (async) -console.log('\nGetting all processes (async)\n---\n'); -memoryjs.getProcesses((error, processes) => { - processes.forEach(({ szExeFile }) => console.log(szExeFile)); -}); - -/* process = -{ cntThreads: 47, - szExeFile: "csgo.exe", - th32ProcessID: 10316, - th32ParentProcessID: 7804, - pcPriClassBase: 8 } */ - -// get all modules (sync) -console.log('\nGetting all modules (sync)\n---\n'); -const modules = memoryjs.getModules(processObject.th32ProcessID); -modules.forEach(({ szExeFile }) => console.log(szExeFile)); - -// get all modules (async) -console.log('\nGetting all modules (async)\n---\n'); -memoryjs.getModules(processObject.th32ProcessID, (error, modules) => { - modules.forEach(({ szExeFile }) => console.log(szExeFile)); -}); - -// find a module associated with a process (sync) -console.log('\nFinding module "client.dll" (sync)\n---\n'); -console.log(memoryjs.findModule('client.dll', processObject.th32ProcessID)); - -// find a module associated with a process (async) -console.log('\nFinding module "client.dll" (async)\n---\n'); -memoryjs.findModule('client.dll', processObject.th32ProcessID, (error, module) => { - console.log(module.szModule); - clientModule = module; -}); - -/* module = -{ modBaseAddr: 468123648, - modBaseSize: 80302080, - szExePath: 'c:\\program files (x86)\\steam\\steamapps\\common\\counter-strike global offensive\\csgo\\bin\\client.dll', - szModule: 'client.dll', - th32ProcessID: 10316 } */ - -const address = clientModule.modBaseAddr + offset; - -// read memory (sync) -console.log(`value of 0x${address.toString(16)}: ${memoryjs.readMemory(processObject.handle, address, memoryjs.INT)}`); - -// read memory (async) -memoryjs.readMemory(processObject.handle, address, memoryjs.INT, (error, result) => { - console.log(`value of 0x${address.toString(16)}: ${result}`); -}); - -// write memory -memoryjs.writeMemory(processObject.handle, address, 1, memoryjs.INT); - -// pattern reading -const signature = 'A3 ? ? ? ? C7 05 ? ? ? ? ? ? ? ? E8 ? ? ? ? 59 C3 6A'; -const signatureTypes = memoryjs.READ | memoryjs.SUBTRACT; -const patternOffset = 0x1; -const addressOffset = 0x10; -const dwLocalPlayer = memoryjs.findPattern(processObject.handle, clientModule.szModule, signature, signatureTypes, patternOffset, addressOffset); -console.log(`value of dwLocalPlayer: 0x${dwLocalPlayer.toString(16)}`); - -// inject dll -memoryjs.injectDll(processObject.handle, 'C:\\TestDLL.dll', (error, success) => { - console.log(`injected TestDLL.dll into process: ${success} ${error}`); -}); - -// unload dll (by name) -memoryjs.unloadDll(processObject.handle, 'TestDLL.dll', (error, success) => { - console.log(`unloaded TestDLL.dll from process: ${success} ${error}`); -}); - -// unload dll (by module base address) -// const testDll = memoryjs.findModule('TestDLL.dll', processObject.th32ProcessID); -// const success = memoryjs.unloadDll(processObject.handle, testDll.modBaseAddr); -// console.log(`unloaded TestDLL.dll from process: ${success}`); diff --git a/examples/read_game_memory.ts b/examples/read_game_memory.ts new file mode 100644 index 0000000..16651c9 --- /dev/null +++ b/examples/read_game_memory.ts @@ -0,0 +1,61 @@ +import { openProcess, closeProcess, readMemory } from '../lib'; + +const PROCESS_NAME = "DarkSoulsRemastered.exe"; + +try { + // 1. Open the game process + console.log(`Attempting to open process: ${PROCESS_NAME}`); + const processObject = openProcess(PROCESS_NAME); + + if (!processObject || !processObject.handle) { + console.error(`Failed to open process "${PROCESS_NAME}". Is the game running?`); + process.exit(1); // Use Bun's exit + } + + console.log(`Process "${PROCESS_NAME}" opened successfully.`); + console.log(`Process ID: ${processObject.th32ProcessID}`); + console.log(`Base Address: 0x${processObject.modBaseAddr.toString(16)}`); // Log base address in hex + + // 2. Define offsets (these are specific to Dark Souls Remastered and might need updates) + const playerDataBase = 0x1D278F0; + const playerDataStruct = 0x10; + const soulsOffset = 0x94; + + // 3. Read the pointer chain to find the souls address + console.log(`Reading player data base pointer at BaseAddress + 0x${playerDataBase.toString(16)}`); + const pointer1Address = processObject.modBaseAddr + playerDataBase; + const pointer1Value = readMemory(processObject.handle, pointer1Address, "int"); // Assuming 32-bit pointers/game + if (pointer1Value === 0) { + console.error(`Failed to read base pointer at 0x${pointer1Address.toString(16)}. Value was 0.`); + closeProcess(processObject.handle); + process.exit(1); + } + console.log(`Read Pointer 1 Value (Player Data Base): 0x${pointer1Value.toString(16)}`); + + + console.log(`Reading player data struct pointer at Pointer1Value + 0x${playerDataStruct.toString(16)}`); + const pointer2Address = pointer1Value + playerDataStruct; + const pointer2Value = readMemory(processObject.handle, pointer2Address, "int"); + if (pointer2Value === 0) { + console.error(`Failed to read pointer 2 at 0x${pointer2Address.toString(16)}. Value was 0.`); + closeProcess(processObject.handle); + process.exit(1); + } + console.log(`Read Pointer 2 Value (Player Data Struct): 0x${pointer2Value.toString(16)}`); + + const soulsAddress = pointer2Value + soulsOffset; + console.log(`Calculated Souls Address: 0x${soulsAddress.toString(16)}`); + + // 4. Read the souls value from the final address + const currentSouls = readMemory(processObject.handle, soulsAddress, "int"); + + console.log(`\nCurrent Player Souls: ${currentSouls}`); + + // 5. Close the process handle + console.log("Closing process handle."); + closeProcess(processObject.handle); + console.log("Process handle closed."); + +} catch (error) { + console.error("An error occurred:", error); +} diff --git a/examples/vectors.js b/examples/vectors.js deleted file mode 100644 index 7e1dc11..0000000 --- a/examples/vectors.js +++ /dev/null @@ -1,47 +0,0 @@ -const memoryjs = require('./index'); -const processName = 'Test Project.exe'; - -const processObject = memoryjs.openProcess(processName); -console.log(JSON.stringify(processObject, null, 3)); - -const modules = memoryjs.getModules(processObject.th32ProcessID); -modules.forEach(module => console.log(module)); - -/* How to read a "string" - * C++ code: - * ``` - * std::string str = "this is a sample string"; - * std::cout << "Address: " << (DWORD) str.c_str() << ", value: " << str.c_str() << std::endl; - * ``` - * This will create a string and the address of the string and the value of the string. - */ - -const str = memoryjs.readMemory(0x69085bc0, memoryjs.STRING); -console.log(str); // "this is a sample string"; - -/* How to read and write vectors - * C++ code: - * ``` - * struct Vector3 { float x, y, z; }; - * struct Vector4 { float w, x, y, z; }; - * Vector3 vec3 = { 1.0f, 2.0f, 3.0f }; - * Vector4 vec4 = { 1.0f, 2.0f, 3.0f, 4.0f }; - * std::cout << "[Vec3] Address: " << &vec3 << std::endl; - * std::cout << "[Vec4] Address: " << &vec4 << std::endl; - */ - -let vec3 = { - x: 0, y: 0, z: 0, -}; -memoryjs.writeMemory(0x000001, vec3, memoryjs.VEC3); -vec3 = memoryjs.readMemory(0x000001, memoryjs.VEC3); // { x, y, z } -console.log(vec3); - -let vec4 = { - w: 0, x: 0, y: 0, z: 0, -}; -memoryjs.writeMemory(0x000002, vec4, memoryjs.VEC4); -vec4 = memoryjs.readMemory(0x000002, memoryjs.VEC4); // { w, x, y, z } -console.log(vec4); - -memoryjs.closeProcess(processObject.handle); diff --git a/index.ts b/index.ts deleted file mode 100644 index 506bf84..0000000 --- a/index.ts +++ /dev/null @@ -1,638 +0,0 @@ -import fs from "node:fs"; -import Debugger from "./src/debugger"; -import { STRUCTRON_TYPE_STRING, isDataTypeBE } from "./src/utils"; - -// Type imports -import type { - AllocationType, - CallFunctionCallback, - DataType, - DataTypeToType, - DataTypeToWriteType, - FindModuleCallback, - FindPatternCallback, - FunctionArg, - FunctionReturnValue, - FunctionType, - GetModulesCallback, - GetProcessesCallback, - GetRegionsCallback, - InjectDllCallback, - MemoryJS, - MemoryRegion, - ModuleInfo, - OpenProcessCallback, - ProcessInfo, - Protection, - ReadBufferCallback, - ReadMemoryBECallback, - ReadMemoryCallback, - UnloadDllCallback, - VirtualAllocExCallback, - VirtualProtectExCallback, - VirtualQueryExCallback, -} from "./src/types"; - -const memoryjs = require("./build/Release/memoryjs.node") as MemoryJS; - -/* TODO: - * - remove callbacks from all functions and implement promise support using Napi - * - validate argument types in JS space instead of C++ - * - refactor read/write memory functions to use buffers instead? - * - remove `closeProcess` in favour of `closeHandle` - * - REFACTOR IMPORTS ON ALL SRC FILES AND ORGANIZE, EXPORT ALL FROM INDEX.TS - */ - -export function openProcess(processName: string): ProcessInfo; -export function openProcess(processId: number): ProcessInfo; -export function openProcess( - processName: string, - callback: OpenProcessCallback, -): undefined; -export function openProcess( - processId: number, - callback: OpenProcessCallback, -): undefined; -export function openProcess( - processIdentifier: string | number, - callback?: OpenProcessCallback, -): ProcessInfo | undefined { - // Handle synchronous calls - if (!callback) { - if (typeof processIdentifier === "string") { - return memoryjs.openProcess(processIdentifier as string); - } - return memoryjs.openProcess(processIdentifier as number); - } - - // Handle asynchronous calls - if (typeof processIdentifier === "string") { - return memoryjs.openProcess(processIdentifier as string, callback); - } - return memoryjs.openProcess(processIdentifier as number, callback); -} - -export function closeProcess(handle: number): undefined { - return memoryjs.closeProcess(handle); -} - -export function getProcesses(): ProcessInfo[]; -export function getProcesses(callback: GetProcessesCallback): undefined; -export function getProcesses( - callback?: GetProcessesCallback, -): ProcessInfo[] | undefined { - if (!callback) { - return memoryjs.getProcesses(); - } - - return memoryjs.getProcesses(callback); -} - -export function findModule(moduleName: string, processId: number): ModuleInfo; -export function findModule( - moduleName: string, - processId: number, - callback: FindModuleCallback, -): undefined; -export function findModule( - moduleName: string, - processId: number, - callback?: FindModuleCallback, -): ModuleInfo | undefined { - if (moduleName && processId) { - return memoryjs.findModule(moduleName, processId); - } - - return memoryjs.findModule(moduleName, processId, callback); -} - -export function getModules(processId: number): ModuleInfo[]; -export function getModules( - processId: number, - callback: GetModulesCallback, -): undefined; -export function getModules( - processId: number, - callback?: GetModulesCallback, -): ModuleInfo[] | undefined { - if (!callback) { - return memoryjs.getModules(processId); - } - - return memoryjs.getModules(processId, callback); -} - -export function readMemory( - handle: number, - address: number | bigint, - dataType: T, -): DataTypeToType; -export function readMemory( - handle: number, - address: number | bigint, - dataType: T, - callback: ReadMemoryCallback>, -): undefined; -export function readMemory( - handle: number, - address: number | bigint, - dataType: T, - callback?: ReadMemoryCallback>, -): DataTypeToType | undefined { - if (isDataTypeBE(dataType)) { - return readMemoryBE(handle, address, dataType, callback as ReadMemoryBECallback>); - } - - if (!callback) { - return memoryjs.readMemory(handle, address, dataType); - } - - return memoryjs.readMemory(handle, address, dataType, callback); -} - -export function readMemoryBE( - handle: number, - address: number | bigint, - dataType: T, -): DataTypeToType; -export function readMemoryBE( - handle: number, - address: number | bigint, - dataType: T, - callback: ReadMemoryBECallback>, -): undefined; -export function readMemoryBE( - handle: number, - address: number | bigint, - dataType: T, - callback?: ReadMemoryBECallback>, -): DataTypeToType | undefined { - let value = null; - - switch (dataType) { - case "int64_be": - value = readBuffer(handle, address, 8).readBigInt64BE(); - break; - - case "uint64_be": - value = readBuffer(handle, address, 8).readBigUInt64BE(); - break; - - case "int32_be": - case "int_be": - case "long_be": - value = readBuffer(handle, address, 4).readInt32BE(); - break; - - case "uint32_be": - case "uint_be": - case "ulong_be": - value = readBuffer(handle, address, 4).readUInt32BE(); - break; - - case "int16_be": - case "short_be": - value = readBuffer(handle, address, 2).readInt16BE(); - break; - - case "uint16_be": - case "ushort_be": - value = readBuffer(handle, address, 2).readUInt16BE(); - break; - - case "float_be": - value = readBuffer(handle, address, 4).readFloatBE(); - break; - - case "double_be": - value = readBuffer(handle, address, 8).readDoubleBE(); - break; - } - - if (!callback) { - if (value === null) { - throw new Error("Invalid data type argument!"); - } - return value as DataTypeToType; - } - - callback( - value === null ? "Invalid data type argument!" : "", - value as DataTypeToType, - ); -} - -export function readBuffer( - handle: number, - address: number | bigint, - size: number, -): Buffer; -export function readBuffer( - handle: number, - address: number | bigint, - size: number, - callback: ReadBufferCallback, -): undefined; -export function readBuffer( - handle: number, - address: number | bigint, - size: number, - callback?: ReadBufferCallback, -): Buffer | undefined { - if (!callback) { - return memoryjs.readBuffer(handle, address, size); - } - return memoryjs.readBuffer(handle, address, size, callback); -} - -export function writeMemory( - handle: number, - address: number | bigint, - value: DataTypeToWriteType, - dataType: T, -): undefined { - let dataValue: DataTypeToWriteType = value; - if ( - (dataType === "str" || dataType === "string") && - typeof value === "string" - ) { - dataValue = `${value}\0` as DataTypeToWriteType; // add terminator - } - - const bigintTypes = ["int64", "int64_be", "uint64", "uint64_be"]; - if (bigintTypes.indexOf(dataType) !== -1 && typeof value !== "bigint") { - throw new Error(`${dataType.toUpperCase()} expects type BigInt`); - } - - if (isDataTypeBE(dataType)) { - return writeMemoryBE(handle, address, dataValue, dataType); - } - - return memoryjs.writeMemory(handle, address, dataValue, dataType); -} - -export function writeMemoryBE( - handle: number, - address: number | bigint, - value: DataTypeToWriteType, - dataType: T, -): undefined { - let buffer: Buffer | null = null; - - switch (dataType) { - case "int64_be": - if (typeof value !== "bigint") { - throw new Error("INT64_BE expects type BigInt"); - } - buffer = Buffer.alloc(8); - buffer.writeBigInt64BE(value); - break; - - case "uint64_be": - if (typeof value !== "bigint") { - throw new Error("UINT64_BE expects type BigInt"); - } - buffer = Buffer.alloc(8); - buffer.writeBigUInt64BE(value); - break; - - case "int32_be": - case "int_be": - case "long_be": - buffer = Buffer.alloc(4); - buffer.writeInt32BE(value as number); - break; - - case "uint32_be": - case "uint_be": - case "ulong_be": - buffer = Buffer.alloc(4); - buffer.writeUInt32BE(value as number); - break; - - case "int16_be": - case "short_be": - buffer = Buffer.alloc(2); - buffer.writeInt16BE(value as number); - break; - - case "uint16_be": - case "ushort_be": - buffer = Buffer.alloc(2); - buffer.writeUInt16BE(value as number); - break; - - case "float_be": - buffer = Buffer.alloc(4); - buffer.writeFloatBE(value as number); - break; - - case "double_be": - buffer = Buffer.alloc(8); - buffer.writeDoubleBE(value as number); - break; - } - - if (buffer == null) { - throw new Error("Invalid data type argument!"); - } - - return writeBuffer(handle, address, buffer); -} - -export function writeBuffer( - handle: number, - address: number | bigint, - buffer: Buffer, -): undefined { - return memoryjs.writeBuffer(handle, address, buffer); -} - -export function findPattern( - handle: number, - pattern: string, - flags: number, - patternOffset: number, -): number; -export function findPattern( - handle: number, - pattern: string, - flags: number, - patternOffset: number, - callback: FindPatternCallback, -): undefined; -export function findPattern( - handle: number, - pattern: string, - flags: number, - patternOffset: number, - callback?: FindPatternCallback, -): number | undefined { - if (!callback) { - return memoryjs.findPattern(handle, pattern, flags, patternOffset); - } - - return memoryjs.findPattern(handle, pattern, flags, patternOffset, callback); -} - -export function callFunction( - handle: number, - args: FunctionArg[], - returnType: FunctionType, - address: number | bigint, -): FunctionReturnValue; -export function callFunction( - handle: number, - args: FunctionArg[], - returnType: FunctionType, - address: number | bigint, - callback: CallFunctionCallback, -): undefined; -export function callFunction( - handle: number, - args: FunctionArg[], - returnType: FunctionType, - address: number | bigint, - callback?: CallFunctionCallback, -): FunctionReturnValue | undefined { - if (!callback) { - return memoryjs.callFunction(handle, args, returnType, address); - } - - return memoryjs.callFunction(handle, args, returnType, address, callback); -} - -export function virtualAllocEx( - handle: number, - address: number | bigint | null, - size: number, - allocationType: AllocationType, - protection: Protection, -): number; -export function virtualAllocEx( - handle: number, - address: number | bigint | null, - size: number, - allocationType: AllocationType, - protection: Protection, - callback: VirtualAllocExCallback, -): undefined; -export function virtualAllocEx( - handle: number, - address: number | bigint | null, - size: number, - allocationType: AllocationType, - protection: Protection, - callback?: VirtualAllocExCallback, -): number | undefined{ - if (!callback) { - return memoryjs.virtualAllocEx( - handle, - address, - size, - allocationType, - protection, - ); - } - - return memoryjs.virtualAllocEx( - handle, - address, - size, - allocationType, - protection, - callback, - ); -} - -export function virtualProtectEx( - handle: number, - address: number | bigint, - size: number, - protection: Protection, -): number; -export function virtualProtectEx( - handle: number, - address: number | bigint, - size: number, - protection: Protection, - callback: VirtualProtectExCallback, -): undefined; -export function virtualProtectEx( - handle: number, - address: number | bigint, - size: number, - protection: Protection, - callback?: VirtualProtectExCallback, -): number | undefined { - if (!callback) { - return memoryjs.virtualProtectEx(handle, address, size, protection); - } - - return memoryjs.virtualProtectEx(handle, address, size, protection, callback); -} - -export function getRegions(handle: number): MemoryRegion[]; -export function getRegions(handle: number, callback: GetRegionsCallback): undefined; -export function getRegions( - handle: number, - callback?: GetRegionsCallback, -): MemoryRegion[] | undefined { - if (!callback) { - return memoryjs.getRegions(handle); - } - - return memoryjs.getRegions(handle, callback); -} - -export function virtualQueryEx( - handle: number, - address: number | bigint, -): MemoryRegion; -export function virtualQueryEx( - handle: number, - address: number | bigint, - callback: VirtualQueryExCallback, -): undefined; -export function virtualQueryEx( - handle: number, - address: number | bigint, - callback?: VirtualQueryExCallback, -): MemoryRegion | undefined { - if (!callback) { - return memoryjs.virtualQueryEx(handle, address); - } - - return memoryjs.virtualQueryEx(handle, address, callback); -} - -export function injectDll(handle: number, dllPath: string): boolean; -export function injectDll( - handle: number, - dllPath: string, - callback: InjectDllCallback, -): undefined; -export function injectDll( - handle: number, - dllPath: string, - callback?: InjectDllCallback, -): boolean | undefined { - if (!dllPath.endsWith(".dll")) { - throw new Error("Given path is invalid: file is not of type 'dll'."); - } - - if (!fs.existsSync(dllPath)) { - throw new Error("Given path is invalid: file does not exist."); - } - - if (!callback) { - return memoryjs.injectDll(handle, dllPath); - } - - return memoryjs.injectDll(handle, dllPath, callback); -} - -export function unloadDll( - handle: number, - moduleaddress: number | bigint, -): boolean; -export function unloadDll(handle: number, moduleName: string): boolean; -export function unloadDll( - handle: number, - moduleaddress: number | bigint, - callback: UnloadDllCallback, -): undefined; -export function unloadDll( - handle: number, - moduleName: string, - callback: UnloadDllCallback, -): undefined; -export function unloadDll( - handle: number, - moduleAddressOrName: number | bigint | string, - callback?: UnloadDllCallback, -): boolean | undefined { - // Handle synchronous calls - if (!callback) { - if (typeof moduleAddressOrName === "number") { - return memoryjs.unloadDll(handle, moduleAddressOrName as number); - } - return memoryjs.unloadDll(handle, moduleAddressOrName as string); - } - - // Handle asynchronous calls - if (typeof moduleAddressOrName === "number") { - return memoryjs.unloadDll(handle, moduleAddressOrName as number, callback); - } - return memoryjs.unloadDll(handle, moduleAddressOrName as string, callback); -} - -// Re-export types -export type { - AllocationType, - CallFunctionCallback, - DataType, - DataTypeToType, - DataTypeToWriteType, - FindModuleCallback, - FindPatternCallback, - FunctionArg, - FunctionReturnValue, - FunctionType, - GetModulesCallback, - GetProcessesCallback, - GetRegionsCallback, - InjectDllCallback, - MemoryJS, - MemoryRegion, - ModuleInfo, - OpenProcessCallback, - ProcessInfo, - Protection, - ReadBufferCallback, - ReadMemoryBECallback, - ReadMemoryCallback, - UnloadDllCallback, - VirtualAllocExCallback, - VirtualProtectExCallback, - VirtualQueryExCallback, -} from "./src/types"; - -// Re-export utility types -export type { - BufferEncoding, - StructronContext, - StructronType, - Platform, -} from "./src/utils"; - -// Export functions and values -export { Debugger, isDataTypeBE }; - -export default { - openProcess, - closeProcess, - getProcesses, - findModule, - getModules, - readMemory, - readBuffer, - writeMemory, - writeBuffer, - findPattern, - callFunction, - virtualAllocEx, - virtualProtectEx, - getRegions, - virtualQueryEx, - injectDll, - unloadDll, - attachDebugger: memoryjs.attachDebugger, - detachDebugger: memoryjs.detachDebugger, - awaitDebugEvent: memoryjs.awaitDebugEvent, - handleDebugEvent: memoryjs.handleDebugEvent, - setHardwareBreakpoint: memoryjs.setHardwareBreakpoint, - removeHardwareBreakpoint: memoryjs.removeHardwareBreakpoint, - - STRUCTRON_TYPE_STRING, -}; diff --git a/lefthook.yml b/lefthook.yml index e5fe549..604b7b6 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -5,6 +5,11 @@ pre-commit: run: bunx @biomejs/biome check --write --no-errors-on-unmatched --files-ignore-unknown=true --colors=off {staged_files} stage_fixed: true +commit-msg: + commands: + lint-commit-msg: + run: bunx commitlint --edit {1} + pre-push: commands: check: diff --git a/native/debugger.cc b/native/debugger.cc index e979405..93559e7 100644 --- a/native/debugger.cc +++ b/native/debugger.cc @@ -4,7 +4,6 @@ * https://github.com/ReClassNET/ReClass.NET */ -#include #include #include #include diff --git a/native/dll.h b/native/dll.h index c52b5a6..e35f889 100644 --- a/native/dll.h +++ b/native/dll.h @@ -3,13 +3,12 @@ #define DLL_H #define WIN32_LEAN_AND_MEAN -#include #include #include #include namespace dll { - bool inject(HANDLE handle, std::string dllPath, const char** errorMessage, LPDWORD moduleHandle) { + inline bool inject(HANDLE handle, std::string dllPath, const char** errorMessage, LPDWORD moduleHandle) { // allocate space in target process memory for DLL path LPVOID targetProcessPath = VirtualAllocEx(handle, NULL, dllPath.length() + 1, MEM_COMMIT, PAGE_EXECUTE_READWRITE); @@ -53,7 +52,7 @@ namespace dll { return *moduleHandle > 0; } - bool unload(HANDLE handle, const char** errorMessage, HMODULE moduleHandle) { + inline bool unload(HANDLE handle, const char** errorMessage, HMODULE moduleHandle) { HMODULE kernel32 = LoadLibrary("kernel32"); if (kernel32 == 0) { diff --git a/native/functions.cc b/native/functions.cc index 1685a9d..efd67ba 100644 --- a/native/functions.cc +++ b/native/functions.cc @@ -1,7 +1,5 @@ -#include #include #include -#include #include "functions.h" char functions::readChar(HANDLE hProcess, DWORD64 address) { diff --git a/native/functions.h b/native/functions.h index 605053a..31a7d06 100644 --- a/native/functions.h +++ b/native/functions.h @@ -6,6 +6,7 @@ #include #include #include +#include struct Call { int returnValue; @@ -61,8 +62,8 @@ namespace functions { LPVOID address = functions::reserveString(pHandle, value.c_str(), value.length()); // Little endian representation - for (int i = 0; i < 4; i++) { - int shifted = ((int)address >> (i * 8)) & 0xFF; + for (int i = 0; i < sizeof(void*); i++) { + unsigned char shifted = ((uintptr_t)address >> (i * 8)) & 0xFF; argShellcode.push_back(shifted); } @@ -112,8 +113,8 @@ namespace functions { callShellcode.push_back(0xA3); } - for (int i = 0; i < 4; i++) { - int shifted = ((DWORD)returnValuePointer >> (i * 8)) & 0xFF; + for (int i = 0; i < sizeof(void*); i++) { + unsigned char shifted = ((uintptr_t)returnValuePointer >> (i * 8)) & 0xFF; callShellcode.push_back(shifted); } } diff --git a/native/memory.cc b/native/memory.cc index 6943dba..4812265 100644 --- a/native/memory.cc +++ b/native/memory.cc @@ -1,4 +1,3 @@ -#include #include #include #include diff --git a/native/memory.h b/native/memory.h index 3b36264..6f7129d 100644 --- a/native/memory.h +++ b/native/memory.h @@ -5,6 +5,8 @@ #include #include +#include +#include class memory { public: diff --git a/native/memoryjs.cc b/native/memoryjs.cc deleted file mode 100644 index 362adac..0000000 --- a/native/memoryjs.cc +++ /dev/null @@ -1,1514 +0,0 @@ -#include -#include -#include -#include -#include "module.h" -#include "process.h" -#include "memoryjs.h" -#include "memory.h" -#include "pattern.h" -#include "functions.h" -#include "dll.h" -#include "debugger.h" - -#pragma comment(lib, "psapi.lib") - -process Process; -// module Module; -memory Memory; -pattern Pattern; -// functions Functions; - -struct Vector3 { - float x, y, z; -}; - -struct Vector4 { - float w, x, y, z; -}; - -Napi::Value openProcess(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 1 && args.Length() != 2) { - Napi::Error::New(env, "requires 1 argument, or 2 arguments if a callback is being used").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsString() && !args[0].IsNumber()) { - Napi::Error::New(env, "first argument must be a string or a number").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (args.Length() == 2 && !args[1].IsFunction()) { - Napi::Error::New(env, "second argument must be a function").ThrowAsJavaScriptException(); - return env.Null(); - } - - // Define error message that may be set by the function that opens the process - const char* errorMessage = ""; - - process::Pair pair; - - if (args[0].IsString()) { - std::string processName(args[0].As().Utf8Value()); - pair = Process.openProcess(processName.c_str(), &errorMessage); - - // In case it failed to open, let's keep retrying - // while(!strcmp(process.szExeFile, "")) { - // process = Process.openProcess((char*) *(processName), &errorMessage); - // }; - } - - if (args[0].IsNumber()) { - pair = Process.openProcess(args[0].As().Uint32Value(), &errorMessage); - - // In case it failed to open, let's keep retrying - // while(!strcmp(process.szExeFile, "")) { - // process = Process.openProcess(info[0].As().Uint32Value(), &errorMessage); - // }; - } - - // If an error message was returned from the function that opens the process, throw the error. - // Only throw an error if there is no callback (if there's a callback, the error is passed there). - if (strcmp(errorMessage, "") && args.Length() != 2) { - Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); - return env.Null(); - } - - // Create a v8 Object (JSON) to store the process information - Napi::Object processInfo = Napi::Object::New(env); - - processInfo.Set(Napi::String::New(env, "dwSize"), Napi::Value::From(env, (int)pair.process.dwSize)); - processInfo.Set(Napi::String::New(env, "th32ProcessID"), Napi::Value::From(env, (int)pair.process.th32ProcessID)); - processInfo.Set(Napi::String::New(env, "cntThreads"), Napi::Value::From(env, (int)pair.process.cntThreads)); - processInfo.Set(Napi::String::New(env, "th32ParentProcessID"), Napi::Value::From(env, (int)pair.process.th32ParentProcessID)); - processInfo.Set(Napi::String::New(env, "pcPriClassBase"), Napi::Value::From(env, (int)pair.process.pcPriClassBase)); - processInfo.Set(Napi::String::New(env, "szExeFile"), Napi::String::New(env, pair.process.szExeFile)); - processInfo.Set(Napi::String::New(env, "handle"), Napi::Value::From(env, (uintptr_t)pair.handle)); - - DWORD64 base = module::getBaseAddress(pair.process.szExeFile, pair.process.th32ProcessID); - processInfo.Set(Napi::String::New(env, "modBaseAddr"), Napi::Value::From(env, (uintptr_t)base)); - - // openProcess can either take one argument or can take - // two arguments for asychronous use (second argument is the callback) - if (args.Length() == 2) { - // Callback to let the user handle with the information - Napi::Function callback = args[1].As(); - callback.Call(env.Global(), { Napi::String::New(env, errorMessage), processInfo }); - return env.Null(); - } else { - // return JSON - return processInfo; - } -} - -Napi::Value closeProcess(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 1) { - Napi::Error::New(env, "requires 1 argument").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber()) { - Napi::Error::New(env, "first argument must be a number").ThrowAsJavaScriptException(); - return env.Null(); - } - - Process.closeProcess((HANDLE)args[0].As().Int64Value()); - return env.Null(); -} - -Napi::Value getProcesses(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() > 1) { - Napi::Error::New(env, "requires either 0 arguments or 1 argument if a callback is being used").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (args.Length() == 1 && !args[0].IsFunction()) { - Napi::Error::New(env, "first argument must be a function").ThrowAsJavaScriptException(); - return env.Null(); - } - - // Define error message that may be set by the function that gets the processes - const char* errorMessage = ""; - - std::vector processEntries = Process.getProcesses(&errorMessage); - - // If an error message was returned from the function that gets the processes, throw the error. - // Only throw an error if there is no callback (if there's a callback, the error is passed there). - if (strcmp(errorMessage, "") && args.Length() != 1) { - Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); - return env.Null(); - } - - // Creates v8 array with the size being that of the processEntries vector processes is an array of JavaScript objects - Napi::Array processes = Napi::Array::New(env, processEntries.size()); - - // Loop over all processes found - for (std::vector::size_type i = 0; i != processEntries.size(); i++) { - // Create a v8 object to store the current process' information - Napi::Object process = Napi::Object::New(env); - - process.Set(Napi::String::New(env, "cntThreads"), Napi::Value::From(env, (int)processEntries[i].cntThreads)); - process.Set(Napi::String::New(env, "szExeFile"), Napi::String::New(env, processEntries[i].szExeFile)); - process.Set(Napi::String::New(env, "th32ProcessID"), Napi::Value::From(env, (int)processEntries[i].th32ProcessID)); - process.Set(Napi::String::New(env, "th32ParentProcessID"), Napi::Value::From(env, (int)processEntries[i].th32ParentProcessID)); - process.Set(Napi::String::New(env, "pcPriClassBase"), Napi::Value::From(env, (int)processEntries[i].pcPriClassBase)); - - // Push the object to the array - processes.Set(i, process); - } - - /* getProcesses can either take no arguments or one argument - one argument is for asychronous use (the callback) */ - if (args.Length() == 1) { - // Callback to let the user handle with the information - Napi::Function callback = args[0].As(); - callback.Call(env.Global(), { Napi::String::New(env, errorMessage), processes }); - return env.Null(); - } else { - // return JSON - return processes; - } -} - -Napi::Value getModules(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 1 && args.Length() != 2) { - Napi::Error::New(env, "requires 1 argument, or 2 arguments if a callback is being used").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber()) { - Napi::Error::New(env, "first argument must be a number").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (args.Length() == 2 && !args[1].IsFunction()) { - Napi::Error::New(env, "first argument must be a number, second argument must be a function").ThrowAsJavaScriptException(); - return env.Null(); - } - - // Define error message that may be set by the function that gets the modules - const char* errorMessage = ""; - - std::vector moduleEntries = module::getModules(args[0].As().Int32Value(), &errorMessage); - - // If an error message was returned from the function getting the modules, throw the error. - // Only throw an error if there is no callback (if there's a callback, the error is passed there). - if (strcmp(errorMessage, "") && args.Length() != 2) { - Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); - return env.Null(); - } - - // Creates v8 array with the size being that of the moduleEntries vector - // modules is an array of JavaScript objects - Napi::Array modules = Napi::Array::New(env, moduleEntries.size()); - - // Loop over all modules found - for (std::vector::size_type i = 0; i != moduleEntries.size(); i++) { - // Create a v8 object to store the current module's information - Napi::Object module = Napi::Object::New(env); - - module.Set(Napi::String::New(env, "modBaseAddr"), Napi::Value::From(env, (uintptr_t)moduleEntries[i].modBaseAddr)); - module.Set(Napi::String::New(env, "modBaseSize"), Napi::Value::From(env, (int)moduleEntries[i].modBaseSize)); - module.Set(Napi::String::New(env, "szExePath"), Napi::String::New(env, moduleEntries[i].szExePath)); - module.Set(Napi::String::New(env, "szModule"), Napi::String::New(env, moduleEntries[i].szModule)); - module.Set(Napi::String::New(env, "th32ProcessID"), Napi::Value::From(env, (int)moduleEntries[i].th32ProcessID)); - module.Set(Napi::String::New(env, "GlblcntUsage"), Napi::Value::From(env, (int)moduleEntries[i].GlblcntUsage)); - - // Push the object to the array - modules.Set(i, module); - } - - // getModules can either take one argument or two arguments - // one/two arguments is for asychronous use (the callback) - if (args.Length() == 2) { - // Callback to let the user handle with the information - Napi::Function callback = args[1].As(); - callback.Call(env.Global(), { Napi::String::New(env, errorMessage), modules }); - return env.Null(); - } else { - // return JSON - return modules; - } -} - -Napi::Value findModule(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 1 && args.Length() != 2 && args.Length() != 3) { - Napi::Error::New(env, "requires 1 argument, 2 arguments, or 3 arguments if a callback is being used").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsString() && !args[1].IsNumber()) { - Napi::Error::New(env, "first argument must be a string, second argument must be a number").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (args.Length() == 3 && !args[2].IsFunction()) { - Napi::Error::New(env, "third argument must be a function").ThrowAsJavaScriptException(); - return env.Null(); - } - - std::string moduleName(args[0].As().Utf8Value()); - - // Define error message that may be set by the function that gets the modules - const char* errorMessage = ""; - - MODULEENTRY32 module = module::findModule(moduleName.c_str(), args[1].As().Int32Value(), &errorMessage); - - // If an error message was returned from the function getting the module, throw the error. - // Only throw an error if there is no callback (if there's a callback, the error is passed there). - if (strcmp(errorMessage, "") && args.Length() != 3) { - Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); - return env.Null(); - } - - // In case it failed to open, let's keep retrying - while (!strcmp(module.szExePath, "")) { - module = module::findModule(moduleName.c_str(), args[1].As().Int32Value(), &errorMessage); - }; - - // Create a v8 Object (JSON) to store the process information - Napi::Object moduleInfo = Napi::Object::New(env); - - moduleInfo.Set(Napi::String::New(env, "modBaseAddr"), Napi::Value::From(env, (uintptr_t)module.modBaseAddr)); - moduleInfo.Set(Napi::String::New(env, "modBaseSize"), Napi::Value::From(env, (int)module.modBaseSize)); - moduleInfo.Set(Napi::String::New(env, "szExePath"), Napi::String::New(env, module.szExePath)); - moduleInfo.Set(Napi::String::New(env, "szModule"), Napi::String::New(env, module.szModule)); - moduleInfo.Set(Napi::String::New(env, "th32ProcessID"), Napi::Value::From(env, (int)module.th32ProcessID)); - moduleInfo.Set(Napi::String::New(env, "GlblcntUsage"), Napi::Value::From(env, (int)module.GlblcntUsage)); - - // findModule can either take one or two arguments, - // three arguments for asychronous use (third argument is the callback) - if (args.Length() == 3) { - // Callback to let the user handle with the information - Napi::Function callback = args[2].As(); - callback.Call(env.Global(), { Napi::String::New(env, errorMessage), moduleInfo }); - return env.Null(); - } else { - // return JSON - return moduleInfo; - } -} - -Napi::Value readMemory(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 3 && args.Length() != 4) { - Napi::Error::New(env, "requires 3 arguments, or 4 arguments if a callback is being used").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber() && !args[1].IsNumber() && !args[2].IsString()) { - Napi::Error::New(env, "first and second argument must be a number, third argument must be a string").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (args.Length() == 4 && !args[3].IsFunction()) { - Napi::Error::New(env, "fourth argument must be a function").ThrowAsJavaScriptException(); - return env.Null(); - } - - std::string dataTypeArg(args[2].As().Utf8Value()); - const char* dataType = dataTypeArg.c_str(); - - // Define the error message that will be set if no data type is recognised - const char* errorMessage = ""; - Napi::Value retVal = env.Null(); - - HANDLE handle = (HANDLE)args[0].As().Int64Value(); - DWORD64 address = args[1].As().Int64Value(); - - if (!strcmp(dataType, "int8") || !strcmp(dataType, "byte") || !strcmp(dataType, "char")) { - - int8_t result = Memory.readMemory(handle, address); - retVal = Napi::Value::From(env, result); - - } else if (!strcmp(dataType, "uint8") || !strcmp(dataType, "ubyte") || !strcmp(dataType, "uchar")) { - - uint8_t result = Memory.readMemory(handle, address); - retVal = Napi::Value::From(env, result); - - } else if (!strcmp(dataType, "int16") || !strcmp(dataType, "short")) { - - int16_t result = Memory.readMemory(handle, address); - retVal = Napi::Value::From(env, result); - - } else if (!strcmp(dataType, "uint16") || !strcmp(dataType, "ushort") || !strcmp(dataType, "word")) { - - uint16_t result = Memory.readMemory(handle, address); - retVal = Napi::Value::From(env, result); - - } else if (!strcmp(dataType, "int32") || !strcmp(dataType, "int") || !strcmp(dataType, "long")) { - - int32_t result = Memory.readMemory(handle, address); - retVal = Napi::Value::From(env, result); - - } else if (!strcmp(dataType, "uint32") || !strcmp(dataType, "uint") || !strcmp(dataType, "ulong") || !strcmp(dataType, "dword")) { - - uint32_t result = Memory.readMemory(handle, address); - retVal = Napi::Value::From(env, result); - - } else if (!strcmp(dataType, "int64")) { - - int64_t result = Memory.readMemory(handle, address); - retVal = Napi::Value::From(env, Napi::BigInt::New(env, result)); - - } else if (!strcmp(dataType, "uint64")) { - - uint64_t result = Memory.readMemory(handle, address); - retVal = Napi::Value::From(env, Napi::BigInt::New(env, result)); - - } else if (!strcmp(dataType, "float")) { - - float result = Memory.readMemory(handle, address); - retVal = Napi::Value::From(env, result); - - } else if (!strcmp(dataType, "double")) { - - double result = Memory.readMemory(handle, address); - retVal = Napi::Value::From(env, result); - - } else if (!strcmp(dataType, "ptr") || !strcmp(dataType, "pointer")) { - - intptr_t result = Memory.readMemory(handle, address); - - if (sizeof(intptr_t) == 8) { - retVal = Napi::Value::From(env, Napi::BigInt::New(env, (int64_t) result)); - } else { - retVal = Napi::Value::From(env, result); - } - - } else if (!strcmp(dataType, "uptr") || !strcmp(dataType, "upointer")) { - - uintptr_t result = Memory.readMemory(handle, address); - - if (sizeof(uintptr_t) == 8) { - retVal = Napi::Value::From(env, Napi::BigInt::New(env, (uint64_t) result)); - } else { - retVal = Napi::Value::From(env, result); - } - - } else if (!strcmp(dataType, "bool") || !strcmp(dataType, "boolean")) { - - bool result = Memory.readMemory(handle, address); - retVal = Napi::Boolean::New(env, result); - - } else if (!strcmp(dataType, "string") || !strcmp(dataType, "str")) { - - std::string str; - if (!Memory.readString(handle, address, &str)) { - errorMessage = "unable to read string"; - } else { - retVal = Napi::String::New(env, str); - } - - } else if (!strcmp(dataType, "vector3") || !strcmp(dataType, "vec3")) { - - Vector3 result = Memory.readMemory(handle, address); - Napi::Object moduleInfo = Napi::Object::New(env); - moduleInfo.Set(Napi::String::New(env, "x"), Napi::Value::From(env, result.x)); - moduleInfo.Set(Napi::String::New(env, "y"), Napi::Value::From(env, result.y)); - moduleInfo.Set(Napi::String::New(env, "z"), Napi::Value::From(env, result.z)); - retVal = moduleInfo; - - } else if (!strcmp(dataType, "vector4") || !strcmp(dataType, "vec4")) { - - Vector4 result = Memory.readMemory(handle, address); - Napi::Object moduleInfo = Napi::Object::New(env); - moduleInfo.Set(Napi::String::New(env, "w"), Napi::Value::From(env, result.w)); - moduleInfo.Set(Napi::String::New(env, "x"), Napi::Value::From(env, result.x)); - moduleInfo.Set(Napi::String::New(env, "y"), Napi::Value::From(env, result.y)); - moduleInfo.Set(Napi::String::New(env, "z"), Napi::Value::From(env, result.z)); - retVal = moduleInfo; - - } else { - errorMessage = "unexpected data type"; - } - - if (strcmp(errorMessage, "") && args.Length() != 4) { - Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); - return env.Null(); - } - - if (args.Length() == 4) { - Napi::Function callback = args[3].As(); - callback.Call(env.Global(), { Napi::String::New(env, errorMessage), retVal }); - return env.Null(); - } else { - return retVal; - } -} - -Napi::Value readBuffer(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 3 && args.Length() != 4) { - Napi::Error::New(env, "requires 3 arguments, or 4 arguments if a callback is being used").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber() && !args[1].IsNumber() && !args[2].IsNumber()) { - Napi::Error::New(env, "first, second and third arguments must be a number").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (args.Length() == 4 && !args[3].IsFunction()) { - Napi::Error::New(env, "fourth argument must be a function").ThrowAsJavaScriptException(); - return env.Null(); - } - - HANDLE handle = (HANDLE)args[0].As().Int64Value(); - DWORD64 address = args[1].As().Int64Value(); - SIZE_T size = args[2].As().Int64Value(); - - // To fix the memory leak problem that was happening here, we need to release the - // temporary buffer we create after we're done creating a Napi::Buffer from it. - // Napi::Buffer::New doesn't free the memory, so it has be done manually - // but it can segfault when the memory is freed before being accessed. - // The solution is to use Napi::Buffer::Copy, and then we can manually free it. - // - // see: https://github.com/nodejs/node/issues/40936 - // see: https://sagivo.com/2015/09/30/Go-Native-Calling-C-From-NodeJS.html - const char* data = (char*) malloc(sizeof(char) * size); - Memory.readBuffer(handle, address, size, data); - - Napi::Buffer buffer = Napi::Buffer::Copy(env, data, size); - free((void*)data); - - if (args.Length() == 4) { - Napi::Function callback = args[3].As(); - callback.Call(env.Global(), { Napi::String::New(env, ""), buffer }); - return env.Null(); - } else { - return buffer; - } -} - -Napi::Value writeMemory(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 4) { - Napi::Error::New(env, "requires 4 arguments").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber() && !args[1].IsNumber() && !args[3].IsString()) { - Napi::Error::New(env, "first and second argument must be a number, third argument must be a string").ThrowAsJavaScriptException(); - return env.Null(); - } - - std::string dataTypeArg(args[3].As().Utf8Value()); - const char* dataType = dataTypeArg.c_str(); - - HANDLE handle = (HANDLE)args[0].As().Int64Value(); - DWORD64 address = args[1].As().Int64Value(); - - if (!strcmp(dataType, "int8") || !strcmp(dataType, "byte") || !strcmp(dataType, "char")) { - - Memory.writeMemory(handle, address, args[2].As().Int32Value()); - - } else if (!strcmp(dataType, "uint8") || !strcmp(dataType, "ubyte") || !strcmp(dataType, "uchar")) { - - Memory.writeMemory(handle, address, args[2].As().Uint32Value()); - - } else if (!strcmp(dataType, "int16") || !strcmp(dataType, "short")) { - - Memory.writeMemory(handle, address, args[2].As().Int32Value()); - - } else if (!strcmp(dataType, "uint16") || !strcmp(dataType, "ushort") || !strcmp(dataType, "word")) { - - Memory.writeMemory(handle, address, args[2].As().Uint32Value()); - - } else if (!strcmp(dataType, "int32") || !strcmp(dataType, "int") || !strcmp(dataType, "long")) { - - Memory.writeMemory(handle, address, args[2].As().Int32Value()); - - } else if (!strcmp(dataType, "uint32") || !strcmp(dataType, "uint") || !strcmp(dataType, "ulong") || !strcmp(dataType, "dword")) { - - Memory.writeMemory(handle, address, args[2].As().Uint32Value()); - - } else if (!strcmp(dataType, "int64")) { - - Napi::BigInt bigInt = args[2].As(); - bool lossless; - Memory.writeMemory(handle, address, bigInt.Int64Value(&lossless)); - - } else if (!strcmp(dataType, "uint64")) { - - Napi::BigInt bigInt = args[2].As(); - bool lossless; - Memory.writeMemory(handle, address, bigInt.Uint64Value(&lossless)); - - } else if (!strcmp(dataType, "float")) { - - Memory.writeMemory(handle, address, args[2].As().FloatValue()); - - } else if (!strcmp(dataType, "double")) { - - Memory.writeMemory(handle, address, args[2].As().DoubleValue()); - - } else if (!strcmp(dataType, "ptr") || !strcmp(dataType, "pointer")) { - - Napi::BigInt bigInt = args[2].As(); - - if (sizeof(intptr_t) == 8 && !bigInt.IsBigInt()) { - std::string error = "Writing memoryjs.PTR or memoryjs.POINTER on 64 bit target build requires you to supply a BigInt."; - error += " Rebuild the library with `npm run build32` to target 32 bit applications."; - Napi::Error::New(env, error).ThrowAsJavaScriptException(); - return env.Null(); - } - - if (bigInt.IsBigInt()) { - bool lossless; - Memory.writeMemory(handle, address, bigInt.Int64Value(&lossless)); - } else { - Memory.writeMemory(handle, address, args[2].As().Int32Value()); - } - - } else if (!strcmp(dataType, "uptr") || !strcmp(dataType, "upointer")) { - - Napi::BigInt bigInt = args[2].As(); - - if (sizeof(uintptr_t) == 8 && !bigInt.IsBigInt()) { - std::string error = "Writing memoryjs.PTR or memoryjs.POINTER on 64 bit target build requires you to supply a BigInt."; - error += " Rebuild the library with `npm run build32` to target 32 bit applications."; - Napi::Error::New(env, error).ThrowAsJavaScriptException(); - return env.Null(); - } - - if (bigInt.IsBigInt()) { - bool lossless; - Memory.writeMemory(handle, address, bigInt.Uint64Value(&lossless)); - } else { - Memory.writeMemory(handle, address, args[2].As().Uint32Value()); - } - - } else if (!strcmp(dataType, "bool") || !strcmp(dataType, "boolean")) { - - Memory.writeMemory(handle, address, args[2].As().Value()); - - } else if (!strcmp(dataType, "string") || !strcmp(dataType, "str")) { - - std::string valueParam(args[2].As().Utf8Value()); - valueParam.append("", 1); - - // Write String, Method 1 - //Memory.writeMemory(handle, address, std::string(*valueParam)); - - // Write String, Method 2 - Memory.writeMemory(handle, address, (char*) valueParam.data(), valueParam.size()); - - } else if (!strcmp(dataType, "vector3") || !strcmp(dataType, "vec3")) { - - Napi::Object value = args[2].As(); - Vector3 vector = { - value.Get(Napi::String::New(env, "x")).As().FloatValue(), - value.Get(Napi::String::New(env, "y")).As().FloatValue(), - value.Get(Napi::String::New(env, "z")).As().FloatValue() - }; - Memory.writeMemory(handle, address, vector); - - } else if (!strcmp(dataType, "vector4") || !strcmp(dataType, "vec4")) { - - Napi::Object value = args[2].As(); - Vector4 vector = { - value.Get(Napi::String::New(env, "w")).As().FloatValue(), - value.Get(Napi::String::New(env, "x")).As().FloatValue(), - value.Get(Napi::String::New(env, "y")).As().FloatValue(), - value.Get(Napi::String::New(env, "z")).As().FloatValue() - }; - Memory.writeMemory(handle, address, vector); - - } else { - Napi::Error::New(env, "unexpected data type").ThrowAsJavaScriptException(); - } - - return env.Null(); -} - -Napi::Value writeBuffer(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 3) { - Napi::Error::New(env, "required 3 arguments").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber() && !args[1].IsNumber()) { - Napi::Error::New(env, "first and second argument must be a number").ThrowAsJavaScriptException(); - return env.Null(); - } - - HANDLE handle = (HANDLE)args[0].As().Int64Value(); - DWORD64 address = args[1].As().Int64Value(); - SIZE_T length = args[2].As>().Length(); - const char* data = args[2].As>().Data(); - Memory.writeMemory(handle, address, data, length); - - return env.Null(); -} - -// Napi::Value findPattern(const Napi::CallbackInfo& args) { -// Napi::Env env = args.Env(); - -// HANDLE handle = (HANDLE)args[0].As().Int64Value(); -// DWORD64 baseAddress = args[1].As().Int64Value(); -// DWORD64 baseSize = args[2].As().Int64Value(); -// std::string signature(args[3].As().Utf8Value()); -// short flags = args[4].As().Uint32Value(); -// uint32_t patternOffset = args[5].As().Uint32Value(); - -// // matching address -// uintptr_t address = 0; -// char* errorMessage = ""; - -// // read memory region occupied by the module to pattern match inside -// std::vector moduleBytes = std::vector(baseSize); -// ReadProcessMemory(handle, (LPVOID)baseAddress, &moduleBytes[0], baseSize, nullptr); -// unsigned char* byteBase = const_cast(&moduleBytes.at(0)); - -// Pattern.findPattern(handle, baseAddress, byteBase, baseSize, signature.c_str(), flags, patternOffset, &address); - -// if (address == 0) { -// errorMessage = "unable to match pattern inside any modules or regions"; -// } - -// if (args.Length() == 5) { -// Napi::Function callback = args[4].As(); -// callback.Call(env.Global(), { Napi::String::New(env, errorMessage), Napi::Value::From(env, address) }); -// return env.Null(); -// } else { -// return Napi::Value::From(env, address); -// } -// } - -Napi::Value findPattern(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 4 && args.Length() != 5) { - Napi::Error::New(env, "requires 4 arguments, 5 with callback").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber() || !args[1].IsString() || !args[2].IsNumber() || !args[3].IsNumber()) { - Napi::Error::New(env, "expected: number, string, string, number").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (args.Length() == 5 && !args[4].IsFunction()) { - Napi::Error::New(env, "callback argument must be a function").ThrowAsJavaScriptException(); - return env.Null(); - } - - HANDLE handle = (HANDLE)args[0].As().Int64Value(); - std::string pattern(args[1].As().Utf8Value()); - short flags = args[2].As().Uint32Value(); - uint32_t patternOffset = args[3].As().Uint32Value(); - - // matching address - uintptr_t address = 0; - const char* errorMessage = ""; - - std::vector modules = module::getModules(GetProcessId(handle), &errorMessage); - Pattern.search(handle, modules, 0, pattern.c_str(), flags, patternOffset, &address); - - // if no match found inside any modules, search memory regions - if (address == 0) { - std::vector regions = Memory.getRegions(handle); - Pattern.search(handle, regions, 0, pattern.c_str(), flags, patternOffset, &address); - } - - if (address == 0) { - errorMessage = "unable to match pattern inside any modules or regions"; - } - - if (args.Length() == 5) { - Napi::Function callback = args[4].As(); - callback.Call(env.Global(), { Napi::String::New(env, errorMessage), Napi::Value::From(env, address) }); - return env.Null(); - } else { - return Napi::Value::From(env, address); - } -} - -Napi::Value findPatternByModule(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 5 && args.Length() != 6) { - Napi::Error::New(env, "requires 5 arguments, 6 with callback").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber() || !args[1].IsString() || !args[2].IsString() || !args[3].IsNumber() || !args[4].IsNumber()) { - Napi::Error::New(env, "expected: number, string, string, number, number").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (args.Length() == 6 && !args[5].IsFunction()) { - Napi::Error::New(env, "callback argument must be a function").ThrowAsJavaScriptException(); - return env.Null(); - } - - HANDLE handle = (HANDLE)args[0].As().Int64Value(); - std::string moduleName(args[1].As().Utf8Value()); - std::string pattern(args[2].As().Utf8Value()); - short flags = args[3].As().Uint32Value(); - uint32_t patternOffset = args[4].As().Uint32Value(); - - // matching address - uintptr_t address = 0; - const char* errorMessage = ""; - - MODULEENTRY32 module = module::findModule(moduleName.c_str(), GetProcessId(handle), &errorMessage); - - uintptr_t baseAddress = (uintptr_t) module.modBaseAddr; - DWORD baseSize = module.modBaseSize; - - // read memory region occupied by the module to pattern match inside - std::vector moduleBytes = std::vector(baseSize); - ReadProcessMemory(handle, (LPVOID)baseAddress, &moduleBytes[0], baseSize, nullptr); - unsigned char* byteBase = const_cast(&moduleBytes.at(0)); - - Pattern.findPattern(handle, baseAddress, byteBase, baseSize, pattern.c_str(), flags, patternOffset, &address); - - if (address == 0) { - errorMessage = "unable to match pattern inside any modules or regions"; - } - - if (args.Length() == 6) { - Napi::Function callback = args[5].As(); - callback.Call(env.Global(), { Napi::String::New(env, errorMessage), Napi::Value::From(env, address) }); - return env.Null(); - } else { - return Napi::Value::From(env, address); - } -} - -Napi::Value findPatternByAddress(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 5 && args.Length() != 6) { - Napi::Error::New(env, "requires 5 arguments, 6 with callback").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber() || !args[1].IsNumber() || !args[2].IsString() || !args[3].IsNumber() || !args[4].IsNumber()) { - Napi::Error::New(env, "expected: number, number, string, number, number").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (args.Length() == 6 && !args[5].IsFunction()) { - Napi::Error::New(env, "callback argument must be a function").ThrowAsJavaScriptException(); - return env.Null(); - } - - HANDLE handle = (HANDLE)args[0].As().Int64Value(); - DWORD64 baseAddress = args[1].As().Int64Value(); - std::string pattern(args[2].As().Utf8Value()); - short flags = args[3].As().Uint32Value(); - uint32_t patternOffset = args[4].As().Uint32Value(); - - // matching address - uintptr_t address = 0; - const char* errorMessage = ""; - - std::vector modules = module::getModules(GetProcessId(handle), &errorMessage); - Pattern.search(handle, modules, baseAddress, pattern.c_str(), flags, patternOffset, &address); - - if (address == 0) { - std::vector regions = Memory.getRegions(handle); - Pattern.search(handle, regions, baseAddress, pattern.c_str(), flags, patternOffset, &address); - } - - if (address == 0) { - errorMessage = "unable to match pattern inside any modules or regions"; - } - - if (args.Length() == 6) { - Napi::Function callback = args[5].As(); - callback.Call(env.Global(), { Napi::String::New(env, errorMessage), Napi::Value::From(env, address) }); - return env.Null(); - } else { - return Napi::Value::From(env, address); - } -} - -Napi::Value callFunction(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 4 && args.Length() != 5) { - Napi::Error::New(env, "requires 4 arguments, 5 with callback").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber() && !args[1].IsObject() && !args[2].IsNumber() && !args[3].IsNumber()) { - Napi::Error::New(env, "invalid arguments").ThrowAsJavaScriptException(); - return env.Null(); - } - - // TODO: temp (?) solution to forcing variables onto the heap - // to ensure consistent addresses. copy everything to a vector, and use the - // vector's instances of the variables as the addresses being passed to `functions.call()`. - // Another solution: do `int x = new int(4)` and then use `&x` for the address - std::vector heap; - - std::vector parsedArgs; - Napi::Array arguments = args[1].As(); - for (unsigned int i = 0; i < arguments.Length(); i++) { - Napi::Object argument = arguments.Get(i).As(); - - functions::Type type = (functions::Type) argument.Get(Napi::String::New(env, "type")).As().Uint32Value(); - - if (type == functions::Type::T_STRING) { - std::string stringValue = argument.Get(Napi::String::New(env, "value")).As().Utf8Value(); - parsedArgs.push_back({ type, &stringValue }); - } - - if (type == functions::Type::T_INT) { - int data = argument.Get(Napi::String::New(env, "value")).As().Int32Value(); - - // As we only pass the addresses of the variable to the `call` function and not a copy - // of the variable itself, we need to ensure that the variable stays alive and in a unique - // memory location until the `call` function has been executed. So manually allocate memory, - // track it, and then free it once the function has been called. - // TODO: find a better solution? - int* memory = (int*) malloc(sizeof(int)); - *memory = data; - heap.push_back(memory); - - parsedArgs.push_back({ type, memory }); - } - - if (type == functions::Type::T_FLOAT) { - float data = argument.Get(Napi::String::New(env, "value")).As().FloatValue(); - - float* memory = (float*) malloc(sizeof(float)); - *memory = data; - heap.push_back(memory); - - parsedArgs.push_back({ type, memory }); - } - } - - HANDLE handle = (HANDLE)args[0].As().Int64Value(); - functions::Type returnType = (functions::Type) args[2].As().Uint32Value(); - DWORD64 address = args[3].As().Int64Value(); - - const char* errorMessage = ""; - Call data = functions::call(handle, parsedArgs, returnType, address, &errorMessage); - - // Free all the memory we allocated - for (auto &memory : heap) { - free(memory); - } - - heap.clear(); - - if (strcmp(errorMessage, "") && args.Length() != 5) { - Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); - return env.Null(); - } - - Napi::Object info = Napi::Object::New(env); - - Napi::String keyString = Napi::String::New(env, "returnValue"); - - if (returnType == functions::Type::T_STRING) { - info.Set(keyString, Napi::String::New(env, data.returnString.c_str())); - } - - if (returnType == functions::Type::T_CHAR) { - info.Set(keyString, Napi::Value::From(env, (char) data.returnValue)); - } - - if (returnType == functions::Type::T_BOOL) { - info.Set(keyString, Napi::Value::From(env, (bool) data.returnValue)); - } - - if (returnType == functions::Type::T_INT) { - info.Set(keyString, Napi::Value::From(env, (int) data.returnValue)); - } - - if (returnType == functions::Type::T_FLOAT) { - float value = *(float *)&data.returnValue; - info.Set(keyString, Napi::Value::From(env, value)); - } - - if (returnType == functions::Type::T_DOUBLE) { - double value = *(double *)&data.returnValue; - info.Set(keyString, Napi::Value::From(env, value)); - } - - info.Set(Napi::String::New(env, "exitCode"), Napi::Value::From(env, data.exitCode)); - - if (args.Length() == 5) { - // Callback to let the user handle with the information - Napi::Function callback = args[2].As(); - callback.Call(env.Global(), { Napi::String::New(env, errorMessage), info }); - return env.Null(); - } else { - // return JSON - return info; - } - -} - -Napi::Value virtualProtectEx(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 4 && args.Length() != 5) { - Napi::Error::New(env, "requires 4 arguments, 5 with callback").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber() && !args[1].IsNumber() && !args[2].IsNumber()) { - Napi::Error::New(env, "All arguments should be numbers.").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (args.Length() == 5 && !args[4].IsFunction()) { - Napi::Error::New(env, "callback needs to be a function").ThrowAsJavaScriptException(); - return env.Null(); - } - - DWORD result; - HANDLE handle = (HANDLE)args[0].As().Int64Value(); - DWORD64 address = args[1].As().Int64Value(); - SIZE_T size = args[2].As().Int64Value(); - DWORD protection = args[3].As().Uint32Value(); - - bool success = VirtualProtectEx(handle, (LPVOID) address, size, protection, &result); - - const char* errorMessage = ""; - - if (success == 0) { - errorMessage = "an error occurred calling VirtualProtectEx"; - // errorMessage = GetLastErrorToString().c_str(); - } - - // If there is an error and there is no callback, throw the error - if (strcmp(errorMessage, "") && args.Length() != 5) { - Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); - return env.Null(); - } - - if (args.Length() == 5) { - // Callback to let the user handle with the information - Napi::Function callback = args[5].As(); - callback.Call(env.Global(), { - Napi::String::New(env, errorMessage), - Napi::Value::From(env, result) - }); - return env.Null(); - } else { - return Napi::Value::From(env, result); - } -} - -Napi::Value getRegions(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 1 && args.Length() != 2) { - Napi::Error::New(env, "requires 1 argument, 2 with callback").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber()) { - Napi::Error::New(env, "invalid arguments: first argument must be a number").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (args.Length() == 2 && !args[1].IsFunction()) { - Napi::Error::New(env, "callback needs to be a function").ThrowAsJavaScriptException(); - return env.Null(); - } - - HANDLE handle = (HANDLE)args[0].As().Int64Value(); - std::vector regions = Memory.getRegions(handle); - - Napi::Array regionsArray = Napi::Array::New(env, regions.size()); - - for (std::vector::size_type i = 0; i != regions.size(); i++) { - Napi::Object region = Napi::Object::New(env); - - region.Set(Napi::String::New(env, "BaseAddress"), Napi::Value::From(env, (DWORD64) regions[i].BaseAddress)); - region.Set(Napi::String::New(env, "AllocationBase"), Napi::Value::From(env, (DWORD64) regions[i].AllocationBase)); - region.Set(Napi::String::New(env, "AllocationProtect"), Napi::Value::From(env, (DWORD) regions[i].AllocationProtect)); - region.Set(Napi::String::New(env, "RegionSize"), Napi::Value::From(env, (SIZE_T) regions[i].RegionSize)); - region.Set(Napi::String::New(env, "State"), Napi::Value::From(env, (DWORD) regions[i].State)); - region.Set(Napi::String::New(env, "Protect"), Napi::Value::From(env, (DWORD) regions[i].Protect)); - region.Set(Napi::String::New(env, "Type"), Napi::Value::From(env, (DWORD) regions[i].Type)); - - char moduleName[MAX_PATH]; - DWORD size = GetModuleFileNameExA(handle, (HINSTANCE)regions[i].AllocationBase, moduleName, MAX_PATH); - - if (size != 0) { - region.Set(Napi::String::New(env, "szExeFile"), Napi::String::New(env, moduleName)); - } - - regionsArray.Set(i, region); - } - - if (args.Length() == 2) { - // Callback to let the user handle with the information - Napi::Function callback = args[1].As(); - callback.Call(env.Global(), { Napi::String::New(env, ""), regionsArray }); - return env.Null(); - } else { - // return JSON - return regionsArray; - } -} - -Napi::Value virtualQueryEx(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 2 && args.Length() != 3) { - Napi::Error::New(env, "requires 2 arguments, 3 with callback").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber() || !args[1].IsNumber()) { - Napi::Error::New(env, "first and second argument need to be a number").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (args.Length() == 3 && !args[2].IsFunction()) { - Napi::Error::New(env, "callback needs to be a function").ThrowAsJavaScriptException(); - return env.Null(); - } - - HANDLE handle = (HANDLE)args[0].As().Int64Value(); - DWORD64 address = args[1].As().Int64Value(); - - MEMORY_BASIC_INFORMATION information; - SIZE_T result = VirtualQueryEx(handle, (LPVOID)address, &information, sizeof(information)); - - const char* errorMessage = ""; - - if (result == 0 || result != sizeof(information)) { - errorMessage = "an error occurred calling VirtualQueryEx"; - // errorMessage = GetLastErrorToString().c_str(); - } - - // If there is an error and there is no callback, throw the error - if (strcmp(errorMessage, "") && args.Length() != 3) { - Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); - return env.Null(); - } - - Napi::Object region = Napi::Object::New(env); - - region.Set(Napi::String::New(env, "BaseAddress"), Napi::Value::From(env, (DWORD64) information.BaseAddress)); - region.Set(Napi::String::New(env, "AllocationBase"), Napi::Value::From(env, (DWORD64) information.AllocationBase)); - region.Set(Napi::String::New(env, "AllocationProtect"), Napi::Value::From(env, (DWORD) information.AllocationProtect)); - region.Set(Napi::String::New(env, "RegionSize"), Napi::Value::From(env, (SIZE_T) information.RegionSize)); - region.Set(Napi::String::New(env, "State"), Napi::Value::From(env, (DWORD) information.State)); - region.Set(Napi::String::New(env, "Protect"), Napi::Value::From(env, (DWORD) information.Protect)); - region.Set(Napi::String::New(env, "Type"), Napi::Value::From(env, (DWORD) information.Type)); - - if (args.Length() == 3) { - // Callback to let the user handle with the information - Napi::Function callback = args[1].As(); - callback.Call(env.Global(), { Napi::String::New(env, ""), region }); - return env.Null(); - } else { - // return JSON - return region; - } -} - -Napi::Value virtualAllocEx(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 5 && args.Length() != 6) { - Napi::Error::New(env, "requires 5 arguments, 6 with callback").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber() || !args[2].IsNumber() || !args[3].IsNumber() || !args[4].IsNumber()) { - Napi::Error::New(env, "invalid arguments: arguments 0, 2, 3 and 4 need to be numbers").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (args.Length() == 6 && !args[5].IsFunction()) { - Napi::Error::New(env, "callback needs to be a function").ThrowAsJavaScriptException(); - return env.Null(); - } - - HANDLE handle = (HANDLE)args[0].As().Int64Value(); - SIZE_T size = args[2].As().Int64Value(); - DWORD allocationType = args[3].As().Uint32Value(); - DWORD protection = args[4].As().Uint32Value(); - LPVOID address; - - // Means in the JavaScript space `null` was passed through. - if (args[1] == env.Null()) { - address = NULL; - } else { - address = (LPVOID) args[1].As().Int64Value(); - } - - LPVOID allocatedAddress = VirtualAllocEx(handle, address, size, allocationType, protection); - - const char* errorMessage = ""; - - // If null, it means an error occurred - if (allocatedAddress == NULL) { - errorMessage = "an error occurred calling VirtualAllocEx"; - // errorMessage = GetLastErrorToString().c_str(); - } - - // If there is an error and there is no callback, throw the error - if (strcmp(errorMessage, "") && args.Length() != 6) { - Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); - return env.Null(); - } - - if (args.Length() == 6) { - // Callback to let the user handle with the information - Napi::Function callback = args[5].As(); - callback.Call(env.Global(), { - Napi::String::New(env, errorMessage), - Napi::Value::From(env, (intptr_t)allocatedAddress) - }); - return env.Null(); - } else { - return Napi::Value::From(env, (intptr_t)allocatedAddress); - } -} - -Napi::Value attachDebugger(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 2) { - Napi::Error::New(env, "requires 2 arguments").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber() || !args[1].IsBoolean()) { - Napi::Error::New(env, "first argument needs to be a number, second a boolean").ThrowAsJavaScriptException(); - return env.Null(); - } - - DWORD processId = args[0].As().Uint32Value(); - bool killOnExit = args[1].As().Value(); - - bool success = debugger::attach(processId, killOnExit); - return Napi::Boolean::New(env, success); -} - -Napi::Value detachDebugger(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - DWORD processId = args[0].As().Uint32Value(); - - if (args.Length() != 1) { - Napi::Error::New(env, "requires only 1 argument").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber()) { - Napi::Error::New(env, "only argument needs to be a number").ThrowAsJavaScriptException(); - return env.Null(); - } - - bool success = debugger::detatch(processId); - return Napi::Boolean::New(env, success); -} - -Napi::Value awaitDebugEvent(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 2) { - Napi::Error::New(env, "requires 2 arguments").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber() || !args[1].IsNumber()) { - Napi::Error::New(env, "both arguments need to be a number").ThrowAsJavaScriptException(); - return env.Null(); - } - - int millisTimeout = args[1].As().Uint32Value(); - - DebugEvent debugEvent; - bool success = debugger::awaitDebugEvent(millisTimeout, &debugEvent); - - Register hardwareRegister = static_cast(args[0].As().Uint32Value()); - - if (success && debugEvent.hardwareRegister == hardwareRegister) { - Napi::Object info = Napi::Object::New(env); - - info.Set(Napi::String::New(env, "processId"), Napi::Value::From(env, (DWORD) debugEvent.processId)); - info.Set(Napi::String::New(env, "threadId"), Napi::Value::From(env, (DWORD) debugEvent.threadId)); - info.Set(Napi::String::New(env, "exceptionCode"), Napi::Value::From(env, (DWORD) debugEvent.exceptionCode)); - info.Set(Napi::String::New(env, "exceptionFlags"), Napi::Value::From(env, (DWORD) debugEvent.exceptionFlags)); - info.Set(Napi::String::New(env, "exceptionAddress"), Napi::Value::From(env, (DWORD64) debugEvent.exceptionAddress)); - info.Set(Napi::String::New(env, "hardwareRegister"), Napi::Value::From(env, static_cast(debugEvent.hardwareRegister))); - - return info; - } - - // If we aren't interested in passing this event back to the JS space, - // just silently handle it - if (success && debugEvent.hardwareRegister != hardwareRegister) { - debugger::handleDebugEvent(debugEvent.processId, debugEvent.threadId); - } - - return env.Null(); -} - -Napi::Value handleDebugEvent(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 2) { - Napi::Error::New(env, "requires 2 arguments").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber() || !args[1].IsNumber()) { - Napi::Error::New(env, "both arguments need to be numbers").ThrowAsJavaScriptException(); - return env.Null(); - } - - DWORD processId = args[0].As().Uint32Value(); - DWORD threadId = args[1].As().Uint32Value(); - - bool success = debugger::handleDebugEvent(processId, threadId); - return Napi::Boolean::New(env, success); -} - -Napi::Value setHardwareBreakpoint(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 5) { - Napi::Error::New(env, "requires 5 arguments").ThrowAsJavaScriptException(); - return env.Null(); - } - - for (unsigned int i = 0; i < args.Length(); i++) { - if (!args[i].IsNumber()) { - Napi::Error::New(env, "all arguments need to be numbers").ThrowAsJavaScriptException(); - return env.Null(); - } - } - - DWORD processId = args[0].As().Uint32Value(); - DWORD64 address = args[1].As().Int64Value(); - Register hardwareRegister = static_cast(args[2].As().Uint32Value()); - - // Execute = 0x0 - // Access = 0x3 - // Writer = 0x1 - int trigger = args[3].As().Uint32Value(); - - int length = args[4].As().Uint32Value(); - - bool success = debugger::setHardwareBreakpoint(processId, address, hardwareRegister, trigger, length); - return Napi::Boolean::New(env, success); -} - -Napi::Value removeHardwareBreakpoint(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 2) { - Napi::Error::New(env, "requires 2 arguments").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber() || !args[1].IsNumber()) { - Napi::Error::New(env, "both arguments need to be numbers").ThrowAsJavaScriptException(); - return env.Null(); - } - - DWORD processId = args[0].As().Uint32Value(); - Register hardwareRegister = static_cast(args[1].As().Uint32Value()); - - bool success = debugger::setHardwareBreakpoint(processId, 0, hardwareRegister, 0, 0); - return Napi::Boolean::New(env, success); -} - -Napi::Value injectDll(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 2 && args.Length() != 3) { - Napi::Error::New(env, "requires 2 arguments, or 3 with a callback").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber() || !args[1].IsString()) { - Napi::Error::New(env, "first argument needs to be a number, second argument needs to be a string").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (args.Length() == 3 && !args[2].IsFunction()) { - Napi::Error::New(env, "callback needs to be a function").ThrowAsJavaScriptException(); - return env.Null(); - } - - HANDLE handle = (HANDLE)args[0].As().Int64Value(); - std::string dllPath(args[1].As().Utf8Value()); - Napi::Function callback = args[2].As(); - - const char* errorMessage = ""; - DWORD moduleHandle = -1; - bool success = dll::inject(handle, dllPath, &errorMessage, &moduleHandle); - - if (strcmp(errorMessage, "") && args.Length() != 3) { - Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); - return env.Null(); - } - - // `moduleHandle` above is the return value of the `LoadLibrary` procedure, - // which we retrieve through `GetExitCode`. This value can become truncated - // in large address spaces such as 64 bit since `GetExitCode` just returns BOOL, - // so it's unreliable to use as the handle. Since the handle of a module is just a pointer - // to the address of the DLL mapped in the process' virtual address space, we can fetch - // this separately, so we won't return it to prevent it being passed to `unloadDll` - // and in some cases unexpectedly failing when it is truncated. - - if (args.Length() == 3) { - callback.Call(env.Global(), { Napi::String::New(env, errorMessage), Napi::Boolean::New(env, success) }); - return env.Null(); - } else { - return Napi::Boolean::New(env, success); - } -} - -Napi::Value unloadDll(const Napi::CallbackInfo& args) { - Napi::Env env = args.Env(); - - if (args.Length() != 2 && args.Length() != 3) { - Napi::Error::New(env, "requires 2 arguments, or 3 with a callback").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[0].IsNumber()) { - Napi::Error::New(env, "first argument needs to be a number").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (!args[1].IsNumber() && !args[1].IsString()) { - Napi::Error::New(env, "second argument needs to be a number or a string").ThrowAsJavaScriptException(); - return env.Null(); - } - - if (args.Length() == 3 && !args[2].IsFunction()) { - Napi::Error::New(env, "callback needs to be a function").ThrowAsJavaScriptException(); - return env.Null(); - } - - HANDLE handle = (HANDLE)args[0].As().Int64Value(); - Napi::Function callback = args[2].As(); - - HMODULE moduleHandle; - - // get module handle (module base address) directly - if (args[1].IsNumber()) { - moduleHandle = (HMODULE)args[1].As().Int64Value(); - } - - // find module handle from name of DLL - if (args[1].IsString()) { - std::string moduleName(args[1].As().Utf8Value()); - const char* errorMessage = ""; - - MODULEENTRY32 module = module::findModule(moduleName.c_str(), GetProcessId(handle), &errorMessage); - - if (strcmp(errorMessage, "")) { - if (args.Length() != 3) { - Napi::Error::New(env, "unable to find specified module").ThrowAsJavaScriptException(); - return env.Null(); - } else { - callback.Call(env.Global(), { Napi::String::New(env, errorMessage) }); - return Napi::Boolean::New(env, false); - } - } - - moduleHandle = (HMODULE) module.modBaseAddr; - } - - const char* errorMessage = ""; - bool success = dll::unload(handle, &errorMessage, moduleHandle); - - if (strcmp(errorMessage, "") && args.Length() != 3) { - Napi::Error::New(env, errorMessage).ThrowAsJavaScriptException(); - return Napi::Boolean::New(env, false); - } - - if (args.Length() == 3) { - callback.Call(env.Global(), { Napi::String::New(env, errorMessage), Napi::Boolean::New(env, success) }); - return env.Null(); - } else { - return Napi::Boolean::New(env, success); - } -} - -// https://stackoverflow.com/a/17387176 -std::string GetLastErrorToString() { - DWORD errorMessageID = ::GetLastError(); - - // No error message, return empty string - if(errorMessageID == 0) { - return std::string(); - } - - LPSTR messageBuffer = nullptr; - - size_t size = FormatMessageA( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - errorMessageID, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&messageBuffer, - 0, - NULL - ); - - std::string message(messageBuffer, size); - - // Free the buffer - LocalFree(messageBuffer); - return message; -} - -Napi::Object init(Napi::Env env, Napi::Object exports) { - exports.Set(Napi::String::New(env, "openProcess"), Napi::Function::New(env, openProcess)); - exports.Set(Napi::String::New(env, "closeProcess"), Napi::Function::New(env, closeProcess)); - exports.Set(Napi::String::New(env, "getProcesses"), Napi::Function::New(env, getProcesses)); - exports.Set(Napi::String::New(env, "getModules"), Napi::Function::New(env, getModules)); - exports.Set(Napi::String::New(env, "findModule"), Napi::Function::New(env, findModule)); - exports.Set(Napi::String::New(env, "readMemory"), Napi::Function::New(env, readMemory)); - exports.Set(Napi::String::New(env, "readBuffer"), Napi::Function::New(env, readBuffer)); - exports.Set(Napi::String::New(env, "writeMemory"), Napi::Function::New(env, writeMemory)); - exports.Set(Napi::String::New(env, "writeBuffer"), Napi::Function::New(env, writeBuffer)); - exports.Set(Napi::String::New(env, "findPattern"), Napi::Function::New(env, findPattern)); - exports.Set(Napi::String::New(env, "findPatternByModule"), Napi::Function::New(env, findPatternByModule)); - exports.Set(Napi::String::New(env, "findPatternByAddress"), Napi::Function::New(env, findPatternByAddress)); - exports.Set(Napi::String::New(env, "virtualProtectEx"), Napi::Function::New(env, virtualProtectEx)); - exports.Set(Napi::String::New(env, "callFunction"), Napi::Function::New(env, callFunction)); - exports.Set(Napi::String::New(env, "virtualAllocEx"), Napi::Function::New(env, virtualAllocEx)); - exports.Set(Napi::String::New(env, "getRegions"), Napi::Function::New(env, getRegions)); - exports.Set(Napi::String::New(env, "virtualQueryEx"), Napi::Function::New(env, virtualQueryEx)); - exports.Set(Napi::String::New(env, "attachDebugger"), Napi::Function::New(env, attachDebugger)); - exports.Set(Napi::String::New(env, "detachDebugger"), Napi::Function::New(env, detachDebugger)); - exports.Set(Napi::String::New(env, "awaitDebugEvent"), Napi::Function::New(env, awaitDebugEvent)); - exports.Set(Napi::String::New(env, "handleDebugEvent"), Napi::Function::New(env, handleDebugEvent)); - exports.Set(Napi::String::New(env, "setHardwareBreakpoint"), Napi::Function::New(env, setHardwareBreakpoint)); - exports.Set(Napi::String::New(env, "removeHardwareBreakpoint"), Napi::Function::New(env, removeHardwareBreakpoint)); - exports.Set(Napi::String::New(env, "injectDll"), Napi::Function::New(env, injectDll)); - exports.Set(Napi::String::New(env, "unloadDll"), Napi::Function::New(env, unloadDll)); - return exports; -} - -NODE_API_MODULE(memoryjs, init) \ No newline at end of file diff --git a/native/memoryjs.h b/native/memoryjs.h deleted file mode 100644 index c0428ef..0000000 --- a/native/memoryjs.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#ifndef MEMORYJS_H -#define MEMORYJS_H -#define WIN32_LEAN_AND_MEAN - -#include - -class memoryjs { - -public: - memoryjs(); - ~memoryjs(); -}; -#endif -#pragma once diff --git a/native/memoryprocess.cc b/native/memoryprocess.cc new file mode 100644 index 0000000..a264fba --- /dev/null +++ b/native/memoryprocess.cc @@ -0,0 +1,137 @@ +#include "process.h" +#include "module.h" +#include "memory.h" +#include + +process proc; +memory memory; + +extern "C" { + __declspec(dllexport) const char* openProcess(const char* processName) { + const char* errorMessage = nullptr; + auto result = proc.openProcess(processName, &errorMessage); + + static char buffer[1024]; + snprintf(buffer, sizeof(buffer), + "{\"dwSize\":%lu,\"th32ProcessID\":%lu,\"cntThreads\":%lu,\"th32ParentProcessID\":%lu," + "\"pcPriClassBase\":%ld,\"szExeFile\":\"%s\",\"handle\":%llu,\"modBaseAddr\":%llu}", + result.process.dwSize, + result.process.th32ProcessID, + result.process.cntThreads, + result.process.th32ParentProcessID, + result.process.pcPriClassBase, + result.process.szExeFile, + (unsigned long long)result.handle, + (unsigned long long)module::getBaseAddress(result.process.szExeFile, result.process.th32ProcessID) + ); + + return buffer; + } + + // Vector3 and Vector4 structures for memory reading + struct Vector3 { + float x, y, z; + }; + + struct Vector4 { + float w, x, y, z; + }; + + __declspec(dllexport) int readMemory(unsigned long long handle, unsigned long long address, const char* dataType) { + // For simple numeric types, we'll return the value directly + // For complex types, we'll need to handle them differently in the JS side + + // Cast handle to HANDLE (void*) safely using intptr_t as an intermediate type + HANDLE hProcess = (HANDLE)(intptr_t)handle; + DWORD64 memAddress = (DWORD64)address; + + if (!strcmp(dataType, "int8") || !strcmp(dataType, "byte") || !strcmp(dataType, "char")) { + return (int)memory.readMemory(hProcess, memAddress); + + } else if (!strcmp(dataType, "uint8") || !strcmp(dataType, "ubyte") || !strcmp(dataType, "uchar")) { + return (int)memory.readMemory(hProcess, memAddress); + + } else if (!strcmp(dataType, "int16") || !strcmp(dataType, "short")) { + return (int)memory.readMemory(hProcess, memAddress); + + } else if (!strcmp(dataType, "uint16") || !strcmp(dataType, "ushort") || !strcmp(dataType, "word")) { + return (int)memory.readMemory(hProcess, memAddress); + + } else if (!strcmp(dataType, "int32") || !strcmp(dataType, "int") || !strcmp(dataType, "long")) { + return memory.readMemory(hProcess, memAddress); + + } else if (!strcmp(dataType, "uint32") || !strcmp(dataType, "uint") || !strcmp(dataType, "ulong") || !strcmp(dataType, "dword")) { + return (int)memory.readMemory(hProcess, memAddress); + + } else if (!strcmp(dataType, "int64") || !strcmp(dataType, "long long")) { + return memory.readMemory(hProcess, memAddress); + + } else if (!strcmp(dataType, "uint64") || !strcmp(dataType, "ulong long")) { + return (int)memory.readMemory(hProcess, memAddress); + + } else if (!strcmp(dataType, "bool") || !strcmp(dataType, "boolean")) { + return memory.readMemory(hProcess, memAddress) ? 1 : 0; + + } else if (!strcmp(dataType, "float")) { + // For float, we'll reinterpret the bits as an int + float result = memory.readMemory(hProcess, memAddress); + return *(int*)&result; + + } else { + // For unsupported types in this simple implementation, return 0 + // More complex types would need special handling on the JS side + return 0; + } + } + + __declspec(dllexport) void writeMemory(HANDLE handle, DWORD64 address, const char* dataType, const void* valuePtr) { + // This function assumes valuePtr points to data of the type specified by dataType. + // The caller is responsible for ensuring type correctness and memory validity. + + if (!strcmp(dataType, "int8") || !strcmp(dataType, "byte") || !strcmp(dataType, "char")) { + memory.writeMemory(handle, address, *(static_cast(valuePtr))); + } else if (!strcmp(dataType, "uint8") || !strcmp(dataType, "ubyte") || !strcmp(dataType, "uchar")) { + memory.writeMemory(handle, address, *(static_cast(valuePtr))); + } else if (!strcmp(dataType, "int16") || !strcmp(dataType, "short")) { + memory.writeMemory(handle, address, *(static_cast(valuePtr))); + } else if (!strcmp(dataType, "uint16") || !strcmp(dataType, "ushort") || !strcmp(dataType, "word")) { + memory.writeMemory(handle, address, *(static_cast(valuePtr))); + } else if (!strcmp(dataType, "int32") || !strcmp(dataType, "int") || !strcmp(dataType, "long")) { + memory.writeMemory(handle, address, *(static_cast(valuePtr))); + } else if (!strcmp(dataType, "uint32") || !strcmp(dataType, "uint") || !strcmp(dataType, "ulong") || !strcmp(dataType, "dword")) { + memory.writeMemory(handle, address, *(static_cast(valuePtr))); + } else if (!strcmp(dataType, "int64")) { + memory.writeMemory(handle, address, *(static_cast(valuePtr))); + } else if (!strcmp(dataType, "uint64")) { + memory.writeMemory(handle, address, *(static_cast(valuePtr))); + } else if (!strcmp(dataType, "float")) { + memory.writeMemory(handle, address, *(static_cast(valuePtr))); + } else if (!strcmp(dataType, "double")) { + memory.writeMemory(handle, address, *(static_cast(valuePtr))); + } else if (!strcmp(dataType, "ptr") || !strcmp(dataType, "pointer")) { + memory.writeMemory(handle, address, *(static_cast(valuePtr))); + } else if (!strcmp(dataType, "uptr") || !strcmp(dataType, "upointer")) { + memory.writeMemory(handle, address, *(static_cast(valuePtr))); + } else if (!strcmp(dataType, "bool") || !strcmp(dataType, "boolean")) { + memory.writeMemory(handle, address, *(static_cast(valuePtr))); + } else if (!strcmp(dataType, "string") || !strcmp(dataType, "str")) { + // Assumes valuePtr points to a null-terminated C-style string. + // Writes the string content including the null terminator. + const char* strValue = static_cast(valuePtr); + memory.writeMemory(handle, address, strValue, strlen(strValue) + 1); + } else if (!strcmp(dataType, "vector3") || !strcmp(dataType, "vec3")) { + memory.writeMemory(handle, address, *(static_cast(valuePtr))); + } else if (!strcmp(dataType, "vector4") || !strcmp(dataType, "vec4")) { + memory.writeMemory(handle, address, *(static_cast(valuePtr))); + } else { + // Optional: Add error handling for unexpected data type if needed, + // e.g., throw std::runtime_error or return a bool status. + // For now, it does nothing for unknown types. + } + } + + __declspec(dllexport) void closeProcess(HANDLE hProcess) { + process proc; + proc.closeProcess(hProcess); + } +} \ No newline at end of file diff --git a/native/memoryprocess.h b/native/memoryprocess.h new file mode 100644 index 0000000..81066e4 --- /dev/null +++ b/native/memoryprocess.h @@ -0,0 +1,15 @@ +#pragma once +#ifndef MEMORYPROCESS_H +#define MEMORYPROCESS_H +#define WIN32_LEAN_AND_MEAN + +#include + +class memoryprocess { + +public: +memoryprocess(); + ~memoryprocess(); +}; +#endif +#pragma once diff --git a/native/module.cc b/native/module.cc index 6ec1f86..4dd8c93 100644 --- a/native/module.cc +++ b/native/module.cc @@ -1,10 +1,7 @@ -#include #include #include #include #include "module.h" -#include "process.h" -#include "memoryjs.h" DWORD64 module::getBaseAddress(const char* processName, DWORD processId) { const char* errorMessage = ""; diff --git a/native/module.h b/native/module.h index b617e64..c9b0227 100644 --- a/native/module.h +++ b/native/module.h @@ -12,7 +12,6 @@ namespace module { MODULEENTRY32 findModule(const char* moduleName, DWORD processId, const char** errorMessage); std::vector getModules(DWORD processId, const char** errorMessage); std::vector getThreads(DWORD processId, const char** errorMessage); - }; #endif #pragma once diff --git a/native/pattern.cc b/native/pattern.cc index 7c07632..b1783b2 100644 --- a/native/pattern.cc +++ b/native/pattern.cc @@ -1,11 +1,7 @@ -#include #include #include #include #include "pattern.h" -#include "memoryjs.h" -#include "process.h" -#include "memory.h" #define INRANGE(x,a,b) (x >= a && x <= b) #define getBits( x ) (INRANGE(x,'0','9') ? (x - '0') : ((x&(~0x20)) - 'A' + 0xa)) diff --git a/native/pattern.h b/native/pattern.h index 5b108c4..adfa587 100644 --- a/native/pattern.h +++ b/native/pattern.h @@ -5,6 +5,7 @@ #include #include +#include class pattern { public: diff --git a/native/process.cc b/native/process.cc index 4dea0dd..787500a 100644 --- a/native/process.cc +++ b/native/process.cc @@ -1,17 +1,11 @@ -#include #include #include #include #include "process.h" -#include "memoryjs.h" process::process() {} process::~process() {} -using v8::Exception; -using v8::Isolate; -using v8::String; - process::Pair process::openProcess(const char* processName, const char** errorMessage){ PROCESSENTRY32 process; HANDLE handle = NULL; diff --git a/package.json b/package.json index 649e60e..f93e8a1 100644 --- a/package.json +++ b/package.json @@ -1,55 +1,63 @@ { - "name": "@joshmiquel/memoryjs", - "version": "3.6.1", - "description": "Maintained fork of memoryjs with critical fixes. Includes /Zc:strictStrings compiler fixes and other improvements. Original package by Rob--", + "name": "memoryprocess", + "version": "0.1.0-beta.0", + "description": "Maintained fork of memoryjs (Bun-only) with critical fixes. Requires Bun runtime.", + "author": "JoShMiQueL", "type": "module", - "main": "lib/index.js", - "types": "lib/index.d.ts", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", - "build": "bun run build.ts", - "check": "biome check --write " - }, - "repository": { - "type": "git", - "url": "git+https://github.com/JoShMiQueL/memoryjs.git" + "types": "./lib/index.d.ts", + "engineStrict": true, + "engines": { + "bun": ">=1.2.9" }, - "keywords": [ - "memory", - "reading", - "writing", - "management", - "addon", - "maintained-fork", - "windows-memory", - "process-memory" - ], - "author": "JoShMiQueL", - "contributors": [ - { - "name": "Rob--", - "url": "https://github.com/Rob--" + "exports": { + ".": { + "bun": "./lib/index.js", + "node": "./lib/node-error.js", + "types": "./lib/index.d.ts", + "default": "./lib/index.js" } - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/JoShMiQueL/memoryjs/issues" }, - "homepage": "https://github.com/JoShMiQueL/memoryjs#readme", - "dependencies": { - "node-addon-api": "8.3.1" + "scripts": { + "check": "biome check --write" }, "devDependencies": { "@biomejs/biome": "1.9.4", + "@commitlint/cli": "19.8.0", + "@commitlint/config-conventional": "19.8.0", "@microsoft/api-extractor": "7.52.3", + "@semantic-release/commit-analyzer": "13.0.1", + "@semantic-release/git": "10.0.1", + "@semantic-release/github": "11.0.1", + "@semantic-release/npm": "12.0.1", + "@semantic-release/release-notes-generator": "14.0.3", "@types/bun": "latest", - "lefthook": "1.11.10" + "lefthook": "1.11.10", + "semantic-release": "24.2.3" }, "peerDependencies": { - "typescript": "^5" + "typescript": "5.8.3" }, "trustedDependencies": [ "@biomejs/biome", "lefthook" + ], + "license": "MIT", + "homepage": "https://github.com/JoShMiQueL/memoryprocess#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/JoShMiQueL/memoryprocess.git" + }, + "bugs": { + "url": "https://github.com/JoShMiQueL/memoryprocess/issues" + }, + "keywords": [ + "memory", + "reading", + "writing", + "management", + "addon", + "maintained-fork", + "windows-memory", + "process-memory" ] } diff --git a/src/debugger.ts b/src/debugger.ts deleted file mode 100644 index 2a9d0c4..0000000 --- a/src/debugger.ts +++ /dev/null @@ -1,191 +0,0 @@ -import { EventEmitter } from "node:events"; -import type { MemoryJS } from "./types"; - -interface Interval { - register: number; - id: NodeJS.Timeout; -} - -const lengths = { - str: 0, - string: 0, - byte: 1, - int: 4, - int32: 4, - uint32: 4, - int64: 8, - uint64: 8, - dword: 4, - short: 2, - long: 8, - float: 4, - double: 8, - bool: 1, - boolean: 1, - ptr: 4, - pointer: 4, - // str: 0, - // string: 0, - // vec3: 0, - // vector3: 0, - // vec4: 0, - // vector4: 0, -}; - -// Tracks used and unused registers -interface RegisterMap { - DR0: number; - DR1: number; - DR2: number; - DR3: number; -} - -class Registers { - private registers: RegisterMap; - private used: number[]; - - constructor() { - this.registers = Object.freeze({ - DR0: 0x0, - DR1: 0x1, - DR2: 0x2, - DR3: 0x3, - }); - - this.used = []; - } - - getRegister() { - const unused = Object.values(this.registers).filter( - (r) => !this.used.includes(r), - ); - - return unused[0]; - } - - busy(register: number) { - this.used.push(register); - } - - unbusy(register: number) { - this.used.splice(this.used.indexOf(register), 1); - } -} - -class Debugger extends EventEmitter { - private memoryjs: MemoryJS; - private registers: Registers; - private attached: boolean; - private intervals: Interval[]; - constructor(memoryjs: MemoryJS) { - super(); - this.memoryjs = memoryjs; - this.registers = new Registers(); - this.attached = false; - this.intervals = []; - } - - attach(processId: number, killOnDetach = false): boolean { - const success = this.memoryjs.attachDebugger(processId, killOnDetach); - - if (success) { - this.attached = true; - } - - return success; - } - - detach(processId: number): boolean { - this.intervals.map(({ id }) => clearInterval(id)); - return this.memoryjs.detachDebugger(processId); - } - - removeHardwareBreakpoint(processId: number, register: number): boolean { - const success = this.memoryjs.removeHardwareBreakpoint(processId, register); - - if (success) { - this.registers.unbusy(register); - } - - // Find the register's corresponding interval and delete it - for (const { register: r, id } of this.intervals) { - if (r === register) { - clearInterval(id); - } - } - - return success; - } - - setHardwareBreakpoint( - processId: number, - address: number, - trigger: string, - dataType: keyof typeof lengths, - ): number { - let size = lengths[dataType]; - - // If we are breakpointing a string, we need to determine the length of it - if (dataType === "str" || dataType === "string") { - const { handle } = this.memoryjs.openProcess(processId); - const value = this.memoryjs.readMemory( - handle, - address, - "string", - ); - - size = value.length; - - this.memoryjs.closeProcess(handle); - } - - // Obtain an available register - const register = this.registers.getRegister(); - const success = this.memoryjs.setHardwareBreakpoint( - processId, - address, - register, - trigger, - size, - ); - - // If the breakpoint was set, mark this register as busy - if (success) { - this.registers.busy(register); - this.monitor(register); - } - - return register; - } - - monitor(register: number, timeout = 100): undefined { - const id = setInterval(() => { - const debugEvent = this.memoryjs.awaitDebugEvent(register, timeout); - - if (debugEvent) { - this.memoryjs.handleDebugEvent( - debugEvent.processId, - debugEvent.threadId, - ); - - // Global event for all registers - this.emit("debugEvent", { - register, - event: debugEvent, - }); - - // Event per register - this.emit(String(register), debugEvent); - } - }, 100); - - this.intervals.push({ - register, - id, - }); - } -} - -export { lengths }; - -export default Debugger; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..cedf45e --- /dev/null +++ b/src/index.ts @@ -0,0 +1,2 @@ +export * from './memory'; +export * from './process'; diff --git a/src/memory.ts b/src/memory.ts new file mode 100644 index 0000000..67dea0e --- /dev/null +++ b/src/memory.ts @@ -0,0 +1,93 @@ +import { dlopen } from "bun:ffi"; + +// Dynamically resolve the path to the DLL relative to the built file +const libPath = import.meta.resolve("./memoryprocess.dll"); + +const { symbols } = dlopen(libPath, { + readMemory: { + args: ["uint64_t", "uint64_t", "cstring"], + returns: "int", + }, + writeMemory: { + args: ["uint64_t", "uint64_t", "cstring", "ptr"], + returns: "void", + }, +}) + +/** + * Reads memory from a process. + * @param handle - The handle to the process. + * @param address - The memory address to read from. + * @param dataType - The data type to read. // TODO: Define specific types for dataType + * @returns The read value. + */ +export function readMemory(handle: number, address: number, dataType: string): number { + const dataTypeBuffer = Buffer.from(dataType + "\0") + const result = symbols.readMemory(handle, address, dataTypeBuffer) + return result +} + +/** + * Writes memory to a process. + * @param handle - The handle to the process. + * @param address - The memory address to write to. + * @param dataType - The data type to write. // TODO: Define specific types for dataType + * @param value - The value to write. // TODO: Define specific types for value based on dataType + */ +export function writeMemory(handle: number, address: number, dataType: string, value: any): void { + const dataTypeBuffer = Buffer.from(dataType + "\0") + + let valueBuffer: Buffer; + + // Create buffer with correct binary representation based on dataType + // This needs to handle all types supported by the C++ function + if (dataType === "int" || dataType === "int32" || dataType === "long") { + valueBuffer = Buffer.alloc(4); + valueBuffer.writeInt32LE(value as number, 0); + } else if (dataType === "uint" || dataType === "uint32" || dataType === "ulong" || dataType === "dword") { + valueBuffer = Buffer.alloc(4); + valueBuffer.writeUInt32LE(value as number, 0); + } else if (dataType === "short" || dataType === "int16") { + valueBuffer = Buffer.alloc(2); + valueBuffer.writeInt16LE(value as number, 0); + } else if (dataType === "ushort" || dataType === "uint16" || dataType === "word") { + valueBuffer = Buffer.alloc(2); + valueBuffer.writeUInt16LE(value as number, 0); + } else if (dataType === "char" || dataType === "int8" || dataType === "byte") { + valueBuffer = Buffer.alloc(1); + valueBuffer.writeInt8(value as number, 0); + } else if (dataType === "uchar" || dataType === "uint8" || dataType === "ubyte") { + valueBuffer = Buffer.alloc(1); + valueBuffer.writeUInt8(value as number, 0); + } else if (dataType === "float") { + valueBuffer = Buffer.alloc(4); + valueBuffer.writeFloatLE(value as number, 0); + } else if (dataType === "double") { + valueBuffer = Buffer.alloc(8); + valueBuffer.writeDoubleLE(value as number, 0); + } else if (dataType === "int64") { + valueBuffer = Buffer.alloc(8); + valueBuffer.writeBigInt64LE(BigInt(value), 0); + } else if (dataType === "uint64") { + valueBuffer = Buffer.alloc(8); + valueBuffer.writeBigUInt64LE(BigInt(value), 0); + } else if (dataType === "string" || dataType === "str") { + // Ensure null termination for C++ side + valueBuffer = Buffer.from((value as string) + "\0", "utf8"); + } else if (dataType === "bool" || dataType === "boolean") { + valueBuffer = Buffer.alloc(1); + valueBuffer.writeUInt8(value ? 1 : 0, 0); + } else if (dataType === "ptr" || dataType === "pointer") { + valueBuffer = Buffer.alloc(8); // Assuming 64-bit pointers + valueBuffer.writeBigUInt64LE(BigInt(value), 0); + } else if (dataType === "uptr" || dataType === "upointer") { + valueBuffer = Buffer.alloc(8); // Assuming 64-bit pointers + valueBuffer.writeBigUInt64LE(BigInt(value), 0); + } + // TODO: Add Vector3/Vector4 handling if needed + else { + throw new Error(`Unsupported data type for writeMemory: ${dataType}`); + } + + symbols.writeMemory(handle, address, dataTypeBuffer, valueBuffer) +} \ No newline at end of file diff --git a/src/memoryprocess.d.ts b/src/memoryprocess.d.ts new file mode 100644 index 0000000..8a8e71b --- /dev/null +++ b/src/memoryprocess.d.ts @@ -0,0 +1,4 @@ +declare module "*.dll" { + const value: string; + export default value; +} \ No newline at end of file diff --git a/src/process.ts b/src/process.ts new file mode 100644 index 0000000..331f88d --- /dev/null +++ b/src/process.ts @@ -0,0 +1,54 @@ +import { dlopen } from "bun:ffi"; + +// Dynamically resolve the path to the DLL relative to the built file +const libPath = import.meta.resolve("./memoryprocess.dll"); + +export interface ProcessObject { + dwSize: number; + th32ProcessID: number; + cntThreads: number; + th32ParentProcessID: number; + pcPriClassBase: number; + szExeFile: string; + handle: number; + modBaseAddr: number; +} + +const { symbols } = dlopen(libPath, { + openProcess: { + args: ["cstring"], + returns: "cstring", + }, + closeProcess: { + args: ["int"], + returns: "void", + }, +}) + +/** + * Opens a process by name. + * @param processName - The name of the process to open. + * @returns The opened process object. + */ +export function openProcess(processName: string): ProcessObject { + const processNameBuffer = Buffer.from(processName + "\0") + const processCString = symbols.openProcess(processNameBuffer) + const process = JSON.parse(processCString.toString()) as ProcessObject + return process +} + +/** + * Closes a process handle. + * @param handle - The handle to the process to close. + */ +export function closeProcess(handle: number): void { + try { + if (symbols.closeProcess) { + symbols.closeProcess(handle); + } else { + console.error("closeProcess FFI symbol not found."); + } + } catch (e) { + console.error(`Error closing handle ${handle}:`, e); + } +} \ No newline at end of file diff --git a/src/types.ts b/src/types.ts deleted file mode 100644 index f51f385..0000000 --- a/src/types.ts +++ /dev/null @@ -1,529 +0,0 @@ -export interface ProcessInfo { - dwSize: number; - th32ProcessID: number; - cntThreads: number; - th32ParentProcessID: number; - pcPriClassBase: number; - szExeFile: string; - modBaseAddr: number; - handle: number; -} - -export interface ModuleInfo { - modBaseAddr: number; - modBaseSize: number; - szExePath: string; - szModule: string; - th32ProcessID: number; - GlblcntUsage: number; -} - -export type Callback = (error: string | null, result: T) => undefined; - -export type OpenProcessCallback = Callback; -export type OpenProcessFunction = { - (processName: string): ProcessInfo; - (processId: number): ProcessInfo; - (processName: string, callback: OpenProcessCallback): undefined; - (processId: number, callback: OpenProcessCallback): undefined; - (processName: string, callback?: OpenProcessCallback): ProcessInfo | undefined; - (processId: number, callback?: OpenProcessCallback): ProcessInfo | undefined; -}; - -export type CloseProcessFunction = (handle: number) => undefined; - -export type GetProcessesCallback = Callback; -export type GetProcessesFunction = { - (): ProcessInfo[]; - (callback: GetProcessesCallback): undefined; - (callback?: GetProcessesCallback): ProcessInfo[] | undefined; -}; - -export type FindModuleCallback = Callback; -export type FindModuleFunction = { - (moduleName: string, processId: number): ModuleInfo; - (moduleName: string, processId: number, callback: FindModuleCallback): undefined; - ( - moduleName: string, - processId: number, - callback?: FindModuleCallback, - ): ModuleInfo | undefined; -}; - -export type GetModulesCallback = Callback; -export type GetModulesFunction = { - (processId: number): ModuleInfo[]; - (processId: number, callback: GetModulesCallback): undefined; - (processId: number, callback?: GetModulesCallback): ModuleInfo[] | undefined; -}; - -export type DataType = - | "int8" - | "byte" - | "char" - | "uint8" - | "ubyte" - | "uchar" - | "int16" - | "short" - | "uint16" - | "ushort" - | "word" - | "int32" - | "int" - | "long" - | "uint32" - | "uint" - | "ulong" - | "dword" - | "int64" - | "uint64" - | "float" - | "double" - | "ptr" - | "pointer" - | "uptr" - | "upointer" - | "bool" - | "boolean" - | "string" - | "str" - | "vector3" - | "vec3" - | "vector4" - | "vec4" - // Big-endian types - | "int16_be" - | "short_be" - | "uint16_be" - | "ushort_be" - | "int32_be" - | "int_be" - | "long_be" - | "uint32_be" - | "uint_be" - | "ulong_be" - | "int64_be" - | "uint64_be" - | "float_be" - | "double_be"; - -export interface Vector3 { - x: number; - y: number; - z: number; -} - -export interface Vector4 { - w: number; - x: number; - y: number; - z: number; -} - -export type DataTypeToType = T extends - | "int8" - | "byte" - | "char" - ? number - : T extends "uint8" | "ubyte" | "uchar" - ? number - : T extends "int16" | "short" - ? number - : T extends "uint16" | "ushort" | "word" - ? number - : T extends "int32" | "int" | "long" - ? number - : T extends "uint32" | "uint" | "ulong" | "dword" - ? number - : T extends "int64" - ? bigint - : T extends "uint64" - ? bigint - : T extends "float" - ? number - : T extends "double" - ? number - : T extends "ptr" | "pointer" - ? number | bigint - : T extends "uptr" | "upointer" - ? number | bigint - : T extends "bool" | "boolean" - ? boolean - : T extends "string" | "str" - ? string - : T extends "vector3" | "vec3" - ? Vector3 - : T extends "vector4" | "vec4" - ? Vector4 - : T extends "int16_be" | "short_be" - ? number - : T extends "uint16_be" | "ushort_be" - ? number - : T extends - | "int32_be" - | "int_be" - | "long_be" - ? number - : T extends - | "uint32_be" - | "uint_be" - | "ulong_be" - ? number - : T extends "int64_be" - ? bigint - : T extends "uint64_be" - ? bigint - : T extends "float_be" - ? number - : T extends "double_be" - ? number - : never; - -export type ReadMemoryCallback = (error: string, value: T) => undefined; -export type ReadMemoryFunction = { - ( - handle: number, - address: number | bigint, - dataType: T, - ): DataTypeToType; - ( - handle: number, - address: number | bigint, - dataType: T, - callback: ReadMemoryCallback>, - ): undefined; - ( - handle: number, - address: number | bigint, - dataType: T, - callback?: ReadMemoryCallback>, - ): DataTypeToType | undefined; -}; - -export type ReadMemoryBECallback = (error: string, value: T) => undefined; -export type ReadMemoryBEFunction = { - ( - handle: number, - address: number | bigint, - dataType: T, - ): DataTypeToType; - ( - handle: number, - address: number | bigint, - dataType: T, - callback: ReadMemoryBECallback>, - ): undefined; - ( - handle: number, - address: number | bigint, - dataType: T, - callback?: ReadMemoryBECallback>, - ): DataTypeToType | undefined; -}; - -export type ReadBufferCallback = (error: string, buffer: Buffer) => undefined; -export type ReadBufferFunction = { - (handle: number, address: number | bigint, size: number): Buffer; - ( - handle: number, - address: number | bigint, - size: number, - callback: ReadBufferCallback, - ): undefined; - ( - handle: number, - address: number | bigint, - size: number, - callback?: ReadBufferCallback, - ): Buffer | undefined; -}; - -export type DataTypeToWriteType = T extends - | "int8" - | "byte" - | "char" - ? number - : T extends "uint8" | "ubyte" | "uchar" - ? number - : T extends "int16" | "short" - ? number - : T extends "uint16" | "ushort" | "word" - ? number - : T extends "int32" | "int" | "long" - ? number - : T extends "uint32" | "uint" | "ulong" | "dword" - ? number - : T extends "int64" - ? bigint - : T extends "uint64" - ? bigint - : T extends "float" - ? number - : T extends "double" - ? number - : T extends "ptr" | "pointer" - ? number | bigint - : T extends "uptr" | "upointer" - ? number | bigint - : T extends "bool" | "boolean" - ? boolean - : T extends "string" | "str" - ? string - : T extends "vector3" | "vec3" - ? { x: number; y: number; z: number } - : T extends "vector4" | "vec4" - ? { w: number; x: number; y: number; z: number } - : never; - -export type WriteMemoryFunction = ( - handle: number, - address: number | bigint, - value: DataTypeToWriteType, - dataType: T, -) => undefined; - -export type WriteBufferFunction = ( - handle: number, - address: number | bigint, - buffer: Buffer, -) => undefined; - -export type FindPatternCallback = ( - error: string, - address: number | bigint, -) => undefined; -export type FindPatternFunction = { - ( - handle: number, - pattern: string, - flags: number, - patternOffset: number, - ): number; - ( - handle: number, - pattern: string, - flags: number, - patternOffset: number, - callback: FindPatternCallback, - ): undefined; - ( - handle: number, - pattern: string, - flags: number, - patternOffset: number, - callback?: FindPatternCallback, - ): number | undefined; -}; - -export enum FunctionType { - T_STRING = 0, - T_CHAR = 1, - T_BOOL = 2, - T_INT = 3, - T_FLOAT = 4, - T_DOUBLE = 5, -} -export type FunctionArg = { - type: FunctionType; - value: string | number | boolean; -}; -export type FunctionReturnValue = { - returnValue: string | number | boolean; - exitCode: number; -}; -export type CallFunctionCallback = ( - error: string, - result: FunctionReturnValue, -) => undefined; -export type CallFunctionFunction = { - ( - handle: number, - args: FunctionArg[], - returnType: FunctionType, - address: number | bigint, - ): FunctionReturnValue; - ( - handle: number, - args: FunctionArg[], - returnType: FunctionType, - address: number | bigint, - callback: CallFunctionCallback, - ): undefined; -}; - -export enum Protection { - PAGE_NOACCESS = 0x01, - PAGE_READONLY = 0x02, - PAGE_READWRITE = 0x04, - PAGE_WRITECOPY = 0x08, - PAGE_EXECUTE = 0x10, - PAGE_EXECUTE_READ = 0x20, - PAGE_EXECUTE_READWRITE = 0x40, - PAGE_EXECUTE_WRITECOPY = 0x80, - PAGE_GUARD = 0x100, - PAGE_NOCACHE = 0x200, - PAGE_WRITECOMBINE = 0x400, - PAGE_ENCLAVE_UNVALIDATED = 0x20000000, - PAGE_TARGETS_NO_UPDATE = 0x40000000, - PAGE_TARGETS_INVALID = 0x40000000, - PAGE_ENCLAVE_THREAD_CONTROL = 0x80000000, -} - -export enum AllocationType { - MEM_COMMIT = 0x1000, - MEM_RESERVE = 0x2000, - MEM_RESET = 0x80000, - MEM_TOP_DOWN = 0x100000, - MEM_WRITE_WATCH = 0x200000, - MEM_PHYSICAL = 0x400000, - MEM_RESET_UNDO = 0x1000000, - MEM_LARGE_PAGES = 0x20000000, -} - -export type VirtualAllocExCallback = ( - error: string, - address: number | bigint, -) => undefined; -export type VirtualAllocExFunction = { - ( - handle: number, - address: number | bigint | null, - size: number, - allocationType: AllocationType, - protection: Protection, - ): number; - ( - handle: number, - address: number | bigint | null, - size: number, - allocationType: AllocationType, - protection: Protection, - callback: VirtualAllocExCallback, - ): undefined; -}; - -export type VirtualProtectExCallback = ( - error: string, - oldProtection: Protection, -) => undefined; -export type VirtualProtectExFunction = { - ( - handle: number, - address: number | bigint, - size: number, - protection: Protection, - ): number; - ( - handle: number, - address: number | bigint, - size: number, - protection: Protection, - callback: VirtualProtectExCallback, - ): undefined; -}; - -export interface MemoryRegion { - Baseaddress: number | bigint; - AllocationBase: number; - AllocationProtect: Protection; - RegionSize: number; - State: number; - Protect: Protection; - Type: number; - szExeFile?: string; -} -export type GetRegionsCallback = ( - error: string, - regions: MemoryRegion[], -) => undefined; -export type GetRegionsFunction = { - (handle: number): MemoryRegion[]; - (handle: number, callback: GetRegionsCallback): undefined; -}; - -export type VirtualQueryExCallback = ( - error: string, - region: MemoryRegion, -) => undefined; -export type VirtualQueryExFunction = { - (handle: number, address: number | bigint): MemoryRegion; - ( - handle: number, - address: number | bigint, - callback: VirtualQueryExCallback, - ): undefined; -}; - -export type InjectDllCallback = (error: string, success: boolean) => undefined; -export type InjectDllFunction = { - (handle: number, dllPath: string): boolean; - (handle: number, dllPath: string, callback: InjectDllCallback): undefined; -}; - -export type UnloadDllCallback = (error: string, success: boolean) => undefined; -export type UnloadDllFunction = { - (handle: number, moduleaddress: number | bigint): boolean; - (handle: number, moduleName: string): boolean; - ( - handle: number, - moduleaddress: number | bigint, - callback: UnloadDllCallback, - ): undefined; - (handle: number, moduleName: string, callback: UnloadDllCallback): undefined; - ( - handle: number, - moduleaddress: number | bigint, - callback?: UnloadDllCallback, - ): boolean | undefined; - ( - handle: number, - moduleName: string, - callback?: UnloadDllCallback, - ): boolean | undefined; -}; - -export interface MemoryJS { - openProcess: OpenProcessFunction; - closeProcess: CloseProcessFunction; - getProcesses: GetProcessesFunction; - findModule: FindModuleFunction; - getModules: GetModulesFunction; - readMemory: ReadMemoryFunction; - readBuffer: ReadBufferFunction; - writeMemory: WriteMemoryFunction; - writeBuffer: WriteBufferFunction; - findPattern: FindPatternFunction; - callFunction: CallFunctionFunction; - virtualAllocEx: VirtualAllocExFunction; - virtualProtectEx: VirtualProtectExFunction; - virtualQueryEx: VirtualQueryExFunction; - getRegions: GetRegionsFunction; - injectDll: InjectDllFunction; - unloadDll: UnloadDllFunction; - attachDebugger: (processId: number, killOnDetach: boolean) => boolean; - detachDebugger: (processId: number) => boolean; - awaitDebugEvent: ( - register: number, - timeout: number, - ) => { - processId: number; - threadId: number; - exceptionCode: number; - exceptionFlags: number; - exceptionaddress: number | bigint; - hardwareRegister: number; - } | null; - handleDebugEvent: (processId: number, threadId: number) => boolean; - setHardwareBreakpoint: ( - processId: number, - address: number | bigint, - register: number, - trigger: string, - size: number, - ) => boolean; - removeHardwareBreakpoint: ( - processId: number, - hardwareRegister: number, - ) => boolean; -} diff --git a/src/utils.ts b/src/utils.ts deleted file mode 100644 index 47cc3f1..0000000 --- a/src/utils.ts +++ /dev/null @@ -1,125 +0,0 @@ -import type { DataType, MemoryJS } from "./types"; - -export interface StructronContext { - buffer: Buffer; -} - -export interface StructronType { - read(buffer: Buffer, offset: number): string; - write(value: string, context: StructronContext, offset: number): undefined; - SIZE: number; -} - -export type Platform = "32" | "64"; -export type BufferEncoding = "utf8" | "utf16le" | "ascii"; - -const SIZEOF_STDSTRING_32BIT = 24; -const SIZEOF_STDSTRING_64BIT = 32; -const STDSTRING_LENGTH_OFFSET = 0x10; - -/** - * Custom string consumer/producer for Structron (due to complexity of `std::string`) - * `std::string` is a container for a string which makes reading/writing to it tricky, - * it will either store the string itself, or a pointer to the string, based on the - * length of the string. When we want to read from or write to a buffer, we need - * to determine if the string is in the buffer itself, or if the buffer - * just contains a pointer to the string. Based on one of these options, - * we can read from or write to the string. - * - * @param handle the handle to the process - * @param structAddress the base address of the structure in memory - * @param platform the architecture of the process, either "32" or "64" - * @param encoding the encoding type of the string - */ -export const STRUCTRON_TYPE_STRING = - (memoryjs: MemoryJS) => - ( - handle: number, - structAddress: bigint, - platform: Platform, - encoding: BufferEncoding = "utf8", - ): StructronType => ({ - read(buffer: Buffer, offset: number): string { - // get string length from `std::string` container - const length = buffer.readUInt32LE(offset + STDSTRING_LENGTH_OFFSET); - - // if length > 15, `std::string` has a pointer to the string - if (length > 15) { - const pointer = - platform === "64" - ? buffer.readBigInt64LE(offset) - : BigInt(buffer.readUInt32LE(offset)); - return memoryjs.readMemory(handle, pointer, "string"); - } - - // if length <= 15, `std::string` directly contains the string - return buffer.toString(encoding, offset, offset + length); - }, - write(value: string, context: StructronContext, offset: number): undefined { - // address containing the length of the string - const lengthAddress = - structAddress + BigInt(offset + STDSTRING_LENGTH_OFFSET); - - // get existing `std::string` buffer - const bufferSize = - platform === "64" ? SIZEOF_STDSTRING_64BIT : SIZEOF_STDSTRING_32BIT; - const existingBuffer = memoryjs.readBuffer( - handle, - structAddress + BigInt(offset), - bufferSize, - ); - - // fetch length of string in memory (to determine if it's pointer based) - const length = memoryjs.readMemory(handle, lengthAddress, "int32"); - - if ( - (length > 15 && value.length <= 15) || - (length <= 15 && value.length > 15) - ) { - // there are two ways strings are stored: directly or with a pointer, - // we can't go from one to the other (without introducing more complexity), - // so just skip the bytes to prevent crashing. if a pointer is used, we could - // technically write any length, but the next time we try writing, we will read - // the length and assume it's not stored via pointer and will lead to crashes - - // write existing buffer without changes - existingBuffer.copy(context.buffer, offset); - return; - } - - // write new length - memoryjs.writeMemory(handle, lengthAddress, value.length, "uint32"); - existingBuffer.writeUInt32LE(value.length, STDSTRING_LENGTH_OFFSET); - - if (length > 15 && value.length > 15) { - // write new string in memory - const pointer = memoryjs.readMemory( - handle, - structAddress + BigInt(offset), - "pointer", - ); - memoryjs.writeMemory( - handle, - typeof pointer === "number" ? BigInt(pointer) : pointer, - value, - "string", - ); - } else if (length <= 15 && value.length <= 15) { - // write new string directly into buffer - existingBuffer.write(value, encoding); - } - - // write our new `std::string` buffer into the buffer we are creating - existingBuffer.copy(context.buffer, offset); - }, - SIZE: platform === "64" ? SIZEOF_STDSTRING_64BIT : SIZEOF_STDSTRING_32BIT, - }); - -/** - * Type guard to check if a DataType is a big-endian data type - * @param dataType The data type to check - * @returns True if the data type is big-endian - */ -export function isDataTypeBE(dataType: DataType): dataType is DataType { - return dataType.toLowerCase().endsWith("_be"); -} diff --git a/test/allocationTest.js b/test/allocationTest.js deleted file mode 100644 index cef6a9d..0000000 --- a/test/allocationTest.js +++ /dev/null @@ -1,16 +0,0 @@ -const memoryjs = require('../index'); -const processName = 'notepad.exe'; - -const processObject = memoryjs.openProcess(processName); - -const address = memoryjs.virtualAllocEx( - processObject.handle, - null, - 0x60, - memoryjs.MEM_RESERVE | memoryjs.MEM_COMMIT, - memoryjs.PAGE_EXECUTE_READWRITE, -); - -console.log(`Allocated address: 0x${address.toString(16).toUpperCase()}`); - -memoryjs.closeProcess(processObject.handle); diff --git a/test/debuggerTest.js b/test/debuggerTest.js deleted file mode 100644 index 6f579ed..0000000 --- a/test/debuggerTest.js +++ /dev/null @@ -1,44 +0,0 @@ -const memoryjs = require('../index'); -const processName = 'Testing Things.exe'; - -const processObject = memoryjs.openProcess(processName); -const processId = processObject.th32ProcessID; - -// Address of variable -const address = 0xEFFBF0; - -// When should we breakpoint? On read, write or execute -const trigger = memoryjs.TRIGGER_ACCESS; - -memoryjs.attachDebugger(processId); - -// There are 4 hardware registers: -// `memoryjs.DR0` through `memoryjs.DR3` -const registerToUse = memoryjs.DR0; - -// Our `address` references an integer variable. An integer -// is 4 bytes therefore we pass `4` to the `size` parameter. -const size = 4; -memoryjs.setHardwareBreakpoint(processId, address, registerToUse, trigger, size); - -// How long to wait for the debug event before timing out -const timeout = 100; - -// The interval duration must be the same or larger than the `timeout` value. -// `awaitDebugEvent` works by waiting a certain amount of time before timing out, -// therefore we only want to call the method again when we're sure the previous -// call has already timed out. -setInterval(() => { - // `debugEvent` can be null if no event occurred - const debugEvent = memoryjs.awaitDebugEvent(registerToUse, timeout); - - // If a breakpoint occurred, handle it - if (debugEvent) { - memoryjs.handleDebugEvent(debugEvent.processId, debugEvent.threadId); - } -}, timeout); - -// Don't forget to detatch the debugger! -// memoryjs.detatchDebugger(processId); - -memoryjs.closeProcess(processObject.handle); diff --git a/test/functionTest.js b/test/functionTest.js deleted file mode 100644 index da54f18..0000000 --- a/test/functionTest.js +++ /dev/null @@ -1,20 +0,0 @@ -const memoryjs = require('../index'); -const processName = 'FunctionTest.exe'; - -// TODO: Start the target process and obtain the absolute address of -// the function that you want to call and update the variable below. - -const processObject = memoryjs.openProcess(processName); - -const args = [{ type: memoryjs.T_FLOAT, value: 12.34 }]; -const returnType = memoryjs.T_FLOAT; - -const { - returnValue, - exitCode, -} = memoryjs.callFunction(processObject.handle, args, returnType, address); - -console.log(`Return value: ${returnValue}`); -console.log(`Exit code: ${exitCode}`); - -memoryjs.closeProcess(processObject.handle); diff --git a/test/memoryTest.js b/test/memoryTest.js deleted file mode 100644 index 3995ab6..0000000 --- a/test/memoryTest.js +++ /dev/null @@ -1,68 +0,0 @@ -const memoryjs = require('../index'); -const processName = 'MemoryTest.exe'; - -// TODO: Start the MemoryTest process, and check it's output against the outputs of this - -/* Example Output: - -$ node test/memoryTest -type address value -int 0x3AFCB4 2003818640 -dword 0x3AFCA8 2648673792 -short 0x3AFC9C 0 -long 0x3AFC90 0 -float 0x3AFC84 0 -double 0x3AFC74 4.031792002834e-312 -pointer 0x3AFC68 816043786240 -bool 0x3AFC5F false -string 0xB1FAA4 robert -*/ - -const processObject = memoryjs.openProcess(processName); - -const data = [{ - type: memoryjs.INT, - name: 'int', - address: 0x003AFCB4, -}, { - type: memoryjs.DWORD, - name: 'dword', - address: 0x003AFCA8, -}, { - type: memoryjs.SHORT, - name: 'short', - address: 0x003AFC9C, -}, { - type: memoryjs.LONG, - name: 'long', - address: 0x003AFC90, -}, { - type: memoryjs.FLOAT, - name: 'float', - address: 0x003AFC84, -}, { - type: memoryjs.DOUBLE, - name: 'double', - address: 0x003AFC74, -}, { - type: memoryjs.POINTER, - name: 'pointer', - address: 0x003AFC68, -}, { - type: memoryjs.BOOL, - name: 'bool', - address: 0x003AFC5F, -}, { - type: memoryjs.STRING, - name: 'string', - address: 0xb1faa4, -}]; - -console.log('type\taddress\t\tvalue'); - -data.forEach(({ type, name, address }) => { - const result = memoryjs.readMemory(processObject.handle, address, type); - console.log(`${name}\t0x${address.toString(16).toUpperCase()}\t${result}`); -}); - -memoryjs.closeProcess(processObject.handle); diff --git a/test/project.sln b/test/project.sln deleted file mode 100644 index fa1e230..0000000 --- a/test/project.sln +++ /dev/null @@ -1,37 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30503.244 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MemoryTest", "vcxproj\MemoryTest.vcxproj", "{67039DFF-7CB0-4034-8A19-470C8F8CADE9}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FunctionTest", "vcxproj\FunctionTest.vcxproj", "{D2E35EBA-E7AE-424D-B022-52440B65B235}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ProtectionTest", "vcxproj\ProtectionTest.vcxproj", "{8E68E3F6-3D5C-4D4B-AFCC-F13A9DA4D539}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x86 = Debug|x86 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {67039DFF-7CB0-4034-8A19-470C8F8CADE9}.Debug|x86.ActiveCfg = Debug|Win32 - {67039DFF-7CB0-4034-8A19-470C8F8CADE9}.Debug|x86.Build.0 = Debug|Win32 - {67039DFF-7CB0-4034-8A19-470C8F8CADE9}.Release|x86.ActiveCfg = Release|Win32 - {67039DFF-7CB0-4034-8A19-470C8F8CADE9}.Release|x86.Build.0 = Release|Win32 - {D2E35EBA-E7AE-424D-B022-52440B65B235}.Debug|x86.ActiveCfg = Debug|Win32 - {D2E35EBA-E7AE-424D-B022-52440B65B235}.Debug|x86.Build.0 = Debug|Win32 - {D2E35EBA-E7AE-424D-B022-52440B65B235}.Release|x86.ActiveCfg = Release|Win32 - {D2E35EBA-E7AE-424D-B022-52440B65B235}.Release|x86.Build.0 = Release|Win32 - {8E68E3F6-3D5C-4D4B-AFCC-F13A9DA4D539}.Debug|x86.ActiveCfg = Debug|Win32 - {8E68E3F6-3D5C-4D4B-AFCC-F13A9DA4D539}.Debug|x86.Build.0 = Debug|Win32 - {8E68E3F6-3D5C-4D4B-AFCC-F13A9DA4D539}.Release|x86.ActiveCfg = Release|Win32 - {8E68E3F6-3D5C-4D4B-AFCC-F13A9DA4D539}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {403312F9-8A55-4219-A498-9B79B46EC898} - EndGlobalSection -EndGlobal diff --git a/test/protectionTest.js b/test/protectionTest.js deleted file mode 100644 index ad8244d..0000000 --- a/test/protectionTest.js +++ /dev/null @@ -1,12 +0,0 @@ -const memoryjs = require('../index'); -const processName = 'ProtectionTest.exe'; - -// TODO: Start the TestTarget process, and monitor it's return value. - -const processObject = memoryjs.openProcess(processName); -console.log(processObject); - -memoryjs.setProtection(processObject.handle, 0x00FE102D, 4, memoryjs.PAGE_EXECUTE_READWRITE); -memoryjs.writeMemory(processObject.handle, 0x00FE102D, 1337, memoryjs.INT); - -memoryjs.closeProcess(processObject.handle); diff --git a/test/queryTest.js b/test/queryTest.js deleted file mode 100644 index 467072b..0000000 --- a/test/queryTest.js +++ /dev/null @@ -1,55 +0,0 @@ -const memoryjs = require('../index'); -const processName = 'chrome.exe'; - -const processObject = memoryjs.openProcess(processName); - -const regions = memoryjs.getRegions(processObject.handle).reverse().slice(0, 40); - -// Minimum lengths for each column -const lengths = { - BaseAddress: 'BaseAddress'.length, - AllocationBase: 'AllocationBase'.length, - AllocationProtect: 'AllocationProtect'.length, - RegionSize: 'RegionSize'.length, - State: 'State'.length, - Protect: 'Protect'.length, - Type: 'Type'.length, - szExeFile: 'szExeFile'.length, -}; - -// Calculate maximum lengths -regions.forEach((region) => { - Object.entries(region).forEach(([key, value]) => { - const formatted = `0x${value.toString(16)}`; - if (formatted.length > lengths[key]) { - lengths[key] = formatted.length; - } - }); -}); - -let text = ''; -Object.entries(lengths).forEach(([key, value]) => { - if (key === 'szExeFile') { - text += ` ${key}`.padEnd(value + 2, ' '); - } else { - text += key.padStart(value + 2, ' '); - text += ' |'; - } -}); -console.log(text); - -regions.forEach((region) => { - let text = ''; - Object.entries(region).forEach(([key, value]) => { - if (key === 'szExeFile') { - text += ` ${value}`.padEnd(lengths[key] + 2, ' '); - } else { - text += `0x${value.toString(16)}`.padStart(lengths[key] + 2, ' '); - text += ' |'; - } - }); - - console.log(text); -}); - -memoryjs.closeProcess(processObject.handle); diff --git a/test/src/MemoryTest.cpp b/test/src/MemoryTest.cpp deleted file mode 100644 index 48618da..0000000 --- a/test/src/MemoryTest.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include -#include - -using namespace std; - -int main() -{ - cout << "type\taddress\t\tvalue" << endl; - - int _int = -2147483647; - cout << "int\t0x" << hex << &_int << dec << "\t" << _int << endl; - - DWORD _dword = 2147483647; - cout << "dword\t0x" << hex << &_dword << dec << "\t" << _dword << endl; - - short _short = -32768; - cout << "short\t0x" << hex << &_short << dec << "\t" << _short << endl; - - long _long = -2147483647; - cout << "long\t0x" << hex << &_long << dec << "\t" << _long << endl; - - float _float = 3.402823466e+38F / 2; - cout << "float\t0x" << hex << &_float << dec << "\t" << _float << endl; - - double _double = 2.2250738585072014e-308; - cout << "double\t0x" << hex << &_double << dec << "\t" << _double << endl; - - intptr_t _intptr_t = 2147483647; - cout << "pointer\t0x" << hex << &_intptr_t << dec << "\t" << _intptr_t << endl; - - bool _bool = true; - cout << "bool\t0x" << hex << &_bool << dec << "\t" << _bool << endl; - - string _string = "robert"; - cout << "string\t0x" << hex << (DWORD64)_string.c_str() << dec << "\t" << _string << endl; - - getchar(); - - return 0; -} - diff --git a/test/src/functionTest.cpp b/test/src/functionTest.cpp deleted file mode 100644 index a196524..0000000 --- a/test/src/functionTest.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include -#include - -float testAdd(float a) { - std::cout << a << std::endl; - return a; -} - -int main() { - DWORD offset = (DWORD)testAdd - (DWORD)GetModuleHandle(NULL); - std::cout << "Function offset from base: 0x" << std::hex << offset << std::dec << std::endl; - std::cout << "Absolute: 0x" << std::hex << (DWORD)testAdd << std::dec << std::endl; - - getchar(); - return 0; -} \ No newline at end of file diff --git a/test/src/protectionTest.cpp b/test/src/protectionTest.cpp deleted file mode 100644 index a73356e..0000000 --- a/test/src/protectionTest.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// TestTarget.cpp : Defines the entry point for the console application. -// -#include -#include "stdio.h" -#include - -int value = 0; - -__declspec(noinline) void routine() { - value = 100; -} - - -int main() -{ - printf("This program will return an exit code of 0 if you successfuly modify the memory in the given time frame.\n\ -\nWe want to modify the .code section of this exe.\n\ -Address of operation is likely around: 0x%08X.\n\ -Look for the MOV opcode + from its address to get the value address and modify it's memory you will need to change protection on the section of memory.\n", &routine); - - - // Assert that the program is compiled and running with PAGE_EXECUTE_READ on the routine method. - MEMORY_BASIC_INFORMATION mbi; - if (VirtualQuery(&routine, &mbi, sizeof(mbi)) == 0) { - printf("Unable to query memory protection for some reason.\n"); - return 1; - } - if (! (mbi.Protect & PAGE_EXECUTE_READ) ) { - printf("Warning: Expecting memory to be EXECUTE_READ\n"); - return 1; - } - - printf("The address of the value is at 0x%08X but please modify the code in the routine that is setting it to 100 to set it to something else.\n", &value); - printf("On MSVC 2017 Release mode x86 I'm getting this address 0x%08X.\n", ((char*)&routine) + 6); - - - int counter = 0; - while (1) { - // Intentionally set the value to this before and after the call. - value = 0xDEADBEEF; - - routine(); - - if (value != 100) { - routine(); - if (value != 100) { - return 0; - } - else { - printf("Please modify the code not the value in memory.\n"); - } - } - - value = 0xDEADBEEF; - - Sleep(1000); - counter++; - - if (value != 0xDEADBEEF) { - printf("You must modify the code not the value.\n"); - } - - if (counter > 60) { - break; - } - } - - printf("Attempt time expired closing application as failed.\n"); - return 1; -} - diff --git a/test/vcxproj/FunctionTest.vcxproj b/test/vcxproj/FunctionTest.vcxproj deleted file mode 100644 index caf19bf..0000000 --- a/test/vcxproj/FunctionTest.vcxproj +++ /dev/null @@ -1,48 +0,0 @@ - - - - Debug - Win32 - - - Release - Win32 - - - - {D2E35EBA-E7AE-424D-B022-52440B65B235} - - - - Application - v142 - v141 - - - false - $(SolutionDir) - $(Configuration)\$(ProjectName)\ - $(ProjectName) - - - false - $(SolutionDir) - $(Configuration)\$(ProjectName)\ - $(ProjectName) - - - - false - - - - - false - - - - - - - - \ No newline at end of file diff --git a/test/vcxproj/MemoryTest.vcxproj b/test/vcxproj/MemoryTest.vcxproj deleted file mode 100644 index 3c59799..0000000 --- a/test/vcxproj/MemoryTest.vcxproj +++ /dev/null @@ -1,48 +0,0 @@ - - - - Debug - Win32 - - - Release - Win32 - - - - {67039DFF-7CB0-4034-8A19-470C8F8CADE9} - - - - Application - v142 - v141 - - - false - $(SolutionDir) - $(Configuration)\$(ProjectName)\ - $(ProjectName) - - - false - $(SolutionDir) - $(Configuration)\$(ProjectName)\ - $(ProjectName) - - - - false - - - - - false - - - - - - - - \ No newline at end of file diff --git a/test/vcxproj/ProtectionTest.vcxproj b/test/vcxproj/ProtectionTest.vcxproj deleted file mode 100644 index dfacd7a..0000000 --- a/test/vcxproj/ProtectionTest.vcxproj +++ /dev/null @@ -1,48 +0,0 @@ - - - - Debug - Win32 - - - Release - Win32 - - - - {8E68E3F6-3D5C-4D4B-AFCC-F13A9DA4D539} - - - - Application - v142 - v141 - - - false - $(SolutionDir) - $(Configuration)\$(ProjectName)\ - $(ProjectName) - - - false - $(SolutionDir) - $(Configuration)\$(ProjectName)\ - $(ProjectName) - - - - false - - - - - false - - - - - - - - \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index db2f69b..2767c59 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,7 @@ "sourceMap": true, "declarationMap": true, "emitDeclarationOnly": true, - "outDir": "temptypes", + "outDir": "lib", // Environment setup & latest features "lib": ["ESNext"], @@ -12,11 +12,10 @@ "module": "ESNext", "moduleDetection": "force", "jsx": "react-jsx", - "allowJs": true, // Bundler mode "moduleResolution": "bundler", - "allowImportingTsExtensions": true, + // "allowImportingTsExtensions": true, // "verbatimModuleSyntax": true, // "noEmit": true, @@ -29,7 +28,7 @@ // Some stricter flags (disabled by default) "noUnusedLocals": false, "noUnusedParameters": false, - "noPropertyAccessFromIndexSignature": false + "noPropertyAccessFromIndexSignature": false, }, - "include": ["index.ts", "src/**/*"] + "include": ["src/**/*.ts"] }