diff --git a/.agent/skills/electron b/.agent/skills/electron new file mode 120000 index 000000000000..d04d1cd05cfd --- /dev/null +++ b/.agent/skills/electron @@ -0,0 +1 @@ +../../.agents/skills/electron \ No newline at end of file diff --git a/.agents/skills/electron/LICENSE.txt b/.agents/skills/electron/LICENSE.txt new file mode 100644 index 000000000000..d64569567334 --- /dev/null +++ b/.agents/skills/electron/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/.agents/skills/electron/SKILL.md b/.agents/skills/electron/SKILL.md new file mode 100644 index 000000000000..46c08602eaf9 --- /dev/null +++ b/.agents/skills/electron/SKILL.md @@ -0,0 +1,152 @@ +--- +name: electron +description: Provides comprehensive guidance for Electron framework including main process, renderer process, IPC communication, window management, and desktop app development. Use when the user asks about Electron, needs to create desktop applications, implement Electron features, or build cross-platform desktop apps. +license: Complete terms in LICENSE.txt +--- + +## When to use this skill + +Use this skill whenever the user wants to: +- Build cross-platform desktop applications with Electron +- Understand Electron architecture (main process, renderer process, preload) +- Implement IPC (Inter-Process Communication) between processes +- Create and manage BrowserWindow instances +- Implement menus, tray icons, and native features +- Package and distribute Electron applications +- Use Electron Forge for project scaffolding and building +- Debug and test Electron applications +- Implement security best practices +- Use Electron APIs (app, BrowserWindow, ipcMain, ipcRenderer, etc.) + +## How to use this skill + +This skill is organized to match the Electron official documentation structure (https://www.electronjs.org/zh/docs/latest/, https://www.electronjs.org/zh/docs/latest/api/app). When working with Electron: + +1. **Identify the topic** from the user's request: + - Getting started/快速开始 → `examples/getting-started/installation.md` or `examples/getting-started/quick-start.md` + - Main process/主进程 → `examples/processes/main-process.md` + - Renderer process/渲染进程 → `examples/processes/renderer-process.md` + - IPC communication/IPC 通信 → `examples/processes/ipc-communication.md` + - BrowserWindow/窗口 → `examples/api/browser-window.md` + - Menu/菜单 → `examples/api/menu.md` + - Packaging/打包 → `examples/advanced/packaging.md` + - Security/安全 → `examples/advanced/security.md` + +2. **Load the appropriate example file** from the `examples/` directory: + + **Getting Started (快速开始) - `examples/getting-started/`**: + - `examples/getting-started/installation.md` - Installing Electron and basic setup + - `examples/getting-started/quick-start.md` - Quick start tutorial + + **Processes (进程) - `examples/processes/`**: + - `examples/processes/main-process.md` - Main process concepts and usage + - `examples/processes/renderer-process.md` - Renderer process concepts + - `examples/processes/preload-scripts.md` - Preload scripts usage + - `examples/processes/ipc-communication.md` - IPC communication patterns + + **API Examples (API 示例) - `examples/api/`**: + - `examples/api/browser-window.md` - BrowserWindow usage + - `examples/api/menu.md` - Menu and context menu + - `examples/api/tray.md` - System tray + - `examples/api/dialog.md` - File dialogs + - `examples/api/ipc-main.md` - ipcMain usage + - `examples/api/ipc-renderer.md` - ipcRenderer usage + + **Advanced (高级) - `examples/advanced/`**: + - `examples/advanced/packaging.md` - Application packaging + - `examples/advanced/security.md` - Security best practices + - `examples/advanced/auto-updater.md` - Auto updater + - `examples/advanced/native-modules.md` - Native modules + + **Tools (工具) - `examples/tools/`**: + - `examples/tools/electron-forge.md` - Electron Forge usage + - `examples/tools/electron-fiddle.md` - Electron Fiddle usage + +3. **Follow the specific instructions** in that example file for syntax, structure, and best practices + + **Important Notes**: + - All examples follow Electron latest API + - Examples use both CommonJS (require) and ES modules (import) + - Each example file includes key concepts, code examples, and key points + - Always check the example file for best practices and common patterns + - Electron supports Windows, macOS, and Linux + +4. **Reference API documentation** in the `api/` directory when needed: + - `api/app.md` - app module API + - `api/browser-window.md` - BrowserWindow API + - `api/ipc-main.md` - ipcMain API + - `api/ipc-renderer.md` - ipcRenderer API + - `api/menu.md` - Menu API + - `api/tray.md` - Tray API + +5. **Use templates** from the `templates/` directory: + - `templates/main-process.md` - Main process template + - `templates/preload-script.md` - Preload script template + - `templates/renderer-process.md` - Renderer process template + - `templates/package-json.md` - package.json template + + +### Doc mapping (one-to-one with official documentation) + +- `examples/` → https://www.electronjs.org/zh/docs/latest/ +- `api/` → https://www.electronjs.org/zh/docs/latest/api/app + +## Examples and Templates + +This skill includes detailed examples organized to match the official documentation structure. All examples are in the `examples/` directory (see mapping above). + +**To use examples:** +- Identify the topic from the user's request +- Load the appropriate example file from the mapping above +- Follow the instructions, syntax, and best practices in that file +- Adapt the code examples to your specific use case + +**To use templates:** +- Reference templates in `templates/` directory for common scaffolding +- Adapt templates to your specific needs and coding style + +## API Reference + +Detailed API documentation is available in the `api/` directory, organized to match the official Electron API documentation structure: + +### Core APIs (`api/`) +- `api/app.md` - app module API +- `api/browser-window.md` - BrowserWindow API +- `api/ipc-main.md` - ipcMain API +- `api/ipc-renderer.md` - ipcRenderer API +- `api/menu.md` - Menu API +- `api/tray.md` - Tray API +- `api/dialog.md` - Dialog API + +**To use API reference:** +1. Identify the API you need help with +2. Load the corresponding API file from the `api/` directory +3. Find the API signature, parameters, return type, and examples +4. Reference the linked example files for detailed usage patterns +5. All API files include links to relevant example files in the `examples/` directory + +## Best Practices + +1. **Security**: Never enable nodeIntegration in renderer process, use preload scripts +2. **Process separation**: Keep main and renderer processes separate +3. **IPC communication**: Use IPC for safe communication between processes +4. **Resource management**: Properly clean up resources (windows, listeners) +5. **Error handling**: Implement proper error handling and crash reporting +6. **Performance**: Optimize for performance, use webContents for debugging +7. **Packaging**: Use Electron Forge or electron-builder for packaging +8. **Auto updates**: Implement auto-updater for production apps +9. **Native modules**: Handle native module compatibility +10. **Cross-platform**: Test on all target platforms + +## Resources + +- **Official Website**: https://www.electronjs.org/zh/ +- **Documentation**: https://www.electronjs.org/zh/docs/latest/ +- **API Reference**: https://www.electronjs.org/zh/docs/latest/api/app +- **Electron Forge**: https://www.electronforge.io +- **Electron Fiddle**: https://www.electronjs.org/zh/fiddle +- **GitHub Repository**: https://github.com/electron/electron + +## Keywords + +Electron, desktop app, main process, renderer process, preload, IPC, BrowserWindow, Menu, Tray, Dialog, packaging, electron-builder, electron-forge, electron-fiddle, cross-platform, 桌面应用, 主进程, 渲染进程, IPC 通信, 窗口, 菜单, 托盘, 打包 diff --git a/.agents/skills/electron/api/app.md b/.agents/skills/electron/api/app.md new file mode 100644 index 000000000000..59d8452f94a9 --- /dev/null +++ b/.agents/skills/electron/api/app.md @@ -0,0 +1,83 @@ +# app Module API | app 模块 API + +## API Reference + +Electron app module API for application lifecycle management. + +### app Methods + +**Lifecycle:** +- `app.whenReady()` - Returns Promise when app is ready +- `app.quit()` - Quit the application +- `app.exit(exitCode)` - Exit immediately +- `app.relaunch([options])` - Relaunch the app + +**Window Management:** +- `app.getPath(name)` - Get system path +- `app.setPath(name, path)` - Set system path +- `app.getVersion()` - Get app version +- `app.getName()` - Get app name +- `app.setName(name)` - Set app name + +**Platform:** +- `app.getLocale()` - Get locale +- `app.getLocaleCountryCode()` - Get country code +- `app.isReady()` - Check if app is ready +- `app.isPackaged` - Check if app is packaged + +### app Events + +- `ready` - Emitted when Electron has finished initializing +- `window-all-closed` - Emitted when all windows are closed +- `before-quit` - Emitted before app quits +- `will-quit` - Emitted when app will quit +- `quit` - Emitted when app quits +- `activate` - Emitted when app is activated (macOS) +- `second-instance` - Emitted when second instance is launched + +### Example: Basic Usage + +```javascript +const { app, BrowserWindow } = require('electron') + +app.whenReady().then(() => { + createWindow() +}) + +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { + app.quit() + } +}) + +app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) { + createWindow() + } +}) +``` + +### Example: Single Instance + +```javascript +const { app } = require('electron') + +const gotTheLock = app.requestSingleInstanceLock() + +if (!gotTheLock) { + app.quit() +} else { + app.on('second-instance', () => { + // Focus existing window + }) +} +``` + +### Key Points + +- Use app.whenReady() before creating windows +- Handle window-all-closed for proper quit +- macOS requires activate event handling +- Use requestSingleInstanceLock() for single instance +- app has full Node.js access +- Get system paths with app.getPath() diff --git a/.agents/skills/electron/api/browser-window.md b/.agents/skills/electron/api/browser-window.md new file mode 100644 index 000000000000..4d8dc754c6e0 --- /dev/null +++ b/.agents/skills/electron/api/browser-window.md @@ -0,0 +1,84 @@ +# BrowserWindow API | BrowserWindow API + +## API Reference + +BrowserWindow API for creating and controlling application windows. + +### Constructor Options + +**Basic:** +- `width`, `height` - Window size +- `minWidth`, `minHeight` - Minimum size +- `maxWidth`, `maxHeight` - Maximum size +- `resizable` - Whether window is resizable +- `movable` - Whether window is movable + +**Display:** +- `show` - Show window when created +- `frame` - Show window frame +- `titleBarStyle` - Title bar style (macOS) +- `backgroundColor` - Background color +- `opacity` - Window opacity + +**Behavior:** +- `alwaysOnTop` - Keep window on top +- `fullscreen` - Start fullscreen +- `skipTaskbar` - Skip taskbar (Linux/Windows) +- `kiosk` - Kiosk mode + +**webPreferences:** +- `preload` - Preload script path +- `nodeIntegration` - Enable Node.js (not recommended) +- `contextIsolation` - Enable context isolation (recommended) +- `sandbox` - Enable sandbox + +### Instance Methods + +**Content:** +- `loadURL(url[, options])` - Load URL +- `loadFile(filePath[, options])` - Load local file +- `reload()` - Reload window + +**Window Control:** +- `show()` - Show window +- `hide()` - Hide window +- `close()` - Close window +- `focus()` - Focus window +- `blur()` - Remove focus + +**Size/Position:** +- `setSize(width, height)` - Set size +- `getSize()` - Get size +- `setPosition(x, y)` - Set position +- `getPosition()` - Get position +- `center()` - Center window + +**State:** +- `minimize()` - Minimize +- `maximize()` - Maximize +- `restore()` - Restore +- `setFullScreen(flag)` - Set fullscreen + +**DevTools:** +- `webContents.openDevTools()` - Open DevTools +- `webContents.closeDevTools()` - Close DevTools + +### Instance Events + +- `ready-to-show` - Emitted when window is ready +- `closed` - Emitted when window is closed +- `focus` - Emitted when window gains focus +- `blur` - Emitted when window loses focus +- `maximize` - Emitted when maximized +- `unmaximize` - Emitted when unmaximized +- `minimize` - Emitted when minimized +- `restore` - Emitted when restored + +### Key Points + +- Always set contextIsolation: true +- Never set nodeIntegration: true +- Use preload script for IPC +- Handle ready-to-show for smooth loading +- Clean up window references on closed +- Use webContents for DevTools access diff --git a/.agents/skills/electron/examples/advanced/packaging.md b/.agents/skills/electron/examples/advanced/packaging.md new file mode 100644 index 000000000000..bb7a6161d615 --- /dev/null +++ b/.agents/skills/electron/examples/advanced/packaging.md @@ -0,0 +1,140 @@ +# Packaging | 打包 + +**官方文档**: https://www.electronjs.org/zh/docs/latest/, + + +## Instructions + +This example demonstrates how to package Electron applications for distribution. + +### Key Concepts + +- Using Electron Forge +- Using electron-builder +- Platform-specific builds +- Code signing +- Auto-updater integration + +### Example: Electron Forge Setup + +```bash +# Initialize with Electron Forge +npm create electron-app@latest my-app + +# Or add to existing project +npx @electron-forge/cli import +``` + +### Example: Electron Forge Configuration + +```json +// package.json +{ + "name": "my-app", + "version": "1.0.0", + "main": ".vite/build/main.js", + "scripts": { + "start": "electron-forge start", + "package": "electron-forge package", + "make": "electron-forge make", + "publish": "electron-forge publish" + }, + "config": { + "forge": { + "packagerConfig": { + "name": "My App", + "icon": "./assets/icon" + }, + "makers": [ + { + "name": "@electron-forge/maker-squirrel", + "config": { + "name": "my_app" + } + }, + { + "name": "@electron-forge/maker-zip", + "platforms": ["darwin"] + }, + { + "name": "@electron-forge/maker-deb", + "config": {} + }, + { + "name": "@electron-forge/maker-rpm", + "config": {} + } + ] + } + } +} +``` + +### Example: electron-builder Setup + +```json +// package.json +{ + "name": "my-app", + "version": "1.0.0", + "main": "main.js", + "scripts": { + "build": "electron-builder", + "build:win": "electron-builder --win", + "build:mac": "electron-builder --mac", + "build:linux": "electron-builder --linux" + }, + "build": { + "appId": "com.example.myapp", + "productName": "My App", + "directories": { + "output": "dist" + }, + "files": [ + "main.js", + "preload.js", + "renderer/**/*", + "package.json" + ], + "win": { + "target": "nsis", + "icon": "build/icon.ico" + }, + "mac": { + "target": "dmg", + "icon": "build/icon.icns", + "category": "public.app-category.utilities" + }, + "linux": { + "target": "AppImage", + "icon": "build/icon.png" + } + } +} +``` + +### Example: Build Commands + +```bash +# Build for current platform +npm run build + +# Build for specific platform +npm run build:win +npm run build:mac +npm run build:linux + +# Build all platforms +npm run build -- --win --mac --linux +``` + +### Key Points + +- Electron Forge is recommended for new projects +- electron-builder is popular and flexible +- Configure platform-specific settings +- Include only necessary files in build +- Set proper app ID and product name +- Use icons for each platform +- Code signing required for distribution +- Test builds on target platforms diff --git a/.agents/skills/electron/examples/api/browser-window.md b/.agents/skills/electron/examples/api/browser-window.md new file mode 100644 index 000000000000..1709e8bb923b --- /dev/null +++ b/.agents/skills/electron/examples/api/browser-window.md @@ -0,0 +1,182 @@ +# BrowserWindow | 窗口 + +**官方文档**: https://www.electronjs.org/zh/docs/latest/, + + +## Instructions + +This example demonstrates how to use BrowserWindow to create and manage application windows. + +### Key Concepts + +- Creating windows +- Window options +- Loading content +- Window events +- Window methods + +### Example: Basic Window + +```javascript +const { BrowserWindow } = require('electron') +const path = require('path') + +function createWindow() { + const win = new BrowserWindow({ + width: 800, + height: 600, + webPreferences: { + preload: path.join(__dirname, 'preload.js'), + contextIsolation: true, + nodeIntegration: false + } + }) + + win.loadFile('index.html') +} + +createWindow() +``` + +### Example: Window Options + +```javascript +const win = new BrowserWindow({ + width: 1200, + height: 800, + minWidth: 400, + minHeight: 300, + maxWidth: 1920, + maxHeight: 1080, + resizable: true, + movable: true, + minimizable: true, + maximizable: true, + closable: true, + focusable: true, + alwaysOnTop: false, + fullscreen: false, + fullscreenable: true, + simpleFullscreen: false, + skipTaskbar: false, + kiosk: false, + title: 'My App', + icon: path.join(__dirname, 'icon.png'), + show: false, // Don't show until ready + frame: true, + titleBarStyle: 'default', + backgroundColor: '#ffffff', + webPreferences: { + preload: path.join(__dirname, 'preload.js'), + contextIsolation: true, + nodeIntegration: false + } +}) + +// Show when ready +win.once('ready-to-show', () => { + win.show() +}) +``` + +### Example: Loading Content + +```javascript +const win = new BrowserWindow({ width: 800, height: 600 }) + +// Load local file +win.loadFile('index.html') + +// Load URL +win.loadURL('https://example.com') + +// Load with options +win.loadFile('index.html', { + query: { key: 'value' }, + hash: 'section' +}) +``` + +### Example: Window Events + +```javascript +const win = new BrowserWindow({ width: 800, height: 600 }) + +win.on('ready-to-show', () => { + win.show() +}) + +win.on('closed', () => { + win = null +}) + +win.on('focus', () => { + console.log('Window focused') +}) + +win.on('blur', () => { + console.log('Window blurred') +}) + +win.on('maximize', () => { + console.log('Window maximized') +}) + +win.on('unmaximize', () => { + console.log('Window unmaximized') +}) + +win.on('minimize', () => { + console.log('Window minimized') +}) + +win.on('restore', () => { + console.log('Window restored') +}) +``` + +### Example: Window Methods + +```javascript +const win = new BrowserWindow({ width: 800, height: 600 }) + +// Show/Hide +win.show() +win.hide() + +// Minimize/Maximize/Restore +win.minimize() +win.maximize() +win.restore() + +// Close +win.close() + +// Focus +win.focus() +win.blur() + +// Position +win.setPosition(100, 100) +const [x, y] = win.getPosition() + +// Size +win.setSize(1200, 800) +const [width, height] = win.getSize() + +// Center +win.center() + +// DevTools +win.webContents.openDevTools() +win.webContents.closeDevTools() +``` + +### Key Points + +- BrowserWindow creates application windows +- Use show: false and ready-to-show event for smooth loading +- webPreferences should have contextIsolation: true +- Never set nodeIntegration: true in renderer +- Use loadFile() for local files, loadURL() for remote +- Handle closed event to clean up references diff --git a/.agents/skills/electron/examples/api/menu.md b/.agents/skills/electron/examples/api/menu.md new file mode 100644 index 000000000000..c698a4a21ec7 --- /dev/null +++ b/.agents/skills/electron/examples/api/menu.md @@ -0,0 +1,187 @@ +# Menu | 菜单 + +**官方文档**: https://www.electronjs.org/zh/docs/latest/, + + +## Instructions + +This example demonstrates how to use Menu to create application menus and context menus. + +### Key Concepts + +- Application menu +- Context menu +- Menu items +- Menu roles +- Menu accelerators + +### Example: Application Menu + +```javascript +const { app, Menu } = require('electron') + +const template = [ + { + label: 'File', + submenu: [ + { + label: 'New', + accelerator: 'CmdOrCtrl+N', + click: () => { + console.log('New file') + } + }, + { + label: 'Open', + accelerator: 'CmdOrCtrl+O', + click: () => { + console.log('Open file') + } + }, + { type: 'separator' }, + { + label: 'Exit', + accelerator: process.platform === 'darwin' ? 'Cmd+Q' : 'Ctrl+Q', + click: () => { + app.quit() + } + } + ] + }, + { + label: 'Edit', + submenu: [ + { role: 'undo', label: 'Undo' }, + { role: 'redo', label: 'Redo' }, + { type: 'separator' }, + { role: 'cut', label: 'Cut' }, + { role: 'copy', label: 'Copy' }, + { role: 'paste', label: 'Paste' } + ] + }, + { + label: 'View', + submenu: [ + { role: 'reload', label: 'Reload' }, + { role: 'forceReload', label: 'Force Reload' }, + { role: 'toggleDevTools', label: 'Toggle Developer Tools' }, + { type: 'separator' }, + { role: 'resetZoom', label: 'Actual Size' }, + { role: 'zoomIn', label: 'Zoom In' }, + { role: 'zoomOut', label: 'Zoom Out' }, + { type: 'separator' }, + { role: 'togglefullscreen', label: 'Toggle Fullscreen' } + ] + }, + { + label: 'Window', + submenu: [ + { role: 'minimize', label: 'Minimize' }, + { role: 'close', label: 'Close' } + ] + } +] + +// macOS: Add app menu +if (process.platform === 'darwin') { + template.unshift({ + label: app.getName(), + submenu: [ + { role: 'about', label: 'About' }, + { type: 'separator' }, + { role: 'services', label: 'Services' }, + { type: 'separator' }, + { role: 'hide', label: 'Hide' }, + { role: 'hideOthers', label: 'Hide Others' }, + { role: 'unhide', label: 'Show All' }, + { type: 'separator' }, + { role: 'quit', label: 'Quit' } + ] + }) +} + +const menu = Menu.buildFromTemplate(template) +Menu.setApplicationMenu(menu) +``` + +### Example: Context Menu + +```javascript +const { Menu, MenuItem } = require('electron') + +// In preload.js +const { contextBridge } = require('electron') + +contextBridge.exposeInMainWorld('electronAPI', { + showContextMenu: () => { + const menu = new Menu() + + menu.append(new MenuItem({ + label: 'Copy', + role: 'copy' + })) + + menu.append(new MenuItem({ + label: 'Paste', + role: 'paste' + })) + + menu.append(new MenuItem({ + type: 'separator' + })) + + menu.append(new MenuItem({ + label: 'Custom Action', + click: () => { + console.log('Custom action clicked') + } + })) + + menu.popup() + } +}) +``` + +### Example: Dynamic Menu + +```javascript +const { Menu } = require('electron') + +function updateMenu(hasFile) { + const template = [ + { + label: 'File', + submenu: [ + { + label: 'New', + enabled: true, + click: () => createNewFile() + }, + { + label: 'Open', + enabled: true, + click: () => openFile() + }, + { + label: 'Save', + enabled: hasFile, + click: () => saveFile() + } + ] + } + ] + + const menu = Menu.buildFromTemplate(template) + Menu.setApplicationMenu(menu) +} +``` + +### Key Points + +- Use Menu.buildFromTemplate() to create menus +- Use Menu.setApplicationMenu() for app menu +- Use menu.popup() for context menus +- Use role property for standard menu items +- Use accelerator for keyboard shortcuts +- macOS requires special app menu structure +- Context menus should be created in preload or main process diff --git a/.agents/skills/electron/examples/getting-started/installation.md b/.agents/skills/electron/examples/getting-started/installation.md new file mode 100644 index 000000000000..ea756ec72d7a --- /dev/null +++ b/.agents/skills/electron/examples/getting-started/installation.md @@ -0,0 +1,88 @@ +# Installation | 安装 + +**官方文档**: https://www.electronjs.org/zh/docs/latest/, + + +## Instructions + +This example demonstrates how to install Electron and set up a basic project. + +### Key Concepts + +- Installing Electron +- Project structure +- package.json configuration +- Running Electron app + +### Example: Installation + +```bash +# Using npm +npm install electron --save-dev + +# Using yarn +yarn add electron --dev + +# Using pnpm +pnpm add electron --save-dev +``` + +### Example: Basic package.json + +```json +{ + "name": "my-electron-app", + "version": "1.0.0", + "description": "My Electron app", + "main": "main.js", + "scripts": { + "start": "electron .", + "dev": "electron ." + }, + "devDependencies": { + "electron": "^latest" + } +} +``` + +### Example: Project Structure + +``` +my-electron-app/ +├── main.js # Main process entry point +├── preload.js # Preload script (optional) +├── renderer/ +│ ├── index.html # Renderer HTML +│ └── renderer.js # Renderer script +├── package.json +└── README.md +``` + +### Example: Running the App + +```bash +# Start the app +npm start + +# Or directly +npx electron . +``` + +### Example: Using Electron Forge + +```bash +# Create new project with Electron Forge +npm create electron-app@latest my-app + +# Or add to existing project +npx @electron-forge/cli import +``` + +### Key Points + +- Install Electron as dev dependency +- Set `main` field in package.json to main process file +- Use `electron .` to run the app +- Main process file (main.js) is required +- Electron Forge can scaffold projects automatically +- Works on Windows, macOS, and Linux diff --git a/.agents/skills/electron/examples/getting-started/quick-start.md b/.agents/skills/electron/examples/getting-started/quick-start.md new file mode 100644 index 000000000000..7da614e49a69 --- /dev/null +++ b/.agents/skills/electron/examples/getting-started/quick-start.md @@ -0,0 +1,104 @@ +# Quick Start | 快速开始 + +**官方文档**: https://www.electronjs.org/zh/docs/latest/, + + +## Instructions + +This example demonstrates how to create a basic Electron application. + +### Key Concepts + +- Main process setup +- Creating BrowserWindow +- Loading HTML content +- App lifecycle + +### Example: Basic main.js + +```javascript +// main.js +const { app, BrowserWindow } = require('electron') +const path = require('path') + +function createWindow() { + const win = new BrowserWindow({ + width: 800, + height: 600, + webPreferences: { + preload: path.join(__dirname, 'preload.js') + } + }) + + win.loadFile('index.html') +} + +app.whenReady().then(() => { + createWindow() + + app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) { + createWindow() + } + }) +}) + +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { + app.quit() + } +}) +``` + +### Example: Basic index.html + +```html + + +
+ +Welcome to Electron
+ + + +``` + +### Example: Basic preload.js + +```javascript +// preload.js +const { contextBridge, ipcRenderer } = require('electron') + +// Expose protected methods that allow the renderer process to use +// the ipcRenderer without exposing the entire object +contextBridge.exposeInMainWorld('electronAPI', { + openFile: () => ipcRenderer.invoke('dialog:openFile') +}) +``` + +### Example: Basic renderer.js + +```javascript +// renderer.js +document.addEventListener('DOMContentLoaded', () => { + console.log('Renderer process loaded') + + // Use exposed API from preload + window.electronAPI.openFile().then(result => { + console.log('File selected:', result) + }) +}) +``` + +### Key Points + +- Main process (main.js) controls app lifecycle +- BrowserWindow creates application windows +- loadFile() loads local HTML files +- Preload scripts bridge main and renderer safely +- Renderer process runs web content +- Use contextBridge for secure IPC exposure diff --git a/.agents/skills/electron/examples/processes/ipc-communication.md b/.agents/skills/electron/examples/processes/ipc-communication.md new file mode 100644 index 000000000000..a20c0df0ed47 --- /dev/null +++ b/.agents/skills/electron/examples/processes/ipc-communication.md @@ -0,0 +1,140 @@ +# IPC Communication | IPC 通信 + +**官方文档**: https://www.electronjs.org/zh/docs/latest/, + + +## Instructions + +This example demonstrates IPC (Inter-Process Communication) between main and renderer processes. + +### Key Concepts + +- ipcMain in main process +- ipcRenderer in renderer process +- contextBridge for secure exposure +- Two-way communication + +### Example: Basic IPC Setup + +```javascript +// main.js +const { app, BrowserWindow, ipcMain } = require('electron') +const path = require('path') + +let mainWindow + +function createWindow() { + mainWindow = new BrowserWindow({ + width: 800, + height: 600, + webPreferences: { + preload: path.join(__dirname, 'preload.js'), + contextIsolation: true, + nodeIntegration: false + } + }) + + mainWindow.loadFile('index.html') +} + +// Handle IPC from renderer +ipcMain.handle('get-app-version', () => { + return app.getVersion() +}) + +ipcMain.on('window-minimize', () => { + mainWindow.minimize() +}) + +app.whenReady().then(() => { + createWindow() +}) +``` + +### Example: Preload Script + +```javascript +// preload.js +const { contextBridge, ipcRenderer } = require('electron') + +// Expose safe API to renderer +contextBridge.exposeInMainWorld('electronAPI', { + getVersion: () => ipcRenderer.invoke('get-app-version'), + minimizeWindow: () => ipcRenderer.send('window-minimize'), + + // Two-way communication + openFile: () => ipcRenderer.invoke('dialog:openFile'), + + // Listen to main process + onUpdateAvailable: (callback) => { + ipcRenderer.on('update-available', (event, data) => callback(data)) + } +}) +``` + +### Example: Renderer Process + +```javascript +// renderer.js +document.addEventListener('DOMContentLoaded', () => { + // Get app version + window.electronAPI.getVersion().then(version => { + console.log('App version:', version) + }) + + // Minimize window + document.getElementById('minimize-btn').addEventListener('click', () => { + window.electronAPI.minimizeWindow() + }) + + // Open file dialog + document.getElementById('open-file-btn').addEventListener('click', async () => { + const result = await window.electronAPI.openFile() + console.log('Selected file:', result) + }) + + // Listen for updates + window.electronAPI.onUpdateAvailable((data) => { + console.log('Update available:', data) + }) +}) +``` + +### Example: Advanced IPC Patterns + +```javascript +// main.js +const { ipcMain, dialog } = require('electron') + +// Handle with async response +ipcMain.handle('dialog:openFile', async () => { + const { canceled, filePaths } = await dialog.showOpenDialog({ + properties: ['openFile'] + }) + + if (!canceled) { + return filePaths[0] + } + return null +}) + +// Send to renderer +ipcMain.on('check-updates', () => { + // Simulate update check + setTimeout(() => { + mainWindow.webContents.send('update-available', { + version: '1.0.1', + url: 'https://example.com/update' + }) + }, 2000) +}) +``` + +### Key Points + +- Use ipcMain.handle() for request-response pattern +- Use ipcMain.on() for one-way communication +- Use contextBridge.exposeInMainWorld() for secure API exposure +- Never expose ipcRenderer directly to renderer +- Use contextIsolation: true and nodeIntegration: false +- IPC enables safe communication between processes diff --git a/.agents/skills/electron/examples/processes/main-process.md b/.agents/skills/electron/examples/processes/main-process.md new file mode 100644 index 000000000000..2f7237e9883d --- /dev/null +++ b/.agents/skills/electron/examples/processes/main-process.md @@ -0,0 +1,121 @@ +# Main Process | 主进程 + +**官方文档**: https://www.electronjs.org/zh/docs/latest/, + + +## Instructions + +This example demonstrates main process concepts and usage in Electron. + +### Key Concepts + +- Main process role +- App lifecycle events +- Creating windows +- Managing application state + +### Example: App Lifecycle + +```javascript +// main.js +const { app, BrowserWindow } = require('electron') + +let mainWindow + +function createWindow() { + mainWindow = new BrowserWindow({ + width: 800, + height: 600, + webPreferences: { + nodeIntegration: false, + contextIsolation: true, + preload: path.join(__dirname, 'preload.js') + } + }) + + mainWindow.loadFile('index.html') + + mainWindow.on('closed', () => { + mainWindow = null + }) +} + +// App ready +app.whenReady().then(() => { + createWindow() +}) + +// macOS: Re-open window when dock icon is clicked +app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) { + createWindow() + } +}) + +// Quit when all windows are closed (except macOS) +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { + app.quit() + } +}) +``` + +### Example: App Events + +```javascript +const { app } = require('electron') + +// Before app quits +app.on('before-quit', (event) => { + console.log('App is about to quit') +}) + +// Will quit +app.on('will-quit', (event) => { + console.log('App will quit') +}) + +// Quit +app.on('quit', () => { + console.log('App quit') +}) + +// Second instance +app.on('second-instance', () => { + // Focus existing window + if (mainWindow) { + if (mainWindow.isMinimized()) mainWindow.restore() + mainWindow.focus() + } +}) +``` + +### Example: Single Instance App + +```javascript +const { app } = require('electron') + +const gotTheLock = app.requestSingleInstanceLock() + +if (!gotTheLock) { + app.quit() +} else { + app.on('second-instance', () => { + // Handle second instance + }) + + // Continue with app initialization + app.whenReady().then(() => { + createWindow() + }) +} +``` + +### Key Points + +- Main process manages app lifecycle +- Use app.whenReady() before creating windows +- Handle window-all-closed for proper quit behavior +- macOS requires special handling for dock icon +- Use requestSingleInstanceLock() for single instance apps +- Main process has full Node.js access diff --git a/.agents/skills/electron/templates/main-process.md b/.agents/skills/electron/templates/main-process.md new file mode 100644 index 000000000000..94672eec4ee3 --- /dev/null +++ b/.agents/skills/electron/templates/main-process.md @@ -0,0 +1,105 @@ +# Main Process Template | 主进程模板 + +## Basic Main Process Template + +```javascript +// main.js +const { app, BrowserWindow } = require('electron') +const path = require('path') + +let mainWindow + +function createWindow() { + mainWindow = new BrowserWindow({ + width: 800, + height: 600, + webPreferences: { + preload: path.join(__dirname, 'preload.js'), + contextIsolation: true, + nodeIntegration: false + } + }) + + mainWindow.loadFile('index.html') + + // Open DevTools in development + if (process.env.NODE_ENV === 'development') { + mainWindow.webContents.openDevTools() + } + + mainWindow.on('closed', () => { + mainWindow = null + }) +} + +app.whenReady().then(() => { + createWindow() + + app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) { + createWindow() + } + }) +}) + +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { + app.quit() + } +}) +``` + +## With IPC Setup + +```javascript +// main.js +const { app, BrowserWindow, ipcMain } = require('electron') +const path = require('path') + +let mainWindow + +function createWindow() { + mainWindow = new BrowserWindow({ + width: 800, + height: 600, + webPreferences: { + preload: path.join(__dirname, 'preload.js'), + contextIsolation: true, + nodeIntegration: false + } + }) + + mainWindow.loadFile('index.html') + + mainWindow.on('closed', () => { + mainWindow = null + }) +} + +// IPC Handlers +ipcMain.handle('get-app-version', () => { + return app.getVersion() +}) + +ipcMain.on('window-minimize', () => { + if (mainWindow) { + mainWindow.minimize() + } +}) + +app.whenReady().then(() => { + createWindow() +}) + +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { + app.quit() + } +}) + +app.on('activate', () => { + if (BrowserWindow.getAllWindows().length === 0) { + createWindow() + } +}) +``` diff --git a/.agents/skills/electron/templates/preload-script.md b/.agents/skills/electron/templates/preload-script.md new file mode 100644 index 000000000000..e0106e76e730 --- /dev/null +++ b/.agents/skills/electron/templates/preload-script.md @@ -0,0 +1,84 @@ +# Preload Script Template | Preload 脚本模板 + +## Basic Preload Script + +```javascript +// preload.js +const { contextBridge, ipcRenderer } = require('electron') + +// Expose protected methods to renderer +contextBridge.exposeInMainWorld('electronAPI', { + // Get app version + getVersion: () => ipcRenderer.invoke('get-app-version'), + + // Window controls + minimize: () => ipcRenderer.send('window-minimize'), + maximize: () => ipcRenderer.send('window-maximize'), + close: () => ipcRenderer.send('window-close'), + + // File operations + openFile: () => ipcRenderer.invoke('dialog:openFile'), + saveFile: (data) => ipcRenderer.invoke('dialog:saveFile', data), + + // Listen to main process + onUpdateAvailable: (callback) => { + ipcRenderer.on('update-available', (event, data) => callback(data)) + }, + + // Remove listeners + removeAllListeners: (channel) => { + ipcRenderer.removeAllListeners(channel) + } +}) +``` + +## Advanced Preload Script + +```javascript +// preload.js +const { contextBridge, ipcRenderer } = require('electron') + +// Expose API with error handling +contextBridge.exposeInMainWorld('electronAPI', { + // Safe IPC invoke + invoke: async (channel, ...args) => { + const validChannels = [ + 'get-app-version', + 'dialog:openFile', + 'dialog:saveFile' + ] + + if (validChannels.includes(channel)) { + return await ipcRenderer.invoke(channel, ...args) + } + throw new Error(`Invalid channel: ${channel}`) + }, + + // Safe IPC send + send: (channel, ...args) => { + const validChannels = [ + 'window-minimize', + 'window-maximize', + 'window-close' + ] + + if (validChannels.includes(channel)) { + ipcRenderer.send(channel, ...args) + } + }, + + // Safe event listener + on: (channel, callback) => { + const validChannels = ['update-available', 'app-version'] + + if (validChannels.includes(channel)) { + ipcRenderer.on(channel, (event, ...args) => callback(...args)) + } + }, + + // Remove listener + removeListener: (channel, callback) => { + ipcRenderer.removeListener(channel, callback) + } +}) +``` diff --git a/.augment/skills/electron b/.augment/skills/electron new file mode 120000 index 000000000000..d04d1cd05cfd --- /dev/null +++ b/.augment/skills/electron @@ -0,0 +1 @@ +../../.agents/skills/electron \ No newline at end of file diff --git a/.claude/skills/electron b/.claude/skills/electron new file mode 120000 index 000000000000..d04d1cd05cfd --- /dev/null +++ b/.claude/skills/electron @@ -0,0 +1 @@ +../../.agents/skills/electron \ No newline at end of file diff --git a/.cline/skills/electron b/.cline/skills/electron new file mode 120000 index 000000000000..d04d1cd05cfd --- /dev/null +++ b/.cline/skills/electron @@ -0,0 +1 @@ +../../.agents/skills/electron \ No newline at end of file diff --git a/.continue/skills/electron b/.continue/skills/electron new file mode 120000 index 000000000000..d04d1cd05cfd --- /dev/null +++ b/.continue/skills/electron @@ -0,0 +1 @@ +../../.agents/skills/electron \ No newline at end of file diff --git a/.crush/skills/electron b/.crush/skills/electron new file mode 120000 index 000000000000..d04d1cd05cfd --- /dev/null +++ b/.crush/skills/electron @@ -0,0 +1 @@ +../../.agents/skills/electron \ No newline at end of file diff --git a/.cursor/skills/electron b/.cursor/skills/electron new file mode 120000 index 000000000000..d04d1cd05cfd --- /dev/null +++ b/.cursor/skills/electron @@ -0,0 +1 @@ +../../.agents/skills/electron \ No newline at end of file diff --git a/.devcontainer/devcontainer-lock.json b/.devcontainer/devcontainer-lock.json index fdd03c400cc0..cbcde9bb1093 100644 --- a/.devcontainer/devcontainer-lock.json +++ b/.devcontainer/devcontainer-lock.json @@ -4,11 +4,6 @@ "version": "1.0.8", "resolved": "ghcr.io/devcontainers/features/desktop-lite@sha256:e7dc4d37ab9e3d6e7ebb221bac741f5bfe07dae47025399d038b17af2ed8ddb7", "integrity": "sha256:e7dc4d37ab9e3d6e7ebb221bac741f5bfe07dae47025399d038b17af2ed8ddb7" - }, - "ghcr.io/devcontainers/features/rust:1": { - "version": "1.1.3", - "resolved": "ghcr.io/devcontainers/features/rust@sha256:aba6f47303b197976902bf544c786b5efecc03c238ff593583e5e74dfa9c7ccb", - "integrity": "sha256:aba6f47303b197976902bf544c786b5efecc03c238ff593583e5e74dfa9c7ccb" } } } \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 75076a0f8b65..ae90f48d741a 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,11 +1,12 @@ { "name": "Code - OSS", + "remoteUser": "node", + "updateRemoteUserUID": true, "build": { "dockerfile": "Dockerfile" }, "features": { - "ghcr.io/devcontainers/features/desktop-lite:1": {}, - "ghcr.io/devcontainers/features/rust:1": {} + "ghcr.io/devcontainers/features/desktop-lite:1": {} }, "containerEnv": { "DISPLAY": "" // Allow the Dev Containers extension to set DISPLAY, post-create.sh will add it back in ~/.bashrc and ~/.zshrc if not set. diff --git a/.junie/skills/electron b/.junie/skills/electron new file mode 120000 index 000000000000..d04d1cd05cfd --- /dev/null +++ b/.junie/skills/electron @@ -0,0 +1 @@ +../../.agents/skills/electron \ No newline at end of file diff --git a/.kilocode/skills/electron b/.kilocode/skills/electron new file mode 120000 index 000000000000..d04d1cd05cfd --- /dev/null +++ b/.kilocode/skills/electron @@ -0,0 +1 @@ +../../.agents/skills/electron \ No newline at end of file diff --git a/.npmrc b/.npmrc index 71d98e6c5834..192a8dd0b1bd 100644 --- a/.npmrc +++ b/.npmrc @@ -5,3 +5,4 @@ runtime="electron" build_from_source="true" legacy-peer-deps="true" timeout=180000 +node_gyp_cflags=-std=c++20 diff --git a/.qwen/skills/electron b/.qwen/skills/electron new file mode 120000 index 000000000000..d04d1cd05cfd --- /dev/null +++ b/.qwen/skills/electron @@ -0,0 +1 @@ +../../.agents/skills/electron \ No newline at end of file diff --git a/.roo/skills/electron b/.roo/skills/electron new file mode 120000 index 000000000000..d04d1cd05cfd --- /dev/null +++ b/.roo/skills/electron @@ -0,0 +1 @@ +../../.agents/skills/electron \ No newline at end of file diff --git a/.trae/skills/electron b/.trae/skills/electron new file mode 120000 index 000000000000..d04d1cd05cfd --- /dev/null +++ b/.trae/skills/electron @@ -0,0 +1 @@ +../../.agents/skills/electron \ No newline at end of file diff --git a/.windsurf/skills/electron b/.windsurf/skills/electron new file mode 120000 index 000000000000..d04d1cd05cfd --- /dev/null +++ b/.windsurf/skills/electron @@ -0,0 +1 @@ +../../.agents/skills/electron \ No newline at end of file diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index 6be514a4572f..29f49e7348b6 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -4,6 +4,34 @@ This repository incorporates material as listed below or described in the code. +--------------------------------------------------------- + +castrogusttavo/symbols 0.0.18 - MIT +https://open-vsx.org/extension/castrogusttavo/symbols +https://github.com/miguelsolorio/vscode-symbols + +MIT License + +Copyright (c) 2021 Miguel Solorio + +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. + --------------------------------------------------------- @fig/autocomplete-shared 1.1.2 diff --git a/extensions/continue/LICENSE.txt b/extensions/continue/LICENSE.txt new file mode 100644 index 000000000000..a12f2a758059 --- /dev/null +++ b/extensions/continue/LICENSE.txt @@ -0,0 +1,13 @@ +Copyright 2023 Continue + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. \ No newline at end of file diff --git a/extensions/continue/README.md b/extensions/continue/README.md new file mode 100644 index 000000000000..1060646e053e --- /dev/null +++ b/extensions/continue/README.md @@ -0,0 +1,54 @@ +openai or azure",
+ "enum": ["openai", "azure"]
+ },
+ "apiVersion": {
+ "title": "Api Version",
+ "description": "Azure OpenAI API version (e.g. 2023-07-01-preview)",
+ "type": "string"
+ },
+ "deployment": {
+ "title": "Deployment",
+ "description": "Azure OpenAI deployment",
+ "type": "string"
+ },
+ "capabilities": {
+ "type": "object",
+ "description": "We will attempt to automatically detect the capabilities of the model based on its title and provider, but this may not always be accurate. You can override the model's capabilities here.",
+ "properties": {
+ "uploadImage": {
+ "type": "boolean",
+ "description": "Indicates whether the model can upload images."
+ },
+ "tools": {
+ "type": "boolean",
+ "description": "Indicates whether the model can use tools"
+ }
+ }
+ }
+ },
+ "required": ["title", "provider", "model"],
+ "allOf": [
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "type": "str"
+ }
+ },
+ "not": {
+ "required": ["provider"]
+ }
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "description": "Choose a provider first, then model options will be shown here."
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "openai",
+ "anthropic",
+ "cohere",
+ "gemini",
+ "huggingface-inference-api",
+ "replicate",
+ "together",
+ "ncompass",
+ "novita",
+ "cloudflare",
+ "sambanova",
+ "nebius",
+ "xAI",
+ "kindo",
+ "scaleway",
+ "ovhcloud",
+ "venice"
+ ]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "required": ["apiKey"]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["bedrockimport"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "required": ["modelArn"]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["huggingface-tgi", "huggingface-inference-api"]
+ }
+ }
+ },
+ "then": {
+ "required": ["apiBase"]
+ },
+ "required": ["provider"]
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["openai"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "deployment": {
+ "type": "string"
+ },
+ "apiType": {
+ "type": "string"
+ },
+ "apiVersion": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["cloudflare"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "accountId": {
+ "type": "string"
+ },
+ "aiGatewaySlug": {
+ "type": "string"
+ },
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "@cf/meta/llama-3-8b-instruct",
+ "@hf/thebloke/deepseek-coder-6.7b-instruct-awq",
+ "@cf/deepseek-ai/deepseek-math-7b-instruct",
+ "@cf/thebloke/discolm-german-7b-v1-awq",
+ "@cf/tiiuae/falcon-7b-instruct",
+ "@cf/google/gemma-2b-it-lora",
+ "@hf/google/gemma-7b-it",
+ "@cf/google/gemma-7b-it-lora",
+ "@hf/nousresearch/hermes-2-pro-mistral-7b",
+ "@cf/meta/llama-2-7b-chat-fp16",
+ "@cf/meta/llama-2-7b-chat-int8",
+ "@cf/meta-llama/llama-2-7b-chat-hf-lora",
+ "@hf/thebloke/llama-2-13b-chat-awq",
+ "@hf/thebloke/llamaguard-7b-awq",
+ "@cf/mistral/mistral-7b-instruct-v0.1",
+ "@hf/mistral/mistral-7b-instruct-v0.2",
+ "@cf/mistral/mistral-7b-instruct-v0.2-lora",
+ "@hf/thebloke/neural-chat-7b-v3-1-awq",
+ "@cf/openchat/openchat-3.5-0106",
+ "@hf/thebloke/openhermes-2.5-mistral-7b-awq",
+ "@cf/microsoft/phi-2",
+ "@cf/qwen/qwen1.5-0.5b-chat",
+ "@cf/qwen/qwen1.5-1.8b-chat",
+ "@cf/qwen/qwen1.5-7b-chat-awq",
+ "@cf/qwen/qwen1.5-14b-chat-awq",
+ "@cf/defog/sqlcoder-7b-2",
+ "@hf/nexusflow/starling-lm-7b-beta",
+ "@cf/tinyllama/tinyllama-1.1b-chat-v1.0",
+ "@hf/thebloke/zephyr-7b-beta-awq",
+ "@hf/thebloke/deepseek-coder-6.7b-base-awq"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["openai"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "gpt-3.5-turbo",
+ "gpt-3.5-turbo-16k",
+ "gpt-4o",
+ "gpt-4o-mini",
+ "gpt-4",
+ "gpt-3.5-turbo-0613",
+ "gpt-4-32k",
+ "gpt-4-0125-preview",
+ "gpt-4-turbo",
+ "AUTODETECT"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["xAI"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": ["grok-beta", "AUTODETECT"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["replicate"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama3.1-405b",
+ "llama3-8b",
+ "llama3-70b",
+ "codellama-7b",
+ "codellama-13b",
+ "codellama-34b",
+ "llama2-7b",
+ "llama2-13b"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "markdownDescription": "Select a pre-defined option, or find an exact model ID from Replicate [here](https://replicate.com/collections/streaming-language-models).",
+ "x-intellij-html-description": "Select a pre-defined option, or find an exact model ID from Replicate here."
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["openai"]
+ },
+ "apiType": {
+ "not": {
+ "const": "azure"
+ }
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "gpt-3.5-turbo",
+ "gpt-3.5-turbo-16k",
+ "gpt-4o",
+ "gpt-4o-mini",
+ "gpt-4",
+ "gpt-3.5-turbo-0613",
+ "gpt-4-32k",
+ "gpt-4-turbo",
+ "gpt-4-vision-preview",
+ "mistral-7b",
+ "mistral-8x7b",
+ "llama2-7b",
+ "llama2-13b",
+ "codellama-7b",
+ "codellama-13b",
+ "codellama-34b",
+ "codellama-70b",
+ "llama3-8b",
+ "llama3-70b",
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama3.1-405b",
+ "phind-codellama-34b",
+ "wizardcoder-7b",
+ "wizardcoder-13b",
+ "wizardcoder-34b",
+ "zephyr-7b",
+ "codeup-13b",
+ "deepseek-7b",
+ "deepseek-33b",
+ "neural-chat-7b",
+ "deepseek-1b",
+ "stable-code-3b",
+ "starcoder-1b",
+ "starcoder-3b",
+ "starcoder2-3b",
+ "mistral-tiny",
+ "mistral-small",
+ "mistral-medium",
+ "qwen2.5-coder:1.5b",
+ "qwen2.5-coder:3b",
+ "qwen2.5-coder:7b",
+ "qwen2.5-coder:14b",
+ "qwen2.5-coder:32b",
+ "AUTODETECT"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["anthropic"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "cacheBehavior": {
+ "title": "Caching Behavior",
+ "description": "Options for the prompt caching",
+ "properties": {
+ "cacheSystemMessage": {
+ "type": "boolean"
+ },
+ "cacheConversation": {
+ "type": "boolean"
+ }
+ }
+ },
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "claude-sonnet-4",
+ "claude-sonnet-4-5",
+ "claude-opus-4-1",
+ "claude-haiku-4-5"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["cohere"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "enum": [
+ "c4ai-aya-expanse-8b",
+ "c4ai-aya-expanse-32b",
+ "c4ai-aya-vision-8b",
+ "c4ai-aya-vision-32b",
+ "command-r",
+ "command-r-plus",
+ "command-r-03-2024",
+ "command-r-plus-04-2024",
+ "command-r-08-2024",
+ "command-r-plus-08-2024",
+ "command-r7b-12-2024",
+ "command-r7b-arabic-02-2025",
+ "command-a-03-2025",
+ "command-a-vision-07-2025",
+ "command-a-reasoning-08-2025",
+ "command-a-translate-08-2025"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["bedrock"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "claude-3-sonnet-20240229",
+ "claude-3-haiku-20240307",
+ "claude-2"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["sagemaker"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "description": "SageMaker endpoint name"
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["gemini"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "cacheBehavior": {
+ "title": "Caching Behavior",
+ "description": "Options for the prompt caching",
+ "properties": {
+ "cacheSystemMessage": {
+ "type": "boolean"
+ }
+ }
+ },
+ "model": {
+ "enum": [
+ "chat-bison-001",
+ "gemini-pro",
+ "gemini-2.0-flash-exp",
+ "gemini-2.0-flash",
+ "gemini-2.0-flash-thinking-exp-01-21",
+ "gemini-2.0-pro-exp-02-05",
+ "gemini-2.0-flash-lite-preview-02-05",
+ "gemini-2.0-flash-lite",
+ "gemini-2.0-flash-exp-image-generation",
+ "gemini-2.5-pro-latest"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["together"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "mistral-7b",
+ "mistral-8x7b",
+ "llama2-7b",
+ "llama2-13b",
+ "llama3-8b",
+ "llama3-70b",
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama3.1-405b",
+ "codellama-7b",
+ "codellama-13b",
+ "codellama-34b",
+ "codellama-70b",
+ "phind-codellama-34b"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ],
+ "markdownDescription": "Select a pre-defined option, or find an exact model string from Together AI [here](https://docs.together.ai/docs/inference-models).",
+ "x-intellij-html-description": "Select a pre-defined option, or find an exact model string from Together AI here."
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["novita"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "deepseek-r1",
+ "deepseek_v3",
+ "llama3-8b",
+ "llama3-70b",
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama3.1-405b",
+ "llama3.2-1b",
+ "llama3.2-3b",
+ "llama3.2-11b",
+ "llama3.3-70b",
+ "mistral-nemo",
+ "mistral-7b"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ],
+ "markdownDescription": "Select a pre-defined option, or find an exact model string from Novita AI [here](https://novita.ai/llm-api?utm_source=github_continuedev&utm_medium=github_readme&utm_campaign=github_link).",
+ "x-intellij-html-description": "Select a pre-defined option, or find an exact model string from Novita AI here."
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["deepinfra"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "markdownDescription": "Find the model name you want to use from DeepInfra [here](https://deepinfra.com/models?type=text-generation).",
+ "x-intellij-html-description": "Find the model name you want to use from DeepInfra here."
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "huggingface-tgi",
+ "huggingface-inference-api",
+ "llama.cpp",
+ "text-gen-webui",
+ "llamafile"
+ ]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "mistral-7b",
+ "mistral-8x7b",
+ "llama2-7b",
+ "llama2-13b",
+ "codellama-7b",
+ "codellama-13b",
+ "codellama-34b",
+ "codellama-70b",
+ "llama3-8b",
+ "llama3-70b",
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama3.1-405b",
+ "phind-codellama-34b",
+ "wizardcoder-7b",
+ "wizardcoder-13b",
+ "wizardcoder-34b",
+ "zephyr-7b",
+ "codeup-13b",
+ "deepseek-7b",
+ "deepseek-33b",
+ "neural-chat-7b",
+ "deepseek-1b",
+ "stable-code-3b",
+ "starcoder-1b",
+ "starcoder-3b",
+ "starcoder2-3b",
+ "qwen2.5-coder:1.5b",
+ "qwen2.5-coder:3b",
+ "qwen2.5-coder:7b",
+ "qwen2.5-coder:14b",
+ "qwen2.5-coder:32b"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["ollama"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "mistral-7b",
+ "llama2-7b",
+ "llama2-13b",
+ "codellama-7b",
+ "codellama-13b",
+ "codellama-34b",
+ "codellama-70b",
+ "llama3-8b",
+ "llama3-70b",
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama3.1-405b",
+ "phi-2",
+ "phind-codellama-34b",
+ "wizardcoder-7b",
+ "wizardcoder-13b",
+ "wizardcoder-34b",
+ "zephyr-7b",
+ "codeup-13b",
+ "deepseek-7b",
+ "deepseek-33b",
+ "neural-chat-7b",
+ "deepseek-1b",
+ "stable-code-3b",
+ "starcoder-1b",
+ "starcoder-3b",
+ "starcoder2-3b",
+ "qwen2.5-coder:1.5b",
+ "qwen2.5-coder:3b",
+ "qwen2.5-coder:7b",
+ "qwen2.5-coder:14b",
+ "qwen2.5-coder:32b",
+ "AUTODETECT"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ],
+ "markdownDescription": "Select a pre-defined option, or find the exact model tag for an Ollama model [here](https://ollama.ai/library).",
+ "x-intellij-html-description": "Select a pre-defined option, or find the exact model tag for an Ollama model here."
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["mistral"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "enum": [
+ "codestral-latest",
+ "codestral-mamba-latest",
+ "open-mistral-7b",
+ "open-mixtral-8x7b",
+ "open-mixtral-8x22b",
+ "mistral-small-latest",
+ "mistral-large-latest"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["vertexai"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "required": ["projectId", "region"]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["moonshot"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "moonshot-v1-8k",
+ "moonshot-v1-32k",
+ "moonshot-v1-128k",
+ "AUTODETECT"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["deepseek"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "cacheBehavior": {
+ "title": "Caching Behavior",
+ "description": "Options for the prompt caching",
+ "properties": {
+ "cacheSystemMessage": {
+ "type": "boolean"
+ },
+ "cacheConversation": {
+ "type": "boolean"
+ }
+ }
+ },
+ "model": {
+ "enum": ["deepseek-chat", "deepseek-coder"]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["groq"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "enum": [
+ "llama2-70b",
+ "mistral-8x7b",
+ "gemma",
+ "gemma2",
+ "llama3-8b",
+ "llama3-70b",
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama3.1-405b",
+ "AUTODETECT"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["siliconflow"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "enum": [
+ "Qwen/QwQ-32B-Preview",
+ "Qwen/Qwen2.5-Coder-32B-Instruct",
+ "Qwen/Qwen2.5-Coder-7B-Instruct",
+ "Pro/Qwen/Qwen2.5-Coder-7B-Instruct",
+ "Tencent/Hunyuan-A52B-Instruct",
+ "nvidia/Llama-3.1-Nemotron-70B-Instruct",
+ "Qwen/Qwen2-VL-72B-Instruct",
+ "TeleAI/TeleMM",
+ "deepseek-ai/DeepSeek-V2.5",
+ "deepseek-ai/deepseek-vl2",
+ "deepseek-ai/Janus-Pro-7B",
+ "deepseek-ai/DeepSeek-V3",
+ "deepseek-ai/DeepSeek-R1",
+ "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B",
+ "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B",
+ "deepseek-ai/DeepSeek-R1-Distill-Llama-70B",
+ "deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B",
+ "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B",
+ "deepseek-ai/DeepSeek-R1-Distill-Llama-8B"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["scaleway"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "llama-3.1-8b-instruct",
+ "llama-3.1-70b-instruct",
+ "mistral-nemo-instruct-2407",
+ "qwen2.5-coder-32b-instruct",
+ "pixtral-12b-2409"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ],
+ "markdownDescription": "Select a pre-defined option, or find the exact model string from Scaleway [here](https://www.scaleway.com/en/docs/ai-data/generative-apis/reference-content/supported-models/).",
+ "x-intellij-html-description": "Select a pre-defined option, or find the exact model string from Scaleway here."
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["ovhcloud"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama3.3-70b",
+ "qwen2.5-coder-32b",
+ "qwen3-32b",
+ "qwen3-coder-30b-a3b",
+ "qwen2.5-vl-72b",
+ "codestral-mamba-latest",
+ "mistral-7b",
+ "mistral-8x7b",
+ "mistral-nemo",
+ "mistral-small-3.2-24b",
+ "gpt-oss-20b",
+ "gpt-oss-120b",
+ "DeepSeek-R1-Distill-Llama-70B"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ],
+ "markdownDescription": "Select a pre-defined option, or find the exact model string from OVHcloud [AI Endpoints catalog](https://endpoints.ai.cloud.ovh.net/catalog).",
+ "x-intellij-html-description": "Select a pre-defined option, or find the exact model string from OVHcloud AI Endpoints catalog."
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["fireworks"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "enum": ["starcoder-7b"]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["ncompass"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "enum": ["qwen2.5-coder-32b", "qwen2.5-72b", "llama3.3-70b"]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "apiType": {
+ "const": "azure"
+ }
+ },
+ "required": ["apiType"]
+ },
+ "then": {
+ "required": ["deployment", "apiBase"]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["openai"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "useLegacyCompletionsEndpoint": {
+ "type": "boolean"
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["cerebras"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "enum": [
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama-4-scout-17b-16e-instruct"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["flowise"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "timeout": {
+ "title": "Timeout",
+ "description": "Set the timeout for each request to Flowise. If you are running a local version of Flowise it might takes a while to respond, you might want to set this to avoid timeouts.",
+ "default": 5000,
+ "type": "integer"
+ },
+ "additionalHeaders": {
+ "description": "A list of additional headers",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "key": {
+ "title": "Key",
+ "description": "Header key",
+ "type": "string"
+ },
+ "value": {
+ "title": "Value",
+ "description": "Header value",
+ "type": "string"
+ }
+ },
+ "required": ["key", "value"]
+ }
+ },
+ "additionalFlowiseConfiguration": {
+ "description": "A list of additional properties to be sent along `overrideConfig`",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "key": {
+ "title": "Key",
+ "description": "Configuration Property key",
+ "type": "string"
+ },
+ "value": {
+ "title": "Value",
+ "description": "Configuration Property value"
+ }
+ },
+ "required": ["key", "value"]
+ }
+ },
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "gpt-3.5-turbo",
+ "gpt-3.5-turbo-16k",
+ "gpt-4o",
+ "gpt-4o-mini",
+ "gpt-4",
+ "gpt-3.5-turbo-0613",
+ "gpt-4-32k",
+ "gpt-4-turbo",
+ "gpt-4-vision-preview",
+ "mistral-7b",
+ "mistral-8x7b",
+ "llama2-7b",
+ "llama2-13b",
+ "codellama-7b",
+ "codellama-13b",
+ "codellama-34b",
+ "codellama-70b",
+ "llama3-8b",
+ "llama3-70b",
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama3.1-405b",
+ "phind-codellama-34b",
+ "wizardcoder-7b",
+ "wizardcoder-13b",
+ "wizardcoder-34b",
+ "zephyr-7b",
+ "codeup-13b",
+ "deepseek-7b",
+ "deepseek-33b",
+ "claude-sonnet-4",
+ "claude-sonnet-4-5",
+ "claude-opus-4-1",
+ "claude-haiku-4-5",
+ "command-r",
+ "command-r-plus",
+ "chat-bison-001",
+ "gemini-2.5-pro",
+ "mistral-tiny",
+ "mistral-small",
+ "mistral-medium",
+ "deepseek-1b",
+ "stable-code-3b",
+ "starcoder-1b",
+ "starcoder-3b",
+ "starcoder2-3b",
+ "qwen2.5-coder:1.5b",
+ "qwen2.5-coder:3b",
+ "qwen2.5-coder:7b",
+ "qwen2.5-coder:14b",
+ "qwen2.5-coder:32b"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["watsonx"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "apiBase": {
+ "type": "string"
+ },
+ "apiKey": {
+ "type": "string"
+ },
+ "apiVersion": {
+ "type": "string"
+ },
+ "projectId": {
+ "type": "string"
+ },
+ "deploymentId": {
+ "type": "string"
+ },
+ "model": {
+ "enum": [
+ "ibm/granite-13b-chat-v2",
+ "ibm/granite-3b-code-instruct",
+ "ibm/granite-8b-code-instruct",
+ "ibm/granite-20b-code-instruct",
+ "ibm/granite-3b-code-instruct",
+ "ibm/granite-8b-code-instruct",
+ "ibm/granite-34b-code-instruct",
+ "ibm/granite-3-8b-instruct",
+ "ibm/granite-3-2b-instruct",
+ "mistralai/mistral-large",
+ "meta-llama/llama-3-8b-instruct",
+ "meta-llama/llama-3-70b-instruct"
+ ]
+ }
+ },
+ "required": ["apiBase", "apiKey", "apiVersion"]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["sambanova"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "Llama-4-Scout-17B-16E-Instruct",
+ "Llama-4-Maverick-17B-128E-Instruct",
+ "Meta-Llama-3.3-70B-Instruct",
+ "Meta-Llama-3.1-8B-Instruct",
+ "Meta-Llama-3.1-405B-Instruct",
+ "Meta-Llama-3.2-1B-Instruct",
+ "Meta-Llama-3.2-3B-Instruct",
+ "QwQ-32B",
+ "DeepSeek-R1-Distill-Llama-70B",
+ "DeepSeek-R1",
+ "DeepSeek-V3-0324"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ],
+ "description": "Select a pre-defined option."
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["ask-sage"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "gpt-4o",
+ "gpt-4o-mini",
+ "gpt-4gov",
+ "gpt-4ogov",
+ "claude-3.5-sonnet",
+ "claude-3-opus",
+ "mistral-large",
+ "llama-3-chat",
+ "gemini-pro",
+ "AUTODETECT"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["venice"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": ["AUTODETECT"]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+ },
+ "SlashCommand": {
+ "title": "SlashCommand",
+ "type": "object",
+ "properties": {
+ "name": {
+ "title": "Name",
+ "anyOf": [
+ {
+ "enum": [
+ "issue",
+ "share",
+ "cmd",
+ "edit",
+ "comment",
+ "http",
+ "commit",
+ "review"
+ ],
+ "type": "string",
+ "markdownEnumDescriptions": [
+ "Generate a link to a drafted GitHub issue",
+ "Export the current chat session to markdown",
+ "Generate a terminal command and paste it into the terminal",
+ "Edit the highlighted code with given instructions",
+ "Add comments to the highlighted code",
+ "Write a custom slash command at your own HTTP endpoint. Set 'url' in the params object for the endpoint you have setup.",
+ "Generate a commit message for the current changes",
+ "Review code and give feedback"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "description": {
+ "title": "Description",
+ "type": "string"
+ },
+ "step": {
+ "title": "Step",
+ "description": "This property is no longer required and has no effect. To use a built-in slash command, instead set the 'name' property to one of the pre-configured options.",
+ "type": "string"
+ },
+ "params": {
+ "title": "Params",
+ "default": {},
+ "type": "object"
+ }
+ },
+ "allOf": [
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["issue"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "repositoryUrl": {
+ "type": "string",
+ "description": "Enter the URL of the GitHub repository for which you want to generate the issue."
+ }
+ },
+ "required": ["repositoryUrl"]
+ }
+ },
+ "required": ["params"]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["edit"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "recap": {
+ "type": "boolean",
+ "markdownDescription": "If recap is set to `true`, Continue will generate a summary of the changes after making the edit.",
+ "x-intellij-html-description": "If recap is set to true, Continue will generate a summary of the changes after making the edit."
+ },
+ "tokenLimit": {
+ "type": "integer",
+ "description": "By default, Continue doesn't let you edit extremely large ranges (beyond 1,200 tokens), because the LLM is unlikely to succeed. But if you would like to override this limit with the understanding of possible failure you may do so here."
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["share"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "outputDir": {
+ "type": "string",
+ "markdownDescription": "If outputDir is set to `.` or begins with `./` or `.\\`, file will be saved to the current workspace or a subdirectory thereof, respectively. `~` can similarly be used to specify the user's home directory.",
+ "x-intellij-html-description": "If outputDir is set to . or begins with ./ or .\\, file will be saved to the current workspace or a subdirectory thereof, respectively. ~ can similarly be used to specify the user's home directory."
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["commit"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "includeUnstaged": {
+ "type": "boolean",
+ "markdownDescription": "If set to `true`, then unstaged changes are also included in the prompt, otherwise only staged changes are included. Default is `false`.",
+ "x-intellij-html-description": "If set to true, then unstaged changes are also included in the prompt, otherwise only staged changes are included. Default is false."
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "required": ["name", "description"]
+ },
+ "CustomCommand": {
+ "title": "CustomCommand",
+ "type": "object",
+ "properties": {
+ "name": {
+ "title": "Name",
+ "type": "string"
+ },
+ "prompt": {
+ "title": "Prompt",
+ "type": "string"
+ },
+ "description": {
+ "title": "Description",
+ "type": "string"
+ }
+ },
+ "required": ["name", "prompt", "description"]
+ },
+ "ContextProviderWithParams": {
+ "title": "ContextProviderWithParams",
+ "type": "object",
+ "properties": {
+ "name": {
+ "title": "Name",
+ "anyOf": [
+ {
+ "enum": [
+ "diff",
+ "terminal",
+ "debugger",
+ "open",
+ "google",
+ "search",
+ "http",
+ "codebase",
+ "problems",
+ "folder",
+ "issue",
+ "docs",
+ "tree",
+ "highlights",
+ "outline",
+ "postgres",
+ "code",
+ "currentFile",
+ "url",
+ "database",
+ "os",
+ "repo-map",
+ "greptile",
+ "web",
+ "gitlab-mr",
+ "discord",
+ "jira",
+ "commit",
+ "clipboard"
+ ],
+ "markdownEnumDescriptions": [
+ "Reference the contents of the current changes as given by `git diff`",
+ "Reference the last terminal command",
+ "Reference the contents of the local variables in the debugger with top n level (defaulting to 3) of call stack for that thread",
+ "Reference the contents of all open or pinned files.",
+ "Enter a search phrase and include the Google search results as context",
+ "Reference the results of a ripgrep search in your codebase",
+ "Write a custom context provider at your own HTTP endpoint. Set 'url' in the params object for the endpoint you have setup.",
+ "Use embeddings to automatically find relevant files from throughout the codebase",
+ "Reference all linting errors and warnings in the currently open file",
+ "Include important files from a folder in the prompt, as determined by similarity search",
+ "Reference GitHub issues from a repository",
+ "Retrieve important pages from a documentation website, as determined by similarity search",
+ "Display a file tree of the current workspace",
+ "Include important highlighted sections from your code",
+ "Include a repo map showing important code objects",
+ "References Postgres table schema and sample rows",
+ "Reference specific functions and classes from throughout your codebase",
+ "Reference the contents of the currently active file",
+ "Reference the contents of a page at a URL",
+ "Reference table schemas",
+ "Operating system and CPU Information",
+ "Map of files in the repository with important code highlights",
+ "Query your greptile index of the current repo",
+ "Search the web for sources related to your question",
+ "Reference changes and metadata from previous git commits",
+ "Reference the contents of the clipboard"
+ ],
+ "type": "string"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "params": {
+ "title": "Params",
+ "default": {},
+ "type": "object"
+ }
+ },
+ "allOf": [
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["discord"]
+ }
+ }
+ },
+ "then": {
+ "allOf": [
+ {
+ "properties": {
+ "params": {
+ "properties": {
+ "discordKey": {
+ "type": "string",
+ "description": "Your Discord bot token to access the Discord API. Required to fetch messages from servers."
+ },
+ "guildId": {
+ "type": "string",
+ "description": "The ID of the guild (server) from which to fetch channels and messages."
+ },
+ "channels": {
+ "type": "array",
+ "description": "A list of channel objects to search for messages",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "The unique ID of the channel"
+ },
+ "name": {
+ "type": "string",
+ "description": "The name of the channel"
+ }
+ },
+ "required": ["id"]
+ }
+ }
+ },
+ "required": ["discordKey"]
+ }
+ }
+ },
+ {
+ "oneOf": [
+ {
+ "properties": {
+ "params": {
+ "required": ["guildId"]
+ }
+ }
+ },
+ {
+ "properties": {
+ "params": {
+ "required": ["channels"]
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["google"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "serperApiKey": {
+ "type": "string",
+ "description": "Your API key for https://serper.dev in order to get Google search results"
+ }
+ },
+ "required": ["serperApiKey"]
+ }
+ },
+ "required": ["params"]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["web"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "n": {
+ "title": "N",
+ "description": "The number of results to return",
+ "default": 6,
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["search"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "maxResults": {
+ "title": "Max Results",
+ "description": "The maximum number of results to return",
+ "default": 200,
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["open"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "onlyPinned": {
+ "type": "boolean",
+ "description": "If set to true, only 'pinned' files will be included.",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["repo-map"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "includeSignatures": {
+ "type": "boolean",
+ "description": "Include message signatures from repo-map",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["debugger"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "stackDepth": {
+ "title": "Stack Depth",
+ "description": "Stack trace depth to include in context",
+ "default": 3,
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["diff"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "includeUnstaged": {
+ "type": "boolean",
+ "description": "Include diff from unstaged files",
+ "default": true
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["issue"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "githubToken": {
+ "type": "string",
+ "description": "Your GitHub token to access the GitHub API. Required for private repositories."
+ },
+ "repos": {
+ "type": "array",
+ "description": "A list of repositories to search for issues",
+ "items": {
+ "type": "object",
+ "properties": {
+ "owner": {
+ "type": "string",
+ "description": "The owner of the repository"
+ },
+ "repo": {
+ "type": "string",
+ "description": "The name of the repository"
+ },
+ "type": {
+ "type": "string",
+ "description": "The type of issues to search for",
+ "enum": ["open", "closed", "all"]
+ }
+ },
+ "required": ["owner", "repo"]
+ }
+ }
+ },
+ "required": ["repos"]
+ }
+ },
+ "required": ["params"]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["database"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "connections": {
+ "type": "array",
+ "description": "A list of database connections",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "A unique name for this database connection"
+ },
+ "connection_type": {
+ "type": "string",
+ "description": "The type of database (e.g., 'postgres', 'mysql')",
+ "enum": ["postgres", "mysql", "sqlite", "mssql"]
+ },
+ "connection": {
+ "type": "object",
+ "properties": {
+ "user": {
+ "type": "string",
+ "description": "The database user name"
+ },
+ "host": {
+ "type": "string",
+ "description": "The host address of the database server"
+ },
+ "database": {
+ "type": "string",
+ "description": "The name of the database to connect to"
+ },
+ "password": {
+ "type": "string",
+ "description": "The password for the database user"
+ },
+ "port": {
+ "type": "integer",
+ "description": "The port number to connect to at the host"
+ },
+ "filename": {
+ "type": "string",
+ "description": "File location for simple file DB's"
+ }
+ },
+ "required": []
+ }
+ },
+ "required": ["name", "connection_type", "connection"]
+ }
+ }
+ },
+ "required": ["connections"]
+ }
+ },
+ "required": ["params"]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["gitlab-mr"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "domain": {
+ "type": "string",
+ "description": "Your GitLab domain, will default to gitlab.com"
+ },
+ "token": {
+ "type": "string",
+ "description": "Your private access token."
+ },
+ "filterComments": {
+ "type": "boolean",
+ "description": "If you have code selected, filters out comments that aren't related to the selection."
+ }
+ },
+ "required": ["token"]
+ }
+ },
+ "required": ["params"]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["jira"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "domain": {
+ "type": "string",
+ "description": "Your Jira domain, for example company.atlassian.net."
+ },
+ "email": {
+ "type": "string",
+ "description": "The email that you log into Jira with"
+ },
+ "token": {
+ "type": "string",
+ "description": "Your atlassian API token from https://id.atlassian.com/manage-profile/security/api-tokens"
+ },
+ "issueQuery": {
+ "type": "string",
+ "description": "Customize the query used to find Jira issues"
+ },
+ "maxResults": {
+ "type": "string",
+ "description": "The maximum number of issues that will be returned. Defaults to 50."
+ },
+ "apiVersion": {
+ "type": "integer",
+ "markdownDescription": "This context provider supports both Jira API version 2 and 3. It will use version 3 by default since that's what the cloud version uses, but if you have the datacenter version of Jira, you'll need to set the API Version to 2 using the `apiVersion` property.",
+ "x-intellij-html-description": "This context provider supports both Jira API version 2 and 3. It will use version 3 by default since that's what the cloud version uses, but if you have the datacenter version of Jira, you'll need to set the API Version to 2 using the apiVersion property."
+ },
+ "requestOptions": {
+ "title": "Request Options",
+ "description": "Options for the HTTPS request to Jira.",
+ "default": {
+ "timeout": 7200,
+ "verifySsl": null,
+ "caBundlePath": null,
+ "proxy": null,
+ "headers": null,
+ "extraBodyProperties": null
+ },
+ "allOf": [
+ {
+ "$ref": "#/$defs/RequestOptions"
+ }
+ ]
+ }
+ },
+ "required": ["domain", "token"]
+ }
+ },
+ "required": ["params"]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["http"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "url": {
+ "type": "string",
+ "description": "The HTTP endpoint of your context provider server."
+ },
+ "options": {
+ "title": "Custom Options",
+ "description": "Additional options to pass to your custom HTTP server.",
+ "type": "object"
+ }
+ },
+ "required": ["url"]
+ }
+ },
+ "required": ["params"]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["codebase", "folder"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "nRetrieve": {
+ "title": "N Retrieve",
+ "description": "Number of results to initially retrieve from vector database",
+ "default": 50,
+ "type": "integer"
+ },
+ "nFinal": {
+ "title": "N Final",
+ "description": "Final number of results to use after re-ranking",
+ "default": 10,
+ "type": "integer"
+ },
+ "useReranking": {
+ "title": "Use Reranking",
+ "description": "Whether to use re-ranking, which will allow initial selection of nRetrieve results, then will use an LLM to select the top nFinal results. Disabling re-ranking will give faster, but less accurate, results.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["docs"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "nRetrieve": {
+ "title": "N Retrieve",
+ "description": "Number of docs results to initially retrieve from vector database",
+ "default": 50,
+ "type": "integer"
+ },
+ "nFinal": {
+ "title": "N Final",
+ "description": "Final number of docs results to include after re-ranking",
+ "default": 10,
+ "type": "integer"
+ },
+ "useReranking": {
+ "title": "Use Reranking",
+ "description": "Whether to use re-ranking, which will allow initial selection of nRetrieve results, then will use an LLM to select the top nFinal results. Disabling re-ranking will give faster, but less accurate, results.",
+ "default": true,
+ "type": "boolean"
+ },
+ "githubToken": {
+ "type": "string",
+ "title": "Github Token",
+ "description": "Include to crawl Github repositories for documentation"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["postgres"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "host": {
+ "title": "Host",
+ "description": "Database host",
+ "default": "localhost",
+ "type": "string"
+ },
+ "port": {
+ "title": "Port",
+ "description": "Database port",
+ "default": 5432,
+ "type": "integer"
+ },
+ "user": {
+ "title": "User",
+ "description": "Database user",
+ "default": "postgres",
+ "type": "string"
+ },
+ "password": {
+ "title": "Password",
+ "description": "Database password",
+ "type": "string"
+ },
+ "database": {
+ "title": "Database",
+ "description": "Database name",
+ "default": "postgres",
+ "type": "string"
+ },
+ "schema": {
+ "title": "Schema",
+ "description": "Database schema",
+ "default": "public",
+ "type": "string"
+ },
+ "sampleRows": {
+ "title": "Sample Rows",
+ "description": "Number of rows to sample from the database",
+ "default": 3,
+ "type": "integer"
+ }
+ },
+ "required": ["host", "port", "user", "password", "database"]
+ }
+ },
+ "required": ["params"]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["greptile"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "GithubToken": {
+ "title": "GithubToken",
+ "description": "Your github access token",
+ "default": "",
+ "type": "string"
+ },
+ "GreptileToken": {
+ "title": "GreptileToken",
+ "description": "Your greptile access token",
+ "default": "",
+ "type": "string"
+ }
+ },
+ "required": ["GreptileToken", "GithubToken"]
+ }
+ },
+ "required": ["params"]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["commit"]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "Depth": {
+ "title": "depth",
+ "description": "How many previous commits should be loaded",
+ "default": 50,
+ "type": "number"
+ },
+ "LastXCommitsDepth": {
+ "title": "LastXCommitsDepth",
+ "description": "how many commits should be included when querying all recent commits",
+ "default": 10,
+ "type": "number"
+ }
+ }
+ }
+ },
+ "required": ["params"]
+ }
+ }
+ ],
+ "required": ["name"]
+ },
+ "SerializedContinueConfig": {
+ "title": "config.json",
+ "type": "object",
+ "properties": {
+ "docs": {
+ "title": "Docs",
+ "description": "A list of documentation sites to be indexed",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string",
+ "description": "The title of the documentation site"
+ },
+ "startUrl": {
+ "type": "string",
+ "description": "The starting URL for indexing the documentation"
+ },
+ "maxDepth": {
+ "type": "integer",
+ "description": "The maximum link depth when crawling the documentation site"
+ },
+ "faviconUrl": {
+ "type": "string",
+ "description": "The URL path to a favicon for the site - by default, it will be `/favicon.ico` path from the Start URL"
+ },
+ "useLocalCrawling": {
+ "type": "boolean",
+ "description": "Only use local crawling for this documentation site"
+ }
+ },
+ "required": ["title", "startUrl"]
+ }
+ },
+ "allowAnonymousTelemetry": {
+ "title": "Allow Anonymous Telemetry",
+ "markdownDescription": "If this field is set to `true`, we will collect anonymous telemetry as described in the documentation page on telemetry. If set to `false`, we will not collect any data. Learn more in [the docs](https://docs.continue.dev/telemetry).",
+ "x-intellij-html-description": "If this field is set to `true`, we will collect anonymous telemetry as described in the documentation page on telemetry. If set to `false`, we will not collect any data. Learn more in the docs.",
+ "default": true,
+ "type": "boolean"
+ },
+ "models": {
+ "title": "Models",
+ "markdownDescription": "Learn about setting up models in [the documentation](https://docs.continue.dev/model-setup/overview).",
+ "x-intellij-html-description": "Learn about setting up models in the documentation.",
+ "default": [
+ {
+ "title": "Claude 3.7 Sonnet",
+ "provider": "anthropic",
+ "model": "claude-3-7-sonnet-latest",
+ "apiKey": "sk_..."
+ }
+ ],
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/ModelDescription"
+ }
+ },
+ "systemMessage": {
+ "title": "System Message",
+ "description": "A system message that will always be followed by the LLM for Chat and Edit requests",
+ "type": "string"
+ },
+ "completionOptions": {
+ "title": "Completion Options",
+ "description": "Default options for completion. These will be overriden by any options set for a specific model.",
+ "default": {
+ "temperature": null,
+ "topP": null,
+ "topK": null,
+ "presencePenalty": null,
+ "frequencyPenalty": null,
+ "stop": null,
+ "maxTokens": 600
+ },
+ "allOf": [
+ {
+ "$ref": "#/$defs/BaseCompletionOptions"
+ }
+ ]
+ },
+ "requestOptions": {
+ "title": "Request Options",
+ "description": "Default request options for all fetch requests from models and context providers. These will be overriden by any model-specific request options.",
+ "allOf": [
+ {
+ "$ref": "#/$defs/RequestOptions"
+ }
+ ]
+ },
+ "slashCommands": {
+ "title": "Slash Commands",
+ "markdownDescription": "An array of slash commands that let you take custom actions from the sidebar. Learn more in the [documentation](https://docs.continue.dev/customization/slash-commands).",
+ "x-intellij-html-description": "An array of slash commands that let you take custom actions from the sidebar. Learn more in the documentation.",
+ "default": [],
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/SlashCommand"
+ }
+ },
+ "customCommands": {
+ "title": "Custom Commands",
+ "markdownDescription": "An array of custom commands that allow you to reuse prompts. Each has name, description, and prompt properties. When you enter `// in the text input, it will act as a shortcut to the prompt. Learn more in the documentation.",
+ "default": [
+ {
+ "name": "test",
+ "prompt": "{{{ input }}}\n\nWrite a comprehensive set of unit tests for the selected code. It should setup, run tests that check for correctness including important edge cases, and teardown. Ensure that the tests are complete and sophisticated. Give the tests just as chat output, don't edit any file.",
+ "description": "This is an example custom command. Open config.json to edit it and create more"
+ }
+ ],
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/CustomCommand"
+ }
+ },
+ "contextProviders": {
+ "title": "Context Providers",
+ "markdownDescription": "A list of ContextProvider objects that can be used to provide context to the LLM by typing '@'. Read more about ContextProviders in [the documentation](https://docs.continue.dev/customization/context-providers).",
+ "x-intellij-html-description": "A list of ContextProvider objects that can be used to provide context to the LLM by typing '@'. Read more about ContextProviders in the documentation.",
+ "default": [],
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/ContextProviderWithParams"
+ }
+ },
+ "userToken": {
+ "title": "User Token",
+ "description": "An optional token to identify the user.",
+ "type": "string"
+ },
+ "disableIndexing": {
+ "title": "Disable Indexing",
+ "markdownDescription": "If set to `true`, Continue will not index the codebase. This is mainly used for debugging purposes.",
+ "x-intellij-html-description": "If set to true, Continue will not index the codebase. This is mainly used for debugging purposes.",
+ "default": false,
+ "type": "boolean"
+ },
+ "disableSessionTitles": {
+ "title": "Disable Session Titles",
+ "markdownDescription": "If set to `true`, Continue will not make extra requests to the LLM to generate a summary title of each session.",
+ "x-intellij-html-description": "If set to true, Continue will not make extra requests to the LLM to generate a summary title of each session.",
+ "default": false,
+ "type": "boolean"
+ },
+ "embeddingsProvider": {
+ "title": "Embeddings Provider",
+ "markdownDescription": "The method that will be used to generate codebase embeddings. The default is `transformers.js`, which will run locally in the browser. Learn about the other options [here](https://docs.continue.dev/features/codebase-embeddings#embeddings-providers).",
+ "x-intellij-html-description": "The method that will be used to generate codebase embeddings. The default is transformers.js, which will run locally in the browser. Learn about the other options here.transformers.js currently cannot be used in JetBrains.",
+ "type": "object",
+ "properties": {
+ "provider": {
+ "enum": [
+ "huggingface-tei",
+ "transformers.js",
+ "ollama",
+ "openai",
+ "cohere",
+ "continue-proxy",
+ "gemini",
+ "voyage",
+ "nvidia",
+ "bedrock",
+ "sagemaker",
+ "nebius",
+ "vertexai",
+ "deepinfra",
+ "mistral",
+ "watsonx",
+ "lmstudio",
+ "siliconflow",
+ "function-network",
+ "scaleway",
+ "ovhcloud"
+ ]
+ },
+ "model": {
+ "type": "string"
+ },
+ "apiKey": {
+ "type": "string"
+ },
+ "apiBase": {
+ "type": "string"
+ },
+ "requestOptions": {
+ "title": "Request Options",
+ "description": "Request options to be used in any fetch requests made by the embeddings provider",
+ "$ref": "#/$defs/RequestOptions"
+ },
+ "maxEmbeddingChunkSize": {
+ "title": "Maximum Chunk Size",
+ "description": "The maximum number of tokens that each chunk of a document is allowed to have",
+ "type": "integer",
+ "minimum": 128,
+ "exclusiveMaximum": 2147483647
+ },
+ "maxEmbeddingBatchSize": {
+ "title": "Maximum Batch Size",
+ "description": "The maximum number of chunks that can be sent to the embeddings provider in a single request",
+ "type": "integer",
+ "minimum": 1,
+ "exclusiveMaximum": 2147483647
+ },
+ "region": {
+ "title": "Region",
+ "description": "The region where the model is hosted",
+ "$ref": "#/$defs/ModelDescription/properties/region"
+ },
+ "profile": {
+ "title": "Profile",
+ "description": "The AWS security profile to use",
+ "type": "string"
+ },
+ "accessKeyId": {
+ "title": "Access Key ID",
+ "description": "AWS access key id (can be used together with secretAccessKey in place of profile)",
+ "type": "string"
+ },
+ "secretAccessKey": {
+ "title": "Secret Access Key",
+ "description": "AWS secret access key (can be used together with secretAccessKey in place of profile)",
+ "type": "string"
+ }
+ },
+ "required": ["provider"],
+ "allOf": [
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "cohere",
+ "voyage",
+ "nvidia",
+ "gemini",
+ "siliconflow"
+ ]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "required": ["apiKey"]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["sagemaker"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "description": "SageMaker endpoint name"
+ }
+ },
+ "required": ["model"]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["vertexai"]
+ }
+ },
+ "required": ["provider"]
+ },
+ "then": {
+ "properties": {
+ "projectId": {
+ "description": "The name of your VertexAI project"
+ },
+ "region": {
+ "description": "The region your VertexAI model is hosted in - typically us-central1",
+ "default": "us-central1"
+ },
+ "model": {
+ "default": "text-embedding-005"
+ }
+ },
+ "required": ["projectId", "model", "region"]
+ }
+ }
+ ]
+ },
+ "reranker": {
+ "title": "Reranker",
+ "description": "The reranker is responsible for selecting the final results when retrieving snippets from your codebase.",
+ "type": "object",
+ "properties": {
+ "name": {
+ "enum": [
+ "bedrock",
+ "cohere",
+ "voyage",
+ "watsonx",
+ "llm",
+ "huggingface-tei",
+ "siliconflow"
+ ]
+ },
+ "params": {
+ "type": "object"
+ }
+ },
+ "required": ["name"],
+ "allOf": [
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["cohere"]
+ }
+ },
+ "required": ["name"]
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "type": "object",
+ "properties": {
+ "model": {
+ "enum": [
+ "rerank-english-v3.0",
+ "rerank-multilingual-v3.0",
+ "rerank-english-v2.0",
+ "rerank-multilingual-v2.0",
+ "rerank-v3.5"
+ ]
+ },
+ "apiBase": {
+ "type": "string"
+ },
+ "apiKey": {
+ "type": "string"
+ }
+ },
+ "required": ["apiKey"]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["llm"]
+ }
+ },
+ "required": ["name"]
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "type": "object",
+ "properties": {
+ "modelTitle": {
+ "type": "string"
+ }
+ },
+ "required": ["modelTitle"]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["voyage"]
+ }
+ },
+ "required": ["name"]
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "type": "object",
+ "properties": {
+ "apiKey": {
+ "type": "string"
+ },
+ "model": {
+ "enum": [
+ "rerank-lite-1",
+ "rerank-1",
+ "rerank-2",
+ "rerank-2-lite"
+ ]
+ }
+ },
+ "required": ["apiKey"]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["bedrock"]
+ }
+ },
+ "required": ["name"]
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "type": "object",
+ "properties": {
+ "model": {
+ "enum": ["cohere.rerank-v3-5:0", "amazon.rerank-v1:0"]
+ }
+ },
+ "required": ["model"]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["huggingface-tei"]
+ }
+ },
+ "required": ["name"]
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "type": "object",
+ "properties": {
+ "apiBase": {
+ "type": "string",
+ "default": "http://localhost:8080"
+ },
+ "apiKey": {
+ "type": "string"
+ },
+ "truncate": {
+ "type": "boolean",
+ "description": "Whether to truncate long sequences to the maximum allowed context length.",
+ "default": false
+ },
+ "truncation_direction": {
+ "enum": ["Right", "Left"],
+ "description": "Whether to truncate sequences from the left or right.",
+ "default": "Right"
+ }
+ },
+ "required": ["apiBase"]
+ }
+ },
+ "if": {
+ "properties": {
+ "truncate": {
+ "const": true
+ }
+ }
+ },
+ "then": {
+ "required": ["truncation_direction"]
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": ["siliconflow"]
+ }
+ },
+ "required": ["name"]
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "type": "object",
+ "properties": {
+ "model": {
+ "enum": [
+ "BAAI/bge-reranker-v2-m3",
+ "netease-youdao/bce-reranker-base_v1",
+ "Pro/BAAI/bge-reranker-v2-m3"
+ ],
+ "default": "BAAI/bge-reranker-v2-m3"
+ },
+ "apiBase": {
+ "type": "string"
+ },
+ "apiKey": {
+ "type": "string"
+ }
+ },
+ "required": ["apiKey"]
+ }
+ }
+ }
+ }
+ ]
+ },
+ "tabAutocompleteModel": {
+ "title": "Tab Autocomplete Model",
+ "markdownDescription": "The model used for tab autocompletion. If undefined, Continue will default to using qwen2.5-coder:1.5b on a local Ollama instance.\n\n*IMPORTANT*:\n\nIf you use a custom model, ensure that it is one trained for fill-in-the-middle completions. An instruct model is typically not well-suited to autocomplete and you may receive unsatisfactory completions.",
+ "x-intellij-html-description": "The model used for tab autocompletion. If undefined, Continue will default to using qwen2.5-coder:1.5b on a local Ollama instance.true, a scrollbar will be displayed in the chat window to navigate through messages.",
+ "default": false,
+ "type": "boolean"
+ },
+ "codeWrap": {
+ "type": "boolean",
+ "description": "If set to true, code in pre blocks will wrap.",
+ "default": false
+ }
+ }
+ },
+ "analytics": {
+ "type": "object",
+ "properties": {
+ "provider": {
+ "type": "string",
+ "enum": ["posthog", "logstash"],
+ "description": "The 3rd party analytics provider to use.",
+ "default": "posthog",
+ "markdownEnumDescriptions": [
+ "### Posthog\nTo use Posthog, set up an account, obtain your client key, and enter it in the client key field."
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "The URL to which analytics will be sent"
+ },
+ "clientKey": {
+ "type": "string",
+ "description": "The client key to use for analytics"
+ }
+ },
+ "required": ["provider"],
+ "allOf": [
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["posthog"]
+ }
+ }
+ },
+ "then": {
+ "required": ["clientKey"]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": ["logstash"]
+ }
+ }
+ },
+ "then": {
+ "required": ["url"]
+ }
+ }
+ ]
+ },
+ "experimental": {
+ "type": "object",
+ "title": "Experimental",
+ "description": "Experimental properties are subject to change.",
+ "properties": {
+ "defaultContext": {
+ "type": "array",
+ "items": {
+ "allOf": [
+ {
+ "$ref": "#/$defs/ContextProviderWithParams"
+ },
+ {
+ "properties": {
+ "query": {
+ "type": "string",
+ "description": "Required for certain context providers, like 'url' in order to specify the input, or which of the dropdown items to select."
+ }
+ }
+ }
+ ]
+ }
+ },
+ "modelRoles": {
+ "type": "object",
+ "properties": {
+ "inlineEdit": {
+ "description": "The 'title' property of the model you wish to use for inline edits",
+ "type": "string"
+ },
+ "applyCodeBlock": {
+ "description": "The 'title' property of the model you wish to use for applying code blocks",
+ "type": "string"
+ },
+ "repoMapFileSelection": {
+ "description": "The 'title' property of the model you wish to use for repo map file selections",
+ "type": "string"
+ }
+ }
+ },
+ "readResponseTTS": {
+ "type": "boolean",
+ "default": true,
+ "description": "Automatically read LLM chat responses aloud using system TTS models"
+ },
+ "promptPath": {
+ "type": "string"
+ },
+ "quickActions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string",
+ "description": "The title of the quick action that will display in the Code Lens."
+ },
+ "prompt": {
+ "type": "string",
+ "description": "The prompt that will be sent to the model when the quick action is invoked, with the function or class body concatenated."
+ },
+ "sendToChat": {
+ "type": "boolean",
+ "description": "If true, the result of the quick action will be sent to the chat panel. If false, the streamed result will be inserted into the document.",
+ "default": false
+ }
+ },
+ "required": ["prompt", "title"]
+ },
+ "description": "Quick actions are a way to add custom commands to the Code Lens of function and class declarations."
+ },
+ "contextMenuPrompts": {
+ "type": "object",
+ "properties": {
+ "comment": {
+ "type": "string",
+ "default": "Write comments for this code. Do not change anything about the code itself."
+ },
+ "docstring": {
+ "type": "string",
+ "default": "Write a docstring for this code. Do not change anything about the code itself."
+ },
+ "fix": {
+ "type": "string",
+ "default": "Fix this code"
+ },
+ "optimize": {
+ "type": "string",
+ "default": "Optimize this code"
+ },
+ "fixGrammar": {
+ "type": "string",
+ "default": "If there are any grammar or spelling mistakes in this writing, fix them. Do not make other large changes to the writing."
+ }
+ }
+ },
+ "useChromiumForDocsCrawling": {
+ "type": "boolean",
+ "description": "Use Chromium to crawl docs locally. Useful if the default Cheerio crawler fails on sites that require JavaScript rendering. Downloads and installs Chromium to `~/.continue/.utils`.",
+ "default": false
+ },
+ "modelContextProtocolServers": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "transport": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": ["stdio"]
+ },
+ "command": {
+ "type": "string"
+ },
+ "args": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "env": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "description": "Environment variables to pass to the command"
+ }
+ },
+ "required": ["type", "command", "args"]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": ["websocket"]
+ },
+ "url": {
+ "type": "string",
+ "format": "uri"
+ }
+ },
+ "required": ["type", "url"]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": ["sse"]
+ },
+ "url": {
+ "type": "string",
+ "format": "uri"
+ }
+ },
+ "required": ["type", "url"]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": ["streamable-http"]
+ },
+ "url": {
+ "type": "string",
+ "format": "uri"
+ }
+ },
+ "required": ["type", "url"]
+ }
+ ]
+ }
+ },
+ "required": ["transport"]
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/extensions/continue/continue_rc_schema.json b/extensions/continue/continue_rc_schema.json
new file mode 100644
index 000000000000..fb3a760bc90a
--- /dev/null
+++ b/extensions/continue/continue_rc_schema.json
@@ -0,0 +1,3986 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "title": "config.json",
+ "$ref": "#/$defs/SerializedContinueConfig",
+ "$defs": {
+ "BaseCompletionOptions": {
+ "title": "BaseCompletionOptions",
+ "type": "object",
+ "properties": {
+ "stream": {
+ "title": "Stream",
+ "description": "Whether to stream the LLM response. Currently only respected by the 'anthropic' provider. Otherwise will always stream.",
+ "type": "boolean",
+ "default": true
+ },
+ "temperature": {
+ "title": "Temperature",
+ "description": "The temperature of the completion.",
+ "type": "number"
+ },
+ "topP": {
+ "title": "Top P",
+ "description": "The topP of the completion.",
+ "type": "number"
+ },
+ "topK": {
+ "title": "Top K",
+ "description": "The topK of the completion.",
+ "type": "integer"
+ },
+ "presencePenalty": {
+ "title": "Presence Penalty",
+ "description": "The presence penalty Aof the completion.",
+ "type": "number"
+ },
+ "frequencyPenalty": {
+ "title": "Frequency Penalty",
+ "description": "The frequency penalty of the completion.",
+ "type": "number"
+ },
+ "mirostat": {
+ "title": "Mirostat",
+ "description": "Enable Mirostat sampling, controlling perplexity during text generation (default: 0, 0 = disabled, 1 = Mirostat, 2 = Mirostat 2.0). Only available for Ollama, LM Studio, and llama.cpp providers",
+ "type": "number"
+ },
+ "stop": {
+ "title": "Stop",
+ "description": "The stop tokens of the completion.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "maxTokens": {
+ "title": "Max Tokens",
+ "description": "The maximum number of tokens to generate.",
+ "default": 600,
+ "type": "integer"
+ },
+ "numThreads": {
+ "title": "Number of threads",
+ "description": "The number of threads used in the generation process. Only available for Ollama (this is the num_thread parameter)",
+ "type": "integer"
+ },
+ "useMmap": {
+ "title": "Use Memory Map",
+ "description": "Allows the model to be mapped into memory. If disabled can enhance response time on low end devices. Only available for Ollama (this is the use_mmap parameter)",
+ "type": "boolean"
+ },
+ "keepAlive": {
+ "title": "Ollama keep_alive",
+ "description": "The number of seconds after no requests are made to unload the model from memory. Defaults to 60*30 = 30min",
+ "type": "integer"
+ },
+ "numGpu": {
+ "title": "Ollama num_gpu",
+ "description": "Override the number of gpu layers used when loading the model"
+ },
+ "reasoning": {
+ "title": "Reasoning",
+ "description": "Enable thinking/reasoning for Anthropic Claude 3.7+ and some Ollama models",
+ "type": "boolean"
+ },
+ "reasoningBudgetTokens": {
+ "title": "Reasoning Budget Tokens",
+ "description": "Set budget tokens for thinking/reasoning in Anthropic Claude 3.7+ models",
+ "type": "integer"
+ }
+ }
+ },
+ "ClientCertificateOptions": {
+ "title": "ClientCertificateOptions",
+ "type": "object",
+ "properties": {
+ "cert": {
+ "title": "Cert Path",
+ "description": "Path to the client certificate file",
+ "type": "string"
+ },
+ "key": {
+ "title": "Key Path",
+ "description": "Path to the client certificate key file",
+ "type": "string"
+ },
+ "passphrase": {
+ "title": "Passphrase",
+ "description": "Passphrase for the client certificate key file",
+ "type": "string"
+ }
+ },
+ "required": [
+ "cert",
+ "key"
+ ]
+ },
+ "RequestOptions": {
+ "title": "RequestOptions",
+ "type": "object",
+ "properties": {
+ "timeout": {
+ "title": "Timeout",
+ "description": "Set the timeout for each request to the LLM. If you are running a local LLM that takes a while to respond, you might want to set this to avoid timeouts.",
+ "default": 7200,
+ "type": "integer"
+ },
+ "verifySsl": {
+ "title": "Verify Ssl",
+ "description": "Whether to verify SSL certificates for requests.",
+ "type": "boolean"
+ },
+ "caBundlePath": {
+ "title": "Ca Bundle Path",
+ "description": "Path to a custom CA bundle to use when making the HTTP request",
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ },
+ "proxy": {
+ "title": "Proxy",
+ "description": "Proxy URL to use when making the HTTP request",
+ "type": "string"
+ },
+ "headers": {
+ "title": "Headers",
+ "description": "Headers to use when making the HTTP request",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ },
+ "extraBodyProperties": {
+ "title": "Extra Body Properties",
+ "description": "This object will be merged with the body when making the HTTP requests",
+ "type": "object"
+ },
+ "noProxy": {
+ "title": "No Proxy",
+ "description": "A list of hostnames for which Continue should not use the proxy specified in requestOptions.proxy",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "clientCertificate": {
+ "title": "Client Certificate",
+ "description": "Client certificate to use when making the HTTP request",
+ "$ref": "#/$defs/ClientCertificateOptions"
+ }
+ }
+ },
+ "ModelDescription": {
+ "title": "ModelDescription",
+ "type": "object",
+ "properties": {
+ "title": {
+ "title": "Title",
+ "description": "The title you wish to give your model.",
+ "type": "string"
+ },
+ "provider": {
+ "title": "Provider",
+ "description": "The provider of the model. This is used to determine the type of model, and how to interact with it.",
+ "enum": [
+ "openai",
+ "anthropic",
+ "anthropic-vertexai",
+ "cohere",
+ "bedrock",
+ "bedrockimport",
+ "sagemaker",
+ "together",
+ "novita",
+ "ollama",
+ "huggingface-tgi",
+ "huggingface-inference-api",
+ "llama.cpp",
+ "replicate",
+ "gemini",
+ "gemini-vertexai",
+ "lmstudio",
+ "llamafile",
+ "mistral",
+ "mistral-vertexai",
+ "deepinfra",
+ "groq",
+ "fireworks",
+ "ncompass",
+ "cloudflare",
+ "deepseek",
+ "azure",
+ "msty",
+ "watsonx",
+ "openrouter",
+ "sambanova",
+ "nvidia",
+ "vllm",
+ "cerebras",
+ "askSage",
+ "nebius",
+ "vertexai",
+ "xAI",
+ "kindo",
+ "moonshot",
+ "siliconflow",
+ "function-network",
+ "scaleway",
+ "relace",
+ "morph",
+ "ovhcloud",
+ "venice",
+ "inception",
+ "tars"
+ ],
+ "markdownEnumDescriptions": [
+ "### OpenAI\nUse gpt-4, gpt-3.5-turbo, or any other OpenAI model. See [here](https://openai.com/product#made-for-developers) to obtain an API key.\n\n> [Reference](https://docs.continue.dev/reference/Model%20Providers/openai)",
+ "### Anthropic\nTo get started with Anthropic models, you first need to sign up for the open beta [here](https://claude.ai/login) to obtain an API key.\n> [Reference](https://docs.continue.dev/reference/Model%20Providers/anthropicllm)",
+ "### Anthropic Vertex AI\nTo get started you need to enable the [Vertex AI API](https://console.cloud.google.com/marketplace/product/google/aiplatform.googleapis.com) and set up the [Google Application Default Credentials](https://cloud.google.com/docs/authentication/provide-credentials-adc).",
+ "### Cohere\nTo use Cohere, visit the [Cohere dashboard](https://dashboard.cohere.com/api-keys) to create an API key.\n\n> [Reference](https://docs.continue.dev/reference/Model%20Providers/cohere)",
+ "### Bedrock\nTo get started with Bedrock you need to sign up on AWS [here](https://aws.amazon.com/bedrock)",
+ "### Bedrock Imported Models\nTo get started with Bedrock you need to sign up on AWS [here](https://aws.amazon.com/bedrock)",
+ "### Sagemaker\nSagemaker is AWS' machine learning platform.",
+ "### Together\nTogether is a hosted service that provides extremely fast streaming of open-source language models. To get started with Together:\n1. Obtain an API key from [here](https://together.ai)\n2. Paste below\n3. Select a model preset\n> [Reference](https://docs.continue.dev/reference/Model%20Providers/togetherllm)",
+ "### Novita AI\n[Novita AI](https://novita.ai?utm_source=github_continuedev&utm_medium=github_readme&utm_campaign=github_link) offers an affordable, reliable, and simple inference platform with scalable [LLM APIs](https://novita.ai/docs/model-api/reference/introduction.html), empowering developers to build AI applications. To get started with Novita AI:\n1. Obtain an API key from [here](https://novita.ai/settings/key-management?utm_source=github_continuedev&utm_medium=github_readme&utm_campaign=github_link)\n2. Paste below\n3. Select a model preset\n> [Reference](https://docs.continue.dev/reference/Model%20Providers/novita)",
+ "### Ollama\nTo get started with Ollama, follow these steps:\n1. Download from [ollama.ai](https://ollama.ai/) and open the application\n2. Open a terminal and run `ollama run openai or azure",
+ "enum": [
+ "openai",
+ "azure"
+ ]
+ },
+ "apiVersion": {
+ "title": "Api Version",
+ "description": "Azure OpenAI API version (e.g. 2023-07-01-preview)",
+ "type": "string"
+ },
+ "deployment": {
+ "title": "Deployment",
+ "description": "Azure OpenAI deployment",
+ "type": "string"
+ },
+ "capabilities": {
+ "type": "object",
+ "description": "We will attempt to automatically detect the capabilities of the model based on its title and provider, but this may not always be accurate. You can override the model's capabilities here.",
+ "properties": {
+ "uploadImage": {
+ "type": "boolean",
+ "description": "Indicates whether the model can upload images."
+ },
+ "tools": {
+ "type": "boolean",
+ "description": "Indicates whether the model can use tools"
+ }
+ }
+ }
+ },
+ "required": [
+ "title",
+ "provider",
+ "model"
+ ],
+ "allOf": [
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "type": "str"
+ }
+ },
+ "not": {
+ "required": [
+ "provider"
+ ]
+ }
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "description": "Choose a provider first, then model options will be shown here."
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "openai",
+ "anthropic",
+ "cohere",
+ "gemini",
+ "huggingface-inference-api",
+ "replicate",
+ "together",
+ "ncompass",
+ "novita",
+ "cloudflare",
+ "sambanova",
+ "nebius",
+ "xAI",
+ "kindo",
+ "scaleway",
+ "ovhcloud",
+ "venice"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "required": [
+ "apiKey"
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "bedrockimport"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "required": [
+ "modelArn"
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "huggingface-tgi",
+ "huggingface-inference-api"
+ ]
+ }
+ }
+ },
+ "then": {
+ "required": [
+ "apiBase"
+ ]
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "openai"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "deployment": {
+ "type": "string"
+ },
+ "apiType": {
+ "type": "string"
+ },
+ "apiVersion": {
+ "type": "string"
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "cloudflare"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "accountId": {
+ "type": "string"
+ },
+ "aiGatewaySlug": {
+ "type": "string"
+ },
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "@cf/meta/llama-3-8b-instruct",
+ "@hf/thebloke/deepseek-coder-6.7b-instruct-awq",
+ "@cf/deepseek-ai/deepseek-math-7b-instruct",
+ "@cf/thebloke/discolm-german-7b-v1-awq",
+ "@cf/tiiuae/falcon-7b-instruct",
+ "@cf/google/gemma-2b-it-lora",
+ "@hf/google/gemma-7b-it",
+ "@cf/google/gemma-7b-it-lora",
+ "@hf/nousresearch/hermes-2-pro-mistral-7b",
+ "@cf/meta/llama-2-7b-chat-fp16",
+ "@cf/meta/llama-2-7b-chat-int8",
+ "@cf/meta-llama/llama-2-7b-chat-hf-lora",
+ "@hf/thebloke/llama-2-13b-chat-awq",
+ "@hf/thebloke/llamaguard-7b-awq",
+ "@cf/mistral/mistral-7b-instruct-v0.1",
+ "@hf/mistral/mistral-7b-instruct-v0.2",
+ "@cf/mistral/mistral-7b-instruct-v0.2-lora",
+ "@hf/thebloke/neural-chat-7b-v3-1-awq",
+ "@cf/openchat/openchat-3.5-0106",
+ "@hf/thebloke/openhermes-2.5-mistral-7b-awq",
+ "@cf/microsoft/phi-2",
+ "@cf/qwen/qwen1.5-0.5b-chat",
+ "@cf/qwen/qwen1.5-1.8b-chat",
+ "@cf/qwen/qwen1.5-7b-chat-awq",
+ "@cf/qwen/qwen1.5-14b-chat-awq",
+ "@cf/defog/sqlcoder-7b-2",
+ "@hf/nexusflow/starling-lm-7b-beta",
+ "@cf/tinyllama/tinyllama-1.1b-chat-v1.0",
+ "@hf/thebloke/zephyr-7b-beta-awq",
+ "@hf/thebloke/deepseek-coder-6.7b-base-awq"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "openai"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "gpt-3.5-turbo",
+ "gpt-3.5-turbo-16k",
+ "gpt-4o",
+ "gpt-4o-mini",
+ "gpt-4",
+ "gpt-3.5-turbo-0613",
+ "gpt-4-32k",
+ "gpt-4-0125-preview",
+ "gpt-4-turbo",
+ "AUTODETECT"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "xAI"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "grok-beta",
+ "AUTODETECT"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "replicate"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama3.1-405b",
+ "llama3-8b",
+ "llama3-70b",
+ "codellama-7b",
+ "codellama-13b",
+ "codellama-34b",
+ "llama2-7b",
+ "llama2-13b"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "markdownDescription": "Select a pre-defined option, or find an exact model ID from Replicate [here](https://replicate.com/collections/streaming-language-models).",
+ "x-intellij-html-description": "Select a pre-defined option, or find an exact model ID from Replicate here."
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "openai"
+ ]
+ },
+ "apiType": {
+ "not": {
+ "const": "azure"
+ }
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "gpt-3.5-turbo",
+ "gpt-3.5-turbo-16k",
+ "gpt-4o",
+ "gpt-4o-mini",
+ "gpt-4",
+ "gpt-3.5-turbo-0613",
+ "gpt-4-32k",
+ "gpt-4-turbo",
+ "gpt-4-vision-preview",
+ "mistral-7b",
+ "mistral-8x7b",
+ "llama2-7b",
+ "llama2-13b",
+ "codellama-7b",
+ "codellama-13b",
+ "codellama-34b",
+ "codellama-70b",
+ "llama3-8b",
+ "llama3-70b",
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama3.1-405b",
+ "phind-codellama-34b",
+ "wizardcoder-7b",
+ "wizardcoder-13b",
+ "wizardcoder-34b",
+ "zephyr-7b",
+ "codeup-13b",
+ "deepseek-7b",
+ "deepseek-33b",
+ "neural-chat-7b",
+ "deepseek-1b",
+ "stable-code-3b",
+ "starcoder-1b",
+ "starcoder-3b",
+ "starcoder2-3b",
+ "mistral-tiny",
+ "mistral-small",
+ "mistral-medium",
+ "qwen2.5-coder:1.5b",
+ "qwen2.5-coder:3b",
+ "qwen2.5-coder:7b",
+ "qwen2.5-coder:14b",
+ "qwen2.5-coder:32b",
+ "AUTODETECT"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "anthropic"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "cacheBehavior": {
+ "title": "Caching Behavior",
+ "description": "Options for the prompt caching",
+ "properties": {
+ "cacheSystemMessage": {
+ "type": "boolean"
+ },
+ "cacheConversation": {
+ "type": "boolean"
+ }
+ }
+ },
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "claude-sonnet-4",
+ "claude-sonnet-4-5",
+ "claude-opus-4-1",
+ "claude-haiku-4-5"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "cohere"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "enum": [
+ "c4ai-aya-expanse-8b",
+ "c4ai-aya-expanse-32b",
+ "c4ai-aya-vision-8b",
+ "c4ai-aya-vision-32b",
+ "command-r",
+ "command-r-plus",
+ "command-r-03-2024",
+ "command-r-plus-04-2024",
+ "command-r-08-2024",
+ "command-r-plus-08-2024",
+ "command-r7b-12-2024",
+ "command-r7b-arabic-02-2025",
+ "command-a-03-2025",
+ "command-a-vision-07-2025",
+ "command-a-reasoning-08-2025",
+ "command-a-translate-08-2025"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "bedrock"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "claude-3-sonnet-20240229",
+ "claude-3-haiku-20240307",
+ "claude-2"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "sagemaker"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "description": "SageMaker endpoint name"
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "gemini"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "cacheBehavior": {
+ "title": "Caching Behavior",
+ "description": "Options for the prompt caching",
+ "properties": {
+ "cacheSystemMessage": {
+ "type": "boolean"
+ }
+ }
+ },
+ "model": {
+ "enum": [
+ "chat-bison-001",
+ "gemini-pro",
+ "gemini-2.0-flash-exp",
+ "gemini-2.0-flash",
+ "gemini-2.0-flash-thinking-exp-01-21",
+ "gemini-2.0-pro-exp-02-05",
+ "gemini-2.0-flash-lite-preview-02-05",
+ "gemini-2.0-flash-lite",
+ "gemini-2.0-flash-exp-image-generation",
+ "gemini-2.5-pro-latest"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "together"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "mistral-7b",
+ "mistral-8x7b",
+ "llama2-7b",
+ "llama2-13b",
+ "llama3-8b",
+ "llama3-70b",
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama3.1-405b",
+ "codellama-7b",
+ "codellama-13b",
+ "codellama-34b",
+ "codellama-70b",
+ "phind-codellama-34b"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ],
+ "markdownDescription": "Select a pre-defined option, or find an exact model string from Together AI [here](https://docs.together.ai/docs/inference-models).",
+ "x-intellij-html-description": "Select a pre-defined option, or find an exact model string from Together AI here."
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "novita"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "deepseek-r1",
+ "deepseek_v3",
+ "llama3-8b",
+ "llama3-70b",
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama3.1-405b",
+ "llama3.2-1b",
+ "llama3.2-3b",
+ "llama3.2-11b",
+ "llama3.3-70b",
+ "mistral-nemo",
+ "mistral-7b"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ],
+ "markdownDescription": "Select a pre-defined option, or find an exact model string from Novita AI [here](https://novita.ai/llm-api?utm_source=github_continuedev&utm_medium=github_readme&utm_campaign=github_link).",
+ "x-intellij-html-description": "Select a pre-defined option, or find an exact model string from Novita AI here."
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "deepinfra"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "markdownDescription": "Find the model name you want to use from DeepInfra [here](https://deepinfra.com/models?type=text-generation).",
+ "x-intellij-html-description": "Find the model name you want to use from DeepInfra here."
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "huggingface-tgi",
+ "huggingface-inference-api",
+ "llama.cpp",
+ "text-gen-webui",
+ "llamafile"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "mistral-7b",
+ "mistral-8x7b",
+ "llama2-7b",
+ "llama2-13b",
+ "codellama-7b",
+ "codellama-13b",
+ "codellama-34b",
+ "codellama-70b",
+ "llama3-8b",
+ "llama3-70b",
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama3.1-405b",
+ "phind-codellama-34b",
+ "wizardcoder-7b",
+ "wizardcoder-13b",
+ "wizardcoder-34b",
+ "zephyr-7b",
+ "codeup-13b",
+ "deepseek-7b",
+ "deepseek-33b",
+ "neural-chat-7b",
+ "deepseek-1b",
+ "stable-code-3b",
+ "starcoder-1b",
+ "starcoder-3b",
+ "starcoder2-3b",
+ "qwen2.5-coder:1.5b",
+ "qwen2.5-coder:3b",
+ "qwen2.5-coder:7b",
+ "qwen2.5-coder:14b",
+ "qwen2.5-coder:32b"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "ollama"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "mistral-7b",
+ "llama2-7b",
+ "llama2-13b",
+ "codellama-7b",
+ "codellama-13b",
+ "codellama-34b",
+ "codellama-70b",
+ "llama3-8b",
+ "llama3-70b",
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama3.1-405b",
+ "phi-2",
+ "phind-codellama-34b",
+ "wizardcoder-7b",
+ "wizardcoder-13b",
+ "wizardcoder-34b",
+ "zephyr-7b",
+ "codeup-13b",
+ "deepseek-7b",
+ "deepseek-33b",
+ "neural-chat-7b",
+ "deepseek-1b",
+ "stable-code-3b",
+ "starcoder-1b",
+ "starcoder-3b",
+ "starcoder2-3b",
+ "qwen2.5-coder:1.5b",
+ "qwen2.5-coder:3b",
+ "qwen2.5-coder:7b",
+ "qwen2.5-coder:14b",
+ "qwen2.5-coder:32b",
+ "AUTODETECT"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ],
+ "markdownDescription": "Select a pre-defined option, or find the exact model tag for an Ollama model [here](https://ollama.ai/library).",
+ "x-intellij-html-description": "Select a pre-defined option, or find the exact model tag for an Ollama model here."
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "mistral"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "enum": [
+ "codestral-latest",
+ "codestral-mamba-latest",
+ "open-mistral-7b",
+ "open-mixtral-8x7b",
+ "open-mixtral-8x22b",
+ "mistral-small-latest",
+ "mistral-large-latest"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "vertexai"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "required": [
+ "projectId",
+ "region"
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "moonshot"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "moonshot-v1-8k",
+ "moonshot-v1-32k",
+ "moonshot-v1-128k",
+ "AUTODETECT"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "deepseek"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "cacheBehavior": {
+ "title": "Caching Behavior",
+ "description": "Options for the prompt caching",
+ "properties": {
+ "cacheSystemMessage": {
+ "type": "boolean"
+ },
+ "cacheConversation": {
+ "type": "boolean"
+ }
+ }
+ },
+ "model": {
+ "enum": [
+ "deepseek-chat",
+ "deepseek-coder"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "groq"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "enum": [
+ "llama2-70b",
+ "mistral-8x7b",
+ "gemma",
+ "gemma2",
+ "llama3-8b",
+ "llama3-70b",
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama3.1-405b",
+ "AUTODETECT"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "siliconflow"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "enum": [
+ "Qwen/QwQ-32B-Preview",
+ "Qwen/Qwen2.5-Coder-32B-Instruct",
+ "Qwen/Qwen2.5-Coder-7B-Instruct",
+ "Pro/Qwen/Qwen2.5-Coder-7B-Instruct",
+ "Tencent/Hunyuan-A52B-Instruct",
+ "nvidia/Llama-3.1-Nemotron-70B-Instruct",
+ "Qwen/Qwen2-VL-72B-Instruct",
+ "TeleAI/TeleMM",
+ "deepseek-ai/DeepSeek-V2.5",
+ "deepseek-ai/deepseek-vl2",
+ "deepseek-ai/Janus-Pro-7B",
+ "deepseek-ai/DeepSeek-V3",
+ "deepseek-ai/DeepSeek-R1",
+ "deepseek-ai/DeepSeek-R1-Distill-Qwen-14B",
+ "deepseek-ai/DeepSeek-R1-Distill-Qwen-32B",
+ "deepseek-ai/DeepSeek-R1-Distill-Llama-70B",
+ "deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B",
+ "deepseek-ai/DeepSeek-R1-Distill-Qwen-7B",
+ "deepseek-ai/DeepSeek-R1-Distill-Llama-8B"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "scaleway"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "llama-3.1-8b-instruct",
+ "llama-3.1-70b-instruct",
+ "mistral-nemo-instruct-2407",
+ "qwen2.5-coder-32b-instruct",
+ "pixtral-12b-2409"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ],
+ "markdownDescription": "Select a pre-defined option, or find the exact model string from Scaleway [here](https://www.scaleway.com/en/docs/ai-data/generative-apis/reference-content/supported-models/).",
+ "x-intellij-html-description": "Select a pre-defined option, or find the exact model string from Scaleway here."
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "ovhcloud"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama3.3-70b",
+ "qwen2.5-coder-32b",
+ "qwen3-32b",
+ "qwen3-coder-30b-a3b",
+ "qwen2.5-vl-72b",
+ "codestral-mamba-latest",
+ "mistral-7b",
+ "mistral-8x7b",
+ "mistral-nemo",
+ "mistral-small-3.2-24b",
+ "gpt-oss-20b",
+ "gpt-oss-120b",
+ "DeepSeek-R1-Distill-Llama-70B"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ],
+ "markdownDescription": "Select a pre-defined option, or find the exact model string from OVHcloud [AI Endpoints catalog](https://endpoints.ai.cloud.ovh.net/catalog).",
+ "x-intellij-html-description": "Select a pre-defined option, or find the exact model string from OVHcloud AI Endpoints catalog."
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "fireworks"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "enum": [
+ "starcoder-7b"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "ncompass"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "enum": [
+ "qwen2.5-coder-32b",
+ "qwen2.5-72b",
+ "llama3.3-70b"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "apiType": {
+ "const": "azure"
+ }
+ },
+ "required": [
+ "apiType"
+ ]
+ },
+ "then": {
+ "required": [
+ "deployment",
+ "apiBase"
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "openai"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "useLegacyCompletionsEndpoint": {
+ "type": "boolean"
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "cerebras"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "enum": [
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama-4-scout-17b-16e-instruct"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "flowise"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "timeout": {
+ "title": "Timeout",
+ "description": "Set the timeout for each request to Flowise. If you are running a local version of Flowise it might takes a while to respond, you might want to set this to avoid timeouts.",
+ "default": 5000,
+ "type": "integer"
+ },
+ "additionalHeaders": {
+ "description": "A list of additional headers",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "key": {
+ "title": "Key",
+ "description": "Header key",
+ "type": "string"
+ },
+ "value": {
+ "title": "Value",
+ "description": "Header value",
+ "type": "string"
+ }
+ },
+ "required": [
+ "key",
+ "value"
+ ]
+ }
+ },
+ "additionalFlowiseConfiguration": {
+ "description": "A list of additional properties to be sent along `overrideConfig`",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "key": {
+ "title": "Key",
+ "description": "Configuration Property key",
+ "type": "string"
+ },
+ "value": {
+ "title": "Value",
+ "description": "Configuration Property value"
+ }
+ },
+ "required": [
+ "key",
+ "value"
+ ]
+ }
+ },
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "gpt-3.5-turbo",
+ "gpt-3.5-turbo-16k",
+ "gpt-4o",
+ "gpt-4o-mini",
+ "gpt-4",
+ "gpt-3.5-turbo-0613",
+ "gpt-4-32k",
+ "gpt-4-turbo",
+ "gpt-4-vision-preview",
+ "mistral-7b",
+ "mistral-8x7b",
+ "llama2-7b",
+ "llama2-13b",
+ "codellama-7b",
+ "codellama-13b",
+ "codellama-34b",
+ "codellama-70b",
+ "llama3-8b",
+ "llama3-70b",
+ "llama3.1-8b",
+ "llama3.1-70b",
+ "llama3.1-405b",
+ "phind-codellama-34b",
+ "wizardcoder-7b",
+ "wizardcoder-13b",
+ "wizardcoder-34b",
+ "zephyr-7b",
+ "codeup-13b",
+ "deepseek-7b",
+ "deepseek-33b",
+ "claude-sonnet-4",
+ "claude-sonnet-4-5",
+ "claude-opus-4-1",
+ "claude-haiku-4-5",
+ "command-r",
+ "command-r-plus",
+ "chat-bison-001",
+ "gemini-2.5-pro",
+ "mistral-tiny",
+ "mistral-small",
+ "mistral-medium",
+ "deepseek-1b",
+ "stable-code-3b",
+ "starcoder-1b",
+ "starcoder-3b",
+ "starcoder2-3b",
+ "qwen2.5-coder:1.5b",
+ "qwen2.5-coder:3b",
+ "qwen2.5-coder:7b",
+ "qwen2.5-coder:14b",
+ "qwen2.5-coder:32b"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "watsonx"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "apiBase": {
+ "type": "string"
+ },
+ "apiKey": {
+ "type": "string"
+ },
+ "apiVersion": {
+ "type": "string"
+ },
+ "projectId": {
+ "type": "string"
+ },
+ "deploymentId": {
+ "type": "string"
+ },
+ "model": {
+ "enum": [
+ "ibm/granite-13b-chat-v2",
+ "ibm/granite-3b-code-instruct",
+ "ibm/granite-8b-code-instruct",
+ "ibm/granite-20b-code-instruct",
+ "ibm/granite-3b-code-instruct",
+ "ibm/granite-8b-code-instruct",
+ "ibm/granite-34b-code-instruct",
+ "ibm/granite-3-8b-instruct",
+ "ibm/granite-3-2b-instruct",
+ "mistralai/mistral-large",
+ "meta-llama/llama-3-8b-instruct",
+ "meta-llama/llama-3-70b-instruct"
+ ]
+ }
+ },
+ "required": [
+ "apiBase",
+ "apiKey",
+ "apiVersion"
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "sambanova"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "Llama-4-Scout-17B-16E-Instruct",
+ "Llama-4-Maverick-17B-128E-Instruct",
+ "Meta-Llama-3.3-70B-Instruct",
+ "Meta-Llama-3.1-8B-Instruct",
+ "Meta-Llama-3.1-405B-Instruct",
+ "Meta-Llama-3.2-1B-Instruct",
+ "Meta-Llama-3.2-3B-Instruct",
+ "QwQ-32B",
+ "DeepSeek-R1-Distill-Llama-70B",
+ "DeepSeek-R1",
+ "DeepSeek-V3-0324"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ],
+ "description": "Select a pre-defined option."
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "ask-sage"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "gpt-4o",
+ "gpt-4o-mini",
+ "gpt-4gov",
+ "gpt-4ogov",
+ "claude-3.5-sonnet",
+ "claude-3-opus",
+ "mistral-large",
+ "llama-3-chat",
+ "gemini-pro",
+ "AUTODETECT"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "venice"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "anyOf": [
+ {
+ "enum": [
+ "AUTODETECT"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+ },
+ "SlashCommand": {
+ "title": "SlashCommand",
+ "type": "object",
+ "properties": {
+ "name": {
+ "title": "Name",
+ "anyOf": [
+ {
+ "enum": [
+ "issue",
+ "share",
+ "cmd",
+ "edit",
+ "comment",
+ "http",
+ "commit",
+ "review"
+ ],
+ "type": "string",
+ "markdownEnumDescriptions": [
+ "Generate a link to a drafted GitHub issue",
+ "Export the current chat session to markdown",
+ "Generate a terminal command and paste it into the terminal",
+ "Edit the highlighted code with given instructions",
+ "Add comments to the highlighted code",
+ "Write a custom slash command at your own HTTP endpoint. Set 'url' in the params object for the endpoint you have setup.",
+ "Generate a commit message for the current changes",
+ "Review code and give feedback"
+ ]
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "description": {
+ "title": "Description",
+ "type": "string"
+ },
+ "step": {
+ "title": "Step",
+ "description": "This property is no longer required and has no effect. To use a built-in slash command, instead set the 'name' property to one of the pre-configured options.",
+ "type": "string"
+ },
+ "params": {
+ "title": "Params",
+ "default": {},
+ "type": "object"
+ }
+ },
+ "allOf": [
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "issue"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "repositoryUrl": {
+ "type": "string",
+ "description": "Enter the URL of the GitHub repository for which you want to generate the issue."
+ }
+ },
+ "required": [
+ "repositoryUrl"
+ ]
+ }
+ },
+ "required": [
+ "params"
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "edit"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "recap": {
+ "type": "boolean",
+ "markdownDescription": "If recap is set to `true`, Continue will generate a summary of the changes after making the edit.",
+ "x-intellij-html-description": "If recap is set to true, Continue will generate a summary of the changes after making the edit."
+ },
+ "tokenLimit": {
+ "type": "integer",
+ "description": "By default, Continue doesn't let you edit extremely large ranges (beyond 1,200 tokens), because the LLM is unlikely to succeed. But if you would like to override this limit with the understanding of possible failure you may do so here."
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "share"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "outputDir": {
+ "type": "string",
+ "markdownDescription": "If outputDir is set to `.` or begins with `./` or `.\\`, file will be saved to the current workspace or a subdirectory thereof, respectively. `~` can similarly be used to specify the user's home directory.",
+ "x-intellij-html-description": "If outputDir is set to . or begins with ./ or .\\, file will be saved to the current workspace or a subdirectory thereof, respectively. ~ can similarly be used to specify the user's home directory."
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "commit"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "includeUnstaged": {
+ "type": "boolean",
+ "markdownDescription": "If set to `true`, then unstaged changes are also included in the prompt, otherwise only staged changes are included. Default is `false`.",
+ "x-intellij-html-description": "If set to true, then unstaged changes are also included in the prompt, otherwise only staged changes are included. Default is false."
+ }
+ }
+ }
+ }
+ }
+ }
+ ],
+ "required": [
+ "name",
+ "description"
+ ]
+ },
+ "CustomCommand": {
+ "title": "CustomCommand",
+ "type": "object",
+ "properties": {
+ "name": {
+ "title": "Name",
+ "type": "string"
+ },
+ "prompt": {
+ "title": "Prompt",
+ "type": "string"
+ },
+ "description": {
+ "title": "Description",
+ "type": "string"
+ }
+ },
+ "required": [
+ "name",
+ "prompt",
+ "description"
+ ]
+ },
+ "ContextProviderWithParams": {
+ "title": "ContextProviderWithParams",
+ "type": "object",
+ "properties": {
+ "name": {
+ "title": "Name",
+ "anyOf": [
+ {
+ "enum": [
+ "diff",
+ "terminal",
+ "debugger",
+ "open",
+ "google",
+ "search",
+ "http",
+ "codebase",
+ "problems",
+ "folder",
+ "issue",
+ "docs",
+ "tree",
+ "highlights",
+ "outline",
+ "postgres",
+ "code",
+ "currentFile",
+ "url",
+ "database",
+ "os",
+ "repo-map",
+ "greptile",
+ "web",
+ "gitlab-mr",
+ "discord",
+ "jira",
+ "commit",
+ "clipboard"
+ ],
+ "markdownEnumDescriptions": [
+ "Reference the contents of the current changes as given by `git diff`",
+ "Reference the last terminal command",
+ "Reference the contents of the local variables in the debugger with top n level (defaulting to 3) of call stack for that thread",
+ "Reference the contents of all open or pinned files.",
+ "Enter a search phrase and include the Google search results as context",
+ "Reference the results of a ripgrep search in your codebase",
+ "Write a custom context provider at your own HTTP endpoint. Set 'url' in the params object for the endpoint you have setup.",
+ "Use embeddings to automatically find relevant files from throughout the codebase",
+ "Reference all linting errors and warnings in the currently open file",
+ "Include important files from a folder in the prompt, as determined by similarity search",
+ "Reference GitHub issues from a repository",
+ "Retrieve important pages from a documentation website, as determined by similarity search",
+ "Display a file tree of the current workspace",
+ "Include important highlighted sections from your code",
+ "Include a repo map showing important code objects",
+ "References Postgres table schema and sample rows",
+ "Reference specific functions and classes from throughout your codebase",
+ "Reference the contents of the currently active file",
+ "Reference the contents of a page at a URL",
+ "Reference table schemas",
+ "Operating system and CPU Information",
+ "Map of files in the repository with important code highlights",
+ "Query your greptile index of the current repo",
+ "Search the web for sources related to your question",
+ "Reference changes and metadata from previous git commits",
+ "Reference the contents of the clipboard"
+ ],
+ "type": "string"
+ },
+ {
+ "type": "string"
+ }
+ ]
+ },
+ "params": {
+ "title": "Params",
+ "default": {},
+ "type": "object"
+ }
+ },
+ "allOf": [
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "discord"
+ ]
+ }
+ }
+ },
+ "then": {
+ "allOf": [
+ {
+ "properties": {
+ "params": {
+ "properties": {
+ "discordKey": {
+ "type": "string",
+ "description": "Your Discord bot token to access the Discord API. Required to fetch messages from servers."
+ },
+ "guildId": {
+ "type": "string",
+ "description": "The ID of the guild (server) from which to fetch channels and messages."
+ },
+ "channels": {
+ "type": "array",
+ "description": "A list of channel objects to search for messages",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "The unique ID of the channel"
+ },
+ "name": {
+ "type": "string",
+ "description": "The name of the channel"
+ }
+ },
+ "required": [
+ "id"
+ ]
+ }
+ }
+ },
+ "required": [
+ "discordKey"
+ ]
+ }
+ }
+ },
+ {
+ "oneOf": [
+ {
+ "properties": {
+ "params": {
+ "required": [
+ "guildId"
+ ]
+ }
+ }
+ },
+ {
+ "properties": {
+ "params": {
+ "required": [
+ "channels"
+ ]
+ }
+ }
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "google"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "serperApiKey": {
+ "type": "string",
+ "description": "Your API key for https://serper.dev in order to get Google search results"
+ }
+ },
+ "required": [
+ "serperApiKey"
+ ]
+ }
+ },
+ "required": [
+ "params"
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "web"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "n": {
+ "title": "N",
+ "description": "The number of results to return",
+ "default": 6,
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "search"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "maxResults": {
+ "title": "Max Results",
+ "description": "The maximum number of results to return",
+ "default": 200,
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "open"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "onlyPinned": {
+ "type": "boolean",
+ "description": "If set to true, only 'pinned' files will be included.",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "repo-map"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "includeSignatures": {
+ "type": "boolean",
+ "description": "Include message signatures from repo-map",
+ "default": false
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "debugger"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "stackDepth": {
+ "title": "Stack Depth",
+ "description": "Stack trace depth to include in context",
+ "default": 3,
+ "type": "integer"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "diff"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "includeUnstaged": {
+ "type": "boolean",
+ "description": "Include diff from unstaged files",
+ "default": true
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "issue"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "githubToken": {
+ "type": "string",
+ "description": "Your GitHub token to access the GitHub API. Required for private repositories."
+ },
+ "repos": {
+ "type": "array",
+ "description": "A list of repositories to search for issues",
+ "items": {
+ "type": "object",
+ "properties": {
+ "owner": {
+ "type": "string",
+ "description": "The owner of the repository"
+ },
+ "repo": {
+ "type": "string",
+ "description": "The name of the repository"
+ },
+ "type": {
+ "type": "string",
+ "description": "The type of issues to search for",
+ "enum": [
+ "open",
+ "closed",
+ "all"
+ ]
+ }
+ },
+ "required": [
+ "owner",
+ "repo"
+ ]
+ }
+ }
+ },
+ "required": [
+ "repos"
+ ]
+ }
+ },
+ "required": [
+ "params"
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "database"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "connections": {
+ "type": "array",
+ "description": "A list of database connections",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "A unique name for this database connection"
+ },
+ "connection_type": {
+ "type": "string",
+ "description": "The type of database (e.g., 'postgres', 'mysql')",
+ "enum": [
+ "postgres",
+ "mysql",
+ "sqlite",
+ "mssql"
+ ]
+ },
+ "connection": {
+ "type": "object",
+ "properties": {
+ "user": {
+ "type": "string",
+ "description": "The database user name"
+ },
+ "host": {
+ "type": "string",
+ "description": "The host address of the database server"
+ },
+ "database": {
+ "type": "string",
+ "description": "The name of the database to connect to"
+ },
+ "password": {
+ "type": "string",
+ "description": "The password for the database user"
+ },
+ "port": {
+ "type": "integer",
+ "description": "The port number to connect to at the host"
+ },
+ "filename": {
+ "type": "string",
+ "description": "File location for simple file DB's"
+ }
+ },
+ "required": []
+ }
+ },
+ "required": [
+ "name",
+ "connection_type",
+ "connection"
+ ]
+ }
+ }
+ },
+ "required": [
+ "connections"
+ ]
+ }
+ },
+ "required": [
+ "params"
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "gitlab-mr"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "domain": {
+ "type": "string",
+ "description": "Your GitLab domain, will default to gitlab.com"
+ },
+ "token": {
+ "type": "string",
+ "description": "Your private access token."
+ },
+ "filterComments": {
+ "type": "boolean",
+ "description": "If you have code selected, filters out comments that aren't related to the selection."
+ }
+ },
+ "required": [
+ "token"
+ ]
+ }
+ },
+ "required": [
+ "params"
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "jira"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "domain": {
+ "type": "string",
+ "description": "Your Jira domain, for example company.atlassian.net."
+ },
+ "email": {
+ "type": "string",
+ "description": "The email that you log into Jira with"
+ },
+ "token": {
+ "type": "string",
+ "description": "Your atlassian API token from https://id.atlassian.com/manage-profile/security/api-tokens"
+ },
+ "issueQuery": {
+ "type": "string",
+ "description": "Customize the query used to find Jira issues"
+ },
+ "maxResults": {
+ "type": "string",
+ "description": "The maximum number of issues that will be returned. Defaults to 50."
+ },
+ "apiVersion": {
+ "type": "integer",
+ "markdownDescription": "This context provider supports both Jira API version 2 and 3. It will use version 3 by default since that's what the cloud version uses, but if you have the datacenter version of Jira, you'll need to set the API Version to 2 using the `apiVersion` property.",
+ "x-intellij-html-description": "This context provider supports both Jira API version 2 and 3. It will use version 3 by default since that's what the cloud version uses, but if you have the datacenter version of Jira, you'll need to set the API Version to 2 using the apiVersion property."
+ },
+ "requestOptions": {
+ "title": "Request Options",
+ "description": "Options for the HTTPS request to Jira.",
+ "default": {
+ "timeout": 7200,
+ "verifySsl": null,
+ "caBundlePath": null,
+ "proxy": null,
+ "headers": null,
+ "extraBodyProperties": null
+ },
+ "allOf": [
+ {
+ "$ref": "#/$defs/RequestOptions"
+ }
+ ]
+ }
+ },
+ "required": [
+ "domain",
+ "token"
+ ]
+ }
+ },
+ "required": [
+ "params"
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "http"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "url": {
+ "type": "string",
+ "description": "The HTTP endpoint of your context provider server."
+ },
+ "options": {
+ "title": "Custom Options",
+ "description": "Additional options to pass to your custom HTTP server.",
+ "type": "object"
+ }
+ },
+ "required": [
+ "url"
+ ]
+ }
+ },
+ "required": [
+ "params"
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "codebase",
+ "folder"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "nRetrieve": {
+ "title": "N Retrieve",
+ "description": "Number of results to initially retrieve from vector database",
+ "default": 50,
+ "type": "integer"
+ },
+ "nFinal": {
+ "title": "N Final",
+ "description": "Final number of results to use after re-ranking",
+ "default": 10,
+ "type": "integer"
+ },
+ "useReranking": {
+ "title": "Use Reranking",
+ "description": "Whether to use re-ranking, which will allow initial selection of nRetrieve results, then will use an LLM to select the top nFinal results. Disabling re-ranking will give faster, but less accurate, results.",
+ "default": true,
+ "type": "boolean"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "docs"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "nRetrieve": {
+ "title": "N Retrieve",
+ "description": "Number of docs results to initially retrieve from vector database",
+ "default": 50,
+ "type": "integer"
+ },
+ "nFinal": {
+ "title": "N Final",
+ "description": "Final number of docs results to include after re-ranking",
+ "default": 10,
+ "type": "integer"
+ },
+ "useReranking": {
+ "title": "Use Reranking",
+ "description": "Whether to use re-ranking, which will allow initial selection of nRetrieve results, then will use an LLM to select the top nFinal results. Disabling re-ranking will give faster, but less accurate, results.",
+ "default": true,
+ "type": "boolean"
+ },
+ "githubToken": {
+ "type": "string",
+ "title": "Github Token",
+ "description": "Include to crawl Github repositories for documentation"
+ }
+ }
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "postgres"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "host": {
+ "title": "Host",
+ "description": "Database host",
+ "default": "localhost",
+ "type": "string"
+ },
+ "port": {
+ "title": "Port",
+ "description": "Database port",
+ "default": 5432,
+ "type": "integer"
+ },
+ "user": {
+ "title": "User",
+ "description": "Database user",
+ "default": "postgres",
+ "type": "string"
+ },
+ "password": {
+ "title": "Password",
+ "description": "Database password",
+ "type": "string"
+ },
+ "database": {
+ "title": "Database",
+ "description": "Database name",
+ "default": "postgres",
+ "type": "string"
+ },
+ "schema": {
+ "title": "Schema",
+ "description": "Database schema",
+ "default": "public",
+ "type": "string"
+ },
+ "sampleRows": {
+ "title": "Sample Rows",
+ "description": "Number of rows to sample from the database",
+ "default": 3,
+ "type": "integer"
+ }
+ },
+ "required": [
+ "host",
+ "port",
+ "user",
+ "password",
+ "database"
+ ]
+ }
+ },
+ "required": [
+ "params"
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "greptile"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "GithubToken": {
+ "title": "GithubToken",
+ "description": "Your github access token",
+ "default": "",
+ "type": "string"
+ },
+ "GreptileToken": {
+ "title": "GreptileToken",
+ "description": "Your greptile access token",
+ "default": "",
+ "type": "string"
+ }
+ },
+ "required": [
+ "GreptileToken",
+ "GithubToken"
+ ]
+ }
+ },
+ "required": [
+ "params"
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "commit"
+ ]
+ }
+ }
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "properties": {
+ "Depth": {
+ "title": "depth",
+ "description": "How many previous commits should be loaded",
+ "default": 50,
+ "type": "number"
+ },
+ "LastXCommitsDepth": {
+ "title": "LastXCommitsDepth",
+ "description": "how many commits should be included when querying all recent commits",
+ "default": 10,
+ "type": "number"
+ }
+ }
+ }
+ },
+ "required": [
+ "params"
+ ]
+ }
+ }
+ ],
+ "required": [
+ "name"
+ ]
+ },
+ "SerializedContinueConfig": {
+ "title": "config.json",
+ "type": "object",
+ "properties": {
+ "docs": {
+ "title": "Docs",
+ "description": "A list of documentation sites to be indexed",
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string",
+ "description": "The title of the documentation site"
+ },
+ "startUrl": {
+ "type": "string",
+ "description": "The starting URL for indexing the documentation"
+ },
+ "maxDepth": {
+ "type": "integer",
+ "description": "The maximum link depth when crawling the documentation site"
+ },
+ "faviconUrl": {
+ "type": "string",
+ "description": "The URL path to a favicon for the site - by default, it will be `/favicon.ico` path from the Start URL"
+ },
+ "useLocalCrawling": {
+ "type": "boolean",
+ "description": "Only use local crawling for this documentation site"
+ }
+ },
+ "required": [
+ "title",
+ "startUrl"
+ ]
+ }
+ },
+ "allowAnonymousTelemetry": {
+ "title": "Allow Anonymous Telemetry",
+ "markdownDescription": "If this field is set to `true`, we will collect anonymous telemetry as described in the documentation page on telemetry. If set to `false`, we will not collect any data. Learn more in [the docs](https://docs.continue.dev/telemetry).",
+ "x-intellij-html-description": "If this field is set to `true`, we will collect anonymous telemetry as described in the documentation page on telemetry. If set to `false`, we will not collect any data. Learn more in the docs.",
+ "default": true,
+ "type": "boolean"
+ },
+ "models": {
+ "title": "Models",
+ "markdownDescription": "Learn about setting up models in [the documentation](https://docs.continue.dev/model-setup/overview).",
+ "x-intellij-html-description": "Learn about setting up models in the documentation.",
+ "default": [
+ {
+ "title": "Claude 3.7 Sonnet",
+ "provider": "anthropic",
+ "model": "claude-3-7-sonnet-latest",
+ "apiKey": "sk_..."
+ }
+ ],
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/ModelDescription"
+ }
+ },
+ "systemMessage": {
+ "title": "System Message",
+ "description": "A system message that will always be followed by the LLM for Chat and Edit requests",
+ "type": "string"
+ },
+ "completionOptions": {
+ "title": "Completion Options",
+ "description": "Default options for completion. These will be overriden by any options set for a specific model.",
+ "default": {
+ "temperature": null,
+ "topP": null,
+ "topK": null,
+ "presencePenalty": null,
+ "frequencyPenalty": null,
+ "stop": null,
+ "maxTokens": 600
+ },
+ "allOf": [
+ {
+ "$ref": "#/$defs/BaseCompletionOptions"
+ }
+ ]
+ },
+ "requestOptions": {
+ "title": "Request Options",
+ "description": "Default request options for all fetch requests from models and context providers. These will be overriden by any model-specific request options.",
+ "allOf": [
+ {
+ "$ref": "#/$defs/RequestOptions"
+ }
+ ]
+ },
+ "slashCommands": {
+ "title": "Slash Commands",
+ "markdownDescription": "An array of slash commands that let you take custom actions from the sidebar. Learn more in the [documentation](https://docs.continue.dev/customization/slash-commands).",
+ "x-intellij-html-description": "An array of slash commands that let you take custom actions from the sidebar. Learn more in the documentation.",
+ "default": [],
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/SlashCommand"
+ }
+ },
+ "customCommands": {
+ "title": "Custom Commands",
+ "markdownDescription": "An array of custom commands that allow you to reuse prompts. Each has name, description, and prompt properties. When you enter `// in the text input, it will act as a shortcut to the prompt. Learn more in the documentation.",
+ "default": [
+ {
+ "name": "test",
+ "prompt": "{{{ input }}}\n\nWrite a comprehensive set of unit tests for the selected code. It should setup, run tests that check for correctness including important edge cases, and teardown. Ensure that the tests are complete and sophisticated. Give the tests just as chat output, don't edit any file.",
+ "description": "This is an example custom command. Open config.json to edit it and create more"
+ }
+ ],
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/CustomCommand"
+ }
+ },
+ "contextProviders": {
+ "title": "Context Providers",
+ "markdownDescription": "A list of ContextProvider objects that can be used to provide context to the LLM by typing '@'. Read more about ContextProviders in [the documentation](https://docs.continue.dev/customization/context-providers).",
+ "x-intellij-html-description": "A list of ContextProvider objects that can be used to provide context to the LLM by typing '@'. Read more about ContextProviders in the documentation.",
+ "default": [],
+ "type": "array",
+ "items": {
+ "$ref": "#/$defs/ContextProviderWithParams"
+ }
+ },
+ "userToken": {
+ "title": "User Token",
+ "description": "An optional token to identify the user.",
+ "type": "string"
+ },
+ "disableIndexing": {
+ "title": "Disable Indexing",
+ "markdownDescription": "If set to `true`, Continue will not index the codebase. This is mainly used for debugging purposes.",
+ "x-intellij-html-description": "If set to true, Continue will not index the codebase. This is mainly used for debugging purposes.",
+ "default": false,
+ "type": "boolean"
+ },
+ "disableSessionTitles": {
+ "title": "Disable Session Titles",
+ "markdownDescription": "If set to `true`, Continue will not make extra requests to the LLM to generate a summary title of each session.",
+ "x-intellij-html-description": "If set to true, Continue will not make extra requests to the LLM to generate a summary title of each session.",
+ "default": false,
+ "type": "boolean"
+ },
+ "embeddingsProvider": {
+ "title": "Embeddings Provider",
+ "markdownDescription": "The method that will be used to generate codebase embeddings. The default is `transformers.js`, which will run locally in the browser. Learn about the other options [here](https://docs.continue.dev/features/codebase-embeddings#embeddings-providers).",
+ "x-intellij-html-description": "The method that will be used to generate codebase embeddings. The default is transformers.js, which will run locally in the browser. Learn about the other options here.transformers.js currently cannot be used in JetBrains.",
+ "type": "object",
+ "properties": {
+ "provider": {
+ "enum": [
+ "huggingface-tei",
+ "transformers.js",
+ "ollama",
+ "openai",
+ "cohere",
+ "continue-proxy",
+ "gemini",
+ "voyage",
+ "nvidia",
+ "bedrock",
+ "sagemaker",
+ "nebius",
+ "vertexai",
+ "deepinfra",
+ "mistral",
+ "watsonx",
+ "lmstudio",
+ "siliconflow",
+ "function-network",
+ "scaleway",
+ "ovhcloud"
+ ]
+ },
+ "model": {
+ "type": "string"
+ },
+ "apiKey": {
+ "type": "string"
+ },
+ "apiBase": {
+ "type": "string"
+ },
+ "requestOptions": {
+ "title": "Request Options",
+ "description": "Request options to be used in any fetch requests made by the embeddings provider",
+ "$ref": "#/$defs/RequestOptions"
+ },
+ "maxEmbeddingChunkSize": {
+ "title": "Maximum Chunk Size",
+ "description": "The maximum number of tokens that each chunk of a document is allowed to have",
+ "type": "integer",
+ "minimum": 128,
+ "exclusiveMaximum": 2147483647
+ },
+ "maxEmbeddingBatchSize": {
+ "title": "Maximum Batch Size",
+ "description": "The maximum number of chunks that can be sent to the embeddings provider in a single request",
+ "type": "integer",
+ "minimum": 1,
+ "exclusiveMaximum": 2147483647
+ },
+ "region": {
+ "title": "Region",
+ "description": "The region where the model is hosted",
+ "$ref": "#/$defs/ModelDescription/properties/region"
+ },
+ "profile": {
+ "title": "Profile",
+ "description": "The AWS security profile to use",
+ "type": "string"
+ },
+ "accessKeyId": {
+ "title": "Access Key ID",
+ "description": "AWS access key id (can be used together with secretAccessKey in place of profile)",
+ "type": "string"
+ },
+ "secretAccessKey": {
+ "title": "Secret Access Key",
+ "description": "AWS secret access key (can be used together with secretAccessKey in place of profile)",
+ "type": "string"
+ }
+ },
+ "required": [
+ "provider"
+ ],
+ "allOf": [
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "cohere",
+ "voyage",
+ "nvidia",
+ "gemini",
+ "siliconflow"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "required": [
+ "apiKey"
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "sagemaker"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "model": {
+ "description": "SageMaker endpoint name"
+ }
+ },
+ "required": [
+ "model"
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "vertexai"
+ ]
+ }
+ },
+ "required": [
+ "provider"
+ ]
+ },
+ "then": {
+ "properties": {
+ "projectId": {
+ "description": "The name of your VertexAI project"
+ },
+ "region": {
+ "description": "The region your VertexAI model is hosted in - typically us-central1",
+ "default": "us-central1"
+ },
+ "model": {
+ "default": "text-embedding-005"
+ }
+ },
+ "required": [
+ "projectId",
+ "model",
+ "region"
+ ]
+ }
+ }
+ ]
+ },
+ "reranker": {
+ "title": "Reranker",
+ "description": "The reranker is responsible for selecting the final results when retrieving snippets from your codebase.",
+ "type": "object",
+ "properties": {
+ "name": {
+ "enum": [
+ "bedrock",
+ "cohere",
+ "voyage",
+ "watsonx",
+ "llm",
+ "huggingface-tei",
+ "siliconflow"
+ ]
+ },
+ "params": {
+ "type": "object"
+ }
+ },
+ "required": [
+ "name"
+ ],
+ "allOf": [
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "cohere"
+ ]
+ }
+ },
+ "required": [
+ "name"
+ ]
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "type": "object",
+ "properties": {
+ "model": {
+ "enum": [
+ "rerank-english-v3.0",
+ "rerank-multilingual-v3.0",
+ "rerank-english-v2.0",
+ "rerank-multilingual-v2.0",
+ "rerank-v3.5"
+ ]
+ },
+ "apiBase": {
+ "type": "string"
+ },
+ "apiKey": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "apiKey"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "llm"
+ ]
+ }
+ },
+ "required": [
+ "name"
+ ]
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "type": "object",
+ "properties": {
+ "modelTitle": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "modelTitle"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "voyage"
+ ]
+ }
+ },
+ "required": [
+ "name"
+ ]
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "type": "object",
+ "properties": {
+ "apiKey": {
+ "type": "string"
+ },
+ "model": {
+ "enum": [
+ "rerank-lite-1",
+ "rerank-1",
+ "rerank-2",
+ "rerank-2-lite"
+ ]
+ }
+ },
+ "required": [
+ "apiKey"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "bedrock"
+ ]
+ }
+ },
+ "required": [
+ "name"
+ ]
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "type": "object",
+ "properties": {
+ "model": {
+ "enum": [
+ "cohere.rerank-v3-5:0",
+ "amazon.rerank-v1:0"
+ ]
+ }
+ },
+ "required": [
+ "model"
+ ]
+ }
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "huggingface-tei"
+ ]
+ }
+ },
+ "required": [
+ "name"
+ ]
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "type": "object",
+ "properties": {
+ "apiBase": {
+ "type": "string",
+ "default": "http://localhost:8080"
+ },
+ "apiKey": {
+ "type": "string"
+ },
+ "truncate": {
+ "type": "boolean",
+ "description": "Whether to truncate long sequences to the maximum allowed context length.",
+ "default": false
+ },
+ "truncation_direction": {
+ "enum": [
+ "Right",
+ "Left"
+ ],
+ "description": "Whether to truncate sequences from the left or right.",
+ "default": "Right"
+ }
+ },
+ "required": [
+ "apiBase"
+ ]
+ }
+ },
+ "if": {
+ "properties": {
+ "truncate": {
+ "const": true
+ }
+ }
+ },
+ "then": {
+ "required": [
+ "truncation_direction"
+ ]
+ }
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "name": {
+ "enum": [
+ "siliconflow"
+ ]
+ }
+ },
+ "required": [
+ "name"
+ ]
+ },
+ "then": {
+ "properties": {
+ "params": {
+ "type": "object",
+ "properties": {
+ "model": {
+ "enum": [
+ "BAAI/bge-reranker-v2-m3",
+ "netease-youdao/bce-reranker-base_v1",
+ "Pro/BAAI/bge-reranker-v2-m3"
+ ],
+ "default": "BAAI/bge-reranker-v2-m3"
+ },
+ "apiBase": {
+ "type": "string"
+ },
+ "apiKey": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "apiKey"
+ ]
+ }
+ }
+ }
+ }
+ ]
+ },
+ "tabAutocompleteModel": {
+ "title": "Tab Autocomplete Model",
+ "markdownDescription": "The model used for tab autocompletion. If undefined, Continue will default to using qwen2.5-coder:1.5b on a local Ollama instance.\n\n*IMPORTANT*:\n\nIf you use a custom model, ensure that it is one trained for fill-in-the-middle completions. An instruct model is typically not well-suited to autocomplete and you may receive unsatisfactory completions.",
+ "x-intellij-html-description": "The model used for tab autocompletion. If undefined, Continue will default to using qwen2.5-coder:1.5b on a local Ollama instance.true, a scrollbar will be displayed in the chat window to navigate through messages.",
+ "default": false,
+ "type": "boolean"
+ },
+ "codeWrap": {
+ "type": "boolean",
+ "description": "If set to true, code in pre blocks will wrap.",
+ "default": false
+ }
+ }
+ },
+ "analytics": {
+ "type": "object",
+ "properties": {
+ "provider": {
+ "type": "string",
+ "enum": [
+ "posthog",
+ "logstash"
+ ],
+ "description": "The 3rd party analytics provider to use.",
+ "default": "posthog",
+ "markdownEnumDescriptions": [
+ "### Posthog\nTo use Posthog, set up an account, obtain your client key, and enter it in the client key field."
+ ]
+ },
+ "url": {
+ "type": "string",
+ "description": "The URL to which analytics will be sent"
+ },
+ "clientKey": {
+ "type": "string",
+ "description": "The client key to use for analytics"
+ }
+ },
+ "required": [
+ "provider"
+ ],
+ "allOf": [
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "posthog"
+ ]
+ }
+ }
+ },
+ "then": {
+ "required": [
+ "clientKey"
+ ]
+ }
+ },
+ {
+ "if": {
+ "properties": {
+ "provider": {
+ "enum": [
+ "logstash"
+ ]
+ }
+ }
+ },
+ "then": {
+ "required": [
+ "url"
+ ]
+ }
+ }
+ ]
+ },
+ "experimental": {
+ "type": "object",
+ "title": "Experimental",
+ "description": "Experimental properties are subject to change.",
+ "properties": {
+ "defaultContext": {
+ "type": "array",
+ "items": {
+ "allOf": [
+ {
+ "$ref": "#/$defs/ContextProviderWithParams"
+ },
+ {
+ "properties": {
+ "query": {
+ "type": "string",
+ "description": "Required for certain context providers, like 'url' in order to specify the input, or which of the dropdown items to select."
+ }
+ }
+ }
+ ]
+ }
+ },
+ "modelRoles": {
+ "type": "object",
+ "properties": {
+ "inlineEdit": {
+ "description": "The 'title' property of the model you wish to use for inline edits",
+ "type": "string"
+ },
+ "applyCodeBlock": {
+ "description": "The 'title' property of the model you wish to use for applying code blocks",
+ "type": "string"
+ },
+ "repoMapFileSelection": {
+ "description": "The 'title' property of the model you wish to use for repo map file selections",
+ "type": "string"
+ }
+ }
+ },
+ "readResponseTTS": {
+ "type": "boolean",
+ "default": true,
+ "description": "Automatically read LLM chat responses aloud using system TTS models"
+ },
+ "promptPath": {
+ "type": "string"
+ },
+ "quickActions": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string",
+ "description": "The title of the quick action that will display in the Code Lens."
+ },
+ "prompt": {
+ "type": "string",
+ "description": "The prompt that will be sent to the model when the quick action is invoked, with the function or class body concatenated."
+ },
+ "sendToChat": {
+ "type": "boolean",
+ "description": "If true, the result of the quick action will be sent to the chat panel. If false, the streamed result will be inserted into the document.",
+ "default": false
+ }
+ },
+ "required": [
+ "prompt",
+ "title"
+ ]
+ },
+ "description": "Quick actions are a way to add custom commands to the Code Lens of function and class declarations."
+ },
+ "contextMenuPrompts": {
+ "type": "object",
+ "properties": {
+ "comment": {
+ "type": "string",
+ "default": "Write comments for this code. Do not change anything about the code itself."
+ },
+ "docstring": {
+ "type": "string",
+ "default": "Write a docstring for this code. Do not change anything about the code itself."
+ },
+ "fix": {
+ "type": "string",
+ "default": "Fix this code"
+ },
+ "optimize": {
+ "type": "string",
+ "default": "Optimize this code"
+ },
+ "fixGrammar": {
+ "type": "string",
+ "default": "If there are any grammar or spelling mistakes in this writing, fix them. Do not make other large changes to the writing."
+ }
+ }
+ },
+ "useChromiumForDocsCrawling": {
+ "type": "boolean",
+ "description": "Use Chromium to crawl docs locally. Useful if the default Cheerio crawler fails on sites that require JavaScript rendering. Downloads and installs Chromium to `~/.continue/.utils`.",
+ "default": false
+ },
+ "modelContextProtocolServers": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "transport": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "stdio"
+ ]
+ },
+ "command": {
+ "type": "string"
+ },
+ "args": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "env": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ },
+ "description": "Environment variables to pass to the command"
+ }
+ },
+ "required": [
+ "type",
+ "command",
+ "args"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "websocket"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "format": "uri"
+ }
+ },
+ "required": [
+ "type",
+ "url"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "sse"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "format": "uri"
+ }
+ },
+ "required": [
+ "type",
+ "url"
+ ]
+ },
+ {
+ "type": "object",
+ "properties": {
+ "type": {
+ "type": "string",
+ "enum": [
+ "streamable-http"
+ ]
+ },
+ "url": {
+ "type": "string",
+ "format": "uri"
+ }
+ },
+ "required": [
+ "type",
+ "url"
+ ]
+ }
+ ]
+ }
+ },
+ "required": [
+ "transport"
+ ]
+ }
+ }
+ }
+ },
+ "mergeBehavior": {
+ "type": "string",
+ "enum": [
+ "merge",
+ "overwrite"
+ ],
+ "default": "merge",
+ "title": "Merge behavior",
+ "markdownDescription": "If set to 'merge', .continuerc.json will be applied on top of config.json (arrays and objects are merged). If set to 'overwrite', then every top-level property of .continuerc.json will overwrite that property from config.json.",
+ "x-intellij-html-description": "If set to merge, .continuerc.json will be applied on top of config.json (arrays and objects are merged). If set to overwrite, then every top-level property of .continuerc.json will overwrite that property from config.json.
a||125d?(a.sortIndex=c,f(t,a),null===h(r)&&a===h(t)&&(B?(E(L),L=-1):B=!0,K(H,c-d))):(a.sortIndex=e,f(r,a),A||z||(A=!0,I(J)));return a};\nexports.unstable_shouldYield=M;exports.unstable_wrapCallback=function(a){var b=y;return function(){var c=y;y=b;try{return a.apply(this,arguments)}finally{y=c}}};\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/scheduler.production.min.js');\n} else {\n module.exports = require('./cjs/scheduler.development.js');\n}\n","/**\n * @license React\n * react-dom.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n/*\n Modernizr 3.0.0pre (Custom Build) | MIT\n*/\n'use strict';var aa=require(\"react\"),ca=require(\"scheduler\");function p(a){for(var b=\"https://reactjs.org/docs/error-decoder.html?invariant=\"+a,c=1;c 0&&(F=p+n.verticalPadding-n.rowHeight[R]);var W;n.width-w>=m+n.horizontalPadding?W=(n.height+F)/(w+m+n.horizontalPadding):W=(n.height+F)/n.width,F=p+n.verticalPadding;var I;return n.width u?(e-i)*(e-i)+(t-s)*(t-s):v-c},Sr=function(e,t,a){for(var n,i,s,o,l,u=0,v=0;v=ht){var b=e?null:Tt(n);if(b)return H(b);a=!1,f=In,u=new S}else u=e?[]:s;n:for(;++t true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nexport default isSymbol;\n","/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nexport default arrayMap;\n","import Symbol from './_Symbol.js';\nimport arrayMap from './_arrayMap.js';\nimport isArray from './isArray.js';\nimport isSymbol from './isSymbol.js';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n/**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\nfunction baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n if (isArray(value)) {\n // Recursively convert values (susceptible to call stack limits).\n return arrayMap(value, baseToString) + '';\n }\n if (isSymbol(value)) {\n return symbolToString ? symbolToString.call(value) : '';\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nexport default baseToString;\n","/**\n * This method returns `undefined`.\n *\n * @static\n * @memberOf _\n * @since 2.3.0\n * @category Util\n * @example\n *\n * _.times(2, _.noop);\n * // => [undefined, undefined]\n */\nfunction noop() {\n // No operation performed.\n}\n\nexport default noop;\n","/**\n * A specialized version of `_.forEach` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\nfunction arrayEach(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (iteratee(array[index], index, array) === false) {\n break;\n }\n }\n return array;\n}\n\nexport default arrayEach;\n","/**\n * The base implementation of `_.findIndex` and `_.findLastIndex` without\n * support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} predicate The function invoked per iteration.\n * @param {number} fromIndex The index to search from.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction baseFindIndex(array, predicate, fromIndex, fromRight) {\n var length = array.length,\n index = fromIndex + (fromRight ? 1 : -1);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (predicate(array[index], index, array)) {\n return index;\n }\n }\n return -1;\n}\n\nexport default baseFindIndex;\n","/**\n * The base implementation of `_.isNaN` without support for number objects.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.\n */\nfunction baseIsNaN(value) {\n return value !== value;\n}\n\nexport default baseIsNaN;\n","/**\n * A specialized version of `_.indexOf` which performs strict equality\n * comparisons of values, i.e. `===`.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction strictIndexOf(array, value, fromIndex) {\n var index = fromIndex - 1,\n length = array.length;\n\n while (++index < length) {\n if (array[index] === value) {\n return index;\n }\n }\n return -1;\n}\n\nexport default strictIndexOf;\n","import baseFindIndex from './_baseFindIndex.js';\nimport baseIsNaN from './_baseIsNaN.js';\nimport strictIndexOf from './_strictIndexOf.js';\n\n/**\n * The base implementation of `_.indexOf` without `fromIndex` bounds checks.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} value The value to search for.\n * @param {number} fromIndex The index to search from.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction baseIndexOf(array, value, fromIndex) {\n return value === value\n ? strictIndexOf(array, value, fromIndex)\n : baseFindIndex(array, baseIsNaN, fromIndex);\n}\n\nexport default baseIndexOf;\n","import baseIndexOf from './_baseIndexOf.js';\n\n/**\n * A specialized version of `_.includes` for arrays without support for\n * specifying an index to search from.\n *\n * @private\n * @param {Array} [array] The array to inspect.\n * @param {*} target The value to search for.\n * @returns {boolean} Returns `true` if `target` is found, else `false`.\n */\nfunction arrayIncludes(array, value) {\n var length = array == null ? 0 : array.length;\n return !!length && baseIndexOf(array, value, 0) > -1;\n}\n\nexport default arrayIncludes;\n","import arrayLikeKeys from './_arrayLikeKeys.js';\nimport baseKeys from './_baseKeys.js';\nimport isArrayLike from './isArrayLike.js';\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\nexport default keys;\n","import isArray from './isArray.js';\nimport isSymbol from './isSymbol.js';\n\n/** Used to match property names within property paths. */\nvar reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n reIsPlainProp = /^\\w*$/;\n\n/**\n * Checks if `value` is a property name and not a property path.\n *\n * @private\n * @param {*} value The value to check.\n * @param {Object} [object] The object to query keys on.\n * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n */\nfunction isKey(value, object) {\n if (isArray(value)) {\n return false;\n }\n var type = typeof value;\n if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n value == null || isSymbol(value)) {\n return true;\n }\n return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n (object != null && value in Object(object));\n}\n\nexport default isKey;\n","import memoize from './memoize.js';\n\n/** Used as the maximum memoize cache size. */\nvar MAX_MEMOIZE_SIZE = 500;\n\n/**\n * A specialized version of `_.memoize` which clears the memoized function's\n * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n *\n * @private\n * @param {Function} func The function to have its output memoized.\n * @returns {Function} Returns the new memoized function.\n */\nfunction memoizeCapped(func) {\n var result = memoize(func, function(key) {\n if (cache.size === MAX_MEMOIZE_SIZE) {\n cache.clear();\n }\n return key;\n });\n\n var cache = result.cache;\n return result;\n}\n\nexport default memoizeCapped;\n","import memoizeCapped from './_memoizeCapped.js';\n\n/** Used to match property names within property paths. */\nvar rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n/** Used to match backslashes in property paths. */\nvar reEscapeChar = /\\\\(\\\\)?/g;\n\n/**\n * Converts `string` to a property path array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the property path array.\n */\nvar stringToPath = memoizeCapped(function(string) {\n var result = [];\n if (string.charCodeAt(0) === 46 /* . */) {\n result.push('');\n }\n string.replace(rePropName, function(match, number, quote, subString) {\n result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));\n });\n return result;\n});\n\nexport default stringToPath;\n","import baseToString from './_baseToString.js';\n\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString(value) {\n return value == null ? '' : baseToString(value);\n}\n\nexport default toString;\n","import isArray from './isArray.js';\nimport isKey from './_isKey.js';\nimport stringToPath from './_stringToPath.js';\nimport toString from './toString.js';\n\n/**\n * Casts `value` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {Object} [object] The object to query keys on.\n * @returns {Array} Returns the cast property path array.\n */\nfunction castPath(value, object) {\n if (isArray(value)) {\n return value;\n }\n return isKey(value, object) ? [value] : stringToPath(toString(value));\n}\n\nexport default castPath;\n","import isSymbol from './isSymbol.js';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\nfunction toKey(value) {\n if (typeof value == 'string' || isSymbol(value)) {\n return value;\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nexport default toKey;\n","import castPath from './_castPath.js';\nimport toKey from './_toKey.js';\n\n/**\n * The base implementation of `_.get` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\nfunction baseGet(object, path) {\n path = castPath(path, object);\n\n var index = 0,\n length = path.length;\n\n while (object != null && index < length) {\n object = object[toKey(path[index++])];\n }\n return (index && index == length) ? object : undefined;\n}\n\nexport default baseGet;\n","import baseGet from './_baseGet.js';\n\n/**\n * Gets the value at `path` of `object`. If the resolved value is\n * `undefined`, the `defaultValue` is returned in its place.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.get(object, 'a[0].b.c');\n * // => 3\n *\n * _.get(object, ['a', '0', 'b', 'c']);\n * // => 3\n *\n * _.get(object, 'a.b.c', 'default');\n * // => 'default'\n */\nfunction get(object, path, defaultValue) {\n var result = object == null ? undefined : baseGet(object, path);\n return result === undefined ? defaultValue : result;\n}\n\nexport default get;\n","/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\nexport default arrayPush;\n","import Symbol from './_Symbol.js';\nimport isArguments from './isArguments.js';\nimport isArray from './isArray.js';\n\n/** Built-in value references. */\nvar spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined;\n\n/**\n * Checks if `value` is a flattenable `arguments` object or array.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.\n */\nfunction isFlattenable(value) {\n return isArray(value) || isArguments(value) ||\n !!(spreadableSymbol && value && value[spreadableSymbol]);\n}\n\nexport default isFlattenable;\n","import arrayPush from './_arrayPush.js';\nimport isFlattenable from './_isFlattenable.js';\n\n/**\n * The base implementation of `_.flatten` with support for restricting flattening.\n *\n * @private\n * @param {Array} array The array to flatten.\n * @param {number} depth The maximum recursion depth.\n * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.\n * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.\n * @param {Array} [result=[]] The initial result value.\n * @returns {Array} Returns the new flattened array.\n */\nfunction baseFlatten(array, depth, predicate, isStrict, result) {\n var index = -1,\n length = array.length;\n\n predicate || (predicate = isFlattenable);\n result || (result = []);\n\n while (++index < length) {\n var value = array[index];\n if (depth > 0 && predicate(value)) {\n if (depth > 1) {\n // Recursively flatten arrays (susceptible to call stack limits).\n baseFlatten(value, depth - 1, predicate, isStrict, result);\n } else {\n arrayPush(result, value);\n }\n } else if (!isStrict) {\n result[result.length] = value;\n }\n }\n return result;\n}\n\nexport default baseFlatten;\n","/**\n * A specialized version of `_.reduce` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @param {boolean} [initAccum] Specify using the first element of `array` as\n * the initial value.\n * @returns {*} Returns the accumulated value.\n */\nfunction arrayReduce(array, iteratee, accumulator, initAccum) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n if (initAccum && length) {\n accumulator = array[++index];\n }\n while (++index < length) {\n accumulator = iteratee(accumulator, array[index], index, array);\n }\n return accumulator;\n}\n\nexport default arrayReduce;\n","import copyObject from './_copyObject.js';\nimport keys from './keys.js';\n\n/**\n * The base implementation of `_.assign` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssign(object, source) {\n return object && copyObject(source, keys(source), object);\n}\n\nexport default baseAssign;\n","import copyObject from './_copyObject.js';\nimport keysIn from './keysIn.js';\n\n/**\n * The base implementation of `_.assignIn` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssignIn(object, source) {\n return object && copyObject(source, keysIn(source), object);\n}\n\nexport default baseAssignIn;\n","/**\n * A specialized version of `_.filter` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction arrayFilter(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length,\n resIndex = 0,\n result = [];\n\n while (++index < length) {\n var value = array[index];\n if (predicate(value, index, array)) {\n result[resIndex++] = value;\n }\n }\n return result;\n}\n\nexport default arrayFilter;\n","/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\nexport default stubArray;\n","import arrayFilter from './_arrayFilter.js';\nimport stubArray from './stubArray.js';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = !nativeGetSymbols ? stubArray : function(object) {\n if (object == null) {\n return [];\n }\n object = Object(object);\n return arrayFilter(nativeGetSymbols(object), function(symbol) {\n return propertyIsEnumerable.call(object, symbol);\n });\n};\n\nexport default getSymbols;\n","import copyObject from './_copyObject.js';\nimport getSymbols from './_getSymbols.js';\n\n/**\n * Copies own symbols of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\nfunction copySymbols(source, object) {\n return copyObject(source, getSymbols(source), object);\n}\n\nexport default copySymbols;\n","import arrayPush from './_arrayPush.js';\nimport getPrototype from './_getPrototype.js';\nimport getSymbols from './_getSymbols.js';\nimport stubArray from './stubArray.js';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols;\n\n/**\n * Creates an array of the own and inherited enumerable symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) {\n var result = [];\n while (object) {\n arrayPush(result, getSymbols(object));\n object = getPrototype(object);\n }\n return result;\n};\n\nexport default getSymbolsIn;\n","import copyObject from './_copyObject.js';\nimport getSymbolsIn from './_getSymbolsIn.js';\n\n/**\n * Copies own and inherited symbols of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\nfunction copySymbolsIn(source, object) {\n return copyObject(source, getSymbolsIn(source), object);\n}\n\nexport default copySymbolsIn;\n","import arrayPush from './_arrayPush.js';\nimport isArray from './isArray.js';\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\nexport default baseGetAllKeys;\n","import baseGetAllKeys from './_baseGetAllKeys.js';\nimport getSymbols from './_getSymbols.js';\nimport keys from './keys.js';\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n}\n\nexport default getAllKeys;\n","import baseGetAllKeys from './_baseGetAllKeys.js';\nimport getSymbolsIn from './_getSymbolsIn.js';\nimport keysIn from './keysIn.js';\n\n/**\n * Creates an array of own and inherited enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeysIn(object) {\n return baseGetAllKeys(object, keysIn, getSymbolsIn);\n}\n\nexport default getAllKeysIn;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Initializes an array clone.\n *\n * @private\n * @param {Array} array The array to clone.\n * @returns {Array} Returns the initialized clone.\n */\nfunction initCloneArray(array) {\n var length = array.length,\n result = new array.constructor(length);\n\n // Add properties assigned by `RegExp#exec`.\n if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n result.index = array.index;\n result.input = array.input;\n }\n return result;\n}\n\nexport default initCloneArray;\n","import cloneArrayBuffer from './_cloneArrayBuffer.js';\n\n/**\n * Creates a clone of `dataView`.\n *\n * @private\n * @param {Object} dataView The data view to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned data view.\n */\nfunction cloneDataView(dataView, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n}\n\nexport default cloneDataView;\n","/** Used to match `RegExp` flags from their coerced string values. */\nvar reFlags = /\\w*$/;\n\n/**\n * Creates a clone of `regexp`.\n *\n * @private\n * @param {Object} regexp The regexp to clone.\n * @returns {Object} Returns the cloned regexp.\n */\nfunction cloneRegExp(regexp) {\n var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n result.lastIndex = regexp.lastIndex;\n return result;\n}\n\nexport default cloneRegExp;\n","import Symbol from './_Symbol.js';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * Creates a clone of the `symbol` object.\n *\n * @private\n * @param {Object} symbol The symbol object to clone.\n * @returns {Object} Returns the cloned symbol object.\n */\nfunction cloneSymbol(symbol) {\n return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n}\n\nexport default cloneSymbol;\n","import cloneArrayBuffer from './_cloneArrayBuffer.js';\nimport cloneDataView from './_cloneDataView.js';\nimport cloneRegExp from './_cloneRegExp.js';\nimport cloneSymbol from './_cloneSymbol.js';\nimport cloneTypedArray from './_cloneTypedArray.js';\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/**\n * Initializes an object clone based on its `toStringTag`.\n *\n * **Note:** This function only supports cloning values with tags of\n * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.\n *\n * @private\n * @param {Object} object The object to clone.\n * @param {string} tag The `toStringTag` of the object to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneByTag(object, tag, isDeep) {\n var Ctor = object.constructor;\n switch (tag) {\n case arrayBufferTag:\n return cloneArrayBuffer(object);\n\n case boolTag:\n case dateTag:\n return new Ctor(+object);\n\n case dataViewTag:\n return cloneDataView(object, isDeep);\n\n case float32Tag: case float64Tag:\n case int8Tag: case int16Tag: case int32Tag:\n case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n return cloneTypedArray(object, isDeep);\n\n case mapTag:\n return new Ctor;\n\n case numberTag:\n case stringTag:\n return new Ctor(object);\n\n case regexpTag:\n return cloneRegExp(object);\n\n case setTag:\n return new Ctor;\n\n case symbolTag:\n return cloneSymbol(object);\n }\n}\n\nexport default initCloneByTag;\n","import getTag from './_getTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar mapTag = '[object Map]';\n\n/**\n * The base implementation of `_.isMap` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n */\nfunction baseIsMap(value) {\n return isObjectLike(value) && getTag(value) == mapTag;\n}\n\nexport default baseIsMap;\n","import baseIsMap from './_baseIsMap.js';\nimport baseUnary from './_baseUnary.js';\nimport nodeUtil from './_nodeUtil.js';\n\n/* Node.js helper references. */\nvar nodeIsMap = nodeUtil && nodeUtil.isMap;\n\n/**\n * Checks if `value` is classified as a `Map` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a map, else `false`.\n * @example\n *\n * _.isMap(new Map);\n * // => true\n *\n * _.isMap(new WeakMap);\n * // => false\n */\nvar isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap;\n\nexport default isMap;\n","import getTag from './_getTag.js';\nimport isObjectLike from './isObjectLike.js';\n\n/** `Object#toString` result references. */\nvar setTag = '[object Set]';\n\n/**\n * The base implementation of `_.isSet` without Node.js optimizations.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n */\nfunction baseIsSet(value) {\n return isObjectLike(value) && getTag(value) == setTag;\n}\n\nexport default baseIsSet;\n","import baseIsSet from './_baseIsSet.js';\nimport baseUnary from './_baseUnary.js';\nimport nodeUtil from './_nodeUtil.js';\n\n/* Node.js helper references. */\nvar nodeIsSet = nodeUtil && nodeUtil.isSet;\n\n/**\n * Checks if `value` is classified as a `Set` object.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a set, else `false`.\n * @example\n *\n * _.isSet(new Set);\n * // => true\n *\n * _.isSet(new WeakSet);\n * // => false\n */\nvar isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet;\n\nexport default isSet;\n","import Stack from './_Stack.js';\nimport arrayEach from './_arrayEach.js';\nimport assignValue from './_assignValue.js';\nimport baseAssign from './_baseAssign.js';\nimport baseAssignIn from './_baseAssignIn.js';\nimport cloneBuffer from './_cloneBuffer.js';\nimport copyArray from './_copyArray.js';\nimport copySymbols from './_copySymbols.js';\nimport copySymbolsIn from './_copySymbolsIn.js';\nimport getAllKeys from './_getAllKeys.js';\nimport getAllKeysIn from './_getAllKeysIn.js';\nimport getTag from './_getTag.js';\nimport initCloneArray from './_initCloneArray.js';\nimport initCloneByTag from './_initCloneByTag.js';\nimport initCloneObject from './_initCloneObject.js';\nimport isArray from './isArray.js';\nimport isBuffer from './isBuffer.js';\nimport isMap from './isMap.js';\nimport isObject from './isObject.js';\nimport isSet from './isSet.js';\nimport keys from './keys.js';\nimport keysIn from './keysIn.js';\n\n/** Used to compose bitmasks for cloning. */\nvar CLONE_DEEP_FLAG = 1,\n CLONE_FLAT_FLAG = 2,\n CLONE_SYMBOLS_FLAG = 4;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/** Used to identify `toStringTag` values supported by `_.clone`. */\nvar cloneableTags = {};\ncloneableTags[argsTag] = cloneableTags[arrayTag] =\ncloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\ncloneableTags[boolTag] = cloneableTags[dateTag] =\ncloneableTags[float32Tag] = cloneableTags[float64Tag] =\ncloneableTags[int8Tag] = cloneableTags[int16Tag] =\ncloneableTags[int32Tag] = cloneableTags[mapTag] =\ncloneableTags[numberTag] = cloneableTags[objectTag] =\ncloneableTags[regexpTag] = cloneableTags[setTag] =\ncloneableTags[stringTag] = cloneableTags[symbolTag] =\ncloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\ncloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\ncloneableTags[errorTag] = cloneableTags[funcTag] =\ncloneableTags[weakMapTag] = false;\n\n/**\n * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n * traversed objects.\n *\n * @private\n * @param {*} value The value to clone.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Deep clone\n * 2 - Flatten inherited properties\n * 4 - Clone symbols\n * @param {Function} [customizer] The function to customize cloning.\n * @param {string} [key] The key of `value`.\n * @param {Object} [object] The parent object of `value`.\n * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n * @returns {*} Returns the cloned value.\n */\nfunction baseClone(value, bitmask, customizer, key, object, stack) {\n var result,\n isDeep = bitmask & CLONE_DEEP_FLAG,\n isFlat = bitmask & CLONE_FLAT_FLAG,\n isFull = bitmask & CLONE_SYMBOLS_FLAG;\n\n if (customizer) {\n result = object ? customizer(value, key, object, stack) : customizer(value);\n }\n if (result !== undefined) {\n return result;\n }\n if (!isObject(value)) {\n return value;\n }\n var isArr = isArray(value);\n if (isArr) {\n result = initCloneArray(value);\n if (!isDeep) {\n return copyArray(value, result);\n }\n } else {\n var tag = getTag(value),\n isFunc = tag == funcTag || tag == genTag;\n\n if (isBuffer(value)) {\n return cloneBuffer(value, isDeep);\n }\n if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n result = (isFlat || isFunc) ? {} : initCloneObject(value);\n if (!isDeep) {\n return isFlat\n ? copySymbolsIn(value, baseAssignIn(result, value))\n : copySymbols(value, baseAssign(result, value));\n }\n } else {\n if (!cloneableTags[tag]) {\n return object ? value : {};\n }\n result = initCloneByTag(value, tag, isDeep);\n }\n }\n // Check for circular references and return its corresponding clone.\n stack || (stack = new Stack);\n var stacked = stack.get(value);\n if (stacked) {\n return stacked;\n }\n stack.set(value, result);\n\n if (isSet(value)) {\n value.forEach(function(subValue) {\n result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));\n });\n } else if (isMap(value)) {\n value.forEach(function(subValue, key) {\n result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));\n });\n }\n\n var keysFunc = isFull\n ? (isFlat ? getAllKeysIn : getAllKeys)\n : (isFlat ? keysIn : keys);\n\n var props = isArr ? undefined : keysFunc(value);\n arrayEach(props || value, function(subValue, key) {\n if (props) {\n key = subValue;\n subValue = value[key];\n }\n // Recursively populate clone (susceptible to call stack limits).\n assignValue(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));\n });\n return result;\n}\n\nexport default baseClone;\n","/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Adds `value` to the array cache.\n *\n * @private\n * @name add\n * @memberOf SetCache\n * @alias push\n * @param {*} value The value to cache.\n * @returns {Object} Returns the cache instance.\n */\nfunction setCacheAdd(value) {\n this.__data__.set(value, HASH_UNDEFINED);\n return this;\n}\n\nexport default setCacheAdd;\n","/**\n * Checks if `value` is in the array cache.\n *\n * @private\n * @name has\n * @memberOf SetCache\n * @param {*} value The value to search for.\n * @returns {number} Returns `true` if `value` is found, else `false`.\n */\nfunction setCacheHas(value) {\n return this.__data__.has(value);\n}\n\nexport default setCacheHas;\n","import MapCache from './_MapCache.js';\nimport setCacheAdd from './_setCacheAdd.js';\nimport setCacheHas from './_setCacheHas.js';\n\n/**\n *\n * Creates an array cache object to store unique values.\n *\n * @private\n * @constructor\n * @param {Array} [values] The values to cache.\n */\nfunction SetCache(values) {\n var index = -1,\n length = values == null ? 0 : values.length;\n\n this.__data__ = new MapCache;\n while (++index < length) {\n this.add(values[index]);\n }\n}\n\n// Add methods to `SetCache`.\nSetCache.prototype.add = SetCache.prototype.push = setCacheAdd;\nSetCache.prototype.has = setCacheHas;\n\nexport default SetCache;\n","/**\n * A specialized version of `_.some` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {boolean} Returns `true` if any element passes the predicate check,\n * else `false`.\n */\nfunction arraySome(array, predicate) {\n var index = -1,\n length = array == null ? 0 : array.length;\n\n while (++index < length) {\n if (predicate(array[index], index, array)) {\n return true;\n }\n }\n return false;\n}\n\nexport default arraySome;\n","/**\n * Checks if a `cache` value for `key` exists.\n *\n * @private\n * @param {Object} cache The cache to query.\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction cacheHas(cache, key) {\n return cache.has(key);\n}\n\nexport default cacheHas;\n","import SetCache from './_SetCache.js';\nimport arraySome from './_arraySome.js';\nimport cacheHas from './_cacheHas.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * A specialized version of `baseIsEqualDeep` for arrays with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Array} array The array to compare.\n * @param {Array} other The other array to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `array` and `other` objects.\n * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.\n */\nfunction equalArrays(array, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n arrLength = array.length,\n othLength = other.length;\n\n if (arrLength != othLength && !(isPartial && othLength > arrLength)) {\n return false;\n }\n // Check that cyclic values are equal.\n var arrStacked = stack.get(array);\n var othStacked = stack.get(other);\n if (arrStacked && othStacked) {\n return arrStacked == other && othStacked == array;\n }\n var index = -1,\n result = true,\n seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined;\n\n stack.set(array, other);\n stack.set(other, array);\n\n // Ignore non-index properties.\n while (++index < arrLength) {\n var arrValue = array[index],\n othValue = other[index];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, arrValue, index, other, array, stack)\n : customizer(arrValue, othValue, index, array, other, stack);\n }\n if (compared !== undefined) {\n if (compared) {\n continue;\n }\n result = false;\n break;\n }\n // Recursively compare arrays (susceptible to call stack limits).\n if (seen) {\n if (!arraySome(other, function(othValue, othIndex) {\n if (!cacheHas(seen, othIndex) &&\n (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) {\n return seen.push(othIndex);\n }\n })) {\n result = false;\n break;\n }\n } else if (!(\n arrValue === othValue ||\n equalFunc(arrValue, othValue, bitmask, customizer, stack)\n )) {\n result = false;\n break;\n }\n }\n stack['delete'](array);\n stack['delete'](other);\n return result;\n}\n\nexport default equalArrays;\n","/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\nexport default mapToArray;\n","/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\nexport default setToArray;\n","import Symbol from './_Symbol.js';\nimport Uint8Array from './_Uint8Array.js';\nimport eq from './eq.js';\nimport equalArrays from './_equalArrays.js';\nimport mapToArray from './_mapToArray.js';\nimport setToArray from './_setToArray.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/** `Object#toString` result references. */\nvar boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]';\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * A specialized version of `baseIsEqualDeep` for comparing objects of\n * the same `toStringTag`.\n *\n * **Note:** This function only supports comparing values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {string} tag The `toStringTag` of the objects to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) {\n switch (tag) {\n case dataViewTag:\n if ((object.byteLength != other.byteLength) ||\n (object.byteOffset != other.byteOffset)) {\n return false;\n }\n object = object.buffer;\n other = other.buffer;\n\n case arrayBufferTag:\n if ((object.byteLength != other.byteLength) ||\n !equalFunc(new Uint8Array(object), new Uint8Array(other))) {\n return false;\n }\n return true;\n\n case boolTag:\n case dateTag:\n case numberTag:\n // Coerce booleans to `1` or `0` and dates to milliseconds.\n // Invalid dates are coerced to `NaN`.\n return eq(+object, +other);\n\n case errorTag:\n return object.name == other.name && object.message == other.message;\n\n case regexpTag:\n case stringTag:\n // Coerce regexes to strings and treat strings, primitives and objects,\n // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring\n // for more details.\n return object == (other + '');\n\n case mapTag:\n var convert = mapToArray;\n\n case setTag:\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG;\n convert || (convert = setToArray);\n\n if (object.size != other.size && !isPartial) {\n return false;\n }\n // Assume cyclic values are equal.\n var stacked = stack.get(object);\n if (stacked) {\n return stacked == other;\n }\n bitmask |= COMPARE_UNORDERED_FLAG;\n\n // Recursively compare objects (susceptible to call stack limits).\n stack.set(object, other);\n var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack);\n stack['delete'](object);\n return result;\n\n case symbolTag:\n if (symbolValueOf) {\n return symbolValueOf.call(object) == symbolValueOf.call(other);\n }\n }\n return false;\n}\n\nexport default equalByTag;\n","import getAllKeys from './_getAllKeys.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqualDeep` for objects with support for\n * partial deep comparisons.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} stack Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction equalObjects(object, other, bitmask, customizer, equalFunc, stack) {\n var isPartial = bitmask & COMPARE_PARTIAL_FLAG,\n objProps = getAllKeys(object),\n objLength = objProps.length,\n othProps = getAllKeys(other),\n othLength = othProps.length;\n\n if (objLength != othLength && !isPartial) {\n return false;\n }\n var index = objLength;\n while (index--) {\n var key = objProps[index];\n if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) {\n return false;\n }\n }\n // Check that cyclic values are equal.\n var objStacked = stack.get(object);\n var othStacked = stack.get(other);\n if (objStacked && othStacked) {\n return objStacked == other && othStacked == object;\n }\n var result = true;\n stack.set(object, other);\n stack.set(other, object);\n\n var skipCtor = isPartial;\n while (++index < objLength) {\n key = objProps[index];\n var objValue = object[key],\n othValue = other[key];\n\n if (customizer) {\n var compared = isPartial\n ? customizer(othValue, objValue, key, other, object, stack)\n : customizer(objValue, othValue, key, object, other, stack);\n }\n // Recursively compare objects (susceptible to call stack limits).\n if (!(compared === undefined\n ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack))\n : compared\n )) {\n result = false;\n break;\n }\n skipCtor || (skipCtor = key == 'constructor');\n }\n if (result && !skipCtor) {\n var objCtor = object.constructor,\n othCtor = other.constructor;\n\n // Non `Object` object instances with different constructors are not equal.\n if (objCtor != othCtor &&\n ('constructor' in object && 'constructor' in other) &&\n !(typeof objCtor == 'function' && objCtor instanceof objCtor &&\n typeof othCtor == 'function' && othCtor instanceof othCtor)) {\n result = false;\n }\n }\n stack['delete'](object);\n stack['delete'](other);\n return result;\n}\n\nexport default equalObjects;\n","import Stack from './_Stack.js';\nimport equalArrays from './_equalArrays.js';\nimport equalByTag from './_equalByTag.js';\nimport equalObjects from './_equalObjects.js';\nimport getTag from './_getTag.js';\nimport isArray from './isArray.js';\nimport isBuffer from './isBuffer.js';\nimport isTypedArray from './isTypedArray.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n objectTag = '[object Object]';\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * A specialized version of `baseIsEqual` for arrays and objects which performs\n * deep comparisons and tracks traversed objects enabling objects with circular\n * references to be compared.\n *\n * @private\n * @param {Object} object The object to compare.\n * @param {Object} other The other object to compare.\n * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.\n * @param {Function} customizer The function to customize comparisons.\n * @param {Function} equalFunc The function to determine equivalents of values.\n * @param {Object} [stack] Tracks traversed `object` and `other` objects.\n * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.\n */\nfunction baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) {\n var objIsArr = isArray(object),\n othIsArr = isArray(other),\n objTag = objIsArr ? arrayTag : getTag(object),\n othTag = othIsArr ? arrayTag : getTag(other);\n\n objTag = objTag == argsTag ? objectTag : objTag;\n othTag = othTag == argsTag ? objectTag : othTag;\n\n var objIsObj = objTag == objectTag,\n othIsObj = othTag == objectTag,\n isSameTag = objTag == othTag;\n\n if (isSameTag && isBuffer(object)) {\n if (!isBuffer(other)) {\n return false;\n }\n objIsArr = true;\n objIsObj = false;\n }\n if (isSameTag && !objIsObj) {\n stack || (stack = new Stack);\n return (objIsArr || isTypedArray(object))\n ? equalArrays(object, other, bitmask, customizer, equalFunc, stack)\n : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack);\n }\n if (!(bitmask & COMPARE_PARTIAL_FLAG)) {\n var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'),\n othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__');\n\n if (objIsWrapped || othIsWrapped) {\n var objUnwrapped = objIsWrapped ? object.value() : object,\n othUnwrapped = othIsWrapped ? other.value() : other;\n\n stack || (stack = new Stack);\n return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack);\n }\n }\n if (!isSameTag) {\n return false;\n }\n stack || (stack = new Stack);\n return equalObjects(object, other, bitmask, customizer, equalFunc, stack);\n}\n\nexport default baseIsEqualDeep;\n","import baseIsEqualDeep from './_baseIsEqualDeep.js';\nimport isObjectLike from './isObjectLike.js';\n\n/**\n * The base implementation of `_.isEqual` which supports partial comparisons\n * and tracks traversed objects.\n *\n * @private\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @param {boolean} bitmask The bitmask flags.\n * 1 - Unordered comparison\n * 2 - Partial comparison\n * @param {Function} [customizer] The function to customize comparisons.\n * @param {Object} [stack] Tracks traversed `value` and `other` objects.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n */\nfunction baseIsEqual(value, other, bitmask, customizer, stack) {\n if (value === other) {\n return true;\n }\n if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) {\n return value !== value && other !== other;\n }\n return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack);\n}\n\nexport default baseIsEqual;\n","import Stack from './_Stack.js';\nimport baseIsEqual from './_baseIsEqual.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.isMatch` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to inspect.\n * @param {Object} source The object of property values to match.\n * @param {Array} matchData The property names, values, and compare flags to match.\n * @param {Function} [customizer] The function to customize comparisons.\n * @returns {boolean} Returns `true` if `object` is a match, else `false`.\n */\nfunction baseIsMatch(object, source, matchData, customizer) {\n var index = matchData.length,\n length = index,\n noCustomizer = !customizer;\n\n if (object == null) {\n return !length;\n }\n object = Object(object);\n while (index--) {\n var data = matchData[index];\n if ((noCustomizer && data[2])\n ? data[1] !== object[data[0]]\n : !(data[0] in object)\n ) {\n return false;\n }\n }\n while (++index < length) {\n data = matchData[index];\n var key = data[0],\n objValue = object[key],\n srcValue = data[1];\n\n if (noCustomizer && data[2]) {\n if (objValue === undefined && !(key in object)) {\n return false;\n }\n } else {\n var stack = new Stack;\n if (customizer) {\n var result = customizer(objValue, srcValue, key, object, source, stack);\n }\n if (!(result === undefined\n ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack)\n : result\n )) {\n return false;\n }\n }\n }\n return true;\n}\n\nexport default baseIsMatch;\n","import isObject from './isObject.js';\n\n/**\n * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` if suitable for strict\n * equality comparisons, else `false`.\n */\nfunction isStrictComparable(value) {\n return value === value && !isObject(value);\n}\n\nexport default isStrictComparable;\n","import isStrictComparable from './_isStrictComparable.js';\nimport keys from './keys.js';\n\n/**\n * Gets the property names, values, and compare flags of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the match data of `object`.\n */\nfunction getMatchData(object) {\n var result = keys(object),\n length = result.length;\n\n while (length--) {\n var key = result[length],\n value = object[key];\n\n result[length] = [key, value, isStrictComparable(value)];\n }\n return result;\n}\n\nexport default getMatchData;\n","/**\n * A specialized version of `matchesProperty` for source values suitable\n * for strict equality comparisons, i.e. `===`.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction matchesStrictComparable(key, srcValue) {\n return function(object) {\n if (object == null) {\n return false;\n }\n return object[key] === srcValue &&\n (srcValue !== undefined || (key in Object(object)));\n };\n}\n\nexport default matchesStrictComparable;\n","import baseIsMatch from './_baseIsMatch.js';\nimport getMatchData from './_getMatchData.js';\nimport matchesStrictComparable from './_matchesStrictComparable.js';\n\n/**\n * The base implementation of `_.matches` which doesn't clone `source`.\n *\n * @private\n * @param {Object} source The object of property values to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatches(source) {\n var matchData = getMatchData(source);\n if (matchData.length == 1 && matchData[0][2]) {\n return matchesStrictComparable(matchData[0][0], matchData[0][1]);\n }\n return function(object) {\n return object === source || baseIsMatch(object, source, matchData);\n };\n}\n\nexport default baseMatches;\n","/**\n * The base implementation of `_.hasIn` without support for deep paths.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHasIn(object, key) {\n return object != null && key in Object(object);\n}\n\nexport default baseHasIn;\n","import castPath from './_castPath.js';\nimport isArguments from './isArguments.js';\nimport isArray from './isArray.js';\nimport isIndex from './_isIndex.js';\nimport isLength from './isLength.js';\nimport toKey from './_toKey.js';\n\n/**\n * Checks if `path` exists on `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @param {Function} hasFunc The function to check properties.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n */\nfunction hasPath(object, path, hasFunc) {\n path = castPath(path, object);\n\n var index = -1,\n length = path.length,\n result = false;\n\n while (++index < length) {\n var key = toKey(path[index]);\n if (!(result = object != null && hasFunc(object, key))) {\n break;\n }\n object = object[key];\n }\n if (result || ++index != length) {\n return result;\n }\n length = object == null ? 0 : object.length;\n return !!length && isLength(length) && isIndex(key, length) &&\n (isArray(object) || isArguments(object));\n}\n\nexport default hasPath;\n","import baseHasIn from './_baseHasIn.js';\nimport hasPath from './_hasPath.js';\n\n/**\n * Checks if `path` is a direct or inherited property of `object`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path to check.\n * @returns {boolean} Returns `true` if `path` exists, else `false`.\n * @example\n *\n * var object = _.create({ 'a': _.create({ 'b': 2 }) });\n *\n * _.hasIn(object, 'a');\n * // => true\n *\n * _.hasIn(object, 'a.b');\n * // => true\n *\n * _.hasIn(object, ['a', 'b']);\n * // => true\n *\n * _.hasIn(object, 'b');\n * // => false\n */\nfunction hasIn(object, path) {\n return object != null && hasPath(object, path, baseHasIn);\n}\n\nexport default hasIn;\n","import baseIsEqual from './_baseIsEqual.js';\nimport get from './get.js';\nimport hasIn from './hasIn.js';\nimport isKey from './_isKey.js';\nimport isStrictComparable from './_isStrictComparable.js';\nimport matchesStrictComparable from './_matchesStrictComparable.js';\nimport toKey from './_toKey.js';\n\n/** Used to compose bitmasks for value comparisons. */\nvar COMPARE_PARTIAL_FLAG = 1,\n COMPARE_UNORDERED_FLAG = 2;\n\n/**\n * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.\n *\n * @private\n * @param {string} path The path of the property to get.\n * @param {*} srcValue The value to match.\n * @returns {Function} Returns the new spec function.\n */\nfunction baseMatchesProperty(path, srcValue) {\n if (isKey(path) && isStrictComparable(srcValue)) {\n return matchesStrictComparable(toKey(path), srcValue);\n }\n return function(object) {\n var objValue = get(object, path);\n return (objValue === undefined && objValue === srcValue)\n ? hasIn(object, path)\n : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG);\n };\n}\n\nexport default baseMatchesProperty;\n","/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\nexport default baseProperty;\n","import baseGet from './_baseGet.js';\n\n/**\n * A specialized version of `baseProperty` which supports deep paths.\n *\n * @private\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction basePropertyDeep(path) {\n return function(object) {\n return baseGet(object, path);\n };\n}\n\nexport default basePropertyDeep;\n","import baseProperty from './_baseProperty.js';\nimport basePropertyDeep from './_basePropertyDeep.js';\nimport isKey from './_isKey.js';\nimport toKey from './_toKey.js';\n\n/**\n * Creates a function that returns the value at `path` of a given object.\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Util\n * @param {Array|string} path The path of the property to get.\n * @returns {Function} Returns the new accessor function.\n * @example\n *\n * var objects = [\n * { 'a': { 'b': 2 } },\n * { 'a': { 'b': 1 } }\n * ];\n *\n * _.map(objects, _.property('a.b'));\n * // => [2, 1]\n *\n * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');\n * // => [1, 2]\n */\nfunction property(path) {\n return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path);\n}\n\nexport default property;\n","import baseMatches from './_baseMatches.js';\nimport baseMatchesProperty from './_baseMatchesProperty.js';\nimport identity from './identity.js';\nimport isArray from './isArray.js';\nimport property from './property.js';\n\n/**\n * The base implementation of `_.iteratee`.\n *\n * @private\n * @param {*} [value=_.identity] The value to convert to an iteratee.\n * @returns {Function} Returns the iteratee.\n */\nfunction baseIteratee(value) {\n // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.\n // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.\n if (typeof value == 'function') {\n return value;\n }\n if (value == null) {\n return identity;\n }\n if (typeof value == 'object') {\n return isArray(value)\n ? baseMatchesProperty(value[0], value[1])\n : baseMatches(value);\n }\n return property(value);\n}\n\nexport default baseIteratee;\n","import baseFor from './_baseFor.js';\nimport keys from './keys.js';\n\n/**\n * The base implementation of `_.forOwn` without support for iteratee shorthands.\n *\n * @private\n * @param {Object} object The object to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Object} Returns `object`.\n */\nfunction baseForOwn(object, iteratee) {\n return object && baseFor(object, iteratee, keys);\n}\n\nexport default baseForOwn;\n","import isArrayLike from './isArrayLike.js';\n\n/**\n * Creates a `baseEach` or `baseEachRight` function.\n *\n * @private\n * @param {Function} eachFunc The function to iterate over a collection.\n * @param {boolean} [fromRight] Specify iterating from right to left.\n * @returns {Function} Returns the new base function.\n */\nfunction createBaseEach(eachFunc, fromRight) {\n return function(collection, iteratee) {\n if (collection == null) {\n return collection;\n }\n if (!isArrayLike(collection)) {\n return eachFunc(collection, iteratee);\n }\n var length = collection.length,\n index = fromRight ? length : -1,\n iterable = Object(collection);\n\n while ((fromRight ? index-- : ++index < length)) {\n if (iteratee(iterable[index], index, iterable) === false) {\n break;\n }\n }\n return collection;\n };\n}\n\nexport default createBaseEach;\n","import baseForOwn from './_baseForOwn.js';\nimport createBaseEach from './_createBaseEach.js';\n\n/**\n * The base implementation of `_.forEach` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array|Object} Returns `collection`.\n */\nvar baseEach = createBaseEach(baseForOwn);\n\nexport default baseEach;\n","import identity from './identity.js';\n\n/**\n * Casts `value` to `identity` if it's not a function.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {Function} Returns cast function.\n */\nfunction castFunction(value) {\n return typeof value == 'function' ? value : identity;\n}\n\nexport default castFunction;\n","import arrayEach from './_arrayEach.js';\nimport baseEach from './_baseEach.js';\nimport castFunction from './_castFunction.js';\nimport isArray from './isArray.js';\n\n/**\n * Iterates over elements of `collection` and invokes `iteratee` for each element.\n * The iteratee is invoked with three arguments: (value, index|key, collection).\n * Iteratee functions may exit iteration early by explicitly returning `false`.\n *\n * **Note:** As with other \"Collections\" methods, objects with a \"length\"\n * property are iterated like arrays. To avoid this behavior use `_.forIn`\n * or `_.forOwn` for object iteration.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @alias each\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @returns {Array|Object} Returns `collection`.\n * @see _.forEachRight\n * @example\n *\n * _.forEach([1, 2], function(value) {\n * console.log(value);\n * });\n * // => Logs `1` then `2`.\n *\n * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {\n * console.log(key);\n * });\n * // => Logs 'a' then 'b' (iteration order is not guaranteed).\n */\nfunction forEach(collection, iteratee) {\n var func = isArray(collection) ? arrayEach : baseEach;\n return func(collection, castFunction(iteratee));\n}\n\nexport default forEach;\n","import baseEach from './_baseEach.js';\n\n/**\n * The base implementation of `_.filter` without support for iteratee shorthands.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} predicate The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n */\nfunction baseFilter(collection, predicate) {\n var result = [];\n baseEach(collection, function(value, index, collection) {\n if (predicate(value, index, collection)) {\n result.push(value);\n }\n });\n return result;\n}\n\nexport default baseFilter;\n","import arrayFilter from './_arrayFilter.js';\nimport baseFilter from './_baseFilter.js';\nimport baseIteratee from './_baseIteratee.js';\nimport isArray from './isArray.js';\n\n/**\n * Iterates over elements of `collection`, returning an array of all elements\n * `predicate` returns truthy for. The predicate is invoked with three\n * arguments: (value, index|key, collection).\n *\n * **Note:** Unlike `_.remove`, this method returns a new array.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [predicate=_.identity] The function invoked per iteration.\n * @returns {Array} Returns the new filtered array.\n * @see _.reject\n * @example\n *\n * var users = [\n * { 'user': 'barney', 'age': 36, 'active': true },\n * { 'user': 'fred', 'age': 40, 'active': false }\n * ];\n *\n * _.filter(users, function(o) { return !o.active; });\n * // => objects for ['fred']\n *\n * // The `_.matches` iteratee shorthand.\n * _.filter(users, { 'age': 36, 'active': true });\n * // => objects for ['barney']\n *\n * // The `_.matchesProperty` iteratee shorthand.\n * _.filter(users, ['active', false]);\n * // => objects for ['fred']\n *\n * // The `_.property` iteratee shorthand.\n * _.filter(users, 'active');\n * // => objects for ['barney']\n *\n * // Combining several predicates using `_.overEvery` or `_.overSome`.\n * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]]));\n * // => objects for ['fred', 'barney']\n */\nfunction filter(collection, predicate) {\n var func = isArray(collection) ? arrayFilter : baseFilter;\n return func(collection, baseIteratee(predicate, 3));\n}\n\nexport default filter;\n","import arrayMap from './_arrayMap.js';\n\n/**\n * The base implementation of `_.values` and `_.valuesIn` which creates an\n * array of `object` property values corresponding to the property names\n * of `props`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array} props The property names to get values for.\n * @returns {Object} Returns the array of property values.\n */\nfunction baseValues(object, props) {\n return arrayMap(props, function(key) {\n return object[key];\n });\n}\n\nexport default baseValues;\n","import baseValues from './_baseValues.js';\nimport keys from './keys.js';\n\n/**\n * Creates an array of the own enumerable string keyed property values of `object`.\n *\n * **Note:** Non-object values are coerced to objects.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property values.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.values(new Foo);\n * // => [1, 2] (iteration order is not guaranteed)\n *\n * _.values('hi');\n * // => ['h', 'i']\n */\nfunction values(object) {\n return object == null ? [] : baseValues(object, keys(object));\n}\n\nexport default values;\n","/**\n * Checks if `value` is `undefined`.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.\n * @example\n *\n * _.isUndefined(void 0);\n * // => true\n *\n * _.isUndefined(null);\n * // => false\n */\nfunction isUndefined(value) {\n return value === undefined;\n}\n\nexport default isUndefined;\n","/**\n * The base implementation of `_.reduce` and `_.reduceRight`, without support\n * for iteratee shorthands, which iterates over `collection` using `eachFunc`.\n *\n * @private\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} accumulator The initial value.\n * @param {boolean} initAccum Specify using the first or last element of\n * `collection` as the initial value.\n * @param {Function} eachFunc The function to iterate over `collection`.\n * @returns {*} Returns the accumulated value.\n */\nfunction baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) {\n eachFunc(collection, function(value, index, collection) {\n accumulator = initAccum\n ? (initAccum = false, value)\n : iteratee(accumulator, value, index, collection);\n });\n return accumulator;\n}\n\nexport default baseReduce;\n","import arrayReduce from './_arrayReduce.js';\nimport baseEach from './_baseEach.js';\nimport baseIteratee from './_baseIteratee.js';\nimport baseReduce from './_baseReduce.js';\nimport isArray from './isArray.js';\n\n/**\n * Reduces `collection` to a value which is the accumulated result of running\n * each element in `collection` thru `iteratee`, where each successive\n * invocation is supplied the return value of the previous. If `accumulator`\n * is not given, the first element of `collection` is used as the initial\n * value. The iteratee is invoked with four arguments:\n * (accumulator, value, index|key, collection).\n *\n * Many lodash methods are guarded to work as iteratees for methods like\n * `_.reduce`, `_.reduceRight`, and `_.transform`.\n *\n * The guarded methods are:\n * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,\n * and `sortBy`\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Collection\n * @param {Array|Object} collection The collection to iterate over.\n * @param {Function} [iteratee=_.identity] The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @returns {*} Returns the accumulated value.\n * @see _.reduceRight\n * @example\n *\n * _.reduce([1, 2], function(sum, n) {\n * return sum + n;\n * }, 0);\n * // => 3\n *\n * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {\n * (result[value] || (result[value] = [])).push(key);\n * return result;\n * }, {});\n * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)\n */\nfunction reduce(collection, iteratee, accumulator) {\n var func = isArray(collection) ? arrayReduce : baseReduce,\n initAccum = arguments.length < 3;\n\n return func(collection, baseIteratee(iteratee, 4), accumulator, initAccum, baseEach);\n}\n\nexport default reduce;\n","import Set from './_Set.js';\nimport noop from './noop.js';\nimport setToArray from './_setToArray.js';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Creates a set object of `values`.\n *\n * @private\n * @param {Array} values The values to add to the set.\n * @returns {Object} Returns the new set.\n */\nvar createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) {\n return new Set(values);\n};\n\nexport default createSet;\n","import SetCache from './_SetCache.js';\nimport arrayIncludes from './_arrayIncludes.js';\nimport arrayIncludesWith from './_arrayIncludesWith.js';\nimport cacheHas from './_cacheHas.js';\nimport createSet from './_createSet.js';\nimport setToArray from './_setToArray.js';\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/**\n * The base implementation of `_.uniqBy` without support for iteratee shorthands.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {Function} [iteratee] The iteratee invoked per element.\n * @param {Function} [comparator] The comparator invoked per element.\n * @returns {Array} Returns the new duplicate free array.\n */\nfunction baseUniq(array, iteratee, comparator) {\n var index = -1,\n includes = arrayIncludes,\n length = array.length,\n isCommon = true,\n result = [],\n seen = result;\n\n if (comparator) {\n isCommon = false;\n includes = arrayIncludesWith;\n }\n else if (length >= LARGE_ARRAY_SIZE) {\n var set = iteratee ? null : createSet(array);\n if (set) {\n return setToArray(set);\n }\n isCommon = false;\n includes = cacheHas;\n seen = new SetCache;\n }\n else {\n seen = iteratee ? [] : result;\n }\n outer:\n while (++index < length) {\n var value = array[index],\n computed = iteratee ? iteratee(value) : value;\n\n value = (comparator || value !== 0) ? value : 0;\n if (isCommon && computed === computed) {\n var seenIndex = seen.length;\n while (seenIndex--) {\n if (seen[seenIndex] === computed) {\n continue outer;\n }\n }\n if (iteratee) {\n seen.push(computed);\n }\n result.push(value);\n }\n else if (!includes(seen, computed, comparator)) {\n if (seen !== result) {\n seen.push(computed);\n }\n result.push(value);\n }\n }\n return result;\n}\n\nexport default baseUniq;\n"],"names":["symbolTag","isSymbol","value","isObjectLike","baseGetTag","arrayMap","array","iteratee","index","length","result","symbolProto","Symbol","symbolToString","baseToString","isArray","noop","arrayEach","baseFindIndex","predicate","fromIndex","fromRight","baseIsNaN","strictIndexOf","baseIndexOf","arrayIncludes","keys","object","isArrayLike","arrayLikeKeys","baseKeys","reIsDeepProp","reIsPlainProp","isKey","type","MAX_MEMOIZE_SIZE","memoizeCapped","func","memoize","key","cache","rePropName","reEscapeChar","stringToPath","string","match","number","quote","subString","toString","castPath","toKey","baseGet","path","get","defaultValue","arrayPush","values","offset","spreadableSymbol","isFlattenable","isArguments","baseFlatten","depth","isStrict","arrayReduce","accumulator","initAccum","baseAssign","source","copyObject","baseAssignIn","keysIn","arrayFilter","resIndex","stubArray","objectProto","propertyIsEnumerable","nativeGetSymbols","getSymbols","symbol","copySymbols","getSymbolsIn","getPrototype","copySymbolsIn","baseGetAllKeys","keysFunc","symbolsFunc","getAllKeys","getAllKeysIn","hasOwnProperty","initCloneArray","cloneDataView","dataView","isDeep","buffer","cloneArrayBuffer","reFlags","cloneRegExp","regexp","symbolValueOf","cloneSymbol","boolTag","dateTag","mapTag","numberTag","regexpTag","setTag","stringTag","arrayBufferTag","dataViewTag","float32Tag","float64Tag","int8Tag","int16Tag","int32Tag","uint8Tag","uint8ClampedTag","uint16Tag","uint32Tag","initCloneByTag","tag","Ctor","cloneTypedArray","baseIsMap","getTag","nodeIsMap","nodeUtil","isMap","baseUnary","baseIsSet","nodeIsSet","isSet","CLONE_DEEP_FLAG","CLONE_FLAT_FLAG","CLONE_SYMBOLS_FLAG","argsTag","arrayTag","errorTag","funcTag","genTag","objectTag","weakMapTag","cloneableTags","baseClone","bitmask","customizer","stack","isFlat","isFull","isObject","isArr","copyArray","isFunc","isBuffer","cloneBuffer","initCloneObject","Stack","stacked","subValue","props","assignValue","HASH_UNDEFINED","setCacheAdd","setCacheHas","SetCache","MapCache","arraySome","cacheHas","COMPARE_PARTIAL_FLAG","COMPARE_UNORDERED_FLAG","equalArrays","other","equalFunc","isPartial","arrLength","othLength","arrStacked","othStacked","seen","arrValue","othValue","compared","othIndex","mapToArray","map","setToArray","set","equalByTag","Uint8Array","eq","convert","equalObjects","objProps","objLength","othProps","objStacked","skipCtor","objValue","objCtor","othCtor","baseIsEqualDeep","objIsArr","othIsArr","objTag","othTag","objIsObj","othIsObj","isSameTag","isTypedArray","objIsWrapped","othIsWrapped","objUnwrapped","othUnwrapped","baseIsEqual","baseIsMatch","matchData","data","srcValue","isStrictComparable","getMatchData","matchesStrictComparable","baseMatches","baseHasIn","hasPath","hasFunc","isLength","isIndex","hasIn","baseMatchesProperty","baseProperty","basePropertyDeep","property","baseIteratee","identity","baseForOwn","baseFor","createBaseEach","eachFunc","collection","iterable","baseEach","castFunction","forEach","baseFilter","filter","baseValues","isUndefined","baseReduce","reduce","INFINITY","createSet","Set","LARGE_ARRAY_SIZE","baseUniq","comparator","includes","isCommon","outer","computed","seenIndex"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82]}
\ No newline at end of file
diff --git a/extensions/continue/gui/assets/arc.js b/extensions/continue/gui/assets/arc.js
new file mode 100644
index 000000000000..99465de870e7
--- /dev/null
+++ b/extensions/continue/gui/assets/arc.js
@@ -0,0 +1,2 @@
+import{a0 as fn,a1 as an,a2 as y,a3 as ln,a4 as z,a5 as E,a6 as _,a7 as un,a8 as O,a9 as rn,aa as F,ab as o,ac as sn,ad as on,ae as tn}from"./index.js";(function(){try{var u=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{};u.SENTRY_RELEASE={id:"89d47079907d2835afe9a9922c276dbc3fbbe92f"}}catch{}})();try{(function(){var u=typeof window<"u"?window:typeof global<"u"?global:typeof globalThis<"u"?globalThis:typeof self<"u"?self:{},t=new u.Error().stack;t&&(u._sentryDebugIds=u._sentryDebugIds||{},u._sentryDebugIds[t]="c3a85544-aad0-44bd-8148-f6ad0f7d4912",u._sentryDebugIdIdentifier="sentry-dbid-c3a85544-aad0-44bd-8148-f6ad0f7d4912")})()}catch{}function dn(u){return u.innerRadius}function cn(u){return u.outerRadius}function yn(u){return u.startAngle}function gn(u){return u.endAngle}function pn(u){return u&&u.padAngle}function hn(u,t,P,I,v,b,Y,a){var S=P-u,s=I-t,n=Y-v,p=a-b,i=p*S-n*s;if(!(i*iT&&(c=T),h>d&&(h=d)}return c==l.MAX_VALUE?null:(L[0].getParent().paddingLeft!=null?v=L[0].getParent().paddingLeft:v=this.margin,this.left=h-v,this.top=c-v,new g(this.left,this.top))},s.prototype.updateBounds=function(c){for(var h=l.MAX_VALUE,T=-l.MAX_VALUE,d=l.MAX_VALUE,v=-l.MAX_VALUE,L,S,C,G,K,X=this.nodes,Q=X.length,O=0;OL&&(h=L),T
C&&(d=C),vC&&(d=C),vt)return r[0]=f,r[1]=o,r[2]=g,r[3]=X,!1;if(i0&&c.set("dummy"+(c.size+1),K),X},g.relocateComponent=function(t,s,o){if(!o.fixedNodeConstraint){var c=Number.POSITIVE_INFINITY,h=Number.NEGATIVE_INFINITY,T=Number.POSITIVE_INFINITY,d=Number.NEGATIVE_INFINITY;if(o.quality=="draft"){var v=!0,L=!1,S=void 0;try{for(var C=s.nodeIndexes[Symbol.iterator](),G;!(v=(G=C.next()).done);v=!0){var K=G.value,X=f(K,2),Q=X[0],O=X[1],rt=o.cy.getElementById(Q);if(rt){var n=rt.boundingBox(),m=s.xCoords[O]-n.w/2,p=s.xCoords[O]+n.w/2,E=s.yCoords[O]-n.h/2,y=s.yCoords[O]+n.h/2;mC&&(d=C),v
"),m.debug("vertexText"+l);const r=await Le(yt(l)),n={isNode:i,label:r,labelStyle:t.replace("fill:","color:")};return qt(n,s)}else{const r=document.createElementNS("http://www.w3.org/2000/svg","text");r.setAttribute("style",t.replace("color:","fill:"));let n=[];typeof l=="string"?n=l.split(/\\n|\n|
/gi):Array.isArray(l)?n=l:n=[];for(const o of n){const u=document.createElementNS("http://www.w3.org/2000/svg","tspan");u.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),u.setAttribute("dy","1em"),u.setAttribute("x","0"),a?u.setAttribute("class","title-row"):u.setAttribute("class","row"),u.textContent=o.trim(),r.appendChild(u)}return r}},"createLabel"),j=lr,cr=d((e,t,a,i,l)=>{t.arrowTypeStart&&Rt(e,"start",t.arrowTypeStart,a,i,l),t.arrowTypeEnd&&Rt(e,"end",t.arrowTypeEnd,a,i,l)},"addEdgeMarkers"),or={arrow_cross:"cross",arrow_point:"point",arrow_barb:"barb",arrow_circle:"circle",aggregation:"aggregation",extension:"extension",composition:"composition",dependency:"dependency",lollipop:"lollipop"},Rt=d((e,t,a,i,l,s)=>{const r=or[a];if(!r){m.warn(`Unknown arrow type: ${a}`);return}const n=t==="start"?"Start":"End";e.attr(`marker-${t}`,`url(${i}#${l}_${s}-${r}${n})`)},"addEdgeMarker"),St={},W={},hr=d(async(e,t)=>{const a=z(),i=Z(a.flowchart.htmlLabels),l=t.labelType==="markdown"?Ht(e,t.label,{style:t.labelStyle,useHtmlLabels:i,addSvgBackground:!0},a):await j(t.label,t.labelStyle),s=e.insert("g").attr("class","edgeLabel"),r=s.insert("g").attr("class","label");r.node().appendChild(l);let n=l.getBBox();if(i){const u=l.children[0],h=R(l);n=u.getBoundingClientRect(),h.attr("width",n.width),h.attr("height",n.height)}r.attr("transform","translate("+-n.width/2+", "+-n.height/2+")"),St[t.id]=s,t.width=n.width,t.height=n.height;let o;if(t.startLabelLeft){const u=await j(t.startLabelLeft,t.labelStyle),h=e.insert("g").attr("class","edgeTerminals"),y=h.insert("g").attr("class","inner");o=y.node().appendChild(u);const b=u.getBBox();y.attr("transform","translate("+-b.width/2+", "+-b.height/2+")"),W[t.id]||(W[t.id]={}),W[t.id].startLeft=h,rt(o,t.startLabelLeft)}if(t.startLabelRight){const u=await j(t.startLabelRight,t.labelStyle),h=e.insert("g").attr("class","edgeTerminals"),y=h.insert("g").attr("class","inner");o=h.node().appendChild(u),y.node().appendChild(u);const b=u.getBBox();y.attr("transform","translate("+-b.width/2+", "+-b.height/2+")"),W[t.id]||(W[t.id]={}),W[t.id].startRight=h,rt(o,t.startLabelRight)}if(t.endLabelLeft){const u=await j(t.endLabelLeft,t.labelStyle),h=e.insert("g").attr("class","edgeTerminals"),y=h.insert("g").attr("class","inner");o=y.node().appendChild(u);const b=u.getBBox();y.attr("transform","translate("+-b.width/2+", "+-b.height/2+")"),h.node().appendChild(u),W[t.id]||(W[t.id]={}),W[t.id].endLeft=h,rt(o,t.endLabelLeft)}if(t.endLabelRight){const u=await j(t.endLabelRight,t.labelStyle),h=e.insert("g").attr("class","edgeTerminals"),y=h.insert("g").attr("class","inner");o=y.node().appendChild(u);const b=u.getBBox();y.attr("transform","translate("+-b.width/2+", "+-b.height/2+")"),h.node().appendChild(u),W[t.id]||(W[t.id]={}),W[t.id].endRight=h,rt(o,t.endLabelRight)}return l},"insertEdgeLabel");function rt(e,t){z().flowchart.htmlLabels&&e&&(e.style.width=t.length*9+"px",e.style.height="12px")}d(rt,"setTerminalWidth");var dr=d((e,t)=>{m.debug("Moving label abc88 ",e.id,e.label,St[e.id],t);let a=t.updatedPath?t.updatedPath:t.originalPath;const i=z(),{subGraphTitleTotalMargin:l}=we(i);if(e.label){const s=St[e.id];let r=e.x,n=e.y;if(a){const o=et.calcLabelPosition(a);m.debug("Moving label "+e.label+" from (",r,",",n,") to (",o.x,",",o.y,") abc88"),t.updatedPath&&(r=o.x,n=o.y)}s.attr("transform",`translate(${r}, ${n+l/2})`)}if(e.startLabelLeft){const s=W[e.id].startLeft;let r=e.x,n=e.y;if(a){const o=et.calcTerminalLabelPosition(e.arrowTypeStart?10:0,"start_left",a);r=o.x,n=o.y}s.attr("transform",`translate(${r}, ${n})`)}if(e.startLabelRight){const s=W[e.id].startRight;let r=e.x,n=e.y;if(a){const o=et.calcTerminalLabelPosition(e.arrowTypeStart?10:0,"start_right",a);r=o.x,n=o.y}s.attr("transform",`translate(${r}, ${n})`)}if(e.endLabelLeft){const s=W[e.id].endLeft;let r=e.x,n=e.y;if(a){const o=et.calcTerminalLabelPosition(e.arrowTypeEnd?10:0,"end_left",a);r=o.x,n=o.y}s.attr("transform",`translate(${r}, ${n})`)}if(e.endLabelRight){const s=W[e.id].endRight;let r=e.x,n=e.y;if(a){const o=et.calcTerminalLabelPosition(e.arrowTypeEnd?10:0,"end_right",a);r=o.x,n=o.y}s.attr("transform",`translate(${r}, ${n})`)}},"positionEdgeLabel"),gr=d((e,t)=>{const a=e.x,i=e.y,l=Math.abs(t.x-a),s=Math.abs(t.y-i),r=e.width/2,n=e.height/2;return l>=r||s>=n},"outsideNode"),ur=d((e,t,a)=>{m.debug(`intersection calc abc89:
+ outsidePoint: ${JSON.stringify(t)}
+ insidePoint : ${JSON.stringify(a)}
+ node : x:${e.x} y:${e.y} w:${e.width} h:${e.height}`);const i=e.x,l=e.y,s=Math.abs(i-a.x),r=e.width/2;let n=a.x]*>/g,"").trim()==="";await Promise.all([...v].map(k=>new Promise(T=>{function x(){if(k.style.display="flex",k.style.flexDirection="column",N){const g=l.fontSize?l.fontSize:window.getComputedStyle(document.body).fontSize,w=parseInt(g,10)*5+"px";k.style.minWidth=w,k.style.maxWidth=w}else k.style.width="100%";T(k)}d(x,"setupImage"),setTimeout(()=>{k.complete&&x()}),k.addEventListener("error",x),k.addEventListener("load",x)})))}b=E.getBoundingClientRect(),D.attr("width",b.width),D.attr("height",b.height)}return r?o.attr("transform","translate("+-b.width/2+", "+-b.height/2+")"):o.attr("transform","translate(0, "+-b.height/2+")"),t.centerLabel&&o.attr("transform","translate("+-b.width/2+", "+-b.height/2+")"),o.insert("rect",":first-child"),{shapeSvg:n,bbox:b,halfPadding:L,label:o}},"labelHelper"),I=d((e,t)=>{const a=t.node().getBBox();e.width=a.width,e.height=a.height},"updateNodeBounds");function G(e,t,a,i){return e.insert("polygon",":first-child").attr("points",i.map(function(l){return l.x+","+l.y}).join(" ")).attr("class","label-container").attr("transform","translate("+-t/2+","+a/2+")")}d(G,"insertPolygonShape");var vr=d(async(e,t)=>{t.useHtmlLabels||z().flowchart.htmlLabels||(t.centerLabel=!0);const{shapeSvg:i,bbox:l,halfPadding:s}=await F(e,t,"node "+t.classes,!0);m.info("Classes = ",t.classes);const r=i.insert("rect",":first-child");return r.attr("rx",t.rx).attr("ry",t.ry).attr("x",-l.width/2-s).attr("y",-l.height/2-s).attr("width",l.width+t.padding).attr("height",l.height+t.padding),I(t,r),t.intersect=function(n){return C.rect(t,n)},i},"note"),Er=vr,At=d(e=>e?" "+e:"","formatClass"),K=d((e,t)=>`${t||"node default"}${At(e.classes)} ${At(e.class)}`,"getClassesFromNode"),Mt=d(async(e,t)=>{const{shapeSvg:a,bbox:i}=await F(e,t,K(t,void 0),!0),l=i.width+t.padding,s=i.height+t.padding,r=l+s,n=[{x:r/2,y:0},{x:r,y:-r/2},{x:r/2,y:-r},{x:0,y:-r/2}];m.info("Question main (Circle)");const o=G(a,r,r,n);return o.attr("style",t.style),I(t,o),t.intersect=function(u){return m.warn("Intersect called"),C.polygon(t,n,u)},a},"question"),_r=d((e,t)=>{const a=e.insert("g").attr("class","node default").attr("id",t.domId||t.id),i=28,l=[{x:0,y:i/2},{x:i/2,y:0},{x:0,y:-i/2},{x:-i/2,y:0}];return a.insert("polygon",":first-child").attr("points",l.map(function(r){return r.x+","+r.y}).join(" ")).attr("class","state-start").attr("r",7).attr("width",28).attr("height",28),t.width=28,t.height=28,t.intersect=function(r){return C.circle(t,14,r)},a},"choice"),kr=d(async(e,t)=>{const{shapeSvg:a,bbox:i}=await F(e,t,K(t,void 0),!0),l=4,s=i.height+t.padding,r=s/l,n=i.width+2*r+t.padding,o=[{x:r,y:0},{x:n-r,y:0},{x:n,y:-s/2},{x:n-r,y:-s},{x:r,y:-s},{x:0,y:-s/2}],u=G(a,n,s,o);return u.attr("style",t.style),I(t,u),t.intersect=function(h){return C.polygon(t,o,h)},a},"hexagon"),Dr=d(async(e,t)=>{const{shapeSvg:a,bbox:i}=await F(e,t,void 0,!0),l=2,s=i.height+2*t.padding,r=s/l,n=i.width+2*r+t.padding,o=xr(t.directions,i,t),u=G(a,n,s,o);return u.attr("style",t.style),I(t,u),t.intersect=function(h){return C.polygon(t,o,h)},a},"block_arrow"),Tr=d(async(e,t)=>{const{shapeSvg:a,bbox:i}=await F(e,t,K(t,void 0),!0),l=i.width+t.padding,s=i.height+t.padding,r=[{x:-s/2,y:0},{x:l,y:0},{x:l,y:-s},{x:-s/2,y:-s},{x:0,y:-s/2}];return G(a,l,s,r).attr("style",t.style),t.width=l+s,t.height=s,t.intersect=function(o){return C.polygon(t,r,o)},a},"rect_left_inv_arrow"),Nr=d(async(e,t)=>{const{shapeSvg:a,bbox:i}=await F(e,t,K(t),!0),l=i.width+t.padding,s=i.height+t.padding,r=[{x:-2*s/6,y:0},{x:l-s/6,y:0},{x:l+2*s/6,y:-s},{x:s/6,y:-s}],n=G(a,l,s,r);return n.attr("style",t.style),I(t,n),t.intersect=function(o){return C.polygon(t,r,o)},a},"lean_right"),Cr=d(async(e,t)=>{const{shapeSvg:a,bbox:i}=await F(e,t,K(t,void 0),!0),l=i.width+t.padding,s=i.height+t.padding,r=[{x:2*s/6,y:0},{x:l+s/6,y:0},{x:l-2*s/6,y:-s},{x:-s/6,y:-s}],n=G(a,l,s,r);return n.attr("style",t.style),I(t,n),t.intersect=function(o){return C.polygon(t,r,o)},a},"lean_left"),Ir=d(async(e,t)=>{const{shapeSvg:a,bbox:i}=await F(e,t,K(t,void 0),!0),l=i.width+t.padding,s=i.height+t.padding,r=[{x:-2*s/6,y:0},{x:l+2*s/6,y:0},{x:l-s/6,y:-s},{x:s/6,y:-s}],n=G(a,l,s,r);return n.attr("style",t.style),I(t,n),t.intersect=function(o){return C.polygon(t,r,o)},a},"trapezoid"),Br=d(async(e,t)=>{const{shapeSvg:a,bbox:i}=await F(e,t,K(t,void 0),!0),l=i.width+t.padding,s=i.height+t.padding,r=[{x:s/6,y:0},{x:l-s/6,y:0},{x:l+2*s/6,y:-s},{x:-2*s/6,y:-s}],n=G(a,l,s,r);return n.attr("style",t.style),I(t,n),t.intersect=function(o){return C.polygon(t,r,o)},a},"inv_trapezoid"),Or=d(async(e,t)=>{const{shapeSvg:a,bbox:i}=await F(e,t,K(t,void 0),!0),l=i.width+t.padding,s=i.height+t.padding,r=[{x:0,y:0},{x:l+s/2,y:0},{x:l,y:-s/2},{x:l+s/2,y:-s},{x:0,y:-s}],n=G(a,l,s,r);return n.attr("style",t.style),I(t,n),t.intersect=function(o){return C.polygon(t,r,o)},a},"rect_right_inv_arrow"),Rr=d(async(e,t)=>{const{shapeSvg:a,bbox:i}=await F(e,t,K(t,void 0),!0),l=i.width+t.padding,s=l/2,r=s/(2.5+l/50),n=i.height+r+t.padding,o="M 0,"+r+" a "+s+","+r+" 0,0,0 "+l+" 0 a "+s+","+r+" 0,0,0 "+-l+" 0 l 0,"+n+" a "+s+","+r+" 0,0,0 "+l+" 0 l 0,"+-n,u=a.attr("label-offset-y",r).insert("path",":first-child").attr("style",t.style).attr("d",o).attr("transform","translate("+-l/2+","+-(n/2+r)+")");return I(t,u),t.intersect=function(h){const y=C.rect(t,h),b=y.x-t.x;if(s!=0&&(Math.abs(b)
"):y,t.labelStyle,!0,!0));if(Z(z().flowchart.htmlLabels)){const D=L.children[0],v=R(L);h=D.getBoundingClientRect(),v.attr("width",h.width),v.attr("height",h.height)}const E=t.padding/2;return R(L).attr("transform","translate( "+(h.width>b.width?0:(b.width-h.width)/2)+", "+(b.height+E+5)+")"),R(u).attr("transform","translate( "+(h.width
\");\n log.debug(\"vertexText\" + vertexText);\n const label = await replaceIconSubstring(decodeEntities(vertexText));\n const node = {\n isNode,\n label,\n labelStyle: style.replace(\"fill:\", \"color:\")\n };\n let vertexNode = addHtmlLabel(node, config2);\n return vertexNode;\n } else {\n const svgLabel = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\");\n svgLabel.setAttribute(\"style\", style.replace(\"color:\", \"fill:\"));\n let rows = [];\n if (typeof vertexText === \"string\") {\n rows = vertexText.split(/\\\\n|\\n|
/gi);\n } else if (Array.isArray(vertexText)) {\n rows = vertexText;\n } else {\n rows = [];\n }\n for (const row of rows) {\n const tspan = document.createElementNS(\"http://www.w3.org/2000/svg\", \"tspan\");\n tspan.setAttributeNS(\"http://www.w3.org/XML/1998/namespace\", \"xml:space\", \"preserve\");\n tspan.setAttribute(\"dy\", \"1em\");\n tspan.setAttribute(\"x\", \"0\");\n if (isTitle) {\n tspan.setAttribute(\"class\", \"title-row\");\n } else {\n tspan.setAttribute(\"class\", \"row\");\n }\n tspan.textContent = row.trim();\n svgLabel.appendChild(tspan);\n }\n return svgLabel;\n }\n}, \"createLabel\");\nvar createLabel_default = createLabel;\n\n// src/dagre-wrapper/edges.js\nimport { line, curveBasis, select as select2 } from \"d3\";\n\n// src/dagre-wrapper/edgeMarker.ts\nvar addEdgeMarkers = /* @__PURE__ */ __name((svgPath, edge, url, id, diagramType) => {\n if (edge.arrowTypeStart) {\n addEdgeMarker(svgPath, \"start\", edge.arrowTypeStart, url, id, diagramType);\n }\n if (edge.arrowTypeEnd) {\n addEdgeMarker(svgPath, \"end\", edge.arrowTypeEnd, url, id, diagramType);\n }\n}, \"addEdgeMarkers\");\nvar arrowTypesMap = {\n arrow_cross: \"cross\",\n arrow_point: \"point\",\n arrow_barb: \"barb\",\n arrow_circle: \"circle\",\n aggregation: \"aggregation\",\n extension: \"extension\",\n composition: \"composition\",\n dependency: \"dependency\",\n lollipop: \"lollipop\"\n};\nvar addEdgeMarker = /* @__PURE__ */ __name((svgPath, position, arrowType, url, id, diagramType) => {\n const endMarkerType = arrowTypesMap[arrowType];\n if (!endMarkerType) {\n log.warn(`Unknown arrow type: ${arrowType}`);\n return;\n }\n const suffix = position === \"start\" ? \"Start\" : \"End\";\n svgPath.attr(`marker-${position}`, `url(${url}#${id}_${diagramType}-${endMarkerType}${suffix})`);\n}, \"addEdgeMarker\");\n\n// src/dagre-wrapper/edges.js\nvar edgeLabels = {};\nvar terminalLabels = {};\nvar insertEdgeLabel = /* @__PURE__ */ __name(async (elem, edge) => {\n const config2 = getConfig2();\n const useHtmlLabels = evaluate(config2.flowchart.htmlLabels);\n const labelElement = edge.labelType === \"markdown\" ? createText(\n elem,\n edge.label,\n {\n style: edge.labelStyle,\n useHtmlLabels,\n addSvgBackground: true\n },\n config2\n ) : await createLabel_default(edge.label, edge.labelStyle);\n const edgeLabel = elem.insert(\"g\").attr(\"class\", \"edgeLabel\");\n const label = edgeLabel.insert(\"g\").attr(\"class\", \"label\");\n label.node().appendChild(labelElement);\n let bbox = labelElement.getBBox();\n if (useHtmlLabels) {\n const div = labelElement.children[0];\n const dv = select2(labelElement);\n bbox = div.getBoundingClientRect();\n dv.attr(\"width\", bbox.width);\n dv.attr(\"height\", bbox.height);\n }\n label.attr(\"transform\", \"translate(\" + -bbox.width / 2 + \", \" + -bbox.height / 2 + \")\");\n edgeLabels[edge.id] = edgeLabel;\n edge.width = bbox.width;\n edge.height = bbox.height;\n let fo;\n if (edge.startLabelLeft) {\n const startLabelElement = await createLabel_default(edge.startLabelLeft, edge.labelStyle);\n const startEdgeLabelLeft = elem.insert(\"g\").attr(\"class\", \"edgeTerminals\");\n const inner = startEdgeLabelLeft.insert(\"g\").attr(\"class\", \"inner\");\n fo = inner.node().appendChild(startLabelElement);\n const slBox = startLabelElement.getBBox();\n inner.attr(\"transform\", \"translate(\" + -slBox.width / 2 + \", \" + -slBox.height / 2 + \")\");\n if (!terminalLabels[edge.id]) {\n terminalLabels[edge.id] = {};\n }\n terminalLabels[edge.id].startLeft = startEdgeLabelLeft;\n setTerminalWidth(fo, edge.startLabelLeft);\n }\n if (edge.startLabelRight) {\n const startLabelElement = await createLabel_default(edge.startLabelRight, edge.labelStyle);\n const startEdgeLabelRight = elem.insert(\"g\").attr(\"class\", \"edgeTerminals\");\n const inner = startEdgeLabelRight.insert(\"g\").attr(\"class\", \"inner\");\n fo = startEdgeLabelRight.node().appendChild(startLabelElement);\n inner.node().appendChild(startLabelElement);\n const slBox = startLabelElement.getBBox();\n inner.attr(\"transform\", \"translate(\" + -slBox.width / 2 + \", \" + -slBox.height / 2 + \")\");\n if (!terminalLabels[edge.id]) {\n terminalLabels[edge.id] = {};\n }\n terminalLabels[edge.id].startRight = startEdgeLabelRight;\n setTerminalWidth(fo, edge.startLabelRight);\n }\n if (edge.endLabelLeft) {\n const endLabelElement = await createLabel_default(edge.endLabelLeft, edge.labelStyle);\n const endEdgeLabelLeft = elem.insert(\"g\").attr(\"class\", \"edgeTerminals\");\n const inner = endEdgeLabelLeft.insert(\"g\").attr(\"class\", \"inner\");\n fo = inner.node().appendChild(endLabelElement);\n const slBox = endLabelElement.getBBox();\n inner.attr(\"transform\", \"translate(\" + -slBox.width / 2 + \", \" + -slBox.height / 2 + \")\");\n endEdgeLabelLeft.node().appendChild(endLabelElement);\n if (!terminalLabels[edge.id]) {\n terminalLabels[edge.id] = {};\n }\n terminalLabels[edge.id].endLeft = endEdgeLabelLeft;\n setTerminalWidth(fo, edge.endLabelLeft);\n }\n if (edge.endLabelRight) {\n const endLabelElement = await createLabel_default(edge.endLabelRight, edge.labelStyle);\n const endEdgeLabelRight = elem.insert(\"g\").attr(\"class\", \"edgeTerminals\");\n const inner = endEdgeLabelRight.insert(\"g\").attr(\"class\", \"inner\");\n fo = inner.node().appendChild(endLabelElement);\n const slBox = endLabelElement.getBBox();\n inner.attr(\"transform\", \"translate(\" + -slBox.width / 2 + \", \" + -slBox.height / 2 + \")\");\n endEdgeLabelRight.node().appendChild(endLabelElement);\n if (!terminalLabels[edge.id]) {\n terminalLabels[edge.id] = {};\n }\n terminalLabels[edge.id].endRight = endEdgeLabelRight;\n setTerminalWidth(fo, edge.endLabelRight);\n }\n return labelElement;\n}, \"insertEdgeLabel\");\nfunction setTerminalWidth(fo, value) {\n if (getConfig2().flowchart.htmlLabels && fo) {\n fo.style.width = value.length * 9 + \"px\";\n fo.style.height = \"12px\";\n }\n}\n__name(setTerminalWidth, \"setTerminalWidth\");\nvar positionEdgeLabel = /* @__PURE__ */ __name((edge, paths) => {\n log.debug(\"Moving label abc88 \", edge.id, edge.label, edgeLabels[edge.id], paths);\n let path = paths.updatedPath ? paths.updatedPath : paths.originalPath;\n const siteConfig = getConfig2();\n const { subGraphTitleTotalMargin } = getSubGraphTitleMargins(siteConfig);\n if (edge.label) {\n const el = edgeLabels[edge.id];\n let x = edge.x;\n let y = edge.y;\n if (path) {\n const pos = utils_default.calcLabelPosition(path);\n log.debug(\n \"Moving label \" + edge.label + \" from (\",\n x,\n \",\",\n y,\n \") to (\",\n pos.x,\n \",\",\n pos.y,\n \") abc88\"\n );\n if (paths.updatedPath) {\n x = pos.x;\n y = pos.y;\n }\n }\n el.attr(\"transform\", `translate(${x}, ${y + subGraphTitleTotalMargin / 2})`);\n }\n if (edge.startLabelLeft) {\n const el = terminalLabels[edge.id].startLeft;\n let x = edge.x;\n let y = edge.y;\n if (path) {\n const pos = utils_default.calcTerminalLabelPosition(edge.arrowTypeStart ? 10 : 0, \"start_left\", path);\n x = pos.x;\n y = pos.y;\n }\n el.attr(\"transform\", `translate(${x}, ${y})`);\n }\n if (edge.startLabelRight) {\n const el = terminalLabels[edge.id].startRight;\n let x = edge.x;\n let y = edge.y;\n if (path) {\n const pos = utils_default.calcTerminalLabelPosition(\n edge.arrowTypeStart ? 10 : 0,\n \"start_right\",\n path\n );\n x = pos.x;\n y = pos.y;\n }\n el.attr(\"transform\", `translate(${x}, ${y})`);\n }\n if (edge.endLabelLeft) {\n const el = terminalLabels[edge.id].endLeft;\n let x = edge.x;\n let y = edge.y;\n if (path) {\n const pos = utils_default.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, \"end_left\", path);\n x = pos.x;\n y = pos.y;\n }\n el.attr(\"transform\", `translate(${x}, ${y})`);\n }\n if (edge.endLabelRight) {\n const el = terminalLabels[edge.id].endRight;\n let x = edge.x;\n let y = edge.y;\n if (path) {\n const pos = utils_default.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, \"end_right\", path);\n x = pos.x;\n y = pos.y;\n }\n el.attr(\"transform\", `translate(${x}, ${y})`);\n }\n}, \"positionEdgeLabel\");\nvar outsideNode = /* @__PURE__ */ __name((node, point2) => {\n const x = node.x;\n const y = node.y;\n const dx = Math.abs(point2.x - x);\n const dy = Math.abs(point2.y - y);\n const w = node.width / 2;\n const h = node.height / 2;\n if (dx >= w || dy >= h) {\n return true;\n }\n return false;\n}, \"outsideNode\");\nvar intersection = /* @__PURE__ */ __name((node, outsidePoint, insidePoint) => {\n log.debug(`intersection calc abc89:\n outsidePoint: ${JSON.stringify(outsidePoint)}\n insidePoint : ${JSON.stringify(insidePoint)}\n node : x:${node.x} y:${node.y} w:${node.width} h:${node.height}`);\n const x = node.x;\n const y = node.y;\n const dx = Math.abs(x - insidePoint.x);\n const w = node.width / 2;\n let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx;\n const h = node.height / 2;\n const Q = Math.abs(outsidePoint.y - insidePoint.y);\n const R = Math.abs(outsidePoint.x - insidePoint.x);\n if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h) {\n let q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y;\n r = R * q / Q;\n const res = {\n x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - R + r,\n y: insidePoint.y < outsidePoint.y ? insidePoint.y + Q - q : insidePoint.y - Q + q\n };\n if (r === 0) {\n res.x = outsidePoint.x;\n res.y = outsidePoint.y;\n }\n if (R === 0) {\n res.x = outsidePoint.x;\n }\n if (Q === 0) {\n res.y = outsidePoint.y;\n }\n log.debug(`abc89 topp/bott calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, res);\n return res;\n } else {\n if (insidePoint.x < outsidePoint.x) {\n r = outsidePoint.x - w - x;\n } else {\n r = x - w - outsidePoint.x;\n }\n let q = Q * r / R;\n let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - R + r;\n let _y = insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q;\n log.debug(`sides calc abc89, Q ${Q}, q ${q}, R ${R}, r ${r}`, { _x, _y });\n if (r === 0) {\n _x = outsidePoint.x;\n _y = outsidePoint.y;\n }\n if (R === 0) {\n _x = outsidePoint.x;\n }\n if (Q === 0) {\n _y = outsidePoint.y;\n }\n return { x: _x, y: _y };\n }\n}, \"intersection\");\nvar cutPathAtIntersect = /* @__PURE__ */ __name((_points, boundaryNode) => {\n log.debug(\"abc88 cutPathAtIntersect\", _points, boundaryNode);\n let points = [];\n let lastPointOutside = _points[0];\n let isInside = false;\n _points.forEach((point2) => {\n if (!outsideNode(boundaryNode, point2) && !isInside) {\n const inter = intersection(boundaryNode, lastPointOutside, point2);\n let pointPresent = false;\n points.forEach((p) => {\n pointPresent = pointPresent || p.x === inter.x && p.y === inter.y;\n });\n if (!points.some((e) => e.x === inter.x && e.y === inter.y)) {\n points.push(inter);\n }\n isInside = true;\n } else {\n lastPointOutside = point2;\n if (!isInside) {\n points.push(point2);\n }\n }\n });\n return points;\n}, \"cutPathAtIntersect\");\nvar insertEdge = /* @__PURE__ */ __name(function(elem, e, edge, clusterDb, diagramType, graph, id) {\n let points = edge.points;\n log.debug(\"abc88 InsertEdge: edge=\", edge, \"e=\", e);\n let pointsHasChanged = false;\n const tail = graph.node(e.v);\n var head = graph.node(e.w);\n if (head?.intersect && tail?.intersect) {\n points = points.slice(1, edge.points.length - 1);\n points.unshift(tail.intersect(points[0]));\n points.push(head.intersect(points[points.length - 1]));\n }\n if (edge.toCluster) {\n log.debug(\"to cluster abc88\", clusterDb[edge.toCluster]);\n points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node);\n pointsHasChanged = true;\n }\n if (edge.fromCluster) {\n log.debug(\"from cluster abc88\", clusterDb[edge.fromCluster]);\n points = cutPathAtIntersect(points.reverse(), clusterDb[edge.fromCluster].node).reverse();\n pointsHasChanged = true;\n }\n const lineData = points.filter((p) => !Number.isNaN(p.y));\n let curve = curveBasis;\n if (edge.curve && (diagramType === \"graph\" || diagramType === \"flowchart\")) {\n curve = edge.curve;\n }\n const { x, y } = getLineFunctionsWithOffset(edge);\n const lineFunction = line().x(x).y(y).curve(curve);\n let strokeClasses;\n switch (edge.thickness) {\n case \"normal\":\n strokeClasses = \"edge-thickness-normal\";\n break;\n case \"thick\":\n strokeClasses = \"edge-thickness-thick\";\n break;\n case \"invisible\":\n strokeClasses = \"edge-thickness-thick\";\n break;\n default:\n strokeClasses = \"\";\n }\n switch (edge.pattern) {\n case \"solid\":\n strokeClasses += \" edge-pattern-solid\";\n break;\n case \"dotted\":\n strokeClasses += \" edge-pattern-dotted\";\n break;\n case \"dashed\":\n strokeClasses += \" edge-pattern-dashed\";\n break;\n }\n const svgPath = elem.append(\"path\").attr(\"d\", lineFunction(lineData)).attr(\"id\", edge.id).attr(\"class\", \" \" + strokeClasses + (edge.classes ? \" \" + edge.classes : \"\")).attr(\"style\", edge.style);\n let url = \"\";\n if (getConfig2().flowchart.arrowMarkerAbsolute || getConfig2().state.arrowMarkerAbsolute) {\n url = getUrl(true);\n }\n addEdgeMarkers(svgPath, edge, url, id, diagramType);\n let paths = {};\n if (pointsHasChanged) {\n paths.updatedPath = points;\n }\n paths.originalPath = edge.points;\n return paths;\n}, \"insertEdge\");\n\n// src/dagre-wrapper/nodes.js\nimport { select as select4 } from \"d3\";\n\n// src/dagre-wrapper/blockArrowHelper.ts\nvar expandAndDeduplicateDirections = /* @__PURE__ */ __name((directions) => {\n const uniqueDirections = /* @__PURE__ */ new Set();\n for (const direction of directions) {\n switch (direction) {\n case \"x\":\n uniqueDirections.add(\"right\");\n uniqueDirections.add(\"left\");\n break;\n case \"y\":\n uniqueDirections.add(\"up\");\n uniqueDirections.add(\"down\");\n break;\n default:\n uniqueDirections.add(direction);\n break;\n }\n }\n return uniqueDirections;\n}, \"expandAndDeduplicateDirections\");\nvar getArrowPoints = /* @__PURE__ */ __name((duplicatedDirections, bbox, node) => {\n const directions = expandAndDeduplicateDirections(duplicatedDirections);\n const f = 2;\n const height = bbox.height + 2 * node.padding;\n const midpoint = height / f;\n const width = bbox.width + 2 * midpoint + node.padding;\n const padding2 = node.padding / 2;\n if (directions.has(\"right\") && directions.has(\"left\") && directions.has(\"up\") && directions.has(\"down\")) {\n return [\n // Bottom\n { x: 0, y: 0 },\n { x: midpoint, y: 0 },\n { x: width / 2, y: 2 * padding2 },\n { x: width - midpoint, y: 0 },\n { x: width, y: 0 },\n // Right\n { x: width, y: -height / 3 },\n { x: width + 2 * padding2, y: -height / 2 },\n { x: width, y: -2 * height / 3 },\n { x: width, y: -height },\n // Top\n { x: width - midpoint, y: -height },\n { x: width / 2, y: -height - 2 * padding2 },\n { x: midpoint, y: -height },\n // Left\n { x: 0, y: -height },\n { x: 0, y: -2 * height / 3 },\n { x: -2 * padding2, y: -height / 2 },\n { x: 0, y: -height / 3 }\n ];\n }\n if (directions.has(\"right\") && directions.has(\"left\") && directions.has(\"up\")) {\n return [\n { x: midpoint, y: 0 },\n { x: width - midpoint, y: 0 },\n { x: width, y: -height / 2 },\n { x: width - midpoint, y: -height },\n { x: midpoint, y: -height },\n { x: 0, y: -height / 2 }\n ];\n }\n if (directions.has(\"right\") && directions.has(\"left\") && directions.has(\"down\")) {\n return [\n { x: 0, y: 0 },\n { x: midpoint, y: -height },\n { x: width - midpoint, y: -height },\n { x: width, y: 0 }\n ];\n }\n if (directions.has(\"right\") && directions.has(\"up\") && directions.has(\"down\")) {\n return [\n { x: 0, y: 0 },\n { x: width, y: -midpoint },\n { x: width, y: -height + midpoint },\n { x: 0, y: -height }\n ];\n }\n if (directions.has(\"left\") && directions.has(\"up\") && directions.has(\"down\")) {\n return [\n { x: width, y: 0 },\n { x: 0, y: -midpoint },\n { x: 0, y: -height + midpoint },\n { x: width, y: -height }\n ];\n }\n if (directions.has(\"right\") && directions.has(\"left\")) {\n return [\n { x: midpoint, y: 0 },\n { x: midpoint, y: -padding2 },\n { x: width - midpoint, y: -padding2 },\n { x: width - midpoint, y: 0 },\n { x: width, y: -height / 2 },\n { x: width - midpoint, y: -height },\n { x: width - midpoint, y: -height + padding2 },\n { x: midpoint, y: -height + padding2 },\n { x: midpoint, y: -height },\n { x: 0, y: -height / 2 }\n ];\n }\n if (directions.has(\"up\") && directions.has(\"down\")) {\n return [\n // Bottom center\n { x: width / 2, y: 0 },\n // Left pont of bottom arrow\n { x: 0, y: -padding2 },\n { x: midpoint, y: -padding2 },\n // Left top over vertical section\n { x: midpoint, y: -height + padding2 },\n { x: 0, y: -height + padding2 },\n // Top of arrow\n { x: width / 2, y: -height },\n { x: width, y: -height + padding2 },\n // Top of right vertical bar\n { x: width - midpoint, y: -height + padding2 },\n { x: width - midpoint, y: -padding2 },\n { x: width, y: -padding2 }\n ];\n }\n if (directions.has(\"right\") && directions.has(\"up\")) {\n return [\n { x: 0, y: 0 },\n { x: width, y: -midpoint },\n { x: 0, y: -height }\n ];\n }\n if (directions.has(\"right\") && directions.has(\"down\")) {\n return [\n { x: 0, y: 0 },\n { x: width, y: 0 },\n { x: 0, y: -height }\n ];\n }\n if (directions.has(\"left\") && directions.has(\"up\")) {\n return [\n { x: width, y: 0 },\n { x: 0, y: -midpoint },\n { x: width, y: -height }\n ];\n }\n if (directions.has(\"left\") && directions.has(\"down\")) {\n return [\n { x: width, y: 0 },\n { x: 0, y: 0 },\n { x: width, y: -height }\n ];\n }\n if (directions.has(\"right\")) {\n return [\n { x: midpoint, y: -padding2 },\n { x: midpoint, y: -padding2 },\n { x: width - midpoint, y: -padding2 },\n { x: width - midpoint, y: 0 },\n { x: width, y: -height / 2 },\n { x: width - midpoint, y: -height },\n { x: width - midpoint, y: -height + padding2 },\n // top left corner of arrow\n { x: midpoint, y: -height + padding2 },\n { x: midpoint, y: -height + padding2 }\n ];\n }\n if (directions.has(\"left\")) {\n return [\n { x: midpoint, y: 0 },\n { x: midpoint, y: -padding2 },\n // Two points, the right corners\n { x: width - midpoint, y: -padding2 },\n { x: width - midpoint, y: -height + padding2 },\n { x: midpoint, y: -height + padding2 },\n { x: midpoint, y: -height },\n { x: 0, y: -height / 2 }\n ];\n }\n if (directions.has(\"up\")) {\n return [\n // Bottom center\n { x: midpoint, y: -padding2 },\n // Left top over vertical section\n { x: midpoint, y: -height + padding2 },\n { x: 0, y: -height + padding2 },\n // Top of arrow\n { x: width / 2, y: -height },\n { x: width, y: -height + padding2 },\n // Top of right vertical bar\n { x: width - midpoint, y: -height + padding2 },\n { x: width - midpoint, y: -padding2 }\n ];\n }\n if (directions.has(\"down\")) {\n return [\n // Bottom center\n { x: width / 2, y: 0 },\n // Left pont of bottom arrow\n { x: 0, y: -padding2 },\n { x: midpoint, y: -padding2 },\n // Left top over vertical section\n { x: midpoint, y: -height + padding2 },\n { x: width - midpoint, y: -height + padding2 },\n { x: width - midpoint, y: -padding2 },\n { x: width, y: -padding2 }\n ];\n }\n return [{ x: 0, y: 0 }];\n}, \"getArrowPoints\");\n\n// src/dagre-wrapper/intersect/intersect-node.js\nfunction intersectNode(node, point2) {\n return node.intersect(point2);\n}\n__name(intersectNode, \"intersectNode\");\nvar intersect_node_default = intersectNode;\n\n// src/dagre-wrapper/intersect/intersect-ellipse.js\nfunction intersectEllipse(node, rx, ry, point2) {\n var cx = node.x;\n var cy = node.y;\n var px = cx - point2.x;\n var py = cy - point2.y;\n var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px);\n var dx = Math.abs(rx * ry * px / det);\n if (point2.x < cx) {\n dx = -dx;\n }\n var dy = Math.abs(rx * ry * py / det);\n if (point2.y < cy) {\n dy = -dy;\n }\n return { x: cx + dx, y: cy + dy };\n}\n__name(intersectEllipse, \"intersectEllipse\");\nvar intersect_ellipse_default = intersectEllipse;\n\n// src/dagre-wrapper/intersect/intersect-circle.js\nfunction intersectCircle(node, rx, point2) {\n return intersect_ellipse_default(node, rx, rx, point2);\n}\n__name(intersectCircle, \"intersectCircle\");\nvar intersect_circle_default = intersectCircle;\n\n// src/dagre-wrapper/intersect/intersect-line.js\nfunction intersectLine(p1, p2, q1, q2) {\n var a1, a2, b1, b2, c1, c2;\n var r1, r2, r3, r4;\n var denom, offset, num;\n var x, y;\n a1 = p2.y - p1.y;\n b1 = p1.x - p2.x;\n c1 = p2.x * p1.y - p1.x * p2.y;\n r3 = a1 * q1.x + b1 * q1.y + c1;\n r4 = a1 * q2.x + b1 * q2.y + c1;\n if (r3 !== 0 && r4 !== 0 && sameSign(r3, r4)) {\n return;\n }\n a2 = q2.y - q1.y;\n b2 = q1.x - q2.x;\n c2 = q2.x * q1.y - q1.x * q2.y;\n r1 = a2 * p1.x + b2 * p1.y + c2;\n r2 = a2 * p2.x + b2 * p2.y + c2;\n if (r1 !== 0 && r2 !== 0 && sameSign(r1, r2)) {\n return;\n }\n denom = a1 * b2 - a2 * b1;\n if (denom === 0) {\n return;\n }\n offset = Math.abs(denom / 2);\n num = b1 * c2 - b2 * c1;\n x = num < 0 ? (num - offset) / denom : (num + offset) / denom;\n num = a2 * c1 - a1 * c2;\n y = num < 0 ? (num - offset) / denom : (num + offset) / denom;\n return { x, y };\n}\n__name(intersectLine, \"intersectLine\");\nfunction sameSign(r1, r2) {\n return r1 * r2 > 0;\n}\n__name(sameSign, \"sameSign\");\nvar intersect_line_default = intersectLine;\n\n// src/dagre-wrapper/intersect/intersect-polygon.js\nvar intersect_polygon_default = intersectPolygon;\nfunction intersectPolygon(node, polyPoints, point2) {\n var x1 = node.x;\n var y1 = node.y;\n var intersections = [];\n var minX = Number.POSITIVE_INFINITY;\n var minY = Number.POSITIVE_INFINITY;\n if (typeof polyPoints.forEach === \"function\") {\n polyPoints.forEach(function(entry) {\n minX = Math.min(minX, entry.x);\n minY = Math.min(minY, entry.y);\n });\n } else {\n minX = Math.min(minX, polyPoints.x);\n minY = Math.min(minY, polyPoints.y);\n }\n var left = x1 - node.width / 2 - minX;\n var top = y1 - node.height / 2 - minY;\n for (var i = 0; i < polyPoints.length; i++) {\n var p1 = polyPoints[i];\n var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0];\n var intersect = intersect_line_default(\n node,\n point2,\n { x: left + p1.x, y: top + p1.y },\n { x: left + p2.x, y: top + p2.y }\n );\n if (intersect) {\n intersections.push(intersect);\n }\n }\n if (!intersections.length) {\n return node;\n }\n if (intersections.length > 1) {\n intersections.sort(function(p, q) {\n var pdx = p.x - point2.x;\n var pdy = p.y - point2.y;\n var distp = Math.sqrt(pdx * pdx + pdy * pdy);\n var qdx = q.x - point2.x;\n var qdy = q.y - point2.y;\n var distq = Math.sqrt(qdx * qdx + qdy * qdy);\n return distp < distq ? -1 : distp === distq ? 0 : 1;\n });\n }\n return intersections[0];\n}\n__name(intersectPolygon, \"intersectPolygon\");\n\n// src/dagre-wrapper/intersect/intersect-rect.js\nvar intersectRect = /* @__PURE__ */ __name((node, point2) => {\n var x = node.x;\n var y = node.y;\n var dx = point2.x - x;\n var dy = point2.y - y;\n var w = node.width / 2;\n var h = node.height / 2;\n var sx, sy;\n if (Math.abs(dy) * w > Math.abs(dx) * h) {\n if (dy < 0) {\n h = -h;\n }\n sx = dy === 0 ? 0 : h * dx / dy;\n sy = h;\n } else {\n if (dx < 0) {\n w = -w;\n }\n sx = w;\n sy = dx === 0 ? 0 : w * dy / dx;\n }\n return { x: x + sx, y: y + sy };\n}, \"intersectRect\");\nvar intersect_rect_default = intersectRect;\n\n// src/dagre-wrapper/intersect/index.js\nvar intersect_default = {\n node: intersect_node_default,\n circle: intersect_circle_default,\n ellipse: intersect_ellipse_default,\n polygon: intersect_polygon_default,\n rect: intersect_rect_default\n};\n\n// src/dagre-wrapper/shapes/util.js\nimport { select as select3 } from \"d3\";\nvar labelHelper = /* @__PURE__ */ __name(async (parent, node, _classes, isNode) => {\n const config2 = getConfig2();\n let classes2;\n const useHtmlLabels = node.useHtmlLabels || evaluate(config2.flowchart.htmlLabels);\n if (!_classes) {\n classes2 = \"node default\";\n } else {\n classes2 = _classes;\n }\n const shapeSvg = parent.insert(\"g\").attr(\"class\", classes2).attr(\"id\", node.domId || node.id);\n const label = shapeSvg.insert(\"g\").attr(\"class\", \"label\").attr(\"style\", node.labelStyle);\n let labelText;\n if (node.labelText === void 0) {\n labelText = \"\";\n } else {\n labelText = typeof node.labelText === \"string\" ? node.labelText : node.labelText[0];\n }\n const textNode = label.node();\n let text;\n if (node.labelType === \"markdown\") {\n text = createText(\n label,\n sanitizeText(decodeEntities(labelText), config2),\n {\n useHtmlLabels,\n width: node.width || config2.flowchart.wrappingWidth,\n classes: \"markdown-node-label\"\n },\n config2\n );\n } else {\n text = textNode.appendChild(\n await createLabel_default(\n sanitizeText(decodeEntities(labelText), config2),\n node.labelStyle,\n false,\n isNode\n )\n );\n }\n let bbox = text.getBBox();\n const halfPadding = node.padding / 2;\n if (evaluate(config2.flowchart.htmlLabels)) {\n const div = text.children[0];\n const dv = select3(text);\n const images = div.getElementsByTagName(\"img\");\n if (images) {\n const noImgText = labelText.replace(/]*>/g, \"\").trim() === \"\";\n await Promise.all(\n [...images].map(\n (img) => new Promise((res) => {\n function setupImage() {\n img.style.display = \"flex\";\n img.style.flexDirection = \"column\";\n if (noImgText) {\n const bodyFontSize = config2.fontSize ? config2.fontSize : window.getComputedStyle(document.body).fontSize;\n const enlargingFactor = 5;\n const width = parseInt(bodyFontSize, 10) * enlargingFactor + \"px\";\n img.style.minWidth = width;\n img.style.maxWidth = width;\n } else {\n img.style.width = \"100%\";\n }\n res(img);\n }\n __name(setupImage, \"setupImage\");\n setTimeout(() => {\n if (img.complete) {\n setupImage();\n }\n });\n img.addEventListener(\"error\", setupImage);\n img.addEventListener(\"load\", setupImage);\n })\n )\n );\n }\n bbox = div.getBoundingClientRect();\n dv.attr(\"width\", bbox.width);\n dv.attr(\"height\", bbox.height);\n }\n if (useHtmlLabels) {\n label.attr(\"transform\", \"translate(\" + -bbox.width / 2 + \", \" + -bbox.height / 2 + \")\");\n } else {\n label.attr(\"transform\", \"translate(0, \" + -bbox.height / 2 + \")\");\n }\n if (node.centerLabel) {\n label.attr(\"transform\", \"translate(\" + -bbox.width / 2 + \", \" + -bbox.height / 2 + \")\");\n }\n label.insert(\"rect\", \":first-child\");\n return { shapeSvg, bbox, halfPadding, label };\n}, \"labelHelper\");\nvar updateNodeBounds = /* @__PURE__ */ __name((node, element) => {\n const bbox = element.node().getBBox();\n node.width = bbox.width;\n node.height = bbox.height;\n}, \"updateNodeBounds\");\nfunction insertPolygonShape(parent, w, h, points) {\n return parent.insert(\"polygon\", \":first-child\").attr(\n \"points\",\n points.map(function(d) {\n return d.x + \",\" + d.y;\n }).join(\" \")\n ).attr(\"class\", \"label-container\").attr(\"transform\", \"translate(\" + -w / 2 + \",\" + h / 2 + \")\");\n}\n__name(insertPolygonShape, \"insertPolygonShape\");\n\n// src/dagre-wrapper/shapes/note.js\nvar note = /* @__PURE__ */ __name(async (parent, node) => {\n const useHtmlLabels = node.useHtmlLabels || getConfig2().flowchart.htmlLabels;\n if (!useHtmlLabels) {\n node.centerLabel = true;\n }\n const { shapeSvg, bbox, halfPadding } = await labelHelper(\n parent,\n node,\n \"node \" + node.classes,\n true\n );\n log.info(\"Classes = \", node.classes);\n const rect2 = shapeSvg.insert(\"rect\", \":first-child\");\n rect2.attr(\"rx\", node.rx).attr(\"ry\", node.ry).attr(\"x\", -bbox.width / 2 - halfPadding).attr(\"y\", -bbox.height / 2 - halfPadding).attr(\"width\", bbox.width + node.padding).attr(\"height\", bbox.height + node.padding);\n updateNodeBounds(node, rect2);\n node.intersect = function(point2) {\n return intersect_default.rect(node, point2);\n };\n return shapeSvg;\n}, \"note\");\nvar note_default = note;\n\n// src/dagre-wrapper/nodes.js\nvar formatClass = /* @__PURE__ */ __name((str) => {\n if (str) {\n return \" \" + str;\n }\n return \"\";\n}, \"formatClass\");\nvar getClassesFromNode = /* @__PURE__ */ __name((node, otherClasses) => {\n return `${otherClasses ? otherClasses : \"node default\"}${formatClass(node.classes)} ${formatClass(\n node.class\n )}`;\n}, \"getClassesFromNode\");\nvar question = /* @__PURE__ */ __name(async (parent, node) => {\n const { shapeSvg, bbox } = await labelHelper(\n parent,\n node,\n getClassesFromNode(node, void 0),\n true\n );\n const w = bbox.width + node.padding;\n const h = bbox.height + node.padding;\n const s = w + h;\n const points = [\n { x: s / 2, y: 0 },\n { x: s, y: -s / 2 },\n { x: s / 2, y: -s },\n { x: 0, y: -s / 2 }\n ];\n log.info(\"Question main (Circle)\");\n const questionElem = insertPolygonShape(shapeSvg, s, s, points);\n questionElem.attr(\"style\", node.style);\n updateNodeBounds(node, questionElem);\n node.intersect = function(point2) {\n log.warn(\"Intersect called\");\n return intersect_default.polygon(node, points, point2);\n };\n return shapeSvg;\n}, \"question\");\nvar choice = /* @__PURE__ */ __name((parent, node) => {\n const shapeSvg = parent.insert(\"g\").attr(\"class\", \"node default\").attr(\"id\", node.domId || node.id);\n const s = 28;\n const points = [\n { x: 0, y: s / 2 },\n { x: s / 2, y: 0 },\n { x: 0, y: -s / 2 },\n { x: -s / 2, y: 0 }\n ];\n const choice2 = shapeSvg.insert(\"polygon\", \":first-child\").attr(\n \"points\",\n points.map(function(d) {\n return d.x + \",\" + d.y;\n }).join(\" \")\n );\n choice2.attr(\"class\", \"state-start\").attr(\"r\", 7).attr(\"width\", 28).attr(\"height\", 28);\n node.width = 28;\n node.height = 28;\n node.intersect = function(point2) {\n return intersect_default.circle(node, 14, point2);\n };\n return shapeSvg;\n}, \"choice\");\nvar hexagon = /* @__PURE__ */ __name(async (parent, node) => {\n const { shapeSvg, bbox } = await labelHelper(\n parent,\n node,\n getClassesFromNode(node, void 0),\n true\n );\n const f = 4;\n const h = bbox.height + node.padding;\n const m = h / f;\n const w = bbox.width + 2 * m + node.padding;\n const points = [\n { x: m, y: 0 },\n { x: w - m, y: 0 },\n { x: w, y: -h / 2 },\n { x: w - m, y: -h },\n { x: m, y: -h },\n { x: 0, y: -h / 2 }\n ];\n const hex = insertPolygonShape(shapeSvg, w, h, points);\n hex.attr(\"style\", node.style);\n updateNodeBounds(node, hex);\n node.intersect = function(point2) {\n return intersect_default.polygon(node, points, point2);\n };\n return shapeSvg;\n}, \"hexagon\");\nvar block_arrow = /* @__PURE__ */ __name(async (parent, node) => {\n const { shapeSvg, bbox } = await labelHelper(parent, node, void 0, true);\n const f = 2;\n const h = bbox.height + 2 * node.padding;\n const m = h / f;\n const w = bbox.width + 2 * m + node.padding;\n const points = getArrowPoints(node.directions, bbox, node);\n const blockArrow = insertPolygonShape(shapeSvg, w, h, points);\n blockArrow.attr(\"style\", node.style);\n updateNodeBounds(node, blockArrow);\n node.intersect = function(point2) {\n return intersect_default.polygon(node, points, point2);\n };\n return shapeSvg;\n}, \"block_arrow\");\nvar rect_left_inv_arrow = /* @__PURE__ */ __name(async (parent, node) => {\n const { shapeSvg, bbox } = await labelHelper(\n parent,\n node,\n getClassesFromNode(node, void 0),\n true\n );\n const w = bbox.width + node.padding;\n const h = bbox.height + node.padding;\n const points = [\n { x: -h / 2, y: 0 },\n { x: w, y: 0 },\n { x: w, y: -h },\n { x: -h / 2, y: -h },\n { x: 0, y: -h / 2 }\n ];\n const el = insertPolygonShape(shapeSvg, w, h, points);\n el.attr(\"style\", node.style);\n node.width = w + h;\n node.height = h;\n node.intersect = function(point2) {\n return intersect_default.polygon(node, points, point2);\n };\n return shapeSvg;\n}, \"rect_left_inv_arrow\");\nvar lean_right = /* @__PURE__ */ __name(async (parent, node) => {\n const { shapeSvg, bbox } = await labelHelper(parent, node, getClassesFromNode(node), true);\n const w = bbox.width + node.padding;\n const h = bbox.height + node.padding;\n const points = [\n { x: -2 * h / 6, y: 0 },\n { x: w - h / 6, y: 0 },\n { x: w + 2 * h / 6, y: -h },\n { x: h / 6, y: -h }\n ];\n const el = insertPolygonShape(shapeSvg, w, h, points);\n el.attr(\"style\", node.style);\n updateNodeBounds(node, el);\n node.intersect = function(point2) {\n return intersect_default.polygon(node, points, point2);\n };\n return shapeSvg;\n}, \"lean_right\");\nvar lean_left = /* @__PURE__ */ __name(async (parent, node) => {\n const { shapeSvg, bbox } = await labelHelper(\n parent,\n node,\n getClassesFromNode(node, void 0),\n true\n );\n const w = bbox.width + node.padding;\n const h = bbox.height + node.padding;\n const points = [\n { x: 2 * h / 6, y: 0 },\n { x: w + h / 6, y: 0 },\n { x: w - 2 * h / 6, y: -h },\n { x: -h / 6, y: -h }\n ];\n const el = insertPolygonShape(shapeSvg, w, h, points);\n el.attr(\"style\", node.style);\n updateNodeBounds(node, el);\n node.intersect = function(point2) {\n return intersect_default.polygon(node, points, point2);\n };\n return shapeSvg;\n}, \"lean_left\");\nvar trapezoid = /* @__PURE__ */ __name(async (parent, node) => {\n const { shapeSvg, bbox } = await labelHelper(\n parent,\n node,\n getClassesFromNode(node, void 0),\n true\n );\n const w = bbox.width + node.padding;\n const h = bbox.height + node.padding;\n const points = [\n { x: -2 * h / 6, y: 0 },\n { x: w + 2 * h / 6, y: 0 },\n { x: w - h / 6, y: -h },\n { x: h / 6, y: -h }\n ];\n const el = insertPolygonShape(shapeSvg, w, h, points);\n el.attr(\"style\", node.style);\n updateNodeBounds(node, el);\n node.intersect = function(point2) {\n return intersect_default.polygon(node, points, point2);\n };\n return shapeSvg;\n}, \"trapezoid\");\nvar inv_trapezoid = /* @__PURE__ */ __name(async (parent, node) => {\n const { shapeSvg, bbox } = await labelHelper(\n parent,\n node,\n getClassesFromNode(node, void 0),\n true\n );\n const w = bbox.width + node.padding;\n const h = bbox.height + node.padding;\n const points = [\n { x: h / 6, y: 0 },\n { x: w - h / 6, y: 0 },\n { x: w + 2 * h / 6, y: -h },\n { x: -2 * h / 6, y: -h }\n ];\n const el = insertPolygonShape(shapeSvg, w, h, points);\n el.attr(\"style\", node.style);\n updateNodeBounds(node, el);\n node.intersect = function(point2) {\n return intersect_default.polygon(node, points, point2);\n };\n return shapeSvg;\n}, \"inv_trapezoid\");\nvar rect_right_inv_arrow = /* @__PURE__ */ __name(async (parent, node) => {\n const { shapeSvg, bbox } = await labelHelper(\n parent,\n node,\n getClassesFromNode(node, void 0),\n true\n );\n const w = bbox.width + node.padding;\n const h = bbox.height + node.padding;\n const points = [\n { x: 0, y: 0 },\n { x: w + h / 2, y: 0 },\n { x: w, y: -h / 2 },\n { x: w + h / 2, y: -h },\n { x: 0, y: -h }\n ];\n const el = insertPolygonShape(shapeSvg, w, h, points);\n el.attr(\"style\", node.style);\n updateNodeBounds(node, el);\n node.intersect = function(point2) {\n return intersect_default.polygon(node, points, point2);\n };\n return shapeSvg;\n}, \"rect_right_inv_arrow\");\nvar cylinder = /* @__PURE__ */ __name(async (parent, node) => {\n const { shapeSvg, bbox } = await labelHelper(\n parent,\n node,\n getClassesFromNode(node, void 0),\n true\n );\n const w = bbox.width + node.padding;\n const rx = w / 2;\n const ry = rx / (2.5 + w / 50);\n const h = bbox.height + ry + node.padding;\n const shape = \"M 0,\" + ry + \" a \" + rx + \",\" + ry + \" 0,0,0 \" + w + \" 0 a \" + rx + \",\" + ry + \" 0,0,0 \" + -w + \" 0 l 0,\" + h + \" a \" + rx + \",\" + ry + \" 0,0,0 \" + w + \" 0 l 0,\" + -h;\n const el = shapeSvg.attr(\"label-offset-y\", ry).insert(\"path\", \":first-child\").attr(\"style\", node.style).attr(\"d\", shape).attr(\"transform\", \"translate(\" + -w / 2 + \",\" + -(h / 2 + ry) + \")\");\n updateNodeBounds(node, el);\n node.intersect = function(point2) {\n const pos = intersect_default.rect(node, point2);\n const x = pos.x - node.x;\n if (rx != 0 && (Math.abs(x) < node.width / 2 || Math.abs(x) == node.width / 2 && Math.abs(pos.y - node.y) > node.height / 2 - ry)) {\n let y = ry * ry * (1 - x * x / (rx * rx));\n if (y != 0) {\n y = Math.sqrt(y);\n }\n y = ry - y;\n if (point2.y - node.y > 0) {\n y = -y;\n }\n pos.y += y;\n }\n return pos;\n };\n return shapeSvg;\n}, \"cylinder\");\nvar rect = /* @__PURE__ */ __name(async (parent, node) => {\n const { shapeSvg, bbox, halfPadding } = await labelHelper(\n parent,\n node,\n \"node \" + node.classes + \" \" + node.class,\n true\n );\n const rect2 = shapeSvg.insert(\"rect\", \":first-child\");\n const totalWidth = node.positioned ? node.width : bbox.width + node.padding;\n const totalHeight = node.positioned ? node.height : bbox.height + node.padding;\n const x = node.positioned ? -totalWidth / 2 : -bbox.width / 2 - halfPadding;\n const y = node.positioned ? -totalHeight / 2 : -bbox.height / 2 - halfPadding;\n rect2.attr(\"class\", \"basic label-container\").attr(\"style\", node.style).attr(\"rx\", node.rx).attr(\"ry\", node.ry).attr(\"x\", x).attr(\"y\", y).attr(\"width\", totalWidth).attr(\"height\", totalHeight);\n if (node.props) {\n const propKeys = new Set(Object.keys(node.props));\n if (node.props.borders) {\n applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight);\n propKeys.delete(\"borders\");\n }\n propKeys.forEach((propKey) => {\n log.warn(`Unknown node property ${propKey}`);\n });\n }\n updateNodeBounds(node, rect2);\n node.intersect = function(point2) {\n return intersect_default.rect(node, point2);\n };\n return shapeSvg;\n}, \"rect\");\nvar composite = /* @__PURE__ */ __name(async (parent, node) => {\n const { shapeSvg, bbox, halfPadding } = await labelHelper(\n parent,\n node,\n \"node \" + node.classes,\n true\n );\n const rect2 = shapeSvg.insert(\"rect\", \":first-child\");\n const totalWidth = node.positioned ? node.width : bbox.width + node.padding;\n const totalHeight = node.positioned ? node.height : bbox.height + node.padding;\n const x = node.positioned ? -totalWidth / 2 : -bbox.width / 2 - halfPadding;\n const y = node.positioned ? -totalHeight / 2 : -bbox.height / 2 - halfPadding;\n rect2.attr(\"class\", \"basic cluster composite label-container\").attr(\"style\", node.style).attr(\"rx\", node.rx).attr(\"ry\", node.ry).attr(\"x\", x).attr(\"y\", y).attr(\"width\", totalWidth).attr(\"height\", totalHeight);\n if (node.props) {\n const propKeys = new Set(Object.keys(node.props));\n if (node.props.borders) {\n applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight);\n propKeys.delete(\"borders\");\n }\n propKeys.forEach((propKey) => {\n log.warn(`Unknown node property ${propKey}`);\n });\n }\n updateNodeBounds(node, rect2);\n node.intersect = function(point2) {\n return intersect_default.rect(node, point2);\n };\n return shapeSvg;\n}, \"composite\");\nvar labelRect = /* @__PURE__ */ __name(async (parent, node) => {\n const { shapeSvg } = await labelHelper(parent, node, \"label\", true);\n log.trace(\"Classes = \", node.class);\n const rect2 = shapeSvg.insert(\"rect\", \":first-child\");\n const totalWidth = 0;\n const totalHeight = 0;\n rect2.attr(\"width\", totalWidth).attr(\"height\", totalHeight);\n shapeSvg.attr(\"class\", \"label edgeLabel\");\n if (node.props) {\n const propKeys = new Set(Object.keys(node.props));\n if (node.props.borders) {\n applyNodePropertyBorders(rect2, node.props.borders, totalWidth, totalHeight);\n propKeys.delete(\"borders\");\n }\n propKeys.forEach((propKey) => {\n log.warn(`Unknown node property ${propKey}`);\n });\n }\n updateNodeBounds(node, rect2);\n node.intersect = function(point2) {\n return intersect_default.rect(node, point2);\n };\n return shapeSvg;\n}, \"labelRect\");\nfunction applyNodePropertyBorders(rect2, borders, totalWidth, totalHeight) {\n const strokeDashArray = [];\n const addBorder = /* @__PURE__ */ __name((length) => {\n strokeDashArray.push(length, 0);\n }, \"addBorder\");\n const skipBorder = /* @__PURE__ */ __name((length) => {\n strokeDashArray.push(0, length);\n }, \"skipBorder\");\n if (borders.includes(\"t\")) {\n log.debug(\"add top border\");\n addBorder(totalWidth);\n } else {\n skipBorder(totalWidth);\n }\n if (borders.includes(\"r\")) {\n log.debug(\"add right border\");\n addBorder(totalHeight);\n } else {\n skipBorder(totalHeight);\n }\n if (borders.includes(\"b\")) {\n log.debug(\"add bottom border\");\n addBorder(totalWidth);\n } else {\n skipBorder(totalWidth);\n }\n if (borders.includes(\"l\")) {\n log.debug(\"add left border\");\n addBorder(totalHeight);\n } else {\n skipBorder(totalHeight);\n }\n rect2.attr(\"stroke-dasharray\", strokeDashArray.join(\" \"));\n}\n__name(applyNodePropertyBorders, \"applyNodePropertyBorders\");\nvar rectWithTitle = /* @__PURE__ */ __name(async (parent, node) => {\n let classes2;\n if (!node.classes) {\n classes2 = \"node default\";\n } else {\n classes2 = \"node \" + node.classes;\n }\n const shapeSvg = parent.insert(\"g\").attr(\"class\", classes2).attr(\"id\", node.domId || node.id);\n const rect2 = shapeSvg.insert(\"rect\", \":first-child\");\n const innerLine = shapeSvg.insert(\"line\");\n const label = shapeSvg.insert(\"g\").attr(\"class\", \"label\");\n const text2 = node.labelText.flat ? node.labelText.flat() : node.labelText;\n let title = \"\";\n if (typeof text2 === \"object\") {\n title = text2[0];\n } else {\n title = text2;\n }\n log.info(\"Label text abc79\", title, text2, typeof text2 === \"object\");\n const text = label.node().appendChild(await createLabel_default(title, node.labelStyle, true, true));\n let bbox = { width: 0, height: 0 };\n if (evaluate(getConfig2().flowchart.htmlLabels)) {\n const div = text.children[0];\n const dv = select4(text);\n bbox = div.getBoundingClientRect();\n dv.attr(\"width\", bbox.width);\n dv.attr(\"height\", bbox.height);\n }\n log.info(\"Text 2\", text2);\n const textRows = text2.slice(1, text2.length);\n let titleBox = text.getBBox();\n const descr = label.node().appendChild(\n await createLabel_default(\n textRows.join ? textRows.join(\"
\") : textRows,\n node.labelStyle,\n true,\n true\n )\n );\n if (evaluate(getConfig2().flowchart.htmlLabels)) {\n const div = descr.children[0];\n const dv = select4(descr);\n bbox = div.getBoundingClientRect();\n dv.attr(\"width\", bbox.width);\n dv.attr(\"height\", bbox.height);\n }\n const halfPadding = node.padding / 2;\n select4(descr).attr(\n \"transform\",\n \"translate( \" + // (titleBox.width - bbox.width) / 2 +\n (bbox.width > titleBox.width ? 0 : (titleBox.width - bbox.width) / 2) + \", \" + (titleBox.height + halfPadding + 5) + \")\"\n );\n select4(text).attr(\n \"transform\",\n \"translate( \" + // (titleBox.width - bbox.width) / 2 +\n (bbox.width < titleBox.width ? 0 : -(titleBox.width - bbox.width) / 2) + \", 0)\"\n );\n bbox = label.node().getBBox();\n label.attr(\n \"transform\",\n \"translate(\" + -bbox.width / 2 + \", \" + (-bbox.height / 2 - halfPadding + 3) + \")\"\n );\n rect2.attr(\"class\", \"outer title-state\").attr(\"x\", -bbox.width / 2 - halfPadding).attr(\"y\", -bbox.height / 2 - halfPadding).attr(\"width\", bbox.width + node.padding).attr(\"height\", bbox.height + node.padding);\n innerLine.attr(\"class\", \"divider\").attr(\"x1\", -bbox.width / 2 - halfPadding).attr(\"x2\", bbox.width / 2 + halfPadding).attr(\"y1\", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding).attr(\"y2\", -bbox.height / 2 - halfPadding + titleBox.height + halfPadding);\n updateNodeBounds(node, rect2);\n node.intersect = function(point2) {\n return intersect_default.rect(node, point2);\n };\n return shapeSvg;\n}, \"rectWithTitle\");\nvar stadium = /* @__PURE__ */ __name(async (parent, node) => {\n const { shapeSvg, bbox } = await labelHelper(\n parent,\n node,\n getClassesFromNode(node, void 0),\n true\n );\n const h = bbox.height + node.padding;\n const w = bbox.width + h / 4 + node.padding;\n const rect2 = shapeSvg.insert(\"rect\", \":first-child\").attr(\"style\", node.style).attr(\"rx\", h / 2).attr(\"ry\", h / 2).attr(\"x\", -w / 2).attr(\"y\", -h / 2).attr(\"width\", w).attr(\"height\", h);\n updateNodeBounds(node, rect2);\n node.intersect = function(point2) {\n return intersect_default.rect(node, point2);\n };\n return shapeSvg;\n}, \"stadium\");\nvar circle2 = /* @__PURE__ */ __name(async (parent, node) => {\n const { shapeSvg, bbox, halfPadding } = await labelHelper(\n parent,\n node,\n getClassesFromNode(node, void 0),\n true\n );\n const circle3 = shapeSvg.insert(\"circle\", \":first-child\");\n circle3.attr(\"style\", node.style).attr(\"rx\", node.rx).attr(\"ry\", node.ry).attr(\"r\", bbox.width / 2 + halfPadding).attr(\"width\", bbox.width + node.padding).attr(\"height\", bbox.height + node.padding);\n log.info(\"Circle main\");\n updateNodeBounds(node, circle3);\n node.intersect = function(point2) {\n log.info(\"Circle intersect\", node, bbox.width / 2 + halfPadding, point2);\n return intersect_default.circle(node, bbox.width / 2 + halfPadding, point2);\n };\n return shapeSvg;\n}, \"circle\");\nvar doublecircle = /* @__PURE__ */ __name(async (parent, node) => {\n const { shapeSvg, bbox, halfPadding } = await labelHelper(\n parent,\n node,\n getClassesFromNode(node, void 0),\n true\n );\n const gap = 5;\n const circleGroup = shapeSvg.insert(\"g\", \":first-child\");\n const outerCircle = circleGroup.insert(\"circle\");\n const innerCircle = circleGroup.insert(\"circle\");\n circleGroup.attr(\"class\", node.class);\n outerCircle.attr(\"style\", node.style).attr(\"rx\", node.rx).attr(\"ry\", node.ry).attr(\"r\", bbox.width / 2 + halfPadding + gap).attr(\"width\", bbox.width + node.padding + gap * 2).attr(\"height\", bbox.height + node.padding + gap * 2);\n innerCircle.attr(\"style\", node.style).attr(\"rx\", node.rx).attr(\"ry\", node.ry).attr(\"r\", bbox.width / 2 + halfPadding).attr(\"width\", bbox.width + node.padding).attr(\"height\", bbox.height + node.padding);\n log.info(\"DoubleCircle main\");\n updateNodeBounds(node, outerCircle);\n node.intersect = function(point2) {\n log.info(\"DoubleCircle intersect\", node, bbox.width / 2 + halfPadding + gap, point2);\n return intersect_default.circle(node, bbox.width / 2 + halfPadding + gap, point2);\n };\n return shapeSvg;\n}, \"doublecircle\");\nvar subroutine = /* @__PURE__ */ __name(async (parent, node) => {\n const { shapeSvg, bbox } = await labelHelper(\n parent,\n node,\n getClassesFromNode(node, void 0),\n true\n );\n const w = bbox.width + node.padding;\n const h = bbox.height + node.padding;\n const points = [\n { x: 0, y: 0 },\n { x: w, y: 0 },\n { x: w, y: -h },\n { x: 0, y: -h },\n { x: 0, y: 0 },\n { x: -8, y: 0 },\n { x: w + 8, y: 0 },\n { x: w + 8, y: -h },\n { x: -8, y: -h },\n { x: -8, y: 0 }\n ];\n const el = insertPolygonShape(shapeSvg, w, h, points);\n el.attr(\"style\", node.style);\n updateNodeBounds(node, el);\n node.intersect = function(point2) {\n return intersect_default.polygon(node, points, point2);\n };\n return shapeSvg;\n}, \"subroutine\");\nvar start = /* @__PURE__ */ __name((parent, node) => {\n const shapeSvg = parent.insert(\"g\").attr(\"class\", \"node default\").attr(\"id\", node.domId || node.id);\n const circle3 = shapeSvg.insert(\"circle\", \":first-child\");\n circle3.attr(\"class\", \"state-start\").attr(\"r\", 7).attr(\"width\", 14).attr(\"height\", 14);\n updateNodeBounds(node, circle3);\n node.intersect = function(point2) {\n return intersect_default.circle(node, 7, point2);\n };\n return shapeSvg;\n}, \"start\");\nvar forkJoin = /* @__PURE__ */ __name((parent, node, dir) => {\n const shapeSvg = parent.insert(\"g\").attr(\"class\", \"node default\").attr(\"id\", node.domId || node.id);\n let width = 70;\n let height = 10;\n if (dir === \"LR\") {\n width = 10;\n height = 70;\n }\n const shape = shapeSvg.append(\"rect\").attr(\"x\", -1 * width / 2).attr(\"y\", -1 * height / 2).attr(\"width\", width).attr(\"height\", height).attr(\"class\", \"fork-join\");\n updateNodeBounds(node, shape);\n node.height = node.height + node.padding / 2;\n node.width = node.width + node.padding / 2;\n node.intersect = function(point2) {\n return intersect_default.rect(node, point2);\n };\n return shapeSvg;\n}, \"forkJoin\");\nvar end = /* @__PURE__ */ __name((parent, node) => {\n const shapeSvg = parent.insert(\"g\").attr(\"class\", \"node default\").attr(\"id\", node.domId || node.id);\n const innerCircle = shapeSvg.insert(\"circle\", \":first-child\");\n const circle3 = shapeSvg.insert(\"circle\", \":first-child\");\n circle3.attr(\"class\", \"state-start\").attr(\"r\", 7).attr(\"width\", 14).attr(\"height\", 14);\n innerCircle.attr(\"class\", \"state-end\").attr(\"r\", 5).attr(\"width\", 10).attr(\"height\", 10);\n updateNodeBounds(node, circle3);\n node.intersect = function(point2) {\n return intersect_default.circle(node, 7, point2);\n };\n return shapeSvg;\n}, \"end\");\nvar class_box = /* @__PURE__ */ __name(async (parent, node) => {\n const halfPadding = node.padding / 2;\n const rowPadding = 4;\n const lineHeight = 8;\n let classes2;\n if (!node.classes) {\n classes2 = \"node default\";\n } else {\n classes2 = \"node \" + node.classes;\n }\n const shapeSvg = parent.insert(\"g\").attr(\"class\", classes2).attr(\"id\", node.domId || node.id);\n const rect2 = shapeSvg.insert(\"rect\", \":first-child\");\n const topLine = shapeSvg.insert(\"line\");\n const bottomLine = shapeSvg.insert(\"line\");\n let maxWidth = 0;\n let maxHeight = rowPadding;\n const labelContainer = shapeSvg.insert(\"g\").attr(\"class\", \"label\");\n let verticalPos = 0;\n const hasInterface = node.classData.annotations?.[0];\n const interfaceLabelText = node.classData.annotations[0] ? \"\\xAB\" + node.classData.annotations[0] + \"\\xBB\" : \"\";\n const interfaceLabel = labelContainer.node().appendChild(await createLabel_default(interfaceLabelText, node.labelStyle, true, true));\n let interfaceBBox = interfaceLabel.getBBox();\n if (evaluate(getConfig2().flowchart.htmlLabels)) {\n const div = interfaceLabel.children[0];\n const dv = select4(interfaceLabel);\n interfaceBBox = div.getBoundingClientRect();\n dv.attr(\"width\", interfaceBBox.width);\n dv.attr(\"height\", interfaceBBox.height);\n }\n if (node.classData.annotations[0]) {\n maxHeight += interfaceBBox.height + rowPadding;\n maxWidth += interfaceBBox.width;\n }\n let classTitleString = node.classData.label;\n if (node.classData.type !== void 0 && node.classData.type !== \"\") {\n if (getConfig2().flowchart.htmlLabels) {\n classTitleString += \"<\" + node.classData.type + \">\";\n } else {\n classTitleString += \"<\" + node.classData.type + \">\";\n }\n }\n const classTitleLabel = labelContainer.node().appendChild(await createLabel_default(classTitleString, node.labelStyle, true, true));\n select4(classTitleLabel).attr(\"class\", \"classTitle\");\n let classTitleBBox = classTitleLabel.getBBox();\n if (evaluate(getConfig2().flowchart.htmlLabels)) {\n const div = classTitleLabel.children[0];\n const dv = select4(classTitleLabel);\n classTitleBBox = div.getBoundingClientRect();\n dv.attr(\"width\", classTitleBBox.width);\n dv.attr(\"height\", classTitleBBox.height);\n }\n maxHeight += classTitleBBox.height + rowPadding;\n if (classTitleBBox.width > maxWidth) {\n maxWidth = classTitleBBox.width;\n }\n const classAttributes = [];\n node.classData.members.forEach(async (member) => {\n const parsedInfo = member.getDisplayDetails();\n let parsedText = parsedInfo.displayText;\n if (getConfig2().flowchart.htmlLabels) {\n parsedText = parsedText.replace(/
")),c.classed("hover",!0)}).on("mouseout",r=>{a.transition().duration(500).style("opacity",0),ee(r.currentTarget).classed("hover",!1)})},"setupToolTips"),this.direction="TB",this.setAccTitle=nt,this.getAccTitle=rt,this.setAccDescription=ut,this.getAccDescription=lt,this.setDiagramTitle=ot,this.getDiagramTitle=ct,this.getConfig=f(()=>F().class,"getConfig"),this.functions.push(this.setupToolTips.bind(this)),this.clear(),this.addRelation=this.addRelation.bind(this),this.addClassesToNamespace=this.addClassesToNamespace.bind(this),this.addNamespace=this.addNamespace.bind(this),this.setCssClass=this.setCssClass.bind(this),this.addMembers=this.addMembers.bind(this),this.addClass=this.addClass.bind(this),this.setClassLabel=this.setClassLabel.bind(this),this.addAnnotation=this.addAnnotation.bind(this),this.addMember=this.addMember.bind(this),this.cleanupLabel=this.cleanupLabel.bind(this),this.addNote=this.addNote.bind(this),this.defineClass=this.defineClass.bind(this),this.setDirection=this.setDirection.bind(this),this.setLink=this.setLink.bind(this),this.bindFunctions=this.bindFunctions.bind(this),this.clear=this.clear.bind(this),this.setTooltip=this.setTooltip.bind(this),this.setClickEvent=this.setClickEvent.bind(this),this.setCssStyle=this.setCssStyle.bind(this)}splitClassNameAndType(i){const a=v.sanitizeText(i,F());let u="",l=a;if(a.indexOf("~")>0){const r=a.split("~");l=V(r[0]),u=V(r[1])}return{className:l,type:u}}setClassLabel(i,a){const u=v.sanitizeText(i,F());a&&(a=V(a));const{className:l}=this.splitClassNameAndType(u);this.classes.get(l).label=a,this.classes.get(l).text=`${a}${this.classes.get(l).type?`<${this.classes.get(l).type}>`:""}`}addClass(i){const a=v.sanitizeText(i,F()),{className:u,type:l}=this.splitClassNameAndType(a);if(this.classes.has(u))return;const r=v.sanitizeText(u,F());this.classes.set(r,{id:r,type:l,label:r,text:`${r}${l?`<${l}>`:""}`,shape:"classBox",cssClasses:"default",methods:[],members:[],annotations:[],styles:[],domId:pe+r+"-"+Xe}),Xe++}addInterface(i,a){const u={id:`interface${this.interfaces.length}`,label:i,classId:a};this.interfaces.push(u)}lookUpDomId(i){const a=v.sanitizeText(i,F());if(this.classes.has(a))return this.classes.get(a).domId;throw new Error("Class not found: "+a)}clear(){this.relations=[],this.classes=new Map,this.notes=[],this.interfaces=[],this.functions=[],this.functions.push(this.setupToolTips.bind(this)),this.namespaces=new Map,this.namespaceCounter=0,this.direction="TB",ht()}getClass(i){return this.classes.get(i)}getClasses(){return this.classes}getRelations(){return this.relations}getNotes(){return this.notes}addRelation(i){Oe.debug("Adding relation: "+JSON.stringify(i));const a=[this.relationType.LOLLIPOP,this.relationType.AGGREGATION,this.relationType.COMPOSITION,this.relationType.DEPENDENCY,this.relationType.EXTENSION];i.relation.type1===this.relationType.LOLLIPOP&&!a.includes(i.relation.type2)?(this.addClass(i.id2),this.addInterface(i.id1,i.id2),i.id1=`interface${this.interfaces.length-1}`):i.relation.type2===this.relationType.LOLLIPOP&&!a.includes(i.relation.type1)?(this.addClass(i.id1),this.addInterface(i.id2,i.id1),i.id2=`interface${this.interfaces.length-1}`):(this.addClass(i.id1),this.addClass(i.id2)),i.id1=this.splitClassNameAndType(i.id1).className,i.id2=this.splitClassNameAndType(i.id2).className,i.relationTitle1=v.sanitizeText(i.relationTitle1.trim(),F()),i.relationTitle2=v.sanitizeText(i.relationTitle2.trim(),F()),this.relations.push(i)}addAnnotation(i,a){const u=this.splitClassNameAndType(i).className;this.classes.get(u).annotations.push(a)}addMember(i,a){this.addClass(i);const u=this.splitClassNameAndType(i).className,l=this.classes.get(u);if(typeof a=="string"){const r=a.trim();r.startsWith("<<")&&r.endsWith(">>")?l.annotations.push(V(r.substring(2,r.length-2))):r.indexOf(")")>0?l.methods.push(new je(r,"method")):r&&l.members.push(new je(r,"attribute"))}}addMembers(i,a){Array.isArray(a)&&(a.reverse(),a.forEach(u=>this.addMember(i,u)))}addNote(i,a){const u={id:`note${this.notes.length}`,class:a,text:i};this.notes.push(u)}cleanupLabel(i){return i.startsWith(":")&&(i=i.substring(1)),V(i.trim())}setCssClass(i,a){i.split(",").forEach(u=>{let l=u;/\d/.exec(u[0])&&(l=pe+l);const r=this.classes.get(l);r&&(r.cssClasses+=" "+a)})}defineClass(i,a){for(const u of i){let l=this.styleClasses.get(u);l===void 0&&(l={id:u,styles:[],textStyles:[]},this.styleClasses.set(u,l)),a&&a.forEach(r=>{if(/color/.exec(r)){const c=r.replace("fill","bgFill");l.textStyles.push(c)}l.styles.push(r)}),this.classes.forEach(r=>{r.cssClasses.includes(u)&&r.styles.push(...a.flatMap(c=>c.split(",")))})}}setTooltip(i,a){i.split(",").forEach(u=>{a!==void 0&&(this.classes.get(u).tooltip=V(a))})}getTooltip(i,a){return a&&this.namespaces.has(a)?this.namespaces.get(a).classes.get(i).tooltip:this.classes.get(i).tooltip}setLink(i,a,u){const l=F();i.split(",").forEach(r=>{let c=r;/\d/.exec(r[0])&&(c=pe+c);const A=this.classes.get(c);A&&(A.link=we.formatUrl(a,l),l.securityLevel==="sandbox"?A.linkTarget="_top":typeof u=="string"?A.linkTarget=V(u):A.linkTarget="_blank")}),this.setCssClass(i,"clickable")}setClickEvent(i,a,u){i.split(",").forEach(l=>{this.setClickFunc(l,a,u),this.classes.get(l).haveCallback=!0}),this.setCssClass(i,"clickable")}setClickFunc(i,a,u){const l=v.sanitizeText(i,F());if(F().securityLevel!=="loose"||a===void 0)return;const c=l;if(this.classes.has(c)){const A=this.lookUpDomId(c);let g=[];if(typeof u=="string"){g=u.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/);for(let D=0;D
\"));\n el.classed(\"hover\", true);\n }).on(\"mouseout\", (event) => {\n tooltipElem.transition().duration(500).style(\"opacity\", 0);\n const el = select(event.currentTarget);\n el.classed(\"hover\", false);\n });\n }, \"setupToolTips\");\n this.direction = \"TB\";\n this.setAccTitle = setAccTitle;\n this.getAccTitle = getAccTitle;\n this.setAccDescription = setAccDescription;\n this.getAccDescription = getAccDescription;\n this.setDiagramTitle = setDiagramTitle;\n this.getDiagramTitle = getDiagramTitle;\n this.getConfig = /* @__PURE__ */ __name(() => getConfig().class, \"getConfig\");\n this.functions.push(this.setupToolTips.bind(this));\n this.clear();\n this.addRelation = this.addRelation.bind(this);\n this.addClassesToNamespace = this.addClassesToNamespace.bind(this);\n this.addNamespace = this.addNamespace.bind(this);\n this.setCssClass = this.setCssClass.bind(this);\n this.addMembers = this.addMembers.bind(this);\n this.addClass = this.addClass.bind(this);\n this.setClassLabel = this.setClassLabel.bind(this);\n this.addAnnotation = this.addAnnotation.bind(this);\n this.addMember = this.addMember.bind(this);\n this.cleanupLabel = this.cleanupLabel.bind(this);\n this.addNote = this.addNote.bind(this);\n this.defineClass = this.defineClass.bind(this);\n this.setDirection = this.setDirection.bind(this);\n this.setLink = this.setLink.bind(this);\n this.bindFunctions = this.bindFunctions.bind(this);\n this.clear = this.clear.bind(this);\n this.setTooltip = this.setTooltip.bind(this);\n this.setClickEvent = this.setClickEvent.bind(this);\n this.setCssStyle = this.setCssStyle.bind(this);\n }\n static {\n __name(this, \"ClassDB\");\n }\n splitClassNameAndType(_id) {\n const id = common_default.sanitizeText(_id, getConfig());\n let genericType = \"\";\n let className = id;\n if (id.indexOf(\"~\") > 0) {\n const split = id.split(\"~\");\n className = sanitizeText2(split[0]);\n genericType = sanitizeText2(split[1]);\n }\n return { className, type: genericType };\n }\n setClassLabel(_id, label) {\n const id = common_default.sanitizeText(_id, getConfig());\n if (label) {\n label = sanitizeText2(label);\n }\n const { className } = this.splitClassNameAndType(id);\n this.classes.get(className).label = label;\n this.classes.get(className).text = `${label}${this.classes.get(className).type ? `<${this.classes.get(className).type}>` : \"\"}`;\n }\n /**\n * Function called by parser when a node definition has been found.\n *\n * @param id - ID of the class to add\n * @public\n */\n addClass(_id) {\n const id = common_default.sanitizeText(_id, getConfig());\n const { className, type } = this.splitClassNameAndType(id);\n if (this.classes.has(className)) {\n return;\n }\n const name = common_default.sanitizeText(className, getConfig());\n this.classes.set(name, {\n id: name,\n type,\n label: name,\n text: `${name}${type ? `<${type}>` : \"\"}`,\n shape: \"classBox\",\n cssClasses: \"default\",\n methods: [],\n members: [],\n annotations: [],\n styles: [],\n domId: MERMAID_DOM_ID_PREFIX + name + \"-\" + classCounter\n });\n classCounter++;\n }\n addInterface(label, classId) {\n const classInterface = {\n id: `interface${this.interfaces.length}`,\n label,\n classId\n };\n this.interfaces.push(classInterface);\n }\n /**\n * Function to lookup domId from id in the graph definition.\n *\n * @param id - class ID to lookup\n * @public\n */\n lookUpDomId(_id) {\n const id = common_default.sanitizeText(_id, getConfig());\n if (this.classes.has(id)) {\n return this.classes.get(id).domId;\n }\n throw new Error(\"Class not found: \" + id);\n }\n clear() {\n this.relations = [];\n this.classes = /* @__PURE__ */ new Map();\n this.notes = [];\n this.interfaces = [];\n this.functions = [];\n this.functions.push(this.setupToolTips.bind(this));\n this.namespaces = /* @__PURE__ */ new Map();\n this.namespaceCounter = 0;\n this.direction = \"TB\";\n clear();\n }\n getClass(id) {\n return this.classes.get(id);\n }\n getClasses() {\n return this.classes;\n }\n getRelations() {\n return this.relations;\n }\n getNotes() {\n return this.notes;\n }\n addRelation(classRelation) {\n log.debug(\"Adding relation: \" + JSON.stringify(classRelation));\n const invalidTypes = [\n this.relationType.LOLLIPOP,\n this.relationType.AGGREGATION,\n this.relationType.COMPOSITION,\n this.relationType.DEPENDENCY,\n this.relationType.EXTENSION\n ];\n if (classRelation.relation.type1 === this.relationType.LOLLIPOP && !invalidTypes.includes(classRelation.relation.type2)) {\n this.addClass(classRelation.id2);\n this.addInterface(classRelation.id1, classRelation.id2);\n classRelation.id1 = `interface${this.interfaces.length - 1}`;\n } else if (classRelation.relation.type2 === this.relationType.LOLLIPOP && !invalidTypes.includes(classRelation.relation.type1)) {\n this.addClass(classRelation.id1);\n this.addInterface(classRelation.id2, classRelation.id1);\n classRelation.id2 = `interface${this.interfaces.length - 1}`;\n } else {\n this.addClass(classRelation.id1);\n this.addClass(classRelation.id2);\n }\n classRelation.id1 = this.splitClassNameAndType(classRelation.id1).className;\n classRelation.id2 = this.splitClassNameAndType(classRelation.id2).className;\n classRelation.relationTitle1 = common_default.sanitizeText(\n classRelation.relationTitle1.trim(),\n getConfig()\n );\n classRelation.relationTitle2 = common_default.sanitizeText(\n classRelation.relationTitle2.trim(),\n getConfig()\n );\n this.relations.push(classRelation);\n }\n /**\n * Adds an annotation to the specified class Annotations mark special properties of the given type\n * (like 'interface' or 'service')\n *\n * @param className - The class name\n * @param annotation - The name of the annotation without any brackets\n * @public\n */\n addAnnotation(className, annotation) {\n const validatedClassName = this.splitClassNameAndType(className).className;\n this.classes.get(validatedClassName).annotations.push(annotation);\n }\n /**\n * Adds a member to the specified class\n *\n * @param className - The class name\n * @param member - The full name of the member. If the member is enclosed in `<1&&arguments[1]!==void 0?arguments[1]:0,a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,n=1/0,i=t;i1&&arguments[1]!==void 0?arguments[1]:0,a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,n=-1/0,i=t;i1&&arguments[1]!==void 0?arguments[1]:0,a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,n=0,i=0,s=t;s1&&arguments[1]!==void 0?arguments[1]:0,a=arguments.length>2&&arguments[2]!==void 0?arguments[2]:e.length,n=arguments.length>3&&arguments[3]!==void 0?arguments[3]:!0,i=arguments.length>4&&arguments[4]!==void 0?arguments[4]:!0,s=arguments.length>5&&arguments[5]!==void 0?arguments[5]:!0;n?e=e.slice(t,a):(a1&&arguments[1]!==void 0?arguments[1]:!0,a=this[0],n=a.cy();if(n.styleEnabled()&&a){a._private.styleDirty&&(a._private.styleDirty=!1,n.style().apply(a));var i=a._private.style[e];return i??(t?n.style().getDefaultProperty(e):null)}},numericStyle:function(e){var t=this[0];if(t.cy().styleEnabled()&&t){var a=t.pstyle(e);return a.pfValue!==void 0?a.pfValue:a.value}},numericStyleUnits:function(e){var t=this[0];if(t.cy().styleEnabled()&&t)return t.pstyle(e).units},renderedStyle:function(e){var t=this.cy();if(!t.styleEnabled())return this;var a=this[0];if(a)return t.style().getRenderedStyle(a,e)},style:function(e,t){var a=this.cy();if(!a.styleEnabled())return this;var n=!1,i=a.style();if(Le(e)){var s=e;i.applyBypass(this,s,n),this.emitAndNotify("style")}else if(ge(e))if(t===void 0){var o=this[0];return o?i.getStylePropertyValue(o,e):void 0}else i.applyBypass(this,e,t,n),this.emitAndNotify("style");else if(e===void 0){var l=this[0];return l?i.getRawStyle(l):void 0}return this},removeStyle:function(e){var t=this.cy();if(!t.styleEnabled())return this;var a=!1,n=t.style(),i=this;if(e===void 0)for(var s=0;s=s?f(p+1):v(g+1)}var m=i.w/u,b=i.h/l;if(e.condense&&(m=0,b=0),e.avoidOverlap)for(var w=0;w