init
This commit is contained in:
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.vscode
|
||||
node_modules
|
||||
dist
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024 Petr Vavrin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
69
README.md
Normal file
69
README.md
Normal file
@@ -0,0 +1,69 @@
|
||||
## WebSerial TERMINAL
|
||||
|
||||
is a terminal emulator that allows you to connect to a serial device from your web browser.
|
||||
|
||||
Based on the WebSerial API and xterm.js.
|
||||
|
||||
### Online version
|
||||
[terminal.vavrin.eu](https://terminal.vavrin.eu/)
|
||||
|
||||
### Features
|
||||
|
||||
- Connect to a serial device from your web browser
|
||||
|
||||
- Predefined baud rates - 9600, 19200, 38400, 57600, 115200, 230400, 460800, 921600
|
||||
- Default baud rate is 115200
|
||||
- The last used baud rate is saved in the local storage
|
||||
|
||||
- Adjustable font size
|
||||
|
||||
- From 10 to 40
|
||||
- Default is 15
|
||||
- The last used font size is saved in the local storage
|
||||
- Font size can be changed using these methods:
|
||||
- `Ctrl + Mouse Wheel` inside terminal to decrease or increase font size
|
||||
- `Mouse Wheen` inside font size input to decrease or increase font size
|
||||
- Clicking on minus or plus button to decrease or increase font size
|
||||
|
||||
- Send keystrokes to the connected device and receive responses
|
||||
|
||||
- Button `Ctrl+C` to send the break signal
|
||||
|
||||
- Button `Ctrl+D` to send the end of transmission signal
|
||||
|
||||
- Button `Scroll to bottom` to scroll to the bottom of the terminal
|
||||
|
||||
- Button `Show Buffer` to show the buffer of the terminal
|
||||
|
||||
- The buffer is limited to 512 bytes
|
||||
- The buffer is circular and the oldest data is overwritten by the newest data
|
||||
- The buffer shows hexadecimal and ASCII representation of the data
|
||||
- Values with yellow text color or background are the control characters
|
||||
- Values with black background are read bytes
|
||||
- Values with colored background and black text are written bytes
|
||||
- When mouse hovers over the buffer cell, the hexadecimal and ASCII representation is highlighted and value is shown in the top bar
|
||||
- When mouse double clicks on the buffer cell, then value is freezed
|
||||
- When mouse clicks on the buffer cell, then value is unfreezed
|
||||
|
||||
- Button `Reset stats` to reset the statistics about read and written bytes
|
||||
|
||||
### Build
|
||||
|
||||
- Clone the repository
|
||||
- Run `yarn install` or `npm install`
|
||||
- Run `yarn build` or `npm run build`
|
||||
- In `dist` folder, you can find these folders:
|
||||
- `default` - separated local and remote assets
|
||||
- `single-file` - contains all local and remote assets in one file
|
||||
- `single-file-with-remote-assets` - contains all local in one file, remote assets are loaded from the web
|
||||
|
||||
### Run
|
||||
|
||||
- You can run the terminal by opening the `index.html` file in your browser from the `dist` folders.
|
||||
- Or you can run it from a HTTPS server/webhosting.
|
||||
- You can copy `index.html` from `dist/single-file` folder to your microcontroller and run the terminal from there even without internet connection.
|
||||
|
||||
### Resources
|
||||
|
||||
- [WebSerial API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Serial_API)
|
||||
- [xterm.js](https://xtermjs.org/)
|
||||
152
build.js
Normal file
152
build.js
Normal file
@@ -0,0 +1,152 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const axios = require('axios');
|
||||
const { minify } = require('html-minifier-terser');
|
||||
|
||||
async function inlineAsset(html, params) {
|
||||
let asset;
|
||||
const filePath = params.path.startsWith('http') ? params.path : path.join(params.sourceFolder, params.path);
|
||||
|
||||
if (fs.existsSync(filePath)) {
|
||||
if (!params.inlineLocalAssets) {
|
||||
if (filePath.includes('assets')) {
|
||||
const assetPath = path.join(filePath.split('assets')[1]);
|
||||
const targetPath = path.join(params.targetFolder, assetPath);
|
||||
const targetFolder = path.dirname(targetPath);
|
||||
const htmlAssetPath = `.${assetPath.replace(/\\/g, '/')}`;
|
||||
|
||||
if (!fs.existsSync(targetFolder)) {
|
||||
fs.mkdirSync(targetFolder, { recursive: true });
|
||||
}
|
||||
|
||||
fs.copyFileSync(filePath, targetPath);
|
||||
|
||||
if (params.originalTag.toLowerCase() === 'link') {
|
||||
html = html.replace(params.regex, `<link rel="stylesheet" href="${htmlAssetPath}" />`);
|
||||
} else if (params.originalTag.toLowerCase() === 'script') {
|
||||
html = html.replace(params.regex, `<script src="${htmlAssetPath}"></script>`);
|
||||
}
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
asset = fs.readFileSync(filePath, 'utf8');
|
||||
} else {
|
||||
if (!params.inlineRemoteAssets) {
|
||||
return html;
|
||||
}
|
||||
asset = (await axios.get(filePath)).data;
|
||||
}
|
||||
|
||||
return html.replace(params.regex, `<${params.tag}>\n${asset}\n</${params.tag}>`);
|
||||
}
|
||||
|
||||
function cleanTargetPath(targetDir) {
|
||||
if (!fs.existsSync(targetDir)) {
|
||||
return;
|
||||
}
|
||||
|
||||
fs.readdirSync(targetDir).forEach((file) => {
|
||||
const entryPath = path.join(targetDir, file);
|
||||
const stat = fs.lstatSync(entryPath);
|
||||
if (stat.isFile()) {
|
||||
fs.unlinkSync(entryPath);
|
||||
} else if (stat.isDirectory()) {
|
||||
cleanTargetPath(entryPath);
|
||||
}
|
||||
});
|
||||
fs.rmdirSync(targetDir);
|
||||
}
|
||||
|
||||
async function inlineAssets(params) {
|
||||
const sourceFolder = params.sourceFolder;
|
||||
const targetFolder = params.targetFolder;
|
||||
|
||||
console.log(`Inlining assets from ${sourceFolder} to ${targetFolder}`);
|
||||
|
||||
const inputFile = path.join(sourceFolder, params.inputFile);
|
||||
const outputFile = path.join(targetFolder, 'index.html');
|
||||
|
||||
let html = fs.readFileSync(inputFile, 'utf8');
|
||||
|
||||
const inlineLocalAssets = params.inlineLocalAssets || false;
|
||||
const inlineRemoteAssets = params.inlineRemoteAssets || false;
|
||||
|
||||
cleanTargetPath(targetFolder);
|
||||
|
||||
if (!fs.existsSync(targetFolder)) {
|
||||
fs.mkdirSync(targetFolder, { recursive: true });
|
||||
}
|
||||
|
||||
// Match and inline CSS links
|
||||
const cssLinks = [...html.matchAll(/<link[^>]*?\s+href=["'](.*?)["'][^>]*?>/gs)];
|
||||
for (const match of cssLinks) {
|
||||
html = await inlineAsset(html, {
|
||||
path: match[1],
|
||||
regex: match[0],
|
||||
originalTag: 'link',
|
||||
tag: 'style',
|
||||
sourceFolder,
|
||||
targetFolder,
|
||||
inlineLocalAssets,
|
||||
inlineRemoteAssets,
|
||||
});
|
||||
}
|
||||
|
||||
// Match and inline JavaScript src
|
||||
const scriptLinks = [...html.matchAll(/<script[^>]*?\s+src=["'](.*?)["'][^>]*?>\s*<\/script>/gs)];
|
||||
for (const match of scriptLinks) {
|
||||
html = await inlineAsset(html, {
|
||||
path: match[1],
|
||||
regex: match[0],
|
||||
originalTag: 'script',
|
||||
tag: 'script',
|
||||
sourceFolder,
|
||||
targetFolder,
|
||||
inlineLocalAssets,
|
||||
inlineRemoteAssets,
|
||||
});
|
||||
}
|
||||
|
||||
// Minify the HTML
|
||||
const minifiedHtml = await minify(html, {
|
||||
collapseWhitespace: true,
|
||||
removeComments: true,
|
||||
removeRedundantAttributes: true,
|
||||
removeEmptyAttributes: true,
|
||||
minifyCSS: true,
|
||||
minifyJS: true,
|
||||
});
|
||||
|
||||
// Save the minified HTML file
|
||||
fs.writeFileSync(outputFile, minifiedHtml, 'utf8');
|
||||
console.log(`Saved minified HTML to ${outputFile}`);
|
||||
}
|
||||
|
||||
const defaultBuild = {
|
||||
sourceFolder: './src',
|
||||
inputFile: './index.html',
|
||||
targetFolder: './dist/default',
|
||||
inlineLocalAssets: false,
|
||||
inlineRemoteAssets: false,
|
||||
};
|
||||
|
||||
const singleFileWithRemoteAssets = {
|
||||
sourceFolder: './src',
|
||||
inputFile: './index.html',
|
||||
targetFolder: './dist/single-file-with-remote-assets',
|
||||
inlineLocalAssets: true,
|
||||
inlineRemoteAssets: false,
|
||||
};
|
||||
|
||||
const singleFile = {
|
||||
sourceFolder: './src',
|
||||
inputFile: './index.html',
|
||||
targetFolder: './dist/single-file',
|
||||
inlineLocalAssets: true,
|
||||
inlineRemoteAssets: true,
|
||||
};
|
||||
|
||||
inlineAssets(defaultBuild);
|
||||
inlineAssets(singleFileWithRemoteAssets);
|
||||
inlineAssets(singleFile);
|
||||
1
eslint.config.js
Normal file
1
eslint.config.js
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = [{}];
|
||||
14
package.json
Normal file
14
package.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "webserial_term",
|
||||
"version": "1.0.0",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"axios": "^1.11.0",
|
||||
"eslint": "^9.24.0",
|
||||
"html-minifier-terser": "^7.2.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "node build.js"
|
||||
}
|
||||
}
|
||||
316
src/assets/css/styles.css
Normal file
316
src/assets/css/styles.css
Normal file
@@ -0,0 +1,316 @@
|
||||
html {
|
||||
overflow: hidden;
|
||||
}
|
||||
* {
|
||||
font-family: 'Ubuntu Mono', Menlo, Consolas, 'DejaVu Sans Mono', 'Courier New', Courier, monospace;
|
||||
outline: none;
|
||||
}
|
||||
body {
|
||||
background-color: #000000;
|
||||
color: #ffffff;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#app {
|
||||
visibility: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
a {
|
||||
color: #d9cb0a;
|
||||
text-decoration: none;
|
||||
}
|
||||
#top-bar,
|
||||
#bottom-bar {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
padding: 5px 10px;
|
||||
background-color: #272727;
|
||||
height: 25px !important;
|
||||
white-space: nowrap;
|
||||
color: #aaaaaa;
|
||||
}
|
||||
#top-bar {
|
||||
user-select: none;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
#bottom-bar {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
}
|
||||
.corner::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
border-bottom: 7px solid transparent;
|
||||
border-left: 7px solid #272727;
|
||||
width: 0;
|
||||
}
|
||||
.toolbar-button,
|
||||
.toolbar-input,
|
||||
.toolbar-select {
|
||||
align-items: center;
|
||||
background-color: #181818;
|
||||
border-bottom: 1px solid #353535;
|
||||
border-right: 1px solid #353535;
|
||||
border: 0px solid #333333;
|
||||
color: #aaaaaa;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
line-height: 100%;
|
||||
padding: 0 10px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
}
|
||||
.toolbar-button {
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
.toolbar-button:hover,
|
||||
.toolbar-button.active {
|
||||
color: #000000;
|
||||
background-color: #d9cb0a;
|
||||
}
|
||||
.toolbar-space {
|
||||
margin-right: 15px;
|
||||
}
|
||||
.toolbar-spacer {
|
||||
flex-grow: 1;
|
||||
}
|
||||
.toolbar-input-label {
|
||||
font-size: 14px;
|
||||
color: #aaaaaa;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.toolbar-input {
|
||||
width: 25px !important;
|
||||
font-size: 15px;
|
||||
}
|
||||
.toolbar-input::-webkit-outer-spin-button,
|
||||
.toolbar-input::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
.toolbar-select {
|
||||
font-size: 15px;
|
||||
}
|
||||
.toolbar-icons {
|
||||
width: 60px;
|
||||
}
|
||||
.toolbar-svg-icon {
|
||||
width: 30px !important;
|
||||
height: 30px !important;
|
||||
margin-top: 2px;
|
||||
}
|
||||
#main {
|
||||
flex-grow: 1;
|
||||
margin: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
#terminal-container {
|
||||
flex-grow: 1;
|
||||
margin: 10px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.terminal-background {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: calc(100% - 100px);
|
||||
pointer-events: none;
|
||||
font-family: 'Ubuntu Mono', Menlo, Consolas, 'DejaVu Sans Mono', 'Courier New', Courier, monospace;
|
||||
}
|
||||
.xterm .xterm-viewport {
|
||||
overflow-y: scroll;
|
||||
cursor: default;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
scrollbar-color: #333333 #111111;
|
||||
scrollbar-width: thin;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
.xterm-viewport::-webkit-scrollbar {
|
||||
background-color: #333;
|
||||
width: 8px;
|
||||
}
|
||||
.xterm-viewport::-webkit-scrollbar-thumb {
|
||||
background: #00ccff;
|
||||
}
|
||||
#button-connect {
|
||||
width: 150px;
|
||||
}
|
||||
#transfer-stats {
|
||||
overflow: hidden;
|
||||
margin-left: 10px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
#data-table-info {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 45px;
|
||||
right: 30px;
|
||||
height: 40px;
|
||||
flex-direction: row;
|
||||
justify-content: start;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
border: 1px solid #202020;
|
||||
background-color: #0a0a0a;
|
||||
}
|
||||
.data-table-info-title {
|
||||
font-size: 14px;
|
||||
color: #aaaaaa;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.data-table-info-cell {
|
||||
margin-left: 20px;
|
||||
}
|
||||
.data-table-info-label {
|
||||
height: 14px;
|
||||
font-size: 10px;
|
||||
text-align: center;
|
||||
opacity: 0.5;
|
||||
}
|
||||
.data-table-info-value {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
}
|
||||
.data-table-info-value svg {
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
#data-table-info-dec,
|
||||
#data-table-info-hex,
|
||||
#data-table-info-ascii {
|
||||
width: 45px;
|
||||
}
|
||||
#data-table-info-detail {
|
||||
width: 285px;
|
||||
}
|
||||
#data-table-info-bin {
|
||||
width: 80px;
|
||||
}
|
||||
#data-tables {
|
||||
position: absolute;
|
||||
display: none;
|
||||
top: 90px;
|
||||
right: 30px;
|
||||
flex-direction: row;
|
||||
justify-content: start;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
scrollbar-color: #333333 #111111;
|
||||
scrollbar-width: thin;
|
||||
pointer-events: none;
|
||||
}
|
||||
#data-table-hex,
|
||||
#data-table-ascii {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(16, 1fr);
|
||||
font-size: 14px;
|
||||
border-collapse: collapse;
|
||||
border: 1px solid #202020;
|
||||
gap: 0;
|
||||
box-sizing: border-box;
|
||||
height: max-content;
|
||||
pointer-events: auto;
|
||||
}
|
||||
#data-table-ascii {
|
||||
margin-left: 10px;
|
||||
}
|
||||
#data-table-hex div,
|
||||
#data-table-ascii div {
|
||||
display: table-cell;
|
||||
white-space: pre;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
cursor: default;
|
||||
height: 18px !important;
|
||||
line-height: 18px !important;
|
||||
background-color: #0a0a0a;
|
||||
}
|
||||
#data-table-hex div {
|
||||
width: 22px !important;
|
||||
border: 1px solid #000000;
|
||||
}
|
||||
#data-table-ascii div {
|
||||
width: 18px !important;
|
||||
border: 1px solid #000000;
|
||||
}
|
||||
.cell,
|
||||
.cell-in {
|
||||
font-weight: 400;
|
||||
background-color: #0a0a0a;
|
||||
}
|
||||
.cell {
|
||||
color: #313131;
|
||||
}
|
||||
.cell-in {
|
||||
color: #ababab;
|
||||
}
|
||||
.cell-in-escape {
|
||||
color: #d9cb0a;
|
||||
}
|
||||
#data-table-ascii .cell-in-escape,
|
||||
#data-table-ascii .cell-out-escape,
|
||||
#data-table-ascii .cell-highlight-escape {
|
||||
font-size: 10px;
|
||||
}
|
||||
.cell-out,
|
||||
.cell-out-escape {
|
||||
font-weight: 700;
|
||||
color: #0a0a0a;
|
||||
}
|
||||
.cell-out {
|
||||
background-color: #898989 !important;
|
||||
}
|
||||
.cell-out-escape {
|
||||
background-color: #b7ab00 !important;
|
||||
}
|
||||
.cell-highlight,
|
||||
.cell-highlight-escape {
|
||||
font-weight: 700;
|
||||
color: #c8c8c8;
|
||||
background-color: #05198b !important;
|
||||
}
|
||||
#about {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 460px;
|
||||
padding: 20px;
|
||||
background-color: #0a0a0a;
|
||||
border: 1px solid #202020;
|
||||
box-shadow: 0 0 10px #000000;
|
||||
z-index: 100;
|
||||
}
|
||||
#about pre {
|
||||
position: relative;
|
||||
text-align: left;
|
||||
display: inline-block;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
@media (max-width: 880px) {
|
||||
.toolbar-input-label {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
53
src/assets/js/config.js
Normal file
53
src/assets/js/config.js
Normal file
@@ -0,0 +1,53 @@
|
||||
class Config {
|
||||
constructor(defaults) {
|
||||
this.config = {};
|
||||
this.defaults = defaults;
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
if (window.localStorage) {
|
||||
const storedConfig = localStorage.getItem('config');
|
||||
if (storedConfig) {
|
||||
try {
|
||||
const storedConfigJSON = JSON.parse(storedConfig);
|
||||
for (let key of Object.keys(storedConfigJSON)) {
|
||||
if (storedConfigJSON[key] === null) {
|
||||
continue;
|
||||
}
|
||||
this.config[key] = storedConfigJSON[key];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error parsing stored config');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const key in this.defaults) {
|
||||
if (!(key in this.config)) {
|
||||
this.config[key] = this.defaults[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
saveConfig() {
|
||||
if (window.localStorage) {
|
||||
localStorage.setItem('config', JSON.stringify(this.config));
|
||||
}
|
||||
}
|
||||
|
||||
get(key) {
|
||||
if (key in this.config) {
|
||||
return this.config[key];
|
||||
}
|
||||
if (key in this.defaults) {
|
||||
return this.defaults[key];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
set(key, value) {
|
||||
this.config[key] = value;
|
||||
this.saveConfig();
|
||||
}
|
||||
}
|
||||
228
src/assets/js/io-buffer.js
Normal file
228
src/assets/js/io-buffer.js
Normal file
@@ -0,0 +1,228 @@
|
||||
class IOBuffer {
|
||||
constructor(options) {
|
||||
this.dataTables = options.dataTables;
|
||||
this.dataTableHex = options.dataTableHex;
|
||||
this.dataTableInfoLock = options.dataTableInfoLock;
|
||||
this.dataTableInfoDirection = options.dataTableInfoDirection;
|
||||
this.dataTableAscii = options.dataTableAscii;
|
||||
this.dataTableInfoHex = options.dataTableInfoHex;
|
||||
this.dataTableInfoDec = options.dataTableInfoDec;
|
||||
this.dataTableInfoBin = options.dataTableInfoBin;
|
||||
this.dataTableInfoAscii = options.dataTableInfoAscii;
|
||||
this.dataTableInfoDetail = options.dataTableInfoDetail;
|
||||
this.freezedCellInfo = false;
|
||||
|
||||
this.size = options.bufferSize;
|
||||
this.rowLength = options.rowLength;
|
||||
|
||||
this.cellsSize = this.size + this.rowLength;
|
||||
this.buffer = new Array(this.size);
|
||||
this.cells = new Array(this.cellsSize);
|
||||
this.head = 0;
|
||||
this.tail = 0;
|
||||
this.rowOffset = 0;
|
||||
this.releaseNodes = [];
|
||||
this.classes = {
|
||||
in: 'cell-in',
|
||||
out: 'cell-out',
|
||||
init: 'cell',
|
||||
};
|
||||
|
||||
this.escapeChars = [
|
||||
{ value: 'NUL', label: 'NULL character' },
|
||||
{ value: 'SOH', label: 'Start of Heading' },
|
||||
{ value: 'STX', label: 'Start of Text' },
|
||||
{ value: 'ETX', label: 'End of Text' },
|
||||
{ value: 'EOT', label: 'End of Transmission' },
|
||||
{ value: 'ENQ', label: 'Enquiry' },
|
||||
{ value: 'ACK', label: 'Acknowledge' },
|
||||
{ value: 'BEL', label: 'Bell' },
|
||||
{ value: 'BS', label: 'Backspace' },
|
||||
{ value: 'HT', label: 'Horizontal Tab' },
|
||||
{ value: 'LF', label: 'Line feed' },
|
||||
{ value: 'VT', label: 'Vertical Tab' },
|
||||
{ value: 'FF', label: 'Form Feed' },
|
||||
{ value: 'CR', label: 'Carriage return' },
|
||||
{ value: 'SO', label: 'Shift Out' },
|
||||
{ value: 'SI', label: 'Shift In' },
|
||||
{ value: 'DLE', label: 'Data Link Escape' },
|
||||
{ value: 'DC1', label: 'Device Control (XOn)' },
|
||||
{ value: 'DC2', label: 'Device Control' },
|
||||
{ value: 'DC3', label: 'Device Control (XOff)' },
|
||||
{ value: 'DC4', label: 'Device Control' },
|
||||
{ value: 'NAK', label: 'Negative Acknowledge' },
|
||||
{ value: 'SYN', label: 'Synchronous Idle' },
|
||||
{ value: 'ETB', label: 'End of Transmission Block' },
|
||||
{ value: 'CAN', label: 'Cancel' },
|
||||
{ value: 'EM', label: 'End of Medium' },
|
||||
{ value: 'SUB', label: 'Substitute' },
|
||||
{ value: 'ESC', label: 'Escape' },
|
||||
{ value: 'FS', label: 'File Separator' },
|
||||
{ value: 'GS', label: 'Group Separator' },
|
||||
{ value: 'RS', label: 'Record Separator' },
|
||||
{ value: 'US', label: 'Unit Separator' },
|
||||
];
|
||||
this.prepareTableCells();
|
||||
}
|
||||
|
||||
prepareTableCells() {
|
||||
for (let index = 0; index < this.cellsSize; index++) {
|
||||
const hexCell = document.createElement('div');
|
||||
const asciiCell = document.createElement('div');
|
||||
this.dataTableHex.appendChild(hexCell);
|
||||
this.dataTableAscii.appendChild(asciiCell);
|
||||
this.cells[index] = {
|
||||
nodeHex: hexCell,
|
||||
nodeAscii: asciiCell,
|
||||
};
|
||||
}
|
||||
this.reset();
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.head = 0;
|
||||
this.tail = 0;
|
||||
this.rowOffset = 0;
|
||||
this.cells.forEach((cell, index) => {
|
||||
cell.dir = 'init';
|
||||
cell.nodeHex.dataset.index = index;
|
||||
cell.nodeHex.className = 'cell';
|
||||
cell.nodeHex.textContent = ' ';
|
||||
cell.nodeAscii.dataset.index = index;
|
||||
cell.nodeAscii.className = 'cell';
|
||||
cell.nodeAscii.textContent = ' ';
|
||||
cell.value = null;
|
||||
});
|
||||
}
|
||||
|
||||
push(data, dir) {
|
||||
const now = Date.now();
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
this.buffer[this.tail] = {
|
||||
data: data[i],
|
||||
ts: now,
|
||||
dir,
|
||||
};
|
||||
this.tail = (this.tail + 1) % this.size;
|
||||
if (this.tail === this.head) {
|
||||
this.head = (this.head + 1) % this.size;
|
||||
}
|
||||
}
|
||||
this.rowOffset = (this.rowOffset + data.length) % this.rowLength;
|
||||
}
|
||||
|
||||
getCellClassName(cell) {
|
||||
let className = cell.highlight ? 'cell-highlight' : this.classes[cell.dir];
|
||||
if (cell.value !== null && cell.value < 32) {
|
||||
className = `${className}-escape`;
|
||||
}
|
||||
return className;
|
||||
}
|
||||
|
||||
updateCell(index, dir, value) {
|
||||
const cell = this.cells[index];
|
||||
|
||||
if (cell.value !== value) {
|
||||
cell.nodeHex.textContent = value === null ? ' ' : value.toString(16).toUpperCase().padStart(2, '0');
|
||||
|
||||
if (value === null) {
|
||||
cell.nodeAscii.textContent = ' ';
|
||||
} else if (value < 32) {
|
||||
cell.nodeAscii.innerHTML = this.escapeChars[value].value;
|
||||
} else {
|
||||
cell.nodeAscii.textContent = String.fromCharCode(value);
|
||||
}
|
||||
cell.value = value;
|
||||
}
|
||||
|
||||
if (cell.dir !== dir) {
|
||||
cell.dir = dir;
|
||||
}
|
||||
|
||||
const className = this.getCellClassName(cell);
|
||||
if (cell.nodeHex.className !== className) {
|
||||
cell.nodeHex.className = className;
|
||||
cell.nodeAscii.className = className;
|
||||
}
|
||||
}
|
||||
|
||||
showInfo(value, dir) {
|
||||
this.dataTableInfoDirection.textContent = dir === 'init' ? '' : dir.toUpperCase();
|
||||
this.dataTableInfoHex.textContent = value.toString(16).toUpperCase().padStart(2, '0');
|
||||
this.dataTableInfoDec.textContent = value.toString(10);
|
||||
this.dataTableInfoBin.textContent = value.toString(2).padStart(8, '0');
|
||||
this.dataTableInfoAscii.textContent = value < 32 ? this.escapeChars[value].value : String.fromCharCode(value);
|
||||
this.dataTableInfoDetail.textContent = value < 32 ? this.escapeChars[value].label : '';
|
||||
this.dataTableInfoLock.style.display = this.freezedCellInfo ? 'block' : 'none';
|
||||
}
|
||||
|
||||
cleanInfo() {
|
||||
this.dataTableInfoDirection.textContent = '';
|
||||
this.dataTableInfoHex.textContent = '';
|
||||
this.dataTableInfoDec.textContent = '';
|
||||
this.dataTableInfoBin.textContent = '';
|
||||
this.dataTableInfoAscii.textContent = '';
|
||||
this.dataTableInfoDetail.textContent = '';
|
||||
this.dataTableInfoLock.style.display = 'none';
|
||||
}
|
||||
|
||||
highlightCell(index, state) {
|
||||
const cell = this.cells[index];
|
||||
cell.highlight = state;
|
||||
const className = this.getCellClassName(cell);
|
||||
cell.nodeHex.className = className;
|
||||
cell.nodeAscii.className = className;
|
||||
|
||||
if (this.freezedCellInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state && cell.value !== null) {
|
||||
this.showInfo(cell.value, cell.dir);
|
||||
} else {
|
||||
this.cleanInfo();
|
||||
}
|
||||
}
|
||||
|
||||
freezeCellInfo(index) {
|
||||
const cell = this.cells[index];
|
||||
this.freezedCellInfo = true;
|
||||
this.showInfo(cell.value, cell.dir);
|
||||
this.dataTableInfoLock.style.display = 'block';
|
||||
}
|
||||
|
||||
unfreezeCellInfo() {
|
||||
this.freezedCellInfo = false;
|
||||
this.cleanInfo();
|
||||
this.dataTableInfoLock.style.display = 'none';
|
||||
}
|
||||
|
||||
redraw() {
|
||||
let index = this.head;
|
||||
let cellIndex = 0;
|
||||
if (this.head !== 0) {
|
||||
for (let i = 0; i < this.rowOffset; i++) {
|
||||
this.updateCell(cellIndex, 'init', null);
|
||||
cellIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
while (index !== this.tail) {
|
||||
const item = this.buffer[index];
|
||||
this.updateCell(cellIndex, item.dir, item.data);
|
||||
index = (index + 1) % this.size;
|
||||
cellIndex++;
|
||||
}
|
||||
|
||||
const cellsLeft = this.rowLength - (cellIndex % this.rowLength);
|
||||
for (let i = 0; i < cellsLeft; i++) {
|
||||
this.updateCell(cellIndex, 'init', null);
|
||||
cellIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
resize(newHeight) {
|
||||
this.dataTables.style.height = `${newHeight - 60}px`;
|
||||
this.dataTables.scrollTop = this.dataTables.scrollHeight;
|
||||
}
|
||||
}
|
||||
453
src/assets/js/main.js
Normal file
453
src/assets/js/main.js
Normal file
@@ -0,0 +1,453 @@
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const [
|
||||
app,
|
||||
terminalContainer,
|
||||
connectButton,
|
||||
selectSerialPortBaudrate,
|
||||
buttonCtrlC,
|
||||
buttonCtrlD,
|
||||
buttonScrollToBottom,
|
||||
buttonShowAbout,
|
||||
buttonShowBuffer,
|
||||
buttonResetStats,
|
||||
inputFontSize,
|
||||
buttonFontSizeMinus,
|
||||
buttonFontSizePlus,
|
||||
svgDevice,
|
||||
svgToDevice,
|
||||
svgFromDevice,
|
||||
transferStats,
|
||||
dataTableInfo,
|
||||
dataTables,
|
||||
dataTableHex,
|
||||
dataTableAscii,
|
||||
dataTableInfoLock,
|
||||
dataTableInfoDirection,
|
||||
dataTableInfoHex,
|
||||
dataTableInfoDec,
|
||||
dataTableInfoBin,
|
||||
dataTableInfoAscii,
|
||||
dataTableInfoDetail,
|
||||
terminalBackgroundText,
|
||||
] = [
|
||||
'app',
|
||||
'terminal-container',
|
||||
'button-connect',
|
||||
'select-serial-port-baudrate',
|
||||
'button-ctrl-c',
|
||||
'button-ctrl-d',
|
||||
'button-scroll-to-bottom',
|
||||
'button-show-about',
|
||||
'button-show-buffer',
|
||||
'button-reset-stats',
|
||||
'input-font-size',
|
||||
'button-font-size-minus',
|
||||
'button-font-size-plus',
|
||||
'svg-device',
|
||||
'svg-to-device',
|
||||
'svg-from-device',
|
||||
'transfer-stats',
|
||||
'data-table-info',
|
||||
'data-tables',
|
||||
'data-table-hex',
|
||||
'data-table-ascii',
|
||||
'data-table-info-lock',
|
||||
'data-table-info-direction',
|
||||
'data-table-info-hex',
|
||||
'data-table-info-dec',
|
||||
'data-table-info-bin',
|
||||
'data-table-info-ascii',
|
||||
'data-table-info-detail',
|
||||
'terminal-background-text',
|
||||
].map((id) => document.getElementById(id));
|
||||
|
||||
// small animation on terminal background just for fun
|
||||
const backgroundDot = ['•', '•', '•'];
|
||||
const backgroundText = ['T', 'E', 'R', 'M', 'I', 'N', 'A', 'L'];
|
||||
|
||||
function animationPhase(text, stepDelay, endDelay, callback) {
|
||||
terminalBackgroundText.textContent = '';
|
||||
const interval = setInterval(() => {
|
||||
terminalBackgroundText.textContent = terminalBackgroundText.textContent + text.shift();
|
||||
if (text.length) return;
|
||||
clearInterval(interval);
|
||||
if (endDelay && callback) {
|
||||
setTimeout(callback, endDelay);
|
||||
}
|
||||
}, stepDelay);
|
||||
}
|
||||
|
||||
animationPhase(backgroundDot, 200, 400, () => {
|
||||
animationPhase(backgroundText, 70);
|
||||
});
|
||||
|
||||
let port;
|
||||
let reader;
|
||||
let portReadedChars = 0;
|
||||
let portWritedChars = 0;
|
||||
let portLastReadedChars = 0;
|
||||
let portLastWritedChars = 0;
|
||||
let showAbout = false;
|
||||
let showDataBuffer = false;
|
||||
let lastHighlightIndex = null;
|
||||
|
||||
const ioBufferOptions = {
|
||||
dataTables,
|
||||
dataTableHex,
|
||||
dataTableAscii,
|
||||
dataTableInfoLock,
|
||||
dataTableInfoDirection,
|
||||
dataTableInfoHex,
|
||||
dataTableInfoDec,
|
||||
dataTableInfoBin,
|
||||
dataTableInfoAscii,
|
||||
dataTableInfoDetail,
|
||||
bufferSize: 512,
|
||||
rowLength: 16,
|
||||
};
|
||||
|
||||
const defaultConfig = {
|
||||
fontSize: 12,
|
||||
baudRate: 115200,
|
||||
};
|
||||
|
||||
const ioBuffer = new IOBuffer(ioBufferOptions);
|
||||
const config = new Config(defaultConfig);
|
||||
|
||||
inputFontSize.value = parseInt(config.get('fontSize'));
|
||||
selectSerialPortBaudrate.value = parseInt(config.get('baudRate'));
|
||||
|
||||
const { Terminal } = window;
|
||||
const { FitAddon } = window.FitAddon;
|
||||
const terminal = new Terminal({
|
||||
scrollback: 1000,
|
||||
cursorBlink: true,
|
||||
fontFamily: '"Ubuntu Mono", Menlo, Consolas, "DejaVu Sans Mono", "Courier New", Courier, monospace',
|
||||
theme: {
|
||||
background: 'transparent',
|
||||
allowTransparency: true,
|
||||
// selectionBackground: '#bbbbbb',
|
||||
// selectionForeground: '#000000',
|
||||
},
|
||||
});
|
||||
const fitAddon = new FitAddon();
|
||||
terminal.loadAddon(fitAddon);
|
||||
|
||||
terminal.onTitleChange((title) => {
|
||||
document.title = title;
|
||||
});
|
||||
|
||||
terminal.attachCustomKeyEventHandler((event) => {
|
||||
if (event.ctrlKey && (event.type === 'keydown' || event.type === 'keyup')) {
|
||||
let button = null;
|
||||
if (event.code === 'KeyC') {
|
||||
button = buttonCtrlC;
|
||||
} else if (event.code === 'KeyD') {
|
||||
button = buttonCtrlD;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.type === 'keydown') {
|
||||
button.classList.add('active');
|
||||
} else if (event.type === 'keyup') {
|
||||
button.classList.remove('active');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
terminal.open(terminalContainer);
|
||||
fitAddon.fit();
|
||||
|
||||
terminal.onResize(function () {
|
||||
ioBuffer.resize(terminalContainer.clientHeight);
|
||||
});
|
||||
|
||||
terminal.onData(async (data) => {
|
||||
if (port && port.writable) {
|
||||
const writer = port.writable.getWriter();
|
||||
const chars = new TextEncoder().encode(data);
|
||||
portWritedChars += chars.length;
|
||||
ioBuffer.push(chars, 'out');
|
||||
await writer.write(chars);
|
||||
writer.releaseLock();
|
||||
}
|
||||
});
|
||||
|
||||
if (navigator && 'serial' in navigator) {
|
||||
terminal.writeln('WebSerial Terminal - Click on "Connect to Serial" to start.');
|
||||
} else {
|
||||
terminal.writeln('Terminal error: WebSerial not supported');
|
||||
terminal.writeln('Please use a browser that supports it.');
|
||||
terminal.writeln(
|
||||
'Supported browsers: Chrome 89+, Edge 89+, Opera 75+ and other browsers based on Chromium 89+.'
|
||||
);
|
||||
}
|
||||
|
||||
function updateToolbar() {
|
||||
if (!navigator || !('serial' in navigator)) {
|
||||
connectButton.setAttribute('disabled', 'disabled');
|
||||
}
|
||||
const connected = !!port;
|
||||
|
||||
connectButton.textContent = connected ? 'Disconnect' : 'Connect to Serial';
|
||||
buttonCtrlC.style.display = connected ? 'flex' : 'none';
|
||||
buttonCtrlD.style.display = connected ? 'flex' : 'none';
|
||||
buttonScrollToBottom.style.display = connected ? 'flex' : 'none';
|
||||
buttonShowBuffer.textContent = showDataBuffer ? 'Hide Buffer' : 'Show Buffer';
|
||||
|
||||
if (connected) {
|
||||
selectSerialPortBaudrate.setAttribute('disabled', 'disabled');
|
||||
} else {
|
||||
selectSerialPortBaudrate.removeAttribute('disabled');
|
||||
}
|
||||
}
|
||||
|
||||
async function sendToPort(data) {
|
||||
if (port && port.writable) {
|
||||
const writer = port.writable.getWriter();
|
||||
const chars = new TextEncoder().encode(data);
|
||||
portWritedChars += chars.length;
|
||||
ioBuffer.push(chars, 'out');
|
||||
await writer.write(chars);
|
||||
writer.releaseLock();
|
||||
}
|
||||
}
|
||||
|
||||
function chageFontSize(delta) {
|
||||
let fontSize = parseInt(inputFontSize.value, 10);
|
||||
if (isNaN(fontSize)) {
|
||||
fontSize = config.get('fontSize');
|
||||
}
|
||||
if (delta !== undefined) {
|
||||
fontSize = delta < 0 ? fontSize + 1 : fontSize - 1;
|
||||
}
|
||||
fontSize = Math.max(10, Math.min(fontSize, 40));
|
||||
inputFontSize.value = fontSize;
|
||||
terminal.options.fontSize = fontSize;
|
||||
config.set('fontSize', fontSize);
|
||||
fitAddon.fit();
|
||||
}
|
||||
|
||||
function changePortBaudrate() {
|
||||
const baudRate = parseInt(selectSerialPortBaudrate.value, 10);
|
||||
if (baudRate) {
|
||||
config.set('baudRate', baudRate);
|
||||
}
|
||||
}
|
||||
|
||||
function highlightCell(event, state) {
|
||||
const target = event.target;
|
||||
if (lastHighlightIndex !== null) {
|
||||
ioBuffer.highlightCell(lastHighlightIndex, false);
|
||||
lastHighlightIndex = null;
|
||||
}
|
||||
if (target.tagName === 'DIV' && 'index' in target.dataset) {
|
||||
const index = parseInt(target.dataset.index, 10);
|
||||
ioBuffer.highlightCell(index, state);
|
||||
lastHighlightIndex = state ? index : null;
|
||||
}
|
||||
}
|
||||
|
||||
function freeceCell(event) {
|
||||
const target = event.target;
|
||||
if (target.tagName === 'DIV' && 'index' in target.dataset) {
|
||||
const index = parseInt(target.dataset.index, 10);
|
||||
ioBuffer.freezeCellInfo(index);
|
||||
}
|
||||
}
|
||||
|
||||
function unfreeceCell(event) {
|
||||
ioBuffer.unfreezeCellInfo();
|
||||
highlightCell(event, true);
|
||||
}
|
||||
|
||||
async function sendCtrlC() {
|
||||
await sendToPort('\x03');
|
||||
terminal.focus();
|
||||
}
|
||||
|
||||
async function sendCtrlD() {
|
||||
await sendToPort('\x04');
|
||||
terminal.focus();
|
||||
}
|
||||
|
||||
async function scrollToBottom() {
|
||||
terminal.scrollToBottom();
|
||||
terminal.focus();
|
||||
}
|
||||
|
||||
async function resetStats() {
|
||||
portReadedChars = 0;
|
||||
portWritedChars = 0;
|
||||
portLastReadedChars = 0;
|
||||
portLastWritedChars = 0;
|
||||
}
|
||||
|
||||
function updateDataBufferVisibility() {
|
||||
dataTables.style.display = showDataBuffer ? 'flex' : 'none';
|
||||
dataTableInfo.style.display = showDataBuffer ? 'flex' : 'none';
|
||||
if (showDataBuffer) {
|
||||
ioBuffer.redraw();
|
||||
}
|
||||
updateToolbar();
|
||||
}
|
||||
|
||||
function toggleAboutVisibility() {
|
||||
showAbout = !showAbout;
|
||||
about.style.display = showAbout ? 'block' : 'none';
|
||||
}
|
||||
|
||||
function toggleDataBufferVisibility() {
|
||||
showDataBuffer = !showDataBuffer;
|
||||
updateDataBufferVisibility();
|
||||
}
|
||||
|
||||
function onWindowClick(event) {
|
||||
if (showAbout && !about.contains(event.target) && !buttonShowAbout.contains(event.target)) {
|
||||
toggleAboutVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
function confirmExit() {
|
||||
return "You have attempted to leave this page. Are you sure?";
|
||||
}
|
||||
|
||||
async function readFromPort() {
|
||||
const decoder = new TextDecoder('utf-8');
|
||||
try {
|
||||
reader = port.readable.getReader();
|
||||
while (true) {
|
||||
const { value, done } = await reader.read();
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
if (value) {
|
||||
ioBuffer.push(value, 'in');
|
||||
portReadedChars += value.length;
|
||||
const chars = decoder.decode(value, { stream: true });
|
||||
terminal.write(chars);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
terminal.writeln(`Terminal error: reading from serial port.`);
|
||||
} finally {
|
||||
if (reader) {
|
||||
reader.releaseLock();
|
||||
}
|
||||
disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
async function connect() {
|
||||
if (!port) {
|
||||
try {
|
||||
const baudRate = parseInt(selectSerialPortBaudrate.value, 10);
|
||||
if (!baudRate) {
|
||||
terminal.writeln('Terminal error: Invalid baudrate');
|
||||
return;
|
||||
}
|
||||
port = await navigator.serial.requestPort();
|
||||
await port.open({ baudRate });
|
||||
terminal.reset();
|
||||
terminal.focus();
|
||||
portReadedChars = 0;
|
||||
portWritedChars = 0;
|
||||
updateToolbar();
|
||||
readFromPort();
|
||||
window.onbeforeunload = confirmExit;
|
||||
|
||||
port.addEventListener('disconnect', () => {
|
||||
terminal.writeln('Terminal error: Serial port disconnected.');
|
||||
disconnect();
|
||||
});
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
terminal.writeln(`Terminal error: Unable to connect to serial port.`);
|
||||
}
|
||||
} else {
|
||||
disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
async function disconnect() {
|
||||
if (reader) {
|
||||
try {
|
||||
await reader.cancel();
|
||||
} catch (error) {
|
||||
console.error('Error canceling reader:', error);
|
||||
}
|
||||
reader = null;
|
||||
}
|
||||
if (port) {
|
||||
try {
|
||||
await port.close();
|
||||
} catch (error) {
|
||||
console.error('Error closing port:', error);
|
||||
}
|
||||
port = null;
|
||||
}
|
||||
portReadedChars = 0;
|
||||
portWritedChars = 0;
|
||||
document.title = 'WebSerial Terminal';
|
||||
updateToolbar();
|
||||
ioBuffer.reset();
|
||||
window.onbeforeunload = null;
|
||||
}
|
||||
|
||||
window.addEventListener('resize', () => fitAddon.fit());
|
||||
window.addEventListener('click', onWindowClick);
|
||||
terminalContainer.addEventListener('click', () => terminal.focus());
|
||||
connectButton.addEventListener('click', () => connect());
|
||||
buttonCtrlC.addEventListener('click', () => sendCtrlC());
|
||||
buttonCtrlD.addEventListener('click', () => sendCtrlD());
|
||||
buttonScrollToBottom.addEventListener('click', () => scrollToBottom());
|
||||
buttonShowAbout.addEventListener('click', () => toggleAboutVisibility());
|
||||
buttonShowBuffer.addEventListener('click', () => toggleDataBufferVisibility());
|
||||
buttonResetStats.addEventListener('click', () => resetStats());
|
||||
inputFontSize.addEventListener('change', () => chageFontSize());
|
||||
selectSerialPortBaudrate.addEventListener('change', () => changePortBaudrate());
|
||||
buttonFontSizeMinus.addEventListener('click', () => chageFontSize(1));
|
||||
buttonFontSizePlus.addEventListener('click', () => chageFontSize(-1));
|
||||
dataTableHex.addEventListener('mouseover', (event) => highlightCell(event, true));
|
||||
dataTableHex.addEventListener('mouseout', (event) => highlightCell(event, false));
|
||||
dataTableHex.addEventListener('dblclick', freeceCell);
|
||||
dataTableHex.addEventListener('click', unfreeceCell);
|
||||
dataTableAscii.addEventListener('mouseover', (event) => highlightCell(event, true));
|
||||
dataTableAscii.addEventListener('mouseout', (event) => highlightCell(event, false));
|
||||
inputFontSize.addEventListener('wheel', (event) => chageFontSize(event.deltaY), {
|
||||
passive: false,
|
||||
});
|
||||
|
||||
terminalContainer.addEventListener(
|
||||
'wheel',
|
||||
(event) => {
|
||||
if (event.ctrlKey) {
|
||||
event.preventDefault();
|
||||
chageFontSize(event.deltaY);
|
||||
}
|
||||
},
|
||||
{ passive: false }
|
||||
);
|
||||
|
||||
updateDataBufferVisibility();
|
||||
updateToolbar();
|
||||
chageFontSize();
|
||||
ioBuffer.cleanInfo();
|
||||
ioBuffer.resize(terminalContainer.clientHeight);
|
||||
app.style.visibility = 'visible';
|
||||
|
||||
setInterval(() => {
|
||||
const connected = !!port;
|
||||
svgToDevice.style.stroke = portWritedChars - portLastWritedChars > 0 ? '#aa1b1b' : '#313131';
|
||||
svgFromDevice.style.stroke = portReadedChars - portLastReadedChars > 0 ? '#15aa00' : '#313131';
|
||||
portLastReadedChars = portReadedChars;
|
||||
portLastWritedChars = portWritedChars;
|
||||
svgDevice.style.stroke = connected ? '#15aa00' : '#aa1b1b';
|
||||
transferStats.textContent = `Read: ${portReadedChars} bytes, Written: ${portWritedChars} bytes`;
|
||||
if (showDataBuffer) {
|
||||
ioBuffer.redraw();
|
||||
}
|
||||
}, 250);
|
||||
});
|
||||
287
src/index.html
Normal file
287
src/index.html
Normal file
@@ -0,0 +1,287 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/@xterm/xterm@5.5.0/css/xterm.css"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="./assets/css/styles.css"
|
||||
/>
|
||||
<meta charset="UTF-8" />
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0"
|
||||
/>
|
||||
<title>WebSerial TERMINAL</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<div id="top-bar">
|
||||
<button
|
||||
type="button"
|
||||
id="button-connect"
|
||||
class="toolbar-button toolbar-space corner"
|
||||
>
|
||||
Connect to Serial
|
||||
</button>
|
||||
<label
|
||||
for="select-serial-port-baudrate"
|
||||
class="toolbar-input-label"
|
||||
>
|
||||
Baudrate:
|
||||
</label>
|
||||
<select
|
||||
id="select-serial-port-baudrate"
|
||||
class="toolbar-select toolbar-space on-connected-disabled"
|
||||
>
|
||||
<option value="9600">9600</option>
|
||||
<option value="19200">19200</option>
|
||||
<option value="38400">38400</option>
|
||||
<option value="57600">57600</option>
|
||||
<option value="115200">115200</option>
|
||||
<option value="230400">230400</option>
|
||||
<option value="460800">460800</option>
|
||||
<option value="921600">921600</option>
|
||||
</select>
|
||||
<label
|
||||
for="input-font-size"
|
||||
class="toolbar-input-label"
|
||||
>
|
||||
Font Size:
|
||||
</label>
|
||||
<div
|
||||
id="button-font-size-minus"
|
||||
class="toolbar-button corner"
|
||||
>
|
||||
−
|
||||
</div>
|
||||
<input
|
||||
id="input-font-size"
|
||||
class="toolbar-input"
|
||||
type="number"
|
||||
min="10"
|
||||
max="40"
|
||||
/>
|
||||
<div
|
||||
id="button-font-size-plus"
|
||||
class="toolbar-button toolbar-space"
|
||||
>
|
||||
+
|
||||
</div>
|
||||
<div class="toolbar-spacer"></div>
|
||||
<button
|
||||
id="button-ctrl-c"
|
||||
class="toolbar-button toolbar-space on-connected-show corner"
|
||||
>
|
||||
Ctrl+C
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
id="button-ctrl-d"
|
||||
class="toolbar-button toolbar-space on-connected-show corner"
|
||||
>
|
||||
Ctrl+D
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
id="button-scroll-to-bottom"
|
||||
class="toolbar-button on-connected-show corner"
|
||||
>
|
||||
Scroll to bottom
|
||||
</button>
|
||||
</div>
|
||||
<div id="main">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 100 100"
|
||||
class="terminal-background"
|
||||
>
|
||||
<text
|
||||
id="terminal-background-text"
|
||||
x="50%"
|
||||
y="50%"
|
||||
dominant-baseline="middle"
|
||||
text-anchor="middle"
|
||||
font-size="10"
|
||||
fill="gray"
|
||||
style="opacity: 0.1"
|
||||
></text>
|
||||
</svg>
|
||||
<div id="terminal-container"></div>
|
||||
</div>
|
||||
<div id="data-table-info">
|
||||
<div class="data-table-info-cell">
|
||||
<div class="data-table-info-label">Locked</div>
|
||||
<div class="data-table-info-value">
|
||||
<svg
|
||||
id="data-table-info-lock"
|
||||
fill="red"
|
||||
height="22px"
|
||||
width="22px"
|
||||
viewBox="0 0 330 330"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="m 65,325 h 200 c 8,0 15,-6 15,-15 v -170 c 0,-8 -6,-15 -15,-15 H 250 V 89 c 0,-46 -38,-85 -85,-85 -46,0 -85,38 -85,85 v 35 H 65 c -8,0 -15,6 -15,15 v 170 c 0,8 6,15 15,15 z m 117,-93 v 23 c 0,9 -8,17 -17,17 -9,0 -17,-7 -17,-17 V 232 C 139,227 135,218 135,209 c 0,-16 13,-29 29,-29 16,0 29,13 29,29 0,9 -4,17 -11,23 z M 110,89 c 0,-30 24,-55 55,-55 30,0 55,24 55,55 v 35 H 110 Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<div class="data-table-info-cell">
|
||||
<div class="data-table-info-label">Direction</div>
|
||||
<div
|
||||
id="data-table-info-direction"
|
||||
class="data-table-info-value"
|
||||
></div>
|
||||
</div>
|
||||
<div class="data-table-info-cell">
|
||||
<div class="data-table-info-label">HEX</div>
|
||||
<div
|
||||
id="data-table-info-hex"
|
||||
class="data-table-info-value"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
<div class="data-table-info-cell">
|
||||
<div class="data-table-info-label">DEC</div>
|
||||
<div
|
||||
id="data-table-info-dec"
|
||||
class="data-table-info-value"
|
||||
></div>
|
||||
</div>
|
||||
<div class="data-table-info-cell">
|
||||
<div class="data-table-info-label">BIN</div>
|
||||
<div
|
||||
id="data-table-info-bin"
|
||||
class="data-table-info-value"
|
||||
></div>
|
||||
</div>
|
||||
<div class="data-table-info-cell">
|
||||
<div class="data-table-info-label">ASCII</div>
|
||||
<div
|
||||
id="data-table-info-ascii"
|
||||
class="data-table-info-value"
|
||||
></div>
|
||||
</div>
|
||||
<div class="data-table-info-cell">
|
||||
<div class="data-table-info-label">Info</div>
|
||||
<div
|
||||
id="data-table-info-detail"
|
||||
class="data-table-info-value"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="data-tables">
|
||||
<div id="data-table-hex"></div>
|
||||
<div id="data-table-ascii"></div>
|
||||
</div>
|
||||
<div id="about">
|
||||
WebSerial TERMINAL - <small>version 1.0.0</small><br /><br />
|
||||
|
||||
is a terminal emulator that allows you to connect to a serial device from your web browser.<br /><br />
|
||||
|
||||
Based on the
|
||||
<a
|
||||
href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Serial_API"
|
||||
target="_blank"
|
||||
>WebSerial API</a
|
||||
>
|
||||
and
|
||||
<a
|
||||
href="https://xtermjs.org/"
|
||||
target="_blank"
|
||||
>xterm.js</a
|
||||
><br /><br />
|
||||
|
||||
Author:
|
||||
<a
|
||||
href="https://github.com/peterbay"
|
||||
target=""
|
||||
>Peter Bay</a
|
||||
><br /><br />
|
||||
|
||||
Licence: MIT<br /><br />
|
||||
|
||||
Repository: Github -
|
||||
<a
|
||||
href="https://github.com/peterbay/webserial-terminal"
|
||||
target="_blank"
|
||||
>peterbay/webserial-terminal</a
|
||||
>
|
||||
</div>
|
||||
<div id="bottom-bar">
|
||||
<div class="toolbar-icons toolbar-space">
|
||||
<svg
|
||||
class="toolbar-svg-icon"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 400 400"
|
||||
style="margin-top: -3px"
|
||||
>
|
||||
<style>
|
||||
.cls-2 {
|
||||
fill: none;
|
||||
stroke: #313131;
|
||||
stroke-width: 30;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-dasharray: none;
|
||||
}
|
||||
</style>
|
||||
<g class="cls-2">
|
||||
<path
|
||||
d="M 170,116 H 283 V 63 l 95,94 -96,97 v -55 h -79"
|
||||
id="svg-to-device"
|
||||
/>
|
||||
<path
|
||||
d="M 228,283 H 117 V 336 L 20,241 117,145 v 53 h 85"
|
||||
id="svg-from-device"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg
|
||||
class="toolbar-svg-icon"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 400 400"
|
||||
>
|
||||
<g class="cls-2">
|
||||
<path
|
||||
d="M 155 66 L 155 112 L 155 66 z M 200 66 L 200 112 L 200 66 z M 245 66 L 245 112 L 245 66 z M 115 115 L 115 284 L 284 284 L 284 115 L 115 115 z M 66 153 L 112 153 L 66 153 z M 287 153 L 333 153 L 287 153 z M 66 198 L 112 198 L 66 198 z M 287 198 L 333 198 L 287 198 z M 66 243 L 112 243 L 66 243 z M 287 243 L 333 243 L 287 243 z M 155 286 L 155 333 L 155 286 z M 200 286 L 200 333 L 200 286 z M 245 286 L 245 333 L 245 286 z"
|
||||
id="svg-device"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
<span id="transfer-stats"></span>
|
||||
<div class="toolbar-spacer"></div>
|
||||
<button
|
||||
type="button"
|
||||
id="button-show-about"
|
||||
class="toolbar-button corner toolbar-space"
|
||||
>
|
||||
About TERMINAL
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
id="button-reset-stats"
|
||||
class="toolbar-button corner toolbar-space"
|
||||
>
|
||||
Reset Stats
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
id="button-show-buffer"
|
||||
class="toolbar-button corner"
|
||||
>
|
||||
Show Buffer
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@xterm/xterm@5.5.0/lib/xterm.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/@xterm/addon-fit@0.10.0/lib/addon-fit.js"></script>
|
||||
<script src="./assets/js/config.js"></script>
|
||||
<script src="./assets/js/io-buffer.js"></script>
|
||||
<script src="./assets/js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
822
yarn.lock
Normal file
822
yarn.lock
Normal file
@@ -0,0 +1,822 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@eslint-community/eslint-utils@^4.2.0":
|
||||
version "4.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz#d1145bf2c20132d6400495d6df4bf59362fd9d56"
|
||||
integrity sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==
|
||||
dependencies:
|
||||
eslint-visitor-keys "^3.4.3"
|
||||
|
||||
"@eslint-community/regexpp@^4.12.1":
|
||||
version "4.12.1"
|
||||
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0"
|
||||
integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==
|
||||
|
||||
"@eslint/config-array@^0.20.0":
|
||||
version "0.20.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.20.0.tgz#7a1232e82376712d3340012a2f561a2764d1988f"
|
||||
integrity sha512-fxlS1kkIjx8+vy2SjuCB94q3htSNrufYTXubwiBFeaQHbH6Ipi43gFJq2zCMt6PHhImH3Xmr0NksKDvchWlpQQ==
|
||||
dependencies:
|
||||
"@eslint/object-schema" "^2.1.6"
|
||||
debug "^4.3.1"
|
||||
minimatch "^3.1.2"
|
||||
|
||||
"@eslint/config-helpers@^0.2.0":
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.2.1.tgz#26042c028d1beee5ce2235a7929b91c52651646d"
|
||||
integrity sha512-RI17tsD2frtDu/3dmI7QRrD4bedNKPM08ziRYaC5AhkGrzIAJelm9kJU1TznK+apx6V+cqRz8tfpEeG3oIyjxw==
|
||||
|
||||
"@eslint/core@^0.12.0":
|
||||
version "0.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.12.0.tgz#5f960c3d57728be9f6c65bd84aa6aa613078798e"
|
||||
integrity sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.15"
|
||||
|
||||
"@eslint/core@^0.13.0":
|
||||
version "0.13.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.13.0.tgz#bf02f209846d3bf996f9e8009db62df2739b458c"
|
||||
integrity sha512-yfkgDw1KR66rkT5A8ci4irzDysN7FRpq3ttJolR88OqQikAWqwA8j5VZyas+vjyBNFIJ7MfybJ9plMILI2UrCw==
|
||||
dependencies:
|
||||
"@types/json-schema" "^7.0.15"
|
||||
|
||||
"@eslint/eslintrc@^3.3.1":
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.3.1.tgz#e55f7f1dd400600dd066dbba349c4c0bac916964"
|
||||
integrity sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==
|
||||
dependencies:
|
||||
ajv "^6.12.4"
|
||||
debug "^4.3.2"
|
||||
espree "^10.0.1"
|
||||
globals "^14.0.0"
|
||||
ignore "^5.2.0"
|
||||
import-fresh "^3.2.1"
|
||||
js-yaml "^4.1.0"
|
||||
minimatch "^3.1.2"
|
||||
strip-json-comments "^3.1.1"
|
||||
|
||||
"@eslint/js@9.24.0":
|
||||
version "9.24.0"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.24.0.tgz#685277980bb7bf84ecc8e4e133ccdda7545a691e"
|
||||
integrity sha512-uIY/y3z0uvOGX8cp1C2fiC4+ZmBhp6yZWkojtHL1YEMnRt1Y63HB9TM17proGEmeG7HeUY+UP36F0aknKYTpYA==
|
||||
|
||||
"@eslint/object-schema@^2.1.6":
|
||||
version "2.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.6.tgz#58369ab5b5b3ca117880c0f6c0b0f32f6950f24f"
|
||||
integrity sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==
|
||||
|
||||
"@eslint/plugin-kit@^0.2.7":
|
||||
version "0.2.8"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.8.tgz#47488d8f8171b5d4613e833313f3ce708e3525f8"
|
||||
integrity sha512-ZAoA40rNMPwSm+AeHpCq8STiNAwzWLJuP8Xv4CHIc9wv/PSuExjMrmjfYNj682vW0OOiZ1HKxzvjQr9XZIisQA==
|
||||
dependencies:
|
||||
"@eslint/core" "^0.13.0"
|
||||
levn "^0.4.1"
|
||||
|
||||
"@humanfs/core@^0.19.1":
|
||||
version "0.19.1"
|
||||
resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77"
|
||||
integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==
|
||||
|
||||
"@humanfs/node@^0.16.6":
|
||||
version "0.16.6"
|
||||
resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.6.tgz#ee2a10eaabd1131987bf0488fd9b820174cd765e"
|
||||
integrity sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==
|
||||
dependencies:
|
||||
"@humanfs/core" "^0.19.1"
|
||||
"@humanwhocodes/retry" "^0.3.0"
|
||||
|
||||
"@humanwhocodes/module-importer@^1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
|
||||
integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
|
||||
|
||||
"@humanwhocodes/retry@^0.3.0":
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a"
|
||||
integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==
|
||||
|
||||
"@humanwhocodes/retry@^0.4.2":
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.2.tgz#1860473de7dfa1546767448f333db80cb0ff2161"
|
||||
integrity sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==
|
||||
|
||||
"@jridgewell/gen-mapping@^0.3.5":
|
||||
version "0.3.5"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36"
|
||||
integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==
|
||||
dependencies:
|
||||
"@jridgewell/set-array" "^1.2.1"
|
||||
"@jridgewell/sourcemap-codec" "^1.4.10"
|
||||
"@jridgewell/trace-mapping" "^0.3.24"
|
||||
|
||||
"@jridgewell/resolve-uri@^3.1.0":
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6"
|
||||
integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
|
||||
|
||||
"@jridgewell/set-array@^1.2.1":
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280"
|
||||
integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==
|
||||
|
||||
"@jridgewell/source-map@^0.3.3":
|
||||
version "0.3.6"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.6.tgz#9d71ca886e32502eb9362c9a74a46787c36df81a"
|
||||
integrity sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==
|
||||
dependencies:
|
||||
"@jridgewell/gen-mapping" "^0.3.5"
|
||||
"@jridgewell/trace-mapping" "^0.3.25"
|
||||
|
||||
"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a"
|
||||
integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
|
||||
|
||||
"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25":
|
||||
version "0.3.25"
|
||||
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0"
|
||||
integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==
|
||||
dependencies:
|
||||
"@jridgewell/resolve-uri" "^3.1.0"
|
||||
"@jridgewell/sourcemap-codec" "^1.4.14"
|
||||
|
||||
"@types/estree@^1.0.6":
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50"
|
||||
integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==
|
||||
|
||||
"@types/json-schema@^7.0.15":
|
||||
version "7.0.15"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
|
||||
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
|
||||
|
||||
acorn-jsx@^5.3.2:
|
||||
version "5.3.2"
|
||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
||||
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
|
||||
|
||||
acorn@^8.12.0:
|
||||
version "8.14.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.0.tgz#063e2c70cac5fb4f6467f0b11152e04c682795b0"
|
||||
integrity sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==
|
||||
|
||||
acorn@^8.14.0:
|
||||
version "8.14.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb"
|
||||
integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==
|
||||
|
||||
acorn@^8.8.2:
|
||||
version "8.13.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.13.0.tgz#2a30d670818ad16ddd6a35d3842dacec9e5d7ca3"
|
||||
integrity sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==
|
||||
|
||||
ajv@^6.12.4:
|
||||
version "6.12.6"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
|
||||
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
|
||||
dependencies:
|
||||
fast-deep-equal "^3.1.1"
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
json-schema-traverse "^0.4.1"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
ansi-styles@^4.1.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
|
||||
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
|
||||
dependencies:
|
||||
color-convert "^2.0.1"
|
||||
|
||||
argparse@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
|
||||
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
|
||||
|
||||
asynckit@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
|
||||
|
||||
axios@^1.8.4:
|
||||
version "1.8.4"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-1.8.4.tgz#78990bb4bc63d2cae072952d374835950a82f447"
|
||||
integrity sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==
|
||||
dependencies:
|
||||
follow-redirects "^1.15.6"
|
||||
form-data "^4.0.0"
|
||||
proxy-from-env "^1.1.0"
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
buffer-from@^1.0.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
|
||||
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
|
||||
|
||||
callsites@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
|
||||
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
|
||||
|
||||
camel-case@^4.1.2:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a"
|
||||
integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==
|
||||
dependencies:
|
||||
pascal-case "^3.1.2"
|
||||
tslib "^2.0.3"
|
||||
|
||||
chalk@^4.0.0:
|
||||
version "4.1.2"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
||||
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
||||
dependencies:
|
||||
ansi-styles "^4.1.0"
|
||||
supports-color "^7.1.0"
|
||||
|
||||
clean-css@~5.3.2:
|
||||
version "5.3.3"
|
||||
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.3.tgz#b330653cd3bd6b75009cc25c714cae7b93351ccd"
|
||||
integrity sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==
|
||||
dependencies:
|
||||
source-map "~0.6.0"
|
||||
|
||||
color-convert@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
|
||||
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
|
||||
dependencies:
|
||||
color-name "~1.1.4"
|
||||
|
||||
color-name@~1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||
|
||||
combined-stream@^1.0.8:
|
||||
version "1.0.8"
|
||||
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
|
||||
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
|
||||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
commander@^10.0.0:
|
||||
version "10.0.1"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06"
|
||||
integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==
|
||||
|
||||
commander@^2.20.0:
|
||||
version "2.20.3"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
||||
|
||||
cross-spawn@^7.0.6:
|
||||
version "7.0.6"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
|
||||
integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
|
||||
dependencies:
|
||||
path-key "^3.1.0"
|
||||
shebang-command "^2.0.0"
|
||||
which "^2.0.1"
|
||||
|
||||
debug@^4.3.1, debug@^4.3.2:
|
||||
version "4.3.7"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52"
|
||||
integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==
|
||||
dependencies:
|
||||
ms "^2.1.3"
|
||||
|
||||
deep-is@^0.1.3:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
|
||||
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
|
||||
|
||||
delayed-stream@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
|
||||
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
|
||||
|
||||
dot-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751"
|
||||
integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==
|
||||
dependencies:
|
||||
no-case "^3.0.4"
|
||||
tslib "^2.0.3"
|
||||
|
||||
entities@^4.4.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
|
||||
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
|
||||
|
||||
escape-string-regexp@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
|
||||
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
|
||||
|
||||
eslint-scope@^8.3.0:
|
||||
version "8.3.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.3.0.tgz#10cd3a918ffdd722f5f3f7b5b83db9b23c87340d"
|
||||
integrity sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==
|
||||
dependencies:
|
||||
esrecurse "^4.3.0"
|
||||
estraverse "^5.2.0"
|
||||
|
||||
eslint-visitor-keys@^3.4.3:
|
||||
version "3.4.3"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800"
|
||||
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
|
||||
|
||||
eslint-visitor-keys@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz#1f785cc5e81eb7534523d85922248232077d2f8c"
|
||||
integrity sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==
|
||||
|
||||
eslint-visitor-keys@^4.2.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45"
|
||||
integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==
|
||||
|
||||
eslint@^9.24.0:
|
||||
version "9.24.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.24.0.tgz#9a7f2e6cb2de81c405ab244b02f4584c79dc6bee"
|
||||
integrity sha512-eh/jxIEJyZrvbWRe4XuVclLPDYSYYYgLy5zXGGxD6j8zjSAxFEzI2fL/8xNq6O2yKqVt+eF2YhV+hxjV6UKXwQ==
|
||||
dependencies:
|
||||
"@eslint-community/eslint-utils" "^4.2.0"
|
||||
"@eslint-community/regexpp" "^4.12.1"
|
||||
"@eslint/config-array" "^0.20.0"
|
||||
"@eslint/config-helpers" "^0.2.0"
|
||||
"@eslint/core" "^0.12.0"
|
||||
"@eslint/eslintrc" "^3.3.1"
|
||||
"@eslint/js" "9.24.0"
|
||||
"@eslint/plugin-kit" "^0.2.7"
|
||||
"@humanfs/node" "^0.16.6"
|
||||
"@humanwhocodes/module-importer" "^1.0.1"
|
||||
"@humanwhocodes/retry" "^0.4.2"
|
||||
"@types/estree" "^1.0.6"
|
||||
"@types/json-schema" "^7.0.15"
|
||||
ajv "^6.12.4"
|
||||
chalk "^4.0.0"
|
||||
cross-spawn "^7.0.6"
|
||||
debug "^4.3.2"
|
||||
escape-string-regexp "^4.0.0"
|
||||
eslint-scope "^8.3.0"
|
||||
eslint-visitor-keys "^4.2.0"
|
||||
espree "^10.3.0"
|
||||
esquery "^1.5.0"
|
||||
esutils "^2.0.2"
|
||||
fast-deep-equal "^3.1.3"
|
||||
file-entry-cache "^8.0.0"
|
||||
find-up "^5.0.0"
|
||||
glob-parent "^6.0.2"
|
||||
ignore "^5.2.0"
|
||||
imurmurhash "^0.1.4"
|
||||
is-glob "^4.0.0"
|
||||
json-stable-stringify-without-jsonify "^1.0.1"
|
||||
lodash.merge "^4.6.2"
|
||||
minimatch "^3.1.2"
|
||||
natural-compare "^1.4.0"
|
||||
optionator "^0.9.3"
|
||||
|
||||
espree@^10.0.1:
|
||||
version "10.2.0"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-10.2.0.tgz#f4bcead9e05b0615c968e85f83816bc386a45df6"
|
||||
integrity sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==
|
||||
dependencies:
|
||||
acorn "^8.12.0"
|
||||
acorn-jsx "^5.3.2"
|
||||
eslint-visitor-keys "^4.1.0"
|
||||
|
||||
espree@^10.3.0:
|
||||
version "10.3.0"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-10.3.0.tgz#29267cf5b0cb98735b65e64ba07e0ed49d1eed8a"
|
||||
integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==
|
||||
dependencies:
|
||||
acorn "^8.14.0"
|
||||
acorn-jsx "^5.3.2"
|
||||
eslint-visitor-keys "^4.2.0"
|
||||
|
||||
esquery@^1.5.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7"
|
||||
integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==
|
||||
dependencies:
|
||||
estraverse "^5.1.0"
|
||||
|
||||
esrecurse@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
|
||||
integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
|
||||
dependencies:
|
||||
estraverse "^5.2.0"
|
||||
|
||||
estraverse@^5.1.0, estraverse@^5.2.0:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
|
||||
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
|
||||
|
||||
esutils@^2.0.2:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
||||
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
||||
|
||||
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||
|
||||
fast-json-stable-stringify@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
|
||||
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
|
||||
|
||||
fast-levenshtein@^2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
|
||||
|
||||
file-entry-cache@^8.0.0:
|
||||
version "8.0.0"
|
||||
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f"
|
||||
integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==
|
||||
dependencies:
|
||||
flat-cache "^4.0.0"
|
||||
|
||||
find-up@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
|
||||
integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
|
||||
dependencies:
|
||||
locate-path "^6.0.0"
|
||||
path-exists "^4.0.0"
|
||||
|
||||
flat-cache@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c"
|
||||
integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==
|
||||
dependencies:
|
||||
flatted "^3.2.9"
|
||||
keyv "^4.5.4"
|
||||
|
||||
flatted@^3.2.9:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a"
|
||||
integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==
|
||||
|
||||
follow-redirects@^1.15.6:
|
||||
version "1.15.9"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1"
|
||||
integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==
|
||||
|
||||
form-data@^4.0.0:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.1.tgz#ba1076daaaa5bfd7e99c1a6cb02aa0a5cff90d48"
|
||||
integrity sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==
|
||||
dependencies:
|
||||
asynckit "^0.4.0"
|
||||
combined-stream "^1.0.8"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
glob-parent@^6.0.2:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
|
||||
integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
|
||||
dependencies:
|
||||
is-glob "^4.0.3"
|
||||
|
||||
globals@^14.0.0:
|
||||
version "14.0.0"
|
||||
resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e"
|
||||
integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==
|
||||
|
||||
has-flag@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
|
||||
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
|
||||
|
||||
html-minifier-terser@^7.2.0:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-7.2.0.tgz#18752e23a2f0ed4b0f550f217bb41693e975b942"
|
||||
integrity sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==
|
||||
dependencies:
|
||||
camel-case "^4.1.2"
|
||||
clean-css "~5.3.2"
|
||||
commander "^10.0.0"
|
||||
entities "^4.4.0"
|
||||
param-case "^3.0.4"
|
||||
relateurl "^0.2.7"
|
||||
terser "^5.15.1"
|
||||
|
||||
ignore@^5.2.0:
|
||||
version "5.3.2"
|
||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5"
|
||||
integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==
|
||||
|
||||
import-fresh@^3.2.1:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
|
||||
integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
|
||||
dependencies:
|
||||
parent-module "^1.0.0"
|
||||
resolve-from "^4.0.0"
|
||||
|
||||
imurmurhash@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
|
||||
integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
|
||||
|
||||
is-extglob@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
|
||||
|
||||
is-glob@^4.0.0, is-glob@^4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
|
||||
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
|
||||
dependencies:
|
||||
is-extglob "^2.1.1"
|
||||
|
||||
isexe@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
|
||||
|
||||
js-yaml@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
|
||||
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
|
||||
dependencies:
|
||||
argparse "^2.0.1"
|
||||
|
||||
json-buffer@3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
|
||||
integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
|
||||
|
||||
json-schema-traverse@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
|
||||
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
|
||||
|
||||
json-stable-stringify-without-jsonify@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
|
||||
integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
|
||||
|
||||
keyv@^4.5.4:
|
||||
version "4.5.4"
|
||||
resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93"
|
||||
integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==
|
||||
dependencies:
|
||||
json-buffer "3.0.1"
|
||||
|
||||
levn@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
|
||||
integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==
|
||||
dependencies:
|
||||
prelude-ls "^1.2.1"
|
||||
type-check "~0.4.0"
|
||||
|
||||
locate-path@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
|
||||
integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==
|
||||
dependencies:
|
||||
p-locate "^5.0.0"
|
||||
|
||||
lodash.merge@^4.6.2:
|
||||
version "4.6.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
||||
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
||||
|
||||
lower-case@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28"
|
||||
integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==
|
||||
dependencies:
|
||||
tslib "^2.0.3"
|
||||
|
||||
mime-db@1.52.0:
|
||||
version "1.52.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
|
||||
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
|
||||
|
||||
mime-types@^2.1.12:
|
||||
version "2.1.35"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
|
||||
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
|
||||
dependencies:
|
||||
mime-db "1.52.0"
|
||||
|
||||
minimatch@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
|
||||
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
ms@^2.1.3:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||
|
||||
natural-compare@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
|
||||
|
||||
no-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d"
|
||||
integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==
|
||||
dependencies:
|
||||
lower-case "^2.0.2"
|
||||
tslib "^2.0.3"
|
||||
|
||||
optionator@^0.9.3:
|
||||
version "0.9.4"
|
||||
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734"
|
||||
integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==
|
||||
dependencies:
|
||||
deep-is "^0.1.3"
|
||||
fast-levenshtein "^2.0.6"
|
||||
levn "^0.4.1"
|
||||
prelude-ls "^1.2.1"
|
||||
type-check "^0.4.0"
|
||||
word-wrap "^1.2.5"
|
||||
|
||||
p-limit@^3.0.2:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
|
||||
integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
|
||||
dependencies:
|
||||
yocto-queue "^0.1.0"
|
||||
|
||||
p-locate@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
|
||||
integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
|
||||
dependencies:
|
||||
p-limit "^3.0.2"
|
||||
|
||||
param-case@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5"
|
||||
integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==
|
||||
dependencies:
|
||||
dot-case "^3.0.4"
|
||||
tslib "^2.0.3"
|
||||
|
||||
parent-module@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
|
||||
integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
|
||||
dependencies:
|
||||
callsites "^3.0.0"
|
||||
|
||||
pascal-case@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb"
|
||||
integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==
|
||||
dependencies:
|
||||
no-case "^3.0.4"
|
||||
tslib "^2.0.3"
|
||||
|
||||
path-exists@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
|
||||
integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
|
||||
|
||||
path-key@^3.1.0:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
|
||||
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
||||
|
||||
prelude-ls@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
||||
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
|
||||
|
||||
proxy-from-env@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
|
||||
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
|
||||
|
||||
punycode@^2.1.0:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
|
||||
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
|
||||
|
||||
relateurl@^0.2.7:
|
||||
version "0.2.7"
|
||||
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
|
||||
integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==
|
||||
|
||||
resolve-from@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
|
||||
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
|
||||
|
||||
shebang-command@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
|
||||
integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
|
||||
dependencies:
|
||||
shebang-regex "^3.0.0"
|
||||
|
||||
shebang-regex@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
|
||||
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
||||
|
||||
source-map-support@~0.5.20:
|
||||
version "0.5.21"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
|
||||
integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
|
||||
dependencies:
|
||||
buffer-from "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
|
||||
source-map@^0.6.0, source-map@~0.6.0:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||
|
||||
strip-json-comments@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
|
||||
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
|
||||
|
||||
supports-color@^7.1.0:
|
||||
version "7.2.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
|
||||
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
|
||||
dependencies:
|
||||
has-flag "^4.0.0"
|
||||
|
||||
terser@^5.15.1:
|
||||
version "5.36.0"
|
||||
resolved "https://registry.yarnpkg.com/terser/-/terser-5.36.0.tgz#8b0dbed459ac40ff7b4c9fd5a3a2029de105180e"
|
||||
integrity sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==
|
||||
dependencies:
|
||||
"@jridgewell/source-map" "^0.3.3"
|
||||
acorn "^8.8.2"
|
||||
commander "^2.20.0"
|
||||
source-map-support "~0.5.20"
|
||||
|
||||
tslib@^2.0.3:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.0.tgz#d124c86c3c05a40a91e6fdea4021bd31d377971b"
|
||||
integrity sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==
|
||||
|
||||
type-check@^0.4.0, type-check@~0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
|
||||
integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==
|
||||
dependencies:
|
||||
prelude-ls "^1.2.1"
|
||||
|
||||
uri-js@^4.2.2:
|
||||
version "4.4.1"
|
||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
|
||||
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
|
||||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
|
||||
which@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
|
||||
integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
word-wrap@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34"
|
||||
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
|
||||
|
||||
yocto-queue@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
|
||||
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
|
||||
Reference in New Issue
Block a user