diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..03864a1
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,4 @@
+# OpenAI API Configuration
+# Copy this file to .env and replace with your actual API key
+# Get your API key from: https://platform.openai.com/api-keys
+OPENAI_API_KEY=sk-your_api_key_here
diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..55141f7
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,34 @@
+{
+ "root": true,
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": {
+ "ecmaVersion": 2020,
+ "sourceType": "module",
+ "project": "./tsconfig.json"
+ },
+ "plugins": [
+ "@typescript-eslint"
+ ],
+
+ "rules": {
+ "@typescript-eslint/no-unused-vars": [
+ "warn",
+ {
+ "argsIgnorePattern": "^_"
+ }
+ ],
+ "@typescript-eslint/no-explicit-any": "off",
+ "curly": "warn",
+ "eqeqeq": "warn",
+ "no-throw-literal": "warn",
+ "semi": "warn"
+ },
+ "ignorePatterns": [
+ "out",
+ "dist",
+ "node_modules",
+ "src/test/**/*",
+ "**/*.d.ts",
+ "**/*.js"
+ ]
+}
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000..95706e8
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,141 @@
+name: Bug Report
+description: File a bug report to help us improve CodIn
+title: "[Bug]: "
+labels: ["bug", "triage"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for taking the time to fill out this bug report!
+
+ Please search existing issues before creating a new one.
+
+ - type: input
+ id: version
+ attributes:
+ label: CodIn Version
+ description: What version of CodIn are you using?
+ placeholder: "1.2.3"
+ validations:
+ required: true
+
+ - type: input
+ id: vscode-version
+ attributes:
+ label: VS Code Version
+ description: What version of VS Code are you using?
+ placeholder: "1.84.0"
+ validations:
+ required: true
+
+ - type: dropdown
+ id: os
+ attributes:
+ label: Operating System
+ description: What operating system are you using?
+ options:
+ - Windows
+ - macOS
+ - Linux
+ - Other
+ validations:
+ required: true
+
+ - type: textarea
+ id: description
+ attributes:
+ label: Bug Description
+ description: A clear and concise description of what the bug is.
+ placeholder: "When I select code and right-click, the 'Explain Code with AI' option doesn't appear..."
+ validations:
+ required: true
+
+ - type: textarea
+ id: steps
+ attributes:
+ label: Steps to Reproduce
+ description: Steps to reproduce the behavior
+ placeholder: |
+ 1. Open VS Code
+ 2. Select some code
+ 3. Right-click
+ 4. See error...
+ validations:
+ required: true
+
+ - type: textarea
+ id: expected
+ attributes:
+ label: Expected Behavior
+ description: What did you expect to happen?
+ placeholder: "The context menu should show 'Explain Code with AI' option..."
+ validations:
+ required: true
+
+ - type: textarea
+ id: actual
+ attributes:
+ label: Actual Behavior
+ description: What actually happened?
+ placeholder: "The context menu doesn't show the option, or shows an error..."
+ validations:
+ required: true
+
+ - type: textarea
+ id: console-output
+ attributes:
+ label: Console Output
+ description: Any relevant output from VS Code Developer Console (Help > Toggle Developer Tools)
+ render: shell
+ placeholder: "Paste any error messages or console output here..."
+
+ - type: textarea
+ id: extension-logs
+ attributes:
+ label: Extension Logs
+ description: Any relevant logs from the Extension Development Host or Output panel
+ render: shell
+ placeholder: "Paste any extension-related logs here..."
+
+ - type: dropdown
+ id: programming-language
+ attributes:
+ label: Programming Language
+ description: What programming language were you working with?
+ options:
+ - JavaScript
+ - TypeScript
+ - Python
+ - Java
+ - C++
+ - C#
+ - Go
+ - Rust
+ - PHP
+ - Ruby
+ - Swift
+ - Kotlin
+ - Other
+ - Not applicable
+
+ - type: checkboxes
+ id: checklist
+ attributes:
+ label: Pre-submission Checklist
+ description: Please confirm the following before submitting
+ options:
+ - label: I have searched existing issues for duplicates
+ required: true
+ - label: I am using the latest version of CodIn
+ required: true
+ - label: "I have tried reloading VS Code window (Cmd/Ctrl+Shift+P > Developer: Reload Window)"
+ required: true
+ - label: I have provided all necessary information above
+ required: true
+
+ - type: textarea
+ id: additional
+ attributes:
+ label: Additional Context
+ description: Add any other context about the problem here
+ placeholder: "Screenshots, configuration details, related issues, etc..."
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 0000000..ba79699
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,119 @@
+name: Feature Request
+description: Suggest an idea for CodIn
+title: "[Feature]: "
+labels: ["enhancement", "triage"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for suggesting a new feature for CodIn!
+
+ Please search existing issues to see if your feature has already been requested.
+
+ - type: textarea
+ id: problem
+ attributes:
+ label: Problem Statement
+ description: Is your feature request related to a problem? Please describe.
+ placeholder: "I'm always frustrated when..."
+ validations:
+ required: true
+
+ - type: textarea
+ id: solution
+ attributes:
+ label: Proposed Solution
+ description: Describe the solution you'd like to see
+ placeholder: "I would like CodIn to..."
+ validations:
+ required: true
+
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: Alternatives Considered
+ description: Describe any alternative solutions or features you've considered
+ placeholder: "Alternative approaches might include..."
+
+ - type: dropdown
+ id: category
+ attributes:
+ label: Feature Category
+ description: What category does this feature fall into?
+ options:
+ - Code Explanation
+ - Language Support
+ - User Interface
+ - API Integration
+ - Performance
+ - Security
+ - Configuration
+ - Other
+ validations:
+ required: true
+
+ - type: dropdown
+ id: priority
+ attributes:
+ label: Priority Level
+ description: How important is this feature to you?
+ options:
+ - Low (Nice to have)
+ - Medium (Would improve workflow)
+ - High (Essential for my use case)
+ - Critical (Blocking current functionality)
+ validations:
+ required: true
+
+ - type: checkboxes
+ id: implementation
+ attributes:
+ label: Implementation Ideas
+ description: Do you have ideas about how this could be implemented?
+ options:
+ - label: I have specific implementation ideas
+ - label: I am willing to contribute code for this feature
+ - label: I am willing to help with testing
+ - label: I am willing to help with documentation
+
+ - type: textarea
+ id: implementation-details
+ attributes:
+ label: Implementation Details
+ description: If you have specific ideas about implementation, please share them
+ placeholder: "This could be implemented by..."
+
+ - type: textarea
+ id: use-cases
+ attributes:
+ label: Use Cases
+ description: Describe specific use cases where this feature would be helpful
+ placeholder: |
+ 1. When working on large codebases...
+ 2. When explaining code to team members...
+ 3. When learning new programming concepts...
+
+ - type: textarea
+ id: examples
+ attributes:
+ label: Examples
+ description: Provide examples of how this feature would work
+ placeholder: "For example, if I select a React component..."
+
+ - type: checkboxes
+ id: related-tools
+ attributes:
+ label: Related Tools
+ description: Are there similar features in other tools that inspired this request?
+ options:
+ - label: Similar feature exists in another VS Code extension
+ - label: Similar feature exists in another IDE or editor
+ - label: Similar feature exists in other AI tools
+ - label: This is a completely new idea
+
+ - type: textarea
+ id: additional-context
+ attributes:
+ label: Additional Context
+ description: Add any other context, screenshots, or examples about the feature request
+ placeholder: "Screenshots, mockups, links to similar features, etc..."
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..f9710bd
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,95 @@
+name: CI/CD
+
+on:
+ push:
+ branches: [ main, dev ]
+ pull_request:
+ branches: [ main ]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ node-version: [16.x, 18.x, 20.x]
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Use Node.js ${{ matrix.node-version }}
+ uses: actions/setup-node@v3
+ with:
+ node-version: ${{ matrix.node-version }}
+ cache: 'npm'
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Lint code
+ run: npm run lint --if-present
+
+ - name: Compile TypeScript
+ run: npm run compile
+
+ - name: Run tests
+ run: npm test --if-present
+
+ package:
+ runs-on: ubuntu-latest
+ needs: test
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Use Node.js 18
+ uses: actions/setup-node@v3
+ with:
+ node-version: 18
+ cache: 'npm'
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Install VSCE
+ run: npm install -g vsce
+
+ - name: Compile extension
+ run: npm run compile
+
+ - name: Package extension
+ run: vsce package --allow-star-activation
+
+ - name: Upload VSIX artifact
+ uses: actions/upload-artifact@v3
+ with:
+ name: codin-extension
+ path: '*.vsix'
+
+ publish:
+ runs-on: ubuntu-latest
+ needs: [test, package]
+ if: github.ref == 'refs/heads/main' && github.event_name == 'push'
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Use Node.js 18
+ uses: actions/setup-node@v3
+ with:
+ node-version: 18
+ cache: 'npm'
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Install VSCE
+ run: npm install -g vsce
+
+ - name: Compile extension
+ run: npm run compile
+
+ - name: Publish to VS Code Marketplace
+ run: vsce publish -p ${{ secrets.VSCE_PAT }}
+ env:
+ VSCE_PAT: ${{ secrets.VSCE_PAT }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..bcf8e4e
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,83 @@
+name: Release
+
+on:
+ push:
+ tags:
+ - 'v*'
+
+jobs:
+ release:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+
+ - name: Use Node.js 18
+ uses: actions/setup-node@v3
+ with:
+ node-version: 18
+ cache: 'npm'
+
+ - name: Install dependencies
+ run: npm ci
+
+ - name: Install VSCE
+ run: npm install -g vsce
+
+ - name: Compile extension
+ run: npm run compile
+
+ - name: Package extension
+ run: vsce package --allow-star-activation
+
+ - name: Get version from tag
+ id: get_version
+ run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
+
+ - name: Create Release
+ id: create_release
+ uses: actions/create-release@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ tag_name: ${{ github.ref }}
+ release_name: CodIn v${{ steps.get_version.outputs.VERSION }}
+ draft: false
+ prerelease: false
+ body: |
+ ## 🚀 CodIn v${{ steps.get_version.outputs.VERSION }}
+
+ ### What's New
+ - Check [CHANGELOG.md](https://github.com/semicolonailabs/CodIn/blob/main/CHANGELOG.md) for detailed changes
+
+ ### Installation
+ 1. Download the `codin-${{ steps.get_version.outputs.VERSION }}.vsix` file
+ 2. In VS Code: `Cmd+Shift+P` → "Extensions: Install from VSIX..."
+ 3. Select the downloaded file
+ 4. Enjoy AI-powered code explanations! 🎉
+
+ ### Requirements
+ - VS Code 1.70.0 or higher
+ - OpenAI API key for full functionality
+
+ ### Links
+ - [📚 Documentation](https://github.com/semicolonailabs/CodIn#readme)
+ - [🐛 Report Issues](https://github.com/semicolonailabs/CodIn/issues)
+ - [💬 Discussions](https://github.com/semicolonailabs/CodIn/discussions)
+
+ - name: Upload Release Asset
+ uses: actions/upload-release-asset@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ with:
+ upload_url: ${{ steps.create_release.outputs.upload_url }}
+ asset_path: ./codin-${{ steps.get_version.outputs.VERSION }}.vsix
+ asset_name: codin-${{ steps.get_version.outputs.VERSION }}.vsix
+ asset_content_type: application/zip
+
+ - name: Publish to VS Code Marketplace
+ run: vsce publish -p ${{ secrets.VSCE_PAT }}
+ env:
+ VSCE_PAT: ${{ secrets.VSCE_PAT }}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..cf4e2d3
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,49 @@
+# Dependencies
+node_modules/
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+package-lock.json
+yarn.lock
+
+# Build output
+out/
+dist/
+*.vsix
+
+# Testing
+.vscode-test/
+coverage/
+.nyc_output
+test-workspace/
+
+# Environment variables
+.env
+.env.local
+.env.production
+
+# OS files
+.DS_Store
+Thumbs.db
+
+# IDE files
+.vscode/settings.json
+.vscode/launch.json
+*.swp
+*.swo
+*~
+
+# Temporary files
+*.tmp
+*.temp
+.cache/
+
+# Debug files
+debug-extension/
+*debug*.js
+*debug*.json
+
+# Backup files
+*.backup
+*.bak
+src/extension.ts.backup
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..6f3a291
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "liveServer.settings.port": 5501
+}
\ No newline at end of file
diff --git a/.vscodeignore b/.vscodeignore
new file mode 100644
index 0000000..7ed9781
--- /dev/null
+++ b/.vscodeignore
@@ -0,0 +1,29 @@
+src/test
+out/test
+test
+.vscode-test
+.nyc_output
+coverage
+**/*.map
+.gitignore
+.gitattributes
+**/.eslintrc.json
+**/.editorconfig
+**/*.txt
+**/*.md
+!README.md
+!CHANGELOG.md
+!LICENSE
+!SETUP.md
+!.env.example
+node_modules
+.vscode/
+landing-page/
+test-workspace/
+**/*.ts
+!**/*.d.ts
+tsconfig.json
+.git
+*.vsix
+.env
+.mypy_cache/
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..4a8446f
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1 @@
+# ChangelogAll notable changes to the "codin" extension will be documented in this file.The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).## [1.2.3] - 2025-10-08### Fixed- Fixed missing command declarations in package.json- Resolved "Select Explanation Language" command error- Updated publisher ID for marketplace publishing (your-publisher → SemicolonAILabs)### Added- Comprehensive command verification scripts- Marketplace publishing guide- Production-ready documentation## [1.2.2] - 2025-10-08### Fixed- Fixed extension activation issues with universal activation events- Resolved duplicate command registration errors- Fixed TypeScript compilation errors- Added proper node-fetch dependency### Added- Enhanced logging for debugging- Comprehensive error handling- Multiple diagnostic and verification tools### Changed- Improved extension structure and code organization- Updated activation events for better performance## [1.2.1] - 2025-10-08### Added- Multi-language support (15 languages)- Secure API key management with VS Code Secret Storage- CodeLens provider for floating "Explain Code" buttons- Quick Actions integration (Cmd+.)- Context menu integration- Keyboard shortcuts (Cmd+Shift+E)### Changed- Enhanced UI with better progress indicators- Improved error messages with actionable suggestions- Better API key validation## [1.2.0] - 2025-10-08### Added- Initial release of CodIn extension- AI-powered code explanations using OpenAI GPT-3.5-turbo- Support for 50+ programming languages- Basic API key management- Command palette integration- Right-click context menu### Features- Real-time code explanations- Secure API key storage- Multi-language explanation support- Professional webview interface- Cross-platform compatibility## [Unreleased]### Planned- Additional AI models support (GPT-4, Claude, etc.)- Offline code analysis features- Code quality suggestions- Integration with popular IDEs beyond VS Code- Enhanced multi-language support (25+ languages)- Team/enterprise features
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..7ece49c
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,210 @@
+# Contributing to CodIn
+
+Thank you for your interest in contributing to CodIn! This document provides guidelines and information for contributors.
+
+## 🤝 How to Contribute
+
+### Reporting Issues
+- **Bug Reports**: Use GitHub Issues with the "bug" label
+- **Feature Requests**: Use GitHub Issues with the "enhancement" label
+- **Questions**: Use GitHub Discussions for general questions
+
+### Development Setup
+
+1. **Prerequisites**
+ ```bash
+ # Node.js 16+ and npm
+ node --version # Should be 16+
+ npm --version
+
+ # VS Code and VS Code Extension Development
+ code --version
+ ```
+
+2. **Clone and Setup**
+ ```bash
+ git clone https://github.com/semicolonailabs/CodIn.git
+ cd CodIn
+ npm install
+ ```
+
+3. **Development Commands**
+ ```bash
+ # Compile TypeScript
+ npm run compile
+
+ # Watch mode for development
+ npm run watch
+
+ # Package extension
+ vsce package
+
+ # Publish to marketplace
+ vsce publish
+ ```
+
+4. **Testing**
+ ```bash
+ # Install locally for testing
+ code --install-extension codin-1.2.3.vsix
+
+ # Test in VS Code Extension Development Host
+ # Press F5 in VS Code with the project open
+ ```
+
+### Code Style
+
+- **TypeScript**: Follow existing code style
+- **Linting**: Use ESLint configuration provided
+- **Formatting**: Use Prettier for consistent formatting
+- **Comments**: Document complex logic and API interactions
+
+### Pull Request Process
+
+1. **Fork the Repository**
+ ```bash
+ # Fork on GitHub, then clone your fork
+ git clone https://github.com/YOUR-USERNAME/CodIn.git
+ cd CodIn
+ git remote add upstream https://github.com/semicolonailabs/CodIn.git
+ ```
+
+2. **Create Feature Branch**
+ ```bash
+ git checkout -b feature/your-feature-name
+ # or
+ git checkout -b fix/issue-description
+ ```
+
+3. **Make Changes**
+ - Follow existing code patterns
+ - Add/update tests if applicable
+ - Update documentation if needed
+ - Test thoroughly in VS Code
+
+4. **Commit Guidelines**
+ ```bash
+ # Use conventional commit format
+ git commit -m "feat: add new language support for Python"
+ git commit -m "fix: resolve CodeLens activation issue"
+ git commit -m "docs: update README with new features"
+ ```
+
+5. **Submit Pull Request**
+ - Provide clear description of changes
+ - Reference related issues
+ - Include screenshots/demos for UI changes
+ - Ensure all checks pass
+
+### Development Guidelines
+
+#### **Extension Structure**
+```
+src/
+├── extension.ts # Main extension entry point
+├── commands/ # Command implementations
+├── providers/ # CodeLens, CodeAction providers
+├── utils/ # Utility functions
+└── test/ # Test files
+```
+
+#### **Adding New Features**
+
+1. **New Commands**
+ ```typescript
+ // 1. Register in package.json contributes.commands
+ // 2. Implement in extension.ts
+ // 3. Add to context.subscriptions
+ ```
+
+2. **New Languages**
+ ```typescript
+ // Add to SUPPORTED_LANGUAGES constant
+ // Add language-specific instructions
+ // Update documentation
+ ```
+
+3. **UI Components**
+ ```typescript
+ // Follow VS Code theming guidelines
+ // Use semantic HTML in webviews
+ // Ensure accessibility compliance
+ ```
+
+#### **Testing Guidelines**
+
+1. **Manual Testing**
+ - Test all command variants
+ - Test different programming languages
+ - Test API key management
+ - Test error scenarios
+
+2. **Automated Testing**
+ ```bash
+ # Run test suite (when available)
+ npm test
+
+ # Test extension activation
+ # Use verification scripts in repository
+ ```
+
+### Security Considerations
+
+- **API Keys**: Never commit actual API keys
+- **User Data**: Minimize data collection and storage
+- **Dependencies**: Keep dependencies up-to-date
+- **Permissions**: Request minimal necessary permissions
+
+### Performance Guidelines
+
+- **Activation**: Use specific activation events when possible
+- **Memory**: Clean up resources properly
+- **Network**: Handle API rate limits gracefully
+- **UI**: Don't block the main thread
+
+## 🏷️ Issue Labels
+
+- `bug` - Something isn't working
+- `enhancement` - New feature or request
+- `documentation` - Improvements or additions to docs
+- `good first issue` - Good for newcomers
+- `help wanted` - Extra attention is needed
+- `question` - Further information is requested
+
+## 📝 Code of Conduct
+
+- Be respectful and inclusive
+- Help others learn and grow
+- Focus on constructive feedback
+- Follow GitHub Community Guidelines
+
+## 🛠️ Development Tips
+
+### **Debugging Extensions**
+```typescript
+// Use VS Code Developer Tools
+console.log('Debug message');
+
+// Access in VS Code: Help > Toggle Developer Tools
+// Check Extension Development Host console
+```
+
+### **Common Issues**
+- **Commands not registered**: Check package.json declarations
+- **Extension not activating**: Verify activation events
+- **API errors**: Check network connectivity and API keys
+- **TypeScript errors**: Ensure proper type definitions
+
+### **Useful Resources**
+- [VS Code Extension API](https://code.visualstudio.com/api)
+- [Extension Guidelines](https://code.visualstudio.com/api/references/extension-guidelines)
+- [Publishing Extensions](https://code.visualstudio.com/api/working-with-extensions/publishing-extension)
+
+## 📧 Contact
+
+- **Maintainer**: SemicolonAI Labs
+- **Email**: support@semicolonailabs.com
+- **Issues**: [GitHub Issues](https://github.com/semicolonailabs/CodIn/issues)
+- **Discussions**: [GitHub Discussions](https://github.com/semicolonailabs/CodIn/discussions)
+
+Thank you for contributing to CodIn! 🎉
diff --git a/CodIn.png b/CodIn.png
new file mode 100644
index 0000000..3d3bd1a
Binary files /dev/null and b/CodIn.png differ
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..2e3d9f1
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2025 CodIn
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/PROJECT_STRUCTURE.md b/PROJECT_STRUCTURE.md
new file mode 100644
index 0000000..a966512
--- /dev/null
+++ b/PROJECT_STRUCTURE.md
@@ -0,0 +1,218 @@
+# Project Structure
+
+This document describes the organization and structure of the CodIn VS Code extension project.
+
+## 📁 **Root Directory Structure**
+
+```
+CodIn/
+├── .github/ # GitHub configuration
+│ ├── ISSUE_TEMPLATE/ # Issue templates
+│ │ ├── bug_report.yml # Bug report template
+│ │ └── feature_request.yml # Feature request template
+│ └── workflows/ # GitHub Actions
+│ ├── ci.yml # Continuous integration
+│ └── release.yml # Release automation
+├── .vscode/ # VS Code workspace settings
+├── landing-page/ # Marketing/landing page
+├── node_modules/ # Dependencies (generated)
+├── out/ # Compiled output (generated)
+├── src/ # Source code
+│ └── extension.ts # Main extension entry point
+├── .env.example # Environment variables template
+├── .eslintrc.json # ESLint configuration
+├── .gitignore # Git ignore rules
+├── .vscodeignore # VS Code packaging ignore
+├── CHANGELOG.md # Version history
+├── CONTRIBUTING.md # Contribution guidelines
+├── LICENSE # MIT license
+├── README.md # Main documentation
+├── SECURITY.md # Security policy
+├── package.json # Node.js project configuration
+└── tsconfig.json # TypeScript configuration
+```
+
+## 📝 **File Descriptions**
+
+### **Core Extension Files**
+
+#### `src/extension.ts`
+Main extension entry point containing:
+- Extension activation and deactivation logic
+- Command registration and implementations
+- CodeLens and CodeAction providers
+- API key management functions
+- AI explanation logic with OpenAI integration
+- Webview content generation
+- Multi-language support
+
+#### `package.json`
+Extension manifest defining:
+- Extension metadata (name, version, publisher)
+- VS Code engine compatibility
+- Command contributions and menus
+- Activation events and categories
+- Dependencies and scripts
+- Marketplace information
+
+#### `tsconfig.json`
+TypeScript compiler configuration:
+- Target ES2020 for modern JavaScript features
+- CommonJS modules for Node.js compatibility
+- Source maps for debugging
+- Strict type checking enabled
+
+### **Configuration Files**
+
+#### `.eslintrc.json`
+ESLint configuration for code quality:
+- TypeScript-specific rules
+- Best practices enforcement
+- Code style consistency
+- Import/export validations
+
+#### `.vscodeignore`
+Packaging exclusions:
+- Source TypeScript files (only compiled JS included)
+- Development and test files
+- Documentation (except essential files)
+- Node.js development dependencies
+
+#### `.gitignore`
+Version control exclusions:
+- Node.js dependencies
+- Compiled output
+- Temporary and cache files
+- Environment variables and secrets
+
+### **Documentation Files**
+
+#### `README.md`
+Primary documentation including:
+- Feature overview and screenshots
+- Installation instructions
+- Usage examples and tutorials
+- Configuration options
+- Troubleshooting guide
+
+#### `CHANGELOG.md`
+Version history with:
+- Feature additions and improvements
+- Bug fixes and security patches
+- Breaking changes and migrations
+- Release dates and version numbers
+
+#### `CONTRIBUTING.md`
+Developer guidelines covering:
+- Development environment setup
+- Code style and conventions
+- Pull request process
+- Testing requirements
+- Issue reporting templates
+
+#### `SECURITY.md`
+Security policy detailing:
+- Vulnerability reporting process
+- Supported versions for security updates
+- Security best practices for users
+- Data privacy and protection measures
+
+#### `LICENSE`
+MIT license for open source usage
+
+### **Development Files**
+
+#### `.env.example`
+Template for environment variables:
+- OpenAI API key configuration
+- Development settings
+- Local testing parameters
+
+#### GitHub Actions (`.github/workflows/`)
+- **`ci.yml`**: Continuous integration pipeline
+ - Multi-version Node.js testing
+ - TypeScript compilation
+ - Linting and code quality checks
+ - Extension packaging
+- **`release.yml`**: Automated release process
+ - Version tagging
+ - VSIX generation
+ - GitHub release creation
+ - Marketplace publishing
+
+#### Issue Templates (`.github/ISSUE_TEMPLATE/`)
+- **`bug_report.yml`**: Structured bug reporting
+- **`feature_request.yml`**: Feature suggestion format
+
+## 🏗️ **Build Process**
+
+### **Development Workflow**
+1. **Source**: Write TypeScript in `src/`
+2. **Compile**: `npm run compile` → generates `out/extension.js`
+3. **Package**: `npm run package` → creates `.vsix` file
+4. **Test**: Install VSIX in VS Code for testing
+
+### **Release Process**
+1. **Version**: Update version in `package.json`
+2. **Changelog**: Document changes in `CHANGELOG.md`
+3. **Tag**: Create git tag (`v1.2.3`)
+4. **Automate**: GitHub Actions handles building and publishing
+
+## 🔧 **Key Technologies**
+
+### **Core Stack**
+- **TypeScript**: Primary programming language
+- **Node.js**: Runtime environment
+- **VS Code Extension API**: Platform integration
+
+### **AI Integration**
+- **OpenAI API**: GPT-3.5-turbo for code explanations
+- **Fetch API**: HTTP client for API requests
+- **VS Code Secret Storage**: Secure API key management
+
+### **Development Tools**
+- **ESLint**: Code linting and quality
+- **TypeScript Compiler**: Code compilation
+- **VSCE**: VS Code extension packaging
+- **GitHub Actions**: CI/CD automation
+
+## 📊 **Extension Architecture**
+
+### **Activation Flow**
+1. VS Code loads extension on startup (universal activation)
+2. Commands registered in extension.ts
+3. Providers registered for CodeLens and Quick Actions
+4. Event listeners established for UI updates
+
+### **User Interaction Flow**
+1. User selects code in editor
+2. CodeLens button appears above selection
+3. User clicks button or uses context menu
+4. Extension validates API key
+5. Code sent to OpenAI API
+6. Explanation displayed in webview panel
+
+### **Security Architecture**
+1. API keys stored in VS Code Secret Storage (encrypted)
+2. No plain text storage of sensitive data
+3. Minimal data transmission (selected code only)
+4. HTTPS-only communication with OpenAI
+
+## 🚀 **Deployment**
+
+### **Local Installation**
+```bash
+code --install-extension codin-1.2.3.vsix
+```
+
+### **Marketplace Publishing**
+```bash
+vsce publish -p $PERSONAL_ACCESS_TOKEN
+```
+
+### **Automated Deployment**
+- Push to `main` branch triggers CI/CD
+- Successful builds auto-publish to marketplace
+- Releases created automatically from git tags
+
+This structure ensures maintainability, security, and ease of development while providing a professional user experience.
diff --git a/README.md b/README.md
index 6a2c79a..be43b8d 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,191 @@
-# CodIn
-AI-Powered Multi-Language Code Explainer
+# 🤖 CodIn - AI Code Explainer v1.2.3
+
+**Get instant AI-powered explanations for any code snippet in 15+ languages with secure API key management!**
+
+[](https://github.com/semicolonailabs/CodIn)
+[](LICENSE)
+[](https://code.visualstudio.com/)
+
+
+
+## 🌟 **Features**
+
+### 🎯 **Smart Code Explanation**
+- **Multiple Access Methods**: CodeLens buttons, Quick Actions, Context Menu, Command Palette
+- **Real-time Explanations**: Instant AI responses with progress indicators
+- **Cross-Language Support**: Works with Python, JavaScript, TypeScript, Java, C++, and 50+ languages
+
+### 🌍 **Multi-Language Support (15 Languages)**
+- **English** • **Bengali** (বাংলা) • **Arabic** (العربية) • **Spanish** • **French**
+- **German** • **Hindi** • **Chinese** • **Japanese** • **Korean**
+- **Portuguese** • **Russian** • **Italian** • **Dutch** • **Malay**
+- **Native AI Prompts**: Culturally appropriate explanations with local technical terms
+
+### � **Secure API Key Management**
+- **VS Code Secret Storage**: Encrypted, cross-platform security
+- **Command Palette Setup**: No manual file editing required
+- **Password-Masked Input**: Keys never visible on screen
+- **Auto-Migration**: Seamless upgrade from .env files
+
+### 🎨 **Professional UI**
+- **Floating CodeLens Buttons**: `🤖 Explain Code` appears above selected code
+- **Quick Actions**: Press `Cmd+.` for lightbulb menu integration
+- **Clean Popups**: VS Code theme-compatible explanation panels
+- **Language Indicators**: Shows current language in UI elements
+
+## 🎯 **How to Use**
+
+### **Method 1: CodeLens (Floating Button)**
+- Select code → See `🤖 Explain Code (Language)` button above
+- Click to get explanation in side panel
+
+### **Method 2: Quick Actions**
+- Select code → Press `Cmd+.` → Choose `💡 Explain Code`
+- Or click the lightbulb icon
+
+### **Method 3: Context Menu**
+- Select code → Right-click → `CodIn: Explain Code`
+
+### **Method 4: Command Palette**
+- Select code → `Cmd+Shift+P` → `CodIn: Explain Code`
+
+## 💡 **Multi-Language Example**
+
+**Select this Python code:**
+```python
+def factorial(n):
+ if n < 0:
+ raise ValueError("Factorial not defined for negative numbers")
+ return 1 if n <= 1 else n * factorial(n - 1)
+```
+
+**CodIn explains in your chosen language:**
+
+🇺🇸 **English**: "This function calculates the factorial of a number using recursion..."
+
+🇧🇩 **Bengali**: "এই ফাংশনটি রিকার্শন ব্যবহার করে একটি সংখ্যার ফ্যাক্টোরিয়াল গণনা করে..."
+
+🇸🇦 **Arabic**: "تحسب هذه الدالة العاملية لرقم باستخدام العودية..."
+
+🇪🇸 **Spanish**: "Esta función calcula el factorial de un número usando recursión..."
+
+## 🛠️ Supported Languages
+
+- Python (.py)
+- JavaScript (.js)
+- TypeScript (.ts)
+- C++ (.cpp, .cc, .cxx)
+- Java (.java)
+- C# (.cs)
+- Go (.go)
+- Ruby (.rb)
+- PHP (.php)
+- Swift (.swift)
+- And many more!
+
+## 🔐 **API Key Management**
+
+### **Secure Setup Commands:**
+- `CodIn: Set OpenAI API Key` - Password-masked secure setup
+- `CodIn: Check API Key Status` - View connection status
+- `CodIn: Remove OpenAI API Key` - Safe removal with confirmation
+
+### **Security Features:**
+- ✅ **VS Code Secret Storage** (encrypted)
+- ✅ **Password-masked input**
+- ✅ **No plain text storage**
+- ✅ **Auto-migration from .env files**
+
+## 📦 **Installation**
+
+### **From VS Code Marketplace (Recommended)**
+1. Open VS Code
+2. Go to Extensions view (`Cmd+Shift+X`)
+3. Search for "CodIn"
+4. Click "Install" on "CodIn - AI Code Explainer" by SemicolonAILabs
+
+### **From VSIX File**
+1. Download the latest `codin-1.2.3.vsix` from [GitHub Releases](https://github.com/semicolonailabs/CodIn/releases)
+2. In VS Code: `Cmd+Shift+P` → "Extensions: Install from VSIX..."
+3. Select the downloaded file
+
+### **Requirements**
+- VS Code 1.70.0 or higher
+- OpenAI API key (get one from [OpenAI Platform](https://platform.openai.com/api-keys))
+- Internet connection for AI explanations
+
+## ⚙️ **Configuration**
+
+### **Available Settings:**
+```json
+{
+ "codin.explanationLanguage": "English",
+ "codin.showLanguageInPopup": true,
+ "codin.enableCodeLens": true,
+ "codin.enableCodeActions": true
+}
+```
+
+**Access Settings:** `Cmd+,` → Search "codin"
+
+## �️ **Privacy & Security**
+
+### **Enterprise-Grade Security:**
+- **Encrypted Storage**: API keys stored using VS Code Secret Storage (encrypted at rest)
+- **No Plain Text**: Keys never stored in files or visible on screen
+- **Secure Transmission**: HTTPS-only communication with OpenAI
+- **Privacy First**: Code snippets only sent to OpenAI for explanation
+- **No Logging**: CodIn doesn't store or log any user data
+- **Cross-Platform**: Secure on macOS, Windows, and Linux
+
+### **What We Don't Store:**
+- ❌ API keys in plain text
+- ❌ User code snippets
+- ❌ Explanation history
+- ❌ Personal information
+- ❌ Usage analytics
+
+## 🛠️ **Development**
+
+### **Setup for Development**
+```bash
+# Clone the repository
+git clone https://github.com/semicolonailabs/CodIn.git
+cd CodIn
+
+# Install dependencies
+npm install
+
+# Compile TypeScript
+npm run compile
+
+# Watch for changes
+npm run watch
+
+# Package extension
+npm run package
+
+# Run linting
+npm run lint
+```
+
+### **Testing**
+```bash
+# Install locally for testing
+code --install-extension codin-1.2.3.vsix
+
+# Or press F5 in VS Code to launch Extension Development Host
+```
+
+## 🤝 **Contributing**
+
+We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.
+
+Quick links:
+- 🐛 [Report Bugs](https://github.com/semicolonailabs/CodIn/issues/new?template=bug_report.yml)
+- 💡 [Request Features](https://github.com/semicolonailabs/CodIn/issues/new?template=feature_request.yml)
+- 🔧 [Pull Requests](https://github.com/semicolonailabs/CodIn/pulls)
+- 📚 [Documentation](https://github.com/semicolonailabs/CodIn/wiki)
+
+**Enjoy coding with CodIn! 🎉**
+# Built with ❤️ and ☕ by [Saky](https://saky.space) !
\ No newline at end of file
diff --git a/SRS.md b/SRS.md
deleted file mode 100644
index 94cb367..0000000
--- a/SRS.md
+++ /dev/null
@@ -1,238 +0,0 @@
-
-# CodIn – AI-Powered Multi-Language Code Explainer
-**Software Requirement Specification (SRS)**
-
----
-
-## 1. Project Overview
-
-**Project Name:** CodIn
-**Version:** 1.0.0
-**Author:** [Your Name / Organization]
-**Date:** 2025-09-30
-
-**Purpose:**
-CodIn is a VS Code extension that allows developers to select any code snippet while coding and get an AI-powered explanation instantly in a small popup. It supports the top 10 programming languages.
-
-**Target Users:**
-- Developers learning new programming languages
-- Beginners who want code explanation in simple language
-- Professionals needing quick code insights
-
-**Scope:**
-- Multi-language code explanation (Python, JavaScript, Java, C#, C++, Go, Ruby, PHP, TypeScript, Swift)
-- Popup window or sidebar showing AI explanation
-- Right-click context menu option "Explain Code"
-
----
-
-## 2. Functional Requirements
-
-### 2.1 Features
-1. Right-click **“Explain Code”** option in editor
-2. Select code snippet → click → **popup shows AI explanation**
-3. Multi-language support (top 10 languages)
-4. Copy explanation to clipboard
-5. Dynamic AI explanations using OpenAI API
-
-### 2.2 User Interaction
-- **Trigger:** User selects code in editor
-- **Action:** Right-click → Explain Code
-- **Response:** Popup window shows explanation generated by AI
-
-### 2.3 Commands
-| Command | Description |
-|---------|------------|
-| `extension.explainCode` | Explain selected code snippet using AI |
-
----
-
-## 3. Non-Functional Requirements
-
-- **Performance:** Response time ≤ 3 seconds (dependent on API)
-- **Usability:** Small popup, resizable, unobtrusive
-- **Compatibility:** VS Code ≥ 1.70
-- **Reliability:** Handles no-selection gracefully
-- **Security:** API key stored in environment variable, not hard-coded
-
----
-
-## 4. System Architecture
-
-**Components:**
-1. **VS Code Extension:** Frontend & context menu integration
-2. **Selected Code Access:** VS Code API to get highlighted code
-3. **AI Explanation Engine:** OpenAI GPT API for generating explanation
-4. **Popup / Webview:** Display explanation beside editor
-
-**Flow Diagram:**
-```
-User selects code → Right-click "Explain" → Extension sends code to AI → AI returns explanation → Popup displays explanation
-```
-
----
-
-## 5. Supported Languages
-1. Python
-2. JavaScript
-3. Java
-4. C#
-5. C++
-6. Go
-7. Ruby
-8. PHP
-9. TypeScript
-10. Swift
-
----
-
-## 6. Dependencies
-- Node.js
-- npm
-- VS Code
-- OpenAI API Key
-- Node package: `node-fetch`
-
----
-
-## 7. Installation
-
-### 7.1 Prerequisites
-```bash
-# Node.js & npm installed
-# VS Code installed
-# OpenAI API Key set in environment variable
-```
-
-### 7.2 Install from Marketplace
-1. Open VS Code
-2. Extensions → Search **CodIn** → Install
-
-### 7.3 Install Locally
-```bash
-code --install-extension codin-0.1.0.vsix
-```
-
----
-
-## 8. Usage
-
-### 8.1 Command Palette
-1. Select code snippet
-2. Press `Ctrl+Shift+P` → type **Explain Code** → Enter
-
-### 8.2 Context Menu
-1. Select code snippet
-2. Right-click → **Explain Code**
-3. Popup appears with AI-generated explanation
-
-### 8.3 Example
-**Python Code:**
-```python
-for i in range(5):
- print(i)
-```
-**Popup Explanation:**
-```
-This Python code iterates over numbers 0 to 4 and prints each number to the console.
-```
-
----
-
-## 9. Implementation Details
-
-### 9.1 package.json
-```json
-"contributes": {
- "commands": [
- {"command": "extension.explainCode","title": "Explain Selected Code"}
- ],
- "menus": {
- "editor/context": [
- {"command": "extension.explainCode","when": "editorHasSelection","group": "navigation"}
- ]
- }
-}
-```
-
-### 9.2 extension.ts
-```ts
-import * as vscode from 'vscode';
-import fetch from 'node-fetch';
-
-export function activate(context: vscode.ExtensionContext) {
- let disposable = vscode.commands.registerCommand('extension.explainCode', async () => {
- const editor = vscode.window.activeTextEditor;
- if (!editor) return;
-
- const code = editor.document.getText(editor.selection);
- if (!code) {
- vscode.window.showInformationMessage('Select some code first');
- return;
- }
-
- const explanation = await getExplanation(code);
-
- const panel = vscode.window.createWebviewPanel(
- 'codeExplanation','Code Explanation',vscode.ViewColumn.Beside,
- {enableScripts: true, retainContextWhenHidden: true}
- );
-
- panel.webview.html = `
- Explanation: ${explanation} `;
- });
- context.subscriptions.push(disposable);
-}
-
-async function getExplanation(code: string): Promise {
- const response = await fetch("https://api.openai.com/v1/completions", {
- method: "POST",
- headers: {"Authorization": `Bearer ${process.env.OPENAI_API_KEY}`,"Content-Type": "application/json"},
- body: JSON.stringify({model: "text-davinci-003", prompt:`Explain this code:
-${code}`, max_tokens: 300})
- });
- const data = await response.json();
- return data.choices[0].text;
-}
-```
-
----
-
-## 10. Future Enhancements
-- Inline hover explanation
-- Interactive multi-language examples
-- Auto-detect programming language
-- Save explanation history
-- Support more languages
-
----
-
-## 11. Deployment / Publishing
-1. Install `vsce` globally:
-```bash
-npm install -g vsce
-```
-2. Package extension:
-```bash
-vsce package
-```
-3. Publish to VS Code Marketplace:
-```bash
-vsce login
-vsce publish
-```
-
----
-
-## 12. Licensing
-- MIT License © 2025 [Your Name / Organization]
-
----
-
-## 13. Contact / Support
-- GitHub Repository: [https://github.com/your-repo/CodIn](https://github.com/your-repo/CodIn)
-- Issues / Feature Requests: Open a GitHub issue
-
----
-
-**CodIn – Select code → Click “Explain Code” → Popup → AI explains code clearly.**
diff --git a/landing-page/docs.css b/landing-page/docs.css
new file mode 100644
index 0000000..0a82bf9
--- /dev/null
+++ b/landing-page/docs.css
@@ -0,0 +1,108 @@
+body {
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
+ margin: 0;
+ background-color: #f6f8fa;
+ color: #24292e;
+ overflow: hidden; /* Hide body scrollbar */
+}
+
+.docs-container {
+ display: flex;
+ height: 100vh;
+}
+
+.sidebar {
+ width: 250px;
+ background-color: #fff;
+ border-right: 1px solid #e1e4e8;
+ padding: 2rem;
+ display: flex;
+ flex-direction: column;
+}
+
+.logo {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ font-size: 1.2rem;
+ font-weight: bold;
+ margin-bottom: 2rem;
+}
+
+.logo img {
+ width: 32px;
+ height: 32px;
+}
+
+.sidebar nav {
+ flex-grow: 1;
+}
+
+.sidebar nav ul {
+ list-style: none;
+ padding: 0;
+}
+
+.sidebar nav li a {
+ text-decoration: none;
+ color: #586069;
+ display: block;
+ padding: 0.5rem 0;
+ transition: color 0.3s ease;
+}
+
+.sidebar nav li a:hover {
+ color: #0366d6;
+}
+
+.version-info {
+ font-size: 0.8rem;
+ color: #586069;
+}
+
+.version-info span {
+ display: block;
+}
+
+.content {
+ flex: 1;
+ padding: 3rem;
+ max-width: 800px;
+ overflow-y: auto; /* Make content scrollable */
+}
+
+.content h1, .content h2 {
+ border-bottom: 1px solid #eaecef;
+ padding-bottom: 0.5rem;
+ margin-top: 2rem;
+ margin-bottom: 1rem;
+}
+
+.content p {
+ line-height: 1.7;
+}
+
+.content code {
+ background-color: #f1f1f1;
+ padding: 0.2rem 0.4rem;
+ border-radius: 3px;
+ font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier, monospace;
+}
+
+.content pre {
+ background-color: #f6f8fa;
+ padding: 1rem;
+ border-radius: 6px;
+ border: 1px solid #e1e4e8;
+ overflow-x: auto;
+}
+
+.content pre code {
+ background-color: transparent;
+ padding: 0;
+ border-radius: 0;
+}
+
+.content ol, .content ul {
+ padding-left: 2rem;
+}
diff --git a/landing-page/docs.html b/landing-page/docs.html
new file mode 100644
index 0000000..106111b
--- /dev/null
+++ b/landing-page/docs.html
@@ -0,0 +1,302 @@
+
+
+
+
+
+ CodIn Documentation
+
+
+
+
+
+
+
+ Introduction
+ CodIn is a powerful VS Code extension that brings AI-powered code explanations directly to your editor. Get instant, clear explanations of any code snippet in over 15 languages including English, Spanish, French, German, Hindi, Chinese, Japanese, and more. Whether you're learning a new programming language, working with complex algorithms, or onboarding to a new codebase, CodIn helps you understand code faster and boost your productivity.
+ Key Features:
+
+ 🤖 AI-powered code explanations using OpenAI GPT-3.5-turbo
+ 🌍 Multi-language support (15+ explanation languages)
+ 🔒 Secure API key management with VS Code Secret Storage
+ ⚡ Multiple access methods: CodeLens, context menu, and keyboard shortcuts
+ 🎯 Real-time UI updates and progress indicators
+
+
+
+ Installation
+ You can install CodIn directly from the Visual Studio Code Marketplace.
+
+ Open Visual Studio Code.
+ Go to the Extensions view by clicking on the Extensions icon in the Activity Bar on the side of the window or by pressing Ctrl+Shift+X.
+ Search for "CodIn".
+ Click the "Install" button.
+
+
+
+ Usage
+ CodIn offers multiple ways to get code explanations:
+
+ Method 1: Context Menu (Right-click)
+
+ Select any code snippet in your editor
+ Right-click on the selection
+ Choose "Explain Code" from the context menu
+ View the explanation in a new panel
+
+
+ Method 2: CodeLens (Inline)
+
+ Open any code file - CodeLens appears automatically
+ Click "Explain" above functions, classes, or code blocks
+ Get instant explanations without selecting text
+
+
+ Method 3: Command Palette
+
+ Press Ctrl+Shift+P (or Cmd+Shift+P on Mac)
+ Type "CodIn" to see all available commands
+ Choose from explain, translate, or configuration options
+
+
+ Method 4: Keyboard Shortcuts
+
+ Ctrl+Alt+E - Explain selected code
+ Ctrl+Alt+L - Select explanation language
+ Ctrl+Alt+A - Set OpenAI API key
+
+
+
+ Supported Languages
+
+ Programming Languages
+ CodIn works with all programming languages supported by VS Code, including:
+
+ JavaScript & TypeScript
+ Python
+ Java & C#
+ C & C++
+ Go & Rust
+ Ruby & PHP
+ Swift & Kotlin
+ HTML & CSS
+ SQL & Bash
+ And many more...
+
+
+ Explanation Languages
+ Get explanations in your preferred language:
+
+ 🇺🇸 English
+ 🇪🇸 Spanish (Español)
+ 🇫🇷 French (Français)
+ 🇩🇪 German (Deutsch)
+ 🇮🇳 Hindi (हिन्दी)
+ 🇧🇩 Bengali (বাংলা)
+ 🇸🇦 Arabic (العربية)
+ 🇨🇳 Chinese (中文)
+ 🇯🇵 Japanese (日本語)
+ 🇰🇷 Korean (한국어)
+ 🇵🇹 Portuguese (Português)
+ 🇷🇺 Russian (Русский)
+ 🇮🇹 Italian (Italiano)
+ 🇳🇱 Dutch (Nederlands)
+ 🇲🇾 Malay (Bahasa Melayu)
+
+ Change your explanation language anytime using Ctrl+Alt+L or the Command Palette.
+
+
+ Configuration
+
+ Setting Up Your OpenAI API Key
+ CodIn uses OpenAI's GPT-3.5-turbo model and requires an API key. Your key is stored securely using VS Code's Secret Storage (encrypted and never logged).
+
+ Easy Setup Methods:
+
+ Command Palette: Press Ctrl+Shift+P, type "CodIn: Set OpenAI API Key"
+ Keyboard Shortcut: Press Ctrl+Alt+A
+ First Use: CodIn will automatically prompt you when you first try to explain code
+
+
+ Getting an OpenAI API Key:
+
+ Visit OpenAI API Keys
+ Sign in or create an account
+ Click "Create new secret key"
+ Copy your key and paste it into CodIn when prompted
+
+
+ Language Preferences
+ Set your preferred explanation language:
+
+ Use Ctrl+Alt+L to change language quickly
+ Or use Command Palette: "CodIn: Select Explanation Language"
+ Your preference is saved automatically for future use
+
+
+ Security & Privacy
+
+ 🔒 API keys are encrypted using VS Code Secret Storage
+ 🚫 No code or explanations are logged locally
+ 🌐 Only selected code is sent to OpenAI for explanation
+ 🔐 All communications use HTTPS encryption
+
+
+
+
+ Advanced Features
+
+ 🎯 Smart CodeLens
+ CodIn automatically detects important code structures and shows "Explain" links:
+
+ Function and method definitions
+ Class declarations
+ Complex algorithms and loops
+ Import/export statements
+
+
+ 🔄 Real-time Updates
+ The extension provides live feedback:
+
+ Progress indicators during explanation generation
+ Dynamic CodeLens refresh when code changes
+ Instant language switching without restart
+
+
+ ⚡ Performance Optimizations
+
+ Efficient API usage with optimized prompts
+ Smart caching to reduce redundant requests
+ Background processing for better responsiveness
+ Minimal VS Code performance impact
+
+
+ 🛠️ Available Commands
+
+
+
+ Command
+ Shortcut
+ Description
+
+
+
+
+ Explain Code
+ Ctrl+Alt+E
+ Explain selected code snippet
+
+
+ Select Language
+ Ctrl+Alt+L
+ Change explanation language
+
+
+ Set API Key
+ Ctrl+Alt+A
+ Configure OpenAI API key
+
+
+ Toggle CodeLens
+ -
+ Enable/disable inline explanations
+
+
+ Clear API Key
+ -
+ Remove stored API key
+
+
+
+
+ 🔒 Security Features
+
+ Encrypted Storage: API keys stored using VS Code Secret Storage
+ No Logging: Code and explanations never saved locally
+ Minimal Permissions: Only necessary VS Code API access
+ HTTPS Only: All communications encrypted in transit
+
+
+ 🎨 Integration with VS Code
+
+ Respects VS Code color themes and fonts
+ Works with all VS Code language extensions
+ Compatible with other productivity extensions
+ Follows VS Code accessibility guidelines
+
+
+
+
+ Troubleshooting
+
+ Common Issues & Solutions
+
+ ❌ "Please set your OpenAI API key first"
+
+ Use Ctrl+Alt+A to set your API key
+ Make sure you copied the complete key from OpenAI
+ Verify your OpenAI account has API credits available
+
+
+ ❌ CodeLens not appearing
+
+ Check that CodeLens is enabled in VS Code settings
+ Try reloading the window: Ctrl+Shift+P → "Developer: Reload Window"
+ Ensure you're in a supported file type
+
+
+ ❌ "Explain Code" option missing from context menu
+
+ Make sure you have text selected before right-clicking
+ Check that the extension is enabled in Extensions view
+ Try using CodeLens or Command Palette instead
+
+
+ ❌ Network or API errors
+
+ Check your internet connection
+ Verify OpenAI API status at status.openai.com
+ Check if your API key has sufficient credits
+ Try again in a few minutes (rate limiting)
+
+
+ ❌ Performance issues
+
+ Large code selections may take longer to process
+ Try explaining smaller code snippets
+ Check VS Code's output panel for any error messages
+
+
+ Debug Information
+ When reporting issues, please include:
+
+ CodIn version: 1.2.3
+ VS Code version
+ Operating system
+ Programming language being explained
+ Error messages from VS Code Output panel
+
+
+
+
+
+
diff --git a/landing-page/index.html b/landing-page/index.html
new file mode 100644
index 0000000..570c7b7
--- /dev/null
+++ b/landing-page/index.html
@@ -0,0 +1,117 @@
+
+
+
+
+
+ CodIn - AI Code Explainer
+
+
+
+
+
+
+
+
+
CodIn
+
+
+
+
+
+
+
+
Understand Code in Seconds
+
CodIn is a revolutionary VS Code extension that uses the power of AI to explain code snippets in plain, easy-to-understand English, right inside your editor.
+
Get Started for Free
+
+
+
+
+ Why You'll Love CodIn
+
+
+
Instant Explanations
+
No more context switching. Get AI-powered explanations for any code snippet without ever leaving your editor.
+
+
+
Multi-Language Support
+
From Python to PHP, CodIn supports the top 10 most popular programming languages.
+
+
+
Seamless Integration
+
A simple right-click is all it takes. CodIn is designed to feel like a native part of VS Code.
+
+
+
+
+
+ How It Works in 3 Simple Steps
+
+
+
1
+
Select Code
+
Highlight any code snippet you want to understand in your VS Code editor.
+
+
+
2
+
Right-Click
+
Right-click on the selected code and choose the "Explain Code" option from the context menu.
+
+
+
3
+
Get Explanation
+
A clear, concise explanation generated by AI will instantly appear in a new panel.
+
+
+
+
+
+ Documentation
+ For more detailed information on how to use and configure CodIn, please refer to our official documentation.
+ Read the Docs
+
+
+
+ What Developers Are Saying
+
+
+
"CodIn has been a game-changer for me while learning Go. I can now understand complex code much faster."
+
- A Happy Developer
+
+
+
"I use CodIn daily to get quick insights into unfamiliar JavaScript libraries. It's an essential tool in my workflow."
+
- Senior Frontend Engineer
+
+
+
+
+
+
+
+ Get CodIn Now
+ Ready to supercharge your coding workflow? Install the extension from the Visual Studio Code Marketplace today.
+ View on Marketplace
+
+
+
+
+
+
+
diff --git a/landing-page/logo.png b/landing-page/logo.png
new file mode 100644
index 0000000..9d58cbe
Binary files /dev/null and b/landing-page/logo.png differ
diff --git a/landing-page/script.js b/landing-page/script.js
new file mode 100644
index 0000000..3566977
--- /dev/null
+++ b/landing-page/script.js
@@ -0,0 +1,9 @@
+document.querySelectorAll('a[href^="#"]').forEach(anchor => {
+ anchor.addEventListener('click', function (e) {
+ e.preventDefault();
+
+ document.querySelector(this.getAttribute('href')).scrollIntoView({
+ behavior: 'smooth'
+ });
+ });
+});
diff --git a/landing-page/style.css b/landing-page/style.css
new file mode 100644
index 0000000..dc7e738
--- /dev/null
+++ b/landing-page/style.css
@@ -0,0 +1,218 @@
+/* General Styles */
+body {
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
+ margin: 0;
+ background-color: #1a1a2e;
+ color: #e0e0e0;
+ line-height: 1.6;
+}
+
+/* Header and Navigation */
+header {
+ background-color: #162447;
+ box-shadow: 0 2px 4px rgba(0,0,0,0.2);
+ padding: 1rem 2rem;
+ position: sticky;
+ top: 0;
+ z-index: 1000;
+}
+
+nav {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.logo {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ font-size: 1.5rem;
+ font-weight: bold;
+}
+
+.logo img {
+ width: 40px;
+ height: 40px;
+}
+
+.nav-links {
+ list-style: none;
+ display: flex;
+ gap: 2rem;
+}
+
+.nav-links a {
+ text-decoration: none;
+ color: #e0e0e0;
+ font-weight: 500;
+ transition: color 0.3s ease;
+}
+
+.nav-links a:hover {
+ color: #1f4068;
+}
+
+/* Hero Section */
+.hero {
+ text-align: center;
+ padding: 5rem 2rem;
+ background: linear-gradient(rgba(26, 26, 46, 0.8), rgba(26, 26, 46, 0.8)), url('background.jpg') no-repeat center center/cover;
+}
+
+.hero-content h1 {
+ font-size: 3.5rem;
+ margin-bottom: 1rem;
+ color: #fff;
+}
+
+.hero-content p {
+ font-size: 1.2rem;
+ color: #b0b0b0;
+ margin-bottom: 2rem;
+ max-width: 600px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.cta-button {
+ background-color: #1f4068;
+ color: #fff;
+ padding: 1rem 2rem;
+ border-radius: 8px;
+ text-decoration: none;
+ font-weight: 500;
+ transition: background-color 0.3s ease;
+}
+
+.cta-button:hover {
+ background-color: #162447;
+}
+
+/* Sections */
+.features, .usage, .documentation, .testimonials, .community, .download {
+ padding: 5rem 2rem;
+ text-align: center;
+}
+
+.features h2, .usage h2, .documentation h2, .testimonials h2, .community h2, .download h2 {
+ font-size: 2.8rem;
+ margin-bottom: 3rem;
+ color: #fff;
+}
+
+/* Feature Cards */
+.feature-cards, .testimonial-cards {
+ display: flex;
+ justify-content: center;
+ gap: 2rem;
+ flex-wrap: wrap;
+}
+
+.card {
+ background-color: #162447;
+ padding: 2rem;
+ border-radius: 10px;
+ box-shadow: 0 4px 8px rgba(0,0,0,0.3);
+ max-width: 320px;
+ transition: transform 0.3s ease;
+}
+
+.card:hover {
+ transform: translateY(-10px);
+}
+
+/* Usage Steps */
+.usage-steps {
+ display: flex;
+ justify-content: center;
+ gap: 4rem;
+ margin-top: 3rem;
+}
+
+.step {
+ text-align: center;
+ max-width: 250px;
+}
+
+.step-number {
+ width: 60px;
+ height: 60px;
+ border-radius: 50%;
+ background-color: #1f4068;
+ color: #fff;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 2rem;
+ font-weight: bold;
+ margin-bottom: 1rem;
+ border: 3px solid #1a1a2e;
+}
+
+/* Documentation */
+.documentation p {
+ font-size: 1.2rem;
+ color: #b0b0b0;
+ margin-bottom: 2rem;
+ max-width: 600px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+/* Testimonials */
+.testimonials {
+ background-color: #162447;
+}
+
+.testimonial-cards .card {
+ background-color: #1a1a2e;
+}
+
+.testimonial-cards span {
+ display: block;
+ margin-top: 1rem;
+ font-style: italic;
+ color: #b0b0b0;
+}
+
+/* Community Section */
+.community-links {
+ display: flex;
+ justify-content: center;
+ gap: 2rem;
+ margin-top: 2rem;
+}
+
+.community-link {
+ color: #e0e0e0;
+ text-decoration: none;
+ font-size: 1.2rem;
+ transition: color 0.3s ease;
+}
+
+.community-link:hover {
+ color: #1f4068;
+}
+
+.community-link i {
+ margin-right: 0.5rem;
+}
+
+/* Download Section */
+.download p {
+ font-size: 1.2rem;
+ color: #b0b0b0;
+ margin-bottom: 2rem;
+ max-width: 600px;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+/* Footer */
+footer {
+ text-align: center;
+ padding: 2rem;
+ background-color: #0d1117;
+ color: #e0e0e0;
+}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..b4bcf1d
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,2170 @@
+{
+ "name": "codin",
+ "version": "1.2.3",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "codin",
+ "version": "1.2.3",
+ "dependencies": {
+ "@types/node-fetch": "^2.6.13",
+ "node-fetch": "^3.3.2"
+ },
+ "devDependencies": {
+ "@types/node": "16.x",
+ "@types/vscode": "^1.70.0",
+ "@typescript-eslint/eslint-plugin": "^6.21.0",
+ "@typescript-eslint/parser": "^6.21.0",
+ "eslint": "^8.57.1",
+ "typescript": "^4.8.4"
+ },
+ "engines": {
+ "vscode": "^1.70.0"
+ }
+ },
+ "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/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/eslintrc": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
+ "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^9.6.0",
+ "globals": "^13.19.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": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@eslint/eslintrc/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/@eslint/js": {
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz",
+ "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array": {
+ "version": "0.13.0",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz",
+ "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==",
+ "deprecated": "Use @eslint/config-array instead",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanwhocodes/object-schema": "^2.0.3",
+ "debug": "^4.3.1",
+ "minimatch": "^3.0.5"
+ },
+ "engines": {
+ "node": ">=10.10.0"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@humanwhocodes/config-array/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/@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/object-schema": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+ "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
+ "deprecated": "Use @eslint/object-schema instead",
+ "dev": true,
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@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": "16.18.126",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.126.tgz",
+ "integrity": "sha512-OTcgaiwfGFBKacvfwuHzzn1KLxH/er8mluiy8/uM3sGXHaRe73RrSIj01jow9t4kJEW633Ov+cOexXeiApTyAw==",
+ "license": "MIT"
+ },
+ "node_modules/@types/node-fetch": {
+ "version": "2.6.13",
+ "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz",
+ "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "form-data": "^4.0.4"
+ }
+ },
+ "node_modules/@types/semver": {
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/vscode": {
+ "version": "1.104.0",
+ "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.104.0.tgz",
+ "integrity": "sha512-0KwoU2rZ2ecsTGFxo4K1+f+AErRsYW0fsp6A0zufzGuhyczc2IoKqYqcwXidKXmy2u8YB2GsYsOtiI9Izx3Tig==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz",
+ "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.5.1",
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/type-utils": "6.21.0",
+ "@typescript-eslint/utils": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
+ "debug": "^4.3.4",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.4",
+ "natural-compare": "^1.4.0",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
+ "eslint": "^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz",
+ "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz",
+ "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz",
+ "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "@typescript-eslint/utils": "6.21.0",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz",
+ "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz",
+ "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/visitor-keys": "6.21.0",
+ "debug": "^4.3.4",
+ "globby": "^11.1.0",
+ "is-glob": "^4.0.3",
+ "minimatch": "9.0.3",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz",
+ "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@types/json-schema": "^7.0.12",
+ "@types/semver": "^7.5.0",
+ "@typescript-eslint/scope-manager": "6.21.0",
+ "@typescript-eslint/types": "6.21.0",
+ "@typescript-eslint/typescript-estree": "6.21.0",
+ "semver": "^7.5.4"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz",
+ "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "6.21.0",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^16.0.0 || >=18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@ungap/structured-clone": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz",
+ "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "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-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/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-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/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/array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/async-function": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz",
+ "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/async-generator-function": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-generator-function/-/async-generator-function-1.0.0.tgz",
+ "integrity": "sha512-+NAXNqgCrB95ya4Sr66i1CL2hqLVckAk7xwRYWdcm39/ELQ6YNn1aw5r0bdQtqNZgQpEWzc5yc/igXc7aL5SLA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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/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/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/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==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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/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/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/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/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/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/data-uri-to-buffer": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
+ "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "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/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/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "esutils": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "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-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": {
+ "version": "8.57.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz",
+ "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
+ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.2.0",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.4",
+ "@eslint/js": "8.57.1",
+ "@humanwhocodes/config-array": "^0.13.0",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@nodelib/fs.walk": "^1.2.8",
+ "@ungap/structured-clone": "^1.2.0",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.2",
+ "debug": "^4.3.2",
+ "doctrine": "^3.0.0",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
+ "esquery": "^1.4.2",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "globals": "^13.19.0",
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "is-path-inside": "^3.0.3",
+ "js-yaml": "^4.1.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.4.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3",
+ "strip-ansi": "^6.0.1",
+ "text-table": "^0.2.0"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "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/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/eslint/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/espree": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.9.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^3.4.1"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "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/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-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/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/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fetch-blob": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
+ "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "node-domexception": "^1.0.0",
+ "web-streams-polyfill": "^3.0.3"
+ },
+ "engines": {
+ "node": "^12.20 || >= 14.13"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
+ "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^3.0.4"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "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/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/flat-cache": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
+ "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.3",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ }
+ },
+ "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/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/formdata-polyfill": {
+ "version": "4.0.10",
+ "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
+ "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
+ "license": "MIT",
+ "dependencies": {
+ "fetch-blob": "^3.1.2"
+ },
+ "engines": {
+ "node": ">=12.20.0"
+ }
+ },
+ "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/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/generator-function": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.0.tgz",
+ "integrity": "sha512-xPypGGincdfyl/AiSGa7GjXLkvld9V7GjZlowup9SHIJnQnHLFiLODCd/DqKOp0PBagbHJ68r1KJI9Mut7m4sA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.1.tgz",
+ "integrity": "sha512-fk1ZVEeOX9hVZ6QzoBNEC55+Ucqg4sTVwrVuigZhuRPESVFpMyXnd3sbXvPOwp7Y9riVyANiqhEuRF0G1aVSeQ==",
+ "license": "MIT",
+ "dependencies": {
+ "async-function": "^1.0.0",
+ "async-generator-function": "^1.0.0",
+ "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",
+ "generator-function": "^2.0.0",
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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/glob/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/glob/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/globals": {
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globby": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
+ "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.2.9",
+ "ignore": "^5.2.0",
+ "merge2": "^1.4.1",
+ "slash": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "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/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==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "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-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-path-inside": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
+ "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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/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/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-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/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/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/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/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/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "license": "MIT",
+ "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==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "9.0.3",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
+ "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "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/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/node-domexception": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
+ "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
+ "deprecated": "Use your platform's native DOMException instead",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "github",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.5.0"
+ }
+ },
+ "node_modules/node-fetch": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
+ "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
+ "license": "MIT",
+ "dependencies": {
+ "data-uri-to-buffer": "^4.0.0",
+ "fetch-blob": "^3.1.4",
+ "formdata-polyfill": "^4.0.10"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/node-fetch"
+ }
+ },
+ "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/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": "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/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/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-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "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/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/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/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/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/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "deprecated": "Rimraf versions prior to v4 are no longer supported",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "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/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/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-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/text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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/ts-api-utils": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.4.3.tgz",
+ "integrity": "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
+ "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-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "4.9.5",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
+ "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=4.2.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/web-streams-polyfill": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
+ "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "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/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/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 0000000..60dd116
--- /dev/null
+++ b/package.json
@@ -0,0 +1,173 @@
+{
+ "name": "codin",
+ "displayName": "CodIn - AI Code Explainer",
+ "description": "AI-powered code explanations for 15+ programming languages",
+ "version": "1.2.3",
+ "publisher": "SemicolonAILabs",
+ "engines": {
+ "vscode": "^1.70.0"
+ },
+ "categories": [
+ "Education",
+ "Machine Learning",
+ "Other"
+ ],
+ "keywords": [
+ "ai",
+ "code explanation",
+ "openai",
+ "learning",
+ "documentation"
+ ],
+ "activationEvents": [
+ "*"
+ ],
+ "main": "./out/extension.js",
+ "contributes": {
+ "commands": [
+ {
+ "command": "extension.explainCode",
+ "title": "Explain Code with AI",
+ "category": "CodIn"
+ },
+ {
+ "command": "extension.explainFunction",
+ "title": "Explain Function",
+ "category": "CodIn"
+ },
+ {
+ "command": "extension.explainClass",
+ "title": "Explain Class/Object",
+ "category": "CodIn"
+ },
+ {
+ "command": "extension.explainAlgorithm",
+ "title": "Explain Algorithm",
+ "category": "CodIn"
+ },
+ {
+ "command": "extension.setupApiKey",
+ "title": "Setup OpenAI API Key",
+ "category": "CodIn"
+ },
+ {
+ "command": "extension.setApiKey",
+ "title": "Set OpenAI API Key",
+ "category": "CodIn"
+ },
+ {
+ "command": "extension.removeApiKey",
+ "title": "Remove OpenAI API Key",
+ "category": "CodIn"
+ },
+ {
+ "command": "extension.checkApiKey",
+ "title": "Check API Key Status",
+ "category": "CodIn"
+ },
+ {
+ "command": "extension.selectLanguage",
+ "title": "Select Explanation Language",
+ "category": "CodIn"
+ }
+ ],
+ "menus": {
+ "editor/context": [
+ {
+ "command": "extension.explainCode",
+ "when": "editorHasSelection",
+ "group": "codin@1"
+ },
+ {
+ "command": "extension.explainFunction",
+ "when": "editorHasSelection",
+ "group": "codin@2"
+ },
+ {
+ "command": "extension.explainClass",
+ "when": "editorHasSelection",
+ "group": "codin@3"
+ },
+ {
+ "command": "extension.explainAlgorithm",
+ "when": "editorHasSelection",
+ "group": "codin@4"
+ }
+ ],
+ "commandPalette": [
+ {
+ "command": "extension.explainCode",
+ "when": "editorIsOpen"
+ },
+ {
+ "command": "extension.explainFunction",
+ "when": "editorIsOpen"
+ },
+ {
+ "command": "extension.explainClass",
+ "when": "editorIsOpen"
+ },
+ {
+ "command": "extension.explainAlgorithm",
+ "when": "editorIsOpen"
+ },
+ {
+ "command": "extension.setupApiKey",
+ "when": "true"
+ },
+ {
+ "command": "extension.setApiKey",
+ "when": "true"
+ },
+ {
+ "command": "extension.removeApiKey",
+ "when": "true"
+ },
+ {
+ "command": "extension.checkApiKey",
+ "when": "true"
+ },
+ {
+ "command": "extension.selectLanguage",
+ "when": "true"
+ }
+ ]
+ },
+ "keybindings": [
+ {
+ "command": "extension.explainCode",
+ "key": "ctrl+shift+e",
+ "mac": "cmd+shift+e",
+ "when": "editorTextFocus && editorHasSelection"
+ }
+ ]
+ },
+ "scripts": {
+ "vscode:prepublish": "npm run compile",
+ "compile": "tsc -p ./",
+ "watch": "tsc -watch -p ./",
+ "pretest": "npm run compile && npm run lint",
+ "lint": "eslint src/extension.ts",
+ "lint:fix": "eslint src --ext ts --fix",
+ "test": "echo \"Tests not yet implemented\" && exit 0",
+ "package": "vsce package --allow-star-activation",
+ "publish": "vsce publish",
+ "clean": "rm -rf out node_modules *.vsix"
+ },
+ "devDependencies": {
+ "@types/node": "16.x",
+ "@types/vscode": "^1.70.0",
+ "@typescript-eslint/eslint-plugin": "^6.21.0",
+ "@typescript-eslint/parser": "^6.21.0",
+ "eslint": "^8.57.1",
+ "typescript": "^4.8.4"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/semicolonailabs/CodIn.git"
+ },
+ "dependencies": {
+ "@types/node-fetch": "^2.6.13",
+ "node-fetch": "^3.3.2"
+ }
+}
diff --git a/src/extension.ts b/src/extension.ts
new file mode 100644
index 0000000..032b1b5
--- /dev/null
+++ b/src/extension.ts
@@ -0,0 +1 @@
+import * as vscode from 'vscode';import * as path from 'path';import * as fs from 'fs';// Constantsconst API_KEY_SECRET_KEY = 'codin.openai.apikey';// Supported languages with their display names and promptsconst SUPPORTED_LANGUAGES = { 'English': 'English', 'Bengali': 'Bengali (বাংলা)', 'Melayu': 'Malay (Bahasa Melayu)', 'Arabic': 'Arabic (العربية)', 'Spanish': 'Spanish (Español)', 'French': 'French (Français)', 'German': 'German (Deutsch)', 'Hindi': 'Hindi (हिंदी)', 'Chinese (Simplified)': 'Chinese Simplified (简体中文)', 'Japanese': 'Japanese (日本語)', 'Korean': 'Korean (한국어)', 'Portuguese': 'Portuguese (Português)', 'Russian': 'Russian (Русский)', 'Italian': 'Italian (Italiano)', 'Dutch': 'Dutch (Nederlands)'};// Load environment variablesfunction loadEnvFile(workspaceFolder: string): { [key: string]: string } { const envPath = path.join(workspaceFolder, '.env'); const env: { [key: string]: string } = {}; try { if (fs.existsSync(envPath)) { const envContent = fs.readFileSync(envPath, 'utf8'); const lines = envContent.split('\n'); for (const line of lines) { const trimmedLine = line.trim(); if (trimmedLine && !trimmedLine.startsWith('#')) { const [key, ...valueParts] = trimmedLine.split('='); if (key && valueParts.length > 0) { env[key.trim()] = valueParts.join('=').trim(); } } } } } catch (error) { console.error('Error reading .env file:', error); } return env;}// CodeAction Provider for floating "Explain Code" buttonclass CodInCodeActionProvider implements vscode.CodeActionProvider { provideCodeActions( _document: vscode.TextDocument, _range: vscode.Range | vscode.Selection, _context: vscode.CodeActionContext, _token: vscode.CancellationToken ): vscode.CodeAction[] | undefined { // Only show action if there's a selection const editor = vscode.window.activeTextEditor; if (!editor || editor.selection.isEmpty) { return undefined; } // Get current language preference const config = vscode.workspace.getConfiguration('codin'); const currentLanguage = config.get('explanationLanguage', 'English'); // Create the "Explain Code" action with language info const explainAction = new vscode.CodeAction(`💡 Explain Code (${currentLanguage})`, vscode.CodeActionKind.QuickFix); explainAction.command = { title: 'Explain Code', command: 'extension.explainCode' }; // Create "Select Language" action const selectLanguageAction = new vscode.CodeAction('🌍 Select Explanation Language', vscode.CodeActionKind.QuickFix); selectLanguageAction.command = { title: 'Select Language', command: 'extension.selectLanguage' }; // Make explain action preferred so it appears first explainAction.isPreferred = true; return [explainAction, selectLanguageAction]; }}// CodeLens Provider for inline "Explain Code" buttonclass CodInCodeLensProvider implements vscode.CodeLensProvider { private _onDidChangeCodeLenses: vscode.EventEmitter = new vscode.EventEmitter(); public readonly onDidChangeCodeLenses: vscode.Event = this._onDidChangeCodeLenses.event; provideCodeLenses(document: vscode.TextDocument, _token: vscode.CancellationToken): vscode.CodeLens[] | Thenable { const editor = vscode.window.activeTextEditor; if (!editor || editor.document !== document || editor.selection.isEmpty) { return []; } // Create a CodeLens at the start of the selection const selectionStart = editor.selection.start; const range = new vscode.Range(selectionStart, selectionStart); // Get current language preference const config = vscode.workspace.getConfiguration('codin'); const currentLanguage = config.get('explanationLanguage', 'English'); const codeLens = new vscode.CodeLens(range); codeLens.command = { title: `🤖 Explain Code (${currentLanguage})`, command: 'extension.explainCode' }; return [codeLens]; } refresh(): void { this._onDidChangeCodeLenses.fire(); }}// Helper function to get API key from secure storageasync function getApiKey(context: vscode.ExtensionContext): Promise { const apiKey = await context.secrets.get(API_KEY_SECRET_KEY); return apiKey;}// Helper function to set API key in secure storageasync function setApiKey(context: vscode.ExtensionContext, apiKey: string): Promise { await context.secrets.store(API_KEY_SECRET_KEY, apiKey);}// Helper function to remove API key from secure storageasync function removeApiKey(context: vscode.ExtensionContext): Promise { await context.secrets.delete(API_KEY_SECRET_KEY);}// Helper function to validate API key formatfunction validateApiKey(apiKey: string): boolean { return !!(apiKey && apiKey.trim().length > 0 && apiKey.startsWith('sk-'));}export function activate(context: vscode.ExtensionContext) { console.log('🚀 CodIn extension is being activated...'); // Create CodeLens provider instance const codeLensProvider = new CodInCodeLensProvider(); // Register the CodeAction provider for all file types const codeActionProvider = vscode.languages.registerCodeActionsProvider( { scheme: 'file' }, // Works for all file types new CodInCodeActionProvider(), { providedCodeActionKinds: [vscode.CodeActionKind.QuickFix, vscode.CodeActionKind.Empty] } ); // Register CodeLens provider for all file types const codeLensProviderDisposable = vscode.languages.registerCodeLensProvider( { scheme: 'file' }, codeLensProvider ); // Listen for selection changes to refresh CodeLens const selectionChangeListener = vscode.window.onDidChangeTextEditorSelection(() => { codeLensProvider.refresh(); }); // Register the main explain code command const explainCodeDisposable = vscode.commands.registerCommand('extension.explainCode', async () => { console.log('📝 CodIn: explainCode command triggered'); // Get API key from secure storage let apiKey = await getApiKey(context); // Fallback: Try to get from .env file if not in secure storage (backward compatibility) if (!apiKey) { const workspaceFolder = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath; if (workspaceFolder) { const env = loadEnvFile(workspaceFolder); apiKey = env.OPENAI_API_KEY; // If found in .env, offer to migrate to secure storage if (apiKey && validateApiKey(apiKey)) { const migrate = await vscode.window.showInformationMessage( 'Found API key in .env file. Would you like to migrate to secure storage?', 'Yes, Migrate', 'Keep .env', 'Not Now' ); if (migrate === 'Yes, Migrate') { await setApiKey(context, apiKey); vscode.window.showInformationMessage('✅ API key migrated to secure storage!'); } } } } if (!apiKey) { const action = await vscode.window.showErrorMessage( 'OpenAI API key not found. Please set your API key to use CodIn.', 'Set API Key', 'Learn More' ); if (action === 'Set API Key') { await vscode.commands.executeCommand('extension.setApiKey'); } else if (action === 'Learn More') { vscode.env.openExternal(vscode.Uri.parse('https://platform.openai.com/api-keys')); } return; } if (!validateApiKey(apiKey)) { const action = await vscode.window.showErrorMessage( 'Invalid API key format. OpenAI API keys must start with "sk-".', 'Set New Key', 'Check Key Status' ); if (action === 'Set New Key') { await vscode.commands.executeCommand('extension.setApiKey'); } else if (action === 'Check Key Status') { await vscode.commands.executeCommand('extension.checkApiKey'); } return; } const editor = vscode.window.activeTextEditor; if (!editor) { vscode.window.showInformationMessage('No active editor found.'); return; } const selection = editor.selection; const code = editor.document.getText(selection); if (!code || code.trim() === '') { vscode.window.showInformationMessage('No code selected. Please select some code to explain.'); return; } console.log('🔍 CodIn: Code selected, generating explanation...'); // Show progress indicator await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: "Explaining code...", cancellable: false }, async (progress) => { progress.report({ increment: 0, message: "Generating explanation..." }); const panel = vscode.window.createWebviewPanel( 'codeExplanation', 'Code Explanation', vscode.ViewColumn.Beside, { enableScripts: true, retainContextWhenHidden: true } ); panel.webview.html = getLoadingWebviewContent(); try { progress.report({ increment: 50, message: "Getting AI response..." }); // Get current language preference const config = vscode.workspace.getConfiguration('codin'); const selectedLanguage = config.get('explanationLanguage', 'English'); const explanation = await getExplanation(code, apiKey!, selectedLanguage); progress.report({ increment: 100, message: "Complete!" }); panel.webview.html = getWebviewContent(explanation, code, selectedLanguage); console.log('✅ CodIn: Explanation generated successfully'); } catch (error: any) { console.error('❌ CodIn: Error explaining code:', error); vscode.window.showErrorMessage(`Error getting explanation: ${error.message}`); panel.webview.html = getErrorWebviewContent(error.message); } }); }); // Register additional command variants that all redirect to main command const explainFunctionDisposable = vscode.commands.registerCommand('extension.explainFunction', () => { console.log('🔄 CodIn: explainFunction -> explainCode'); vscode.commands.executeCommand('extension.explainCode'); }); const explainClassDisposable = vscode.commands.registerCommand('extension.explainClass', () => { console.log('🔄 CodIn: explainClass -> explainCode'); vscode.commands.executeCommand('extension.explainCode'); }); const explainAlgorithmDisposable = vscode.commands.registerCommand('extension.explainAlgorithm', () => { console.log('🔄 CodIn: explainAlgorithm -> explainCode'); vscode.commands.executeCommand('extension.explainCode'); }); const setupApiKeyDisposable = vscode.commands.registerCommand('extension.setupApiKey', () => { console.log('🔄 CodIn: setupApiKey -> setApiKey'); vscode.commands.executeCommand('extension.setApiKey'); }); // Register API key setup command const setApiKeyDisposable = vscode.commands.registerCommand('extension.setApiKey', async () => { console.log('🔑 CodIn: setApiKey command triggered'); const apiKey = await vscode.window.showInputBox({ prompt: 'Enter your OpenAI API Key', placeHolder: 'sk-...', password: true, // Masks the input for security ignoreFocusOut: true, validateInput: (value: string) => { if (!value || value.trim().length === 0) { return 'API key cannot be empty'; } if (!value.startsWith('sk-')) { return 'OpenAI API keys must start with "sk-"'; } if (value.length < 20) { return 'API key appears to be too short'; } return undefined; // Valid } }); if (apiKey) { try { await setApiKey(context, apiKey.trim()); vscode.window.showInformationMessage( '✅ OpenAI API Key saved successfully!', 'Test with Code' ).then((action) => { if (action === 'Test with Code') { vscode.commands.executeCommand('extension.explainCode'); } }); console.log('✅ CodIn: API key saved successfully'); } catch (error) { console.error('❌ CodIn: Failed to save API key:', error); vscode.window.showErrorMessage(`❌ Failed to save API key: ${error}`); } } }); // Register API key removal command const removeApiKeyDisposable = vscode.commands.registerCommand('extension.removeApiKey', async () => { console.log('🗑️ CodIn: removeApiKey command triggered'); const currentKey = await getApiKey(context); if (!currentKey) { vscode.window.showInformationMessage('ℹ️ No API key is currently stored.'); return; } const confirm = await vscode.window.showWarningMessage( 'Are you sure you want to remove the stored OpenAI API key?', { modal: true }, 'Remove Key' ); if (confirm === 'Remove Key') { try { await removeApiKey(context); vscode.window.showInformationMessage('✅ OpenAI API Key removed successfully!'); console.log('✅ CodIn: API key removed successfully'); } catch (error) { console.error('❌ CodIn: Failed to remove API key:', error); vscode.window.showErrorMessage(`❌ Failed to remove API key: ${error}`); } } }); // Register API key check command const checkApiKeyDisposable = vscode.commands.registerCommand('extension.checkApiKey', async () => { console.log('🔍 CodIn: checkApiKey command triggered'); const apiKey = await getApiKey(context); if (apiKey) { const maskedKey = apiKey.substring(0, 7) + '...' + apiKey.substring(apiKey.length - 4); vscode.window.showInformationMessage( `✅ API Key Status: Connected\n🔑 Key: ${maskedKey}`, 'Test Connection', 'Remove Key' ).then((action) => { if (action === 'Test Connection') { vscode.commands.executeCommand('extension.explainCode'); } else if (action === 'Remove Key') { vscode.commands.executeCommand('extension.removeApiKey'); } }); } else { vscode.window.showWarningMessage( '⚠️ No API Key Found\nPlease set your OpenAI API key to use CodIn.', 'Set API Key', 'Learn More' ).then((action) => { if (action === 'Set API Key') { vscode.commands.executeCommand('extension.setApiKey'); } else if (action === 'Learn More') { vscode.env.openExternal(vscode.Uri.parse('https://platform.openai.com/api-keys')); } }); } }); // Register language selection command const selectLanguageDisposable = vscode.commands.registerCommand('extension.selectLanguage', async () => { console.log('🌍 CodIn: selectLanguage command triggered'); const languageOptions = Object.entries(SUPPORTED_LANGUAGES).map(([key, display]) => ({ label: display, description: key === vscode.workspace.getConfiguration('codin').get('explanationLanguage') ? '(Current)' : '', value: key })); const selected = await vscode.window.showQuickPick(languageOptions, { placeHolder: 'Select your preferred language for code explanations', matchOnDescription: true, matchOnDetail: true }); if (selected) { const config = vscode.workspace.getConfiguration('codin'); await config.update('explanationLanguage', selected.value, vscode.ConfigurationTarget.Global); // Refresh CodeLens to show new language codeLensProvider.refresh(); vscode.window.showInformationMessage( `Code explanations will now be generated in ${selected.label}`, 'Test with Code' ).then((action) => { if (action === 'Test with Code') { vscode.commands.executeCommand('extension.explainCode'); } }); console.log(`✅ CodIn: Language changed to ${selected.label}`); } }); // Add all disposables to subscriptions context.subscriptions.push(explainCodeDisposable); context.subscriptions.push(explainFunctionDisposable); context.subscriptions.push(explainClassDisposable); context.subscriptions.push(explainAlgorithmDisposable); context.subscriptions.push(setupApiKeyDisposable); context.subscriptions.push(setApiKeyDisposable); context.subscriptions.push(removeApiKeyDisposable); context.subscriptions.push(checkApiKeyDisposable); context.subscriptions.push(selectLanguageDisposable); context.subscriptions.push(codeActionProvider); context.subscriptions.push(codeLensProviderDisposable); context.subscriptions.push(selectionChangeListener); console.log('✅ CodIn extension activated successfully! Commands registered:'); console.log('- extension.explainCode ✅'); console.log('- extension.explainFunction ✅'); console.log('- extension.explainClass ✅'); console.log('- extension.explainAlgorithm ✅'); console.log('- extension.setupApiKey ✅'); console.log('- extension.setApiKey ✅'); console.log('- extension.removeApiKey ✅'); console.log('- extension.checkApiKey ✅'); console.log('- extension.selectLanguage ✅');}// Helper function to get language-specific instructions for AIfunction getLanguageInstructions(language: string): string { const instructions: { [key: string]: string } = { 'English': 'You are a helpful coding assistant that explains code clearly and concisely in English.', 'Bengali': 'আপনি একজন সহায়ক কোডিং সহায়ক যিনি বাংলায় স্পষ্ট এবং সংক্ষিপ্তভাবে কোড ব্যাখ্যা করেন।', 'Melayu': 'Anda adalah pembantu pengekodan yang membantu menjelaskan kod dengan jelas dan ringkas dalam Bahasa Melayu.', 'Arabic': 'أنت مساعد برمجة مفيد يشرح الكود بوضوح وإيجاز باللغة العربية.', 'Spanish': 'Eres un asistente de programación útil que explica el código de manera clara y concisa en español.', 'French': 'Vous êtes un assistant de codage utile qui explique le code clairement et de manière concise en français.', 'German': 'Du bist ein hilfreicher Coding-Assistent, der Code klar und prägnant auf Deutsch erklärt.', 'Hindi': 'आप एक सहायक कोडिंग सहायक हैं जो हिंदी में स्पष्ट और संक्षिप्त रूप से कोड समझाते हैं।', 'Chinese (Simplified)': '你是一个有用的编程助手,用简体中文清晰简洁地解释代码。', 'Japanese': 'あなたは日本語でコードを明確かつ簡潔に説明する有用なコーディングアシスタントです。', 'Korean': '당신은 한국어로 코드를 명확하고 간결하게 설명하는 유용한 코딩 도우미입니다.', 'Portuguese': 'Você é um assistente de codificação útil que explica o código de forma clara e concisa em português.', 'Russian': 'Вы полезный помощник по программированию, который ясно и кратко объясняет код на русском языке.', 'Italian': 'Sei un assistente di codifica utile che spiega il codice chiaramente e concisamente in italiano.', 'Dutch': 'Je bent een nuttige codeerassistent die code duidelijk en beknopt uitlegt in het Nederlands.' }; return instructions[language] || instructions['English'];}async function getExplanation(code: string, apiKey: string, language: string = 'English'): Promise { const languageInstructions = getLanguageInstructions(language); const prompt = `${languageInstructions}Explain the following code snippet in simple, clear language. Focus on what the code does, how it works, and any important concepts:\`\`\`${code}\`\`\`Please provide a concise but thorough explanation in ${language}.`; try { console.log('🌐 CodIn: Making API request to OpenAI...'); // Import fetch dynamically to work around TypeScript issues const fetchModule = await import('node-fetch'); const fetch = fetchModule.default; const response = await fetch("https://api.openai.com/v1/chat/completions", { method: "POST", headers: { "Authorization": `Bearer ${apiKey}`, "Content-Type": "application/json", }, body: JSON.stringify({ model: "gpt-3.5-turbo", messages: [ { role: "system", content: languageInstructions + " Focus on functionality, purpose, and key concepts." }, { role: "user", content: prompt } ], max_tokens: 500, temperature: 0.3, }), }); if (!response.ok) { let errorMessage = 'Unknown error'; try { const errorData: any = await response.json(); errorMessage = errorData.error?.message || `HTTP ${response.status}: ${response.statusText}`; } catch { errorMessage = `HTTP ${response.status}: ${response.statusText}`; } throw new Error(`OpenAI API error: ${errorMessage}`); } const data: any = await response.json(); if (!data.choices || data.choices.length === 0) { throw new Error('No explanation generated by OpenAI'); } console.log('✅ CodIn: API response received successfully'); return data.choices[0].message.content.trim(); } catch (error: any) { console.error('❌ CodIn: API error:', error); throw new Error(`Failed to get explanation: ${error.message}`); }}function getWebviewContent(explanation: string, code: string, language: string = 'English'): string { const config = vscode.workspace.getConfiguration('codin'); const showLanguage = config.get('showLanguageInPopup', true); const languageDisplay = (SUPPORTED_LANGUAGES as any)[language] || language; return ` Code Explanation 📝 Selected Code: ${escapeHtml(code)}
💡 Explanation: ${explanation.replace(/\n/g, ' ')}
💡 Quick Commands: • Different language? Cmd+Shift+P → "CodIn: Select Explanation Language" • Manage API key? Cmd+Shift+P → "CodIn: Set OpenAI API Key"
`;}function getLoadingWebviewContent(): string { return ` Code Explanation
Analyzing your code and generating explanation...
`;}function getErrorWebviewContent(errorMessage: string): string { return ` Code Explanation ❌ Error Failed to generate explanation: ${escapeHtml(errorMessage)}
Please try again or check your API key configuration.
`;}function escapeHtml(unsafe: string): string { return unsafe .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'");}export function deactivate() { console.log('👋 CodIn extension deactivated');}
\ No newline at end of file
diff --git a/src/test/runTest.ts b/src/test/runTest.ts
new file mode 100644
index 0000000..7ecd963
--- /dev/null
+++ b/src/test/runTest.ts
@@ -0,0 +1,22 @@
+import * as path from 'path';
+import { runTests } from '@vscode/test-electron';
+
+async function main() {
+ try {
+ // The folder containing the Extension Manifest package.json
+ // Passed to `--extensionDevelopmentPath`
+ const extensionDevelopmentPath = path.resolve(__dirname, '../../');
+
+ // The path to test runner
+ // Passed to --extensionTestsPath
+ const extensionTestsPath = path.resolve(__dirname, './suite/index');
+
+ // Download VS Code, unzip it and run the integration test
+ await runTests({ extensionDevelopmentPath, extensionTestsPath });
+ } catch (err) {
+ console.error('Failed to run tests', err);
+ process.exit(1);
+ }
+}
+
+main();
diff --git a/src/test/suite/extension.test.ts b/src/test/suite/extension.test.ts
new file mode 100644
index 0000000..a4089bb
--- /dev/null
+++ b/src/test/suite/extension.test.ts
@@ -0,0 +1,23 @@
+import * as assert from 'assert';
+import * as vscode from 'vscode';
+// import * as myExtension from '../../extension';
+
+suite('Extension Test Suite', () => {
+ vscode.window.showInformationMessage('Start all tests.');
+
+ test('Extension should be present', () => {
+ assert.ok(vscode.extensions.getExtension('semicolonailabs.codin'));
+ });
+
+ test('Extension should activate', async () => {
+ const extension = vscode.extensions.getExtension('semicolonailabs.codin');
+ assert.ok(extension);
+ await extension!.activate();
+ assert.strictEqual(extension!.isActive, true);
+ });
+
+ test('Command should be registered', async () => {
+ const commands = await vscode.commands.getCommands(true);
+ assert.ok(commands.includes('extension.explainCode'));
+ });
+});
diff --git a/src/test/suite/index.ts b/src/test/suite/index.ts
new file mode 100644
index 0000000..fdc20ac
--- /dev/null
+++ b/src/test/suite/index.ts
@@ -0,0 +1,57 @@
+import * as path from 'path';
+import Mocha from 'mocha';
+import * as fs from 'fs';
+
+export function run(): Promise {
+ // Create the mocha test
+ const mocha = new Mocha({
+ ui: 'tdd',
+ color: true
+ });
+
+ const testsRoot = path.resolve(__dirname, '..');
+
+ return new Promise((resolve, reject) => {
+ // Simple file discovery
+ const testFiles = findTestFiles(testsRoot);
+
+ // Add files to the test suite
+ testFiles.forEach((f: string) => mocha.addFile(f));
+
+ try {
+ // Run the mocha test
+ mocha.run((failures: number) => {
+ if (failures > 0) {
+ reject(new Error(`${failures} tests failed.`));
+ } else {
+ resolve();
+ }
+ });
+ } catch (err) {
+ console.error(err);
+ reject(err);
+ }
+ });
+}
+
+function findTestFiles(dir: string): string[] {
+ const files: string[] = [];
+
+ try {
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
+
+ for (const entry of entries) {
+ const fullPath = path.join(dir, entry.name);
+
+ if (entry.isDirectory()) {
+ files.push(...findTestFiles(fullPath));
+ } else if (entry.isFile() && entry.name.endsWith('.test.js')) {
+ files.push(fullPath);
+ }
+ }
+ } catch (err) {
+ console.error('Error reading directory:', dir, err);
+ }
+
+ return files;
+}
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 0000000..0de000f
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,19 @@
+{
+ "compilerOptions": {
+ "module": "commonjs",
+ "target": "es2020",
+ "outDir": "out",
+ "lib": [
+ "es2020"
+ ],
+ "sourceMap": true,
+ "rootDir": "src",
+ "strict": true,
+ "esModuleInterop": true
+ },
+ "exclude": [
+ "node_modules",
+ ".vscode-test",
+ "src/test/**/*"
+ ]
+}
\ No newline at end of file