diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index b43b0fa9..8bc64d7d 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1 +1,2 @@
-* @jacksayshi
\ No newline at end of file
+* @jacksayshi
+* @UcheWendy
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/.github/ISSUE_TEMPLATE/CONTRIBUTING.md
similarity index 95%
rename from CONTRIBUTING.md
rename to .github/ISSUE_TEMPLATE/CONTRIBUTING.md
index bee3eb43..1bb02829 100644
--- a/CONTRIBUTING.md
+++ b/.github/ISSUE_TEMPLATE/CONTRIBUTING.md
@@ -1,81 +1,81 @@
-# Contributing to Digital Bones Box
-
-Thank you for checking out **Digital Bones Box**! We are so happy you are here. If you are intrested in contributing to the project below are some guidelines that help us make most out of your contribution.
-
-## Getting Started
-
-### How to Contribute
-
-### 1. **Fork the Repository**
-- Navigate to the Digital Bones Box repository on GitHub
-- Click the "Fork" button on the top right of the repository page to create your own copy.
-
-
-### 2. **Clone Your Fork**
-- Clone the repository to your local machine:
- ```bash
- git clone https://github.com/oss-slu/DigitalBonesBox
- cd your-repo
-
-
-### 3. Create a New Branch
-- Create a new branch for your contribution:
- ```bash
- git checkout -b feature-branch
- ```
-
----
-
-## Contribution Workflow
-
-### 1.Choose an Issue associated with the label **hacktoberfest**
-- Choose the Issue associated with the label hacktoberfest and clearly read all the details and acceptance criteria for the issue before starting to work on the issue.
-
-### 2. Make Your Changes
-- Work on your branch locally. Implement your changes and test them thoroughly to ensure they work correctly.
-- For any UI changes, please include screenshots in the pull request.
-
-### 3. Commit Your Changes
-- Commit messages should be clear and concise. Follow the format:
- ```
- git commit -m "Add feature X to improve performance"
- ```
-- Make sure your commit is properly documented and explains the **why** and **what** of the changes.
-
-### 4. Push Your Changes
-- Push your branch to GitHub:
- ```bash
- git push origin feature-branch
- ```
-
-### 5. Submit a Pull Request (PR)
-- Navigate to your fork on GitHub and click the **Pull Request** button.
-- Ensure your PR:
- - References the related issue number (e.g., `Fixes #123`).
- - Provides a clear description of what was changed and why.
- - Includes relevant tests or screenshots where applicable.
- - follow the Pull Request template.
-
----
-
-## Code Guidelines
-
-- Keep your code readable, maintainable, and well-documented.
-
-### 1. Documentation
-- Update documentation as necessary. If your change impacts functionality, be sure to update the corresponding documentation in the **Help** or **README** files.
-
----
-
-## Issue Reporting
-
-### 1. Suggesting Enhancements
-- If you have ideas for new features, improvements, or optimizations, submit them through a GitHub issue and tag it with **enhancement**.
-
----
-
-## Community
-
-- If you have any questions or need guidance, feel free to or reach out via email sritammiraja.iragavarapu@slu.edu
-
-Thank you for your contributions!
+# Contributing to Digital Bones Box
+
+Thank you for checking out **Digital Bones Box**! We are so happy you are here. If you are intrested in contributing to the project below are some guidelines that help us make most out of your contribution.
+
+## Getting Started
+
+### How to Contribute
+
+### 1. **Fork the Repository**
+- Navigate to the Digital Bones Box repository on GitHub
+- Click the "Fork" button on the top right of the repository page to create your own copy.
+
+
+### 2. **Clone Your Fork**
+- Clone the repository to your local machine:
+ ```bash
+ git clone https://github.com/oss-slu/DigitalBonesBox
+ cd your-repo
+
+
+### 3. Create a New Branch
+- Create a new branch for your contribution:
+ ```bash
+ git checkout -b feature-branch
+ ```
+
+---
+
+## Contribution Workflow
+
+### 1.Choose an Issue associated with the label **hacktoberfest**
+- Choose the Issue associated with the label hacktoberfest and clearly read all the details and acceptance criteria for the issue before starting to work on the issue.
+
+### 2. Make Your Changes
+- Work on your branch locally. Implement your changes and test them thoroughly to ensure they work correctly.
+- For any UI changes, please include screenshots in the pull request.
+
+### 3. Commit Your Changes
+- Commit messages should be clear and concise. Follow the format:
+ ```
+ git commit -m "Add feature X to improve performance"
+ ```
+- Make sure your commit is properly documented and explains the **why** and **what** of the changes.
+
+### 4. Push Your Changes
+- Push your branch to GitHub:
+ ```bash
+ git push origin feature-branch
+ ```
+
+### 5. Submit a Pull Request (PR)
+- Navigate to your fork on GitHub and click the **Pull Request** button.
+- Ensure your PR:
+ - References the related issue number (e.g., `Fixes #123`).
+ - Provides a clear description of what was changed and why.
+ - Includes relevant tests or screenshots where applicable.
+ - follow the Pull Request template.
+
+---
+
+## Code Guidelines
+
+- Keep your code readable, maintainable, and well-documented.
+
+### 1. Documentation
+- Update documentation as necessary. If your change impacts functionality, be sure to update the corresponding documentation in the **Help** or **README** files.
+
+---
+
+## Issue Reporting
+
+### 1. Suggesting Enhancements
+- If you have ideas for new features, improvements, or optimizations, submit them through a GitHub issue and tag it with **enhancement**.
+
+---
+
+## Community
+
+- If you have any questions or need guidance, feel free to or reach out via email wendy.onwuagana@slu.edu or daniel.shown@slu.edu
+
+Thank you for your contributions!
diff --git a/.github/ISSUE_TEMPLATE/GOOD_FIRST_ISSUE.md b/.github/ISSUE_TEMPLATE/GOOD_FIRST_ISSUE.md
new file mode 100644
index 00000000..2c676834
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/GOOD_FIRST_ISSUE.md
@@ -0,0 +1,44 @@
+### Finding Your First Contribution
+Welcome to the DigitalBoneBox project! We're thrilled you're interested in contributing. This guide is designed to help you find and complete your first issue.
+
+### What is a "Good First Issue"?
+A "Good First Issue" is a task that has been specifically identified by our team as being a great entry point for new contributors. These issues are typically:
+
+1. Well-defined: The goal is clear and the scope is small.
+
+2. Low-impact: They don't involve changing critical parts of the application.
+
+3. A great learning opportunity: They are a perfect way to get familiar with our codebase, our contribution workflow, and our team.
+
+Examples of good first issues in this project might include:
+
+Fixing a typo in the UI.
+
+Improving the styling of a button or a menu.
+
+Adding a small, self-contained feature, like a "Back to Top" button.
+
+Improving the comments or documentation in a specific part of the code.
+
+### How to Find a Good First Issue
+We use a specific label on GitHub to mark these tasks. You can find a good first issue by looking at our wide range of issues created in our repo and identifying an issue tagged "Good First Issue".
+
+### Your First Contribution Workflow
+Once you've found an issue that interests you, here’s how to get started:
+
+1. Claim the Issue: Let everyone know you're working on it! You can assign the issue to yourself by clicking the "assign" button in the sidebar on the right of the issue page. It's also a good idea to leave a quick comment like, "I'd like to work on this!" This helps us avoid having multiple people working on the same thing.
+
+2. Follow the Contribution Guide: Our main CONTRIBUTING.md file has all the technical steps you need to get the project set up on your local machine. Please follow it carefully to fork the repository, create your branch, and run the application.
+
+3. Work on the Code: Make the necessary changes to the code to address the issue.
+
+4. Submit a Pull Request: Once you're finished, submit a pull request. we have a pull request template we use for our project which you can use for your reference under ISSUE_TEMPLATE. Once that is done, Our team will then review your work.
+
+### Questions or Need Help?
+We're here to help you succeed! If you get stuck, have a question, or just want to discuss an idea, please don't hesitate to:
+
+Leave a comment on the issue you're working on.
+
+Reach out to the project maintainers via the contact information in our CONTRIBUTING.md file.
+
+Thank you for your interest in contributing to DigitalBoneBox!
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 00000000..a5b1eb60
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,17 @@
+---
+name: Bug report
+about: Create a report to help us improve
+title: ''
+labels: bug
+assignees: ''
+
+---
+
+**Describe the bug + expected behavior**
+*A clear and concise description of what the bug is, and what you expected to happen.*
+
+**Steps to reproduce**
+*A list of steps it takes to see this bug.*
+
+**Additional context**
+*Add any other context or screenshots about the bug here.*
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 00000000..c0f9606d
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,17 @@
+---
+name: Feature request
+about: Suggest a change to this project
+title: ''
+labels: enhancement
+assignees: ''
+
+---
+
+**Describe the feature that you would like added**
+*A clear and concise description of the feature, and why is should be added to the project.*
+
+**Tasks that need to completed for this feature**
+*A list of individual tasks that likely must be done before the feature can be considered "complete".*
+
+**Additional context**
+*Add any other context or screenshots about the feature request here.*
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/taskcard.md b/.github/ISSUE_TEMPLATE/taskcard.md
new file mode 100644
index 00000000..0bac1aa9
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/taskcard.md
@@ -0,0 +1,35 @@
+---
+name: General Task Card
+about: For standard development tasks, chores, or refactoring.
+title: '[Task]: '
+labels: task, enhancement
+assignees: ''
+
+---
+
+### 🎯 Goal / Objective
+*A clear and concise description of what this task aims to achieve. Why is this task important for the sprint?*
+
+---
+
+### ✅ Tasks to be Completed
+*A checklist of the specific, actionable steps required to complete this issue. This helps track progress.*
+
+- [ ] Task 1:
+- [ ] Task 2:
+- [ ] Task 3:
+
+---
+
+### Acceptance Criteria
+*A checklist of conditions that must be met for this task to be considered complete. How will we verify that it's done correctly?*
+
+- [ ] The new feature is implemented as described.
+- [ ] All related code passes the repository's workflow checks (linting, tests).
+- [ ] The application runs without errors after the changes are made.
+- [ ] (If applicable) New automated tests have been added to cover the changes.
+
+---
+
+### Additional Context
+*Add any other context, notes, screenshots, or links that might be helpful for completing this task.*
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE.md
similarity index 100%
rename from .github/ISSUE_TEMPLATE/pull_request_template.md
rename to .github/PULL_REQUEST_TEMPLATE.md
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 00000000..84802681
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,27 @@
+name: Lint JavaScript
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v3
+ with:
+ node-version: '18'
+
+ - name: Install dependencies
+ run: npm install
+
+ - name: Run ESLint
+ run: npm run lint
diff --git a/.gitignore b/.gitignore
index c2658d7d..20de9305 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
node_modules/
+.vscode/
diff --git a/README.md b/README.md
index 36f990e4..21985a17 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,62 @@
-# DigitalBoneBox
+# DigitalBoneBox : A Web-Based Study Tool for Human Anatomy
+
This project is a Web App project aims to convert an existing PowerPoint-based educational tool into an interactive, mobile-friendly web application.
+
+## How / why did we get here?
+
+This project is based on the work of Prof. Brian Elliott, created during his final years of education.
+In the human anatomy class, students must purchase a bone set to study the bones of the human body,
+but they are not allowed to take these models out of the lab. Prof. Elliott observed that this
+restriction could cause inconvenience for students who want to quickly review the bones before an exam. To address this, he created a PowerPoint presentation that includes images of the bones taken from different angles (with permission from the department), and he annotated these images to highlight the various bones in the set using different colors and filters. He utilized all available features to create an easily accessible presentation that students could use for quick revision or brief study sessions before tests.
+
+However, he wanted to make this resource even more accessible. He envisioned offering students a
+platform they could access on their iPads, or laptops—devices commonly used by students. This is
+where the web application comes in. It is designed to be a quick and easy guide for students to use
+for exams, to quiz themselves on essential knowledge, or to learn from material that is simple and
+provides an overview of the human bones. This application is based on the information in the
+presentations created by Prof. Brian Elliott.
+
+## Tech Stack
+
+This project was developed using the following technologies:
+
+Node.js: Used for server-side development to handle requests and serve the application.
+HTML: For structuring the content of the web pages.
+HTMX: A lightweight JavaScript library for enhancing interactivity by allowing partial page updates without a full page reload.
+CSS: For styling and layout of the web pages to ensure a clean and responsive design for users across devices.
+
+## Features
+
+Interactive and accessible web application for students to study human anatomy.
+Quick revision tool with annotated images of bones.
+Designed for use on iPads, laptops, or other devices commonly used by students.
+
+- **Toggle Sidebar**:
+ - A collapsible sidebar that enhances navigation within the app.
+ - Includes **placeholder options** such as **Search**, **Contact**, **Recent**, and **Help**, which are non-functional and reserved for future implementation.
+ - Users can open and close the sidebar using the ☰ button on the top-left corner of the page.
+
+## Setup:
+
+To run this project locally, you will need to have Node.js installed. The application consists of a backend API and a frontend client, which can be run together with a single command.
+
+1. Clone the repository:
+
+- git clone [https://github.com/oss-slu/DigitalBonesBox.git](https://github.com/oss-slu/DigitalBonesBox.git)
+- cd DigitalBonesBox
+
+2. Install dependencies:
+This command will install the necessary packages for both the root project and the boneset-api server.
+
+- npm install && npm install --prefix boneset-api
+
+3. Run the application:
+This command will start both the backend API server and the frontend live server concurrently.
+
+- npm start
+
+Your browser should automatically open to the application.
+
+## Contributing
+
+Contributions are welcome! Check out the CONTRIBUTING.md for guidelines.
diff --git a/boneset-api/data/final_bony_pelvis.json b/boneset-api/data/final_bony_pelvis.json
new file mode 100644
index 00000000..cb79eb95
--- /dev/null
+++ b/boneset-api/data/final_bony_pelvis.json
@@ -0,0 +1,316 @@
+{
+ "id": "bony_pelvis",
+ "name": "Bony Pelvis",
+ "bones": [
+ {
+ "id": "ilium",
+ "name": "Ilium",
+ "description": [
+ "Forms the superior part of the bony pelvis.",
+ "Articulates with the sacrum to form the sacroiliac joint."
+ ],
+ "image_url": "/images/bony_pelvis/ilium.jpg",
+ "annotations": [
+ {
+ "text": "Ilium",
+ "position": {
+ "x": 5586937,
+ "y": 2083816,
+ "width": 393457,
+ "height": 215444
+ }
+ }
+ ],
+ "subbones": [
+ {
+ "id": "iliac_crest",
+ "name": "Iliac Crest",
+ "description": [
+ "Superior border of the ilium from ASIS to PSIS.",
+ "External lip: attachments for tensor fascia lata, external oblique, latissimus dorsi.",
+ "Inner lip: attachments for iliac fascia, internal oblique, transversus abdominis, quadratus lumborum, sacrospinalis, iliacus.",
+ "Surface landmark for L4 level; used for lumbar puncture."
+ ],
+ "image_url": "/images/bony_pelvis/iliac_crest.jpg",
+ "annotations": [
+ {
+ "text": "Iliac Crest",
+ "position": {
+ "x": 5431116,
+ "y": 1912315,
+ "width": 595035,
+ "height": 215444
+ }
+ }
+ ]
+ },
+
+ {
+ "id": "acetabulum",
+ "name": "Acetabulum",
+ "description": [
+ "Deep hemispherical socket of the hip bone.",
+ "Formed by the ilium (superior), ischium (posteroinferior), and pubis (anteroinferior); receives the head of the femur."
+ ],
+ "image_url": "/images/bony_pelvis/acetabulum.jpg",
+ "annotations": [
+ {
+ "text": "Acetabulum",
+ "position": { "x": 5450756, "y": 3572102, "width": 692939, "height": 215444 }
+ }
+ ]
+ },
+
+ {
+ "id": "anterior_superior_iliac_spine",
+ "name": "Anterior Superior Iliac Spine",
+ "description": [
+ "Bony projection at the anterior end of the iliac crest.",
+ "Attachment for inguinal ligament and sartorius origin."
+ ],
+ "image_url": "/images/bony_pelvis/anterior_superior_iliac_spine.jpg",
+ "annotations": [
+ {
+ "text": "Anterior Superior Iliac Spine",
+ "position": {
+ "x": 5407752,
+ "y": 2590801,
+ "width": 766897,
+ "height": 461665
+ }
+ }
+ ]
+ },
+ {
+ "id": "anterior_inferior_iliac_spine",
+ "name": "Anterior Inferior Iliac Spine",
+ "description": [
+ "Inferior to ASIS on anterior border of ilium.",
+ "Attachment for straight head of rectus femoris and iliofemoral ligament."
+ ],
+ "image_url": "/images/bony_pelvis/anterior_inferior_iliac_spine.jpg",
+ "annotations": [
+ {
+ "text": "Anterior Inferior Iliac Spine",
+ "position": {
+ "x": 5271485,
+ "y": 3229154,
+ "width": 766897,
+ "height": 461665
+ }
+ }
+ ]
+ },
+ {
+ "id": "posterior_superior_iliac_spine",
+ "name": "Posterior Superior Iliac Spine",
+ "description": [
+ "Posterior end of the iliac crest; surface landmark.",
+ "Attachment for posterior sacroiliac ligaments."
+ ],
+ "image_url": "/images/bony_pelvis/posterior_superior_iliac_spine.jpg",
+ "annotations": [
+ {
+ "text": "Posterior Superior Iliac Spine",
+ "position": {
+ "x": 7881241,
+ "y": 1445569,
+ "width": 766897,
+ "height": 461665
+ }
+ }
+ ]
+ },
+ {
+ "id": "posterior_inferior_iliac_spine",
+ "name": "Posterior Inferior Iliac Spine",
+ "description": [
+ "Small prominence along the border of the greater sciatic notch."
+ ],
+ "image_url": "/images/bony_pelvis/posterior_inferior_iliac_spine.jpg",
+ "annotations": [
+ {
+ "text": "Posterior Inferior Iliac Spine",
+ "position": {
+ "x": 7887969,
+ "y": 3816698,
+ "width": 766897,
+ "height": 461665
+ }
+ }
+ ]
+ },
+ {
+ "id": "auricular_surface",
+ "name": "Auricular Surface",
+ "description": [
+ "Roughened posterior ilium surface, normally covered with cartilage.",
+ "Articulates with the lateral surface of the sacrum at the sacroiliac joint."
+ ],
+ "image_url": "/images/bony_pelvis/auricular_surface.jpg",
+ "annotations": [
+ {
+ "text": "Auricular surface",
+ "position": {
+ "x": 7169365,
+ "y": 1417638,
+ "width": 624749,
+ "height": 338554
+ }
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "id": "ischium",
+ "name": "Ischium",
+ "description": [
+ "Forms the inferoposterior part of the pelvic bone.",
+ "Situated posterior to the pubis and inferior to the ilium."
+ ],
+ "image_url": "/images/bony_pelvis/ischium.jpg",
+ "annotations": [
+ {
+ "text": "Ischium",
+ "position": {
+ "x": 5446767,
+ "y": 5263629,
+ "width": 507320,
+ "height": 215444
+ }
+ }
+ ],
+ "subbones": [
+ {
+ "id": "ischial_ramus",
+ "name": "Ramus",
+ "description": [
+ "Inferior portion of the ischium; continuous with the inferior pubic ramus.",
+ "Forms part of the border of the obturator foramen.",
+ "Attachment for ischiocavernosus and the crus of the penis or clitoris."
+ ],
+ "image_url": "/images/bony_pelvis/ischial_ramus.jpg",
+ "annotations": []
+ },
+ {
+ "id": "ischial_tuberosity",
+ "name": "Ischial Tuberosity",
+ "description": [
+ "Large posterior swelling (the 'sits bone').",
+ "Attachments: adductor magnus, semimembranosus, semitendinosus, long head of biceps femoris.",
+ "Attachment for the sacrotuberous ligament."
+ ],
+ "image_url": "/images/bony_pelvis/ischial_tuberosity.jpg",
+ "annotations": []
+ },
+ {
+ "id": "ischial_spine",
+ "name": "Ischial Spine",
+ "description": [
+ "Bony projection on posterior surface of the body of the ischium.",
+ "Separates the greater and lesser sciatic notches.",
+ "Attachment for the sacrospinous ligament and superior gemellus."
+ ],
+ "image_url": "/images/bony_pelvis/ischial_spine.jpg",
+ "annotations": []
+ },
+ {
+ "id": "greater_sciatic_notch",
+ "name": "Greater Sciatic Notch",
+ "description": [
+ "Large notch superior to the ischial spine.",
+ "Converted to the greater sciatic foramen by the sacrospinous and sacrotuberous ligaments.",
+ "Transmits: superior gluteal vessels/nerve, piriformis, sciatic nerve, inferior gluteal vessels/nerve, internal pudendal vessels and pudendal nerve, posterior femoral cutaneous nerve, nerves to quadratus femoris and obturator internus."
+ ],
+ "image_url": "/images/bony_pelvis/greater_sciatic_notch.jpg",
+ "annotations": []
+ },
+ {
+ "id": "lesser_sciatic_notch",
+ "name": "Lesser Sciatic Notch",
+ "description": [
+ "Smaller notch inferior to the ischial spine.",
+ "Converted to the lesser sciatic foramen by the sacrotuberous ligament.",
+ "Transmits: tendon of obturator internus, internal pudendal vessels and pudendal nerve, nerve to obturator internus."
+ ],
+ "image_url": "/images/bony_pelvis/lesser_sciatic_notch.jpg",
+ "annotations": []
+ }
+ ]
+ },
+ {
+ "id": "pubis",
+ "name": "Pubis",
+ "description": [
+ "Forms the anteroinferior part of the pelvis.",
+ "Connects the two pelvic bones from each side."
+ ],
+ "image_url": "/images/bony_pelvis/pubis.jpg",
+ "annotations": [
+ {
+ "text": "Pubis",
+ "position": {
+ "x": 5682077,
+ "y": 4259252,
+ "width": 419318,
+ "height": 215444
+ }
+ }
+ ],
+ "subbones": [
+ {
+ "id": "superior_pubic_ramus",
+ "name": "Superior Pubic Ramus",
+ "description": [
+ "Projects posterolaterally from the body; contains the pectineal line.",
+ "Obturator groove on inferior surface contributes to the obturator canal."
+ ],
+ "image_url": "/images/bony_pelvis/superior_pubic_ramus.jpg",
+ "annotations": []
+ },
+ {
+ "id": "inferior_pubic_ramus",
+ "name": "Inferior Pubic Ramus",
+ "description": [
+ "Projects inferiorly and laterally from the body.",
+ "Joins with the ischial ramus to form part of the obturator foramen."
+ ],
+ "image_url": "/images/bony_pelvis/inferior_pubic_ramus.jpg",
+ "annotations": []
+ },
+ {
+ "id": "pectineal_line",
+ "name": "Pectineal Line",
+ "description": [
+ "Prominent ridge on the superior ramus.",
+ "Attachment for pectineus muscle, conjoint tendon, and lacunar and pectineal ligaments."
+ ],
+ "image_url": "/images/bony_pelvis/pectineal_line.jpg",
+ "annotations": []
+ },
+ {
+ "id": "symphyseal_surface",
+ "name": "Symphyseal Surface",
+ "description": [
+ "Joint surface on each pubis forming a secondary cartilaginous joint (symphysis).",
+ "Covered with hyaline cartilage and linked by the fibrocartilaginous pubic symphysis.",
+ "Remodels during pregnancy, increasing flexibility for delivery."
+ ],
+ "image_url": "/images/bony_pelvis/symphyseal_surface.jpg",
+ "annotations": []
+ },
+ {
+ "id": "pubic_tubercle",
+ "name": "Pubic Tubercle",
+ "description": [
+ "Bony projection at the lateral end of the pubic crest.",
+ "Attachment for the inguinal ligament."
+ ],
+ "image_url": "/images/bony_pelvis/pubic_tubercle.jpg",
+ "annotations": []
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/boneset-api/package-lock.json b/boneset-api/package-lock.json
new file mode 100644
index 00000000..7e65a2a7
--- /dev/null
+++ b/boneset-api/package-lock.json
@@ -0,0 +1,934 @@
+{
+ "name": "boneset-api",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "boneset-api",
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "axios": "^1.8.4",
+ "cors": "^2.8.5",
+ "dotenv": "^16.4.7",
+ "express": "^4.21.2",
+ "express-rate-limit": "^8.1.0"
+ }
+ },
+ "node_modules/accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "license": "MIT"
+ },
+ "node_modules/axios": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.12.2.tgz",
+ "integrity": "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==",
+ "license": "MIT",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.4",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/body-parser": {
+ "version": "1.20.3",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
+ "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.5",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "on-finished": "2.4.1",
+ "qs": "6.13.0",
+ "raw-body": "2.5.2",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/content-type": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
+ "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
+ },
+ "node_modules/cors": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/dotenv": {
+ "version": "16.4.7",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
+ "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
+ },
+ "node_modules/encodeurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/express": {
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
+ "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
+ "dependencies": {
+ "accepts": "~1.3.8",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.20.3",
+ "content-disposition": "0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "0.7.1",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "1.3.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "merge-descriptors": "1.0.3",
+ "methods": "~1.1.2",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.12",
+ "proxy-addr": "~2.0.7",
+ "qs": "6.13.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "0.19.0",
+ "serve-static": "1.16.2",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/express-rate-limit": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.1.0.tgz",
+ "integrity": "sha512-4nLnATuKupnmwqiJc27b4dCFmB/T60ExgmtDD7waf4LdrbJ8CPZzZRHYErDYNhoz+ql8fUdYwM/opf90PoPAQA==",
+ "license": "MIT",
+ "dependencies": {
+ "ip-address": "10.0.1"
+ },
+ "engines": {
+ "node": ">= 16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/express-rate-limit"
+ },
+ "peerDependencies": {
+ "express": ">= 4.11"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
+ "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "statuses": "2.0.1",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.9",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+ "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz",
+ "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==",
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "node_modules/ip-address": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.0.1.tgz",
+ "integrity": "sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/merge-descriptors": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
+ "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/path-to-regexp": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
+ "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ },
+ "node_modules/qs": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
+ "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
+ "dependencies": {
+ "side-channel": "^1.0.6"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+ "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "node_modules/send": {
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
+ "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/send/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ },
+ "node_modules/serve-static": {
+ "version": "1.16.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
+ "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
+ "dependencies": {
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.19.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ }
+ }
+}
diff --git a/boneset-api/package.json b/boneset-api/package.json
new file mode 100644
index 00000000..06265763
--- /dev/null
+++ b/boneset-api/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "boneset-api",
+ "version": "1.0.0",
+ "description": "",
+ "main": "index.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "axios": "^1.8.4",
+ "cors": "^2.8.5",
+ "dotenv": "^16.4.7",
+ "express": "^4.21.2",
+ "express-rate-limit": "^8.1.0"
+ }
+}
diff --git a/boneset-api/server.js b/boneset-api/server.js
new file mode 100644
index 00000000..d0505adc
--- /dev/null
+++ b/boneset-api/server.js
@@ -0,0 +1,247 @@
+// boneset-api/server.js
+const express = require("express");
+const axios = require("axios");
+const cors = require("cors");
+const rateLimit = require("express-rate-limit");
+
+const app = express();
+const PORT = process.env.PORT || 8000;
+
+app.use(cors());
+app.use(express.json());
+
+const GITHUB_REPO = "https://raw.githubusercontent.com/oss-slu/DigitalBonesBox/data/DataPelvis/";
+const BONESET_JSON_URL = `${GITHUB_REPO}boneset/bony_pelvis.json`;
+const BONES_DIR_URL = `${GITHUB_REPO}bones/`;
+
+// Rate limiter for search endpoint
+const searchLimiter = rateLimit({
+ windowMs: 60 * 1000,
+ max: 100,
+ standardHeaders: true,
+ legacyHeaders: false,
+});
+
+// Cache for search data
+let searchCache = null;
+
+// HTML escaping helper
+function escapeHtml(str = "") {
+ return String(str).replace(/[&<>"']/g, (c) => ({
+ "&": "&",
+ "<": "<",
+ ">": ">",
+ "\"": """,
+ "'": "'",
+ })[c]);
+}
+
+// GitHub JSON fetcher
+async function fetchJSON(url) {
+ try {
+ const response = await axios.get(url, { timeout: 10_000 });
+ return response.data;
+ } catch (error) {
+ console.error(`Failed to fetch ${url}:`, error.message);
+ return null;
+ }
+}
+
+// Initialize search cache at startup
+async function initializeSearchCache() {
+ try {
+ console.log("Initializing search cache...");
+ const bonesetData = await fetchJSON(BONESET_JSON_URL);
+ if (!bonesetData) {
+ console.error("Failed to load boneset data for search cache");
+ return;
+ }
+
+ const searchData = [];
+
+ // Add boneset to search data
+ searchData.push({
+ id: bonesetData.id,
+ name: bonesetData.name,
+ type: "boneset",
+ boneset: bonesetData.id,
+ bone: null,
+ subbone: null
+ });
+
+ // Load all bones and sub-bones
+ for (const boneId of bonesetData.bones || []) {
+ const boneData = await fetchJSON(`${BONES_DIR_URL}${boneId}.json`);
+ if (boneData) {
+ // Add bone to search data
+ searchData.push({
+ id: boneData.id,
+ name: boneData.name,
+ type: "bone",
+ boneset: bonesetData.id,
+ bone: boneData.id,
+ subbone: null
+ });
+
+ // Add sub-bones to search data
+ for (const subBoneId of boneData.subBones || []) {
+ const subBoneName = subBoneId.replace(/_/g, " ");
+ searchData.push({
+ id: subBoneId,
+ name: subBoneName,
+ type: "subbone",
+ boneset: bonesetData.id,
+ bone: boneData.id,
+ subbone: subBoneId
+ });
+ }
+ }
+ }
+
+ searchCache = searchData;
+ console.log(`Search cache initialized with ${searchData.length} items`);
+ } catch (error) {
+ console.error("Error initializing search cache:", error);
+ }
+}
+
+// Search function with ranking
+function searchItems(query, limit = 20) {
+ if (!searchCache) return [];
+
+ const q = query.toLowerCase().trim();
+ const results = [];
+
+ // First pass: prefix matches (higher priority)
+ for (const item of searchCache) {
+ if (item.name.toLowerCase().startsWith(q)) {
+ results.push({ ...item, priority: 1 });
+ }
+ }
+
+ // Second pass: substring matches (lower priority)
+ for (const item of searchCache) {
+ if (!item.name.toLowerCase().startsWith(q) && item.name.toLowerCase().includes(q)) {
+ results.push({ ...item, priority: 2 });
+ }
+ }
+
+ // Sort by priority, then by name
+ results.sort((a, b) => {
+ if (a.priority !== b.priority) return a.priority - b.priority;
+ return a.name.localeCompare(b.name);
+ });
+
+ return results.slice(0, limit);
+}
+
+// Routes
+app.get("/", (_req, res) => {
+ res.json({ message: "Welcome to the Boneset API" });
+});
+
+app.get("/combined-data", async (_req, res) => {
+ try {
+ const bonesetData = await fetchJSON(BONESET_JSON_URL);
+ if (!bonesetData) {
+ return res.status(500).json({ error: "Failed to load boneset data" });
+ }
+
+ const bonesets = [{ id: bonesetData.id, name: bonesetData.name }];
+ const bones = [];
+ const subbones = [];
+
+ for (const boneId of bonesetData.bones || []) {
+ const boneData = await fetchJSON(`${BONES_DIR_URL}${boneId}.json`);
+ if (boneData) {
+ bones.push({ id: boneData.id, name: boneData.name, boneset: bonesetData.id });
+ (boneData.subBones || []).forEach((subBoneId) => {
+ subbones.push({ id: subBoneId, name: subBoneId.replace(/_/g, " "), bone: boneData.id });
+ });
+ }
+ }
+
+ res.json({ bonesets, bones, subbones });
+ } catch (error) {
+ console.error("Error fetching combined data:", error.message);
+ res.status(500).json({ error: "Internal Server Error" });
+ }
+});
+
+app.get("/api/description/", async (req, res) => {
+ const { boneId } = req.query;
+ if (!boneId) {
+ return res.send(" ");
+ }
+
+ const GITHUB_DESC_URL = `https://raw.githubusercontent.com/oss-slu/DigitalBonesBox/data/DataPelvis/descriptions/${boneId}_description.json`;
+
+ try {
+ const response = await axios.get(GITHUB_DESC_URL);
+ const descriptionData = response.data;
+
+ let html = `
${escapeHtml(descriptionData.name)} `;
+ descriptionData.description.forEach(point => {
+ html += `${escapeHtml(point)} `;
+ });
+ res.send(html);
+ } catch (error) {
+ res.send("Description not available. ");
+ }
+});
+
+// Search endpoint
+app.get("/api/search", searchLimiter, (req, res) => {
+ const query = req.query.q;
+
+ console.log("Search request received for:", query);
+
+ // Handle empty or too short queries
+ if (!query || query.trim().length < 2) {
+ return res.send("Enter at least 2 characters to search ");
+ }
+
+ const searchTerm = query.trim();
+
+ try {
+ if (!searchCache) {
+ return res.send("Search not available - cache not initialized ");
+ }
+
+ const results = searchItems(searchTerm, 20);
+ console.log(`Found ${results.length} results for "${searchTerm}"`);
+
+ if (results.length === 0) {
+ return res.send("No results found ");
+ }
+
+ let html = "";
+ for (const result of results) {
+ const escapedName = escapeHtml(result.name);
+ const escapedType = escapeHtml(result.type);
+
+ html += `
+ ${escapedName} (${escapedType})
+ `;
+ }
+
+ res.send(html);
+ } catch (error) {
+ console.error("Search error:", error);
+ res.status(500).send("Search error occurred ");
+ }
+});
+
+// Initialize search cache on startup
+initializeSearchCache();
+
+app.listen(PORT, () => {
+ console.log(`🚀 Server running on http://127.0.0.1:${PORT}`);
+});
\ No newline at end of file
diff --git a/data_extraction/AutomatedExtractionScript.py b/data_extraction/AutomatedExtractionScript.py
new file mode 100644
index 00000000..35a5b8ad
--- /dev/null
+++ b/data_extraction/AutomatedExtractionScript.py
@@ -0,0 +1,124 @@
+import os
+import xml.etree.ElementTree as ET
+
+def extract_images_from_slide_xml(slide_xml_path, rels_xml_path, media_folder, output_folder):
+ """
+ Extracts images from a single slide XML file and renames them based on rId.
+
+ Args:
+ slide_xml_path (str): Path to the slide XML file.
+ rels_xml_path (str): Path to the relationships XML file for the slide.
+ media_folder (str): Path to the media folder containing images.
+ output_folder (str): Path to store extracted images.
+ """
+
+ try:
+ tree = ET.parse(slide_xml_path)
+ root = tree.getroot()
+ except ET.ParseError as e:
+ print(f"[ERROR] Failed to parse {slide_xml_path}: {e}")
+ return
+ except FileNotFoundError:
+ print(f"[ERROR] Slide file not found: {slide_xml_path}")
+ return
+
+ # Define XML namespaces
+ ns = {'a': 'http://schemas.openxmlformats.org/drawingml/2006/main',
+ 'r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'}
+
+ # Extract r:embed IDs that reference images
+ embed_ids = [blip.attrib.get(f"{{{ns['r']}}}embed") for blip in root.findall(".//a:blip", ns) if blip.attrib.get(f"{{{ns['r']}}}embed")]
+
+ if not embed_ids:
+ print(f"[INFO] No images found in {slide_xml_path}. Skipping...")
+ return
+
+ try:
+ rels_tree = ET.parse(rels_xml_path)
+ rels_root = rels_tree.getroot()
+ except ET.ParseError as e:
+ print(f"[ERROR] Failed to parse {rels_xml_path}: {e}")
+ return
+ except FileNotFoundError:
+ print(f"[ERROR] Relationship file not found: {rels_xml_path}")
+ return
+
+ # Extract XML namespace for relationships
+ rels_ns = rels_root.tag.split('}')[0] + '}' if '}' in rels_root.tag else ''
+
+ # Map rId to the actual image filename
+ relationships = {rel.attrib.get('Id', '').strip(): rel.attrib.get('Target', '').strip()
+ for rel in rels_root.findall(f".//{rels_ns}Relationship")}
+
+ # Extract slide number (e.g., "slide1" → 1)
+ slide_name = os.path.splitext(os.path.basename(slide_xml_path))[0] # "slide1"
+ slide_number = slide_name.replace("slide", "") # Extracts "1"
+
+ # Create output folder for slide images
+ slide_output_folder = os.path.join(output_folder, slide_name)
+ if not os.path.exists(slide_output_folder):
+ os.makedirs(slide_output_folder)
+
+ # Process each embedded image
+ for embed_id in embed_ids:
+ if embed_id in relationships:
+ target = relationships[embed_id]
+ image_path = os.path.join(media_folder, os.path.basename(target))
+
+ if os.path.exists(image_path):
+ # Extract image extension (e.g., ".png", ".jpg")
+ image_extension = os.path.splitext(target)[-1]
+
+ # New image name: "slide1_rId8.png"
+ new_image_name = f"slide{slide_number}_{embed_id}{image_extension}"
+ image_output_path = os.path.join(slide_output_folder, new_image_name)
+
+ # Copy and rename the image
+ try:
+ with open(image_path, 'rb') as img_in, open(image_output_path, 'wb') as img_out:
+ img_out.write(img_in.read())
+ print(f"[SUCCESS] Extracted: {image_output_path}")
+ except Exception as e:
+ print(f"[ERROR] Failed to copy image {image_path}: {e}")
+ else:
+ print(f"[WARNING] Image file not found: {image_path} (Referenced in {rels_xml_path})")
+ else:
+ print(f"[WARNING] No relationship found for embed ID: {embed_id} (Referenced in {slide_xml_path})")
+
+def process_pptx_folders(slides_folder, rels_folder, media_folder, output_folder):
+ """
+ Processes all slides in the PowerPoint file and extracts images from each slide.
+
+ Args:
+ slides_folder (str): Path to the folder containing slide XML files.
+ rels_folder (str): Path to the folder containing relationships XML files.
+ media_folder (str): Path to the media folder containing images.
+ output_folder (str): Path to store extracted images.
+ """
+
+ if not os.path.exists(output_folder):
+ os.makedirs(output_folder)
+
+ for slide_file in sorted(os.listdir(slides_folder)):
+ if slide_file.startswith("slide") and slide_file.endswith(".xml"):
+ slide_path = os.path.join(slides_folder, slide_file)
+ rels_path = os.path.join(rels_folder, slide_file + ".rels")
+
+ if os.path.exists(rels_path):
+ extract_images_from_slide_xml(slide_path, rels_path, media_folder, output_folder)
+ else:
+ print(f"[WARNING] Missing relationship file: {rels_path}. Skipping slide {slide_file}.")
+
+if __name__ == "__main__":
+ """
+ Main execution block:
+ - Defines necessary folder paths.
+ - Calls process_pptx_folders() to extract images from all slides.
+ """
+
+ slides_folder = "/Users/burhankhan/Desktop/ppt/slides"
+ rels_folder = "/Users/burhankhan/Desktop/ppt/slides/_rels"
+ media_folder = "/Users/burhankhan/Desktop/ppt/media"
+ output_folder = "/Users/burhankhan/Desktop/AutomatedScript"
+
+ process_pptx_folders(slides_folder, rels_folder, media_folder, output_folder)
diff --git a/data_extraction/Extract_Bone_Descriptions.py b/data_extraction/Extract_Bone_Descriptions.py
new file mode 100644
index 00000000..cc0c1eed
--- /dev/null
+++ b/data_extraction/Extract_Bone_Descriptions.py
@@ -0,0 +1,52 @@
+import xml.etree.ElementTree as ET
+import json
+import os
+
+def parse_slide_xml(xml_file, output_json_path):
+ tree = ET.parse(xml_file)
+ root = tree.getroot()
+
+ ns = {
+ 'p': 'http://schemas.openxmlformats.org/presentationml/2006/main',
+ 'a': 'http://schemas.openxmlformats.org/drawingml/2006/main'
+ }
+
+ descriptions = []
+ bone_name = "Unknown"
+
+ for sp in root.findall(".//p:sp", ns):
+ xfrm = sp.find(".//a:xfrm", ns)
+ if xfrm is not None:
+ pos = xfrm.find("a:off", ns)
+ size = xfrm.find("a:ext", ns)
+
+ if pos is not None and size is not None:
+ x, y = int(pos.attrib.get("x", 0)), int(pos.attrib.get("y", 0))
+ width, height = int(size.attrib.get("cx", 0)), int(size.attrib.get("cy", 0))
+
+ # Range in which the descriptions are held
+ if x > 8011000 and y > 3000000:
+ text_elements = sp.findall(".//a:t", ns)
+ bullet_points = [t.text for t in text_elements if t.text and t.text != 'No Labels']
+
+ if bullet_points:
+ if bone_name == "Unknown":
+ bone_name = bullet_points[0] # Assign first extracted text as the bone name
+ bullet_points = bullet_points[1:] # Remove name from descriptions
+ descriptions.extend(bullet_points)
+
+ bone_data = {
+ "name": bone_name,
+ "id": bone_name.lower().replace(" ", "_"), # Generate an ID from the name
+ "description": descriptions
+ }
+
+ with open(output_json_path, 'w') as f:
+ json.dump(bone_data, f, indent=4)
+
+ print(f"Descriptions saved to {output_json_path}")
+
+# Example usage
+xml_file = "/Users/joshbudzynski/Downloads/example_folder/ppt/slides/slide3.xml"
+output_json = "slide3_Descriptions.json"
+parse_slide_xml(xml_file, output_json)
diff --git a/data_extraction/__pycache__/api.cpython-310.pyc b/data_extraction/__pycache__/api.cpython-310.pyc
new file mode 100644
index 00000000..74bb369b
Binary files /dev/null and b/data_extraction/__pycache__/api.cpython-310.pyc differ
diff --git a/data_extraction/extract_ppt_annotations.py b/data_extraction/extract_ppt_annotations.py
new file mode 100644
index 00000000..430a036c
--- /dev/null
+++ b/data_extraction/extract_ppt_annotations.py
@@ -0,0 +1,189 @@
+import os
+import xml.etree.ElementTree as ET
+import json
+
+
+def load_bone_data(json_directory):
+ """
+ Loads known bonesets, bones, and sub-bones from JSON files into dictionaries.
+ """
+ categories = ["bonesets", "bones", "subbones"]
+ bone_data = {category: set() for category in categories} # Store names for fast lookup
+
+ for category in categories:
+ json_path = os.path.join(json_directory, f"{category}.json")
+ if os.path.exists(json_path):
+ with open(json_path, 'r') as file:
+ try:
+ data = json.load(file)
+ if isinstance(data, list):
+ bone_data[category].update({entry.lower().replace(" ", "_") for entry in data})
+ except json.JSONDecodeError as e:
+ print(f"[ERROR] Could not load {category}.json: {e}")
+
+ return bone_data
+
+
+def generate_annotation_link(text, bone_data):
+ """
+ Generate a hyperlink for an annotation based on its category (boneset, bone, or subbone).
+ """
+ text_key = text.lower().replace(" ", "_") # Normalize text
+
+ # Check for boneset, bone, or subbone match
+ if text_key in bone_data['bonesets']:
+ return f"/data/json/bonesets/{text_key}.json"
+ elif text_key in bone_data['bones']:
+ return f"/data/json/bones/{text_key}.json"
+ elif text_key in bone_data['subbones']:
+ return f"/data/json/subbones/{text_key}.json"
+
+ return None # No link if not found
+
+
+def extract_images_from_slide_xml(slide_xml_path, rels_xml_path, media_folder, output_folder, json_output, bone_data):
+ """
+ Extract images from a slide XML, rename them, and write image details to a JSON file.
+ """
+ try:
+ tree = ET.parse(slide_xml_path)
+ root = tree.getroot()
+ except (ET.ParseError, FileNotFoundError) as e:
+ print(f"[ERROR] Failed to parse {slide_xml_path}: {e}")
+ return
+
+ ns = {'a': 'http://schemas.openxmlformats.org/drawingml/2006/main',
+ 'r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'}
+
+ # Extract image IDs from the slide XML
+ embed_ids = [blip.attrib.get(f"{{{ns['r']}}}embed") for blip in root.findall(".//a:blip", ns) if blip.attrib.get(f"{{{ns['r']}}}embed")]
+
+ if not embed_ids:
+ print(f"[INFO] No images found in {slide_xml_path}. Skipping...")
+ return
+
+ try:
+ rels_tree = ET.parse(rels_xml_path)
+ rels_root = rels_tree.getroot()
+ except (ET.ParseError, FileNotFoundError) as e:
+ print(f"[ERROR] Failed to parse {rels_xml_path}: {e}")
+ return
+
+ # Namespace for relationships
+ rels_ns = rels_root.tag.split('}')[0] + '}' if '}' in rels_root.tag else ''
+
+ # Map rId to actual image path
+ relationships = {rel.attrib.get('Id', '').strip(): rel.attrib.get('Target', '').strip()
+ for rel in rels_root.findall(f".//{rels_ns}Relationship")}
+
+ # Extract slide number and set up output folder
+ slide_name = os.path.splitext(os.path.basename(slide_xml_path))[0]
+ slide_number = slide_name.replace("slide", "")
+ slide_output_folder = os.path.join(output_folder, slide_name)
+ os.makedirs(slide_output_folder, exist_ok=True)
+
+ # JSON structure for image and annotation details
+ slide_data = {
+ "slide": slide_name,
+ "images": [],
+ "annotations": []
+ }
+
+ # Extract and rename images
+ for embed_id in embed_ids:
+ if embed_id in relationships:
+ target = relationships[embed_id]
+ image_path = os.path.join(media_folder, os.path.basename(target))
+
+ if os.path.exists(image_path):
+ image_extension = os.path.splitext(target)[-1]
+ new_image_name = f"slide{slide_number}_{embed_id}{image_extension}"
+ image_output_path = os.path.join(slide_output_folder, new_image_name)
+
+ try:
+ with open(image_path, 'rb') as img_in, open(image_output_path, 'wb') as img_out:
+ img_out.write(img_in.read())
+
+ print(f"[SUCCESS] Extracted: {image_output_path}")
+
+ # Add image metadata to JSON (Simplified)
+ slide_data["images"].append({
+ "rId": embed_id,
+ "extracted_name": new_image_name
+ })
+ except Exception as e:
+ print(f"[ERROR] Failed to copy image {image_path}: {e}")
+ else:
+ print(f"[WARNING] Image not found: {image_path}")
+
+ # Extract annotations from slide XML
+ ns_p = {'p': 'http://schemas.openxmlformats.org/presentationml/2006/main',
+ 'a': 'http://schemas.openxmlformats.org/drawingml/2006/main'}
+ middle_x_min, middle_x_max = 2000000, 6000000
+ middle_y_min, middle_y_max = 1000000, 7000000
+
+ for sp in root.findall(".//p:sp", ns_p):
+ annotation = {}
+ text_elements = sp.findall(".//a:t", ns_p)
+ text = ''.join([t.text for t in text_elements if t.text])
+
+ xfrm = sp.find(".//a:xfrm", ns_p)
+ if xfrm is not None:
+ pos = xfrm.find("a:off", ns_p)
+ size = xfrm.find("a:ext", ns_p)
+ if pos is not None and size is not None:
+ x, y = int(pos.attrib.get("x", 0)), int(pos.attrib.get("y", 0))
+ width, height = int(size.attrib.get("cx", 0)), int(size.attrib.get("cy", 0))
+
+ if middle_x_min <= x <= middle_x_max and middle_y_min <= y <= middle_y_max:
+ annotation["text"] = text
+ annotation["position"] = {"x": x, "y": y, "width": width, "height": height}
+
+ # Use the updated function to generate the correct link
+ if text:
+ annotation["link"] = generate_annotation_link(text, bone_data)
+
+ slide_data["annotations"].append(annotation)
+
+ # Write JSON file for the slide
+ json_output_path = os.path.join(json_output, f"{slide_name}_annotations.json")
+ os.makedirs(json_output, exist_ok=True)
+
+ with open(json_output_path, 'w') as json_file:
+ json.dump(slide_data, json_file, indent=4)
+
+ print(f"[SUCCESS] JSON saved: {json_output_path}")
+
+
+def process_pptx_folders(slides_folder, rels_folder, media_folder, output_folder, json_output, json_directory):
+ """
+ Processes all slides, extracts images, annotations, and writes JSON files.
+ """
+ os.makedirs(output_folder, exist_ok=True)
+ os.makedirs(json_output, exist_ok=True)
+
+ # Load bone data dynamically
+ bone_data = load_bone_data(json_directory)
+
+ for slide_file in sorted(os.listdir(slides_folder)):
+ if slide_file.startswith("slide") and slide_file.endswith(".xml"):
+ slide_path = os.path.join(slides_folder, slide_file)
+ rels_path = os.path.join(rels_folder, slide_file + ".rels")
+
+ if os.path.exists(rels_path):
+ extract_images_from_slide_xml(slide_path, rels_path, media_folder, output_folder, json_output, bone_data)
+ else:
+ print(f"[WARNING] Missing relationship file: {rels_path}. Skipping {slide_file}.")
+
+
+if __name__ == "__main__":
+ # Folder paths (replace with your paths)
+ slides_folder = "/Users/joshbudzynski/Downloads/example_folder/ppt/slides"
+ rels_folder = "/Users/joshbudzynski/Downloads/example_folder/ppt/slides/_rels"
+ media_folder = "/Users/joshbudzynski/Downloads/example_folder/ppt/media"
+ output_folder = "/Users/joshbudzynski/Downloads/example_folder/ppt/AutomatedScript"
+ json_output = "/Users/joshbudzynski/Downloads/example_folder/ppt/json_output"
+ json_directory = "/Users/joshbudzynski/Downloads/example_folder/ppt/data/json"
+
+ # Run the process for all slides
+ process_pptx_folders(slides_folder, rels_folder, media_folder, output_folder, json_output, json_directory)
diff --git a/data_extraction/scripts/README_bony_pelvis_rotation.md b/data_extraction/scripts/README_bony_pelvis_rotation.md
new file mode 100644
index 00000000..e0cf76de
--- /dev/null
+++ b/data_extraction/scripts/README_bony_pelvis_rotation.md
@@ -0,0 +1,85 @@
+### Purpose:
+
+Parses PowerPoint slide XML to:
+
+derive a normalized two-image template (left/right bounds, rotation, flips) from a representative slide,
+
+extract per-slide media rIds and (optionally) resolve them to media file paths via .rels,
+
+optionally audit each slide to see whether its two main images match the template within a tolerance.
+
+⚠️ Designed for slides that have two main pictures (side-by-side). One-image slides will fail the audit with reason: "fewer-than-two-pics".
+
+### Expected inputs:
+
+--slides-dir: directory containing slideN.xml
+
+--rels-dir (optional): directory containing slideN.xml.rels
+
+Representative slide number with the desired geometry (defaults to 2)
+
+### Outputs:
+
+--out-template (JSON): normalized geometry for left/right images
+(template_bony_pelvis.json)
+
+--out-metadata (JSON): list of slides with media rIds, and if --rels-dir is provided, resolved media targets/paths (bony_pelvis_metadata.json)
+
+When --audit is set: an "audit" block with tolerance, verified_slides, and failed_slides.
+
+### Key options:
+
+--slides: list of slide numbers to process (default: 2 3)
+
+--representative: slide to build the template from (default: 2)
+
+--audit: run audit and include results in metadata output
+
+--tolerance: numeric tolerance for normalized geometry comparisons (default: 0.02)
+
+--min-area: minimum area fraction to consider a picture “main” (default: 0.05)
+
+### Quickstart:
+
+# 1) Create template + metadata (no audit)
+python3 data_extraction/scripts/bony_pelvis_rotation.py \
+ --slides-dir data_extraction/fixtures/slides \
+ --rels-dir data_extraction/fixtures/rels \
+ --slides 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
+ --representative 2 \
+ --out-template data_extraction/annotations/template_bony_pelvis.json \
+ --out-metadata data_extraction/annotations/bony_pelvis_metadata.json
+
+# 2) With audit (recommended before committing)
+python3 data_extraction/scripts/bony_pelvis_rotation.py \
+ --slides-dir data_extraction/fixtures/slides \
+ --rels-dir data_extraction/fixtures/rels \
+ --slides 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
+ --out-metadata data_extraction/annotations/bony_pelvis_metadata.json \
+ --audit --tolerance 0.02
+
+### Interpreting the audit:
+
+verified_slides: slides whose two main images match the template within --tolerance
+
+failed_slides: slides that differ; failure keys like left.normY, right.normH, or left.rot_deg
+
+reason: "fewer-than-two-pics": the slide doesn’t have two “main” pictures (common for single-image slides)
+
+### Handling one-image slides:
+
+This script can’t produce a side-by-side match for single-image slides. You can either:
+
+Exclude them from --slides when auditing, or
+
+Keep them listed but expect fewer-than-two-pics in audit results.
+(Downstream apps should treat these as single-image layouts.)
+
+### File structure example:
+data_extraction/
+ fixtures/
+ slides/ slide2.xml ... slide20.xml
+ rels/ slide2.xml.rels ... slide20.xml.rels
+ annotations/
+ template_bony_pelvis.json
+ bony_pelvis_metadata.json
diff --git a/data_extraction/scripts/README_bony_pelvis_text_labels.md b/data_extraction/scripts/README_bony_pelvis_text_labels.md
new file mode 100644
index 00000000..1d821a79
--- /dev/null
+++ b/data_extraction/scripts/README_bony_pelvis_text_labels.md
@@ -0,0 +1,93 @@
+### Purpose:
+
+Extracts white text labels and the white leader lines/connector lines that point from labels into the image on a given slide. Outputs one JSON per slide containing:
+
+- label text
+
+- text box position/size/rotation (in EMUs)
+
+- any hyperlinks on the label (and their target slide, if present)
+
+- line geometry for the connected pointer/connector shapes
+
+- deduplicated target regions (endpoints of the connected graph) the label points to
+
+Uses a small graph walk from any line endpoints that touch the label’s text box (with padding), then collects terminal endpoints outside the box.
+
+### Expected inputs:
+
+--slides-dir: directory containing slideN.xml
+
+--rels-dir: directory containing slideN.xml.rels
+
+--slide: the slide number to process
+
+### Outputs:
+
+--out: path to write JSON. If not provided, writes
+data_extraction/annotations/slide{N}_text_annotations.json.
+
+Each JSON contains:
+
+{
+ "slide_number": 9,
+ "text_annotations": [
+ {
+ "annotation_id": "annot_1",
+ "bone_name": "Bony Pelvis",
+ "subbone_name": "Ischial spine",
+ "text_box": { "x": ..., "y": ..., "width": ..., "height": ..., "rotation_emu": ... },
+ "has_hyperlink": true,
+ "hyperlink": { "rId": "rId8", "target": "/ppt/slides/slide10.xml", "target_slide": 10 },
+ "pointer_lines": [ { "kind": "connector", "start_point": {...}, "end_point": {...}, ... } ],
+ "target_regions": [ { "x": ..., "y": ... }, ... ]
+ }
+ ],
+ "total_text_annotations": 3,
+ "config": { "padding_emu": 4000.0, "snap_emu": 8000.0 }
+}
+
+### How it works (brief):
+
+Detect labels: White-filled text (either srgbClr #FFFFFF or scheme colors lt1/bg1).
+
+Detect lines: White-stroke p:cxnSp connectors and simple p:sp lines.
+
+Graph follow: Build a snapped endpoint graph, start from nodes that lie within the label’s padded box, traverse connected edges, and collect terminal nodes outside the label as candidate target regions.
+
+# Key options:
+
+--padding (default 4000 EMU): padding around the text box to consider endpoints “touching” the label.
+
+--snap (default 8000 EMU): snap size for coalescing nearly identical line junctions.
+
+### Quickstart:
+
+# Example: dump slide 9 labels/lines to default path
+python3 data_extraction/scripts/bony_pelvis_text_labels.py \
+ --slides-dir data_extraction/fixtures/slides \
+ --rels-dir data_extraction/fixtures/rels \
+ --slide 9
+
+# Write to a custom file (e.g., renamed convention)
+python3 data_extraction/scripts/bony_pelvis_text_labels.py \
+ --slides-dir data_extraction/fixtures/slides \
+ --rels-dir data_extraction/fixtures/rels \
+ --slide 9 \
+ --out DataPelvis/annotations/slide09_ischium_text_labels.json
+
+#### Notes & tips:
+
+Only white labels/lines are considered—keep that styling consistent in PPT.
+
+If a label has no connected white lines, pointer_lines can be empty and target_regions may be [].
+
+Hyperlinks on either the shape’s cNvPr or text runs are captured when present in .rels.
+
+Common troubleshooting
+
+“No labels found”: ensure label text is actually white and not an inherited theme color that resolves to non-white.
+
+Too many target points: reduce --padding and/or increase --snap so endpoints near the label consolidate better.
+
+Missing hyperlink target_slide: requires a valid rId in the label and a matching entry in slideN.xml.rels.
\ No newline at end of file
diff --git a/data_extraction/scripts/bony_pelvis_rotation.py b/data_extraction/scripts/bony_pelvis_rotation.py
new file mode 100644
index 00000000..72382794
--- /dev/null
+++ b/data_extraction/scripts/bony_pelvis_rotation.py
@@ -0,0 +1,211 @@
+import argparse, json, os, re
+import xml.etree.ElementTree as ET
+
+NS = {
+ "p": "http://schemas.openxmlformats.org/presentationml/2006/main",
+ "a": "http://schemas.openxmlformats.org/drawingml/2006/main",
+ "r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
+}
+PKG_REL_NS = "http://schemas.openxmlformats.org/package/2006/relationships"
+
+EMU_PER_DEG = 60000.0
+_SLIDE_NUM_RE = re.compile(r"(\d+)")
+
+def _num(el, attr, default=0.0):
+ try: return float(el.get(attr))
+ except Exception: return default
+
+def _slide_num(path):
+ m = _SLIDE_NUM_RE.search(os.path.splitext(os.path.basename(path))[0])
+ return int(m.group(1)) if m else None
+
+def two_largest_pics(root, min_area_frac=0.05):
+ pics = []
+ for pic in root.findall(".//p:pic", NS):
+ xfrm = pic.find(".//a:xfrm", NS)
+ if xfrm is None:
+ continue
+ off, ext = xfrm.find("a:off", NS), xfrm.find("a:ext", NS)
+ if off is None or ext is None:
+ continue
+ x, y = _num(off, "x"), _num(off, "y")
+ cx, cy = _num(ext, "cx"), _num(ext, "cy")
+ area = cx * cy
+ blip = pic.find(".//a:blip", NS)
+ embed = blip.get("{%s}embed" % NS["r"]) if blip is not None else None
+ rot_emu = _num(xfrm, "rot", 0.0)
+ pics.append({
+ "x": x, "y": y, "cx": cx, "cy": cy, "area": area,
+ "rot_emu": rot_emu,
+ "rot_deg": rot_emu / EMU_PER_DEG,
+ "flipH": (xfrm.get("flipH") == "1"),
+ "flipV": (xfrm.get("flipV") == "1"),
+ "embed": embed
+ })
+ pics.sort(key=lambda d: d["area"], reverse=True)
+ if not pics:
+ return []
+ thr = pics[0]["area"] * float(min_area_frac or 0.0)
+ filtered = [p for p in pics if p["area"] >= thr]
+ return (filtered[:2] if len(filtered) >= 2 else pics[:2])
+
+def _bbox(a, b):
+ x1, y1 = min(a["x"], b["x"]), min(a["y"], b["y"])
+ x2, y2 = max(a["x"]+a["cx"], b["x"]+b["cx"]), max(a["y"]+a["cy"], b["y"]+b["cy"])
+ return {"x": x1, "y": y1, "w": (x2-x1), "h": (y2-y1)}
+
+def _norm(item, box):
+ w, h = (box["w"] or 1.0), (box["h"] or 1.0)
+ return {
+ "normX": (item["x"]-box["x"])/w, "normY": (item["y"]-box["y"])/h,
+ "normW": item["cx"]/w, "normH": item["cy"]/h
+ }
+
+def compute_template(slide_path, min_area_frac):
+ root = ET.parse(slide_path).getroot()
+ top2 = two_largest_pics(root, min_area_frac)
+ if len(top2) < 2:
+ raise SystemExit("Template slide must contain two main pictures.")
+ left, right = sorted(top2, key=lambda d: d["x"])
+ box = _bbox(left, right)
+ return {
+ "layout": "side-by-side",
+ "left": {
+ **_norm(left, box),
+ "rot_deg": left["rot_deg"],
+ "rot_emu": left["rot_emu"],
+ "flipH": left["flipH"], "flipV": left["flipV"]
+ },
+ "right": {
+ **_norm(right, box),
+ "rot_deg": right["rot_deg"],
+ "rot_emu": right["rot_emu"],
+ "flipH": right["flipH"], "flipV": right["flipV"]
+ },
+ "norm_basis": "two-image-union"
+ }
+
+def extract_slide_metadata(slide_path, bone_set, min_area_frac):
+ root = ET.parse(slide_path).getroot()
+ top2 = two_largest_pics(root, min_area_frac)
+ if len(top2) < 2:
+ return None
+ left, right = sorted(top2, key=lambda d: d["x"])
+ return {
+ "slide": _slide_num(slide_path),
+ "bone_set": bone_set,
+ "left_media": left["embed"],
+ "right_media": right["embed"],
+ "subbone": None, "sub_subbone": None
+ }
+
+def _close(a, b, tol):
+ return abs(a-b) <= tol
+
+def audit_slide(slide_path, template, tol, min_area_frac):
+ root = ET.parse(slide_path).getroot()
+ top2 = two_largest_pics(root, min_area_frac)
+ if len(top2) < 2:
+ return {"slide": _slide_num(slide_path), "ok": False, "reason": "fewer-than-two-pics"}
+ left, right = sorted(top2, key=lambda d: d["x"])
+ box = _bbox(left, right)
+ L = {**_norm(left, box), "rot_deg": left["rot_deg"]}
+ R = {**_norm(right, box), "rot_deg": right["rot_deg"]}
+ fails = []
+ for side, got, want in (("left", L, template["left"]), ("right", R, template["right"])):
+ for k in ("normX","normY","normW","normH"):
+ if not _close(got[k], want[k], tol):
+ fails.append(f"{side}.{k}")
+ if not _close(got["rot_deg"], want["rot_deg"], tol*10):
+ fails.append(f"{side}.rot_deg")
+ return {"slide": _slide_num(slide_path), "ok": not fails, "fails": fails}
+
+# ---- rId -> filename/path resolver (optional via --rels-dir) ----
+
+def _read_rels_map(rels_path):
+ if not os.path.exists(rels_path):
+ return {}
+ root = ET.parse(rels_path).getroot()
+ out = {}
+ for rel in root.findall(f".//{{{PKG_REL_NS}}}Relationship"):
+ rid = rel.attrib.get("Id")
+ if rid:
+ out[rid] = {"Type": rel.attrib.get("Type",""), "Target": rel.attrib.get("Target","")}
+ return out
+
+def resolve_media_path(slides_dir, rels_dir, slide_num, rid):
+ rels_path = os.path.join(rels_dir, f"slide{slide_num}.xml.rels")
+ rels = _read_rels_map(rels_path)
+ info = rels.get(rid)
+ if not info or not info.get("Target"):
+ return {"target": "", "path": ""}
+ target = info["Target"]
+ fs_path = os.path.normpath(os.path.join(slides_dir, target))
+ return {"target": target, "path": fs_path}
+
+def main():
+ ap = argparse.ArgumentParser()
+ ap.add_argument("--slides-dir", required=True)
+ ap.add_argument("--rels-dir", required=False, default=None, help="Directory of slideN.xml.rels (optional)")
+ ap.add_argument("--slides", type=int, nargs="+", default=[2,3])
+ ap.add_argument("--representative", type=int, default=2)
+ ap.add_argument("--out-template", default="data_extraction/annotations/template_bony_pelvis.json")
+ ap.add_argument("--out-metadata", default="data_extraction/annotations/bony_pelvis_metadata.json")
+ ap.add_argument("--audit", action="store_true")
+ ap.add_argument("--tolerance", type=float, default=0.02)
+ ap.add_argument("--min-area", type=float, default=0.05)
+ args = ap.parse_args()
+
+ rep_path = os.path.join(args.slides_dir, f"slide{args.representative}.xml")
+ if not os.path.exists(rep_path):
+ raise SystemExit(f"Missing representative slide: {rep_path}")
+
+ template = compute_template(rep_path, args.min_area)
+
+ tpl_dir = os.path.dirname(args.out_template)
+ if tpl_dir:
+ os.makedirs(tpl_dir, exist_ok=True)
+ with open(args.out_template, "w") as f:
+ json.dump({
+ "bone_set": "Bony Pelvis",
+ "display_format": "side-by-side",
+ "extracted_from_slide": args.representative,
+ "normalized_geometry": template
+ }, f, indent=2)
+
+ metadata, verified, failures = [], [], []
+ for n in args.slides:
+ path = os.path.join(args.slides_dir, f"slide{n}.xml")
+ if not os.path.exists(path):
+ continue
+ md = extract_slide_metadata(path, "Bony Pelvis", args.min_area)
+ if md:
+ # enrich with media targets/paths if rels-dir provided
+ if args.rels_dir:
+ left = resolve_media_path(args.slides_dir, args.rels_dir, n, md["left_media"])
+ right = resolve_media_path(args.slides_dir, args.rels_dir, n, md["right_media"])
+ md["left_media_target"] = left["target"]
+ md["right_media_target"] = right["target"]
+ md["left_media_path"] = left["path"]
+ md["right_media_path"] = right["path"]
+ metadata.append(md)
+ if args.audit:
+ res = audit_slide(path, template, args.tolerance, args.min_area)
+ (verified if res["ok"] else failures).append(res)
+
+ os.makedirs(os.path.dirname(args.out_metadata) or ".", exist_ok=True)
+ out = {"slides": metadata}
+ if args.audit:
+ out["audit"] = {
+ "tolerance": args.tolerance,
+ "verified_slides": [v["slide"] for v in verified],
+ "failed_slides": failures
+ }
+ with open(args.out_metadata, "w") as f:
+ json.dump(out, f, indent=2)
+
+ print(f"template -> {args.out_template}")
+ print(f"metadata -> {args.out_metadata}")
+
+if __name__ == "__main__":
+ main()
\ No newline at end of file
diff --git a/data_extraction/scripts/bony_pelvis_text_labels.py b/data_extraction/scripts/bony_pelvis_text_labels.py
new file mode 100644
index 00000000..2718eb4b
--- /dev/null
+++ b/data_extraction/scripts/bony_pelvis_text_labels.py
@@ -0,0 +1,262 @@
+import argparse, json, os, re, math
+import xml.etree.ElementTree as ET
+
+NS = {
+ "p": "http://schemas.openxmlformats.org/presentationml/2006/main",
+ "a": "http://schemas.openxmlformats.org/drawingml/2006/main",
+ "r": "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
+}
+PKG_REL_NS = "http://schemas.openxmlformats.org/package/2006/relationships"
+R_ID_KEY = "{%s}id" % NS["r"]
+
+# --------------------------- helpers ---------------------------
+
+def emu_box(xfrm):
+ off = xfrm.find("a:off", NS); ext = xfrm.find("a:ext", NS)
+ x = float(off.get("x")); y = float(off.get("y"))
+ w = float(ext.get("cx")); h = float(ext.get("cy"))
+ rot_emu = float(xfrm.get("rot") or 0.0)
+ return {"x": x, "y": y, "width": w, "height": h, "rotation_emu": rot_emu}
+
+def is_white_color(solid_fill):
+ if solid_fill is None: return False
+ srgb = solid_fill.find("a:srgbClr", NS)
+ if srgb is not None: return srgb.get("val","").upper() == "FFFFFF"
+ scheme = solid_fill.find("a:schemeClr", NS)
+ return scheme is not None and scheme.get("val") in ("lt1","bg1")
+
+def text_is_white(sp):
+ for rpr in sp.findall(".//a:rPr", NS):
+ if is_white_color(rpr.find("a:solidFill", NS)):
+ return True
+ return False
+
+def line_is_white(shape):
+ ln = shape.find(".//a:ln", NS)
+ return is_white_color(ln.find("a:solidFill", NS)) if ln is not None else False
+
+def build_rels_map(rels_path):
+ m = {}
+ if not os.path.exists(rels_path): return m
+ root = ET.parse(rels_path).getroot()
+ for rel in root.findall(f".//{{{PKG_REL_NS}}}Relationship"):
+ rid = rel.attrib.get("Id")
+ if rid:
+ m[rid] = {"Type": rel.attrib.get("Type",""), "Target": rel.attrib.get("Target","")}
+ return m
+
+def _link_payload(rid, rels_map):
+ info = {"rId": rid, "target": (rels_map.get(rid) or {}).get("Target","")}
+ m = re.search(r"slide(\d+)\.xml", info["target"])
+ if m: info["target_slide"] = int(m.group(1))
+ return info
+
+def resolve_hyperlink_for_shape(shape_el, rels_map):
+ cNvPr = shape_el.find("./p:nvSpPr/p:cNvPr", NS)
+ if cNvPr is not None:
+ hl = cNvPr.find("a:hlinkClick", NS)
+ if hl is not None and R_ID_KEY in hl.attrib:
+ return _link_payload(hl.attrib[R_ID_KEY], rels_map)
+ for rPr in shape_el.findall(".//a:rPr", NS):
+ hl = rPr.find("a:hlinkClick", NS)
+ if hl is not None and R_ID_KEY in hl.attrib:
+ return _link_payload(hl.attrib[R_ID_KEY], rels_map)
+ return None
+
+def rect_contains_with_padding(rect, x, y, pad):
+ return (rect["x"]-pad <= x <= rect["x"]+rect["width"]+pad and
+ rect["y"]-pad <= y <= rect["y"]+rect["height"]+pad)
+
+def snap_point(pt, snap):
+ return (round(pt[0]/snap)*snap, round(pt[1]/snap)*snap)
+
+def rot_cos_sin(emu):
+ # 60000 EMUs = 1 degree
+ ang = (emu/60000.0) * math.pi/180.0
+ return math.cos(ang), math.sin(ang)
+
+# Given a line's a:xfrm box, compute **true endpoints** accounting for rotation.
+def endpoints_from_xfrm(xfrm):
+ box = emu_box(xfrm)
+ cx, cy = box["width"]/2.0, box["height"]/2.0
+ cx0, cy0 = box["x"] + cx, box["y"] + cy # center
+ c, s = rot_cos_sin(box["rotation_emu"])
+ # vector from center to corner of bbox (cx,cy) rotated; endpoints are +/- that vector
+ vx, vy = (c*cx - s*cy), (s*cx + c*cy)
+ p1 = (cx0 - vx, cy0 - vy)
+ p2 = (cx0 + vx, cy0 + vy)
+ return p1, p2, box
+
+# ---------------------- extraction: texts ----------------------
+
+def extract_text_boxes(root, rels_map, bone_set="Bony Pelvis"):
+ out = []
+ for sp in root.findall(".//p:sp", NS):
+ if sp.find(".//p:txBody", NS) is None:
+ continue
+ if not text_is_white(sp):
+ continue
+ xfrm = sp.find(".//a:xfrm", NS)
+ if xfrm is None:
+ continue
+ text = "".join(t.text or "" for t in sp.findall(".//a:t", NS)).strip()
+ if not text:
+ continue
+ hyperlink = resolve_hyperlink_for_shape(sp, rels_map)
+ cNv = sp.find("./p:nvSpPr/p:cNvPr", NS)
+ out.append({
+ "annotation_id": f"annot_{len(out)+1}",
+ "bone_name": bone_set,
+ "subbone_name": text,
+ "text_content": text,
+ "text_box": emu_box(xfrm) | {"shape_id": cNv.get("id") if cNv is not None else None},
+ "has_hyperlink": hyperlink is not None,
+ "hyperlink": hyperlink or {}
+ })
+ return out
+
+# ---------------------- extraction: lines ----------------------
+
+def _collect_line_shape(shp, kind, lines):
+ if not line_is_white(shp):
+ return
+ xfrm = shp.find(".//a:xfrm", NS)
+ if xfrm is None:
+ return
+ p1, p2, box = endpoints_from_xfrm(xfrm)
+ ln = shp.find(".//a:ln", NS)
+ width = int(ln.get("w") or 0) if ln is not None else 0
+ head = ln.find("a:headEnd", NS) if ln is not None else None
+ cNv = shp.find(f"./p:nv{'CxnSp' if kind=='connector' else 'Sp'}Pr/p:cNvPr", NS)
+ lines.append({
+ "line_id": f"line_{len(lines)+1}",
+ "kind": kind,
+ "start_point": {"x": p1[0], "y": p1[1]},
+ "end_point": {"x": p2[0], "y": p2[1]},
+ "style": {"width": width, "arrow_head": (head.get("type") if head is not None else "none")},
+ "shape_id": cNv.get("id") if cNv is not None else None,
+ "bbox": box
+ })
+
+def extract_lines(root):
+ lines = []
+ for shp in root.findall(".//p:cxnSp", NS): # connectors
+ _collect_line_shape(shp, "connector", lines)
+ # simple line shapes (p:sp with no text, but with stroke)
+ for shp in root.findall(".//p:sp", NS):
+ if shp.find(".//p:txBody", NS) is None and shp.find(".//a:ln", NS) is not None:
+ _collect_line_shape(shp, "line", lines)
+ return lines
+
+# -------------------- graph + connection logic --------------------
+
+def build_graph(lines, snap):
+ nodes = {} # snapped point -> index
+ deg = {} # degree per node
+ edges = [] # (u, v, line_obj)
+ def add_node(pt):
+ key = snap_point(pt, snap)
+ if key not in nodes:
+ nodes[key] = len(nodes)
+ deg[nodes[key]] = 0
+ return nodes[key], key
+ for ln in lines:
+ u, uk = add_node((ln["start_point"]["x"], ln["start_point"]["y"]))
+ v, vk = add_node((ln["end_point"]["x"], ln["end_point"]["y"]))
+ edges.append((u, v, ln))
+ deg[u] += 1; deg[v] += 1
+ adj = {i: [] for i in range(len(nodes))}
+ for u, v, ln in edges:
+ adj[u].append((v, ln)); adj[v].append((u, ln))
+ inv_nodes = {idx: pt for pt, idx in nodes.items()}
+ return adj, inv_nodes, deg
+
+def follow_from_label(text_box, adj, inv_nodes, deg, pad):
+ # start nodes: any graph node inside/on the padded text box
+ starts = [i for i, (x,y) in inv_nodes.items() if rect_contains_with_padding(text_box, x, y, pad)]
+ visited_nodes, visited_edges = set(), set()
+ terminals = set()
+ stack = starts[:]
+ while stack:
+ cur = stack.pop()
+ if cur in visited_nodes:
+ continue
+ visited_nodes.add(cur)
+ is_touching_label = rect_contains_with_padding(text_box, *inv_nodes[cur], pad)
+ for nxt, ln in adj.get(cur, []):
+ eid = id(ln)
+ if eid not in visited_edges:
+ visited_edges.add(eid)
+ if nxt not in visited_nodes:
+ stack.append(nxt)
+ # terminal if degree==1 and not touching label
+ if deg.get(cur, 0) <= 1 and not is_touching_label:
+ terminals.add(cur)
+ return list(terminals), list(visited_edges)
+
+# ----------------------------- main flow -----------------------------
+
+def main():
+ ap = argparse.ArgumentParser()
+ ap.add_argument("--slides-dir", required=True)
+ ap.add_argument("--rels-dir", required=True)
+ ap.add_argument("--slide", type=int, required=True)
+ ap.add_argument("--out")
+ ap.add_argument("--padding", type=float, default=4000.0, help="EMU padding around text box")
+ ap.add_argument("--snap", type=float, default=8000.0, help="EMU snap size for junctions")
+ args = ap.parse_args()
+
+ slide_xml = os.path.join(args.slides_dir, f"slide{args.slide}.xml")
+ rels_xml = os.path.join(args.rels_dir, f"slide{args.slide}.xml.rels")
+ root = ET.parse(slide_xml).getroot()
+ rels_map = build_rels_map(rels_xml)
+
+ texts = extract_text_boxes(root, rels_map, bone_set="Bony Pelvis")
+ lines = extract_lines(root)
+ adj, inv_nodes, deg = build_graph(lines, snap=args.snap)
+
+ # connection-based association
+ for t in texts:
+ terminals, used_edges = follow_from_label(t["text_box"], adj, inv_nodes, deg, pad=args.padding)
+ # dedupe nearly-identical terminals by snapped point
+ term_pts = []
+ seen = set()
+ for idx in terminals:
+ pt = inv_nodes[idx]
+ if pt not in seen:
+ seen.add(pt)
+ term_pts.append({"x": pt[0], "y": pt[1]})
+ # collect the actual line objects that were traversed
+ pointer_lines = []
+ used = set()
+ for u in adj:
+ for v, ln in adj[u]:
+ eid = id(ln)
+ if eid in used_edges and eid not in used:
+ used.add(eid)
+ pointer_lines.append(ln)
+ # keep outputs small & stable
+ pointer_lines.sort(key=lambda ln: (ln["shape_id"] or 0, ln["line_id"]))
+ # sort target points by distance from the label center
+ tcx = t["text_box"]["x"] + t["text_box"]["width"] / 2.0
+ tcy = t["text_box"]["y"] + t["text_box"]["height"] / 2.0
+ term_pts.sort(key=lambda p: (p["x"] - tcx)**2 + (p["y"] - tcy)**2)
+
+ t["pointer_lines"] = pointer_lines
+ t["target_regions"] = term_pts
+
+ payload = {
+ "slide_number": args.slide,
+ "text_annotations": texts,
+ "total_text_annotations": len(texts),
+ "config": {"padding_emu": args.padding, "snap_emu": args.snap}
+ }
+
+ out_path = args.out or f"data_extraction/annotations/slide{args.slide}_text_annotations.json"
+ os.makedirs(os.path.dirname(out_path), exist_ok=True)
+ with open(out_path, "w") as f:
+ json.dump(payload, f, indent=2)
+ print(f"Wrote {out_path}")
+
+if __name__ == "__main__":
+ main()
diff --git a/data_extraction/slide2_pelvis_annotations.json b/data_extraction/slide2_pelvis_annotations.json
new file mode 100644
index 00000000..d7a9c797
--- /dev/null
+++ b/data_extraction/slide2_pelvis_annotations.json
@@ -0,0 +1,140 @@
+[
+ {
+ "text": "",
+ "position": {
+ "x": 2743200,
+ "y": 1299410,
+ "width": 5943600,
+ "height": 4952999
+ }
+ },
+ {
+ "text": "Right Pelvis (lateral aspect)",
+ "position": {
+ "x": 3579863,
+ "y": 6251729,
+ "width": 1323299,
+ "height": 215444
+ }
+ },
+ {
+ "text": "Ilium",
+ "position": {
+ "x": 5586937,
+ "y": 2083816,
+ "width": 393457,
+ "height": 215444
+ }
+ },
+ {
+ "text": "",
+ "position": {
+ "x": 3873661,
+ "y": 4149666,
+ "width": 1134543,
+ "height": 1310358
+ },
+ "color": "C133AD"
+ },
+ {
+ "text": "",
+ "position": {
+ "x": 4562474,
+ "y": 3962400,
+ "width": 1014265,
+ "height": 1060450
+ },
+ "color": "2F8E29"
+ },
+ {
+ "text": "Pubis",
+ "position": {
+ "x": 5682077,
+ "y": 4259252,
+ "width": 419318,
+ "height": 215444
+ }
+ },
+ {
+ "text": "Ischium",
+ "position": {
+ "x": 5446767,
+ "y": 5263629,
+ "width": 507320,
+ "height": 215444
+ }
+ },
+ {
+ "text": "Acetabulum",
+ "position": {
+ "x": 5450756,
+ "y": 3572102,
+ "width": 692939,
+ "height": 215444
+ }
+ },
+ "000000",
+ {
+ "shape": "line",
+ "position": {
+ "x": 4267200,
+ "y": 2191538,
+ "width": 1319736,
+ "height": 0
+ }
+ },
+ {
+ "shape": "line",
+ "position": {
+ "x": 5980394,
+ "y": 2191538,
+ "width": 1411007,
+ "height": 0
+ }
+ },
+ {
+ "shape": "line",
+ "position": {
+ "x": 5954088,
+ "y": 5371351,
+ "width": 961063,
+ "height": 0
+ }
+ },
+ {
+ "shape": "line",
+ "position": {
+ "x": 4495801,
+ "y": 5371351,
+ "width": 950967,
+ "height": 0
+ }
+ },
+ {
+ "shape": "line",
+ "position": {
+ "x": 5105401,
+ "y": 4366974,
+ "width": 576677,
+ "height": 0
+ }
+ },
+ {
+ "shape": "line",
+ "position": {
+ "x": 5171505,
+ "y": 3679824,
+ "width": 279250,
+ "height": 0
+ }
+ },
+ {
+ "shape": "line",
+ "position": {
+ "x": 4562474,
+ "y": 3679825,
+ "width": 609031,
+ "height": 495300
+ }
+ }
+]
\ No newline at end of file
diff --git a/data_extraction/slide3_Descriptions.json b/data_extraction/slide3_Descriptions.json
new file mode 100644
index 00000000..5a64c27b
--- /dev/null
+++ b/data_extraction/slide3_Descriptions.json
@@ -0,0 +1,62 @@
+{
+ "slide": "slide3.xml",
+ "images": [
+ {
+ "rId": "rId11",
+ "image_name": "image1.png"
+ },
+ {
+ "rId": "rId12",
+ "image_name": "image2.png"
+ }
+ ],
+ "annotations": [
+ {},
+ {
+ "text": "Bony Pelvis"
+ },
+ {
+ "text": "Home"
+ },
+ {},
+ {},
+ {},
+ {
+ "text": "Right Pelvis(medial aspect)"
+ },
+ {
+ "text": "Right Pelvis (lateral aspect)"
+ },
+ {
+ "text": "Iliac CrestAnterior Iliac spinesPosterior Iliac spinesAuricular surface"
+ },
+ {
+ "text": "IliumThe Ilium forms the superior part of the bony pelvis.It articulates with the sacrum to form the sacroiliac joint."
+ },
+ {
+ "text": "Bony Pelvis Ilium Ischium Pubis ",
+ "color": "000000"
+ },
+ {
+ "text": "Iliac Crest"
+ },
+ {
+ "text": "Anterior Superior Iliac Spine"
+ },
+ {
+ "text": "Anterior Inferior Iliac Spine"
+ },
+ {
+ "text": "Posterior Inferior Iliac Spine"
+ },
+ {
+ "text": "Posterior Superior Iliac Spine"
+ },
+ {
+ "text": "Auricular surface"
+ },
+ {
+ "text": "No labels"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/data_extraction/slide3_annotations.json b/data_extraction/slide3_annotations.json
new file mode 100644
index 00000000..8ad01e76
--- /dev/null
+++ b/data_extraction/slide3_annotations.json
@@ -0,0 +1,236 @@
+[
+ {
+ "text": "",
+ "position": {
+ "x": 2743200,
+ "y": 1299410,
+ "width": 5943600,
+ "height": 4952999
+ }
+ },
+ {
+ "text": "Bony Pelvis",
+ "position": {
+ "x": 5428944,
+ "y": 2254478,
+ "width": 590857,
+ "height": 215444
+ }
+ },
+ {
+ "text": "Home",
+ "position": {
+ "x": 5428944,
+ "y": 2254478,
+ "width": 590857,
+ "height": 215444
+ }
+ },
+ {
+ "text": "Radius",
+ "position": {
+ "x": "1524000",
+ "y": "6248400",
+ "width": "9144000",
+ "height": "0"
+ }
+ },
+ {
+ "position": {
+ "x": "8686800",
+ "y": "1311440",
+ "width": "1981200",
+ "height": "4936961"
+ }
+ },
+ {
+ "position": {
+ "x": "1524000",
+ "y": "1311439",
+ "width": "1219200",
+ "height": "4936961"
+ }
+ },
+ {
+ "text": "Right Pelvis(medial aspect)",
+ "position": {
+ "x": "6477427",
+ "y": "6248399",
+ "width": "1316687",
+ "height": "215444"
+ }
+ },
+ {
+ "text": "Right Pelvis (lateral aspect)",
+ "position": {
+ "x": "3579863",
+ "y": "6251729",
+ "width": "1323299",
+ "height": "215444"
+ }
+ },
+ {
+ "text": "Iliac CrestAnterior Iliac spinesPosterior Iliac spinesAuricular surface",
+ "position": {
+ "x": "8823068",
+ "y": "1322155",
+ "width": "1148008",
+ "height": "805605"
+ }
+ },
+ {
+ "text": "IliumThe Ilium forms the superior part of the bony pelvis.It articulates with the sacrum to form the sacroiliac joint.",
+ "position": {
+ "x": "8757818",
+ "y": "3505200",
+ "width": "1828800",
+ "height": "1231106"
+ }
+ },
+ {
+ "text": "Bony Pelvis Ilium Ischium Pubis ",
+ "position": {
+ "x": "1529348",
+ "y": "1330154",
+ "width": "1213853",
+ "height": "1015663"
+ }
+ },
+ {
+ "text": "Iliac Crest",
+ "position": {
+ "x": "5431116",
+ "y": "1912315",
+ "width": "595035",
+ "height": "215444"
+ }
+ },
+ {
+ "text": "Anterior Superior Iliac Spine",
+ "position": {
+ "x": "5407752",
+ "y": "2590801",
+ "width": "766897",
+ "height": "461665"
+ }
+ },
+ {
+ "text": "Anterior Inferior Iliac Spine",
+ "position": {
+ "x": "5271485",
+ "y": "3229154",
+ "width": "766897",
+ "height": "461665"
+ }
+ },
+ {
+ "text": "Posterior Inferior Iliac Spine",
+ "position": {
+ "x": "7887969",
+ "y": "3816698",
+ "width": "766897",
+ "height": "461665"
+ }
+ },
+ {
+ "text": "Posterior Superior Iliac Spine",
+ "position": {
+ "x": "7881241",
+ "y": "1445569",
+ "width": "766897",
+ "height": "461665"
+ }
+ },
+ {
+ "text": "Auricular surface",
+ "position": {
+ "x": "7169365",
+ "y": "1417638",
+ "width": "624749",
+ "height": "338554"
+ }
+ },
+ {
+ "text": "No labels",
+ "position": {
+ "x": "9189990",
+ "y": "6400801",
+ "width": "974820",
+ "height": "307777"
+ }
+ },
+ {
+ "shape": "line",
+ "color": "000000",
+ "position": {
+ "x": "1524000",
+ "y": "1295401",
+ "width": "9144000",
+ "height": "4009"
+ }
+ },
+ {
+ "shape": "line",
+ "position": {
+ "x": "8686800",
+ "y": "3459986",
+ "width": "1965420",
+ "height": "0"
+ }
+ },
+ {
+ "shape": "line",
+ "position": {
+ "x": "4212167",
+ "y": "2020037",
+ "width": "1218948",
+ "height": "0"
+ }
+ },
+ {
+ "shape": "line",
+ "position": {
+ "x": "6026150",
+ "y": "2020037",
+ "width": "1212850",
+ "height": "0"
+ }
+ },
+ {
+ "shape": "line",
+ "position": {
+ "x": "5008205",
+ "y": "2821633",
+ "width": "399547",
+ "height": "0"
+ }
+ },
+ {
+ "shape": "line",
+ "position": {
+ "x": "4915392",
+ "y": "3459986",
+ "width": "356092",
+ "height": "0"
+ }
+ },
+ {
+ "shape": "line",
+ "position": {
+ "x": "8153401",
+ "y": "3505201",
+ "width": "118017",
+ "height": "311497"
+ }
+ },
+
+ {
+ "text": "Radius",
+ "position": {
+ "x": 3124200,
+ "y": 4189504,
+ "width": 483352,
+ "height": 215444
+ }
+ }
+]
\ No newline at end of file
diff --git a/data_extraction/slide9Pelvis.xml b/data_extraction/slide9Pelvis.xml
new file mode 100644
index 00000000..0cde45f4
--- /dev/null
+++ b/data_extraction/slide9Pelvis.xml
@@ -0,0 +1,7341 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Bony Pelvis
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Home
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Right Pelvis
+
+
+
+ (medial aspect)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Right Pelvis
+
+
+
+ (lateral aspect)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Bony Pelvis
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ilium
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ischium
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Pubis
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ramus
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ischial tuberosity
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ramus
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ischial tuberosity
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ischial spine
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Sciatic notches
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ischium
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Forms the inferoposterior part of the pelvic bone.
+
+
+
+
+
+
+
+
+
+ Situated posterior to the pubis and inferior to the
+ ilium.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Ischial spine
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Greater sciatic notch
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Lesser sciatic notch
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ No labels
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Body
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Body
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master title style
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master text styles
+
+
+
+
+
+
+ Second level
+
+
+
+
+
+
+ Third level
+
+
+
+
+
+
+ Fourth level
+
+
+
+
+
+
+ Fifth level
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2/16/2025
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ‹#›
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master title style
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master text styles
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2/16/2025
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ‹#›
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master title style
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master subtitle style
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2/16/2025
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ‹#›
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master title style
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master text styles
+
+
+
+
+
+
+ Second level
+
+
+
+
+
+
+ Third level
+
+
+
+
+
+
+ Fourth level
+
+
+
+
+
+
+ Fifth level
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2/16/2025
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ‹#›
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master title style
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master text styles
+
+
+
+
+
+
+ Second level
+
+
+
+
+
+
+ Third level
+
+
+
+
+
+
+ Fourth level
+
+
+
+
+
+
+ Fifth level
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master text styles
+
+
+
+
+
+
+ Second level
+
+
+
+
+
+
+ Third level
+
+
+
+
+
+
+ Fourth level
+
+
+
+
+
+
+ Fifth level
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2/16/2025
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ‹#›
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master title style
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master text styles
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master text styles
+
+
+
+
+
+
+ Second level
+
+
+
+
+
+
+ Third level
+
+
+
+
+
+
+ Fourth level
+
+
+
+
+
+
+ Fifth level
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master text styles
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master text styles
+
+
+
+
+
+
+ Second level
+
+
+
+
+
+
+ Third level
+
+
+
+
+
+
+ Fourth level
+
+
+
+
+
+
+ Fifth level
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2/16/2025
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ‹#›
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master title style
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2/16/2025
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ‹#›
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2/16/2025
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ‹#›
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master title style
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master text styles
+
+
+
+
+
+
+ Second level
+
+
+
+
+
+
+ Third level
+
+
+
+
+
+
+ Fourth level
+
+
+
+
+
+
+ Fifth level
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master text styles
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2/16/2025
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ‹#›
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master title style
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master text styles
+
+
+
+
+
+
+ Second level
+
+
+
+
+
+
+ Third level
+
+
+
+
+
+
+ Fourth level
+
+
+
+
+
+
+ Fifth level
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2/16/2025
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ‹#›
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master title style
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master text styles
+
+
+
+
+
+
+ Second level
+
+
+
+
+
+
+ Third level
+
+
+
+
+
+
+ Fourth level
+
+
+
+
+
+
+ Fifth level
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2/16/2025
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ‹#›
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master title style
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master text styles
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2/16/2025
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ‹#›
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2/16/2025
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Click to edit Master text styles
+
+
+
+
+
+
+ Second level
+
+
+
+
+
+
+ Third level
+
+
+
+
+
+
+ Fourth level
+
+
+
+
+
+
+ Fifth level
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ‹#›
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /9j/4AAQSkZJRgABAQAAYABgAAD/4QB0RXhpZgAATU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUA
+ AAABAAAARgEoAAMAAAABAAIAAIdpAAQAAAABAAAATgAAAAAAAABgAAAAAQAAAGAAAAABAAKgAgAE
+ AAAAAQAAAOugAwAEAAAAAQAAAXMAAAAA/+0AOFBob3Rvc2hvcCAzLjAAOEJJTQQEAAAAAAAAOEJJ
+ TQQlAAAAAAAQ1B2M2Y8AsgTpgAmY7PhCfv/iB+hJQ0NfUFJPRklMRQABAQAAB9hhcHBsAiAAAG1u
+ dHJSR0IgWFlaIAfZAAIAGQALABoAC2Fjc3BBUFBMAAAAAGFwcGwAAAAAAAAAAAAAAAAAAAAAAAD2
+ 1gABAAAAANMtYXBwbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAC2Rlc2MAAAEIAAAAb2RzY20AAAF4AAAFnGNwcnQAAAcUAAAAOHd0cHQAAAdMAAAAFHJYWVoA
+ AAdgAAAAFGdYWVoAAAd0AAAAFGJYWVoAAAeIAAAAFHJUUkMAAAecAAAADmNoYWQAAAesAAAALGJU
+ UkMAAAecAAAADmdUUkMAAAecAAAADmRlc2MAAAAAAAAAFEdlbmVyaWMgUkdCIFByb2ZpbGUAAAAA
+ AAAAAAAAABRHZW5lcmljIFJHQiBQcm9maWxlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAABtbHVjAAAAAAAAAB8AAAAMc2tTSwAAACgAAAGEZGFESwAAAC4A
+ AAGsY2FFUwAAACQAAAHadmlWTgAAACQAAAH+cHRCUgAAACYAAAIidWtVQQAAACoAAAJIZnJGVQAA
+ ACgAAAJyaHVIVQAAACgAAAKaemhUVwAAABYAAALCbmJOTwAAACYAAALYY3NDWgAAACIAAAL+aGVJ
+ TAAAAB4AAAMgaXRJVAAAACgAAAM+cm9STwAAACQAAANmZGVERQAAACwAAAOKa29LUgAAABYAAAO2
+ c3ZTRQAAACYAAALYemhDTgAAABYAAAPMamFKUAAAABoAAAPiZWxHUgAAACIAAAP8cHRQTwAAACYA
+ AAQebmxOTAAAACgAAAREZXNFUwAAACYAAAQedGhUSAAAACQAAARsdHJUUgAAACIAAASQZmlGSQAA
+ ACgAAASyaHJIUgAAACgAAATacGxQTAAAACwAAAUCcnVSVQAAACIAAAUuYXJFRwAAACYAAAVQZW5V
+ UwAAACYAAAV2AFYBYQBlAG8AYgBlAGMAbgD9ACAAUgBHAEIAIABwAHIAbwBmAGkAbABHAGUAbgBl
+ AHIAZQBsACAAUgBHAEIALQBiAGUAcwBrAHIAaQB2AGUAbABzAGUAUABlAHIAZgBpAGwAIABSAEcA
+ QgAgAGcAZQBuAOgAcgBpAGMAQx6lAHUAIABoAOwAbgBoACAAUgBHAEIAIABDAGgAdQBuAGcAUABl
+ AHIAZgBpAGwAIABSAEcAQgAgAEcAZQBuAOkAcgBpAGMAbwQXBDAEMwQwBDsETAQ9BDgEOQAgBD8E
+ QAQ+BEQEMAQ5BDsAIABSAEcAQgBQAHIAbwBmAGkAbAAgAGcA6QBuAOkAcgBpAHEAdQBlACAAUgBW
+ AEIAwQBsAHQAYQBsAOEAbgBvAHMAIABSAEcAQgAgAHAAcgBvAGYAaQBskBp1KAAgAFIARwBCACCC
+ cl9pY8+P8ABHAGUAbgBlAHIAaQBzAGsAIABSAEcAQgAtAHAAcgBvAGYAaQBsAE8AYgBlAGMAbgD9
+ ACAAUgBHAEIAIABwAHIAbwBmAGkAbAXkBegF1QXkBdkF3AAgAFIARwBCACAF2wXcBdwF2QBQAHIA
+ bwBmAGkAbABvACAAUgBHAEIAIABnAGUAbgBlAHIAaQBjAG8AUAByAG8AZgBpAGwAIABSAEcAQgAg
+ AGcAZQBuAGUAcgBpAGMAQQBsAGwAZwBlAG0AZQBpAG4AZQBzACAAUgBHAEIALQBQAHIAbwBmAGkA
+ bMd8vBgAIABSAEcAQgAg1QS4XNMMx3xmbpAaACAAUgBHAEIAIGPPj/Blh072TgCCLAAgAFIARwBC
+ ACAw1zDtMNUwoTCkMOsDkwO1A70DuQO6A8wAIAPAA8EDvwPGA68DuwAgAFIARwBCAFAAZQByAGYA
+ aQBsACAAUgBHAEIAIABnAGUAbgDpAHIAaQBjAG8AQQBsAGcAZQBtAGUAZQBuACAAUgBHAEIALQBw
+ AHIAbwBmAGkAZQBsDkIOGw4jDkQOHw4lDkwAIABSAEcAQgAgDhcOMQ5IDicORA4bAEcAZQBuAGUA
+ bAAgAFIARwBCACAAUAByAG8AZgBpAGwAaQBZAGwAZQBpAG4AZQBuACAAUgBHAEIALQBwAHIAbwBm
+ AGkAaQBsAGkARwBlAG4AZQByAGkBDQBrAGkAIABSAEcAQgAgAHAAcgBvAGYAaQBsAFUAbgBpAHcA
+ ZQByAHMAYQBsAG4AeQAgAHAAcgBvAGYAaQBsACAAUgBHAEIEHgQxBEkEOAQ5ACAEPwRABD4ERAQ4
+ BDsETAAgAFIARwBCBkUGRAZBACAGKgY5BjEGSgZBACAAUgBHAEIAIAYnBkQGOQYnBkUARwBlAG4A
+ ZQByAGkAYwAgAFIARwBCACAAUAByAG8AZgBpAGwAZXRleHQAAAAAQ29weXJpZ2h0IDIwMDcgQXBw
+ bGUgSW5jLiwgYWxsIHJpZ2h0cyByZXNlcnZlZC4AWFlaIAAAAAAAAPNSAAEAAAABFs9YWVogAAAA
+ AAAAdE0AAD3uAAAD0FhZWiAAAAAAAABadQAArHMAABc0WFlaIAAAAAAAACgaAAAVnwAAuDZjdXJ2
+ AAAAAAAAAAEBzQAAc2YzMgAAAAAAAQxCAAAF3v//8yYAAAeSAAD9kf//+6L///2jAAAD3AAAwGz/
+ wAARCAFzAOsDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAA
+ AgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcY
+ GRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKT
+ lJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP0
+ 9fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQA
+ AQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2
+ Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOk
+ paanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9sAQwAC
+ AgICAgIDAgIDBQMDAwUGBQUFBQYIBgYGBgYICggICAgICAoKCgoKCgoKDAwMDAwMDg4ODg4PDw8P
+ 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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ /9j/4AAQSkZJRgABAQAAYABgAAD/4QB0RXhpZgAATU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUA
+ AAABAAAARgEoAAMAAAABAAIAAIdpAAQAAAABAAAATgAAAAAAAABgAAAAAQAAAGAAAAABAAKgAgAE
+ AAAAAQAAAQygAwAEAAAAAQAAAWgAAAAA/+0AOFBob3Rvc2hvcCAzLjAAOEJJTQQEAAAAAAAAOEJJ
+ TQQlAAAAAAAQ1B2M2Y8AsgTpgAmY7PhCfv/iB+hJQ0NfUFJPRklMRQABAQAAB9hhcHBsAiAAAG1u
+ dHJSR0IgWFlaIAfZAAIAGQALABoAC2Fjc3BBUFBMAAAAAGFwcGwAAAAAAAAAAAAAAAAAAAAAAAD2
+ 1gABAAAAANMtYXBwbAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAC2Rlc2MAAAEIAAAAb2RzY20AAAF4AAAFnGNwcnQAAAcUAAAAOHd0cHQAAAdMAAAAFHJYWVoA
+ AAdgAAAAFGdYWVoAAAd0AAAAFGJYWVoAAAeIAAAAFHJUUkMAAAecAAAADmNoYWQAAAesAAAALGJU
+ UkMAAAecAAAADmdUUkMAAAecAAAADmRlc2MAAAAAAAAAFEdlbmVyaWMgUkdCIFByb2ZpbGUAAAAA
+ AAAAAAAAABRHZW5lcmljIFJHQiBQcm9maWxlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+ AAAAAAAAAAAAAAAAAAAAAAAAAABtbHVjAAAAAAAAAB8AAAAMc2tTSwAAACgAAAGEZGFESwAAAC4A
+ AAGsY2FFUwAAACQAAAHadmlWTgAAACQAAAH+cHRCUgAAACYAAAIidWtVQQAAACoAAAJIZnJGVQAA
+ ACgAAAJyaHVIVQAAACgAAAKaemhUVwAAABYAAALCbmJOTwAAACYAAALYY3NDWgAAACIAAAL+aGVJ
+ TAAAAB4AAAMgaXRJVAAAACgAAAM+cm9STwAAACQAAANmZGVERQAAACwAAAOKa29LUgAAABYAAAO2
+ c3ZTRQAAACYAAALYemhDTgAAABYAAAPMamFKUAAAABoAAAPiZWxHUgAAACIAAAP8cHRQTwAAACYA
+ AAQebmxOTAAAACgAAAREZXNFUwAAACYAAAQedGhUSAAAACQAAARsdHJUUgAAACIAAASQZmlGSQAA
+ ACgAAASyaHJIUgAAACgAAATacGxQTAAAACwAAAUCcnVSVQAAACIAAAUuYXJFRwAAACYAAAVQZW5V
+ UwAAACYAAAV2AFYBYQBlAG8AYgBlAGMAbgD9ACAAUgBHAEIAIABwAHIAbwBmAGkAbABHAGUAbgBl
+ AHIAZQBsACAAUgBHAEIALQBiAGUAcwBrAHIAaQB2AGUAbABzAGUAUABlAHIAZgBpAGwAIABSAEcA
+ QgAgAGcAZQBuAOgAcgBpAGMAQx6lAHUAIABoAOwAbgBoACAAUgBHAEIAIABDAGgAdQBuAGcAUABl
+ AHIAZgBpAGwAIABSAEcAQgAgAEcAZQBuAOkAcgBpAGMAbwQXBDAEMwQwBDsETAQ9BDgEOQAgBD8E
+ QAQ+BEQEMAQ5BDsAIABSAEcAQgBQAHIAbwBmAGkAbAAgAGcA6QBuAOkAcgBpAHEAdQBlACAAUgBW
+ AEIAwQBsAHQAYQBsAOEAbgBvAHMAIABSAEcAQgAgAHAAcgBvAGYAaQBskBp1KAAgAFIARwBCACCC
+ cl9pY8+P8ABHAGUAbgBlAHIAaQBzAGsAIABSAEcAQgAtAHAAcgBvAGYAaQBsAE8AYgBlAGMAbgD9
+ ACAAUgBHAEIAIABwAHIAbwBmAGkAbAXkBegF1QXkBdkF3AAgAFIARwBCACAF2wXcBdwF2QBQAHIA
+ bwBmAGkAbABvACAAUgBHAEIAIABnAGUAbgBlAHIAaQBjAG8AUAByAG8AZgBpAGwAIABSAEcAQgAg
+ AGcAZQBuAGUAcgBpAGMAQQBsAGwAZwBlAG0AZQBpAG4AZQBzACAAUgBHAEIALQBQAHIAbwBmAGkA
+ bMd8vBgAIABSAEcAQgAg1QS4XNMMx3xmbpAaACAAUgBHAEIAIGPPj/Blh072TgCCLAAgAFIARwBC
+ ACAw1zDtMNUwoTCkMOsDkwO1A70DuQO6A8wAIAPAA8EDvwPGA68DuwAgAFIARwBCAFAAZQByAGYA
+ aQBsACAAUgBHAEIAIABnAGUAbgDpAHIAaQBjAG8AQQBsAGcAZQBtAGUAZQBuACAAUgBHAEIALQBw
+ AHIAbwBmAGkAZQBsDkIOGw4jDkQOHw4lDkwAIABSAEcAQgAgDhcOMQ5IDicORA4bAEcAZQBuAGUA
+ bAAgAFIARwBCACAAUAByAG8AZgBpAGwAaQBZAGwAZQBpAG4AZQBuACAAUgBHAEIALQBwAHIAbwBm
+ AGkAaQBsAGkARwBlAG4AZQByAGkBDQBrAGkAIABSAEcAQgAgAHAAcgBvAGYAaQBsAFUAbgBpAHcA
+ ZQByAHMAYQBsAG4AeQAgAHAAcgBvAGYAaQBsACAAUgBHAEIEHgQxBEkEOAQ5ACAEPwRABD4ERAQ4
+ BDsETAAgAFIARwBCBkUGRAZBACAGKgY5BjEGSgZBACAAUgBHAEIAIAYnBkQGOQYnBkUARwBlAG4A
+ ZQByAGkAYwAgAFIARwBCACAAUAByAG8AZgBpAGwAZXRleHQAAAAAQ29weXJpZ2h0IDIwMDcgQXBw
+ bGUgSW5jLiwgYWxsIHJpZ2h0cyByZXNlcnZlZC4AWFlaIAAAAAAAAPNSAAEAAAABFs9YWVogAAAA
+ AAAAdE0AAD3uAAAD0FhZWiAAAAAAAABadQAArHMAABc0WFlaIAAAAAAAACgaAAAVnwAAuDZjdXJ2
+ AAAAAAAAAAEBzQAAc2YzMgAAAAAAAQxCAAAF3v//8yYAAAeSAAD9kf//+6L///2jAAAD3AAAwGz/
+ wAARCAFoAQwDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAA
+ AgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcY
+ GRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKT
+ lJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP0
+ 9fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQA
+ AQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2
+ Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOk
+ paanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9sAQwAC
+ AgICAgIDAgIDBQMDAwUGBQUFBQYIBgYGBgYICggICAgICAoKCgoKCgoKDAwMDAwMDg4ODg4PDw8P
+ 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
+ ACiiigAooooAKKKKACiiigAooooAKKKKAP/Z
+
+
+
+
+
+
+
+
+
+ /9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsK
+ CwsNDhIQDQ4RDgsLEBYQERMUFRUVDA8XGBYUGBIUFRT/2wBDAQMEBAUEBQkFBQkUDQsNFBQUFBQU
+ FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBT/wAARCACQAQADASIA
+ AhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQA
+ AAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3
+ ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWm
+ p6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEA
+ AwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSEx
+ BhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElK
+ U1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3
+ uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD9U6KK
+ KACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoooo
+ AKKKKACiiigDwP8AaO/trUPiD8NdH0oX91DeLqj3Gn2fie70FZ/LhiKF57Y7jtJJCkEcmvPvCP7R
+ HjDT/hfcXVvfWGot4K8LxanrDa1A893rU63l9aTW9vNHMqjDae6JORL5rTRNtGfm+nvFngDwx4+h
+ t4fE/hvSPEcNuxeGPVrGK6WJiMEqJFOCR3FVNe8D+FhY2d9P4X0a6m0CFpNLM1hExstgDKISV/d8
+ ov3cdB6UAeIal8dPiZB517p9p4e1SK51XxJpenaRHYXC3Ltpk1z5e6X7RtZpY7V0wEUB5FbOAUNn
+ 4ifFnUPHv7Ofj/xboNzMmiPfRW/h+80W4ktby6tlmt4pXEwkXazT/aUUqUGwKc8k1fuNO8b3mmPB
+ H408GeH9QWN7uK8sPAU7TWk1yheSaEtqDr5h8xizFTuLHIOTUXh3w34k8JeC9M8HW3inwa+gadaw
+ 21vb3Xga9mjljUAoxY6mQ7FgCSeS3PvT5XYnmS6nLL4p+J/w38XJouh6Dq9tpviQy3Gl6f4q1OPX
+ L2z+ywr9oJeXUUG2Vpo2VPtTlVglYIN3yyeF/wBozVvD9vrvjbxI8EXhWXVNOfVoRefbU0mK48O2
+ dxH9mlRzG0Zuz5eVyrtPuB6k+l614B8a/ETRoYNa134eeIdMLiZLfU/AlxPGHGQG2SakcMMkZxnk
+ 1+bX7Q3/AAUk+JPwj+NHjrwM/gf4Xa6ml3a6XNfXHh25RryO3bdCHX7Y3CMSVUkhTyKRR9tW/wAZ
+ viZY/wBsxLpelJ4mXUbcapZwrNfPbj+xLK5l8izlvYy6xzTBH8hs7cN5TO7NX0j4L8Qx+LvBug67
+ DLBPFqlhb3qS2u/ynWSNXDJvVW2ndxuUHGMgHivxQ17/AIK0/EbxTFNFrXww+E+rxTzrdSpf+H7m
+ cSTCMRiRg10cuEAQMedoA6Vuw/8ABaX4128KRReEvh7FFGoVETTb0KoAwAB9s4FAH7WUV+K3/D6v
+ 43/9Ct8P/wDwXX3/AMmUf8Pq/jf/ANCt8P8A/wAF19/8mUAftTRX4rf8Pq/jf/0K3w//APBdff8A
+ yZR/w+r+N/8A0K3w/wD/AAXX3/yZQB+1NFfit/w+r+N//QrfD/8A8F19/wDJlH/D6v43/wDQrfD/
+ AP8ABdff/JlAH7U0V+K3/D6v43/9Ct8P/wDwXX3/AMmUf8Pq/jf/ANCt8P8A/wAF19/8mUAftTRX
+ 4rf8Pq/jf/0K3w//APBdff8AyZR/w+r+N/8A0K3w/wD/AAXX3/yZQB+1NFfit/w+r+N//QrfD/8A
+ 8F19/wDJlH/D6v43/wDQrfD/AP8ABdff/JlAH7U0V+SvwB/4KufGr40/Gjwf4Gn0XwFpUOvahHYt
+ ex6VeytCG/iCm9GfpkV+i2qah480O6S2vvHvg62mdQ6q3hG85BJHUal6imJtLc9UorzfTYfiNrFq
+ Lmy8ceDrmAkqJE8KXWMjr/zEqtf2L8Uf+hw8I/8AhKXX/wAsqQzvqK4H+xvih/0OHhH/AMJS6/8A
+ llVfUrH4oafpt1dDxd4RcwRPLt/4RW6GdoJx/wAhL2oA9Goqrpd22oaZZ3TKFaaFJCo6AlQcfrVq
+ gAooooAKKKKACs7xJ/yLuqf9esv/AKAa0azvEn/Iu6p/16y/+gGgDhvEl5aabofhySW/XS3ktAxl
+ NgLlZNqR8MMjt69s8jFGh+OvDtvasl9cNeztJlWbS/KIUgcbVB4Bzz710cOjXWreH9Fa21ObTmjs
+ 1XMWSG3InJGQCQAcZzjdWnoel3WlxSJdajJqJbG1pFxt6+59f0rRNctmYOMua6/r8TSjjSFAiKqI
+ OiqMAV/Oh+3b/wAnhfFv/sPz/wAxX9GNfznft2/8nhfFv/sPz/zFZm54RRRVvSNJvNe1Wz0zT7d7
+ u/vJkt7e3jGWkkZgqqPckgUAVKK/Sb4U/wDBNnw3oOhxXHja6PiDXJUVntoneK1tzjJUFSGf03Hj
+ /ZFVfiV/wT/8HanaypokFz4Z1HB8maGZpoHbtvRyTj/dK/jXE8XTjLld/XoWoNq6Pzjorsvip8I/
+ Evwb8SNoviSy+zzEb4LiMlobhP7yNjkeoOCO4FcbXYmmrogKKKKYBRRW14L8G6x8QvFOm+HdBsn1
+ DVtQlEMEEfcnqSeygAkk8AAk0bAYtFfrz+zr+xf4O+DfhcLq+nWPirxPcgG81G9tllSPj/VwK4O1
+ Bzz1bqcDCjG/aC/Y28BeNIXvrLw4mlXmPmuNGC27j3KgbG/EZ44IryamZU6ctU7dzohRlPRPU/J+
+ ivYPjn+zT4g+C5ivyx1jw3cECLU4YivlseiTLzsb0OSD2OcgeP16VOpCrFTg7pmMouLtI93/AGEv
+ +TwvhJ/2H4P5mv6B/FmqXFjfRpFqk1irQ7jHFY+fnk87s8H271/Px+wl/wAnhfCT/sPwfzNf0N6t
+ o9zqEwkg1OeyGzYVi6dc569e3+RjVb6mcr20OSbxDdqI/wDiorjoznGjkkgMeOvHA4HX8663SdP1
+ O1uGkvNWF/Cy8Ri2WLB4wcg/Xj3qq3hu/ZUX+3LkbRjIBBbryfm68/oK0tJsZ9PhkSe9kvWZyweQ
+ YKg/wj2qm10IinfUvVneJP8AkXdU/wCvWX/0A1o1neJP+Rd1T/r1l/8AQDUGoeG/+Rd0v/r1i/8A
+ QBWjWd4b/wCRd0v/AK9Yv/QBWjQAUUUUAFFFFABWd4k/5F3VP+vWX/0A1o1neJP+Rd1T/r1l/wDQ
+ DQAeG/8AkXdL/wCvWL/0AVo1neG/+Rd0v/r1i/8AQBWjQAV/Od+3b/yeF8W/+w/P/MV/RjX8537d
+ v/J4Xxb/AOw/P/MUAeEV9xf8E0fgH/wkniy8+I2sWbHT9K/0fSvNT5Zbhsh5Vz18tfl9Mue618qf
+ BX4Y3fxi+JeieFbRmiW8lLXFwoz5MCAtI/1Cg4z1JA71+2Hw/wDDel+BfDOmaLotpHYaZY26wQQR
+ jgKO/uSckk8kkk1yV6qj7nVjtodHJbrNMBt+719KzvF0cEMdsSBu6f5/KujeFIYGl3feIO4+prA8
+ YQm4tbcgZZeleTUk43sXCKZ5f8ev2ftF+O3w7u9KuoY47wRlrW6C5a3mA+V1/HggfeGR3r8ZPEvh
+ zUfCPiDUNF1a2ez1Kwma3nhkGCrKcH6juD3BBr959NvBY2ySSyBFI5LHAx61+Vv/AAUI8TeFPE3x
+ XtZNCmt7nVrZZrfUZrXBUqrL5SsR1cZkHqBtHYV24WprypbiaZ8sUUUV6hAV+n3/AATZ/Z3i8K+B
+ m+JOq2wOta8jR6f5i829mDjcPQyMM/7oX1NfnR8L/A118TPiJ4c8K2YbztWvorTco+4rMA7/AEVd
+ zH2Ffvx4f0Ow8O+H7DSdPt1trGxgjtreFOkcaKFVR9AAK4MVOyUF1Lj3KElr9nhDDnB5964Hxl4q
+ J1qPQ9Pj868ky8h/hjAHQnpzXp11a+TbgE5JOelcDfatpdnqj6hHbRgOGSW5K4LbDt7DnnivmsRZ
+ W5nY7KW+hwnjTwno2oWuoeHtRtEudK1CA21zFJyp3LyM9j6Ecg4PFfmb+0r+zBffAq4i1K0vDqfh
+ q7uWt4ZZFxNA+CypJjhsqDhhjO1uBxn9MvFmsDxJqix6ZZt9nhJ86aTgFyB7/wCc18/ft3WYb9nV
+ 7h9m+LVbWIDdyDh8/wBevrW+X1J06qpx2Y61pR5nufKH7CX/ACeF8JP+w/B/M1/RjX8537CX/J4X
+ wk/7D8H8zX9GNfWnnhRRRQAVneJP+Rd1T/r1l/8AQDWjWd4k/wCRd1T/AK9Zf/QDQAeG/wDkXdL/
+ AOvWL/0AVo1neG/+Rd0v/r1i/wDQBWjQAUUUUAFFFFABWd4k/wCRd1T/AK9Zf/QDWjWd4k/5F3VP
+ +vWX/wBANAB4b/5F3S/+vWL/ANAFaNZ3hv8A5F3S/wDr1i/9AFaNABX8537dv/J4Xxb/AOw/P/MV
+ /RjX8537dv8AyeF8W/8AsPz/AMxQB9Nf8Ev/AIdaZqPhDxX4ojEcmuG//sxyRl4rYRJJ8vpuZmz6
+ +WvpX3ZHCLPAlBMS8Hrke9fl3/wTu/aStvgv8QNQ8Na0IY/D3iTYZb6e4WJLGSJJGEhLcFSpKnkH
+ hcZ6H9M/iN8X/BXw90k6h4i1e10q2IAMk0oAfIzhR1Ykdhk15OIotzck9WUpdGdP5rNGYs7kGMHH
+ pWP4hvo1t1Z+FXrn0HcVynwv+P3gD41WOqTeCdcXVv7PdEvFNvJC8W/Ozh1BIO1uRkfKazvHXiqK
+ z3ST3cVpax5UyyuFz7V5lVuEuV7m8bWucT+0H/avin4UeJdN0mYwXC2Vx5M8TFcP5RIXPYknGe1f
+ jtX6p/Gv4pJp/wAHPE17oqrqaw2UgcQNhgGGwt0zhd24nsAa/KyvYwStBuxjJ6hRRRXokHoPwB+K
+ EXwX+MHhvxnPYtqMGlzO0ltGwVmV4njJUnjIDkjPUiv2t+B/xY0742fDfSfGWlQ3Vvp+peZ5cV4g
+ SRDHI0bBgCR95D0Jr8Ea/V3/AIJm/FWPxd8FG8LOrR3PhOV45GKYVoZnkljbd0Jz5ikdto9a83GU
+ 04qfY0g+h9dazqCQwNJJIIok6sxwBXjrSQXVkkLETm0TY8e7iRueo75zn8af8WPFs+qyLaWzeXap
+ 02/xN6mvgn9rrxF4r8F6zoMlvrmp6XpGo28qltLmMTi4R/mLEYLLsdMLuHfmvnFRWNqqKlZnapOj
+ G9j7H1LxJNYXiJDGsdrF9xOPm5zn0618V/tzfGiLxc2k+FtI1ON7G1uJpdTsYlO4XUZ2IXY9wGkA
+ Ax6nPy48Kn+K3jI23y/ELUplT5o0murjzuOgzggH23Y96g8E+F9P8XwXFxqUl8959p+eWO9tYwyk
+ ZOfPdSWzn5unPPPX28Jl31eanKV7HPUrc6skd9+wl/yeF8JP+w/B/M1/RjX87f7Ieh6fH+2p8M9L
+ 8n7XYDX7eNo7vypRIMc52FkYZzjBPGK/oC/4Vz4T/wChX0X/AMF8P/xNe0cx0VFclq3w98PQ6fK9
+ h4Q0K5u1wUiksYVVuRkZ28cZrm4/CMrSKG+G3htUZhltkHyDHI+783PfjjtQB6jWd4k/5F3VP+vW
+ X/0A1nf8K58J/wDQr6L/AOC+H/4ms/xB8O/Ckeg6k6eGdHVltpSGWwiBB2Hn7tAHQ+G/+Rd0v/r1
+ i/8AQBWjWd4b/wCRd0v/AK9Yv/QBWjQAUUUUAFFFFABWd4k/5F3VP+vWX/0A1o1neJP+Rd1T/r1l
+ /wDQDQAeG/8AkXdL/wCvWL/0AVo1neG/+Rd0v/r1i/8AQBWjQAV/Od+3b/yeF8W/+w/P/MV/RjX8
+ 8f7Z/h/+3v2xPjAP7R0/TxH4glBN/P5QO44yODnHfHrQB851ZvtSvNSaNry6nu2jUIhnkZyqgYCj
+ J4AA6V0DfD+RVmP9v6ARHxxqSfOdqt8vr97HpkEdqxIdGuJo1kWS0CsMgPeQqfxBbI/GgD76/wCC
+ W+nG18LfEzWG4jMtpEeO0aTOf/Rgqz8SNW1PxVrVxcXMrmPcfLjGdqj0Ar03/gnn8K5/Cf7Ot/c3
+ V3bPdeJ7ia7iW3mWQJCIxEoJXILZVyQCcZA6g1S13wO9nqE0Eg2qGIDHpjvzXiVpKNfm7msXeJ5l
+ 4ZhdVe3uIxLaXCNFNDJysiMCGUj0IJFfF/xh+Hknwx8fajon7x7RSJ7OWQcyQOMqSe5HKn3U19e+
+ OvjF4N+GF7Np99fm81GP71pZrvdDgHB7KfYkdaf4wtfCnxj8G6d/b+mSSLc2qXNjqlq6i5tfMUMA
+ OMEdMocjIPQ4I6cPzxk3PRMmpJacp8F0V6L8VPg7J8NoYLuPWbbVbK4l8uPETwzfdJBZDkY4PRjz
+ 9a86r0jO9wr9aP2SPhzF8Ff2btKlkT7PrPiKIarqBYYf94Mwxn0Cx7OPUt618cfsY/soXHxk16Hx
+ T4jt2t/BGnTBgsi4/tOVTnyl/wCmYI+dv+Ajkkr7x+1v+1laeA/iBF4QtbSe7WxgjluZIHVQJH5C
+ YPou0/8AAq8jGSdd/V6W/U3h7vvM9va/F47A4/PpXlP7UXwxPxI+CusQ2UJutX0pl1O0WNfmYoCJ
+ FHrmMvwOpC1mfCf47+F/iNarDpl6U1LYWksrlRHMuOpAycj3Ga9Am1i/sY99s+x2/wBWzcrn0+vt
+ XixpVKUk0tUdPMne+zPygrV0HxVqnhnzv7NuRb+dt35iR84BA+8Dj7x6etdF8VvMg8f+I4tZ02a1
+ 1sXcnniOZVi35+8E8v7p4brznrWp8LfCdh4g0qeS50qPUpRc7NzWuoSmNdq45tht5yeGOeO3f7CL
+ urs4Ds/2Ib6fUv2zvhXd3Mnm3E3iGF5JCACzEnJ4r97/ABff/ZbjTkguJoEaBSplubuMlQejBEb5
+ unLEMTx61+C37F0UcH7bnw0jhRI4U8TRqiRhwqqHYAASfOB/vc+vNf0I6t4dtNbdGuXvFKDA+y30
+ 9v8An5brnv19aYHnlrqKy3Crd6pdLbTfJIYby+EowgHyKYhg5A7jOSepxWws2iSQtJ/buvmNRvI3
+ 3IOFHI+5k/dJx1NdE3g7T2CZl1L5W3g/2rdZzgjr5noT+noKtaZ4ftNJlZ7d7wll27Z72aZAPZXc
+ gfgKAOXju9D+0W8Y17WS6kYjaSfkkjG75f8AaHU9PxqxBHYSeHdZuLC/1G8RbSSJheyzMARH1Ak7
+ nHUeprsqzvEn/Iu6p/16y/8AoBoAPDf/ACLul/8AXrF/6AK0azvDf/Iu6X/16xf+gCtGgAooooAK
+ KKKACs7xJ/yLuqf9esv/AKAa0azvEn/Iu6p/16y/+gGgA8N/8i7pf/XrF/6AK0azvDf/ACLul/8A
+ XrF/6AK0aACv5zv27f8Ak8L4t/8AYfn/AJiv6Ma/nO/bt/5PC+Lf/Yfn/mKAPCKKKKAP0n/4J9/b
+ NJ/Z9ujOzLHe6vdXVoxY/KixwxnH9350erP7Qni7UPh/4J13xJbXUxnggWKGPPy+dI4RWI9FLZ/C
+ vH/2Ifjtp+neFr74d6pJFbXxna60mWQ7RPvwHgz2II3Ad9zDsM/QeoaRZeNdH1HR9ajgvbW4XypL
+ aY4V8nIzggj/AHh0IB4rx4xlHFS51oyqlvZqx+ZPh7w9rfxG8UQ2FhFNqWq383zO2WOWPLu3YDOS
+ x6V9meIr7QPhP4b0zTtS1K3to7CyhtwMgyzFECllTqdxBPTvXdeIte8DfAPQTFLHpvhmIgiOxtoj
+ 59ww4xhQWY8/ebj1NfAni6+Hi7xNqesXOuW8kl5O8o83z2ZVJO1c+X0AwB9K9Fx9o9dEjNO+xZ+K
+ nxCl+I3iZr/yjb2cKeTawsclUB6t/tE8n8u1e4fsc/s+eDPipa6l4k8U6o1wNIvFi/4R9RsWYFQy
+ vI4O7YTvG0AfcPzYyK+etJ8Mw6tBPIde0qxMUnlhLuSVGkH99cRn5frg+1aHgP4ia98J/FH9paFf
+ Kk0b7Jo1O+C5RW+6w/iU44PXuMU60Zzg403Zlw5YvVaH7C6fqEFrp8NhYW8NhZ20YjitrdAkcaAY
+ Cqo4AA7Cvzv/AG4/hPr1j8VLvxZbadd3ui6nbwu91DGZEgkVRGUYj7uQqkE4zuwOld94W/bx0Sa1
+ eTW7K/tbr73lwqJFB9FbIyPqBWL4m/4KAtfahHDpfhySHTs4kuLiYGYj2QfKP++vyrxsNQxFGfNy
+ 6m85RlseB/DP4R/EbWfEWm3nh3QdUtJ4p0ePUZIGiiiO4fMXYAEDPI54zxX6U3kdvolwbmWaNYF+
+ +WHykDuR/nFfKDftyabHb5XTNUnn6bWMar+e4/yryb4qftTeJPiNp8+mW0Y0bTJuJUjkLyyLj7rN
+ xx7AV11KNatNOWiXYzjJJHP/ABw8S6R8SPir4j1/T72Kztbm52Rxzxv8yRqsaupRWyGCBucEZxz1
+ rmvD/h5tQ84QeJtL03bIEH2q4lh8zI+8Pk6ducflzXNUV6cUopJGZ7x+wr/yeL8Jvm3/APE/g+b1
+ 5PNf0YV/Od+wl/yeF8JP+w/B/M1/RjTAKKKKACs7xJ/yLuqf9esv/oBrRrO8Sf8AIu6p/wBesv8A
+ 6AaADw3/AMi7pf8A16xf+gCtGs7w3/yLul/9esX/AKAK0aACiiigAooooAKzvEn/ACLuqf8AXrL/
+ AOgGtGs7xJ/yLuqf9esv/oBoAPDf/Iu6X/16xf8AoArRrO8N/wDIu6X/ANesX/oArRoAK/ni/bO/
+ sT/hsj4v/wBtf2h5f9vTGMWGzJ5GQd/Tjvz9K/odr+c79u3/AJPC+Lf/AGH5/wCYoA8y2+B/3n7z
+ xB1+Q+XByNvf5uOc/hz7VR1Y+GozaHTBq04w32lLsxR88bShXdx1yCO3vxh0UAatvqVhYzJcWtlc
+ C5jIaJproMqsDwxARScdRz1xnI4Pbw/tIfEGKy+ztrrzuDlbqaNWmX234yfxz0FeZ0UCNzVPF974
+ gujd60iazfNwbu8eQylewJVxkDtnoMDoAA618S2UOiyWE3hrS7mZkkRdQdrhbhCxyGG2UISpxjKH
+ jg5rBooGS215cWZkNvPJAZEaJ/LcruQ8FTjqD3FRUUUAFFFFABRRRQAUUUUAe7/sJf8AJ4Xwk/7D
+ 8H8zX9GNfznfsJf8nhfCT/sPwfzNf0Y0AFFFFABWd4k/5F3VP+vWX/0A1o1neJP+Rd1T/r1l/wDQ
+ DQAeG/8AkXdL/wCvWL/0AVo1neG/+Rd0v/r1i/8AQBWjQAUUUUAFFFFABVe/tF1CxuLVmKrNG0ZY
+ dQCCM/rViigDyrXtW8S/DnSbEav438M2VrgW8LyeGLty21e+y+PYelc//wALpl/6KR4W/wDCSv8A
+ /wCTK1/2kvhLrvxe8LWOmaFcWNtNHM5ma+nkhGxkK/KUjc7skdq+ZE/YG+IkcrNH4ns40LMwiXxB
+ eBFJJPA+zc8nvmgD6i8KeMPEHjia4h0Tx14XvpbdQ8ijwteJtBOAfmvhn8K+UPiz/wAEidG+MfxJ
+ 8ReNta+JV9a6rrl297cw2GkokCO3UIGlZgPqx+tfRX7MnwJ8T/BubUR4gv7G/ilto4IJLe8muZmK
+ sSTI0kSZPTnmvfKAPzN/4cf+E/8AoqOtf+CyH/4usTxJ/wAEX/Dnh8WrQeNvFOsxysVc2Gl2xaLp
+ tJDSrkEnqOmCTxX6m0UAflHH/wAEcdEeYI3iLxpGjBCJG02wIAYDIOLnIKnII56cEg5q3H/wRn8O
+ OrE+L/GC4GedJtOflJwP3/tj6kdua/VGigD8tNP/AOCL/hm+vEgbxx4rtEbP7+40m1CDA6HExPt0
+ /pWz/wAOP/Cf/RUda/8ABZD/APF1+mVFAH5m/wDDj/wn/wBFR1r/AMFkP/xdH/Dj/wAJ/wDRUda/
+ 8FkP/wAXX6ZUUAfmb/w4/wDCf/RUda/8FkP/AMXXJyf8Ec9FXU7myXxF4ylaFmC3C6bZCCRdzBWD
+ m4H3gpOMZGVzjNfq9RQB+U9l/wAEb9Augxk8TeNLXAJAl0uyyRz6XJ546e4qX/hzV4cW3jkbxd4x
+ 3MQPLXSbQsvTr+/x3/Q1+qdFAH5hab/wRN8LahbmV/iN4hsm3FfKudLgDcd/lkIwfrVv/hx/4T/6
+ KjrX/gsh/wDi6/TKigD8+fhN/wAEidG+DnxJ8O+NtF+JV9darod2l7bQ3+ko8DuvQOFlViPow+tf
+ af8AZXxD/wCho8M/+E3cf/J9dnRQB45efEbVbC8uLWf4g+FY7i3laGVP+EWvDtdWKsOL3sQRUX/C
+ 0dQ/6KJ4U/8ACVvf/k2vKviR+x34t8ceNtW1yDXbXT1uL2aaD7Lqc8DiNpZXUMBCRuxJg4J6YBxn
+ PO3n7CnjS81Ce7/4Sz7OZWkbyrfW7mNE8w5YKFt/lGeevYVz88+xye0q9vwPobRPGmveI9RjsNO8
+ e+Fbm7kBKxDwvdgnAyet8B0Fb994f+IF/Zz20ninw0I5o2jYr4buMgEYOP8AT/evKfgL+zd4n+E/
+ iy2vtR1a11DT4w/ym+lnlTMQjVUDRKAvAOM9ST3r6QrWDbWptTlKSvJFfT7QafY21qrF1hjWMMep
+ 2gDP6VYooqzUKKKKAP/Z
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Luke Tomlinson
+ Luke Tomlinson
+ 1
+ 2025-02-16T19:50:39Z
+ 2025-02-16T19:51:45Z
+
+
+
+
+
+
+ 1
+ 68
+ Microsoft Office PowerPoint
+ Widescreen
+ 27
+ 1
+ 1
+ 0
+ 0
+ false
+
+
+
+ Fonts Used
+
+
+ 3
+
+
+ Theme
+
+
+ 1
+
+
+ Slide Titles
+
+
+ 1
+
+
+
+
+
+ Aptos
+ Aptos Display
+ Arial
+ Office Theme
+ Bony Pelvis
+
+
+
+ false
+ false
+ false
+ 16.0000
+
+
+
+
\ No newline at end of file
diff --git a/data_extraction/xml_boneset_reader.py b/data_extraction/xml_boneset_reader.py
new file mode 100644
index 00000000..bd9fc79f
--- /dev/null
+++ b/data_extraction/xml_boneset_reader.py
@@ -0,0 +1,100 @@
+import os
+import xml.etree.ElementTree as ET
+import json
+
+def extract_bones_from_xml(xml_path):
+ """
+ Parses the XML file and extracts bonesets and their associated bones.
+ Bonesets are determined by hyperlink text with size 1200.
+ Bones with size 900 are assigned to the most recent bolded boneset.
+ """
+ try:
+ print(f"Parsing XML: {xml_path}")
+ tree = ET.parse(xml_path)
+ root = tree.getroot()
+ except ET.ParseError as e:
+ print(f"Error parsing {xml_path}: {e}")
+ return {}
+
+ # Namespace handling for XML
+ ns = {
+ 'p': 'http://schemas.openxmlformats.org/presentationml/2006/main',
+ 'a': 'http://schemas.openxmlformats.org/drawingml/2006/main',
+ 'r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'
+ }
+
+ bonesets = {} # Dictionary to store bonesets
+ bonesetContent =[]
+ total_boneset = None
+ bolded_set = None
+ boldedList=[]
+
+ # Extract bonesets based on hyperlinks and size attributes
+ for sp_element in root.findall(".//p:sp", ns):
+ for r_element in sp_element.findall(".//p:txBody//a:r", ns):
+ rPr_element = r_element.find("a:rPr", ns)
+ text_element = r_element.find("a:t", ns)
+
+ if rPr_element is not None and text_element is not None:
+ text = text_element.text.strip()
+ size = rPr_element.get("sz")
+ is_bold = rPr_element.get("b") == "1"
+ has_hyperlink = rPr_element.find("a:hlinkClick", ns) is not None
+
+ if has_hyperlink:
+ if size == "1200":
+ if is_bold:
+ bolded_set = text
+ bonesets[bolded_set] = list()
+
+ if total_boneset is None:
+ total_boneset = text
+ bonesets[total_boneset] = list()
+ continue
+ # These are their own bonesets
+ bonesets[total_boneset].append(text.capitalize())
+ elif size == "900":
+ if not bolded_set:
+ bonesetContent.append(text.capitalize())
+ else:
+ bonesets[bolded_set].append(text.capitalize())
+ for i in boldedList:
+ bonesets[bolded_set].append(i)
+
+
+ return bonesets, bonesetContent
+
+def generate_json_output(bonesets, output_json_path):
+ """
+ Converts bonesets dictionary into a structured JSON format and writes it to a file.
+ """
+ structured_data = []
+
+ for boneset_name, bonesetContent in bonesets.items():
+ structured_data.append({
+ "name": boneset_name,
+ "id": boneset_name.lower().replace(" ", "_"),
+ "bones": bonesetContent
+ })
+
+ # Save to JSON file
+ try:
+ with open(output_json_path, 'w') as json_file:
+ json.dump(structured_data, json_file, indent=4)
+ print(f"JSON file saved: {output_json_path}")
+ except IOError as e:
+ print(f"Error writing to {output_json_path}: {e}")
+
+if __name__ == "__main__":
+ # Get the directory of the current script
+ current_dir = os.path.dirname(os.path.abspath(__file__))
+
+ # Define the XML and JSON file paths relative to the script's directory
+ xml_file_path = os.path.join(current_dir, "slide9Pelvis.xml")
+ json_file_path = os.path.join(current_dir, "output.json")
+
+ # Extract bonesets and their bones
+ bonesets, bonesetContent = extract_bones_from_xml(xml_file_path)
+
+ # Generate and save JSON output
+ generate_json_output(bonesets, json_file_path)
diff --git a/editor/push.html b/editor/push.html
new file mode 100644
index 00000000..e55d541c
--- /dev/null
+++ b/editor/push.html
@@ -0,0 +1,24 @@
+
+
+
+
+
+ Automate Git Push
+
+
+
+ Automate Git Push
+
+
+
+
diff --git a/eslint.config.js b/eslint.config.js
new file mode 100644
index 00000000..74afdb38
--- /dev/null
+++ b/eslint.config.js
@@ -0,0 +1,17 @@
+export default [
+ {
+ files: ["**/*.js"],
+ languageOptions: {
+ ecmaVersion: "latest",
+ sourceType: "module",
+ globals: {
+ window: "readonly",
+ document: "readonly",
+ },
+ },
+ rules: {
+ semi: ["error", "always"],
+ quotes: ["error", "double"],
+ },
+ },
+];
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..0b05d48c
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,8266 @@
+{
+ "name": "digitalbonesbox",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "digitalbonesbox",
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "axios": "^1.8.4",
+ "body-parser": "^1.20.3",
+ "cors": "^2.8.5",
+ "express": "^4.21.2",
+ "simple-git": "^3.27.0"
+ },
+ "devDependencies": {
+ "concurrently": "^9.2.1",
+ "eslint": "^9.24.0",
+ "jest": "^29.7.0",
+ "jest-environment-jsdom": "^29.7.0",
+ "live-server": "^1.2.2"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.26.2",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
+ "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/compat-data": {
+ "version": "7.26.2",
+ "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.2.tgz",
+ "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/core": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.0.tgz",
+ "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@ampproject/remapping": "^2.2.0",
+ "@babel/code-frame": "^7.26.0",
+ "@babel/generator": "^7.26.0",
+ "@babel/helper-compilation-targets": "^7.25.9",
+ "@babel/helper-module-transforms": "^7.26.0",
+ "@babel/helpers": "^7.26.0",
+ "@babel/parser": "^7.26.0",
+ "@babel/template": "^7.25.9",
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.26.0",
+ "convert-source-map": "^2.0.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.2",
+ "json5": "^2.2.3",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/babel"
+ }
+ },
+ "node_modules/@babel/core/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@babel/core/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.26.2",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.2.tgz",
+ "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.26.2",
+ "@babel/types": "^7.26.0",
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.25",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-compilation-targets": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz",
+ "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/compat-data": "^7.25.9",
+ "@babel/helper-validator-option": "^7.25.9",
+ "browserslist": "^4.24.0",
+ "lru-cache": "^5.1.1",
+ "semver": "^6.3.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-imports": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz",
+ "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/traverse": "^7.25.9",
+ "@babel/types": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-module-transforms": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz",
+ "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-module-imports": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "@babel/traverse": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/@babel/helper-plugin-utils": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz",
+ "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
+ "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
+ "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-option": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz",
+ "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helpers": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.0.tgz",
+ "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.25.9",
+ "@babel/types": "^7.26.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.26.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.2.tgz",
+ "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.26.0"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-bigint": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz",
+ "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-properties": {
+ "version": "7.12.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz",
+ "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.12.13"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-class-static-block": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz",
+ "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-attributes": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz",
+ "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-import-meta": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz",
+ "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-json-strings": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz",
+ "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-jsx": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz",
+ "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-logical-assignment-operators": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz",
+ "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz",
+ "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-numeric-separator": {
+ "version": "7.10.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz",
+ "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.10.4"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-catch-binding": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz",
+ "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-optional-chaining": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz",
+ "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-private-property-in-object": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz",
+ "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-top-level-await": {
+ "version": "7.14.5",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz",
+ "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.14.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/plugin-syntax-typescript": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz",
+ "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0-0"
+ }
+ },
+ "node_modules/@babel/template": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz",
+ "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.25.9",
+ "@babel/parser": "^7.25.9",
+ "@babel/types": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.9.tgz",
+ "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.25.9",
+ "@babel/generator": "^7.25.9",
+ "@babel/parser": "^7.25.9",
+ "@babel/template": "^7.25.9",
+ "@babel/types": "^7.25.9",
+ "debug": "^4.3.1",
+ "globals": "^11.1.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@babel/traverse/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@babel/types": {
+ "version": "7.26.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.0.tgz",
+ "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+ "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
+ "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz",
+ "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.6",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/config-array/node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@eslint/config-array/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz",
+ "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.15.2",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz",
+ "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
+ "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/@eslint/eslintrc/node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.35.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.35.0.tgz",
+ "integrity": "sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
+ "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz",
+ "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.15.2",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
+ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.7",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz",
+ "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.4.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
+ "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@istanbuljs/load-nyc-config": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
+ "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "camelcase": "^5.3.1",
+ "find-up": "^4.1.0",
+ "get-package-type": "^0.1.0",
+ "js-yaml": "^3.13.1",
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jest/console": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz",
+ "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "jest-message-util": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/core": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz",
+ "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/console": "^29.7.0",
+ "@jest/reporters": "^29.7.0",
+ "@jest/test-result": "^29.7.0",
+ "@jest/transform": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.9",
+ "jest-changed-files": "^29.7.0",
+ "jest-config": "^29.7.0",
+ "jest-haste-map": "^29.7.0",
+ "jest-message-util": "^29.7.0",
+ "jest-regex-util": "^29.6.3",
+ "jest-resolve": "^29.7.0",
+ "jest-resolve-dependencies": "^29.7.0",
+ "jest-runner": "^29.7.0",
+ "jest-runtime": "^29.7.0",
+ "jest-snapshot": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "jest-validate": "^29.7.0",
+ "jest-watcher": "^29.7.0",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^29.7.0",
+ "slash": "^3.0.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/environment": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz",
+ "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/fake-timers": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "jest-mock": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/expect": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz",
+ "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "expect": "^29.7.0",
+ "jest-snapshot": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/expect-utils": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz",
+ "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jest-get-type": "^29.6.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/fake-timers": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz",
+ "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@sinonjs/fake-timers": "^10.0.2",
+ "@types/node": "*",
+ "jest-message-util": "^29.7.0",
+ "jest-mock": "^29.7.0",
+ "jest-util": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/globals": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz",
+ "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "^29.7.0",
+ "@jest/expect": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "jest-mock": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/reporters": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz",
+ "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@bcoe/v8-coverage": "^0.2.3",
+ "@jest/console": "^29.7.0",
+ "@jest/test-result": "^29.7.0",
+ "@jest/transform": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@jridgewell/trace-mapping": "^0.3.18",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "exit": "^0.1.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "istanbul-lib-coverage": "^3.0.0",
+ "istanbul-lib-instrument": "^6.0.0",
+ "istanbul-lib-report": "^3.0.0",
+ "istanbul-lib-source-maps": "^4.0.0",
+ "istanbul-reports": "^3.1.3",
+ "jest-message-util": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "jest-worker": "^29.7.0",
+ "slash": "^3.0.0",
+ "string-length": "^4.0.1",
+ "strip-ansi": "^6.0.0",
+ "v8-to-istanbul": "^9.0.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@jest/schemas": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
+ "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sinclair/typebox": "^0.27.8"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/source-map": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz",
+ "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.18",
+ "callsites": "^3.0.0",
+ "graceful-fs": "^4.2.9"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/test-result": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz",
+ "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/console": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "collect-v8-coverage": "^1.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/test-sequencer": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz",
+ "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/test-result": "^29.7.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.7.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/transform": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz",
+ "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@jest/types": "^29.6.3",
+ "@jridgewell/trace-mapping": "^0.3.18",
+ "babel-plugin-istanbul": "^6.1.1",
+ "chalk": "^4.0.0",
+ "convert-source-map": "^2.0.0",
+ "fast-json-stable-stringify": "^2.1.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.7.0",
+ "jest-regex-util": "^29.6.3",
+ "jest-util": "^29.7.0",
+ "micromatch": "^4.0.4",
+ "pirates": "^4.0.4",
+ "slash": "^3.0.0",
+ "write-file-atomic": "^4.0.2"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jest/types": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
+ "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "^29.6.3",
+ "@types/istanbul-lib-coverage": "^2.0.0",
+ "@types/istanbul-reports": "^3.0.0",
+ "@types/node": "*",
+ "@types/yargs": "^17.0.8",
+ "chalk": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+ "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/set-array": "^1.2.1",
+ "@jridgewell/sourcemap-codec": "^1.4.10",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/set-array": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+ "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.25",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
+ "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@kwsites/file-exists": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz",
+ "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==",
+ "dependencies": {
+ "debug": "^4.1.1"
+ }
+ },
+ "node_modules/@kwsites/file-exists/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@kwsites/file-exists/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ },
+ "node_modules/@kwsites/promise-deferred": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz",
+ "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw=="
+ },
+ "node_modules/@sinclair/typebox": {
+ "version": "0.27.8",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
+ "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@sinonjs/commons": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz",
+ "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "type-detect": "4.0.8"
+ }
+ },
+ "node_modules/@sinonjs/fake-timers": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz",
+ "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@sinonjs/commons": "^3.0.0"
+ }
+ },
+ "node_modules/@tootallnate/once": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
+ "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/@types/babel__core": {
+ "version": "7.20.5",
+ "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
+ "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.20.7",
+ "@babel/types": "^7.20.7",
+ "@types/babel__generator": "*",
+ "@types/babel__template": "*",
+ "@types/babel__traverse": "*"
+ }
+ },
+ "node_modules/@types/babel__generator": {
+ "version": "7.6.8",
+ "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz",
+ "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz",
+ "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "node_modules/@types/babel__traverse": {
+ "version": "7.20.6",
+ "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz",
+ "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.20.7"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/graceful-fs": {
+ "version": "4.1.9",
+ "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
+ "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/istanbul-lib-coverage": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
+ "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/istanbul-lib-report": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
+ "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-coverage": "*"
+ }
+ },
+ "node_modules/@types/istanbul-reports": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
+ "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/istanbul-lib-report": "*"
+ }
+ },
+ "node_modules/@types/jsdom": {
+ "version": "20.0.1",
+ "resolved": "https://registry.npmjs.org/@types/jsdom/-/jsdom-20.0.1.tgz",
+ "integrity": "sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "@types/tough-cookie": "*",
+ "parse5": "^7.0.0"
+ }
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "22.10.0",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.0.tgz",
+ "integrity": "sha512-XC70cRZVElFHfIUB40FgZOBbgJYFKKMa5nb9lxcwYstFG/Mi+/Y0bGS+rs6Dmhmkpq4pnNiLiuZAbc02YCOnmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.20.0"
+ }
+ },
+ "node_modules/@types/stack-utils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz",
+ "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/tough-cookie": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz",
+ "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/yargs": {
+ "version": "17.0.33",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
+ "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@types/yargs-parser": {
+ "version": "21.0.3",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
+ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/abab": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
+ "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==",
+ "deprecated": "Use your platform's native atob() and btoa() methods instead",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/accepts": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
+ "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==",
+ "dependencies": {
+ "mime-types": "~2.1.34",
+ "negotiator": "0.6.3"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-globals": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz",
+ "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.1.0",
+ "acorn-walk": "^8.0.2"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/acorn-walk": {
+ "version": "8.3.4",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
+ "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "acorn": "^8.11.0"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/agent-base/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/agent-base/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.21.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/apache-crypt": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmjs.org/apache-crypt/-/apache-crypt-1.2.6.tgz",
+ "integrity": "sha512-072WetlM4blL8PREJVeY+WHiUh1R5VNt2HfceGS8aKqttPHcmqE5pkKuXPz/ULmJOFkc8Hw3kfKl6vy7Qka6DA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "unix-crypt-td-js": "^1.1.4"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/apache-md5": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/apache-md5/-/apache-md5-1.1.8.tgz",
+ "integrity": "sha512-FCAJojipPn0bXjuEpjOOOMN8FZDkxfWWp4JGN9mifU2IhxvKyXZYqpzPHdnTSUpmPDy+tsslB6Z1g+Vg6nVbYA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
+ },
+ "node_modules/array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/async-each": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.6.tgz",
+ "integrity": "sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "license": "MIT"
+ },
+ "node_modules/atob": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+ "dev": true,
+ "license": "(MIT OR Apache-2.0)",
+ "bin": {
+ "atob": "bin/atob.js"
+ },
+ "engines": {
+ "node": ">= 4.5.0"
+ }
+ },
+ "node_modules/axios": {
+ "version": "1.8.4",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz",
+ "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==",
+ "dependencies": {
+ "follow-redirects": "^1.15.6",
+ "form-data": "^4.0.0",
+ "proxy-from-env": "^1.1.0"
+ }
+ },
+ "node_modules/babel-jest": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz",
+ "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/transform": "^29.7.0",
+ "@types/babel__core": "^7.1.14",
+ "babel-plugin-istanbul": "^6.1.1",
+ "babel-preset-jest": "^29.6.3",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.8.0"
+ }
+ },
+ "node_modules/babel-plugin-istanbul": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz",
+ "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/helper-plugin-utils": "^7.0.0",
+ "@istanbuljs/load-nyc-config": "^1.0.0",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-instrument": "^5.0.4",
+ "test-exclude": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz",
+ "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/core": "^7.12.3",
+ "@babel/parser": "^7.14.7",
+ "@istanbuljs/schema": "^0.1.2",
+ "istanbul-lib-coverage": "^3.2.0",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/babel-plugin-jest-hoist": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz",
+ "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/template": "^7.3.3",
+ "@babel/types": "^7.3.3",
+ "@types/babel__core": "^7.1.14",
+ "@types/babel__traverse": "^7.0.6"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/babel-preset-current-node-syntax": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.1.0.tgz",
+ "integrity": "sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/plugin-syntax-async-generators": "^7.8.4",
+ "@babel/plugin-syntax-bigint": "^7.8.3",
+ "@babel/plugin-syntax-class-properties": "^7.12.13",
+ "@babel/plugin-syntax-class-static-block": "^7.14.5",
+ "@babel/plugin-syntax-import-attributes": "^7.24.7",
+ "@babel/plugin-syntax-import-meta": "^7.10.4",
+ "@babel/plugin-syntax-json-strings": "^7.8.3",
+ "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3",
+ "@babel/plugin-syntax-numeric-separator": "^7.10.4",
+ "@babel/plugin-syntax-object-rest-spread": "^7.8.3",
+ "@babel/plugin-syntax-optional-catch-binding": "^7.8.3",
+ "@babel/plugin-syntax-optional-chaining": "^7.8.3",
+ "@babel/plugin-syntax-private-property-in-object": "^7.14.5",
+ "@babel/plugin-syntax-top-level-await": "^7.14.5"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/babel-preset-jest": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz",
+ "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "babel-plugin-jest-hoist": "^29.6.3",
+ "babel-preset-current-node-syntax": "^1.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "^7.0.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cache-base": "^1.0.1",
+ "class-utils": "^0.3.5",
+ "component-emitter": "^1.2.1",
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.1",
+ "mixin-deep": "^1.2.0",
+ "pascalcase": "^0.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/base/node_modules/define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/base/node_modules/is-descriptor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz",
+ "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.1",
+ "is-data-descriptor": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/basic-auth": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
+ "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "5.1.2"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/basic-auth/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/batch": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
+ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/bcryptjs": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
+ "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/binary-extensions": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
+ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/bindings": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
+ "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "file-uri-to-path": "1.0.0"
+ }
+ },
+ "node_modules/body-parser": {
+ "version": "1.20.3",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz",
+ "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "content-type": "~1.0.5",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "on-finished": "2.4.1",
+ "qs": "6.13.0",
+ "raw-body": "2.5.2",
+ "type-is": "~1.6.18",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/browserslist": {
+ "version": "4.24.2",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz",
+ "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "caniuse-lite": "^1.0.30001669",
+ "electron-to-chromium": "^1.5.41",
+ "node-releases": "^2.0.18",
+ "update-browserslist-db": "^1.1.1"
+ },
+ "bin": {
+ "browserslist": "cli.js"
+ },
+ "engines": {
+ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
+ }
+ },
+ "node_modules/bser": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz",
+ "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "node-int64": "^0.4.0"
+ }
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "collection-visit": "^1.0.0",
+ "component-emitter": "^1.2.1",
+ "get-value": "^2.0.6",
+ "has-value": "^1.0.0",
+ "isobject": "^3.0.1",
+ "set-value": "^2.0.0",
+ "to-object-path": "^0.3.0",
+ "union-value": "^1.0.0",
+ "unset-value": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
+ "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "set-function-length": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/caniuse-lite": {
+ "version": "1.0.30001684",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001684.tgz",
+ "integrity": "sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "CC-BY-4.0"
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/char-regex": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
+ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "2.1.8",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz",
+ "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "anymatch": "^2.0.0",
+ "async-each": "^1.0.1",
+ "braces": "^2.3.2",
+ "glob-parent": "^3.1.0",
+ "inherits": "^2.0.3",
+ "is-binary-path": "^1.0.0",
+ "is-glob": "^4.0.0",
+ "normalize-path": "^3.0.0",
+ "path-is-absolute": "^1.0.0",
+ "readdirp": "^2.2.1",
+ "upath": "^1.1.1"
+ },
+ "optionalDependencies": {
+ "fsevents": "^1.2.7"
+ }
+ },
+ "node_modules/chokidar/node_modules/anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "micromatch": "^3.1.4",
+ "normalize-path": "^2.1.1"
+ }
+ },
+ "node_modules/chokidar/node_modules/anymatch/node_modules/normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "remove-trailing-separator": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/chokidar/node_modules/braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/chokidar/node_modules/define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/chokidar/node_modules/fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/chokidar/node_modules/fsevents": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
+ "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
+ "deprecated": "Upgrade to fsevents v2 to mitigate potential security issues",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "dependencies": {
+ "bindings": "^1.5.0",
+ "nan": "^2.12.1"
+ },
+ "engines": {
+ "node": ">= 4.0"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ }
+ },
+ "node_modules/chokidar/node_modules/glob-parent/node_modules/is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/chokidar/node_modules/is-descriptor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz",
+ "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.1",
+ "is-data-descriptor": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/chokidar/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/chokidar/node_modules/is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/chokidar/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/chokidar/node_modules/micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/chokidar/node_modules/micromatch/node_modules/extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/chokidar/node_modules/micromatch/node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/chokidar/node_modules/to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ci-info": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz",
+ "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cjs-module-lexer": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz",
+ "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-union": "^3.1.0",
+ "define-property": "^0.2.5",
+ "isobject": "^3.0.0",
+ "static-extend": "^0.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/co": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+ "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">= 1.0.0",
+ "node": ">= 0.12.0"
+ }
+ },
+ "node_modules/collect-v8-coverage": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz",
+ "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "map-visit": "^1.0.0",
+ "object-visit": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/colors": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz",
+ "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.1.90"
+ }
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/component-emitter": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
+ "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/concurrently": {
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.2.1.tgz",
+ "integrity": "sha512-fsfrO0MxV64Znoy8/l1vVIjjHa29SZyyqPgQBwhiDcaW8wJc2W3XWVOGx4M3oJBnv/zdUZIIp1gDeS98GzP8Ng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "4.1.2",
+ "rxjs": "7.8.2",
+ "shell-quote": "1.8.3",
+ "supports-color": "8.1.1",
+ "tree-kill": "1.2.2",
+ "yargs": "17.7.2"
+ },
+ "bin": {
+ "conc": "dist/bin/concurrently.js",
+ "concurrently": "dist/bin/concurrently.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/open-cli-tools/concurrently?sponsor=1"
+ }
+ },
+ "node_modules/concurrently/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/connect": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz",
+ "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "finalhandler": "1.1.2",
+ "parseurl": "~1.3.3",
+ "utils-merge": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ }
+ },
+ "node_modules/connect/node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/connect/node_modules/finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/connect/node_modules/on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/connect/node_modules/statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/content-type": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/convert-source-map": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
+ "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cookie": {
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz",
+ "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
+ },
+ "node_modules/copy-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cors": {
+ "version": "2.8.5",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
+ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/create-jest": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz",
+ "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "chalk": "^4.0.0",
+ "exit": "^0.1.2",
+ "graceful-fs": "^4.2.9",
+ "jest-config": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "prompts": "^2.0.1"
+ },
+ "bin": {
+ "create-jest": "bin/create-jest.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/cssom": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz",
+ "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cssstyle": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
+ "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssom": "~0.3.6"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cssstyle/node_modules/cssom": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/data-urls": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz",
+ "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abab": "^2.0.6",
+ "whatwg-mimetype": "^3.0.0",
+ "whatwg-url": "^11.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/decimal.js": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
+ "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/decode-uri-component": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
+ "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/dedent": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz",
+ "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "babel-plugin-macros": "^3.1.0"
+ },
+ "peerDependenciesMeta": {
+ "babel-plugin-macros": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/define-data-property": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
+ "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
+ "dependencies": {
+ "es-define-property": "^1.0.0",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/destroy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz",
+ "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==",
+ "engines": {
+ "node": ">= 0.8",
+ "npm": "1.2.8000 || >= 1.4.16"
+ }
+ },
+ "node_modules/detect-newline": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
+ "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/diff-sequences": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
+ "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/domexception": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz",
+ "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==",
+ "deprecated": "Use your platform's native DOMException instead",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "webidl-conversions": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/duplexer": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
+ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="
+ },
+ "node_modules/electron-to-chromium": {
+ "version": "1.5.66",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.66.tgz",
+ "integrity": "sha512-pI2QF6+i+zjPbqRzJwkMvtvkdI7MjVbSh2g8dlMguDJIXEPw+kwasS1Jl+YGPEBfGVxsVgGUratAKymPdPo2vQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/emittery": {
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz",
+ "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/emittery?sponsor=1"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/encodeurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
+ "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
+ "dependencies": {
+ "get-intrinsic": "^1.2.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/escodegen": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
+ "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esprima": "^4.0.1",
+ "estraverse": "^5.2.0",
+ "esutils": "^2.0.2"
+ },
+ "bin": {
+ "escodegen": "bin/escodegen.js",
+ "esgenerate": "bin/esgenerate.js"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "optionalDependencies": {
+ "source-map": "~0.6.1"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.35.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.35.0.tgz",
+ "integrity": "sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.8.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.21.0",
+ "@eslint/config-helpers": "^0.3.1",
+ "@eslint/core": "^0.15.2",
+ "@eslint/eslintrc": "^3.3.1",
+ "@eslint/js": "9.35.0",
+ "@eslint/plugin-kit": "^0.3.5",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "@types/json-schema": "^7.0.15",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.4.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/debug": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint/node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/eslint/node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/event-stream": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
+ "integrity": "sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "duplexer": "~0.1.1",
+ "from": "~0",
+ "map-stream": "~0.1.0",
+ "pause-stream": "0.0.11",
+ "split": "0.3",
+ "stream-combiner": "~0.0.4",
+ "through": "~2.3.1"
+ }
+ },
+ "node_modules/execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
+ "license": "MIT",
+ "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"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/expect": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz",
+ "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/expect-utils": "^29.7.0",
+ "jest-get-type": "^29.6.3",
+ "jest-matcher-utils": "^29.7.0",
+ "jest-message-util": "^29.7.0",
+ "jest-util": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/express": {
+ "version": "4.21.2",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
+ "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==",
+ "dependencies": {
+ "accepts": "~1.3.8",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.20.3",
+ "content-disposition": "0.5.4",
+ "content-type": "~1.0.4",
+ "cookie": "0.7.1",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "1.3.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "merge-descriptors": "1.0.3",
+ "methods": "~1.1.2",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.12",
+ "proxy-addr": "~2.0.7",
+ "qs": "6.13.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.2.1",
+ "send": "0.19.0",
+ "serve-static": "1.16.2",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extglob/node_modules/define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extglob/node_modules/is-descriptor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz",
+ "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.1",
+ "is-data-descriptor": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/faye-websocket": {
+ "version": "0.11.4",
+ "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
+ "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "websocket-driver": ">=0.5.1"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/fb-watchman": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz",
+ "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "bser": "2.1.1"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/file-uri-to-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
+ "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
+ "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "on-finished": "2.4.1",
+ "parseurl": "~1.3.3",
+ "statuses": "2.0.1",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.9",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+ "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
+ "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "map-cache": "^0.2.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/from": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
+ "integrity": "sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/gensync": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
+ "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
+ "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "has-proto": "^1.0.1",
+ "has-symbols": "^1.0.3",
+ "hasown": "^2.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-package-type": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
+ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+ "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+ "dependencies": {
+ "get-intrinsic": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-property-descriptors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
+ "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
+ "dependencies": {
+ "es-define-property": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-proto": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
+ "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-value": "^2.0.6",
+ "has-values": "^1.0.0",
+ "isobject": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^3.0.0",
+ "kind-of": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-values/node_modules/is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/has-values/node_modules/is-number/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/html-encoding-sniffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
+ "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-encoding": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/http-auth": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/http-auth/-/http-auth-3.1.3.tgz",
+ "integrity": "sha512-Jbx0+ejo2IOx+cRUYAGS1z6RGc6JfYUNkysZM4u4Sfk1uLlGv814F7/PIjQQAuThLdAWxb74JMGd5J8zex1VQg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "apache-crypt": "^1.1.2",
+ "apache-md5": "^1.0.6",
+ "bcryptjs": "^2.3.0",
+ "uuid": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4.6.1"
+ }
+ },
+ "node_modules/http-errors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
+ "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
+ "dependencies": {
+ "depd": "2.0.0",
+ "inherits": "2.0.4",
+ "setprototypeof": "1.2.0",
+ "statuses": "2.0.1",
+ "toidentifier": "1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/http-parser-js": {
+ "version": "0.5.10",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz",
+ "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
+ "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@tootallnate/once": "2",
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/http-proxy-agent/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/http-proxy-agent/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+ "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/https-proxy-agent/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/https-proxy-agent/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=10.17.0"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/import-fresh/node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/import-local": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz",
+ "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "pkg-dir": "^4.2.0",
+ "resolve-cwd": "^3.0.0"
+ },
+ "bin": {
+ "import-local-fixture": "fixtures/cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/is-accessor-descriptor": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz",
+ "integrity": "sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-binary-path": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+ "integrity": "sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "binary-extensions": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-core-module": {
+ "version": "2.15.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz",
+ "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-data-descriptor": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz",
+ "integrity": "sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-descriptor": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.7.tgz",
+ "integrity": "sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.1",
+ "is-data-descriptor": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-generator-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz",
+ "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-potential-custom-element-name": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-wsl": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+ "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-instrument": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz",
+ "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@babel/core": "^7.23.9",
+ "@babel/parser": "^7.23.9",
+ "@istanbuljs/schema": "^0.1.3",
+ "istanbul-lib-coverage": "^3.2.0",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-instrument/node_modules/semver": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz",
+ "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0",
+ "source-map": "^0.6.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/istanbul-lib-source-maps/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
+ "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jest": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz",
+ "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/core": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "import-local": "^3.0.2",
+ "jest-cli": "^29.7.0"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-changed-files": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz",
+ "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "execa": "^5.0.0",
+ "jest-util": "^29.7.0",
+ "p-limit": "^3.1.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-circus": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz",
+ "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "^29.7.0",
+ "@jest/expect": "^29.7.0",
+ "@jest/test-result": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "co": "^4.6.0",
+ "dedent": "^1.0.0",
+ "is-generator-fn": "^2.0.0",
+ "jest-each": "^29.7.0",
+ "jest-matcher-utils": "^29.7.0",
+ "jest-message-util": "^29.7.0",
+ "jest-runtime": "^29.7.0",
+ "jest-snapshot": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "p-limit": "^3.1.0",
+ "pretty-format": "^29.7.0",
+ "pure-rand": "^6.0.0",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-cli": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz",
+ "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/core": "^29.7.0",
+ "@jest/test-result": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "chalk": "^4.0.0",
+ "create-jest": "^29.7.0",
+ "exit": "^0.1.2",
+ "import-local": "^3.0.2",
+ "jest-config": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "jest-validate": "^29.7.0",
+ "yargs": "^17.3.1"
+ },
+ "bin": {
+ "jest": "bin/jest.js"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0"
+ },
+ "peerDependenciesMeta": {
+ "node-notifier": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-config": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz",
+ "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@jest/test-sequencer": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "babel-jest": "^29.7.0",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "deepmerge": "^4.2.2",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-circus": "^29.7.0",
+ "jest-environment-node": "^29.7.0",
+ "jest-get-type": "^29.6.3",
+ "jest-regex-util": "^29.6.3",
+ "jest-resolve": "^29.7.0",
+ "jest-runner": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "jest-validate": "^29.7.0",
+ "micromatch": "^4.0.4",
+ "parse-json": "^5.2.0",
+ "pretty-format": "^29.7.0",
+ "slash": "^3.0.0",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "@types/node": "*",
+ "ts-node": ">=9.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "ts-node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-diff": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz",
+ "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "diff-sequences": "^29.6.3",
+ "jest-get-type": "^29.6.3",
+ "pretty-format": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-docblock": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz",
+ "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "detect-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-each": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz",
+ "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^29.6.3",
+ "jest-util": "^29.7.0",
+ "pretty-format": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-environment-jsdom": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz",
+ "integrity": "sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "^29.7.0",
+ "@jest/fake-timers": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/jsdom": "^20.0.0",
+ "@types/node": "*",
+ "jest-mock": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "jsdom": "^20.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "peerDependencies": {
+ "canvas": "^2.5.0"
+ },
+ "peerDependenciesMeta": {
+ "canvas": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-environment-node": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz",
+ "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "^29.7.0",
+ "@jest/fake-timers": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "jest-mock": "^29.7.0",
+ "jest-util": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-get-type": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz",
+ "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-haste-map": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz",
+ "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@types/graceful-fs": "^4.1.3",
+ "@types/node": "*",
+ "anymatch": "^3.0.3",
+ "fb-watchman": "^2.0.0",
+ "graceful-fs": "^4.2.9",
+ "jest-regex-util": "^29.6.3",
+ "jest-util": "^29.7.0",
+ "jest-worker": "^29.7.0",
+ "micromatch": "^4.0.4",
+ "walker": "^1.0.8"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "^2.3.2"
+ }
+ },
+ "node_modules/jest-leak-detector": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz",
+ "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jest-get-type": "^29.6.3",
+ "pretty-format": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-matcher-utils": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz",
+ "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "jest-diff": "^29.7.0",
+ "jest-get-type": "^29.6.3",
+ "pretty-format": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-message-util": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz",
+ "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.12.13",
+ "@jest/types": "^29.6.3",
+ "@types/stack-utils": "^2.0.0",
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "micromatch": "^4.0.4",
+ "pretty-format": "^29.7.0",
+ "slash": "^3.0.0",
+ "stack-utils": "^2.0.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-mock": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz",
+ "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "jest-util": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-pnp-resolver": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz",
+ "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "peerDependencies": {
+ "jest-resolve": "*"
+ },
+ "peerDependenciesMeta": {
+ "jest-resolve": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jest-regex-util": {
+ "version": "29.6.3",
+ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz",
+ "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-resolve": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz",
+ "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.7.0",
+ "jest-pnp-resolver": "^1.2.2",
+ "jest-util": "^29.7.0",
+ "jest-validate": "^29.7.0",
+ "resolve": "^1.20.0",
+ "resolve.exports": "^2.0.0",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-resolve-dependencies": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz",
+ "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jest-regex-util": "^29.6.3",
+ "jest-snapshot": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-runner": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz",
+ "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/console": "^29.7.0",
+ "@jest/environment": "^29.7.0",
+ "@jest/test-result": "^29.7.0",
+ "@jest/transform": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "emittery": "^0.13.1",
+ "graceful-fs": "^4.2.9",
+ "jest-docblock": "^29.7.0",
+ "jest-environment-node": "^29.7.0",
+ "jest-haste-map": "^29.7.0",
+ "jest-leak-detector": "^29.7.0",
+ "jest-message-util": "^29.7.0",
+ "jest-resolve": "^29.7.0",
+ "jest-runtime": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "jest-watcher": "^29.7.0",
+ "jest-worker": "^29.7.0",
+ "p-limit": "^3.1.0",
+ "source-map-support": "0.5.13"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-runtime": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz",
+ "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/environment": "^29.7.0",
+ "@jest/fake-timers": "^29.7.0",
+ "@jest/globals": "^29.7.0",
+ "@jest/source-map": "^29.6.3",
+ "@jest/test-result": "^29.7.0",
+ "@jest/transform": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "cjs-module-lexer": "^1.0.0",
+ "collect-v8-coverage": "^1.0.0",
+ "glob": "^7.1.3",
+ "graceful-fs": "^4.2.9",
+ "jest-haste-map": "^29.7.0",
+ "jest-message-util": "^29.7.0",
+ "jest-mock": "^29.7.0",
+ "jest-regex-util": "^29.6.3",
+ "jest-resolve": "^29.7.0",
+ "jest-snapshot": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "slash": "^3.0.0",
+ "strip-bom": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-snapshot": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz",
+ "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/core": "^7.11.6",
+ "@babel/generator": "^7.7.2",
+ "@babel/plugin-syntax-jsx": "^7.7.2",
+ "@babel/plugin-syntax-typescript": "^7.7.2",
+ "@babel/types": "^7.3.3",
+ "@jest/expect-utils": "^29.7.0",
+ "@jest/transform": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "babel-preset-current-node-syntax": "^1.0.0",
+ "chalk": "^4.0.0",
+ "expect": "^29.7.0",
+ "graceful-fs": "^4.2.9",
+ "jest-diff": "^29.7.0",
+ "jest-get-type": "^29.6.3",
+ "jest-matcher-utils": "^29.7.0",
+ "jest-message-util": "^29.7.0",
+ "jest-util": "^29.7.0",
+ "natural-compare": "^1.4.0",
+ "pretty-format": "^29.7.0",
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-snapshot/node_modules/semver": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/jest-util": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz",
+ "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "chalk": "^4.0.0",
+ "ci-info": "^3.2.0",
+ "graceful-fs": "^4.2.9",
+ "picomatch": "^2.2.3"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-validate": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz",
+ "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/types": "^29.6.3",
+ "camelcase": "^6.2.0",
+ "chalk": "^4.0.0",
+ "jest-get-type": "^29.6.3",
+ "leven": "^3.1.0",
+ "pretty-format": "^29.7.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-validate/node_modules/camelcase": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
+ "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/jest-watcher": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz",
+ "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/test-result": "^29.7.0",
+ "@jest/types": "^29.6.3",
+ "@types/node": "*",
+ "ansi-escapes": "^4.2.1",
+ "chalk": "^4.0.0",
+ "emittery": "^0.13.1",
+ "jest-util": "^29.7.0",
+ "string-length": "^4.0.1"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-worker": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz",
+ "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "jest-util": "^29.7.0",
+ "merge-stream": "^2.0.0",
+ "supports-color": "^8.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/jest-worker/node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsdom": {
+ "version": "20.0.3",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz",
+ "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "abab": "^2.0.6",
+ "acorn": "^8.8.1",
+ "acorn-globals": "^7.0.0",
+ "cssom": "^0.5.0",
+ "cssstyle": "^2.3.0",
+ "data-urls": "^3.0.2",
+ "decimal.js": "^10.4.2",
+ "domexception": "^4.0.0",
+ "escodegen": "^2.0.0",
+ "form-data": "^4.0.0",
+ "html-encoding-sniffer": "^3.0.0",
+ "http-proxy-agent": "^5.0.0",
+ "https-proxy-agent": "^5.0.1",
+ "is-potential-custom-element-name": "^1.0.1",
+ "nwsapi": "^2.2.2",
+ "parse5": "^7.1.1",
+ "saxes": "^6.0.0",
+ "symbol-tree": "^3.2.4",
+ "tough-cookie": "^4.1.2",
+ "w3c-xmlserializer": "^4.0.0",
+ "webidl-conversions": "^7.0.0",
+ "whatwg-encoding": "^2.0.0",
+ "whatwg-mimetype": "^3.0.0",
+ "whatwg-url": "^11.0.0",
+ "ws": "^8.11.0",
+ "xml-name-validator": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "peerDependencies": {
+ "canvas": "^2.5.0"
+ },
+ "peerDependenciesMeta": {
+ "canvas": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
+ "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json5": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "json5": "lib/cli.js"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/kleur": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz",
+ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/live-server": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/live-server/-/live-server-1.2.2.tgz",
+ "integrity": "sha512-t28HXLjITRGoMSrCOv4eZ88viHaBVIjKjdI5PO92Vxlu+twbk6aE0t7dVIaz6ZWkjPilYFV6OSdMYl9ybN2B4w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "chokidar": "^2.0.4",
+ "colors": "1.4.0",
+ "connect": "^3.6.6",
+ "cors": "latest",
+ "event-stream": "3.3.4",
+ "faye-websocket": "0.11.x",
+ "http-auth": "3.1.x",
+ "morgan": "^1.9.1",
+ "object-assign": "latest",
+ "opn": "latest",
+ "proxy-middleware": "latest",
+ "send": "latest",
+ "serve-index": "^1.9.1"
+ },
+ "bin": {
+ "live-server": "live-server.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lru-cache": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
+ "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^3.0.2"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/make-dir/node_modules/semver": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/makeerror": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz",
+ "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tmpl": "1.0.5"
+ }
+ },
+ "node_modules/map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/map-stream": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
+ "integrity": "sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==",
+ "dev": true
+ },
+ "node_modules/map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "object-visit": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/merge-descriptors": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
+ "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==",
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/mixin-deep": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+ "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "for-in": "^1.0.2",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/mixin-deep/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/morgan": {
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.1.tgz",
+ "integrity": "sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "basic-auth": "~2.0.1",
+ "debug": "2.6.9",
+ "depd": "~2.0.0",
+ "on-finished": "~2.3.0",
+ "on-headers": "~1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/morgan/node_modules/on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "node_modules/nan": {
+ "version": "2.23.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.23.0.tgz",
+ "integrity": "sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/nanomatch": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "fragment-cache": "^0.2.1",
+ "is-windows": "^1.0.2",
+ "kind-of": "^6.0.2",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/nanomatch/node_modules/define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/nanomatch/node_modules/extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/nanomatch/node_modules/is-descriptor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz",
+ "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.1",
+ "is-data-descriptor": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/nanomatch/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/nanomatch/node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/node-int64": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz",
+ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-releases": {
+ "version": "2.0.18",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz",
+ "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/nwsapi": {
+ "version": "2.2.13",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.13.tgz",
+ "integrity": "sha512-cTGB9ptp9dY9A5VbMSe7fQBcl/tt22Vcqdq8+eN93rblOuE0aCFu4aZ2vMwct/2t+lFnosm8RkQW1I0Omb1UtQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "copy-descriptor": "^0.1.0",
+ "define-property": "^0.2.5",
+ "kind-of": "^3.0.3"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-copy/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
+ "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "isobject": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/on-headers": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz",
+ "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/opn": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/opn/-/opn-6.0.0.tgz",
+ "integrity": "sha512-I9PKfIZC+e4RXZ/qr1RhgyCnGgYX0UEIlXgWnCOVACIvFgaC9rz6Won7xbdhoHrd8IIhV7YEpHjreNUNkqCGkQ==",
+ "deprecated": "The package has been renamed to `open`",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-wsl": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/p-locate/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "license": "MIT",
+ "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"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parse5": {
+ "version": "7.2.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
+ "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "entities": "^4.5.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-dirname": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+ "integrity": "sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-to-regexp": {
+ "version": "0.1.12",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
+ "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ=="
+ },
+ "node_modules/pause-stream": {
+ "version": "0.0.11",
+ "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
+ "integrity": "sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==",
+ "dev": true,
+ "license": [
+ "MIT",
+ "Apache2"
+ ],
+ "dependencies": {
+ "through": "~2.3"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pirates": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz",
+ "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/pkg-dir": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
+ "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "find-up": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/pretty-format": {
+ "version": "29.7.0",
+ "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
+ "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jest/schemas": "^29.6.3",
+ "ansi-styles": "^5.0.0",
+ "react-is": "^18.0.0"
+ },
+ "engines": {
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+ }
+ },
+ "node_modules/pretty-format/node_modules/ansi-styles": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/prompts": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz",
+ "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kleur": "^3.0.3",
+ "sisteransi": "^1.0.5"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ },
+ "node_modules/proxy-middleware": {
+ "version": "0.15.0",
+ "resolved": "https://registry.npmjs.org/proxy-middleware/-/proxy-middleware-0.15.0.tgz",
+ "integrity": "sha512-EGCG8SeoIRVMhsqHQUdDigB2i7qU7fCsWASwn54+nPutYO8n4q6EiwMzyfWlC+dzRFExP+kvcnDFdBDHoZBU7Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/psl": {
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.13.0.tgz",
+ "integrity": "sha512-BFwmFXiJoFqlUpZ5Qssolv15DMyc84gTBds1BjsV1BfXEo1UyyD7GsmN67n7J77uRhoSNW1AXtXKPLcBFQn9Aw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.3.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/pure-rand": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz",
+ "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/dubzzz"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fast-check"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/qs": {
+ "version": "6.13.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
+ "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
+ "dependencies": {
+ "side-channel": "^1.0.6"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/querystringify": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
+ "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz",
+ "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==",
+ "dependencies": {
+ "bytes": "3.1.2",
+ "http-errors": "2.0.0",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/react-is": {
+ "version": "18.3.1",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
+ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/readable-stream/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/readdirp": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "graceful-fs": "^4.1.11",
+ "micromatch": "^3.1.10",
+ "readable-stream": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/readdirp/node_modules/braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/readdirp/node_modules/define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/readdirp/node_modules/fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/readdirp/node_modules/is-descriptor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz",
+ "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.1",
+ "is-data-descriptor": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/readdirp/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/readdirp/node_modules/is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/readdirp/node_modules/is-number/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/readdirp/node_modules/kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/readdirp/node_modules/micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/readdirp/node_modules/micromatch/node_modules/extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/readdirp/node_modules/to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "extend-shallow": "^3.0.2",
+ "safe-regex": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/regex-not/node_modules/extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/regex-not/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/remove-trailing-separator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/repeat-element": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz",
+ "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/requires-port": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/resolve": {
+ "version": "1.22.8",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
+ "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-core-module": "^2.13.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/resolve-cwd": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz",
+ "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==",
+ "deprecated": "https://github.com/lydell/resolve-url#deprecated",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/resolve.exports": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz",
+ "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12"
+ }
+ },
+ "node_modules/rxjs": {
+ "version": "7.8.2",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
+ "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "tslib": "^2.1.0"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ret": "~0.1.10"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "node_modules/saxes": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
+ "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "xmlchars": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=v12.22.7"
+ }
+ },
+ "node_modules/semver": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/send": {
+ "version": "0.19.0",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
+ "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==",
+ "dependencies": {
+ "debug": "2.6.9",
+ "depd": "2.0.0",
+ "destroy": "1.2.0",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "2.0.0",
+ "mime": "1.6.0",
+ "ms": "2.1.3",
+ "on-finished": "2.4.1",
+ "range-parser": "~1.2.1",
+ "statuses": "2.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/send/node_modules/encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/send/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ },
+ "node_modules/serve-index": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
+ "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "~1.3.4",
+ "batch": "0.6.1",
+ "debug": "2.6.9",
+ "escape-html": "~1.0.3",
+ "http-errors": "~1.6.2",
+ "mime-types": "~2.1.17",
+ "parseurl": "~1.3.2"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/serve-index/node_modules/depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/serve-index/node_modules/http-errors": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.0",
+ "statuses": ">= 1.4.0 < 2"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/serve-index/node_modules/inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/serve-index/node_modules/setprototypeof": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/serve-index/node_modules/statuses": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/serve-static": {
+ "version": "1.16.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz",
+ "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==",
+ "dependencies": {
+ "encodeurl": "~2.0.0",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.19.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/set-function-length": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
+ "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
+ "dependencies": {
+ "define-data-property": "^1.1.4",
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2",
+ "get-intrinsic": "^1.2.4",
+ "gopd": "^1.0.1",
+ "has-property-descriptors": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/set-value": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+ "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "extend-shallow": "^2.0.1",
+ "is-extendable": "^0.1.1",
+ "is-plain-object": "^2.0.3",
+ "split-string": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shell-quote": {
+ "version": "1.8.3",
+ "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz",
+ "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
+ "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
+ "dependencies": {
+ "call-bind": "^1.0.7",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.4",
+ "object-inspect": "^1.13.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/simple-git": {
+ "version": "3.27.0",
+ "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.27.0.tgz",
+ "integrity": "sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==",
+ "dependencies": {
+ "@kwsites/file-exists": "^1.1.1",
+ "@kwsites/promise-deferred": "^1.1.1",
+ "debug": "^4.3.5"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/steveukx/git-js?sponsor=1"
+ }
+ },
+ "node_modules/simple-git/node_modules/debug": {
+ "version": "4.3.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/simple-git/node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
+ },
+ "node_modules/sisteransi": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
+ "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/snapdragon": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "base": "^0.11.1",
+ "debug": "^2.2.0",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "map-cache": "^0.2.2",
+ "source-map": "^0.5.6",
+ "source-map-resolve": "^0.5.0",
+ "use": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.0",
+ "snapdragon-util": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-node/node_modules/define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-node/node_modules/is-descriptor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz",
+ "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.1",
+ "is-data-descriptor": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.2.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon-util/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/snapdragon/node_modules/source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-resolve": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz",
+ "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==",
+ "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "atob": "^2.1.2",
+ "decode-uri-component": "^0.2.0",
+ "resolve-url": "^0.2.1",
+ "source-map-url": "^0.4.0",
+ "urix": "^0.1.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.13",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
+ "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/source-map-url": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz",
+ "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==",
+ "deprecated": "See https://github.com/lydell/source-map-url#deprecated",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/split": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz",
+ "integrity": "sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "through": "2"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "extend-shallow": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/split-string/node_modules/extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/split-string/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/stack-utils": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
+ "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-property": "^0.2.5",
+ "object-copy": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/statuses": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
+ "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/stream-combiner": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
+ "integrity": "sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "duplexer": "~0.1.1"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/string_decoder/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/string-length": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
+ "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "char-regex": "^1.0.2",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
+ "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/symbol-tree": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/test-exclude": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+ "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^7.1.4",
+ "minimatch": "^3.0.4"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tmpl": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
+ "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-object-path/node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "regex-not": "^1.0.2",
+ "safe-regex": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/to-regex/node_modules/define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-regex/node_modules/extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-regex/node_modules/is-descriptor": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.3.tgz",
+ "integrity": "sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-accessor-descriptor": "^1.0.1",
+ "is-data-descriptor": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/to-regex/node_modules/is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-plain-object": "^2.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/tough-cookie": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz",
+ "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "psl": "^1.1.33",
+ "punycode": "^2.1.1",
+ "universalify": "^0.2.0",
+ "url-parse": "^1.5.3"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
+ "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "punycode": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/tree-kill": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
+ "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "tree-kill": "cli.js"
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "dev": true,
+ "license": "0BSD"
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "dependencies": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "6.20.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
+ "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/union-value": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+ "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "arr-union": "^3.1.0",
+ "get-value": "^2.0.6",
+ "is-extendable": "^0.1.1",
+ "set-value": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/universalify": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
+ "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.0.0"
+ }
+ },
+ "node_modules/unix-crypt-td-js": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/unix-crypt-td-js/-/unix-crypt-td-js-1.1.4.tgz",
+ "integrity": "sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw==",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-value": "^0.3.1",
+ "isobject": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/unset-value/node_modules/has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-value": "^2.0.3",
+ "has-values": "^0.1.4",
+ "isobject": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/unset-value/node_modules/has-value/node_modules/isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "isarray": "1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/unset-value/node_modules/has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/upath": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
+ "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4",
+ "yarn": "*"
+ }
+ },
+ "node_modules/update-browserslist-db": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
+ "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/browserslist"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/browserslist"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.0"
+ },
+ "bin": {
+ "update-browserslist-db": "cli.js"
+ },
+ "peerDependencies": {
+ "browserslist": ">= 4.21.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==",
+ "deprecated": "Please see https://github.com/lydell/urix#deprecated",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/url-parse": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
+ "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "querystringify": "^2.1.1",
+ "requires-port": "^1.0.0"
+ }
+ },
+ "node_modules/use": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==",
+ "engines": {
+ "node": ">= 0.4.0"
+ }
+ },
+ "node_modules/uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+ "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "uuid": "bin/uuid"
+ }
+ },
+ "node_modules/v8-to-istanbul": {
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz",
+ "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.12",
+ "@types/istanbul-lib-coverage": "^2.0.1",
+ "convert-source-map": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10.12.0"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/w3c-xmlserializer": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
+ "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "xml-name-validator": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/walker": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
+ "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "makeerror": "1.0.12"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/websocket-driver": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
+ "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "http-parser-js": ">=0.5.1",
+ "safe-buffer": ">=5.1.0",
+ "websocket-extensions": ">=0.1.1"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/websocket-extensions": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
+ "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/whatwg-encoding": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
+ "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "0.6.3"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/whatwg-encoding/node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/whatwg-mimetype": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz",
+ "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/whatwg-url": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz",
+ "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "^3.0.0",
+ "webidl-conversions": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/write-file-atomic": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz",
+ "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^3.0.7"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/ws": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
+ "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.0.0"
+ },
+ "peerDependencies": {
+ "bufferutil": "^4.0.1",
+ "utf-8-validate": ">=5.0.2"
+ },
+ "peerDependenciesMeta": {
+ "bufferutil": {
+ "optional": true
+ },
+ "utf-8-validate": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/xml-name-validator": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
+ "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/xmlchars": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
+ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "dev": true,
+ "license": "MIT",
+ "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"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 00000000..d9153f85
--- /dev/null
+++ b/package.json
@@ -0,0 +1,38 @@
+{
+ "name": "digitalbonesbox",
+ "version": "1.0.0",
+ "type": "module",
+ "description": "This project is a Web App project aims to convert an existing PowerPoint-based educational tool into an interactive, mobile-friendly web application.",
+ "main": "server.js",
+ "scripts": {
+ "test": "jest",
+ "start": "concurrently \"npm run start:api\" \"npm run start:web\"",
+ "start:api": "npm start --prefix boneset-api",
+ "start:web": "live-server --port=5500 --open=templates/boneset.html",
+ "lint": "eslint . --ext .js",
+ "lint:fix": "eslint . --ext .js --fix"
+ },
+ "jest": {
+ "testEnvironment": "jsdom"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "dependencies": {
+ "axios": "^1.8.4",
+ "body-parser": "^1.20.3",
+ "cors": "^2.8.5",
+ "express": "^4.21.2",
+ "simple-git": "^3.27.0"
+ },
+ "devDependencies": {
+ "concurrently": "^9.2.1",
+ "eslint": "^9.24.0",
+ "jest": "^29.7.0",
+ "jest-environment-jsdom": "^29.7.0",
+ "live-server": "^1.2.2"
+ },
+ "directories": {
+ "test": "tests"
+ }
+}
diff --git a/templates/boneset.html b/templates/boneset.html
new file mode 100644
index 00000000..ec0c4085
--- /dev/null
+++ b/templates/boneset.html
@@ -0,0 +1,94 @@
+
+
+
+
+
+
+ Bone Set Viewer
+
+
+
+
+
+
+
+
+
Home
+
Tutor
+
Study
+
+
+ Login
+ Sign Up
+
+
+
+
+
+
+
+
Bone Set Viewer
+
+
+
+
+
+
+
+
Choose a Boneset, Bone, or Sub-bone:
+
+
+ --Please select a Boneset--
+
+
+ --Please select a Bone--
+
+
+ --Please choose a Sub-Bone--
+
+
+
+
+
+
+
+ Previous
+ Next
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/templates/helpButton.html b/templates/helpButton.html
new file mode 100644
index 00000000..8694784d
--- /dev/null
+++ b/templates/helpButton.html
@@ -0,0 +1,43 @@
+
+ Help
+
+
+
+
+
How to Use the Bone Set Viewer
+
+
+ Use the dropdown menus to navigate through the bone sets
+ Select a boneset first, then choose specific bones
+ View detailed images and descriptions for each selection
+ Use the Previous/Next buttons to browse through items
+ Press ESC key or click Close to dismiss this help window
+
+
+ Close Guide
+
+
+
+
\ No newline at end of file
diff --git a/templates/js/api.js b/templates/js/api.js
new file mode 100644
index 00000000..2741e8d6
--- /dev/null
+++ b/templates/js/api.js
@@ -0,0 +1,42 @@
+// api.js - Centralized API configuration and data fetching
+
+// Centralized API configuration
+const API_CONFIG = {
+ BASE_URL: "http://127.0.0.1:8000",
+ ENDPOINTS: {
+ COMBINED_DATA: "/combined-data",
+ MOCK_BONE_DATA: "./js/mock-bone-data.json"
+ }
+};
+
+export async function fetchCombinedData() {
+ const API_URL = `${API_CONFIG.BASE_URL}${API_CONFIG.ENDPOINTS.COMBINED_DATA}`;
+
+ try {
+ const response = await fetch(API_URL);
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ }
+ return await response.json();
+ } catch (error) {
+ console.error("Error fetching combined data:", error);
+ throw error;
+ }
+}
+
+export async function fetchMockBoneData() {
+ try {
+ const response = await fetch(API_CONFIG.ENDPOINTS.MOCK_BONE_DATA);
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ }
+ const data = await response.json();
+ return data;
+ } catch (error) {
+ console.error("Error fetching mock bone data:", error);
+ return null;
+ }
+}
+
+// Export configuration for other modules to use
+export { API_CONFIG };
diff --git a/templates/js/description.js b/templates/js/description.js
new file mode 100644
index 00000000..6e418326
--- /dev/null
+++ b/templates/js/description.js
@@ -0,0 +1,26 @@
+// js/description.js
+const GITHUB_RAW_URL = "https://raw.githubusercontent.com/oss-slu/DigitalBonesBox/data/DataPelvis/descriptions/";
+
+export async function loadDescription(id) {
+ const container = document.getElementById("description-Container");
+ container.innerHTML = "";
+ const descUrl = `${GITHUB_RAW_URL}${id}_description.json`;
+
+ try {
+ const response = await fetch(descUrl);
+ const data = await response.json();
+
+ const nameItem = document.createElement("li");
+ nameItem.innerHTML = `${data.name} `;
+ container.appendChild(nameItem);
+
+ data.description.forEach(point => {
+ const li = document.createElement("li");
+ li.textContent = point;
+ container.appendChild(li);
+ });
+ } catch (error) {
+ container.innerHTML = "Error loading description. ";
+ console.error("Failed to fetch description:", error);
+ }
+}
diff --git a/templates/js/dropdowns.js b/templates/js/dropdowns.js
new file mode 100644
index 00000000..aa447b52
--- /dev/null
+++ b/templates/js/dropdowns.js
@@ -0,0 +1,65 @@
+// js/dropdowns.js
+import { loadDescription } from "./description.js";
+
+export function populateBonesetDropdown(bonesets) {
+ const bonesetSelect = document.getElementById("boneset-select");
+ bonesetSelect.innerHTML = "--Please select a Boneset-- ";
+
+ bonesets.forEach((set) => {
+ const option = document.createElement("option");
+ option.value = set.id;
+ option.textContent = set.name;
+ bonesetSelect.appendChild(option);
+ });
+}
+
+export function setupDropdownListeners(combinedData) {
+ const bonesetSelect = document.getElementById("boneset-select");
+ const boneSelect = document.getElementById("bone-select");
+ const subboneSelect = document.getElementById("subbone-select");
+
+ bonesetSelect.addEventListener("change", (e) => {
+ const selectedBonesetId = e.target.value;
+
+ boneSelect.innerHTML = "--Please choose a Bone-- ";
+ subboneSelect.innerHTML = "--Please choose a Sub-Bone-- ";
+ subboneSelect.disabled = true;
+
+ const relatedBones = combinedData.bones.filter(
+ (b) => b.boneset === selectedBonesetId
+ );
+ relatedBones.forEach((bone) => {
+ const option = document.createElement("option");
+ option.value = bone.id;
+ option.textContent = bone.name;
+ boneSelect.appendChild(option);
+ });
+
+ boneSelect.disabled = relatedBones.length === 0;
+ });
+
+ boneSelect.addEventListener("change", (e) => {
+ const selectedBoneId = e.target.value;
+
+ subboneSelect.innerHTML = "--Please choose a Sub-Bone-- ";
+
+ const relatedSubbones = combinedData.subbones.filter(
+ (sb) => sb.bone === selectedBoneId
+ );
+ relatedSubbones.forEach((sb) => {
+ const option = document.createElement("option");
+ option.value = sb.id;
+ option.textContent = sb.name;
+ subboneSelect.appendChild(option);
+ });
+
+ subboneSelect.disabled = relatedSubbones.length === 0;
+
+ if (selectedBoneId) loadDescription(selectedBoneId);
+ });
+
+ subboneSelect.addEventListener("change", (e) => {
+ const selectedSubboneId = e.target.value;
+ if (selectedSubboneId) loadDescription(selectedSubboneId);
+ });
+}
diff --git a/templates/js/main.js b/templates/js/main.js
new file mode 100644
index 00000000..e53df251
--- /dev/null
+++ b/templates/js/main.js
@@ -0,0 +1,94 @@
+import { fetchCombinedData, fetchMockBoneData } from "./api.js";
+import { populateBonesetDropdown, setupDropdownListeners } from "./dropdowns.js";
+import { initializeSidebar, loadHelpButton } from "./sidebar.js";
+import { setupNavigation, setBoneAndSubbones, disableButtons } from "./navigation.js";
+import { loadDescription } from "./description.js";
+import { displayBoneData, clearViewer } from "./viewer.js";
+import { initializeSearch } from "./search.js";
+
+let combinedData = { bonesets: [], bones: [], subbones: [] };
+let mockBoneData = null;
+
+/**
+ * Handles bone selection from dropdown
+ * @param {string} boneId - The ID of the selected bone
+ */
+function handleBoneSelection(boneId) {
+ if (!mockBoneData) {
+ console.log("Mock data not available");
+ return;
+ }
+
+ const bone = mockBoneData.bones.find(b => b.id === boneId);
+ if (!bone) {
+ console.log(`No mock data found for bone: ${boneId}`);
+ clearViewer();
+ return;
+ }
+
+ // Use the dedicated viewer module to display the bone
+ displayBoneData(bone);
+}
+
+document.addEventListener("DOMContentLoaded", async () => {
+ // 1. Initialize search functionality
+ initializeSearch();
+
+ // 2. Sidebar behavior and help button
+ initializeSidebar();
+ loadHelpButton();
+
+ // 3. Load mock bone data using centralized API
+ mockBoneData = await fetchMockBoneData();
+
+ // 4. Fetch data and populate dropdowns
+ combinedData = await fetchCombinedData();
+ populateBonesetDropdown(combinedData.bonesets);
+ setupDropdownListeners(combinedData);
+
+ // 5. Setup navigation after everything else
+ setupNavigation(combinedData);
+ disableButtons();
+
+ // 6. Update navigation when bone changes
+ const boneDropdown = document.getElementById("bone-select");
+ boneDropdown.addEventListener("change", (event) => {
+ const selectedBone = event.target.value;
+
+ const relatedSubbones = combinedData.subbones
+ .filter(sb => sb.bone === selectedBone)
+ .map(sb => sb.id);
+
+ setBoneAndSubbones(selectedBone, relatedSubbones);
+ populateSubboneDropdown(document.getElementById("subbone-select"), relatedSubbones);
+ disableButtons();
+
+ // Handle bone selection using dedicated function
+ if (selectedBone) {
+ handleBoneSelection(selectedBone);
+ } else {
+ clearViewer();
+ }
+ });
+
+ // 7. Auto-select the first boneset
+ const boneset = combinedData.bonesets[0];
+ if (boneset) {
+ document.getElementById("boneset-select").value = boneset.id;
+ const event = new Event("change");
+ document.getElementById("boneset-select").dispatchEvent(event);
+ }
+
+ // 8. Initialize display
+ clearViewer();
+});
+
+function populateSubboneDropdown(dropdown, subbones) {
+ dropdown.innerHTML = "";
+ subbones.forEach((subboneId) => {
+ const option = document.createElement("option");
+ option.value = subboneId;
+ option.textContent = subboneId.replace(/_/g, " ");
+ dropdown.appendChild(option);
+ });
+}
diff --git a/templates/js/navigation.js b/templates/js/navigation.js
new file mode 100644
index 00000000..7e087160
--- /dev/null
+++ b/templates/js/navigation.js
@@ -0,0 +1,49 @@
+let currentBone = null;
+let currentSubboneIndex = -1;
+let subbones = [];
+
+export function setupNavigation(prevButton, nextButton, subboneDropdown, updateDescription) {
+ prevButton.addEventListener("click", () => {
+ prevSubbone();
+ updateUI(subboneDropdown, updateDescription);
+ });
+
+ nextButton.addEventListener("click", () => {
+ nextSubbone();
+ updateUI(subboneDropdown, updateDescription);
+ });
+
+ disableButtons(prevButton, nextButton);
+}
+
+export function setBoneAndSubbones(bone, boneSubbones) {
+ currentBone = bone;
+ subbones = boneSubbones || [];
+ currentSubboneIndex = subbones.length > 0 ? 0 : -1;
+}
+
+function prevSubbone() {
+ if (currentSubboneIndex > 0) {
+ currentSubboneIndex--;
+ }
+}
+
+function nextSubbone() {
+ if (currentSubboneIndex < subbones.length - 1) {
+ currentSubboneIndex++;
+ }
+}
+
+function updateUI(subboneDropdown, updateDescription) {
+ if (subbones.length === 0 || currentSubboneIndex === -1) return;
+
+ subboneDropdown.selectedIndex = currentSubboneIndex;
+ const selectedSubbone = subbones[currentSubboneIndex];
+ updateDescription(selectedSubbone);
+}
+
+export function disableButtons(prevButton, nextButton) {
+ const disabled = subbones.length === 0;
+ prevButton.disabled = disabled;
+ nextButton.disabled = disabled;
+}
diff --git a/templates/js/search.js b/templates/js/search.js
new file mode 100644
index 00000000..01cc1e57
--- /dev/null
+++ b/templates/js/search.js
@@ -0,0 +1,186 @@
+let selectedIndex = -1;
+let searchTimeout;
+
+// Handle search result clicks and keyboard navigation
+export function initializeSearch() {
+ const searchBar = document.getElementById("search-bar");
+ const searchResultsContainer = document.getElementById("search-results");
+ const searchLoading = document.getElementById("search-loading");
+
+ if (!searchBar || !searchResultsContainer) {
+ console.error("Search elements not found");
+ return;
+ }
+
+ console.log("Search initialized");
+
+ // Handle typing in search bar
+ searchBar.addEventListener("input", (e) => {
+ clearTimeout(searchTimeout);
+ const query = e.target.value.trim();
+
+ if (query.length < 2) {
+ searchResultsContainer.innerHTML = "";
+ searchLoading.style.display = "none";
+ return;
+ }
+
+ searchLoading.style.display = "block";
+
+ searchTimeout = setTimeout(() => {
+ performSearch(query);
+ }, 300);
+ });
+
+ // Handle keyboard navigation
+ searchBar.addEventListener("keydown", (e) => {
+ const results = searchResultsContainer.querySelectorAll(".search-result");
+
+ if (e.key === "ArrowDown") {
+ e.preventDefault();
+ selectedIndex = Math.min(selectedIndex + 1, results.length - 1);
+ updateSelection(results);
+ } else if (e.key === "ArrowUp") {
+ e.preventDefault();
+ selectedIndex = Math.max(selectedIndex - 1, -1);
+ updateSelection(results);
+ } else if (e.key === "Enter") {
+ e.preventDefault();
+ if (selectedIndex >= 0 && results[selectedIndex]) {
+ selectSearchResult(results[selectedIndex]);
+ }
+ } else if (e.key === "Escape") {
+ clearSearch();
+ }
+ });
+
+ // Handle clicks outside search to close results
+ document.addEventListener("click", (e) => {
+ if (!searchBar.contains(e.target) && !searchResultsContainer.contains(e.target)) {
+ if (!e.target.closest(".search-result")) {
+ clearSearchResults();
+ }
+ }
+ });
+}
+
+async function performSearch(query) {
+ const searchResultsContainer = document.getElementById("search-results");
+ const searchLoading = document.getElementById("search-loading");
+
+ try {
+ console.log("Performing search for:", query);
+ const response = await fetch(`http://127.0.0.1:8000/api/search?q=${encodeURIComponent(query)}`);
+
+ if (!response.ok) {
+ throw new Error(`HTTP error! status: ${response.status}`);
+ }
+
+ const html = await response.text();
+ console.log("Search response received");
+
+ searchResultsContainer.innerHTML = html;
+ searchLoading.style.display = "none";
+ selectedIndex = -1;
+
+ // Attach click handlers to new results
+ attachClickHandlers();
+
+ } catch (error) {
+ console.error("Search error:", error);
+ searchResultsContainer.innerHTML = "Search failed. Make sure the server is running. ";
+ searchLoading.style.display = "none";
+ }
+}
+
+function attachClickHandlers() {
+ const results = document.querySelectorAll(".search-result");
+ results.forEach(result => {
+ result.addEventListener("click", (e) => {
+ e.preventDefault();
+ selectSearchResult(result);
+ });
+ });
+}
+
+function updateSelection(results) {
+ results.forEach((result, index) => {
+ if (index === selectedIndex) {
+ result.classList.add("selected");
+ result.scrollIntoView({ block: "nearest" });
+ } else {
+ result.classList.remove("selected");
+ }
+ });
+}
+
+function selectSearchResult(resultElement) {
+ const type = resultElement.dataset.type;
+ const bonesetId = resultElement.dataset.boneset;
+ const boneId = resultElement.dataset.bone;
+ const subboneId = resultElement.dataset.subbone;
+
+ console.log("Selected search result:", { type, bonesetId, boneId, subboneId });
+
+ // Update dropdowns based on search result
+ updateDropdowns(type, bonesetId, boneId, subboneId);
+
+ // Clear search after selection
+ clearSearch();
+}
+
+function updateDropdowns(type, bonesetId, boneId, subboneId) {
+ const bonesetSelect = document.getElementById("boneset-select");
+ const boneSelect = document.getElementById("bone-select");
+ const subboneSelect = document.getElementById("subbone-select");
+
+ // Always set boneset first
+ if (bonesetId && bonesetSelect) {
+ bonesetSelect.value = bonesetId;
+ bonesetSelect.dispatchEvent(new Event("change"));
+
+ // Wait for bone dropdown to populate, then set bone
+ if (boneId && (type === "bone" || type === "subbone")) {
+ setTimeout(() => {
+ if (boneSelect) {
+ boneSelect.disabled = false;
+ boneSelect.value = boneId;
+ boneSelect.dispatchEvent(new Event("change"));
+
+ // Wait for subbone dropdown to populate, then set subbone
+ if (subboneId && type === "subbone") {
+ setTimeout(() => {
+ if (subboneSelect) {
+ subboneSelect.disabled = false;
+ subboneSelect.value = subboneId;
+ subboneSelect.dispatchEvent(new Event("change"));
+ }
+ }, 200);
+ }
+ }
+ }, 200);
+ }
+ }
+}
+
+function clearSearch() {
+ const searchBar = document.getElementById("search-bar");
+ searchBar.value = "";
+ clearSearchResults();
+}
+
+function clearSearchResults() {
+ const searchResults = document.getElementById("search-results");
+ const searchLoading = document.getElementById("search-loading");
+
+ if (searchResults) {
+ searchResults.innerHTML = "";
+ }
+ if (searchLoading) {
+ searchLoading.style.display = "none";
+ }
+ selectedIndex = -1;
+}
+
+// Initialize when DOM is loaded
+document.addEventListener("DOMContentLoaded", initializeSearch);
\ No newline at end of file
diff --git a/templates/js/sidebar.js b/templates/js/sidebar.js
new file mode 100644
index 00000000..7e382119
--- /dev/null
+++ b/templates/js/sidebar.js
@@ -0,0 +1,82 @@
+// js/sidebar.js
+export function initializeSidebar() {
+ const toggleButton = document.getElementById("toggle-sidebar");
+ const sidebarContainer = document.getElementById("sidebar-container");
+
+ async function loadSidebar() {
+ if (!sidebarContainer.innerHTML) {
+ try {
+ const response = await fetch("sidebar.html");
+ const sidebarHTML = await response.text();
+ sidebarContainer.innerHTML = sidebarHTML;
+ } catch (error) {
+ console.error("Error loading sidebar:", error);
+ }
+ }
+ }
+
+ if (toggleButton) {
+ toggleButton.addEventListener("click", async () => {
+ await loadSidebar(); // Ensure the sidebar is loaded
+ const sidebarElement = document.getElementById("sidebar");
+
+ if (sidebarElement) {
+ const currentLeft = window.getComputedStyle(sidebarElement).left;
+ if (currentLeft === "0px") {
+ sidebarElement.style.left = "-250px"; // Close sidebar
+ } else {
+ sidebarElement.style.left = "0px"; // Open sidebar
+ }
+ }
+ });
+ }
+}
+
+export async function loadHelpButton() {
+ const helpButtonContainer = document.getElementById("help-button-container");
+ if (helpButtonContainer) {
+ try {
+ const response = await fetch("helpButton.html");
+ const helpButtonHTML = await response.text();
+ helpButtonContainer.innerHTML = helpButtonHTML;
+
+ const helpButton = document.getElementById("text-button-Help");
+ const helpModal = document.getElementById("help-modal");
+ const closeHelpModal = document.getElementById("close-help-modal");
+
+ if (helpButton && helpModal && closeHelpModal) {
+ // Handle click events
+ helpButton.addEventListener("click", () => {
+ helpModal.classList.add("is-visible");
+ });
+
+ closeHelpModal.addEventListener("click", () => {
+ helpModal.classList.remove("is-visible");
+ });
+
+ // Handle keyboard events
+ helpButton.addEventListener("keydown", (event) => {
+ if (event.key === "Enter" || event.key === " ") {
+ event.preventDefault();
+ helpModal.classList.add("is-visible");
+ }
+ });
+
+ // Close on escape key
+ document.addEventListener("keydown", (event) => {
+ if (event.key === "Escape" && helpModal.classList.contains("is-visible")) {
+ helpModal.classList.remove("is-visible");
+ }
+ });
+ }
+ } catch (error) {
+ console.error("Error loading help button:", error);
+ }
+ }
+}
+
+document.addEventListener("DOMContentLoaded", () => {
+ initializeSidebar();
+ loadHelpButton();
+});
+
diff --git a/templates/js/viewer.js b/templates/js/viewer.js
new file mode 100644
index 00000000..5280be97
--- /dev/null
+++ b/templates/js/viewer.js
@@ -0,0 +1,104 @@
+// viewer.js - Dedicated module for managing viewer state and display
+
+/**
+ * Displays bone image with error handling for broken URLs
+ * @param {Object} boneData - The bone object from mock data
+ */
+export function displayBoneImage(boneData) {
+ const boneImage = document.getElementById("bone-image");
+ if (!boneImage) {
+ console.error("Bone image element not found");
+ return;
+ }
+
+ if (boneData.image_url) {
+ boneImage.src = boneData.image_url;
+ boneImage.alt = `${boneData.name} bone image`;
+ boneImage.style.display = "block";
+
+ // Handle image load errors gracefully
+ boneImage.onerror = () => {
+ console.warn(`Failed to load image for ${boneData.name}: ${boneData.image_url}`);
+ boneImage.src = "https://via.placeholder.com/600x400/CCCCCC/666666?text=Image+Load+Failed";
+ boneImage.alt = `${boneData.name} - Image failed to load`;
+ };
+
+ // Clear any previous error handlers when image loads successfully
+ boneImage.onload = () => {
+ boneImage.onerror = null;
+ };
+ } else {
+ // Handle missing image_url
+ boneImage.src = "https://via.placeholder.com/600x400/CCCCCC/666666?text=No+Image+Available";
+ boneImage.alt = `${boneData.name} - No image available`;
+ boneImage.style.display = "block";
+ console.warn(`No image URL provided for bone: ${boneData.name}`);
+ }
+}
+
+/**
+ * Displays annotations list for the selected bone
+ * @param {Array} annotations - Array of annotation objects
+ */
+export function displayAnnotations(annotations) {
+ const annotationsOverlay = document.getElementById("annotations-overlay");
+ if (!annotationsOverlay) {
+ console.error("Annotations overlay element not found");
+ return;
+ }
+
+ // Clear previous annotations
+ annotationsOverlay.innerHTML = "";
+
+ if (!annotations || annotations.length === 0) {
+ annotationsOverlay.innerHTML = "No annotations available for this bone.
";
+ return;
+ }
+
+ // Create annotation list
+ const annotationsList = document.createElement("ul");
+ annotationsList.className = "annotations-list";
+
+ annotations.forEach((annotation) => {
+ const listItem = document.createElement("li");
+ listItem.className = "annotation-item";
+ listItem.textContent = annotation.text;
+ annotationsList.appendChild(listItem);
+ });
+
+ annotationsOverlay.appendChild(annotationsList);
+}
+
+/**
+ * Main function to display complete bone data (image + annotations)
+ * @param {Object} boneData - The complete bone object
+ */
+export function displayBoneData(boneData) {
+ if (!boneData) {
+ console.error("No bone data provided to display");
+ return;
+ }
+
+ displayBoneImage(boneData);
+ displayAnnotations(boneData.annotations);
+}
+
+/**
+ * Clears the viewer display
+ */
+export function clearViewer() {
+ const boneImage = document.getElementById("bone-image");
+ const annotationsOverlay = document.getElementById("annotations-overlay");
+
+ if (boneImage) {
+ boneImage.src = "";
+ boneImage.alt = "";
+ boneImage.style.display = "none";
+ boneImage.onerror = null; // Clear error handlers
+ boneImage.onload = null;
+ }
+
+ if (annotationsOverlay) {
+ annotationsOverlay.innerHTML = "Select a bone to view image and annotations.
";
+ }
+}
\ No newline at end of file
diff --git a/templates/sidebar.html b/templates/sidebar.html
new file mode 100644
index 00000000..74d8cd34
--- /dev/null
+++ b/templates/sidebar.html
@@ -0,0 +1,52 @@
+
+
+
+
+
diff --git a/templates/style.css b/templates/style.css
new file mode 100644
index 00000000..730828a1
--- /dev/null
+++ b/templates/style.css
@@ -0,0 +1,447 @@
+body {
+ font-family: Arial, sans-serif;
+ background-color: #f9f9f9;
+ margin: 0;
+ padding: 0;
+}
+
+.container {
+ width: 80%;
+ margin: 40px auto;
+ background-color: #fff;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+ padding: 20px;
+ border-radius: 8px;
+}
+
+h1 {
+ text-align: center;
+ color: #333;
+}
+
+input[type="text"] {
+ width: 100%;
+ padding: 10px;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ margin-bottom: 10px;
+}
+
+#search-results {
+ list-style-type: none;
+ padding: 0;
+ margin: 0;
+}
+
+#search-results li {
+ padding: 10px;
+ background-color: #e6f7ff;
+ border: 1px solid #d9d9d9;
+ margin-bottom: 5px;
+ border-radius: 4px;
+ cursor: pointer;
+}
+
+#search-results li:hover {
+ background-color: #bae7ff;
+}
+
+label {
+ font-weight: bold;
+ margin-right: 10px;
+}
+
+select {
+ width: 100%;
+ padding: 10px;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+}
+
+.navigation-buttons {
+ display: flex;
+ justify-content: space-between;
+ margin-top: 20px;
+}
+
+button {
+ padding: 10px 20px;
+ background-color: #007bff;
+ color: #fff;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+}
+
+button:disabled {
+ background-color: #ccc;
+}
+
+button:hover:not(:disabled) {
+ background-color: #0056b3;
+}
+
+#bone-sets-container {
+ margin-top: 20px;
+}
+
+h2 {
+ color: #333;
+}
+
+ul {
+ list-style-type: none;
+ padding: 0;
+}
+
+ul li {
+ margin: 5px 0;
+}
+
+/* Badge at the top of the webpage */
+#badge {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 50px;
+ background-color: #333;
+ color: #fff;
+ display: flex;
+ align-items: center;
+ padding: 0 20px;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+ z-index: 1000; /* Ensures it stays on top of all elements */
+}
+
+#editor-view {
+ margin-top: 40px; /* Add margin to move the content below the badge */
+ padding: 20px; /* Keep consistent padding for readability */
+}
+
+#text-button-Home {
+ padding: 20px;
+ cursor: pointer;
+}
+
+#text-button-Tutor {
+ padding: 20px;
+ cursor: pointer;
+}
+
+#text-button-Study {
+ padding: 20px;
+ cursor: pointer;
+}
+
+#text-button-Help {
+ padding: 20px;
+ cursor: pointer;
+}
+
+#text-button-Login {
+ padding: 20px;
+ cursor: pointer;
+ align-items: right;
+}
+
+#text-button-SignUp {
+ padding: 20px;
+ cursor: pointer;
+ align-items: right;
+}
+
+#innerbadge {
+ display: flex; /* Enable Flexbox for the container */
+ justify-content: flex-end; /* Align items to the far right */
+ align-items: center; /* Optional: Vertically center the items */
+ width: 100%; /* Ensure the container spans the full width of the screen */
+ padding-right: 20px; /* Adds space between the buttons and the right edge */
+ box-sizing: border-box;
+ width: 75%
+}
+
+.annotation-box {
+ position: absolute;
+ border: 2px solid red;
+ background-color: rgba(255, 0, 0, 0.2);
+ cursor: pointer;
+ pointer-events: auto;
+}
+
+.imagescontainer {
+ position: relative;
+ width: 80%;
+ margin: 40px auto;
+ background-color: #fff;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+ border-radius: 8px;
+ overflow: hidden;
+}
+
+/* Image and annotations display styles */
+.viewer-wrapper {
+ display: flex;
+ gap: 20px;
+ margin-top: 20px;
+ align-items: flex-start;
+}
+
+#bone-image {
+ max-width: 600px;
+ height: auto;
+ border: 2px solid #ddd;
+ border-radius: 8px;
+ display: none;
+}
+
+#annotations-overlay {
+ flex: 1;
+ max-width: 400px;
+ padding: 15px;
+ background-color: #f8f9fa;
+ border: 1px solid #dee2e6;
+ border-radius: 8px;
+ min-height: 200px;
+}
+
+.annotations-list {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.annotation-item {
+ background-color: white;
+ margin-bottom: 10px;
+ padding: 12px;
+ border-left: 4px solid #007bff;
+ border-radius: 4px;
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+ font-size: 14px;
+ line-height: 1.4;
+}
+
+.annotation-item:last-child {
+ margin-bottom: 0;
+}
+
+/* Search functionality styles */
+.search-container {
+ position: relative;
+ margin-bottom: 10px;
+}
+
+#search-bar {
+ width: 100%;
+ padding: 12px 16px;
+ border: 2px solid #ddd;
+ border-radius: 8px;
+ font-size: 16px;
+ transition: border-color 0.2s ease;
+ box-sizing: border-box;
+}
+
+#search-bar:focus {
+ outline: none;
+ border-color: #007bff;
+ box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.1);
+}
+
+.search-loading {
+ position: absolute;
+ right: 16px;
+ top: 50%;
+ transform: translateY(-50%);
+ font-size: 12px;
+ color: #666;
+ background: white;
+ padding: 2px 6px;
+ border-radius: 4px;
+}
+
+.search-results {
+ max-height: 300px;
+ overflow-y: auto;
+ border: 1px solid #ddd;
+ border-radius: 8px;
+ background: white;
+ margin-bottom: 20px;
+ box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+ list-style: none;
+ padding: 0;
+ margin: 0 0 20px 0;
+}
+
+.search-results:empty {
+ display: none;
+}
+
+.search-result {
+ padding: 12px 16px;
+ border-bottom: 1px solid #eee;
+ cursor: pointer;
+ transition: background-color 0.2s ease;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.search-result:last-child {
+ border-bottom: none;
+}
+
+.search-result:hover,
+.search-result:focus {
+ background-color: #f0f8ff;
+ outline: none;
+}
+
+.search-result.selected {
+ background-color: #e6f3ff;
+}
+
+.search-result small {
+ color: #666;
+ font-size: 0.85em;
+ font-weight: normal;
+}
+
+.search-placeholder,
+.search-error,
+.search-no-results {
+ padding: 12px 16px;
+ color: #666;
+ font-style: italic;
+ cursor: default;
+ text-align: center;
+}
+
+.search-error {
+ color: #d32f2f;
+}
+
+.search-no-results {
+ color: #666;
+}
+
+/* Responsive design for smaller screens */
+@media (max-width: 768px) {
+ .viewer-wrapper {
+ flex-direction: column;
+ }
+
+ #annotations-overlay {
+ max-width: 100%;
+ }
+
+ #bone-image {
+ max-width: 100%;
+ }
+}
+
+.help-modal {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100vw;
+ height: 100vh;
+ background: rgba(0, 0, 0, 0.85);
+ display: none;
+ z-index: 1000;
+ justify-content: center;
+ align-items: center;
+ padding: 1.5rem;
+ backdrop-filter: blur(4px);
+ transition: opacity 0.3s ease;
+}
+
+.help-modal.is-visible {
+ display: flex;
+ animation: modalFadeIn 0.3s ease;
+}
+
+.help-modal-content {
+ background: linear-gradient(to bottom, #ffffff, #f8f9fa);
+ padding: 1rem;
+ border-radius: 12px;
+ width: 90%;
+ max-width: 500px;
+ max-height: 85vh;
+ overflow-y: auto;
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
+}
+
+#help-modal-title {
+ color: #1a4b8c;
+ font-size: 1.4rem;
+ margin-bottom: 0.5rem;
+ border-bottom: 2px solid #e9ecef;
+ padding-bottom: 0.5rem;
+}
+
+.help-content {
+ padding: 0;
+}
+
+.help-content p {
+ margin-bottom: 0.75rem;
+ line-height: 1.4;
+ color: #1a4b8c;
+}
+
+.help-content ul {
+ margin: 0;
+ padding-left: 1rem;
+}
+
+.help-content li {
+ color: #1a4b8c;
+ margin-bottom: 0.4rem;
+ line-height: 1.3;
+}
+
+#close-help-modal {
+ margin-top: 1rem;
+ padding: 0.5rem 1.25rem;
+ width: auto;
+ min-width: 120px;
+}
+
+#close-help-modal:hover {
+ background-color: #0d2d5e;
+ transform: translateY(-1px);
+ box-shadow: 0 4px 12px rgba(26, 75, 140, 0.2);
+}
+
+#close-help-modal:focus {
+ outline: none;
+ box-shadow: 0 0 0 3px rgba(26, 75, 140, 0.4);
+}
+
+@keyframes modalFadeIn {
+ from { opacity: 0; }
+ to { opacity: 1; }
+}
+
+@keyframes modalSlideUp {
+ from {
+ transform: translateY(20px);
+ opacity: 0;
+ }
+ to {
+ transform: translateY(0);
+ opacity: 1;
+ }
+}
+
+/* High contrast mode support */
+@media (forced-colors: active) {
+ .help-modal-content {
+ border: 2px solid CanvasText;
+ }
+ #close-help-modal {
+ border: 2px solid CanvasText;
+ }
+}
+
diff --git a/templates/test.js b/templates/test.js
new file mode 100644
index 00000000..d3cf594e
--- /dev/null
+++ b/templates/test.js
@@ -0,0 +1,342 @@
+const html = `
+
+
+
+
+
+`;
+document.body.innerHTML = html;
+
+require("./sidebar.js"); // Import the JavaScript code
+
+beforeEach(() => {
+ global.fetch = jest.fn(() =>
+ Promise.resolve({
+ text: () =>
+ Promise.resolve(`
+
+ `),
+ })
+ );
+
+ const sidebarContainer = document.getElementById("sidebar-container");
+ sidebarContainer.innerHTML = ""; // Reset sidebar container
+
+ const sidebarElement = document.getElementById("sidebar");
+ if (sidebarElement) {
+ sidebarElement.style.left = "-250px"; // Explicitly set the initial state
+ }
+});
+
+beforeAll(() => {
+ document.dispatchEvent(new Event("DOMContentLoaded")); // Simulate DOMContentLoaded
+});
+
+afterEach(() => {
+ // Reset sidebar state after each test
+ const sidebarElement = document.getElementById("sidebar");
+ if (sidebarElement) {
+ sidebarElement.style.left = "-250px"; // Ensure sidebar is closed
+ }
+ jest.restoreAllMocks(); // Clean up mocks
+});
+
+describe("Sidebar Toggle Functionality", () => {
+ test("loads sidebar content when the button is clicked", async () => {
+ const toggleButton = document.getElementById("toggle-sidebar");
+ toggleButton.click();
+ await new Promise(process.nextTick);
+
+ const sidebarElement = document.getElementById("sidebar");
+ expect(sidebarElement).toBeTruthy();
+ expect(sidebarElement.innerHTML).toContain("Sidebar Content");
+ });
+
+ test("toggles sidebar open and closed", async () => {
+ const toggleButton = document.getElementById("toggle-sidebar");
+ const sidebarElement = document.getElementById("sidebar");
+
+ // Ensure the sidebar starts hidden
+ let computedStyle = window.getComputedStyle(sidebarElement);
+ expect(computedStyle.left).toBe("-250px"); // Sidebar is initially hidden
+
+ // Simulate opening the sidebar
+ toggleButton.click();
+ await new Promise((resolve) => setTimeout(resolve, 50)); // Wait for event propagation
+ computedStyle = window.getComputedStyle(sidebarElement);
+ expect(computedStyle.left).toBe("0px"); // Sidebar is open
+
+ // Simulate closing the sidebar
+ toggleButton.click();
+ await new Promise((resolve) => setTimeout(resolve, 50)); // Wait for event propagation
+ computedStyle = window.getComputedStyle(sidebarElement);
+ expect(computedStyle.left).toBe("-250px"); // Sidebar is closed
+ });
+});
+
+describe("Badge Button", () => {
+ test("badge button is present and clickable", () => {
+ const badgeButton = document.getElementById("toggle-sidebar");
+ expect(badgeButton).toBeTruthy();
+ expect(badgeButton.tagName).toBe("BUTTON");
+ });
+
+ test("badge button has correct initial text", () => {
+ const badgeButton = document.getElementById("toggle-sidebar");
+ expect(badgeButton.textContent).toBe("☰");
+ });
+});
+
+describe("Sidebar Styling", () => {
+ test("sidebar starts hidden by default", () => {
+ const sidebar = document.getElementById("sidebar");
+ expect(sidebar).toBeTruthy();
+
+ const computedStyle = window.getComputedStyle(sidebar);
+ expect(computedStyle.left).toBe("-250px"); // Sidebar is hidden initially
+ });
+
+ test("sidebar transitions smoothly", () => {
+ const sidebar = document.getElementById("sidebar");
+ expect(sidebar.style.transition).toContain("left 0.3s ease");
+ });
+
+
+});
+
+// testing for viewer display
+
+describe("Viewer Display Logic", () => {
+ let mockBoneData;
+
+ beforeEach(() => {
+ // Add viewer HTML elements to the DOM
+ const viewerHTML = `
+
+
+
+
Select a bone to view image and annotations.
+
+
+ `;
+ document.body.innerHTML += viewerHTML;
+
+ // Mock the bone data structure
+ mockBoneData = {
+ bones: [
+ {
+ id: "ischium",
+ name: "Ischium",
+ image_url: "https://via.placeholder.com/600x400/4A90E2/FFFFFF?text=Ischium+Bone",
+ annotations: [
+ {
+ text: "Ischial Tuberosity - Attachment point for hamstring muscles",
+ position: { x: 300, y: 150 }
+ },
+ {
+ text: "Ischial Spine - Forms part of the lesser sciatic notch",
+ position: { x: 250, y: 100 }
+ },
+ {
+ text: "Ischial Ramus - Forms part of the obturator foramen",
+ position: { x: 350, y: 200 }
+ }
+ ]
+ }
+ ]
+ };
+
+ // Mock fetch for the mock data file
+ global.fetch = jest.fn((url) => {
+ if (url.includes("mock-bone-data.json")) {
+ return Promise.resolve({
+ ok: true,
+ json: () => Promise.resolve(mockBoneData)
+ });
+ }
+ return Promise.reject(new Error("Not found"));
+ });
+ });
+
+ afterEach(() => {
+ // Clean up DOM
+ const viewerWrapper = document.querySelector(".viewer-wrapper");
+ if (viewerWrapper) {
+ viewerWrapper.remove();
+ }
+ jest.restoreAllMocks();
+ });
+
+ test("bone image src attribute is correctly updated after selection", () => {
+ const boneImage = document.getElementById("bone-image");
+ const bone = mockBoneData.bones[0];
+
+ // Simulate the displayBoneData function logic
+ boneImage.src = bone.image_url;
+ boneImage.alt = `${bone.name} bone image`;
+ boneImage.style.display = "block";
+
+ expect(boneImage.src).toBe("https://via.placeholder.com/600x400/4A90E2/FFFFFF?text=Ischium+Bone");
+ expect(boneImage.alt).toBe("Ischium bone image");
+ expect(boneImage.style.display).toBe("block");
+ });
+
+ test("correct number of annotation elements are created in annotations overlay", () => {
+ const annotationsOverlay = document.getElementById("annotations-overlay");
+ const bone = mockBoneData.bones[0];
+
+ // Clear previous content
+ annotationsOverlay.innerHTML = "";
+
+ // Simulate the displayAnnotations function logic
+ const annotationsList = document.createElement("ul");
+ annotationsList.className = "annotations-list";
+
+ bone.annotations.forEach((annotation) => {
+ const listItem = document.createElement("li");
+ listItem.className = "annotation-item";
+ listItem.textContent = annotation.text;
+ annotationsList.appendChild(listItem);
+ });
+
+ annotationsOverlay.appendChild(annotationsList);
+
+ // Verify correct number of annotations
+ const annotationItems = annotationsOverlay.querySelectorAll(".annotation-item");
+ expect(annotationItems).toHaveLength(3);
+
+ // Verify annotation content
+ expect(annotationItems[0].textContent).toBe("Ischial Tuberosity - Attachment point for hamstring muscles");
+ expect(annotationItems[1].textContent).toBe("Ischial Spine - Forms part of the lesser sciatic notch");
+ expect(annotationItems[2].textContent).toBe("Ischial Ramus - Forms part of the obturator foramen");
+ });
+
+ test("placeholder message is shown when no bone is selected", () => {
+ const boneImage = document.getElementById("bone-image");
+ const annotationsOverlay = document.getElementById("annotations-overlay");
+
+ // Simulate clearBoneDisplay function logic
+ boneImage.src = "";
+ boneImage.alt = "";
+ boneImage.style.display = "none";
+ annotationsOverlay.innerHTML = "Select a bone to view image and annotations.
";
+
+ expect(boneImage.src).toBe("");
+ expect(boneImage.style.display).toBe("none");
+ expect(annotationsOverlay.innerHTML).toBe("Select a bone to view image and annotations.
");
+ });
+
+ test("handles bone with no annotations gracefully", () => {
+ const annotationsOverlay = document.getElementById("annotations-overlay");
+
+ // Simulate bone with empty annotations array
+ const boneWithNoAnnotations = {
+ id: "test_bone",
+ name: "Test Bone",
+ image_url: "test-url.jpg",
+ annotations: []
+ };
+
+ // Clear previous content
+ annotationsOverlay.innerHTML = "";
+
+ // Simulate displayAnnotations with empty array
+ if (!boneWithNoAnnotations.annotations || boneWithNoAnnotations.annotations.length === 0) {
+ annotationsOverlay.innerHTML = "No annotations available for this bone.
";
+ }
+
+ expect(annotationsOverlay.innerHTML).toBe("No annotations available for this bone.
");
+ });
+
+ test("annotation items have correct CSS classes", () => {
+ const annotationsOverlay = document.getElementById("annotations-overlay");
+ const bone = mockBoneData.bones[0];
+
+ // Clear and populate annotations
+ annotationsOverlay.innerHTML = "";
+ const annotationsList = document.createElement("ul");
+ annotationsList.className = "annotations-list";
+
+ bone.annotations.forEach((annotation) => {
+ const listItem = document.createElement("li");
+ listItem.className = "annotation-item";
+ listItem.textContent = annotation.text;
+ annotationsList.appendChild(listItem);
+ });
+
+ annotationsOverlay.appendChild(annotationsList);
+
+ // Verify CSS classes
+ const list = annotationsOverlay.querySelector("ul");
+ expect(list.className).toBe("annotations-list");
+
+ const items = annotationsOverlay.querySelectorAll("li");
+ items.forEach(item => {
+ expect(item.className).toBe("annotation-item");
+ });
+
+ });
+
+});
+
+// ------ New tests from main: Help Modal ------
+describe("Help Modal Functionality", () => {
+ beforeEach(() => {
+ // Add help button and modal HTML to the test environment (append so earlier DOM stays)
+ document.body.innerHTML += `
+ Help
+
+ `;
+ });
+
+ test("modal is hidden by default", () => {
+ const helpModal = document.getElementById("help-modal");
+ expect(helpModal.classList.contains("is-visible")).toBeFalsy();
+ const computedStyle = window.getComputedStyle(helpModal);
+ expect(computedStyle.display).not.toBe("flex");
+ });
+
+ test("modal becomes visible when Help button is clicked", () => {
+ const helpButton = document.getElementById("text-button-Help");
+ const helpModal = document.getElementById("help-modal");
+
+ helpButton.click();
+
+ expect(helpModal.classList.contains("is-visible")).toBeTruthy();
+ });
+
+ test("modal becomes hidden when Close button is clicked", () => {
+ const helpModal = document.getElementById("help-modal");
+ const closeButton = document.getElementById("close-help-modal");
+
+ // First make modal visible
+ helpModal.classList.add("is-visible");
+
+ // Then click close button
+ closeButton.click();
+
+ expect(helpModal.classList.contains("is-visible")).toBeFalsy();
+ });
+
+ test("modal closes when Escape key is pressed", () => {
+ const helpModal = document.getElementById("help-modal");
+
+ // First make modal visible
+ helpModal.classList.add("is-visible");
+
+ // Simulate pressing Escape key
+ const escapeKeyEvent = new KeyboardEvent("keydown", { key: "Escape" });
+ document.dispatchEvent(escapeKeyEvent);
+
+ expect(helpModal.classList.contains("is-visible")).toBeFalsy();
+
+ });
+});