├── .gitignore ├── .gitattributes ├── client ├── src │ ├── vite-env.d.ts │ ├── img │ │ ├── file.png │ │ ├── desktop.jpg │ │ ├── desktop1.jpg │ │ └── desktopp.jpg │ ├── components │ │ ├── styles │ │ │ ├── index.css │ │ │ ├── Files.css │ │ │ ├── Commit.css │ │ │ ├── Menu.css │ │ │ ├── Branches.css │ │ │ ├── GitGraph.css │ │ │ └── Editor.css │ │ ├── Menu │ │ │ ├── utility │ │ │ │ ├── menuOptions.ts │ │ │ │ └── utilityComponents.tsx │ │ │ ├── Clock.tsx │ │ │ ├── ShowGraph.tsx │ │ │ ├── Menu.tsx │ │ │ └── Help.tsx │ │ ├── Git │ │ │ ├── GitGraphWrapper.tsx │ │ │ ├── BranchSwitcher.tsx │ │ │ ├── Branches.tsx │ │ │ ├── GitGraph.tsx │ │ │ └── Commits.tsx │ │ ├── Actions │ │ │ └── Actions.tsx │ │ ├── Files │ │ │ └── Files.tsx │ │ └── Editor │ │ │ └── Editor.tsx │ ├── utils │ │ ├── texts.ts │ │ ├── utilityFunctions.ts │ │ └── goFunctions.ts │ ├── types │ │ └── types.ts │ ├── main.tsx │ ├── atoms │ │ └── atoms.ts │ ├── index.css │ ├── App.css │ ├── assets │ │ └── react.svg │ └── App.tsx ├── public │ ├── harmony.png │ └── helpers │ │ ├── wasm │ │ └── main.wasm │ │ └── wasm_exec.js ├── tsconfig.node.json ├── .gitignore ├── vite.config.ts ├── tsconfig.json ├── index.html ├── vite.config.ts.timestamp-1664023584131.mjs ├── package.json └── pnpm-lock.yaml ├── .prettierignore ├── nova ├── Makefile ├── texts │ └── texts.go ├── handlers │ └── inputs.go ├── main.go ├── go.mod ├── virtual │ ├── virtualSystem.go │ └── functions.go ├── mapping │ └── mapping.go └── go.sum ├── Makefile ├── .vscode └── settings.json ├── .prettierrc.js ├── server.js ├── package.json ├── LICENSE ├── README.md └── pnpm-lock.yaml /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.html linguist-detectable=false -------------------------------------------------------------------------------- /client/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | client/**/build 2 | client/**/dist 3 | coverage 4 | *.yaml 5 | *.sh 6 | *.json -------------------------------------------------------------------------------- /client/src/img/file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomscoder/harmony/HEAD/client/src/img/file.png -------------------------------------------------------------------------------- /client/public/harmony.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomscoder/harmony/HEAD/client/public/harmony.png -------------------------------------------------------------------------------- /client/src/img/desktop.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomscoder/harmony/HEAD/client/src/img/desktop.jpg -------------------------------------------------------------------------------- /client/src/img/desktop1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomscoder/harmony/HEAD/client/src/img/desktop1.jpg -------------------------------------------------------------------------------- /client/src/img/desktopp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomscoder/harmony/HEAD/client/src/img/desktopp.jpg -------------------------------------------------------------------------------- /nova/Makefile: -------------------------------------------------------------------------------- 1 | compile: 2 | GOOS=js GOARCH=wasm go build -o ../client/public/helpers/wasm/main.wasm main.go -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | wasmify: 2 | echo $(cat $HOME/go/misc/wasm/wasm_exec.js) 3 | 4 | compile: 5 | cd nova && make compile -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "go.toolsEnvVars": { 3 | "GOOS": "js", 4 | "GOARCH": "wasm" 5 | } 6 | } -------------------------------------------------------------------------------- /client/public/helpers/wasm/main.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomscoder/harmony/HEAD/client/public/helpers/wasm/main.wasm -------------------------------------------------------------------------------- /client/src/components/styles/index.css: -------------------------------------------------------------------------------- 1 | @import 'Branches.css'; 2 | @import 'Commit.css'; 3 | @import 'Editor.css'; 4 | @import 'Files.css'; 5 | @import 'GitGraph.css'; 6 | @import 'Menu.css'; 7 | -------------------------------------------------------------------------------- /client/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 | -------------------------------------------------------------------------------- /nova/texts/texts.go: -------------------------------------------------------------------------------- 1 | package texts 2 | 3 | const ( 4 | CurrentDirectory = "." 5 | FileOpenedSuccessfully = "File opened" 6 | RESET = "\033[0;0m" 7 | GREEN = "\033[1;32m" 8 | HtmlEmptyStringMsg = `Cannot be empty` 9 | ) 10 | -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | // npm run format or npm run dev 2 | module.exports = { 3 | trailingComma: 'all', 4 | tabWidth: 2, 5 | semi: true, 6 | singleQuote: true, 7 | printWidth: 250, 8 | arrowParens: 'always', 9 | bracketSpacing: true, 10 | insertPragma: false, 11 | }; 12 | -------------------------------------------------------------------------------- /client/src/utils/texts.ts: -------------------------------------------------------------------------------- 1 | export const CREATE_BRANCH = 'CREATE_BRANCH'; 2 | export const CREATE_FILE = 'CREATE_FILE'; 3 | export const CREATE_COMMIT = 'CREATE_COMMIT'; 4 | export const UPLOAD_FILE = 'UPLOAD_FILE'; 5 | export const GRAPH_MODE = 'GRAPH_MODE'; 6 | export const HELP = 'HELP'; 7 | -------------------------------------------------------------------------------- /client/src/components/Menu/utility/menuOptions.ts: -------------------------------------------------------------------------------- 1 | import { CREATE_BRANCH, CREATE_COMMIT, CREATE_FILE, UPLOAD_FILE } from '../../../utils/texts'; 2 | 3 | export const options = new Map([ 4 | [0, CREATE_FILE], 5 | [1, UPLOAD_FILE], 6 | [2, CREATE_BRANCH], 7 | [3, CREATE_COMMIT], 8 | ]); 9 | -------------------------------------------------------------------------------- /client/src/types/types.ts: -------------------------------------------------------------------------------- 1 | type harmonyCommit = { 2 | hash?: string; 3 | message?: string; 4 | }; 5 | 6 | export type gitFootPrintType = { 7 | branch: string; 8 | commit: harmonyCommit; 9 | }; 10 | 11 | export type EditorProps = { text: string; save: any; close: any; filename: string }; 12 | -------------------------------------------------------------------------------- /client/.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 | -------------------------------------------------------------------------------- /client/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite'; 2 | import react from '@vitejs/plugin-react'; 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | server: { 7 | proxy: { 8 | '/api': { 9 | target: 'https://github.com', 10 | changeOrigin: true, 11 | rewrite: (path) => path.replace(/^\/api/, ''), 12 | }, 13 | }, 14 | }, 15 | plugins: [react()], 16 | }); 17 | -------------------------------------------------------------------------------- /client/src/utils/utilityFunctions.ts: -------------------------------------------------------------------------------- 1 | import { CREATE_BRANCH, CREATE_COMMIT, CREATE_FILE, HELP, UPLOAD_FILE } from './texts'; 2 | 3 | export const keyChecker = (key: string) => { 4 | switch (key) { 5 | case 'b': 6 | return CREATE_BRANCH; 7 | case 'k': 8 | return CREATE_COMMIT; 9 | case 'f': 10 | return CREATE_FILE; 11 | case 'u': 12 | return UPLOAD_FILE; 13 | case 'h': 14 | return HELP; 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /nova/handlers/inputs.go: -------------------------------------------------------------------------------- 1 | package handlers 2 | 3 | import ( 4 | "nova/texts" 5 | ns "nova/virtual" 6 | "strings" 7 | 8 | "github.com/go-git/go-billy/v5" 9 | ) 10 | 11 | func Init(ns ns.NovaStore, store billy.Filesystem, filename string, content string) string { 12 | ns.SetWatcher(store) 13 | ns.OpenFile(store, filename) 14 | ns.Save(store, filename, content) 15 | filenames := ns.GetFiles(store, texts.CurrentDirectory) 16 | 17 | return strings.Join(filenames, " ") 18 | } 19 | -------------------------------------------------------------------------------- /client/src/components/styles/Files.css: -------------------------------------------------------------------------------- 1 | .saved-message { 2 | background-color: #44d6ff; 3 | padding: 0.8em; 4 | } 5 | #create-file-by-name, 6 | .file-selectors-wrapper .custom-file-upload { 7 | width: 100%; 8 | padding: 0.4em; 9 | background-color: black; 10 | color: white; 11 | transition: all 0.2s ease; 12 | } 13 | 14 | .file-selectors-wrapper input[type='file'] { 15 | display: none; 16 | } 17 | 18 | .custom-file-upload { 19 | opacity: 0.5; 20 | cursor: pointer; 21 | } 22 | -------------------------------------------------------------------------------- /client/src/components/Git/GitGraphWrapper.tsx: -------------------------------------------------------------------------------- 1 | import GitGraph from './GitGraph'; 2 | import BranchSwitcher from './BranchSwitcher'; 3 | 4 | const GitGraphWrapper = () => { 5 | return ( 6 | <> 7 |
8 | Graph 9 |
10 | 11 | 12 |
13 |
14 | 15 | ); 16 | }; 17 | 18 | export default GitGraphWrapper; 19 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | // Listen on a specific host via the HOST environment variable 2 | var host = process.env.HOST || '0.0.0.0'; 3 | // Listen on a specific port via the PORT environment variable 4 | var port = process.env.PORT || 5000; 5 | 6 | var cors_proxy = require('cors-anywhere'); 7 | cors_proxy 8 | .createServer({ 9 | originWhitelist: [], // Allow all origins 10 | requireHeader: ['origin', 'x-requested-with'], 11 | removeHeaders: ['cookie', 'cookie2'], 12 | }) 13 | .listen(port, host, function () { 14 | console.log('Running CORS Anywhere on ' + host + ':' + port); 15 | }); 16 | -------------------------------------------------------------------------------- /client/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 | -------------------------------------------------------------------------------- /client/src/components/styles/Commit.css: -------------------------------------------------------------------------------- 1 | .last-commit p { 2 | font-size: 0.7em; 3 | } 4 | 5 | .text-input-wrapper .close-btn svg { 6 | vertical-align: middle; 7 | } 8 | 9 | .commit-msg-input { 10 | background-color: black; 11 | width: 100%; 12 | padding: 0.4em; 13 | color: white; 14 | transition: all 0.2s ease; 15 | border: none; 16 | } 17 | .commit-msg-input.commit-success { 18 | border: solid #12fcd4; 19 | } 20 | 21 | .commit-msg-input.commit-error { 22 | border: solid red; 23 | } 24 | 25 | .commit-msg-input:focus { 26 | outline: none; 27 | } 28 | 29 | @media screen and (max-width: 768px) { 30 | .last-commit p { 31 | font-size: 0.5em; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /client/src/components/Menu/Clock.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | 3 | const Clock = () => { 4 | const [time, setTime] = useState(''); 5 | 6 | const getTime = () => { 7 | const date = new Date(); 8 | const timeFormat = `${date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`; 9 | setTime(timeFormat); 10 | }; 11 | useEffect(() => { 12 | getTime(); 13 | const interval = setInterval(getTime, 1000); 14 | return () => { 15 | clearInterval(interval); 16 | }; 17 | }, []); 18 | 19 | return ( 20 | <> 21 |
{time}
22 | 23 | ); 24 | }; 25 | 26 | export default Clock; 27 | -------------------------------------------------------------------------------- /client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Harmony 8 | 9 | 10 | 11 |
12 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /client/src/components/Actions/Actions.tsx: -------------------------------------------------------------------------------- 1 | import { useRecoilValue } from 'recoil'; 2 | import { actionState, virtualBranchState } from '../../atoms/atoms'; 3 | import { CREATE_BRANCH, CREATE_COMMIT, GRAPH_MODE } from '../../utils/texts'; 4 | import Branches from '../Git/Branches'; 5 | import Commit from '../Git/Commits'; 6 | import GitGraphWrapper from '../Git/GitGraphWrapper'; 7 | 8 | const Actions = () => { 9 | const getAction = useRecoilValue(actionState); 10 | const virtualBranch = useRecoilValue(virtualBranchState); 11 | 12 | return ( 13 | <> 14 | {getAction === CREATE_COMMIT && !!virtualBranch && } 15 | {getAction === CREATE_BRANCH && } 16 | {getAction === GRAPH_MODE && } 17 | 18 | ); 19 | }; 20 | 21 | export default Actions; 22 | -------------------------------------------------------------------------------- /nova/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "nova/mapping" 5 | "syscall/js" 6 | ) 7 | 8 | func main() { 9 | ch := make(chan struct{}, 0) 10 | js.Global().Set("createVirtualFiles", mapping.CreateVirtualFiles()) 11 | js.Global().Set("openVirtualFile", mapping.OpenVirtualFile()) 12 | js.Global().Set("saveVirtualFile", mapping.SaveVirtualFile()) 13 | js.Global().Set("virtualCommit", mapping.VirtualCommit()) 14 | js.Global().Set("getCurrentBranch", mapping.GetCurrentBranch()) 15 | js.Global().Set("getVirtualFiles", mapping.GetVirtualFiles()) 16 | js.Global().Set("goToBranch", mapping.GoToBranch()) 17 | js.Global().Set("goToCommit", mapping.GoToCommit()) 18 | js.Global().Set("exploreDirectory", mapping.ExploreDirectory()) 19 | js.Global().Set("isDirectory", mapping.IsDirectory()) 20 | <-ch 21 | } 22 | -------------------------------------------------------------------------------- /client/src/main.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import App from './App'; 4 | import { RecoilRoot } from 'recoil'; 5 | 6 | import { ThemeProvider, createTheme } from '@mui/material/styles'; 7 | import CssBaseline from '@mui/material/CssBaseline'; 8 | 9 | const darkTheme = createTheme({ 10 | palette: { 11 | mode: 'dark', 12 | }, 13 | }); 14 | 15 | import './index.css'; 16 | import '@fontsource/roboto/300.css'; 17 | import '@fontsource/roboto/400.css'; 18 | import '@fontsource/roboto/500.css'; 19 | import '@fontsource/roboto/700.css'; 20 | 21 | ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render( 22 | 23 | 24 | 25 | 26 | 27 | , 28 | ); 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "harmony", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "run:client": "cd client && pnpm dev", 9 | "run:server": "node server.js", 10 | "compile:nova": "make compile", 11 | "dev": "concurrently \"pnpm run:server\" \"pnpm compile:nova && pnpm run:client\"", 12 | "build": "make compile && cd client && pnpm build", 13 | "format": "prettier --config ./.prettierrc.js --write --loglevel silent '**/*.{js,ts,tsx,css}'" 14 | }, 15 | "keywords": [], 16 | "author": "", 17 | "license": "ISC", 18 | "devDependencies": { 19 | "concurrently": "^7.4.0", 20 | "prettier": "^2.7.1" 21 | }, 22 | "dependencies": { 23 | "cors-anywhere": "^0.4.4", 24 | "express": "^4.18.1" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /client/src/components/styles/Menu.css: -------------------------------------------------------------------------------- 1 | .menu-wrapper { 2 | position: fixed; 3 | bottom: 0; 4 | left: 0; 5 | display: flex; 6 | justify-content: space-evenly; 7 | align-items: center; 8 | width: 100%; 9 | padding: 0.3em; 10 | background-color: #121212; 11 | z-index: 1; 12 | } 13 | 14 | .time { 15 | font-size: 1em; 16 | opacity: 0.5; 17 | } 18 | 19 | .menu-action, 20 | .contributors a { 21 | width: 100%; 22 | display: flex; 23 | justify-content: flex-start; 24 | align-items: center; 25 | } 26 | 27 | .menu-action span, 28 | .contributors span { 29 | margin-left: 0.8em; 30 | } 31 | 32 | .contributors { 33 | opacity: 0.5; 34 | font-weight: normal; 35 | } 36 | 37 | .contributors * { 38 | color: #ffac4b; 39 | } 40 | 41 | div[aria-describedby='alert-dialog-slide-description'] { 42 | background-image: none; 43 | } 44 | 45 | .tutorial { 46 | width: 100%; 47 | } 48 | -------------------------------------------------------------------------------- /client/src/atoms/atoms.ts: -------------------------------------------------------------------------------- 1 | import { atom } from 'recoil'; 2 | 3 | export const virtualFilesState = atom({ 4 | key: 'virtualFilesState', 5 | default: [], 6 | }); 7 | 8 | export const virtualBranchState = atom({ 9 | key: 'virtualBranchState', 10 | default: '', 11 | }); 12 | 13 | export const virtualBranchesState = atom({ 14 | key: 'virtualBranchesState', 15 | default: [], 16 | }); 17 | 18 | export const createVirtualBranchMessageState = atom({ 19 | key: 'createVirtualBranchMessageState', 20 | default: '', 21 | }); 22 | 23 | export const actionState = atom({ 24 | key: 'actionState', 25 | default: '', 26 | }); 27 | 28 | export const freeModeDisabledState = atom({ 29 | key: 'freeModeDisabledState', 30 | default: false, 31 | }); 32 | 33 | export const gitFootPrintsState = atom({ 34 | key: 'gitFootPrintsState', 35 | default: [ 36 | { 37 | branch: 'master', 38 | commit: {}, 39 | }, 40 | ] as any, 41 | }); 42 | -------------------------------------------------------------------------------- /nova/go.mod: -------------------------------------------------------------------------------- 1 | module nova 2 | 3 | go 1.17 4 | 5 | require ( 6 | github.com/go-git/go-billy/v5 v5.3.1 7 | github.com/go-git/go-git/v5 v5.4.2 8 | ) 9 | 10 | require ( 11 | github.com/Microsoft/go-winio v0.4.16 // indirect 12 | github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 // indirect 13 | github.com/acomagu/bufpipe v1.0.3 // indirect 14 | github.com/emirpasic/gods v1.12.0 // indirect 15 | github.com/go-git/gcfg v1.5.0 // indirect 16 | github.com/imdario/mergo v0.3.12 // indirect 17 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect 18 | github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 // indirect 19 | github.com/mitchellh/go-homedir v1.1.0 // indirect 20 | github.com/sergi/go-diff v1.1.0 // indirect 21 | github.com/xanzy/ssh-agent v0.3.0 // indirect 22 | golang.org/x/crypto v0.1.0 // indirect 23 | golang.org/x/net v0.1.0 // indirect 24 | golang.org/x/sys v0.1.0 // indirect 25 | gopkg.in/warnings.v0 v0.1.2 // indirect 26 | ) 27 | -------------------------------------------------------------------------------- /client/src/components/styles/Branches.css: -------------------------------------------------------------------------------- 1 | .add-branches { 2 | position: absolute; 3 | bottom: 4em; 4 | right: 2em; 5 | cursor: pointer; 6 | } 7 | 8 | .add-branches svg path { 9 | fill: #ffac4b; 10 | } 11 | 12 | .branch-name-input { 13 | width: 100%; 14 | padding: 0.4em; 15 | background-color: black; 16 | border: 0.7px solid #1e1e1e; 17 | color: white; 18 | } 19 | 20 | .branch-name-input:focus { 21 | outline: none; 22 | } 23 | 24 | .current-branch-name { 25 | position: fixed; 26 | top: 3em; 27 | left: 15%; 28 | width: 70%; 29 | color: white; 30 | overflow-x: auto; 31 | overflow-y: hidden; 32 | text-align: center; 33 | } 34 | 35 | span.branch-name { 36 | opacity: 0.3; 37 | padding: 0.3em; 38 | } 39 | 40 | span.create-before-proceeding { 41 | opacity: 0.8; 42 | color: #ffac4b; 43 | } 44 | 45 | li.active-branch { 46 | color: #ffac4b; 47 | } 48 | 49 | @media screen and (max-width: 768px) { 50 | .current-branch-name { 51 | left: 25%; 52 | width: 50%; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Thomas Albertini 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /client/vite.config.ts.timestamp-1664023584131.mjs: -------------------------------------------------------------------------------- 1 | // vite.config.ts 2 | import { defineConfig } from "vite"; 3 | import react from "@vitejs/plugin-react"; 4 | var vite_config_default = defineConfig({ 5 | plugins: [react()] 6 | }); 7 | export { 8 | vite_config_default as default 9 | }; 10 | //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCIvVXNlcnMvdGhvbWFzYWxiZXJ0aW5pL0Rlc2t0b3AvaGFybW9ueS9jbGllbnRcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfZmlsZW5hbWUgPSBcIi9Vc2Vycy90aG9tYXNhbGJlcnRpbmkvRGVza3RvcC9oYXJtb255L2NsaWVudC92aXRlLmNvbmZpZy50c1wiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9pbXBvcnRfbWV0YV91cmwgPSBcImZpbGU6Ly8vVXNlcnMvdGhvbWFzYWxiZXJ0aW5pL0Rlc2t0b3AvaGFybW9ueS9jbGllbnQvdml0ZS5jb25maWcudHNcIjtpbXBvcnQgeyBkZWZpbmVDb25maWcgfSBmcm9tICd2aXRlJ1xuaW1wb3J0IHJlYWN0IGZyb20gJ0B2aXRlanMvcGx1Z2luLXJlYWN0J1xuXG4vLyBodHRwczovL3ZpdGVqcy5kZXYvY29uZmlnL1xuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcbiAgcGx1Z2luczogW3JlYWN0KCldXG59KVxuIl0sCiAgIm1hcHBpbmdzIjogIjtBQUF5VCxTQUFTLG9CQUFvQjtBQUN0VixPQUFPLFdBQVc7QUFHbEIsSUFBTyxzQkFBUSxhQUFhO0FBQUEsRUFDMUIsU0FBUyxDQUFDLE1BQU0sQ0FBQztBQUNuQixDQUFDOyIsCiAgIm5hbWVzIjogW10KfQo= 11 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite --port 3000 --host", 8 | "build": "tsc && vite build", 9 | "preview": "vite preview" 10 | }, 11 | "dependencies": { 12 | "@babel/core": ">=7.0.0 <8.0.0", 13 | "@emotion/react": "^11.10.4", 14 | "@emotion/styled": "^11.10.4", 15 | "@fontsource/roboto": "^4.5.8", 16 | "@gitgraph/js": "^1.4.0", 17 | "@mui/lab": "5.0.0-alpha.102", 18 | "@mui/material": "^5.10.7", 19 | "@react-icons/all-files": "^4.1.0", 20 | "add": "^2.0.6", 21 | "core@^7.0.0": "link:babel/core@^7.0.0", 22 | "monaco-editor": "^0.34.0", 23 | "monaco-languageclient": "^4.0.0", 24 | "react": "^18.2.0", 25 | "react-device-detect": "^2.2.2", 26 | "react-dom": "^18.2.0", 27 | "react-draggable": "^4.4.5", 28 | "react-monaco-editor": "^0.50.1", 29 | "react-select": "^5.4.0", 30 | "reactjs-popup": "^2.0.5", 31 | "recoil": "^0.7.5", 32 | "vscode-oniguruma": "^1.6.2", 33 | "vscode-textmate": "^7.0.1" 34 | }, 35 | "devDependencies": { 36 | "@types/react": "^18.0.17", 37 | "@types/react-dom": "^18.0.6", 38 | "@vitejs/plugin-react": "^2.1.0", 39 | "typescript": "^4.6.4", 40 | "vite": "^3.1.0" 41 | } 42 | } -------------------------------------------------------------------------------- /client/src/components/styles/GitGraph.css: -------------------------------------------------------------------------------- 1 | .graph-mode-container { 2 | position: absolute; 3 | top: calc(50% + 1.5em); 4 | left: 50%; 5 | transform: translate(-50%, calc(-50% - 3em)); 6 | width: 40%; 7 | height: 80%; 8 | background-color: #1e1e1e; 9 | display: block; 10 | position: relative; 11 | } 12 | 13 | .graph-actions { 14 | height: 80%; 15 | overflow: auto; 16 | } 17 | 18 | #graph-branches-list { 19 | display: flex; 20 | justify-content: space-evenly; 21 | border-top: solid #fff; 22 | background-color: #1e1e1e; 23 | width: 100%; 24 | position: absolute; 25 | bottom: 0; 26 | z-index: 1000; 27 | width: 100%; 28 | overflow-x: auto; 29 | } 30 | 31 | .graph-mode-wrapper { 32 | height: 100%; 33 | width: 100%; 34 | } 35 | 36 | #graph { 37 | padding: 6em !important; 38 | } 39 | 40 | .graph-mode-container strong { 41 | display: block; 42 | width: 100%; 43 | text-align: center; 44 | border: 1px solid #fff; 45 | position: sticky; 46 | top: 0; 47 | z-index: 1; 48 | background-color: #1e1e1e; 49 | cursor: pointer; 50 | } 51 | 52 | g { 53 | cursor: pointer; 54 | } 55 | 56 | @media screen and (max-width: 1200px) { 57 | .graph-mode-container { 58 | width: 55%; 59 | } 60 | } 61 | 62 | @media screen and (max-width: 768px) { 63 | .graph-mode-container { 64 | width: 100%; 65 | height: calc(100% - 3em); 66 | } 67 | 68 | #graph { 69 | padding: 3em !important; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /client/src/utils/goFunctions.ts: -------------------------------------------------------------------------------- 1 | export const createVirtualFilesWrapper = (filename: string, content?: string) => 2 | // @ts-ignore 3 | createVirtualFiles( 4 | JSON.stringify({ 5 | files: [ 6 | { 7 | name: filename, 8 | content: !!content ? content : `Created at: ${new Date().toLocaleString()}`, 9 | }, 10 | ], 11 | }), 12 | ); 13 | 14 | export const saveVirtualFilesWrapper = (openFile: string, content: string) => 15 | // @ts-ignore 16 | saveVirtualFile( 17 | JSON.stringify({ 18 | files: [ 19 | { 20 | name: openFile, 21 | content: content, 22 | }, 23 | ], 24 | }), 25 | ); 26 | 27 | // @ts-ignore 28 | export const openVirtualFilesWrapper = (virtualFile: never) => openVirtualFile(virtualFile); 29 | 30 | // @ts-ignore 31 | export const getVirtualFilesWrapper = () => getVirtualFiles().split(' '); 32 | 33 | // @ts-ignore 34 | export const goToBranchWrapper = (branchName: string) => goToBranch(branchName).split(' '); 35 | 36 | export const virtualCommitWrapper = (commitMsg: string) => { 37 | // @ts-ignore 38 | const commit = virtualCommit(commitMsg); 39 | try { 40 | return JSON.parse(commit); 41 | } catch (err) { 42 | return 'No file modifications found'; 43 | } 44 | }; 45 | 46 | // @ts-ignore 47 | export const goToCommitWrapper = (hash: string) => goToCommit(hash); 48 | 49 | export const exploreDirectoryWrapper = (filename: string) => { 50 | // @ts-ignore 51 | const filepath = `./${filename}/` + exploreDirectory(filename); 52 | return filepath.split(' '); 53 | }; 54 | 55 | // @ts-ignore 56 | export const isDirectoryWrapper = (filename: string) => isDirectory(filename); 57 | -------------------------------------------------------------------------------- /client/src/components/Git/BranchSwitcher.tsx: -------------------------------------------------------------------------------- 1 | import { MenuItem } from '@mui/material'; 2 | import { useEffect, useState } from 'react'; 3 | import { useRecoilState, useSetRecoilState } from 'recoil'; 4 | import { actionState, virtualBranchesState, virtualBranchState, virtualFilesState } from '../../atoms/atoms'; 5 | import { getVirtualFilesWrapper, goToBranchWrapper } from '../../utils/goFunctions'; 6 | 7 | const BranchSwitcher = () => { 8 | const setVirtualFiles = useSetRecoilState(virtualFilesState); 9 | const [virtualBranch, setVirtualBranch] = useRecoilState(virtualBranchState); 10 | const setAction = useSetRecoilState(actionState); 11 | 12 | const [branches, setBranches] = useRecoilState(virtualBranchesState); 13 | 14 | const [branchName, setBranchName] = useState(''); 15 | 16 | const handleMenuItemClick = (event: React.MouseEvent, branch: string) => { 17 | setBranchName(branch); 18 | setBranches(goToBranchWrapper(branch)); 19 | }; 20 | 21 | useEffect(() => { 22 | if (!!branchName) { 23 | // Gets files stored in the current worktree 24 | setVirtualFiles(getVirtualFilesWrapper()); 25 | setVirtualBranch(branchName); 26 | setAction(''); 27 | } 28 | }, [branches]); 29 | 30 | return ( 31 |
32 | {branches.map((branch, index) => { 33 | const active = branch === virtualBranch ? 'active-branch' : ''; 34 | return ( 35 | handleMenuItemClick(event, branch)}> 36 | {branch} 37 | 38 | ); 39 | })} 40 |
41 | ); 42 | }; 43 | 44 | export default BranchSwitcher; 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Harmony 2 | 3 | Quickly upload, create, open, read, modify and download files, on the fly. 4 | 5 | Harmony also keep tracks of your changes or "workspaces" through git branches and git commits, all in-memory in your browser. 6 | 7 | 8 | 9 | > Just me experimenting with WebAssembly. 10 |
11 | 12 | Harmony implements via WebAssembly a virtual file system and a in-memory version of Git, written in Go, (a revisited version of my Nova project) where all the file operations happen. 13 | 14 | Save and switch between your "workspaces" in few clicks or even quicker with shortcuts. 15 | 16 | 17 | 18 | 19 | ## Harmony supports git commits and branches. 20 | 21 | 22 | 23 | https://user-images.githubusercontent.com/78874117/193465430-7a76e848-1e5b-406a-b2b0-99869a031f3a.mp4 24 | 25 | 26 | ## Navigate back to a specific commit with the graph 27 | 28 | https://user-images.githubusercontent.com/78874117/194714002-f6ec20c5-c7cc-4144-85e1-0bdb65097b7d.mov 29 | 30 | 31 | Create branches, 32 | create files, 33 | upload files, 34 | change them, 35 | save them, 36 | commit them, 37 | switch branches, 38 | repeat. 39 | 40 | Simply refresh the page to restart anew. 41 | 42 | #### Run it locally 43 | Requires `pnpm`, `go 44 | 45 | - Install go packages - 46 | 47 | ```bash 48 | $ pnpm dev 49 | ``` 50 | This will compile Nova via `make`, and also spin up a reverse proxy 51 | 52 | ### Important 53 | > Prepend `http://0.0.0.0:5000` to the repo url in `nova/virtual/functions.go` (to not incur in CORS errors - in Development) 54 | -------------------------------------------------------------------------------- /client/src/components/styles/Editor.css: -------------------------------------------------------------------------------- 1 | .nova-editor { 2 | position: absolute; 3 | top: 0; 4 | left: 50%; 5 | transform: translateX(-50%); 6 | width: 100%; 7 | height: calc(100vh - 3em); 8 | } 9 | 10 | .nova-editor form { 11 | width: 50%; 12 | display: flex; 13 | flex-direction: column; 14 | align-items: flex-end; 15 | } 16 | 17 | .nova-editor form .react-monaco-editor-container { 18 | width: 100% !important; 19 | text-align: initial; 20 | margin: auto; 21 | border: 0.3px solid white; 22 | } 23 | 24 | .nova-editor form strong.editor-file-name { 25 | width: 100%; 26 | text-align: center; 27 | background-color: #121212; 28 | cursor: grab; 29 | align-items: center; 30 | padding: 0 2em; 31 | } 32 | 33 | .nova-editor form .editor-btn-container { 34 | display: flex; 35 | width: 100%; 36 | } 37 | 38 | .nova-editor form .editor-btn-container button, 39 | #create-file-btn, 40 | #downloader { 41 | background-color: #1e1e1e; 42 | color: white; 43 | border: 0.3px solid white; 44 | border-radius: 0; 45 | width: 100%; 46 | } 47 | 48 | .nova-editor form .editor-btn-container button:hover, 49 | #create-file-btn, 50 | #downloader:hover { 51 | background-color: #44d6ff; 52 | } 53 | 54 | .nova-editor form .editor-btn-container button#clear-icon svg path { 55 | stroke: #fff; 56 | } 57 | 58 | #downloader { 59 | padding: 0.53em 1em; 60 | background-color: #ffac4b; 61 | text-align: center; 62 | } 63 | 64 | @media screen and (max-width: 768px) { 65 | .nova-editor form { 66 | width: 98%; 67 | display: flex; 68 | flex-direction: column; 69 | align-items: flex-end; 70 | } 71 | 72 | .nova-editor form strong.editor-file-name:first-child { 73 | font-size: 13px; 74 | } 75 | 76 | .nova-editor form .editor-btn-container button, 77 | #downloader { 78 | padding: 0.3em; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /client/src/components/Menu/ShowGraph.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | 3 | import { AiOutlineBranches as BranchIcon } from '@react-icons/all-files/ai/AiOutlineBranches'; 4 | 5 | import { styled } from '@mui/material/styles'; 6 | import Tooltip, { TooltipProps, tooltipClasses } from '@mui/material/Tooltip'; 7 | import Button from '@mui/material/Button'; 8 | 9 | import { actionState, virtualBranchesState } from '../../atoms/atoms'; 10 | import { useRecoilValue, useSetRecoilState } from 'recoil'; 11 | import { GRAPH_MODE } from '../../utils/texts'; 12 | 13 | const BootstrapTooltip = styled(({ className, ...props }: TooltipProps) => )(({ theme }) => ({ 14 | [`& .${tooltipClasses.arrow}`]: { 15 | color: theme.palette.common.black, 16 | }, 17 | [`& .${tooltipClasses.tooltip}`]: { 18 | backgroundColor: theme.palette.common.black, 19 | }, 20 | })); 21 | 22 | const ShowGraph = () => { 23 | const branches = useRecoilValue(virtualBranchesState); 24 | const setAction = useSetRecoilState(actionState); 25 | 26 | const [tooltipOpen, setTooltipOpen] = useState(false); 27 | 28 | const handleClickOpen = () => { 29 | setAction((prev: string) => { 30 | return !!prev ? '' : GRAPH_MODE; 31 | }); 32 | }; 33 | 34 | return ( 35 | <> 36 | {branches.length === 0 ? ( 37 | 38 |
{ 40 | setTooltipOpen((prev) => !prev); 41 | }} 42 | > 43 | 46 |
47 |
48 | ) : ( 49 | 52 | )} 53 | 54 | ); 55 | }; 56 | 57 | export default ShowGraph; 58 | -------------------------------------------------------------------------------- /client/src/index.css: -------------------------------------------------------------------------------- 1 | :root { 2 | font-family: Inter, Avenir, Helvetica, Arial, sans-serif; 3 | font-size: 16px; 4 | line-height: 24px; 5 | font-weight: 400; 6 | 7 | color-scheme: light dark; 8 | color: rgba(255, 255, 255, 0.87); 9 | 10 | font-synthesis: none; 11 | text-rendering: optimizeLegibility; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | -webkit-text-size-adjust: 100%; 15 | } 16 | 17 | /* width */ 18 | ::-webkit-scrollbar { 19 | width: 10px; 20 | } 21 | 22 | /* Track */ 23 | ::-webkit-scrollbar-track { 24 | background: #1e1e1e; 25 | } 26 | 27 | /* Handle */ 28 | ::-webkit-scrollbar-thumb { 29 | background: #888; 30 | } 31 | 32 | /* Handle on hover */ 33 | ::-webkit-scrollbar-thumb:hover { 34 | background: rgb(64, 64, 64); 35 | } 36 | 37 | html, 38 | body { 39 | background: url('./img/desktop.jpg') !important; 40 | background-size: cover !important; 41 | background-repeat: no-repeat !important; 42 | } 43 | 44 | button:focus { 45 | outline: none !important; 46 | } 47 | 48 | a { 49 | text-decoration: inherit; 50 | } 51 | 52 | body { 53 | margin: 0; 54 | display: flex; 55 | place-items: center; 56 | min-width: 320px; 57 | min-height: 100vh; 58 | color: white; 59 | } 60 | 61 | #layer.editor-open { 62 | position: absolute; 63 | top: 0; 64 | left: 0; 65 | width: 100%; 66 | height: 100%; 67 | background-color: rgba(0, 0, 0, 0.7); 68 | } 69 | 70 | h1 { 71 | font-size: 3.2em; 72 | line-height: 1.1; 73 | } 74 | 75 | button { 76 | border-radius: 8px; 77 | border: 1px solid transparent; 78 | padding: 0.6em 1.2em; 79 | font-size: 1em; 80 | font-weight: 500; 81 | font-family: inherit; 82 | background-color: #1a1a1a; 83 | cursor: pointer; 84 | transition: border-color 0.25s; 85 | } 86 | button:hover { 87 | border-color: #646cff; 88 | } 89 | button:focus, 90 | button:focus-visible { 91 | outline: 4px auto -webkit-focus-ring-color; 92 | } 93 | 94 | @media (prefers-color-scheme: light) { 95 | :root { 96 | color: #213547; 97 | background-color: #1e1e1e; 98 | } 99 | a:hover { 100 | color: #747bff; 101 | } 102 | button { 103 | background-color: #f9f9f9; 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /client/src/components/Git/Branches.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef, useState } from 'react'; 2 | import { useRecoilState, useSetRecoilState } from 'recoil'; 3 | import { virtualFilesState, virtualBranchState, actionState, virtualBranchesState, gitFootPrintsState } from '../../atoms/atoms'; 4 | import { getVirtualFilesWrapper, goToBranchWrapper } from '../../utils/goFunctions'; 5 | 6 | import type { gitFootPrintType } from '../../types/types'; 7 | 8 | import { AiOutlineClose as CloseIcon } from '@react-icons/all-files/ai/AiOutlineClose'; 9 | 10 | const Branches = () => { 11 | const setVirtualFiles = useSetRecoilState(virtualFilesState); 12 | const [virtualBranch, setVirtualBranch] = useRecoilState(virtualBranchState); 13 | const setAction = useSetRecoilState(actionState); 14 | const setGitFootprints = useSetRecoilState(gitFootPrintsState); 15 | 16 | const [branches, setBranches] = useRecoilState(virtualBranchesState); 17 | const [branchName, setBranchName] = useState(''); 18 | const inputBranchRef = useRef(null); 19 | 20 | useEffect(() => { 21 | (inputBranchRef.current! as HTMLInputElement).focus(); 22 | }, []); 23 | 24 | useEffect(() => { 25 | if (!!branchName) { 26 | // Gets files stored in the current worktree 27 | setVirtualFiles(getVirtualFilesWrapper()); 28 | setVirtualBranch(branchName); 29 | // Record action 30 | setGitFootprints((prev: gitFootPrintType[]) => [ 31 | ...prev, 32 | { 33 | branch: branchName, 34 | commit: {}, 35 | }, 36 | ]); 37 | setAction(''); 38 | } 39 | }, [branches]); 40 | 41 | const handleCloseClick = () => { 42 | setAction(''); 43 | }; 44 | 45 | const addBranchHandler = (e: any) => { 46 | e.preventDefault(); 47 | (inputBranchRef.current! as HTMLInputElement).value = ''; 48 | // Checkout to branch - creates a new branch if it doesn't exist 49 | setBranches(goToBranchWrapper(branchName)); 50 | }; 51 | 52 | return ( 53 | <> 54 |
55 |
56 |
57 | setBranchName(e.target.value)} /> 58 | 59 | 60 | 61 |
62 |
63 |
64 | 65 | ); 66 | }; 67 | 68 | export default Branches; 69 | -------------------------------------------------------------------------------- /client/src/components/Git/GitGraph.tsx: -------------------------------------------------------------------------------- 1 | import { createGitgraph, templateExtend } from '@gitgraph/js'; 2 | import { useEffect, useState } from 'react'; 3 | import { useRecoilValue, useSetRecoilState } from 'recoil'; 4 | import { actionState, gitFootPrintsState, virtualFilesState } from '../../atoms/atoms'; 5 | import { gitFootPrintType } from '../../types/types'; 6 | import { getVirtualFilesWrapper, goToCommitWrapper } from '../../utils/goFunctions'; 7 | 8 | const GitGraph = () => { 9 | const gitFootPrints = useRecoilValue(gitFootPrintsState); 10 | const setVirtualFiles = useSetRecoilState(virtualFilesState); 11 | const setAction = useSetRecoilState(actionState); 12 | 13 | const clickOnCommitHandler = (hash: string | undefined) => { 14 | if (!!hash) { 15 | goToCommitWrapper(hash); 16 | setVirtualFiles(getVirtualFilesWrapper()); 17 | setAction(''); 18 | } 19 | }; 20 | 21 | useEffect(() => { 22 | const graphContainer = document.getElementById('graph') as HTMLDivElement; 23 | const gitgraph = createGitgraph(graphContainer, { 24 | responsive: true, 25 | // @ts-ignore 26 | template: new templateExtend('metro', { 27 | branch: { 28 | lineWidth: 3, 29 | label: { 30 | borderRadius: 0, 31 | strokeColor: 'black', 32 | color: 'black', 33 | font: 'normal 10pt Arial', 34 | }, 35 | }, 36 | commit: { 37 | dot: { 38 | size: 12, 39 | }, 40 | message: { 41 | font: 'normal 10pt Arial', 42 | displayAuthor: false, 43 | }, 44 | }, 45 | colors: ['#d5a5f7', '#44d6ff', '#ffac4b', '#ff5b9b', '#d7d2d8', '#12fcd4', '#004a98'], 46 | }), 47 | author: 'Nova Harmony ', 48 | }); 49 | 50 | gitFootPrints.forEach((footPrint: gitFootPrintType, index: number) => { 51 | const branchName: string = footPrint.branch; 52 | 53 | gitgraph.branch(footPrint.branch).commit({ 54 | hash: footPrint.commit?.hash ?? '', 55 | subject: index === 0 ? branchName : footPrint.commit?.message ?? `Checkout to ${footPrint.branch}`, 56 | onClick: () => clickOnCommitHandler(footPrint.commit.hash), 57 | onMessageClick: () => clickOnCommitHandler(footPrint.commit.hash), 58 | style: { 59 | color: '#1e1e1e', 60 | message: { 61 | color: '#fff', 62 | displayHash: !!footPrint.commit.hash, 63 | }, 64 | }, 65 | }); 66 | }); 67 | }, []); 68 | 69 | return ( 70 |
71 |
72 |
73 | ); 74 | }; 75 | 76 | export default GitGraph; 77 | -------------------------------------------------------------------------------- /client/src/App.css: -------------------------------------------------------------------------------- 1 | @import './components//styles/index.css'; 2 | 3 | #root { 4 | width: 100%; 5 | height: 100vh; 6 | overflow: hidden; 7 | } 8 | 9 | #github a { 10 | color: white; 11 | } 12 | 13 | .virtual-file-wrapper { 14 | padding: 1em; 15 | height: 7.5em; 16 | z-index: 0; 17 | } 18 | 19 | .virtual-file-wrapper svg { 20 | transition: all 0.3s ease; 21 | } 22 | 23 | .virtual-file-wrapper svg path { 24 | stroke: #000; 25 | stroke-width: 5; 26 | } 27 | 28 | .virtual-file-wrapper.dir svg path { 29 | fill: #ffca8e; 30 | } 31 | 32 | .virtual-file-wrapper:hover { 33 | background-color: rgba(68, 214, 255, 0.3); 34 | border: 0.01em solid white; 35 | } 36 | 37 | .virtual-file-wrapper svg:hover { 38 | transform: scale(1.2); 39 | } 40 | 41 | .virtual-file-wrapper svg path { 42 | fill: #fff; 43 | } 44 | 45 | .virtual-file-wrapper.modified svg path { 46 | fill: #f4f4ff; 47 | } 48 | 49 | #create-file-by-name { 50 | background-color: black; 51 | border: none; 52 | padding: 0.6em; 53 | color: white; 54 | } 55 | 56 | #create-file-by-name:focus { 57 | outline: none; 58 | } 59 | 60 | input[type='file'] { 61 | display: none; 62 | } 63 | 64 | .text-input-wrapper { 65 | position: fixed; 66 | top: 0; 67 | left: 0; 68 | display: flex; 69 | flex-direction: row; 70 | justify-content: space-between; 71 | width: 100%; 72 | align-items: center; 73 | background-color: black; 74 | transition: all 0.2s ease; 75 | z-index: 1; 76 | } 77 | 78 | .text-input-wrapper .close-btn { 79 | padding: 0.2em; 80 | opacity: 0.5; 81 | cursor: pointer; 82 | } 83 | 84 | .files-area { 85 | display: flex; 86 | flex-direction: row-reverse; 87 | flex-wrap: wrap; 88 | align-items: flex-end; 89 | width: 100%; 90 | height: calc(100vh - 3em); 91 | margin: 0 auto; 92 | overflow-y: auto; 93 | } 94 | 95 | .files-area.dir-open { 96 | position: relative; 97 | background-color: rgba(30, 30, 30, 0.9); 98 | width: 70%; 99 | height: 70vh; 100 | position: absolute; 101 | top: 50%; 102 | left: 50%; 103 | transform: translate(-50%, -50%); 104 | } 105 | 106 | .files-area.dir-open .dir-menu { 107 | border: solid #f4f4ff; 108 | background-color: #1e1e1e; 109 | position: absolute; 110 | top: 0; 111 | width: 100%; 112 | text-align: center; 113 | z-index: 1; 114 | } 115 | 116 | .files-area.dir-open .dir-menu svg { 117 | position: absolute; 118 | left: 2em; 119 | height: 100%; 120 | cursor: pointer; 121 | } 122 | 123 | .file { 124 | text-align: center; 125 | background-color: #1e1e1e; 126 | padding: 0.2em 0.5em; 127 | } 128 | 129 | @media screen and (max-width: 768px) { 130 | .file-selectors p + div form { 131 | text-align: center; 132 | } 133 | .files-area.dir-open { 134 | background-color: #1e1e1e; 135 | width: 100%; 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /client/src/components/Menu/utility/utilityComponents.tsx: -------------------------------------------------------------------------------- 1 | import { AiOutlineFile as FileIcon } from '@react-icons/all-files/ai/AiOutlineFile'; 2 | import { AiOutlineBranches as BranchIcon } from '@react-icons/all-files/ai/AiOutlineBranches'; 3 | import { AiOutlineCloudUpload as UploadFileIcon } from '@react-icons/all-files/ai/AiOutlineCloudUpload'; 4 | import { VscGitCommit as CommitIcon } from '@react-icons/all-files/vsc/VscGitCommit'; 5 | import { AiFillGithub as GithubIcon } from '@react-icons/all-files/ai/AiFillGithub'; 6 | import { BsUnlock as UnlockedIcon } from '@react-icons/all-files/bs/BsUnlock'; 7 | import { BsLock as LockedIcon } from '@react-icons/all-files/bs/BsLock'; 8 | 9 | import { useRecoilState } from 'recoil'; 10 | import { freeModeDisabledState } from '../../../atoms/atoms'; 11 | 12 | export const AddFile = () => { 13 | return ( 14 | <> 15 |
16 | 17 | Create a file 18 |
19 | 20 | ); 21 | }; 22 | 23 | export const CreateBranch = () => { 24 | return ( 25 | <> 26 |
27 | 28 | Checkout to a branch 29 |
30 | 31 | ); 32 | }; 33 | 34 | export const CreateCommit = () => { 35 | return ( 36 | <> 37 |
38 | 39 | Commit changes 40 |
41 | 42 | ); 43 | }; 44 | 45 | export const UploadFile = () => { 46 | return ( 47 | <> 48 |
49 | 50 | Upload a file 51 |
52 | 53 | ); 54 | }; 55 | 56 | export const Contributors = () => { 57 | return ( 58 | <> 59 | 67 | 68 | ); 69 | }; 70 | 71 | export const FreeMode = ({ handleClose }: { handleClose: () => void }) => { 72 | const [freeModeDisabled, setFreeModeDisabled] = useRecoilState(freeModeDisabledState); 73 | return ( 74 | <> 75 |
76 | {!freeModeDisabled && ( 77 |
{ 79 | setFreeModeDisabled(true); 80 | handleClose(); 81 | }} 82 | > 83 | 84 | Lock file drag 85 |
86 | )} 87 | {freeModeDisabled && ( 88 |
{ 90 | setFreeModeDisabled(false); 91 | handleClose(); 92 | }} 93 | > 94 | 95 | Unlock file drag 96 |
97 | )} 98 |
99 | 100 | ); 101 | }; 102 | -------------------------------------------------------------------------------- /nova/virtual/virtualSystem.go: -------------------------------------------------------------------------------- 1 | package virtual 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "nova/texts" 7 | 8 | "github.com/go-git/go-billy/v5" 9 | "github.com/go-git/go-billy/v5/util" 10 | "github.com/go-git/go-git/v5" 11 | "github.com/go-git/go-git/v5/plumbing" 12 | "github.com/go-git/go-git/v5/plumbing/object" 13 | "github.com/go-git/go-git/v5/storage/memory" 14 | ) 15 | 16 | type StoreInterface interface { 17 | SetWatcher(store billy.Filesystem) map[string]string 18 | CreateStore() (billy.Filesystem, *memory.Storage) 19 | GetFiles(store billy.Filesystem, dir string) []string 20 | OpenFile(store billy.Filesystem, fileName string) billy.File 21 | Save(store billy.Filesystem, filename string, content string) 22 | GetFileContent(store billy.Filesystem, fileName string) string 23 | SetBranch(repo *git.Repository) 24 | Screenshot(store billy.Filesystem, wt *git.Worktree, msg string) string 25 | GotoBranch(repo *git.Repository, branchName string) error 26 | GoToCommit(repo *git.Repository, commitHash string) error 27 | IsDirectory(store billy.Filesystem, dir string, filename string) bool 28 | ExploreDirectory(store billy.Filesystem, dir string, filename string) []string 29 | } 30 | type NovaStore struct { 31 | Watcher map[string]string 32 | CurrentBranch *plumbing.Reference 33 | } 34 | 35 | func (ns *NovaStore) SetWatcher(store billy.Filesystem) map[string]string { 36 | ns.Watcher = make(map[string]string) 37 | ns.Watcher = fileLastModification(store) 38 | return ns.Watcher 39 | } 40 | 41 | func (ns *NovaStore) CreateStore() (billy.Filesystem, *memory.Storage) { 42 | return createVirtualSystem() 43 | } 44 | 45 | func (ns *NovaStore) GetFiles(store billy.Filesystem, dir string) []string { 46 | return listFiles(store, dir) 47 | } 48 | 49 | func (ns *NovaStore) ExploreDirectory(store billy.Filesystem, dir string, filename string) []string { 50 | return getDirectoryFiles(store, dir, filename) 51 | } 52 | 53 | func (ns *NovaStore) IsDirectory(store billy.Filesystem, dir string, filename string) bool { 54 | return isDirectory(store, dir, filename) 55 | } 56 | 57 | func (ns *NovaStore) OpenFile(store billy.Filesystem, fileName string) billy.File { 58 | fileGotCreated, file := openFile(store, fileName) 59 | if fileGotCreated != nil { 60 | log.Println(texts.FileOpenedSuccessfully, fileName) 61 | ns.SetWatcher(fileGotCreated) 62 | } 63 | return file 64 | } 65 | 66 | func (ns *NovaStore) Save(store billy.Filesystem, filename string, content string) { 67 | util.WriteFile(store, filename, []byte(content), 0644) 68 | } 69 | 70 | func (ns *NovaStore) GetFileContent(store billy.Filesystem, fileName string) string { 71 | return readFileContent(store, fileName) 72 | } 73 | 74 | func (ns *NovaStore) SetBranch(repo *git.Repository) { 75 | currentBranch, err := repo.Head() 76 | if err != nil { 77 | log.Fatal(err) 78 | } 79 | ns.CurrentBranch = currentBranch 80 | } 81 | 82 | func (ns *NovaStore) Screenshot(store billy.Filesystem, wt *git.Worktree, msg string) string { 83 | files, _ := store.ReadDir(texts.CurrentDirectory) 84 | 85 | for _, file := range files { 86 | wt.Add(file.Name()) 87 | } 88 | 89 | hash, err := wt.Commit(msg, &git.CommitOptions{ 90 | Author: &object.Signature{ 91 | Name: "Nova Harmony", 92 | Email: "nova@harmony.com", 93 | }, 94 | }) 95 | 96 | if err != nil { 97 | fmt.Println(err.Error()) 98 | return "Couldn't commit" 99 | } 100 | return hash.String() 101 | } 102 | 103 | func (ns *NovaStore) GotoBranch(repo *git.Repository, branchName string) error { 104 | err := createBranch(repo, branchName) 105 | if err != nil { 106 | return err 107 | } 108 | ns.SetBranch(repo) 109 | return nil 110 | } 111 | 112 | func (ns *NovaStore) GoToCommit(repo *git.Repository, commitHash string) error { 113 | err := checkoutToCommit(repo, commitHash) 114 | if err != nil { 115 | return err 116 | } 117 | 118 | return nil 119 | } 120 | -------------------------------------------------------------------------------- /client/src/components/Git/Commits.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef, useState } from 'react'; 2 | import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; 3 | import { virtualCommitWrapper } from '../../utils/goFunctions'; 4 | import { actionState, createVirtualBranchMessageState, gitFootPrintsState, virtualBranchState } from '../../atoms/atoms'; 5 | 6 | import { AiOutlineClose as CloseIcon } from '@react-icons/all-files/ai/AiOutlineClose'; 7 | 8 | import { gitFootPrintType } from '../../types/types'; 9 | 10 | const Commit = () => { 11 | const virtualBranch = useRecoilValue(virtualBranchState); 12 | const setCreateVirtualBranchMessage = useSetRecoilState(createVirtualBranchMessageState); 13 | const setAction = useSetRecoilState(actionState); 14 | const [gitFootPrints, setGitFootprints] = useRecoilState(gitFootPrintsState); 15 | 16 | const [commitMsg, setCommitMsg] = useState(); 17 | const [commitError, setCommitError] = useState(false); 18 | const [commitSuccess, setCommitSuccess] = useState(false); 19 | const [commitSuccessMessage, setCommitSuccessMessage] = useState(''); 20 | const [commitErrorMessage, setCommitErrorMessage] = useState(''); 21 | const inputCommitRef = useRef(null); 22 | 23 | const handleCloseClick = () => { 24 | setAction(''); 25 | }; 26 | 27 | const disabledInputClickHandler = () => { 28 | if (!!virtualBranch === false) { 29 | setCreateVirtualBranchMessage('Create or checkout to a branch'); 30 | } 31 | }; 32 | 33 | useEffect(() => { 34 | (inputCommitRef.current! as HTMLInputElement).focus(); 35 | }, []); 36 | 37 | useEffect(() => { 38 | if (commitSuccess) (inputCommitRef.current! as HTMLInputElement).classList.add('commit-success'); 39 | if (!commitSuccess) (inputCommitRef.current! as HTMLInputElement).classList.remove('commit-success'); 40 | 41 | if (commitError) (inputCommitRef.current! as HTMLInputElement).classList.add('commit-error'); 42 | if (!commitError) (inputCommitRef.current! as HTMLInputElement).classList.remove('commit-error'); 43 | }, [commitError, commitSuccess]); 44 | 45 | const commitsFormHandler = (e: any) => { 46 | e.preventDefault(); 47 | (inputCommitRef.current! as HTMLInputElement).value = ''; 48 | // creates a new commit 49 | const commit = virtualCommitWrapper(commitMsg as string); 50 | 51 | if (typeof commit === 'string') { 52 | setCommitErrorMessage(`${commit} - Try again`); 53 | return setCommitError(true); 54 | } 55 | setGitFootprints((prev: gitFootPrintType[]) => [ 56 | ...prev, 57 | { 58 | branch: virtualBranch, 59 | commit: commit, 60 | }, 61 | ]); 62 | console.log(commit); 63 | setCommitSuccessMessage('Committed successfully'); 64 | // DEPRECATED: setAction(''); makes the input disappear 65 | // hence the commitSuccess won't have any visual effects anymore 66 | setCommitSuccess(true); 67 | return setAction(''); 68 | }; 69 | 70 | const commitsInputOnChangeHandler = (e: any) => { 71 | setCommitMsg(e.target.value); 72 | setCommitError(false); 73 | setCommitSuccess(false); 74 | }; 75 | 76 | return ( 77 | <> 78 |
79 |
80 | 88 | 89 | 90 | 91 |
92 |
93 | 94 | ); 95 | }; 96 | 97 | export default Commit; 98 | -------------------------------------------------------------------------------- /client/src/assets/react.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/src/components/Menu/Menu.tsx: -------------------------------------------------------------------------------- 1 | import { forwardRef, useEffect, useState } from 'react'; 2 | 3 | import MenuItem from '@mui/material/MenuItem'; 4 | import Button from '@mui/material/Button'; 5 | import Dialog from '@mui/material/Dialog'; 6 | import Slide from '@mui/material/Slide'; 7 | import { TransitionProps } from '@mui/material/transitions'; 8 | import { Divider, styled } from '@mui/material'; 9 | import Tooltip, { TooltipProps, tooltipClasses } from '@mui/material/Tooltip'; 10 | 11 | // icons 12 | import { RiLayoutGridFill as MenuIcon } from '@react-icons/all-files/ri/RiLayoutGridFill'; 13 | 14 | import { useRecoilValue, useSetRecoilState } from 'recoil'; 15 | import { actionState, virtualBranchState } from '../../atoms/atoms'; 16 | 17 | import { AddFile, Contributors, CreateBranch, CreateCommit, FreeMode, UploadFile } from './utility/utilityComponents'; 18 | import { CREATE_BRANCH, HELP } from '../../utils/texts'; 19 | 20 | import { options } from './utility/menuOptions'; 21 | import Help from './Help'; 22 | import ShowGraph from './ShowGraph'; 23 | import Clock from './Clock'; 24 | 25 | const Transition = forwardRef(function Transition( 26 | props: TransitionProps & { 27 | children: React.ReactElement; 28 | }, 29 | ref: React.Ref, 30 | ) { 31 | return ; 32 | }); 33 | 34 | const icons = [, , , ]; 35 | 36 | const BootstrapTooltip = styled(({ className, ...props }: TooltipProps) => )(({ theme }) => ({ 37 | [`& .${tooltipClasses.arrow}`]: { 38 | color: theme.palette.common.black, 39 | }, 40 | [`& .${tooltipClasses.tooltip}`]: { 41 | backgroundColor: theme.palette.common.black, 42 | }, 43 | })); 44 | 45 | const HarmonyMenu = () => { 46 | const setAction = useSetRecoilState(actionState); 47 | const virtualBranch = useRecoilValue(virtualBranchState); 48 | 49 | const [open, setOpen] = useState(false); 50 | const [openTooltip, setOpenTooltip] = useState(true); 51 | 52 | const handleClickOpen = () => { 53 | setOpen(true); 54 | }; 55 | 56 | const handleClose = () => { 57 | setOpen(false); 58 | }; 59 | 60 | const handleMenuItemClick = (event: React.MouseEvent, index: number) => { 61 | if (options.has(index)) { 62 | setAction(options.get(index) as string); 63 | handleClose(); 64 | } 65 | }; 66 | 67 | const handleTooltip = () => { 68 | setOpenTooltip(false); 69 | }; 70 | 71 | useEffect(() => { 72 | const timeout = setTimeout(handleTooltip, 3000); 73 | return () => { 74 | clearTimeout(timeout); 75 | }; 76 | }, []); 77 | 78 | const id = open ? 'simple-popover' : undefined; 79 | 80 | return ( 81 |
82 |
83 | 84 | 93 | 94 | 95 | {icons.map((icon, index) => { 96 | const option = options.get(index); 97 | const disabled = !!virtualBranch === false && option !== CREATE_BRANCH && option !== HELP; 98 | return ( 99 | handleMenuItemClick(event, index)}> 100 | {icon} 101 | 102 | ); 103 | })} 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 |
113 | 114 | 115 | 116 |
117 | ); 118 | }; 119 | 120 | export default HarmonyMenu; 121 | -------------------------------------------------------------------------------- /nova/virtual/functions.go: -------------------------------------------------------------------------------- 1 | package virtual 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "log" 7 | 8 | "nova/texts" 9 | "os" 10 | "strings" 11 | 12 | "github.com/go-git/go-billy/v5" 13 | "github.com/go-git/go-billy/v5/memfs" 14 | "github.com/go-git/go-billy/v5/util" 15 | "github.com/go-git/go-git/v5" 16 | "github.com/go-git/go-git/v5/plumbing" 17 | "github.com/go-git/go-git/v5/storage/memory" 18 | ) 19 | 20 | func createVirtualSystem() (billy.Filesystem, *memory.Storage) { 21 | storer := memory.NewStorage() 22 | novaFs := memfs.New() 23 | 24 | repo, _ := git.Clone(storer, novaFs, &git.CloneOptions{ 25 | URL: "http://0.0.0.0:5000/https://github.com/thomscoder/harmony-bare.git", 26 | }) 27 | fmt.Println(repo.Head()) 28 | return novaFs, storer 29 | } 30 | 31 | func listFiles(store billy.Filesystem, dir string) []string { 32 | files, err := store.ReadDir(dir) 33 | var fileInfos []string 34 | 35 | if err != nil { 36 | log.Println(err) 37 | return nil 38 | } 39 | for _, file := range files { 40 | if file.IsDir() { 41 | listFiles(store, file.Name()) 42 | } 43 | fileInfos = append(fileInfos, file.Name()) 44 | fmt.Printf("%s %s%s %s\n", file.Mode(), texts.GREEN, dir+"/"+file.Name(), texts.RESET) 45 | } 46 | return fileInfos 47 | } 48 | 49 | func isDirectory(store billy.Filesystem, dir string, filename string) bool { 50 | files, err := store.ReadDir(dir) 51 | 52 | if err != nil { 53 | log.Println(err) 54 | return false 55 | } 56 | 57 | for _, file := range files { 58 | if file.Name() == filename { 59 | if file.IsDir() { 60 | return true 61 | } 62 | } 63 | } 64 | 65 | return false 66 | } 67 | 68 | func getDirectoryFiles(store billy.Filesystem, dir string, filename string) []string { 69 | files, err := store.ReadDir(dir) 70 | 71 | if err != nil { 72 | log.Println(err) 73 | return nil 74 | } 75 | for _, file := range files { 76 | if file.Name() == filename { 77 | if file.IsDir() { 78 | return listFiles(store, file.Name()) 79 | } 80 | } 81 | } 82 | return nil 83 | } 84 | 85 | func openFile(store billy.Filesystem, fileName string) (billy.Filesystem, billy.File) { 86 | newFile, err := store.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0644) 87 | if err != nil { 88 | log.Println(err) 89 | return nil, nil 90 | } 91 | newFile.Close() 92 | return store, newFile 93 | } 94 | 95 | func readFileContent(store billy.Filesystem, fileName string) string { 96 | file, err := util.ReadFile(store, fileName) 97 | if err != nil { 98 | log.Println(err) 99 | return "Couldn't read " + fileName 100 | } 101 | return string(file) 102 | } 103 | 104 | func turnToString(r io.Reader, file billy.File) (res string, err error) { 105 | var sb strings.Builder 106 | if _, err = io.Copy(&sb, r); err == nil { 107 | res = sb.String() 108 | file.Write([]byte(res)) 109 | } 110 | return 111 | } 112 | 113 | func fileLastModification(store billy.Filesystem) map[string]string { 114 | oldFiles := make(map[string]string) 115 | files, _ := store.ReadDir(texts.CurrentDirectory) 116 | for _, file := range files { 117 | stat, _ := store.Stat(file.Name()) 118 | oldFiles[file.Name()] = stat.ModTime().String() 119 | } 120 | return oldFiles 121 | } 122 | 123 | func createBranch(repo *git.Repository, branchName string) error { 124 | exists := false 125 | wt, _ := repo.Worktree() 126 | branches, _ := repo.Branches() 127 | branches.ForEach(func(branch *plumbing.Reference) error { 128 | 129 | if branch.Name().Short() == branchName { 130 | exists = true 131 | err := wt.Checkout(&git.CheckoutOptions{ 132 | Create: false, 133 | Force: false, 134 | Branch: plumbing.NewBranchReferenceName(branchName), 135 | }) 136 | if err != nil { 137 | return err 138 | } 139 | return nil 140 | } 141 | return nil 142 | }) 143 | if exists == false { 144 | err := wt.Checkout(&git.CheckoutOptions{ 145 | Create: true, 146 | Force: false, 147 | Branch: plumbing.NewBranchReferenceName(branchName), 148 | }) 149 | if err != nil { 150 | return err 151 | } 152 | } 153 | return nil 154 | } 155 | 156 | func checkoutToCommit(repo *git.Repository, commitHash string) error { 157 | wt, _ := repo.Worktree() 158 | 159 | err := wt.Checkout((&git.CheckoutOptions{ 160 | Hash: plumbing.NewHash(commitHash), 161 | })) 162 | 163 | if err != nil { 164 | return err 165 | } 166 | 167 | return nil 168 | } 169 | -------------------------------------------------------------------------------- /nova/mapping/mapping.go: -------------------------------------------------------------------------------- 1 | package mapping 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "nova/handlers" 7 | "nova/texts" 8 | nova "nova/virtual" 9 | "strings" 10 | "syscall/js" 11 | 12 | "github.com/go-git/go-git/v5" 13 | "github.com/go-git/go-git/v5/plumbing" 14 | ) 15 | 16 | var novaStore nova.NovaStore = nova.NovaStore{} 17 | var store, storer = novaStore.CreateStore() 18 | 19 | var repository, err = git.Open(storer, store) 20 | 21 | type Files struct { 22 | Files []File `json:"files"` 23 | } 24 | 25 | type File struct { 26 | Name string `json:"name"` 27 | Content string `json:"content"` 28 | } 29 | 30 | func jsonReader(jsonFile []byte) (string, string) { 31 | 32 | var files Files 33 | 34 | json.Unmarshal(jsonFile, &files) 35 | 36 | return files.Files[0].Name, files.Files[0].Content 37 | } 38 | 39 | func OpenVirtualFile() js.Func { 40 | return js.FuncOf(func(this js.Value, args []js.Value) interface{} { 41 | filename := args[0].String() 42 | 43 | if len(filename) == 0 { 44 | return texts.HtmlEmptyStringMsg 45 | } 46 | return novaStore.GetFileContent(store, filename) 47 | }) 48 | } 49 | 50 | func SaveVirtualFile() js.Func { 51 | return js.FuncOf(func(this js.Value, args []js.Value) interface{} { 52 | filename, content := jsonReader([]byte(args[0].String())) 53 | 54 | if len(filename) == 0 { 55 | return texts.HtmlEmptyStringMsg 56 | } 57 | novaStore.Save(store, filename, content) 58 | 59 | return "Saved" 60 | }) 61 | } 62 | 63 | func GetCurrentBranch() js.Func { 64 | return js.FuncOf(func(this js.Value, args []js.Value) interface{} { 65 | return novaStore.CurrentBranch.Name().Short() 66 | }) 67 | } 68 | 69 | func VirtualCommit() js.Func { 70 | return js.FuncOf(func(this js.Value, args []js.Value) interface{} { 71 | wt, _ := repository.Worktree() 72 | status, err := wt.Status() 73 | if status.String() == "" { 74 | return "" 75 | } 76 | commit := make(map[string]string) 77 | 78 | commitMsg := args[0].String() 79 | 80 | if err != nil { 81 | fmt.Println(err.Error()) 82 | return err.Error() 83 | } 84 | hash := novaStore.Screenshot(store, wt, commitMsg) 85 | if hash != "" { 86 | commit["hash"] = hash 87 | commit["message"] = commitMsg 88 | commitsToJson, _ := json.Marshal(commit) 89 | fmt.Println(commit) 90 | return string(commitsToJson) 91 | } 92 | return "err" 93 | 94 | }) 95 | } 96 | 97 | func CreateVirtualFiles() js.Func { 98 | return js.FuncOf(func(this js.Value, args []js.Value) interface{} { 99 | filename, content := jsonReader([]byte(args[0].String())) 100 | 101 | novaStore.SetBranch(repository) 102 | if len(filename) == 0 { 103 | return texts.HtmlEmptyStringMsg 104 | } 105 | return handlers.Init(novaStore, store, filename, content) 106 | }) 107 | } 108 | 109 | func GetVirtualFiles() js.Func { 110 | return js.FuncOf(func(this js.Value, args []js.Value) interface{} { 111 | filenames := novaStore.GetFiles(store, texts.CurrentDirectory) 112 | 113 | return strings.Join(filenames, " ") 114 | }) 115 | } 116 | 117 | func GoToBranch() js.Func { 118 | return js.FuncOf(func(this js.Value, args []js.Value) interface{} { 119 | var branches []string 120 | 121 | branchName := args[0].String() 122 | novaStore.SetBranch(repository) 123 | _err := novaStore.GotoBranch(repository, branchName) 124 | 125 | if _err != nil { 126 | return _err 127 | } 128 | 129 | _branches, branchesErr := repository.Branches() 130 | if branchesErr != nil { 131 | return branchesErr 132 | } 133 | _branches.ForEach(func(branch *plumbing.Reference) error { 134 | branches = append(branches, branch.Name().Short()) 135 | return nil 136 | }) 137 | return strings.Join(branches, " ") 138 | }) 139 | } 140 | 141 | func GoToCommit() js.Func { 142 | return js.FuncOf(func(this js.Value, args []js.Value) interface{} { 143 | commitHash := args[0].String() 144 | novaStore.GoToCommit(repository, commitHash) 145 | return commitHash 146 | }) 147 | } 148 | 149 | func ExploreDirectory() js.Func { 150 | return js.FuncOf(func(this js.Value, args []js.Value) interface{} { 151 | filename := args[0].String() 152 | filenames := novaStore.ExploreDirectory(store, texts.CurrentDirectory, filename) 153 | return strings.Join(filenames, " ") 154 | }) 155 | } 156 | 157 | func IsDirectory() js.Func { 158 | return js.FuncOf(func(this js.Value, args []js.Value) interface{} { 159 | filename := args[0].String() 160 | return novaStore.IsDirectory(store, texts.CurrentDirectory, filename) 161 | }) 162 | } 163 | -------------------------------------------------------------------------------- /client/src/components/Files/Files.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef, useState } from 'react'; 2 | import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; 3 | import { createVirtualFilesWrapper } from '../../utils/goFunctions'; 4 | import { actionState, createVirtualBranchMessageState, virtualBranchState, virtualFilesState } from '../../atoms/atoms'; 5 | 6 | import { AiOutlineClose as CloseIcon } from '@react-icons/all-files/ai/AiOutlineClose'; 7 | 8 | import { CREATE_FILE, UPLOAD_FILE } from '../../utils/texts'; 9 | 10 | const Files = () => { 11 | const setVirtualFiles = useSetRecoilState(virtualFilesState); 12 | const virtualBranch = useRecoilValue(virtualBranchState); 13 | const setCreateVirtualBranchMessage = useSetRecoilState(createVirtualBranchMessageState); 14 | const [action, setAction] = useRecoilState(actionState); 15 | 16 | const [file, setFile] = useState(); 17 | const [fileContent, setFileContent] = useState(); 18 | const [virtualFileCreation, setVirtualFileCreation] = useState(''); 19 | const [disableFileCreation, setDisableFileCreation] = useState(false); 20 | 21 | const fileCreationInputRef = useRef(null); 22 | 23 | const handleCloseClick = () => { 24 | setAction(''); 25 | }; 26 | 27 | const disabledInputClickHandler = () => { 28 | if (!!virtualBranch === false) { 29 | setCreateVirtualBranchMessage('Create or checkout to a branch'); 30 | } 31 | }; 32 | 33 | const fileSelectorHandler = (e: any) => { 34 | e.preventDefault(); 35 | const created = createVirtualFilesWrapper(virtualFileCreation); 36 | setVirtualFiles(created.split(' ')); 37 | (fileCreationInputRef.current! as HTMLInputElement).value = ''; 38 | setAction(''); 39 | }; 40 | 41 | useEffect(() => { 42 | if (action === UPLOAD_FILE) { 43 | const fileSelector = document.getElementById('file-selector') as HTMLInputElement; 44 | fileSelector.addEventListener('change', (event) => { 45 | // @ts-ignore 46 | const fileList = event?.target!.files; 47 | setFile(fileList[0]); 48 | }); 49 | } else { 50 | if (fileCreationInputRef.current!) (fileCreationInputRef.current! as HTMLInputElement).focus(); 51 | } 52 | }, [action]); 53 | 54 | useEffect(() => { 55 | if (file) { 56 | const reader = new FileReader(); 57 | reader.onload = (evt: ProgressEvent) => { 58 | setFileContent(evt?.target!.result); 59 | }; 60 | reader.readAsText(file); 61 | } 62 | }, [file]); 63 | 64 | useEffect(() => { 65 | if (file && fileContent) { 66 | const created = createVirtualFilesWrapper(file.name, fileContent as string | undefined); 67 | if (created) { 68 | setVirtualFiles(created.split(' ')); 69 | const fileSelector = document.getElementById('file-selector') as HTMLInputElement; 70 | fileSelector.type = 'text'; 71 | fileSelector.type = 'file'; 72 | } 73 | } 74 | }, [fileContent]); 75 | 76 | useEffect(() => { 77 | if (!!virtualFileCreation) { 78 | setDisableFileCreation(false); 79 | } else { 80 | setDisableFileCreation(true); 81 | } 82 | }, [virtualFileCreation]); 83 | 84 | return ( 85 | <> 86 |
87 | {action === UPLOAD_FILE && ( 88 |
89 | 93 | 94 | 95 | 96 |
97 | )} 98 |
99 | {action === CREATE_FILE && !!virtualBranch && ( 100 |
101 |
102 | { 109 | setVirtualFileCreation(e.target.value); 110 | }} 111 | /> 112 | 113 | 114 | 115 |
116 |
117 | )} 118 |
119 |
120 | 121 | ); 122 | }; 123 | 124 | export default Files; 125 | -------------------------------------------------------------------------------- /client/src/components/Menu/Help.tsx: -------------------------------------------------------------------------------- 1 | import DialogContent from '@mui/material/DialogContent'; 2 | import DialogContentText from '@mui/material/DialogContentText'; 3 | import DialogTitle from '@mui/material/DialogTitle'; 4 | import Slide from '@mui/material/Slide'; 5 | import { TransitionProps } from '@mui/material/transitions'; 6 | import Dialog from '@mui/material/Dialog'; 7 | import Button from '@mui/material/Button'; 8 | 9 | import { BiHelpCircle as HelpIcon } from '@react-icons/all-files/bi/BiHelpCircle'; 10 | 11 | import { forwardRef, useState } from 'react'; 12 | import { actionState } from '../../atoms/atoms'; 13 | import { useRecoilState } from 'recoil'; 14 | import { HELP } from '../../utils/texts'; 15 | 16 | const Transition = forwardRef(function Transition( 17 | props: TransitionProps & { 18 | children: React.ReactElement; 19 | }, 20 | ref: React.Ref, 21 | ) { 22 | return ; 23 | }); 24 | 25 | const Help = () => { 26 | const [action, setAction] = useRecoilState(actionState); 27 | 28 | const [open, setOpen] = useState(false); 29 | 30 | const handleClickOpen = () => { 31 | setOpen(true); 32 | }; 33 | 34 | const handleClose = () => { 35 | setOpen(false); 36 | }; 37 | 38 | const id = open ? 'simple-popover' : undefined; 39 | 40 | return ( 41 | <> 42 |
43 | 53 | 54 | {'Harmony✨'} 55 | 56 | 57 | Harmony is a minimalistic Git interface ran entirely on the Web. 58 |
59 | Create, upload and edit mulitple files, on the fly, in the browser. Create branches and commits, in-memory, to keep track of your changes. Powered by WebAssembly. 60 |
61 |
62 | On page load, Harmony clones an empty repository (only README and LICENSE files present) and asks you to switch to a branch to start keeping track of what you do. 63 |
64 | After that you can start uploading or creating files, branches, commits and so on... 65 |
66 | It is up to you when (and if) to commit (locally - in-memory for now) the changes. By committing you can freely switch between branches without losing what you have done. 67 |
68 | Refresh the page to restart anew. 69 |
70 |
71 | Double click on file to open the editor. 72 |
73 | (Lock and unlock file drag - on mobile lock the drag to edit the content of a file) 74 |
75 |
76 | Shortcuts 77 |
- Ctrl + Shift + B : Create a branch (or switching to one) 78 |
- Ctrl + Shift + K : Create a new commit 79 |
- Ctrl + Shift + F : Create a new file 80 |
- Ctrl + Shift + U : Upload a new file 81 |
- Ctrl + Shift + H : Open this guide 82 |
83 | 84 |
85 |
86 | Harmony keeps track of the branches and commits you create allowing you to go back to a specific commit. 87 | 88 |
89 | Click on the commits with the Hash (not the Checkout commits) to visit that particular commit. 90 |
91 |
92 |
93 | Harmony also has a basic support for Folders (does not support nested folders yet) 94 | 95 |
96 | Create one by simply creating a new file with this format: "DIRECTORY_NAME/FILE_NAME". 97 |
98 | {(action === HELP || open) && ( 99 | 111 | )} 112 |
113 |
114 |
115 |
116 | 117 | ); 118 | }; 119 | 120 | export default Help; 121 | -------------------------------------------------------------------------------- /client/src/App.tsx: -------------------------------------------------------------------------------- 1 | import { Fragment, useEffect, useState } from 'react'; 2 | import Draggable from 'react-draggable'; 3 | import { isMobile } from 'react-device-detect'; 4 | 5 | import { IoMdDocument as DocumentIcon } from '@react-icons/all-files/io/IoMdDocument'; 6 | import { IoIosFolderOpen as FolderIcon } from '@react-icons/all-files/io/IoIosFolderOpen'; 7 | import { AiOutlineArrowLeft as BackArrowIcon } from '@react-icons/all-files/ai/AiOutlineArrowLeft'; 8 | 9 | import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil'; 10 | import { actionState, freeModeDisabledState, virtualFilesState } from './atoms/atoms'; 11 | import { exploreDirectoryWrapper, isDirectoryWrapper, openVirtualFilesWrapper, saveVirtualFilesWrapper } from './utils/goFunctions'; 12 | import Actions from './components/Actions/Actions'; 13 | 14 | import Files from './components/Files/Files'; 15 | import { Editor } from './components/Editor/Editor'; 16 | import HarmonyMenu from './components/Menu/Menu'; 17 | import { HELP } from './utils/texts'; 18 | import { keyChecker } from './utils/utilityFunctions'; 19 | 20 | // css 21 | import './App.css'; 22 | 23 | function App() { 24 | const [virtualFiles, setVirtualFiles] = useRecoilState(virtualFilesState); 25 | const setAction = useSetRecoilState(actionState); 26 | const freeModeDisabled = useRecoilValue(freeModeDisabledState); 27 | 28 | const [editorContent, setEditorContent] = useState(''); 29 | const [openFile, setOpenFile] = useState(''); 30 | const [prevOpenedFiles, setPrevOpenedFiles] = useState>([]); 31 | const [openDir, setOpenDir] = useState(''); 32 | const [oldVirtualFiles, setOldVirtualFiles] = useState>([]); 33 | 34 | const goBackInDirectories = () => { 35 | if (oldVirtualFiles.length > 0) { 36 | setVirtualFiles([...oldVirtualFiles]); 37 | return setOldVirtualFiles([]); 38 | } 39 | }; 40 | 41 | const clickOnFileHandler = (virtualFile: never, isDirectory: boolean = false) => { 42 | if (!isDirectory) { 43 | // Get the file content from Go functions 44 | // Open the file 45 | setEditorContent(openVirtualFilesWrapper(virtualFile)); 46 | setPrevOpenedFiles((prev: Array) => [...prev, virtualFile]); 47 | setOpenFile(virtualFile); 48 | } else { 49 | // Keep track of the directory you open to go back 50 | setOldVirtualFiles(virtualFiles); 51 | // Explore direcory 52 | setVirtualFiles(exploreDirectoryWrapper(virtualFile) as never[]); 53 | setOpenDir(virtualFile); 54 | } 55 | }; 56 | 57 | const saveChanges = (content: string) => { 58 | saveVirtualFilesWrapper(openFile, content); 59 | }; 60 | 61 | const closeEditor = () => { 62 | setOpenFile(''); 63 | }; 64 | 65 | const keyboardShortcut = (e: KeyboardEvent) => { 66 | // Keyboard shortcuts 67 | if (e.metaKey || e.ctrlKey) { 68 | if (e.shiftKey) { 69 | setAction(keyChecker(e.key)!); 70 | } 71 | } 72 | }; 73 | 74 | useEffect(() => { 75 | window.addEventListener('keydown', keyboardShortcut); 76 | if (localStorage.getItem('harmony-tutorial')) { 77 | localStorage.removeItem('harmony-tutorial'); 78 | } 79 | // Show the tutorial 80 | if (!localStorage.getItem('new-harmony-tutorial')) { 81 | setAction(HELP); 82 | localStorage.setItem('new-harmony-tutorial', 'true'); 83 | } 84 | 85 | return () => { 86 | window.removeEventListener('keydown', keyboardShortcut); 87 | }; 88 | }, []); 89 | 90 | return ( 91 | 92 | 93 | 94 | 95 |
96 |
0 ? 'dir-open' : ''}`} style={filesAreaStyle}> 97 | {oldVirtualFiles.length > 0 && ( 98 |
99 | {openDir} 100 | 101 |
102 | )} 103 | {virtualFiles.map((virtualFile, index) => { 104 | // Check if directory 105 | const isDirectory = isDirectoryWrapper(virtualFile); 106 | // Check if file was prev opened 107 | const prevOpened = !!prevOpenedFiles.find((f) => f === virtualFile) ? 'modified' : ''; 108 | // Regex on name 109 | const virtualFileName = (virtualFile as string).split('/').at(-1); 110 | // Double click on files to open (on mobile should disable the drag - from the menu) 111 | return ( 112 | 113 |
{ 115 | clickOnFileHandler(virtualFile, isDirectory); 116 | }} 117 | className={`virtual-file-wrapper ${prevOpened} ${isDirectory ? 'dir' : ''}`} 118 | > 119 | {isDirectory ? : } 120 |
121 | {virtualFileName} 122 |
123 |
124 |
125 | ); 126 | })} 127 |
128 | {openFile && !!editorContent && ( 129 |
130 | 131 |
132 | )} 133 |
134 |
135 | ); 136 | } 137 | 138 | const filesAreaStyle = { 139 | alignContent: isMobile ? 'flex-start' : 'center', 140 | justifyContent: isMobile ? 'flex-end' : 'center', 141 | }; 142 | 143 | export default App; 144 | -------------------------------------------------------------------------------- /client/src/components/Editor/Editor.tsx: -------------------------------------------------------------------------------- 1 | import { Fragment, useState } from 'react'; 2 | import Draggable from 'react-draggable'; 3 | 4 | import MonacoEditor, { EditorDidMount } from 'react-monaco-editor'; 5 | import * as monaco from 'monaco-editor'; 6 | import { MonacoServices } from 'monaco-languageclient'; 7 | 8 | import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'; 9 | import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'; 10 | import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'; 11 | import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'; 12 | import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'; 13 | 14 | import { RiDownloadCloud2Line as DownloadIcon } from '@react-icons/all-files/ri/RiDownloadCloud2Line'; 15 | import { RiDownloadCloud2Fill as DownloadIconFill } from '@react-icons/all-files/ri/RiDownloadCloud2Fill'; 16 | import { AiOutlineSave as SaveIcon } from '@react-icons/all-files/ai/AiOutlineSave'; 17 | import { AiOutlineCopy as CopyIcon } from '@react-icons/all-files/ai/AiOutlineCopy'; 18 | import { AiOutlineClose as CloseIcon } from '@react-icons/all-files/ai/AiOutlineClose'; 19 | import { GrClear as ClearIcon } from '@react-icons/all-files/gr/GrClear'; 20 | import { EditorProps } from '../../types/types'; 21 | 22 | self.MonacoEnvironment = { 23 | getWorker(_, label) { 24 | if (label === 'json') { 25 | return new jsonWorker(); 26 | } 27 | if (label === 'css' || label === 'scss' || label === 'less') { 28 | return new cssWorker(); 29 | } 30 | if (label === 'html' || label === 'handlebars' || label === 'razor') { 31 | return new htmlWorker(); 32 | } 33 | if (label === 'typescript' || label === 'javascript') { 34 | return new tsWorker(); 35 | } 36 | return new editorWorker(); 37 | }, 38 | }; 39 | 40 | const MONACO_OPTIONS: monaco.editor.IEditorConstructionOptions = { 41 | autoIndent: 'full', 42 | automaticLayout: true, 43 | contextmenu: true, 44 | fontFamily: 'monospace', 45 | fontSize: 13, 46 | lineHeight: 24, 47 | hideCursorInOverviewRuler: true, 48 | matchBrackets: 'always', 49 | minimap: { 50 | enabled: false, 51 | }, 52 | readOnly: false, 53 | scrollbar: { 54 | horizontalSliderSize: 4, 55 | verticalSliderSize: 18, 56 | }, 57 | }; 58 | 59 | export function Editor({ text, save, close, filename }: EditorProps) { 60 | const [writtenText, setWrittenText] = useState(''); 61 | const [saved, setSaved] = useState(false); 62 | const [fileExt, setFileExt] = useState(''); 63 | const [copied, setCopied] = useState(false); 64 | const [downloader, setDownloader] = useState(false); 65 | const [editorUri, setEditorUri] = useState(); 66 | 67 | const textSaver = (e: any) => { 68 | e.preventDefault(); 69 | save(writtenText); 70 | setSaved(true); 71 | }; 72 | 73 | const editorDidMount: EditorDidMount = (editor) => { 74 | MonacoServices.install(monaco as any); 75 | if (editor && editor.getModel()) { 76 | const editorModel = editor.getModel(); 77 | setEditorUri(editorModel?.uri); 78 | if (editorModel) { 79 | editorModel.setValue(text); 80 | } 81 | } 82 | const pattern = /\w+(?![\.\w])/; 83 | const lang = filename.match(pattern)![0]; 84 | switch (lang) { 85 | case 'js': 86 | setFileExt('javascript'); 87 | break; 88 | case 'ts': 89 | setFileExt('typescript'); 90 | break; 91 | default: 92 | setFileExt(lang); 93 | break; 94 | } 95 | editor.focus(); 96 | }; 97 | 98 | const onChange = (newCode: string, event: monaco.editor.IModelContentChangedEvent) => { 99 | setWrittenText(newCode); 100 | setSaved(false); 101 | setCopied(false); 102 | setDownloader(false); 103 | }; 104 | 105 | const download = (text: string, name: string, type: string) => { 106 | var a = document.getElementById('downloader') as any; 107 | var file = new Blob([text], { type: type }); 108 | a.href = URL.createObjectURL(file); 109 | a.download = name; 110 | }; 111 | 112 | return ( 113 | 114 | 115 |
116 | 117 | 118 | {saved ? Saved : copied ? Copied : 'Editing'} {filename} 119 | 120 | 121 | 122 |
123 | 134 | 137 | 147 | 154 | 155 | 156 | {!downloader && ( 157 | 166 | )} 167 | 176 |
177 | 178 |
179 |
180 | ); 181 | } 182 | -------------------------------------------------------------------------------- /nova/go.sum: -------------------------------------------------------------------------------- 1 | github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= 2 | github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk= 3 | github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= 4 | github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= 5 | github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= 6 | github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= 7 | github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= 8 | github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= 9 | github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= 10 | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= 11 | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= 12 | github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 13 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 14 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 15 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 16 | github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= 17 | github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= 18 | github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= 19 | github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= 20 | github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= 21 | github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= 22 | github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= 23 | github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= 24 | github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= 25 | github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= 26 | github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8= 27 | github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= 28 | github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= 29 | github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= 30 | github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= 31 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 32 | github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= 33 | github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= 34 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= 35 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= 36 | github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= 37 | github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= 38 | github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= 39 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 40 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 41 | github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= 42 | github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 43 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 44 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 45 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 46 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 47 | github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= 48 | github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= 49 | github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= 50 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 51 | github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= 52 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 53 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 54 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 55 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 56 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 57 | github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= 58 | github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= 59 | github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= 60 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 61 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 62 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 63 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 64 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 65 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 66 | github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= 67 | github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= 68 | github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= 69 | golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 70 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 71 | golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= 72 | golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= 73 | golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= 74 | golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= 75 | golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= 76 | golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= 77 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 78 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 79 | golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= 80 | golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= 81 | golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= 82 | golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= 83 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 84 | golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 85 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 86 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 87 | golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 88 | golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 89 | golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 90 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 91 | golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 92 | golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 93 | golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 94 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 95 | golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 96 | golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 97 | golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= 98 | golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 99 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 100 | golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 101 | golang.org/x/term v0.1.0 h1:g6Z6vPFA9dYBAF7DWcH6sCcOntplXsDKcliusYijMlw= 102 | golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= 103 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 104 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 105 | golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= 106 | golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= 107 | golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= 108 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 109 | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 110 | golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= 111 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 112 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 113 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 114 | gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 115 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 116 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 117 | gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= 118 | gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= 119 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 120 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 121 | gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= 122 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 123 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 124 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 125 | -------------------------------------------------------------------------------- /client/public/helpers/wasm_exec.js: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | 'use strict'; 6 | 7 | (() => { 8 | const enosys = () => { 9 | const err = new Error('not implemented'); 10 | err.code = 'ENOSYS'; 11 | return err; 12 | }; 13 | 14 | if (!globalThis.fs) { 15 | let outputBuf = ''; 16 | globalThis.fs = { 17 | constants: { 18 | O_WRONLY: -1, 19 | O_RDWR: -1, 20 | O_CREAT: -1, 21 | O_TRUNC: -1, 22 | O_APPEND: -1, 23 | O_EXCL: -1, 24 | }, // unused 25 | writeSync(fd, buf) { 26 | outputBuf += decoder.decode(buf); 27 | const nl = outputBuf.lastIndexOf('\n'); 28 | if (nl != -1) { 29 | console.log(outputBuf.substr(0, nl)); 30 | outputBuf = outputBuf.substr(nl + 1); 31 | } 32 | return buf.length; 33 | }, 34 | write(fd, buf, offset, length, position, callback) { 35 | if (offset !== 0 || length !== buf.length || position !== null) { 36 | callback(enosys()); 37 | return; 38 | } 39 | const n = this.writeSync(fd, buf); 40 | callback(null, n); 41 | }, 42 | chmod(path, mode, callback) { 43 | callback(enosys()); 44 | }, 45 | chown(path, uid, gid, callback) { 46 | callback(enosys()); 47 | }, 48 | close(fd, callback) { 49 | callback(enosys()); 50 | }, 51 | fchmod(fd, mode, callback) { 52 | callback(enosys()); 53 | }, 54 | fchown(fd, uid, gid, callback) { 55 | callback(enosys()); 56 | }, 57 | fstat(fd, callback) { 58 | callback(enosys()); 59 | }, 60 | fsync(fd, callback) { 61 | callback(null); 62 | }, 63 | ftruncate(fd, length, callback) { 64 | callback(enosys()); 65 | }, 66 | lchown(path, uid, gid, callback) { 67 | callback(enosys()); 68 | }, 69 | link(path, link, callback) { 70 | callback(enosys()); 71 | }, 72 | lstat(path, callback) { 73 | callback(enosys()); 74 | }, 75 | mkdir(path, perm, callback) { 76 | callback(enosys()); 77 | }, 78 | open(path, flags, mode, callback) { 79 | callback(enosys()); 80 | }, 81 | read(fd, buffer, offset, length, position, callback) { 82 | callback(enosys()); 83 | }, 84 | readdir(path, callback) { 85 | callback(enosys()); 86 | }, 87 | readlink(path, callback) { 88 | callback(enosys()); 89 | }, 90 | rename(from, to, callback) { 91 | callback(enosys()); 92 | }, 93 | rmdir(path, callback) { 94 | callback(enosys()); 95 | }, 96 | stat(path, callback) { 97 | callback(enosys()); 98 | }, 99 | symlink(path, link, callback) { 100 | callback(enosys()); 101 | }, 102 | truncate(path, length, callback) { 103 | callback(enosys()); 104 | }, 105 | unlink(path, callback) { 106 | callback(enosys()); 107 | }, 108 | utimes(path, atime, mtime, callback) { 109 | callback(enosys()); 110 | }, 111 | }; 112 | } 113 | 114 | if (!globalThis.process) { 115 | globalThis.process = { 116 | getuid() { 117 | return -1; 118 | }, 119 | getgid() { 120 | return -1; 121 | }, 122 | geteuid() { 123 | return -1; 124 | }, 125 | getegid() { 126 | return -1; 127 | }, 128 | getgroups() { 129 | throw enosys(); 130 | }, 131 | pid: -1, 132 | ppid: -1, 133 | umask() { 134 | throw enosys(); 135 | }, 136 | cwd() { 137 | throw enosys(); 138 | }, 139 | chdir() { 140 | throw enosys(); 141 | }, 142 | }; 143 | } 144 | 145 | if (!globalThis.crypto) { 146 | throw new Error('globalThis.crypto is not available, polyfill required (crypto.getRandomValues only)'); 147 | } 148 | 149 | if (!globalThis.performance) { 150 | throw new Error('globalThis.performance is not available, polyfill required (performance.now only)'); 151 | } 152 | 153 | if (!globalThis.TextEncoder) { 154 | throw new Error('globalThis.TextEncoder is not available, polyfill required'); 155 | } 156 | 157 | if (!globalThis.TextDecoder) { 158 | throw new Error('globalThis.TextDecoder is not available, polyfill required'); 159 | } 160 | 161 | const encoder = new TextEncoder('utf-8'); 162 | const decoder = new TextDecoder('utf-8'); 163 | 164 | globalThis.Go = class { 165 | constructor() { 166 | this.argv = ['js']; 167 | this.env = {}; 168 | this.exit = (code) => { 169 | if (code !== 0) { 170 | console.warn('exit code:', code); 171 | } 172 | }; 173 | this._exitPromise = new Promise((resolve) => { 174 | this._resolveExitPromise = resolve; 175 | }); 176 | this._pendingEvent = null; 177 | this._scheduledTimeouts = new Map(); 178 | this._nextCallbackTimeoutID = 1; 179 | 180 | const setInt64 = (addr, v) => { 181 | this.mem.setUint32(addr + 0, v, true); 182 | this.mem.setUint32(addr + 4, Math.floor(v / 4294967296), true); 183 | }; 184 | 185 | const getInt64 = (addr) => { 186 | const low = this.mem.getUint32(addr + 0, true); 187 | const high = this.mem.getInt32(addr + 4, true); 188 | return low + high * 4294967296; 189 | }; 190 | 191 | const loadValue = (addr) => { 192 | const f = this.mem.getFloat64(addr, true); 193 | if (f === 0) { 194 | return undefined; 195 | } 196 | if (!isNaN(f)) { 197 | return f; 198 | } 199 | 200 | const id = this.mem.getUint32(addr, true); 201 | return this._values[id]; 202 | }; 203 | 204 | const storeValue = (addr, v) => { 205 | const nanHead = 0x7ff80000; 206 | 207 | if (typeof v === 'number' && v !== 0) { 208 | if (isNaN(v)) { 209 | this.mem.setUint32(addr + 4, nanHead, true); 210 | this.mem.setUint32(addr, 0, true); 211 | return; 212 | } 213 | this.mem.setFloat64(addr, v, true); 214 | return; 215 | } 216 | 217 | if (v === undefined) { 218 | this.mem.setFloat64(addr, 0, true); 219 | return; 220 | } 221 | 222 | let id = this._ids.get(v); 223 | if (id === undefined) { 224 | id = this._idPool.pop(); 225 | if (id === undefined) { 226 | id = this._values.length; 227 | } 228 | this._values[id] = v; 229 | this._goRefCounts[id] = 0; 230 | this._ids.set(v, id); 231 | } 232 | this._goRefCounts[id]++; 233 | let typeFlag = 0; 234 | switch (typeof v) { 235 | case 'object': 236 | if (v !== null) { 237 | typeFlag = 1; 238 | } 239 | break; 240 | case 'string': 241 | typeFlag = 2; 242 | break; 243 | case 'symbol': 244 | typeFlag = 3; 245 | break; 246 | case 'function': 247 | typeFlag = 4; 248 | break; 249 | } 250 | this.mem.setUint32(addr + 4, nanHead | typeFlag, true); 251 | this.mem.setUint32(addr, id, true); 252 | }; 253 | 254 | const loadSlice = (addr) => { 255 | const array = getInt64(addr + 0); 256 | const len = getInt64(addr + 8); 257 | return new Uint8Array(this._inst.exports.mem.buffer, array, len); 258 | }; 259 | 260 | const loadSliceOfValues = (addr) => { 261 | const array = getInt64(addr + 0); 262 | const len = getInt64(addr + 8); 263 | const a = new Array(len); 264 | for (let i = 0; i < len; i++) { 265 | a[i] = loadValue(array + i * 8); 266 | } 267 | return a; 268 | }; 269 | 270 | const loadString = (addr) => { 271 | const saddr = getInt64(addr + 0); 272 | const len = getInt64(addr + 8); 273 | return decoder.decode(new DataView(this._inst.exports.mem.buffer, saddr, len)); 274 | }; 275 | 276 | const timeOrigin = Date.now() - performance.now(); 277 | this.importObject = { 278 | go: { 279 | // Go's SP does not change as long as no Go code is running. Some operations (e.g. calls, getters and setters) 280 | // may synchronously trigger a Go event handler. This makes Go code get executed in the middle of the imported 281 | // function. A goroutine can switch to a new stack if the current stack is too small (see morestack function). 282 | // This changes the SP, thus we have to update the SP used by the imported function. 283 | 284 | // func wasmExit(code int32) 285 | 'runtime.wasmExit': (sp) => { 286 | sp >>>= 0; 287 | const code = this.mem.getInt32(sp + 8, true); 288 | this.exited = true; 289 | delete this._inst; 290 | delete this._values; 291 | delete this._goRefCounts; 292 | delete this._ids; 293 | delete this._idPool; 294 | this.exit(code); 295 | }, 296 | 297 | // func wasmWrite(fd uintptr, p unsafe.Pointer, n int32) 298 | 'runtime.wasmWrite': (sp) => { 299 | sp >>>= 0; 300 | const fd = getInt64(sp + 8); 301 | const p = getInt64(sp + 16); 302 | const n = this.mem.getInt32(sp + 24, true); 303 | fs.writeSync(fd, new Uint8Array(this._inst.exports.mem.buffer, p, n)); 304 | }, 305 | 306 | // func resetMemoryDataView() 307 | 'runtime.resetMemoryDataView': (sp) => { 308 | sp >>>= 0; 309 | this.mem = new DataView(this._inst.exports.mem.buffer); 310 | }, 311 | 312 | // func nanotime1() int64 313 | 'runtime.nanotime1': (sp) => { 314 | sp >>>= 0; 315 | setInt64(sp + 8, (timeOrigin + performance.now()) * 1000000); 316 | }, 317 | 318 | // func walltime() (sec int64, nsec int32) 319 | 'runtime.walltime': (sp) => { 320 | sp >>>= 0; 321 | const msec = new Date().getTime(); 322 | setInt64(sp + 8, msec / 1000); 323 | this.mem.setInt32(sp + 16, (msec % 1000) * 1000000, true); 324 | }, 325 | 326 | // func scheduleTimeoutEvent(delay int64) int32 327 | 'runtime.scheduleTimeoutEvent': (sp) => { 328 | sp >>>= 0; 329 | const id = this._nextCallbackTimeoutID; 330 | this._nextCallbackTimeoutID++; 331 | this._scheduledTimeouts.set( 332 | id, 333 | setTimeout( 334 | () => { 335 | this._resume(); 336 | while (this._scheduledTimeouts.has(id)) { 337 | // for some reason Go failed to register the timeout event, log and try again 338 | // (temporary workaround for https://github.com/golang/go/issues/28975) 339 | console.warn('scheduleTimeoutEvent: missed timeout event'); 340 | this._resume(); 341 | } 342 | }, 343 | getInt64(sp + 8) + 1, // setTimeout has been seen to fire up to 1 millisecond early 344 | ), 345 | ); 346 | this.mem.setInt32(sp + 16, id, true); 347 | }, 348 | 349 | // func clearTimeoutEvent(id int32) 350 | 'runtime.clearTimeoutEvent': (sp) => { 351 | sp >>>= 0; 352 | const id = this.mem.getInt32(sp + 8, true); 353 | clearTimeout(this._scheduledTimeouts.get(id)); 354 | this._scheduledTimeouts.delete(id); 355 | }, 356 | 357 | // func getRandomData(r []byte) 358 | 'runtime.getRandomData': (sp) => { 359 | sp >>>= 0; 360 | crypto.getRandomValues(loadSlice(sp + 8)); 361 | }, 362 | 363 | // func finalizeRef(v ref) 364 | 'syscall/js.finalizeRef': (sp) => { 365 | sp >>>= 0; 366 | const id = this.mem.getUint32(sp + 8, true); 367 | this._goRefCounts[id]--; 368 | if (this._goRefCounts[id] === 0) { 369 | const v = this._values[id]; 370 | this._values[id] = null; 371 | this._ids.delete(v); 372 | this._idPool.push(id); 373 | } 374 | }, 375 | 376 | // func stringVal(value string) ref 377 | 'syscall/js.stringVal': (sp) => { 378 | sp >>>= 0; 379 | storeValue(sp + 24, loadString(sp + 8)); 380 | }, 381 | 382 | // func valueGet(v ref, p string) ref 383 | 'syscall/js.valueGet': (sp) => { 384 | sp >>>= 0; 385 | const result = Reflect.get(loadValue(sp + 8), loadString(sp + 16)); 386 | sp = this._inst.exports.getsp() >>> 0; // see comment above 387 | storeValue(sp + 32, result); 388 | }, 389 | 390 | // func valueSet(v ref, p string, x ref) 391 | 'syscall/js.valueSet': (sp) => { 392 | sp >>>= 0; 393 | Reflect.set(loadValue(sp + 8), loadString(sp + 16), loadValue(sp + 32)); 394 | }, 395 | 396 | // func valueDelete(v ref, p string) 397 | 'syscall/js.valueDelete': (sp) => { 398 | sp >>>= 0; 399 | Reflect.deleteProperty(loadValue(sp + 8), loadString(sp + 16)); 400 | }, 401 | 402 | // func valueIndex(v ref, i int) ref 403 | 'syscall/js.valueIndex': (sp) => { 404 | sp >>>= 0; 405 | storeValue(sp + 24, Reflect.get(loadValue(sp + 8), getInt64(sp + 16))); 406 | }, 407 | 408 | // valueSetIndex(v ref, i int, x ref) 409 | 'syscall/js.valueSetIndex': (sp) => { 410 | sp >>>= 0; 411 | Reflect.set(loadValue(sp + 8), getInt64(sp + 16), loadValue(sp + 24)); 412 | }, 413 | 414 | // func valueCall(v ref, m string, args []ref) (ref, bool) 415 | 'syscall/js.valueCall': (sp) => { 416 | sp >>>= 0; 417 | try { 418 | const v = loadValue(sp + 8); 419 | const m = Reflect.get(v, loadString(sp + 16)); 420 | const args = loadSliceOfValues(sp + 32); 421 | const result = Reflect.apply(m, v, args); 422 | sp = this._inst.exports.getsp() >>> 0; // see comment above 423 | storeValue(sp + 56, result); 424 | this.mem.setUint8(sp + 64, 1); 425 | } catch (err) { 426 | sp = this._inst.exports.getsp() >>> 0; // see comment above 427 | storeValue(sp + 56, err); 428 | this.mem.setUint8(sp + 64, 0); 429 | } 430 | }, 431 | 432 | // func valueInvoke(v ref, args []ref) (ref, bool) 433 | 'syscall/js.valueInvoke': (sp) => { 434 | sp >>>= 0; 435 | try { 436 | const v = loadValue(sp + 8); 437 | const args = loadSliceOfValues(sp + 16); 438 | const result = Reflect.apply(v, undefined, args); 439 | sp = this._inst.exports.getsp() >>> 0; // see comment above 440 | storeValue(sp + 40, result); 441 | this.mem.setUint8(sp + 48, 1); 442 | } catch (err) { 443 | sp = this._inst.exports.getsp() >>> 0; // see comment above 444 | storeValue(sp + 40, err); 445 | this.mem.setUint8(sp + 48, 0); 446 | } 447 | }, 448 | 449 | // func valueNew(v ref, args []ref) (ref, bool) 450 | 'syscall/js.valueNew': (sp) => { 451 | sp >>>= 0; 452 | try { 453 | const v = loadValue(sp + 8); 454 | const args = loadSliceOfValues(sp + 16); 455 | const result = Reflect.construct(v, args); 456 | sp = this._inst.exports.getsp() >>> 0; // see comment above 457 | storeValue(sp + 40, result); 458 | this.mem.setUint8(sp + 48, 1); 459 | } catch (err) { 460 | sp = this._inst.exports.getsp() >>> 0; // see comment above 461 | storeValue(sp + 40, err); 462 | this.mem.setUint8(sp + 48, 0); 463 | } 464 | }, 465 | 466 | // func valueLength(v ref) int 467 | 'syscall/js.valueLength': (sp) => { 468 | sp >>>= 0; 469 | setInt64(sp + 16, parseInt(loadValue(sp + 8).length)); 470 | }, 471 | 472 | // valuePrepareString(v ref) (ref, int) 473 | 'syscall/js.valuePrepareString': (sp) => { 474 | sp >>>= 0; 475 | const str = encoder.encode(String(loadValue(sp + 8))); 476 | storeValue(sp + 16, str); 477 | setInt64(sp + 24, str.length); 478 | }, 479 | 480 | // valueLoadString(v ref, b []byte) 481 | 'syscall/js.valueLoadString': (sp) => { 482 | sp >>>= 0; 483 | const str = loadValue(sp + 8); 484 | loadSlice(sp + 16).set(str); 485 | }, 486 | 487 | // func valueInstanceOf(v ref, t ref) bool 488 | 'syscall/js.valueInstanceOf': (sp) => { 489 | sp >>>= 0; 490 | this.mem.setUint8(sp + 24, loadValue(sp + 8) instanceof loadValue(sp + 16) ? 1 : 0); 491 | }, 492 | 493 | // func copyBytesToGo(dst []byte, src ref) (int, bool) 494 | 'syscall/js.copyBytesToGo': (sp) => { 495 | sp >>>= 0; 496 | const dst = loadSlice(sp + 8); 497 | const src = loadValue(sp + 32); 498 | if (!(src instanceof Uint8Array || src instanceof Uint8ClampedArray)) { 499 | this.mem.setUint8(sp + 48, 0); 500 | return; 501 | } 502 | const toCopy = src.subarray(0, dst.length); 503 | dst.set(toCopy); 504 | setInt64(sp + 40, toCopy.length); 505 | this.mem.setUint8(sp + 48, 1); 506 | }, 507 | 508 | // func copyBytesToJS(dst ref, src []byte) (int, bool) 509 | 'syscall/js.copyBytesToJS': (sp) => { 510 | sp >>>= 0; 511 | const dst = loadValue(sp + 8); 512 | const src = loadSlice(sp + 16); 513 | if (!(dst instanceof Uint8Array || dst instanceof Uint8ClampedArray)) { 514 | this.mem.setUint8(sp + 48, 0); 515 | return; 516 | } 517 | const toCopy = src.subarray(0, dst.length); 518 | dst.set(toCopy); 519 | setInt64(sp + 40, toCopy.length); 520 | this.mem.setUint8(sp + 48, 1); 521 | }, 522 | 523 | debug: (value) => { 524 | console.log(value); 525 | }, 526 | }, 527 | }; 528 | } 529 | 530 | async run(instance) { 531 | if (!(instance instanceof WebAssembly.Instance)) { 532 | throw new Error('Go.run: WebAssembly.Instance expected'); 533 | } 534 | this._inst = instance; 535 | this.mem = new DataView(this._inst.exports.mem.buffer); 536 | this._values = [ 537 | // JS values that Go currently has references to, indexed by reference id 538 | NaN, 539 | 0, 540 | null, 541 | true, 542 | false, 543 | globalThis, 544 | this, 545 | ]; 546 | this._goRefCounts = new Array(this._values.length).fill(Infinity); // number of references that Go has to a JS value, indexed by reference id 547 | this._ids = new Map([ 548 | // mapping from JS values to reference ids 549 | [0, 1], 550 | [null, 2], 551 | [true, 3], 552 | [false, 4], 553 | [globalThis, 5], 554 | [this, 6], 555 | ]); 556 | this._idPool = []; // unused ids that have been garbage collected 557 | this.exited = false; // whether the Go program has exited 558 | 559 | // Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory. 560 | let offset = 4096; 561 | 562 | const strPtr = (str) => { 563 | const ptr = offset; 564 | const bytes = encoder.encode(str + '\0'); 565 | new Uint8Array(this.mem.buffer, offset, bytes.length).set(bytes); 566 | offset += bytes.length; 567 | if (offset % 8 !== 0) { 568 | offset += 8 - (offset % 8); 569 | } 570 | return ptr; 571 | }; 572 | 573 | const argc = this.argv.length; 574 | 575 | const argvPtrs = []; 576 | this.argv.forEach((arg) => { 577 | argvPtrs.push(strPtr(arg)); 578 | }); 579 | argvPtrs.push(0); 580 | 581 | const keys = Object.keys(this.env).sort(); 582 | keys.forEach((key) => { 583 | argvPtrs.push(strPtr(`${key}=${this.env[key]}`)); 584 | }); 585 | argvPtrs.push(0); 586 | 587 | const argv = offset; 588 | argvPtrs.forEach((ptr) => { 589 | this.mem.setUint32(offset, ptr, true); 590 | this.mem.setUint32(offset + 4, 0, true); 591 | offset += 8; 592 | }); 593 | 594 | // The linker guarantees global data starts from at least wasmMinDataAddr. 595 | // Keep in sync with cmd/link/internal/ld/data.go:wasmMinDataAddr. 596 | const wasmMinDataAddr = 4096 + 8192; 597 | if (offset >= wasmMinDataAddr) { 598 | throw new Error('total length of command line and environment variables exceeds limit'); 599 | } 600 | 601 | this._inst.exports.run(argc, argv); 602 | if (this.exited) { 603 | this._resolveExitPromise(); 604 | } 605 | await this._exitPromise; 606 | } 607 | 608 | _resume() { 609 | if (this.exited) { 610 | throw new Error('Go program has already exited'); 611 | } 612 | this._inst.exports.resume(); 613 | if (this.exited) { 614 | this._resolveExitPromise(); 615 | } 616 | } 617 | 618 | _makeFuncWrapper(id) { 619 | const go = this; 620 | return function () { 621 | const event = { id: id, this: this, args: arguments }; 622 | go._pendingEvent = event; 623 | go._resume(); 624 | return event.result; 625 | }; 626 | } 627 | }; 628 | })(); 629 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: 5.4 2 | 3 | specifiers: 4 | concurrently: ^7.4.0 5 | cors-anywhere: ^0.4.4 6 | express: ^4.18.1 7 | prettier: ^2.7.1 8 | 9 | dependencies: 10 | cors-anywhere: 0.4.4 11 | express: 4.18.1 12 | 13 | devDependencies: 14 | concurrently: 7.4.0 15 | prettier: 2.7.1 16 | 17 | packages: 18 | 19 | /accepts/1.3.8: 20 | resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} 21 | engines: {node: '>= 0.6'} 22 | dependencies: 23 | mime-types: 2.1.35 24 | negotiator: 0.6.3 25 | dev: false 26 | 27 | /ansi-regex/5.0.1: 28 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 29 | engines: {node: '>=8'} 30 | dev: true 31 | 32 | /ansi-styles/4.3.0: 33 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 34 | engines: {node: '>=8'} 35 | dependencies: 36 | color-convert: 2.0.1 37 | dev: true 38 | 39 | /array-flatten/1.1.1: 40 | resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} 41 | dev: false 42 | 43 | /body-parser/1.20.0: 44 | resolution: {integrity: sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==} 45 | engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} 46 | dependencies: 47 | bytes: 3.1.2 48 | content-type: 1.0.4 49 | debug: 2.6.9 50 | depd: 2.0.0 51 | destroy: 1.2.0 52 | http-errors: 2.0.0 53 | iconv-lite: 0.4.24 54 | on-finished: 2.4.1 55 | qs: 6.10.3 56 | raw-body: 2.5.1 57 | type-is: 1.6.18 58 | unpipe: 1.0.0 59 | transitivePeerDependencies: 60 | - supports-color 61 | dev: false 62 | 63 | /bytes/3.1.2: 64 | resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} 65 | engines: {node: '>= 0.8'} 66 | dev: false 67 | 68 | /call-bind/1.0.2: 69 | resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} 70 | dependencies: 71 | function-bind: 1.1.1 72 | get-intrinsic: 1.1.3 73 | dev: false 74 | 75 | /chalk/4.1.2: 76 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 77 | engines: {node: '>=10'} 78 | dependencies: 79 | ansi-styles: 4.3.0 80 | supports-color: 7.2.0 81 | dev: true 82 | 83 | /cliui/7.0.4: 84 | resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} 85 | dependencies: 86 | string-width: 4.2.3 87 | strip-ansi: 6.0.1 88 | wrap-ansi: 7.0.0 89 | dev: true 90 | 91 | /color-convert/2.0.1: 92 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 93 | engines: {node: '>=7.0.0'} 94 | dependencies: 95 | color-name: 1.1.4 96 | dev: true 97 | 98 | /color-name/1.1.4: 99 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 100 | dev: true 101 | 102 | /concurrently/7.4.0: 103 | resolution: {integrity: sha512-M6AfrueDt/GEna/Vg9BqQ+93yuvzkSKmoTixnwEJkH0LlcGrRC2eCmjeG1tLLHIYfpYJABokqSGyMcXjm96AFA==} 104 | engines: {node: ^12.20.0 || ^14.13.0 || >=16.0.0} 105 | hasBin: true 106 | dependencies: 107 | chalk: 4.1.2 108 | date-fns: 2.29.3 109 | lodash: 4.17.21 110 | rxjs: 7.5.7 111 | shell-quote: 1.7.3 112 | spawn-command: 0.0.2-1 113 | supports-color: 8.1.1 114 | tree-kill: 1.2.2 115 | yargs: 17.5.1 116 | dev: true 117 | 118 | /content-disposition/0.5.4: 119 | resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} 120 | engines: {node: '>= 0.6'} 121 | dependencies: 122 | safe-buffer: 5.2.1 123 | dev: false 124 | 125 | /content-type/1.0.4: 126 | resolution: {integrity: sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==} 127 | engines: {node: '>= 0.6'} 128 | dev: false 129 | 130 | /cookie-signature/1.0.6: 131 | resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} 132 | dev: false 133 | 134 | /cookie/0.5.0: 135 | resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} 136 | engines: {node: '>= 0.6'} 137 | dev: false 138 | 139 | /cors-anywhere/0.4.4: 140 | resolution: {integrity: sha512-8OBFwnzMgR4mNrAeAyOLB2EruS2z7u02of2bOu7i9kKYlZG+niS7CTHLPgEXKWW2NAOJWRry9RRCaL9lJRjNqg==} 141 | engines: {node: '>=0.10.0'} 142 | dependencies: 143 | http-proxy: 1.11.1 144 | proxy-from-env: 0.0.1 145 | dev: false 146 | 147 | /date-fns/2.29.3: 148 | resolution: {integrity: sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==} 149 | engines: {node: '>=0.11'} 150 | dev: true 151 | 152 | /debug/2.6.9: 153 | resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} 154 | peerDependencies: 155 | supports-color: '*' 156 | peerDependenciesMeta: 157 | supports-color: 158 | optional: true 159 | dependencies: 160 | ms: 2.0.0 161 | dev: false 162 | 163 | /depd/2.0.0: 164 | resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} 165 | engines: {node: '>= 0.8'} 166 | dev: false 167 | 168 | /destroy/1.2.0: 169 | resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} 170 | engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} 171 | dev: false 172 | 173 | /ee-first/1.1.1: 174 | resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} 175 | dev: false 176 | 177 | /emoji-regex/8.0.0: 178 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 179 | dev: true 180 | 181 | /encodeurl/1.0.2: 182 | resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} 183 | engines: {node: '>= 0.8'} 184 | dev: false 185 | 186 | /escalade/3.1.1: 187 | resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} 188 | engines: {node: '>=6'} 189 | dev: true 190 | 191 | /escape-html/1.0.3: 192 | resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} 193 | dev: false 194 | 195 | /etag/1.8.1: 196 | resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} 197 | engines: {node: '>= 0.6'} 198 | dev: false 199 | 200 | /eventemitter3/1.2.0: 201 | resolution: {integrity: sha512-DOFqA1MF46fmZl2xtzXR3MPCRsXqgoFqdXcrCVYM3JNnfUeHTm/fh/v/iU7gBFpwkuBmoJPAm5GuhdDfSEJMJA==} 202 | dev: false 203 | 204 | /express/4.18.1: 205 | resolution: {integrity: sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==} 206 | engines: {node: '>= 0.10.0'} 207 | dependencies: 208 | accepts: 1.3.8 209 | array-flatten: 1.1.1 210 | body-parser: 1.20.0 211 | content-disposition: 0.5.4 212 | content-type: 1.0.4 213 | cookie: 0.5.0 214 | cookie-signature: 1.0.6 215 | debug: 2.6.9 216 | depd: 2.0.0 217 | encodeurl: 1.0.2 218 | escape-html: 1.0.3 219 | etag: 1.8.1 220 | finalhandler: 1.2.0 221 | fresh: 0.5.2 222 | http-errors: 2.0.0 223 | merge-descriptors: 1.0.1 224 | methods: 1.1.2 225 | on-finished: 2.4.1 226 | parseurl: 1.3.3 227 | path-to-regexp: 0.1.7 228 | proxy-addr: 2.0.7 229 | qs: 6.10.3 230 | range-parser: 1.2.1 231 | safe-buffer: 5.2.1 232 | send: 0.18.0 233 | serve-static: 1.15.0 234 | setprototypeof: 1.2.0 235 | statuses: 2.0.1 236 | type-is: 1.6.18 237 | utils-merge: 1.0.1 238 | vary: 1.1.2 239 | transitivePeerDependencies: 240 | - supports-color 241 | dev: false 242 | 243 | /finalhandler/1.2.0: 244 | resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} 245 | engines: {node: '>= 0.8'} 246 | dependencies: 247 | debug: 2.6.9 248 | encodeurl: 1.0.2 249 | escape-html: 1.0.3 250 | on-finished: 2.4.1 251 | parseurl: 1.3.3 252 | statuses: 2.0.1 253 | unpipe: 1.0.0 254 | transitivePeerDependencies: 255 | - supports-color 256 | dev: false 257 | 258 | /forwarded/0.2.0: 259 | resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} 260 | engines: {node: '>= 0.6'} 261 | dev: false 262 | 263 | /fresh/0.5.2: 264 | resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} 265 | engines: {node: '>= 0.6'} 266 | dev: false 267 | 268 | /function-bind/1.1.1: 269 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} 270 | dev: false 271 | 272 | /get-caller-file/2.0.5: 273 | resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} 274 | engines: {node: 6.* || 8.* || >= 10.*} 275 | dev: true 276 | 277 | /get-intrinsic/1.1.3: 278 | resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==} 279 | dependencies: 280 | function-bind: 1.1.1 281 | has: 1.0.3 282 | has-symbols: 1.0.3 283 | dev: false 284 | 285 | /has-flag/4.0.0: 286 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 287 | engines: {node: '>=8'} 288 | dev: true 289 | 290 | /has-symbols/1.0.3: 291 | resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} 292 | engines: {node: '>= 0.4'} 293 | dev: false 294 | 295 | /has/1.0.3: 296 | resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} 297 | engines: {node: '>= 0.4.0'} 298 | dependencies: 299 | function-bind: 1.1.1 300 | dev: false 301 | 302 | /http-errors/2.0.0: 303 | resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} 304 | engines: {node: '>= 0.8'} 305 | dependencies: 306 | depd: 2.0.0 307 | inherits: 2.0.4 308 | setprototypeof: 1.2.0 309 | statuses: 2.0.1 310 | toidentifier: 1.0.1 311 | dev: false 312 | 313 | /http-proxy/1.11.1: 314 | resolution: {integrity: sha512-qz7jZarkVG3G6GMq+4VRJPSN4NkIjL4VMTNhKGd8jc25BumeJjWWvnY3A7OkCGa8W1TTxbaK3dcE0ijFalITVA==} 315 | engines: {node: '>=0.10.0'} 316 | dependencies: 317 | eventemitter3: 1.2.0 318 | requires-port: 0.0.1 319 | dev: false 320 | 321 | /iconv-lite/0.4.24: 322 | resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} 323 | engines: {node: '>=0.10.0'} 324 | dependencies: 325 | safer-buffer: 2.1.2 326 | dev: false 327 | 328 | /inherits/2.0.4: 329 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 330 | dev: false 331 | 332 | /ipaddr.js/1.9.1: 333 | resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} 334 | engines: {node: '>= 0.10'} 335 | dev: false 336 | 337 | /is-fullwidth-code-point/3.0.0: 338 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 339 | engines: {node: '>=8'} 340 | dev: true 341 | 342 | /lodash/4.17.21: 343 | resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} 344 | dev: true 345 | 346 | /media-typer/0.3.0: 347 | resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} 348 | engines: {node: '>= 0.6'} 349 | dev: false 350 | 351 | /merge-descriptors/1.0.1: 352 | resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} 353 | dev: false 354 | 355 | /methods/1.1.2: 356 | resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} 357 | engines: {node: '>= 0.6'} 358 | dev: false 359 | 360 | /mime-db/1.52.0: 361 | resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} 362 | engines: {node: '>= 0.6'} 363 | dev: false 364 | 365 | /mime-types/2.1.35: 366 | resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} 367 | engines: {node: '>= 0.6'} 368 | dependencies: 369 | mime-db: 1.52.0 370 | dev: false 371 | 372 | /mime/1.6.0: 373 | resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} 374 | engines: {node: '>=4'} 375 | hasBin: true 376 | dev: false 377 | 378 | /ms/2.0.0: 379 | resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} 380 | dev: false 381 | 382 | /ms/2.1.3: 383 | resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} 384 | dev: false 385 | 386 | /negotiator/0.6.3: 387 | resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} 388 | engines: {node: '>= 0.6'} 389 | dev: false 390 | 391 | /object-inspect/1.12.2: 392 | resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} 393 | dev: false 394 | 395 | /on-finished/2.4.1: 396 | resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} 397 | engines: {node: '>= 0.8'} 398 | dependencies: 399 | ee-first: 1.1.1 400 | dev: false 401 | 402 | /parseurl/1.3.3: 403 | resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} 404 | engines: {node: '>= 0.8'} 405 | dev: false 406 | 407 | /path-to-regexp/0.1.7: 408 | resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} 409 | dev: false 410 | 411 | /prettier/2.7.1: 412 | resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==} 413 | engines: {node: '>=10.13.0'} 414 | hasBin: true 415 | dev: true 416 | 417 | /proxy-addr/2.0.7: 418 | resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} 419 | engines: {node: '>= 0.10'} 420 | dependencies: 421 | forwarded: 0.2.0 422 | ipaddr.js: 1.9.1 423 | dev: false 424 | 425 | /proxy-from-env/0.0.1: 426 | resolution: {integrity: sha512-B9Hnta3CATuMS0q6kt5hEezOPM+V3dgaRewkFtFoaRQYTVNsHqUvFXmndH06z3QO1ZdDnRELv5vfY6zAj/gG7A==} 427 | dev: false 428 | 429 | /qs/6.10.3: 430 | resolution: {integrity: sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==} 431 | engines: {node: '>=0.6'} 432 | dependencies: 433 | side-channel: 1.0.4 434 | dev: false 435 | 436 | /range-parser/1.2.1: 437 | resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} 438 | engines: {node: '>= 0.6'} 439 | dev: false 440 | 441 | /raw-body/2.5.1: 442 | resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} 443 | engines: {node: '>= 0.8'} 444 | dependencies: 445 | bytes: 3.1.2 446 | http-errors: 2.0.0 447 | iconv-lite: 0.4.24 448 | unpipe: 1.0.0 449 | dev: false 450 | 451 | /require-directory/2.1.1: 452 | resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} 453 | engines: {node: '>=0.10.0'} 454 | dev: true 455 | 456 | /requires-port/0.0.1: 457 | resolution: {integrity: sha512-AzPDCliPoWDSvEVYRQmpzuPhGGEnPrQz9YiOEvn+UdB9ixBpw+4IOZWtwctmpzySLZTy7ynpn47V14H4yaowtA==} 458 | dev: false 459 | 460 | /rxjs/7.5.7: 461 | resolution: {integrity: sha512-z9MzKh/UcOqB3i20H6rtrlaE/CgjLOvheWK/9ILrbhROGTweAi1BaFsTT9FbwZi5Trr1qNRs+MXkhmR06awzQA==} 462 | dependencies: 463 | tslib: 2.4.0 464 | dev: true 465 | 466 | /safe-buffer/5.2.1: 467 | resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 468 | dev: false 469 | 470 | /safer-buffer/2.1.2: 471 | resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} 472 | dev: false 473 | 474 | /send/0.18.0: 475 | resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} 476 | engines: {node: '>= 0.8.0'} 477 | dependencies: 478 | debug: 2.6.9 479 | depd: 2.0.0 480 | destroy: 1.2.0 481 | encodeurl: 1.0.2 482 | escape-html: 1.0.3 483 | etag: 1.8.1 484 | fresh: 0.5.2 485 | http-errors: 2.0.0 486 | mime: 1.6.0 487 | ms: 2.1.3 488 | on-finished: 2.4.1 489 | range-parser: 1.2.1 490 | statuses: 2.0.1 491 | transitivePeerDependencies: 492 | - supports-color 493 | dev: false 494 | 495 | /serve-static/1.15.0: 496 | resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} 497 | engines: {node: '>= 0.8.0'} 498 | dependencies: 499 | encodeurl: 1.0.2 500 | escape-html: 1.0.3 501 | parseurl: 1.3.3 502 | send: 0.18.0 503 | transitivePeerDependencies: 504 | - supports-color 505 | dev: false 506 | 507 | /setprototypeof/1.2.0: 508 | resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} 509 | dev: false 510 | 511 | /shell-quote/1.7.3: 512 | resolution: {integrity: sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==} 513 | dev: true 514 | 515 | /side-channel/1.0.4: 516 | resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} 517 | dependencies: 518 | call-bind: 1.0.2 519 | get-intrinsic: 1.1.3 520 | object-inspect: 1.12.2 521 | dev: false 522 | 523 | /spawn-command/0.0.2-1: 524 | resolution: {integrity: sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg==} 525 | dev: true 526 | 527 | /statuses/2.0.1: 528 | resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} 529 | engines: {node: '>= 0.8'} 530 | dev: false 531 | 532 | /string-width/4.2.3: 533 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 534 | engines: {node: '>=8'} 535 | dependencies: 536 | emoji-regex: 8.0.0 537 | is-fullwidth-code-point: 3.0.0 538 | strip-ansi: 6.0.1 539 | dev: true 540 | 541 | /strip-ansi/6.0.1: 542 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 543 | engines: {node: '>=8'} 544 | dependencies: 545 | ansi-regex: 5.0.1 546 | dev: true 547 | 548 | /supports-color/7.2.0: 549 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 550 | engines: {node: '>=8'} 551 | dependencies: 552 | has-flag: 4.0.0 553 | dev: true 554 | 555 | /supports-color/8.1.1: 556 | resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} 557 | engines: {node: '>=10'} 558 | dependencies: 559 | has-flag: 4.0.0 560 | dev: true 561 | 562 | /toidentifier/1.0.1: 563 | resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} 564 | engines: {node: '>=0.6'} 565 | dev: false 566 | 567 | /tree-kill/1.2.2: 568 | resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} 569 | hasBin: true 570 | dev: true 571 | 572 | /tslib/2.4.0: 573 | resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} 574 | dev: true 575 | 576 | /type-is/1.6.18: 577 | resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} 578 | engines: {node: '>= 0.6'} 579 | dependencies: 580 | media-typer: 0.3.0 581 | mime-types: 2.1.35 582 | dev: false 583 | 584 | /unpipe/1.0.0: 585 | resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} 586 | engines: {node: '>= 0.8'} 587 | dev: false 588 | 589 | /utils-merge/1.0.1: 590 | resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} 591 | engines: {node: '>= 0.4.0'} 592 | dev: false 593 | 594 | /vary/1.1.2: 595 | resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} 596 | engines: {node: '>= 0.8'} 597 | dev: false 598 | 599 | /wrap-ansi/7.0.0: 600 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} 601 | engines: {node: '>=10'} 602 | dependencies: 603 | ansi-styles: 4.3.0 604 | string-width: 4.2.3 605 | strip-ansi: 6.0.1 606 | dev: true 607 | 608 | /y18n/5.0.8: 609 | resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} 610 | engines: {node: '>=10'} 611 | dev: true 612 | 613 | /yargs-parser/21.1.1: 614 | resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} 615 | engines: {node: '>=12'} 616 | dev: true 617 | 618 | /yargs/17.5.1: 619 | resolution: {integrity: sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==} 620 | engines: {node: '>=12'} 621 | dependencies: 622 | cliui: 7.0.4 623 | escalade: 3.1.1 624 | get-caller-file: 2.0.5 625 | require-directory: 2.1.1 626 | string-width: 4.2.3 627 | y18n: 5.0.8 628 | yargs-parser: 21.1.1 629 | dev: true 630 | -------------------------------------------------------------------------------- /client/pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: 5.4 2 | 3 | specifiers: 4 | '@babel/core': '>=7.0.0 <8.0.0' 5 | '@emotion/react': ^11.10.4 6 | '@emotion/styled': ^11.10.4 7 | '@fontsource/roboto': ^4.5.8 8 | '@gitgraph/js': ^1.4.0 9 | '@mui/lab': 5.0.0-alpha.102 10 | '@mui/material': ^5.10.7 11 | '@react-icons/all-files': ^4.1.0 12 | '@types/react': ^18.0.17 13 | '@types/react-dom': ^18.0.6 14 | '@vitejs/plugin-react': ^2.1.0 15 | add: ^2.0.6 16 | core@^7.0.0: link:babel/core@^7.0.0 17 | monaco-editor: ^0.34.0 18 | monaco-languageclient: ^4.0.0 19 | react: ^18.2.0 20 | react-device-detect: ^2.2.2 21 | react-dom: ^18.2.0 22 | react-draggable: ^4.4.5 23 | react-monaco-editor: ^0.50.1 24 | react-select: ^5.4.0 25 | reactjs-popup: ^2.0.5 26 | recoil: ^0.7.5 27 | typescript: ^4.6.4 28 | vite: ^3.1.0 29 | vscode-oniguruma: ^1.6.2 30 | vscode-textmate: ^7.0.1 31 | 32 | dependencies: 33 | '@babel/core': 7.19.1 34 | '@emotion/react': 11.10.4_axxkdcpdr7up57umjkldobkynm 35 | '@emotion/styled': 11.10.4_sn4wuyy54zwps25tv4w7lbiz6i 36 | '@fontsource/roboto': 4.5.8 37 | '@gitgraph/js': 1.4.0 38 | '@mui/lab': 5.0.0-alpha.102_7g47ktvxgejelb3b2n6rycl75e 39 | '@mui/material': 5.10.7_af5ln35zuaotaffazii6n6bke4 40 | '@react-icons/all-files': 4.1.0_react@18.2.0 41 | add: 2.0.6 42 | core@^7.0.0: link:babel/core@^7.0.0 43 | monaco-editor: 0.34.0 44 | monaco-languageclient: 4.0.0_2dqbcwnoiqa4sunjfnse34uode 45 | react: 18.2.0 46 | react-device-detect: 2.2.2_biqbaboplfbrettd7655fr4n2y 47 | react-dom: 18.2.0_react@18.2.0 48 | react-draggable: 4.4.5_biqbaboplfbrettd7655fr4n2y 49 | react-monaco-editor: 0.50.1_uyf53jp3lmzmat2ssjsud325z4 50 | react-select: 5.4.0_gh7jwvvgp2fodlhsbspbg5vef4 51 | reactjs-popup: 2.0.5_biqbaboplfbrettd7655fr4n2y 52 | recoil: 0.7.5_biqbaboplfbrettd7655fr4n2y 53 | vscode-oniguruma: 1.6.2 54 | vscode-textmate: 7.0.1 55 | 56 | devDependencies: 57 | '@types/react': 18.0.20 58 | '@types/react-dom': 18.0.6 59 | '@vitejs/plugin-react': 2.1.0_vite@3.1.3 60 | typescript: 4.8.3 61 | vite: 3.1.3 62 | 63 | packages: 64 | 65 | /@ampproject/remapping/2.2.0: 66 | resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==} 67 | engines: {node: '>=6.0.0'} 68 | dependencies: 69 | '@jridgewell/gen-mapping': 0.1.1 70 | '@jridgewell/trace-mapping': 0.3.15 71 | 72 | /@babel/code-frame/7.18.6: 73 | resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} 74 | engines: {node: '>=6.9.0'} 75 | dependencies: 76 | '@babel/highlight': 7.18.6 77 | 78 | /@babel/compat-data/7.19.1: 79 | resolution: {integrity: sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg==} 80 | engines: {node: '>=6.9.0'} 81 | 82 | /@babel/core/7.19.1: 83 | resolution: {integrity: sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw==} 84 | engines: {node: '>=6.9.0'} 85 | dependencies: 86 | '@ampproject/remapping': 2.2.0 87 | '@babel/code-frame': 7.18.6 88 | '@babel/generator': 7.19.0 89 | '@babel/helper-compilation-targets': 7.19.1_@babel+core@7.19.1 90 | '@babel/helper-module-transforms': 7.19.0 91 | '@babel/helpers': 7.19.0 92 | '@babel/parser': 7.19.1 93 | '@babel/template': 7.18.10 94 | '@babel/traverse': 7.19.1 95 | '@babel/types': 7.19.0 96 | convert-source-map: 1.8.0 97 | debug: 4.3.4 98 | gensync: 1.0.0-beta.2 99 | json5: 2.2.1 100 | semver: 6.3.0 101 | transitivePeerDependencies: 102 | - supports-color 103 | 104 | /@babel/generator/7.19.0: 105 | resolution: {integrity: sha512-S1ahxf1gZ2dpoiFgA+ohK9DIpz50bJ0CWs7Zlzb54Z4sG8qmdIrGrVqmy1sAtTVRb+9CU6U8VqT9L0Zj7hxHVg==} 106 | engines: {node: '>=6.9.0'} 107 | dependencies: 108 | '@babel/types': 7.19.0 109 | '@jridgewell/gen-mapping': 0.3.2 110 | jsesc: 2.5.2 111 | 112 | /@babel/helper-annotate-as-pure/7.18.6: 113 | resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} 114 | engines: {node: '>=6.9.0'} 115 | dependencies: 116 | '@babel/types': 7.19.0 117 | dev: true 118 | 119 | /@babel/helper-compilation-targets/7.19.1_@babel+core@7.19.1: 120 | resolution: {integrity: sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg==} 121 | engines: {node: '>=6.9.0'} 122 | peerDependencies: 123 | '@babel/core': ^7.0.0 124 | dependencies: 125 | '@babel/compat-data': 7.19.1 126 | '@babel/core': 7.19.1 127 | '@babel/helper-validator-option': 7.18.6 128 | browserslist: 4.21.4 129 | semver: 6.3.0 130 | 131 | /@babel/helper-environment-visitor/7.18.9: 132 | resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} 133 | engines: {node: '>=6.9.0'} 134 | 135 | /@babel/helper-function-name/7.19.0: 136 | resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} 137 | engines: {node: '>=6.9.0'} 138 | dependencies: 139 | '@babel/template': 7.18.10 140 | '@babel/types': 7.19.0 141 | 142 | /@babel/helper-hoist-variables/7.18.6: 143 | resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} 144 | engines: {node: '>=6.9.0'} 145 | dependencies: 146 | '@babel/types': 7.19.0 147 | 148 | /@babel/helper-module-imports/7.18.6: 149 | resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} 150 | engines: {node: '>=6.9.0'} 151 | dependencies: 152 | '@babel/types': 7.19.0 153 | 154 | /@babel/helper-module-transforms/7.19.0: 155 | resolution: {integrity: sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==} 156 | engines: {node: '>=6.9.0'} 157 | dependencies: 158 | '@babel/helper-environment-visitor': 7.18.9 159 | '@babel/helper-module-imports': 7.18.6 160 | '@babel/helper-simple-access': 7.18.6 161 | '@babel/helper-split-export-declaration': 7.18.6 162 | '@babel/helper-validator-identifier': 7.19.1 163 | '@babel/template': 7.18.10 164 | '@babel/traverse': 7.19.1 165 | '@babel/types': 7.19.0 166 | transitivePeerDependencies: 167 | - supports-color 168 | 169 | /@babel/helper-plugin-utils/7.19.0: 170 | resolution: {integrity: sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==} 171 | engines: {node: '>=6.9.0'} 172 | 173 | /@babel/helper-simple-access/7.18.6: 174 | resolution: {integrity: sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==} 175 | engines: {node: '>=6.9.0'} 176 | dependencies: 177 | '@babel/types': 7.19.0 178 | 179 | /@babel/helper-split-export-declaration/7.18.6: 180 | resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} 181 | engines: {node: '>=6.9.0'} 182 | dependencies: 183 | '@babel/types': 7.19.0 184 | 185 | /@babel/helper-string-parser/7.18.10: 186 | resolution: {integrity: sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==} 187 | engines: {node: '>=6.9.0'} 188 | 189 | /@babel/helper-validator-identifier/7.19.1: 190 | resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} 191 | engines: {node: '>=6.9.0'} 192 | 193 | /@babel/helper-validator-option/7.18.6: 194 | resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} 195 | engines: {node: '>=6.9.0'} 196 | 197 | /@babel/helpers/7.19.0: 198 | resolution: {integrity: sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==} 199 | engines: {node: '>=6.9.0'} 200 | dependencies: 201 | '@babel/template': 7.18.10 202 | '@babel/traverse': 7.19.1 203 | '@babel/types': 7.19.0 204 | transitivePeerDependencies: 205 | - supports-color 206 | 207 | /@babel/highlight/7.18.6: 208 | resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} 209 | engines: {node: '>=6.9.0'} 210 | dependencies: 211 | '@babel/helper-validator-identifier': 7.19.1 212 | chalk: 2.4.2 213 | js-tokens: 4.0.0 214 | 215 | /@babel/parser/7.19.1: 216 | resolution: {integrity: sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A==} 217 | engines: {node: '>=6.0.0'} 218 | hasBin: true 219 | dependencies: 220 | '@babel/types': 7.19.0 221 | 222 | /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.19.1: 223 | resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} 224 | engines: {node: '>=6.9.0'} 225 | peerDependencies: 226 | '@babel/core': ^7.0.0-0 227 | dependencies: 228 | '@babel/core': 7.19.1 229 | '@babel/helper-plugin-utils': 7.19.0 230 | 231 | /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.19.1: 232 | resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==} 233 | engines: {node: '>=6.9.0'} 234 | peerDependencies: 235 | '@babel/core': ^7.0.0-0 236 | dependencies: 237 | '@babel/core': 7.19.1 238 | '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.19.1 239 | dev: true 240 | 241 | /@babel/plugin-transform-react-jsx-self/7.18.6_@babel+core@7.19.1: 242 | resolution: {integrity: sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig==} 243 | engines: {node: '>=6.9.0'} 244 | peerDependencies: 245 | '@babel/core': ^7.0.0-0 246 | dependencies: 247 | '@babel/core': 7.19.1 248 | '@babel/helper-plugin-utils': 7.19.0 249 | dev: true 250 | 251 | /@babel/plugin-transform-react-jsx-source/7.18.6_@babel+core@7.19.1: 252 | resolution: {integrity: sha512-utZmlASneDfdaMh0m/WausbjUjEdGrQJz0vFK93d7wD3xf5wBtX219+q6IlCNZeguIcxS2f/CvLZrlLSvSHQXw==} 253 | engines: {node: '>=6.9.0'} 254 | peerDependencies: 255 | '@babel/core': ^7.0.0-0 256 | dependencies: 257 | '@babel/core': 7.19.1 258 | '@babel/helper-plugin-utils': 7.19.0 259 | dev: true 260 | 261 | /@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.19.1: 262 | resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==} 263 | engines: {node: '>=6.9.0'} 264 | peerDependencies: 265 | '@babel/core': ^7.0.0-0 266 | dependencies: 267 | '@babel/core': 7.19.1 268 | '@babel/helper-annotate-as-pure': 7.18.6 269 | '@babel/helper-module-imports': 7.18.6 270 | '@babel/helper-plugin-utils': 7.19.0 271 | '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.19.1 272 | '@babel/types': 7.19.0 273 | dev: true 274 | 275 | /@babel/runtime/7.19.0: 276 | resolution: {integrity: sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==} 277 | engines: {node: '>=6.9.0'} 278 | dependencies: 279 | regenerator-runtime: 0.13.9 280 | dev: false 281 | 282 | /@babel/template/7.18.10: 283 | resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} 284 | engines: {node: '>=6.9.0'} 285 | dependencies: 286 | '@babel/code-frame': 7.18.6 287 | '@babel/parser': 7.19.1 288 | '@babel/types': 7.19.0 289 | 290 | /@babel/traverse/7.19.1: 291 | resolution: {integrity: sha512-0j/ZfZMxKukDaag2PtOPDbwuELqIar6lLskVPPJDjXMXjfLb1Obo/1yjxIGqqAJrmfaTIY3z2wFLAQ7qSkLsuA==} 292 | engines: {node: '>=6.9.0'} 293 | dependencies: 294 | '@babel/code-frame': 7.18.6 295 | '@babel/generator': 7.19.0 296 | '@babel/helper-environment-visitor': 7.18.9 297 | '@babel/helper-function-name': 7.19.0 298 | '@babel/helper-hoist-variables': 7.18.6 299 | '@babel/helper-split-export-declaration': 7.18.6 300 | '@babel/parser': 7.19.1 301 | '@babel/types': 7.19.0 302 | debug: 4.3.4 303 | globals: 11.12.0 304 | transitivePeerDependencies: 305 | - supports-color 306 | 307 | /@babel/types/7.19.0: 308 | resolution: {integrity: sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==} 309 | engines: {node: '>=6.9.0'} 310 | dependencies: 311 | '@babel/helper-string-parser': 7.18.10 312 | '@babel/helper-validator-identifier': 7.19.1 313 | to-fast-properties: 2.0.0 314 | 315 | /@codingame/monaco-vscode-api/1.69.11_2dqbcwnoiqa4sunjfnse34uode: 316 | resolution: {integrity: sha512-+WE/vYHZcrNos/ZADTt0bKfDI07hixfsu3Y0eCF2kxwWWNYbKWIbBWupOmFCy7oU8AggYWO/dFWlAYsGDwqKLQ==} 317 | peerDependencies: 318 | vscode-oniguruma: ^1.6.2 319 | vscode-textmate: ^7.0.1 320 | dependencies: 321 | monaco-editor: 0.34.0 322 | vscode-oniguruma: 1.6.2 323 | vscode-textmate: 7.0.1 324 | dev: false 325 | 326 | /@emotion/babel-plugin/11.10.2_@babel+core@7.19.1: 327 | resolution: {integrity: sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==} 328 | peerDependencies: 329 | '@babel/core': ^7.0.0 330 | dependencies: 331 | '@babel/core': 7.19.1 332 | '@babel/helper-module-imports': 7.18.6 333 | '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.19.1 334 | '@babel/runtime': 7.19.0 335 | '@emotion/hash': 0.9.0 336 | '@emotion/memoize': 0.8.0 337 | '@emotion/serialize': 1.1.0 338 | babel-plugin-macros: 3.1.0 339 | convert-source-map: 1.8.0 340 | escape-string-regexp: 4.0.0 341 | find-root: 1.1.0 342 | source-map: 0.5.7 343 | stylis: 4.0.13 344 | dev: false 345 | 346 | /@emotion/cache/11.10.3: 347 | resolution: {integrity: sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==} 348 | dependencies: 349 | '@emotion/memoize': 0.8.0 350 | '@emotion/sheet': 1.2.0 351 | '@emotion/utils': 1.2.0 352 | '@emotion/weak-memoize': 0.3.0 353 | stylis: 4.0.13 354 | dev: false 355 | 356 | /@emotion/hash/0.9.0: 357 | resolution: {integrity: sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==} 358 | dev: false 359 | 360 | /@emotion/is-prop-valid/1.2.0: 361 | resolution: {integrity: sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==} 362 | dependencies: 363 | '@emotion/memoize': 0.8.0 364 | dev: false 365 | 366 | /@emotion/memoize/0.8.0: 367 | resolution: {integrity: sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==} 368 | dev: false 369 | 370 | /@emotion/react/11.10.4_axxkdcpdr7up57umjkldobkynm: 371 | resolution: {integrity: sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA==} 372 | peerDependencies: 373 | '@babel/core': ^7.0.0 374 | '@types/react': '*' 375 | react: '>=16.8.0' 376 | peerDependenciesMeta: 377 | '@babel/core': 378 | optional: true 379 | '@types/react': 380 | optional: true 381 | dependencies: 382 | '@babel/core': 7.19.1 383 | '@babel/runtime': 7.19.0 384 | '@emotion/babel-plugin': 11.10.2_@babel+core@7.19.1 385 | '@emotion/cache': 11.10.3 386 | '@emotion/serialize': 1.1.0 387 | '@emotion/use-insertion-effect-with-fallbacks': 1.0.0_react@18.2.0 388 | '@emotion/utils': 1.2.0 389 | '@emotion/weak-memoize': 0.3.0 390 | '@types/react': 18.0.20 391 | hoist-non-react-statics: 3.3.2 392 | react: 18.2.0 393 | dev: false 394 | 395 | /@emotion/serialize/1.1.0: 396 | resolution: {integrity: sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==} 397 | dependencies: 398 | '@emotion/hash': 0.9.0 399 | '@emotion/memoize': 0.8.0 400 | '@emotion/unitless': 0.8.0 401 | '@emotion/utils': 1.2.0 402 | csstype: 3.1.1 403 | dev: false 404 | 405 | /@emotion/sheet/1.2.0: 406 | resolution: {integrity: sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w==} 407 | dev: false 408 | 409 | /@emotion/styled/11.10.4_sn4wuyy54zwps25tv4w7lbiz6i: 410 | resolution: {integrity: sha512-pRl4R8Ez3UXvOPfc2bzIoV8u9P97UedgHS4FPX594ntwEuAMA114wlaHvOK24HB48uqfXiGlYIZYCxVJ1R1ttQ==} 411 | peerDependencies: 412 | '@babel/core': ^7.0.0 413 | '@emotion/react': ^11.0.0-rc.0 414 | '@types/react': '*' 415 | react: '>=16.8.0' 416 | peerDependenciesMeta: 417 | '@babel/core': 418 | optional: true 419 | '@types/react': 420 | optional: true 421 | dependencies: 422 | '@babel/core': 7.19.1 423 | '@babel/runtime': 7.19.0 424 | '@emotion/babel-plugin': 11.10.2_@babel+core@7.19.1 425 | '@emotion/is-prop-valid': 1.2.0 426 | '@emotion/react': 11.10.4_axxkdcpdr7up57umjkldobkynm 427 | '@emotion/serialize': 1.1.0 428 | '@emotion/use-insertion-effect-with-fallbacks': 1.0.0_react@18.2.0 429 | '@emotion/utils': 1.2.0 430 | '@types/react': 18.0.20 431 | react: 18.2.0 432 | dev: false 433 | 434 | /@emotion/unitless/0.8.0: 435 | resolution: {integrity: sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==} 436 | dev: false 437 | 438 | /@emotion/use-insertion-effect-with-fallbacks/1.0.0_react@18.2.0: 439 | resolution: {integrity: sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==} 440 | peerDependencies: 441 | react: '>=16.8.0' 442 | dependencies: 443 | react: 18.2.0 444 | dev: false 445 | 446 | /@emotion/utils/1.2.0: 447 | resolution: {integrity: sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==} 448 | dev: false 449 | 450 | /@emotion/weak-memoize/0.3.0: 451 | resolution: {integrity: sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==} 452 | dev: false 453 | 454 | /@esbuild/android-arm/0.15.8: 455 | resolution: {integrity: sha512-CyEWALmn+no/lbgbAJsbuuhT8s2J19EJGHkeyAwjbFJMrj80KJ9zuYsoAvidPTU7BgBf87r/sgae8Tw0dbOc4Q==} 456 | engines: {node: '>=12'} 457 | cpu: [arm] 458 | os: [android] 459 | requiresBuild: true 460 | dependencies: 461 | esbuild-wasm: 0.15.8 462 | dev: true 463 | optional: true 464 | 465 | /@esbuild/linux-loong64/0.15.8: 466 | resolution: {integrity: sha512-pE5RQsOTSERCtfZdfCT25wzo7dfhOSlhAXcsZmuvRYhendOv7djcdvtINdnDp2DAjP17WXlBB4nBO6sHLczmsg==} 467 | engines: {node: '>=12'} 468 | cpu: [loong64] 469 | os: [linux] 470 | requiresBuild: true 471 | dev: true 472 | optional: true 473 | 474 | /@fontsource/roboto/4.5.8: 475 | resolution: {integrity: sha512-CnD7zLItIzt86q4Sj3kZUiLcBk1dSk81qcqgMGaZe7SQ1P8hFNxhMl5AZthK1zrDM5m74VVhaOpuMGIL4gagaA==} 476 | dev: false 477 | 478 | /@gitgraph/core/1.5.0: 479 | resolution: {integrity: sha512-8CeeHbkKoFHM1y9vfjYiHyEpzl1mEhVrg5c/eFgDBsntOYswoDKU2yOf6DjtVINcE60wmcuynBSJqjMkQo07Ww==} 480 | dev: false 481 | 482 | /@gitgraph/js/1.4.0: 483 | resolution: {integrity: sha512-7wxTTCFnRVjsqj+Zt09+3F79WhH4MK46ZS20AwbcB/MJFshSMeMH4nYmNDPa9McVsiL+cFsvW1pmZoquAOoHMw==} 484 | dependencies: 485 | '@gitgraph/core': 1.5.0 486 | dev: false 487 | 488 | /@jridgewell/gen-mapping/0.1.1: 489 | resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} 490 | engines: {node: '>=6.0.0'} 491 | dependencies: 492 | '@jridgewell/set-array': 1.1.2 493 | '@jridgewell/sourcemap-codec': 1.4.14 494 | 495 | /@jridgewell/gen-mapping/0.3.2: 496 | resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} 497 | engines: {node: '>=6.0.0'} 498 | dependencies: 499 | '@jridgewell/set-array': 1.1.2 500 | '@jridgewell/sourcemap-codec': 1.4.14 501 | '@jridgewell/trace-mapping': 0.3.15 502 | 503 | /@jridgewell/resolve-uri/3.1.0: 504 | resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} 505 | engines: {node: '>=6.0.0'} 506 | 507 | /@jridgewell/set-array/1.1.2: 508 | resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} 509 | engines: {node: '>=6.0.0'} 510 | 511 | /@jridgewell/sourcemap-codec/1.4.14: 512 | resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} 513 | 514 | /@jridgewell/trace-mapping/0.3.15: 515 | resolution: {integrity: sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==} 516 | dependencies: 517 | '@jridgewell/resolve-uri': 3.1.0 518 | '@jridgewell/sourcemap-codec': 1.4.14 519 | 520 | /@mui/base/5.0.0-alpha.100_7ey2zzynotv32rpkwno45fsx4e: 521 | resolution: {integrity: sha512-bSoJEKCENtmJrJDECHUe9PiqztIUACuSskyqw9ypqE7Dz3WxL3e8puFsWBkUsz+WOCjXh4B4Xljn88Ucxxv5HA==} 522 | engines: {node: '>=12.0.0'} 523 | peerDependencies: 524 | '@types/react': ^17.0.0 || ^18.0.0 525 | react: ^17.0.0 || ^18.0.0 526 | react-dom: ^17.0.0 || ^18.0.0 527 | peerDependenciesMeta: 528 | '@types/react': 529 | optional: true 530 | dependencies: 531 | '@babel/runtime': 7.19.0 532 | '@emotion/is-prop-valid': 1.2.0 533 | '@mui/types': 7.2.0_@types+react@18.0.20 534 | '@mui/utils': 5.10.6_react@18.2.0 535 | '@popperjs/core': 2.11.6 536 | '@types/react': 18.0.20 537 | clsx: 1.2.1 538 | prop-types: 15.8.1 539 | react: 18.2.0 540 | react-dom: 18.2.0_react@18.2.0 541 | react-is: 18.2.0 542 | dev: false 543 | 544 | /@mui/base/5.0.0-alpha.99_7ey2zzynotv32rpkwno45fsx4e: 545 | resolution: {integrity: sha512-D04H6O1c0Jv561yI0SVbpa8MpqpW3G43CwJxV2o6ALfI0DMJ45w07dGafmDchb6aCWTRTdggd3rjgmuzyNwPiQ==} 546 | engines: {node: '>=12.0.0'} 547 | peerDependencies: 548 | '@types/react': ^17.0.0 || ^18.0.0 549 | react: ^17.0.0 || ^18.0.0 550 | react-dom: ^17.0.0 || ^18.0.0 551 | peerDependenciesMeta: 552 | '@types/react': 553 | optional: true 554 | dependencies: 555 | '@babel/runtime': 7.19.0 556 | '@emotion/is-prop-valid': 1.2.0 557 | '@mui/types': 7.2.0_@types+react@18.0.20 558 | '@mui/utils': 5.10.6_react@18.2.0 559 | '@popperjs/core': 2.11.6 560 | '@types/react': 18.0.20 561 | clsx: 1.2.1 562 | prop-types: 15.8.1 563 | react: 18.2.0 564 | react-dom: 18.2.0_react@18.2.0 565 | react-is: 18.2.0 566 | dev: false 567 | 568 | /@mui/core-downloads-tracker/5.10.7: 569 | resolution: {integrity: sha512-3N0UYVy3MbrHzM3j6f7fIUCZ+bQ1/sSZq143tLxwSssW3Z4AqE83brpr5flEY1Lx+Aowv/cPyQMmZxzRlFCGqw==} 570 | dev: false 571 | 572 | /@mui/lab/5.0.0-alpha.102_7g47ktvxgejelb3b2n6rycl75e: 573 | resolution: {integrity: sha512-hIJ82FGdll2NmEp6b2kBhIZ5j/yiOThObBoSYo7WhH+cQCLowbgdAMH45JP9/R8J2qe2lq1K/PI3bLgcGVZ+Rw==} 574 | engines: {node: '>=12.0.0'} 575 | peerDependencies: 576 | '@emotion/react': ^11.5.0 577 | '@emotion/styled': ^11.3.0 578 | '@mui/material': ^5.0.0 579 | '@types/react': ^17.0.0 || ^18.0.0 580 | react: ^17.0.0 || ^18.0.0 581 | react-dom: ^17.0.0 || ^18.0.0 582 | peerDependenciesMeta: 583 | '@emotion/react': 584 | optional: true 585 | '@emotion/styled': 586 | optional: true 587 | '@types/react': 588 | optional: true 589 | dependencies: 590 | '@babel/runtime': 7.19.0 591 | '@emotion/react': 11.10.4_axxkdcpdr7up57umjkldobkynm 592 | '@emotion/styled': 11.10.4_sn4wuyy54zwps25tv4w7lbiz6i 593 | '@mui/base': 5.0.0-alpha.100_7ey2zzynotv32rpkwno45fsx4e 594 | '@mui/material': 5.10.7_af5ln35zuaotaffazii6n6bke4 595 | '@mui/system': 5.10.8_4mv32nu4vciambuqqzuu4gtvj4 596 | '@mui/types': 7.2.0_@types+react@18.0.20 597 | '@mui/utils': 5.10.6_react@18.2.0 598 | '@types/react': 18.0.20 599 | clsx: 1.2.1 600 | prop-types: 15.8.1 601 | react: 18.2.0 602 | react-dom: 18.2.0_react@18.2.0 603 | react-is: 18.2.0 604 | dev: false 605 | 606 | /@mui/material/5.10.7_af5ln35zuaotaffazii6n6bke4: 607 | resolution: {integrity: sha512-o1jcQGii+q7ORrXhBiMmGzFDaboc1qTgOOC3zDW+NR9ryVzWzL7qEeqoORbgDB5zk9OBsXCjB91fUH/ls5xMwg==} 608 | engines: {node: '>=12.0.0'} 609 | peerDependencies: 610 | '@emotion/react': ^11.5.0 611 | '@emotion/styled': ^11.3.0 612 | '@types/react': ^17.0.0 || ^18.0.0 613 | react: ^17.0.0 || ^18.0.0 614 | react-dom: ^17.0.0 || ^18.0.0 615 | peerDependenciesMeta: 616 | '@emotion/react': 617 | optional: true 618 | '@emotion/styled': 619 | optional: true 620 | '@types/react': 621 | optional: true 622 | dependencies: 623 | '@babel/runtime': 7.19.0 624 | '@emotion/react': 11.10.4_axxkdcpdr7up57umjkldobkynm 625 | '@emotion/styled': 11.10.4_sn4wuyy54zwps25tv4w7lbiz6i 626 | '@mui/base': 5.0.0-alpha.99_7ey2zzynotv32rpkwno45fsx4e 627 | '@mui/core-downloads-tracker': 5.10.7 628 | '@mui/system': 5.10.7_4mv32nu4vciambuqqzuu4gtvj4 629 | '@mui/types': 7.2.0_@types+react@18.0.20 630 | '@mui/utils': 5.10.6_react@18.2.0 631 | '@types/react': 18.0.20 632 | '@types/react-transition-group': 4.4.5 633 | clsx: 1.2.1 634 | csstype: 3.1.1 635 | prop-types: 15.8.1 636 | react: 18.2.0 637 | react-dom: 18.2.0_react@18.2.0 638 | react-is: 18.2.0 639 | react-transition-group: 4.4.5_biqbaboplfbrettd7655fr4n2y 640 | dev: false 641 | 642 | /@mui/private-theming/5.10.6_w5j4k42lgipnm43s3brx6h3c34: 643 | resolution: {integrity: sha512-I/W0QyTLRdEx6py3lKAquKO/rNF/7j+nIOM/xCyI9kU0fcotVTcTY08mKMsS6vrzdWpi6pAkD0wP0KwWy5R5VA==} 644 | engines: {node: '>=12.0.0'} 645 | peerDependencies: 646 | '@types/react': ^17.0.0 || ^18.0.0 647 | react: ^17.0.0 || ^18.0.0 648 | peerDependenciesMeta: 649 | '@types/react': 650 | optional: true 651 | dependencies: 652 | '@babel/runtime': 7.19.0 653 | '@mui/utils': 5.10.6_react@18.2.0 654 | '@types/react': 18.0.20 655 | prop-types: 15.8.1 656 | react: 18.2.0 657 | dev: false 658 | 659 | /@mui/styled-engine/5.10.7_hfzxdiydbrbhhfpkwuv3jhvwmq: 660 | resolution: {integrity: sha512-CCrtW+vvCKEm6pOE/QcutQ+ORC/iE6D1ghscN4l7LE2JXPvTXO/z0yu8Wxug1JEDlWm4r1Qa0PzJe1P9bjKzNA==} 661 | engines: {node: '>=12.0.0'} 662 | peerDependencies: 663 | '@emotion/react': ^11.4.1 664 | '@emotion/styled': ^11.3.0 665 | react: ^17.0.0 || ^18.0.0 666 | peerDependenciesMeta: 667 | '@emotion/react': 668 | optional: true 669 | '@emotion/styled': 670 | optional: true 671 | dependencies: 672 | '@babel/runtime': 7.19.0 673 | '@emotion/cache': 11.10.3 674 | '@emotion/react': 11.10.4_axxkdcpdr7up57umjkldobkynm 675 | '@emotion/styled': 11.10.4_sn4wuyy54zwps25tv4w7lbiz6i 676 | csstype: 3.1.1 677 | prop-types: 15.8.1 678 | react: 18.2.0 679 | dev: false 680 | 681 | /@mui/styled-engine/5.10.8_hfzxdiydbrbhhfpkwuv3jhvwmq: 682 | resolution: {integrity: sha512-w+y8WI18EJV6zM/q41ug19cE70JTeO6sWFsQ7tgePQFpy6ToCVPh0YLrtqxUZXSoMStW5FMw0t9fHTFAqPbngw==} 683 | engines: {node: '>=12.0.0'} 684 | peerDependencies: 685 | '@emotion/react': ^11.4.1 686 | '@emotion/styled': ^11.3.0 687 | react: ^17.0.0 || ^18.0.0 688 | peerDependenciesMeta: 689 | '@emotion/react': 690 | optional: true 691 | '@emotion/styled': 692 | optional: true 693 | dependencies: 694 | '@babel/runtime': 7.19.0 695 | '@emotion/cache': 11.10.3 696 | '@emotion/react': 11.10.4_axxkdcpdr7up57umjkldobkynm 697 | '@emotion/styled': 11.10.4_sn4wuyy54zwps25tv4w7lbiz6i 698 | csstype: 3.1.1 699 | prop-types: 15.8.1 700 | react: 18.2.0 701 | dev: false 702 | 703 | /@mui/system/5.10.7_4mv32nu4vciambuqqzuu4gtvj4: 704 | resolution: {integrity: sha512-kwyhjjKGsgtBRFl6vSqidDZcNKU5S1juTgm4Xi2fyWxaEbIQb9Sh9y0iVP2bNCJzgDr0alLaENOZOEaDWHISAQ==} 705 | engines: {node: '>=12.0.0'} 706 | peerDependencies: 707 | '@emotion/react': ^11.5.0 708 | '@emotion/styled': ^11.3.0 709 | '@types/react': ^17.0.0 || ^18.0.0 710 | react: ^17.0.0 || ^18.0.0 711 | peerDependenciesMeta: 712 | '@emotion/react': 713 | optional: true 714 | '@emotion/styled': 715 | optional: true 716 | '@types/react': 717 | optional: true 718 | dependencies: 719 | '@babel/runtime': 7.19.0 720 | '@emotion/react': 11.10.4_axxkdcpdr7up57umjkldobkynm 721 | '@emotion/styled': 11.10.4_sn4wuyy54zwps25tv4w7lbiz6i 722 | '@mui/private-theming': 5.10.6_w5j4k42lgipnm43s3brx6h3c34 723 | '@mui/styled-engine': 5.10.7_hfzxdiydbrbhhfpkwuv3jhvwmq 724 | '@mui/types': 7.2.0_@types+react@18.0.20 725 | '@mui/utils': 5.10.6_react@18.2.0 726 | '@types/react': 18.0.20 727 | clsx: 1.2.1 728 | csstype: 3.1.1 729 | prop-types: 15.8.1 730 | react: 18.2.0 731 | dev: false 732 | 733 | /@mui/system/5.10.8_4mv32nu4vciambuqqzuu4gtvj4: 734 | resolution: {integrity: sha512-hRQ354zcrYP/KHqK8FheICSvE9raQaUgQaV+A3oD4JETaFUCVI9Ytt+RcQYgTqx02xlCXIjl8LK1rPjTneySqw==} 735 | engines: {node: '>=12.0.0'} 736 | peerDependencies: 737 | '@emotion/react': ^11.5.0 738 | '@emotion/styled': ^11.3.0 739 | '@types/react': ^17.0.0 || ^18.0.0 740 | react: ^17.0.0 || ^18.0.0 741 | peerDependenciesMeta: 742 | '@emotion/react': 743 | optional: true 744 | '@emotion/styled': 745 | optional: true 746 | '@types/react': 747 | optional: true 748 | dependencies: 749 | '@babel/runtime': 7.19.0 750 | '@emotion/react': 11.10.4_axxkdcpdr7up57umjkldobkynm 751 | '@emotion/styled': 11.10.4_sn4wuyy54zwps25tv4w7lbiz6i 752 | '@mui/private-theming': 5.10.6_w5j4k42lgipnm43s3brx6h3c34 753 | '@mui/styled-engine': 5.10.8_hfzxdiydbrbhhfpkwuv3jhvwmq 754 | '@mui/types': 7.2.0_@types+react@18.0.20 755 | '@mui/utils': 5.10.6_react@18.2.0 756 | '@types/react': 18.0.20 757 | clsx: 1.2.1 758 | csstype: 3.1.1 759 | prop-types: 15.8.1 760 | react: 18.2.0 761 | dev: false 762 | 763 | /@mui/types/7.2.0_@types+react@18.0.20: 764 | resolution: {integrity: sha512-lGXtFKe5lp3UxTBGqKI1l7G8sE2xBik8qCfrLHD5olwP/YU0/ReWoWT7Lp1//ri32dK39oPMrJN8TgbkCSbsNA==} 765 | peerDependencies: 766 | '@types/react': '*' 767 | peerDependenciesMeta: 768 | '@types/react': 769 | optional: true 770 | dependencies: 771 | '@types/react': 18.0.20 772 | dev: false 773 | 774 | /@mui/utils/5.10.6_react@18.2.0: 775 | resolution: {integrity: sha512-g0Qs8xN/MW2M3fLL8197h5J2VB9U+49fLlnKKqC6zy/yus5cZwdT+Gwec+wUMxgwQoxMDn+J8oDWAn28kEOR/Q==} 776 | engines: {node: '>=12.0.0'} 777 | peerDependencies: 778 | react: ^17.0.0 || ^18.0.0 779 | dependencies: 780 | '@babel/runtime': 7.19.0 781 | '@types/prop-types': 15.7.5 782 | '@types/react-is': 17.0.3 783 | prop-types: 15.8.1 784 | react: 18.2.0 785 | react-is: 18.2.0 786 | dev: false 787 | 788 | /@popperjs/core/2.11.6: 789 | resolution: {integrity: sha512-50/17A98tWUfQ176raKiOGXuYpLyyVMkxxG6oylzL3BPOlA6ADGdK7EYunSa4I064xerltq9TGXs8HmOk5E+vw==} 790 | dev: false 791 | 792 | /@react-icons/all-files/4.1.0_react@18.2.0: 793 | resolution: {integrity: sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ==} 794 | peerDependencies: 795 | react: '*' 796 | dependencies: 797 | react: 18.2.0 798 | dev: false 799 | 800 | /@types/parse-json/4.0.0: 801 | resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} 802 | dev: false 803 | 804 | /@types/prop-types/15.7.5: 805 | resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} 806 | 807 | /@types/react-dom/18.0.6: 808 | resolution: {integrity: sha512-/5OFZgfIPSwy+YuIBP/FgJnQnsxhZhjjrnxudMddeblOouIodEQ75X14Rr4wGSG/bknL+Omy9iWlLo1u/9GzAA==} 809 | dependencies: 810 | '@types/react': 18.0.20 811 | dev: true 812 | 813 | /@types/react-is/17.0.3: 814 | resolution: {integrity: sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==} 815 | dependencies: 816 | '@types/react': 18.0.20 817 | dev: false 818 | 819 | /@types/react-transition-group/4.4.5: 820 | resolution: {integrity: sha512-juKD/eiSM3/xZYzjuzH6ZwpP+/lejltmiS3QEzV/vmb/Q8+HfDmxu+Baga8UEMGBqV88Nbg4l2hY/K2DkyaLLA==} 821 | dependencies: 822 | '@types/react': 18.0.20 823 | dev: false 824 | 825 | /@types/react/18.0.20: 826 | resolution: {integrity: sha512-MWul1teSPxujEHVwZl4a5HxQ9vVNsjTchVA+xRqv/VYGCuKGAU6UhfrTdF5aBefwD1BHUD8i/zq+O/vyCm/FrA==} 827 | dependencies: 828 | '@types/prop-types': 15.7.5 829 | '@types/scheduler': 0.16.2 830 | csstype: 3.1.1 831 | 832 | /@types/scheduler/0.16.2: 833 | resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} 834 | 835 | /@vitejs/plugin-react/2.1.0_vite@3.1.3: 836 | resolution: {integrity: sha512-am6rPyyU3LzUYne3Gd9oj9c4Rzbq5hQnuGXSMT6Gujq45Il/+bunwq3lrB7wghLkiF45ygMwft37vgJ/NE8IAA==} 837 | engines: {node: ^14.18.0 || >=16.0.0} 838 | peerDependencies: 839 | vite: ^3.0.0 840 | dependencies: 841 | '@babel/core': 7.19.1 842 | '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.19.1 843 | '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.19.1 844 | '@babel/plugin-transform-react-jsx-self': 7.18.6_@babel+core@7.19.1 845 | '@babel/plugin-transform-react-jsx-source': 7.18.6_@babel+core@7.19.1 846 | magic-string: 0.26.3 847 | react-refresh: 0.14.0 848 | vite: 3.1.3 849 | transitivePeerDependencies: 850 | - supports-color 851 | dev: true 852 | 853 | /add/2.0.6: 854 | resolution: {integrity: sha512-j5QzrmsokwWWp6kUcJQySpbG+xfOBqqKnup3OIk1pz+kB/80SLorZ9V8zHFLO92Lcd+hbvq8bT+zOGoPkmBV0Q==} 855 | dev: false 856 | 857 | /ansi-styles/3.2.1: 858 | resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} 859 | engines: {node: '>=4'} 860 | dependencies: 861 | color-convert: 1.9.3 862 | 863 | /babel-plugin-macros/3.1.0: 864 | resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} 865 | engines: {node: '>=10', npm: '>=6'} 866 | dependencies: 867 | '@babel/runtime': 7.19.0 868 | cosmiconfig: 7.0.1 869 | resolve: 1.22.1 870 | dev: false 871 | 872 | /balanced-match/1.0.2: 873 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 874 | dev: false 875 | 876 | /brace-expansion/1.1.11: 877 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 878 | dependencies: 879 | balanced-match: 1.0.2 880 | concat-map: 0.0.1 881 | dev: false 882 | 883 | /browserslist/4.21.4: 884 | resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} 885 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} 886 | hasBin: true 887 | dependencies: 888 | caniuse-lite: 1.0.30001409 889 | electron-to-chromium: 1.4.256 890 | node-releases: 2.0.6 891 | update-browserslist-db: 1.0.9_browserslist@4.21.4 892 | 893 | /callsites/3.1.0: 894 | resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} 895 | engines: {node: '>=6'} 896 | dev: false 897 | 898 | /caniuse-lite/1.0.30001409: 899 | resolution: {integrity: sha512-V0mnJ5dwarmhYv8/MzhJ//aW68UpvnQBXv8lJ2QUsvn2pHcmAuNtu8hQEDz37XnA1iE+lRR9CIfGWWpgJ5QedQ==} 900 | 901 | /chalk/2.4.2: 902 | resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} 903 | engines: {node: '>=4'} 904 | dependencies: 905 | ansi-styles: 3.2.1 906 | escape-string-regexp: 1.0.5 907 | supports-color: 5.5.0 908 | 909 | /clsx/1.2.1: 910 | resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} 911 | engines: {node: '>=6'} 912 | dev: false 913 | 914 | /color-convert/1.9.3: 915 | resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} 916 | dependencies: 917 | color-name: 1.1.3 918 | 919 | /color-name/1.1.3: 920 | resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} 921 | 922 | /concat-map/0.0.1: 923 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 924 | dev: false 925 | 926 | /convert-source-map/1.8.0: 927 | resolution: {integrity: sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==} 928 | dependencies: 929 | safe-buffer: 5.1.2 930 | 931 | /cosmiconfig/7.0.1: 932 | resolution: {integrity: sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==} 933 | engines: {node: '>=10'} 934 | dependencies: 935 | '@types/parse-json': 4.0.0 936 | import-fresh: 3.3.0 937 | parse-json: 5.2.0 938 | path-type: 4.0.0 939 | yaml: 1.10.2 940 | dev: false 941 | 942 | /csstype/3.1.1: 943 | resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} 944 | 945 | /debug/4.3.4: 946 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} 947 | engines: {node: '>=6.0'} 948 | peerDependencies: 949 | supports-color: '*' 950 | peerDependenciesMeta: 951 | supports-color: 952 | optional: true 953 | dependencies: 954 | ms: 2.1.2 955 | 956 | /dom-helpers/5.2.1: 957 | resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} 958 | dependencies: 959 | '@babel/runtime': 7.19.0 960 | csstype: 3.1.1 961 | dev: false 962 | 963 | /electron-to-chromium/1.4.256: 964 | resolution: {integrity: sha512-x+JnqyluoJv8I0U9gVe+Sk2st8vF0CzMt78SXxuoWCooLLY2k5VerIBdpvG7ql6GKI4dzNnPjmqgDJ76EdaAKw==} 965 | 966 | /error-ex/1.3.2: 967 | resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} 968 | dependencies: 969 | is-arrayish: 0.2.1 970 | dev: false 971 | 972 | /esbuild-android-64/0.15.8: 973 | resolution: {integrity: sha512-bVh8FIKOolF7/d4AMzt7xHlL0Ljr+mYKSHI39TJWDkybVWHdn6+4ODL3xZGHOxPpdRpitemXA1WwMKYBsw8dGw==} 974 | engines: {node: '>=12'} 975 | cpu: [x64] 976 | os: [android] 977 | requiresBuild: true 978 | dependencies: 979 | esbuild-wasm: 0.15.8 980 | dev: true 981 | optional: true 982 | 983 | /esbuild-android-arm64/0.15.8: 984 | resolution: {integrity: sha512-ReAMDAHuo0H1h9LxRabI6gwYPn8k6WiUeyxuMvx17yTrJO+SCnIfNc/TSPFvDwtK9MiyiKG/2dBYHouT/M0BXQ==} 985 | engines: {node: '>=12'} 986 | cpu: [arm64] 987 | os: [android] 988 | requiresBuild: true 989 | dev: true 990 | optional: true 991 | 992 | /esbuild-darwin-64/0.15.8: 993 | resolution: {integrity: sha512-KaKcGfJ+yto7Fo5gAj3xwxHMd1fBIKatpCHK8znTJLVv+9+NN2/tIPBqA4w5rBwjX0UqXDeIE2v1xJP+nGEXgA==} 994 | engines: {node: '>=12'} 995 | cpu: [x64] 996 | os: [darwin] 997 | requiresBuild: true 998 | dev: true 999 | optional: true 1000 | 1001 | /esbuild-darwin-arm64/0.15.8: 1002 | resolution: {integrity: sha512-8tjEaBgAKnXCkP7bhEJmEqdG9HEV6oLkF36BrMzpfW2rgaw0c48Zrxe+9RlfeGvs6gDF4w+agXyTjikzsS3izw==} 1003 | engines: {node: '>=12'} 1004 | cpu: [arm64] 1005 | os: [darwin] 1006 | requiresBuild: true 1007 | dev: true 1008 | optional: true 1009 | 1010 | /esbuild-freebsd-64/0.15.8: 1011 | resolution: {integrity: sha512-jaxcsGHYzn2L0/lffON2WfH4Nc+d/EwozVTP5K2v016zxMb5UQMhLoJzvLgBqHT1SG0B/mO+a+THnJCMVg15zw==} 1012 | engines: {node: '>=12'} 1013 | cpu: [x64] 1014 | os: [freebsd] 1015 | requiresBuild: true 1016 | dev: true 1017 | optional: true 1018 | 1019 | /esbuild-freebsd-arm64/0.15.8: 1020 | resolution: {integrity: sha512-2xp2UlljMvX8HExtcg7VHaeQk8OBU0CSl1j18B5CcZmSDkLF9p3utuMXIopG3a08fr9Hv+Dz6+seSXUow/G51w==} 1021 | engines: {node: '>=12'} 1022 | cpu: [arm64] 1023 | os: [freebsd] 1024 | requiresBuild: true 1025 | dev: true 1026 | optional: true 1027 | 1028 | /esbuild-linux-32/0.15.8: 1029 | resolution: {integrity: sha512-9u1E54BRz1FQMl86iaHK146+4ID2KYNxL3trLZT4QLLx3M7Q9n4lGG3lrzqUatGR2cKy8c33b0iaCzsItZWkFg==} 1030 | engines: {node: '>=12'} 1031 | cpu: [ia32] 1032 | os: [linux] 1033 | requiresBuild: true 1034 | dev: true 1035 | optional: true 1036 | 1037 | /esbuild-linux-64/0.15.8: 1038 | resolution: {integrity: sha512-4HxrsN9eUzJXdVGMTYA5Xler82FuZUu21bXKN42zcLHHNKCAMPUzD62I+GwDhsdgUBAUj0tRXDdsQHgaP6v0HA==} 1039 | engines: {node: '>=12'} 1040 | cpu: [x64] 1041 | os: [linux] 1042 | requiresBuild: true 1043 | dev: true 1044 | optional: true 1045 | 1046 | /esbuild-linux-arm/0.15.8: 1047 | resolution: {integrity: sha512-7DVBU9SFjX4+vBwt8tHsUCbE6Vvl6y6FQWHAgyw1lybC5gULqn/WnjHYHN2/LJaZRsDBvxWT4msEgwLGq1Wd3Q==} 1048 | engines: {node: '>=12'} 1049 | cpu: [arm] 1050 | os: [linux] 1051 | requiresBuild: true 1052 | dev: true 1053 | optional: true 1054 | 1055 | /esbuild-linux-arm64/0.15.8: 1056 | resolution: {integrity: sha512-1OCm7Aq0tEJT70PbxmHSGYDLYP8DKH8r4Nk7/XbVzWaduo9beCjGBB+tGZIHK6DdTQ3h00/4Tb/70YMH/bOtKg==} 1057 | engines: {node: '>=12'} 1058 | cpu: [arm64] 1059 | os: [linux] 1060 | requiresBuild: true 1061 | dev: true 1062 | optional: true 1063 | 1064 | /esbuild-linux-mips64le/0.15.8: 1065 | resolution: {integrity: sha512-yeFoNPVFPEzZvFYBfUQNG2TjGRaCyV1E27OcOg4LOtnGrxb2wA+mkW3luckyv1CEyd00mpAg7UdHx8nlx3ghgA==} 1066 | engines: {node: '>=12'} 1067 | cpu: [mips64el] 1068 | os: [linux] 1069 | requiresBuild: true 1070 | dev: true 1071 | optional: true 1072 | 1073 | /esbuild-linux-ppc64le/0.15.8: 1074 | resolution: {integrity: sha512-CEyMMUUNabXibw8OSNmBXhOIGhnjNVl5Lpseiuf00iKN0V47oqDrbo4dsHz1wH62m49AR8iG8wpDlTqfYgKbtg==} 1075 | engines: {node: '>=12'} 1076 | cpu: [ppc64] 1077 | os: [linux] 1078 | requiresBuild: true 1079 | dev: true 1080 | optional: true 1081 | 1082 | /esbuild-linux-riscv64/0.15.8: 1083 | resolution: {integrity: sha512-OCGSOaspMUjexSCU8ZiA0UnV/NiRU+s2vIfEcAQWQ6u32R+2luyfh/4ZaY6jFbylJE07Esc/yRvb9Q5fXuClXA==} 1084 | engines: {node: '>=12'} 1085 | cpu: [riscv64] 1086 | os: [linux] 1087 | requiresBuild: true 1088 | dev: true 1089 | optional: true 1090 | 1091 | /esbuild-linux-s390x/0.15.8: 1092 | resolution: {integrity: sha512-RHdpdfxRTSrZXZJlFSLazFU4YwXLB5Rgf6Zr5rffqSsO4y9JybgtKO38bFwxZNlDXliYISXN/YROKrG9s7mZQA==} 1093 | engines: {node: '>=12'} 1094 | cpu: [s390x] 1095 | os: [linux] 1096 | requiresBuild: true 1097 | dev: true 1098 | optional: true 1099 | 1100 | /esbuild-netbsd-64/0.15.8: 1101 | resolution: {integrity: sha512-VolFFRatBH09T5QMWhiohAWCOien1R1Uz9K0BRVVTBgBaVBt7eArsXTKxVhUgRf2vwu2c2SXkuP0r7HLG0eozw==} 1102 | engines: {node: '>=12'} 1103 | cpu: [x64] 1104 | os: [netbsd] 1105 | requiresBuild: true 1106 | dev: true 1107 | optional: true 1108 | 1109 | /esbuild-openbsd-64/0.15.8: 1110 | resolution: {integrity: sha512-HTAPlg+n4kUeE/isQxlCfsOz0xJGNoT5LJ9oYZWFKABfVf4Ycu7Zlf5ITgOnrdheTkz8JeL/gISIOCFAoOXrSA==} 1111 | engines: {node: '>=12'} 1112 | cpu: [x64] 1113 | os: [openbsd] 1114 | requiresBuild: true 1115 | dev: true 1116 | optional: true 1117 | 1118 | /esbuild-sunos-64/0.15.8: 1119 | resolution: {integrity: sha512-qMP/jR/FzcIOwKj+W+Lb+8Cfr8GZHbHUJxAPi7DUhNZMQ/6y7sOgRzlOSpRrbbUntrRZh0MqOyDhJ3Gpo6L1QA==} 1120 | engines: {node: '>=12'} 1121 | cpu: [x64] 1122 | os: [sunos] 1123 | requiresBuild: true 1124 | dev: true 1125 | optional: true 1126 | 1127 | /esbuild-wasm/0.15.8: 1128 | resolution: {integrity: sha512-Y7uCl5RNO4URjlemjdx++ukVHEMt5s5AfMWYUnMiK4Sry+pPCvQIctzXq6r6FKCyGKjX6/NGMCqR2OX6aLxj0w==} 1129 | engines: {node: '>=12'} 1130 | hasBin: true 1131 | requiresBuild: true 1132 | dev: true 1133 | optional: true 1134 | 1135 | /esbuild-windows-32/0.15.8: 1136 | resolution: {integrity: sha512-RKR1QHh4iWzjUhkP8Yqi75PPz/KS+b8zw3wUrzw6oAkj+iU5Qtyj61ZDaSG3Qf2vc6hTIUiPqVTqBH0NpXFNwg==} 1137 | engines: {node: '>=12'} 1138 | cpu: [ia32] 1139 | os: [win32] 1140 | requiresBuild: true 1141 | dev: true 1142 | optional: true 1143 | 1144 | /esbuild-windows-64/0.15.8: 1145 | resolution: {integrity: sha512-ag9ptYrsizgsR+PQE8QKeMqnosLvAMonQREpLw4evA4FFgOBMLEat/dY/9txbpozTw9eEOYyD3a4cE9yTu20FA==} 1146 | engines: {node: '>=12'} 1147 | cpu: [x64] 1148 | os: [win32] 1149 | requiresBuild: true 1150 | dev: true 1151 | optional: true 1152 | 1153 | /esbuild-windows-arm64/0.15.8: 1154 | resolution: {integrity: sha512-dbpAb0VyPaUs9mgw65KRfQ9rqiWCHpNzrJusoPu+LpEoswosjt/tFxN7cd2l68AT4qWdBkzAjDLRon7uqMeWcg==} 1155 | engines: {node: '>=12'} 1156 | cpu: [arm64] 1157 | os: [win32] 1158 | requiresBuild: true 1159 | dev: true 1160 | optional: true 1161 | 1162 | /esbuild/0.15.8: 1163 | resolution: {integrity: sha512-Remsk2dmr1Ia65sU+QasE6svJbsHe62lzR+CnjpUvbZ+uSYo1SitiOWPRfZQkCu82YWZBBKXiD/j0i//XWMZ+Q==} 1164 | engines: {node: '>=12'} 1165 | hasBin: true 1166 | requiresBuild: true 1167 | optionalDependencies: 1168 | '@esbuild/android-arm': 0.15.8 1169 | '@esbuild/linux-loong64': 0.15.8 1170 | esbuild-android-64: 0.15.8 1171 | esbuild-android-arm64: 0.15.8 1172 | esbuild-darwin-64: 0.15.8 1173 | esbuild-darwin-arm64: 0.15.8 1174 | esbuild-freebsd-64: 0.15.8 1175 | esbuild-freebsd-arm64: 0.15.8 1176 | esbuild-linux-32: 0.15.8 1177 | esbuild-linux-64: 0.15.8 1178 | esbuild-linux-arm: 0.15.8 1179 | esbuild-linux-arm64: 0.15.8 1180 | esbuild-linux-mips64le: 0.15.8 1181 | esbuild-linux-ppc64le: 0.15.8 1182 | esbuild-linux-riscv64: 0.15.8 1183 | esbuild-linux-s390x: 0.15.8 1184 | esbuild-netbsd-64: 0.15.8 1185 | esbuild-openbsd-64: 0.15.8 1186 | esbuild-sunos-64: 0.15.8 1187 | esbuild-windows-32: 0.15.8 1188 | esbuild-windows-64: 0.15.8 1189 | esbuild-windows-arm64: 0.15.8 1190 | dev: true 1191 | 1192 | /escalade/3.1.1: 1193 | resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} 1194 | engines: {node: '>=6'} 1195 | 1196 | /escape-string-regexp/1.0.5: 1197 | resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} 1198 | engines: {node: '>=0.8.0'} 1199 | 1200 | /escape-string-regexp/4.0.0: 1201 | resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} 1202 | engines: {node: '>=10'} 1203 | dev: false 1204 | 1205 | /find-root/1.1.0: 1206 | resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} 1207 | dev: false 1208 | 1209 | /fsevents/2.3.2: 1210 | resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} 1211 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 1212 | os: [darwin] 1213 | requiresBuild: true 1214 | dev: true 1215 | optional: true 1216 | 1217 | /function-bind/1.1.1: 1218 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} 1219 | 1220 | /gensync/1.0.0-beta.2: 1221 | resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} 1222 | engines: {node: '>=6.9.0'} 1223 | 1224 | /globals/11.12.0: 1225 | resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} 1226 | engines: {node: '>=4'} 1227 | 1228 | /hamt_plus/1.0.2: 1229 | resolution: {integrity: sha512-t2JXKaehnMb9paaYA7J0BX8QQAY8lwfQ9Gjf4pg/mk4krt+cmwmU652HOoWonf+7+EQV97ARPMhhVgU1ra2GhA==} 1230 | dev: false 1231 | 1232 | /has-flag/3.0.0: 1233 | resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} 1234 | engines: {node: '>=4'} 1235 | 1236 | /has/1.0.3: 1237 | resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} 1238 | engines: {node: '>= 0.4.0'} 1239 | dependencies: 1240 | function-bind: 1.1.1 1241 | 1242 | /hoist-non-react-statics/3.3.2: 1243 | resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} 1244 | dependencies: 1245 | react-is: 16.13.1 1246 | dev: false 1247 | 1248 | /import-fresh/3.3.0: 1249 | resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} 1250 | engines: {node: '>=6'} 1251 | dependencies: 1252 | parent-module: 1.0.1 1253 | resolve-from: 4.0.0 1254 | dev: false 1255 | 1256 | /is-arrayish/0.2.1: 1257 | resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} 1258 | dev: false 1259 | 1260 | /is-core-module/2.10.0: 1261 | resolution: {integrity: sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==} 1262 | dependencies: 1263 | has: 1.0.3 1264 | 1265 | /js-tokens/4.0.0: 1266 | resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} 1267 | 1268 | /jsesc/2.5.2: 1269 | resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} 1270 | engines: {node: '>=4'} 1271 | hasBin: true 1272 | 1273 | /json-parse-even-better-errors/2.3.1: 1274 | resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} 1275 | dev: false 1276 | 1277 | /json5/2.2.1: 1278 | resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==} 1279 | engines: {node: '>=6'} 1280 | hasBin: true 1281 | 1282 | /lines-and-columns/1.2.4: 1283 | resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} 1284 | dev: false 1285 | 1286 | /loose-envify/1.4.0: 1287 | resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} 1288 | hasBin: true 1289 | dependencies: 1290 | js-tokens: 4.0.0 1291 | dev: false 1292 | 1293 | /lru-cache/6.0.0: 1294 | resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} 1295 | engines: {node: '>=10'} 1296 | dependencies: 1297 | yallist: 4.0.0 1298 | dev: false 1299 | 1300 | /magic-string/0.26.3: 1301 | resolution: {integrity: sha512-u1Po0NDyFcwdg2nzHT88wSK0+Rih0N1M+Ph1Sp08k8yvFFU3KR72wryS7e1qMPJypt99WB7fIFVCA92mQrMjrg==} 1302 | engines: {node: '>=12'} 1303 | dependencies: 1304 | sourcemap-codec: 1.4.8 1305 | dev: true 1306 | 1307 | /memoize-one/5.2.1: 1308 | resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} 1309 | dev: false 1310 | 1311 | /minimatch/3.1.2: 1312 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 1313 | dependencies: 1314 | brace-expansion: 1.1.11 1315 | dev: false 1316 | 1317 | /monaco-editor/0.34.0: 1318 | resolution: {integrity: sha512-VF+S5zG8wxfinLKLrWcl4WUizMx+LeJrG4PM/M78OhcwocpV0jiyhX/pG6Q9jIOhrb/ckYi6nHnaR5OojlOZCQ==} 1319 | dev: false 1320 | 1321 | /monaco-languageclient/4.0.0_2dqbcwnoiqa4sunjfnse34uode: 1322 | resolution: {integrity: sha512-IRQag1btvne1Hwb97l5B+aitf6zCp7Pp1aj5JYYW2zSWz5Q5rS73l+0RuY5UknwVNX/6YkpGO6KZygAahzAs8A==} 1323 | engines: {node: '>=16.11.0', npm: '>=8.0.0'} 1324 | dependencies: 1325 | vscode: /@codingame/monaco-vscode-api/1.69.11_2dqbcwnoiqa4sunjfnse34uode 1326 | vscode-jsonrpc: 8.0.2 1327 | vscode-languageclient: 8.0.2 1328 | transitivePeerDependencies: 1329 | - vscode-oniguruma 1330 | - vscode-textmate 1331 | dev: false 1332 | 1333 | /ms/2.1.2: 1334 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 1335 | 1336 | /nanoid/3.3.4: 1337 | resolution: {integrity: sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==} 1338 | engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} 1339 | hasBin: true 1340 | dev: true 1341 | 1342 | /node-releases/2.0.6: 1343 | resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} 1344 | 1345 | /object-assign/4.1.1: 1346 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} 1347 | engines: {node: '>=0.10.0'} 1348 | dev: false 1349 | 1350 | /parent-module/1.0.1: 1351 | resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} 1352 | engines: {node: '>=6'} 1353 | dependencies: 1354 | callsites: 3.1.0 1355 | dev: false 1356 | 1357 | /parse-json/5.2.0: 1358 | resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} 1359 | engines: {node: '>=8'} 1360 | dependencies: 1361 | '@babel/code-frame': 7.18.6 1362 | error-ex: 1.3.2 1363 | json-parse-even-better-errors: 2.3.1 1364 | lines-and-columns: 1.2.4 1365 | dev: false 1366 | 1367 | /path-parse/1.0.7: 1368 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 1369 | 1370 | /path-type/4.0.0: 1371 | resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} 1372 | engines: {node: '>=8'} 1373 | dev: false 1374 | 1375 | /picocolors/1.0.0: 1376 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} 1377 | 1378 | /postcss/8.4.16: 1379 | resolution: {integrity: sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==} 1380 | engines: {node: ^10 || ^12 || >=14} 1381 | dependencies: 1382 | nanoid: 3.3.4 1383 | picocolors: 1.0.0 1384 | source-map-js: 1.0.2 1385 | dev: true 1386 | 1387 | /prop-types/15.8.1: 1388 | resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} 1389 | dependencies: 1390 | loose-envify: 1.4.0 1391 | object-assign: 4.1.1 1392 | react-is: 16.13.1 1393 | dev: false 1394 | 1395 | /react-device-detect/2.2.2_biqbaboplfbrettd7655fr4n2y: 1396 | resolution: {integrity: sha512-zSN1gIAztUekp5qUT/ybHwQ9fmOqVT1psxpSlTn1pe0CO+fnJHKRLOWWac5nKxOxvOpD/w84hk1I+EydrJp7SA==} 1397 | peerDependencies: 1398 | react: '>= 0.14.0' 1399 | react-dom: '>= 0.14.0' 1400 | dependencies: 1401 | react: 18.2.0 1402 | react-dom: 18.2.0_react@18.2.0 1403 | ua-parser-js: 1.0.2 1404 | dev: false 1405 | 1406 | /react-dom/18.2.0_react@18.2.0: 1407 | resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} 1408 | peerDependencies: 1409 | react: ^18.2.0 1410 | dependencies: 1411 | loose-envify: 1.4.0 1412 | react: 18.2.0 1413 | scheduler: 0.23.0 1414 | dev: false 1415 | 1416 | /react-draggable/4.4.5_biqbaboplfbrettd7655fr4n2y: 1417 | resolution: {integrity: sha512-OMHzJdyJbYTZo4uQE393fHcqqPYsEtkjfMgvCHr6rejT+Ezn4OZbNyGH50vv+SunC1RMvwOTSWkEODQLzw1M9g==} 1418 | peerDependencies: 1419 | react: '>= 16.3.0' 1420 | react-dom: '>= 16.3.0' 1421 | dependencies: 1422 | clsx: 1.2.1 1423 | prop-types: 15.8.1 1424 | react: 18.2.0 1425 | react-dom: 18.2.0_react@18.2.0 1426 | dev: false 1427 | 1428 | /react-is/16.13.1: 1429 | resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} 1430 | dev: false 1431 | 1432 | /react-is/18.2.0: 1433 | resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} 1434 | dev: false 1435 | 1436 | /react-monaco-editor/0.50.1_uyf53jp3lmzmat2ssjsud325z4: 1437 | resolution: {integrity: sha512-qvYdJhQdkPIrPDMxCrEl0T2x9TfBB+aUbrpFv69FwoTybeyfAjxgJ219MYSsgn3c/g06BgyLX4ENrXM4niZ9ag==} 1438 | peerDependencies: 1439 | '@types/react': '>=17 <= 18' 1440 | monaco-editor: ^0.34.0 1441 | react: '>=17 <= 18' 1442 | dependencies: 1443 | '@types/react': 18.0.20 1444 | monaco-editor: 0.34.0 1445 | prop-types: 15.8.1 1446 | react: 18.2.0 1447 | dev: false 1448 | 1449 | /react-refresh/0.14.0: 1450 | resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} 1451 | engines: {node: '>=0.10.0'} 1452 | dev: true 1453 | 1454 | /react-select/5.4.0_gh7jwvvgp2fodlhsbspbg5vef4: 1455 | resolution: {integrity: sha512-CjE9RFLUvChd5SdlfG4vqxZd55AZJRrLrHzkQyTYeHlpOztqcgnyftYAolJ0SGsBev6zAs6qFrjm6KU3eo2hzg==} 1456 | peerDependencies: 1457 | react: ^16.8.0 || ^17.0.0 || ^18.0.0 1458 | react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 1459 | dependencies: 1460 | '@babel/runtime': 7.19.0 1461 | '@emotion/cache': 11.10.3 1462 | '@emotion/react': 11.10.4_axxkdcpdr7up57umjkldobkynm 1463 | '@types/react-transition-group': 4.4.5 1464 | memoize-one: 5.2.1 1465 | prop-types: 15.8.1 1466 | react: 18.2.0 1467 | react-dom: 18.2.0_react@18.2.0 1468 | react-transition-group: 4.4.5_biqbaboplfbrettd7655fr4n2y 1469 | transitivePeerDependencies: 1470 | - '@babel/core' 1471 | - '@types/react' 1472 | dev: false 1473 | 1474 | /react-transition-group/4.4.5_biqbaboplfbrettd7655fr4n2y: 1475 | resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} 1476 | peerDependencies: 1477 | react: '>=16.6.0' 1478 | react-dom: '>=16.6.0' 1479 | dependencies: 1480 | '@babel/runtime': 7.19.0 1481 | dom-helpers: 5.2.1 1482 | loose-envify: 1.4.0 1483 | prop-types: 15.8.1 1484 | react: 18.2.0 1485 | react-dom: 18.2.0_react@18.2.0 1486 | dev: false 1487 | 1488 | /react/18.2.0: 1489 | resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} 1490 | engines: {node: '>=0.10.0'} 1491 | dependencies: 1492 | loose-envify: 1.4.0 1493 | dev: false 1494 | 1495 | /reactjs-popup/2.0.5_biqbaboplfbrettd7655fr4n2y: 1496 | resolution: {integrity: sha512-b5hv9a6aGsHEHXFAgPO5s1Jw1eSkopueyUVxQewGdLgqk2eW0IVXZrPRpHR629YcgIpC2oxtX8OOZ8a7bQJbxA==} 1497 | engines: {node: '>=10'} 1498 | peerDependencies: 1499 | react: '>=16' 1500 | react-dom: '>=16' 1501 | dependencies: 1502 | react: 18.2.0 1503 | react-dom: 18.2.0_react@18.2.0 1504 | dev: false 1505 | 1506 | /recoil/0.7.5_biqbaboplfbrettd7655fr4n2y: 1507 | resolution: {integrity: sha512-GVShsj5+M/2GULWBs5WBJGcsNis/d3YvDiaKjYh3mLKXftjtmk9kfaQ8jwjoIXySCwn8/RhgJ4Sshwgzj2UpFA==} 1508 | peerDependencies: 1509 | react: '>=16.13.1' 1510 | react-dom: '*' 1511 | react-native: '*' 1512 | peerDependenciesMeta: 1513 | react-dom: 1514 | optional: true 1515 | react-native: 1516 | optional: true 1517 | dependencies: 1518 | hamt_plus: 1.0.2 1519 | react: 18.2.0 1520 | react-dom: 18.2.0_react@18.2.0 1521 | dev: false 1522 | 1523 | /regenerator-runtime/0.13.9: 1524 | resolution: {integrity: sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==} 1525 | dev: false 1526 | 1527 | /resolve-from/4.0.0: 1528 | resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} 1529 | engines: {node: '>=4'} 1530 | dev: false 1531 | 1532 | /resolve/1.22.1: 1533 | resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} 1534 | hasBin: true 1535 | dependencies: 1536 | is-core-module: 2.10.0 1537 | path-parse: 1.0.7 1538 | supports-preserve-symlinks-flag: 1.0.0 1539 | 1540 | /rollup/2.78.1: 1541 | resolution: {integrity: sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==} 1542 | engines: {node: '>=10.0.0'} 1543 | hasBin: true 1544 | optionalDependencies: 1545 | fsevents: 2.3.2 1546 | dev: true 1547 | 1548 | /safe-buffer/5.1.2: 1549 | resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} 1550 | 1551 | /scheduler/0.23.0: 1552 | resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} 1553 | dependencies: 1554 | loose-envify: 1.4.0 1555 | dev: false 1556 | 1557 | /semver/6.3.0: 1558 | resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} 1559 | hasBin: true 1560 | 1561 | /semver/7.3.7: 1562 | resolution: {integrity: sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==} 1563 | engines: {node: '>=10'} 1564 | hasBin: true 1565 | dependencies: 1566 | lru-cache: 6.0.0 1567 | dev: false 1568 | 1569 | /source-map-js/1.0.2: 1570 | resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} 1571 | engines: {node: '>=0.10.0'} 1572 | dev: true 1573 | 1574 | /source-map/0.5.7: 1575 | resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} 1576 | engines: {node: '>=0.10.0'} 1577 | dev: false 1578 | 1579 | /sourcemap-codec/1.4.8: 1580 | resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} 1581 | dev: true 1582 | 1583 | /stylis/4.0.13: 1584 | resolution: {integrity: sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==} 1585 | dev: false 1586 | 1587 | /supports-color/5.5.0: 1588 | resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} 1589 | engines: {node: '>=4'} 1590 | dependencies: 1591 | has-flag: 3.0.0 1592 | 1593 | /supports-preserve-symlinks-flag/1.0.0: 1594 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 1595 | engines: {node: '>= 0.4'} 1596 | 1597 | /to-fast-properties/2.0.0: 1598 | resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} 1599 | engines: {node: '>=4'} 1600 | 1601 | /typescript/4.8.3: 1602 | resolution: {integrity: sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==} 1603 | engines: {node: '>=4.2.0'} 1604 | hasBin: true 1605 | dev: true 1606 | 1607 | /ua-parser-js/1.0.2: 1608 | resolution: {integrity: sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg==} 1609 | dev: false 1610 | 1611 | /update-browserslist-db/1.0.9_browserslist@4.21.4: 1612 | resolution: {integrity: sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==} 1613 | hasBin: true 1614 | peerDependencies: 1615 | browserslist: '>= 4.21.0' 1616 | dependencies: 1617 | browserslist: 4.21.4 1618 | escalade: 3.1.1 1619 | picocolors: 1.0.0 1620 | 1621 | /vite/3.1.3: 1622 | resolution: {integrity: sha512-/3XWiktaopByM5bd8dqvHxRt5EEgRikevnnrpND0gRfNkrMrPaGGexhtLCzv15RcCMtV2CLw+BPas8YFeSG0KA==} 1623 | engines: {node: ^14.18.0 || >=16.0.0} 1624 | hasBin: true 1625 | peerDependencies: 1626 | less: '*' 1627 | sass: '*' 1628 | stylus: '*' 1629 | terser: ^5.4.0 1630 | peerDependenciesMeta: 1631 | less: 1632 | optional: true 1633 | sass: 1634 | optional: true 1635 | stylus: 1636 | optional: true 1637 | terser: 1638 | optional: true 1639 | dependencies: 1640 | esbuild: 0.15.8 1641 | postcss: 8.4.16 1642 | resolve: 1.22.1 1643 | rollup: 2.78.1 1644 | optionalDependencies: 1645 | fsevents: 2.3.2 1646 | dev: true 1647 | 1648 | /vscode-jsonrpc/8.0.2: 1649 | resolution: {integrity: sha512-RY7HwI/ydoC1Wwg4gJ3y6LpU9FJRZAUnTYMXthqhFXXu77ErDd/xkREpGuk4MyYkk4a+XDWAMqe0S3KkelYQEQ==} 1650 | engines: {node: '>=14.0.0'} 1651 | dev: false 1652 | 1653 | /vscode-languageclient/8.0.2: 1654 | resolution: {integrity: sha512-lHlthJtphG9gibGb/y72CKqQUxwPsMXijJVpHEC2bvbFqxmkj9LwQ3aGU9dwjBLqsX1S4KjShYppLvg1UJDF/Q==} 1655 | engines: {vscode: ^1.67.0} 1656 | dependencies: 1657 | minimatch: 3.1.2 1658 | semver: 7.3.7 1659 | vscode-languageserver-protocol: 3.17.2 1660 | dev: false 1661 | 1662 | /vscode-languageserver-protocol/3.17.2: 1663 | resolution: {integrity: sha512-8kYisQ3z/SQ2kyjlNeQxbkkTNmVFoQCqkmGrzLH6A9ecPlgTbp3wDTnUNqaUxYr4vlAcloxx8zwy7G5WdguYNg==} 1664 | dependencies: 1665 | vscode-jsonrpc: 8.0.2 1666 | vscode-languageserver-types: 3.17.2 1667 | dev: false 1668 | 1669 | /vscode-languageserver-types/3.17.2: 1670 | resolution: {integrity: sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA==} 1671 | dev: false 1672 | 1673 | /vscode-oniguruma/1.6.2: 1674 | resolution: {integrity: sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==} 1675 | dev: false 1676 | 1677 | /vscode-textmate/7.0.1: 1678 | resolution: {integrity: sha512-zQ5U/nuXAAMsh691FtV0wPz89nSkHbs+IQV8FDk+wew9BlSDhf4UmWGlWJfTR2Ti6xZv87Tj5fENzKf6Qk7aLw==} 1679 | dev: false 1680 | 1681 | /yallist/4.0.0: 1682 | resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} 1683 | dev: false 1684 | 1685 | /yaml/1.10.2: 1686 | resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} 1687 | engines: {node: '>= 6'} 1688 | dev: false 1689 | --------------------------------------------------------------------------------