├── .gitignore ├── .vscode ├── config.sh ├── defsettings.json └── tasks.json ├── README.md ├── assets └── screenshot.jpg ├── main.py ├── package.json ├── plugin.json ├── pnpm-lock.yaml ├── rollup.config.js ├── src ├── backend.ts ├── index.tsx └── types.d.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | lib-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | *.swp 10 | 11 | pids 12 | logs 13 | results 14 | tmp 15 | 16 | # Coverage reports 17 | coverage 18 | 19 | # API keys and secrets 20 | .env 21 | 22 | # Dependency directory 23 | node_modules 24 | bower_components 25 | 26 | # Editors 27 | .idea 28 | *.iml 29 | 30 | # OS metadata 31 | .DS_Store 32 | Thumbs.db 33 | 34 | # Ignore built ts files 35 | dist/ 36 | 37 | __pycache__/ 38 | 39 | /.yalc 40 | yalc.lock 41 | 42 | .vscode/settings.json 43 | -------------------------------------------------------------------------------- /.vscode/config.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | SCRIPT_DIR="$( cd -- "$( dirname -- "${BASH_SOURCE[0]:-$0}"; )" &> /dev/null && pwd 2> /dev/null; )"; 3 | # printf "${SCRIPT_DIR}\n" 4 | # printf "$(dirname $0)\n" 5 | if ! [[ -e "${SCRIPT_DIR}/settings.json" ]]; then 6 | printf '.vscode/settings.json does not exist. Creating it with default settings. Exiting afterwards. Run your task again.\n\n' 7 | cp "${SCRIPT_DIR}/defsettings.json" "${SCRIPT_DIR}/settings.json" 8 | exit 1 9 | else 10 | printf '.vscode/settings.json does exist. Congrats.\n' 11 | printf 'Make sure to change settings.json to match your deck.\n' 12 | fi -------------------------------------------------------------------------------- /.vscode/defsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "deckip" : "0.0.0.0", 3 | "deckport" : "22", 4 | "deckpass" : "ssap", 5 | "deckkey" : "-i ${env:HOME}/.ssh/id_rsa", 6 | "deckdir" : "/home/deck" 7 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "tasks": [ 4 | // OTHER 5 | { 6 | "label": "checkforsettings", 7 | "type": "shell", 8 | "group": "none", 9 | "detail": "Check that settings.json has been created", 10 | "command": "bash -c ${workspaceFolder}/.vscode/config.sh", 11 | "problemMatcher": [] 12 | }, 13 | // BUILD 14 | { 15 | "label": "pnpmsetup", 16 | "type": "shell", 17 | "group": "build", 18 | "detail": "Setup pnpm", 19 | "command": "pnpm i", 20 | "problemMatcher": [] 21 | }, 22 | { 23 | "label": "updatefrontendlib", 24 | "type": "shell", 25 | "group": "build", 26 | "detail": "Update deck-frontend-lib", 27 | "command": "pnpm update decky-frontend-lib --latest", 28 | "problemMatcher": [] 29 | }, 30 | { 31 | "label": "build", 32 | "type": "npm", 33 | "group": "build", 34 | "detail": "rollup -c", 35 | "script": "build", 36 | "path": "", 37 | "problemMatcher": [] 38 | }, 39 | { 40 | "label": "buildall", 41 | "group": "build", 42 | "detail": "Build decky-plugin-template", 43 | "dependsOrder": "sequence", 44 | "dependsOn": [ 45 | "pnpmsetup", 46 | "build" 47 | ], 48 | "problemMatcher": [] 49 | }, 50 | // DEPLOY 51 | { 52 | "label": "createfolders", 53 | "detail": "Create plugins folder in expected directory", 54 | "type": "shell", 55 | "group": "none", 56 | "dependsOn": [ 57 | "checkforsettings" 58 | ], 59 | "command": "ssh deck@${config:deckip} -p ${config:deckport} ${config:deckkey} 'mkdir -p ${config:deckdir}/homebrew/dev/pluginloader && mkdir -p ${config:deckdir}/homebrew/dev/plugins'", 60 | "problemMatcher": [] 61 | }, 62 | { 63 | "label": "deploy", 64 | "detail": "Deploy dev plugin to deck", 65 | "type": "shell", 66 | "group": "none", 67 | "dependsOn": [ 68 | "createfolders", 69 | "chmodfolders" 70 | ], 71 | "command": "rsync -azp --delete --rsh='ssh -p ${config:deckport} ${config:deckkey}' --exclude='.git/' --exclude='.github/' --exclude='.vscode/' --exclude='node_modules/' --exclude='src/' --exclude='*.log' --exclude='.gitignore' . deck@${config:deckip}:${config:deckdir}/homebrew/dev/plugins/${workspaceFolderBasename}", 72 | "problemMatcher": [] 73 | }, 74 | { 75 | "label": "chmodfolders", 76 | "detail": "chmods folders to prevent perms issues", 77 | "type": "shell", 78 | "group": "none", 79 | "command": "ssh deck@${config:deckip} -p ${config:deckport} ${config:deckkey} 'echo '${config:deckpass}' | sudo -S chmod -R ug+rw ${config:deckdir}/homebrew/dev/'", 80 | "problemMatcher": [] 81 | }, 82 | { 83 | "label": "deployall", 84 | "dependsOrder": "sequence", 85 | "group": "none", 86 | "dependsOn": [ 87 | "deploy", 88 | "chmodfolders" 89 | ], 90 | "problemMatcher": [] 91 | }, 92 | // ALL-IN-ONE 93 | { 94 | "label": "allinone", 95 | "detail": "Build and deploy", 96 | "dependsOrder": "sequence", 97 | "group": "test", 98 | "dependsOn": [ 99 | "buildall", 100 | "deployall" 101 | ], 102 | "problemMatcher": [] 103 | } 104 | ] 105 | } 106 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Decky System Toolbox Plugin 2 | 3 | A Decky plugin for the Steam Deck containing various settings useful for tinkerers 4 | 5 | ## Features 6 | 7 | ### Services 8 | - SSH Server toggle 9 | - CEF Debugger forwarding toggle 10 | 11 | ### Settings 12 | - Transparent Huge pages toggle 13 | 14 | ## Screenshot 15 | 16 | ![](/assets/screenshot.jpg) 17 | -------------------------------------------------------------------------------- /assets/screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/WerWolv/SDH-SystemToolbox/81e744dac8975c70ebae76f1cec871f69a30f924/assets/screenshot.jpg -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | import subprocess 2 | 3 | class Plugin: 4 | 5 | ### Helpers 6 | 7 | def _get_service_state(self, service): 8 | return subprocess.Popen(f"systemctl is-active {service}", stdout=subprocess.PIPE, shell=True).communicate()[0] == b'active\n' 9 | 10 | def _set_service_state(self, service, state): 11 | if state: 12 | subprocess.Popen(f"systemctl enable --now {service}", stdout=subprocess.PIPE, shell=True).wait() 13 | else: 14 | subprocess.Popen(f"systemctl disable --now {service}", stdout=subprocess.PIPE, shell=True).wait() 15 | 16 | return self._get_service_state(self, service) 17 | 18 | 19 | ### SSH Server 20 | 21 | async def get_ssh_server_state(self): 22 | return self._get_service_state(self, "sshd") 23 | 24 | async def set_ssh_server_state(self, state): 25 | return self._set_service_state(self, "sshd", state) 26 | 27 | 28 | ### CEF Debugging Forwarding 29 | 30 | async def get_cef_debugger_forwarder_state(self): 31 | return self._get_service_state(self, "steam-web-debug-portforward") 32 | 33 | async def set_cef_debugger_forwarder_state(self, state): 34 | return self._set_service_state(self, "steam-web-debug-portforward", state) 35 | 36 | 37 | ### Linux Huge Pages 38 | 39 | async def get_huge_pages_state(self): 40 | with open("/sys/kernel/mm/transparent_hugepage/enabled", "r") as f: 41 | return f.read().strip().startswith("[always]") 42 | 43 | async def set_huge_pages_state(self, state): 44 | if state: 45 | with open("/sys/kernel/mm/transparent_hugepage/enabled", "w") as f: 46 | f.write("always") 47 | else: 48 | with open("/sys/kernel/mm/transparent_hugepage/enabled", "w") as f: 49 | f.write("madvise") 50 | 51 | return await self.get_huge_pages_state(self) 52 | 53 | 54 | ### Main 55 | 56 | async def _main(self): 57 | pass 58 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "system-toolbox", 3 | "version": "v1.0.3", 4 | "description": "A Decky plugin for the Steam Deck containing various settings useful for tinkerers", 5 | "scripts": { 6 | "build": "shx rm -rf dist && rollup -c", 7 | "watch": "rollup -c -w", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/SteamDeckHomebrew/decky-plugin-template.git" 13 | }, 14 | "keywords": [ 15 | "decky", 16 | "plugin", 17 | "plugin-template", 18 | "steam-deck", 19 | "deck" 20 | ], 21 | "author": "WerWolv ", 22 | "license": "GPL-2.0-or-later", 23 | "bugs": { 24 | "url": "https://github.com/WerWolv/SDH-SystemToolbox/issues" 25 | }, 26 | "homepage": "https://werwolv.net", 27 | "devDependencies": { 28 | "@rollup/plugin-commonjs": "^21.1.0", 29 | "@rollup/plugin-json": "^4.1.0", 30 | "@rollup/plugin-node-resolve": "^13.2.1", 31 | "@rollup/plugin-replace": "^4.0.0", 32 | "@rollup/plugin-typescript": "^8.3.2", 33 | "@types/react": "16.14.0", 34 | "@types/webpack": "^5.28.0", 35 | "rollup": "^2.70.2", 36 | "rollup-plugin-import-assets": "^1.1.1", 37 | "shx": "^0.3.4", 38 | "tslib": "^2.4.0", 39 | "typescript": "^4.6.4" 40 | }, 41 | "dependencies": { 42 | "decky-frontend-lib": "^3.25.0", 43 | "react-icons": "^4.3.1" 44 | }, 45 | "pnpm": { 46 | "peerDependencyRules": { 47 | "ignoreMissing": [ 48 | "react", 49 | "react-dom" 50 | ] 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /plugin.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "System Toolbox", 3 | "author": "WerWolv", 4 | "flags": [ "root" ], 5 | "publish": { 6 | "tags": [ "tools", "services", "kernel", "root" ], 7 | "description": "Helpful tools to control various settings of the Steam Deck", 8 | "image": "https://raw.githubusercontent.com/WerWolv/SDH-SystemToolbox/main/assets/screenshot.jpg" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '6.0' 2 | 3 | dependencies: 4 | decky-frontend-lib: 5 | specifier: ^3.25.0 6 | version: 3.25.0 7 | react-icons: 8 | specifier: ^4.3.1 9 | version: 4.4.0 10 | 11 | devDependencies: 12 | '@rollup/plugin-commonjs': 13 | specifier: ^21.1.0 14 | version: 21.1.0(rollup@2.75.6) 15 | '@rollup/plugin-json': 16 | specifier: ^4.1.0 17 | version: 4.1.0(rollup@2.75.6) 18 | '@rollup/plugin-node-resolve': 19 | specifier: ^13.2.1 20 | version: 13.3.0(rollup@2.75.6) 21 | '@rollup/plugin-replace': 22 | specifier: ^4.0.0 23 | version: 4.0.0(rollup@2.75.6) 24 | '@rollup/plugin-typescript': 25 | specifier: ^8.3.2 26 | version: 8.3.3(rollup@2.75.6)(tslib@2.4.0)(typescript@4.7.3) 27 | '@types/react': 28 | specifier: 16.14.0 29 | version: 16.14.0 30 | '@types/webpack': 31 | specifier: ^5.28.0 32 | version: 5.28.0 33 | rollup: 34 | specifier: ^2.70.2 35 | version: 2.75.6 36 | rollup-plugin-import-assets: 37 | specifier: ^1.1.1 38 | version: 1.1.1(rollup@2.75.6) 39 | shx: 40 | specifier: ^0.3.4 41 | version: 0.3.4 42 | tslib: 43 | specifier: ^2.4.0 44 | version: 2.4.0 45 | typescript: 46 | specifier: ^4.6.4 47 | version: 4.7.3 48 | 49 | packages: 50 | 51 | /@jridgewell/gen-mapping@0.3.1: 52 | resolution: {integrity: sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==} 53 | engines: {node: '>=6.0.0'} 54 | dependencies: 55 | '@jridgewell/set-array': 1.1.1 56 | '@jridgewell/sourcemap-codec': 1.4.13 57 | '@jridgewell/trace-mapping': 0.3.13 58 | dev: true 59 | 60 | /@jridgewell/resolve-uri@3.0.7: 61 | resolution: {integrity: sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==} 62 | engines: {node: '>=6.0.0'} 63 | dev: true 64 | 65 | /@jridgewell/set-array@1.1.1: 66 | resolution: {integrity: sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==} 67 | engines: {node: '>=6.0.0'} 68 | dev: true 69 | 70 | /@jridgewell/source-map@0.3.2: 71 | resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==} 72 | dependencies: 73 | '@jridgewell/gen-mapping': 0.3.1 74 | '@jridgewell/trace-mapping': 0.3.13 75 | dev: true 76 | 77 | /@jridgewell/sourcemap-codec@1.4.13: 78 | resolution: {integrity: sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==} 79 | dev: true 80 | 81 | /@jridgewell/trace-mapping@0.3.13: 82 | resolution: {integrity: sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==} 83 | dependencies: 84 | '@jridgewell/resolve-uri': 3.0.7 85 | '@jridgewell/sourcemap-codec': 1.4.13 86 | dev: true 87 | 88 | /@rollup/plugin-commonjs@21.1.0(rollup@2.75.6): 89 | resolution: {integrity: sha512-6ZtHx3VHIp2ReNNDxHjuUml6ur+WcQ28N1yHgCQwsbNkQg2suhxGMDQGJOn/KuDxKtd1xuZP5xSTwBA4GQ8hbA==} 90 | engines: {node: '>= 8.0.0'} 91 | peerDependencies: 92 | rollup: ^2.38.3 93 | dependencies: 94 | '@rollup/pluginutils': 3.1.0(rollup@2.75.6) 95 | commondir: 1.0.1 96 | estree-walker: 2.0.2 97 | glob: 7.2.3 98 | is-reference: 1.2.1 99 | magic-string: 0.25.9 100 | resolve: 1.22.0 101 | rollup: 2.75.6 102 | dev: true 103 | 104 | /@rollup/plugin-json@4.1.0(rollup@2.75.6): 105 | resolution: {integrity: sha512-yfLbTdNS6amI/2OpmbiBoW12vngr5NW2jCJVZSBEz+H5KfUJZ2M7sDjk0U6GOOdCWFVScShte29o9NezJ53TPw==} 106 | peerDependencies: 107 | rollup: ^1.20.0 || ^2.0.0 108 | dependencies: 109 | '@rollup/pluginutils': 3.1.0(rollup@2.75.6) 110 | rollup: 2.75.6 111 | dev: true 112 | 113 | /@rollup/plugin-node-resolve@13.3.0(rollup@2.75.6): 114 | resolution: {integrity: sha512-Lus8rbUo1eEcnS4yTFKLZrVumLPY+YayBdWXgFSHYhTT2iJbMhoaaBL3xl5NCdeRytErGr8tZ0L71BMRmnlwSw==} 115 | engines: {node: '>= 10.0.0'} 116 | peerDependencies: 117 | rollup: ^2.42.0 118 | dependencies: 119 | '@rollup/pluginutils': 3.1.0(rollup@2.75.6) 120 | '@types/resolve': 1.17.1 121 | deepmerge: 4.2.2 122 | is-builtin-module: 3.1.0 123 | is-module: 1.0.0 124 | resolve: 1.22.0 125 | rollup: 2.75.6 126 | dev: true 127 | 128 | /@rollup/plugin-replace@4.0.0(rollup@2.75.6): 129 | resolution: {integrity: sha512-+rumQFiaNac9y64OHtkHGmdjm7us9bo1PlbgQfdihQtuNxzjpaB064HbRnewUOggLQxVCCyINfStkgmBeQpv1g==} 130 | peerDependencies: 131 | rollup: ^1.20.0 || ^2.0.0 132 | dependencies: 133 | '@rollup/pluginutils': 3.1.0(rollup@2.75.6) 134 | magic-string: 0.25.9 135 | rollup: 2.75.6 136 | dev: true 137 | 138 | /@rollup/plugin-typescript@8.3.3(rollup@2.75.6)(tslib@2.4.0)(typescript@4.7.3): 139 | resolution: {integrity: sha512-55L9SyiYu3r/JtqdjhwcwaECXP7JeJ9h1Sg1VWRJKIutla2MdZQodTgcCNybXLMCnqpNLEhS2vGENww98L1npg==} 140 | engines: {node: '>=8.0.0'} 141 | peerDependencies: 142 | rollup: ^2.14.0 143 | tslib: '*' 144 | typescript: '>=3.7.0' 145 | peerDependenciesMeta: 146 | tslib: 147 | optional: true 148 | dependencies: 149 | '@rollup/pluginutils': 3.1.0(rollup@2.75.6) 150 | resolve: 1.22.0 151 | rollup: 2.75.6 152 | tslib: 2.4.0 153 | typescript: 4.7.3 154 | dev: true 155 | 156 | /@rollup/pluginutils@3.1.0(rollup@2.75.6): 157 | resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} 158 | engines: {node: '>= 8.0.0'} 159 | peerDependencies: 160 | rollup: ^1.20.0||^2.0.0 161 | dependencies: 162 | '@types/estree': 0.0.39 163 | estree-walker: 1.0.1 164 | picomatch: 2.3.1 165 | rollup: 2.75.6 166 | dev: true 167 | 168 | /@types/eslint-scope@3.7.3: 169 | resolution: {integrity: sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==} 170 | dependencies: 171 | '@types/eslint': 8.4.3 172 | '@types/estree': 0.0.51 173 | dev: true 174 | 175 | /@types/eslint@8.4.3: 176 | resolution: {integrity: sha512-YP1S7YJRMPs+7KZKDb9G63n8YejIwW9BALq7a5j2+H4yl6iOv9CB29edho+cuFRrvmJbbaH2yiVChKLJVysDGw==} 177 | dependencies: 178 | '@types/estree': 0.0.51 179 | '@types/json-schema': 7.0.11 180 | dev: true 181 | 182 | /@types/estree@0.0.39: 183 | resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} 184 | dev: true 185 | 186 | /@types/estree@0.0.51: 187 | resolution: {integrity: sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==} 188 | dev: true 189 | 190 | /@types/json-schema@7.0.11: 191 | resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} 192 | dev: true 193 | 194 | /@types/node@17.0.42: 195 | resolution: {integrity: sha512-Q5BPGyGKcvQgAMbsr7qEGN/kIPN6zZecYYABeTDBizOsau+2NMdSVTar9UQw21A2+JyA2KRNDYaYrPB0Rpk2oQ==} 196 | dev: true 197 | 198 | /@types/prop-types@15.7.5: 199 | resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} 200 | dev: true 201 | 202 | /@types/react@16.14.0: 203 | resolution: {integrity: sha512-jJjHo1uOe+NENRIBvF46tJimUvPnmbQ41Ax0pEm7pRvhPg+wuj8VMOHHiMvaGmZRzRrCtm7KnL5OOE/6kHPK8w==} 204 | dependencies: 205 | '@types/prop-types': 15.7.5 206 | csstype: 3.1.0 207 | dev: true 208 | 209 | /@types/resolve@1.17.1: 210 | resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} 211 | dependencies: 212 | '@types/node': 17.0.42 213 | dev: true 214 | 215 | /@types/webpack@5.28.0: 216 | resolution: {integrity: sha512-8cP0CzcxUiFuA9xGJkfeVpqmWTk9nx6CWwamRGCj95ph1SmlRRk9KlCZ6avhCbZd4L68LvYT6l1kpdEnQXrF8w==} 217 | dependencies: 218 | '@types/node': 17.0.42 219 | tapable: 2.2.1 220 | webpack: 5.73.0 221 | transitivePeerDependencies: 222 | - '@swc/core' 223 | - esbuild 224 | - uglify-js 225 | - webpack-cli 226 | dev: true 227 | 228 | /@webassemblyjs/ast@1.11.1: 229 | resolution: {integrity: sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==} 230 | dependencies: 231 | '@webassemblyjs/helper-numbers': 1.11.1 232 | '@webassemblyjs/helper-wasm-bytecode': 1.11.1 233 | dev: true 234 | 235 | /@webassemblyjs/floating-point-hex-parser@1.11.1: 236 | resolution: {integrity: sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==} 237 | dev: true 238 | 239 | /@webassemblyjs/helper-api-error@1.11.1: 240 | resolution: {integrity: sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==} 241 | dev: true 242 | 243 | /@webassemblyjs/helper-buffer@1.11.1: 244 | resolution: {integrity: sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==} 245 | dev: true 246 | 247 | /@webassemblyjs/helper-numbers@1.11.1: 248 | resolution: {integrity: sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==} 249 | dependencies: 250 | '@webassemblyjs/floating-point-hex-parser': 1.11.1 251 | '@webassemblyjs/helper-api-error': 1.11.1 252 | '@xtuc/long': 4.2.2 253 | dev: true 254 | 255 | /@webassemblyjs/helper-wasm-bytecode@1.11.1: 256 | resolution: {integrity: sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==} 257 | dev: true 258 | 259 | /@webassemblyjs/helper-wasm-section@1.11.1: 260 | resolution: {integrity: sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==} 261 | dependencies: 262 | '@webassemblyjs/ast': 1.11.1 263 | '@webassemblyjs/helper-buffer': 1.11.1 264 | '@webassemblyjs/helper-wasm-bytecode': 1.11.1 265 | '@webassemblyjs/wasm-gen': 1.11.1 266 | dev: true 267 | 268 | /@webassemblyjs/ieee754@1.11.1: 269 | resolution: {integrity: sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==} 270 | dependencies: 271 | '@xtuc/ieee754': 1.2.0 272 | dev: true 273 | 274 | /@webassemblyjs/leb128@1.11.1: 275 | resolution: {integrity: sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==} 276 | dependencies: 277 | '@xtuc/long': 4.2.2 278 | dev: true 279 | 280 | /@webassemblyjs/utf8@1.11.1: 281 | resolution: {integrity: sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==} 282 | dev: true 283 | 284 | /@webassemblyjs/wasm-edit@1.11.1: 285 | resolution: {integrity: sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==} 286 | dependencies: 287 | '@webassemblyjs/ast': 1.11.1 288 | '@webassemblyjs/helper-buffer': 1.11.1 289 | '@webassemblyjs/helper-wasm-bytecode': 1.11.1 290 | '@webassemblyjs/helper-wasm-section': 1.11.1 291 | '@webassemblyjs/wasm-gen': 1.11.1 292 | '@webassemblyjs/wasm-opt': 1.11.1 293 | '@webassemblyjs/wasm-parser': 1.11.1 294 | '@webassemblyjs/wast-printer': 1.11.1 295 | dev: true 296 | 297 | /@webassemblyjs/wasm-gen@1.11.1: 298 | resolution: {integrity: sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==} 299 | dependencies: 300 | '@webassemblyjs/ast': 1.11.1 301 | '@webassemblyjs/helper-wasm-bytecode': 1.11.1 302 | '@webassemblyjs/ieee754': 1.11.1 303 | '@webassemblyjs/leb128': 1.11.1 304 | '@webassemblyjs/utf8': 1.11.1 305 | dev: true 306 | 307 | /@webassemblyjs/wasm-opt@1.11.1: 308 | resolution: {integrity: sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==} 309 | dependencies: 310 | '@webassemblyjs/ast': 1.11.1 311 | '@webassemblyjs/helper-buffer': 1.11.1 312 | '@webassemblyjs/wasm-gen': 1.11.1 313 | '@webassemblyjs/wasm-parser': 1.11.1 314 | dev: true 315 | 316 | /@webassemblyjs/wasm-parser@1.11.1: 317 | resolution: {integrity: sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==} 318 | dependencies: 319 | '@webassemblyjs/ast': 1.11.1 320 | '@webassemblyjs/helper-api-error': 1.11.1 321 | '@webassemblyjs/helper-wasm-bytecode': 1.11.1 322 | '@webassemblyjs/ieee754': 1.11.1 323 | '@webassemblyjs/leb128': 1.11.1 324 | '@webassemblyjs/utf8': 1.11.1 325 | dev: true 326 | 327 | /@webassemblyjs/wast-printer@1.11.1: 328 | resolution: {integrity: sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==} 329 | dependencies: 330 | '@webassemblyjs/ast': 1.11.1 331 | '@xtuc/long': 4.2.2 332 | dev: true 333 | 334 | /@xtuc/ieee754@1.2.0: 335 | resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} 336 | dev: true 337 | 338 | /@xtuc/long@4.2.2: 339 | resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} 340 | dev: true 341 | 342 | /acorn-import-assertions@1.8.0(acorn@8.7.1): 343 | resolution: {integrity: sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==} 344 | peerDependencies: 345 | acorn: ^8 346 | dependencies: 347 | acorn: 8.7.1 348 | dev: true 349 | 350 | /acorn@8.7.1: 351 | resolution: {integrity: sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==} 352 | engines: {node: '>=0.4.0'} 353 | hasBin: true 354 | dev: true 355 | 356 | /ajv-keywords@3.5.2(ajv@6.12.6): 357 | resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} 358 | peerDependencies: 359 | ajv: ^6.9.1 360 | dependencies: 361 | ajv: 6.12.6 362 | dev: true 363 | 364 | /ajv@6.12.6: 365 | resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} 366 | dependencies: 367 | fast-deep-equal: 3.1.3 368 | fast-json-stable-stringify: 2.1.0 369 | json-schema-traverse: 0.4.1 370 | uri-js: 4.4.1 371 | dev: true 372 | 373 | /balanced-match@1.0.2: 374 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 375 | dev: true 376 | 377 | /brace-expansion@1.1.11: 378 | resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} 379 | dependencies: 380 | balanced-match: 1.0.2 381 | concat-map: 0.0.1 382 | dev: true 383 | 384 | /browserslist@4.20.4: 385 | resolution: {integrity: sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==} 386 | engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} 387 | hasBin: true 388 | dependencies: 389 | caniuse-lite: 1.0.30001352 390 | electron-to-chromium: 1.4.154 391 | escalade: 3.1.1 392 | node-releases: 2.0.5 393 | picocolors: 1.0.0 394 | dev: true 395 | 396 | /buffer-from@1.1.2: 397 | resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} 398 | dev: true 399 | 400 | /builtin-modules@3.3.0: 401 | resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} 402 | engines: {node: '>=6'} 403 | dev: true 404 | 405 | /caniuse-lite@1.0.30001352: 406 | resolution: {integrity: sha512-GUgH8w6YergqPQDGWhJGt8GDRnY0L/iJVQcU3eJ46GYf52R8tk0Wxp0PymuFVZboJYXGiCqwozAYZNRjVj6IcA==} 407 | dev: true 408 | 409 | /chrome-trace-event@1.0.3: 410 | resolution: {integrity: sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==} 411 | engines: {node: '>=6.0'} 412 | dev: true 413 | 414 | /commander@2.20.3: 415 | resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} 416 | dev: true 417 | 418 | /commondir@1.0.1: 419 | resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} 420 | dev: true 421 | 422 | /concat-map@0.0.1: 423 | resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} 424 | dev: true 425 | 426 | /csstype@3.1.0: 427 | resolution: {integrity: sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA==} 428 | dev: true 429 | 430 | /decky-frontend-lib@3.25.0: 431 | resolution: {integrity: sha512-2lBoHS2AIRmuluq/bGdHBz+uyToQE7k3K/vDq1MQbDZ4eC+8CGDuh2T8yZOj3D0yjGP2MdikNNAWPA9Z5l2qDg==} 432 | dev: false 433 | 434 | /deepmerge@4.2.2: 435 | resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} 436 | engines: {node: '>=0.10.0'} 437 | dev: true 438 | 439 | /electron-to-chromium@1.4.154: 440 | resolution: {integrity: sha512-GbV9djOkrnj6xmW+YYVVEI3VCQnJ0pnSTu7TW2JyjKd5cakoiSaG5R4RbEtfaD92GsY10DzbU3GYRe+IOA9kqA==} 441 | dev: true 442 | 443 | /enhanced-resolve@5.9.3: 444 | resolution: {integrity: sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow==} 445 | engines: {node: '>=10.13.0'} 446 | dependencies: 447 | graceful-fs: 4.2.10 448 | tapable: 2.2.1 449 | dev: true 450 | 451 | /es-module-lexer@0.9.3: 452 | resolution: {integrity: sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==} 453 | dev: true 454 | 455 | /escalade@3.1.1: 456 | resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} 457 | engines: {node: '>=6'} 458 | dev: true 459 | 460 | /eslint-scope@5.1.1: 461 | resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} 462 | engines: {node: '>=8.0.0'} 463 | dependencies: 464 | esrecurse: 4.3.0 465 | estraverse: 4.3.0 466 | dev: true 467 | 468 | /esrecurse@4.3.0: 469 | resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} 470 | engines: {node: '>=4.0'} 471 | dependencies: 472 | estraverse: 5.3.0 473 | dev: true 474 | 475 | /estraverse@4.3.0: 476 | resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} 477 | engines: {node: '>=4.0'} 478 | dev: true 479 | 480 | /estraverse@5.3.0: 481 | resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} 482 | engines: {node: '>=4.0'} 483 | dev: true 484 | 485 | /estree-walker@0.6.1: 486 | resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} 487 | dev: true 488 | 489 | /estree-walker@1.0.1: 490 | resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} 491 | dev: true 492 | 493 | /estree-walker@2.0.2: 494 | resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} 495 | dev: true 496 | 497 | /events@3.3.0: 498 | resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} 499 | engines: {node: '>=0.8.x'} 500 | dev: true 501 | 502 | /fast-deep-equal@3.1.3: 503 | resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} 504 | dev: true 505 | 506 | /fast-json-stable-stringify@2.1.0: 507 | resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} 508 | dev: true 509 | 510 | /fs.realpath@1.0.0: 511 | resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} 512 | dev: true 513 | 514 | /fsevents@2.3.3: 515 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 516 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 517 | os: [darwin] 518 | requiresBuild: true 519 | dev: true 520 | optional: true 521 | 522 | /function-bind@1.1.1: 523 | resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} 524 | dev: true 525 | 526 | /glob-to-regexp@0.4.1: 527 | resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} 528 | dev: true 529 | 530 | /glob@7.2.3: 531 | resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} 532 | dependencies: 533 | fs.realpath: 1.0.0 534 | inflight: 1.0.6 535 | inherits: 2.0.4 536 | minimatch: 3.1.2 537 | once: 1.4.0 538 | path-is-absolute: 1.0.1 539 | dev: true 540 | 541 | /graceful-fs@4.2.10: 542 | resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} 543 | dev: true 544 | 545 | /has-flag@4.0.0: 546 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 547 | engines: {node: '>=8'} 548 | dev: true 549 | 550 | /has@1.0.3: 551 | resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} 552 | engines: {node: '>= 0.4.0'} 553 | dependencies: 554 | function-bind: 1.1.1 555 | dev: true 556 | 557 | /inflight@1.0.6: 558 | resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} 559 | dependencies: 560 | once: 1.4.0 561 | wrappy: 1.0.2 562 | dev: true 563 | 564 | /inherits@2.0.4: 565 | resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} 566 | dev: true 567 | 568 | /interpret@1.4.0: 569 | resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} 570 | engines: {node: '>= 0.10'} 571 | dev: true 572 | 573 | /is-builtin-module@3.1.0: 574 | resolution: {integrity: sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==} 575 | engines: {node: '>=6'} 576 | dependencies: 577 | builtin-modules: 3.3.0 578 | dev: true 579 | 580 | /is-core-module@2.9.0: 581 | resolution: {integrity: sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==} 582 | dependencies: 583 | has: 1.0.3 584 | dev: true 585 | 586 | /is-module@1.0.0: 587 | resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} 588 | dev: true 589 | 590 | /is-reference@1.2.1: 591 | resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} 592 | dependencies: 593 | '@types/estree': 0.0.51 594 | dev: true 595 | 596 | /jest-worker@27.5.1: 597 | resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} 598 | engines: {node: '>= 10.13.0'} 599 | dependencies: 600 | '@types/node': 17.0.42 601 | merge-stream: 2.0.0 602 | supports-color: 8.1.1 603 | dev: true 604 | 605 | /json-parse-even-better-errors@2.3.1: 606 | resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} 607 | dev: true 608 | 609 | /json-schema-traverse@0.4.1: 610 | resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} 611 | dev: true 612 | 613 | /loader-runner@4.3.0: 614 | resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} 615 | engines: {node: '>=6.11.5'} 616 | dev: true 617 | 618 | /magic-string@0.25.9: 619 | resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} 620 | dependencies: 621 | sourcemap-codec: 1.4.8 622 | dev: true 623 | 624 | /merge-stream@2.0.0: 625 | resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} 626 | dev: true 627 | 628 | /mime-db@1.52.0: 629 | resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} 630 | engines: {node: '>= 0.6'} 631 | dev: true 632 | 633 | /mime-types@2.1.35: 634 | resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} 635 | engines: {node: '>= 0.6'} 636 | dependencies: 637 | mime-db: 1.52.0 638 | dev: true 639 | 640 | /minimatch@3.1.2: 641 | resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} 642 | dependencies: 643 | brace-expansion: 1.1.11 644 | dev: true 645 | 646 | /minimist@1.2.6: 647 | resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} 648 | dev: true 649 | 650 | /neo-async@2.6.2: 651 | resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} 652 | dev: true 653 | 654 | /node-releases@2.0.5: 655 | resolution: {integrity: sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q==} 656 | dev: true 657 | 658 | /once@1.4.0: 659 | resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} 660 | dependencies: 661 | wrappy: 1.0.2 662 | dev: true 663 | 664 | /path-is-absolute@1.0.1: 665 | resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} 666 | engines: {node: '>=0.10.0'} 667 | dev: true 668 | 669 | /path-parse@1.0.7: 670 | resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} 671 | dev: true 672 | 673 | /picocolors@1.0.0: 674 | resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} 675 | dev: true 676 | 677 | /picomatch@2.3.1: 678 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 679 | engines: {node: '>=8.6'} 680 | dev: true 681 | 682 | /punycode@2.1.1: 683 | resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} 684 | engines: {node: '>=6'} 685 | dev: true 686 | 687 | /randombytes@2.1.0: 688 | resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} 689 | dependencies: 690 | safe-buffer: 5.2.1 691 | dev: true 692 | 693 | /react-icons@4.4.0: 694 | resolution: {integrity: sha512-fSbvHeVYo/B5/L4VhB7sBA1i2tS8MkT0Hb9t2H1AVPkwGfVHLJCqyr2Py9dKMxsyM63Eng1GkdZfbWj+Fmv8Rg==} 695 | peerDependencies: 696 | react: '*' 697 | peerDependenciesMeta: 698 | react: 699 | optional: true 700 | dev: false 701 | 702 | /rechoir@0.6.2: 703 | resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} 704 | engines: {node: '>= 0.10'} 705 | dependencies: 706 | resolve: 1.22.0 707 | dev: true 708 | 709 | /resolve@1.22.0: 710 | resolution: {integrity: sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==} 711 | hasBin: true 712 | dependencies: 713 | is-core-module: 2.9.0 714 | path-parse: 1.0.7 715 | supports-preserve-symlinks-flag: 1.0.0 716 | dev: true 717 | 718 | /rollup-plugin-import-assets@1.1.1(rollup@2.75.6): 719 | resolution: {integrity: sha512-u5zJwOjguTf2N+wETq2weNKGvNkuVc1UX/fPgg215p5xPvGOaI6/BTc024E9brvFjSQTfIYqgvwogQdipknu1g==} 720 | peerDependencies: 721 | rollup: '>=1.9.0' 722 | dependencies: 723 | rollup: 2.75.6 724 | rollup-pluginutils: 2.8.2 725 | url-join: 4.0.1 726 | dev: true 727 | 728 | /rollup-pluginutils@2.8.2: 729 | resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} 730 | dependencies: 731 | estree-walker: 0.6.1 732 | dev: true 733 | 734 | /rollup@2.75.6: 735 | resolution: {integrity: sha512-OEf0TgpC9vU6WGROJIk1JA3LR5vk/yvqlzxqdrE2CzzXnqKXNzbAwlWUXis8RS3ZPe7LAq+YUxsRa0l3r27MLA==} 736 | engines: {node: '>=10.0.0'} 737 | hasBin: true 738 | optionalDependencies: 739 | fsevents: 2.3.3 740 | dev: true 741 | 742 | /safe-buffer@5.2.1: 743 | resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} 744 | dev: true 745 | 746 | /schema-utils@3.1.1: 747 | resolution: {integrity: sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==} 748 | engines: {node: '>= 10.13.0'} 749 | dependencies: 750 | '@types/json-schema': 7.0.11 751 | ajv: 6.12.6 752 | ajv-keywords: 3.5.2(ajv@6.12.6) 753 | dev: true 754 | 755 | /serialize-javascript@6.0.0: 756 | resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} 757 | dependencies: 758 | randombytes: 2.1.0 759 | dev: true 760 | 761 | /shelljs@0.8.5: 762 | resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} 763 | engines: {node: '>=4'} 764 | hasBin: true 765 | dependencies: 766 | glob: 7.2.3 767 | interpret: 1.4.0 768 | rechoir: 0.6.2 769 | dev: true 770 | 771 | /shx@0.3.4: 772 | resolution: {integrity: sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==} 773 | engines: {node: '>=6'} 774 | hasBin: true 775 | dependencies: 776 | minimist: 1.2.6 777 | shelljs: 0.8.5 778 | dev: true 779 | 780 | /source-map-support@0.5.21: 781 | resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} 782 | dependencies: 783 | buffer-from: 1.1.2 784 | source-map: 0.6.1 785 | dev: true 786 | 787 | /source-map@0.6.1: 788 | resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} 789 | engines: {node: '>=0.10.0'} 790 | dev: true 791 | 792 | /sourcemap-codec@1.4.8: 793 | resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} 794 | dev: true 795 | 796 | /supports-color@8.1.1: 797 | resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} 798 | engines: {node: '>=10'} 799 | dependencies: 800 | has-flag: 4.0.0 801 | dev: true 802 | 803 | /supports-preserve-symlinks-flag@1.0.0: 804 | resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} 805 | engines: {node: '>= 0.4'} 806 | dev: true 807 | 808 | /tapable@2.2.1: 809 | resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} 810 | engines: {node: '>=6'} 811 | dev: true 812 | 813 | /terser-webpack-plugin@5.3.3(webpack@5.73.0): 814 | resolution: {integrity: sha512-Fx60G5HNYknNTNQnzQ1VePRuu89ZVYWfjRAeT5rITuCY/1b08s49e5kSQwHDirKZWuoKOBRFS98EUUoZ9kLEwQ==} 815 | engines: {node: '>= 10.13.0'} 816 | peerDependencies: 817 | '@swc/core': '*' 818 | esbuild: '*' 819 | uglify-js: '*' 820 | webpack: ^5.1.0 821 | peerDependenciesMeta: 822 | '@swc/core': 823 | optional: true 824 | esbuild: 825 | optional: true 826 | uglify-js: 827 | optional: true 828 | dependencies: 829 | '@jridgewell/trace-mapping': 0.3.13 830 | jest-worker: 27.5.1 831 | schema-utils: 3.1.1 832 | serialize-javascript: 6.0.0 833 | terser: 5.14.1 834 | webpack: 5.73.0 835 | dev: true 836 | 837 | /terser@5.14.1: 838 | resolution: {integrity: sha512-+ahUAE+iheqBTDxXhTisdA8hgvbEG1hHOQ9xmNjeUJSoi6DU/gMrKNcfZjHkyY6Alnuyc+ikYJaxxfHkT3+WuQ==} 839 | engines: {node: '>=10'} 840 | hasBin: true 841 | dependencies: 842 | '@jridgewell/source-map': 0.3.2 843 | acorn: 8.7.1 844 | commander: 2.20.3 845 | source-map-support: 0.5.21 846 | dev: true 847 | 848 | /tslib@2.4.0: 849 | resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} 850 | dev: true 851 | 852 | /typescript@4.7.3: 853 | resolution: {integrity: sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==} 854 | engines: {node: '>=4.2.0'} 855 | hasBin: true 856 | dev: true 857 | 858 | /uri-js@4.4.1: 859 | resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} 860 | dependencies: 861 | punycode: 2.1.1 862 | dev: true 863 | 864 | /url-join@4.0.1: 865 | resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} 866 | dev: true 867 | 868 | /watchpack@2.4.0: 869 | resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} 870 | engines: {node: '>=10.13.0'} 871 | dependencies: 872 | glob-to-regexp: 0.4.1 873 | graceful-fs: 4.2.10 874 | dev: true 875 | 876 | /webpack-sources@3.2.3: 877 | resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} 878 | engines: {node: '>=10.13.0'} 879 | dev: true 880 | 881 | /webpack@5.73.0: 882 | resolution: {integrity: sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA==} 883 | engines: {node: '>=10.13.0'} 884 | hasBin: true 885 | peerDependencies: 886 | webpack-cli: '*' 887 | peerDependenciesMeta: 888 | webpack-cli: 889 | optional: true 890 | dependencies: 891 | '@types/eslint-scope': 3.7.3 892 | '@types/estree': 0.0.51 893 | '@webassemblyjs/ast': 1.11.1 894 | '@webassemblyjs/wasm-edit': 1.11.1 895 | '@webassemblyjs/wasm-parser': 1.11.1 896 | acorn: 8.7.1 897 | acorn-import-assertions: 1.8.0(acorn@8.7.1) 898 | browserslist: 4.20.4 899 | chrome-trace-event: 1.0.3 900 | enhanced-resolve: 5.9.3 901 | es-module-lexer: 0.9.3 902 | eslint-scope: 5.1.1 903 | events: 3.3.0 904 | glob-to-regexp: 0.4.1 905 | graceful-fs: 4.2.10 906 | json-parse-even-better-errors: 2.3.1 907 | loader-runner: 4.3.0 908 | mime-types: 2.1.35 909 | neo-async: 2.6.2 910 | schema-utils: 3.1.1 911 | tapable: 2.2.1 912 | terser-webpack-plugin: 5.3.3(webpack@5.73.0) 913 | watchpack: 2.4.0 914 | webpack-sources: 3.2.3 915 | transitivePeerDependencies: 916 | - '@swc/core' 917 | - esbuild 918 | - uglify-js 919 | dev: true 920 | 921 | /wrappy@1.0.2: 922 | resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} 923 | dev: true 924 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import commonjs from '@rollup/plugin-commonjs'; 2 | import json from '@rollup/plugin-json'; 3 | import { nodeResolve } from '@rollup/plugin-node-resolve'; 4 | import replace from '@rollup/plugin-replace'; 5 | import typescript from '@rollup/plugin-typescript'; 6 | import { defineConfig } from 'rollup'; 7 | import importAssets from 'rollup-plugin-import-assets'; 8 | 9 | import { name } from "./plugin.json"; 10 | 11 | export default defineConfig({ 12 | input: './src/index.tsx', 13 | plugins: [ 14 | commonjs(), 15 | nodeResolve(), 16 | typescript(), 17 | json(), 18 | replace({ 19 | preventAssignment: false, 20 | 'process.env.NODE_ENV': JSON.stringify('production'), 21 | }), 22 | importAssets({ 23 | publicPath: `http://127.0.0.1:1337/plugins/${name}/` 24 | }) 25 | ], 26 | context: 'window', 27 | external: ['react', 'react-dom', 'decky-frontend-lib'], 28 | output: { 29 | file: 'dist/index.js', 30 | globals: { 31 | react: 'SP_REACT', 32 | 'react-dom': 'SP_REACTDOM', 33 | 'decky-frontend-lib': 'DFL', 34 | }, 35 | format: 'iife', 36 | exports: 'default', 37 | }, 38 | }); 39 | -------------------------------------------------------------------------------- /src/backend.ts: -------------------------------------------------------------------------------- 1 | import { ServerAPI } from "decky-frontend-lib" 2 | 3 | var server: ServerAPI | undefined = undefined; 4 | 5 | export function resolvePromise(promise: Promise, callback: any) { 6 | (async function () { 7 | let data = await promise; 8 | if (data.success) 9 | callback(data.result); 10 | })(); 11 | } 12 | 13 | export function callBackendFunction(promise: Promise) { 14 | (async function () { 15 | await promise; 16 | })(); 17 | } 18 | 19 | export function setServer(s: ServerAPI) { 20 | server = s; 21 | } 22 | 23 | 24 | export function setSSHServerState(state: boolean) : Promise { 25 | return server!.callPluginMethod("set_ssh_server_state", { "state": state }); 26 | } 27 | 28 | export function getSSHServerState(): Promise { 29 | return server!.callPluginMethod("get_ssh_server_state", {}); 30 | } 31 | 32 | 33 | export function setCEFServerState(state: boolean) : Promise { 34 | return server!.callPluginMethod("set_cef_debugger_forwarder_state", { "state": state }); 35 | } 36 | 37 | export function getCEFServerState(): Promise { 38 | return server!.callPluginMethod("get_cef_debugger_forwarder_state", {}); 39 | } 40 | 41 | 42 | export function setHugePagesState(state: boolean) : Promise { 43 | return server!.callPluginMethod("set_huge_pages_state", { "state": state }); 44 | } 45 | 46 | export function getHugePagesState(): Promise { 47 | return server!.callPluginMethod("get_huge_pages_state", {}); 48 | } -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | definePlugin, 3 | PanelSection, 4 | PanelSectionRow, 5 | ServerAPI, 6 | staticClasses, 7 | ToggleField, 8 | } from "decky-frontend-lib"; 9 | import { VFC, useState } from "react"; 10 | import { FaToolbox } from "react-icons/fa"; 11 | 12 | import * as backend from "./backend" 13 | import {networkInterfaces} from 'os'; 14 | 15 | const Content: VFC<{ server: ServerAPI }> = ({server}) => { 16 | backend.setServer(server); 17 | 18 | const [sshServerToggleValue, setSshServerToggleState] = useState(false); 19 | const [cefServerToggleValue, setCefServerToggleState] = useState(false); 20 | const [largePagesToggleValue, setLargePagesToggleState] = useState(false); 21 | 22 | backend.resolvePromise(backend.getSSHServerState(), setSshServerToggleState); 23 | backend.resolvePromise(backend.getCEFServerState(), setCefServerToggleState); 24 | backend.resolvePromise(backend.getHugePagesState(), setLargePagesToggleState); 25 | 26 | return ( 27 | 28 | 29 | 30 | { 35 | backend.setSSHServerState(value); 36 | setSshServerToggleState(value); 37 | }} 38 | /> 39 | 40 | 41 | 42 | { 47 | backend.setCEFServerState(value); 48 | setCefServerToggleState(value); 49 | }} 50 | /> 51 | 52 | 53 | 54 | 55 | { 60 | backend.setHugePagesState(value); 61 | setLargePagesToggleState(value); 62 | }} 63 | /> 64 | 65 | 66 | 67 | ); 68 | }; 69 | 70 | function localIpAddress () { 71 | const interfaces = Object.values(networkInterfaces()) 72 | for (let iface of interfaces) { 73 | for (let alias of iface!) { 74 | if (alias.family === "IPv4" 75 | && alias.address !== "127.0.0.1" 76 | && !alias.internal) { 77 | return alias.address 78 | } 79 | } 80 | } 81 | 82 | return "0.0.0.0" 83 | } 84 | 85 | export default definePlugin((serverApi: ServerAPI) => { 86 | return { 87 | title:
Example Plugin
, 88 | content: , 89 | icon: , 90 | onDismount() { 91 | 92 | }, 93 | }; 94 | }); 95 | -------------------------------------------------------------------------------- /src/types.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.svg" { 2 | const content: string; 3 | export default content; 4 | } 5 | 6 | declare module "*.png" { 7 | const content: string; 8 | export default content; 9 | } 10 | 11 | declare module "*.jpg" { 12 | const content: string; 13 | export default content; 14 | } 15 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "dist", 4 | "module": "ESNext", 5 | "target": "ES2020", 6 | "jsx": "react", 7 | "jsxFactory": "window.SP_REACT.createElement", 8 | "declaration": false, 9 | "moduleResolution": "node", 10 | "noUnusedLocals": true, 11 | "noUnusedParameters": true, 12 | "esModuleInterop": true, 13 | "noImplicitReturns": true, 14 | "noImplicitThis": true, 15 | "noImplicitAny": true, 16 | "strict": true, 17 | "suppressImplicitAnyIndexErrors": true, 18 | "allowSyntheticDefaultImports": true, 19 | "skipLibCheck": true 20 | }, 21 | "include": ["src"], 22 | "exclude": ["node_modules"] 23 | } 24 | --------------------------------------------------------------------------------