diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/docs/_command-template.md b/docs/_command-template.md new file mode 100644 index 0000000..31bb836 --- /dev/null +++ b/docs/_command-template.md @@ -0,0 +1,26 @@ +# Command documentation template + +Use this template to create or standardize a command/function page in the documentation. Every command page must follow the structure below and include one representative, runnable example for a generic MSX. + +Description +- Provide a concise explanation of what the command or function does and where it is typically used. + +Syntax +> Show the formal syntax and list the parameters with short descriptions. + +Example program +- Add a single, clear example program that can be executed on a generic MSX. Include a link to the example `.BAS` file stored in the `examples/` directory. + +```basic +10 REM Example program for COMMAND_NAME +20 REM Add your code here +30 END +``` + +Explanation +- Step-by-step explanation of what the example does and what to expect when running it on a generic MSX. + +See also +- Link to related commands or examples. + +[<< Back](./index.md) diff --git a/docs/chrs.md b/docs/chrs.md index b324b4d..ad3150a 100644 --- a/docs/chrs.md +++ b/docs/chrs.md @@ -1,13 +1,18 @@ ### CHR$ -The CHR$ **function** in MSX BASIC is used to convert an ASCII code (a number) into its corresponding character. This function is useful when you need to display special characters or control codes that are not easily typed from the keyboard. -#### Syntax ->CHR$(`number`) +Description -An integer value between 0 and 255 representing the ASCII code of the character you want to display. +CHR$ is a function that returns the character corresponding to a numeric code. It is commonly used to display special characters or control codes that cannot be typed directly from the keyboard. -#### Example Program -The following MSX BASIC program prints all available ASCII characters (from 0 to 255) on the screen: +Syntax + +> CHR$(number) + +- `number` — Integer code of the character (typical range 0–255). The function returns a one-character string. + +Example program + +- Example file: `../examples/CHRS/LIST-ALL-CHARS.BAS` ```basic 10 FOR I = 0 TO 255 @@ -16,8 +21,8 @@ The following MSX BASIC program prints all available ASCII characters (from 0 to 40 END ``` -This program uses a `FOR` loop to iterate through all ASCII codes from 0 to 255, converting each code to its corresponding character using the `CHR$` function and printing it on the screen. +Explanation -The semicolon (;) at the end of the `PRINT` statement ensures that the characters are printed on the same line. +This program iterates through numeric character codes from 0 to 255 and prints the character returned by `CHR$` for each code. The semicolon after `PRINT` keeps output on the same line. Note that many codes correspond to non-printable control characters and may affect the display or cursor position; the output will vary depending on the MSX text mode and the emulator or hardware. -[<< Back](./index.md) \ No newline at end of file +[<< Back](./index.md) diff --git a/docs/circle.md b/docs/circle.md new file mode 100644 index 0000000..112b3f9 --- /dev/null +++ b/docs/circle.md @@ -0,0 +1,33 @@ +### CIRCLE + +Description + +`CIRCLE` draws a circle, arc, or ellipse on a graphics screen. It supports radius, optional tracing angles to draw arcs, and an aspect ratio parameter to stretch horizontally or vertically. + +Syntax + +> CIRCLE [STEP](X,Y), radius [, color [, tracingStart [, tracingEnd [, aspect]]]] + +- `X,Y` — Center coordinates. +- `radius` — Radius of the main axis. +- `color` — Optional color index. +- `tracingStart`, `tracingEnd` — Angles in radians (0..2π) to draw partial arcs. +- `aspect` — Aspect ratio for ellipse drawing. + +Example — multiple concentric circles/ellipses + +- Example file: `../examples/CIRCLE/CIRCLE-DEMO.BAS` + +```basic +10 SCREEN 2: COLOR 15,1,7: CLS +20 FOR R = 10 TO 80 STEP 10 +30 CIRCLE (127,95), R, INT(R/10) + 1 +40 NEXT R +50 GOTO 50 +``` + +Explanation + +This program draws several circles of increasing radius centered at `(127,95)` using different colors. The `aspect` parameter is omitted; on some machines (PAL vs NTSC) the same radius may appear slightly stretched. + +[<< Back](./index.md) diff --git a/docs/close.md b/docs/close.md new file mode 100644 index 0000000..3d41a60 --- /dev/null +++ b/docs/close.md @@ -0,0 +1,30 @@ +### CLOSE + +Description + +`CLOSE` closes open file handles and releases associated I/O buffers. Without parameters it closes all open files. Closing files ensures data is flushed to the device. + +Syntax + +> CLOSE [#file1, #file2, ...] + +- `#fileN` — File handle(s) previously assigned by `OPEN`. When omitted all opened files are closed. + +Example + +```basic +10 MAXFILES = 2 +20 OPEN "CAS:DEMO" FOR INPUT AS #1 +30 OPEN "LPT:" FOR OUTPUT AS #2 +40 INPUT #1, A$ +50 PRINT #2, A$ +60 CLOSE #2 +70 CLOSE #1 +80 END +``` + +Explanation + +This snippet demonstrates opening two files and closing them explicitly when finished. Closing files prevents data loss and frees file slots for new `OPEN` operations. + +[<< Back](./index.md) diff --git a/docs/cls.md b/docs/cls.md new file mode 100644 index 0000000..67949f2 --- /dev/null +++ b/docs/cls.md @@ -0,0 +1,26 @@ +### CLS + +Description + +`CLS` clears the current screen and resets the text cursor position to the top-left (implementation-dependent coordinates). It does not clear program variables. + +Syntax + +> CLS + +Example + +- Example file: `../examples/CLS/CLS-COLOR.BAS` + +```basic +10 CLS +20 COLOR 7,0,1 +30 PRINT "Screen cleared and colors set" +40 END +``` + +Explanation + +`CLS` wipes the text/graphics display region; follow with `COLOR` and `PRINT` to update the screen contents. + +[<< Back](./index.md) diff --git a/docs/color.md b/docs/color.md new file mode 100644 index 0000000..7d5bf58 --- /dev/null +++ b/docs/color.md @@ -0,0 +1,29 @@ +### COLOR + +Description + +`COLOR` configures foreground (text), background and border colors used by subsequent text and some graphics commands. Colors are specified by numeric indices (implementation palette depends on MSX generation and video mode). + +Syntax + +> COLOR foreground[, background[, border]] + +- `foreground` — Color index for text/plot color. +- `background` — Optional background color index. +- `border` — Optional border color index. + +Example + +- Example file: `../examples/COLOR/COLOR-DEMO.BAS` + +```basic +10 COLOR 7,0,1 +20 PRINT "White text, black background, blue border" +30 END +``` + +Explanation + +The example sets the text color to 7 (white), background to 0 (black) and the screen border to 1 (blue). The actual color mapping may vary by machine and mode. + +[<< Back](./index.md) diff --git a/docs/dim.md b/docs/dim.md index 7830ab2..ff8203d 100644 --- a/docs/dim.md +++ b/docs/dim.md @@ -1,14 +1,20 @@ ### DIM -The `DIM` command in MSX BASIC is used to declare and allocate memory for arrays. Arrays are used to store multiple values in a single variable, which can be accessed using an index. +Description -#### Syntax ->DIM array_name(`size`) +`DIM` reserves memory for one or more arrays and initializes the array variables. Arrays allow storing a collection of values under a single name and accessing each element by index. -- *array_name*: The name of the array. -- *size*: The number of elements in the array. +Syntax + +> DIM array_name(size) + +- `array_name` — Name of the array. +- `size` — Upper bound for the array index. For multi-dimensional arrays use multiple bounds separated by commas, e.g. `DIM A(n, m)`. + +Example program + +- Example file: `../examples/DIM/SINGLE-DIM.BAS` -#### Single-Dimensional Array ```basic 10 DIM A(5) 20 FOR I = 1 TO 5 @@ -21,25 +27,8 @@ The `DIM` command in MSX BASIC is used to declare and allocate memory for arrays 90 END ``` -This example declares a single-dimensional array A with 5 elements, reads values into the array, and prints them. - -#### Multi-Dimensional Array -```basic -10 DIM B(3, 3) -20 FOR I = 1 TO 3 -30 FOR J = 1 TO 3 -40 READ B(I, J) -50 NEXT J -60 NEXT I -70 FOR I = 1 TO 3 -80 FOR J = 1 TO 3 -90 PRINT "B("; I; ","; J; ") = "; B(I, J) -100 NEXT J -110 NEXT I -120 DATA 1, 2, 3, 4, 5, 6, 7, 8, 9 -130 END -``` +Explanation -This example declares a two-dimensional array B with 3x3 elements, reads values into the array, and prints them. +This program declares a one-dimensional array `A` and reads five values into it using `READ` and `DATA`. The second loop prints each element with its index. For multi-dimensional arrays use `DIM` with multiple bounds and access elements with multiple indices, e.g. `B(I, J)`. -[<< Back](./index.md) \ No newline at end of file +[<< Back](./index.md) diff --git a/docs/end.md b/docs/end.md new file mode 100644 index 0000000..34b675e --- /dev/null +++ b/docs/end.md @@ -0,0 +1,26 @@ +### END + +Description + +`END` terminates program execution and closes open files. Execution stops and the interpreter returns to the READY prompt. + +Syntax + +> END + +Example + +- Example file: `../examples/END/END-DEMO.BAS` + +```basic +10 PRINT "START" +20 END +30 PRINT "NEVER REACHED" +40 END +``` + +Explanation + +When the interpreter reaches line 20 (`END`) execution stops. Any statements after `END` in the program are not executed. + +[<< Back](./index.md) diff --git a/docs/for-next.md b/docs/for-next.md index 36c3931..1ddedc1 100644 --- a/docs/for-next.md +++ b/docs/for-next.md @@ -1,22 +1,33 @@ ### FOR / NEXT -The `FOR / NEXT` loop is used to execute a block of code repeatedly for a defined number of iterations. It automatically manages a counter variable, starting from an initial value, incrementing it by a specified step (default is 1), and stopping when it exceeds the specified limit. -```basic -FOR = TO [STEP ] - -NEXT +Description -``` -- Variable: A counter variable that controls the loop. -- Start: The initial value of the counter. -- End: The value at which the loop stops. -- STEP (optional): Defines the increment (positive or negative) applied to the counter after each iteration. Default is 1. +`FOR ... NEXT` is a loop structure that repeats a block of statements a fixed number of times. A counter variable advances automatically from a start value to an end value optionally using a step increment. + +Syntax + +> FOR variable = start TO end [STEP increment] +> statements +> NEXT [variable] +- `variable` — Loop counter variable. +- `start` — Initial value for the counter. +- `end` — Final value for the counter; loop stops when the counter passes this value. +- `STEP` (optional) — Signed increment applied each iteration. Default is `1`. + +Example program + +- Example file: `../examples/FOR-NEXT/LOOP.BAS` ```basic -10 FOR I = 1 TO 5 +10 FOR I = 1 TO 50 20 PRINT I 30 NEXT I +40 END ``` -[<< Back](./index.md) \ No newline at end of file +Explanation + +This example prints the numbers from 1 to 50. The loop executes the `PRINT` statement 50 times; the counter `I` is incremented automatically by 1 each iteration. To change the increment use `STEP`, e.g. `FOR I = 1 TO 50 STEP 2`. + +[<< Back](./index.md) diff --git a/docs/gosub.md b/docs/gosub.md index ca3bdef..5b0aa40 100644 --- a/docs/gosub.md +++ b/docs/gosub.md @@ -1,14 +1,34 @@ ### GOSUB / RETURN -The GOSUB command is used to call a subroutine, which is a block of code that can be executed from multiple places in the program. The RETURN command is used to return to the line following the GOSUB call. -```basic -10 GOSUB 100 -20 PRINT "Back to main program" -30 END +Description + +`GOSUB` transfers execution to a subroutine located at a specified line number. `RETURN` brings execution back to the statement following the `GOSUB` call. Subroutines help avoid duplicating code and organize functionality. + +Syntax + +> GOSUB line_number +> ... +> RETURN + +- `line_number` — The line number where the subroutine starts. -100 PRINT "In subroutine" -110 RETURN +Example program +- Example file: `../examples/GOSUB/SURFACE-CALC.BAS` + +```basic +10 PRINT "SURFACE AREA CALCULATOR" +20 INPUT "INSERT HEIGHT";A +30 INPUT "INSERT WIDTH";B +40 GOSUB 70 +50 PRINT "SURFACE AREA IS:";SURFACE +60 END +70 SURFACE = A * B +80 RETURN ``` -[<< Back](./index.md) \ No newline at end of file +Explanation + +The main program (lines 10–60) reads `A` and `B` from the user and calls the subroutine at line 70 with `GOSUB 70`. The subroutine computes `SURFACE = A * B` and uses `RETURN` to go back to the line after the `GOSUB`. The main program then prints the computed area and ends. + +[<< Back](./index.md) diff --git a/docs/goto.md b/docs/goto.md index 747886d..66d8310 100644 --- a/docs/goto.md +++ b/docs/goto.md @@ -1,12 +1,29 @@ ### GOTO -The GOTO command is used to jump to a specific line number in the program. This allows for non-linear execution of code, which can be useful for creating loops or conditional statements. +Description + +`GOTO` transfers program control to a specified line number. It can be used to create loops or to jump over sections of code, but excessive use may make programs harder to read and maintain. + +Syntax + +> GOTO line_number + +- `line_number` — The destination line number to continue execution from. + +Example program + +- Example file: `../examples/GOTO/INFINITE-PRINT.BAS` ```basic -10 A=1 +10 A = 1 20 PRINT A -30 A=A+1 +30 A = A + 1 40 GOTO 20 50 END ``` -[<< Back](./index.md) \ No newline at end of file + +Explanation + +This program demonstrates a simple loop created with `GOTO`. After printing `A`, the program increments it and jumps back to line 20, printing repeatedly. This example creates an infinite loop; on a real MSX you can interrupt the program with the system `STOP` or `BREAK` key (depending on your emulator or hardware). + +[<< Back](./index.md) diff --git a/docs/if-then.md b/docs/if-then.md new file mode 100644 index 0000000..0fda7d8 --- /dev/null +++ b/docs/if-then.md @@ -0,0 +1,45 @@ +### IF...THEN + +Description + +Conditional statement that evaluates a logical expression and executes one statement when the condition is true; an optional `ELSE` allows a single alternative statement when false. MSX BASIC typically supports single-line `IF ... THEN ... ELSE` usage. + +Syntax + +> IF condition THEN statement [ELSE statement] + +- `condition` — Boolean expression (comparisons using `=`, `<>`, `<`, `>`, `<=`, `>=`). +- `statement` — A single BASIC statement (can be `PRINT`, `GOTO`, `GOSUB`, etc.). + +Example 1 — Single-line IF with ELSE + +- Example file: `../examples/IF-THEN/IF-THEN-ELSE.BAS` + +```basic +10 REM IF...THEN...ELSE example +20 INPUT "Enter a number: "; A +30 IF A > 0 THEN PRINT "POSITIVE" ELSE PRINT "ZERO OR NEGATIVE" +40 GOTO 20 +50 END +``` + +Explanation + +Line 30 evaluates `A > 0`. If true it prints `POSITIVE`; otherwise it prints `ZERO OR NEGATIVE`. + +Example 2 — IF THEN GOTO (flow control) + +```basic +10 INPUT "Enter 0 to quit: "; N +20 IF N = 0 THEN GOTO 80 +30 PRINT "N not zero" +40 GOTO 10 +80 PRINT "Goodbye" +90 END +``` + +Explanation + +This example uses `IF ... THEN GOTO` to branch execution to a different line number when a condition is met. + +[<< Back](./index.md) diff --git a/docs/index.md b/docs/index.md index d6e13e6..16d1a7c 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,12 +1,70 @@ ## Index of commands -- [LOCATE](./locate.md) +### Basic / Output + +- [PRINT](./print.md) +- [CLS](./cls.md) +- [COLOR](./color.md) + +### Control flow & program management + +- [IF / THEN](./if-then.md) - [GOTO](./goto.md) - [FOR / NEXT](./for-next.md) -- [INPUT](./input.md) - [GOSUB / RETURN](./gosub.md) -- [READ / DATA](./read-data.md) +- [RUN](./run.md) +- [END](./end.md) +- [STOP](./stop.md) +- [NEW](./new.md) +- [LIST](./list.md) + +### Variables & assignment + +- [LET](./let.md) +- [DIM](./dim.md) + +### Input and keyboard + +- [INPUT](./input.md) - [INKEY$](./inkeys.md) + +### Display & positioning + +- [LOCATE](./locate.md) + +### Graphics + +- [SCREEN](./screen.md) +- [PSET](./pset.md) +- [PRESET](./preset.md) +- [POINT](./point.md) +- [LINE](./line.md) +- [CIRCLE](./circle.md) +- [PAINT](./paint.md) + +### Data handling + +- [READ / DATA](./read-data.md) +- [RESTORE](./read-data.md) + (see the `READ / DATA` page for `RESTORE` examples) + +### Low-level memory + +- [POKE](./poke.md) +- [PEEK](./peek.md) + +### Sound & music + +- [SOUND](./sound.md) +- [PLAY](./play.md) + +### File I/O + +- [OPEN](./open.md) +- [CLOSE](./close.md) +- [SAVE](./save.md) +- [LOAD](./load.md) + --- ## Functions @@ -15,5 +73,4 @@ - [INT](./int.md) - [RND](./rnd.md) - [<< Back](../README.md) diff --git a/docs/inkeys.md b/docs/inkeys.md index 6486edf..96b8cf7 100644 --- a/docs/inkeys.md +++ b/docs/inkeys.md @@ -1,34 +1,19 @@ ### INKEY$ -The `INKEY$` command in MSX BASIC is used to detect and return a single character from the keyboard buffer. It is often used for real-time input handling in programs, such as games or interactive applications. +Description -#### Syntax ->`variable$` = INKEY$ +`INKEY$` reads a single character from the keyboard buffer without waiting. It returns an empty string `""` if no key is pressed and is commonly used for real-time or non-blocking input (for example, in games or interactive programs). -- *variable$* is a string variable that will store the character read from the keyboard buffer. -- If no key is pressed, `INKEY$` returns an empty string (""). +Syntax -#### Loop Until Key Press -```basic -PRINT "Press any key to continue..." -DO - a$ = INKEY$ -LOOP UNTIL a$ <> "" -PRINT "You pressed: "; a$ -``` -#### Real-time Input Handling -```basic -PRINT "Press 'Q' to quit." -DO - a$ = INKEY$ - IF a$ = "Q" OR a$ = "q" THEN EXIT DO -LOOP -PRINT "Program terminated." -``` +> variable$ = INKEY$ + +- `variable$` — String variable that receives the pressed key (single character) or `""` if no key is available. + +Example program -In these examples, INKEY$ is used to capture and respond to user input immediately, making it a powerful tool for interactive MSX BASIC programs. ``` +- Example file: `../examples/INKEYS/MOVE-CHAR-SCREEN.BAS` -### Draw with the `@` Character on the Screen ```basic 10 SCREEN 0: WIDTH 40 20 LOCATE 10, 10: PRINT "@" @@ -45,18 +30,9 @@ In these examples, INKEY$ is used to capture and respond to user input immediate 130 LOCATE x, y: PRINT "@" 140 GOTO 40 ``` -#### Initialize Screen and Position: -- **Line 10**: Set the screen mode to text mode (SCREEN 0) and set the width to 40 columns. -- **Line 20**: Place the `@` character at the initial position (10, 10). -- **Line 30**: Initialize the variables x and y to store the current position of the @ character. -Main Loop: -- **Line 40**: Read a key press using INKEY$. -- **Lines 50-80**: Update the position based on the key pressed (W, S, A, D). -- **Lines 90-120**: Ensure the @ character stays within the screen boundaries. -- **Line 130**: Move the @ character to the new position. -- **Line 140**: Repeat the loop to continuously check for key presses and update the position. +Explanation -This code will allow you to move the `@` character around the screen using the specified keys. ``` +This interactive example places an `@` character on screen and lets the user move it using `W`, `A`, `S`, `D` keys. The program reads keyboard input using `INKEY$` and updates the position without blocking. It also limits the position so the character stays inside a 40x24 text area. To stop the program press the emulator's STOP/BREAK key or close the session. -[<< Back](./index.md) \ No newline at end of file +[<< Back](./index.md) diff --git a/docs/input.md b/docs/input.md index a67ab98..62babbc 100644 --- a/docs/input.md +++ b/docs/input.md @@ -1,23 +1,45 @@ ### INPUT -The INPUT command is used to receive user input during program execution. It allows the program to store the input value in a variable for further processing. + +Description + +`INPUT` retrieves one or more values from the keyboard (interactive) or from a sequential file when used with file redirection. It is used to prompt the user and store typed values into variables. + +Syntax + +> INPUT ["prompt";] var1[, var2, ...] + +- `"prompt"` — Optional prompt text shown before waiting for input. When present, put a semicolon (`;`) after the prompt to keep the cursor on the same line. +- `var1, var2, ...` — One or more variables that receive the entered values. Use string variables (ending with `$`) for text. + +Example 1 — Read a name (string) ```basic -INPUT "Prompt message: "; Variable +10 INPUT "Enter your name: "; Name$ +20 PRINT "Hello, "; Name$ +30 END ``` -- **Prompt message**: The text displayed to the user, explaining what input is expected. -- **Variable**: The variable where the user’s input is stored. String variables typically end with $ (e.g., Name$ for text). +Explanation -#### Example +Line 10 prints the prompt and waits for the user to type a name. The entered text is stored in `Name$`. Line 20 prints a greeting using the value stored in `Name$`. + +Example 2 — Numeric input and using an example file + +- Example file: `../examples/INPUT/MULTIPLY-5.BAS` ```basic -10 INPUT "Enter your name: ", Name$ -20 PRINT "Hello, "; Name$ +10 INPUT "Multiply X 5"; A +20 PRINT A * 5 +30 END ``` -- The program prompts the user to "Enter your name:". -- The input is stored in the variable Name$. -- The program then greets the user with their name by printing -> "Hello, [Name]!". +Explanation + +This program prompts the user to enter a number (`A`), multiplies it by 5 and prints the result. The example file `MULTIPLY-5.BAS` in `examples/INPUT/` contains the same program for direct testing on a generic MSX. + +Notes + +- Use `LINE INPUT` when you need to read a full line including spaces into a string variable. +- When multiple variables are specified, the user must separate values with commas when typing them (e.g., `12,34`). -[<< Back](./index.md) \ No newline at end of file +[<< Back](./index.md) diff --git a/docs/int.md b/docs/int.md index 7475512..7c82678 100644 --- a/docs/int.md +++ b/docs/int.md @@ -1,22 +1,30 @@ ### INT -The `INT` function in **MSX BASIC** is used to return the integer part of a given number by truncating the decimal portion. This function is useful when you need to work with whole numbers and discard any fractional part. +Description -#### Syntax ->INT(number) +`INT` returns the integer part of a numeric expression. It truncates toward negative infinity (i.e., `INT(-3.9)` yields `-4`). Use `INT` when you need whole-number results from real-valued expressions. -- *number*: The number from which you want to extract the integer part. +Syntax + +> INT(number) + +- `number` — Numeric expression whose integer part is required. + +Example 1 — Basic usage -#### Basic Usage ```basic 10 PRINT INT(5.7) 20 PRINT INT(-3.9) 30 END ``` -This example prints the integer parts of 5.7 and -3.9, which are 5 and -4 respectively. +Explanation + +The program prints `5` for `INT(5.7)` and `-4` for `INT(-3.9)` because `INT` returns the greatest integer less than or equal to the argument. -#### Using INT in a Loop +Example 2 — Using INT in a loop + +- Example file: `../examples/INT/LOOPED-INT.BAS` ```basic 10 FOR I = 1 TO 10 @@ -24,6 +32,9 @@ This example prints the integer parts of 5.7 and -3.9, which are 5 and -4 respec 30 NEXT I 40 END ``` -This example uses a loop to print the integer part of the numbers from 0.5 to 5.0 in increments of 0.5. -[<< Back](./index.md) \ No newline at end of file +Explanation + +This loop prints the integer part of the values `0.5, 1.0, 1.5, ...` (i.e., `I/2`) for `I = 1..10`, demonstrating how `INT` behaves on a sequence of real values. + +[<< Back](./index.md) diff --git a/docs/let.md b/docs/let.md new file mode 100644 index 0000000..02ba933 --- /dev/null +++ b/docs/let.md @@ -0,0 +1,30 @@ +### LET + +Description + +`LET` assigns a value to a variable. The keyword `LET` is optional — bare `variable = expression` is equivalent. + +Syntax + +> LET variable = expression + +- `variable` — Numeric or string variable (string names end with `$`). +- `expression` — Numeric or string expression compatible with the variable type. + +Example + +- Example file: `../examples/LET/ASSIGNMENT.BAS` + +```basic +10 REM LET optional assignment example +20 LET A = 10 +30 B = A + 5 +40 PRINT "A ="; A; " B ="; B +50 END +``` + +Explanation + +Line 20 explicitly uses `LET` while line 30 assigns a value without `LET`. Both are functionally identical. + +[<< Back](./index.md) diff --git a/docs/line.md b/docs/line.md new file mode 100644 index 0000000..706b676 --- /dev/null +++ b/docs/line.md @@ -0,0 +1,46 @@ +### LINE + +Description + +`LINE` draws straight lines or rectangles on a graphics screen. A `Shape` parameter allows drawing filled rectangles (`BF`) or empty rectangles (`B`). It supports logical operators on MSX2+. + +Syntax + +> LINE [STEP](X1,Y1)-(STEP)(X2,Y2), color [, shape] [, operator] + +- `STEP` — Optional prefix to use coordinates relative to the current cursor position when present. +- `X1,Y1` — Starting coordinate. +- `X2,Y2` — Ending coordinate. +- `color` — Optional color index. +- `shape` — `B` for empty rectangle or `BF` for filled rectangle. When omitted a line is drawn. +- `operator` — Optional logical operator (MSX2+). + +Example 1 — Concentric rectangles pattern + +- Example file: `../examples/LINE/LINE-PATTERN.BAS` + +```basic +10 SCREEN 2: COLOR 15,1,7: CLS +20 FOR I = 0 TO 95 STEP 8 +30 LINE (128-I,95-I)-(128+I,95+I),1,B +40 NEXT +50 GOTO 50 +``` + +Explanation + +This program draws a sequence of empty rectangles centered on `(128,95)` producing a concentric-frame pattern. `STEP` is not used here; coordinates are absolute. + +Example 2 — Filled rectangle + +```basic +10 SCREEN 2: COLOR 15,1,7: CLS +20 LINE (10,10)-(100,60), 3, BF +30 GOTO 30 +``` + +Explanation + +The `BF` shape parameter draws a filled rectangle between the two coordinates. + +[<< Back](./index.md) diff --git a/docs/list.md b/docs/list.md new file mode 100644 index 0000000..43bd55b --- /dev/null +++ b/docs/list.md @@ -0,0 +1,28 @@ +### LIST + +Description + +`LIST` displays the BASIC program currently in memory. You can list the entire program or a specific range of line numbers. + +Syntax + +> LIST [start[-end]] + +- `start` — Optional starting line number to display. +- `end` — Optional ending line number. + +Example + +- Example file: `../examples/LIST/LIST-DEMO.BAS` + +```basic +10 PRINT "This program will be listed with LIST" +20 PRINT "Line two" +30 END +``` + +Explanation + +Type `LIST` at the READY prompt to show the program source. `LIST 10-20` restricts output to the specified line range. + +[<< Back](./index.md) diff --git a/docs/load.md b/docs/load.md new file mode 100644 index 0000000..46ddc1e --- /dev/null +++ b/docs/load.md @@ -0,0 +1,26 @@ +### LOAD + +Description + +`LOAD` retrieves a BASIC program from an external device into memory. Optionally, the `R` flag executes the loaded program immediately. + +Syntax + +> LOAD ":\\"[,R] + +- `device` — Device name (e.g., `CAS` for cassette, `A` for disk). If omitted the default device is used. +- `R` — Optional flag to run the program after load. + +Example — Load and run a previously saved program + +- After saving `HELLO.BAS` to disk or cassette, at the READY prompt use one of: + - `LOAD "A:HELLO.BAS",R` (load from disk and run) + - `LOAD "CAS:HELLO",R` (load from cassette and run) + +Example file for reference (this is the program you saved): `../examples/SAVE/SAVE-DEMO.BAS` + +Explanation + +`LOAD` behavior depends on the storage device and file format. Tokenized programs load faster. Use the `R` parameter to immediately execute the program after loading. + +[<< Back](./index.md) diff --git a/docs/locate.md b/docs/locate.md index 560130e..3f81213 100644 --- a/docs/locate.md +++ b/docs/locate.md @@ -1,17 +1,48 @@ -## Locate +### LOCATE -The `LOCATE` command is used to set the cursor position on the screen. It takes two parameters: the row and the column where the cursor should move. +Description -The maximum characters in screen are: -- horizontal: 0 - 36 -- vertical: 0 - 23 +`LOCATE` positions the text cursor before the next text output (e.g., `PRINT`, `INPUT`, `LINE INPUT`). Coordinates are interpreted relative to the current text screen mode and `WIDTH` setting. -For example, `LOCATE 10, 5` moves the cursor to the 10th row and 5th column. +Syntax + +> LOCATE [#window,] X, Y[, Cursor] + +- `X` — Column coordinate (horizontal). Interpreter accepts 0–255; practical range depends on `WIDTH` (e.g., `WIDTH 40` gives 1..40 columns in common setups). +- `Y` — Row coordinate (vertical). Interpreter accepts 0–255; practical range depends on screen height (commonly 1..24 for many text modes). +- `Cursor` — Optional numeric parameter that controls cursor visibility (0 hides the cursor when the system is busy; non-zero keeps it visible). +- `#window` — Delta BASIC window prefix (advanced usage); omit on a generic MSX. + +Notes + +- Some implementations accept coordinates starting at `0`, others use `1` as the top-left position. For portable code, explicitly set `WIDTH` and use coordinates within that screen geometry. +- If the `X` coordinate is omitted (e.g., `LOCATE ,Y`), behavior can vary; many implementations default `X` to 0. Prefer specifying both coordinates. + +Example 1 — Basic placement + +- Example file: `../examples/LOCATE/HELLO-WORLD.BAS` ```basic -10 PRINT "MSX BASIC" -20 LOCATE 10,10:PRINT "HELLO WORLD" +10 PRINT "MSX BASIC" +20 LOCATE 10,10: PRINT "HELLO WORLD" 30 END ``` -[<< Back](./index.md) \ No newline at end of file +Explanation + +`LOCATE 10,10` moves the cursor to the column/row position before printing `HELLO WORLD`. The actual on-screen location depends on the current `WIDTH` and screen mode. + +Example 2 — Set only row + +```basic +10 SCREEN 0: WIDTH 40 +20 LOCATE ,14 +30 PRINT "Centered-ish text on row 14" +40 END +``` + +Explanation + +This example shows using `LOCATE` with the `X` coordinate omitted. The interpreter will place the cursor at the specified row and a default column (implementation-dependent). Using `WIDTH` ensures the program behaves predictably on a generic MSX. + +[<< Back](./index.md) diff --git a/docs/new.md b/docs/new.md new file mode 100644 index 0000000..c3774e4 --- /dev/null +++ b/docs/new.md @@ -0,0 +1,25 @@ +### NEW + +Description + +`NEW` clears the program currently loaded in memory, closes open files and resets program state (variables are typically cleared). After `NEW`, the program buffer is empty and `LIST` prints nothing. + +Syntax + +> NEW + +Example + +- Example file: `../examples/NEW/NEW-DEMO.BAS` + +```basic +10 REM Save program then type NEW at the prompt to clear program and variables +20 PRINT "This program will be cleared by NEW" +30 END +``` + +Explanation + +After issuing `NEW` at the READY prompt the program in memory is erased. Use `SAVE` before `NEW` to persist the program to disk/cassette if required. + +[<< Back](./index.md) diff --git a/docs/open.md b/docs/open.md new file mode 100644 index 0000000..157d05e --- /dev/null +++ b/docs/open.md @@ -0,0 +1,39 @@ +### OPEN + +Description + +`OPEN` prepares a file or device for sequential (INPUT/OUTPUT/APPEND) or random access. It is used to read and write text or binary data to devices such as disk drives, cassette, printer, or the graphics/text screen (`GRP:` / `CRT:`). + +Syntax + +> OPEN ":\\" FOR AS # [LEN ] + +- `device` — Device name (e.g., `A:`, `CAS:`, `GRP:`). If omitted the system default is used. +- `mode` — `OUTPUT` (write), `INPUT` (read), `APPEND` (append to an existing file) or omitted for random access. +- `fileNumber` — File handle (1..15) used by `PRINT #`, `INPUT #`, `GET #`, `PUT #`, etc. +- `LEN` — Record length for random access files (optional). + +Example — Create and read a text file + +- Example file: `../examples/OPEN/OPEN-TEXT.BAS` + +```basic +10 REM Create and read a text file using OPEN/PRINT#/LINE INPUT +20 OPEN "HELLO.TXT" FOR OUTPUT AS #1 +30 PRINT #1, "Hello world!" +40 PRINT #1, "Saved from OPEN example" +50 CLOSE #1 +60 OPEN "HELLO.TXT" FOR INPUT AS #1 +70 IF EOF(1) THEN 110 +80 LINE INPUT #1, A$ +90 PRINT A$ +100 IF NOT EOF(1) THEN GOTO 80 +110 CLOSE #1 +120 END +``` + +Explanation + +Use `OPEN ... FOR OUTPUT AS #n` to create or overwrite a file and `OPEN ... FOR INPUT AS #n` to read it. Use `PRINT #n, ...` and `LINE INPUT #n, var$` to write and read text lines. Remember to `CLOSE #n` when finished. + +[<< Back](./index.md) diff --git a/docs/paint.md b/docs/paint.md new file mode 100644 index 0000000..d02ae2d --- /dev/null +++ b/docs/paint.md @@ -0,0 +1,32 @@ +### PAINT + +Description + +`PAINT` fills an enclosed area on a graphics screen with a specified color. It operates like a flood-fill: specify a starting pixel coordinate and a fill color; optionally provide a border color to limit the fill. + +Syntax + +> PAINT [(STEP)(X,Y)], fillingColor [, borderColor] + +- `X,Y` — Starting coordinate for the flood fill. +- `fillingColor` — Color to fill with (optional; defaults to current foreground color). +- `borderColor` — Optional color that defines the region boundary. + +Example — Fill a circle and a rectangle + +- Example file: `../examples/PAINT/PAINT-DEMO.BAS` + +```basic +10 COLOR 15,4,7: SCREEN 2: CLS +20 CIRCLE (80,80), 30, 8 +30 PAINT (80,80), 8 +40 LINE (170,20)-(220,80),2,B +50 PAINT (180,40), 2, 2 +60 GOTO 60 +``` + +Explanation + +The program draws a circle and then fills its interior using `PAINT`. It also draws an empty rectangle and fills it specifying a filling color and border color. If the border is not continuous the fill may spill; specify the `borderColor` to avoid unintended behavior. + +[<< Back](./index.md) diff --git a/docs/peek.md b/docs/peek.md new file mode 100644 index 0000000..2c0093d --- /dev/null +++ b/docs/peek.md @@ -0,0 +1,28 @@ +### PEEK + +Description + +`PEEK` returns the byte stored at a given memory address. It is the counterpart to `POKE` and is useful for low-level inspection of system memory. + +Syntax + +> PEEK(address) + +- `address` — Memory address to read (0–65535). +- Returns an integer between 0 and 255. + +Example + +- Example file: `../examples/PEEK/PEEK-READ.BAS` + +```basic +10 REM PEEK demonstration +20 PRINT "PEEK(60000) ="; PEEK(60000) +30 END +``` + +Explanation + +`PEEK` reads a single byte from the specified address. Values returned depend on the machine state and memory layout; avoid reading addresses that may contain program or system state unless intentionally inspecting them. + +[<< Back](./index.md) diff --git a/docs/play.md b/docs/play.md new file mode 100644 index 0000000..16c24ce --- /dev/null +++ b/docs/play.md @@ -0,0 +1,39 @@ +### PLAY + +Description + +`PLAY` executes Music Macro Language (MML) strings to play notes on PSG, MSX-MUSIC, MSX-AUDIO or external MIDI devices (depending on system and configuration). It is a higher-level way to produce melodies compared to `SOUND`. + +Syntax + +> PLAY [#device,] "", "", ... + +- `#device` — Optional device selector (0 = PSG default, other values for MSX-MUSIC, MSX-AUDIO, etc. when available). +- Each MML string describes notes, durations, octave, volume and control commands for a channel. + +Example 1 — Simple PSG melody + +- Example file: `../examples/PLAY/PLAY-MEL.BAS` + +```basic +10 REM Play a short PSG melody on the default device +20 PLAY "CDE","","" +30 END +``` + +Explanation + +This simple `PLAY` call plays notes `C D E` on the first PSG channel. When only PSG is used, you can omit the `#device` parameter. Provide additional MML strings for multiple channels. + +Example 2 — Short melody with octave change + +```basic +10 PLAY "T120O4CDEFGAB>c" +20 END +``` + +Explanation + +`T120` sets tempo (120), `O4` sets octave 4 and `>c` moves up one octave for the last `c` note. MML is expressive; consult an MML reference for more complex compositions. + +[<< Back](./index.md) diff --git a/docs/point.md b/docs/point.md new file mode 100644 index 0000000..d719960 --- /dev/null +++ b/docs/point.md @@ -0,0 +1,36 @@ +### POINT + +Description + +`POINT` returns the color index of a specified pixel in a graphic screen. It is useful to inspect pixels when implementing collision detection, color-based logic, or to verify drawing operations. + +Syntax + +> POINT [(STEP)(X,Y)] + +- `STEP` — Optional prefix to use coordinates relative to current cursor position. +- `X,Y` — Pixel coordinates (typical ranges depend on `SCREEN` mode; e.g., X 0..255, Y 0..191). +- Returns an integer color index. + +Example 1 — Plot points and read their colors + +- Example file: `../examples/POINT/POINT-DEMO.BAS` + +```basic +10 REM Plot points then sample their color with POINT +20 SCREEN 2: COLOR 15,1,7: CLS +30 PSET (80,60), 5 +40 PSET (100,60), 6 +50 A = POINT(80,60) +60 B = POINT(100,60) +70 SCREEN 0 +80 PRINT "POINT(80,60) ="; A +90 PRINT "POINT(100,60) ="; B +100 END +``` + +Explanation + +The program draws two colored pixels on `SCREEN 2` and reads their color values using `POINT`. It then switches back to text mode and prints the sampled color indices. + +[<< Back](./index.md) diff --git a/docs/poke.md b/docs/poke.md new file mode 100644 index 0000000..438dd67 --- /dev/null +++ b/docs/poke.md @@ -0,0 +1,30 @@ +### POKE + +Description + +`POKE` writes a byte value directly into RAM at the specified memory address. This is a low-level operation and can corrupt memory or crash the system if used incorrectly. + +Syntax + +> POKE address, value + +- `address` — Memory address (0–65535). Some dialects accept hexadecimal with `&H...`. +- `value` — Numeric byte value (0–255). + +Example + +- Example file: `../examples/POKE/POKE-PEEK.BAS` + +```basic +10 REM WARNING: POKE writes to memory. Use with caution on real hardware. +20 POKE 60000, 123 +30 PRINT "POKED 123 into 60000" +40 PRINT "PEEK(60000) ="; PEEK(60000) +50 END +``` + +Explanation + +This program demonstrates writing a value to an arbitrary memory location and then reading it back with `PEEK`. On some MSX systems this may overwrite important data; prefer documented system APIs or `VPOKE`/`VPEEK` for VRAM operations when appropriate. + +[<< Back](./index.md) diff --git a/docs/preset.md b/docs/preset.md new file mode 100644 index 0000000..636463f --- /dev/null +++ b/docs/preset.md @@ -0,0 +1,36 @@ +### PRESET + +Description + +`PRESET` writes a pixel using the current background color (or a supplied color) on a graphic screen. When used without a color parameter it often clears or removes a pixel (sets it to background color); when a color is supplied it behaves like `PSET`. + +Syntax + +> PRESET [(STEP)(X,Y)], color [, operator] + +- `STEP` — Optional relative coordinates prefix. +- `X,Y` — Pixel coordinates. +- `color` — Optional color index (omitting it uses the background color). +- `operator` — Optional logical operator (MSX2+). + +Example — Random presets after drawing a shape + +- Example file: `../examples/PRESET/PRESET-RANDOM.BAS` + +```basic +10 REM PRESET example: draw lines then random presets +20 SCREEN 2: COLOR 15,1,7: CLS +30 LINE (20,20)-(200,120), 3, B +40 FOR I=1 TO 200 +50 X = INT(RND(1) * 180) + 20 +60 Y = INT(RND(1) * 100) + 20 +70 PRESET (X,Y) +80 NEXT I +90 GOTO 90 +``` + +Explanation + +This example draws an outlined rectangle then plots random `PRESET` points that use the background color by default (effectively erasing or toggling pixels depending on operator and mode). On MSX2+ you can supply logical operators to control how the pixel is combined with existing data. + +[<< Back](./index.md) diff --git a/docs/print.md b/docs/print.md new file mode 100644 index 0000000..5dce73a --- /dev/null +++ b/docs/print.md @@ -0,0 +1,51 @@ +### PRINT + +Description + +`PRINT` outputs text and numeric expressions to the current output device (screen by default) or to an open file. The shorthand symbol `?` can be used in place of `PRINT`. + +Syntax + +> PRINT [#file,] [USING format;] item1[, item2; ...] + +- `item` — String literal, expression, variable, or function result. +- Items separated by `;` are concatenated without an automatic line break. +- Items separated by `,` are separated by tab spacing. +- `#file` — Optional file number (0–15) opened with `OPEN` to redirect output. + +Example 1 — Basic text and numeric output + +- Example file: `../examples/PRINT/PRINT-BASIC.BAS` + +```basic +10 REM Basic PRINT usage +20 PRINT "HELLO, WORLD" +30 PRINT "SUM ="; 2 + 3 +40 PRINT "A"; "B"; "C" +50 PRINT "COL1", "COL2" +60 ? "SHORTHAND PRINT" +70 END +``` + +Explanation + +- Line 20 prints a string followed by a line break. +- Line 30 prints a label and an expression concatenated (no extra space) because of `;`. +- Line 40 prints three strings concatenated without additional spacing. +- Line 50 uses `,` to separate items — the interpreter emits a tab/spaced column separation. +- Line 60 uses `?` as shorthand for `PRINT`. + +Example 2 — Empty item to produce blank lines + +```basic +10 PRINT "One" +20 PRINT +30 PRINT "Three" +40 END +``` + +Explanation + +A standalone `PRINT` emits a blank line. Use it to create vertical spacing in output. + +[<< Back](./index.md) diff --git a/docs/pset.md b/docs/pset.md new file mode 100644 index 0000000..2068988 --- /dev/null +++ b/docs/pset.md @@ -0,0 +1,53 @@ +### PSET + +Description + +`PSET` plots a single pixel at the specified coordinates on a graphic screen. It accepts an optional color and a logical operator (MSX2+). Use `PSET` for fine-grained drawing when building low-level graphics. + +Syntax + +> PSET [(STEP)(X,Y)], color [, operator] + +- `STEP` — Optional prefix to use coordinates relative to current cursor position. +- `X,Y` — Pixel coordinates (ranges depend on `SCREEN` mode; typical MSX1 ranges: X 0..255, Y 0..191). +- `color` — Optional color index. If omitted, the current plot color is used. +- `operator` — Optional logical operator (AND, OR, XOR, PRESET, PSET, and variants prefixed by `T` for transparency) available on MSX2+. + +Example 1 — Random dots (simple) + +- Example file: `../examples/PSET/PSET-RANDOM.BAS` + +```basic +10 REM Draw 500 random colored pixels +20 SCREEN 2: COLOR 15,1,7: CLS +30 FOR I = 1 TO 500 +40 X = INT(RND(1) * 256) +50 Y = INT(RND(1) * 192) +60 C = INT(RND(1) * 15) + 1 +70 PSET (X,Y), C +80 NEXT I +90 GOTO 90 +``` + +Explanation + +This program uses `PSET` to place 500 colored pixels at random coordinates. `SCREEN 2` is a commonly available graphics mode on many MSX systems; adapt `SCREEN` and coordinate ranges if your machine uses a different mode. + +Example 2 — Operator demo (MSX2+) + +```basic +10 SCREEN 5: COLOR 2,12,4: CLS +20 PSET (110,96), 1, AND +30 PSET (114,96), 1, TAND +40 PSET (118,96), 1, OR +50 PSET (122,96), 1, TOR +60 PSET (126,96), 1, PRESET +70 PSET (130,96), 1, TPSET +80 GOTO 80 +``` + +Explanation + +On MSX2+ machines `PSET` supports logical operators to combine new pixel data with existing pixels. The `T` prefix variants treat color 0 as transparent. + +[<< Back](./index.md) diff --git a/docs/read-data.md b/docs/read-data.md index 9e3a547..c83e271 100644 --- a/docs/read-data.md +++ b/docs/read-data.md @@ -1,19 +1,22 @@ ### READ / DATA -The `READ` command is used to read data values that have been defined with the `DATA` command. This allows for easy storage and retrieval of multiple values. The `DATA` command is used to define a list of values, which can then be read sequentially using the `READ` command. This is particularly useful for initializing variables or arrays with predefined values. +Description -#### Syntax ->READ variable +`DATA` defines a sequence of literal values embedded in the program source. `READ` retrieves the next value(s) from the `DATA` list and assigns them to variables. `RESTORE` resets the `READ` pointer to the start of the `DATA` (or to a specified line number), allowing the same data to be read again. ->DATA value1, value2, ..., valueN +Syntax -The `variable` that will store the value read from the DATA statement. +> READ var1[, var2, ...] +> DATA value1[, value2, ...] +> RESTORE [line_number] -`value1`, `value2`, ..., `valueN`: -A comma-separated list of values to be read. +- `var1, var2, ...` — Variables that receive values from the next `DATA` fields, read sequentially. +- `value1, ...` — Comma-separated literal values in the `DATA` statement. +- `RESTORE` — Resets the internal pointer used by `READ`. If `line_number` is specified, the pointer is set to the `DATA` statement at that line. -#### Example -The following MSX BASIC program demonstrates how to use the READ and DATA commands to initialize an array with predefined values and then print those values: +Example 1 — Initialize an array from DATA + +- Example file: `../examples/READ-DATA/USERS-LIST.BAS` ```basic 10 DIM A(5) @@ -27,12 +30,32 @@ The following MSX BASIC program demonstrates how to use the READ and DATA comman 90 END ``` -In this example: +Explanation + +The program declares `A(5)` and reads five values from the `DATA` line into the array. The second loop prints the values stored in the array. `DATA` fields are read sequentially by `READ`. + +Example 2 — Using RESTORE to reread DATA + +- Example file: `../examples/READ-DATA/RESTORE.BAS` + +```basic +10 READ A, B, C +20 RESTORE +30 READ D, E, F +40 PRINT A; B; C +50 PRINT D; E; F +60 END +70 DATA 10, 20, 30 +``` + +Explanation + +- Lines 10 and 30 each `READ` three values from the single `DATA` line at 70. +- `RESTORE` (line 20) resets the `READ` pointer so the second `READ` reads the same values again into `D`, `E`, `F`. + +Notes -- Line 10: Declares an array A with 5 elements. -- Lines 20-40: Uses a FOR loop to read values from the DATA statement into the array A. -- Lines 50-70: Uses another FOR loop to print the values stored in the array A. -- Line 80: Defines the values to be read by the READ command. -- Line 90: Ends the program. +- `DATA` fields are not variables and are not counted as program lines; they are literal constants embedded in the program source. +- Use `RESTORE line_number` to target a specific `DATA` statement when multiple `DATA` lines are present. -[<< Back](./index.md) \ No newline at end of file +[<< Back](./index.md) diff --git a/docs/rem.md b/docs/rem.md new file mode 100644 index 0000000..f170a1a --- /dev/null +++ b/docs/rem.md @@ -0,0 +1,30 @@ +### REM + +Description + +`REM` (remark) and the apostrophe `'` introduce comments in MSX BASIC source. Comments are ignored by the interpreter and are used to document code. + +Syntax + +> REM text +> ' text + +- `REM` — Full-word comment marker. +- `'` — Single-quote shorthand comment marker; often preferred for brevity. + +Example + +- Example file: `../examples/REM/COMMENTS.BAS` + +```basic +10 REM This is a REM comment +20 ' This is an apostrophe comment +30 PRINT "Comments do not affect execution" +40 END +``` + +Explanation + +Lines beginning with `REM` or `'` are ignored by the interpreter and serve as inline documentation for humans. + +[<< Back](./index.md) diff --git a/docs/rnd.md b/docs/rnd.md index f53f5af..275b2b6 100644 --- a/docs/rnd.md +++ b/docs/rnd.md @@ -1,24 +1,31 @@ ### RND -The `RND` function in **MSX BASIC** is used to generate random numbers. It can produce either a random number between 0 and 1, or a random integer within a specified range. -#### Syntax ->RND(`type`) +Description -- *type* : A numeric value that determines the type of random number generated. +`RND` returns pseudo-random numbers. It is commonly used to generate floating values in the range [0,1) and to build random integers by combining `RND` with `INT` and arithmetic. -- `0`: Generates the same sequence of random numbers each time the program is run. -- `1`: Generates a new random number between 0 and 1. -- `-1`: Reseeds the random number generator with a new seed based on the system clock. +Syntax -#### Generate a Random Number Between 0 and 1 +> RND(type) + +- `type` — Numeric argument that controls the generator behavior: + - `0` — Produce a reproducible sequence (same sequence every run). + - `1` — Generate a new pseudo-random value between 0 and 1. + - `-1` — Reseed the generator using the system clock (useful for non-reproducible runs). + +Example 1 — Single random value ```basic 10 PRINT RND(1) 20 END ``` -This example prints a random number between 0 and 1. -#### Generate a Random Integer Between 1 and 10 +Explanation + +Prints a single floating pseudo-random number in the range 0..1 (implementation-dependent precision). + +Example 2 — Random integers in range 1..10 + ```basic 10 FOR I = 1 TO 10 20 PRINT INT(RND(1) * 10) + 1 @@ -26,4 +33,13 @@ This example prints a random number between 0 and 1. 40 END ``` -[<< Back](./index.md) \ No newline at end of file +Explanation + +`INT(RND(1) * 10) + 1` maps the floating result of `RND(1)` into the integer range 1..10. Use `RND(0)` if you need the same sequence for testing, or `RND(-1)` to reseed from the clock for varied runs. + +Notes + +- `RND` returns pseudo-random values; for reproducible behavior use `RND(0)` at the start of the program. +- The exact distribution and period depend on the MSX BASIC implementation. + +[<< Back](./index.md) diff --git a/docs/run.md b/docs/run.md new file mode 100644 index 0000000..5d06d55 --- /dev/null +++ b/docs/run.md @@ -0,0 +1,26 @@ +### RUN + +Description + +`RUN` executes the BASIC program currently loaded in memory. If a line number is supplied (implementation-dependent), execution may begin at that line; typically `RUN` without arguments starts at the first program line. + +Syntax + +> RUN [line] + +- `line` — Optional starting line number (not universally supported across all MSX variants). + +Example + +- Example file: `../examples/RUN/RUN-DEMO.BAS` + +```basic +10 PRINT "This program demonstrates RUN" +20 END +``` + +Explanation + +After entering or loading a program into memory, type `RUN` at the READY prompt to start execution. Some emulators or MSX variants allow `RUN ` to start at a specific line number. + +[<< Back](./index.md) diff --git a/docs/save.md b/docs/save.md new file mode 100644 index 0000000..610a7fb --- /dev/null +++ b/docs/save.md @@ -0,0 +1,32 @@ +### SAVE + +Description + +`SAVE` writes the BASIC program currently in memory to an external device (cassette, disk, memory device). The stored format may be ASCII or tokenized depending on parameters and device. + +Syntax + +> SAVE ":\\"[,A] + +- `device` — Device name (e.g., `CAS` for cassette, `A` for disk drive A). If omitted the default device is used. +- `A` — Optional flag to save in ASCII format (useful for tape or cross-platform readability); otherwise tokenized format is used. + +Example — Save a small program (instructions) + +- Example file: `../examples/SAVE/SAVE-DEMO.BAS` + +```basic +10 PRINT "HELLO, SAVE DEMO" +20 END +``` + +To save this program from the READY prompt: + +- Tape: `SAVE "CAS:HELLO",A` (ASCII on cassette) +- Disk: `SAVE "A:HELLO.BAS",A` or `SAVE "A:HELLO.BAS"` (tokenized) + +Explanation + +`SAVE` behavior depends on the target device: cassette often uses ASCII; disk supports both ASCII and tokenized formats. Provide the device prefix to control the destination explicitly. When saving to disk, use typical 8.3 filenames (e.g., `HELLO.BAS`). + +[<< Back](./index.md) diff --git a/docs/screen.md b/docs/screen.md new file mode 100644 index 0000000..65962be --- /dev/null +++ b/docs/screen.md @@ -0,0 +1,56 @@ +### SCREEN + +Description + +`SCREEN` selects the display mode and several display-related parameters (sprite size, key click, cassette baud, printer type, interlace) used by the BASIC interpreter. Changing `SCREEN` also affects available drawing primitives and color capabilities. + +Syntax + +> SCREEN displayMode[, spriteSize[, keyclick[, baudRate[, printerType[, interlace]]]]] + +- `displayMode` — Numeric screen mode (0..13). Common values: `0` (text), `1` (text 8x8), `2` (graphics on many MSX1 machines). Mode availability depends on MSX generation. +- `spriteSize` — Sprite magnification/size (0..3). +- `keyclick` — Keyboard click enable (0/1). +- `baudRate` — Cassette write speed (1=1200, 2=2400). +- `printerType` — Printer type parameter (machine-dependent). +- `interlace` — Interlace mode parameter (MSX2+ only). + +Example 1 — Switch to a simple graphics screen and draw shapes + +- Example file: `../examples/SCREEN/SCREEN-SWITCH.BAS` + +```basic +10 REM Switch to graphics, draw and return to text +20 SCREEN 0: PRINT "Press any key to switch to GRAPHICS" +30 A$ = INKEY$ +40 IF A$ = "" THEN 30 +50 SCREEN 2: COLOR 15,1,7: CLS +60 LINE (10,10)-(200,100),2 +70 CIRCLE (127,95),50,3 +80 OPEN "GRP:" FOR OUTPUT AS #1 +90 PRINT #1, "You are in GRAPHICS mode - press any key" +100 A$ = INKEY$ +110 IF A$ = "" THEN 100 +120 CLOSE #1 +130 SCREEN 0: CLS +140 PRINT "Back to text mode" +150 END +``` + +Explanation + +This program waits in text mode, switches to `SCREEN 2` (a common graphics mode), sets colors and draws a line and a circle. It uses `OPEN "GRP:" FOR OUTPUT` to print a short message in the graphics page and waits for a key before restoring `SCREEN 0`. + +Example 2 — Specify additional parameters (MSX2+ compatible) + +```basic +10 SCREEN 2,3,0,,,1 ' SCREEN mode 2, spritesize 3, keyclick off, interlace on (MSX2+) +20 REM Additional parameters are optional and machine dependent +30 END +``` + +Explanation + +The second example demonstrates passing optional `SCREEN` parameters. Not all MSX systems support every parameter — consult the machine reference if an argument triggers a syntax error. + +[<< Back](./index.md) diff --git a/docs/sound.md b/docs/sound.md new file mode 100644 index 0000000..c86d204 --- /dev/null +++ b/docs/sound.md @@ -0,0 +1,53 @@ +### SOUND + +Description + +`SOUND` writes a value directly to a PSG (AY-3-8910 / YM2149) register. It provides low-level control over tone frequency, noise, mixer and volumes. Use with care — incorrect values may silence channels or produce unexpected audio. + +Syntax + +> SOUND register, value + +- `register` — PSG register number (0..13). Each register controls frequency bits, noise, mixer, volume, envelope, etc. +- `value` — Numeric byte value appropriate to the selected register. + +Example 1 — Initialize PSG and play a note (decimal) + +- Example file: `../examples/SOUND/SOUND-NOTE.BAS` + +```basic +10 REM Play a single note on PSG channel A +20 FOR R = 0 TO 13 +30 IF R = 7 THEN SOUND R, 191 ELSE SOUND R, 0 +40 NEXT R +50 SOUND 0, 172 ' low 8 bits of frequency for channel A +60 SOUND 1, 1 ' high 4 bits of frequency for channel A +70 SOUND 8, 12 ' volume for channel A +80 SOUND 7, 190 ' enable channel A tone generator +90 FOR T = 1 TO 5000: NEXT T +100 END +``` + +Explanation + +The snippet clears PSG registers, configures channel A frequency and volume, and enables the tone generator via register 7. `SOUND` operates on hardware registers; exact pitch mapping depends on PSG clock. + +Example 2 — Simple modulation loop (demo) + +```basic +10 FOR I = 0 TO 13 +20 IF I = 7 THEN SOUND I,191 ELSE SOUND I,0 +30 NEXT +40 FOR T = 1 TO 1000 +50 SOUND 6, INT(RND(1)*31) +60 SOUND 8, INT(RND(1)*16) +70 FOR J = 1 TO 500: NEXT J +80 NEXT +90 END +``` + +Explanation + +This loop modifies noise frequency and volume for a short randomized effect. `SOUND` is low-level — for structured music prefer `PLAY` (MML) or higher-level audio APIs. + +[<< Back](./index.md) diff --git a/docs/start.md b/docs/start.md index 63824f7..da212da 100644 --- a/docs/start.md +++ b/docs/start.md @@ -1,91 +1,42 @@ -# Getting Started with MSX BASIC Programming +# Getting Started with MSX BASIC Programming -This guide introduces fundamental MSX BASIC commands and how to use the built-in MSX code editor. +This short guide covers the minimal workflow to write, run, and manage BASIC programs on a generic MSX system or emulator. -BASIC stands for **Beginners All-purpose Symbolic Instruction Code**. It was designed to teach computer programming concepts easily. In MSX you'll find an improved version able to run in any other computer using this MSX standar. +Environment ---- +- Boot an MSX or an MSX emulator to reach the BASIC prompt (Ready/Ok). BASIC is the built-in interpreter. +- Programs are typed directly with line numbers, or entered in an editor provided by the emulator. -## Accessing the MSX BASIC Environment -1. Turn on your MSX computer or emulator, and it should boot directly into the BASIC interpreter, showing a prompt like `Ok`. +Essential commands -2. From here, you can start typing commands directly or writing programs. +- `NEW` — clear program memory and variables. +- `AUTO` — automatic line numbering (e.g., `AUTO 10,10`). +- `LIST [start-end]` — show program source in memory. +- `RUN` — execute the program in memory. +- `SAVE` / `LOAD` — persist and retrieve programs (device-dependent). +- `PRINT` — output text and expressions. +- `INPUT` — read keyboard input. +- `CLS`, `COLOR` — control display. ---- - -## Useful Commands to Begin - -### NEW -> Clears the current program from memory - -```basic - NEW -``` -### AUTO -> Automatically generates line numbers as you type, value. - -```basic - AUTO 10,10 -``` -Starts line numbering at 10 and increments by 10 for each new line, helping you manage your program structure. - -Stop AUTO mode with the STOP key. - -### COLOR -> Sets the screen colors (foreground, background, and border). - - -```basic -COLOR 7,0,1 -``` - -Sets the text color to white (7), the background to black (0), and the border to blue (1). - -### LIST -> Displays the current program stored in memory. +Minimal example -```basic -LIST -``` -Shows all lines in the program. To view specific lines, use: - -```basic -LIST 10-30 -``` -### RUN -> Executes the program in memory. - -```basic -RUN -``` - -Runs the program from the first line. - -### PRINT -> Displays text or values on the screen. -```basic -10 REM This is a comment -20 PRINT "LOADING" -``` - -### Writing a Simple Program -Here’s an example program to get you started: ```basic 10 CLS 20 COLOR 7,0,1 -30 PRINT "WELCOME TO MSX BASIC!" +30 PRINT "WELCOME TO MSX BASIC" 40 INPUT "What is your name? "; N$ -50 PRINT "HELLO "; N$; "!" +50 PRINT "HELLO "; N$ 60 END - ``` -### Tips for Beginners -Always start with CLS and COLOR to make the screen output clear and visually appealing. -Use AUTO to keep your code organized with line numbers. +- Type or paste the program into the interpreter (use `AUTO` to generate line numbers). +- Run it with `RUN`. + +Notes -Experiment with mathematical operations (PRINT 2+3) and loops (e.g., using FOR and NEXT). +- Keep programs short and test iteratively. +- Use `REM` or `'` to document code. Prefer `SAVE` before `NEW`. -Explore the [index of commands](./index.md) in this guide to learn more MSX BASIC instructions. +See also: `docs/index.md` for the command reference. [<< Back](../README.md) diff --git a/docs/stop.md b/docs/stop.md new file mode 100644 index 0000000..e84ec20 --- /dev/null +++ b/docs/stop.md @@ -0,0 +1,26 @@ +### STOP + +Description + +`STOP` halts program execution and returns control to the READY prompt. Execution can be resumed with the `CONT` command. `STOP` can also trigger an `ON STOP GOSUB` handler when configured. + +Syntax + +> STOP + +Example + +- Example file: `../examples/STOP/STOP-DEMO.BAS` + +```basic +10 PRINT "BEFORE STOP" +20 STOP +30 PRINT "AFTER STOP" +40 END +``` + +Explanation + +When `STOP` is executed the program halts at line 20; the `PRINT` at line 30 does not run unless the user types `CONT` at the prompt to resume execution. + +[<< Back](./index.md) diff --git a/examples/CIRCLE/CIRCLE-DEMO.BAS b/examples/CIRCLE/CIRCLE-DEMO.BAS new file mode 100644 index 0000000..8322249 --- /dev/null +++ b/examples/CIRCLE/CIRCLE-DEMO.BAS @@ -0,0 +1,13 @@ +10 REM Concentric circles demo +20 SCREEN 2: COLOR 15,1,7: CLS +30 FOR R = 10 TO 80 STEP 10 +40 CIRCLE (127,95), R, INT(R/10) + 1 +50 NEXT R +60 OPEN "GRP:" FOR OUTPUT AS #1 +70 PRINT #1, "Press any key to continue..." +80 DO +90 A$ = INKEY$ +100 LOOP UNTIL A$ <> "" +110 CLOSE #1 +120 SCREEN 0 +130 END diff --git a/examples/CLS/CLS-COLOR.BAS b/examples/CLS/CLS-COLOR.BAS new file mode 100644 index 0000000..1a37709 --- /dev/null +++ b/examples/CLS/CLS-COLOR.BAS @@ -0,0 +1,4 @@ +10 CLS +20 COLOR 7,0,1 +30 PRINT "Screen cleared and colors set" +40 END diff --git a/examples/COLOR/COLOR-DEMO.BAS b/examples/COLOR/COLOR-DEMO.BAS new file mode 100644 index 0000000..9627ac5 --- /dev/null +++ b/examples/COLOR/COLOR-DEMO.BAS @@ -0,0 +1,3 @@ +10 COLOR 7,0,1 +20 PRINT "White text, black background, blue border" +30 END diff --git a/examples/END/END-DEMO.BAS b/examples/END/END-DEMO.BAS new file mode 100644 index 0000000..7159a7f --- /dev/null +++ b/examples/END/END-DEMO.BAS @@ -0,0 +1,4 @@ +10 PRINT "START" +20 END +30 PRINT "NEVER REACHED" +40 END diff --git a/examples/GOTO/INFINITE-PRINT.BAS b/examples/GOTO/INFINITE-PRINT.BAS index a915c8b..513484a 100644 --- a/examples/GOTO/INFINITE-PRINT.BAS +++ b/examples/GOTO/INFINITE-PRINT.BAS @@ -1,5 +1,9 @@ -10 A=1 -20 PRINT A -30 A=A+1 -40 GOTO 20 -50 END \ No newline at end of file +10 REM Infinite counter that stops on any keypress +20 A = 1 +30 PRINT A +40 A = A + 1 +45 FOR D = 1 TO 50: NEXT D +50 A$ = INKEY$ +60 IF A$ <> "" THEN END +70 GOTO 30 +80 END diff --git a/examples/IF-THEN/IF-THEN-ELSE.BAS b/examples/IF-THEN/IF-THEN-ELSE.BAS new file mode 100644 index 0000000..efabfca --- /dev/null +++ b/examples/IF-THEN/IF-THEN-ELSE.BAS @@ -0,0 +1,5 @@ +10 REM IF...THEN...ELSE example +20 INPUT "Enter a number: "; A +30 IF A > 0 THEN PRINT "POSITIVE" ELSE PRINT "ZERO OR NEGATIVE" +40 GOTO 20 +50 END diff --git a/examples/INKEYS/MOVE-CHAR-SCREEN.BAS b/examples/INKEYS/MOVE-CHAR-SCREEN.BAS index de2d150..b8231c1 100644 --- a/examples/INKEYS/MOVE-CHAR-SCREEN.BAS +++ b/examples/INKEYS/MOVE-CHAR-SCREEN.BAS @@ -1,14 +1,21 @@ 10 SCREEN 0: WIDTH 40 -20 LOCATE 10, 10: PRINT "@" +20 CLS 30 x = 10: y = 10 -40 a$ = INKEY$ -50 IF a$ = "W" OR a$ = "w" THEN y = y - 1 -60 IF a$ = "S" OR a$ = "s" THEN y = y + 1 -70 IF a$ = "A" OR a$ = "a" THEN x = x - 1 -80 IF a$ = "D" OR a$ = "d" THEN x = x + 1 -90 IF x < 1 THEN x = 1 -100 IF x > 40 THEN x = 40 -110 IF y < 1 THEN y = 1 -120 IF y > 24 THEN y = 24 -130 LOCATE x, y: PRINT "@" -140 GOTO 40 +40 LOCATE x, y: PRINT "@" +50 A$ = "" +60 DO +70 A$ = INKEY$ +80 IF A$ = "W" OR A$ = "w" THEN LOCATE x, y: PRINT " ": y = y - 1 +90 IF A$ = "S" OR A$ = "s" THEN LOCATE x, y: PRINT " ": y = y + 1 +100 IF A$ = "A" OR A$ = "a" THEN LOCATE x, y: PRINT " ": x = x - 1 +110 IF A$ = "D" OR A$ = "d" THEN LOCATE x, y: PRINT " ": x = x + 1 +120 IF x < 1 THEN x = 1 +130 IF x > 40 THEN x = 40 +140 IF y < 1 THEN y = 1 +150 IF y > 24 THEN y = 24 +160 LOCATE x, y: PRINT "@" +170 FOR J = 1 TO 10: NEXT J +180 LOOP UNTIL A$ = "Q" OR A$ = "q" +190 CLS +200 PRINT "Exited." +210 END diff --git a/examples/LET/ASSIGNMENT.BAS b/examples/LET/ASSIGNMENT.BAS new file mode 100644 index 0000000..5f1758c --- /dev/null +++ b/examples/LET/ASSIGNMENT.BAS @@ -0,0 +1,5 @@ +10 REM LET optional assignment example +20 LET A = 10 +30 B = A + 5 +40 PRINT "A ="; A; " B ="; B +50 END diff --git a/examples/LINE/LINE-PATTERN.BAS b/examples/LINE/LINE-PATTERN.BAS new file mode 100644 index 0000000..a40c162 --- /dev/null +++ b/examples/LINE/LINE-PATTERN.BAS @@ -0,0 +1,13 @@ +10 REM Concentric rectangles using LINE +20 SCREEN 2: COLOR 15,1,7: CLS +30 FOR I = 0 TO 95 STEP 8 +40 LINE (128-I,95-I)-(128+I,95+I),1,B +50 NEXT +60 OPEN "GRP:" FOR OUTPUT AS #1 +70 PRINT #1, "Press any key to continue..." +80 DO +90 A$ = INKEY$ +100 LOOP UNTIL A$ <> "" +110 CLOSE #1 +120 SCREEN 0 +130 END diff --git a/examples/LIST/LIST-DEMO.BAS b/examples/LIST/LIST-DEMO.BAS new file mode 100644 index 0000000..a268e30 --- /dev/null +++ b/examples/LIST/LIST-DEMO.BAS @@ -0,0 +1,3 @@ +10 PRINT "This program will be listed with LIST" +20 PRINT "Line two" +30 END diff --git a/examples/NEW/NEW-DEMO.BAS b/examples/NEW/NEW-DEMO.BAS new file mode 100644 index 0000000..487bac6 --- /dev/null +++ b/examples/NEW/NEW-DEMO.BAS @@ -0,0 +1,3 @@ +10 REM Save program then type NEW at the prompt to clear program and variables +20 PRINT "This program will be cleared by NEW" +30 END diff --git a/examples/OPEN/OPEN-TEXT.BAS b/examples/OPEN/OPEN-TEXT.BAS new file mode 100644 index 0000000..45f2600 --- /dev/null +++ b/examples/OPEN/OPEN-TEXT.BAS @@ -0,0 +1,12 @@ +10 REM Create and read a text file using OPEN/PRINT#/LINE INPUT +20 OPEN "HELLO.TXT" FOR OUTPUT AS #1 +30 PRINT #1, "Hello world!" +40 PRINT #1, "Saved from OPEN example" +50 CLOSE #1 +60 OPEN "HELLO.TXT" FOR INPUT AS #1 +70 IF EOF(1) THEN 110 +80 LINE INPUT #1, A$ +90 PRINT A$ +100 IF NOT EOF(1) THEN GOTO 80 +110 CLOSE #1 +120 END diff --git a/examples/PAINT/PAINT-DEMO.BAS b/examples/PAINT/PAINT-DEMO.BAS new file mode 100644 index 0000000..8395298 --- /dev/null +++ b/examples/PAINT/PAINT-DEMO.BAS @@ -0,0 +1,13 @@ +10 COLOR 15,4,7: SCREEN 2: CLS +20 CIRCLE (80,80), 30, 8 +30 PAINT (80,80), 8 +40 LINE (170,20)-(220,80),2,B +50 PAINT (180,40), 2, 2 +60 OPEN "GRP:" FOR OUTPUT AS #1 +70 PRINT #1, "Press any key to continue..." +80 DO +90 A$ = INKEY$ +100 LOOP UNTIL A$ <> "" +110 CLOSE #1 +120 SCREEN 0 +130 END diff --git a/examples/PEEK/PEEK-READ.BAS b/examples/PEEK/PEEK-READ.BAS new file mode 100644 index 0000000..c1613e6 --- /dev/null +++ b/examples/PEEK/PEEK-READ.BAS @@ -0,0 +1,3 @@ +10 REM PEEK demonstration +20 PRINT "PEEK(60000) ="; PEEK(60000) +30 END diff --git a/examples/PLAY/PLAY-MEL.BAS b/examples/PLAY/PLAY-MEL.BAS new file mode 100644 index 0000000..330a9e8 --- /dev/null +++ b/examples/PLAY/PLAY-MEL.BAS @@ -0,0 +1,3 @@ +10 REM Simple PLAY melody (PSG) +20 PLAY "CDE","","" +30 END diff --git a/examples/POINT/POINT-DEMO.BAS b/examples/POINT/POINT-DEMO.BAS new file mode 100644 index 0000000..4a2b74d --- /dev/null +++ b/examples/POINT/POINT-DEMO.BAS @@ -0,0 +1,10 @@ +10 REM Plot points then sample their color with POINT +20 SCREEN 2: COLOR 15,1,7: CLS +30 PSET (80,60), 5 +40 PSET (100,60), 6 +50 A = POINT(80,60) +60 B = POINT(100,60) +70 SCREEN 0 +80 PRINT "POINT(80,60) ="; A +90 PRINT "POINT(100,60) ="; B +100 END diff --git a/examples/POKE/POKE-PEEK.BAS b/examples/POKE/POKE-PEEK.BAS new file mode 100644 index 0000000..c8e989e --- /dev/null +++ b/examples/POKE/POKE-PEEK.BAS @@ -0,0 +1,5 @@ +10 REM WARNING: POKE writes to memory. Use with caution on real hardware. +20 POKE 60000, 123 +30 PRINT "POKED 123 into 60000" +40 PRINT "PEEK(60000) ="; PEEK(60000) +50 END diff --git a/examples/PRESET/PRESET-RANDOM.BAS b/examples/PRESET/PRESET-RANDOM.BAS new file mode 100644 index 0000000..cb23d34 --- /dev/null +++ b/examples/PRESET/PRESET-RANDOM.BAS @@ -0,0 +1,16 @@ +10 REM PRESET example: draw lines then random presets, wait for key to exit +20 SCREEN 2: COLOR 15,1,7: CLS +30 LINE (20,20)-(200,120), 3, B +40 FOR I=1 TO 200 +50 X = INT(RND(1) * 180) + 20 +60 Y = INT(RND(1) * 100) + 20 +70 PRESET (X,Y) +80 NEXT I +90 OPEN "GRP:" FOR OUTPUT AS #1 +100 PRINT #1, "Press any key to continue..." +110 DO +120 A$ = INKEY$ +130 LOOP UNTIL A$ <> "" +140 CLOSE #1 +150 SCREEN 0 +160 END diff --git a/examples/PRINT/PRINT-BASIC.BAS b/examples/PRINT/PRINT-BASIC.BAS new file mode 100644 index 0000000..8e725de --- /dev/null +++ b/examples/PRINT/PRINT-BASIC.BAS @@ -0,0 +1,7 @@ +10 REM PRINT basic usage: semicolon vs comma and shorthand '?' +20 PRINT "HELLO, WORLD" +30 PRINT "SUM ="; 2 + 3 +40 PRINT "A"; "B"; "C" +50 PRINT "COL1", "COL2" +60 ? "SHORTHAND PRINT" +70 END diff --git a/examples/PSET/PSET-RANDOM.BAS b/examples/PSET/PSET-RANDOM.BAS new file mode 100644 index 0000000..e784d8a --- /dev/null +++ b/examples/PSET/PSET-RANDOM.BAS @@ -0,0 +1,16 @@ +10 REM Draw 500 random colored pixels with PSET, wait for key to exit +20 SCREEN 2: COLOR 15,1,7: CLS +30 FOR I = 1 TO 500 +40 X = INT(RND(1) * 256) +50 Y = INT(RND(1) * 192) +60 C = INT(RND(1) * 15) + 1 +70 PSET (X,Y), C +80 NEXT I +90 OPEN "GRP:" FOR OUTPUT AS #1 +100 PRINT #1, "Press any key to continue..." +110 DO +120 A$ = INKEY$ +130 LOOP UNTIL A$ <> "" +140 CLOSE #1 +150 SCREEN 0 +160 END diff --git a/examples/REM/COMMENTS.BAS b/examples/REM/COMMENTS.BAS new file mode 100644 index 0000000..11ffdab --- /dev/null +++ b/examples/REM/COMMENTS.BAS @@ -0,0 +1,4 @@ +10 REM This is a REM comment +20 ' This is an apostrophe comment +30 PRINT "Comments do not affect execution" +40 END diff --git a/examples/RUN/RUN-DEMO.BAS b/examples/RUN/RUN-DEMO.BAS new file mode 100644 index 0000000..adcc695 --- /dev/null +++ b/examples/RUN/RUN-DEMO.BAS @@ -0,0 +1,2 @@ +10 PRINT "This program demonstrates RUN" +20 END diff --git a/examples/SAVE/SAVE-DEMO.BAS b/examples/SAVE/SAVE-DEMO.BAS new file mode 100644 index 0000000..166ffdb --- /dev/null +++ b/examples/SAVE/SAVE-DEMO.BAS @@ -0,0 +1,3 @@ +10 REM Simple program to save +20 PRINT "HELLO, SAVE DEMO" +30 END diff --git a/examples/SCREEN/SCREEN-SWITCH.BAS b/examples/SCREEN/SCREEN-SWITCH.BAS new file mode 100644 index 0000000..c3449a1 --- /dev/null +++ b/examples/SCREEN/SCREEN-SWITCH.BAS @@ -0,0 +1,15 @@ +10 REM Switch to graphics, draw shapes, then return to text +20 SCREEN 0: PRINT "Press any key to switch to GRAPHICS" +30 A$ = INKEY$ +40 IF A$ = "" THEN 30 +50 SCREEN 2: COLOR 15,1,7: CLS +60 LINE (10,10)-(200,100),2 +70 CIRCLE (127,95),50,3 +80 OPEN "GRP:" FOR OUTPUT AS #1 +90 PRINT #1, "You are in GRAPHICS mode - press any key" +100 A$ = INKEY$ +110 IF A$ = "" THEN 100 +120 CLOSE #1 +130 SCREEN 0: CLS +140 PRINT "Back to text mode" +150 END diff --git a/examples/SOUND/SOUND-NOTE.BAS b/examples/SOUND/SOUND-NOTE.BAS new file mode 100644 index 0000000..fe745a7 --- /dev/null +++ b/examples/SOUND/SOUND-NOTE.BAS @@ -0,0 +1,10 @@ +10 REM Play a single note on PSG channel A +20 FOR R = 0 TO 13 +30 IF R = 7 THEN SOUND R, 191 ELSE SOUND R, 0 +40 NEXT R +50 SOUND 0, 172 ' low 8 bits of frequency for channel A +60 SOUND 1, 1 ' high 4 bits of frequency for channel A +70 SOUND 8, 12 ' volume for channel A +80 SOUND 7, 190 ' enable channel A tone generator +90 FOR T = 1 TO 5000: NEXT T +100 END diff --git a/examples/STOP/STOP-DEMO.BAS b/examples/STOP/STOP-DEMO.BAS new file mode 100644 index 0000000..db56977 --- /dev/null +++ b/examples/STOP/STOP-DEMO.BAS @@ -0,0 +1,4 @@ +10 PRINT "BEFORE STOP" +20 STOP +30 PRINT "AFTER STOP" +40 END diff --git a/index.html b/index.html new file mode 100644 index 0000000..a3f3828 --- /dev/null +++ b/index.html @@ -0,0 +1,12 @@ + + + + + + MSX BASIC Docs + + +
+ + + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..d0b8d92 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1207 @@ +{ + "name": "msx-basic-docs", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "msx-basic-docs", + "version": "0.1.0", + "dependencies": { + "js-yaml": "^4.1.0", + "markdown-it": "^13.0.1", + "markdown-it-anchor": "^8.6.6", + "prismjs": "^1.29.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^7.15.0" + }, + "devDependencies": { + "@types/js-yaml": "^4.0.5", + "@types/prismjs": "^1.26.0", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0", + "@vitejs/plugin-react": "^4.0.0", + "typescript": "^5.0.4", + "vite": "^5.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", + "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz", + "integrity": "sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz", + "integrity": "sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz", + "integrity": "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.27", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", + "integrity": "sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.3.tgz", + "integrity": "sha512-DAZDBHQfG2oQuhY7mc6I3/qB4LU2fQCjRvxbDwd/Jdvb9fypP4IJ4qmtu6lNjes6B531AI8cg1aKC2di97bUxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.3.tgz", + "integrity": "sha512-cRxsE8c13mZOh3vP+wLDxpQBRrOHDIGOWyDL93Sy0Ga8y515fBcC2pjUfFwUe5T7tqvTvWbCpg1URM/AXdWIXA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/markdown-it": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", + "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", + "license": "MIT", + "peer": true, + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "license": "MIT", + "peer": true + }, + "node_modules/@types/prismjs": { + "version": "1.26.6", + "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.6.tgz", + "integrity": "sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/prop-types": { + "version": "15.7.15", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz", + "integrity": "sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "18.3.28", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.28.tgz", + "integrity": "sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.3.7", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz", + "integrity": "sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^18.0.0" + } + }, + "node_modules/@vitejs/plugin-react": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz", + "integrity": "sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.28.0", + "@babel/plugin-transform-react-jsx-self": "^7.27.1", + "@babel/plugin-transform-react-jsx-source": "^7.27.1", + "@rolldown/pluginutils": "1.0.0-beta.27", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.17.0" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.27", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.27.tgz", + "integrity": "sha512-zEs/ufmZoUd7WftKpKyXaT6RFxpQ5Qm9xytKRHvJfxFV9DFJkZph9RvJ1LcOUi0Z1ZVijMte65JbILeV+8QQEA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.28.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz", + "integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.10.12", + "caniuse-lite": "^1.0.30001782", + "electron-to-chromium": "^1.5.328", + "node-releases": "^2.0.36", + "update-browserslist-db": "^1.2.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001792", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz", + "integrity": "sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.352", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.352.tgz", + "integrity": "sha512-9wHk8x6dyuimoe18EdiDPWKExNdxYqo4fn4FwOVVper6RxT3cmpBwBkWWfSOCYJjQdIco/nPhJhNLmn4Ufg1Yg==", + "dev": true, + "license": "ISC" + }, + "node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "license": "MIT", + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/markdown-it": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.2.tgz", + "integrity": "sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it-anchor": { + "version": "8.6.7", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz", + "integrity": "sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA==", + "license": "Unlicense", + "peerDependencies": { + "@types/markdown-it": "*", + "markdown-it": "*" + } + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz", + "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.38", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.38.tgz", + "integrity": "sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.2" + }, + "peerDependencies": { + "react": "^18.3.1" + } + }, + "node_modules/react-refresh": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", + "integrity": "sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-router": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.15.0.tgz", + "integrity": "sha512-HW9vYwuM8f4yx66Izy8xfrzCM+SBJluoZcCbww9A1TySax11S5Vgw6fi3ZjMONw9J4gQwngL7PzkyIpJJpJ7RQ==", + "license": "MIT", + "dependencies": { + "cookie": "^1.0.1", + "set-cookie-parser": "^2.6.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/react-router-dom": { + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.15.0.tgz", + "integrity": "sha512-VcrVg64Fo8nwBvDscajG8gRTLIuTC6N50nb22l2HOOV4PTOHgoGp8mUjy9wLiHYoYTSYI36tUnXZgasSRFZorQ==", + "license": "MIT", + "dependencies": { + "react-router": "7.15.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "react": ">=18", + "react-dom": ">=18" + } + }, + "node_modules/rollup": { + "version": "4.60.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.3.tgz", + "integrity": "sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.60.3", + "@rollup/rollup-android-arm64": "4.60.3", + "@rollup/rollup-darwin-arm64": "4.60.3", + "@rollup/rollup-darwin-x64": "4.60.3", + "@rollup/rollup-freebsd-arm64": "4.60.3", + "@rollup/rollup-freebsd-x64": "4.60.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.3", + "@rollup/rollup-linux-arm-musleabihf": "4.60.3", + "@rollup/rollup-linux-arm64-gnu": "4.60.3", + "@rollup/rollup-linux-arm64-musl": "4.60.3", + "@rollup/rollup-linux-loong64-gnu": "4.60.3", + "@rollup/rollup-linux-loong64-musl": "4.60.3", + "@rollup/rollup-linux-ppc64-gnu": "4.60.3", + "@rollup/rollup-linux-ppc64-musl": "4.60.3", + "@rollup/rollup-linux-riscv64-gnu": "4.60.3", + "@rollup/rollup-linux-riscv64-musl": "4.60.3", + "@rollup/rollup-linux-s390x-gnu": "4.60.3", + "@rollup/rollup-linux-x64-gnu": "4.60.3", + "@rollup/rollup-linux-x64-musl": "4.60.3", + "@rollup/rollup-openbsd-x64": "4.60.3", + "@rollup/rollup-openharmony-arm64": "4.60.3", + "@rollup/rollup-win32-arm64-msvc": "4.60.3", + "@rollup/rollup-win32-ia32-msvc": "4.60.3", + "@rollup/rollup-win32-x64-gnu": "4.60.3", + "@rollup/rollup-win32-x64-msvc": "4.60.3", + "fsevents": "~2.3.2" + } + }, + "node_modules/scheduler": { + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-cookie-parser": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", + "license": "MIT" + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..de4236c --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "msx-basic-docs", + "version": "0.1.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview --port 5173" + }, + "dependencies": { + "js-yaml": "^4.1.0", + "markdown-it": "^13.0.1", + "markdown-it-anchor": "^8.6.6", + "prismjs": "^1.29.0", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^7.15.0" + }, + "devDependencies": { + "@types/js-yaml": "^4.0.5", + "@types/prismjs": "^1.26.0", + "@types/react": "^18.2.0", + "@types/react-dom": "^18.2.0", + "@vitejs/plugin-react": "^4.0.0", + "typescript": "^5.0.4", + "vite": "^5.0.0" + } +} diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..e45d7e9 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,42 @@ +import React, { useMemo } from 'react' +import { Routes, Route, Navigate, useNavigate } from 'react-router-dom' +import Layout from './components/Layout/Layout' +import MarkdownPage from './pages/MarkdownPage' + +type DocsMap = { + slug: string + title: string + content: string +} + +const rawModules = import.meta.glob('/docs/*.md', { as: 'raw', eager: true }) as Record + +function getSlug(path: string) { + const parts = path.split('/') + const file = parts[parts.length - 1] + return file.replace(/\.md$/i, '') +} + +function getTitleFromContent(content: string) { + const m = content.match(/^#\s+(.*)/m) + return m ? m[1].trim() : '' +} + +export default function App(): JSX.Element { + const docs: DocsMap[] = useMemo(() => { + return Object.keys(rawModules) + .map((p) => ({ slug: getSlug(p), content: rawModules[p], title: getTitleFromContent(rawModules[p]) })) + .sort((a, b) => a.slug.localeCompare(b.slug)) + }, []) + + const first = docs[0]?.slug ?? 'index' + + return ( + + } /> + } /> + } /> + } /> + + ) +} diff --git a/src/Header.module.css b/src/Header.module.css new file mode 100644 index 0000000..dd6d1a0 --- /dev/null +++ b/src/Header.module.css @@ -0,0 +1,27 @@ +/* Minimal styles for existing Header.tsx to avoid build errors */ +.header { background: #fff; border-bottom: 1px solid #eee } +.headerContent { max-width: 1200px; margin: 0 auto; display: flex; align-items: center; justify-content: space-between; padding: 12px 20px } +.logo { text-decoration: none } +.logoText { font-weight: 700 } +.logoSubtitle { font-size: 12px; color: #666 } + +/* Navigation */ +.nav { display: none } +.navOpen { display: block } +.navList { list-style: none; margin: 0; padding: 0; display: flex; gap: 18px; align-items: center; } +.navItem { margin: 0 } +.navLink { color: #1a73e8; text-decoration: none; font-weight: 500; padding: 6px 8px; border-radius: 6px } +.navLink:hover, .navLink:focus { text-decoration: underline; background: rgba(26,115,232,0.06) } + +.menuButton { background: transparent; border: none } +.hamburger span { display: block; width: 18px; height: 2px; background: #111; margin: 3px 0 } + +@media (min-width: 900px) { + .nav { display: block } + .menuButton { display: none } +} + +@media (max-width: 900px) { + /* on small screens, show vertical nav when open */ + .navOpen .navList { flex-direction: column; gap: 8px } +} diff --git a/src/Header.tsx b/src/Header.tsx new file mode 100644 index 0000000..42ca7a3 --- /dev/null +++ b/src/Header.tsx @@ -0,0 +1,62 @@ +import React from 'react' +import styles from './Header.module.css' + +export default function Header(): JSX.Element { + const [openMenu, setOpenMenu] = React.useState(false) + + return ( +
+
+ + MSX BASIC + Documentación + + + + + +
+
+ ) +} diff --git a/src/components/Layout/Layout.module.css b/src/components/Layout/Layout.module.css new file mode 100644 index 0000000..0aaf5e3 --- /dev/null +++ b/src/components/Layout/Layout.module.css @@ -0,0 +1,7 @@ +.root { display: flex; flex-direction: column; min-height: 100vh; } +.container { display: flex; gap: 24px; max-width: 1200px; margin: 0 auto; width: 100%; padding: 20px; } +.main { flex: 1; min-width: 0; } + +@media (max-width: 900px) { + .container { padding: 12px; } +} diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx new file mode 100644 index 0000000..35eedaf --- /dev/null +++ b/src/components/Layout/Layout.tsx @@ -0,0 +1,16 @@ +import React from 'react' +import styles from './Layout.module.css' +import Sidebar from '../Sidebar/Sidebar' +import Header from '../../Header' + +export default function Layout({ children, docs }: { children: React.ReactNode; docs: { slug: string; title: string; content: string }[] }) { + return ( +
+
+
+ +
{children}
+
+
+ ) +} diff --git a/src/components/Sidebar/Sidebar.module.css b/src/components/Sidebar/Sidebar.module.css new file mode 100644 index 0000000..c62a373 --- /dev/null +++ b/src/components/Sidebar/Sidebar.module.css @@ -0,0 +1,10 @@ +.sidebar { width: 260px; position: sticky; top: 90px; height: calc(100vh - 100px); overflow: auto; border-right: 1px solid #eee; padding-right: 12px } +.list { list-style: none; padding: 0; margin: 0; } +.item { margin-bottom: 8px; } +.item a { color: #333; text-decoration: none; } +.item a:hover { text-decoration: underline; } +.active a { font-weight: 600; } + +@media (max-width: 900px) { + .sidebar { width: 100%; position: relative; height: auto; border-right: none; padding-right: 0; } +} diff --git a/src/components/Sidebar/Sidebar.tsx b/src/components/Sidebar/Sidebar.tsx new file mode 100644 index 0000000..b9ff33d --- /dev/null +++ b/src/components/Sidebar/Sidebar.tsx @@ -0,0 +1,20 @@ +import React from 'react' +import { Link, useParams } from 'react-router-dom' +import styles from './Sidebar.module.css' + +export default function Sidebar({ docs }: { docs: { slug: string; title: string; content: string }[] }) { + const { slug } = useParams() + return ( + + ) +} diff --git a/src/components/TOC/TOC.module.css b/src/components/TOC/TOC.module.css new file mode 100644 index 0000000..25108c4 --- /dev/null +++ b/src/components/TOC/TOC.module.css @@ -0,0 +1,6 @@ +.toc { font-size: 14px; padding: 8px; background: #fafafa; border-radius: 6px; } +.toc ul { list-style: none; margin: 0; padding: 0; } +.toc li { margin: 6px 0; } +.toc a { color: #333; text-decoration: none; } +.level2 { padding-left: 10px; } +.level3 { padding-left: 18px; font-size: 13px } diff --git a/src/components/TOC/TOC.tsx b/src/components/TOC/TOC.tsx new file mode 100644 index 0000000..9fd437d --- /dev/null +++ b/src/components/TOC/TOC.tsx @@ -0,0 +1,17 @@ +import React from 'react' +import styles from './TOC.module.css' + +export default function TOC({ items }: { items: { id: string; text: string; level: number }[] }) { + if (!items || items.length === 0) return
+ return ( + + ) +} diff --git a/src/env.d.ts b/src/env.d.ts new file mode 100644 index 0000000..9c70d56 --- /dev/null +++ b/src/env.d.ts @@ -0,0 +1,16 @@ +/// + +declare module '*.module.css' { + const classes: { [key: string]: string } + export default classes +} + +declare module '*.md' { + const content: string + export default content +} + +declare module '*.yml' { + const content: string + export default content +} diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..5480582 --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,13 @@ +import React from 'react' +import { createRoot } from 'react-dom/client' +import { BrowserRouter } from 'react-router-dom' +import App from './App' +import './styles/global.css' + +createRoot(document.getElementById('root')!).render( + + + + + +) diff --git a/src/pages/MarkdownPage.module.css b/src/pages/MarkdownPage.module.css new file mode 100644 index 0000000..83f6b63 --- /dev/null +++ b/src/pages/MarkdownPage.module.css @@ -0,0 +1,41 @@ +.article { padding: 24px; max-width: 1100px; margin: 0 auto; } +.header { margin-bottom: 12px; } +.title { font-size: 28px; margin: 0 0 8px 0; } +.wrapper { display: flex; gap: 24px; } +.content { flex: 1; min-width: 0; } +.toc { width: 260px; } + +@media (max-width: 900px) { + .wrapper { flex-direction: column; } + .toc { width: 100%; order: 2; } +} + +/* Basic content styles */ +.content h1, .content h2, .content h3 { scroll-margin-top: 80px; } + +/* Improved code block styles for readability */ +.content pre { + background: #0b0b0c; + color: #e6e6e6; + padding: 16px; + border-radius: 8px; + overflow: auto; + box-shadow: 0 8px 24px rgba(11,11,12,0.25); + font-size: 14px; + line-height: 1.6; + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, 'Roboto Mono', 'Courier New', monospace; +} + +/* Ensure code inside pre inherits color and no extra background */ +.content pre code { background: transparent; color: inherit; padding: 0; font-size: inherit; } + +/* Inline code keep subtle background */ +.content code { background: #f5f5f7; padding: 2px 6px; border-radius: 4px; } + +/* make selection readable inside code blocks */ +.content pre ::selection { background: rgba(255,255,255,0.12); color: #fff; } +.content pre code ::selection { background: rgba(255,255,255,0.12); color: #fff; } + +.content img { max-width: 100%; } +.content table { width: 100%; border-collapse: collapse; } +.content table th, .content table td { border: 1px solid #ddd; padding: 8px; } diff --git a/src/pages/MarkdownPage.tsx b/src/pages/MarkdownPage.tsx new file mode 100644 index 0000000..17f7474 --- /dev/null +++ b/src/pages/MarkdownPage.tsx @@ -0,0 +1,71 @@ +import React from 'react' +import { useParams } from 'react-router-dom' +import MarkdownIt from 'markdown-it' +import markdownItAnchor from 'markdown-it-anchor' +import Prism from 'prismjs' +import 'prismjs/components/prism-bash.js' +import 'prismjs/components/prism-jsx.js' +import 'prismjs/components/prism-python.js' +import styles from './MarkdownPage.module.css' +import TOC from '../components/TOC/TOC' + +type Doc = { slug: string; title: string; content: string } + +function useMarkdown() { + return React.useMemo(() => { + const md = new MarkdownIt({ html: true, linkify: true }) + md.use(markdownItAnchor, { permalink: true, permalinkClass: 'anchor', permalinkBefore: true }) + + const defaultRender = md.renderer.rules.fence || function(tokens, idx, options, env, self) { + return self.renderToken(tokens, idx, options) + } + + md.renderer.rules.fence = function (tokens, idx, options, env, self) { + const token = tokens[idx] + const info = token.info ? String(token.info).trim() : '' + const lang = info.split(/\s+/g)[0] + const code = token.content + if (lang && Prism.languages[lang]) { + try { + const highlighted = Prism.highlight(code, Prism.languages[lang], lang) + return `
${highlighted}
` + } catch (e) { + // fallthrough + } + } + return `
${md.utils.escapeHtml(code)}
` + } + + return md + }, []) +} + +export default function MarkdownPage({ docs }: { docs: Doc[] }): JSX.Element { + const { slug } = useParams<{ slug: string }>() + const md = useMarkdown() + + const doc = React.useMemo(() => docs.find(d => d.slug === (slug ?? '')) ?? docs[0], [docs, slug]) + const html = React.useMemo(() => md.render(doc?.content ?? ''), [md, doc]) + + // build TOC from rendered HTML + const toc = React.useMemo(() => { + if (!html) return [] as { id: string; text: string; level: number }[] + const parser = new DOMParser() + const docm = parser.parseFromString(html, 'text/html') + const nodes = Array.from(docm.querySelectorAll('h1,h2,h3')) + return nodes.map(n => ({ id: n.id || (n.textContent || '').trim().toLowerCase().replace(/[^a-z0-9]+/g, '-'), text: n.textContent || '', level: parseInt(n.tagName.substring(1), 10) })) + }, [html]) + + return ( +
+
+

{doc?.title || doc?.slug}

+
+ +
+
+ +
+
+ ) +} diff --git a/src/styles/global.css b/src/styles/global.css new file mode 100644 index 0000000..a65ce47 --- /dev/null +++ b/src/styles/global.css @@ -0,0 +1,10 @@ +/* Basic reset and global styles */ +:root { --bg: #fff; --text: #111 } +* { box-sizing: border-box } +html,body,#root { height: 100%; margin: 0; } +body { font-family: Inter, ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial; background: var(--bg); color: var(--text); line-height: 1.5 } +a { color: #1a73e8 } + +/* Prism minimal theme */ +pre[class*="language-"] { background: #0b0b0c; color: #e6e6e6; padding: 12px; border-radius: 6px; overflow: auto } +code { font-family: source-code-pro, Menlo, Monaco, 'Courier New', monospace } diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..de3bc50 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }], +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..afcfae6 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "module": "ESNext", + "moduleResolution": "Node", + "types": ["node"] + } +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..fe4d75f --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,19 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +export default defineConfig({ + plugins: [react()], + root: process.cwd(), + resolve: { + alias: { + '@docs': '/docs', + }, + }, + server: { + port: 5173, + }, + build: { + outDir: 'dist', + sourcemap: false, + }, +}) diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..c16099b --- /dev/null +++ b/yarn.lock @@ -0,0 +1,843 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.28.6", "@babel/code-frame@^7.29.0": + version "7.29.0" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz" + integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw== + dependencies: + "@babel/helper-validator-identifier" "^7.28.5" + js-tokens "^4.0.0" + picocolors "^1.1.1" + +"@babel/compat-data@^7.28.6": + version "7.29.3" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz" + integrity sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg== + +"@babel/core@^7.28.0": + version "7.29.0" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz" + integrity sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA== + dependencies: + "@babel/code-frame" "^7.29.0" + "@babel/generator" "^7.29.0" + "@babel/helper-compilation-targets" "^7.28.6" + "@babel/helper-module-transforms" "^7.28.6" + "@babel/helpers" "^7.28.6" + "@babel/parser" "^7.29.0" + "@babel/template" "^7.28.6" + "@babel/traverse" "^7.29.0" + "@babel/types" "^7.29.0" + "@jridgewell/remapping" "^2.3.5" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.29.0": + version "7.29.1" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz" + integrity sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw== + dependencies: + "@babel/parser" "^7.29.0" + "@babel/types" "^7.29.0" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" + +"@babel/helper-compilation-targets@^7.28.6": + version "7.28.6" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz" + integrity sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA== + dependencies: + "@babel/compat-data" "^7.28.6" + "@babel/helper-validator-option" "^7.27.1" + browserslist "^4.24.0" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-globals@^7.28.0": + version "7.28.0" + resolved "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz" + integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== + +"@babel/helper-module-imports@^7.28.6": + version "7.28.6" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz" + integrity sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw== + dependencies: + "@babel/traverse" "^7.28.6" + "@babel/types" "^7.28.6" + +"@babel/helper-module-transforms@^7.28.6": + version "7.28.6" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz" + integrity sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA== + dependencies: + "@babel/helper-module-imports" "^7.28.6" + "@babel/helper-validator-identifier" "^7.28.5" + "@babel/traverse" "^7.28.6" + +"@babel/helper-plugin-utils@^7.27.1": + version "7.28.6" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz" + integrity sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug== + +"@babel/helper-string-parser@^7.27.1": + version "7.27.1" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz" + integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== + +"@babel/helper-validator-identifier@^7.28.5": + version "7.28.5" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz" + integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q== + +"@babel/helper-validator-option@^7.27.1": + version "7.27.1" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz" + integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== + +"@babel/helpers@^7.28.6": + version "7.29.2" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz" + integrity sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw== + dependencies: + "@babel/template" "^7.28.6" + "@babel/types" "^7.29.0" + +"@babel/parser@^7.1.0", "@babel/parser@^7.20.7", "@babel/parser@^7.28.6", "@babel/parser@^7.29.0": + version "7.29.3" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.29.3.tgz" + integrity sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA== + dependencies: + "@babel/types" "^7.29.0" + +"@babel/plugin-transform-react-jsx-self@^7.27.1": + version "7.27.1" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.27.1.tgz" + integrity sha512-6UzkCs+ejGdZ5mFFC/OCUrv028ab2fp1znZmCZjAOBKiBK2jXD1O+BPSfX8X2qjJ75fZBMSnQn3Rq2mrBJK2mw== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-transform-react-jsx-source@^7.27.1": + version "7.27.1" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.27.1.tgz" + integrity sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/template@^7.28.6": + version "7.28.6" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz" + integrity sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ== + dependencies: + "@babel/code-frame" "^7.28.6" + "@babel/parser" "^7.28.6" + "@babel/types" "^7.28.6" + +"@babel/traverse@^7.28.6", "@babel/traverse@^7.29.0": + version "7.29.0" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz" + integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA== + dependencies: + "@babel/code-frame" "^7.29.0" + "@babel/generator" "^7.29.0" + "@babel/helper-globals" "^7.28.0" + "@babel/parser" "^7.29.0" + "@babel/template" "^7.28.6" + "@babel/types" "^7.29.0" + debug "^4.3.1" + +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.28.2", "@babel/types@^7.28.6", "@babel/types@^7.29.0": + version "7.29.0" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz" + integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.28.5" + +"@esbuild/aix-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz#c7184a326533fcdf1b8ee0733e21c713b975575f" + integrity sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ== + +"@esbuild/android-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz#09d9b4357780da9ea3a7dfb833a1f1ff439b4052" + integrity sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A== + +"@esbuild/android-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz#9b04384fb771926dfa6d7ad04324ecb2ab9b2e28" + integrity sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg== + +"@esbuild/android-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz#29918ec2db754cedcb6c1b04de8cd6547af6461e" + integrity sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA== + +"@esbuild/darwin-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz#e495b539660e51690f3928af50a76fb0a6ccff2a" + integrity sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ== + +"@esbuild/darwin-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz#c13838fa57372839abdddc91d71542ceea2e1e22" + integrity sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw== + +"@esbuild/freebsd-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz#646b989aa20bf89fd071dd5dbfad69a3542e550e" + integrity sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g== + +"@esbuild/freebsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz#aa615cfc80af954d3458906e38ca22c18cf5c261" + integrity sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ== + +"@esbuild/linux-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz#70ac6fa14f5cb7e1f7f887bcffb680ad09922b5b" + integrity sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q== + +"@esbuild/linux-arm@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz#fc6fd11a8aca56c1f6f3894f2bea0479f8f626b9" + integrity sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA== + +"@esbuild/linux-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz#3271f53b3f93e3d093d518d1649d6d68d346ede2" + integrity sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg== + +"@esbuild/linux-loong64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz#ed62e04238c57026aea831c5a130b73c0f9f26df" + integrity sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg== + +"@esbuild/linux-mips64el@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz#e79b8eb48bf3b106fadec1ac8240fb97b4e64cbe" + integrity sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg== + +"@esbuild/linux-ppc64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz#5f2203860a143b9919d383ef7573521fb154c3e4" + integrity sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w== + +"@esbuild/linux-riscv64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz#07bcafd99322d5af62f618cb9e6a9b7f4bb825dc" + integrity sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA== + +"@esbuild/linux-s390x@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz#b7ccf686751d6a3e44b8627ababc8be3ef62d8de" + integrity sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A== + +"@esbuild/linux-x64@0.21.5": + version "0.21.5" + resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz" + integrity sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ== + +"@esbuild/netbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz#bbe430f60d378ecb88decb219c602667387a6047" + integrity sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg== + +"@esbuild/openbsd-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz#99d1cf2937279560d2104821f5ccce220cb2af70" + integrity sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow== + +"@esbuild/sunos-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz#08741512c10d529566baba837b4fe052c8f3487b" + integrity sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg== + +"@esbuild/win32-arm64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz#675b7385398411240735016144ab2e99a60fc75d" + integrity sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A== + +"@esbuild/win32-ia32@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz#1bfc3ce98aa6ca9a0969e4d2af72144c59c1193b" + integrity sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA== + +"@esbuild/win32-x64@0.21.5": + version "0.21.5" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz#acad351d582d157bb145535db2a6ff53dd514b5c" + integrity sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw== + +"@jridgewell/gen-mapping@^0.3.12", "@jridgewell/gen-mapping@^0.3.5": + version "0.3.13" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz" + integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/remapping@^2.3.5": + version "2.3.5" + resolved "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz" + integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.5" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz" + integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== + +"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.28": + version "0.3.31" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz" + integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@rolldown/pluginutils@1.0.0-beta.27": + version "1.0.0-beta.27" + resolved "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz" + integrity sha512-+d0F4MKMCbeVUJwG96uQ4SgAznZNSq93I3V+9NHA4OpvqG8mRCpGdKmK8l/dl02h2CCDHwW2FqilnTyDcAnqjA== + +"@rollup/rollup-android-arm-eabi@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.3.tgz#31503ca40424374cd6c5198031cf4d5a73de9727" + integrity sha512-x35CNW/ANXG3hE/EZpRU8MXX1JDN86hBb2wMGAtltkz7pc6cxgjpy1OMMfDosOQ+2hWqIkag/fGok1Yady9nGw== + +"@rollup/rollup-android-arm64@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.3.tgz#7cbc30c88507013d0f982cfeb8884337ba1e0bb2" + integrity sha512-xw3xtkDApIOGayehp2+Rz4zimfkaX65r4t47iy+ymQB2G4iJCBBfj0ogVg5jpvjpn8UWn/+q9tprxleYeNp3Hw== + +"@rollup/rollup-darwin-arm64@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.3.tgz#bc341a93bb2111326a2865f55d1d23baedecf40c" + integrity sha512-vo6Y5Qfpx7/5EaamIwi0WqW2+zfiusVihKatLvtN1VFVy3D13uERk/6gZLU1UiHRL6fDXqj/ELIeVRGnvcTE1g== + +"@rollup/rollup-darwin-x64@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.3.tgz#dfa0236581c55ecc0bcaeb2ea1f2e800c58dc3e2" + integrity sha512-D+0QGcZhBzTN82weOnsSlY7V7+RMmPuF1CkbxyMAGE8+ZHeUjyb76ZiWmBlCu//AQQONvxcqRbwZTajZKqjuOw== + +"@rollup/rollup-freebsd-arm64@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.3.tgz#4c5977413b87808a13b5edd524e46fafddb85b52" + integrity sha512-6HnvHCT7fDyj6R0Ph7A6x8dQS/S38MClRWeDLqc0MdfWkxjiu1HSDYrdPhqSILzjTIC/pnXbbJbo+ft+gy/9hQ== + +"@rollup/rollup-freebsd-x64@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.3.tgz#5cb2cee62ffee3ada4a0b44353e96cf98cfc7c3c" + integrity sha512-KHLgC3WKlUYW3ShFKnnosZDOJ0xjg9zp7au3sIm2bs/tGBeC2ipmvRh/N7JKi0t9Ue20C0dpEshi8WUubg+cnA== + +"@rollup/rollup-linux-arm-gnueabihf@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.3.tgz#04700cad36dd43ae81044fe7ee73e925845c4b85" + integrity sha512-DV6fJoxEYWJOvaZIsok7KrYl0tPvga5OZ2yvKHNNYyk/2roMLqQAbGhr78EQ5YhHpnhLKJD3S1WFusAkmUuV5g== + +"@rollup/rollup-linux-arm-musleabihf@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.3.tgz#548ebf3997b3a6dcc7cdd7da813ff0c46000ac0a" + integrity sha512-mQKoJAzvuOs6F+TZybQO4GOTSMUu7v0WdxEk24krQ/uUxXoPTtHjuaUuPmFhtBcM4K0ons8nrE3JyhTuCFtT/w== + +"@rollup/rollup-linux-arm64-gnu@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.3.tgz#0264608f504b33725639ebe93be02c40e71a35c1" + integrity sha512-Whjj2qoiJ6+OOJMGptTYazaJvjOJm+iKHpXQM1P3LzGjt7Ff++Tp7nH4N8J/BUA7R9IHfDyx4DJIflifwnbmIA== + +"@rollup/rollup-linux-arm64-musl@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.3.tgz#147cf4889502cd3b331a800b8ca6741f87873079" + integrity sha512-4YTNHKqGng5+yiZt3mg77nmyuCfmNfX4fPmyUapBcIk+BdwSwmCWGXOUxhXbBEkFHtoN5boLj/5NON+u5QC9tg== + +"@rollup/rollup-linux-loong64-gnu@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.3.tgz#0c27c6b5258dcb3d0290e3bd04ba6277c9d7e541" + integrity sha512-SU3kNlhkpI4UqlUc2VXPGK9o886ZsSeGfMAX2ba2b8DKmMXq4AL7KUrkSWVbb7koVqx41Yczx6dx5PNargIrEA== + +"@rollup/rollup-linux-loong64-musl@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.3.tgz#f0f18075ea0bfa2c992f8e3933b39b6ef91f7799" + integrity sha512-6lDLl5h4TXpB1mTf2rQWnAk/LcXrx9vBfu/DT5TIPhvMhRWaZ5MxkIc8u4lJAmBo6klTe1ywXIUHFjylW505sg== + +"@rollup/rollup-linux-ppc64-gnu@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.3.tgz#149bb5cb8893589ffaa1924b4eac4282e9fa4c69" + integrity sha512-BMo8bOw8evlup/8G+cj5xWtPyp93xPdyoSN16Zy90Q2QZ0ZYRhCt6ZJSwbrRzG9HApFabjwj2p25TUPDWrhzqQ== + +"@rollup/rollup-linux-ppc64-musl@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.3.tgz#200a063e298b05f996917d2aa53de749d54c0ca0" + integrity sha512-E0L8X1dZN1/Rph+5VPF6Xj2G7JJvMACVXtamTJIDrVI44Y3K+G8gQaMEAavbqCGTa16InptiVrX6eM6pmJ+7qA== + +"@rollup/rollup-linux-riscv64-gnu@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.3.tgz#6d6d6eb996197ba86f95f9a6c442bc862f0756d4" + integrity sha512-oZJ/WHaVfHUiRAtmTAeo3DcevNsVvH8mbvodjZy7D5QKvCefO371SiKRpxoDcCxB3PTRTLayWBkvmDQKTcX/sw== + +"@rollup/rollup-linux-riscv64-musl@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.3.tgz#9deb86001785cfcbc761457f50cd7c112fda0df9" + integrity sha512-Dhbyh7j9FybM3YaTgaHmVALwA8AkUwTPccyCQ79TG9AJUsMQqgN1DDEZNr4+QUfwiWvLDumW5vdwzoeUF+TNxQ== + +"@rollup/rollup-linux-s390x-gnu@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.3.tgz#d8228720c6e42da190d96c31a3495d70cf8284b9" + integrity sha512-cJd1X5XhHHlltkaypz1UcWLA8AcoIi1aWhsvaWDskD1oz2eKCypnqvTQ8ykMNI0RSmm7NkTdSqSSD7zM0xa6Ig== + +"@rollup/rollup-linux-x64-gnu@4.60.3": + version "4.60.3" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.3.tgz" + integrity sha512-DAZDBHQfG2oQuhY7mc6I3/qB4LU2fQCjRvxbDwd/Jdvb9fypP4IJ4qmtu6lNjes6B531AI8cg1aKC2di97bUxA== + +"@rollup/rollup-linux-x64-musl@4.60.3": + version "4.60.3" + resolved "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.3.tgz" + integrity sha512-cRxsE8c13mZOh3vP+wLDxpQBRrOHDIGOWyDL93Sy0Ga8y515fBcC2pjUfFwUe5T7tqvTvWbCpg1URM/AXdWIXA== + +"@rollup/rollup-openbsd-x64@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.3.tgz#e1080f0efb8b15cda39b3e62de5fb806079ab6e9" + integrity sha512-QaWcIgRxqEdQdhJqW4DJctsH6HCmo5vHxY0krHSX4jMtOqfzC+dqDGuHM87bu4H8JBeibWx7jFz+h6/4C8wA5Q== + +"@rollup/rollup-openharmony-arm64@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.3.tgz#1fbda2d95c29dbfceb62785431754cd5aab86c72" + integrity sha512-AaXwSvUi3QIPtroAUw1t5yHGIyqKEXwH54WUocFolZhpGDruJcs8c+xPNDRn4XiQsS7MEwnYsHW2l0MBLDMkWg== + +"@rollup/rollup-win32-arm64-msvc@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.3.tgz#deab3470815f97996f1d0d3608549cf1b7e4ffc2" + integrity sha512-65LAKM/bAWDqKNEelHlcHvm2V+Vfb8C6INFxQXRHCvaVN1rJfwr4NvdP4FyzUaLqWfaCGaadf6UbTm8xJeYfEg== + +"@rollup/rollup-win32-ia32-msvc@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.3.tgz#817acae2ed4572960b59235ff2322381b6d82f26" + integrity sha512-EEM2gyhBF5MFnI6vMKdX1LAosE627RGBzIoGMdLloPZkXrUN0Ckqgr2Qi8+J3zip/8NVVro3/FjB+tjhZUgUHA== + +"@rollup/rollup-win32-x64-gnu@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.3.tgz#48129be99b0250d76b9c6d0ac983bef563a1c48a" + integrity sha512-E5Eb5H/DpxaoXH++Qkv28RcUJboMopmdDUALBczvHMf7hNIxaDZqwY5lK12UK1BHacSmvupoEWGu+n993Z0y1A== + +"@rollup/rollup-win32-x64-msvc@4.60.3": + version "4.60.3" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.3.tgz#cc6f094a3ffe5556bb4a831ee6fb572b8cd81a75" + integrity sha512-hPt/bgL5cE+Qp+/TPHBqptcAgPzgj46mPcg/16zNUmbQk0j+mOEQV/+Lqu8QRtDV3Ek95Q6FeFITpuhl6OTsAA== + +"@types/babel__core@^7.20.5": + version "7.20.5" + resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== + dependencies: + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.27.0" + resolved "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz" + integrity sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.4" + resolved "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*": + version "7.28.0" + resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz" + integrity sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q== + dependencies: + "@babel/types" "^7.28.2" + +"@types/estree@1.0.8": + version "1.0.8" + resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz" + integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== + +"@types/js-yaml@^4.0.5": + version "4.0.9" + resolved "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz" + integrity sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg== + +"@types/prismjs@^1.26.0": + version "1.26.6" + resolved "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.6.tgz" + integrity sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw== + +"@types/prop-types@*": + version "15.7.15" + resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz" + integrity sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw== + +"@types/react-dom@^18.2.0": + version "18.3.7" + resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.7.tgz" + integrity sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ== + +"@types/react@^18.2.0": + version "18.3.28" + resolved "https://registry.npmjs.org/@types/react/-/react-18.3.28.tgz" + integrity sha512-z9VXpC7MWrhfWipitjNdgCauoMLRdIILQsAEV+ZesIzBq/oUlxk0m3ApZuMFCXdnS4U7KrI+l3WRUEGQ8K1QKw== + dependencies: + "@types/prop-types" "*" + csstype "^3.2.2" + +"@vitejs/plugin-react@^4.0.0": + version "4.7.0" + resolved "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz" + integrity sha512-gUu9hwfWvvEDBBmgtAowQCojwZmJ5mcLn3aufeCsitijs3+f2NsrPtlAWIR6OPiqljl96GVCUbLe0HyqIpVaoA== + dependencies: + "@babel/core" "^7.28.0" + "@babel/plugin-transform-react-jsx-self" "^7.27.1" + "@babel/plugin-transform-react-jsx-source" "^7.27.1" + "@rolldown/pluginutils" "1.0.0-beta.27" + "@types/babel__core" "^7.20.5" + react-refresh "^0.17.0" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +baseline-browser-mapping@^2.10.12: + version "2.10.27" + resolved "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.27.tgz" + integrity sha512-zEs/ufmZoUd7WftKpKyXaT6RFxpQ5Qm9xytKRHvJfxFV9DFJkZph9RvJ1LcOUi0Z1ZVijMte65JbILeV+8QQEA== + +browserslist@^4.24.0: + version "4.28.2" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz" + integrity sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg== + dependencies: + baseline-browser-mapping "^2.10.12" + caniuse-lite "^1.0.30001782" + electron-to-chromium "^1.5.328" + node-releases "^2.0.36" + update-browserslist-db "^1.2.3" + +caniuse-lite@^1.0.30001782: + version "1.0.30001792" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001792.tgz" + integrity sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +cookie@^1.0.1: + version "1.1.1" + resolved "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz" + integrity sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ== + +csstype@^3.2.2: + version "3.2.3" + resolved "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz" + integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ== + +debug@^4.1.0, debug@^4.3.1: + version "4.4.3" + resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + +electron-to-chromium@^1.5.328: + version "1.5.352" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.352.tgz" + integrity sha512-9wHk8x6dyuimoe18EdiDPWKExNdxYqo4fn4FwOVVper6RxT3cmpBwBkWWfSOCYJjQdIco/nPhJhNLmn4Ufg1Yg== + +entities@~3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz" + integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== + +esbuild@^0.21.3: + version "0.21.5" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz" + integrity sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw== + optionalDependencies: + "@esbuild/aix-ppc64" "0.21.5" + "@esbuild/android-arm" "0.21.5" + "@esbuild/android-arm64" "0.21.5" + "@esbuild/android-x64" "0.21.5" + "@esbuild/darwin-arm64" "0.21.5" + "@esbuild/darwin-x64" "0.21.5" + "@esbuild/freebsd-arm64" "0.21.5" + "@esbuild/freebsd-x64" "0.21.5" + "@esbuild/linux-arm" "0.21.5" + "@esbuild/linux-arm64" "0.21.5" + "@esbuild/linux-ia32" "0.21.5" + "@esbuild/linux-loong64" "0.21.5" + "@esbuild/linux-mips64el" "0.21.5" + "@esbuild/linux-ppc64" "0.21.5" + "@esbuild/linux-riscv64" "0.21.5" + "@esbuild/linux-s390x" "0.21.5" + "@esbuild/linux-x64" "0.21.5" + "@esbuild/netbsd-x64" "0.21.5" + "@esbuild/openbsd-x64" "0.21.5" + "@esbuild/sunos-x64" "0.21.5" + "@esbuild/win32-arm64" "0.21.5" + "@esbuild/win32-ia32" "0.21.5" + "@esbuild/win32-x64" "0.21.5" + +escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + +fsevents@~2.3.2, fsevents@~2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^4.1.0: + version "4.1.1" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz" + integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== + dependencies: + argparse "^2.0.1" + +jsesc@^3.0.2: + version "3.1.0" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz" + integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== + +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +linkify-it@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz" + integrity sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw== + dependencies: + uc.micro "^1.0.1" + +loose-envify@^1.1.0: + version "1.4.0" + resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +markdown-it-anchor@^8.6.6: + version "8.6.7" + resolved "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.7.tgz" + integrity sha512-FlCHFwNnutLgVTflOYHPW2pPcl2AACqVzExlkGQNsi4CJgqOHN7YTgDd4LuhgN1BFO3TS0vLAruV1Td6dwWPJA== + +markdown-it@^13.0.1: + version "13.0.2" + resolved "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.2.tgz" + integrity sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w== + dependencies: + argparse "^2.0.1" + entities "~3.0.1" + linkify-it "^4.0.1" + mdurl "^1.0.1" + uc.micro "^1.0.5" + +mdurl@^1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz" + integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== + +ms@^2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +nanoid@^3.3.11: + version "3.3.12" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz" + integrity sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ== + +node-releases@^2.0.36: + version "2.0.38" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.38.tgz" + integrity sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw== + +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + +postcss@^8.4.43: + version "8.5.14" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz" + integrity sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg== + dependencies: + nanoid "^3.3.11" + picocolors "^1.1.1" + source-map-js "^1.2.1" + +prismjs@^1.29.0: + version "1.30.0" + resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz" + integrity sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw== + +react-dom@^18.2.0: + version "18.3.1" + resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz" + integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.2" + +react-refresh@^0.17.0: + version "0.17.0" + resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz" + integrity sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ== + +react-router-dom@^7.15.0: + version "7.15.0" + resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.15.0.tgz" + integrity sha512-VcrVg64Fo8nwBvDscajG8gRTLIuTC6N50nb22l2HOOV4PTOHgoGp8mUjy9wLiHYoYTSYI36tUnXZgasSRFZorQ== + dependencies: + react-router "7.15.0" + +react-router@7.15.0: + version "7.15.0" + resolved "https://registry.npmjs.org/react-router/-/react-router-7.15.0.tgz" + integrity sha512-HW9vYwuM8f4yx66Izy8xfrzCM+SBJluoZcCbww9A1TySax11S5Vgw6fi3ZjMONw9J4gQwngL7PzkyIpJJpJ7RQ== + dependencies: + cookie "^1.0.1" + set-cookie-parser "^2.6.0" + +react@^18.2.0: + version "18.3.1" + resolved "https://registry.npmjs.org/react/-/react-18.3.1.tgz" + integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== + dependencies: + loose-envify "^1.1.0" + +rollup@^4.20.0: + version "4.60.3" + resolved "https://registry.npmjs.org/rollup/-/rollup-4.60.3.tgz" + integrity sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A== + dependencies: + "@types/estree" "1.0.8" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.60.3" + "@rollup/rollup-android-arm64" "4.60.3" + "@rollup/rollup-darwin-arm64" "4.60.3" + "@rollup/rollup-darwin-x64" "4.60.3" + "@rollup/rollup-freebsd-arm64" "4.60.3" + "@rollup/rollup-freebsd-x64" "4.60.3" + "@rollup/rollup-linux-arm-gnueabihf" "4.60.3" + "@rollup/rollup-linux-arm-musleabihf" "4.60.3" + "@rollup/rollup-linux-arm64-gnu" "4.60.3" + "@rollup/rollup-linux-arm64-musl" "4.60.3" + "@rollup/rollup-linux-loong64-gnu" "4.60.3" + "@rollup/rollup-linux-loong64-musl" "4.60.3" + "@rollup/rollup-linux-ppc64-gnu" "4.60.3" + "@rollup/rollup-linux-ppc64-musl" "4.60.3" + "@rollup/rollup-linux-riscv64-gnu" "4.60.3" + "@rollup/rollup-linux-riscv64-musl" "4.60.3" + "@rollup/rollup-linux-s390x-gnu" "4.60.3" + "@rollup/rollup-linux-x64-gnu" "4.60.3" + "@rollup/rollup-linux-x64-musl" "4.60.3" + "@rollup/rollup-openbsd-x64" "4.60.3" + "@rollup/rollup-openharmony-arm64" "4.60.3" + "@rollup/rollup-win32-arm64-msvc" "4.60.3" + "@rollup/rollup-win32-ia32-msvc" "4.60.3" + "@rollup/rollup-win32-x64-gnu" "4.60.3" + "@rollup/rollup-win32-x64-msvc" "4.60.3" + fsevents "~2.3.2" + +scheduler@^0.23.2: + version "0.23.2" + resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz" + integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== + dependencies: + loose-envify "^1.1.0" + +semver@^6.3.1: + version "6.3.1" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +set-cookie-parser@^2.6.0: + version "2.7.2" + resolved "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz" + integrity sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw== + +source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + +typescript@^5.0.4: + version "5.9.3" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz" + integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw== + +uc.micro@^1.0.1, uc.micro@^1.0.5: + version "1.0.6" + resolved "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz" + integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA== + +update-browserslist-db@^1.2.3: + version "1.2.3" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz" + integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w== + dependencies: + escalade "^3.2.0" + picocolors "^1.1.1" + +vite@^5.0.0: + version "5.4.21" + resolved "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz" + integrity sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw== + dependencies: + esbuild "^0.21.3" + postcss "^8.4.43" + rollup "^4.20.0" + optionalDependencies: + fsevents "~2.3.3" + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==