From 5b14eebc79d1e53e65eec51b97e647ef1d5037ff Mon Sep 17 00:00:00 2001 From: tcorzo Date: Wed, 30 Oct 2024 22:36:22 +0000 Subject: [PATCH 1/8] =?UTF-8?q?=E2=9C=A8=20Show=20current=20register=20in?= =?UTF-8?q?=20the=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- src/components/Emulator.vue | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 19b049c..d74eb32 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,9 @@ a template for your own programs. ## Roadmap - [x] Implement basic functionality -- [ ] Add breakpoints +- [x] Add breakpoints - [ ] Show errors in the UI - [ ] Separate Data registers from Instruction registers - [ ] Export program to CSV -- [ ] Indicate current register in the UI +- [x] Indicate current register in the UI - [ ] Flash register when it changes diff --git a/src/components/Emulator.vue b/src/components/Emulator.vue index 5c411bd..e5add67 100644 --- a/src/components/Emulator.vue +++ b/src/components/Emulator.vue @@ -19,7 +19,8 @@ const registers = Array.from(globalState.emulator.registers.values()); - + {{ register.address }} @@ -51,3 +52,11 @@ const registers = Array.from(globalState.emulator.registers.values()); + + From 3cd7e1a9afd23b8c30e608c2da302c8fa01beb70 Mon Sep 17 00:00:00 2001 From: tcorzo Date: Thu, 31 Oct 2024 02:45:07 +0000 Subject: [PATCH 2/8] =?UTF-8?q?=E2=9C=A8=20UI=20improvements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.vue | 42 ++----- src/components/Editor.vue | 38 +++++++ src/components/Emulator.vue | 107 +++++++++++------- .../{AuxTable.vue => editor/EditAuxTable.vue} | 4 +- .../EditOperationsTable.vue} | 11 +- .../EditProgramTable.vue} | 4 +- src/components/emulator/AuxRegisters.vue | 50 ++++++++ src/components/emulator/DataRegisters.vue | 50 ++++++++ src/components/emulator/ProgramRegisters.vue | 50 ++++++++ src/style.css | 4 +- 10 files changed, 273 insertions(+), 87 deletions(-) create mode 100644 src/components/Editor.vue rename src/components/{AuxTable.vue => editor/EditAuxTable.vue} (94%) rename src/components/{OperationsTable.vue => editor/EditOperationsTable.vue} (61%) rename src/components/{ProgramTable.vue => editor/EditProgramTable.vue} (95%) create mode 100644 src/components/emulator/AuxRegisters.vue create mode 100644 src/components/emulator/DataRegisters.vue create mode 100644 src/components/emulator/ProgramRegisters.vue diff --git a/src/App.vue b/src/App.vue index 8da9d85..6da82e4 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,38 +1,22 @@ @@ -41,12 +25,6 @@ provide('globalState', globalState); padding: 20px; } -#editor { - display: flex; - flex-direction: row; - align-items: top; -} - .mode-toggle { margin-bottom: 20px; padding: 10px 20px; @@ -62,7 +40,9 @@ provide('globalState', globalState); margin-bottom: 20px; } -.aux-table, .operations-table, .program-table { +.aux-table, +.operations-table, +.program-table { flex: 1; margin: 0 10px; } @@ -71,7 +51,9 @@ table { width: 100%; border-collapse: collapse; } -th, td { + +th, +td { border: 1px solid black; padding: 8px; text-align: center; diff --git a/src/components/Editor.vue b/src/components/Editor.vue new file mode 100644 index 0000000..3bdaaff --- /dev/null +++ b/src/components/Editor.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/src/components/Emulator.vue b/src/components/Emulator.vue index e5add67..79ea0b3 100644 --- a/src/components/Emulator.vue +++ b/src/components/Emulator.vue @@ -1,62 +1,83 @@ diff --git a/src/components/AuxTable.vue b/src/components/editor/EditAuxTable.vue similarity index 94% rename from src/components/AuxTable.vue rename to src/components/editor/EditAuxTable.vue index 267af4b..45a9148 100644 --- a/src/components/AuxTable.vue +++ b/src/components/editor/EditAuxTable.vue @@ -1,8 +1,8 @@ @@ -17,13 +17,8 @@ const globalState: GlobalState = inject('globalState') || {} as GlobalState; - - - {{ operation.code }} - - - {{ operation.operation_type.name }} - + + {{ operation.operation_type.name }} diff --git a/src/components/ProgramTable.vue b/src/components/editor/EditProgramTable.vue similarity index 95% rename from src/components/ProgramTable.vue rename to src/components/editor/EditProgramTable.vue index 843d2f2..d8b5810 100644 --- a/src/components/ProgramTable.vue +++ b/src/components/editor/EditProgramTable.vue @@ -1,8 +1,8 @@ + + + + diff --git a/src/components/emulator/DataRegisters.vue b/src/components/emulator/DataRegisters.vue new file mode 100644 index 0000000..27536c9 --- /dev/null +++ b/src/components/emulator/DataRegisters.vue @@ -0,0 +1,50 @@ + + + + + diff --git a/src/components/emulator/ProgramRegisters.vue b/src/components/emulator/ProgramRegisters.vue new file mode 100644 index 0000000..6d98fff --- /dev/null +++ b/src/components/emulator/ProgramRegisters.vue @@ -0,0 +1,50 @@ + + + + + diff --git a/src/style.css b/src/style.css index bb131d6..e54dcda 100644 --- a/src/style.css +++ b/src/style.css @@ -47,7 +47,7 @@ button { transition: border-color 0.25s; } button:hover { - border-color: #646cff; + border-color: chocolate; } button:focus, button:focus-visible { @@ -74,6 +74,6 @@ button:focus-visible { color: #747bff; } button { - background-color: #f9f9f9; + background-color: #e6e6e6; } } From 062998222438f6818a7d9c567f7348267516141b Mon Sep 17 00:00:00 2001 From: tcorzo Date: Sat, 2 Nov 2024 21:11:03 +0000 Subject: [PATCH 3/8] =?UTF-8?q?=E2=9C=A8=20Refactor=20Abacus=20Emulator=20?= =?UTF-8?q?and=20enhance=20error=20handling=20-=20Updated=20deno.json=20to?= =?UTF-8?q?=20use=20imports=20-=20Modified=20package.json=20for=20better?= =?UTF-8?q?=20formatting=20-=20Added=20Error.vue=20component=20for=20displ?= =?UTF-8?q?aying=20emulator=20errors=20-=20Enhanced=20Program=20and=20Regi?= =?UTF-8?q?ster=20classes=20with=20cloning=20methods=20-=20Moved=20AbacusE?= =?UTF-8?q?mulator=20instance=20from=20globalState=20to=20Emulator=20compo?= =?UTF-8?q?nent=20-=20Implemented=20error=20handling=20for=20unknown=20add?= =?UTF-8?q?resses=20and=20timeouts=20in=20AbacusEmulator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deno.json | 4 +- deno.lock | 674 ++++++++++++++++++- package.json | 5 +- src/abacus/abacus.ts | 42 +- src/abacus/importer.ts | 10 +- src/abacus/program.ts | 25 +- src/components/Emulator.vue | 19 +- src/components/emulator/AuxRegisters.vue | 6 +- src/components/emulator/DataRegisters.vue | 6 +- src/components/emulator/Error.vue | 23 + src/components/emulator/ProgramRegisters.vue | 6 +- src/state.ts | 58 +- 12 files changed, 829 insertions(+), 49 deletions(-) create mode 100644 src/components/emulator/Error.vue diff --git a/deno.json b/deno.json index 12a7930..516b961 100644 --- a/deno.json +++ b/deno.json @@ -1,3 +1,5 @@ { - "importMap": "./import_map.json" + "imports": { + "@/": "./src/" + } } diff --git a/deno.lock b/deno.lock index e15b7cf..04a4bc3 100644 --- a/deno.lock +++ b/deno.lock @@ -4,7 +4,13 @@ "jsr:@std/assert@*": "1.0.6", "jsr:@std/assert@^1.0.6": "1.0.6", "jsr:@std/expect@*": "1.0.5", - "jsr:@std/internal@^1.0.4": "1.0.4" + "jsr:@std/internal@^1.0.4": "1.0.4", + "npm:@vitejs/plugin-vue@^5.1.4": "5.1.4_vite@5.4.9_vue@3.5.12__typescript@5.6.3_typescript@5.6.3", + "npm:gh-pages@^6.2.0": "6.2.0", + "npm:typescript@^5.5.3": "5.6.3", + "npm:vite@^5.4.8": "5.4.9", + "npm:vue-tsc@^2.1.6": "2.1.6_typescript@5.6.3", + "npm:vue@^3.5.10": "3.5.12_typescript@5.6.3" }, "jsr": { "@std/assert@1.0.6": { @@ -24,6 +30,672 @@ "integrity": "62e8e4911527e5e4f307741a795c0b0a9e6958d0b3790716ae71ce085f755422" } }, + "npm": { + "@babel/helper-string-parser@7.25.7": { + "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==" + }, + "@babel/helper-validator-identifier@7.25.7": { + "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==" + }, + "@babel/parser@7.25.8": { + "integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==", + "dependencies": [ + "@babel/types" + ] + }, + "@babel/types@7.25.8": { + "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==", + "dependencies": [ + "@babel/helper-string-parser", + "@babel/helper-validator-identifier", + "to-fast-properties" + ] + }, + "@esbuild/aix-ppc64@0.21.5": { + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==" + }, + "@esbuild/android-arm64@0.21.5": { + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==" + }, + "@esbuild/android-arm@0.21.5": { + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==" + }, + "@esbuild/android-x64@0.21.5": { + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==" + }, + "@esbuild/darwin-arm64@0.21.5": { + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==" + }, + "@esbuild/darwin-x64@0.21.5": { + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==" + }, + "@esbuild/freebsd-arm64@0.21.5": { + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==" + }, + "@esbuild/freebsd-x64@0.21.5": { + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==" + }, + "@esbuild/linux-arm64@0.21.5": { + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==" + }, + "@esbuild/linux-arm@0.21.5": { + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==" + }, + "@esbuild/linux-ia32@0.21.5": { + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==" + }, + "@esbuild/linux-loong64@0.21.5": { + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==" + }, + "@esbuild/linux-mips64el@0.21.5": { + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==" + }, + "@esbuild/linux-ppc64@0.21.5": { + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==" + }, + "@esbuild/linux-riscv64@0.21.5": { + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==" + }, + "@esbuild/linux-s390x@0.21.5": { + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==" + }, + "@esbuild/linux-x64@0.21.5": { + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==" + }, + "@esbuild/netbsd-x64@0.21.5": { + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==" + }, + "@esbuild/openbsd-x64@0.21.5": { + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==" + }, + "@esbuild/sunos-x64@0.21.5": { + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==" + }, + "@esbuild/win32-arm64@0.21.5": { + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==" + }, + "@esbuild/win32-ia32@0.21.5": { + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==" + }, + "@esbuild/win32-x64@0.21.5": { + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==" + }, + "@jridgewell/sourcemap-codec@1.5.0": { + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "@nodelib/fs.scandir@2.1.5": { + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": [ + "@nodelib/fs.stat", + "run-parallel" + ] + }, + "@nodelib/fs.stat@2.0.5": { + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" + }, + "@nodelib/fs.walk@1.2.8": { + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": [ + "@nodelib/fs.scandir", + "fastq" + ] + }, + "@rollup/rollup-android-arm-eabi@4.24.0": { + "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==" + }, + "@rollup/rollup-android-arm64@4.24.0": { + "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==" + }, + "@rollup/rollup-darwin-arm64@4.24.0": { + "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==" + }, + "@rollup/rollup-darwin-x64@4.24.0": { + "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==" + }, + "@rollup/rollup-linux-arm-gnueabihf@4.24.0": { + "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==" + }, + "@rollup/rollup-linux-arm-musleabihf@4.24.0": { + "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==" + }, + "@rollup/rollup-linux-arm64-gnu@4.24.0": { + "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==" + }, + "@rollup/rollup-linux-arm64-musl@4.24.0": { + "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==" + }, + "@rollup/rollup-linux-powerpc64le-gnu@4.24.0": { + "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==" + }, + "@rollup/rollup-linux-riscv64-gnu@4.24.0": { + "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==" + }, + "@rollup/rollup-linux-s390x-gnu@4.24.0": { + "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==" + }, + "@rollup/rollup-linux-x64-gnu@4.24.0": { + "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==" + }, + "@rollup/rollup-linux-x64-musl@4.24.0": { + "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==" + }, + "@rollup/rollup-win32-arm64-msvc@4.24.0": { + "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==" + }, + "@rollup/rollup-win32-ia32-msvc@4.24.0": { + "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==" + }, + "@rollup/rollup-win32-x64-msvc@4.24.0": { + "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==" + }, + "@types/estree@1.0.6": { + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" + }, + "@vitejs/plugin-vue@5.1.4_vite@5.4.9_vue@3.5.12__typescript@5.6.3_typescript@5.6.3": { + "integrity": "sha512-N2XSI2n3sQqp5w7Y/AN/L2XDjBIRGqXko+eDp42sydYSBeJuSm5a1sLf8zakmo8u7tA8NmBgoDLA1HeOESjp9A==", + "dependencies": [ + "vite", + "vue" + ] + }, + "@volar/language-core@2.4.6": { + "integrity": "sha512-FxUfxaB8sCqvY46YjyAAV6c3mMIq/NWQMVvJ+uS4yxr1KzOvyg61gAuOnNvgCvO4TZ7HcLExBEsWcDu4+K4E8A==", + "dependencies": [ + "@volar/source-map" + ] + }, + "@volar/source-map@2.4.6": { + "integrity": "sha512-Nsh7UW2ruK+uURIPzjJgF0YRGP5CX9nQHypA2OMqdM2FKy7rh+uv3XgPnWPw30JADbKvZ5HuBzG4gSbVDYVtiw==" + }, + "@volar/typescript@2.4.6": { + "integrity": "sha512-NMIrA7y5OOqddL9VtngPWYmdQU03htNKFtAYidbYfWA0TOhyGVd9tfcP4TsLWQ+RBWDZCbBqsr8xzU0ZOxYTCQ==", + "dependencies": [ + "@volar/language-core", + "path-browserify", + "vscode-uri" + ] + }, + "@vue/compiler-core@3.5.12": { + "integrity": "sha512-ISyBTRMmMYagUxhcpyEH0hpXRd/KqDU4ymofPgl2XAkY9ZhQ+h0ovEZJIiPop13UmR/54oA2cgMDjgroRelaEw==", + "dependencies": [ + "@babel/parser", + "@vue/shared", + "entities", + "estree-walker", + "source-map-js" + ] + }, + "@vue/compiler-dom@3.5.12": { + "integrity": "sha512-9G6PbJ03uwxLHKQ3P42cMTi85lDRvGLB2rSGOiQqtXELat6uI4n8cNz9yjfVHRPIu+MsK6TE418Giruvgptckg==", + "dependencies": [ + "@vue/compiler-core", + "@vue/shared" + ] + }, + "@vue/compiler-sfc@3.5.12": { + "integrity": "sha512-2k973OGo2JuAa5+ZlekuQJtitI5CgLMOwgl94BzMCsKZCX/xiqzJYzapl4opFogKHqwJk34vfsaKpfEhd1k5nw==", + "dependencies": [ + "@babel/parser", + "@vue/compiler-core", + "@vue/compiler-dom", + "@vue/compiler-ssr", + "@vue/shared", + "estree-walker", + "magic-string", + "postcss", + "source-map-js" + ] + }, + "@vue/compiler-ssr@3.5.12": { + "integrity": "sha512-eLwc7v6bfGBSM7wZOGPmRavSWzNFF6+PdRhE+VFJhNCgHiF8AM7ccoqcv5kBXA2eWUfigD7byekvf/JsOfKvPA==", + "dependencies": [ + "@vue/compiler-dom", + "@vue/shared" + ] + }, + "@vue/compiler-vue2@2.7.16": { + "integrity": "sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==", + "dependencies": [ + "de-indent", + "he" + ] + }, + "@vue/language-core@2.1.6_typescript@5.6.3": { + "integrity": "sha512-MW569cSky9R/ooKMh6xa2g1D0AtRKbL56k83dzus/bx//RDJk24RHWkMzbAlXjMdDNyxAaagKPRquBIxkxlCkg==", + "dependencies": [ + "@volar/language-core", + "@vue/compiler-dom", + "@vue/compiler-vue2", + "@vue/shared", + "computeds", + "minimatch", + "muggle-string", + "path-browserify", + "typescript" + ] + }, + "@vue/reactivity@3.5.12": { + "integrity": "sha512-UzaN3Da7xnJXdz4Okb/BGbAaomRHc3RdoWqTzlvd9+WBR5m3J39J1fGcHes7U3za0ruYn/iYy/a1euhMEHvTAg==", + "dependencies": [ + "@vue/shared" + ] + }, + "@vue/runtime-core@3.5.12": { + "integrity": "sha512-hrMUYV6tpocr3TL3Ad8DqxOdpDe4zuQY4HPY3X/VRh+L2myQO8MFXPAMarIOSGNu0bFAjh1yBkMPXZBqCk62Uw==", + "dependencies": [ + "@vue/reactivity", + "@vue/shared" + ] + }, + "@vue/runtime-dom@3.5.12": { + "integrity": "sha512-q8VFxR9A2MRfBr6/55Q3umyoN7ya836FzRXajPB6/Vvuv0zOPL+qltd9rIMzG/DbRLAIlREmnLsplEF/kotXKA==", + "dependencies": [ + "@vue/reactivity", + "@vue/runtime-core", + "@vue/shared", + "csstype" + ] + }, + "@vue/server-renderer@3.5.12_vue@3.5.12__typescript@5.6.3": { + "integrity": "sha512-I3QoeDDeEPZm8yR28JtY+rk880Oqmj43hreIBVTicisFTx/Dl7JpG72g/X7YF8hnQD3IFhkky5i2bPonwrTVPg==", + "dependencies": [ + "@vue/compiler-ssr", + "@vue/shared", + "vue" + ] + }, + "@vue/shared@3.5.12": { + "integrity": "sha512-L2RPSAwUFbgZH20etwrXyVyCBu9OxRSi8T/38QsvnkJyvq2LufW2lDCOzm7t/U9C1mkhJGWYfCuFBCmIuNivrg==" + }, + "array-union@2.1.0": { + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + }, + "async@3.2.6": { + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==" + }, + "balanced-match@1.0.2": { + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" + }, + "brace-expansion@2.0.1": { + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": [ + "balanced-match" + ] + }, + "braces@3.0.3": { + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dependencies": [ + "fill-range" + ] + }, + "commander@11.1.0": { + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==" + }, + "commondir@1.0.1": { + "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==" + }, + "computeds@0.0.1": { + "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==" + }, + "csstype@3.1.3": { + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "de-indent@1.0.2": { + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==" + }, + "dir-glob@3.0.1": { + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dependencies": [ + "path-type" + ] + }, + "email-addresses@5.0.0": { + "integrity": "sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw==" + }, + "entities@4.5.0": { + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" + }, + "esbuild@0.21.5": { + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dependencies": [ + "@esbuild/aix-ppc64", + "@esbuild/android-arm", + "@esbuild/android-arm64", + "@esbuild/android-x64", + "@esbuild/darwin-arm64", + "@esbuild/darwin-x64", + "@esbuild/freebsd-arm64", + "@esbuild/freebsd-x64", + "@esbuild/linux-arm", + "@esbuild/linux-arm64", + "@esbuild/linux-ia32", + "@esbuild/linux-loong64", + "@esbuild/linux-mips64el", + "@esbuild/linux-ppc64", + "@esbuild/linux-riscv64", + "@esbuild/linux-s390x", + "@esbuild/linux-x64", + "@esbuild/netbsd-x64", + "@esbuild/openbsd-x64", + "@esbuild/sunos-x64", + "@esbuild/win32-arm64", + "@esbuild/win32-ia32", + "@esbuild/win32-x64" + ] + }, + "escape-string-regexp@1.0.5": { + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" + }, + "estree-walker@2.0.2": { + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" + }, + "fast-glob@3.3.2": { + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dependencies": [ + "@nodelib/fs.stat", + "@nodelib/fs.walk", + "glob-parent", + "merge2", + "micromatch" + ] + }, + "fastq@1.17.1": { + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dependencies": [ + "reusify" + ] + }, + "filename-reserved-regex@2.0.0": { + "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==" + }, + "filenamify@4.3.0": { + "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", + "dependencies": [ + "filename-reserved-regex", + "strip-outer", + "trim-repeated" + ] + }, + "fill-range@7.1.1": { + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dependencies": [ + "to-regex-range" + ] + }, + "find-cache-dir@3.3.2": { + "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", + "dependencies": [ + "commondir", + "make-dir", + "pkg-dir" + ] + }, + "find-up@4.1.0": { + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": [ + "locate-path", + "path-exists" + ] + }, + "fs-extra@11.2.0": { + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dependencies": [ + "graceful-fs", + "jsonfile", + "universalify" + ] + }, + "fsevents@2.3.3": { + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==" + }, + "gh-pages@6.2.0": { + "integrity": "sha512-HMXJ8th9u5wRXaZCnLcs/d3oVvCHiZkaP5KQExQljYGwJjQbSPyTdHe/Gc1IvYUR/rWiZLxNobIqfoMHKTKjHQ==", + "dependencies": [ + "async", + "commander", + "email-addresses", + "filenamify", + "find-cache-dir", + "fs-extra", + "globby" + ] + }, + "glob-parent@5.1.2": { + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dependencies": [ + "is-glob" + ] + }, + "globby@11.1.0": { + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dependencies": [ + "array-union", + "dir-glob", + "fast-glob", + "ignore", + "merge2", + "slash" + ] + }, + "graceful-fs@4.2.11": { + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "he@1.2.0": { + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" + }, + "ignore@5.3.2": { + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==" + }, + "is-extglob@2.1.1": { + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" + }, + "is-glob@4.0.3": { + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dependencies": [ + "is-extglob" + ] + }, + "is-number@7.0.0": { + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + }, + "jsonfile@6.1.0": { + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": [ + "graceful-fs", + "universalify" + ] + }, + "locate-path@5.0.0": { + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": [ + "p-locate" + ] + }, + "magic-string@0.30.12": { + "integrity": "sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==", + "dependencies": [ + "@jridgewell/sourcemap-codec" + ] + }, + "make-dir@3.1.0": { + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dependencies": [ + "semver@6.3.1" + ] + }, + "merge2@1.4.1": { + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + }, + "micromatch@4.0.8": { + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dependencies": [ + "braces", + "picomatch" + ] + }, + "minimatch@9.0.5": { + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": [ + "brace-expansion" + ] + }, + "muggle-string@0.4.1": { + "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==" + }, + "nanoid@3.3.7": { + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==" + }, + "p-limit@2.3.0": { + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": [ + "p-try" + ] + }, + "p-locate@4.1.0": { + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": [ + "p-limit" + ] + }, + "p-try@2.2.0": { + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + }, + "path-browserify@1.0.1": { + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==" + }, + "path-exists@4.0.0": { + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + }, + "path-type@4.0.0": { + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + }, + "picocolors@1.1.1": { + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "picomatch@2.3.1": { + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "pkg-dir@4.2.0": { + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dependencies": [ + "find-up" + ] + }, + "postcss@8.4.47": { + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "dependencies": [ + "nanoid", + "picocolors", + "source-map-js" + ] + }, + "queue-microtask@1.2.3": { + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" + }, + "reusify@1.0.4": { + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" + }, + "rollup@4.24.0": { + "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", + "dependencies": [ + "@rollup/rollup-android-arm-eabi", + "@rollup/rollup-android-arm64", + "@rollup/rollup-darwin-arm64", + "@rollup/rollup-darwin-x64", + "@rollup/rollup-linux-arm-gnueabihf", + "@rollup/rollup-linux-arm-musleabihf", + "@rollup/rollup-linux-arm64-gnu", + "@rollup/rollup-linux-arm64-musl", + "@rollup/rollup-linux-powerpc64le-gnu", + "@rollup/rollup-linux-riscv64-gnu", + "@rollup/rollup-linux-s390x-gnu", + "@rollup/rollup-linux-x64-gnu", + "@rollup/rollup-linux-x64-musl", + "@rollup/rollup-win32-arm64-msvc", + "@rollup/rollup-win32-ia32-msvc", + "@rollup/rollup-win32-x64-msvc", + "@types/estree", + "fsevents" + ] + }, + "run-parallel@1.2.0": { + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dependencies": [ + "queue-microtask" + ] + }, + "semver@6.3.1": { + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + }, + "semver@7.6.3": { + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==" + }, + "slash@3.0.0": { + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + }, + "source-map-js@1.2.1": { + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==" + }, + "strip-outer@1.0.1": { + "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "dependencies": [ + "escape-string-regexp" + ] + }, + "to-fast-properties@2.0.0": { + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" + }, + "to-regex-range@5.0.1": { + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dependencies": [ + "is-number" + ] + }, + "trim-repeated@1.0.0": { + "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", + "dependencies": [ + "escape-string-regexp" + ] + }, + "typescript@5.6.3": { + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==" + }, + "universalify@2.0.1": { + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==" + }, + "vite@5.4.9": { + "integrity": "sha512-20OVpJHh0PAM0oSOELa5GaZNWeDjcAvQjGXy2Uyr+Tp+/D2/Hdz6NLgpJLsarPTA2QJ6v8mX2P1ZfbsSKvdMkg==", + "dependencies": [ + "esbuild", + "fsevents", + "postcss", + "rollup" + ] + }, + "vscode-uri@3.0.8": { + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==" + }, + "vue-tsc@2.1.6_typescript@5.6.3": { + "integrity": "sha512-f98dyZp5FOukcYmbFpuSCJ4Z0vHSOSmxGttZJCsFeX0M4w/Rsq0s4uKXjcSRsZqsRgQa6z7SfuO+y0HVICE57Q==", + "dependencies": [ + "@volar/typescript", + "@vue/language-core", + "semver@7.6.3", + "typescript" + ] + }, + "vue@3.5.12_typescript@5.6.3": { + "integrity": "sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==", + "dependencies": [ + "@vue/compiler-dom", + "@vue/compiler-sfc", + "@vue/runtime-dom", + "@vue/server-renderer", + "@vue/shared", + "typescript" + ] + } + }, "workspace": { "packageJson": { "dependencies": [ diff --git a/package.json b/package.json index ea21402..1c1d6c0 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,10 @@ "build": "vue-tsc -b && vite build", "preview": "vite preview" }, - "dependencies": { "gh-pages": "^6.2.0", "vue": "^3.5.10" }, + "dependencies": { + "gh-pages": "^6.2.0", + "vue": "^3.5.10" + }, "devDependencies": { "@vitejs/plugin-vue": "^5.1.4", "typescript": "^5.5.3", diff --git a/src/abacus/abacus.ts b/src/abacus/abacus.ts index 571552d..cef9110 100644 --- a/src/abacus/abacus.ts +++ b/src/abacus/abacus.ts @@ -7,7 +7,11 @@ export default class AbacusEmulator { private _accumulator: string = '0000'; // 4 bytes private _current_address: string = '000'; // 3 bytes for the address public registers: Map = new Map(); // 3 bytes for the address - public _breakpoints: string[] = []; + private _breakpoints: string[] = []; + private finished: boolean = false; + public error: string = ''; + + public timeout = 3000; // 3 seconds in milliseconds constructor() { } @@ -45,6 +49,20 @@ export default class AbacusEmulator { this.registers.set(address, register); } + + /** + * Checks if a register exists at the specified address. + * + * @param address - The memory address to check for a register. + * @returns `true` if a register exists at the specified address, `false` otherwise. + */ + public checkRegister(address: string): boolean { + if (!this.registers.get(address)) + return false; + + return true; + } + public addBreakpoint(address: string): void { this._breakpoints.push(address); } @@ -68,6 +86,7 @@ export default class AbacusEmulator { this.accumulator = '0000'; this.current_address = program.registers[0].address; this.registers = new Map(program.registers.map(r => [r.address, r])); + this.error = ''; for (const auxRegister of program.aux_registers) { this.setRegister(auxRegister.address, auxRegister); @@ -83,11 +102,20 @@ export default class AbacusEmulator { throw new Error('No program loaded'); } + const startTime = Date.now(); + const currentTimeout = this.timeout; + // Continue after current breakpoint if (this.hasBreakpoint(this.current_address)) this.step(); while (true) { + // Check timeout + if (Date.now() - startTime > currentTimeout) { + this.error = `Program execution timeout ${currentTimeout}ms`; + return; + } + // End of program if (this.current_address === '000') break; @@ -101,17 +129,25 @@ export default class AbacusEmulator { } public step() { + console.log('Step'); + if (!this.program) throw new Error('No program loaded'); if (this.current_address === '000') return; + if (!this.checkRegister(this.current_address)) { + this.error = `Unknown address: ${this.current_address}`; + return; + } + + console.log(this.current_register); const operation = this.operations.get(this.current_register.opcode); if (!operation) { - console.error(`Unknown operation code: ${this.current_register.opcode} at address ${this.current_address}`); - throw new Error("Unknown operation code"); + this.error = `Unknown operation code: ${this.current_register.opcode} at address ${this.current_address}`; + return; } const old_address = this.current_address; diff --git a/src/abacus/importer.ts b/src/abacus/importer.ts index f4faca2..b84a3da 100644 --- a/src/abacus/importer.ts +++ b/src/abacus/importer.ts @@ -54,12 +54,12 @@ export class ProgramImporter { } } - return { - name: 'imported_program', - description: '', + return new Program( + 'imported_program', + '', operations, - aux_registers: auxRegisters, + auxRegisters, registers - }; + ); } } diff --git a/src/abacus/program.ts b/src/abacus/program.ts index 7bfc432..82f3c59 100644 --- a/src/abacus/program.ts +++ b/src/abacus/program.ts @@ -24,12 +24,35 @@ export class Register { return this.value.slice(-3); } + public clone(): Register { + return new Register({ address: this.address, value: this.value, comment: this.comment }); + } + } -export interface Program { +export class Program { name: string; description: string; operations: Operation[]; aux_registers: Register[]; registers: Register[]; + + constructor(name: string, description: string, operations: Operation[], aux_registers: Register[], registers: Register[]) { + this.name = name; + this.description = description; + this.operations = operations; + this.aux_registers = aux_registers; + this.registers = registers; + } + + public clone(): Program { + return new Program( + this.name, + this.description, + [...this.operations], + this.aux_registers.map(r => r.clone()), + this.registers.map(r => r.clone()) + ); + } + } diff --git a/src/components/Emulator.vue b/src/components/Emulator.vue index 79ea0b3..b780db3 100644 --- a/src/components/Emulator.vue +++ b/src/components/Emulator.vue @@ -1,10 +1,18 @@