ducklingscript


Nameducklingscript JSON
Version 0.1.3.1 PyPI version JSON
download
home_pagehttps://github.com/DragonOfShuu/DucklingScript/
SummaryA transcompiler for converting DucklingScript code into Rubber Ducky Language 1.0
upload_time2023-12-10 23:20:51
maintainer
docs_urlNone
authorDragon of Shuu
requires_python>=3.11,<4.0
license
keywords duckyscript flipper ducky key injection
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            ![DucklingScript Header](https://github.com/DragonOfShuu/DucklingScript/blob/main/git_docs/DucklingScriptHeader.png?raw=true)

<!-- # DUCKLINGSCRIPT -->
![PyPI - Downloads](https://img.shields.io/pypi/dm/ducklingscript)

Welcome to DucklingScript, a language that compiles into Rubber Ducky Scripting Language 1.0! DucklingScript is the best language to use for BadUSB on the Flipper Zero. Although this is the main idea, there are many other applications as well!

# Table of Contents
Please note that not all sections are listed, but mainly the most important headers are.

 - [Why DucklingScript](#why-ducklingscript)
 - [Language Basics](#language-basics)
 - [Installation](#installation)
 - [DucklingScript: Crash Course](#ducklingscript-crash-course)
   - [Project Creation](#project-creation)
   - [Simple Commands](#simple-commands)
     - [Command Grouping](#command-grouping)
     - [Dollar Sign Operator](#dollar-sign-operator)
   - [Block Commands](#block-commands)
   - [Variables and Functions](#variables-and-functions)
   - [Flow Control](#flow-control)
     - [If Statements](#conditional-statements)
     - [For Loops](#for-loops)
     - [While Loops](#while-loops)
   - [Multi-File Projects](#multi-file-projects)
   - [Debugging Commands](#debugging-commands)
   - [Expression Evaluation](#expression-evaluation)
 - [Command Line Interface](#command-line-interface)
   - [Commands](#cli-commands)
     - [New](#new)
     - [Compile](#compile)
     - [Help](#help)
     - [All](#all)
     - [Version](#version)
   - [Global Config](#global-config-file)
 - [Contributing](#contributing)
 - [Future Plans](#future-plans)

# Why DucklingScript?

There are many key points to using DucklingScript. Here are some of those now.

## Type Safety

Because DucklingScript has to go through a compilation process, it means DucklingScript can validate your script will work on your hardware. It will tell you that there is an error, and it will tell you exactly where. For example, CTRL requires one character. DucklingScript will validate that this is true.

## Flow Control

Rubber Ducky Scripting Language 1.0 and even the Flipper's implementation don't add any kind of flow control. e.g. if statements, while/for loops, etc. DucklingScript gives you those capabilities, and more!

## Syntactical Speed

Normal Rubber Ducky Scripting 1.0 doesn't give much room for speed, and oftentimes leads you to repeating yourself in code. Not only does DucklingScript add commands to improve this, it also makes small syntactical changes. Such as:

Rubber Ducky 1.0
```
STRINGLN Hello,
STRINGLN world,
STRINGLN it is I!
```
DucklingScript
```
STRINGLN 
    Hello,
    world,
    it is I!
```

## Forward Compatibility

If you use a command that does not exist in Rubber Ducky 1.0, DucklingScript will simply warn you that this is the case (these warnings can even be supressed using a flag on compilation, or editing the config file). However, it does not stop you from doing so. This allows you to use future commands!

# Language Basics

First off, DucklingScript allows for all syntax of [Rubber Ducky Scripting Language 1.0](https://web.archive.org/web/20220816200129/http://github.com/hak5darren/USB-Rubber-Ducky/wiki/Duckyscript), as well as the [Flipper Zero's BadUsb ducky extension](https://docs.flipper.net/bad-usb).

| ⚠️ Note For Flipper Compatibility ⚠️ |
|-------------
| If you are not using a device that can parse flipper commands, then you cannot use them. Please make sure to disable flipper commands if this is the case through the config file. |

# Installation

DucklingScript has been test on:

 - Windows 11
 - MacOS Ventura
 - Ubuntu Jammy (Linux)

## Step One

Make sure to have Python 3.11 or higher installed.

There are many places on the internet that will
explain how to download Python, but if 
you are on Windows, I recommend going 
[here](https://www.python.org/downloads/).

From here, you can either use pipx or pip to
install DucklingScript; I highly recommend
using pipx, because it handles putting the
scripts on `PATH` for you.

<details>
<summary>With pipx (recommended)</summary>

## Step Two

Install Pipx:
```bash
python3.11 -m pip install pipx
python3.11 -m pipx ensurepath
```

|⚠️|It is recommended that if you have mulitple Python versions to put the python version at the end of the command, as seen above.
|-|-|

This command should run flawlessly:
```bash
pipx --version
```

## Step Three
To install on any of the major operating systems, simply run:
```bash
pipx install ducklingscript
```

## Step Four

You now have a few options on how to run the command. This way works in most circumstances:
```bash
duckling --help
```

</details>

<details>
<summary>Without pipx</summary>

## Step Two
To install on any of the major operating systems, simply run:
```bash
pip3.11 install ducklingscript
```

|⚠️|It is recommended that if you have mulitple Python versions to put the python version at the end of the command, as seen above.
|-|-|

## Step Three

You now have a few options on how to run the command. This way works in most circumstances:
```bash
duckling --help
```

However, if the script is not put on `PATH`, then it might be best to do it this way:
```bash
pip -m ducklingscript --help
```

</details>


# DucklingScript: "Crash Course"

First, make sure to check the [Language Basics](#language-basics), and look through the documentation there to learn Rubber Ducky 1.0 and the Flipper commands.

## Project Creation

To create a new project, you can use the `new` command. Simply give the name for your project, and optionally a directory:
```bash
duckling new example-proj
```

|⚠️|You don't have to make a project; you can simply make a txt file and compile it if you wish
|-|-|

After making the project, go into the folder and you will see a `config.yaml` and a `main.txt`.
Any time your run the project, any of your global config settings will be overrided by the config inside the project.

To compile your project, simply run this command in the terminal while in your project:
```bash
duckling compile main.txt
```
When compiling any file in the root directory of your project, the config file will automatically be used.

DucklingScript files use the `.txt` file extension. This will be important for when we import external files later.

## Simple Commands

Simple commands can be characterized by a command that is a command and no argument, or a command with arguments, and no trailing code blocks. All Rubber Ducky 1.0 and Flipper Commands are Simple Commands.

However, in DucklingScript they have extended syntax.

### Command Grouping

Using indentation, you don't have to repeat yourself. You can simply make an indentation after the command, and write all arguments for the command. This may seem a bit confusing, so here's an example:

DucklingScript
```
STRING 
    Hello World!
    I enjoy DucklingScript!
```
Compiles into:
```bash
STRING Hello World!
STRING I enjoy DucklingScript!
```

This is a powerful feature, allowing you to type out everything you need all at once, instead of repeatedly typing `STRING`.

However, if you start using indents inside of those indents, you might encounter an error. You may need these extra indents if you are for example having your injection device write code. In that case, simply use three quotation marks like so:

```
STRINGLN
    """
    print("Starting Hacking Software...")
    for i in range(10):
        print(f"Hacking your pc in {i} second(s)")
        if i < 4:
            print("This is your final warning!")
    """
```

### Dollar Sign Operator

All simple commands that don't already [evaluate](#expression-evaluation) their arguments can use the dollar sign operator. This turns the argument into an expression that will evaluated.

This allows you to write mathematical expressions, or use variables; you can read more of that [here](#expression-evaluation).

| ⚠️ | When using the dollar sign operator, all strings are required to be incased in quotations like this: `"Hello World"`
|-|-|

### Examples

DucklingScript:
```
$CTRL 1+1
```
Compiled:
```bash
CTRL 2
```

DucklingScript:
```
$STRING "Hello " + "world!"
```
Compiled:
```bash
STRING Hello world!
```

This becomes more relevant and more important when we introduce variables.

## Block Commands

All Block commands will be commands that require an argument, and then a code block after. As of writing, all block commands are added by DucklingScript.

### Examples

DucklingScript
```
REM Command with arg
REPEAT 10
    REM Command's code block
    STRING foo
    STRING bar
```

*More info on `REPEAT` [here](#for-loops).

## Variables and Functions

### Variables
A variable can be understood as a sort of "drawer" that has a label, and contains some form of data of a specific type (either a string, number, or a boolean). Read more about data types and expression evaluation [here](#expression-evaluation).

```
VAR counter 0
REM a variable named "counter" now equals 0
```

```
VAR switch TRUE
REM a variable named "switch" is now TRUE
REM (Make sure that TRUE is in all caps)
```

### Functions

Functions allow you to run the same piece of code as many times as you want, where ever you want, plus the ability to control the variables inside.

To make a function, use the command named either `FUNC` or `FUNCTION`. After that, give the name, then following the name include all variable names separated by a comma.

To run a function, use the `RUN` command, followed by the name of the function to run, and then the value for all variables separated by comma in order as they were declared on function creation.

DucklingScript
```
FUNC hello
    STRING Hello World!

RUN hello
STRING In the middle
RUN hello
```
Compiled
```
STRING Hello World!
STRING In the middle
STRING Hello World!
```

DucklingScript
```
FUNC hello phrase,number
    $STRING "The number given was: "+number
    $STRING phrase

RUN hello "Foo/Bar",10
```
Compiled
```
STRING The number given was: 10
STRING Foo/Bar
```

It is also possible to leave a function early if you wish. Using the `RETURN` command, you can exit a function early.

DucklingScript
```
FUNC hello 
    STRING Hello!
    RETURN
    REM This does not run.
    STRING Goodbye!

RUN hello
```
Compiled
```
STRING Hello!
```

| ⚠️ | The return command can also be used outside of a function to exit out of your program early
|-|-|

## Flow Control

These are commands that manage how your injection is ran. These are conditionals and loops.

### Conditional Statements

Conditional Statements allow you to run code, only if a certain condition is met. In DucklingScript, we use the commands `IF`, `ELIF`, and `ELSE` to evaluate conditionals.

`ELIF` can only come after an `IF`, and `ELSE` can only come after an `ELIF` or `IF`. If any `IF` or `ELIF` are true, then all subsequent `ELIF`s and `ELSE`s are ignored. After that, you can create a new `IF` statement by using the `IF` command once again.

### Examples

DucklingScript
```
VAR a 10

REM if a is equal to 10
IF a == 10
    REM this code is ran
    STRINGLN Hello World

REM if a is not equal to 10
ELSE 
    STRINGLN Hello World Not Found :/
```

Compiled
```
STRINGLN Hello World
```

DucklingScript
```
VAR a 10

IF a > 10
    STRING a is greater than 10
ELIF a < 10
    STRING a is less than 10
ELSE
    STRING a is 10
```

Compiled
```
STRING a is 10
```

### For Loops

Rubber Ducky 1.0 actually includes a sort of "for" loop already. To do this, write `REPEAT` (DucklingScript also accepts `FOR`, and it does the same things) directly after the command you want to repeat. 

Please note that although possible in DucklingScript, DucklingScript does not support the ability to check if you have compiled code BEFORE the repeat statement, and therefore cannot fix any syntax issues in doing so.

| ⚠️ | Please note that there is a limit to for loops; for loops will eventually error if they run too many times. This can be avoided however by using inner for loops, but that is not recommended.
|-|-|

DucklingScript/Rubber Ducky 1.0
```
STRINGLN Hello World!
REPEAT 4
```

End Result
```
STRINGLN Hello World!
STRINGLN Hello World!
STRINGLN Hello World!
STRINGLN Hello World!
```

This is great, but unfortunately this will only work for one line of code. DucklingScript resolves this by including added syntax using indentation!

DucklingScript
```
REPEAT 3
    STRING Not only can I repeat...
    STRING ...but so can I!
```

Compiled
```
STRING Not only can I repeat...
STRING ...but so can I!
STRING Not only can I repeat...
STRING ...but so can I!
STRING Not only can I repeat...
STRING ...but so can I!
```

Not only that, but DucklingScript also includes the ability to count the amount of repeats that have occurred in a variable!

Please note that the first iteration is considered to be `0`.

The syntax for this is: `<variable name>, <iteration count>`.

DucklingScript
```
REPEAT i,3
    $STRING "this is iteration number "+i+"!" 
```
Compiled
```
STRING this is iteration number 0!
STRING this is iteration number 1!
STRING this is iteration number 2!
```

### While Loops

While loops are loops that continue to loop whilst a condition is true. 

| ⚠️ | Please note that there is a limit to while loops; while loops will eventually error if they run too many times.
|-|-|

DucklingScript
```
VAR a 10
WHILE a!=15
    VAR a a+1
    $STRING a
```
Compiled
```
STRING 11
STRING 12
STRING 13
STRING 14
STRING 15
```

DucklingScript
```
VAR a ""
WHILE a!="eee":
    VAR a a+"e"
    $STRING a
```
Compiled
```
STRING e
STRING ee
STRING eee
```

Just like the for loop, the while loop also allows you to implement a variable that stores the number of iterations completed.

DucklingScript
```
VAR a ""
WHILE count,a!="eee"
    VAR a a+"e"
    $STRING a + " [iteration: "+count+"]" 
```
Compiled
```
STRING e [iteration: 0]
STRING ee [iteration: 1]
STRING eee [iteration: 2]
```

### Loop Controls

DucklingScript offers to additional commands to assist with loop usage. These two commands help extend the usage of both kinds of loops.

#### BREAKLOOP

`BREAKLOOP`/`BREAK_LOOP` allows you to *break out* of a loop. This is especially useful if under a certain circumstance you need to leave a loop early.

DucklingScript
```
REPEAT i,10
    $STRING "iteration "+i
    IF i==2
        BREAKLOOP
```
Compiled
```
STRING iteration 0
STRING iteration 1
STRING iteration 2
```

As you can see, we left the while loop early because `i` was equal to two.

#### CONTINUELOOP

`CONTINUELOOP`/`CONTINUE_LOOP`/`CONTINUE` allows you to *continue* through the loop.

DucklingScript
```
REPEAT i,5
    IF i==3
        CONTINUELOOP
    $STRING "I like the number "+i+"!" 
```
Compiled
```
STRING I like the number 0!
STRING I like the number 1!
STRING I like the number 2!
STRING I like the number 4!
```

As you can see, the number 3 is missing from the compiled, because `CONTINUE` continued the loop, ignoring the resulting code after it.

## Multi-File Projects

DuckingScript supports multi-file projects using the `START`, `STARTENV`, `STARTCODE` commands.

All `START` commands start with the same general syntax, and they allow you to compile the code from another file into the output file. For this to work however, make sure to use the `.txt` extension on all files.

To start another file, simply use the `START` command, and for the argument put the file name. As long as both files are in the same folder, this will work flawlessly.

File Structure
```
Project
|-main.txt
|-startme.txt
```
DucklingScript - startme.txt
```
STRING "startme" says hello!
```
DucklingScript - main.txt
```
START startme
STRING ran startme file.
```
Compiled
```
STRING "startme" says hello!
STRING ran startme file.
```

This is great and all, but would if you want to access a file that is inside a folder? Or maybe the file is one level up. In this case comes the dot operator. To go inside a folder, give the name of the folder, then put a dot after. After that dot put the name of the file.

Similarly, if you want to go a level up, put a dot at the very beginning of the argument.

File Structure
```
Project
|-above.txt
|-middle
  |-main.txt
  |-below
    |-below.txt
```
DucklingScript - above.txt
```
STRING Hello from above!
```
DucklingScript - below.txt
```
STRING Hello from below!
```
DucklingScript - main.txt
```
REM Using the dot operator at the beginning, we can go up a folder
REM Using the dot operator in the middle allows use to go into a folder
START
    .above
    below.below
```
Compiled
```
STRING Hello from above!
STRING Hello from below!
```

## Debugging Commands

Because DucklingScript ramps up the complexity of your programs, discovering exactly what is happening might become difficult. This is why DucklingScript adds more commands for debugging!

First is `PRINT`, which allows you to send text to the console when you ocmpile your injection.

DucklingScript
```
PRINT Hello World!
```
Console output
```
--> Captured STD:OUT
example.txt - 1 > Hello World!
---
```

The next one is `NOTEXIST`/`NOT_EXIST`, which allows you to raise an error if the given variable exists.

DucklingScript
```
VAR a "hello world"
NOTEXIST a
```
Console Output
```
---
In file 'X:\test.txt', on line 2
> NOTEXIST a
GeneralError: 'a' does exist.
---
```

The next up is the opposite of `NOTEXIST`, which is `EXIST`. This raises an error if the given variable doesn't exist.

DucklingScript
```
EXIST a
```
Console Output
```
---
In file 'X:\test.txt', on line 1
> EXIST a
GeneralError: 'a' does not exist.
---
```

Finally, we have `PASS`, which allows you to fill in the block space for a block command without actually doing anything. Although a comment works too, `PASS` is cleaner, and allows you to find what hasn't been completed yet in a language specific way.

DucklingScript
```
FUNC a
    PASS
```

## Expression Evaluation

DucklingScript allows mathematical/logical/conditional expressions. Assuming you already have a basic understanding of 'normal' programming, you should understand ***most*** of this already.

### Data Types

A string is a data type containing characters. It must be wrapped in quotation marks.
```
"Hello World"
```

A number is a data type containing, well, a number
```
100
```
A boolean is either a TRUE or FALSE value. When using these keywords in DucklingScript, make sure to keep them as all caps.
```
TRUE
FALSE
```

### Mathematics

DucklingScript will follow the rules of PEMDAS (please note that addition/subtraction, and multiplication/division are evaluated left to right. However, multiplation/division is evaluated before addition/subtraction).

Please note floor division and modulus share the same precedence as multiplication/division.

Here are all of the operators that DucklingScript accepts:

Exponents:
```
10^2
```
Result is 100

Addition/subtraction
```
5+5
5-5
```
Result is 10, and 0

Multiplication/division
```
5*5
5/5
```
Result is 25, and 1

Floor Division
```
3//2
```
Result is 1 (the decimal is essentially truncated, meaning removed)

Modulus
```
5%2
```
Result is 1 (when dividing 5 by 2, there is a remainder of 1)

As well as these, `string`s can also be added together, and can even be added together with other data types:

```
"Hello, I like the number "+5
```
Result is `Hello, I like the number 5`

### Conditionals

Conditional operators produce a true/false statement (a boolean). Conditionals are evaluated after all mathematical statements, and all Conditionals have the same precedence, meaning they are evaluated left to right.

Equal to
```
5==2
10==10
```
Results are `FALSE`, and `TRUE`

Not equal to
```
5!=2
10!=10
```
Results are `TRUE`, and `FALSE`

Greater than
```
5>2
10>10
```
Results are `TRUE`, and `FALSE`

Lesser than
```
5<2
10<10
```
Both result in `FALSE`

Greater than or equal to
```
5>=2
10>=10
```
Both result in `TRUE`

Lesser than or equal to
```
5<=2
10<=10
```
Results are `FALSE`, and `TRUE`

Not
```
!(FALSE)
!(5!=2)
!TRUE
```
The results are `TRUE`, `FALSE`, and an *error*

| ⚠️ | Unlike other programming languages, in DucklingScript the `NOT` operator requires parenthesis
|-|-|

# Command Line Interface (CLI)

The command line interface is used to compile your code, and help assist you on your programming endeavors.

When you need help on using the CLI, you can use `--help`:
```bash
duckling --help
```

You can also use `--help` on specific commands:
```bash
duckling compile --help
```

## CLI Commands
### New

Creates a new project. This project will include a config file, and a main file.

Command:
```
duckling new [OPTIONS] NAME [PATH]
```

Example:
```
duckling new example-proj
```
Output Tree
```
example-proj
|- config.yaml
|- main.txt
```

### Compile

The `compile` command compiles your DucklingScript code into Rubber Ducky Language 1.0. Give the file to compile, and then give the output location.

Usage:
```
Usage: duckling compile [OPTIONS] FILENAME [OUTPUT]
```

Options given to you through the command can also be adjusted through global config files.

### Help

The `help` command gives you details on any command you give it. 

Usage:
```
duckling help [OPTIONS] COMMAND_NAME
```

Output if we give it `string`:
```
duckling help string
```

![DucklingScript help example](https://github.com/DragonOfShuu/DucklingScript/blob/main/git_docs/Duckling-help-ex.png?raw=true)

### All

The `all` command gives all the commands in the programming language. In the future, this may include all *plug-in* commands as well.

All commands as of November 28th, 2023:
![All DucklingScript example](https://github.com/DragonOfShuu/DucklingScript/blob/main/git_docs/Duckling-all-ex.png?raw=true)

### Version

Gives the current version of DucklingScript.

Command:
```
duckling version
```

Output as of November 28th, 2023:
```
Ducklingscript is version 0.1.0
```

## Global Config File

Upon using the CLI in anyway, a global config is made/edited. The keys inside of the
global config should be identical to the keys that you find inside of the project
scoped config file. By editing the global config, you can change configurations for
any time you compile a project-less script.

# Contributing

Python versin must be 3.11 or higher. From then on, I recommend
putting the python version at the end of any command involving
`python` or `pip`, like so:

```bash
python3.11 --version
pip3.11 --version
```

By doing this, you avoid mixing python versions.

## Installing Poetry

Then, you will need to install [poetry](https://python-poetry.org/docs/). You can either
use the docs given, or you can follow the steps below.

I recommend using pipx, however poetry offers many options. Find the pipx documentation
[here](https://pipx.pypa.io/stable/installation/).

These steps should work on Windows. **However, pipx recommends using `brew` to install 
pipx on MacOS.**
```bash
python3.11 -m pip install pipx
python3.11 -m pipx ensurepath
```

Restart your terminal, then run:
```bash
pipx install poetry
poetry --version
```
Poetry should now work as a command.

## With Poetry Installed

With poetry installed, inside of the directory 
of the project, run these commands:

```bash
poetry install
poetry shell
```

This will install the necessary dependencies, and take you 
into the virtual environment for the project.

Now, while in the virtual environment, you can run the
`duckling` command!

```bash
duckling --version
```

## Contribution Requirements

Before making a pull request, please format your project
using the black command (while in the virtual environment
provided by poetry of course):

Run this at the root of the project dir:
```bash
black .
```

As well as this, make sure all tests succeed:
```bash
pytest
```

If you've read through this section throughly, write
"I've read the Contribution Requirements" in your
pull request.

# Future Plans

DucklingScript is still not fully complete, so naturally of course there are still plans in the works.

Here are the main ones:

 - **Add Plugin Support.** This will allow users to use plugins made by the community; these could include macros (such as open powershell), or possibly new functionality (like a block command).

 - **Add Built-in Flipper-Connect System.** This would allow a developer to compile their code directly onto the flipper, which cuts out the need to use a software such as qFlipper.

 - **Live Python Interpretation.** This would run your code directly on your computer, and skip the process of compiling to Rubber Ducky Language 1.0. 
            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/DragonOfShuu/DucklingScript/",
    "name": "ducklingscript",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.11,<4.0",
    "maintainer_email": "",
    "keywords": "duckyscript,flipper,ducky,key injection",
    "author": "Dragon of Shuu",
    "author_email": "loganmcederlof@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/4a/de/b402784f8c7077c7897af6fe072ea0b3101b1d8d294a0347ed55e6e8269c/ducklingscript-0.1.3.1.tar.gz",
    "platform": null,
    "description": "![DucklingScript Header](https://github.com/DragonOfShuu/DucklingScript/blob/main/git_docs/DucklingScriptHeader.png?raw=true)\n\n<!-- # DUCKLINGSCRIPT -->\n![PyPI - Downloads](https://img.shields.io/pypi/dm/ducklingscript)\n\nWelcome to DucklingScript, a language that compiles into Rubber Ducky Scripting Language 1.0! DucklingScript is the best language to use for BadUSB on the Flipper Zero. Although this is the main idea, there are many other applications as well!\n\n# Table of Contents\nPlease note that not all sections are listed, but mainly the most important headers are.\n\n - [Why DucklingScript](#why-ducklingscript)\n - [Language Basics](#language-basics)\n - [Installation](#installation)\n - [DucklingScript: Crash Course](#ducklingscript-crash-course)\n   - [Project Creation](#project-creation)\n   - [Simple Commands](#simple-commands)\n     - [Command Grouping](#command-grouping)\n     - [Dollar Sign Operator](#dollar-sign-operator)\n   - [Block Commands](#block-commands)\n   - [Variables and Functions](#variables-and-functions)\n   - [Flow Control](#flow-control)\n     - [If Statements](#conditional-statements)\n     - [For Loops](#for-loops)\n     - [While Loops](#while-loops)\n   - [Multi-File Projects](#multi-file-projects)\n   - [Debugging Commands](#debugging-commands)\n   - [Expression Evaluation](#expression-evaluation)\n - [Command Line Interface](#command-line-interface)\n   - [Commands](#cli-commands)\n     - [New](#new)\n     - [Compile](#compile)\n     - [Help](#help)\n     - [All](#all)\n     - [Version](#version)\n   - [Global Config](#global-config-file)\n - [Contributing](#contributing)\n - [Future Plans](#future-plans)\n\n# Why DucklingScript?\n\nThere are many key points to using DucklingScript. Here are some of those now.\n\n## Type Safety\n\nBecause DucklingScript has to go through a compilation process, it means DucklingScript can validate your script will work on your hardware. It will tell you that there is an error, and it will tell you exactly where. For example, CTRL requires one character. DucklingScript will validate that this is true.\n\n## Flow Control\n\nRubber Ducky Scripting Language 1.0 and even the Flipper's implementation don't add any kind of flow control. e.g. if statements, while/for loops, etc. DucklingScript gives you those capabilities, and more!\n\n## Syntactical Speed\n\nNormal Rubber Ducky Scripting 1.0 doesn't give much room for speed, and oftentimes leads you to repeating yourself in code. Not only does DucklingScript add commands to improve this, it also makes small syntactical changes. Such as:\n\nRubber Ducky 1.0\n```\nSTRINGLN Hello,\nSTRINGLN world,\nSTRINGLN it is I!\n```\nDucklingScript\n```\nSTRINGLN \n    Hello,\n    world,\n    it is I!\n```\n\n## Forward Compatibility\n\nIf you use a command that does not exist in Rubber Ducky 1.0, DucklingScript will simply warn you that this is the case (these warnings can even be supressed using a flag on compilation, or editing the config file). However, it does not stop you from doing so. This allows you to use future commands!\n\n# Language Basics\n\nFirst off, DucklingScript allows for all syntax of [Rubber Ducky Scripting Language 1.0](https://web.archive.org/web/20220816200129/http://github.com/hak5darren/USB-Rubber-Ducky/wiki/Duckyscript), as well as the [Flipper Zero's BadUsb ducky extension](https://docs.flipper.net/bad-usb).\n\n| \u26a0\ufe0f Note For Flipper Compatibility \u26a0\ufe0f |\n|-------------\n| If you are not using a device that can parse flipper commands, then you cannot use them. Please make sure to disable flipper commands if this is the case through the config file. |\n\n# Installation\n\nDucklingScript has been test on:\n\n - Windows 11\n - MacOS Ventura\n - Ubuntu Jammy (Linux)\n\n## Step One\n\nMake sure to have Python 3.11 or higher installed.\n\nThere are many places on the internet that will\nexplain how to download Python, but if \nyou are on Windows, I recommend going \n[here](https://www.python.org/downloads/).\n\nFrom here, you can either use pipx or pip to\ninstall DucklingScript; I highly recommend\nusing pipx, because it handles putting the\nscripts on `PATH` for you.\n\n<details>\n<summary>With pipx (recommended)</summary>\n\n## Step Two\n\nInstall Pipx:\n```bash\npython3.11 -m pip install pipx\npython3.11 -m pipx ensurepath\n```\n\n|\u26a0\ufe0f|It is recommended that if you have mulitple Python versions to put the python version at the end of the command, as seen above.\n|-|-|\n\nThis command should run flawlessly:\n```bash\npipx --version\n```\n\n## Step Three\nTo install on any of the major operating systems, simply run:\n```bash\npipx install ducklingscript\n```\n\n## Step Four\n\nYou now have a few options on how to run the command. This way works in most circumstances:\n```bash\nduckling --help\n```\n\n</details>\n\n<details>\n<summary>Without pipx</summary>\n\n## Step Two\nTo install on any of the major operating systems, simply run:\n```bash\npip3.11 install ducklingscript\n```\n\n|\u26a0\ufe0f|It is recommended that if you have mulitple Python versions to put the python version at the end of the command, as seen above.\n|-|-|\n\n## Step Three\n\nYou now have a few options on how to run the command. This way works in most circumstances:\n```bash\nduckling --help\n```\n\nHowever, if the script is not put on `PATH`, then it might be best to do it this way:\n```bash\npip -m ducklingscript --help\n```\n\n</details>\n\n\n# DucklingScript: \"Crash Course\"\n\nFirst, make sure to check the [Language Basics](#language-basics), and look through the documentation there to learn Rubber Ducky 1.0 and the Flipper commands.\n\n## Project Creation\n\nTo create a new project, you can use the `new` command. Simply give the name for your project, and optionally a directory:\n```bash\nduckling new example-proj\n```\n\n|\u26a0\ufe0f|You don't have to make a project; you can simply make a txt file and compile it if you wish\n|-|-|\n\nAfter making the project, go into the folder and you will see a `config.yaml` and a `main.txt`.\nAny time your run the project, any of your global config settings will be overrided by the config inside the project.\n\nTo compile your project, simply run this command in the terminal while in your project:\n```bash\nduckling compile main.txt\n```\nWhen compiling any file in the root directory of your project, the config file will automatically be used.\n\nDucklingScript files use the `.txt` file extension. This will be important for when we import external files later.\n\n## Simple Commands\n\nSimple commands can be characterized by a command that is a command and no argument, or a command with arguments, and no trailing code blocks. All Rubber Ducky 1.0 and Flipper Commands are Simple Commands.\n\nHowever, in DucklingScript they have extended syntax.\n\n### Command Grouping\n\nUsing indentation, you don't have to repeat yourself. You can simply make an indentation after the command, and write all arguments for the command. This may seem a bit confusing, so here's an example:\n\nDucklingScript\n```\nSTRING \n    Hello World!\n    I enjoy DucklingScript!\n```\nCompiles into:\n```bash\nSTRING Hello World!\nSTRING I enjoy DucklingScript!\n```\n\nThis is a powerful feature, allowing you to type out everything you need all at once, instead of repeatedly typing `STRING`.\n\nHowever, if you start using indents inside of those indents, you might encounter an error. You may need these extra indents if you are for example having your injection device write code. In that case, simply use three quotation marks like so:\n\n```\nSTRINGLN\n    \"\"\"\n    print(\"Starting Hacking Software...\")\n    for i in range(10):\n        print(f\"Hacking your pc in {i} second(s)\")\n        if i < 4:\n            print(\"This is your final warning!\")\n    \"\"\"\n```\n\n### Dollar Sign Operator\n\nAll simple commands that don't already [evaluate](#expression-evaluation) their arguments can use the dollar sign operator. This turns the argument into an expression that will evaluated.\n\nThis allows you to write mathematical expressions, or use variables; you can read more of that [here](#expression-evaluation).\n\n| \u26a0\ufe0f | When using the dollar sign operator, all strings are required to be incased in quotations like this: `\"Hello World\"`\n|-|-|\n\n### Examples\n\nDucklingScript:\n```\n$CTRL 1+1\n```\nCompiled:\n```bash\nCTRL 2\n```\n\nDucklingScript:\n```\n$STRING \"Hello \" + \"world!\"\n```\nCompiled:\n```bash\nSTRING Hello world!\n```\n\nThis becomes more relevant and more important when we introduce variables.\n\n## Block Commands\n\nAll Block commands will be commands that require an argument, and then a code block after. As of writing, all block commands are added by DucklingScript.\n\n### Examples\n\nDucklingScript\n```\nREM Command with arg\nREPEAT 10\n    REM Command's code block\n    STRING foo\n    STRING bar\n```\n\n*More info on `REPEAT` [here](#for-loops).\n\n## Variables and Functions\n\n### Variables\nA variable can be understood as a sort of \"drawer\" that has a label, and contains some form of data of a specific type (either a string, number, or a boolean). Read more about data types and expression evaluation [here](#expression-evaluation).\n\n```\nVAR counter 0\nREM a variable named \"counter\" now equals 0\n```\n\n```\nVAR switch TRUE\nREM a variable named \"switch\" is now TRUE\nREM (Make sure that TRUE is in all caps)\n```\n\n### Functions\n\nFunctions allow you to run the same piece of code as many times as you want, where ever you want, plus the ability to control the variables inside.\n\nTo make a function, use the command named either `FUNC` or `FUNCTION`. After that, give the name, then following the name include all variable names separated by a comma.\n\nTo run a function, use the `RUN` command, followed by the name of the function to run, and then the value for all variables separated by comma in order as they were declared on function creation.\n\nDucklingScript\n```\nFUNC hello\n    STRING Hello World!\n\nRUN hello\nSTRING In the middle\nRUN hello\n```\nCompiled\n```\nSTRING Hello World!\nSTRING In the middle\nSTRING Hello World!\n```\n\nDucklingScript\n```\nFUNC hello phrase,number\n    $STRING \"The number given was: \"+number\n    $STRING phrase\n\nRUN hello \"Foo/Bar\",10\n```\nCompiled\n```\nSTRING The number given was: 10\nSTRING Foo/Bar\n```\n\nIt is also possible to leave a function early if you wish. Using the `RETURN` command, you can exit a function early.\n\nDucklingScript\n```\nFUNC hello \n    STRING Hello!\n    RETURN\n    REM This does not run.\n    STRING Goodbye!\n\nRUN hello\n```\nCompiled\n```\nSTRING Hello!\n```\n\n| \u26a0\ufe0f | The return command can also be used outside of a function to exit out of your program early\n|-|-|\n\n## Flow Control\n\nThese are commands that manage how your injection is ran. These are conditionals and loops.\n\n### Conditional Statements\n\nConditional Statements allow you to run code, only if a certain condition is met. In DucklingScript, we use the commands `IF`, `ELIF`, and `ELSE` to evaluate conditionals.\n\n`ELIF` can only come after an `IF`, and `ELSE` can only come after an `ELIF` or `IF`. If any `IF` or `ELIF` are true, then all subsequent `ELIF`s and `ELSE`s are ignored. After that, you can create a new `IF` statement by using the `IF` command once again.\n\n### Examples\n\nDucklingScript\n```\nVAR a 10\n\nREM if a is equal to 10\nIF a == 10\n    REM this code is ran\n    STRINGLN Hello World\n\nREM if a is not equal to 10\nELSE \n    STRINGLN Hello World Not Found :/\n```\n\nCompiled\n```\nSTRINGLN Hello World\n```\n\nDucklingScript\n```\nVAR a 10\n\nIF a > 10\n    STRING a is greater than 10\nELIF a < 10\n    STRING a is less than 10\nELSE\n    STRING a is 10\n```\n\nCompiled\n```\nSTRING a is 10\n```\n\n### For Loops\n\nRubber Ducky 1.0 actually includes a sort of \"for\" loop already. To do this, write `REPEAT` (DucklingScript also accepts `FOR`, and it does the same things) directly after the command you want to repeat. \n\nPlease note that although possible in DucklingScript, DucklingScript does not support the ability to check if you have compiled code BEFORE the repeat statement, and therefore cannot fix any syntax issues in doing so.\n\n| \u26a0\ufe0f | Please note that there is a limit to for loops; for loops will eventually error if they run too many times. This can be avoided however by using inner for loops, but that is not recommended.\n|-|-|\n\nDucklingScript/Rubber Ducky 1.0\n```\nSTRINGLN Hello World!\nREPEAT 4\n```\n\nEnd Result\n```\nSTRINGLN Hello World!\nSTRINGLN Hello World!\nSTRINGLN Hello World!\nSTRINGLN Hello World!\n```\n\nThis is great, but unfortunately this will only work for one line of code. DucklingScript resolves this by including added syntax using indentation!\n\nDucklingScript\n```\nREPEAT 3\n    STRING Not only can I repeat...\n    STRING ...but so can I!\n```\n\nCompiled\n```\nSTRING Not only can I repeat...\nSTRING ...but so can I!\nSTRING Not only can I repeat...\nSTRING ...but so can I!\nSTRING Not only can I repeat...\nSTRING ...but so can I!\n```\n\nNot only that, but DucklingScript also includes the ability to count the amount of repeats that have occurred in a variable!\n\nPlease note that the first iteration is considered to be `0`.\n\nThe syntax for this is: `<variable name>, <iteration count>`.\n\nDucklingScript\n```\nREPEAT i,3\n    $STRING \"this is iteration number \"+i+\"!\" \n```\nCompiled\n```\nSTRING this is iteration number 0!\nSTRING this is iteration number 1!\nSTRING this is iteration number 2!\n```\n\n### While Loops\n\nWhile loops are loops that continue to loop whilst a condition is true. \n\n| \u26a0\ufe0f | Please note that there is a limit to while loops; while loops will eventually error if they run too many times.\n|-|-|\n\nDucklingScript\n```\nVAR a 10\nWHILE a!=15\n    VAR a a+1\n    $STRING a\n```\nCompiled\n```\nSTRING 11\nSTRING 12\nSTRING 13\nSTRING 14\nSTRING 15\n```\n\nDucklingScript\n```\nVAR a \"\"\nWHILE a!=\"eee\":\n    VAR a a+\"e\"\n    $STRING a\n```\nCompiled\n```\nSTRING e\nSTRING ee\nSTRING eee\n```\n\nJust like the for loop, the while loop also allows you to implement a variable that stores the number of iterations completed.\n\nDucklingScript\n```\nVAR a \"\"\nWHILE count,a!=\"eee\"\n    VAR a a+\"e\"\n    $STRING a + \" [iteration: \"+count+\"]\" \n```\nCompiled\n```\nSTRING e [iteration: 0]\nSTRING ee [iteration: 1]\nSTRING eee [iteration: 2]\n```\n\n### Loop Controls\n\nDucklingScript offers to additional commands to assist with loop usage. These two commands help extend the usage of both kinds of loops.\n\n#### BREAKLOOP\n\n`BREAKLOOP`/`BREAK_LOOP` allows you to *break out* of a loop. This is especially useful if under a certain circumstance you need to leave a loop early.\n\nDucklingScript\n```\nREPEAT i,10\n    $STRING \"iteration \"+i\n    IF i==2\n        BREAKLOOP\n```\nCompiled\n```\nSTRING iteration 0\nSTRING iteration 1\nSTRING iteration 2\n```\n\nAs you can see, we left the while loop early because `i` was equal to two.\n\n#### CONTINUELOOP\n\n`CONTINUELOOP`/`CONTINUE_LOOP`/`CONTINUE` allows you to *continue* through the loop.\n\nDucklingScript\n```\nREPEAT i,5\n    IF i==3\n        CONTINUELOOP\n    $STRING \"I like the number \"+i+\"!\" \n```\nCompiled\n```\nSTRING I like the number 0!\nSTRING I like the number 1!\nSTRING I like the number 2!\nSTRING I like the number 4!\n```\n\nAs you can see, the number 3 is missing from the compiled, because `CONTINUE` continued the loop, ignoring the resulting code after it.\n\n## Multi-File Projects\n\nDuckingScript supports multi-file projects using the `START`, `STARTENV`, `STARTCODE` commands.\n\nAll `START` commands start with the same general syntax, and they allow you to compile the code from another file into the output file. For this to work however, make sure to use the `.txt` extension on all files.\n\nTo start another file, simply use the `START` command, and for the argument put the file name. As long as both files are in the same folder, this will work flawlessly.\n\nFile Structure\n```\nProject\n|-main.txt\n|-startme.txt\n```\nDucklingScript - startme.txt\n```\nSTRING \"startme\" says hello!\n```\nDucklingScript - main.txt\n```\nSTART startme\nSTRING ran startme file.\n```\nCompiled\n```\nSTRING \"startme\" says hello!\nSTRING ran startme file.\n```\n\nThis is great and all, but would if you want to access a file that is inside a folder? Or maybe the file is one level up. In this case comes the dot operator. To go inside a folder, give the name of the folder, then put a dot after. After that dot put the name of the file.\n\nSimilarly, if you want to go a level up, put a dot at the very beginning of the argument.\n\nFile Structure\n```\nProject\n|-above.txt\n|-middle\n  |-main.txt\n  |-below\n    |-below.txt\n```\nDucklingScript - above.txt\n```\nSTRING Hello from above!\n```\nDucklingScript - below.txt\n```\nSTRING Hello from below!\n```\nDucklingScript - main.txt\n```\nREM Using the dot operator at the beginning, we can go up a folder\nREM Using the dot operator in the middle allows use to go into a folder\nSTART\n    .above\n    below.below\n```\nCompiled\n```\nSTRING Hello from above!\nSTRING Hello from below!\n```\n\n## Debugging Commands\n\nBecause DucklingScript ramps up the complexity of your programs, discovering exactly what is happening might become difficult. This is why DucklingScript adds more commands for debugging!\n\nFirst is `PRINT`, which allows you to send text to the console when you ocmpile your injection.\n\nDucklingScript\n```\nPRINT Hello World!\n```\nConsole output\n```\n--> Captured STD:OUT\nexample.txt - 1 > Hello World!\n---\n```\n\nThe next one is `NOTEXIST`/`NOT_EXIST`, which allows you to raise an error if the given variable exists.\n\nDucklingScript\n```\nVAR a \"hello world\"\nNOTEXIST a\n```\nConsole Output\n```\n---\nIn file 'X:\\test.txt', on line 2\n> NOTEXIST a\nGeneralError: 'a' does exist.\n---\n```\n\nThe next up is the opposite of `NOTEXIST`, which is `EXIST`. This raises an error if the given variable doesn't exist.\n\nDucklingScript\n```\nEXIST a\n```\nConsole Output\n```\n---\nIn file 'X:\\test.txt', on line 1\n> EXIST a\nGeneralError: 'a' does not exist.\n---\n```\n\nFinally, we have `PASS`, which allows you to fill in the block space for a block command without actually doing anything. Although a comment works too, `PASS` is cleaner, and allows you to find what hasn't been completed yet in a language specific way.\n\nDucklingScript\n```\nFUNC a\n    PASS\n```\n\n## Expression Evaluation\n\nDucklingScript allows mathematical/logical/conditional expressions. Assuming you already have a basic understanding of 'normal' programming, you should understand ***most*** of this already.\n\n### Data Types\n\nA string is a data type containing characters. It must be wrapped in quotation marks.\n```\n\"Hello World\"\n```\n\nA number is a data type containing, well, a number\n```\n100\n```\nA boolean is either a TRUE or FALSE value. When using these keywords in DucklingScript, make sure to keep them as all caps.\n```\nTRUE\nFALSE\n```\n\n### Mathematics\n\nDucklingScript will follow the rules of PEMDAS (please note that addition/subtraction, and multiplication/division are evaluated left to right. However, multiplation/division is evaluated before addition/subtraction).\n\nPlease note floor division and modulus share the same precedence as multiplication/division.\n\nHere are all of the operators that DucklingScript accepts:\n\nExponents:\n```\n10^2\n```\nResult is 100\n\nAddition/subtraction\n```\n5+5\n5-5\n```\nResult is 10, and 0\n\nMultiplication/division\n```\n5*5\n5/5\n```\nResult is 25, and 1\n\nFloor Division\n```\n3//2\n```\nResult is 1 (the decimal is essentially truncated, meaning removed)\n\nModulus\n```\n5%2\n```\nResult is 1 (when dividing 5 by 2, there is a remainder of 1)\n\nAs well as these, `string`s can also be added together, and can even be added together with other data types:\n\n```\n\"Hello, I like the number \"+5\n```\nResult is `Hello, I like the number 5`\n\n### Conditionals\n\nConditional operators produce a true/false statement (a boolean). Conditionals are evaluated after all mathematical statements, and all Conditionals have the same precedence, meaning they are evaluated left to right.\n\nEqual to\n```\n5==2\n10==10\n```\nResults are `FALSE`, and `TRUE`\n\nNot equal to\n```\n5!=2\n10!=10\n```\nResults are `TRUE`, and `FALSE`\n\nGreater than\n```\n5>2\n10>10\n```\nResults are `TRUE`, and `FALSE`\n\nLesser than\n```\n5<2\n10<10\n```\nBoth result in `FALSE`\n\nGreater than or equal to\n```\n5>=2\n10>=10\n```\nBoth result in `TRUE`\n\nLesser than or equal to\n```\n5<=2\n10<=10\n```\nResults are `FALSE`, and `TRUE`\n\nNot\n```\n!(FALSE)\n!(5!=2)\n!TRUE\n```\nThe results are `TRUE`, `FALSE`, and an *error*\n\n| \u26a0\ufe0f | Unlike other programming languages, in DucklingScript the `NOT` operator requires parenthesis\n|-|-|\n\n# Command Line Interface (CLI)\n\nThe command line interface is used to compile your code, and help assist you on your programming endeavors.\n\nWhen you need help on using the CLI, you can use `--help`:\n```bash\nduckling --help\n```\n\nYou can also use `--help` on specific commands:\n```bash\nduckling compile --help\n```\n\n## CLI Commands\n### New\n\nCreates a new project. This project will include a config file, and a main file.\n\nCommand:\n```\nduckling new [OPTIONS] NAME [PATH]\n```\n\nExample:\n```\nduckling new example-proj\n```\nOutput Tree\n```\nexample-proj\n|- config.yaml\n|- main.txt\n```\n\n### Compile\n\nThe `compile` command compiles your DucklingScript code into Rubber Ducky Language 1.0. Give the file to compile, and then give the output location.\n\nUsage:\n```\nUsage: duckling compile [OPTIONS] FILENAME [OUTPUT]\n```\n\nOptions given to you through the command can also be adjusted through global config files.\n\n### Help\n\nThe `help` command gives you details on any command you give it. \n\nUsage:\n```\nduckling help [OPTIONS] COMMAND_NAME\n```\n\nOutput if we give it `string`:\n```\nduckling help string\n```\n\n![DucklingScript help example](https://github.com/DragonOfShuu/DucklingScript/blob/main/git_docs/Duckling-help-ex.png?raw=true)\n\n### All\n\nThe `all` command gives all the commands in the programming language. In the future, this may include all *plug-in* commands as well.\n\nAll commands as of November 28th, 2023:\n![All DucklingScript example](https://github.com/DragonOfShuu/DucklingScript/blob/main/git_docs/Duckling-all-ex.png?raw=true)\n\n### Version\n\nGives the current version of DucklingScript.\n\nCommand:\n```\nduckling version\n```\n\nOutput as of November 28th, 2023:\n```\nDucklingscript is version 0.1.0\n```\n\n## Global Config File\n\nUpon using the CLI in anyway, a global config is made/edited. The keys inside of the\nglobal config should be identical to the keys that you find inside of the project\nscoped config file. By editing the global config, you can change configurations for\nany time you compile a project-less script.\n\n# Contributing\n\nPython versin must be 3.11 or higher. From then on, I recommend\nputting the python version at the end of any command involving\n`python` or `pip`, like so:\n\n```bash\npython3.11 --version\npip3.11 --version\n```\n\nBy doing this, you avoid mixing python versions.\n\n## Installing Poetry\n\nThen, you will need to install [poetry](https://python-poetry.org/docs/). You can either\nuse the docs given, or you can follow the steps below.\n\nI recommend using pipx, however poetry offers many options. Find the pipx documentation\n[here](https://pipx.pypa.io/stable/installation/).\n\nThese steps should work on Windows. **However, pipx recommends using `brew` to install \npipx on MacOS.**\n```bash\npython3.11 -m pip install pipx\npython3.11 -m pipx ensurepath\n```\n\nRestart your terminal, then run:\n```bash\npipx install poetry\npoetry --version\n```\nPoetry should now work as a command.\n\n## With Poetry Installed\n\nWith poetry installed, inside of the directory \nof the project, run these commands:\n\n```bash\npoetry install\npoetry shell\n```\n\nThis will install the necessary dependencies, and take you \ninto the virtual environment for the project.\n\nNow, while in the virtual environment, you can run the\n`duckling` command!\n\n```bash\nduckling --version\n```\n\n## Contribution Requirements\n\nBefore making a pull request, please format your project\nusing the black command (while in the virtual environment\nprovided by poetry of course):\n\nRun this at the root of the project dir:\n```bash\nblack .\n```\n\nAs well as this, make sure all tests succeed:\n```bash\npytest\n```\n\nIf you've read through this section throughly, write\n\"I've read the Contribution Requirements\" in your\npull request.\n\n# Future Plans\n\nDucklingScript is still not fully complete, so naturally of course there are still plans in the works.\n\nHere are the main ones:\n\n - **Add Plugin Support.** This will allow users to use plugins made by the community; these could include macros (such as open powershell), or possibly new functionality (like a block command).\n\n - **Add Built-in Flipper-Connect System.** This would allow a developer to compile their code directly onto the flipper, which cuts out the need to use a software such as qFlipper.\n\n - **Live Python Interpretation.** This would run your code directly on your computer, and skip the process of compiling to Rubber Ducky Language 1.0. ",
    "bugtrack_url": null,
    "license": "",
    "summary": "A transcompiler for converting DucklingScript code into Rubber Ducky Language 1.0",
    "version": "0.1.3.1",
    "project_urls": {
        "Documentation": "https://github.com/DragonOfShuu/DucklingScript/blob/main/README.md",
        "DragonOfShuu.dev": "https://dragonofshuu.dev/",
        "Homepage": "https://github.com/DragonOfShuu/DucklingScript/",
        "Repository": "https://github.com/DragonOfShuu/DucklingScript/"
    },
    "split_keywords": [
        "duckyscript",
        "flipper",
        "ducky",
        "key injection"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "762a302e6fc44ee1375c1659ae86ae96db02e9560622c30f0023e69c18387fa1",
                "md5": "3f6761553ea3075727771acc66629f86",
                "sha256": "dc8581a2b995a90d38fa7050da741eb715014347173722e12832d042e9b599be"
            },
            "downloads": -1,
            "filename": "ducklingscript-0.1.3.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "3f6761553ea3075727771acc66629f86",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.11,<4.0",
            "size": 71211,
            "upload_time": "2023-12-10T23:20:49",
            "upload_time_iso_8601": "2023-12-10T23:20:49.492945Z",
            "url": "https://files.pythonhosted.org/packages/76/2a/302e6fc44ee1375c1659ae86ae96db02e9560622c30f0023e69c18387fa1/ducklingscript-0.1.3.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "4adeb402784f8c7077c7897af6fe072ea0b3101b1d8d294a0347ed55e6e8269c",
                "md5": "2469d6d4d18cfb1c17e9fa11fd3fef02",
                "sha256": "1be211e44915a77fd980282a2778f7a6d00beabcc05b9829ab7a0f622c38d5a1"
            },
            "downloads": -1,
            "filename": "ducklingscript-0.1.3.1.tar.gz",
            "has_sig": false,
            "md5_digest": "2469d6d4d18cfb1c17e9fa11fd3fef02",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.11,<4.0",
            "size": 44320,
            "upload_time": "2023-12-10T23:20:51",
            "upload_time_iso_8601": "2023-12-10T23:20:51.332275Z",
            "url": "https://files.pythonhosted.org/packages/4a/de/b402784f8c7077c7897af6fe072ea0b3101b1d8d294a0347ed55e6e8269c/ducklingscript-0.1.3.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-12-10 23:20:51",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "DragonOfShuu",
    "github_project": "DucklingScript",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "ducklingscript"
}
        
Elapsed time: 0.15131s