├── .gitignore ├── .npmrc ├── .DS_Store ├── packages ├── example │ ├── src │ │ ├── vite-env.d.ts │ │ ├── pages │ │ │ ├── model-list.css │ │ │ ├── result.tsx │ │ │ ├── functions.tsx │ │ │ ├── keywords.tsx │ │ │ └── model-list.tsx │ │ ├── context.ts │ │ ├── main.tsx │ │ ├── data │ │ │ ├── hint.ts │ │ │ ├── function.ts │ │ │ ├── operation.ts │ │ │ └── model.ts │ │ ├── component │ │ │ ├── function.tsx │ │ │ ├── operation.tsx │ │ │ └── model-field.tsx │ │ ├── assets │ │ │ └── react.svg │ │ └── App.tsx │ ├── tsconfig.node.json │ ├── vite.config.ts │ ├── tailwind.config.js │ ├── .gitignore │ ├── index.html │ ├── tsconfig.json │ ├── package.json │ └── public │ │ └── vite.svg ├── .DS_Store └── bp-script-editor │ ├── src │ ├── index.ts │ ├── plugin │ │ ├── base-theme.ts │ │ ├── custom-completions.ts │ │ ├── keywords.ts │ │ ├── functions.ts │ │ ├── placeholders.ts │ │ └── hint.ts │ ├── interface.ts │ ├── common-placeholder-theme.ts │ ├── extensions.ts │ └── editor.tsx │ ├── tsconfig.json │ ├── dev.rollup.config.js │ ├── prod.rollup.config.js │ ├── package.json │ ├── build │ └── index.d.ts │ └── package-lock.json ├── pnpm-workspace.yaml ├── .vscode └── settings.json ├── .github └── workflows │ └── main.yml ├── package.json └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | strict-peer-dependencies=false -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbfu/bp-script-editor/HEAD/.DS_Store -------------------------------------------------------------------------------- /packages/example/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | # 所有在 packages/ 子目录下的 package 3 | - 'packages/**' -------------------------------------------------------------------------------- /packages/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dbfu/bp-script-editor/HEAD/packages/.DS_Store -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "\"typescript.tsdk\": \"./node_modules/typescript/lib\"" 3 | } -------------------------------------------------------------------------------- /packages/example/src/pages/model-list.css: -------------------------------------------------------------------------------- 1 | .model-list .selected { 2 | background-color: rgba(36, 116, 255, 0.1); 3 | color: rgb(36, 116, 255); 4 | } -------------------------------------------------------------------------------- /packages/example/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "ESNext", 5 | "moduleResolution": "Node", 6 | "allowSyntheticDefaultImports": true 7 | }, 8 | "include": ["vite.config.ts"] 9 | } 10 | -------------------------------------------------------------------------------- /packages/example/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | import WindiCSS from 'vite-plugin-windicss' 4 | 5 | // https://vitejs.dev/config/ 6 | export default defineConfig({ 7 | base: './', 8 | plugins: [react(), WindiCSS()], 9 | }) 10 | -------------------------------------------------------------------------------- /packages/example/src/context.ts: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { ScriptEditorRef } from '@byteplan/bp-script-editor'; 3 | 4 | export interface ContextType { 5 | editorRef: React.RefObject | null; 6 | } 7 | 8 | export const GlobalContext = React.createContext({ 9 | editorRef: null, 10 | }); 11 | -------------------------------------------------------------------------------- /packages/example/tailwind.config.js: -------------------------------------------------------------------------------- 1 | 2 | import { defineConfig } from 'windicss/helpers' 3 | 4 | export default defineConfig({ 5 | theme: { 6 | }, 7 | preflight: false, 8 | plugins: [], 9 | extract: { 10 | include: ['**/*.{jsx,js,ts,tsx,css,html}'], 11 | exclude: ['node_modules', '.git', '.next'], 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /packages/bp-script-editor/src/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './editor' 2 | export { CommonPlaceholderThemes } from './common-placeholder-theme' 3 | export { 4 | FunctionType, 5 | CommonPlaceholderTheme, 6 | CompletionsType, 7 | ScriptEditorRef, 8 | PlaceholderThemesType, 9 | HintPathType, 10 | } from './interface' 11 | 12 | 13 | -------------------------------------------------------------------------------- /packages/example/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App' 4 | 5 | import 'antd/dist/reset.css'; 6 | 7 | import 'virtual:windi.css' 8 | 9 | 10 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( 11 | 12 | 13 | , 14 | ) 15 | -------------------------------------------------------------------------------- /packages/example/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /packages/bp-script-editor/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react", 4 | "allowSyntheticDefaultImports": true, 5 | "allowJs": true, 6 | "importHelpers": true, 7 | "module": "es2015", 8 | "moduleResolution": "node", 9 | "target": "es6" 10 | }, 11 | "include": ["./src/*.ts", "./src/*.tsx", "./src/*.js"], 12 | "exclude": ["node_modules"] 13 | } 14 | -------------------------------------------------------------------------------- /packages/example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 脚本编辑器 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/bp-script-editor/src/plugin/base-theme.ts: -------------------------------------------------------------------------------- 1 | import { 2 | EditorView, 3 | } from '@codemirror/view'; 4 | 5 | export const baseTheme: any = EditorView.baseTheme({ 6 | '&.cm-editor': { 7 | fontSize: '15px', 8 | }, 9 | '&.cm-editor.cm-focused': { 10 | outline: 'none', 11 | }, 12 | '&.cm-editor .cm-gutterElement': { 13 | lineHeight: '28px', 14 | }, 15 | '&.cm-editor .cm-line': { 16 | lineHeight: '28px', 17 | }, 18 | '&.cm-editor .ͼt .ͼs': { 19 | color: '#d73a49', 20 | }, 21 | }); -------------------------------------------------------------------------------- /packages/example/src/data/hint.ts: -------------------------------------------------------------------------------- 1 | import { HintPathType } from '@byteplan/bp-script-editor'; 2 | 3 | export const hintPaths: HintPathType[] = [{ 4 | label: 'user', 5 | template: 'user', 6 | detail: '用户', 7 | type: 'variable', 8 | children: [{ 9 | label: 'department', 10 | template: 'department', 11 | detail: '部门', 12 | type: 'property', 13 | children: [{ 14 | label: 'name', 15 | template: 'name', 16 | detail: '名称', 17 | type: 'property', 18 | }], 19 | }], 20 | }] -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI Github Pages 2 | on: 3 | push: 4 | branches: 5 | - main 6 | jobs: 7 | build-and-deploy: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v3 11 | - uses: pnpm/action-setup@v2.1.0 12 | with: 13 | version: 7.2.1 14 | - name: Install ️ 15 | run: pnpm install --no-frozen-lockfile 16 | - name: Build 17 | run: npm run build:example 18 | 19 | - name: Deploy 20 | uses: JamesIves/github-pages-deploy-action@v4.3.3 21 | with: 22 | branch: gh-pages 23 | folder: packages/example/dist 24 | 25 | -------------------------------------------------------------------------------- /packages/example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "useDefineForClassFields": true, 5 | "lib": ["DOM", "DOM.Iterable", "ESNext"], 6 | "allowJs": false, 7 | "skipLibCheck": true, 8 | "esModuleInterop": false, 9 | "allowSyntheticDefaultImports": true, 10 | "strict": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "module": "ESNext", 13 | "moduleResolution": "Node", 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "noEmit": true, 17 | "jsx": "react-jsx" 18 | }, 19 | "include": ["src"], 20 | "references": [{ "path": "./tsconfig.node.json" }] 21 | } 22 | -------------------------------------------------------------------------------- /packages/bp-script-editor/src/plugin/custom-completions.ts: -------------------------------------------------------------------------------- 1 | import { snippetCompletion } from '@codemirror/autocomplete'; 2 | import { CompletionsType } from '../interface'; 3 | 4 | export function customCompletions(completions: CompletionsType[]) { 5 | return (context: any) => { 6 | let word = context.matchBefore(/\w*/); 7 | if (word.from == word.to && !context.explicit) return null; 8 | return { 9 | from: word.from, 10 | options: completions?.map((item) => ( 11 | snippetCompletion(item.template, { 12 | label: item.label, 13 | detail: item.detail, 14 | type: item.type, 15 | }) 16 | )) || [], 17 | }; 18 | } 19 | } -------------------------------------------------------------------------------- /packages/example/src/data/function.ts: -------------------------------------------------------------------------------- 1 | import { FunctionType } from '@byteplan/bp-script-editor'; 2 | 3 | 4 | export const functions: FunctionType[] = [ 5 | { 6 | label: 'if', 7 | template: 'func.if(${p}, ${v1}, ${v2})', 8 | detail: 9 | '判断函数,p为条件,当p为真的时候,返回v1,当p为假的时候,返回v2', 10 | type: 'function', 11 | handle: `(p, v1, v2) => { 12 | return p ? v1 : v2; 13 | }`, 14 | }, 15 | { 16 | label: 'sum', 17 | template: 'func.sum(${num1}, ${num2}, ${num3}, ${...})', 18 | detail: '求和函数,把所有参数加一起返回', 19 | type: 'function', 20 | handle: `(...args) => { 21 | return args.reduce((prev, cur) => { 22 | return prev + +cur; 23 | }, 0); 24 | }`, 25 | }, 26 | ] -------------------------------------------------------------------------------- /packages/example/src/data/operation.ts: -------------------------------------------------------------------------------- 1 | import { CompletionsType } from '@byteplan/bp-script-editor'; 2 | 3 | export const operations: CompletionsType[] = [ 4 | { 5 | label: '==', 6 | template: '== ', 7 | detail: '判断两遍是否相等', 8 | type: 'keyword', 9 | }, 10 | { 11 | label: '!=', 12 | template: '!= ', 13 | detail: '判断两遍是否不相等', 14 | type: 'keyword', 15 | }, 16 | { 17 | label: '+', 18 | template: '+ ', 19 | detail: '加', 20 | type: 'keyword', 21 | }, 22 | { 23 | label: '-', 24 | template: '- ', 25 | detail: '减', 26 | type: 'keyword', 27 | }, 28 | { 29 | label: '*', 30 | template: '* ', 31 | detail: '乘', 32 | type: 'keyword', 33 | }, 34 | { 35 | label: '/', 36 | template: '/ ', 37 | detail: '除', 38 | type: 'keyword', 39 | }, 40 | ] -------------------------------------------------------------------------------- /packages/example/src/data/model.ts: -------------------------------------------------------------------------------- 1 | 2 | export interface Model { 3 | code: string, 4 | name: string; 5 | children?: Model[]; 6 | type: "model" | "field"; 7 | value?: any; 8 | } 9 | 10 | export const models: Model[] = [ 11 | { 12 | code: 'user', 13 | name: '用户', 14 | type: 'model', 15 | children: [ 16 | { 17 | name: 'id', 18 | code: 'id', 19 | type: 'field', 20 | value: 1, 21 | }, 22 | { 23 | name: '姓名', 24 | code: 'name', 25 | type: 'field', 26 | value: '张三', 27 | }, 28 | { 29 | name: '年龄', 30 | code: 'age', 31 | type: 'field', 32 | value: 18, 33 | }, 34 | { 35 | name: '性别', 36 | code: 'sex', 37 | type: 'field', 38 | value: 1, 39 | }, 40 | ], 41 | }, 42 | ] -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bp-script-editor", 3 | "version": "1.0.0", 4 | "description": "在线公式脚本编辑器", 5 | "main": "index.js", 6 | "homepage": "https://dbfu.github.io/bp-script-editor", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1", 9 | "build": "pnpm --filter '@byteplan/bp-script-editor' run build", 10 | "build:example": "pnpm --filter '@byteplan/example' run build", 11 | "dev": "pnpm --filter '@byteplan/example' run dev" 12 | }, 13 | "keywords": [ 14 | "codemirror6", 15 | "script", 16 | "editor" 17 | ], 18 | "author": "876809592@qq.com", 19 | "license": "ISC", 20 | "dependencies": { 21 | "@codemirror/autocomplete": "^6.4.2", 22 | "@uiw/codemirror-theme-github": "^4.19.9", 23 | "react": "^18.2.0", 24 | "react-dom": "^18.2.0", 25 | "rollup": "^3.19.1" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/bp-script-editor/dev.rollup.config.js: -------------------------------------------------------------------------------- 1 | import resolve from '@rollup/plugin-node-resolve'; 2 | import typescript from 'rollup-plugin-typescript2'; 3 | import commonjs from '@rollup/plugin-commonjs'; 4 | import dts from 'rollup-plugin-dts'; 5 | import { defineConfig } from 'rollup' 6 | import clear from 'rollup-plugin-clear'; 7 | 8 | export default defineConfig([{ 9 | input: './src/index.ts', 10 | output: 11 | [ 12 | { 13 | format: "es", 14 | file: "./build/bundle.es.js" 15 | }, 16 | ], 17 | plugins: [ 18 | resolve(), 19 | commonjs(), 20 | typescript(), 21 | clear({ 22 | targets: ['build'] 23 | }), 24 | ], 25 | external: ['react', 'react-dom'] 26 | }, { 27 | input: './src/index.ts', 28 | plugins: [dts()], 29 | output: { 30 | format: 'esm', 31 | file: './build/index.d.ts', 32 | }, 33 | }]); 34 | -------------------------------------------------------------------------------- /packages/bp-script-editor/src/interface.ts: -------------------------------------------------------------------------------- 1 | export interface CompletionsType { 2 | template: string; 3 | label: string; 4 | detail: string; 5 | type: string; 6 | } 7 | 8 | export interface PlaceholderThemesType { 9 | [K: string]: CommonPlaceholderTheme; 10 | } 11 | 12 | export interface FunctionType extends CompletionsType { 13 | handle: any; 14 | } 15 | 16 | export interface CommonPlaceholderTheme { 17 | textColor: string; 18 | backgroudColor: string; 19 | borderColor: string; 20 | } 21 | 22 | export interface ScriptEditorRef { 23 | insertText?: (text: string, isTemplate: boolean) => void; 24 | clearText?: () => void; 25 | setText?: (text: string) => void; 26 | } 27 | 28 | export interface HintPathType { 29 | label: string; 30 | detail: string; 31 | type: 'function' | 'keyword' | 'variable' | 'text' | 'property'; 32 | template: string; 33 | children?: HintPathType[]; 34 | } 35 | -------------------------------------------------------------------------------- /packages/example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@byteplan/example", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "@byteplan/bp-script-editor": "workspace:*", 13 | "@codemirror/lang-javascript": "^6.1.4", 14 | "@codemirror/state": "^6.2.0", 15 | "@types/react-color": "^3.0.6", 16 | "ahooks": "^3.7.5", 17 | "antd": "^5.3.1", 18 | "react": "^18.2.0", 19 | "react-color": "^2.19.3", 20 | "react-colorful": "^5.6.1", 21 | "react-dom": "^18.2.0", 22 | "vite-plugin-windicss": "^1.8.10", 23 | "windicss": "^3.5.6" 24 | }, 25 | "devDependencies": { 26 | "@types/react": "^18.0.28", 27 | "@types/react-dom": "^18.0.11", 28 | "@vitejs/plugin-react": "^3.1.0", 29 | "typescript": "^4.9.3", 30 | "vite": "^4.2.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/example/src/component/function.tsx: -------------------------------------------------------------------------------- 1 | import React, { useContext, FC } from 'react'; 2 | import { Tooltip } from 'antd'; 3 | import { GlobalContext } from '../context'; 4 | import { FunctionType } from '@byteplan/bp-script-editor'; 5 | 6 | interface PropsTypes { 7 | functions: FunctionType[]; 8 | } 9 | 10 | const Function: FC = ({ functions }) => { 11 | const { editorRef } = useContext(GlobalContext); 12 | 13 | return ( 14 |
15 | {functions.map((item) => ( 16 | 17 |
{ 19 | if (editorRef?.current?.insertText) { 20 | editorRef.current.insertText(`${item.template}`, true); 21 | } 22 | }} 23 | className="px-[12px] py-[4px] hover:(bg-[rgba(0,0,0,0.04)]) cursor-pointer rounded-md" 24 | > 25 | {item.label} 26 |
27 |
28 | ))} 29 |
30 | ); 31 | } 32 | 33 | export default Function; 34 | -------------------------------------------------------------------------------- /packages/example/src/component/operation.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC, useContext } from 'react'; 2 | import { Tooltip } from 'antd'; 3 | import { GlobalContext } from '../context'; 4 | import { CompletionsType } from '@byteplan/bp-script-editor'; 5 | 6 | interface PropsType { 7 | operations: CompletionsType[]; 8 | } 9 | 10 | const Operation: FC = ({ operations }) => { 11 | const { editorRef } = useContext(GlobalContext); 12 | 13 | return ( 14 |
15 | {operations.map((item) => ( 16 | 17 |
{ 19 | if (editorRef?.current?.insertText) { 20 | editorRef.current.insertText(item.template, false); 21 | } 22 | }} 23 | className="px-[12px] py-[4px] hover:(bg-[rgba(0,0,0,0.04)]) cursor-pointer rounded-md" 24 | > 25 | {item.label} 26 |
27 |
28 | ))} 29 |
30 | ); 31 | } 32 | 33 | export default Operation; 34 | -------------------------------------------------------------------------------- /packages/bp-script-editor/prod.rollup.config.js: -------------------------------------------------------------------------------- 1 | import resolve from '@rollup/plugin-node-resolve'; 2 | import typescript from 'rollup-plugin-typescript2'; 3 | import commonjs from '@rollup/plugin-commonjs'; 4 | import { terser } from 'rollup-plugin-terser' 5 | import dts from 'rollup-plugin-dts'; 6 | import { defineConfig } from 'rollup' 7 | import clear from 'rollup-plugin-clear'; 8 | 9 | export default defineConfig([{ 10 | input: './src/index.ts', 11 | output: 12 | [ 13 | { 14 | format: 'umd', 15 | name: 'bpScriptEditor', 16 | file: './build/bundle.umd.js' 17 | }, { 18 | format: 'amd', 19 | file: './build/bundle.amd.js' 20 | }, 21 | { 22 | format: 'cjs', 23 | file: './build/bundle.cjs.js' 24 | }, 25 | { 26 | format: "es", 27 | file: "./build/bundle.es.js" 28 | }, 29 | ], 30 | 31 | plugins: [ 32 | terser(), 33 | resolve(), 34 | commonjs(), 35 | typescript(), 36 | clear({ 37 | targets: ['build'] 38 | }), 39 | ], 40 | external: ['react', 'react-dom'] 41 | }, 42 | { 43 | input: './src/index.ts', 44 | plugins: [dts()], 45 | output: { 46 | format: 'esm', 47 | file: './build/index.d.ts', 48 | }, 49 | }]); 50 | -------------------------------------------------------------------------------- /packages/example/src/pages/result.tsx: -------------------------------------------------------------------------------- 1 | import { FC, useEffect } from 'react'; 2 | import { Form, Modal, Input } from 'antd'; 3 | 4 | interface PropType { 5 | formatFunctions: string; 6 | result: string; 7 | open: boolean; 8 | onClose: any; 9 | } 10 | 11 | const RunResult: FC = ({ 12 | formatFunctions, 13 | result, 14 | open, 15 | onClose, 16 | }) => { 17 | 18 | const [form] = Form.useForm(); 19 | 20 | useEffect(() => { 21 | if (open) { 22 | form.resetFields(); 23 | form.setFieldsValue({ 24 | formatFunctions, 25 | result, 26 | }) 27 | } 28 | }, [open]); 29 | 30 | return ( 31 | { onClose() }} 36 | width={800} 37 | > 38 |
44 | 48 | 49 | 50 | 54 | 55 | 56 |
57 | 58 |
59 | ) 60 | } 61 | 62 | export default RunResult; -------------------------------------------------------------------------------- /packages/bp-script-editor/src/common-placeholder-theme.ts: -------------------------------------------------------------------------------- 1 | export const CommonPlaceholderThemes = { 2 | magenta: { 3 | textColor: '#c41d7f', 4 | backgroudColor: '#fff0f6', 5 | borderColor: '#ffadd2', 6 | }, 7 | red: { 8 | textColor: '#cf1322', 9 | backgroudColor: '#fff1f0', 10 | borderColor: '#ffa39e', 11 | }, 12 | volcano: { 13 | textColor: '#d4380d', 14 | backgroudColor: '#fff2e8', 15 | borderColor: '#ffbb96', 16 | }, 17 | orange: { 18 | textColor: '#d46b08', 19 | backgroudColor: '#fff7e6', 20 | borderColor: '#ffd591', 21 | }, 22 | gold: { 23 | textColor: '#d48806', 24 | backgroudColor: '#fffbe6', 25 | borderColor: '#ffe58f', 26 | }, 27 | lime: { 28 | textColor: '#7cb305', 29 | backgroudColor: '#fcffe6', 30 | borderColor: '#eaff8f', 31 | }, 32 | green: { 33 | textColor: '#389e0d', 34 | backgroudColor: '#f6ffed', 35 | borderColor: '#b7eb8f', 36 | }, 37 | cyan: { 38 | textColor: '#08979c', 39 | backgroudColor: '#e6fffb', 40 | borderColor: '#87e8de', 41 | }, 42 | blue: { 43 | textColor: '#0958d9', 44 | backgroudColor: '#e6f4ff', 45 | borderColor: '#91caff', 46 | }, 47 | geekblue: { 48 | textColor: '#1d39c4', 49 | backgroudColor: '#f0f5ff', 50 | borderColor: '#adc6ff', 51 | }, 52 | purple: { 53 | textColor: '#531dab', 54 | backgroudColor: '#f9f0ff', 55 | borderColor: '#d3adf7', 56 | }, 57 | } -------------------------------------------------------------------------------- /packages/example/public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/example/src/component/model-field.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC, useContext, useMemo } from 'react'; 2 | import { Tree } from 'antd'; 3 | 4 | import { GlobalContext } from '../context'; 5 | import { Model } from '../data/model'; 6 | 7 | interface PropsType { 8 | models: Model[]; 9 | placeholderTypes: { 10 | [k: string]: string; 11 | } 12 | } 13 | 14 | 15 | const ModelField: FC = ({ 16 | placeholderTypes, 17 | models, 18 | }) => { 19 | const { editorRef } = useContext(GlobalContext); 20 | 21 | const formatTree = (list: Model[], parent?: any): any[] => { 22 | return list.map((item: Model) => { 23 | const data: any = { 24 | title: item.name, 25 | key: `${parent?.key || ''}${item.code}`, 26 | parent, 27 | code: item.code, 28 | }; 29 | data.children = formatTree(item.children || [], data); 30 | return data; 31 | }); 32 | }; 33 | 34 | const treeData: any[] = useMemo(() => { 35 | return formatTree(models); 36 | }, [models]); 37 | 38 | return ( 39 | { 42 | const text = `[[${placeholderTypes.Field}.${info.node.parent.title}:${info.node.parent.code}.${info.node.title}:${info.node.code}]] `; 43 | if (editorRef?.current?.insertText) { 44 | editorRef?.current?.insertText(text, false); 45 | } 46 | }} 47 | treeData={treeData} 48 | /> 49 | ); 50 | } 51 | 52 | export default ModelField; 53 | -------------------------------------------------------------------------------- /packages/bp-script-editor/src/extensions.ts: -------------------------------------------------------------------------------- 1 | import { autocompletion } from '@codemirror/autocomplete'; 2 | import { EditorView } from '@codemirror/view'; 3 | import { CompletionsType, FunctionType, HintPathType, PlaceholderThemesType } from './interface'; 4 | 5 | import { baseTheme } from './plugin/base-theme'; 6 | import { customCompletions } from './plugin/custom-completions'; 7 | import { functionPlugin } from './plugin/functions'; 8 | import { keywordsPlugin } from './plugin/keywords'; 9 | import { placeholdersPlugin } from './plugin/placeholders'; 10 | import { hintPlugin } from './plugin/hint' 11 | 12 | export const extensions = ({ 13 | completions, 14 | keywords, 15 | placeholderThemes, 16 | mode, 17 | functions, 18 | keywordsColor, 19 | keywordsClassName, 20 | hintPaths, 21 | }: { 22 | keywords?: string[]; 23 | completions: CompletionsType[]; 24 | placeholderThemes: PlaceholderThemesType; 25 | mode: string; 26 | functions: FunctionType[]; 27 | keywordsColor?: string; 28 | keywordsClassName?: string; 29 | hintPaths?: HintPathType[]; 30 | }): any[] => { 31 | return [ 32 | keywords.length ? keywordsPlugin(keywords, keywordsColor, keywordsClassName) : null, 33 | baseTheme, 34 | placeholdersPlugin(placeholderThemes, mode), 35 | EditorView.lineWrapping, 36 | autocompletion({ 37 | override: [ 38 | customCompletions(completions), 39 | hintPaths?.length ? hintPlugin(hintPaths) : null, 40 | ].filter(o => !!o) 41 | }), 42 | functionPlugin(functions), 43 | ].filter(o => !!o); 44 | } 45 | 46 | -------------------------------------------------------------------------------- /packages/bp-script-editor/src/plugin/keywords.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Decoration, 3 | ViewPlugin, 4 | MatchDecorator, 5 | EditorView, 6 | ViewUpdate, 7 | DecorationSet, 8 | } from '@codemirror/view'; 9 | 10 | export const keywordsPlugin = ( 11 | keywords: string[] = [], 12 | keywordsColor?: string, 13 | keywordsClassName?: string, 14 | ) => { 15 | 16 | const regexp = new RegExp(keywords.join('|'), 'g'); 17 | 18 | const keywordsMatcher = new MatchDecorator({ 19 | regexp, 20 | decoration: (match, view, pos) => { 21 | const lineText = view.state.doc.lineAt(pos).text; 22 | const [matchText] = match; 23 | 24 | // 如果当前匹配字段后面一位有值且不是空格的时候,这种情况不能算匹配到,不做处理 25 | if (lineText?.[pos + matchText.length] && lineText?.[pos + matchText.length] !== ' ') { 26 | return Decoration.mark({}); 27 | } 28 | 29 | // 如果当前匹配字段前面一位有值且不是空格的时候,这种情况不能算匹配到,不做处理 30 | if (lineText?.[pos - 1] && lineText?.[pos - 1] !== ' ') { 31 | return Decoration.mark({}); 32 | } 33 | 34 | let style: string; 35 | 36 | if (keywordsColor) { 37 | style = `color: ${keywordsColor};`; 38 | } 39 | 40 | return Decoration.mark({ 41 | attributes: { 42 | style, 43 | }, 44 | class: keywordsClassName, 45 | }); 46 | }, 47 | }); 48 | 49 | return ViewPlugin.fromClass( 50 | class { 51 | keywords: DecorationSet; 52 | constructor(view: EditorView) { 53 | this.keywords = keywordsMatcher.createDeco(view); 54 | } 55 | update(update: ViewUpdate) { 56 | this.keywords = keywordsMatcher.updateDeco( 57 | update, 58 | this.keywords 59 | ); 60 | } 61 | }, 62 | { 63 | decorations: (instance: any) => { 64 | return instance.keywords; 65 | } 66 | } 67 | ); 68 | } 69 | 70 | 71 | -------------------------------------------------------------------------------- /packages/bp-script-editor/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@byteplan/bp-script-editor", 3 | "version": "0.0.8", 4 | "keywords": [ 5 | "script", 6 | "editor" 7 | ], 8 | "author": { 9 | "name": "dbfu" 10 | }, 11 | "scripts": { 12 | "build": "rollup -c ./prod.rollup.config.js", 13 | "dev": "rollup -c ./dev.rollup.config.js -w" 14 | }, 15 | "devDependencies": { 16 | "@babel/core": "^7.20.12", 17 | "@babel/plugin-proposal-class-properties": "^7.18.6", 18 | "@babel/plugin-proposal-decorators": "^7.20.13", 19 | "@babel/plugin-syntax-jsx": "^7.18.6", 20 | "@babel/plugin-transform-react-jsx": "^7.20.13", 21 | "@babel/plugin-transform-runtime": "^7.19.6", 22 | "@babel/preset-env": "^7.20.2", 23 | "@babel/preset-react": "^7.18.6", 24 | "@rollup/plugin-babel": "^6.0.3", 25 | "@rollup/plugin-commonjs": "^24.0.1", 26 | "@rollup/plugin-node-resolve": "^15.0.1", 27 | "@types/react": "^18.0.28", 28 | "rollup": "^3.15.0", 29 | "rollup-plugin-babel": "^4.4.0", 30 | "rollup-plugin-dts": "^5.3.0", 31 | "rollup-plugin-terser": "^7.0.2", 32 | "rollup-plugin-typescript2": "^0.34.1", 33 | "tslib": "^2.5.0", 34 | "typescript": "^5.0.2" 35 | }, 36 | "type": "module", 37 | "main": "build/bundle.cjs.js", 38 | "module": "build/bundle.es.js", 39 | "typings": "build/index.d.ts", 40 | "dependencies": { 41 | "@codemirror/autocomplete": "^6.4.2", 42 | "@codemirror/lang-javascript": "^6.1.4", 43 | "@codemirror/state": "^6.2.0", 44 | "@codemirror/view": "^6.9.2", 45 | "@uiw/codemirror-theme-github": "^4.19.9", 46 | "@uiw/react-codemirror": "^4.19.9", 47 | "react": "^18.2.0", 48 | "react-dom": "^18.2.0", 49 | "rollup-plugin-clear": "^2.0.7" 50 | }, 51 | "files": [ 52 | "build" 53 | ], 54 | "publishConfig": { 55 | "access": "public" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /packages/bp-script-editor/src/plugin/functions.ts: -------------------------------------------------------------------------------- 1 | import { DecorationSet } from '@codemirror/view'; 2 | import { ViewUpdate } from '@codemirror/view'; 3 | import { EditorView, WidgetType } from '@codemirror/view'; 4 | import { 5 | Decoration, 6 | ViewPlugin, 7 | MatchDecorator, 8 | } from '@codemirror/view'; 9 | import { FunctionType } from '../interface'; 10 | 11 | 12 | export const functionPlugin = (functions: FunctionType[]) => { 13 | class FunctionWidget extends WidgetType { 14 | text: string; 15 | 16 | constructor(text: string) { 17 | super(); 18 | this.text = text; 19 | } 20 | 21 | eq(other: FunctionWidget) { 22 | return this.text == other.text; 23 | } 24 | 25 | toDOM() { 26 | const elt = document.createElement('span'); 27 | elt.style.cssText = ` 28 | color: #d73a49; 29 | font-size: 14px; 30 | `; 31 | elt.textContent = this.text; 32 | 33 | const span = document.createElement('span'); 34 | span.style.cssText = 'color: #6a737d;'; 35 | span.textContent = "("; 36 | elt.appendChild(span); 37 | return elt; 38 | } 39 | ignoreEvent() { 40 | return true; 41 | } 42 | } 43 | 44 | const functionMatcher = new MatchDecorator({ 45 | regexp: /func\.(.+?)\(/g, 46 | decoration: (match) => { 47 | const funcName = match[1]; 48 | if (functions.some(o => o.label === funcName)) { 49 | return Decoration.replace({ 50 | widget: new FunctionWidget(`${funcName}`), 51 | }); 52 | } 53 | return null; 54 | }, 55 | }); 56 | 57 | return ViewPlugin.fromClass( 58 | class { 59 | function: DecorationSet; 60 | constructor(view: EditorView) { 61 | this.function = functionMatcher.createDeco(view); 62 | } 63 | update(update: ViewUpdate) { 64 | this.function = functionMatcher.updateDeco( 65 | update, 66 | this.function 67 | ); 68 | } 69 | }, 70 | { 71 | decorations: (instance: any) => { 72 | return instance.function; 73 | }, 74 | provide: (plugin: ViewPlugin) => 75 | EditorView.atomicRanges.of((view) => { 76 | return view.plugin(plugin)?.function || Decoration.none; 77 | }), 78 | } 79 | ); 80 | } 81 | 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 组件demo地址: 2 | 3 | # 组件使用文档 4 | 5 | 1. 安装依赖 6 | 7 | ``` jsx 8 | npm i @byteplan/bp-script-editor 9 | yarn add @byteplan/bp-script-editor 10 | pnpm i @byteplan/bp-script-editor 11 | ``` 12 | 13 | 2. 代码示例 14 | 15 | ``` jsx 16 | import Editor from '@byteplan/bp-script-editor'; 17 | 18 | 31 | ``` 32 | 33 | 3. 属性说明 34 | 35 | | 属性 | 说明 | 数据格式 36 | | ---- | ---- | ---- 37 | | completions | 自动补全定义的数据 | [CompletionsType[]](#completionstype) 38 | | keywords | 关键字 | string[] 39 | | keywordsColor | 关键字颜色 支持#ffffff或white格式 | string 40 | | keywordsClassName | 关键字类名 | string 41 | | height | 高度 | string 42 | | width | 宽度 | string 43 | | placeholderThemes | 占位符类型主题 | [PlaceholderThemesType](#placeholderthemestype) 44 | | defaultValue | 默认值 | string 45 | | functions | 函数 | [CompletionsType[]](#completionstype) 46 | | mode | 模式 | code | name 47 | | hintPaths | 代码提示 | [[HintPathType]](#hintpathtype) 48 | | onValueChange | 值改变的回调 | (value: string) => void 49 | 50 | 4. 方法 51 | 52 | | 名称 | 说明 | 参数 53 | | ---- | ---- | ---- 54 | | insertText | 插入文本 | (text, isTemplate) => void,有类似${}这样的占位符,需要把isTemplate设置为true 55 | | clearText | 清空文本 | () => void 56 | | setText | 设置文本 | (text) => void,会把编辑器的内容使用text替换掉 57 | 58 | # CompletionsType 59 | 60 | ```js 61 | template: string; // 自动插入时补全的文本 62 | label: string; // 要匹配的文本 63 | detail: string; // 描述 64 | type: string; // 类型 65 | ``` 66 | 67 | # PlaceholderThemesType 68 | 69 | ```js 70 | [K: string]: CommonPlaceholderTheme; 71 | ``` 72 | 73 | # CommonPlaceholderTheme 74 | 75 | ```js 76 | textColor: string; 77 | backgroudColor: string; 78 | borderColor: string; 79 | ``` 80 | 81 | # CompletionsType 82 | 83 | ```js 84 | template: string; 85 | label: string; 86 | detail: string; 87 | type: string; 88 | ``` 89 | 90 | # HintPathType 91 | 92 | ```js 93 | label: string; 94 | detail: string; 95 | type: 'function' | 'keyword' | 'variable' | 'text' | 'property'; 96 | template: string; 97 | children?: HintPathType[]; 98 | ``` 99 | -------------------------------------------------------------------------------- /packages/bp-script-editor/src/plugin/placeholders.ts: -------------------------------------------------------------------------------- 1 | import { ViewUpdate } from '@codemirror/view'; 2 | import { DecorationSet } from '@codemirror/view'; 3 | import { 4 | Decoration, 5 | ViewPlugin, 6 | MatchDecorator, 7 | EditorView, 8 | WidgetType, 9 | } from '@codemirror/view'; 10 | 11 | import { PlaceholderThemesType } from '../interface'; 12 | 13 | export const placeholdersPlugin = (themes: PlaceholderThemesType, mode: string = 'name') => { 14 | 15 | class PlaceholderWidget extends WidgetType { 16 | curFlag: string; 17 | text: string; 18 | 19 | constructor(text: string) { 20 | super(); 21 | if (text) { 22 | const [curFlag, ...texts] = text.split('.'); 23 | if (curFlag && texts.length) { 24 | this.text = texts.map(t => t.split(':')[mode === 'code' ? 1 : 0]).join('.'); 25 | this.curFlag = curFlag; 26 | } 27 | } 28 | } 29 | 30 | eq(other: PlaceholderWidget) { 31 | return this.text == other.text; 32 | } 33 | 34 | toDOM() { 35 | let elt = document.createElement('span'); 36 | if (!this.text) return elt; 37 | 38 | const { backgroudColor, borderColor, textColor } = themes[this.curFlag]; 39 | elt.style.cssText = ` 40 | border: 1px solid ${borderColor}; 41 | border-radius: 4px; 42 | line-height: 20px; 43 | background: ${backgroudColor}; 44 | color: ${textColor}; 45 | font-size: 12px; 46 | padding: 2px 7px; 47 | user-select: none; 48 | `; 49 | elt.textContent = this.text; 50 | return elt; 51 | } 52 | ignoreEvent() { 53 | return true; 54 | } 55 | } 56 | 57 | const placeholderMatcher = new MatchDecorator({ 58 | regexp: /\[\[(.+?)\]\]/g, 59 | decoration: (match) => { 60 | return Decoration.replace({ 61 | widget: new PlaceholderWidget(match[1]), 62 | }); 63 | }, 64 | }); 65 | 66 | return ViewPlugin.fromClass( 67 | class { 68 | placeholders: DecorationSet; 69 | constructor(view: EditorView) { 70 | this.placeholders = placeholderMatcher.createDeco(view); 71 | } 72 | update(update: ViewUpdate) { 73 | this.placeholders = placeholderMatcher.updateDeco( 74 | update, 75 | this.placeholders 76 | ); 77 | } 78 | }, 79 | { 80 | decorations: (instance: any) => { 81 | return instance.placeholders; 82 | }, 83 | provide: (plugin: any) => 84 | EditorView.atomicRanges.of((view: any) => { 85 | return view.plugin(plugin)?.placeholders || Decoration.none; 86 | }), 87 | } 88 | ); 89 | } 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /packages/example/src/pages/functions.tsx: -------------------------------------------------------------------------------- 1 | import { FC, useMemo, useState } from 'react' 2 | import { Button, Drawer, Form, Table, Modal, Input } from 'antd' 3 | import { FunctionType } from '@byteplan/bp-script-editor'; 4 | 5 | interface PropsType { 6 | open: boolean; 7 | functions: FunctionType[]; 8 | onChange: any; 9 | onClose: any; 10 | } 11 | 12 | const Functions: FC = ({ 13 | open, 14 | functions, 15 | onChange, 16 | onClose, 17 | }) => { 18 | 19 | const [form] = Form.useForm(); 20 | const [formOpen, setFormOpen] = useState(false); 21 | 22 | const columns = useMemo(() => { 23 | return [{ 24 | dataIndex: 'label', 25 | title: '名称', 26 | }, { 27 | dataIndex: 'template', 28 | title: '模版', 29 | }, { 30 | dataIndex: 'detail', 31 | title: '描述', 32 | }, { 33 | dataIndex: 'handle', 34 | title: '实现', 35 | }] 36 | }, []) 37 | 38 | const finish = (values: any) => { 39 | onChange([ 40 | { 41 | ...values, 42 | type: 'function', 43 | }, 44 | ...functions 45 | ]); 46 | setFormOpen(false); 47 | } 48 | 49 | return ( 50 | 57 | 66 | 73 | { 77 | setFormOpen(false); 78 | }} 79 | width={640} 80 | onOk={() => { form.submit() }} 81 | > 82 |
88 | 92 | 93 | 94 | 98 | 99 | 100 | 104 | 105 | 106 | 110 | 111 | 112 | 113 |
114 | 115 | ) 116 | } 117 | 118 | export default Functions; -------------------------------------------------------------------------------- /packages/bp-script-editor/build/index.d.ts: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Extension } from '@codemirror/state'; 3 | 4 | interface CompletionsType { 5 | template: string; 6 | label: string; 7 | detail: string; 8 | type: string; 9 | } 10 | interface PlaceholderThemesType { 11 | [K: string]: CommonPlaceholderTheme; 12 | } 13 | interface FunctionType extends CompletionsType { 14 | handle: any; 15 | } 16 | interface CommonPlaceholderTheme { 17 | textColor: string; 18 | backgroudColor: string; 19 | borderColor: string; 20 | } 21 | interface ScriptEditorRef { 22 | insertText?: (text: string, isTemplate: boolean) => void; 23 | clearText?: () => void; 24 | setText?: (text: string) => void; 25 | } 26 | interface HintPathType { 27 | label: string; 28 | detail: string; 29 | type: 'function' | 'keyword' | 'variable' | 'text' | 'property'; 30 | template: string; 31 | children?: HintPathType[]; 32 | } 33 | 34 | interface PropsType { 35 | completions: CompletionsType[]; 36 | keywords?: string[]; 37 | onValueChange?: (value: string) => void; 38 | placeholderThemes: PlaceholderThemesType; 39 | mode: string; 40 | functions: FunctionType[]; 41 | height?: string; 42 | width?: string; 43 | keywordsClassName?: string; 44 | keywordsColor?: string; 45 | defaultValue?: string; 46 | hintPaths?: HintPathType[]; 47 | extensions?: Extension[]; 48 | } 49 | declare const _default: React.ForwardRefExoticComponent>; 50 | 51 | declare const CommonPlaceholderThemes: { 52 | magenta: { 53 | textColor: string; 54 | backgroudColor: string; 55 | borderColor: string; 56 | }; 57 | red: { 58 | textColor: string; 59 | backgroudColor: string; 60 | borderColor: string; 61 | }; 62 | volcano: { 63 | textColor: string; 64 | backgroudColor: string; 65 | borderColor: string; 66 | }; 67 | orange: { 68 | textColor: string; 69 | backgroudColor: string; 70 | borderColor: string; 71 | }; 72 | gold: { 73 | textColor: string; 74 | backgroudColor: string; 75 | borderColor: string; 76 | }; 77 | lime: { 78 | textColor: string; 79 | backgroudColor: string; 80 | borderColor: string; 81 | }; 82 | green: { 83 | textColor: string; 84 | backgroudColor: string; 85 | borderColor: string; 86 | }; 87 | cyan: { 88 | textColor: string; 89 | backgroudColor: string; 90 | borderColor: string; 91 | }; 92 | blue: { 93 | textColor: string; 94 | backgroudColor: string; 95 | borderColor: string; 96 | }; 97 | geekblue: { 98 | textColor: string; 99 | backgroudColor: string; 100 | borderColor: string; 101 | }; 102 | purple: { 103 | textColor: string; 104 | backgroudColor: string; 105 | borderColor: string; 106 | }; 107 | }; 108 | 109 | export { CommonPlaceholderTheme, CommonPlaceholderThemes, CompletionsType, FunctionType, HintPathType, PlaceholderThemesType, ScriptEditorRef, _default as default }; 110 | -------------------------------------------------------------------------------- /packages/bp-script-editor/src/plugin/hint.ts: -------------------------------------------------------------------------------- 1 | import { CompletionContext, snippetCompletion } from '@codemirror/autocomplete'; 2 | import { HintPathType } from '../interface' 3 | 4 | export const hintPlugin = (hintPaths: HintPathType[]) => { 5 | return (context: CompletionContext) => { 6 | // 匹配当前输入前面的所有非空字符 7 | const word = context.matchBefore(/\S*/); 8 | 9 | // 判断如果为空,则返回null 10 | if (!word || (word.from == word.to && !context.explicit)) return null; 11 | 12 | // 获取最后一个字符 13 | const latestChar = word.text[word.text.length - 1]; 14 | 15 | // 获取当前输入行所有文本 16 | const curLineText = context.state.doc.lineAt(context.pos).text; 17 | 18 | let path: string = ''; 19 | 20 | // 从当前字符往前遍历,直到遇到空格或前面没有字符了,把遍历的字符串存起来 21 | for (let i = word.to; i >= 0; i -= 1) { 22 | if (i === 0) { 23 | path = curLineText.slice(i, word.to); 24 | break; 25 | } 26 | if (curLineText[i] === ' ') { 27 | // 这里加1,是为了把前面的空格去掉 28 | path = curLineText.slice(i + 1, word.to); 29 | break; 30 | } 31 | } 32 | 33 | if (!path) return null; 34 | 35 | // 下面返回提示的数组一共有三种情况 36 | 37 | // 第一种:得到的字符串中没有.,并且最后一个输入的字符不是点。 38 | // 直接把定义提示数组的所有根节点返回 39 | 40 | // 第二种:字符串有.,并且最后一个输入的字符不是点。 41 | // 首先用.分割字符串得到字符串数组,把最后一个数组元素删除,然后遍历数组,根据路径获取当前对象的children,然后格式化返回。 42 | // 这里返回值里面的from字段有个坑,form其实就是你当前需要匹配字段的开始位置,假设你输入user.na,实际上这个form是n的位置, 43 | // to是a的位置,所以我这里给form处理了一下 44 | 45 | // 第三种:最后一个输入的字符是点 46 | // 和第二种情况处理方法差不多,区别就是不用删除数组最后一个元素,并且格式化的时候,需要给label前面补上.,然后才能匹配上。 47 | 48 | if (!path.includes('.') && latestChar !== '.') { 49 | return { 50 | from: word.from, 51 | options: hintPaths?.map?.((item: any) => ( 52 | snippetCompletion(`${item.label}`, { 53 | label: `${item.label}`, 54 | detail: item.detail, 55 | type: item.type, 56 | }) 57 | )) || [], 58 | }; 59 | } else if (path.includes('.') && latestChar !== '.') { 60 | const paths = path.split('.').filter(o => o); 61 | const cur = paths.pop() || ''; 62 | 63 | let temp: any = hintPaths; 64 | paths.forEach(p => { 65 | temp = temp.find((o: any) => o.label === p)?.children || []; 66 | }); 67 | 68 | return { 69 | from: word.to - cur.length, 70 | to: word.to, 71 | options: temp?.map?.((item: any) => ( 72 | snippetCompletion(`${item.label}`, { 73 | label: `${item.label}`, 74 | detail: item.detail, 75 | type: item.type, 76 | }) 77 | )) || [], 78 | }; 79 | } else if (latestChar === '.') { 80 | const paths = path.split('.').filter(o => o); 81 | if (!paths.length) return null; 82 | 83 | let temp: any = hintPaths; 84 | paths.forEach(p => { 85 | temp = temp.find((o: any) => o.label === p)?.children || []; 86 | }); 87 | 88 | return { 89 | from: word.to - 1, 90 | to: word.to, 91 | options: temp?.map?.((item: any) => ( 92 | snippetCompletion(`.${item.label}`, { 93 | label: `.${item.label}`, 94 | detail: item.detail, 95 | type: item.type, 96 | }) 97 | )) || [], 98 | }; 99 | } 100 | return null; 101 | }; 102 | } 103 | -------------------------------------------------------------------------------- /packages/example/src/pages/keywords.tsx: -------------------------------------------------------------------------------- 1 | import { FC, useState, useRef, useEffect } from 'react' 2 | import { Modal, Tag, Input, InputRef } from 'antd' 3 | import { HexColorPicker } from 'react-colorful'; 4 | 5 | export interface KeywordsConfigType { 6 | keywords: string[]; 7 | color: string; 8 | } 9 | 10 | interface PropsType { 11 | open: boolean; 12 | onChange?: any; 13 | keywordsConfig: KeywordsConfigType; 14 | onClose: any; 15 | } 16 | 17 | const Keywords: FC = ({ 18 | open, 19 | onChange, 20 | keywordsConfig, 21 | onClose, 22 | }) => { 23 | 24 | const [color, setColor] = useState(keywordsConfig.color); 25 | const [inputVisible, setInputVisible] = useState(false); 26 | const inputRef = useRef(null); 27 | const [inputValue, setInputValue] = useState(); 28 | const [localkeywords, setLocalkeywords] = useState(keywordsConfig.keywords) 29 | 30 | const onColorChange = (newColor: string) => { 31 | setColor(newColor); 32 | } 33 | 34 | const handleClose = (removedTag: string) => { 35 | const newTags = localkeywords.filter((word) => word !== removedTag); 36 | console.log(newTags); 37 | setLocalkeywords(newTags); 38 | }; 39 | 40 | const handleInputChange = (e: React.ChangeEvent) => { 41 | setInputValue(e.target.value); 42 | }; 43 | 44 | const handleInputConfirm = () => { 45 | if (inputValue && !localkeywords.includes(inputValue)) { 46 | setLocalkeywords(prev => [...prev, inputValue]); 47 | } 48 | setInputVisible(false); 49 | setInputValue(''); 50 | }; 51 | 52 | useEffect(() => { 53 | if (inputVisible) { 54 | inputRef.current?.focus(); 55 | } 56 | }, [inputVisible]); 57 | 58 | return ( 59 | { 63 | onChange({ 64 | color, 65 | keywords: localkeywords, 66 | }); 67 | onClose(); 68 | }} 69 | onCancel={() => { 70 | onClose(); 71 | }} 72 | > 73 |
74 |
颜色:
75 |
76 | 77 |
78 |
79 |
80 |
关键字:
81 |
82 | {localkeywords.map(item => ( 83 | { 87 | e.preventDefault(); 88 | handleClose(item); 89 | }} 90 | > 91 | {item} 92 | 93 | ))} 94 | { 95 | inputVisible ? ( 96 | ) : ( 106 | { 108 | setInputVisible(true); 109 | }} 110 | className="cursor-pointer" 111 | > 112 | + 添加 113 | 114 | ) 115 | } 116 |
117 |
118 |
119 | ) 120 | } 121 | 122 | export default Keywords; -------------------------------------------------------------------------------- /packages/example/src/assets/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/bp-script-editor/src/editor.tsx: -------------------------------------------------------------------------------- 1 | import React, { 2 | forwardRef, 3 | useImperativeHandle, 4 | useRef, 5 | useCallback, 6 | ForwardRefRenderFunction, 7 | useMemo, 8 | } from 'react'; 9 | import { githubLight } from '@uiw/codemirror-theme-github'; 10 | import ReactCodeMirror, { ReactCodeMirrorRef } from '@uiw/react-codemirror'; 11 | import { snippet } from '@codemirror/autocomplete'; 12 | import { Extension } from '@codemirror/state'; 13 | 14 | import { extensions } from './extensions'; 15 | import { CompletionsType, FunctionType, HintPathType, PlaceholderThemesType, ScriptEditorRef } from './interface'; 16 | 17 | interface PropsType { 18 | completions: CompletionsType[]; 19 | keywords?: string[]; 20 | onValueChange?: (value: string) => void; 21 | placeholderThemes: PlaceholderThemesType; 22 | mode: string; 23 | functions: FunctionType[]; 24 | height?: string; 25 | width?: string; 26 | keywordsClassName?: string; 27 | keywordsColor?: string; 28 | defaultValue?: string; 29 | hintPaths?: HintPathType[]; 30 | extensions?: Extension[]; 31 | } 32 | 33 | const Editor: ForwardRefRenderFunction = ({ 34 | completions, 35 | onValueChange, 36 | keywords, 37 | placeholderThemes, 38 | mode, 39 | functions, 40 | height, 41 | width, 42 | keywordsColor, 43 | keywordsClassName, 44 | defaultValue, 45 | hintPaths, 46 | extensions: extensionsProps, 47 | }, 48 | ref, 49 | ) => { 50 | const editorRef = useRef(null); 51 | 52 | const insertText = useCallback((text: string, isTemplate?: boolean) => { 53 | const { view } = editorRef.current!; 54 | if (!view) return; 55 | 56 | const { state } = view; 57 | if (!state) return; 58 | 59 | const [range] = state?.selection?.ranges || []; 60 | 61 | view.focus(); 62 | 63 | if (isTemplate) { 64 | snippet(text)( 65 | { 66 | state, 67 | dispatch: view.dispatch, 68 | }, 69 | { 70 | label: text, 71 | detail: text, 72 | }, 73 | range.from, 74 | range.to 75 | ); 76 | } else { 77 | view.dispatch({ 78 | changes: { 79 | from: range.from, 80 | to: range.to, 81 | insert: text, 82 | }, 83 | selection: { 84 | anchor: range.from + text.length 85 | }, 86 | }); 87 | } 88 | }, []); 89 | 90 | const clearText = useCallback(() => { 91 | const { view } = editorRef.current; 92 | view.dispatch({ 93 | changes: { 94 | from: 0, 95 | to: view.state.doc.length, 96 | insert: '', 97 | }, 98 | selection: { 99 | anchor: 0, 100 | }, 101 | }); 102 | view.focus(); 103 | }, []); 104 | 105 | const setText = useCallback((text: string) => { 106 | const { view } = editorRef.current; 107 | view.dispatch({ 108 | changes: { 109 | from: 0, 110 | to: view.state.doc.length, 111 | insert: text, 112 | }, 113 | selection: { 114 | anchor: text.length, 115 | }, 116 | }); 117 | view.focus(); 118 | }, []); 119 | 120 | useImperativeHandle( 121 | ref, 122 | () => { 123 | return { 124 | insertText, 125 | clearText, 126 | setText, 127 | originEditorRef: editorRef, 128 | }; 129 | }, 130 | [insertText, clearText, setText] 131 | ); 132 | 133 | console.log(extensionsProps); 134 | const extensionsMemo = useMemo( 135 | () => 136 | [ 137 | ...extensions({ 138 | completions, 139 | keywords, 140 | placeholderThemes, 141 | mode, 142 | functions, 143 | keywordsColor, 144 | keywordsClassName, 145 | hintPaths, 146 | }), 147 | ...(extensionsProps || []) 148 | ], 149 | [ 150 | completions, 151 | keywords, 152 | placeholderThemes, 153 | mode, 154 | functions, 155 | keywordsColor, 156 | keywordsClassName, 157 | hintPaths, 158 | extensionsProps, 159 | ] 160 | ); 161 | 162 | const onChangeHandle = useCallback( 163 | (value: string) => { 164 | onValueChange && onValueChange(value); 165 | }, 166 | [onValueChange] 167 | ); 168 | 169 | return ( 170 | 179 | ); 180 | } 181 | 182 | 183 | export default forwardRef(Editor); 184 | -------------------------------------------------------------------------------- /packages/example/src/pages/model-list.tsx: -------------------------------------------------------------------------------- 1 | import React, { FC, useMemo, useState, useEffect } from 'react' 2 | import { Drawer, Table, Button, Modal, Form, Input, message } from 'antd' 3 | 4 | import { Model } from '../data/model' 5 | 6 | import './model-list.css' 7 | 8 | interface PropType { 9 | models: Model[]; 10 | onModelsChange?: (models: Model[]) => void; 11 | open: boolean; 12 | onClose: () => void; 13 | } 14 | 15 | const ModelList: FC = ({ 16 | models, 17 | onModelsChange, 18 | onClose, 19 | open, 20 | }) => { 21 | 22 | const [selected, setSelected] = useState(); 23 | const [localModels, setLocalModels] = useState(models); 24 | 25 | const [modelOpen, setModelOpen] = useState(false); 26 | const [fieldOpen, setFieldOpen] = useState(false); 27 | 28 | const [modelForm] = Form.useForm(); 29 | const [fieldForm] = Form.useForm(); 30 | 31 | const tableData = useMemo(() => { 32 | return localModels.find(o => o.code === selected)?.children || []; 33 | }, [selected, localModels]); 34 | 35 | const newModel = (values: any) => { 36 | setLocalModels(prev => [...prev, { 37 | name: values.name, 38 | code: values.code, 39 | type: 'model', 40 | children: [], 41 | }]); 42 | setSelected(values.code); 43 | setModelOpen(false); 44 | }; 45 | 46 | const newModelField = (values: any) => { 47 | if (!selected) return; 48 | 49 | if (tableData.some(o => o.code === values.code)) { 50 | message.error('字段代码不能重复'); 51 | return; 52 | } 53 | 54 | const index = localModels.findIndex(o => o.code === selected); 55 | 56 | if (!localModels[index].children) { 57 | localModels[index].children = []; 58 | } 59 | 60 | localModels[index].children = [ 61 | ...(localModels[index].children || []), 62 | { 63 | name: values.name, 64 | code: values.code, 65 | value: values.value, 66 | type: 'field', 67 | } 68 | ]; 69 | 70 | setLocalModels([...localModels]); 71 | setFieldOpen(false); 72 | } 73 | 74 | const removeField = (code: string) => { 75 | if (!code) return; 76 | 77 | const index = localModels.findIndex(o => o.code === selected); 78 | 79 | localModels[index].children = (localModels[index].children || []).filter(o => o.code !== code); 80 | 81 | setLocalModels([...localModels]); 82 | } 83 | 84 | const removeModel = (code: string) => { 85 | if (!code) return; 86 | 87 | setSelected(null); 88 | setLocalModels(prev => prev.filter(o => o.code !== code)); 89 | } 90 | 91 | useEffect(() => { 92 | if (onModelsChange) { 93 | onModelsChange(localModels); 94 | } 95 | }, [localModels]); 96 | 97 | 98 | const columns = useMemo(() => { 99 | return [{ 100 | dataIndex: 'name', 101 | title: '名称', 102 | }, { 103 | dataIndex: 'code', 104 | title: '代码', 105 | }, { 106 | dataIndex: 'value', 107 | title: '值', 108 | }, { 109 | title: '操作', 110 | dataIndex: 'code', 111 | render: (code: string) => { 112 | return ( 113 | { removeField(code) }}>删除 114 | ) 115 | } 116 | }] 117 | }, [selected]) 118 | 119 | return ( 120 | { 125 | onClose(); 126 | }} 127 | > 128 |
129 |
130 |
131 | 140 |
141 | { 142 | localModels.map(m => ( 143 |
{ setSelected(m.code) }} 145 | key={m.code} 146 | className={`flex items-center justify-between h-[60px] px-[18px] transition-colors duration-100 hover:bg-[#f2f4f6] cursor-pointer rounded-lg ${selected === m.code ? 'selected' : ''}`} 147 | > 148 |
149 |
{m.name}
150 |
{m.code}
151 |
152 | {selected === m.code && ( 153 |
{ 155 | e.stopPropagation(); 156 | removeModel(m.code); 157 | }} 158 | > 159 | X 160 |
161 | )} 162 |
163 | )) 164 | } 165 |
166 |
167 | {!!selected && ( 168 |
169 | 178 |
179 | )} 180 |
187 | 188 | 189 | { 193 | modelForm.submit(); 194 | }} 195 | onCancel={() => { 196 | setModelOpen(false); 197 | }} 198 | > 199 |
206 | 213 | 214 | 215 | 222 | 223 | 224 | 225 |
226 | { 230 | fieldForm.submit(); 231 | }} 232 | onCancel={() => { 233 | setFieldOpen(false); 234 | }} 235 | > 236 |
243 | 250 | 251 | 252 | 259 | 260 | 261 | 265 | 266 | 267 | 268 |
269 | 270 | ) 271 | } 272 | 273 | export default ModelList; -------------------------------------------------------------------------------- /packages/example/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { useState, useCallback, useMemo, useRef } from 'react'; 2 | import { Button, Tabs, Space } from 'antd'; 3 | import { useLocalStorageState } from 'ahooks' 4 | 5 | import Editor, { CommonPlaceholderThemes, FunctionType, ScriptEditorRef } from '@byteplan/bp-script-editor' 6 | 7 | import Function from './component/function'; 8 | import ModelField from './component/model-field'; 9 | import Operation from './component/operation'; 10 | 11 | import { GlobalContext } from './context'; 12 | import { Model, models } from './data/model'; 13 | import { functions } from './data/function'; 14 | import { operations } from './data/operation'; 15 | import ModelList from './pages/model-list'; 16 | import Keywords, { KeywordsConfigType } from './pages/keywords'; 17 | import Functions from './pages/functions'; 18 | import RunResult from './pages/result'; 19 | import { hintPaths } from './data/hint'; 20 | 21 | const placeholderTypes = { 22 | Field: 'f', 23 | }; 24 | 25 | const placeholderThemes = { 26 | [placeholderTypes.Field]: CommonPlaceholderThemes.blue, 27 | }; 28 | 29 | function App() { 30 | 31 | const [value, setValue] = useState(''); 32 | const [mode, setMode] = useState('name'); 33 | const [modelListOpen, setModelListOpen] = useState(false); 34 | const [keywordsOpen, setKeywordsOpen] = useState(false); 35 | const [functionsOpen, setFunctionsOpen] = useState(false); 36 | const [runResultOpen, setRunResultOpen] = useState(false); 37 | const [formatFunctions, setFormatFunctions] = useState(''); 38 | const [runResult, setRunResult] = useState(''); 39 | 40 | const [localModels, setLocalModels] = useLocalStorageState( 41 | 'model-list', 42 | { defaultValue: models } 43 | ); 44 | 45 | const [keywordsConfig, setKeywordsConfig] = useLocalStorageState( 46 | 'keywords-config', 47 | { 48 | defaultValue: { 49 | color: 'red', 50 | keywords: [], 51 | } 52 | } 53 | ); 54 | 55 | const [localFunctions, setLocalFunctions] = useLocalStorageState( 56 | 'functions', 57 | { 58 | defaultValue: functions, 59 | } 60 | ); 61 | 62 | 63 | const tabs = useMemo( 64 | () => [ 65 | { 66 | key: 'model-field', 67 | label: '字段', 68 | children: ( 69 | 70 | ), 71 | }, 72 | { 73 | key: 'function', 74 | label: '函数', 75 | children: , 76 | }, 77 | { 78 | key: 'operation', 79 | label: '逻辑运算符', 80 | children: , 81 | }, 82 | ], 83 | [localFunctions, operations, placeholderTypes, localModels] 84 | ); 85 | 86 | const data = useMemo(() => { 87 | return localModels.reduce((prevModel: any, model: Model) => { 88 | prevModel[model.code] = model.children?.reduce((prevField: any, field: Model) => { 89 | prevField[field.code] = field.value; 90 | return prevField; 91 | }, {}) 92 | return prevModel; 93 | }, {}); 94 | }, []); 95 | 96 | const onValueChange = useCallback((value: string) => { 97 | setValue(value); 98 | }, []); 99 | 100 | 101 | 102 | const test = () => { 103 | 104 | if (!value) return; 105 | 106 | let result = value.replace(/\[\[(.+?)\]\]/g, (_: string, $2: string) => { 107 | const [type, ...rest] = $2.split('.'); 108 | 109 | if (type === 'f') { 110 | const [modelCode, fieldCode] = rest.map((t) => t.split(':')[1]); 111 | return `data?.['${modelCode}']?.['${fieldCode}']`; 112 | } 113 | 114 | return ''; 115 | }); 116 | 117 | if (!result) return; 118 | result = result.split('\n').pop() || ''; 119 | if (!result) return; 120 | 121 | console.log(`function: return ${result}`); 122 | 123 | const func = new window.Function('func', 'data', `return ${result}`); 124 | 125 | const funcs = localFunctions.reduce((prev: { [k in string]: any }, cur) => { 126 | 127 | if (cur.handle) { 128 | const handle = new window.Function(`return ${cur.handle}`); 129 | prev[cur.label] = handle(); 130 | } 131 | 132 | return prev; 133 | }, {}); 134 | 135 | const runRes = func( 136 | funcs, 137 | data 138 | ); 139 | 140 | setFormatFunctions(`return ${result}`); 141 | setRunResult(runRes); 142 | setRunResultOpen(true); 143 | }; 144 | 145 | const open = () => { 146 | window.open("https://github.com/dbfu/bp-script-editor"); 147 | } 148 | 149 | const completions = useMemo( 150 | () => [...localFunctions, ...operations], 151 | [localFunctions, operations] 152 | ); 153 | 154 | const editorRef = useRef(null); 155 | 156 | return ( 157 | 158 |
159 |
160 | 161 | 164 | 167 | 170 | 173 | 183 | 191 | 192 | 193 | 194 | 195 |
196 | 197 |
198 |
199 | 200 |
201 |
202 | 215 |
216 |
217 | { setModelListOpen(false) }} 221 | models={localModels} 222 | /> 223 | { 225 | setKeywordsOpen(false 226 | ) 227 | }} 228 | onChange={setKeywordsConfig} 229 | open={keywordsOpen} 230 | keywordsConfig={keywordsConfig} 231 | /> 232 | { setFunctionsOpen(false) }} 237 | /> 238 | { 243 | setRunResultOpen(false); 244 | }} 245 | /> 246 |
247 |
248 | ); 249 | } 250 | 251 | export default App; 252 | -------------------------------------------------------------------------------- /packages/bp-script-editor/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@byteplan/bp-script-editor", 3 | "version": "0.0.2", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@byteplan/bp-script-editor", 9 | "version": "0.0.2", 10 | "dependencies": { 11 | "@codemirror/autocomplete": "^6.4.2", 12 | "@codemirror/lang-javascript": "^6.1.4", 13 | "@codemirror/view": "^6.9.2", 14 | "@uiw/codemirror-theme-github": "^4.19.9", 15 | "@uiw/react-codemirror": "^4.19.9", 16 | "react": "^18.2.0", 17 | "react-dom": "^18.2.0", 18 | "rollup-plugin-clear": "^2.0.7" 19 | }, 20 | "devDependencies": { 21 | "@babel/core": "^7.20.12", 22 | "@babel/plugin-proposal-class-properties": "^7.18.6", 23 | "@babel/plugin-proposal-decorators": "^7.20.13", 24 | "@babel/plugin-syntax-jsx": "^7.18.6", 25 | "@babel/plugin-transform-react-jsx": "^7.20.13", 26 | "@babel/plugin-transform-runtime": "^7.19.6", 27 | "@babel/preset-env": "^7.20.2", 28 | "@babel/preset-react": "^7.18.6", 29 | "@rollup/plugin-babel": "^6.0.3", 30 | "@rollup/plugin-commonjs": "^24.0.1", 31 | "@rollup/plugin-node-resolve": "^15.0.1", 32 | "@types/react": "^18.0.28", 33 | "rollup": "^3.15.0", 34 | "rollup-plugin-babel": "^4.4.0", 35 | "rollup-plugin-dts": "^5.3.0", 36 | "rollup-plugin-terser": "^7.0.2", 37 | "rollup-plugin-typescript2": "^0.34.1", 38 | "tslib": "^2.5.0", 39 | "typescript": "^5.0.2" 40 | } 41 | }, 42 | "../../node_modules/.pnpm/@babel+core@7.21.3/node_modules/@babel/core": { 43 | "version": "7.21.3", 44 | "dev": true, 45 | "license": "MIT", 46 | "dependencies": { 47 | "@ampproject/remapping": "^2.2.0", 48 | "@babel/code-frame": "^7.18.6", 49 | "@babel/generator": "^7.21.3", 50 | "@babel/helper-compilation-targets": "^7.20.7", 51 | "@babel/helper-module-transforms": "^7.21.2", 52 | "@babel/helpers": "^7.21.0", 53 | "@babel/parser": "^7.21.3", 54 | "@babel/template": "^7.20.7", 55 | "@babel/traverse": "^7.21.3", 56 | "@babel/types": "^7.21.3", 57 | "convert-source-map": "^1.7.0", 58 | "debug": "^4.1.0", 59 | "gensync": "^1.0.0-beta.2", 60 | "json5": "^2.2.2", 61 | "semver": "^6.3.0" 62 | }, 63 | "devDependencies": { 64 | "@babel/helper-transform-fixture-test-runner": "^7.20.14", 65 | "@babel/plugin-syntax-flow": "^7.18.6", 66 | "@babel/plugin-transform-flow-strip-types": "^7.21.0", 67 | "@babel/plugin-transform-modules-commonjs": "^7.21.2", 68 | "@babel/preset-env": "^7.20.2", 69 | "@jridgewell/trace-mapping": "^0.3.17", 70 | "@types/convert-source-map": "^1.5.1", 71 | "@types/debug": "^4.1.0", 72 | "@types/gensync": "^1.0.0", 73 | "@types/resolve": "^1.3.2", 74 | "@types/semver": "^5.4.0", 75 | "rimraf": "^3.0.0", 76 | "ts-node": "^10.9.1" 77 | }, 78 | "engines": { 79 | "node": ">=6.9.0" 80 | }, 81 | "funding": { 82 | "type": "opencollective", 83 | "url": "https://opencollective.com/babel" 84 | } 85 | }, 86 | "../../node_modules/.pnpm/@babel+plugin-proposal-class-properties@7.18.6_@babel+core@7.21.3/node_modules/@babel/plugin-proposal-class-properties": { 87 | "version": "7.18.6", 88 | "dev": true, 89 | "license": "MIT", 90 | "dependencies": { 91 | "@babel/helper-create-class-features-plugin": "^7.18.6", 92 | "@babel/helper-plugin-utils": "^7.18.6" 93 | }, 94 | "devDependencies": { 95 | "@babel/core": "^7.18.6", 96 | "@babel/helper-plugin-test-runner": "^7.18.6" 97 | }, 98 | "engines": { 99 | "node": ">=6.9.0" 100 | }, 101 | "peerDependencies": { 102 | "@babel/core": "^7.0.0-0" 103 | } 104 | }, 105 | "../../node_modules/.pnpm/@babel+plugin-proposal-decorators@7.21.0_@babel+core@7.21.3/node_modules/@babel/plugin-proposal-decorators": { 106 | "version": "7.21.0", 107 | "dev": true, 108 | "license": "MIT", 109 | "dependencies": { 110 | "@babel/helper-create-class-features-plugin": "^7.21.0", 111 | "@babel/helper-plugin-utils": "^7.20.2", 112 | "@babel/helper-replace-supers": "^7.20.7", 113 | "@babel/helper-split-export-declaration": "^7.18.6", 114 | "@babel/plugin-syntax-decorators": "^7.21.0" 115 | }, 116 | "devDependencies": { 117 | "@babel/core": "^7.21.0", 118 | "@babel/helper-plugin-test-runner": "^7.18.6", 119 | "@babel/traverse": "^7.21.0", 120 | "@types/charcodes": "^0.2.0", 121 | "array.prototype.concat": "^1.0.2", 122 | "babel-plugin-polyfill-es-shims": "^0.7.1", 123 | "charcodes": "^0.2.0", 124 | "object.getownpropertydescriptors": "^2.1.1" 125 | }, 126 | "engines": { 127 | "node": ">=6.9.0" 128 | }, 129 | "peerDependencies": { 130 | "@babel/core": "^7.0.0-0" 131 | } 132 | }, 133 | "../../node_modules/.pnpm/@babel+plugin-syntax-jsx@7.18.6_@babel+core@7.21.3/node_modules/@babel/plugin-syntax-jsx": { 134 | "version": "7.18.6", 135 | "dev": true, 136 | "license": "MIT", 137 | "dependencies": { 138 | "@babel/helper-plugin-utils": "^7.18.6" 139 | }, 140 | "devDependencies": { 141 | "@babel/core": "^7.18.6" 142 | }, 143 | "engines": { 144 | "node": ">=6.9.0" 145 | }, 146 | "peerDependencies": { 147 | "@babel/core": "^7.0.0-0" 148 | } 149 | }, 150 | "../../node_modules/.pnpm/@babel+plugin-transform-react-jsx@7.21.0_@babel+core@7.21.3/node_modules/@babel/plugin-transform-react-jsx": { 151 | "version": "7.21.0", 152 | "dev": true, 153 | "license": "MIT", 154 | "dependencies": { 155 | "@babel/helper-annotate-as-pure": "^7.18.6", 156 | "@babel/helper-module-imports": "^7.18.6", 157 | "@babel/helper-plugin-utils": "^7.20.2", 158 | "@babel/plugin-syntax-jsx": "^7.18.6", 159 | "@babel/types": "^7.21.0" 160 | }, 161 | "devDependencies": { 162 | "@babel/core": "^7.21.0", 163 | "@babel/helper-plugin-test-runner": "^7.18.6", 164 | "@babel/traverse": "^7.21.0" 165 | }, 166 | "engines": { 167 | "node": ">=6.9.0" 168 | }, 169 | "peerDependencies": { 170 | "@babel/core": "^7.0.0-0" 171 | } 172 | }, 173 | "../../node_modules/.pnpm/@babel+plugin-transform-runtime@7.21.0_@babel+core@7.21.3/node_modules/@babel/plugin-transform-runtime": { 174 | "version": "7.21.0", 175 | "dev": true, 176 | "license": "MIT", 177 | "dependencies": { 178 | "@babel/helper-module-imports": "^7.18.6", 179 | "@babel/helper-plugin-utils": "^7.20.2", 180 | "babel-plugin-polyfill-corejs2": "^0.3.3", 181 | "babel-plugin-polyfill-corejs3": "^0.6.0", 182 | "babel-plugin-polyfill-regenerator": "^0.4.1", 183 | "semver": "^6.3.0" 184 | }, 185 | "devDependencies": { 186 | "@babel/core": "^7.21.0", 187 | "@babel/helper-plugin-test-runner": "^7.18.6", 188 | "@babel/helpers": "^7.21.0", 189 | "@babel/preset-env": "^7.20.2", 190 | "@babel/runtime": "^7.21.0", 191 | "@babel/runtime-corejs3": "^7.21.0", 192 | "@babel/template": "^7.20.7", 193 | "@babel/types": "^7.21.0", 194 | "make-dir": "^2.1.0" 195 | }, 196 | "engines": { 197 | "node": ">=6.9.0" 198 | }, 199 | "peerDependencies": { 200 | "@babel/core": "^7.0.0-0" 201 | } 202 | }, 203 | "../../node_modules/.pnpm/@babel+preset-env@7.20.2_@babel+core@7.21.3/node_modules/@babel/preset-env": { 204 | "version": "7.20.2", 205 | "dev": true, 206 | "license": "MIT", 207 | "dependencies": { 208 | "@babel/compat-data": "^7.20.1", 209 | "@babel/helper-compilation-targets": "^7.20.0", 210 | "@babel/helper-plugin-utils": "^7.20.2", 211 | "@babel/helper-validator-option": "^7.18.6", 212 | "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", 213 | "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", 214 | "@babel/plugin-proposal-async-generator-functions": "^7.20.1", 215 | "@babel/plugin-proposal-class-properties": "^7.18.6", 216 | "@babel/plugin-proposal-class-static-block": "^7.18.6", 217 | "@babel/plugin-proposal-dynamic-import": "^7.18.6", 218 | "@babel/plugin-proposal-export-namespace-from": "^7.18.9", 219 | "@babel/plugin-proposal-json-strings": "^7.18.6", 220 | "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", 221 | "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", 222 | "@babel/plugin-proposal-numeric-separator": "^7.18.6", 223 | "@babel/plugin-proposal-object-rest-spread": "^7.20.2", 224 | "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", 225 | "@babel/plugin-proposal-optional-chaining": "^7.18.9", 226 | "@babel/plugin-proposal-private-methods": "^7.18.6", 227 | "@babel/plugin-proposal-private-property-in-object": "^7.18.6", 228 | "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", 229 | "@babel/plugin-syntax-async-generators": "^7.8.4", 230 | "@babel/plugin-syntax-class-properties": "^7.12.13", 231 | "@babel/plugin-syntax-class-static-block": "^7.14.5", 232 | "@babel/plugin-syntax-dynamic-import": "^7.8.3", 233 | "@babel/plugin-syntax-export-namespace-from": "^7.8.3", 234 | "@babel/plugin-syntax-import-assertions": "^7.20.0", 235 | "@babel/plugin-syntax-json-strings": "^7.8.3", 236 | "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", 237 | "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", 238 | "@babel/plugin-syntax-numeric-separator": "^7.10.4", 239 | "@babel/plugin-syntax-object-rest-spread": "^7.8.3", 240 | "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", 241 | "@babel/plugin-syntax-optional-chaining": "^7.8.3", 242 | "@babel/plugin-syntax-private-property-in-object": "^7.14.5", 243 | "@babel/plugin-syntax-top-level-await": "^7.14.5", 244 | "@babel/plugin-transform-arrow-functions": "^7.18.6", 245 | "@babel/plugin-transform-async-to-generator": "^7.18.6", 246 | "@babel/plugin-transform-block-scoped-functions": "^7.18.6", 247 | "@babel/plugin-transform-block-scoping": "^7.20.2", 248 | "@babel/plugin-transform-classes": "^7.20.2", 249 | "@babel/plugin-transform-computed-properties": "^7.18.9", 250 | "@babel/plugin-transform-destructuring": "^7.20.2", 251 | "@babel/plugin-transform-dotall-regex": "^7.18.6", 252 | "@babel/plugin-transform-duplicate-keys": "^7.18.9", 253 | "@babel/plugin-transform-exponentiation-operator": "^7.18.6", 254 | "@babel/plugin-transform-for-of": "^7.18.8", 255 | "@babel/plugin-transform-function-name": "^7.18.9", 256 | "@babel/plugin-transform-literals": "^7.18.9", 257 | "@babel/plugin-transform-member-expression-literals": "^7.18.6", 258 | "@babel/plugin-transform-modules-amd": "^7.19.6", 259 | "@babel/plugin-transform-modules-commonjs": "^7.19.6", 260 | "@babel/plugin-transform-modules-systemjs": "^7.19.6", 261 | "@babel/plugin-transform-modules-umd": "^7.18.6", 262 | "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", 263 | "@babel/plugin-transform-new-target": "^7.18.6", 264 | "@babel/plugin-transform-object-super": "^7.18.6", 265 | "@babel/plugin-transform-parameters": "^7.20.1", 266 | "@babel/plugin-transform-property-literals": "^7.18.6", 267 | "@babel/plugin-transform-regenerator": "^7.18.6", 268 | "@babel/plugin-transform-reserved-words": "^7.18.6", 269 | "@babel/plugin-transform-shorthand-properties": "^7.18.6", 270 | "@babel/plugin-transform-spread": "^7.19.0", 271 | "@babel/plugin-transform-sticky-regex": "^7.18.6", 272 | "@babel/plugin-transform-template-literals": "^7.18.9", 273 | "@babel/plugin-transform-typeof-symbol": "^7.18.9", 274 | "@babel/plugin-transform-unicode-escapes": "^7.18.10", 275 | "@babel/plugin-transform-unicode-regex": "^7.18.6", 276 | "@babel/preset-modules": "^0.1.5", 277 | "@babel/types": "^7.20.2", 278 | "babel-plugin-polyfill-corejs2": "^0.3.3", 279 | "babel-plugin-polyfill-corejs3": "^0.6.0", 280 | "babel-plugin-polyfill-regenerator": "^0.4.1", 281 | "core-js-compat": "^3.25.1", 282 | "semver": "^6.3.0" 283 | }, 284 | "devDependencies": { 285 | "@babel/core": "^7.20.2", 286 | "@babel/core-7.12": "npm:@babel/core@7.12.9", 287 | "@babel/helper-plugin-test-runner": "^7.18.6", 288 | "@babel/traverse": "^7.20.1" 289 | }, 290 | "engines": { 291 | "node": ">=6.9.0" 292 | }, 293 | "peerDependencies": { 294 | "@babel/core": "^7.0.0-0" 295 | } 296 | }, 297 | "../../node_modules/.pnpm/@babel+preset-react@7.18.6_@babel+core@7.21.3/node_modules/@babel/preset-react": { 298 | "version": "7.18.6", 299 | "dev": true, 300 | "license": "MIT", 301 | "dependencies": { 302 | "@babel/helper-plugin-utils": "^7.18.6", 303 | "@babel/helper-validator-option": "^7.18.6", 304 | "@babel/plugin-transform-react-display-name": "^7.18.6", 305 | "@babel/plugin-transform-react-jsx": "^7.18.6", 306 | "@babel/plugin-transform-react-jsx-development": "^7.18.6", 307 | "@babel/plugin-transform-react-pure-annotations": "^7.18.6" 308 | }, 309 | "devDependencies": { 310 | "@babel/core": "^7.18.6", 311 | "@babel/helper-plugin-test-runner": "^7.18.6" 312 | }, 313 | "engines": { 314 | "node": ">=6.9.0" 315 | }, 316 | "peerDependencies": { 317 | "@babel/core": "^7.0.0-0" 318 | } 319 | }, 320 | "../../node_modules/.pnpm/@codemirror+autocomplete@6.4.2_@codemirror+view@6.9.2/node_modules/@codemirror/autocomplete": { 321 | "version": "6.4.2", 322 | "license": "MIT", 323 | "dependencies": { 324 | "@codemirror/language": "^6.0.0", 325 | "@codemirror/state": "^6.0.0", 326 | "@codemirror/view": "^6.6.0", 327 | "@lezer/common": "^1.0.0" 328 | }, 329 | "devDependencies": { 330 | "@codemirror/buildhelper": "^0.1.5" 331 | }, 332 | "peerDependencies": { 333 | "@codemirror/language": "^6.0.0", 334 | "@codemirror/state": "^6.0.0", 335 | "@codemirror/view": "^6.0.0", 336 | "@lezer/common": "^1.0.0" 337 | } 338 | }, 339 | "../../node_modules/.pnpm/@codemirror+lang-javascript@6.1.4/node_modules/@codemirror/lang-javascript": { 340 | "version": "6.1.4", 341 | "license": "MIT", 342 | "dependencies": { 343 | "@codemirror/autocomplete": "^6.0.0", 344 | "@codemirror/language": "^6.6.0", 345 | "@codemirror/lint": "^6.0.0", 346 | "@codemirror/state": "^6.0.0", 347 | "@codemirror/view": "^6.0.0", 348 | "@lezer/common": "^1.0.0", 349 | "@lezer/javascript": "^1.0.0" 350 | }, 351 | "devDependencies": { 352 | "@codemirror/buildhelper": "^0.1.5", 353 | "@lezer/lr": "^1.0.0" 354 | } 355 | }, 356 | "../../node_modules/.pnpm/@codemirror+view@6.9.2/node_modules/@codemirror/view": { 357 | "version": "6.9.2", 358 | "license": "MIT", 359 | "dependencies": { 360 | "@codemirror/state": "^6.1.4", 361 | "style-mod": "^4.0.0", 362 | "w3c-keyname": "^2.2.4" 363 | }, 364 | "devDependencies": { 365 | "@codemirror/buildhelper": "^0.1.6" 366 | } 367 | }, 368 | "../../node_modules/.pnpm/@rollup+plugin-babel@6.0.3_juvh72w4ry7wdzu3k4tlty4ke4/node_modules/@rollup/plugin-babel": { 369 | "version": "6.0.3", 370 | "dev": true, 371 | "license": "MIT", 372 | "dependencies": { 373 | "@babel/helper-module-imports": "^7.18.6", 374 | "@rollup/pluginutils": "^5.0.1" 375 | }, 376 | "devDependencies": { 377 | "@babel/core": "^7.19.1", 378 | "@babel/plugin-external-helpers": "^7.18.6", 379 | "@babel/plugin-proposal-decorators": "^7.19.1", 380 | "@babel/plugin-syntax-dynamic-import": "^7.8.3", 381 | "@babel/plugin-transform-runtime": "^7.19.1", 382 | "@babel/preset-env": "^7.19.1", 383 | "@rollup/plugin-json": "^5.0.0", 384 | "@rollup/plugin-node-resolve": "^15.0.0", 385 | "@types/babel__core": "^7.1.9", 386 | "rollup": "^3.2.3", 387 | "source-map": "^0.7.4" 388 | }, 389 | "engines": { 390 | "node": ">=14.0.0" 391 | }, 392 | "peerDependencies": { 393 | "@babel/core": "^7.0.0", 394 | "@types/babel__core": "^7.1.9", 395 | "rollup": "^1.20.0||^2.0.0||^3.0.0" 396 | }, 397 | "peerDependenciesMeta": { 398 | "@types/babel__core": { 399 | "optional": true 400 | }, 401 | "rollup": { 402 | "optional": true 403 | } 404 | } 405 | }, 406 | "../../node_modules/.pnpm/@rollup+plugin-commonjs@24.0.1_rollup@3.19.1/node_modules/@rollup/plugin-commonjs": { 407 | "version": "24.0.1", 408 | "dev": true, 409 | "license": "MIT", 410 | "dependencies": { 411 | "@rollup/pluginutils": "^5.0.1", 412 | "commondir": "^1.0.1", 413 | "estree-walker": "^2.0.2", 414 | "glob": "^8.0.3", 415 | "is-reference": "1.2.1", 416 | "magic-string": "^0.27.0" 417 | }, 418 | "devDependencies": { 419 | "@rollup/plugin-json": "^5.0.0", 420 | "@rollup/plugin-node-resolve": "^15.0.0", 421 | "locate-character": "^2.0.5", 422 | "require-relative": "^0.8.7", 423 | "rollup": "3.0.0-7", 424 | "shx": "^0.3.4", 425 | "source-map": "^0.7.4", 426 | "source-map-support": "^0.5.21", 427 | "typescript": "^4.8.3" 428 | }, 429 | "engines": { 430 | "node": ">=14.0.0" 431 | }, 432 | "peerDependencies": { 433 | "rollup": "^2.68.0||^3.0.0" 434 | }, 435 | "peerDependenciesMeta": { 436 | "rollup": { 437 | "optional": true 438 | } 439 | } 440 | }, 441 | "../../node_modules/.pnpm/@rollup+plugin-node-resolve@15.0.1_rollup@3.19.1/node_modules/@rollup/plugin-node-resolve": { 442 | "version": "15.0.1", 443 | "dev": true, 444 | "license": "MIT", 445 | "dependencies": { 446 | "@rollup/pluginutils": "^5.0.1", 447 | "@types/resolve": "1.20.2", 448 | "deepmerge": "^4.2.2", 449 | "is-builtin-module": "^3.2.0", 450 | "is-module": "^1.0.0", 451 | "resolve": "^1.22.1" 452 | }, 453 | "devDependencies": { 454 | "@babel/core": "^7.19.1", 455 | "@babel/plugin-transform-typescript": "^7.10.5", 456 | "@rollup/plugin-babel": "^6.0.0", 457 | "@rollup/plugin-commonjs": "^23.0.0", 458 | "@rollup/plugin-json": "^5.0.0", 459 | "es5-ext": "^0.10.62", 460 | "rollup": "^3.2.3", 461 | "source-map": "^0.7.4", 462 | "string-capitalize": "^1.0.1" 463 | }, 464 | "engines": { 465 | "node": ">=14.0.0" 466 | }, 467 | "peerDependencies": { 468 | "rollup": "^2.78.0||^3.0.0" 469 | }, 470 | "peerDependenciesMeta": { 471 | "rollup": { 472 | "optional": true 473 | } 474 | } 475 | }, 476 | "../../node_modules/.pnpm/@uiw+codemirror-theme-github@4.19.9_@codemirror+view@6.9.2/node_modules/@uiw/codemirror-theme-github": { 477 | "version": "4.19.9", 478 | "license": "MIT", 479 | "dependencies": { 480 | "@uiw/codemirror-themes": "4.19.9" 481 | } 482 | }, 483 | "../../node_modules/.pnpm/@uiw+react-codemirror@4.19.9_e6uob5njowrusdmcrg6qxzpedi/node_modules/@uiw/react-codemirror": { 484 | "version": "4.19.9", 485 | "license": "MIT", 486 | "dependencies": { 487 | "@babel/runtime": "^7.18.6", 488 | "@codemirror/commands": "^6.1.0", 489 | "@codemirror/state": "^6.1.1", 490 | "@codemirror/theme-one-dark": "^6.0.0", 491 | "@uiw/codemirror-extensions-basic-setup": "4.19.9", 492 | "codemirror": "^6.0.0" 493 | }, 494 | "peerDependencies": { 495 | "@babel/runtime": ">=7.11.0", 496 | "@codemirror/state": ">=6.0.0", 497 | "@codemirror/theme-one-dark": ">=6.0.0", 498 | "@codemirror/view": ">=6.0.0", 499 | "codemirror": ">=6.0.0", 500 | "react": ">=16.8.0", 501 | "react-dom": ">=16.8.0" 502 | } 503 | }, 504 | "../../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom": { 505 | "version": "18.2.0", 506 | "license": "MIT", 507 | "dependencies": { 508 | "loose-envify": "^1.1.0", 509 | "scheduler": "^0.23.0" 510 | }, 511 | "peerDependencies": { 512 | "react": "^18.2.0" 513 | } 514 | }, 515 | "../../node_modules/.pnpm/react@18.2.0/node_modules/react": { 516 | "version": "18.2.0", 517 | "license": "MIT", 518 | "dependencies": { 519 | "loose-envify": "^1.1.0" 520 | }, 521 | "engines": { 522 | "node": ">=0.10.0" 523 | } 524 | }, 525 | "../../node_modules/.pnpm/rollup-plugin-babel@4.4.0_juvh72w4ry7wdzu3k4tlty4ke4/node_modules/rollup-plugin-babel": { 526 | "version": "4.4.0", 527 | "dev": true, 528 | "license": "MIT", 529 | "dependencies": { 530 | "@babel/helper-module-imports": "^7.0.0", 531 | "rollup-pluginutils": "^2.8.1" 532 | }, 533 | "devDependencies": { 534 | "@babel/core": "^7.3.4", 535 | "@babel/plugin-external-helpers": "^7.0.0", 536 | "@babel/plugin-proposal-decorators": "^7.0.0", 537 | "@babel/plugin-transform-runtime": "^7.0.0", 538 | "@babel/preset-env": "^7.3.4", 539 | "buble": "^0.19.3", 540 | "eslint": "^5.15.1", 541 | "eslint-config-prettier": "^3.3.0", 542 | "eslint-plugin-prettier": "^3.0.0", 543 | "husky": "^1.0.1", 544 | "lint-staged": "^7.2.2", 545 | "mocha": "^5.2.0", 546 | "prettier": "^1.15.3", 547 | "rollup": "^2.0.1", 548 | "rollup-plugin-buble": "^0.19.2", 549 | "rollup-plugin-json": "^3.0.0", 550 | "source-map": "^0.6.1", 551 | "source-map-support": "^0.5.6" 552 | }, 553 | "peerDependencies": { 554 | "@babel/core": "7 || ^7.0.0-rc.2", 555 | "rollup": ">=0.60.0 <3" 556 | } 557 | }, 558 | "../../node_modules/.pnpm/rollup-plugin-clear@2.0.7/node_modules/rollup-plugin-clear": { 559 | "version": "2.0.7", 560 | "license": "ISC", 561 | "dependencies": { 562 | "rimraf": "^2.6.2" 563 | }, 564 | "devDependencies": { 565 | "@types/jest": "^22.1.2", 566 | "@types/rimraf": "^2.0.2", 567 | "jest": "^22.2.2", 568 | "rollup": "^0.55.5", 569 | "rollup-plugin-commonjs": "^8.3.0", 570 | "rollup-plugin-filesize": "^1.5.0", 571 | "rollup-plugin-node-resolve": "^3.0.2", 572 | "rollup-plugin-progress": "^0.4.0", 573 | "rollup-plugin-typescript2": "^0.11.1", 574 | "ts-jest": "^22.0.4", 575 | "typescript": "^2.7.1" 576 | } 577 | }, 578 | "../../node_modules/.pnpm/rollup-plugin-dts@5.3.0_7iejawhbqmte5pthjozf4tfuqy/node_modules/rollup-plugin-dts": { 579 | "version": "5.3.0", 580 | "dev": true, 581 | "license": "LGPL-3.0", 582 | "dependencies": { 583 | "magic-string": "^0.30.0" 584 | }, 585 | "devDependencies": { 586 | "@babel/code-frame": "^7.18.6", 587 | "@types/babel__code-frame": "^7.0.3", 588 | "@types/d3-drag": "^3.0.2", 589 | "@types/estree": "1.0.0", 590 | "@types/node": "^18.15.3", 591 | "@types/react": "^18.0.28", 592 | "c8": "^7.13.0", 593 | "rollup": "3.19.1", 594 | "typescript": "5.0.2" 595 | }, 596 | "engines": { 597 | "node": ">=v14" 598 | }, 599 | "funding": { 600 | "url": "https://github.com/sponsors/Swatinem" 601 | }, 602 | "optionalDependencies": { 603 | "@babel/code-frame": "^7.18.6" 604 | }, 605 | "peerDependencies": { 606 | "rollup": "^3.0.0", 607 | "typescript": "^4.1 || ^5.0" 608 | } 609 | }, 610 | "../../node_modules/.pnpm/rollup-plugin-terser@7.0.2_rollup@3.19.1/node_modules/rollup-plugin-terser": { 611 | "version": "7.0.2", 612 | "dev": true, 613 | "license": "MIT", 614 | "dependencies": { 615 | "@babel/code-frame": "^7.10.4", 616 | "jest-worker": "^26.2.1", 617 | "serialize-javascript": "^4.0.0", 618 | "terser": "^5.0.0" 619 | }, 620 | "devDependencies": { 621 | "@babel/core": "^7.11.1", 622 | "jest": "^26.2.2", 623 | "prettier": "^2.0.5", 624 | "rollup": "^2.23.1" 625 | }, 626 | "peerDependencies": { 627 | "rollup": "^2.0.0" 628 | } 629 | }, 630 | "../../node_modules/.pnpm/rollup-plugin-typescript2@0.34.1_7iejawhbqmte5pthjozf4tfuqy/node_modules/rollup-plugin-typescript2": { 631 | "version": "0.34.1", 632 | "dev": true, 633 | "license": "MIT", 634 | "dependencies": { 635 | "@rollup/pluginutils": "^4.1.2", 636 | "find-cache-dir": "^3.3.2", 637 | "fs-extra": "^10.0.0", 638 | "semver": "^7.3.7", 639 | "tslib": "^2.4.0" 640 | }, 641 | "devDependencies": { 642 | "@jest/globals": "^28.0.3", 643 | "@rollup/plugin-commonjs": "^22.0.0", 644 | "@rollup/plugin-node-resolve": "13.2.1", 645 | "@types/find-cache-dir": "^2.0.0", 646 | "@types/fs-extra": "8.0.1", 647 | "@types/graphlib": "2.1.7", 648 | "@types/jest": "^27.5.0", 649 | "@types/lodash": "4.14.161", 650 | "@types/node": "8.0.47", 651 | "@types/object-hash": "1.3.3", 652 | "@types/semver": "7.3.12", 653 | "colors": "1.4.0", 654 | "graphlib": "2.1.8", 655 | "jest": "^28.0.0", 656 | "lodash": "4.17.21", 657 | "object-hash": "3.0.0", 658 | "rimraf": "3.0.2", 659 | "rollup": "^2.70.2", 660 | "rollup-plugin-re": "1.0.7", 661 | "rollup-plugin-typescript2": "0.34.0", 662 | "ts-jest": "^28.0.0", 663 | "tslint": "6.1.3", 664 | "typescript": "^4.6.3" 665 | }, 666 | "peerDependencies": { 667 | "rollup": ">=1.26.3", 668 | "typescript": ">=2.4.0" 669 | } 670 | }, 671 | "../../node_modules/.pnpm/rollup@3.19.1/node_modules/rollup": { 672 | "version": "3.19.1", 673 | "dev": true, 674 | "license": "MIT", 675 | "bin": { 676 | "rollup": "dist/bin/rollup" 677 | }, 678 | "devDependencies": { 679 | "@codemirror/commands": "^6.2.1", 680 | "@codemirror/lang-javascript": "^6.1.4", 681 | "@codemirror/language": "^6.6.0", 682 | "@codemirror/search": "^6.2.3", 683 | "@codemirror/state": "^6.2.0", 684 | "@codemirror/view": "^6.9.2", 685 | "@jridgewell/sourcemap-codec": "^1.4.14", 686 | "@mermaid-js/mermaid-cli": "^10.0.2", 687 | "@rollup/plugin-alias": "^4.0.3", 688 | "@rollup/plugin-buble": "^1.0.2", 689 | "@rollup/plugin-commonjs": "^24.0.1", 690 | "@rollup/plugin-json": "^6.0.0", 691 | "@rollup/plugin-node-resolve": "^15.0.1", 692 | "@rollup/plugin-replace": "^5.0.2", 693 | "@rollup/plugin-terser": "^0.4.0", 694 | "@rollup/plugin-typescript": "^11.0.0", 695 | "@rollup/pluginutils": "^5.0.2", 696 | "@types/estree": "1.0.0", 697 | "@types/node": "^14.18.36", 698 | "@types/signal-exit": "^3.0.1", 699 | "@types/yargs-parser": "^21.0.0", 700 | "@typescript-eslint/eslint-plugin": "^5.54.1", 701 | "@typescript-eslint/parser": "^5.54.1", 702 | "@vue/eslint-config-prettier": "^7.1.0", 703 | "@vue/eslint-config-typescript": "^11.0.2", 704 | "acorn": "^8.8.2", 705 | "acorn-import-assertions": "^1.8.0", 706 | "acorn-jsx": "^5.3.2", 707 | "acorn-walk": "^8.2.0", 708 | "buble": "^0.20.0", 709 | "builtin-modules": "^3.3.0", 710 | "chokidar": "^3.5.3", 711 | "colorette": "^2.0.19", 712 | "concurrently": "^7.6.0", 713 | "core-js": "^3.29.0", 714 | "date-time": "^4.0.0", 715 | "es5-shim": "^4.6.7", 716 | "es6-shim": "^0.35.7", 717 | "eslint": "^8.35.0", 718 | "eslint-config-prettier": "^8.7.0", 719 | "eslint-plugin-import": "^2.27.5", 720 | "eslint-plugin-prettier": "^4.2.1", 721 | "eslint-plugin-unicorn": "^46.0.0", 722 | "eslint-plugin-vue": "^9.9.0", 723 | "fixturify": "^3.0.0", 724 | "flru": "^1.0.2", 725 | "fs-extra": "^11.1.0", 726 | "github-api": "^3.4.0", 727 | "hash.js": "^1.1.7", 728 | "husky": "^8.0.3", 729 | "inquirer": "^9.1.4", 730 | "is-reference": "^3.0.1", 731 | "lint-staged": "^13.1.2", 732 | "locate-character": "^2.0.5", 733 | "magic-string": "^0.30.0", 734 | "mocha": "^10.2.0", 735 | "nyc": "^15.1.0", 736 | "pinia": "^2.0.33", 737 | "prettier": "^2.8.4", 738 | "pretty-bytes": "^6.1.0", 739 | "pretty-ms": "^8.0.0", 740 | "requirejs": "^2.3.6", 741 | "rollup": "^3.18.0", 742 | "rollup-plugin-license": "^3.0.1", 743 | "rollup-plugin-string": "^3.0.0", 744 | "rollup-plugin-thatworks": "^1.0.4", 745 | "semver": "^7.3.8", 746 | "shx": "^0.3.4", 747 | "signal-exit": "^3.0.7", 748 | "source-map": "^0.7.4", 749 | "source-map-support": "^0.5.21", 750 | "systemjs": "^6.14.0", 751 | "terser": "^5.16.5", 752 | "tslib": "^2.5.0", 753 | "typescript": "^4.9.5", 754 | "vitepress": "^1.0.0-alpha.50", 755 | "vue": "^3.2.47", 756 | "weak-napi": "^2.0.2", 757 | "yargs-parser": "^21.1.1" 758 | }, 759 | "engines": { 760 | "node": ">=14.18.0", 761 | "npm": ">=8.0.0" 762 | }, 763 | "optionalDependencies": { 764 | "fsevents": "~2.3.2" 765 | } 766 | }, 767 | "../../node_modules/.pnpm/tslib@2.5.0/node_modules/tslib": { 768 | "version": "2.5.0", 769 | "dev": true, 770 | "license": "0BSD" 771 | }, 772 | "../../node_modules/.pnpm/typescript@5.0.2/node_modules/typescript": { 773 | "version": "5.0.2", 774 | "dev": true, 775 | "license": "Apache-2.0", 776 | "bin": { 777 | "tsc": "bin/tsc", 778 | "tsserver": "bin/tsserver" 779 | }, 780 | "devDependencies": { 781 | "@esfx/canceltoken": "^1.0.0", 782 | "@octokit/rest": "latest", 783 | "@types/chai": "^4.3.4", 784 | "@types/fs-extra": "^9.0.13", 785 | "@types/glob": "^8.1.0", 786 | "@types/microsoft__typescript-etw": "^0.1.1", 787 | "@types/minimist": "^1.2.2", 788 | "@types/mocha": "^10.0.1", 789 | "@types/ms": "^0.7.31", 790 | "@types/node": "latest", 791 | "@types/source-map-support": "^0.5.6", 792 | "@types/which": "^2.0.1", 793 | "@typescript-eslint/eslint-plugin": "^5.33.1", 794 | "@typescript-eslint/parser": "^5.33.1", 795 | "@typescript-eslint/utils": "^5.33.1", 796 | "azure-devops-node-api": "^11.2.0", 797 | "chai": "^4.3.7", 798 | "chalk": "^4.1.2", 799 | "chokidar": "^3.5.3", 800 | "del": "^6.1.1", 801 | "diff": "^5.1.0", 802 | "esbuild": "^0.17.2", 803 | "eslint": "^8.22.0", 804 | "eslint-formatter-autolinkable-stylish": "^1.2.0", 805 | "eslint-plugin-import": "^2.26.0", 806 | "eslint-plugin-local": "^1.0.0", 807 | "eslint-plugin-no-null": "^1.0.2", 808 | "eslint-plugin-simple-import-sort": "^10.0.0", 809 | "fast-xml-parser": "^4.0.11", 810 | "fs-extra": "^9.1.0", 811 | "glob": "^8.1.0", 812 | "hereby": "^1.6.4", 813 | "jsonc-parser": "^3.2.0", 814 | "minimist": "^1.2.8", 815 | "mocha": "^10.2.0", 816 | "mocha-fivemat-progress-reporter": "^0.1.0", 817 | "ms": "^2.1.3", 818 | "node-fetch": "^3.2.10", 819 | "source-map-support": "^0.5.21", 820 | "typescript": "5.0.0-dev.20230112", 821 | "which": "^2.0.2" 822 | }, 823 | "engines": { 824 | "node": ">=12.20" 825 | } 826 | }, 827 | "node_modules/@babel/core": { 828 | "resolved": "../../node_modules/.pnpm/@babel+core@7.21.3/node_modules/@babel/core", 829 | "link": true 830 | }, 831 | "node_modules/@babel/plugin-proposal-class-properties": { 832 | "resolved": "../../node_modules/.pnpm/@babel+plugin-proposal-class-properties@7.18.6_@babel+core@7.21.3/node_modules/@babel/plugin-proposal-class-properties", 833 | "link": true 834 | }, 835 | "node_modules/@babel/plugin-proposal-decorators": { 836 | "resolved": "../../node_modules/.pnpm/@babel+plugin-proposal-decorators@7.21.0_@babel+core@7.21.3/node_modules/@babel/plugin-proposal-decorators", 837 | "link": true 838 | }, 839 | "node_modules/@babel/plugin-syntax-jsx": { 840 | "resolved": "../../node_modules/.pnpm/@babel+plugin-syntax-jsx@7.18.6_@babel+core@7.21.3/node_modules/@babel/plugin-syntax-jsx", 841 | "link": true 842 | }, 843 | "node_modules/@babel/plugin-transform-react-jsx": { 844 | "resolved": "../../node_modules/.pnpm/@babel+plugin-transform-react-jsx@7.21.0_@babel+core@7.21.3/node_modules/@babel/plugin-transform-react-jsx", 845 | "link": true 846 | }, 847 | "node_modules/@babel/plugin-transform-runtime": { 848 | "resolved": "../../node_modules/.pnpm/@babel+plugin-transform-runtime@7.21.0_@babel+core@7.21.3/node_modules/@babel/plugin-transform-runtime", 849 | "link": true 850 | }, 851 | "node_modules/@babel/preset-env": { 852 | "resolved": "../../node_modules/.pnpm/@babel+preset-env@7.20.2_@babel+core@7.21.3/node_modules/@babel/preset-env", 853 | "link": true 854 | }, 855 | "node_modules/@babel/preset-react": { 856 | "resolved": "../../node_modules/.pnpm/@babel+preset-react@7.18.6_@babel+core@7.21.3/node_modules/@babel/preset-react", 857 | "link": true 858 | }, 859 | "node_modules/@codemirror/autocomplete": { 860 | "resolved": "../../node_modules/.pnpm/@codemirror+autocomplete@6.4.2_@codemirror+view@6.9.2/node_modules/@codemirror/autocomplete", 861 | "link": true 862 | }, 863 | "node_modules/@codemirror/lang-javascript": { 864 | "resolved": "../../node_modules/.pnpm/@codemirror+lang-javascript@6.1.4/node_modules/@codemirror/lang-javascript", 865 | "link": true 866 | }, 867 | "node_modules/@codemirror/view": { 868 | "resolved": "../../node_modules/.pnpm/@codemirror+view@6.9.2/node_modules/@codemirror/view", 869 | "link": true 870 | }, 871 | "node_modules/@rollup/plugin-babel": { 872 | "resolved": "../../node_modules/.pnpm/@rollup+plugin-babel@6.0.3_juvh72w4ry7wdzu3k4tlty4ke4/node_modules/@rollup/plugin-babel", 873 | "link": true 874 | }, 875 | "node_modules/@rollup/plugin-commonjs": { 876 | "resolved": "../../node_modules/.pnpm/@rollup+plugin-commonjs@24.0.1_rollup@3.19.1/node_modules/@rollup/plugin-commonjs", 877 | "link": true 878 | }, 879 | "node_modules/@rollup/plugin-node-resolve": { 880 | "resolved": "../../node_modules/.pnpm/@rollup+plugin-node-resolve@15.0.1_rollup@3.19.1/node_modules/@rollup/plugin-node-resolve", 881 | "link": true 882 | }, 883 | "node_modules/@types/prop-types": { 884 | "version": "15.7.5", 885 | "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", 886 | "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", 887 | "dev": true 888 | }, 889 | "node_modules/@types/react": { 890 | "version": "18.0.28", 891 | "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz", 892 | "integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==", 893 | "dev": true, 894 | "dependencies": { 895 | "@types/prop-types": "*", 896 | "@types/scheduler": "*", 897 | "csstype": "^3.0.2" 898 | } 899 | }, 900 | "node_modules/@types/scheduler": { 901 | "version": "0.16.2", 902 | "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", 903 | "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", 904 | "dev": true 905 | }, 906 | "node_modules/@uiw/codemirror-theme-github": { 907 | "resolved": "../../node_modules/.pnpm/@uiw+codemirror-theme-github@4.19.9_@codemirror+view@6.9.2/node_modules/@uiw/codemirror-theme-github", 908 | "link": true 909 | }, 910 | "node_modules/@uiw/react-codemirror": { 911 | "resolved": "../../node_modules/.pnpm/@uiw+react-codemirror@4.19.9_e6uob5njowrusdmcrg6qxzpedi/node_modules/@uiw/react-codemirror", 912 | "link": true 913 | }, 914 | "node_modules/csstype": { 915 | "version": "3.1.1", 916 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", 917 | "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", 918 | "dev": true 919 | }, 920 | "node_modules/react": { 921 | "resolved": "../../node_modules/.pnpm/react@18.2.0/node_modules/react", 922 | "link": true 923 | }, 924 | "node_modules/react-dom": { 925 | "resolved": "../../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom", 926 | "link": true 927 | }, 928 | "node_modules/rollup": { 929 | "resolved": "../../node_modules/.pnpm/rollup@3.19.1/node_modules/rollup", 930 | "link": true 931 | }, 932 | "node_modules/rollup-plugin-babel": { 933 | "resolved": "../../node_modules/.pnpm/rollup-plugin-babel@4.4.0_juvh72w4ry7wdzu3k4tlty4ke4/node_modules/rollup-plugin-babel", 934 | "link": true 935 | }, 936 | "node_modules/rollup-plugin-clear": { 937 | "resolved": "../../node_modules/.pnpm/rollup-plugin-clear@2.0.7/node_modules/rollup-plugin-clear", 938 | "link": true 939 | }, 940 | "node_modules/rollup-plugin-dts": { 941 | "resolved": "../../node_modules/.pnpm/rollup-plugin-dts@5.3.0_7iejawhbqmte5pthjozf4tfuqy/node_modules/rollup-plugin-dts", 942 | "link": true 943 | }, 944 | "node_modules/rollup-plugin-terser": { 945 | "resolved": "../../node_modules/.pnpm/rollup-plugin-terser@7.0.2_rollup@3.19.1/node_modules/rollup-plugin-terser", 946 | "link": true 947 | }, 948 | "node_modules/rollup-plugin-typescript2": { 949 | "resolved": "../../node_modules/.pnpm/rollup-plugin-typescript2@0.34.1_7iejawhbqmte5pthjozf4tfuqy/node_modules/rollup-plugin-typescript2", 950 | "link": true 951 | }, 952 | "node_modules/tslib": { 953 | "resolved": "../../node_modules/.pnpm/tslib@2.5.0/node_modules/tslib", 954 | "link": true 955 | }, 956 | "node_modules/typescript": { 957 | "resolved": "../../node_modules/.pnpm/typescript@5.0.2/node_modules/typescript", 958 | "link": true 959 | } 960 | }, 961 | "dependencies": { 962 | "@babel/core": { 963 | "version": "file:../../node_modules/.pnpm/@babel+core@7.21.3/node_modules/@babel/core", 964 | "requires": { 965 | "@ampproject/remapping": "^2.2.0", 966 | "@babel/code-frame": "^7.18.6", 967 | "@babel/generator": "^7.21.3", 968 | "@babel/helper-compilation-targets": "^7.20.7", 969 | "@babel/helper-module-transforms": "^7.21.2", 970 | "@babel/helper-transform-fixture-test-runner": "^7.20.14", 971 | "@babel/helpers": "^7.21.0", 972 | "@babel/parser": "^7.21.3", 973 | "@babel/plugin-syntax-flow": "^7.18.6", 974 | "@babel/plugin-transform-flow-strip-types": "^7.21.0", 975 | "@babel/plugin-transform-modules-commonjs": "^7.21.2", 976 | "@babel/preset-env": "^7.20.2", 977 | "@babel/template": "^7.20.7", 978 | "@babel/traverse": "^7.21.3", 979 | "@babel/types": "^7.21.3", 980 | "@jridgewell/trace-mapping": "^0.3.17", 981 | "@types/convert-source-map": "^1.5.1", 982 | "@types/debug": "^4.1.0", 983 | "@types/gensync": "^1.0.0", 984 | "@types/resolve": "^1.3.2", 985 | "@types/semver": "^5.4.0", 986 | "convert-source-map": "^1.7.0", 987 | "debug": "^4.1.0", 988 | "gensync": "^1.0.0-beta.2", 989 | "json5": "^2.2.2", 990 | "rimraf": "^3.0.0", 991 | "semver": "^6.3.0", 992 | "ts-node": "^10.9.1" 993 | } 994 | }, 995 | "@babel/plugin-proposal-class-properties": { 996 | "version": "file:../../node_modules/.pnpm/@babel+plugin-proposal-class-properties@7.18.6_@babel+core@7.21.3/node_modules/@babel/plugin-proposal-class-properties", 997 | "requires": { 998 | "@babel/core": "^7.18.6", 999 | "@babel/helper-create-class-features-plugin": "^7.18.6", 1000 | "@babel/helper-plugin-test-runner": "^7.18.6", 1001 | "@babel/helper-plugin-utils": "^7.18.6" 1002 | } 1003 | }, 1004 | "@babel/plugin-proposal-decorators": { 1005 | "version": "file:../../node_modules/.pnpm/@babel+plugin-proposal-decorators@7.21.0_@babel+core@7.21.3/node_modules/@babel/plugin-proposal-decorators", 1006 | "requires": { 1007 | "@babel/core": "^7.21.0", 1008 | "@babel/helper-create-class-features-plugin": "^7.21.0", 1009 | "@babel/helper-plugin-test-runner": "^7.18.6", 1010 | "@babel/helper-plugin-utils": "^7.20.2", 1011 | "@babel/helper-replace-supers": "^7.20.7", 1012 | "@babel/helper-split-export-declaration": "^7.18.6", 1013 | "@babel/plugin-syntax-decorators": "^7.21.0", 1014 | "@babel/traverse": "^7.21.0", 1015 | "@types/charcodes": "^0.2.0", 1016 | "array.prototype.concat": "^1.0.2", 1017 | "babel-plugin-polyfill-es-shims": "^0.7.1", 1018 | "charcodes": "^0.2.0", 1019 | "object.getownpropertydescriptors": "^2.1.1" 1020 | } 1021 | }, 1022 | "@babel/plugin-syntax-jsx": { 1023 | "version": "file:../../node_modules/.pnpm/@babel+plugin-syntax-jsx@7.18.6_@babel+core@7.21.3/node_modules/@babel/plugin-syntax-jsx", 1024 | "requires": { 1025 | "@babel/core": "^7.18.6", 1026 | "@babel/helper-plugin-utils": "^7.18.6" 1027 | } 1028 | }, 1029 | "@babel/plugin-transform-react-jsx": { 1030 | "version": "file:../../node_modules/.pnpm/@babel+plugin-transform-react-jsx@7.21.0_@babel+core@7.21.3/node_modules/@babel/plugin-transform-react-jsx", 1031 | "requires": { 1032 | "@babel/core": "^7.21.0", 1033 | "@babel/helper-annotate-as-pure": "^7.18.6", 1034 | "@babel/helper-module-imports": "^7.18.6", 1035 | "@babel/helper-plugin-test-runner": "^7.18.6", 1036 | "@babel/helper-plugin-utils": "^7.20.2", 1037 | "@babel/plugin-syntax-jsx": "^7.18.6", 1038 | "@babel/traverse": "^7.21.0", 1039 | "@babel/types": "^7.21.0" 1040 | } 1041 | }, 1042 | "@babel/plugin-transform-runtime": { 1043 | "version": "file:../../node_modules/.pnpm/@babel+plugin-transform-runtime@7.21.0_@babel+core@7.21.3/node_modules/@babel/plugin-transform-runtime", 1044 | "requires": { 1045 | "@babel/core": "^7.21.0", 1046 | "@babel/helper-module-imports": "^7.18.6", 1047 | "@babel/helper-plugin-test-runner": "^7.18.6", 1048 | "@babel/helper-plugin-utils": "^7.20.2", 1049 | "@babel/helpers": "^7.21.0", 1050 | "@babel/preset-env": "^7.20.2", 1051 | "@babel/runtime": "^7.21.0", 1052 | "@babel/runtime-corejs3": "^7.21.0", 1053 | "@babel/template": "^7.20.7", 1054 | "@babel/types": "^7.21.0", 1055 | "babel-plugin-polyfill-corejs2": "^0.3.3", 1056 | "babel-plugin-polyfill-corejs3": "^0.6.0", 1057 | "babel-plugin-polyfill-regenerator": "^0.4.1", 1058 | "make-dir": "^2.1.0", 1059 | "semver": "^6.3.0" 1060 | } 1061 | }, 1062 | "@babel/preset-env": { 1063 | "version": "file:../../node_modules/.pnpm/@babel+preset-env@7.20.2_@babel+core@7.21.3/node_modules/@babel/preset-env", 1064 | "requires": { 1065 | "@babel/compat-data": "^7.20.1", 1066 | "@babel/core": "^7.20.2", 1067 | "@babel/core-7.12": "npm:@babel/core@7.12.9", 1068 | "@babel/helper-compilation-targets": "^7.20.0", 1069 | "@babel/helper-plugin-test-runner": "^7.18.6", 1070 | "@babel/helper-plugin-utils": "^7.20.2", 1071 | "@babel/helper-validator-option": "^7.18.6", 1072 | "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6", 1073 | "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9", 1074 | "@babel/plugin-proposal-async-generator-functions": "^7.20.1", 1075 | "@babel/plugin-proposal-class-properties": "^7.18.6", 1076 | "@babel/plugin-proposal-class-static-block": "^7.18.6", 1077 | "@babel/plugin-proposal-dynamic-import": "^7.18.6", 1078 | "@babel/plugin-proposal-export-namespace-from": "^7.18.9", 1079 | "@babel/plugin-proposal-json-strings": "^7.18.6", 1080 | "@babel/plugin-proposal-logical-assignment-operators": "^7.18.9", 1081 | "@babel/plugin-proposal-nullish-coalescing-operator": "^7.18.6", 1082 | "@babel/plugin-proposal-numeric-separator": "^7.18.6", 1083 | "@babel/plugin-proposal-object-rest-spread": "^7.20.2", 1084 | "@babel/plugin-proposal-optional-catch-binding": "^7.18.6", 1085 | "@babel/plugin-proposal-optional-chaining": "^7.18.9", 1086 | "@babel/plugin-proposal-private-methods": "^7.18.6", 1087 | "@babel/plugin-proposal-private-property-in-object": "^7.18.6", 1088 | "@babel/plugin-proposal-unicode-property-regex": "^7.18.6", 1089 | "@babel/plugin-syntax-async-generators": "^7.8.4", 1090 | "@babel/plugin-syntax-class-properties": "^7.12.13", 1091 | "@babel/plugin-syntax-class-static-block": "^7.14.5", 1092 | "@babel/plugin-syntax-dynamic-import": "^7.8.3", 1093 | "@babel/plugin-syntax-export-namespace-from": "^7.8.3", 1094 | "@babel/plugin-syntax-import-assertions": "^7.20.0", 1095 | "@babel/plugin-syntax-json-strings": "^7.8.3", 1096 | "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", 1097 | "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", 1098 | "@babel/plugin-syntax-numeric-separator": "^7.10.4", 1099 | "@babel/plugin-syntax-object-rest-spread": "^7.8.3", 1100 | "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", 1101 | "@babel/plugin-syntax-optional-chaining": "^7.8.3", 1102 | "@babel/plugin-syntax-private-property-in-object": "^7.14.5", 1103 | "@babel/plugin-syntax-top-level-await": "^7.14.5", 1104 | "@babel/plugin-transform-arrow-functions": "^7.18.6", 1105 | "@babel/plugin-transform-async-to-generator": "^7.18.6", 1106 | "@babel/plugin-transform-block-scoped-functions": "^7.18.6", 1107 | "@babel/plugin-transform-block-scoping": "^7.20.2", 1108 | "@babel/plugin-transform-classes": "^7.20.2", 1109 | "@babel/plugin-transform-computed-properties": "^7.18.9", 1110 | "@babel/plugin-transform-destructuring": "^7.20.2", 1111 | "@babel/plugin-transform-dotall-regex": "^7.18.6", 1112 | "@babel/plugin-transform-duplicate-keys": "^7.18.9", 1113 | "@babel/plugin-transform-exponentiation-operator": "^7.18.6", 1114 | "@babel/plugin-transform-for-of": "^7.18.8", 1115 | "@babel/plugin-transform-function-name": "^7.18.9", 1116 | "@babel/plugin-transform-literals": "^7.18.9", 1117 | "@babel/plugin-transform-member-expression-literals": "^7.18.6", 1118 | "@babel/plugin-transform-modules-amd": "^7.19.6", 1119 | "@babel/plugin-transform-modules-commonjs": "^7.19.6", 1120 | "@babel/plugin-transform-modules-systemjs": "^7.19.6", 1121 | "@babel/plugin-transform-modules-umd": "^7.18.6", 1122 | "@babel/plugin-transform-named-capturing-groups-regex": "^7.19.1", 1123 | "@babel/plugin-transform-new-target": "^7.18.6", 1124 | "@babel/plugin-transform-object-super": "^7.18.6", 1125 | "@babel/plugin-transform-parameters": "^7.20.1", 1126 | "@babel/plugin-transform-property-literals": "^7.18.6", 1127 | "@babel/plugin-transform-regenerator": "^7.18.6", 1128 | "@babel/plugin-transform-reserved-words": "^7.18.6", 1129 | "@babel/plugin-transform-shorthand-properties": "^7.18.6", 1130 | "@babel/plugin-transform-spread": "^7.19.0", 1131 | "@babel/plugin-transform-sticky-regex": "^7.18.6", 1132 | "@babel/plugin-transform-template-literals": "^7.18.9", 1133 | "@babel/plugin-transform-typeof-symbol": "^7.18.9", 1134 | "@babel/plugin-transform-unicode-escapes": "^7.18.10", 1135 | "@babel/plugin-transform-unicode-regex": "^7.18.6", 1136 | "@babel/preset-modules": "^0.1.5", 1137 | "@babel/traverse": "^7.20.1", 1138 | "@babel/types": "^7.20.2", 1139 | "babel-plugin-polyfill-corejs2": "^0.3.3", 1140 | "babel-plugin-polyfill-corejs3": "^0.6.0", 1141 | "babel-plugin-polyfill-regenerator": "^0.4.1", 1142 | "core-js-compat": "^3.25.1", 1143 | "semver": "^6.3.0" 1144 | } 1145 | }, 1146 | "@babel/preset-react": { 1147 | "version": "file:../../node_modules/.pnpm/@babel+preset-react@7.18.6_@babel+core@7.21.3/node_modules/@babel/preset-react", 1148 | "requires": { 1149 | "@babel/core": "^7.18.6", 1150 | "@babel/helper-plugin-test-runner": "^7.18.6", 1151 | "@babel/helper-plugin-utils": "^7.18.6", 1152 | "@babel/helper-validator-option": "^7.18.6", 1153 | "@babel/plugin-transform-react-display-name": "^7.18.6", 1154 | "@babel/plugin-transform-react-jsx": "^7.18.6", 1155 | "@babel/plugin-transform-react-jsx-development": "^7.18.6", 1156 | "@babel/plugin-transform-react-pure-annotations": "^7.18.6" 1157 | } 1158 | }, 1159 | "@codemirror/autocomplete": { 1160 | "version": "file:../../node_modules/.pnpm/@codemirror+autocomplete@6.4.2_@codemirror+view@6.9.2/node_modules/@codemirror/autocomplete", 1161 | "requires": { 1162 | "@codemirror/buildhelper": "^0.1.5", 1163 | "@codemirror/language": "^6.0.0", 1164 | "@codemirror/state": "^6.0.0", 1165 | "@codemirror/view": "^6.6.0", 1166 | "@lezer/common": "^1.0.0" 1167 | } 1168 | }, 1169 | "@codemirror/lang-javascript": { 1170 | "version": "file:../../node_modules/.pnpm/@codemirror+lang-javascript@6.1.4/node_modules/@codemirror/lang-javascript", 1171 | "requires": { 1172 | "@codemirror/autocomplete": "^6.0.0", 1173 | "@codemirror/buildhelper": "^0.1.5", 1174 | "@codemirror/language": "^6.6.0", 1175 | "@codemirror/lint": "^6.0.0", 1176 | "@codemirror/state": "^6.0.0", 1177 | "@codemirror/view": "^6.0.0", 1178 | "@lezer/common": "^1.0.0", 1179 | "@lezer/javascript": "^1.0.0", 1180 | "@lezer/lr": "^1.0.0" 1181 | } 1182 | }, 1183 | "@codemirror/view": { 1184 | "version": "file:../../node_modules/.pnpm/@codemirror+view@6.9.2/node_modules/@codemirror/view", 1185 | "requires": { 1186 | "@codemirror/buildhelper": "^0.1.6", 1187 | "@codemirror/state": "^6.1.4", 1188 | "style-mod": "^4.0.0", 1189 | "w3c-keyname": "^2.2.4" 1190 | } 1191 | }, 1192 | "@rollup/plugin-babel": { 1193 | "version": "file:../../node_modules/.pnpm/@rollup+plugin-babel@6.0.3_juvh72w4ry7wdzu3k4tlty4ke4/node_modules/@rollup/plugin-babel", 1194 | "requires": { 1195 | "@babel/core": "^7.19.1", 1196 | "@babel/helper-module-imports": "^7.18.6", 1197 | "@babel/plugin-external-helpers": "^7.18.6", 1198 | "@babel/plugin-proposal-decorators": "^7.19.1", 1199 | "@babel/plugin-syntax-dynamic-import": "^7.8.3", 1200 | "@babel/plugin-transform-runtime": "^7.19.1", 1201 | "@babel/preset-env": "^7.19.1", 1202 | "@rollup/plugin-json": "^5.0.0", 1203 | "@rollup/plugin-node-resolve": "^15.0.0", 1204 | "@rollup/pluginutils": "^5.0.1", 1205 | "@types/babel__core": "^7.1.9", 1206 | "rollup": "^3.2.3", 1207 | "source-map": "^0.7.4" 1208 | } 1209 | }, 1210 | "@rollup/plugin-commonjs": { 1211 | "version": "file:../../node_modules/.pnpm/@rollup+plugin-commonjs@24.0.1_rollup@3.19.1/node_modules/@rollup/plugin-commonjs", 1212 | "requires": { 1213 | "@rollup/plugin-json": "^5.0.0", 1214 | "@rollup/plugin-node-resolve": "^15.0.0", 1215 | "@rollup/pluginutils": "^5.0.1", 1216 | "commondir": "^1.0.1", 1217 | "estree-walker": "^2.0.2", 1218 | "glob": "^8.0.3", 1219 | "is-reference": "1.2.1", 1220 | "locate-character": "^2.0.5", 1221 | "magic-string": "^0.27.0", 1222 | "require-relative": "^0.8.7", 1223 | "rollup": "3.0.0-7", 1224 | "shx": "^0.3.4", 1225 | "source-map": "^0.7.4", 1226 | "source-map-support": "^0.5.21", 1227 | "typescript": "^4.8.3" 1228 | } 1229 | }, 1230 | "@rollup/plugin-node-resolve": { 1231 | "version": "file:../../node_modules/.pnpm/@rollup+plugin-node-resolve@15.0.1_rollup@3.19.1/node_modules/@rollup/plugin-node-resolve", 1232 | "requires": { 1233 | "@babel/core": "^7.19.1", 1234 | "@babel/plugin-transform-typescript": "^7.10.5", 1235 | "@rollup/plugin-babel": "^6.0.0", 1236 | "@rollup/plugin-commonjs": "^23.0.0", 1237 | "@rollup/plugin-json": "^5.0.0", 1238 | "@rollup/pluginutils": "^5.0.1", 1239 | "@types/resolve": "1.20.2", 1240 | "deepmerge": "^4.2.2", 1241 | "es5-ext": "^0.10.62", 1242 | "is-builtin-module": "^3.2.0", 1243 | "is-module": "^1.0.0", 1244 | "resolve": "^1.22.1", 1245 | "rollup": "^3.2.3", 1246 | "source-map": "^0.7.4", 1247 | "string-capitalize": "^1.0.1" 1248 | } 1249 | }, 1250 | "@types/prop-types": { 1251 | "version": "15.7.5", 1252 | "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", 1253 | "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", 1254 | "dev": true 1255 | }, 1256 | "@types/react": { 1257 | "version": "18.0.28", 1258 | "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz", 1259 | "integrity": "sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==", 1260 | "dev": true, 1261 | "requires": { 1262 | "@types/prop-types": "*", 1263 | "@types/scheduler": "*", 1264 | "csstype": "^3.0.2" 1265 | } 1266 | }, 1267 | "@types/scheduler": { 1268 | "version": "0.16.2", 1269 | "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", 1270 | "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", 1271 | "dev": true 1272 | }, 1273 | "@uiw/codemirror-theme-github": { 1274 | "version": "file:../../node_modules/.pnpm/@uiw+codemirror-theme-github@4.19.9_@codemirror+view@6.9.2/node_modules/@uiw/codemirror-theme-github", 1275 | "requires": { 1276 | "@uiw/codemirror-themes": "4.19.9" 1277 | } 1278 | }, 1279 | "@uiw/react-codemirror": { 1280 | "version": "file:../../node_modules/.pnpm/@uiw+react-codemirror@4.19.9_e6uob5njowrusdmcrg6qxzpedi/node_modules/@uiw/react-codemirror", 1281 | "requires": { 1282 | "@babel/runtime": "^7.18.6", 1283 | "@codemirror/commands": "^6.1.0", 1284 | "@codemirror/state": "^6.1.1", 1285 | "@codemirror/theme-one-dark": "^6.0.0", 1286 | "@uiw/codemirror-extensions-basic-setup": "4.19.9", 1287 | "codemirror": "^6.0.0" 1288 | } 1289 | }, 1290 | "csstype": { 1291 | "version": "3.1.1", 1292 | "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", 1293 | "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==", 1294 | "dev": true 1295 | }, 1296 | "react": { 1297 | "version": "file:../../node_modules/.pnpm/react@18.2.0/node_modules/react", 1298 | "requires": { 1299 | "loose-envify": "^1.1.0" 1300 | } 1301 | }, 1302 | "react-dom": { 1303 | "version": "file:../../node_modules/.pnpm/react-dom@18.2.0_react@18.2.0/node_modules/react-dom", 1304 | "requires": { 1305 | "loose-envify": "^1.1.0", 1306 | "scheduler": "^0.23.0" 1307 | } 1308 | }, 1309 | "rollup": { 1310 | "version": "file:../../node_modules/.pnpm/rollup@3.19.1/node_modules/rollup", 1311 | "requires": { 1312 | "@codemirror/commands": "^6.2.1", 1313 | "@codemirror/lang-javascript": "^6.1.4", 1314 | "@codemirror/language": "^6.6.0", 1315 | "@codemirror/search": "^6.2.3", 1316 | "@codemirror/state": "^6.2.0", 1317 | "@codemirror/view": "^6.9.2", 1318 | "@jridgewell/sourcemap-codec": "^1.4.14", 1319 | "@mermaid-js/mermaid-cli": "^10.0.2", 1320 | "@rollup/plugin-alias": "^4.0.3", 1321 | "@rollup/plugin-buble": "^1.0.2", 1322 | "@rollup/plugin-commonjs": "^24.0.1", 1323 | "@rollup/plugin-json": "^6.0.0", 1324 | "@rollup/plugin-node-resolve": "^15.0.1", 1325 | "@rollup/plugin-replace": "^5.0.2", 1326 | "@rollup/plugin-terser": "^0.4.0", 1327 | "@rollup/plugin-typescript": "^11.0.0", 1328 | "@rollup/pluginutils": "^5.0.2", 1329 | "@types/estree": "1.0.0", 1330 | "@types/node": "^14.18.36", 1331 | "@types/signal-exit": "^3.0.1", 1332 | "@types/yargs-parser": "^21.0.0", 1333 | "@typescript-eslint/eslint-plugin": "^5.54.1", 1334 | "@typescript-eslint/parser": "^5.54.1", 1335 | "@vue/eslint-config-prettier": "^7.1.0", 1336 | "@vue/eslint-config-typescript": "^11.0.2", 1337 | "acorn": "^8.8.2", 1338 | "acorn-import-assertions": "^1.8.0", 1339 | "acorn-jsx": "^5.3.2", 1340 | "acorn-walk": "^8.2.0", 1341 | "buble": "^0.20.0", 1342 | "builtin-modules": "^3.3.0", 1343 | "chokidar": "^3.5.3", 1344 | "colorette": "^2.0.19", 1345 | "concurrently": "^7.6.0", 1346 | "core-js": "^3.29.0", 1347 | "date-time": "^4.0.0", 1348 | "es5-shim": "^4.6.7", 1349 | "es6-shim": "^0.35.7", 1350 | "eslint": "^8.35.0", 1351 | "eslint-config-prettier": "^8.7.0", 1352 | "eslint-plugin-import": "^2.27.5", 1353 | "eslint-plugin-prettier": "^4.2.1", 1354 | "eslint-plugin-unicorn": "^46.0.0", 1355 | "eslint-plugin-vue": "^9.9.0", 1356 | "fixturify": "^3.0.0", 1357 | "flru": "^1.0.2", 1358 | "fs-extra": "^11.1.0", 1359 | "fsevents": "~2.3.2", 1360 | "github-api": "^3.4.0", 1361 | "hash.js": "^1.1.7", 1362 | "husky": "^8.0.3", 1363 | "inquirer": "^9.1.4", 1364 | "is-reference": "^3.0.1", 1365 | "lint-staged": "^13.1.2", 1366 | "locate-character": "^2.0.5", 1367 | "magic-string": "^0.30.0", 1368 | "mocha": "^10.2.0", 1369 | "nyc": "^15.1.0", 1370 | "pinia": "^2.0.33", 1371 | "prettier": "^2.8.4", 1372 | "pretty-bytes": "^6.1.0", 1373 | "pretty-ms": "^8.0.0", 1374 | "requirejs": "^2.3.6", 1375 | "rollup": "^3.18.0", 1376 | "rollup-plugin-license": "^3.0.1", 1377 | "rollup-plugin-string": "^3.0.0", 1378 | "rollup-plugin-thatworks": "^1.0.4", 1379 | "semver": "^7.3.8", 1380 | "shx": "^0.3.4", 1381 | "signal-exit": "^3.0.7", 1382 | "source-map": "^0.7.4", 1383 | "source-map-support": "^0.5.21", 1384 | "systemjs": "^6.14.0", 1385 | "terser": "^5.16.5", 1386 | "tslib": "^2.5.0", 1387 | "typescript": "^4.9.5", 1388 | "vitepress": "^1.0.0-alpha.50", 1389 | "vue": "^3.2.47", 1390 | "weak-napi": "^2.0.2", 1391 | "yargs-parser": "^21.1.1" 1392 | } 1393 | }, 1394 | "rollup-plugin-babel": { 1395 | "version": "file:../../node_modules/.pnpm/rollup-plugin-babel@4.4.0_juvh72w4ry7wdzu3k4tlty4ke4/node_modules/rollup-plugin-babel", 1396 | "requires": { 1397 | "@babel/core": "^7.3.4", 1398 | "@babel/helper-module-imports": "^7.0.0", 1399 | "@babel/plugin-external-helpers": "^7.0.0", 1400 | "@babel/plugin-proposal-decorators": "^7.0.0", 1401 | "@babel/plugin-transform-runtime": "^7.0.0", 1402 | "@babel/preset-env": "^7.3.4", 1403 | "buble": "^0.19.3", 1404 | "eslint": "^5.15.1", 1405 | "eslint-config-prettier": "^3.3.0", 1406 | "eslint-plugin-prettier": "^3.0.0", 1407 | "husky": "^1.0.1", 1408 | "lint-staged": "^7.2.2", 1409 | "mocha": "^5.2.0", 1410 | "prettier": "^1.15.3", 1411 | "rollup": "^2.0.1", 1412 | "rollup-plugin-buble": "^0.19.2", 1413 | "rollup-plugin-json": "^3.0.0", 1414 | "rollup-pluginutils": "^2.8.1", 1415 | "source-map": "^0.6.1", 1416 | "source-map-support": "^0.5.6" 1417 | } 1418 | }, 1419 | "rollup-plugin-clear": { 1420 | "version": "file:../../node_modules/.pnpm/rollup-plugin-clear@2.0.7/node_modules/rollup-plugin-clear", 1421 | "requires": { 1422 | "@types/jest": "^22.1.2", 1423 | "@types/rimraf": "^2.0.2", 1424 | "jest": "^22.2.2", 1425 | "rimraf": "^2.6.2", 1426 | "rollup": "^0.55.5", 1427 | "rollup-plugin-commonjs": "^8.3.0", 1428 | "rollup-plugin-filesize": "^1.5.0", 1429 | "rollup-plugin-node-resolve": "^3.0.2", 1430 | "rollup-plugin-progress": "^0.4.0", 1431 | "rollup-plugin-typescript2": "^0.11.1", 1432 | "ts-jest": "^22.0.4", 1433 | "typescript": "^2.7.1" 1434 | } 1435 | }, 1436 | "rollup-plugin-dts": { 1437 | "version": "file:../../node_modules/.pnpm/rollup-plugin-dts@5.3.0_7iejawhbqmte5pthjozf4tfuqy/node_modules/rollup-plugin-dts", 1438 | "requires": { 1439 | "@babel/code-frame": "^7.18.6", 1440 | "@types/babel__code-frame": "^7.0.3", 1441 | "@types/d3-drag": "^3.0.2", 1442 | "@types/estree": "1.0.0", 1443 | "@types/node": "^18.15.3", 1444 | "@types/react": "^18.0.28", 1445 | "c8": "^7.13.0", 1446 | "magic-string": "^0.30.0", 1447 | "rollup": "3.19.1", 1448 | "typescript": "5.0.2" 1449 | } 1450 | }, 1451 | "rollup-plugin-terser": { 1452 | "version": "file:../../node_modules/.pnpm/rollup-plugin-terser@7.0.2_rollup@3.19.1/node_modules/rollup-plugin-terser", 1453 | "requires": { 1454 | "@babel/code-frame": "^7.10.4", 1455 | "@babel/core": "^7.11.1", 1456 | "jest": "^26.2.2", 1457 | "jest-worker": "^26.2.1", 1458 | "prettier": "^2.0.5", 1459 | "rollup": "^2.23.1", 1460 | "serialize-javascript": "^4.0.0", 1461 | "terser": "^5.0.0" 1462 | } 1463 | }, 1464 | "rollup-plugin-typescript2": { 1465 | "version": "file:../../node_modules/.pnpm/rollup-plugin-typescript2@0.34.1_7iejawhbqmte5pthjozf4tfuqy/node_modules/rollup-plugin-typescript2", 1466 | "requires": { 1467 | "@jest/globals": "^28.0.3", 1468 | "@rollup/plugin-commonjs": "^22.0.0", 1469 | "@rollup/plugin-node-resolve": "13.2.1", 1470 | "@rollup/pluginutils": "^4.1.2", 1471 | "@types/find-cache-dir": "^2.0.0", 1472 | "@types/fs-extra": "8.0.1", 1473 | "@types/graphlib": "2.1.7", 1474 | "@types/jest": "^27.5.0", 1475 | "@types/lodash": "4.14.161", 1476 | "@types/node": "8.0.47", 1477 | "@types/object-hash": "1.3.3", 1478 | "@types/semver": "7.3.12", 1479 | "colors": "1.4.0", 1480 | "find-cache-dir": "^3.3.2", 1481 | "fs-extra": "^10.0.0", 1482 | "graphlib": "2.1.8", 1483 | "jest": "^28.0.0", 1484 | "lodash": "4.17.21", 1485 | "object-hash": "3.0.0", 1486 | "rimraf": "3.0.2", 1487 | "rollup": "^2.70.2", 1488 | "rollup-plugin-re": "1.0.7", 1489 | "rollup-plugin-typescript2": "0.34.0", 1490 | "semver": "^7.3.7", 1491 | "ts-jest": "^28.0.0", 1492 | "tslib": "^2.4.0", 1493 | "tslint": "6.1.3", 1494 | "typescript": "^4.6.3" 1495 | } 1496 | }, 1497 | "tslib": { 1498 | "version": "file:../../node_modules/.pnpm/tslib@2.5.0/node_modules/tslib" 1499 | }, 1500 | "typescript": { 1501 | "version": "file:../../node_modules/.pnpm/typescript@5.0.2/node_modules/typescript", 1502 | "requires": { 1503 | "@esfx/canceltoken": "^1.0.0", 1504 | "@octokit/rest": "latest", 1505 | "@types/chai": "^4.3.4", 1506 | "@types/fs-extra": "^9.0.13", 1507 | "@types/glob": "^8.1.0", 1508 | "@types/microsoft__typescript-etw": "^0.1.1", 1509 | "@types/minimist": "^1.2.2", 1510 | "@types/mocha": "^10.0.1", 1511 | "@types/ms": "^0.7.31", 1512 | "@types/node": "latest", 1513 | "@types/source-map-support": "^0.5.6", 1514 | "@types/which": "^2.0.1", 1515 | "@typescript-eslint/eslint-plugin": "^5.33.1", 1516 | "@typescript-eslint/parser": "^5.33.1", 1517 | "@typescript-eslint/utils": "^5.33.1", 1518 | "azure-devops-node-api": "^11.2.0", 1519 | "chai": "^4.3.7", 1520 | "chalk": "^4.1.2", 1521 | "chokidar": "^3.5.3", 1522 | "del": "^6.1.1", 1523 | "diff": "^5.1.0", 1524 | "esbuild": "^0.17.2", 1525 | "eslint": "^8.22.0", 1526 | "eslint-formatter-autolinkable-stylish": "^1.2.0", 1527 | "eslint-plugin-import": "^2.26.0", 1528 | "eslint-plugin-local": "^1.0.0", 1529 | "eslint-plugin-no-null": "^1.0.2", 1530 | "eslint-plugin-simple-import-sort": "^10.0.0", 1531 | "fast-xml-parser": "^4.0.11", 1532 | "fs-extra": "^9.1.0", 1533 | "glob": "^8.1.0", 1534 | "hereby": "^1.6.4", 1535 | "jsonc-parser": "^3.2.0", 1536 | "minimist": "^1.2.8", 1537 | "mocha": "^10.2.0", 1538 | "mocha-fivemat-progress-reporter": "^0.1.0", 1539 | "ms": "^2.1.3", 1540 | "node-fetch": "^3.2.10", 1541 | "source-map-support": "^0.5.21", 1542 | "typescript": "5.0.0-dev.20230112", 1543 | "which": "^2.0.2" 1544 | } 1545 | } 1546 | } 1547 | } 1548 | --------------------------------------------------------------------------------